16#define WHO "qmail-mrtg"
81static void outs(
char *s)
83 if (buffer_puts(&
bo,s) == -1)
_exit(1);
84 if (buffer_puts(&
bo,
"\n") == -1)
_exit(1);
85 if (buffer_flush(&
bo) == -1)
_exit(1);
92 if (buffer_put(&
bo,
num,fmt_ulong(
num,(
unsigned long) i)) == -1)
_exit(1);
93 if (buffer_puts(&
bo,
"\n") == -1)
_exit(1);
94 if (buffer_flush(&
bo) == -1)
_exit(1);
100static void mrtg_results(
char flag)
130static void mrtg_sendlog(
char *
in,
char flag)
135 case '1':
if (case_starts(
in,
"delivery")) {
136 i = str_chr(
in,
':') + 2;
137 if (case_starts(
in + i,
"success:"))
success++;
141 case '2':
if (case_starts(
in,
"info msg")) {
142 i = str_chr(
in,
':') + 8;
143 if ((
j = str_chr(
in + i,
' ')))
in[i +
j] =
'\0';
146 case '3':
if (case_starts(
in,
"status:")) {
147 i = str_rchr(
in,
'c') + 4;
148 k = str_rchr(
in,
'r') + 7;
149 if ((
j = str_chr(
in + i,
'/')))
in[i +
j] =
'\0';
151 if ((
j = str_chr(
in +
k,
'/')))
in[
k +
j] =
'\0';
154 case '4':
if (case_starts(
in,
"delivery")) {
155 i = str_chr(
in,
':') + 2;
156 if (case_starts(
in + i,
"failure:"))
failure++;
157 if (case_starts(
in + i,
"deferral:"))
deferral++;
159 case '5':
if (case_starts(
in,
"bounce msg"))
bounces++;
160 if (case_starts(
in,
"triple bounce:"))
triples++;
162 case '6':
if (case_starts(
in,
"delivery")) {
164 if (case_starts(
in + i,
"qmtp:_ok"))
qmtp++;
165 if (case_starts(
in + i,
"qmtps:_ok"))
qmtps++;
171static void mrtg_smtplog(
char *
in,
char flag)
180 case 'a':
if (case_starts(
in + i,
"Accept"))
asessions++;
183 case 'b':
if (case_starts(
in + i,
"Accept::ORIG:"))
aorig++;
184 if (case_starts(
in + i,
"Accept::RCPT:"))
arcpt++;
186 case 'c':
if (case_starts(
in +
j,
"Reject::SNDR::Invalid_Relay"))
rsend++;
187 if (case_starts(
in +
j,
"Reject::SNDR::Bad_Helo"))
rhelo++;
188 if (case_starts(
in +
j,
"Reject::SNDR::DNS_Helo"))
rhelo++;
190 case 'd':
if (case_starts(
in +
j,
"Reject::ORIG::Bad_Mailfrom"))
rorigbad++;
191 if (case_starts(
in +
j,
"Reject::ORIG::DNS_MF"))
rorigdns++;
193 case 'e':
if (case_starts(
in +
j,
"Reject::RCPT::Bad_Rcptto"))
rrcptbad++;
194 if (case_starts(
in +
j,
"Reject::RCPT::Failed_Rcptto"))
rrcptfail++;
196 case 'f':
if (case_starts(
in +
j,
"Reject::DATA::Invalid_Size"))
rsize++;
197 if (case_starts(
in +
j,
"Reject::DATA::Bad_MIME"))
rmime++;
198 if (case_starts(
in +
j,
"Reject::DATA::MIME_Attach"))
rmime++;
199 if (case_starts(
in +
j,
"Reject::DATA::Bad_Loader"))
rloader++;
201 case 'g':
if (case_starts(
in +
j,
"Reject::DATA::Spam_Message"))
rspam++;
202 if (case_starts(
in +
j,
"Reject::DATA::Virus_Infected"))
rvirus++;
204 case 'h':
if (case_starts(
in + i,
"Accept::AUTH:"))
aauth++;
205 if (case_starts(
in +
j,
"Reject::AUTH:"))
rauth++;
207 case 'i':
if (case_starts(
in +
k,
"P:ESMTPS"))
atls++;
208 if (case_starts(
in +
j,
"Reject::TLS:"))
rtls++;
210 case 'j':
if (case_starts(
in + i,
"Accept::SPF:"))
spfpass++;
211 if (case_starts(
in +
j,
"Reject::SPF:"))
spfail++;
213 case 'k':
if (case_starts(
in + i,
"Deferred::SNDR::Grey_Listed"))
grey++;
215 case 'z':
if (case_starts(
in,
"tcpserver") || case_starts(
in,
"sslserver") || case_starts(
in,
"rblsmtpd")) {
216 i = str_chr(
in,
':') + 2;
217 if (case_starts(
in + i,
"ok"))
sok++;
218 if (case_starts(
in + i,
"deny"))
sdeny++;
219 j = str_chr(
in+i,
':') + 2;
220 if (case_starts(
in + i +
j,
"451"))
rbl++;
221 if (case_starts(
in + i +
j,
"553"))
rbl++;
222 if (case_starts(
in + i +
j,
"greetdelay:"))
greet++;
228static void mrtg_pop3log(
char *
in,
char flag)
233 case 'A': i = str_chr(
in,
'A');
j = str_chr(
in,
'R');
234 if (case_starts(
in + i,
"Accept::AUTH:"))
apop++;
235 if (case_starts(
in +
j,
"Reject::AUTH:"))
rpop++;
237 case 'B':
if (case_starts(
in,
"tcpserver:") || case_starts(
in,
"sslserver:")) {
238 i = str_chr(
in,
':') + 2;
239 if (case_starts(
in + i,
"ok"))
pok++;
240 if (case_starts(
in + i,
"deny"))
pdeny++;
246int main(
int argc,
char *
const *argv)
253 unsigned long calltime;
254 unsigned long seconds;
255 unsigned long nanoseconds;
256 unsigned int history = 305;
263 logmsg(
WHO,100,USAGE,
"qmail-mrtg [ -1 | -2 | -3 | -4 | -5 | -6 |\
264 -a | -b | -c | -d | -e | -f | -g | -h | -i | -j | -k | -z | -A | -B ] [time (min)] \n\
265 qmail-mrtg needs to be called every [time] minutes (i.e. by crontab) - default 305 secs");
267 flag = *(argv[1] + 1);
268 if (argc == 3) { scan_ulong(argv[2],&u); history = 60 * u + 5; }
282 if (
line.s[0] ==
'@') {
292 seconds += nanoseconds >> 28;
293 nanoseconds &= 0xfffffff;
297 seconds -= 4611686018427387914ULL;
298 seconds = seconds > 0 ? seconds : 0;
300 outs(
"Error: No TAI64N timestamp available.");
305 if (seconds <= calltime && seconds >= (calltime - history)) {
306 if (flag >=
'1' && flag <=
'9') mrtg_sendlog(
line.s +
TAI64NLEN + 2,flag);
307 else if (flag >=
'a' && flag <=
'z') mrtg_smtplog(
line.s +
TAI64NLEN + 2,flag);
308 else if (flag >=
'A' && flag <=
'Z') mrtg_pop3log(
line.s +
TAI64NLEN + 2,flag);
314 outs(
"Warning: Not enough time left between calls");
void c(char *, char *, char *, int, int, int)
char bufspace[BUFSIZE_LINE]
char bufsmall[BUFFER_SMALL]