/* $Id: textfile.c,v 1.9 2000/05/10 03:24:36 jared Exp $ */

#include <sys/types.h>
#include <time.h>
#include "config.h"

extern struct hostinfo *currenthead;

/*
 * dump the currently broken network devices/services to the filename
 * specified
 *
 * overwrite it if it exists, do not follow symlinks
 * use the umask specified for file creation
 * html = 0 (text) html = 1 (dump in html format)
 *
 */
void
dump_to_file(char *filename, int html)
{
	FILE *fh; /* filehandle for writing out status */
	
	char newfname[128], updated_at[128];

        time_t now;
        struct tm *ltm;

        now = time(NULL);
        ltm = localtime(&now);
        snprintf(updated_at, 127, 
                "%d/%d/%d @ %02d:%02d:%02d\n",
                ltm->tm_mon + 1, 
                ltm->tm_mday, 
                ltm->tm_year + 1900, 
                ltm->tm_hour,
                ltm->tm_min, 
                ltm->tm_sec);


	snprintf(newfname, 127, "%s%d",filename, getpid());
	
	if (filename == NULL)
	{
		fprintf(stderr, "Error! dump_to_file called with filename == nULL\n");
		return;
	}

	/* Delete anything that might be in our way */
	if(unlink(newfname) == -1)
	{
		if (debug)
		{
			perror("textfile.c:dump_to_file:unlink newfilename");
		}
	}

	fh = fopen(newfname, "w");
	
	if (fh == NULL)
	{
		if (debug)
			perror("dump_to_file:fopen");
		return;
	}

	if (html == 1) /* html format */
	{
		fprintf(fh, "<HTML>\n<HEAD>\n");
		fprintf(fh, "<TITLE>%s Network Summary</TITLE>\n", VERS);
                fprintf(fh, "<META HTTP-EQUIV=\"Refresh\" CONTENT=60>\n");
		fprintf(fh, "</HEAD>\n");
		fprintf(fh, "<h2>%s Network Summary</h2><p>\n", VERS);
		fprintf(fh, "\n<BODY BGCOLOR=\"#ffffff\">\n");
		fprintf(fh, "<TABLE BORDER=\"1\">\n");
		fprintf(fh, "<TR>\n");
                fprintf(fh, "<TD>Last Updated:<br>%s</TD>\n", updated_at);
                fprintf(fh, "<TR>\n");
		fprintf(fh, "<TD>HostName</TD>\n");
		fprintf(fh, "<TD>Description</td>\n");
		fprintf(fh, "<TD>Type</TD>\n");
		fprintf(fh, "<TD>Port</TD>\n");
		fprintf(fh, "<TD>Count</TD>\n");
		fprintf(fh, "<TD>Notified</TD>\n");
		fprintf(fh, "<TD>Status</TD>\n");
		fprintf(fh, "<TD>Time Up</TD>\n");
		fprintf(fh, "<TD>Time Failed</TD>\n");
		fprintf(fh, "<TD>Last Outage</TD>\n");
		fprintf(fh, "</TR>\n");

	} else { /* non html */
		fprintf(fh,"Network Summary     %s\n", VERS);
	        fprintf(fh,"%-25s%-6s%-5s%-6s%-6s%-15s%s\n", "Hostname", 
			"Type", "Port", "Count", "Notified", "Stat", 
			"Time Failed");
	}

	/* print the hosts that are down and stuff */
	walk_this_way(fh, currenthead, html, now);

	if ( html == 1) /* html end of stuff */
	{
		fprintf(fh, "</TABLE>\n");
		fprintf(fh, "\n</BODY>\n");
		fprintf(fh, "\n</HTML>\n");
	} else {  /* ascii trailer */
		/* not used */

	}

	fclose(fh); /* close the file handle -- don't leak it */

	chmod(newfname, 0444);

	rename(newfname, filename);

	return;
}

void	add_line(FILE *fh, struct hostinfo down, int html, time_t now)
{
        char *downdata = timedata(down.deathtime);
        char *updata = timedata(down.last_up);
	if (html == 1)
	{
		if (down.lastcheck != SYSM_OK) 
		{
			if (!down.contacted)
			{
			   fprintf(fh, "<TR BGCOLOR=\"#%s\">\n", recentcolor);
			} else {
			   fprintf(fh, "<TR BGCOLOR=\"#%s\">\n", downcolor);
			}
		} else {
			fprintf(fh, "<TR BGCOLOR=\"#%s\">\n", upcolor);
		}

		fprintf(fh, 
"<TD>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%ld</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>\n", 
			down.hostname, down.message, type_to_name(down.type), 
			down.port, down.downct, yes_no(down.contacted), 
			errtostr(down.lastcheck), updata, downdata, 
			str_difftime(down.last_up, now));
		fprintf(fh, "</TR>\n");
	} else { /* ascii */
		fprintf(fh,"%-25s%-6s%-5d%-6ld%-6s%-15s%s\n", down.hostname,
			type_to_name(down.type), down.port, down.downct,
			yes_no(down.contacted), errtostr(down.lastcheck), downdata);

	}
	FREE(downdata);
	FREE(updata);
}

void	walk_this_way(FILE *fh, struct hostinfo *here, int html, time_t now)
{
	if (here == NULL)
		return;

	if (here->lastcheck != 0 ||showupalso)
	{
		add_line(fh, *here, html, now);
		if (showupalso)
			walk_this_way(fh, here->child, html, now);
	} else {
		walk_this_way(fh, here->child, html, now);
	}

	walk_this_way(fh, here->sibling, html, now);
}
