1 /*
2 * sma -- Sendmail log analyser
3 *
4 * Copyright (c) 2000 - 2003 Jarkko Turkulainen. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY JARKKO TURKULAINEN ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL JARKKO TURKULAINEN BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $Date: 2003/01/01 13:54:00 $
30 */
31
32 #include "sma.h"
33
34 void
ascii(FILE * fp)35 ascii(FILE *fp) {
36 unsigned int j, h;
37 char *p;
38 struct host *hptr;
39
40 const char *wdtab[] = { "Sunday", "Monday",
41 "Tuesday", "Wednesday", "Thursday",
42 "Friday", "Saturday" };
43
44 const char *hrtab[] = { "00-01", "01-02", "02-03",
45 "03-04", "04-05", "05-06", "06-07", "07-08",
46 "08-09", "09-10", "10-11", "11-12", "12-13",
47 "13-14", "14-15", "15-16", "16-17", "17-18",
48 "18-19", "19-20", "20-21", "21-22", "22-23", "23-00" };
49
50 curr = localtime(&tval);
51 p = asctime(curr);
52 p[strlen(p)-1] = '\0';
53
54 fprintf(fp, "\n%s\n", Cchar);
55 if (htchar)
56 fprintf(fp, "%s\n", htchar);
57 else
58 fprintf(fp, "Generated at %s by SMA, version %s\n",
59 p, VERSION);
60 fprintf(fp, "-----------------------------------------------------------------------------\n\n");
61
62 for (hptr = first.next; hptr; hptr = hptr->next) {
63 if (!(hptr->inum) || !(hptr->inum))
64 continue;
65 fprintf(fp, "\nServer: %s\n\n", hptr->name);
66 if (pgflag) {
67 fprintf(fp, "General information\n");
68 fprintf(fp, "-----------------------------------------------------------------------------\n");
69 fprintf(fp, " %-33s %s", "First log entry", ctime(&hptr->ftime));
70 fprintf(fp, " %-33s %s", "Last log entry", ctime(&hptr->ltime));
71 fprintf(fp, " %-33s %d\n", "Alias table rebuilds", hptr->alias);
72 fprintf(fp, " %-33s %d\n", "Too many hops", hptr->hopc);
73 fprintf(fp, " %-33s %d\n", "Mail loops", hptr->lcerror);
74 fprintf(fp, " %-33s %d\n", "Other SYSERR", hptr->oserror);
75 fprintf(fp, " %-33s %d\n", "Ruleset based rejections", hptr->rule);
76 fprintf(fp, " %-33s %d\n\n", "Sendmail daemon restarts", hptr->dstart);
77
78
79 fprintf(fp, "%s%35s\n", "Inbound messages", "Outbound messages");
80 fprintf(fp, "-----------------------------------------------------------------------------\n");
81
82 /*
83 * Hm. it seems that Win32 printf cannot handle correctly long's..
84 * This is not the right thing to do, consider some typedef instead..
85 * But hey, I should drop the Win32 support anyway, who uses it?
86 */
87 #ifdef _WIN32
88 fprintf(fp, " %-20s %7d", "Total", (int)hptr->inum);
89 fprintf(fp, " %-15s %7d\n", "Total", (int)hptr->gonum);
90 fprintf(fp, " %-20s %7.2f", "Average size (kB)",
91 (double)hptr->size/(double)hptr->inum/1000);
92 #else
93 fprintf(fp, " %-20s %7ld", "Total", hptr->inum);
94 fprintf(fp, " %-15s %7ld\n", "Total", hptr->gonum);
95 fprintf(fp, " %-20s %7.2Lf", "Average size (kB)",
96 hptr->size/(double)hptr->inum/1000);
97 #endif
98
99 fprintf(fp, " %-15s %7d\n", "Sent", hptr->sent);
100
101 fprintf(fp, " %-20s %7.2f", "Messages/hour",
102 3600*(float)hptr->inum/(float)hptr->dtime);
103 fprintf(fp, " %-15s %7d\n", "Deferred", hptr->defe);
104
105 fprintf(fp, " %-20s %7.2f", "Messages/min",
106 60*(float)hptr->inum/(float)hptr->dtime);
107 fprintf(fp, " %-15s %7d\n", "Queued", hptr->queu);
108
109 fprintf(fp, " %-20s %7.2f", "Messages/sec",
110 (float)hptr->inum/(float)hptr->dtime);
111 fprintf(fp, " %-15s %7d\n", "Other error",
112 hptr->other + hptr->hunk + hptr->uunk + hptr->service);
113 }
114
115 if (epnum) {
116 fprintf(fp, "\n\nTop envelope pairs\n");
117 fprintf(fp, "-----------------------------------------------------------------------------\n");
118 fprintf(fp, "%5s %-45s %6s %10s %7s\n",
119 "Nr", "Sender/Recipient", "Msgs", "MB", "%");
120 fprintf(fp, "-----------------------------------------------------------------------------\n");
121
122 for (j = 0; j < (MIN(epnum, hptr->edif)); j++) {
123 #ifdef _WIN32
124 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1,
125 hptr->setab[j]->fname,
126 (strlen(hptr->setab[j]->fname) >= 40) ? "$" : " ",
127 hptr->setab[j]->num,
128 (double)hptr->setab[j]->size/1000000);
129 #else
130 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1,
131 hptr->setab[j]->fname,
132 (strlen(hptr->setab[j]->fname) >= 40) ? "$" : " ",
133 hptr->setab[j]->num,
134 hptr->setab[j]->size/1000000);
135 #endif
136
137 if (sflag) {
138 fprintf(fp, " %7.2f\n",
139 100*(float)hptr->setab[j]->size/(float)hptr->osize);
140 } else {
141 fprintf(fp, " %7.2f\n",
142 100*(float)hptr->setab[j]->num/(float)hptr->onum);
143 }
144 fprintf(fp, " %.40s%s", hptr->setab[j]->tname,
145 (strlen(hptr->setab[j]->tname) >= 40) ? "$\n" : "\n");
146 }
147 }
148
149
150 if (lnum) {
151 fprintf(fp, "\nTop envelope senders");
152 if (sef) fprintf(fp, " (filter: %s)\n", sef);
153 else fprintf(fp, "\n");
154 fprintf(fp, "-----------------------------------------------------------------------------\n");
155 fprintf(fp, "%5s %-45s %6s %10s %7s\n",
156 "Nr", "Sender", "Msgs", "MB", "%");
157 fprintf(fp, "-----------------------------------------------------------------------------\n");
158
159 for (j = 0; j < (MIN(lnum, hptr->idif)); j++) {
160 #ifdef _WIN32
161 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1,
162 hptr->sitab[j]->name,
163 (strlen(hptr->sitab[j]->name) >= 40) ? "$" : " ",
164 hptr->sitab[j]->num,
165 (double)hptr->sitab[j]->size/1000000);
166 #else
167 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1,
168 hptr->sitab[j]->name,
169 (strlen(hptr->sitab[j]->name) >= 40) ? "$" : " ",
170 hptr->sitab[j]->num,
171 hptr->sitab[j]->size/1000000);
172 #endif
173
174 if (sflag) {
175 fprintf(fp, " %7.2f\n",
176 100*(float)hptr->sitab[j]->size/(float)hptr->isize);
177 } else {
178 fprintf(fp, " %7.2f\n",
179 100*(float)hptr->sitab[j]->num/(float)hptr->inum);
180 }
181 }
182 }
183
184 if (lrnum) {
185 fprintf(fp, "\nTop envelope recipients");
186 if (ref) fprintf(fp, " (filter: %s)\n", ref);
187 else fprintf(fp, "\n");
188 fprintf(fp, "-----------------------------------------------------------------------------\n");
189 fprintf(fp, "%5s %-45s %6s %10s %7s\n",
190 "Nr", "Recipient", "Msgs", "MB", "%");
191 fprintf(fp, "-----------------------------------------------------------------------------\n");
192 for (j = 0; j < (MIN(lrnum, hptr->odif)); j++) {
193 #ifdef _WIN32
194 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1,
195 hptr->sotab[j]->name,
196 (strlen(hptr->sotab[j]->name) >= 40) ? "$" : " ",
197 hptr->sotab[j]->num,
198 (double)hptr->sotab[j]->size/1000000);
199 #else
200 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1,
201 hptr->sotab[j]->name,
202 (strlen(hptr->sotab[j]->name) >= 40) ? "$" : " ",
203 hptr->sotab[j]->num,
204 hptr->sotab[j]->size/1000000);
205 #endif
206
207 if (sflag) {
208 fprintf(fp, " %7.2f\n",
209 100*(float)hptr->sotab[j]->size/(float)hptr->osize);
210 } else {
211 fprintf(fp, " %7.2f\n",
212 100*(float)hptr->sotab[j]->num/(float)hptr->onum);
213 }
214 }
215 }
216
217 if (rpnum) {
218 fprintf(fp, "\n\nTop relay pairs\n");
219 fprintf(fp, "-----------------------------------------------------------------------------\n");
220 fprintf(fp, "%5s %-45s %6s %10s %7s\n",
221 "Nr", "Sender relay/Recipient relay", "Msgs", "MB", "%");
222 fprintf(fp, "-----------------------------------------------------------------------------\n");
223
224 for (j = 0; j < (MIN(rpnum, hptr->rrdif)); j++) {
225 #ifdef _WIN32
226 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1,
227 hptr->srtab[j]->fname,
228 (strlen(hptr->srtab[j]->fname) >= 40) ? "$" : " ",
229 hptr->srtab[j]->num,
230 (double)hptr->srtab[j]->size/1000000);
231 #else
232 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1,
233 hptr->srtab[j]->fname,
234 (strlen(hptr->srtab[j]->fname) >= 40) ? "$" : " ",
235 hptr->srtab[j]->num,
236 hptr->srtab[j]->size/1000000);
237 #endif
238 if (sflag) {
239 fprintf(fp, " %7.2f\n",
240 100*(float)hptr->srtab[j]->size/(float)hptr->osize);
241 } else {
242 fprintf(fp, " %7.2f\n",
243 100*(float)hptr->srtab[j]->num/(float)hptr->onum);
244 }
245 fprintf(fp, " %.40s%s", hptr->srtab[j]->tname,
246 (strlen(hptr->srtab[j]->tname) >= 40) ? "$\n" : "\n");
247 }
248 }
249
250
251 if (rnum) {
252 fprintf(fp, "\nTop relay addresses, sender");
253 if (srf) fprintf(fp, " (filter: %s)\n", srf);
254 else fprintf(fp, "\n");
255 fprintf(fp, "-----------------------------------------------------------------------------\n");
256 fprintf(fp, "%5s %-45s %6s %10s %7s\n",
257 "Nr", "Relay", "Msgs", "MB", "%");
258 fprintf(fp, "-----------------------------------------------------------------------------\n");
259
260 for (j = 0; j < (MIN(rnum, hptr->ridif)); j++) {
261 #ifdef _WIN32
262 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1,
263 hptr->rsitab[j]->name,
264 (strlen(hptr->rsitab[j]->name) >= 40) ? "$" : " ",
265 hptr->rsitab[j]->num,
266 (double)hptr->rsitab[j]->size/1000000);
267 #else
268 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1,
269 hptr->rsitab[j]->name,
270 (strlen(hptr->rsitab[j]->name) >= 40) ? "$" : " ",
271 hptr->rsitab[j]->num,
272 hptr->rsitab[j]->size/1000000);
273 #endif
274
275 if (sflag) {
276 fprintf(fp, " %7.2f\n",
277 100*(float)hptr->rsitab[j]->size/(float)hptr->isize);
278 } else {
279 fprintf(fp, " %7.2f\n",
280 100*(float)hptr->rsitab[j]->num/(float)hptr->rinum);
281 }
282
283 }
284 }
285
286 if (rrnum) {
287 fprintf(fp, "\nTop relay addresses, recipient");
288 if (rrf) fprintf(fp, " (filter: %s)\n", rrf);
289 else fprintf(fp, "\n");
290 fprintf(fp, "-----------------------------------------------------------------------------\n");
291 fprintf(fp, "%5s %-45s %6s %10s %7s\n",
292 "Nr", "Relay", "Msgs", "MB", "%");
293 fprintf(fp, "-----------------------------------------------------------------------------\n");
294 for (j = 0; j < (MIN(rrnum, hptr->rodif)); j++) {
295 #ifdef _WIN32
296 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2f", j+1,
297 hptr->rsotab[j]->name,
298 (strlen(hptr->rsotab[j]->name) >= 40) ? "$" : " ",
299 hptr->rsotab[j]->num,
300 (double)hptr->rsotab[j]->size/1000000);
301 #else
302 fprintf(fp, "%5d %-40.40s%-5s %6d %10.2Lf", j+1,
303 hptr->rsotab[j]->name,
304 (strlen(hptr->rsotab[j]->name) >= 40) ? "$" : " ",
305 hptr->rsotab[j]->num,
306 hptr->rsotab[j]->size/1000000);
307 #endif
308 if (sflag) {
309 fprintf(fp, " %7.2f\n",
310 100*(float)hptr->rsotab[j]->size/(float)hptr->osize);
311 } else {
312 fprintf(fp, " %7.2f\n",
313 100*(float)hptr->rsotab[j]->num/(float)hptr->ronum);
314 }
315 }
316 }
317
318 if (stnum) {
319 fprintf(fp, "\n\nTop status messages\n");
320 fprintf(fp, "-----------------------------------------------------------------------------\n");
321 fprintf(fp, "%5s %7s %6s %s\n",
322 "Nr", "Msgs", "%", " Status");
323 fprintf(fp, "-----------------------------------------------------------------------------\n");
324 for (j = 0; j < (MIN(stnum, hptr->sdif)); j++) {
325 fprintf(fp, "%5d %7d %6.2f %s %-52s\n", j+1,
326 hptr->ssttab[j]->num,
327 100*(float)hptr->ssttab[j]->num/(float)hptr->onum,
328 " ", hptr->ssttab[j]->name);
329 }
330 }
331
332 if (rsnum) {
333 fprintf(fp, "\n\nTop ruleset rejections\n");
334 fprintf(fp, "-----------------------------------------------------------------------------\n");
335 fprintf(fp, "%5s %7s %6s %s\n",
336 "Nr", "Msgs", "%", rsrnum ? " Reason / Top relays" : " Reason");
337 fprintf(fp, "-----------------------------------------------------------------------------\n");
338 for (j = 0; j < (MIN(rsnum, hptr->rdif)); j++) {
339 fprintf(fp, "%5d %7d %6.2f %s %-52s\n", j+1,
340 hptr->sruletab[j]->num,
341 100*(float)hptr->sruletab[j]->num/(float)hptr->rule,
342 " ", hptr->sruletab[j]->name);
343
344 if (rsrnum) {
345 fprintf(fp, " ------------------------------------------------------------------------\n");
346 for (h = 0; h < (MIN(rsrnum, hptr->sruletab[j]->reldif)); h++) {
347 fprintf(fp, "%13d %6.2f %s %s\n",
348 hptr->sruletab[j]->srrelaytab[h]->num,
349 100*(float)hptr->sruletab[j]->srrelaytab[h]->num/(float)hptr->sruletab[j]->num,
350 " ", hptr->sruletab[j]->srrelaytab[h]->name);
351 }
352 fprintf(fp, "\n");
353 }
354
355 }
356 }
357
358 if (!nflag) {
359 fprintf(fp, "\n\n%s%42s\n", "Inbound messages per day", "Outbound messages per day");
360 fprintf(fp, "-----------------------------------------------------------------------------\n");
361 fprintf(fp, "%s %-9s %9s %9s %10s %-9s %9s %9s\n",
362 " ", "Day", "Total", "Average",
363 " ", "Day", "Total", "Average");
364 fprintf(fp, "-----------------------------------------------------------------------------\n");
365 for (j = 0; j < 7; j++) {
366 if (hptr->idd[j])
367 fprintf(fp, "%s %-9s %9d %9.2f %10s %-9s %9d %9.2f\n",
368 " ", wdtab[j], hptr->idd[j], hptr->fidd[j],
369 " ", wdtab[j], hptr->odd[j], hptr->fodd[j]);
370 }
371
372 fprintf(fp, "\n\n%s%42s\n", "Inbound messages per hour", "Outbound messages per hour");
373 fprintf(fp, "-----------------------------------------------------------------------------\n");
374 fprintf(fp, "%s %-9s %9s %9s %10s %-9s %9s %9s\n",
375 " ", "Hour", "Total", "Average",
376 " ", "Hour", "Total", "Average");
377 fprintf(fp, "-----------------------------------------------------------------------------\n");
378
379 for (j = 0; j < 24; j++) {
380 if (hptr->ihh[j]) {
381 fprintf(fp, "%s %-9s %9d %9.2f %10s %-9s %9d %9.2f\n",
382 " ", hrtab[j], hptr->ihh[j], hptr->fihh[j],
383 " ", hrtab[j], hptr->ohh[j], hptr->fohh[j]);
384 }
385 }
386
387 }
388 }
389 fprintf(fp, "\n\n-----------------------------------------------------------------------------\n");
390 if (ftchar)
391 fprintf(fp, "%s\n", ftchar);
392 else
393 fprintf(fp, "Copyright (c) 2000 - 2003 Jarkko Turkulainen."
394 " All rights reserved.\n");
395 }
396