/*
 *
 * bbrun.c
 *
 * Robert-Andre Croteau
 * Version 1.9b
 * Apr 08th, 2002
 *
 * (c) Copyright Quest Software, Inc.  1997-2002  All rights reserved.
 *
 * Start a program and optionnally prefix that program's
 *   output date and program name.
 *
 */


#include "bb.h"		/* THE BIG BROTHER INCLUDE FILE */
#include <sys/types.h>
#ifdef TIMEH
#include <time.h>       /* FOR TIMING STUFF SMM */
#if GETTIMEOFDAY
#include <sys/time.h>
#endif
#else
#include <sys/time.h>   /* FOR TIMING STUFF SMM */
#endif
#include <sys/stat.h>

char bbprog[] = "";	/* Don't define it as it won't appear in bb_errmsg() */

int main(argc, argv)
int argc;       
char *argv[];
{
char *progp,*execname;
char *bbsleep,*bbpid;
time_t starttime,endtime,bbtime,sleeptime;
struct stat statbuf;
char cmdline[1024];
FILE *pipef,*bbpidf;
char pipeline[1024];
char errmsg[2048];
int prefix;
int bb_errmsg();

	/* There should be either 1 or 2 arguments */
	if( argc != 2  && argc != 3 ) {
		bb_errmsg("bbrun","Invalid count of arguments");
		bb_errmsg("bbrun","Usage: bbrun [-a] <program/script>");
		exit(2);
	} 

	/* If there's 2, then the 1st one should be -a */
	if( (argc == 3) && (strcmp(argv[1],"-a") != 0) ) {
		bb_errmsg("bbrun","Invalid argument");
		bb_errmsg("bbrun","Usage: bbrun [-a] <program/script>");
		exit(3);
	}

	/* Is program name the 1st or 2nd argument */
	if( argc == 2 ) {
		prefix = 0;
		progp = argv[1];
	}
	else {
		prefix = 1;
		progp = argv[2];
	}

	/* Does it exist ? */
	if( stat(progp,&statbuf) != 0 ) {
		/* doesn't exist */
		bb_errmsg("bbrun","Program/script not found");
		exit(4);
	}
	
	if( strlen(progp) > (sizeof(cmdline)-strlen(" 2>&1 ")-1) ) {
		bb_errmsg("bbrun","Program/script path too long");
		exit(5);
	}

	/* Env variable BBSLEEP should have been defined */
	if( (bbsleep=getenv("BBSLEEP")) == NULL ) {
		bb_errmsg("bbrun","BBSLEEP undefined");
		exit(6);
	}
	/* and non-null */
	if( (strlen(bbsleep) == 0) || (atoi(bbsleep) == 0) ) {
		bb_errmsg("bbrun","BBSLEEP undefined/invalid");
		exit(7);
	}

	/* Env variable BBPID should have been defined */
	if( (bbpid=getenv("BBPID")) == NULL ) {
		bb_errmsg("bbrun","BBPID undefined");
		exit(8);
	}
	/* and non-null */
	if( strlen(bbpid) == 0 ) {
		bb_errmsg("bbrun","BBPID undefined");
		exit(9);
	}

	if( (bbpidf=fopen(bbpid,"a")) == NULL ) {
		bb_errmsg("bbrun","Can't open file defined in BBPID");
		exit(10);
	}
	else {
		fprintf(bbpidf,"%d\n",getpid());
		fclose(bbpidf);
	}

	sprintf(cmdline,"%s 2>&1",progp);
	if( (execname=strrchr(progp,'/')) != NULL ) {
		execname++;
	}
	else {
		execname = progp;
	}

	while(1) {
		starttime = time(NULL);
		if( (pipef=popen(cmdline,"r")) != NULL ) {
			memset(pipeline,0,sizeof(pipeline));
			while( fgets(pipeline,sizeof(pipeline)-1,pipef) != 0 ) {
				/* Remove newline */
				if( prefix ) {
					pipeline[strlen(pipeline)-1] = '\0';
					bb_errmsg(execname,pipeline);
				}
				else {
					fprintf(stderr,"%s",pipeline);
				}
				memset(pipeline,0,sizeof(pipeline));
			}
			pclose(pipef);
		}
		else {
			bb_errmsg(stderr,"Could not execute program/script");
		}

		endtime = time(NULL);

		bbtime = endtime - starttime;
		if( bbtime < atoi(bbsleep) ) {	
			/* Fix for invalid BBTIME
			 * If xntpd/ntpdate changes date back a few
			 * seconds/mins/hours may cause this
			 */
			if( bbtime < 0 ) {
				sprintf(errmsg,"(%s) Runtime of %dsecs is invalid",execname,(int)bbtime);
				bb_errmsg("bbrun",errmsg);
				bbtime = 0 - bbtime;
				bbtime %= atoi(bbsleep);
			}
			sleeptime = atoi(bbsleep) - bbtime;
			if( sleeptime > 0 ) {
				sleep(sleeptime);
			}
			else {
				sleep(atoi(bbsleep));
			}
		}
        	else {
			sprintf(errmsg,"(%s) Runtime of %dsecs is longer than BBSLEEP (%s)",execname,(int)bbtime,bbsleep);
			bb_errmsg("bbrun",errmsg);
		}
	}

	exit(0);
}
