/**************************************************
OpengateM - a MAC address authentication system

 module for misc routines

Copyright (C) 2011 Opengate Project Team
Written by Yoshiaki Watanabe

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Email: watanaby@is.saga-u.ac.jp
**************************************************/
#include "opengatemd.h"

/******************************/
/* lock functions using fcntl */
/******************************/
int lock(int fd){
  struct flock lck;
  
  lck.l_type=F_WRLCK;
  lck.l_whence=SEEK_SET;
  lck.l_start=0;
  lck.l_len=0;
  return fcntl(fd, F_SETLKW, &lck);
}
  
/********************************/
/* unlock functions using fcntl */
/********************************/
int unlock(int fd)
{
  struct flock lck;

  lck.l_type=F_UNLCK;
  lck.l_whence=SEEK_SET;
  lck.l_start=0;
  lck.l_len=0;
  return fcntl(fd, F_SETLK, &lck);
}

/*****************************************************************/
/* return true, if pStr is null-pointer or points to null-string */
/*****************************************************************/
int isNull(const char *pStr)
{
  if(pStr==NULL) return TRUE;
  if(*pStr=='\0') return TRUE;
  return FALSE;
}

/**************************************************/
/* popen with argument list                       */
/* rootPriv: if 1, run command as root user       */
/* type : open type "r" or "w"                    */
/* path : command path to fork/exec               */
/* ... : command arguments. last must be (char*)0 */
/*  DO NOT SET [user entered string] in args      */
/*  to prevent hacking                            */
/**************************************************/
FILE *Popenl(int rootPriv, const char *type, const char *path, ...)
{
  char	commandLine[BUFFMAXLN];
  va_list     ap;
  char *pStr;
  FILE *file;

  /* insert command path */
  strlcpy(commandLine, path, BUFFMAXLN);

  /* insert command arguments */
  va_start(ap, path);
  
  while((pStr=va_arg(ap, char *))!=(char *)0){
    strcat(commandLine, " ");
    strlcat(commandLine, pStr, BUFFMAXLN);
  }
  free(pStr);
  va_end(ap);

  /* if desired, add root privilege */
  if(rootPriv==1){
    if(seteuid(0)!=0){
      err_msg("ERR at %s#%d: cannot add root privilege ",
	      __FILE__,__LINE__);
    } 
  }

  /* open the pipe to the program  */
  if(debug>1) err_msg("DEBUG:=>popen(%s, %s)", commandLine, type);
  file=popen(commandLine, type);
  if(debug>1) err_msg("DEBUG:(%x)<=popen( )",file);  

  /* remove root privilege */
  seteuid(getuid()); 

  return file;
}


/**************************************************/
/* system with argument list                      */
/* rootPriv: if 1, run command as root user       */
/* path : command path to fork/exec               */
/* ... : command arguments. last must be (char*)0 */
/*  DO NOT SET [user entered string] in args      */
/*  to prevent hacking                            */
/**************************************************/
int Systeml(int rootPriv, const char *path, ...)
{
  char	commandLine[BUFFMAXLN];
  va_list     ap;
  char *pStr;
  int ret;

  /* insert command path */
  strlcpy(commandLine, path, BUFFMAXLN);

  /* insert command arguments */
  va_start(ap, path);
  
  while((pStr=va_arg(ap, char *))!=(char *)0){
    strcat(commandLine, " ");
    strlcat(commandLine, pStr, BUFFMAXLN);
  }
  free(pStr);
  va_end(ap);

  /* if desired, add root privilege */
  if(rootPriv==1){
    if(seteuid(0)!=0){
      err_msg("ERR at %s#%d: cannot add root privilege ",
	      __FILE__,__LINE__);
    } 
  }

  /* execute shell  */
  if(debug>1) err_msg("DEBUG:=>system(%s)", commandLine);
  ret=system(commandLine);
  if(debug>1) err_msg("DEBUG:<=system()");

  /* remove root privilege */
  seteuid(getuid()); 
  return ret;
}

/****************************************/
/****************************************/
int Pclose(FILE *stream)
{
  int ret;

  if(debug>1) err_msg("DEBUG:=>pclose( )");
  ret = pclose(stream);
  if(debug>1) err_msg("DEBUG:<=pclose( )");  

  return ret;
}


int Lock(int fd)
{
  int ret;

  if(debug>1) err_msg("DEBUG:=>lock( )");
  ret=lock(fd);
  if(debug>1) err_msg("DEBUG:(%d)<=lock( )",ret);

  return ret;
}


int Unlock(int fd)
{
  int ret;

  if(debug>1) err_msg("DEBUG:=>unlock( )");
  ret=unlock(fd);
  if(debug>1) err_msg("DEBUG:(%d)<=unlock( )",ret);

  return ret;
}


int
Open(const char *pathname, int oflag, mode_t mode)
{
	int		fd;

	if ( (fd = open(pathname, oflag, mode)) == -1)
		err_msg("open error for %s", pathname);
	return(fd);
}

int
Close(int fd)
{
  int ret;

  /*if( (ret=close(fd)) == -1)
   *  err_msg("close error");
   */

  ret=close(fd);

  return ret;
}

pid_t
Fork(void)
{
	pid_t	pid;

	if ( (pid = fork()) == -1)
		err_msg("fork error");
	return(pid);
}

int
Pipe(int *fds)
{
  int ret;
	if ((ret=pipe(fds)) < 0)
		err_msg("pipe error");

	return ret;
}

void *
Malloc(size_t size)
{
	void	*ptr;

	if ( (ptr = malloc(size)) == NULL)
		err_msg("malloc error");
	return(ptr);
}

