/*
 *
 * dohostsvc.c
 * BIG BROTHER BUILD HTML STATUS LOG
 * Robert-Andre Croteau
 * Version 1.9c
 * May 06th, 2002
 *
 * (c) Copyright Quest Software, Inc.  1997-2002  All rights reserved.
 *
 * Take the status log and save an HTML version of it in a buffer
 *
 */


#include "bb.h"		/* THE BIG BROTHER INCLUDE FILE */
#include <errno.h>
#include <sys/stat.h>
#include <ctype.h>


static char *webhistory;
static char *cgibinurl;
static char *bbskin;			/* SMM STRIKES AGAIN */
static char *logtime;
static char *bbacksdir;
char *headerpage,*footerpage;		/* SMM MADE THESE NON STATIC */
int footerpage_size,headerpage_size;	/* SMM MADE THESE NON STATIC */
static char headname[MAXLINE];
static char footname[MAXLINE];

int getheader(bbwebdir, bbheader)
char *bbwebdir;
char *bbheader;
{
FILE *bbhead;
struct stat statbuf;
int statres,retc;

	/*
	 * All this env stuff should be modularized ...
	 */
	/* Get where the  acks log files are saved (BBACKS) */
	bbacksdir=(char *)getenv("BBACKS");
	if ( bbacksdir == NULL )
		bbacksdir = "";
        webhistory = (char *) getenv("WEBHISTORY");
        if ( webhistory == NULL )
                webhistory = "";
        cgibinurl = (char *) getenv("CGIBINURL");
        if ( cgibinurl == NULL )
                cgibinurl = "";
        bbskin = (char *) getenv("BBSKIN");	/* SMM SKINS */
        if ( bbskin == NULL )
                bbskin = "gifs";		/* THE USUAL PLACE */
        logtime = (char *) getenv("LOGTIME");
        if ( logtime == NULL )
                logtime = "LOGTIME not set";

	if ( headerpage != NULL )
		free(headerpage);

	headerpage = NULL;

	/* Get file info for header file */
	if (bbheader)		/* SMM */
		sprintf(headname, "%s/%s", bbwebdir, bbheader);
	else
		sprintf(headname, "%s/hostsvc_header", bbwebdir);
	statres=stat(headname, &statbuf);
	if( statres == -1 )
		return(0);

	headerpage_size = statbuf.st_size + 4096;

	/* Fill the buffer */
	headerpage = (char *) calloc(1,headerpage_size);

	if( headerpage == NULL ) {
		return(0);
	}

	*headerpage = '\0';
	
	/* Open and read header file in one call*/
	if( (bbhead = fopen(headname, "r")) != NULL ) {
		retc = fread(headerpage,statbuf.st_size,1,bbhead);
		/* Was the header file read in completely ? */
		if ( retc != 1 || strlen(headerpage) != statbuf.st_size ) {
			free(headerpage);
			headerpage = NULL;
		}
		else {
#if DEBUG
			debug("header: %s\n",headerpage);
#endif
		}
		fclose(bbhead);
	}
	else {
		return(0);
	}

	return(1);
}

int getfooter(bbwebdir, bbfooter)
char *bbwebdir;
char *bbfooter;
{
FILE *bbfoot;
struct stat statbuf;
int statres,retc;

	if ( footerpage != NULL )
		free(footerpage);

	footerpage = NULL;

	/* Get file info for footer file */
	if (bbfooter)				/* SMM */
		sprintf(footname, "%s/%s", bbwebdir, bbfooter);
	else
		sprintf(footname, "%s/hostsvc_footer", bbwebdir);
	statres=stat(footname, &statbuf);

	if( statres == -1 )
		return(0);

	footerpage_size = statbuf.st_size + 4096;

	/* Fill the buffer  */
	footerpage = (char *) calloc(1,footerpage_size);

	if( footerpage == NULL ) {
		return(0);
	}

	*footerpage = '\0';
	
	/* Open and read footer file in one call*/
	if( (bbfoot = fopen(footname, "r")) != NULL ) {
		retc = fread(footerpage,statbuf.st_size,1,bbfoot);
		/* Was the footer file read in completely ? */
		if ( retc != 1 || strlen(footerpage) != statbuf.st_size ) {
			free(footerpage);
			footerpage = NULL;
		}
		else {
#if DEBUG
			debug("footer: %s\n",footerpage);
#endif
		}
		fclose(bbfoot);
	}
	else {
		return(0);
	}

	return(1);
}

char *dohostsvc(status,filename,bbweb,bbwebdir,timebuf)
char *status;
char *filename;
char *bbweb;
char *bbwebdir;
char *timebuf;
{
char hostname[MAXLINE];
char bbbkgfile[MAXLINE],bbip[MAXLINE],bbipname[MAXLINE];
char *dotheight,*dotwidth,*mkbbrowfont,*mkbbcolfont,*mkbbackfont;
char redline[MAXLINE],greenline[MAXLINE],yellowline[MAXLINE],purpleline[MAXLINE],clearline[MAXLINE],blueline[MAXLINE];
char *bbhost,*bbsvc;
char htmlline[MAXLINE],dataline[MAXLINE];
char *ptrmsg,*nlmsg,*lastptrmsg;
char *tempheaderpage,*tempfooterpage;
char *hostsvcdata;
int hostsvcdata_size,msglen,first;
char color[80],*charp;
char *dur;
char *sentby;
char *tempptr;
int  templen;
char ackfilename[MAXLINE],ack_event[MAXLINE],ack_rcpt[MAXLINE];
char ack_number[MAXLINE],ack_timestamp[MAXLINE],ack_msg[MAXLINE],ack_delay[MAXLINE];
char *ackfilebuf;
struct stat statbuf;
time_t timenow;
char *ack_tag,*msgptr;
extern char *readfile();

	strncpy(color,status,sizeof(color)-1);
	/* Get color, 1st space or tab marks end of line */
	charp = (char *) strchr(color,' ');
	if( charp != NULL )
		*charp = '\0';
	charp = (char *) strchr(color,'\t');
	if( charp != NULL )
		*charp = '\0';
	
	hostsvcdata_size = strlen(status) + headerpage_size + footerpage_size + 4096;

	hostsvcdata = (char *) malloc(hostsvcdata_size);
	if (hostsvcdata == NULL )
		return(NULL);
	hostsvcdata[0] = '\0';

	/* Find the values of BBHOST / BBSVC 	*/
	/* filename:  xxx,domain,com.disk	*/
	/*            xxx.svc			*/
	/* BBHOST -> xxx.domain.com or xxx	*/
	/* BBSVC -> disk			*/
	memset(hostname,0,sizeof(hostname));
	strncpy(hostname,filename,sizeof(hostname)-1);
	bbsvc = (char *) strrchr(hostname,'.');
	if( bbsvc ) {
		*bbsvc = '\0'; /* NULL for bbhost */
		bbsvc++;
	}
	bbhost = hostname;
	while( (bbhost=(char *)strchr(bbhost,',')) != NULL ) {
		*bbhost = '.';
	}
	bbhost=hostname;

	/* Go get IP address of host, if 0.0.0.0, return hostname (3rd arg==0) */
	getipaddr(bbhost,bbipname,sizeof(bbipname),0);
	/* Go get IP address of host, always return IP addr (3rd arg==1), unless not found then return hostname */
	getipaddr(bbhost,bbip,sizeof(bbip),1);

	if( headerpage != NULL ) {
		tempheaderpage = (char *) malloc(headerpage_size);
		if( tempheaderpage != NULL ) {
			strcpy(tempheaderpage,headerpage);
			replacestr(tempheaderpage,headerpage_size,"&BBDATE",timebuf);
			sprintf(bbbkgfile,"%s/bkg-%s.gif",bbskin, color);
			replacestr(tempheaderpage,headerpage_size,"&BBBACKGROUND",bbbkgfile);
			replacestr(tempheaderpage,headerpage_size,"&BBWEB",bbweb);
			replacestr(tempheaderpage,headerpage_size,"&BBRELDATE",BBRELDATE);
			replacestr(tempheaderpage,headerpage_size,"&BBREL",BBREL);
			replacestr(tempheaderpage,headerpage_size,"&BBCOLOR",color);
			replacestr(tempheaderpage,headerpage_size,"&BBHOST",bbhost);
			replacestr(tempheaderpage,headerpage_size,"&BBSVC",bbsvc);
			replacestr(tempheaderpage,headerpage_size,"&BBIPNAME",bbipname);
			replacestr(tempheaderpage,headerpage_size,"&BBIP",bbip);
			replacestr(tempheaderpage,headerpage_size,"&BBSKIN",bbskin); /* SMM */
			replacestr(tempheaderpage,headerpage_size,"&CGIBINURL",cgibinurl);
			replacestr(tempheaderpage,headerpage_size,"&LOGTIME",logtime);

			strcat(hostsvcdata,tempheaderpage);

			free(tempheaderpage);
		}
		else {
			strcat(hostsvcdata,"<HTML><BODY>\n<HR size=4>\n<BR>bbd is out of memory ... investigate<BR>\n<HR size=4>\n");
		}
	}
	else {
		/* Print proper error message, thanks to Mark Deiss <mcd@crexm.acs-gsg.com> */
		strcat(hostsvcdata,"<HTML><BODY>\n<HR size=4>\n<BR>");
		strcat(hostsvcdata,headname);
		strcat(hostsvcdata," was not found, please create this file with your custom header<BR>\n<HR size=4>\n");
	}

	/* Now print generic stuff */

	if( (mkbbrowfont = (char *) getenv("MKBBROWFONT")) == NULL ) {
		mkbbrowfont = "";
	}
	if( (mkbbcolfont = (char *) getenv("MKBBCOLFONT")) == NULL ) {
		mkbbcolfont = "";
	}
	if( (mkbbackfont = (char *) getenv("MKBBACKFONT")) == NULL ) {
		mkbbackfont = "";
	}
	if( (dotheight = (char *) getenv("DOTHEIGHT")) == NULL ) {
		dotheight = "";
	}
	if( (dotwidth = (char *) getenv("DOTWIDTH")) == NULL ) {
		dotwidth = "";
	}

	strcat(hostsvcdata,"\n\n<!-- Start of code generated by Big Brother Systems and Network Monitor -->\n\n");
	strcat(hostsvcdata,"<BR><BR>\n");
	strcat(hostsvcdata,"\n\n<A NAME=begindata>&nbsp;</A>\n\n");
	strcat(hostsvcdata,"<CENTER><TABLE ALIGN=CENTER BORDER=0>\n");
	sprintf(dataline,"<TR><TH><FONT %s>\n", mkbbrowfont);
	strcat(hostsvcdata,dataline);
	sprintf(dataline,"%s - %s<BR><HR WIDTH=60%%></TH>\n",bbhost,bbsvc);
	strcat(hostsvcdata,dataline);
	strcat(hostsvcdata,"<TR><TD><H3>\n");

	ptrmsg = status;

	/* Add a newline at the end of the message if there isn't one */
	msglen = strlen(ptrmsg);
	if ( ptrmsg[msglen-1] != '\n' ) {
		ptrmsg[msglen+1] = '\0';
		ptrmsg[msglen] = '\n';
	}

	/* Read all lines except the last 2 lines, "received from" and "unchanged" */
	/* Each log ends with these two lines */
	/* Status unchanged in 23.22 days */
	/* Status message received from 204.19.117.80 */
	/* Those are displayed differently */
	dur = sentby = "";
	lastptrmsg = (char *) strrchr(ptrmsg,'\n');	/* go to last newline */
	if ( lastptrmsg != NULL ) {
		*lastptrmsg = '\0';
		lastptrmsg = (char *) strrchr(ptrmsg,'\n');
		if ( lastptrmsg != NULL ) {
			*lastptrmsg = '\0';
			sentby = lastptrmsg + 1; /* next is received from message */
			lastptrmsg = (char *) strrchr(ptrmsg,'\n');
			if( lastptrmsg != NULL ) {
				dur = lastptrmsg + 1; /* next is status unchanged in */
				*lastptrmsg = '\0';
			}
		}
	}
	if( lastptrmsg == NULL ) {
		lastptrmsg = ptrmsg + strlen(ptrmsg);
	}

	memset(ack_event,0,sizeof(ack_event));
	memset(ack_rcpt,0,sizeof(ack_rcpt));
	memset(ack_number,0,sizeof(ack_number));
	memset(ack_delay,0,sizeof(ack_delay));
	memset(ack_timestamp,0,sizeof(ack_timestamp));
	memset(ackfilename,0,sizeof(ackfilename));
	strncpy(ackfilename,bbacksdir,sizeof(ackfilename)-1);
	strncat(ackfilename,"/ack.",sizeof(ackfilename)-strlen(ackfilename)-1);
	strncat(ackfilename,bbhost,sizeof(ackfilename)-strlen(ackfilename)-1);
	strncat(ackfilename,".",sizeof(ackfilename)-strlen(ackfilename)-1);
	strncat(ackfilename,bbsvc,sizeof(ackfilename)-strlen(ackfilename)-1);
	memset(ack_msg,0,sizeof(ack_msg));
	ack_tag = "";
	msgptr = "";
	timenow = time(NULL);
	if( stat(ackfilename, &statbuf) == 0 ) {
		if( statbuf.st_mtime > timenow ) {
			if( (ackfilebuf=readfile(ackfilename,MAXLINE-1)) != NULL ) {
				sscanf(ackfilebuf,"%s %s %s %s %s",ack_event,ack_rcpt,ack_number,ack_delay,ack_timestamp);
				strcpy(ack_msg,"Current acknowledgement by ");
				strncat(ack_msg,ack_rcpt,sizeof(ack_msg)-strlen(ack_msg)-1);
				if( strlen(ack_timestamp) > 0 ) {
					if( (msgptr=(char *)strstr(ackfilebuf,ack_timestamp)) != NULL ) {
						msgptr += strlen(ack_timestamp) + 1;
						if( *msgptr ) {
							stripleadtrailspaces(msgptr);
							strncat(ack_msg," - comment: ",sizeof(ack_msg)-strlen(ack_msg)-1);
							strncat(ack_msg,msgptr,sizeof(ack_msg)-strlen(ack_msg)-1);
						}
					}
				}
				free(ackfilebuf);
			}
			else {
				strcpy(ack_msg,"This event has been acked");
			}
			ack_tag = "-ack";
		}
	}

	sprintf(greenline,"<IMG SRC=\"%s/green.gif\" ALT=\"green\" HEIGHT=\"%s\" WIDTH=\"%s\" BORDER=0>",bbskin,dotheight,dotwidth);
	sprintf(redline,"<IMG SRC=\"%s/red%s.gif\" ALT=\"red\" HEIGHT=\"%s\" WIDTH=\"%s\" BORDER=0>",bbskin,ack_tag,dotheight,dotwidth);
	sprintf(yellowline,"<IMG SRC=\"%s/yellow%s.gif\" ALT=\"yellow\" HEIGHT=\"%s\" WIDTH=\"%s\" BORDER=0>",bbskin,ack_tag,dotheight,dotwidth);
	sprintf(purpleline,"<IMG SRC=\"%s/purple%s.gif\" ALT=\"purple\" HEIGHT=\"%s\" WIDTH=\"%s\" BORDER=0>",bbskin,ack_tag,dotheight,dotwidth);
	sprintf(clearline,"<IMG SRC=\"%s/clear.gif\" ALT=\"clear\" HEIGHT=\"%s\" WIDTH=\"%s\" BORDER=0>",bbskin, dotheight,dotwidth);
	/* This line was missing, thanks to John Horne <J.Horne@plymouth.ac.uk> */
	sprintf(blueline,"<IMG SRC=\"%s/blue.gif\" ALT=\"blue\" HEIGHT=\"%s\" WIDTH=\"%s\" BORDER=0>",bbskin, dotheight,dotwidth);
	first = 0;
	while( ((nlmsg=(char *)strchr(ptrmsg,(int) '\n')) != NULL) && (ptrmsg < lastptrmsg)  ) {
		*nlmsg='\0';
		strcpy(htmlline,ptrmsg);
		replacestr(htmlline,sizeof(htmlline),"&green",greenline);
		replacestr(htmlline,sizeof(htmlline),"&red",redline);
		replacestr(htmlline,sizeof(htmlline),"&yellow",yellowline);
		replacestr(htmlline,sizeof(htmlline),"&purple",purpleline);
		replacestr(htmlline,sizeof(htmlline),"&clear",clearline);
		/* This line was missing, thanks to John Horne <J.Horne@plymouth.ac.uk> */
		replacestr(htmlline,sizeof(htmlline),"&blue",blueline);
		if( (strlen(hostsvcdata) + strlen(htmlline) + 1024) > hostsvcdata_size-1 ) {
			templen = strlen(hostsvcdata);
			hostsvcdata_size += strlen(htmlline) + 4096;
			tempptr = hostsvcdata;
			hostsvcdata = (char *) realloc(hostsvcdata,hostsvcdata_size);
			if( hostsvcdata == NULL ) {
				free(tempptr);
				return(NULL);
			}
			hostsvcdata[templen] = '\0';
		}
       		strcat(hostsvcdata,htmlline);
		strcat(hostsvcdata,"\n");
		if (first == 0) {		/* FIRST LINE */
       			strcat(hostsvcdata, "</H3><PRE>\n");
			first = 1;
		}
		ptrmsg = nlmsg + 1;
	}

	templen = strlen(ptrmsg) + 4096;
	if( (strlen(hostsvcdata)+templen) > (hostsvcdata_size-1) ) {
		hostsvcdata_size += templen;
		templen = strlen(hostsvcdata);
		tempptr = hostsvcdata;
		hostsvcdata = (char *) realloc(hostsvcdata,hostsvcdata_size);
		if( hostsvcdata == NULL ) {
			free(tempptr);
			return(NULL);
		}
		hostsvcdata[templen] = '\0';
	}

       	strcat(hostsvcdata, ptrmsg); /* PUKE message line */

	if (first == 0) {		
       		strcat(hostsvcdata,"</H3>\n");
	}
	else {
		strcat(hostsvcdata,"</PRE>\n");
	}

	strcat(hostsvcdata, "</TD></TR></TABLE>\n");
	strcat(hostsvcdata, "<BR><BR>\n");
	strcat(hostsvcdata,"<TABLE ALIGN=CENTER BORDER=0>\n");
	strcat(hostsvcdata,"<TR><TD ALIGN=CENTER>\n");
	sprintf(dataline,"<FONT %s>\n", mkbbcolfont);
	strcat(hostsvcdata,dataline);
       	sprintf(dataline, "%s<BR>", dur);   	/* PUKE  status unchanged */
	strcat(hostsvcdata,dataline);
       	sprintf(dataline, "%s</FONT>", sentby);  /* PUKE  status from ip */
	strcat(hostsvcdata,dataline);
	if( strlen(ack_msg) > 0 ) {
		convert_web_str(ack_msg);
		sprintf(dataline, "<BR><FONT %s>%s</FONT>",mkbbackfont,ack_msg);
		strcat(hostsvcdata,dataline);
	}
	strcat(hostsvcdata,"</TD></TR>\n");
	strcat(hostsvcdata,"</TABLE>\n");
	if ( webhistory && cgibinurl && !strcmp(webhistory,"TRUE") ) {
#ifdef LARRD
		/* If LARRD is defined then you'll get a link to the  */
		/* graph for that host.service pair */
		sprintf(dataline,"<BR><BR><CENTER><A HREF=\"%s/larrd-grapher.cgi?host=%s&service=%s\"><IMG SRC=\"%s/larrd-grapher.cgi?host=%s&service=%s&graph=hourly\"ALT=\"larrd is accumulating %s\" BORDER=0></A><BR><CENTER>\n",cgibinurl,bbhost,bbsvc,cgibinurl,bbhost,bbsvc,bbsvc);
                 strcat(hostsvcdata,dataline);
#endif
		/* Changed ALT="HIST..." to NAME="HIST..." */
		/* Thanks to Andrew Dalgleish <andrewd@axonet.com.au> */
		sprintf(dataline,"<BR><BR><CENTER><FORM ACTION=\"%s/bb-hist.sh\"><INPUT TYPE=SUBMIT VALUE=\"HISTORY\"><INPUT TYPE=HIDDEN NAME=\"HISTFILE\" VALUE=\"%s\"><INPUT TYPE=HIDDEN NAME=\"ENTRIES\" VALUE=\"50\"></FORM></CENTER>\n",cgibinurl,filename);
		strcat(hostsvcdata,dataline);
	}
	else {
		sprintf(dataline,"<BR><BR><CENTER><A HREF=\"hist/%s\"><B>HISTORY</B></a></CENTER>\n",filename);
		strcat(hostsvcdata,dataline);
	}

	strcat(hostsvcdata,"</CENTER>\n\n<!-- End of code generated by Big Brother Systems and Network Monitor -->\n\n");

	/* Open and read footer file */
	if( footerpage != NULL ) {
		tempfooterpage = (char *) malloc(footerpage_size);
		if( tempfooterpage != NULL ) {
			strcpy(tempfooterpage,footerpage);
			replacestr(tempfooterpage,footerpage_size,"&BBDATE",timebuf);
			sprintf(bbbkgfile,"%s/bkg-%s.gif",bbskin,color);
			replacestr(tempfooterpage,footerpage_size,"&BBBACKGROUND",bbbkgfile);
			replacestr(tempfooterpage,footerpage_size,"&BBWEB",bbweb);
			replacestr(tempfooterpage,footerpage_size,"&BBRELDATE",BBRELDATE);
			replacestr(tempfooterpage,footerpage_size,"&BBREL",BBREL);
			replacestr(tempfooterpage,footerpage_size,"&BBCOLOR",color);
			replacestr(tempfooterpage,footerpage_size,"&BBHOST",bbhost);
			replacestr(tempfooterpage,footerpage_size,"&BBSVC",bbsvc);
			replacestr(tempfooterpage,footerpage_size,"&BBSKIN",bbskin); /* SMM */
			replacestr(tempfooterpage,footerpage_size,"&CGIBINURL",cgibinurl);
			/* replaced header with footer, thanks to */
			/* Patrice GUERLAIS <patrice.guerlais@echo.fr> */
			replacestr(tempfooterpage,footerpage_size,"&LOGTIME",logtime);

			templen = strlen(tempfooterpage) + 4096;
			if( (strlen(hostsvcdata)+templen) > (hostsvcdata_size-1) ) {
				hostsvcdata_size += templen;
				templen = strlen(hostsvcdata);
				tempptr = hostsvcdata;
				hostsvcdata = (char *) realloc(hostsvcdata,hostsvcdata_size);
				if( hostsvcdata == NULL ) {
					free(tempptr);
					return(NULL);
				}
				hostsvcdata[templen] = '\0';
			}

			strcat(hostsvcdata,tempfooterpage);
			free(tempfooterpage);
		}
		else {
			strcat(hostsvcdata,"<HTML><BODY>\n<HR size=4>\n<BR>bbd is out of memory ... investigate<BR>\n<HR size=4>\n");
		 }
	}
	else {
		/* Print proper error message, thanks to Mark Deiss <mcd@crexm.acs-gsg.com> */
		strcat(hostsvcdata,"<HR size=4><BR>");
		strcat(hostsvcdata,footname);
		strcat(hostsvcdata," was not found, please create this file with your custom footer<BR><HR size=4> ");
	}

#ifdef MAYBEONEDAY
	sprintf(dataline,"<BR><BR><CENTER><H6><I><!-- By abiding to the license agreement you must leave the link back to BB --><FONT FACE=\"Arial, Helvetica\" COLOR=\"silver\"><A HREF=\"http://www.bb4.com\">Big Brother Systems &amp; Network Monitor %s </A><BR>&copy; Copyright Quest Software, Inc.  1997-2002<BR>All rights reserved.</FONT></I></H6></CENTER></BODY></HTML>",BBREL);
	strcat(hostsvcdata,dataline);
#endif


	return(hostsvcdata);
}
