
/* $Id: utils.c,v 1.56 2009/03/29 19:15:44 jayrfink Exp $ */

/*
 * Independent C Utilities written by Jason (Jay) R. Fink
 * LICENSE: See COPYING file for details
 */

#include "utils.h"

void   exit_utils  (int);                          /* Daemonize helper   */
char * sec_strncpy (char *, const char *, size_t); /* Opts Parser helper */

/*
 * copy_argv: copy out any unprocessed arguments off of argv and return
 *
 * requires: argument vector
 * returns : string
 */
char *copy_argv(char **argv)
{
	char **p;
	u_int len = 0;
	char *buf;
	char *src, *dst;

	p = argv;

	if (*p == 0)
		return 0;

	while (*p)
		len += strlen(*p++) + 1;

	buf = (char *) malloc(len);
	if (buf == NULL) {
		fprintf(stdout, "copy_argv: malloc");
		exit(1);
	}

	p = argv;
	dst = buf;
	while ((src = *p++) != NULL) {
		while ((*dst++ = *src++) != '\0');
		dst[-1] = ' ';
	}
	dst[-1] = '\0';

	return buf;
}

/* 
 * execwip: call external command or script and furnish an IP address
 *          as the only argument.
 *
 * requires: path and ip
 * returns : success or fail (0 or 1)
 */
int execwip(const char *path, char *ip)
{
	int retval;
	char fullcmd[1024];

	strcpy(fullcmd, path);
	strcat(fullcmd, " ");
	strcat(fullcmd, ip);
#ifdef DEBUG
	printf("debug: calling script %s with argument of %s\n");
#endif
	retval = 0;
	retval = system(fullcmd);

	return (retval);
}


/*
 * daemonize: Daemonize a process
 *
 * requires: NA
 * returns : result (int)
 */
int daemonize (void) 
{
	int pid_child;

	signal (SIGALRM, SIG_IGN);
	signal (SIGHUP, SIG_IGN);
	signal (SIGPIPE, SIG_IGN);
	signal (SIGTERM, exit_utils);
	signal (SIGABRT, exit_utils);
	signal (SIGURG, exit_utils);
	signal (SIGKILL, exit_utils);

	if ((pid_child = fork ()) < 0)
		return (1);
	else if (pid_child > 0)
		exit (0);

	setsid ();
	chdir ("/");
	umask (077);

	/* close stdout, stdin, stderr */
	close(0);
	close(1);
	close(2);

	return (0);
}
void exit_utils (int status)  { exit (status); } /* For daemonize only */

/*
 * append_file: Appends a string to the static logfile
 *
 * requires: Message string and logfile
 * returns : NA
 */
void logit(char *str, char *file)
{
        FILE *fp;

        if ((fp = fopen(file, "a")) == NULL) {
                fprintf(stderr, "error: could not open file %s", file);
                exit(1);
        }

        fputs(str, fp);
        fclose(fp);
}

/* 
 * sec_strncpy: strncpy secure replacement
 *
 * requires: dst, src, size
 * returns : string
 */
char * sec_strncpy (char *dst, const char *src, size_t size)
{
	if (!dst) {
		dst = NULL;
		return (NULL);
	} else if (size < 1) {
		dst = NULL;
		return (NULL);
	}

	memset (dst, '\0', size);
	strncpy (dst, src, size - 1);

	return (dst);
}

/* 
 * quote_check: Checks for quotes at ends of a string
 *
 * requires: buffer and token
 * returns : success (0) or fail (1)
 */
short int quote_check (char * buffer, char *token)
{
	if (strstr(buffer,"\"") == (char *)NULL) {
		fprintf(stderr,"No quotes around %s skipping\n",token);
		return 1;
	}

	return 0;
}

/*
 * get_cfg_param: Parse an option out of a config file
 * in the form of OPTION_NAME = "argument string"
 *
 * requires: token, val and file
 * returns : config value
 */
int get_cfg_param (char *token, char *cval, char *configfile)
{
	FILE *config;
	char buffer[MAXBUF], buf[MAXBUF];
	int cnt = 0;

	if ((config = fopen (configfile, "r")) == NULL) {
		fprintf(stderr, "Cannot open config file: %s.\n", configfile);
		return (1);
	} else {
		while ((fgets (buffer, MAXBUF, config)) != NULL) {
			if (buffer[0] != '#') { /* this skips comments */
				/*
				 * search for the token and make sure the 
				 * trailing character is a " " or "=" to make 
				 * sure the entire token was found 
		                 * cut off the '=' and send it back 
				 */
				if ((strstr (buffer, token) != (char *) NULL) &&
					((buffer[strlen(token)] == '=') || 
					(buffer[strlen(token)] == ' '))) {
					if(quote_check(buffer,token) > 0) {
						fclose(config);
						return (1);
					}

					sec_strncpy(buf,strstr(buffer,"\"") +1,
							 MAXBUF);
					/* strip unprintable/linefeed (if any)*/
					cnt = 0;
					while (cnt < MAXBUF - 1) {
						if((isprint(buf[cnt])) &&
							buf[cnt] != '"')
							cval[cnt]=buf[cnt];
						else {
							cval[cnt]='\0';
							break;
						}

						cnt++;
					}

					cval[MAXBUF - 1] = '\0';
					fclose (config);
					return (0);
				}
			}
		}
		fclose (config);
		return (1);
	}
}

