/*
 * sma -- Sendmail log analyser
 *
 * Copyright (c) 2000 - 2003 Jarkko Turkulainen. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY JARKKO TURKULAINEN ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL JARKKO TURKULAINEN BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $Date: 2003/03/22 15:30:37 $
 */

#include "sma.h"

void
html(FILE *fp) {
	unsigned int j, h;
	struct host *hptr;

	const char *wdtab[] = { "Sunday", "Monday", 
	  "Tuesday", "Wednesday", "Thursday", 
	  "Friday", "Saturday" };

	const char *hrtab[] = { "00-01", "01-02", "02-03",
	  "03-04", "04-05", "05-06", "06-07", "07-08",
	  "08-09", "09-10", "10-11", "11-12", "12-13",
	  "13-14", "14-15", "15-16", "16-17", "17-18",
	  "18-19", "19-20", "20-21", "21-22", "22-23", "23-00" };
	
	curr = localtime(&tval);

	fprintf(fp, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
	if (iflag) {
		/* Print embedded ASCII report */
		fprintf(fp, "<!--\n");
		ascii(fp);
		fprintf(fp, "\n-->\n");
	}
	fprintf(fp, "<HTML>\n"
		"  <HEAD>\n"
		"    <META http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n"
		"    <META name=\"Generator\" content=\"SMA version %s\">\n", VERSION);
	fprintf(fp, "    <TITLE>sendmail log analysis report</TITLE>\n"
		"  </HEAD>\n\n"
		"  <BODY TEXT=\"#000000\" BGCOLOR=\"#%s\" LINK=\"#0000ff\""
		" VLINK=\"#000080\" ALINK=\"#ff0000\">\n", bchar);
	if (puchar) {
		fprintf(fp, "    <TABLE WIDTH=\"90%%\">\n"
			"      <TR>\n");
		if (plchar)
			fprintf(fp, "        <TD VALIGN=top>"
				"<A HREF=\"%s\"><IMG SRC=\"%s\""
				" ALT=\"%s\" %s></A></TD>\n", 
				plchar, puchar, 
				pachar ? pachar : PICTURE_ALT, 
				ppchar ? ppchar : "");
		else
			fprintf(fp, "        <TD VALIGN=top>"
				"<IMG SRC=\"%s\" ALT=\"%s\" %s></TD>\n", 
				puchar, pachar ? pachar : PICTURE_ALT, 
				ppchar ? ppchar : "");
		fprintf(fp, "        <TD><H1>%s</H1>\n", Cchar);
		if (htchar)
			fprintf(fp, "            <I>%s</I>\n", htchar);
		else
			fprintf(fp, "            <I>Generated at %s by SMA, "
				"version %s</I>\n", stripn(asctime(curr)), 
				VERSION);
		fprintf(fp, "        </TD>\n"
			"      </TR>\n"
			"    </TABLE>\n");
	} else {
		fprintf(fp, "    <H1>%s</H1>\n", Cchar);
		if (htchar)
			fprintf(fp, "    <I>%s</I>\n", htchar);
		else
			fprintf(fp, "    <I>Generated at %s by SMA, "
				"version %s</I>\n", stripn(asctime(curr)),
				VERSION);
	}
	fprintf(fp, "    <P><HR ALIGN=left NOSHADE WIDTH=\"90%%\">\n\n"
		"    <A NAME=index></A>\n"
		"    <H2>Index</H2>\n");

	for (hptr = first.next; hptr; hptr = hptr->next) {
		 if (!(hptr->inum) || !(hptr->inum))
                        continue;

		fprintf(fp, "    <A HREF=\"#%s\">%s</A><BR>\n", hptr->name, hptr->name);
		fprintf(fp, "    <UL>\n");
		if (pgflag) {
		fprintf(fp, "      <LI><A HREF=\"#%sgen\">General information</A></LI>\n", 
			hptr->name);
		}
		if (epnum)
		fprintf(fp, "      <LI><A HREF=\"#%sepair\">Top envelope pairs</A></LI>\n", hptr->name);
		if (lnum)
		fprintf(fp, "      <LI><A HREF=\"#%ssend\">Top envelope senders</A></LI>\n", hptr->name);
		if (lrnum)
		fprintf(fp, "      <LI><A HREF=\"#%srece\">Top envelope recipients</A></LI>\n", hptr->name);
		if (rpnum)
		fprintf(fp, "      <LI><A HREF=\"#%srpair\">Top relay pairs</A></LI>\n", hptr->name);
		if (rnum)
		fprintf(fp, "      <LI><A HREF=\"#%srsend\">Top relay addresses, sender</A></LI>\n", hptr->name);
		if (rrnum)
		fprintf(fp, "      <LI><A HREF=\"#%srrece\">Top relay addresses, recipient</A></LI>\n", hptr->name);
		if (stnum)
		fprintf(fp, "      <LI><A HREF=\"#%sstatus\">Top status messages</A></LI>\n", hptr->name);
		if (rsnum)
		fprintf(fp, "      <LI><A HREF=\"#%srule\">Top ruleset rejections</A></LI>\n", hptr->name);
		if (!nflag)
		fprintf(fp, "      <LI><A HREF=\"#%sdist\">Message distribution</A></LI>\n", 
			hptr->name);
		fprintf(fp, "    </UL>\n");
		
	}
	fprintf(fp, "    <BR><HR ALIGN=left NOSHADE WIDTH=\"90%%\">\n\n");

	for (hptr = first.next; hptr; hptr = hptr->next) {
		 if (!(hptr->inum) || !(hptr->inum))
                        continue;

		fprintf(fp, "    <A NAME=%s></A>\n", hptr->name);
		fprintf(fp, "    <H3>%s</H3>\n", hptr->name);

		if (pgflag) {
		fprintf(fp, "    <A NAME=%sgen></A>\n", hptr->name);
		fprintf(fp, "    <B>General information</B><BR>\n"
			"    <TABLE BORDER=1 WIDTH=\"60%%\">\n"
			"      <TR>\n"
			"        <TD BGCOLOR=\"#%s\">First log entry</TD>\n", tbchar);
		fprintf(fp, "        <TD ALIGN=center>%s</TD>\n", 
		  stripn(ctime(&hptr->ftime)));

		fprintf(fp, "      </TR>\n"
			"      <TR>\n"
			"        <TD BGCOLOR=\"#%s\">Last log entry</TD>\n", tbchar);
		fprintf(fp, "        <TD ALIGN=center>%s</TD>\n", 
		  stripn(ctime(&hptr->ltime)));

		fprintf(fp, "      </TR>\n"
			"      <TR>\n"
			"        <TD BGCOLOR=\"#%s\">"
			"Alias table rebuilds</TD>\n", tbchar);
		fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", hptr->alias);

		fprintf(fp, "      </TR>\n"
			"      <TR>\n"
			"        <TD BGCOLOR=\"#%s\">"
			"Too many hops</TD>\n", tbchar);
		fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", hptr->hopc);

		fprintf(fp, "      </TR>\n"
			"      <TR>\n"
			"        <TD BGCOLOR=\"#%s\">"
			"Mail loops</TD>\n", tbchar);
		fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", hptr->lcerror);

		fprintf(fp, "      </TR>\n"
			"      <TR>\n"
			"        <TD BGCOLOR=\"#%s\">"
			"Other SYSERR</TD>\n", tbchar);
		fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", hptr->oserror);

		fprintf(fp, "      </TR>\n"
			"      <TR>\n"
			"        <TD BGCOLOR=\"#%s\">"
			"Ruleset based rejections</TD>\n", tbchar);
		fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", hptr->rule);

		fprintf(fp, "      </TR>\n"
			"      <TR>\n"
			"        <TD BGCOLOR=\"#%s\">"
			"Sendmail daemon restarts</TD>\n", tbchar);
		fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", hptr->dstart);

		fprintf(fp, "      </TR>\n"
			"    </TABLE><P>\n"
			"    <TABLE WIDTH=\"90%%\">\n"
			"      <TR VALIGN=top>\n"
			"        <TD WIDTH=\"50%%\"><B>Inbound messages</B><BR>\n"
			"          <TABLE WIDTH=\"100%%\" BORDER=1>\n"
			"            <TR>\n"
			"              <TD WIDTH=\"50%%\" BGCOLOR=\"#%s\">Total</TD>\n", tbchar);
#ifdef _WIN32
		fprintf(fp, "              <TD ALIGN=center>%d</TD>\n", (int)hptr->inum);
#else
		fprintf(fp, "              <TD ALIGN=center>%ld</TD>\n", hptr->inum);
#endif
		fprintf(fp, "            </TR>\n"

			"            <TR>\n"
			"              <TD BGCOLOR=\"#%s\">Average size (kB)</TD>\n", tbchar);
#ifdef _WIN32
		fprintf(fp, "              <TD ALIGN=center >%.2f</TD>\n", 
			(double)hptr->size/(double)hptr->inum/1000);
#else
		fprintf(fp, "              <TD ALIGN=center >%.2Lf</TD>\n", 
			hptr->size/(double)hptr->inum/1000);
#endif
		fprintf(fp, "            </TR>\n"

			"            <TR>\n"
			"              <TD BGCOLOR=\"#%s\">Messages/hour</TD>\n", tbchar);
		fprintf(fp, "              <TD ALIGN=center >%.2f</TD>\n", 
			3600*(float)hptr->inum/(float)hptr->dtime);
		fprintf(fp, "            </TR>\n"

			"            <TR>\n"
			"              <TD BGCOLOR=\"#%s\">Messages/min</TD>\n", tbchar);
		fprintf(fp, "              <TD ALIGN=center >%.2f</TD>\n", 
			60*(float)hptr->inum/(float)hptr->dtime);

		fprintf(fp, "            </TR>\n"

			"            <TR>\n"
			"              <TD BGCOLOR=\"#%s\">Messages/sec</TD>\n", tbchar);
		fprintf(fp, "              <TD align=center >%.2f</TD>\n", 
			(float)hptr->inum/(float)hptr->dtime);

		fprintf(fp, "            </TR>\n"
			"          </TABLE>\n"
			"        </TD>\n"
			"        <TD WIDTH=\"50%%\"><b>Outbound messages</b><BR>\n"
			"          <TABLE WIDTH=\"100%%\" BORDER=1>\n"
			"            <TR>\n"
			"              <TD WIDTH=\"50%%\" BGCOLOR=\"#%s\">Total</TD>\n", tbchar);
#ifdef _WIN32
		fprintf(fp, "              <TD ALIGN=center >%d</TD>\n", (int)hptr->gonum);
#else
		fprintf(fp, "              <TD ALIGN=center >%ld</TD>\n", hptr->gonum);
#endif
		fprintf(fp, "            </TR>\n"

			"            <TR>\n"
			"              <TD BGCOLOR=\"#%s\">Sent</TD>\n", tbchar);
		fprintf(fp, "              <TD ALIGN=center>%d</TD>\n", hptr->sent);
		fprintf(fp, "            </TR>\n"

			"            <TR>\n"
			"              <TD BGCOLOR=\"#%s\">Deferred</TD>\n", tbchar);
		fprintf(fp, "              <TD ALIGN=center >%d</TD>\n", hptr->defe);
		fprintf(fp, "            </TR>\n"

			"            <TR>\n"
			"              <TD BGCOLOR=\"#%s\">Queued</TD>\n", tbchar);
		fprintf(fp, "              <TD ALIGN=center >%d</TD>\n", hptr->queu);
		fprintf(fp, "            </TR>\n"

			"            <TR>\n"
			"              <TD BGCOLOR=\"#%s\">Other error</TD>\n", tbchar);
		fprintf(fp, "              <TD ALIGN=center>%d</TD>\n", 
			hptr->other + hptr->hunk + hptr->uunk + hptr->service);
		fprintf(fp, "            </TR>\n"
			"          </TABLE>\n"
			"        </TD>\n"
			"      </TR>\n"
			"    </TABLE><P>\n\n"
			"    [<A HREF=\"#index\">Index</A>]\n");
		fprintf(fp, "    [<A HREF=\"#%s\">%s</A>]\n\n", hptr->name, hptr->name);
		
		}

		if (epnum) {
		fprintf(fp, "    <A NAME=%sepair></A>\n", hptr->name);
		fprintf(fp, "    <P><B>Top envelope pairs");
                fprintf(fp, "</B><BR>\n");
		fprintf(fp, "    <TABLE BORDER=1 WIDTH=\"90%%\">\n"
			"      <TR>\n"
			"        <TD ALIGN=center WIDTH=\"5%%\" BGCOLOR=\"#%s\">"
			"Number</TD>\n"
			"        <TD WIDTH=\"60%%\" BGCOLOR=\"#%s\">Sender/Recipient</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"Messages</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"Transfers (MB)</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"%%</TD>\n"
			"      </TR>\n", tbchar, tbchar, tbchar, tbchar, tbchar);
		for (j = 0; j < (MIN(epnum, hptr->edif)); j++) {
			fprintf(fp, "      <TR>\n");
			fprintf(fp, "        <TD ALIGN=center >%d</TD>\n", j+1);
			fprintf(fp, "        <TD>%s<BR>%s</TD>\n", hptr->setab[j]->fname, hptr->setab[j]->tname);
			fprintf(fp, "        <TD ALIGN=center >%d</TD>\n", 
				hptr->setab[j]->num);
#ifdef _WIN32
			fprintf(fp, "        <TD ALIGN=center >%.2f</TD>\n", 
				(double)hptr->setab[j]->size/1000000);
#else
			fprintf(fp, "        <TD ALIGN=center >%.2Lf</TD>\n", 
				hptr->setab[j]->size/1000000);
#endif
			if (sflag) {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->setab[j]->size/(float)hptr->osize);
			fprintf(fp, "      </TR>\n");
			} else {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->setab[j]->num/(float)hptr->onum);
			fprintf(fp, "      </TR>\n");
			}
		}
		fprintf(fp, "    </TABLE><P>\n\n"
			"    [<A HREF=\"#index\">Index</a>]\n");
		fprintf(fp, "    [<A HREF=\"#%s\">%s</a>]\n\n", hptr->name, hptr->name);
		}

		if (lnum) {
		fprintf(fp, "    <A NAME=%ssend></A>\n", hptr->name);
		fprintf(fp, "    <P><B>Top envelope senders");
		if (sef) fprintf(fp, " (filter: %s)</B><BR>\n", sef);
                else fprintf(fp, "</B><BR>\n");
		fprintf(fp, "    <TABLE BORDER=1 WIDTH=\"90%%\">\n"
			"      <TR>\n"
			"        <TD ALIGN=center WIDTH=\"5%%\" BGCOLOR=\"#%s\">"
			"Number</TD>\n"
			"        <TD WIDTH=\"60%%\" BGCOLOR=\"#%s\">Sender</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"Messages</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"Transfers (MB)</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"%%</TD>\n"
			"      </TR>\n", tbchar, tbchar, tbchar, tbchar, tbchar);

		for (j = 0; j < (MIN(lnum, hptr->idif)); j++) {
			fprintf(fp, "      <TR>\n");
			fprintf(fp, "        <TD ALIGN=center >%d</TD>\n", j+1);
			fprintf(fp, "        <TD>%s</TD>\n", hptr->sitab[j]->name);
			fprintf(fp, "        <TD ALIGN=center >%d</TD>\n", 
				hptr->sitab[j]->num);
#ifdef _WIN32
			fprintf(fp, "        <TD ALIGN=center >%.2f</TD>\n", 
				(double)hptr->sitab[j]->size/1000000);
#else
			fprintf(fp, "        <TD ALIGN=center >%.2Lf</TD>\n", 
				hptr->sitab[j]->size/1000000);
#endif
			if (sflag) {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->sitab[j]->size/(float)hptr->isize);
			fprintf(fp, "      </TR>\n");
			} else {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->sitab[j]->num/(float)hptr->inum);
			fprintf(fp, "      </TR>\n");
			}
		}
		fprintf(fp, "    </TABLE><P>\n\n"
			"    [<A HREF=\"#index\">Index</a>]\n");
		fprintf(fp, "    [<A HREF=\"#%s\">%s</a>]\n\n", hptr->name, hptr->name);
		}



		if (lrnum) {
		fprintf(fp, "    <A NAME=%srece></A>\n", hptr->name);
		fprintf(fp, "    <P><B>Top envelope recipients");
		if (ref) fprintf(fp, " (filter: %s)</B><BR>\n", ref);
                else fprintf(fp, "</B><BR>\n");
		fprintf(fp, "    <TABLE BORDER=1 WIDTH=\"90%%\">\n"
			"      <TR>\n"
			"        <TD ALIGN=center WIDTH=\"5%%\" BGCOLOR=\"#%s\">"
			"Number</TD>\n"
			"        <TD WIDTH=\"60%%\" BGCOLOR=\"#%s\">Recipient</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			 "Messages</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			 "Transfers (MB)</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"%%</TD>\n"
			"      </TR>\n", tbchar, tbchar, tbchar, tbchar, tbchar);

		for (j = 0; j < (MIN(lrnum, hptr->odif)); j++) {
			fprintf(fp, "      <TR>\n");
			fprintf(fp, "        <TD ALIGN=center >%d</TD>\n", j+1);
			fprintf(fp, "        <TD>%s</TD>\n", hptr->sotab[j]->name);
			fprintf(fp, "        <TD ALIGN=center >%d</TD>\n", 
				hptr->sotab[j]->num);
#ifdef _WIN32
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
				(double)hptr->sotab[j]->size/1000000);
#else
			fprintf(fp, "        <TD ALIGN=center>%.2Lf</TD>\n", 
				hptr->sotab[j]->size/1000000);
#endif
			if (sflag) {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->sotab[j]->size/(float)hptr->osize);
			fprintf(fp, "      </TR>\n");
			} else {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->sotab[j]->num/(float)hptr->onum);
			fprintf(fp, "      </TR>\n");
			}
		}
		fprintf(fp, "    </TABLE><P>\n\n"
			"    [<A HREF=\"#index\">Index</a>]\n");

		fprintf(fp, "    [<A HREF=\"#%s\">%s</a>]\n\n", hptr->name, hptr->name);
		}

		if (rpnum) {
		fprintf(fp, "    <A NAME=%srpair></A>\n", hptr->name);
		fprintf(fp, "    <P><B>Top relay pairs");
                fprintf(fp, "</B><BR>\n");
		fprintf(fp, "    <TABLE BORDER=1 WIDTH=\"90%%\">\n"
			"      <TR>\n"
			"        <TD ALIGN=center WIDTH=\"5%%\" BGCOLOR=\"#%s\">"
			"Number</TD>\n"
			"        <TD WIDTH=\"60%%\" BGCOLOR=\"#%s\">Sender relay/Recipient relay</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"Messages</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"Transfers (MB)</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"%%</TD>\n"
			"      </TR>\n", tbchar, tbchar, tbchar, tbchar, tbchar);
		for (j = 0; j < (MIN(rpnum, hptr->rrdif)); j++) {
			fprintf(fp, "      <TR>\n");
			fprintf(fp, "        <TD ALIGN=center >%d</TD>\n", j+1);
			fprintf(fp, "        <TD>%s<BR>%s</TD>\n", hptr->srtab[j]->fname, hptr->srtab[j]->tname);
			fprintf(fp, "        <TD ALIGN=center >%d</TD>\n", 
				hptr->srtab[j]->num);
#ifdef _WIN32
			fprintf(fp, "        <TD ALIGN=center >%.2f</TD>\n", 
				(double)hptr->srtab[j]->size/1000000);
#else
			fprintf(fp, "        <TD ALIGN=center >%.2Lf</TD>\n", 
				hptr->srtab[j]->size/1000000);
#endif
			if (sflag) {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->srtab[j]->size/(float)hptr->osize);
			fprintf(fp, "      </TR>\n");
			} else {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->srtab[j]->num/(float)hptr->onum);
			fprintf(fp, "      </TR>\n");
			}
		}
		fprintf(fp, "    </TABLE><P>\n\n"
			"    [<A HREF=\"#index\">Index</a>]\n");
		fprintf(fp, "    [<A HREF=\"#%s\">%s</a>]\n\n", hptr->name, hptr->name);
		}

		if (rnum) {
		fprintf(fp, "    <A NAME=%srsend></A>\n", hptr->name);

		fprintf(fp, "    <P><B>Top relay addresses, sender");
		if (srf) fprintf(fp, " (filter: %s)</B><BR>\n", srf);
                else fprintf(fp, "</B><BR>\n");
		fprintf(fp, "    <TABLE BORDER=1 WIDTH=\"90%%\">\n"
			"      <TR>\n"
			"        <TD ALIGN=center WIDTH=\"5%%\" BGCOLOR=\"#%s\">"
			"Number</TD>\n"
			"        <TD WIDTH=\"55%%\" BGCOLOR=\"#%s\">Relay</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"Messages</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"Transfers (MB)</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"%%</TD>\n"
			"      </TR>\n", tbchar, tbchar, tbchar, tbchar, tbchar);

		for (j = 0; j < (MIN(rnum, hptr->ridif)); j++) {
			fprintf(fp, "      <TR>\n");
			fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", j+1);
			fprintf(fp, "        <TD>%s</TD>\n", hptr->rsitab[j]->name);
			fprintf(fp, "        <TD ALIGN=center >%d</TD>\n", 
				hptr->rsitab[j]->num);
#ifdef _WIN32
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
				(double)hptr->rsitab[j]->size/1000000);
#else
			fprintf(fp, "        <TD ALIGN=center>%.2Lf</TD>\n", 
				hptr->rsitab[j]->size/1000000);
#endif
			if (sflag) {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->rsitab[j]->size/(float)hptr->isize);
			} else {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->rsitab[j]->num/(float)hptr->rinum);
			}
			fprintf(fp, "      </TR>\n");
		}
		fprintf(fp, "    </TABLE><P>\n\n"
			"    [<A HREF=\"#index\">Index</A>]\n");
		fprintf(fp, "    [<A HREF=\"#%s\">%s</A>]\n\n", hptr->name, hptr->name);

		}

		if (rrnum) {
		fprintf(fp, "    <A NAME=%srrece></A>\n", hptr->name);
		fprintf(fp, "    <P><B>Top relay addresses, recipient");
		if (rrf) fprintf(fp, " (filter: %s)</B><BR>\n", rrf);
                else fprintf(fp, "</B><BR>\n");
		fprintf(fp, "    <TABLE BORDER=1 WIDTH=\"90%%\">\n"
			"      <TR>\n"
			"        <TD ALIGN=center WIDTH=\"5%%\" BGCOLOR=\"#%s\">"
			"Number</TD>\n"
			"        <TD WIDTH=\"55%%\" BGCOLOR=\"#%s\">Relay</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"Messages</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"Transfers (MB)</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">"
			"%%</TD>\n"
			"      </TR>\n", tbchar, tbchar, tbchar, tbchar, tbchar);

		for (j = 0; j < (MIN(rrnum, hptr->rodif)); j++) {
			fprintf(fp, "      <TR>\n");
			fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", j+1);
			fprintf(fp, "        <TD>%s</TD>\n", hptr->rsotab[j]->name);
			fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", 
				hptr->rsotab[j]->num);
#ifdef _WIN32
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
				(double)hptr->rsotab[j]->size/1000000);
#else
			fprintf(fp, "        <TD ALIGN=center>%.2Lf</TD>\n", 
				hptr->rsotab[j]->size/1000000);
#endif
			if (sflag) {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->rsotab[j]->size/(float)hptr->osize);
			} else {
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->rsotab[j]->num/(float)hptr->ronum);
			}
			fprintf(fp, "      </TR>\n");
		}
		fprintf(fp, "    </TABLE><P>\n\n"
			"    [<A HREF=\"#index\">Index</A>]\n");
		fprintf(fp, "    [<A HREF=\"#%s\">%s</A>]\n\n", hptr->name, hptr->name);
		}

		if (stnum) {
		fprintf(fp, "    <A NAME=%sstatus></A>\n", hptr->name);
		fprintf(fp, "    <P><B>Top status messages");
                fprintf(fp, "</B><BR>\n");
		fprintf(fp, "    <TABLE BORDER=1 WIDTH=\"90%%\">\n"
			"      <TR>\n"
			"        <TD ALIGN=center WIDTH=\"5%%\" BGCOLOR=\"#%s\">"
			"Number</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">Msgs</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">%%</TD>\n"
			"        <TD WIDTH=\"75%%\" BGCOLOR=\"#%s\">"
			"Status</TD>\n"
			"      </TR>\n", tbchar, tbchar, tbchar, tbchar);

		for (j = 0; j < (MIN(stnum, hptr->sdif)); j++) {
			fprintf(fp, "      <TR>\n");
			fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", j+1);

			fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", 
				hptr->ssttab[j]->num);
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->ssttab[j]->num/(float)hptr->onum);

			fprintf(fp, "        <TD>%s</TD>\n", hptr->ssttab[j]->name);
			fprintf(fp, "      </TR>\n");
		}
		fprintf(fp, "    </TABLE><P>\n\n"
			"    [<A HREF=\"#index\">Index</A>]\n");
		fprintf(fp, "    [<A HREF=\"#%s\">%s</A>]\n\n", hptr->name, hptr->name);
		}

		if (rsnum) {
		fprintf(fp, "    <A NAME=%srule></A>\n", hptr->name);
		fprintf(fp, "    <P><B>Top ruleset rejections");
                fprintf(fp, "</B><BR>\n");
		fprintf(fp, "    <TABLE BORDER=1 WIDTH=\"90%%\">\n"
			"      <TR>\n"
			"        <TD ALIGN=center WIDTH=\"5%%\" BGCOLOR=\"#%s\">"
			"Number</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">Msgs</TD>\n"
			"        <TD ALIGN=center BGCOLOR=\"#%s\">%%</TD>\n"
			"        <TD WIDTH=\"75%%\" BGCOLOR=\"#%s\">"
			"%s</TD>\n"
			"      </TR>\n", tbchar, tbchar, tbchar, tbchar,
			rsrnum ? "Reason / Top relays" : "Reason");

		for (j = 0; j < (MIN(rsnum, hptr->rdif)); j++) {
			fprintf(fp, "      <TR>\n");
			fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", j+1);

			fprintf(fp, "        <TD ALIGN=center>%d</TD>\n", 
				hptr->sruletab[j]->num);
			fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n", 
			  100*(float)hptr->sruletab[j]->num/(float)hptr->rule);

			fprintf(fp, "        <TD>");
			while (*(hptr->sruletab[j]->name) != '\0') {
				if (*(hptr->sruletab[j]->name) == '<')
					fprintf(fp, "&lt;");
				else if (*(hptr->sruletab[j]->name) == '>')
					fprintf(fp, "&gt;");
				else
					fputc(*(hptr->sruletab[j]->name), fp);
				hptr->sruletab[j]->name++;
			}
			fprintf(fp, "</TD>\n");
			fprintf(fp, "      </TR>\n");

			if (rsrnum) {
			for (h = 0; h < (MIN(rsrnum, hptr->sruletab[j]->reldif)); h++) {
				fprintf(fp, "      <TR>\n");
				fprintf(fp, "        <TD></TD>\n");
				fprintf(fp, "        <TD ALIGN=center>%d</TD>\n",
					hptr->sruletab[j]->srrelaytab[h]->num);
				fprintf(fp, "        <TD ALIGN=center>%.2f</TD>\n",
					100*(float)hptr->sruletab[j]->srrelaytab[h]->num/(float)hptr->sruletab[j]->num);
				fprintf(fp, "        <TD>%s</TD>\n",
					hptr->sruletab[j]->srrelaytab[h]->name);
				fprintf(fp, "      </TR>\n");
			}
			}

		}
		fprintf(fp, "    </TABLE><P>\n\n"
			"    [<A HREF=\"#index\">Index</A>]\n");
		fprintf(fp, "    [<A HREF=\"#%s\">%s</A>]\n\n", hptr->name, hptr->name);
		}

		if (!nflag) {
		fprintf(fp, "    <A NAME=%sdist></A><P>\n", hptr->name);
		fprintf(fp, "    <TABLE WIDTH=\"90%%\">\n"
			"      <TR>\n"
			"        <TD><B>Inbound messages per day</B><BR>\n"
			"          <TABLE WIDTH=\"100%%\" BORDER=1>\n"
			"            <TR>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Day</TD>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Total</TD>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Average</TD>\n"
			"            </TR>\n", tbchar, tbchar, tbchar);

		for (j = 0; j < 7; j++) {
			if (hptr->idd[j]) {
			fprintf(fp, "            <TR>\n");
			fprintf(fp, "              <TD ALIGN=center BGCOLOR=\"#%s\">"
				"%s</TD>\n", tbchar, wdtab[j]);
			fprintf(fp, "              <TD ALIGN=center>%d</TD>\n", 
				hptr->idd[j]);
			fprintf(fp, "              <TD ALIGN=center >%.2f</TD>\n", 
				hptr->fidd[j]);
			fprintf(fp, "            </TR>\n");
			}
		}

		fprintf(fp, "          </TABLE>\n"
			"        </TD>\n"
			"        <TD><B>Outbound messages per day</B><BR>\n"
			"          <TABLE WIDTH=\"100%%\" BORDER=1>\n"
			"            <TR>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Day</TD>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Total</TD>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Average</TD>\n"
			"            </TR>\n", tbchar, tbchar, tbchar);

		for (j = 0; j < 7; j++) {
			if (hptr->odd[j]) {
			fprintf(fp, "            <TR>\n"
				"              <TD ALIGN=center BGCOLOR=\"#%s\">"
				"%s</TD>\n", tbchar, wdtab[j]);
			fprintf(fp, "              <TD ALIGN=center>%d</TD>\n", 
				hptr->odd[j]);
			fprintf(fp, "              <TD ALIGN=center>%.2f</TD>\n", 
				hptr->fodd[j]);
			fprintf(fp, "            </TR>\n");
			}
		}
		fprintf(fp, "          </TABLE>\n"
			"        </TD>\n"
			"      </TR>\n"
			"    </TABLE><P>\n"
			"    <TABLE WIDTH=\"90%%\">\n"
			"      <TR>\n"
			"        <TD><B>Inbound messages per hour</B><BR>\n"
			"          <TABLE BORDER=1 WIDTH=\"100%%\">\n"
			"            <TR>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Hour</TD>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Total</TD>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Average</TD>\n"
			"            </TR>\n", tbchar, tbchar, tbchar);

		for (j = 0; j < 24; j++) {
			if (hptr->ihh[j]) {
			fprintf(fp, "            <TR>\n");
			fprintf(fp, "              <TD ALIGN=center BGCOLOR=\"#%s\">"
				"%s</TD>\n", tbchar, hrtab[j]);
			fprintf(fp, "              <TD ALIGN=center>%d</TD>\n", 
				hptr->ihh[j]);
			fprintf(fp, "              <TD ALIGN=center >%.2f</TD>\n", 
				hptr->fihh[j]);
			fprintf(fp, "            </TR>\n");
			}
		}

		fprintf(fp, "           </TABLE>\n"
			"        </TD>\n"
			"        <TD><B>Outbound messages per hour</B><BR>\n"
			"          <TABLE BORDER=1 WIDTH=\"100%%\">\n"
			"            <TR>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Hour</TD>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Total</TD>\n"
			"              <TD ALIGN=center BGCOLOR=\"#%s\">Average</TD>\n"
			"            </TR>\n", tbchar, tbchar, tbchar);

		for (j = 0; j < 24; j++) {
			if (hptr->ohh[j]) {
			fprintf(fp, "            <TR>\n");
			fprintf(fp, "              <TD ALIGN=center BGCOLOR=\"#%s\">"
				"%s</TD>\n", tbchar, hrtab[j]);
			fprintf(fp, "              <TD ALIGN=center>%d</TD>\n", 
				hptr->ohh[j]);
			fprintf(fp, "              <TD ALIGN=center>%.2f</TD>\n", 
				hptr->fohh[j]);
			fprintf(fp, "            </TR>\n");
			}
		}
		fprintf(fp, "          </TABLE>\n"
			"        </TD>\n"
			"      </TR>\n"
			"    </TABLE><P>\n\n"
			"    [<A HREF=\"#index\">Index</A>]\n");
		fprintf(fp, "    [<A HREF=\"#%s\">%s</A>]\n\n", hptr->name, hptr->name);
		}
		fprintf(fp, "    <BR><BR><HR ALIGN=left NOSHADE WIDTH=\"90%%\">\n");
	}
	if (ftchar)
			fprintf(fp, "    <I>%s</I>\n", ftchar);
		else
			fprintf(fp, "    <I>Copyright (c) 2000 - 2003"
				" Jarkko Turkulainen. All rights reserved.</I>\n");
	fprintf(fp, "  </BODY>\n</HTML>\n");
}


syntax highlighted by Code2HTML, v. 0.9.1