summaryrefslogtreecommitdiff
path: root/src/qmail-mrtg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmail-mrtg.c')
-rw-r--r--src/qmail-mrtg.c398
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);
}