diff options
Diffstat (limited to 'src/qmail-mrtg.c')
-rw-r--r-- | src/qmail-mrtg.c | 398 |
1 files changed, 249 insertions, 149 deletions
diff --git a/src/qmail-mrtg.c b/src/qmail-mrtg.c index 1ccedeb..cecd067 100644 --- a/src/qmail-mrtg.c +++ b/src/qmail-mrtg.c @@ -1,18 +1,20 @@ #include <unistd.h> -#include "stralloc.h" + #include "buffer.h" -#include "getln.h" +#include "case.h" #include "exit.h" +#include "fmt.h" +#include "getln.h" +#include "logmsg.h" #include "open.h" #include "scan.h" -#include "fmt.h" -#include "case.h" -#include "now.h" #include "str.h" +#include "stralloc.h" + #include "datetime.h" -#include "logmsg.h" +#include "now.h" -#define WHO "qmail-mrtg" +#define WHO "qmail-mrtg" #define TAI64NLEN 24 /** @file qmail-mrtg.c @@ -75,174 +77,262 @@ int grey = 0; int rbl = 0; char bufsmall[64]; -buffer bo = BUFFER_INIT(write,1,bufsmall,sizeof(bufsmall)); +buffer bo = BUFFER_INIT(write, 1, bufsmall, sizeof(bufsmall)); -static void outs(char *s) +static void outs(char *s) { - if (buffer_puts(&bo,s) == -1) _exit(1); - if (buffer_puts(&bo,"\n") == -1) _exit(1); + if (buffer_puts(&bo, s) == -1) _exit(1); + if (buffer_puts(&bo, "\n") == -1) _exit(1); if (buffer_flush(&bo) == -1) _exit(1); } -static void out(int i) +static void out(int i) { char num[FMT_ULONG]; - if (buffer_put(&bo,num,fmt_ulong(num,(unsigned long) i)) == -1) _exit(1); - if (buffer_puts(&bo,"\n") == -1) _exit(1); + if (buffer_put(&bo, num, fmt_ulong(num, (unsigned long)i)) == -1) _exit(1); + if (buffer_puts(&bo, "\n") == -1) _exit(1); if (buffer_flush(&bo) == -1) _exit(1); } char bufspace[1024]; -buffer bi = BUFFER_INIT(read,0,bufspace,sizeof(bufspace)); +buffer bi = BUFFER_INIT(read, 0, bufspace, sizeof(bufspace)); -void mrtg_results(char flag) +void mrtg_results(char flag) { switch (flag) { - case '1': out(success); out(tlstrans); break; - case '2': bytes = bytes/1024; out(bytes); out(bytes); break; - case '3': out(local); out(remote); break; - case '4': out(failure); out(deferral); break; - case '5': out(bounces); out(triples); break; - case '6': qmtps += qmtp; out(qmtp); out(qmtps); break; /* QMTP */ - - case 'a': out(asessions); out(rsessions); break; /* total */ - case 'b': out(aorig); out(arcpt); break; /* accepted */ - case 'c': out(rsend); out(rhelo); break; /* rejected MTA */ - case 'd': out(rorigbad); out(rorigdns); break; /* Orig */ - case 'e': out(rrcptbad); out(rrcptfail); break; /* Recipient */ - case 'f': out(rmime); out(rloader); break; /* Warlord */ - case 'g': out(rvirus); out(rspam); break; /* Infected/Spam */ - case 'h': out(aauth); out(rauth); break; /* Auth */ - case 'i': out(atls); out(rtls); break; /* TLS */ - case 'j': out(spfpass); out(spfail); break; /* SPF */ - case 'k': out(grey); break; /* Greylisted */ - case 'z': sdeny +=rbl; out(sok); out(sdeny); break; /* reject session */ - - case 'A': out(apop); out(rpop); break; - case 'B': out(pok); out(pdeny); break; + case '1': + out(success); + out(tlstrans); + break; + case '2': + bytes = bytes / 1024; + out(bytes); + out(bytes); + break; + case '3': + out(local); + out(remote); + break; + case '4': + out(failure); + out(deferral); + break; + case '5': + out(bounces); + out(triples); + break; + case '6': + qmtps += qmtp; + out(qmtp); + out(qmtps); + break; /* QMTP */ + + case 'a': + out(asessions); + out(rsessions); + break; /* total */ + case 'b': + out(aorig); + out(arcpt); + break; /* accepted */ + case 'c': + out(rsend); + out(rhelo); + break; /* rejected MTA */ + case 'd': + out(rorigbad); + out(rorigdns); + break; /* Orig */ + case 'e': + out(rrcptbad); + out(rrcptfail); + break; /* Recipient */ + case 'f': + out(rmime); + out(rloader); + break; /* Warlord */ + case 'g': + out(rvirus); + out(rspam); + break; /* Infected/Spam */ + case 'h': + out(aauth); + out(rauth); + break; /* Auth */ + case 'i': + out(atls); + out(rtls); + break; /* TLS */ + case 'j': + out(spfpass); + out(spfail); + break; /* SPF */ + case 'k': out(grey); break; /* Greylisted */ + case 'z': + sdeny += rbl; + out(sok); + out(sdeny); + break; /* reject session */ + + case 'A': + out(apop); + out(rpop); + break; + case 'B': + out(pok); + out(pdeny); + break; default: break; } } -void mrtg_sendlog(char *in, char flag) +void mrtg_sendlog(char *in, char flag) { int i, j, k = 0; - switch (flag) { - case '1': if (case_starts(in,"delivery")) { - i = str_chr(in,':') + 2; - if (case_starts(in + i,"success:")) success++; - i = str_chr(in,'T'); - if (case_starts(in + i,"TLS_")) tlstrans++; - }; break; - case '2': if (case_starts(in,"info msg")) { - i = str_chr(in,':') + 8; - if ((j = str_chr(in + i,' '))) in[i + j] = '\0'; - bytes += atoi(in + i); - }; break; - case '3': if (case_starts(in,"status:")) { - i = str_rchr(in,'c') + 4; - k = str_rchr(in,'r') + 7; - if ((j = str_chr(in + i,'/'))) in[i + j] = '\0'; - if (atoi(in + i) > local) local = atoi(in + i); - if ((j = str_chr(in + k,'/'))) in[k + j] = '\0'; - if (atoi(in + k) > remote) remote = atoi(in + k); - }; break; - case '4': if (case_starts(in,"delivery")) { - i = str_chr(in,':') + 2; - if (case_starts(in + i,"failure:")) failure++; - if (case_starts(in + i,"deferral:")) deferral++; - }; break; - case '5': if (case_starts(in,"bounce msg")) bounces++; - if (case_starts(in,"triple bounce:")) triples++; - break; - case '6': if (case_starts(in,"delivery")) { - i = str_chr(in,'q'); - if (case_starts(in + i,"qmtp:_ok")) qmtp++; - if (case_starts(in + i,"qmtps:_ok")) qmtps++; - }; break; - default: break; + switch (flag) { + case '1': + if (case_starts(in, "delivery")) { + i = str_chr(in, ':') + 2; + if (case_starts(in + i, "success:")) success++; + i = str_chr(in, 'T'); + if (case_starts(in + i, "TLS_")) tlstrans++; + }; + break; + case '2': + if (case_starts(in, "info msg")) { + i = str_chr(in, ':') + 8; + if ((j = str_chr(in + i, ' '))) in[i + j] = '\0'; + bytes += atoi(in + i); + }; + break; + case '3': + if (case_starts(in, "status:")) { + i = str_rchr(in, 'c') + 4; + k = str_rchr(in, 'r') + 7; + if ((j = str_chr(in + i, '/'))) in[i + j] = '\0'; + if (atoi(in + i) > local) local = atoi(in + i); + if ((j = str_chr(in + k, '/'))) in[k + j] = '\0'; + if (atoi(in + k) > remote) remote = atoi(in + k); + }; + break; + case '4': + if (case_starts(in, "delivery")) { + i = str_chr(in, ':') + 2; + if (case_starts(in + i, "failure:")) failure++; + if (case_starts(in + i, "deferral:")) deferral++; + }; + break; + case '5': + if (case_starts(in, "bounce msg")) bounces++; + if (case_starts(in, "triple bounce:")) triples++; + break; + case '6': + if (case_starts(in, "delivery")) { + i = str_chr(in, 'q'); + if (case_starts(in + i, "qmtp:_ok")) qmtp++; + if (case_starts(in + i, "qmtps:_ok")) qmtps++; + }; + break; + default: break; } } -void mrtg_smtplog(char *in, char flag) +void mrtg_smtplog(char *in, char flag) { int i, j, k = 0; - i = str_chr(in,'A'); - j = str_chr(in,'R'); - k = str_chr(in,'P'); + i = str_chr(in, 'A'); + j = str_chr(in, 'R'); + k = str_chr(in, 'P'); switch (flag) { - case 'a': if (case_starts(in + i,"Accept")) asessions++; - if (case_starts(in + j,"Reject")) rsessions++; - break; - case 'b': if (case_starts(in + i,"Accept::ORIG:")) aorig++; - if (case_starts(in + i,"Accept::RCPT:")) arcpt++; - break; - case 'c': if (case_starts(in + j,"Reject::SNDR::Invalid_Relay")) rsend++; - if (case_starts(in + j,"Reject::SNDR::Bad_Helo")) rhelo++; - if (case_starts(in + j,"Reject::SNDR::DNS_Helo")) rhelo++; - break; - case 'd': if (case_starts(in + j,"Reject::ORIG::Bad_Mailfrom")) rorigbad++; - if (case_starts(in + j,"Reject::ORIG::DNS_MF")) rorigdns++; - break; - case 'e': if (case_starts(in + j,"Reject::RCPT::Bad_Rcptto")) rrcptbad++; - if (case_starts(in + j,"Reject::RCPT::Failed_Rcptto")) rrcptfail++; - break; - case 'f': if (case_starts(in + j,"Reject::DATA::Invalid_Size")) rsize++; - if (case_starts(in + j,"Reject::DATA::Bad_MIME")) rmime++; - if (case_starts(in + j,"Reject::DATA::MIME_Attach")) rmime++; - if (case_starts(in + j,"Reject::DATA::Bad_Loader")) rloader++; - break; - case 'g': if (case_starts(in + j,"Reject::DATA::Spam_Message")) rspam++; - if (case_starts(in + j,"Reject::DATA::Virus_Infected")) rvirus++; - break; - case 'h': if (case_starts(in + i,"Accept::AUTH:")) aauth++; - if (case_starts(in + j,"Reject::AUTH:")) rauth++; - break; - case 'i': if (case_starts(in + k,"P:ESMTPS")) atls++; - if (case_starts(in + j,"Reject::TLS:")) rtls++; - break; - case 'j': if (case_starts(in + i,"Accept::SPF:")) spfpass++; - if (case_starts(in + j,"Reject::SPF:")) spfail++; - break; - case 'k': if (case_starts(in + i,"Deferred::SNDR::Grey_Listed")) grey++; - break; - case 'z': if (case_starts(in,"tcpserver") || case_starts(in,"sslserver") || case_starts(in,"rblsmtpd")) { - i = str_chr(in,':') + 2; - if (case_starts(in + i,"ok")) sok++; - if (case_starts(in + i,"deny")) sdeny++; - j = str_chr(in+i,':') + 2; - if (case_starts(in + i + j,"451")) rbl++; - if (case_starts(in + i + j,"553")) rbl++; - if (case_starts(in + i + j,"greetdelay:")) greet++; - } break; - default: break; + case 'a': + if (case_starts(in + i, "Accept")) asessions++; + if (case_starts(in + j, "Reject")) rsessions++; + break; + case 'b': + if (case_starts(in + i, "Accept::ORIG:")) aorig++; + if (case_starts(in + i, "Accept::RCPT:")) arcpt++; + break; + case 'c': + if (case_starts(in + j, "Reject::SNDR::Invalid_Relay")) rsend++; + if (case_starts(in + j, "Reject::SNDR::Bad_Helo")) rhelo++; + if (case_starts(in + j, "Reject::SNDR::DNS_Helo")) rhelo++; + break; + case 'd': + if (case_starts(in + j, "Reject::ORIG::Bad_Mailfrom")) rorigbad++; + if (case_starts(in + j, "Reject::ORIG::DNS_MF")) rorigdns++; + break; + case 'e': + if (case_starts(in + j, "Reject::RCPT::Bad_Rcptto")) rrcptbad++; + if (case_starts(in + j, "Reject::RCPT::Failed_Rcptto")) rrcptfail++; + break; + case 'f': + if (case_starts(in + j, "Reject::DATA::Invalid_Size")) rsize++; + if (case_starts(in + j, "Reject::DATA::Bad_MIME")) rmime++; + if (case_starts(in + j, "Reject::DATA::MIME_Attach")) rmime++; + if (case_starts(in + j, "Reject::DATA::Bad_Loader")) rloader++; + break; + case 'g': + if (case_starts(in + j, "Reject::DATA::Spam_Message")) rspam++; + if (case_starts(in + j, "Reject::DATA::Virus_Infected")) rvirus++; + break; + case 'h': + if (case_starts(in + i, "Accept::AUTH:")) aauth++; + if (case_starts(in + j, "Reject::AUTH:")) rauth++; + break; + case 'i': + if (case_starts(in + k, "P:ESMTPS")) atls++; + if (case_starts(in + j, "Reject::TLS:")) rtls++; + break; + case 'j': + if (case_starts(in + i, "Accept::SPF:")) spfpass++; + if (case_starts(in + j, "Reject::SPF:")) spfail++; + break; + case 'k': + if (case_starts(in + i, "Deferred::SNDR::Grey_Listed")) grey++; + break; + case 'z': + if (case_starts(in, "tcpserver") || case_starts(in, "sslserver") || case_starts(in, "rblsmtpd")) { + i = str_chr(in, ':') + 2; + if (case_starts(in + i, "ok")) sok++; + if (case_starts(in + i, "deny")) sdeny++; + j = str_chr(in + i, ':') + 2; + if (case_starts(in + i + j, "451")) rbl++; + if (case_starts(in + i + j, "553")) rbl++; + if (case_starts(in + i + j, "greetdelay:")) greet++; + } + break; + default: break; } -} +} -void mrtg_pop3log(char *in, char flag) +void mrtg_pop3log(char *in, char flag) { int i, j = 0; switch (flag) { - case 'A': i = str_chr(in,'A'); j = str_chr(in,'R'); - if (case_starts(in + i,"Accept::AUTH:")) apop++; - if (case_starts(in + j,"Reject::AUTH:")) rpop++; - break; - case 'B': if (case_starts(in,"tcpserver:") || case_starts(in,"sslserver:")) { - i = str_chr(in,':') + 2; - if (case_starts(in + i,"ok")) pok++; - if (case_starts(in + i,"deny")) pdeny++; - }; break; - default: break; + case 'A': + i = str_chr(in, 'A'); + j = str_chr(in, 'R'); + if (case_starts(in + i, "Accept::AUTH:")) apop++; + if (case_starts(in + j, "Reject::AUTH:")) rpop++; + break; + case 'B': + if (case_starts(in, "tcpserver:") || case_starts(in, "sslserver:")) { + i = str_chr(in, ':') + 2; + if (case_starts(in + i, "ok")) pok++; + if (case_starts(in + i, "deny")) pdeny++; + }; + break; + default: break; } } -int main(int argc, char **argv) +int main(int argc, char **argv) { int i; int c; @@ -258,27 +348,34 @@ int main(int argc, char **argv) stralloc line = {0}; calltime = now(); - if (argc < 2) - logmsg(WHO,100,USAGE,"qmail-mrtg [ -1 | -2 | -3 | -4 | -5 | -6 |\ + if (argc < 2) + logmsg( + WHO, + 100, + USAGE, + "qmail-mrtg [ -1 | -2 | -3 | -4 | -5 | -6 |\ -a | -b | -c | -d | -e | -f | -g | -h | -i | -j | -k | -z | -A | -B ] [time] \n\ qmail-mrtg needs to be called every [time] minutes (i.e. by crontab) - default 305 secs"); flag = *(argv[1] + 1); - if (argc == 3) { scan_ulong(argv[2],&u); history = 60 * u; } + if (argc == 3) { + scan_ulong(argv[2], &u); + history = 60 * u; + } -/* Read input lines sequentially */ + /* Read input lines sequentially */ - buffer_init(&bi,read,0,bufspace,sizeof(bufspace)); + buffer_init(&bi, read, 0, bufspace, sizeof(bufspace)); for (;;) { - if (getln(&bi,&line,&match,'\n') != 0) _exit(1); + if (getln(&bi, &line, &match, '\n') != 0) _exit(1); if (!match) break; if (!stralloc_0(&line)) _exit(1); seconds = 0; nanoseconds = 0; - if (line.s[0] == '@') { /* tai64 timestamp */ + if (line.s[0] == '@') { /* tai64 timestamp */ for (i = 1; i <= TAI64NLEN; i++) { c = (int)line.s[i]; u = c - '0'; @@ -300,23 +397,26 @@ int main(int argc, char **argv) _exit(1); } - if (enoughtime) { /* default history = 305 sec => evaluate logs every ~5 mins */ + if (enoughtime) { /* default history = 305 sec => evaluate logs every ~5 mins */ if (seconds <= calltime && seconds >= (calltime - history)) { - if (flag >= '1' && flag <= '9') mrtg_sendlog(line.s + TAI64NLEN + 2,flag); - else if (flag >= 'a' && flag <= 'z') mrtg_smtplog(line.s + TAI64NLEN + 2,flag); - else if (flag >= 'A' && flag <= 'Z') mrtg_pop3log(line.s + TAI64NLEN + 2,flag); + if (flag >= '1' && flag <= '9') + mrtg_sendlog(line.s + TAI64NLEN + 2, flag); + else if (flag >= 'a' && flag <= 'z') + mrtg_smtplog(line.s + TAI64NLEN + 2, flag); + else if (flag >= 'A' && flag <= 'Z') + mrtg_pop3log(line.s + TAI64NLEN + 2, flag); } - } else { + } else { if (seconds) { enoughtime++; } else { outs("Warning: Not enough time left between calls"); _exit(1); - } + } } } mrtg_results(flag); - + _exit(0); } |