/* * 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/01/01 13:54:00 $ */ #include "sma.h" void ascii(FILE *fp) { unsigned int j, h; char *p; 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); p = asctime(curr); p[strlen(p)-1] = '\0'; fprintf(fp, "\n%s\n", Cchar); if (htchar) fprintf(fp, "%s\n", htchar); else fprintf(fp, "Generated at %s by SMA, version %s\n", p, VERSION); fprintf(fp, "-----------------------------------------------------------------------------\n\n"); for (hptr = first.next; hptr; hptr = hptr->next) { if (!(hptr->inum) || !(hptr->inum)) continue; fprintf(fp, "\nServer: %s\n\n", hptr->name); if (pgflag) { fprintf(fp, "General information\n"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, " %-33s %s", "First log entry", ctime(&hptr->ftime)); fprintf(fp, " %-33s %s", "Last log entry", ctime(&hptr->ltime)); fprintf(fp, " %-33s %d\n", "Alias table rebuilds", hptr->alias); fprintf(fp, " %-33s %d\n", "Too many hops", hptr->hopc); fprintf(fp, " %-33s %d\n", "Mail loops", hptr->lcerror); fprintf(fp, " %-33s %d\n", "Other SYSERR", hptr->oserror); fprintf(fp, " %-33s %d\n", "Ruleset based rejections", hptr->rule); fprintf(fp, " %-33s %d\n\n", "Sendmail daemon restarts", hptr->dstart); fprintf(fp, "%s%35s\n", "Inbound messages", "Outbound messages"); fprintf(fp, "-----------------------------------------------------------------------------\n"); /* * Hm. it seems that Win32 printf cannot handle correctly long's.. * This is not the right thing to do, consider some typedef instead.. * But hey, I should drop the Win32 support anyway, who uses it? */ #ifdef _WIN32 fprintf(fp, " %-20s %7d", "Total", (int)hptr->inum); fprintf(fp, " %-15s %7d\n", "Total", (int)hptr->gonum); fprintf(fp, " %-20s %7.2f", "Average size (kB)", (double)hptr->size/(double)hptr->inum/1000); #else fprintf(fp, " %-20s %7ld", "Total", hptr->inum); fprintf(fp, " %-15s %7ld\n", "Total", hptr->gonum); fprintf(fp, " %-20s %7.2Lf", "Average size (kB)", hptr->size/(double)hptr->inum/1000); #endif fprintf(fp, " %-15s %7d\n", "Sent", hptr->sent); fprintf(fp, " %-20s %7.2f", "Messages/hour", 3600*(float)hptr->inum/(float)hptr->dtime); fprintf(fp, " %-15s %7d\n", "Deferred", hptr->defe); fprintf(fp, " %-20s %7.2f", "Messages/min", 60*(float)hptr->inum/(float)hptr->dtime); fprintf(fp, " %-15s %7d\n", "Queued", hptr->queu); fprintf(fp, " %-20s %7.2f", "Messages/sec", (float)hptr->inum/(float)hptr->dtime); fprintf(fp, " %-15s %7d\n", "Other error", hptr->other + hptr->hunk + hptr->uunk + hptr->service); } if (epnum) { fprintf(fp, "\n\nTop envelope pairs\n"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, "%5s %-45s %6s %10s %7s\n", "Nr", "Sender/Recipient", "Msgs", "MB", "%"); fprintf(fp, "-----------------------------------------------------------------------------\n"); for (j = 0; j < (MIN(epnum, hptr->edif)); j++) { #ifdef _WIN32 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1, hptr->setab[j]->fname, (strlen(hptr->setab[j]->fname) >= 40) ? "$" : " ", hptr->setab[j]->num, (double)hptr->setab[j]->size/1000000); #else fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1, hptr->setab[j]->fname, (strlen(hptr->setab[j]->fname) >= 40) ? "$" : " ", hptr->setab[j]->num, hptr->setab[j]->size/1000000); #endif if (sflag) { fprintf(fp, " %7.2f\n", 100*(float)hptr->setab[j]->size/(float)hptr->osize); } else { fprintf(fp, " %7.2f\n", 100*(float)hptr->setab[j]->num/(float)hptr->onum); } fprintf(fp, " %.40s%s", hptr->setab[j]->tname, (strlen(hptr->setab[j]->tname) >= 40) ? "$\n" : "\n"); } } if (lnum) { fprintf(fp, "\nTop envelope senders"); if (sef) fprintf(fp, " (filter: %s)\n", sef); else fprintf(fp, "\n"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, "%5s %-45s %6s %10s %7s\n", "Nr", "Sender", "Msgs", "MB", "%"); fprintf(fp, "-----------------------------------------------------------------------------\n"); for (j = 0; j < (MIN(lnum, hptr->idif)); j++) { #ifdef _WIN32 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1, hptr->sitab[j]->name, (strlen(hptr->sitab[j]->name) >= 40) ? "$" : " ", hptr->sitab[j]->num, (double)hptr->sitab[j]->size/1000000); #else fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1, hptr->sitab[j]->name, (strlen(hptr->sitab[j]->name) >= 40) ? "$" : " ", hptr->sitab[j]->num, hptr->sitab[j]->size/1000000); #endif if (sflag) { fprintf(fp, " %7.2f\n", 100*(float)hptr->sitab[j]->size/(float)hptr->isize); } else { fprintf(fp, " %7.2f\n", 100*(float)hptr->sitab[j]->num/(float)hptr->inum); } } } if (lrnum) { fprintf(fp, "\nTop envelope recipients"); if (ref) fprintf(fp, " (filter: %s)\n", ref); else fprintf(fp, "\n"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, "%5s %-45s %6s %10s %7s\n", "Nr", "Recipient", "Msgs", "MB", "%"); fprintf(fp, "-----------------------------------------------------------------------------\n"); for (j = 0; j < (MIN(lrnum, hptr->odif)); j++) { #ifdef _WIN32 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1, hptr->sotab[j]->name, (strlen(hptr->sotab[j]->name) >= 40) ? "$" : " ", hptr->sotab[j]->num, (double)hptr->sotab[j]->size/1000000); #else fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1, hptr->sotab[j]->name, (strlen(hptr->sotab[j]->name) >= 40) ? "$" : " ", hptr->sotab[j]->num, hptr->sotab[j]->size/1000000); #endif if (sflag) { fprintf(fp, " %7.2f\n", 100*(float)hptr->sotab[j]->size/(float)hptr->osize); } else { fprintf(fp, " %7.2f\n", 100*(float)hptr->sotab[j]->num/(float)hptr->onum); } } } if (rpnum) { fprintf(fp, "\n\nTop relay pairs\n"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, "%5s %-45s %6s %10s %7s\n", "Nr", "Sender relay/Recipient relay", "Msgs", "MB", "%"); fprintf(fp, "-----------------------------------------------------------------------------\n"); for (j = 0; j < (MIN(rpnum, hptr->rrdif)); j++) { #ifdef _WIN32 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1, hptr->srtab[j]->fname, (strlen(hptr->srtab[j]->fname) >= 40) ? "$" : " ", hptr->srtab[j]->num, (double)hptr->srtab[j]->size/1000000); #else fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1, hptr->srtab[j]->fname, (strlen(hptr->srtab[j]->fname) >= 40) ? "$" : " ", hptr->srtab[j]->num, hptr->srtab[j]->size/1000000); #endif if (sflag) { fprintf(fp, " %7.2f\n", 100*(float)hptr->srtab[j]->size/(float)hptr->osize); } else { fprintf(fp, " %7.2f\n", 100*(float)hptr->srtab[j]->num/(float)hptr->onum); } fprintf(fp, " %.40s%s", hptr->srtab[j]->tname, (strlen(hptr->srtab[j]->tname) >= 40) ? "$\n" : "\n"); } } if (rnum) { fprintf(fp, "\nTop relay addresses, sender"); if (srf) fprintf(fp, " (filter: %s)\n", srf); else fprintf(fp, "\n"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, "%5s %-45s %6s %10s %7s\n", "Nr", "Relay", "Msgs", "MB", "%"); fprintf(fp, "-----------------------------------------------------------------------------\n"); for (j = 0; j < (MIN(rnum, hptr->ridif)); j++) { #ifdef _WIN32 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1, hptr->rsitab[j]->name, (strlen(hptr->rsitab[j]->name) >= 40) ? "$" : " ", hptr->rsitab[j]->num, (double)hptr->rsitab[j]->size/1000000); #else fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1, hptr->rsitab[j]->name, (strlen(hptr->rsitab[j]->name) >= 40) ? "$" : " ", hptr->rsitab[j]->num, hptr->rsitab[j]->size/1000000); #endif if (sflag) { fprintf(fp, " %7.2f\n", 100*(float)hptr->rsitab[j]->size/(float)hptr->isize); } else { fprintf(fp, " %7.2f\n", 100*(float)hptr->rsitab[j]->num/(float)hptr->rinum); } } } if (rrnum) { fprintf(fp, "\nTop relay addresses, recipient"); if (rrf) fprintf(fp, " (filter: %s)\n", rrf); else fprintf(fp, "\n"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, "%5s %-45s %6s %10s %7s\n", "Nr", "Relay", "Msgs", "MB", "%"); fprintf(fp, "-----------------------------------------------------------------------------\n"); for (j = 0; j < (MIN(rrnum, hptr->rodif)); j++) { #ifdef _WIN32 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1, hptr->rsotab[j]->name, (strlen(hptr->rsotab[j]->name) >= 40) ? "$" : " ", hptr->rsotab[j]->num, (double)hptr->rsotab[j]->size/1000000); #else fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1, hptr->rsotab[j]->name, (strlen(hptr->rsotab[j]->name) >= 40) ? "$" : " ", hptr->rsotab[j]->num, hptr->rsotab[j]->size/1000000); #endif if (sflag) { fprintf(fp, " %7.2f\n", 100*(float)hptr->rsotab[j]->size/(float)hptr->osize); } else { fprintf(fp, " %7.2f\n", 100*(float)hptr->rsotab[j]->num/(float)hptr->ronum); } } } if (stnum) { fprintf(fp, "\n\nTop status messages\n"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, "%5s %7s %6s %s\n", "Nr", "Msgs", "%", " Status"); fprintf(fp, "-----------------------------------------------------------------------------\n"); for (j = 0; j < (MIN(stnum, hptr->sdif)); j++) { fprintf(fp, "%5d %7d %6.2f %s %-52s\n", j+1, hptr->ssttab[j]->num, 100*(float)hptr->ssttab[j]->num/(float)hptr->onum, " ", hptr->ssttab[j]->name); } } if (rsnum) { fprintf(fp, "\n\nTop ruleset rejections\n"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, "%5s %7s %6s %s\n", "Nr", "Msgs", "%", rsrnum ? " Reason / Top relays" : " Reason"); fprintf(fp, "-----------------------------------------------------------------------------\n"); for (j = 0; j < (MIN(rsnum, hptr->rdif)); j++) { fprintf(fp, "%5d %7d %6.2f %s %-52s\n", j+1, hptr->sruletab[j]->num, 100*(float)hptr->sruletab[j]->num/(float)hptr->rule, " ", hptr->sruletab[j]->name); if (rsrnum) { fprintf(fp, " ------------------------------------------------------------------------\n"); for (h = 0; h < (MIN(rsrnum, hptr->sruletab[j]->reldif)); h++) { fprintf(fp, "%13d %6.2f %s %s\n", hptr->sruletab[j]->srrelaytab[h]->num, 100*(float)hptr->sruletab[j]->srrelaytab[h]->num/(float)hptr->sruletab[j]->num, " ", hptr->sruletab[j]->srrelaytab[h]->name); } fprintf(fp, "\n"); } } } if (!nflag) { fprintf(fp, "\n\n%s%42s\n", "Inbound messages per day", "Outbound messages per day"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, "%s %-9s %9s %9s %10s %-9s %9s %9s\n", " ", "Day", "Total", "Average", " ", "Day", "Total", "Average"); fprintf(fp, "-----------------------------------------------------------------------------\n"); for (j = 0; j < 7; j++) { if (hptr->idd[j]) fprintf(fp, "%s %-9s %9d %9.2f %10s %-9s %9d %9.2f\n", " ", wdtab[j], hptr->idd[j], hptr->fidd[j], " ", wdtab[j], hptr->odd[j], hptr->fodd[j]); } fprintf(fp, "\n\n%s%42s\n", "Inbound messages per hour", "Outbound messages per hour"); fprintf(fp, "-----------------------------------------------------------------------------\n"); fprintf(fp, "%s %-9s %9s %9s %10s %-9s %9s %9s\n", " ", "Hour", "Total", "Average", " ", "Hour", "Total", "Average"); fprintf(fp, "-----------------------------------------------------------------------------\n"); for (j = 0; j < 24; j++) { if (hptr->ihh[j]) { fprintf(fp, "%s %-9s %9d %9.2f %10s %-9s %9d %9.2f\n", " ", hrtab[j], hptr->ihh[j], hptr->fihh[j], " ", hrtab[j], hptr->ohh[j], hptr->fohh[j]); } } } } fprintf(fp, "\n\n-----------------------------------------------------------------------------\n"); if (ftchar) fprintf(fp, "%s\n", ftchar); else fprintf(fp, "Copyright (c) 2000 - 2003 Jarkko Turkulainen." " All rights reserved.\n"); }