1 /* $Id$ */
2
3 /***************************************************************************
4 * *
5 * AreaStat *
6 * Copyleft (c) 2004-2010 by The Husky project *
7 * Homepage: https://github.com/huskyproject/areastat/wiki *
8 * *
9 * EchoStat Source, Version 1.06 *
10 * Copyright (c) 2000 by Dmitry Rusov. (2:5090/94, rusov94@mail.ru) *
11 * All rights reserved. *
12 * *
13 ***************************************************************************/
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <time.h>
19
20 #include <huskylib/huskylib.h>
21 //#include <smapi/typedefs.h>
22 //#include <smapi/progprot.h>
23 #include <smapi/msgapi.h>
24
25 #include "areastat.h"
26 #include "version.h"
27
28 #define BUFSIZE 4096
29 #define nfree(a) { if (a != NULL) { free(a); a = NULL; } }
30 #define ISDIGIT(ch) ((ch) >= '0' && (ch) <= '9')
31 #define ISLWSP(ch) ((ch) == ' ' || (ch) == '\t')
32
33 #define secs_in_day 86400
34
35 typedef struct area {
36 char *name;
37 char *path;
38 char *out_file;
39 int type;
40 } s_area, *ps_area;
41
42 typedef struct config {
43
44 unsigned long by_name;
45 unsigned long by_from;
46 unsigned long by_to;
47 unsigned long by_from_to;
48 unsigned long by_total;
49 unsigned long by_size;
50 unsigned long by_qpercent;
51 unsigned long by_subj;
52 unsigned long by_date;
53 unsigned long by_wday;
54 unsigned long by_time;
55 unsigned long days_of_stat;
56 unsigned long areas_count;
57 unsigned long pkt_size;
58 unsigned char make_pkt;
59 hs_addr pkt_orig_addr;
60 hs_addr pkt_dest_addr;
61 char pkt_password[8];
62 char *pkt_from;
63 char *pkt_to;
64 char *pkt_subj;
65 char *pkt_origin;
66 char *pkt_inbound;
67 char *pkt_tearline;
68 ps_area areas;
69
70 } s_config, *ps_config;
71
72 ps_config main_config;
73
74 typedef struct unsorted_item {
75 char *name;
76 unsigned long from;
77 unsigned long to;
78 } s_unsorted_item, *ps_unsorted_item;
79
80 typedef struct named_item {
81 char *name;
82 unsigned long count;
83 } s_named_item, *ps_named_item;
84
85 typedef struct date_item {
86 time_t date;
87 struct tm tm_date;
88 unsigned long count;
89 } s_date_item, *ps_date_item;
90
91 typedef struct time_item {
92 unsigned char hour;
93 unsigned long count;
94 } s_time_item, *ps_time_item;
95
96 typedef struct size_item {
97 char *name;
98 unsigned long size;
99 unsigned long qsize;
100 float qpercent;
101 } s_size_item, *ps_size_item;
102
103 ps_unsorted_item global_data = NULL;
104 unsigned long gd_count = 0;
105
106 ps_named_item from_data = NULL;
107 unsigned long fd_count = 0;
108
109 ps_named_item to_data = NULL;
110 unsigned long td_count = 0;
111
112 ps_named_item from_to_data = NULL;
113 unsigned long ftd_count = 0;
114
115 ps_named_item total_data = NULL;
116 unsigned long ttd_count = 0;
117
118 ps_named_item subj_data = NULL;
119 unsigned long sd_count = 0;
120
121 ps_date_item date_data = NULL;
122 unsigned long dd_count = 0;
123
124 ps_time_item time_data = NULL;
125 unsigned long tttd_count = 0;
126
127 ps_size_item size_data = NULL;
128 unsigned long szd_count = 0;
129
130 time_t global_msgid;
131 unsigned long days = 0;
132 unsigned long messages = 0;
133 float msgs_in_day = 0;
134 FILE * current_std;
135 FILE *out_pkt;
136 char *versionStr;
137 unsigned int isecs;
138
139 static int aDaysFromJan1st[13] = {
140 0, // Jan
141 31, // Feb
142 31+28, // Mar
143 31+28+31, // Apr
144 31+28+31+30, // May
145 31+28+31+30+31, // Jun
146 31+28+31+30+31+30, // Jul
147 31+28+31+30+31+30+31, // Aug
148 31+28+31+30+31+30+31+31, // Sep
149 31+28+31+30+31+30+31+31+30, // Oct
150 31+28+31+30+31+30+31+31+30+31, // Nov
151 31+28+31+30+31+30+31+31+30+31+30, // Dec
152 31+28+31+30+31+30+31+31+30+31+30+31 // Jan
153 };
154
155 static int days_in_months[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
156
name_comparer(const void * str1,const void * str2)157 int name_comparer(const void *str1, const void *str2)
158 {
159 return strcmp(((ps_unsorted_item)str1)->name,((ps_unsorted_item)str2)->name);
160 }
161
ft_comparer(const void * str1,const void * str2)162 int ft_comparer(const void *str1, const void *str2)
163 {
164 return strcmp(((ps_named_item)str1)->name,((ps_named_item)str2)->name);
165 }
166
ftc_comparer(const void * count1,const void * count2)167 int ftc_comparer(const void *count1, const void *count2)
168 {
169 if (((ps_named_item) count1) -> count > ((ps_named_item) count2) -> count) return -1;
170 if (((ps_named_item) count1) -> count == ((ps_named_item) count2) -> count) return 0;
171 return 1;
172 }
173
size_comparer(const void * size1,const void * size2)174 int size_comparer(const void *size1, const void *size2)
175 {
176 if (((ps_size_item) size1) -> size > ((ps_size_item) size2) -> size) return -1;
177 if (((ps_size_item) size1) -> size == ((ps_size_item) size2) -> size) return 0;
178 return 1;
179 }
180
qp_comparer(const void * qp1,const void * qp2)181 int qp_comparer(const void *qp1, const void *qp2)
182 {
183 if (((ps_size_item) qp1) -> qpercent > ((ps_size_item) qp2) -> qpercent) return -1;
184 if (((ps_size_item) qp1) -> qpercent == ((ps_size_item) qp2) -> qpercent) return 0;
185 return 1;
186 }
187
date_comparer(const void * dt1,const void * dt2)188 int date_comparer(const void *dt1, const void *dt2)
189 {
190 if (((ps_date_item) dt1) -> date < ((ps_date_item) dt2) -> date) return -1;
191 if (((ps_date_item) dt1) -> date == ((ps_date_item) dt2) -> date) return 0;
192 return 1;
193 }
194
do_sort_gap(unsigned long count,ps_named_item arr)195 void do_sort_gap(unsigned long count, ps_named_item arr)
196 {
197 unsigned long i=0,j=0;
198 while (j < count)
199 {
200 while (i < count)
201 {
202 i++;
203 if (i >= count && arr[i-1].count == arr[j].count)
204 {
205 qsort (&arr[j], i-j, sizeof(s_named_item), ft_comparer);
206 break;
207 }
208 if (arr[i].count != arr[j].count)
209 {
210 qsort (&arr[j], i-j, sizeof(s_named_item), ft_comparer);
211 break;
212 }
213 }
214 j = i;
215 }
216 }
217
218 /* Next 4 routines was taken from Pete Kvitek's FMA */
219
DoHasAddrChar(char * pch,char ch)220 int DoHasAddrChar(char * pch, char ch)
221 {
222 while (*pch && !ISLWSP(*pch))
223 if (*pch == ch) return 1;
224 else pch++;
225 return 0;
226 }
227
DoIsAddrChar(char ch)228 int DoIsAddrChar(char ch)
229 {
230 return (ch && strchr("0123456789:/.", ch));
231 }
232
ScanNetAddr(hs_addr * pnetAddr,char * psz)233 char * ScanNetAddr(hs_addr * pnetAddr, char * psz)
234 {
235 char * pch, * pchEnd;
236
237 for (pch = psz; ISLWSP(*pch); pch++);
238 pchEnd = pch;
239
240 if (DoIsAddrChar(*pch) && DoHasAddrChar(pch, ':'))
241 {
242 while (ISDIGIT(*pchEnd)) pchEnd++;
243 if (*pchEnd != ':' || pch == pchEnd) return NULL;
244 pnetAddr->zone = (unsigned short)atoi(pch);
245 pch = ++pchEnd;
246 if (!ISDIGIT(*pch) || !DoHasAddrChar(pch, '/')) return NULL;
247 }
248
249 if (DoIsAddrChar(*pch) && DoHasAddrChar(pch, '/'))
250 {
251 while (ISDIGIT(*pchEnd)) pchEnd++;
252 if (*pchEnd != '/' || pch == pchEnd) return NULL;
253 pnetAddr->net = (unsigned short)atoi(pch);
254 pch = ++pchEnd;
255 if (!ISDIGIT(*pch)) return NULL;
256 }
257
258 if (DoIsAddrChar(*pch) && *pch != '.')
259 {
260 while (ISDIGIT(*pchEnd)) pchEnd++;
261 pnetAddr->node = (unsigned short)atoi(pch);
262 pch = pchEnd;
263 }
264
265 if (*pch != '.') {
266 pnetAddr->point = 0;
267 } else {
268 for (pchEnd = ++pch; ISDIGIT(*pchEnd); pchEnd++);
269 pnetAddr->point = (unsigned short)atoi(pch);
270 pch = pchEnd;
271 }
272
273 return (pnetAddr->zone && pnetAddr->net) ? pch : NULL;
274
275 }
276
get_time_from_stamp(struct _stamp mtime)277 unsigned long get_time_from_stamp (struct _stamp mtime)
278 {
279 unsigned long hour, min, sec;
280 unsigned long day, mon, year;
281 unsigned long nDaysSince1970;
282 unsigned long nYearsSince1970;
283
284 hour = mtime.time.hh;
285 min = mtime.time.mm;
286 sec = mtime.time.ss * 2;
287 day = mtime.date.da;
288 mon = mtime.date.mo;
289 year = mtime.date.yr + 80; // Years since 1900
290
291 nYearsSince1970 = year - 70;
292
293 nDaysSince1970 = nYearsSince1970 * 365 + ((nYearsSince1970 + 1) / 4);
294
295 nDaysSince1970 += aDaysFromJan1st[mon - 1] + (day - 1);
296
297 if ((year & 3) == 0 && mon > 2) nDaysSince1970++;
298
299 return (((unsigned long) nDaysSince1970 * (24L * 60L * 60L))
300 + ((unsigned long) hour * (60L * 60L))
301 + ((unsigned long) min * 60L)
302 + (unsigned long) sec);
303
304 }
305
reading_base(unsigned long ii)306 int reading_base(unsigned long ii)
307 {
308 XMSG msg;
309 HAREA in_area;
310 HMSG in_msg;
311 void *ptr;
312 char buffer[BUFSIZE+1], *dummy, *c;
313 dword offset, msgn, qsize, textlen;
314 long got;
315 unsigned long i;
316 word t1=MSGTYPE_NOTH;
317 long nf, nt, qpos;
318 struct _minf mi;
319 time_t atime = time(NULL);
320 time_t mtime = 0, period = 0;
321 struct tm tmp_tm;
322
323 gd_count = fd_count = td_count = ftd_count = ttd_count =
324 sd_count = dd_count = szd_count = tttd_count = 0;
325 days = 0; messages = 0; msgs_in_day = 0;
326
327
328 fprintf(stderr,"Scanning area %s, %s...\n",
329 main_config->areas[ii].name,main_config->areas[ii].path);
330
331 if (main_config->areas[ii].type == 1) t1 = MSGTYPE_SDM; else
332 if (main_config->areas[ii].type == 2) t1 = MSGTYPE_SQUISH; else
333 if (main_config->areas[ii].type == 3) t1 = MSGTYPE_JAM;
334
335 memset(&mi, '\0', sizeof mi);
336 mi.def_zone=2;
337
338 MsgOpenApi(&mi);
339
340 if ((in_area=MsgOpenArea((byte*)main_config->areas[ii].path, MSGAREA_NORMAL, t1))==NULL)
341 {
342 char *tl_str="unknown";
343 switch (t1)
344 {
345 case MSGTYPE_SDM: tl_str="Msg (OPUS)"; break;
346 case MSGTYPE_JAM: tl_str="Jam"; break;
347 case MSGTYPE_SQUISH: tl_str="Squish"; break;
348 }
349 fprintf(stderr,"Error opening area `%s' (type %s) for read!\n\n",
350 main_config->areas[ii].path, tl_str);
351 exit(1);
352 }
353
354 MsgLock(in_area);
355
356 for (msgn=1L; msgn <= MsgHighMsg(in_area); msgn++)
357 {
358 if ((msgn % 5)==0)
359 {
360 fprintf(stderr,"Scanning msg: %lu\r",msgn);
361 fflush(stdout);
362 }
363 if ((in_msg=MsgOpenMsg(in_area,MOPEN_READ,msgn))==NULL) continue;
364 ptr = in_msg;
365 MsgReadMsg(in_msg, &msg, 0L, 0L, NULL, 0, NULL);
366 qsize = 0;
367 textlen = MsgGetTextLen(in_msg);
368 for (offset=0L; offset < textlen;)
369 {
370 if ((textlen-offset) >= BUFSIZE)
371 got = MsgReadMsg(in_msg, NULL, offset, BUFSIZE, buffer, 0L, NULL);
372 else
373 got = MsgReadMsg(in_msg, NULL, offset, textlen-offset, buffer, 0L, NULL);
374
375 if (got == 0)
376 break; /* we read 0 bytes - the end of message */
377 offset += got;
378 // find a quote
379 c = strtok (buffer, "\n\r");
380 while (c != NULL)
381 {
382 c = strtok (NULL,"\n\r");
383 if (c != NULL)
384 {
385 for (qpos = 0; qpos<10 && *c; qpos++)
386 {
387 if (*c == '>')
388 {
389 qsize += strlen (c);
390 break;
391 }
392 c++;
393 }
394 }
395 }
396 if (got <= 0)
397 break;
398 } /* for */
399
400 in_msg = ptr;
401 MsgCloseMsg(in_msg);
402
403 mtime = get_time_from_stamp(msg.date_written);
404 period = atime - mtime;
405 if (!period || period > main_config->days_of_stat * secs_in_day) continue;
406 tmp_tm = *localtime (&mtime);
407 tmp_tm.tm_mon++;
408 messages++;
409
410 // by name
411 nf = 0; nt = 0;
412 for (i=0; i<gd_count; i++)
413 {
414 if (stricmp(global_data[i].name,msg.from) == 0)
415 {
416 global_data[i].from++;
417 nf = 1;
418 }
419 if (stricmp(global_data[i].name,msg.to) == 0)
420 {
421 global_data[i].to++;
422 nt = 1;
423 }
424 }
425
426 if (!nf)
427 {
428 gd_count++;
429 global_data = srealloc (global_data, gd_count * sizeof(s_unsorted_item));
430 global_data[gd_count-1].name = smalloc(strlen(msg.from)+1);
431 strcpy (global_data[gd_count-1].name,msg.from);
432 global_data[gd_count-1].from = 1;
433 global_data[gd_count-1].to = 0;
434 }
435
436
437 if (!nt)
438 {
439 gd_count++;
440 global_data = srealloc (global_data, gd_count * sizeof(s_unsorted_item));
441 global_data[gd_count-1].name = smalloc(strlen(msg.to)+1);
442 strcpy (global_data[gd_count-1].name,msg.to);
443 global_data[gd_count-1].from = 0;
444 global_data[gd_count-1].to = 1;
445 }
446 // by from
447 if (main_config->by_from)
448 {
449 nf = 0;
450 for (i = 0; i < fd_count; i++)
451 {
452 if (!stricmp(from_data[i].name,msg.from))
453 {
454 from_data[i].count++;
455 nf = 1;
456 }
457 }
458
459 if (!nf)
460 {
461 fd_count++;
462 from_data = srealloc (from_data,fd_count * sizeof(s_named_item));
463 from_data[fd_count-1].name = (char *) smalloc(strlen(msg.from)+1);
464 strcpy (from_data[fd_count-1].name,msg.from);
465 from_data[fd_count-1].count = 1;
466 }
467 }
468 // by to
469 if (main_config->by_to)
470 {
471 nf = 0;
472 for (i = 0; i < td_count; i++)
473 {
474 if (!stricmp(to_data[i].name,msg.to))
475 {
476 to_data[i].count++;
477 nf = 1;
478 }
479 }
480
481 if (!nf)
482 {
483 td_count++;
484 to_data = srealloc (to_data, td_count * sizeof(s_named_item));
485 to_data[td_count-1].name = (char *) smalloc(strlen(msg.to)+1);
486 strcpy (to_data[td_count-1].name,msg.to);
487 to_data[td_count-1].count = 1;
488 }
489 }
490 // by subj
491 if (main_config->by_subj)
492 {
493 nf = 0;
494 for (i = 0; i < sd_count; i++)
495 {
496 if (!stricmp(subj_data[i].name,msg.subj))
497 {
498 subj_data[i].count++;
499 nf = 1;
500 }
501 }
502
503 if (!nf)
504 {
505 sd_count++;
506 subj_data = srealloc (subj_data, sd_count * sizeof(s_named_item));
507 subj_data[sd_count-1].name = (char *) smalloc(strlen(msg.subj)+1);
508 strcpy (subj_data[sd_count-1].name,msg.subj);
509 subj_data[sd_count-1].count = 1;
510 }
511 }
512
513 // by date
514 nf = 0;
515 for (i = 0; i < dd_count; i++)
516 {
517 if (tmp_tm.tm_mday == date_data[i].tm_date.tm_mday &&
518 tmp_tm.tm_mon == date_data[i].tm_date.tm_mon &&
519 tmp_tm.tm_year == date_data[i].tm_date.tm_year)
520 {
521 date_data[i].count++;
522 nf = 1;
523 }
524 }
525
526 if (!nf)
527 {
528 dd_count++;
529 date_data = srealloc (date_data, dd_count * sizeof(s_date_item));
530 date_data[dd_count-1].date = mtime;
531 date_data[dd_count-1].tm_date = tmp_tm;
532 date_data[dd_count-1].count = 1;
533 }
534
535 // by time
536 if (main_config->by_time)
537 {
538 nf = 0;
539 for (i = 0; i < tttd_count; i++)
540 {
541 if (tmp_tm.tm_hour == time_data[i].hour)
542 {
543 time_data[i].count++;
544 nf = 1;
545 }
546 }
547
548 if (!nf)
549 {
550 tttd_count++;
551 time_data = srealloc (time_data, tttd_count * sizeof(s_time_item));
552 time_data[tttd_count-1].hour = (unsigned char)tmp_tm.tm_hour;
553 time_data[tttd_count-1].count = 1;
554 }
555 }
556
557 // by size
558 if (main_config->by_size)
559 {
560 nf = 0;
561 for (i = 0; i < szd_count; i++)
562 {
563 if (!stricmp(size_data[i].name,msg.from))
564 {
565 size_data[i].size += offset;
566 size_data[i].qsize += qsize;
567 nf = 1;
568 }
569 }
570
571 if (!nf)
572 {
573 szd_count++;
574 size_data = srealloc (size_data, szd_count * sizeof(s_size_item));
575 size_data[szd_count-1].name = (char *) smalloc(strlen(msg.from)+1);
576 strcpy (size_data[szd_count-1].name,msg.from);
577 size_data[szd_count-1].size = offset;
578 size_data[szd_count-1].qsize = qsize;
579 }
580 }
581
582 // by from -> to
583 if (main_config->by_from_to)
584 {
585
586 nf = 0;
587 dummy = (char *) smalloc (strlen(msg.from)+strlen(msg.to)+2);
588 strcpy (dummy,msg.from);
589 strcat (dummy,"");
590 strcat (dummy,msg.to);
591 for (i = 0; i < ftd_count; i++)
592 {
593 if (!stricmp(from_to_data[i].name,dummy))
594 {
595 from_to_data[i].count++;
596 nf = 1;
597 free(dummy);
598 }
599 }
600
601 if (!nf)
602 {
603 ftd_count++;
604 from_to_data = srealloc (from_to_data, ftd_count * sizeof(s_named_item));
605 from_to_data[ftd_count-1].name = dummy;
606 from_to_data[ftd_count-1].count = 1;
607 }
608 }
609
610 } /* for msgn */
611
612 qsort (date_data, dd_count, sizeof(s_date_item), date_comparer);
613
614 MsgCloseArea(in_area);
615 MsgCloseApi();
616
617 return 0;
618 }
619
free_all()620 int free_all()
621 {
622 unsigned long i;
623
624 for (i = 0; i<gd_count; i++)
625 {
626 free(global_data[i].name);
627 }
628
629 if (global_data) free (global_data);
630 return 0;
631 }
632
print_summary_statistics(unsigned long i)633 int print_summary_statistics(unsigned long i)
634 {
635 struct tm fd, ld;
636 time_t tt = time(NULL);
637
638 if (dd_count > 0)
639 {
640 fd = date_data[0].tm_date;
641 ld = date_data[dd_count-1].tm_date;
642 days = (unsigned long)((date_data[dd_count-1].date-date_data[0].date)/secs_in_day)+1;
643
644 } else {
645
646 fd = *localtime(&tt);
647 ld = *localtime(&tt);
648 }
649
650 if (!days) days = 1;
651 fprintf(current_std,"\n --- Summary\n\n");
652
653 fprintf(current_std," Area: %s\n",main_config->areas[i].name);
654 fprintf(current_std," Period: %s %02d %s %d - %s %02d %s %d\n",
655 weekday_ab[fd.tm_wday],fd.tm_mday,months_ab[fd.tm_mon-1],fd.tm_year+1900,
656 weekday_ab[ld.tm_wday],ld.tm_mday,months_ab[ld.tm_mon-1],ld.tm_year+1900);
657
658 fprintf(current_std," Messages: %lu\n",messages);
659 fprintf(current_std," Total users: %lu\n",gd_count);
660 fprintf(current_std," Active users: %lu\n",fd_count);
661 fprintf(current_std," Days: %lu\n",days);
662 fprintf(current_std," Msgs per day: %lu\n",(unsigned long)messages/days);
663
664 return 0;
665 }
666
print_statistics_by_name()667 int print_statistics_by_name()
668 {
669 unsigned long i,tot_from = 0, tot_to = 0, tot_tot = 0;
670
671 qsort (global_data, gd_count, sizeof(s_unsorted_item), name_comparer);
672
673 fprintf(current_std,"\n --- Sorted by Name\n");
674 fprintf(current_std,"����������������������������������������������������������������������Ŀ\n");
675 fprintf(current_std,"� No. � Name � From � To � Total �\n");
676 fprintf(current_std,"����������������������������������������������������������������������Ĵ\n");
677
678 for (i=0; i<gd_count; i++)
679 {
680 fprintf(current_std,"�%4lu.� %-41s�%6lu�%6lu�%7lu�\n",i+1,global_data[i].name,
681 global_data[i].from,global_data[i].to,global_data[i].from+global_data[i].to);
682 tot_from += global_data[i].from;
683 tot_to += global_data[i].to;
684
685 } /* for */
686
687 tot_tot = tot_from+tot_to;
688 fprintf(current_std,"����������������������������������������������������������������������Ĵ\n");
689 fprintf(current_std,"� � �%6lu�%6lu�%7lu�\n",tot_from,tot_to,tot_tot);
690 fprintf(current_std,"������������������������������������������������������������������������\n");
691
692 return 0;
693 }
694
print_statistics_by_from()695 int print_statistics_by_from()
696 {
697 unsigned long i;
698 char diag[80],name[32];
699
700 qsort (from_data, fd_count, sizeof(s_named_item), ftc_comparer);
701 do_sort_gap(fd_count,from_data);
702
703 fprintf(current_std,"\n --- Sorted by From. Top %lu\n",main_config->by_from);
704
705 fprintf(current_std,"����������������������������������������������������������������������������Ŀ\n");
706 fprintf(current_std,"� No. � Name � From � �\n");
707 fprintf(current_std,"����������������������������������������������������������������������������Ĵ\n");
708
709 for (i=0; i < fd_count; i++)
710 {
711 unsigned long j, k;
712
713 if (i >= main_config->by_from) break;
714
715 strcpy(diag,"\0");
716 k = (unsigned long)((from_data[i].count/(float)(from_data[0].count))*30);
717 if (k == 0) strcpy(diag,"�"); else
718 for (j = 0;j < k ;j++) strcat(diag,"�");
719 for (j=0; j<32; j++) name[j] = '\0';
720 strncpy(name,from_data[i].name,30);
721
722 fprintf(current_std,"�%4lu.� %-31s�%6lu�%-30s�\n",i+1,name,from_data[i].count,diag);
723
724 } /* for */
725
726 fprintf(current_std,"������������������������������������������������������������������������������\n");
727
728 return 0;
729 }
730
print_statistics_by_to()731 int print_statistics_by_to()
732 {
733 unsigned long i;
734 char diag[80],name[32];
735
736 qsort (to_data, td_count, sizeof(s_named_item), ftc_comparer);
737 do_sort_gap(td_count,to_data);
738
739 fprintf(current_std,"\n --- Sorted by To. Top %lu\n",main_config->by_to);
740 fprintf(current_std,"����������������������������������������������������������������������������Ŀ\n");
741 fprintf(current_std,"� No. � Name � To � �\n");
742 fprintf(current_std,"����������������������������������������������������������������������������Ĵ\n");
743
744 for (i=0; i < td_count; i++)
745 {
746 unsigned long j, k;
747
748 if (i >= main_config->by_to) break;
749
750 strcpy(diag,"\0");
751 k = (unsigned long)((to_data[i].count/(float)(to_data[0].count))*30);
752 if (k == 0) strcpy(diag,"�"); else
753 for (j = 0;j < k ;j++) strcat(diag,"�");
754 for (j=0; j<32; j++) name[j] = '\0';
755 strncpy(name,to_data[i].name,30);
756
757 fprintf(current_std,"�%4lu.� %-31s�%6lu�%-30s�\n",i+1,name,to_data[i].count,diag);
758
759 } /* for */
760
761 fprintf(current_std,"������������������������������������������������������������������������������\n");
762
763 return 0;
764 }
765
print_statistics_by_from_to()766 int print_statistics_by_from_to()
767 {
768 unsigned long i;
769 char diag[80],name1[32],name2[32];
770
771 qsort (from_to_data, ftd_count, sizeof(s_named_item), ftc_comparer);
772 do_sort_gap(ftd_count,from_to_data);
773
774 fprintf(current_std,"\n --- Sorted by From -> To. Top %lu\n",main_config->by_from_to);
775 fprintf(current_std,"����������������������������������������������������������������������������Ŀ\n");
776 fprintf(current_std,"� No. � From � To � Msgs � �\n");
777 fprintf(current_std,"����������������������������������������������������������������������������Ĵ\n");
778
779 for (i=0; i < ftd_count; i++)
780 {
781 unsigned long k, l, n;
782
783 if (i >= main_config->by_from_to) break;
784
785 strcpy(diag,"\0");
786 k = (unsigned long)((from_to_data[i].count/(float)(from_to_data[0].count))*16);
787 if (k == 0)
788 strcpy(diag,"�");
789 else
790 {
791 unsigned long j;
792
793 for (j = 0; j < k; j++)
794 strcat(diag,"�");
795 }
796
797 n = 0;
798
799 for (l=0; l<32; l++) name1[l] = '\0';
800 for (l=0; l<20; l++)
801 {
802 if (from_to_data[i].name[n] == '\0' || from_to_data[i].name[n] == '') break;
803 name1[l] = from_to_data[i].name[n];
804 n++;
805 }
806
807 name1[l] = '\0';
808
809 while(from_to_data[i].name[n] && from_to_data[i].name[n] != '') n++;
810
811 for (l=0; l<32; l++) name2[l] = '\0';
812 for (l=0; l<20; l++)
813 {
814 if (from_to_data[i].name[n] == '') n++;
815 if (!from_to_data[i].name[n]) break;
816 name2[l] = from_to_data[i].name[n];
817 n++;
818 }
819
820 name2[l] = '\0';
821
822 fprintf(current_std,"�%4lu.� %-21s� %-22s�%6lu�%-16s�\n",i+1,name1,name2,from_to_data[i].count,diag);
823
824 } /* for */
825
826 fprintf(current_std,"������������������������������������������������������������������������������\n");
827
828 return 0;
829 }
830
print_statistics_by_total()831 int print_statistics_by_total()
832 {
833 unsigned long i;
834 char diag[80],name[32];
835
836 for (i = 0; i < gd_count; i++)
837 {
838 ttd_count++;
839 total_data = srealloc (total_data, ttd_count * sizeof(s_named_item));
840 total_data[ttd_count-1].name = (char *) smalloc(strlen(global_data[i].name)+1);
841 strcpy (total_data[ttd_count-1].name,global_data[i].name);
842 total_data[ttd_count-1].count = global_data[i].from+global_data[i].to;
843 }
844
845 qsort (total_data, ttd_count, sizeof(s_named_item), ftc_comparer);
846 do_sort_gap(ttd_count,total_data);
847
848 fprintf(current_std,"\n --- Sorted by Total. Top %lu\n",main_config->by_total);
849 fprintf(current_std,"����������������������������������������������������������������������������Ŀ\n");
850 fprintf(current_std,"� No. � Name � Msgs � �\n");
851 fprintf(current_std,"����������������������������������������������������������������������������Ĵ\n");
852
853 for (i=0; i < ttd_count; i++)
854 {
855 unsigned long k, j;
856
857 if (i >= main_config->by_total) break;
858
859 strcpy(diag,"\0");
860 k = (unsigned long)((total_data[i].count/(float)(total_data[0].count))*30);
861 if (k == 0) strcpy(diag,"�"); else
862 for (j = 0;j < k ;j++) strcat(diag,"�");
863 for (j=0; j<32; j++) name[j] = '\0';
864 strncpy(name,total_data[i].name,30);
865
866 fprintf(current_std,"�%4lu.� %-31s�%6lu�%-30s�\n",i+1,name,total_data[i].count,diag);
867
868 } /* for */
869
870 fprintf(current_std,"������������������������������������������������������������������������������\n");
871
872 return 0;
873 }
874
print_statistics_by_size()875 int print_statistics_by_size()
876 {
877 unsigned long i,j;
878 char diag[80],name[32];
879
880 qsort (size_data, szd_count, sizeof(s_size_item), size_comparer);
881
882 fprintf(current_std,"\n --- Sorted by Size. Top %lu\n",main_config->by_size);
883 fprintf(current_std,"����������������������������������������������������������������������������Ŀ\n");
884 fprintf(current_std,"� No. � Name � Size � Quote � �\n");
885 fprintf(current_std,"����������������������������������������������������������������������������Ĵ\n");
886
887 for (i=0; i < szd_count; i++)
888 {
889 unsigned long k;
890
891 if (i >= main_config->by_size) break;
892
893 strcpy(diag,"\0");
894 k = (unsigned long)((size_data[i].size/(float)(size_data[0].size))*27);
895 if (k == 0) strcpy(diag,"�"); else
896 for (j = 0;j < k ;j++) strcat(diag,"�");
897 for (j=0; j<32; j++) name[j] = '\0';
898 strncpy(name,size_data[i].name,24);
899
900 fprintf(current_std,"�%4lu.� %-25s�%7lu�%7lu�%-27s�\n",i+1,name,size_data[i].size,size_data[i].qsize,diag);
901
902 } /* for */
903
904
905 fprintf(current_std,"������������������������������������������������������������������������������\n");
906
907 return 0;
908 }
909
print_statistics_by_qpercent()910 int print_statistics_by_qpercent()
911 {
912 unsigned long i;
913 char diag[80],name[32];
914
915 for (i = 0; i < szd_count; i++)
916 size_data[i].qpercent = ((float)size_data[i].qsize/size_data[i].size)*100;
917 qsort (size_data, szd_count, sizeof(s_size_item), qp_comparer);
918
919 fprintf(current_std,"\n --- Sorted by QPercent. Top %lu\n",main_config->by_qpercent);
920 fprintf(current_std,"����������������������������������������������������������������������������Ŀ\n");
921 fprintf(current_std,"� No. � Name � QPer � �\n");
922 fprintf(current_std,"����������������������������������������������������������������������������Ĵ\n");
923
924 for (i=0; i < szd_count; i++)
925 {
926 unsigned long j, k;
927
928 if (i >= main_config->by_qpercent) break;
929
930 strcpy(diag,"\0");
931 if (size_data[0].qpercent >0 )
932 k = (unsigned long)((size_data[i].qpercent/(float)(size_data[0].qpercent))*30);
933 else k = 0;
934 for (j = 0;j < k ;j++) strcat(diag,"�");
935 for (j=0; j<32; j++) name[j] = '\0';
936 strncpy(name,size_data[i].name,30);
937
938 fprintf(current_std,"�%4lu.� %-31s�%6.2lf�%-30s�\n",i+1,name,size_data[i].qpercent,diag);
939
940 } /* for */
941
942 fprintf(current_std,"������������������������������������������������������������������������������\n");
943
944 return 0;
945 }
946
print_statistics_by_subj()947 int print_statistics_by_subj()
948 {
949 unsigned long i;
950 char name[60];
951
952 qsort (subj_data, sd_count, sizeof(s_named_item), ftc_comparer);
953 do_sort_gap(sd_count,subj_data);
954
955 fprintf(current_std,"\n --- Sorted by Subj. Top %lu\n",main_config->by_subj);
956 fprintf(current_std,"����������������������������������������������������������������������Ŀ\n");
957 fprintf(current_std,"� No. � Subj � Msgs �\n");
958 fprintf(current_std,"����������������������������������������������������������������������Ĵ\n");
959
960 for (i=0; i < sd_count; i++)
961 {
962 unsigned long j, l;
963
964 if (i >= main_config->by_subj) break;
965
966 l = strlen(subj_data[i].name);
967
968 for (j = 0; j < 56; j++) name[j] = '\0';
969 for (j = 0; j < 55 && j < l; j++) name[j] = subj_data[i].name[j];
970
971 fprintf(current_std,"�%4lu.� %-56s�%6lu�\n",i+1,name,subj_data[i].count);
972
973 } /* for */
974
975 fprintf(current_std,"������������������������������������������������������������������������\n");
976
977 return 0;
978 }
979
print_statistics_by_date()980 int print_statistics_by_date()
981 {
982 unsigned long i, maxcount;
983 char diag[80];
984
985 fprintf(current_std,"\n --- Sorted by date\n\n");
986
987 maxcount = 0;
988 for (i = 0; i < dd_count; i++) if (date_data[i].count > maxcount)
989 maxcount = date_data[i].count;
990
991 for (i = 0; i < dd_count; i++)
992 {
993 unsigned long k;
994
995 strcpy(diag,"\0");
996 k = (unsigned long)((date_data[i].count/(float)(maxcount))*59);
997 if (k == 0)
998 strcpy(diag,"�");
999 else
1000 {
1001 unsigned long j;
1002
1003 for (j = 0; j < k; j++)
1004 strcat(diag,"�");
1005 }
1006
1007 fprintf(current_std," %02d-%02d-%04d %4lu �%-59s\n",date_data[i].tm_date.tm_mday,
1008 date_data[i].tm_date.tm_mon,date_data[i].tm_date.tm_year+1900,date_data[i].count,diag);
1009
1010 } /* for */
1011
1012 fprintf(current_std," ������������������������������������������������������������>\n");
1013
1014 return 0;
1015 }
1016
print_statistics_by_wdays()1017 int print_statistics_by_wdays()
1018 {
1019 unsigned long i, maxcount;
1020 unsigned long counts[7] = {0,0,0,0,0,0,0};
1021 char diag[80];
1022
1023 fprintf(current_std,"\n --- Sorted by WeekDay\n\n");
1024
1025 for (i = 0; i < dd_count; i++)
1026 {
1027 switch (date_data[i].tm_date.tm_wday)
1028 {
1029 case 0: {counts[0] += date_data[i].count; break;}
1030 case 1: {counts[1] += date_data[i].count; break;}
1031 case 2: {counts[2] += date_data[i].count; break;}
1032 case 3: {counts[3] += date_data[i].count; break;}
1033 case 4: {counts[4] += date_data[i].count; break;}
1034 case 5: {counts[5] += date_data[i].count; break;}
1035 case 6: {counts[6] += date_data[i].count; break;}
1036 }
1037 }
1038
1039 maxcount = 0;
1040 for (i = 0; i <= 6; i++) if (counts[i] > maxcount) maxcount = counts[i];
1041
1042 for (i = 0; i <= 6; i++)
1043 {
1044 unsigned long j, k;
1045
1046 strcpy(diag,"\0");
1047 k = (unsigned long)((counts[i]/(float)(maxcount))*60);
1048 for (j = 0;j < k ;j++) strcat(diag,"�");
1049
1050 fprintf(current_std," %s %6lu�%-60s\n",weekday_ab[i],counts[i],diag);
1051
1052 }
1053
1054 fprintf(current_std," �������������������������������������������������������������>\n");
1055 return 0;
1056 }
1057
print_statistics_by_time()1058 int print_statistics_by_time()
1059 {
1060 unsigned long i, j, maxcount;
1061 unsigned long counts[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1062 char diag[80], str1[] = "� ", str2[] = " ";
1063
1064 fprintf(current_std,"\n --- Sorted by time\n\n");
1065
1066 for (i = 0; i < tttd_count; i++)
1067 {
1068 switch (time_data[i].hour)
1069 {
1070 case 0: {counts[0] += time_data[i].count; break;}
1071 case 1: {counts[1] += time_data[i].count; break;}
1072 case 2: {counts[2] += time_data[i].count; break;}
1073 case 3: {counts[3] += time_data[i].count; break;}
1074 case 4: {counts[4] += time_data[i].count; break;}
1075 case 5: {counts[5] += time_data[i].count; break;}
1076 case 6: {counts[6] += time_data[i].count; break;}
1077 case 7: {counts[7] += time_data[i].count; break;}
1078 case 8: {counts[8] += time_data[i].count; break;}
1079 case 9: {counts[9] += time_data[i].count; break;}
1080 case 10: {counts[10] += time_data[i].count; break;}
1081 case 11: {counts[11] += time_data[i].count; break;}
1082 case 12: {counts[12] += time_data[i].count; break;}
1083 case 13: {counts[13] += time_data[i].count; break;}
1084 case 14: {counts[14] += time_data[i].count; break;}
1085 case 15: {counts[15] += time_data[i].count; break;}
1086 case 16: {counts[16] += time_data[i].count; break;}
1087 case 17: {counts[17] += time_data[i].count; break;}
1088 case 18: {counts[18] += time_data[i].count; break;}
1089 case 19: {counts[19] += time_data[i].count; break;}
1090 case 20: {counts[20] += time_data[i].count; break;}
1091 case 21: {counts[21] += time_data[i].count; break;}
1092 case 22: {counts[22] += time_data[i].count; break;}
1093 case 23: {counts[23] += time_data[i].count; break;}
1094 }
1095 }
1096
1097 maxcount = 0;
1098 for (i = 0; i <= 23; i++) if (counts[i] > maxcount) maxcount = counts[i];
1099
1100 for (j = 20; j > 0; j--)
1101 {
1102 strcpy(diag,"\0");
1103
1104 for (i = 0; i <= 23; i++)
1105 {
1106 unsigned long k;
1107
1108 k = (unsigned long)((counts[i]/(float)(maxcount))*20);
1109
1110 if (k >= j) strcat(diag,"�� "); else
1111 if ((j % 5) == 0) strcat (diag,str1); else strcat (diag,str2);
1112
1113 }
1114
1115 if (j == 20) fprintf(current_std,"100%%�%s\n",diag); else
1116 if (j == 15) fprintf(current_std," 75%%�%s\n",diag); else
1117 if (j == 10) fprintf(current_std," 50%%�%s\n",diag); else
1118 if (j == 5) fprintf(current_std," 25%%�%s\n",diag); else
1119 fprintf(current_std," �%s\n",diag);
1120
1121 }
1122
1123 fprintf(current_std," 0%%�������������������������������������������������������������������������>\n");
1124 fprintf(current_std," 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 \n");
1125
1126 return 0;
1127 }
1128
print_err(char * s,unsigned long i)1129 void print_err(char *s, unsigned long i)
1130 {
1131 printf("Error in config (line %lu): \"%s\"\n\n",i,s);
1132 exit(2);
1133 }
1134
read_cfg(char * cfg_name)1135 s_config *read_cfg(char *cfg_name)
1136 {
1137
1138 FILE *fcfg;
1139 s_config *config;
1140 char *s0,*s1,*s2,*s3,*s4,*buff;
1141 char line[BUFSIZE+1];
1142 time_t at = time (NULL);
1143 struct tm t;
1144 unsigned long i = 0, j = 0, n, wd, md;
1145
1146 if ((fcfg = fopen(cfg_name,"rb")) == NULL)
1147 {
1148 fprintf(stderr,"Cannot open file: \"%s\"\n\n",cfg_name);
1149 exit(2);
1150 }
1151
1152 t = *localtime (&at);
1153
1154 wd = t.tm_wday; if (wd == 0) wd = 7;
1155
1156 config = (s_config *) smalloc(sizeof(s_config));
1157
1158 memset(config, 0, sizeof(s_config));
1159
1160 config->by_from = config->by_to = config->by_from_to = config->by_total =
1161 config->by_size = config->by_qpercent = config->by_subj = config->by_name =
1162 config->by_wday = config->by_date = config->by_time = 0;
1163
1164 config->days_of_stat = 365;
1165
1166 config->areas_count = 0;
1167
1168 config->pkt_size = 10240;
1169 config->make_pkt = 0;
1170 config->pkt_orig_addr.zone = 0;
1171 config->pkt_orig_addr.net = 0;
1172 config->pkt_orig_addr.node = 0;
1173 config->pkt_orig_addr.point = 0;
1174 config->pkt_dest_addr.zone = 0;
1175 config->pkt_dest_addr.net = 0;
1176 config->pkt_dest_addr.node = 0;
1177 config->pkt_dest_addr.point = 0;
1178 for (j = 0; j<8; j++) config->pkt_password[j] = '\0';
1179 config->pkt_from = NULL;
1180 config->pkt_to = NULL;
1181 config->pkt_subj = NULL;
1182 config->pkt_origin = NULL;
1183 config->pkt_inbound = NULL;
1184 config->pkt_tearline = NULL;
1185
1186 buff = malloc(BUFSIZE+1);
1187
1188 while (fgets(line,BUFSIZE,fcfg))
1189 {
1190 i++;
1191
1192 if (line == NULL) continue;
1193
1194 j = strlen (line) - 1;
1195 while(j && (line[j] == '\r' || line[j] == '\n')) {line[j]='\0'; j--;}
1196
1197 strcpy(buff,line);
1198
1199 s0 = strtok(line,"\t \r\n");
1200 if (s0 == NULL) continue;
1201 if (*s0 == ';' || *s0 == '#') continue;
1202
1203 if (!stricmp(s0,"By_Name"))
1204 {
1205 config->by_name = 1;
1206 continue;
1207 }
1208
1209 if (!stricmp(s0,"By_Date"))
1210 {
1211 config->by_date = 1;
1212 continue;
1213 }
1214
1215 if (!stricmp(s0,"By_WDay"))
1216 {
1217 config->by_wday = 1;
1218 continue;
1219 }
1220
1221 if (!stricmp(s0,"By_Time"))
1222 {
1223 config->by_time = 1;
1224 continue;
1225 }
1226
1227 if (!stricmp(s0,"By_From"))
1228 {
1229 s1 = strtok(NULL,"\t \r\n");
1230 if (s1 == NULL) print_err(buff,i);
1231 config->by_from = atoi(s1);
1232 continue;
1233 }
1234
1235 if (!stricmp(s0,"By_To"))
1236 {
1237 s1 = strtok(NULL,"\t \r\n");
1238 if (s1 == NULL) print_err(buff,i);
1239 config->by_to = atoi(s1);
1240 continue;
1241 }
1242
1243 if (!stricmp(s0,"By_FromTo"))
1244 {
1245 s1 = strtok(NULL,"\t \r\n");
1246 if (s1 == NULL) print_err(buff,i);
1247 config->by_from_to = atoi(s1);
1248 continue;
1249 }
1250
1251 if (!stricmp(s0,"By_Total"))
1252 {
1253 s1 = strtok(NULL,"\t \r\n");
1254 if (s1 == NULL) print_err(buff,i);
1255 config->by_total = atoi(s1);
1256 continue;
1257 }
1258
1259 if (!stricmp(s0,"By_Size"))
1260 {
1261 s1 = strtok(NULL,"\t \r\n");
1262 if (s1 == NULL) print_err(buff,i);
1263 config->by_size = atoi(s1);
1264 continue;
1265 }
1266
1267 if (!stricmp(s0,"By_QPercent"))
1268 {
1269 s1 = strtok(NULL,"\t \r\n");
1270 if (s1 == NULL) print_err(buff,i);
1271 config->by_qpercent = atoi(s1);
1272 continue;
1273 }
1274
1275 if (!stricmp(s0,"Subj_By_Total"))
1276 {
1277 s1 = strtok(NULL,"\t \r\n");
1278 if (s1 == NULL) print_err(buff,i);
1279 config->by_subj = atoi(s1);
1280 continue;
1281 }
1282
1283 if (!stricmp(s0,"Stat_Period"))
1284 {
1285 s1 = strtok(NULL,"\t \r\n");
1286 if (s1 == NULL) print_err(buff,i);
1287 if (*s1 == 'm')
1288 {
1289 s1++;
1290 config->days_of_stat = atoi(s1);
1291 if (!config->days_of_stat) print_err(buff,i);
1292 if (config->days_of_stat > 1000) print_err(buff,i);
1293
1294 md = 0;
1295 n = t.tm_mon-1;
1296
1297 for (j=1; j<config->days_of_stat; j++)
1298 {
1299 md += days_in_months[n];
1300 if (!n) n = 11; else n--;
1301 }
1302
1303 config->days_of_stat = md + (t.tm_mday - 1);
1304
1305 } else
1306
1307 if (*s1 == 'w')
1308 {
1309 s1++;
1310 config->days_of_stat = atoi(s1);
1311 if (!config->days_of_stat) print_err(buff,i);
1312 if (config->days_of_stat > 1000) print_err(buff,i);
1313 config->days_of_stat = ( (config->days_of_stat-1) * 7 ) + (wd - 1);
1314 } else
1315
1316 {
1317 config->days_of_stat = atoi(s1);
1318 if (!config->days_of_stat) print_err(buff,i);
1319 if (config->days_of_stat > 32768) print_err(buff,i);
1320
1321 }
1322
1323 continue;
1324 }
1325
1326 if (!stricmp(s0,"Area"))
1327 {
1328 config->areas = srealloc(config->areas, sizeof(s_area)*(config->areas_count+1));
1329
1330 s1 = strtok(NULL,"\t \r\n");
1331 if (s1 == NULL) print_err(buff,i);
1332
1333 config->areas[config->areas_count].name = (char *) smalloc(strlen(s1)+1);
1334 strcpy(config->areas[config->areas_count].name,s1);
1335
1336 s2 = strtok(NULL,"\t \r\n");
1337 if (s2 == NULL) print_err(buff,i);
1338
1339 config->areas[config->areas_count].type = 0;
1340
1341 if (!stricmp(s2,"msg")) config->areas[config->areas_count].type = 1; else
1342 if (!stricmp(s2,"squish")) config->areas[config->areas_count].type = 2; else
1343 if (!stricmp(s2,"jam")) config->areas[config->areas_count].type = 3;
1344
1345 if (!config->areas[config->areas_count].type) print_err(buff,i);
1346
1347
1348 s3 = strtok(NULL,"\t \r\n");
1349 if (s3 == NULL) print_err(buff,i);
1350
1351 config->areas[config->areas_count].path = (char *) smalloc(strlen(s3)+1);
1352 strcpy(config->areas[config->areas_count].path,s3);
1353
1354 s4 = strtok(NULL,"\t \r\n");
1355 if (s4 == NULL) print_err(buff,i);
1356
1357 config->areas[config->areas_count].out_file = (char *) smalloc(strlen(s4)+1);
1358 strcpy(config->areas[config->areas_count].out_file,s4);
1359
1360 config->areas_count++;
1361
1362 continue;
1363 }
1364
1365 if (!stricmp(s0,"Subj_By_Total"))
1366 {
1367 s1 = strtok(NULL,"\t \r\n");
1368 if (s1 == NULL) print_err(buff,i);
1369 config->by_subj = atoi(s1);
1370 continue;
1371 }
1372
1373 if (!stricmp(s0,"Make_Pkt"))
1374 {
1375 config->make_pkt = 1;
1376 continue;
1377 }
1378
1379 if (!stricmp(s0,"Pkt_Size"))
1380 {
1381 s1 = strtok(NULL,"\t \r\n");
1382 if (s1 == NULL) print_err(buff,i);
1383 config->pkt_size = atoi(s1);
1384 if (!config->pkt_size) print_err(buff,i);
1385 if (config->pkt_size > 65536) print_err(buff,i);
1386 continue;
1387 }
1388
1389 if (!stricmp(s0,"Pkt_Inbound"))
1390 {
1391 s1 = strtok(NULL,"\t \r\n");
1392 if (s1 == NULL) print_err(buff,i);
1393 config->pkt_inbound = smalloc(strlen(s1)+2);
1394 strcpy(config->pkt_inbound,s1);
1395 if (config->pkt_inbound[strlen(config->pkt_inbound)-1] != '\\')
1396 strcat(config->pkt_inbound,"\\");
1397 continue;
1398 }
1399
1400 if (!stricmp(s0,"Pkt_FromName"))
1401 {
1402 s1 = strtok(NULL,"\0");
1403 if (s1 == NULL) print_err(buff,i);
1404 while(*s1 && (*s1 == ' ' || *s1 == '\t')) s1++;
1405 j = strlen(s1)-1;
1406 while(j && (s1[j] == ' ' || s1[j] == '\t'))
1407 {
1408 s1[j] = '\0'; j--;
1409 }
1410 if (!*s1) print_err(buff,i);
1411
1412 config->pkt_from = smalloc(strlen(s1)+1);
1413 strcpy(config->pkt_from,s1);
1414
1415 continue;
1416 }
1417
1418 if (!stricmp(s0,"Pkt_ToName"))
1419 {
1420 s1 = strtok(NULL,"\0");
1421 if (s1 == NULL) print_err(buff,i);
1422 while(*s1 && (*s1 == ' ' || *s1 == '\t')) s1++;
1423 j = strlen(s1)-1;
1424 while(j && (s1[j] == ' ' || s1[j] == '\t'))
1425 {
1426 s1[j] = '\0'; j--;
1427 }
1428 if (!*s1) print_err(buff,i);
1429
1430 config->pkt_to = smalloc(strlen(s1)+1);
1431 strcpy(config->pkt_to,s1);
1432
1433 continue;
1434 }
1435
1436 if (!stricmp(s0,"Pkt_Subj"))
1437 {
1438 s1 = strtok(NULL,"\0");
1439 if (s1 == NULL) print_err(buff,i);
1440 while(*s1 && (*s1 == ' ' || *s1 == '\t')) s1++;
1441 j = strlen(s1)-1;
1442 while(j && (s1[j] == ' ' || s1[j] == '\t'))
1443 {
1444 s1[j] = '\0'; j--;
1445 }
1446 if (!*s1) print_err(buff,i);
1447
1448 config->pkt_subj = smalloc(strlen(s1)+1);
1449 strcpy(config->pkt_subj,s1);
1450
1451 continue;
1452 }
1453
1454 if (!stricmp(s0,"Pkt_Tearline"))
1455 {
1456 s1 = strtok(NULL,"\0");
1457 if (s1 == NULL) print_err(buff,i);
1458 while(*s1 && (*s1 == ' ' || *s1 == '\t')) s1++;
1459 j = strlen(s1)-1;
1460 while(j && (s1[j] == ' ' || s1[j] == '\t'))
1461 {
1462 s1[j] = '\0'; j--;
1463 }
1464 if (!*s1) print_err(buff,i);
1465
1466 config->pkt_tearline = smalloc(strlen(s1)+1);
1467 strcpy(config->pkt_tearline,s1);
1468
1469 continue;
1470 }
1471
1472 if (!stricmp(s0,"Pkt_Origin"))
1473 {
1474 s1 = strtok(NULL,"\0");
1475 if (s1 == NULL) print_err(buff,i);
1476 while(*s1 && (*s1 == ' ' || *s1 == '\t')) s1++;
1477 j = strlen(s1)-1;
1478 while(j && (s1[j] == ' ' || s1[j] == '\t'))
1479 {
1480 s1[j] = '\0'; j--;
1481 }
1482 if (!*s1) print_err(buff,i);
1483
1484 config->pkt_origin = smalloc(strlen(s1)+1);
1485 strcpy(config->pkt_origin,s1);
1486
1487 continue;
1488 }
1489
1490 if (!stricmp(s0,"Pkt_Password"))
1491 {
1492 s1 = strtok(NULL,"\0");
1493 if (s1 == NULL) print_err(buff,i);
1494 while(*s1 && (*s1 == ' ' || *s1 == '\t')) s1++;
1495 j = strlen(s1)-1;
1496 while(j && (s1[j] == ' ' || s1[j] == '\t'))
1497 {
1498 s1[j] = '\0'; j--;
1499 }
1500 if (!*s1) print_err(buff,i);
1501
1502 strncpy(config->pkt_password,s1,8);
1503
1504 continue;
1505 }
1506
1507 if (!stricmp(s0,"Pkt_OrigAddress"))
1508 {
1509 s1 = strtok(NULL,"\t \r\n");
1510 if (s1 == NULL) print_err(buff,i);
1511
1512 if (!ScanNetAddr(&config->pkt_orig_addr, s1)) print_err(buff,i);
1513
1514 continue;
1515 }
1516
1517 if (!stricmp(s0,"Pkt_DestAddress"))
1518 {
1519 s1 = strtok(NULL,"\t \r\n");
1520 if (s1 == NULL) print_err(buff,i);
1521
1522 if (!ScanNetAddr(&config->pkt_dest_addr, s1)) print_err(buff,i);
1523
1524 continue;
1525 }
1526
1527 fprintf(stderr,"Unknown keyword: \"%s\"\n",s0);
1528
1529 } /* while */
1530
1531 fclose(fcfg);
1532
1533 free(buff);
1534
1535 return config;
1536
1537 }
1538
free_items()1539 void free_items()
1540 {
1541 unsigned long i;
1542
1543 for (i = 0; i < gd_count; i++) nfree(global_data[i].name);
1544 nfree(global_data);
1545
1546 if (main_config->by_from)
1547 {
1548 for (i = 0; i < fd_count; i++) nfree(from_data[i].name);
1549 nfree (from_data);
1550 }
1551
1552 if (main_config->by_to)
1553 {
1554 for (i = 0; i < td_count; i++) nfree(to_data[i].name);
1555 nfree (to_data);
1556 }
1557
1558 if (main_config->by_from_to)
1559 {
1560 for (i = 0; i < ftd_count; i++) nfree(from_to_data[i].name);
1561 nfree (from_to_data);
1562 }
1563
1564 if (main_config->by_subj)
1565 {
1566 for (i = 0; i < sd_count; i++) nfree(subj_data[i].name);
1567 nfree (subj_data);
1568 }
1569
1570 nfree(date_data);
1571
1572 if (main_config->by_time) nfree(time_data);
1573
1574 if (main_config->by_size)
1575 {
1576 for (i = 0; i < szd_count; i++) nfree(size_data[i].name);
1577 nfree (size_data);
1578 }
1579
1580 }
1581
free_config()1582 void free_config()
1583 {
1584 unsigned long i;
1585
1586 nfree(main_config->pkt_from);
1587 nfree(main_config->pkt_to);
1588 nfree(main_config->pkt_subj);
1589 nfree(main_config->pkt_origin);
1590 nfree(main_config->pkt_inbound);
1591 nfree(main_config->pkt_tearline);
1592
1593 for (i = 0; i < main_config->areas_count; i++)
1594 {
1595 nfree(main_config->areas[i].name);
1596 nfree(main_config->areas[i].path);
1597 nfree(main_config->areas[i].out_file);
1598 }
1599
1600 nfree(main_config->areas);
1601 nfree(main_config);
1602
1603 }
1604
print_write_err()1605 void print_write_err()
1606 {
1607 fprintf(stderr,"Cannot write to pkt\n\n");
1608 exit(2);
1609 }
1610
1611
open_pkt()1612 int open_pkt()
1613 {
1614 PKT_hdr ph;
1615 time_t tt = time(NULL);
1616 struct tm t;
1617 unsigned int i;
1618 char packet_name[1024];
1619
1620 t = *localtime(&tt);
1621
1622 global_msgid++;
1623
1624 sprintf(packet_name,"%s%08lx.pkt",main_config->pkt_inbound,(long)global_msgid);
1625
1626 if ((out_pkt = fopen(packet_name,"wb")) == NULL)
1627 {
1628 fprintf(stderr,"Cannot open file: \"%s\" for write\n\n",packet_name);
1629 exit(2);
1630 }
1631
1632 ph.origNode = main_config->pkt_orig_addr.node;
1633 ph.destNode = main_config->pkt_dest_addr.node;
1634 ph.year = t.tm_year+1900;
1635 ph.month = t.tm_mon;
1636 ph.day = t.tm_mday;
1637 ph.hour = t.tm_hour;
1638 ph.minute = t.tm_min;
1639 ph.second = t.tm_sec;
1640 ph.baud = 0;
1641 ph.packettype = 2;
1642 ph.origNet = main_config->pkt_orig_addr.net;
1643 ph.destNet = main_config->pkt_dest_addr.net;
1644 ph.prodcode = 254;
1645 ph.serialno = 1;
1646 for (i=0; i<8; i++) ph.password[i] = main_config->pkt_password[i];
1647 ph.origZone = main_config->pkt_orig_addr.zone;
1648 ph.destZone = main_config->pkt_dest_addr.zone;
1649 ph.auxNet = ph.origNet;
1650 ph.CapValid = 256;
1651 ph.prodcode2 = 0;
1652 ph.serialno2 = 6;
1653 ph.CapWord = 1;
1654 ph.origZone2 = ph.origZone;
1655 ph.destZone2 = ph.destZone;
1656 ph.origPoint = main_config->pkt_orig_addr.point;
1657 ph.destPoint = main_config->pkt_dest_addr.point;
1658 ph.fill_36[0] = 'X';
1659 ph.fill_36[1] = 'P';
1660 ph.fill_36[2] = 'K';
1661 ph.fill_36[3] = 'T';
1662
1663 fwrite(&ph,sizeof(ph),1,out_pkt);
1664 if (ferror(out_pkt)) print_write_err();
1665
1666 fwrite("\0\0",2,1,out_pkt);
1667 if (ferror(out_pkt)) print_write_err();
1668
1669 return 0;
1670 }
1671
write_msg_hdr(int n)1672 int write_msg_hdr(int n)
1673 {
1674 MSG_hdr mh;
1675 time_t tt = time(NULL);
1676 struct tm t;
1677 char yr[3],yy[10];
1678 char s[255];
1679
1680 t = *localtime(&tt);
1681
1682 mh.origNode = main_config->pkt_orig_addr.node;
1683 mh.destNode = main_config->pkt_dest_addr.node;
1684 mh.origNet = main_config->pkt_orig_addr.net;
1685 mh.destNet = main_config->pkt_dest_addr.net;
1686 mh.AttributeWord = 0;
1687 mh.cost = 0;
1688
1689 sprintf(yy,"%04d",t.tm_year+1900);
1690
1691 if (strlen(yy) == 4)
1692 {
1693 yr[0] = yy[2];
1694 yr[1] = yy[3];
1695 yr[2] = '\0';
1696
1697 } else {
1698
1699 yr[0] = '0';
1700 yr[1] = '0';
1701 yr[2] = '\0';
1702
1703 }
1704
1705 sprintf(mh.DateTime,"%02d %s %s %02d:%02d:%02u",t.tm_mday,
1706 months_ab[t.tm_mon],yr,t.tm_hour,t.tm_min,isecs);
1707
1708 isecs++;
1709 if (isecs > 59) isecs = 0; /* pseudo secs (anti dupes in squish) */
1710
1711 fseek(out_pkt,-2L,SEEK_END);
1712
1713 fwrite("\x02\0",2,1,out_pkt);
1714 if (ferror(out_pkt)) print_write_err();
1715
1716 fwrite(&mh,sizeof(mh),1,out_pkt);
1717 if (ferror(out_pkt)) print_write_err();
1718
1719 fwrite(main_config->pkt_to,strlen(main_config->pkt_to)+1,1,out_pkt);
1720 if (ferror(out_pkt)) print_write_err();
1721
1722 fwrite(main_config->pkt_from,strlen(main_config->pkt_from)+1,1,out_pkt);
1723 if (ferror(out_pkt)) print_write_err();
1724
1725 fwrite(main_config->pkt_subj,strlen(main_config->pkt_subj)+1,1,out_pkt);
1726 if (ferror(out_pkt)) print_write_err();
1727
1728 fwrite("AREA:",5,1,out_pkt);
1729 if (ferror(out_pkt)) print_write_err();
1730
1731 fwrite(main_config->areas[n].name,strlen(main_config->areas[n].name),1,out_pkt);
1732 if (ferror(out_pkt)) print_write_err();
1733
1734 global_msgid++;
1735
1736 if (main_config->pkt_orig_addr.point)
1737 {
1738 sprintf(s,"\r\x01MSGID: %d:%d/%d.%d %08lx",
1739 main_config->pkt_orig_addr.zone,main_config->pkt_orig_addr.net,
1740 main_config->pkt_orig_addr.node,main_config->pkt_orig_addr.point,
1741 (long)global_msgid);
1742
1743 } else {
1744
1745 sprintf(s,"\r\x01MSGID: %d:%d/%d %08lx",
1746 main_config->pkt_orig_addr.zone,main_config->pkt_orig_addr.net,
1747 main_config->pkt_orig_addr.node,(long)global_msgid);
1748
1749 }
1750
1751 fwrite(s,strlen(s),1,out_pkt);
1752 if (ferror(out_pkt)) print_write_err();
1753
1754 fwrite("\r\x01""FLAGS NPD\r",12,1,out_pkt);
1755 if (ferror(out_pkt)) print_write_err();
1756
1757 if (strnicmp(main_config->pkt_tearline, versionStr, strlen(versionStr)))
1758 {
1759 sprintf(s,"\x01PID: %s\r",versionStr);
1760 fwrite(s,strlen(s),1,out_pkt);
1761 if (ferror(out_pkt)) print_write_err();
1762 }
1763
1764 return 0;
1765 }
1766
write_buff_to_pkt(char * buff)1767 int write_buff_to_pkt(char *buff)
1768 {
1769 fwrite (buff, strlen(buff), 1, out_pkt);
1770 if (ferror(out_pkt)) print_write_err();
1771
1772 return 0;
1773 }
1774
end_msg(unsigned char e)1775 int end_msg(unsigned char e)
1776 {
1777 char s[255];
1778
1779 if (e)
1780 {
1781 sprintf(s," -== Continued in next message ==-\r");
1782
1783 fwrite (s, strlen(s), 1, out_pkt);
1784 if (ferror(out_pkt)) print_write_err();
1785 }
1786
1787 sprintf(s,"\r\r--- %s",main_config->pkt_tearline);
1788
1789 fwrite (s, strlen(s), 1, out_pkt);
1790 if (ferror(out_pkt)) print_write_err();
1791
1792 if (main_config->pkt_orig_addr.point)
1793 {
1794 sprintf(s,"\r * Origin: %s (%d:%d/%d.%d)",main_config->pkt_origin,
1795 main_config->pkt_orig_addr.zone,main_config->pkt_orig_addr.net,
1796 main_config->pkt_orig_addr.node,main_config->pkt_orig_addr.point);
1797
1798 } else {
1799
1800 sprintf(s,"\r * Origin: %s (%d:%d/%d)",main_config->pkt_origin,
1801 main_config->pkt_orig_addr.zone,main_config->pkt_orig_addr.net,
1802 main_config->pkt_orig_addr.node);
1803 }
1804
1805 fwrite (s, strlen(s), 1, out_pkt);
1806 if (ferror(out_pkt)) print_write_err();
1807
1808 sprintf(s,"\rSEEN-BY: %d/%d",main_config->pkt_orig_addr.net,
1809 main_config->pkt_orig_addr.node);
1810
1811 fwrite (s, strlen(s), 1, out_pkt);
1812 if (ferror(out_pkt)) print_write_err();
1813
1814 sprintf(s,"\r\x01PATH: %d/%d\r",main_config->pkt_orig_addr.net,
1815 main_config->pkt_orig_addr.node);
1816
1817 fwrite (s, strlen(s), 1, out_pkt);
1818 if (ferror(out_pkt)) print_write_err();
1819
1820 fwrite ("\0\0\0", 3, 1, out_pkt);
1821 if (ferror(out_pkt)) print_write_err();
1822
1823 return 0;
1824 }
1825
main(int argc,char * argv[])1826 int main(int argc,char *argv[])
1827 {
1828 unsigned long i, msg_size = 0;
1829 int j;
1830 char ibuff[256];
1831
1832 global_msgid = time(NULL);
1833 global_msgid %= 0xffffffff;
1834
1835 versionStr = GenVersionStr( "areastat", VER_MAJOR, VER_MINOR, VER_PATCH,
1836 VER_BRANCH, cvs_date );
1837
1838 printf("%s\n", versionStr);
1839
1840 if (argc > 2)
1841 {
1842 fprintf(stderr,"Too many actual parameters\n\n");
1843 argc = 0;
1844 }
1845
1846 if (argc < 2)
1847 {
1848 fprintf(stderr,"\nUsage:\tareastat <config>\n");
1849 exit(1);
1850 }
1851
1852 main_config = read_cfg(argv[1]);
1853
1854 if (main_config->pkt_from == NULL) main_config->pkt_from = sstrdup(versionStr);
1855 if (main_config->pkt_to == NULL) main_config->pkt_to = strdup("All");
1856 if (main_config->pkt_subj == NULL) main_config->pkt_subj = strdup("Statistics");
1857 if (main_config->pkt_origin == NULL) main_config->pkt_origin = strdup("\0");
1858 if (main_config->pkt_inbound == NULL) main_config->pkt_inbound = strdup("\0");
1859 if (main_config->pkt_tearline == NULL) main_config->pkt_tearline = sstrdup(versionStr);
1860
1861 if (strlen(main_config->pkt_inbound) > 256)
1862 {
1863 fprintf(stderr,"Inbound path too long\n\n");
1864 exit(2);
1865 }
1866
1867 if (strlen(main_config->pkt_tearline) > 75)
1868 {
1869 fprintf(stderr,"Tearline too long\n\n");
1870 exit(2);
1871 }
1872
1873 if (strlen(main_config->pkt_origin) > 50)
1874 {
1875 fprintf(stderr,"Origin too long\n\n");
1876 exit(2);
1877 }
1878
1879 for (i = 0; i < main_config->areas_count; i++)
1880 {
1881
1882 if ((current_std = fopen(main_config->areas[i].out_file,"wb")) == NULL)
1883 {
1884 fprintf(stderr,"Cannot open file: \"%s\"\n\n",main_config->areas[i].out_file);
1885 exit(2);
1886 }
1887
1888 reading_base(i);
1889
1890 print_summary_statistics(i);
1891 if (main_config->by_name) print_statistics_by_name();
1892 if (main_config->by_from) print_statistics_by_from();
1893 if (main_config->by_to) print_statistics_by_to();
1894 if (main_config->by_from_to) print_statistics_by_from_to();
1895 if (main_config->by_total) print_statistics_by_total();
1896 if (main_config->by_size) print_statistics_by_size();
1897 if (main_config->by_qpercent) print_statistics_by_qpercent();
1898 if (main_config->by_subj) print_statistics_by_subj();
1899 if (main_config->by_date) print_statistics_by_date();
1900 if (main_config->by_wday) print_statistics_by_wdays();
1901 if (main_config->by_time) print_statistics_by_time();
1902
1903 fprintf(current_std,"\n Statistics created by %s",versionStr);
1904 fprintf(current_std,"\n Written by Dmitry Rusov (C) 2000, The Husky project (C) 2004\n");
1905
1906 fclose(current_std);
1907
1908 if (!main_config->make_pkt)
1909 {
1910 free_items();
1911 continue;
1912 }
1913
1914 open_pkt();
1915
1916 if ((current_std = fopen(main_config->areas[i].out_file,"rb")) == NULL)
1917 {
1918 fprintf(stderr,"Cannot open file: \"%s\"\n\n",main_config->areas[i].out_file);
1919 exit(2);
1920 }
1921
1922 isecs = 0;
1923
1924 write_msg_hdr(i);
1925
1926 if ((current_std = fopen(main_config->areas[i].out_file,"rb")) == NULL)
1927 {
1928 fprintf(stderr,"Cannot open file: \"%s\"\n\n",main_config->areas[i].out_file);
1929 exit(2);
1930 }
1931
1932 msg_size = 0;
1933
1934 while (fgets(ibuff,255,current_std))
1935 {
1936 if (ibuff != NULL && * ibuff)
1937 {
1938 if (ibuff[0] == ' ' && ibuff[1] == '-' && ibuff[2] == '-'
1939 && ibuff[3] == '-' && msg_size > main_config->pkt_size)
1940 {
1941 end_msg(1);
1942 write_msg_hdr(i);
1943 msg_size = 0;
1944 }
1945
1946 j = strlen(ibuff)-1;
1947 if (j >= 0 && ibuff[j] == '\n') ibuff[j] = '\r';
1948
1949 write_buff_to_pkt(ibuff);
1950 msg_size += strlen(ibuff);
1951 }
1952 }
1953 end_msg(0);
1954 fclose(current_std);
1955 fclose(out_pkt);
1956 free_items();
1957
1958 } /* for */
1959 free_config();
1960 fprintf(stderr,"\n\nDone!\n");
1961 return 0;
1962 }
1963