/*
* 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: 2002/09/12 10:46:00 $
*/
extern const char *sma_optarg;
extern int sma_optind;
#include "sma.h"
int
main(int argc, char **argv) {
FILE *fp = NULL;
struct host *hptr;
int c;
#ifdef _WIN32
int getopt(int, char **, char *);
#endif
/* initialize global variables: */
hosts = 0;
tval = time((time_t *)NULL);
curr = localtime(&tval);
first.next = NULL;
pname = argv[0];
/* get arguments: */
while ((c = getopt(argc, argv, "C:D:H:L:b:f:l:r:t:o:O:AFacdhinpsqvw")) != -1)
switch(c) {
case 'A':
dcaddrflag = 1;
break;
case 'D':
Dflag = 1;
Dchar = sma_optarg;
break;
case 'C':
Cflag = 1;
Cchar = sma_optarg;
break;
case 'F':
Fflag = 1;
break;
case 'H':
Hflag = 1;
Hchar = sma_optarg;
break;
case 'a':
aflag = 1;
break;
case 'b':
bflag = 1;
bchar = sma_optarg;
break;
case 'c':
cflag = 1;
break;
case 'd':
dflag = 1;
break;
case 'f':
fflag = 1;
fchar = sma_optarg;
break;
case 'h':
hflag = 1;
break;
case 'i':
iflag = 1;
break;
case 'l':
lflag = 1;
lnum = atoi(sma_optarg);
break;
case 'L':
Lflag = 1;
Lchar = sma_optarg;
break;
case 'r':
rflag = 1;
rnum = atoi(sma_optarg);
break;
case 'n':
nflag = 1;
break;
case 'o':
oflag = 1;
ochar = sma_optarg;
break;
case 'O':
Oflag = 1;
Ochar = sma_optarg;
break;
case 'p':
pflag = 1;
break;
case 's':
sflag = 1;
break;
case 't':
tflag = 1;
tchar = sma_optarg;
break;
case 'q':
qflag = 1;
break;
case 'v':
vflag = 1;
break;
case 'w':
wflag = 1;
break;
default:
usage();
}
argc -= sma_optind;
argv += sma_optind;
/* Debug */
if (vflag)
fprintf(stderr, "%s: running in Debug mode\n", pname);
/* Check argument logic: */
if (hflag) usage();
if (cflag) copying();
if (!pgflag) pgflag = 1;
/* Read in the configuration file: */
if (fchar) {
if (!(fp = fopen(fchar, "r")))
fprintf(stderr, "%s: cannot open %s\n", pname, fchar);
else {
init(fp);
(void)fclose(fp);
}
} else if (!Fflag) {
if (!(fp = fopen(DEFAULT_CONF, "r")))
fprintf(stderr, "%s: cannot open %s, using defaults\n",
pname, "configuration file");
else {
fchar = DEFAULT_CONF;
init(fp);
(void)fclose(fp);
}
}
/* Hash table size: */
if (!tflag || !strncmp(tchar, "normal", 6)) {
asize = ASIZE_NORMAL;
rsize = RSIZE_NORMAL;
} else if (!strncmp(tchar, "big", 3)) {
asize = ASIZE_BIG;
rsize = RSIZE_BIG;
} else if (!strncmp(tchar, "huge", 4)) {
asize = ASIZE_HUGE;
rsize = RSIZE_HUGE;
} else {
if (!(hsstring = strdup(tchar)))
error_memory();
hastring = hsstring;
if (*hsstring == ',') {
hastring = NULL;
if (*(hsstring + 1) == '\0')
hrstring = NULL;
else
hrstring = ++hsstring;
}
while (*hsstring != '\0') {
if (*hsstring == ',') {
*hsstring = '\0';
if (*(hsstring + 1) == '\0')
hrstring = NULL;
else
hrstring = ++hsstring;
break;
}
hsstring++;
}
/* Address Hash table: */
if (hastring != NULL)
asize = atoi(hastring);
else asize = ASIZE_NORMAL;
/* Relay Hash table: */
if (hrstring != NULL)
rsize = atoi(hrstring);
else rsize = RSIZE_NORMAL;
}
if (asize <= 0 || rsize <= 0) {
fprintf(stderr, "%s: Illegal hash table size\n", pname);
usage();
}
if (!Oflag) Oflag = FORMAT_ASCII;
else if (!strncmp(Ochar, "ascii", 5)) Oflag = FORMAT_ASCII;
else if (!strncmp(Ochar, "html", 4)) Oflag = FORMAT_HTML;
else if (!strncmp(Ochar, "clog", 4)) Oflag = FORMAT_CLOG;
else {
fprintf(stderr, "%s: illegal output format \"%s\".\n",
pname, Ochar);
exit (1);
}
if (aflag) Oflag = FORMAT_ASCII;
if (wflag) Oflag = FORMAT_HTML;
if (!Cchar) Cchar = COMMENT;
if (aflag) wflag = 0;
if (!bchar) bchar = BG_COLOR;
if (!tbchar) tbchar = TB_COLOR;
if (!bechar) bechar = BOUNCE_ADDR;
if (lflag) {
if (lnum <= 0) lnum = 0;
lrnum = lnum;
} else if (!lrflag) {
lnum = LDEF;
if (lnum <= 0) lnum = 0;
lrnum = LRDEF;
if (lrnum <= 0) lrnum = 0;
}
if (rflag) {
if (rnum <= 0) rnum = 0;
rrnum = rnum;
} else if (!rrflag) {
rnum = RDEF;
if (rnum <= 0) rnum = 0;
rrnum = RRDEF;
if (rrnum <= 0) rrnum = 0;
}
/* Set output: */
if (ochar) {
if (!(ofp = fopen(ochar, "w"))) {
fprintf(stderr, "%s: cannot open %s\n", pname, ochar);
ofp = stdout;
}
} else
ofp = stdout;
/* Check filter logic: */
/* Envelope and relay filters: */
if (sef || srf || ref || rrf) {
if (!qflag) fprintf(stderr, "%s: setting filters\n", pname);
#ifdef USE_REGEXP
if (csflag)
csflag = REG_EXTENDED|REG_NOSUB;
else
csflag = REG_EXTENDED|REG_ICASE|REG_NOSUB;
#endif
}
if (!sef || !strncmp(sef, "*", 1)) {
sef = (char *)NULL;
} else {
#ifdef USE_REGEXP
if (*sef == '!') {
if (*(sef+1) == '\0')
sef = NULL;
regcomp(&csef, sef+1, csflag);
} else
regcomp(&csef, sef, csflag);
#else
if (*sef == '!' && *(sef+1) == '\0')
sef = (char *)NULL;
#endif
if (!qflag) fprintf(stderr,
" envelope sender filter: %s\n", sef);
}
if (!srf || !strncmp(srf, "*", 1)) srf = (char *)NULL;
else {
#ifdef USE_REGEXP
if (*srf == '!') {
if (*(srf+1) == '\0')
srf = NULL;
regcomp(&csrf, srf+1, csflag);
} else
regcomp(&csrf, srf, csflag);
#else
if (*srf == '!' && *(srf+1) == '\0')
srf = (char *)NULL;
#endif
if (!qflag) fprintf(stderr,
" relay sender filter: %s\n", srf);
}
if (!ref || !strncmp(ref, "*", 1)) ref = (char *)NULL;
else {
#ifdef USE_REGEXP
if (*ref == '!')
regcomp(&cref, ref+1, csflag);
else
regcomp(&cref, ref, csflag);
#else
if (*ref == '!' && *(ref+1) == '\0')
ref = (char *)NULL;
#endif
if (!qflag) fprintf(stderr,
" envelope recipient filter: %s\n", ref);
}
if (!rrf || !strncmp(rrf, "*", 1)) rrf = (char *)NULL;
else {
#ifdef USE_REGEXP
if (*rrf == '!')
regcomp(&crrf, rrf+1, csflag);
else
regcomp(&crrf, rrf, csflag);
#else
if (*rrf == '!' && *(rrf+1) == '\0')
rrf = (char *)NULL;
#endif
if (!qflag) fprintf(stderr,
" relay recipient filter: %s\n", rrf);
}
/* Start -and end times: */
if (Dflag) {
/* Read from command line.. */
if (!(sstring = strdup(Dchar)))
error_memory();
tstring = sstring;
if (*sstring == ',') {
tstring = NULL;
if (*(sstring + 1) == '\0')
estring = NULL;
else
estring = ++sstring;
}
while (*sstring != '\0') {
if (*sstring == ',') {
*sstring = '\0';
if (*(sstring + 1) == '\0')
estring = NULL;
else
estring = ++sstring;
break;
}
sstring++;
}
/* StartTime: */
if (tstring != NULL)
scan_time(&sstime, tstring);
/* EndTime: */
if (estring != NULL)
scan_time(&eetime, estring);
} else {
if (!sstring || !(strncmp(sstring, "*", 1)))
sstring = NULL;
else if (sscanf(sstring, "%d/%d/%d-%d:%d:%d",
&syear, &smonth, &sday, &shour, &sminute, &ssecond) != 6) {
sstring = NULL;
if (!qflag) {
fprintf(stderr, "%s: illegal StartTime, "
"using (*)\n", pname);
}
} else {
sstime = (time_t)conv_time(smonth-1, sday, shour,
sminute, ssecond);
if (!sstime && !qflag)
fprintf(stderr, "%s: illegal StartTime, "
"using (*)\n", pname);
}
if (!estring || !(strncmp(estring, "*", 1)))
estring = NULL;
else if (sscanf(estring, "%d/%d/%d-%d:%d:%d",
&eyear, &emonth, &eday, &ehour, &eminute, &esecond) != 6) {
if (!qflag) {
fprintf(stderr, "%s: illegal EndTime, "
"using (*)\n", pname);
}
} else {
eetime = (time_t)conv_time(emonth-1, eday, ehour,
eminute, esecond);
if (!eetime && !qflag)
fprintf(stderr, "%s: illegal EndTime, "
"using (*)\n", pname);
}
}
/* Print out configuration to stdout: */
if (pflag) {
fprintf(stderr, "%s: configuration:\n", pname);
dump_config(stdout);
exit (0);
}
/* Print configuration in debug mode: */
if (vflag) {
fprintf(stderr, "%s: configuration:\n", pname);
dump_config(stderr);
}
/* loop through remaining arguments (if any) and do parsing: */
if (*argv)
for (; *argv; ++argv) {
if (!qflag) fprintf(stderr,
"%s: opening file %s\n", pname, *argv);
if (!(fp = fopen(*argv, "r")))
fprintf(stderr,
"%s: cannot open %s\n", pname, *argv);
else {
parse(fp, *argv);
(void)fclose(fp);
}
}
else {
if (!qflag)
fprintf(stderr, "%s: reading from stdin\n", pname);
parse(stdin, "stdin");
}
/* If output format is clog, nothing to do here: */
if (Oflag == FORMAT_CLOG) exit (0);
/* check host structure: */
hptr = first.next;
if (!hptr || !(hptr->inum) || !(hptr->onum)) {
if (!qflag)
fprintf(stderr, "%s: nothing to report\n", pname);
exit(1);
}
for (hptr = first.next; hptr; hptr = hptr->next) {
/* rearrange and sort: */
sort(hptr);
/* seconds between first and last log entry: */
hptr->dtime = difftime(hptr->ltime, hptr->ftime);
/* first hour and day: */
hptr->fday = (localtime(&hptr->ftime))->tm_wday;
hptr->fhour = (localtime(&hptr->ftime))->tm_hour;
/* time distributions: */
average(hptr, hptr->idd, hptr->fidd,
hptr->ihh, hptr->fihh);
average(hptr, hptr->odd, hptr->fodd,
hptr->ohh, hptr->fohh);
}
/* print: */
if (Oflag == FORMAT_HTML) html(ofp);
else if (Oflag == FORMAT_ASCII) ascii(ofp);
(void)fclose(ofp);
/* OK: */
exit(0);
}
syntax highlighted by Code2HTML, v. 0.9.1