]> code.citadel.org Git - citadel.git/blob - citadel/stats.c
3a8b877faf5f2add9cdfddca83b6ae9cc6107217
[citadel.git] / citadel / stats.c
1 /* Citadel/UX call log stats program
2  */
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <time.h>
7 #include <stdio.h>
8 #include <errno.h>
9 #include <string.h>
10 #include "citadel.h"
11
12 #define disply(x,y) printf("%20s            %4.1f    %4.1f    %4d\n",x,((float)y)/calls,((float)y)/days,y)
13
14 #define GRANULARITY 100
15
16 int batch_mode = 0;
17
18 struct caller
19   {
20     struct caller *next;
21     char Cname[30];
22     int Ctimescalled;
23   };
24
25 void get_config ();
26 struct config config;
27
28
29 void
30 prompt ()
31 {
32   char buf[16];
33   if (batch_mode == 0)
34     {
35       printf ("Press return to continue...");
36       fgets (buf, 16, stdin);
37     }
38   else
39     {
40       printf ("\n");
41     }
42 }
43
44 int
45 halfhour (time)                 /* Returns half-hour time period of time */
46      long time;
47 {
48   int a;
49   struct tm *tm;
50   tm = (struct tm *) localtime (&time);
51   a = (tm->tm_hour) * 3;
52   if ((tm->tm_min) > 19)
53     ++a;
54   if ((tm->tm_min) > 39)
55     ++a;
56   return (a);
57 }
58
59
60
61 void
62 progress (curr, max)
63      long curr;
64      long max;
65 {
66   static int dots;
67   int pos;
68
69   if (curr == 0L)
70     {
71       printf ("--------------------------------------");
72       printf ("--------------------------------------\r");
73       fflush (stdout);
74       dots = 0;
75     }
76
77   pos = (curr * 72) / max;
78   while (dots < pos)
79     {
80       putc ('*', stdout);
81       fflush (stdout);
82       ++dots;
83     }
84
85   if (dots == 72)
86     {
87       printf ("                                      ");
88       printf ("                                      \r");
89       fflush (stdout);
90     }
91
92 }
93
94
95
96
97 void
98 main (argc, argv)
99      int argc;
100      char *argv[];
101 {
102   time_t LogTime;
103   unsigned int LogType;
104   char LogName[256];
105   struct usersupp usersupp;
106   int a, b, lowest;
107   float p, q;
108   long timeon[72];
109   long timeup[72];
110   char dname[30];
111   int sess = 0;
112   long cftime, cttime, aa;
113   int calls, logins, newusers;
114   int badpws, terms, drops, sleeps;
115   long from, to, tottime;
116   int days, hours, minutes;
117   char aaa[100];
118   struct tm *tm;
119   struct caller *callers = NULL;
120   struct caller *callptr = NULL;
121   FILE *fp, *sortpipe;
122   char thegraph[GRANULARITY][73];
123   int pc_only = 0;
124   char buf[256];
125   FILE *logfp;
126
127   for (a = 0; a < argc; ++a)
128     {
129       if (!strcmp (argv[a], "-b"))
130         batch_mode = 1;
131       if (!strcmp (argv[a], "-p"))
132         pc_only = 1;
133     }
134
135
136   for (a = 0; a < GRANULARITY; ++a)
137     strcpy (thegraph[a],
138             "........................................................................");
139
140   get_config ();
141
142   if (pc_only)
143     goto PC_ONLY_HERE;
144
145   if (!batch_mode)
146     printf ("Scanning call log, please wait...\n\n\n\n");
147
148   from = 0L;
149   to = 0L;
150   for (a = 0; a < 72; ++a)
151     {
152       timeon[a] = 0L;
153       timeup[a] = 0L;
154     }
155   cftime = 0L;
156   cttime = 0L;
157
158   calls = 0;
159   logins = 0;
160   newusers = 0;
161   badpws = 0;
162   terms = 0;
163   drops = 0;
164   sleeps = 0;
165
166
167   logfp = fopen ("citadel.log", "r");
168   if (logfp == NULL)
169     {
170       perror ("Could not open citadel.log");
171       exit (errno);
172     }
173   else
174     {
175       if (!batch_mode)
176         {
177           printf ("Scanning call log, please wait...\n");
178         }
179       while (fgets (buf, 256, logfp) != NULL)
180         {
181           buf[strlen (buf) - 1] = 0;
182
183           LogTime = atol (strtok (buf, "|"));
184           LogType = atol (strtok (NULL, "|"));
185           strcpy (LogName, strtok (NULL, "|"));
186
187           if (LogType != 0)
188             {
189               if ((LogTime < from) || (from == 0L))
190                 from = LogTime;
191               if ((LogTime > to) || (to == 0L))
192                 to = LogTime;
193               strcpy (aaa, "");
194               if (LogType & CL_CONNECT)
195                 {
196                   ++calls;
197                   ++sess;
198                   if (sess == 1)
199                     cftime = LogTime;
200                   strcpy (dname, LogName);
201                 }
202               if (LogType & CL_LOGIN)
203                 {
204                   ++logins;
205                   b = 0;
206                   for (callptr = callers; callptr != NULL; callptr = callptr->next)
207                     {
208                       if (!strcmp (callptr->Cname, LogName))
209                         {
210                           ++b;
211                           ++callptr->Ctimescalled;
212                         }
213                     }
214                   if (b == 0)
215                     {
216                       callptr = (struct caller *) malloc (sizeof (struct caller));
217                       callptr->next = callers;
218                       callers = callptr;
219                       strcpy (callers->Cname, LogName);
220                       callers->Ctimescalled = 1;
221                     }
222                 }
223               if (LogType & CL_NEWUSER)
224                 ++newusers;
225               if (LogType & CL_BADPW)
226                 ++badpws;
227               if (LogType & CL_TERMINATE)
228                 {
229                   ++terms;
230                   --sess;
231                   if (sess == 0)
232                     {
233                       cttime = LogTime;
234                       for (aa = cftime; aa <= cttime; aa = aa + 300L)
235                         timeon[halfhour (aa)] = timeon[halfhour (aa)] + 5L;
236                       cftime = 0L;
237                       cttime = 0L;
238                     }
239                 }
240               if (LogType & CL_DROPCARR)
241                 {
242                   ++drops;
243                   --sess;
244                   if (sess == 0)
245                     {
246                       cttime = LogTime;
247                       for (aa = cftime; aa <= cttime; aa = aa + 300L)
248                         timeon[halfhour (aa)] = timeon[halfhour (aa)] + 5L;
249                       cftime = 0L;
250                       cttime = 0L;
251                     }
252                 }
253               if (LogType & CL_SLEEPING)
254                 {
255                   ++sleeps;
256                   --sess;
257                   if (sess == 0)
258                     {
259                       cttime = LogTime;
260                       for (aa = cftime; aa <= cttime; aa = aa + 300L)
261                         timeon[halfhour (aa)] = timeon[halfhour (aa)] + 5L;
262                       cftime = 0L;
263                       cttime = 0L;
264                     }
265                 }
266
267               if (sess < 0)
268                 sess = 0;
269
270             }
271         }
272       fclose (logfp);
273       tottime = to - from;
274       days = (int) (tottime / 86400L);
275       hours = (int) ((tottime % 86400L) / 3600L);
276       minutes = (int) ((tottime % 3600L) / 60L);
277
278       printf ("                              Avg/Call Avg/Day  Total\n");
279       disply ("Calls:", calls);
280       disply ("Logins:", logins);
281       disply ("New users:", newusers);
282       disply ("Bad pw attempts:", badpws);
283       disply ("Proper logoffs:", terms);
284       disply ("Carrier drops:", drops);
285       disply ("Sleeping drops:", sleeps);
286
287       printf ("\n");
288       tm = (struct tm *) localtime (&from);
289       printf ("From:              %s", (char *) asctime (localtime (&from)));
290       printf ("To:                %s", (char *) asctime (localtime (&to)));
291       printf ("Total report time: ");
292       printf ("%d days, %d hours, %d minutes\n",
293               days, hours, minutes);
294
295       for (aa = from; aa <= to; aa = aa + 1200L)
296         timeup[halfhour (aa)] = timeup[halfhour (aa)] + 20L;
297       prompt ();
298
299       lowest = GRANULARITY - 1;
300       for (b = 0; b < 72; ++b)
301         {
302           for (a = 0; a <= GRANULARITY; ++a)
303             {
304               p = ((float) timeon[b]) / ((float) timeup[b]) * GRANULARITY;
305               q = (float) a;
306               if (p >= q)
307                 {
308                   thegraph[(GRANULARITY - 1) - a][b] = '#';
309                   if (lowest > (GRANULARITY - 1) - a)
310                     lowest = (GRANULARITY - 1) - a;
311                 }
312             }
313         }
314
315       printf ("\n\n\n\n\n\n");
316
317       b = ((GRANULARITY - lowest) / 18);
318       if (b < 1)
319         b = 1;
320       for (a = lowest; a < GRANULARITY; a = a + b)
321         printf ("%2d%% |%s\n",
322                 100 - (a + 1),
323                 thegraph[a]);
324       printf ("    +------------------------------------------------------------------------\n");
325       printf ("     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");
326       fflush (stdout);
327       prompt ();
328
329       printf ("\n\n\n\n");
330
331
332       printf ("Top 20 Callers (sorted by total number of logins)\n");
333       printf ("Calls Avg/Day Username\n");
334       printf ("----- ------- ------------------------------\n");
335       fflush (stdout);
336       sortpipe = (FILE *) popen ("sort |tail -20 |sort -r", "w");
337       for (callptr = callers; callptr != NULL; callptr = callptr->next)
338         {
339           fprintf (sortpipe, "%5d %7.2f %-30s\n",
340                    callptr->Ctimescalled,
341                    (((float) callptr->Ctimescalled) / ((float) days)),
342                    callptr->Cname);
343         }
344       pclose (sortpipe);
345       while (callers != NULL)
346         {
347           callptr = callers->next;
348           free (callers);
349           callers = callptr;
350         }
351       prompt ();
352
353     PC_ONLY_HERE:
354       printf ("Top 20 Contributing Users (post to call ratio)\n");
355       printf ("P/C Ratio Username\n");
356       printf ("--------- ------------------------------\n");
357       fflush (stdout);
358       sortpipe = (FILE *) popen ("sort |tail -20 |sort -r", "w");
359       fp = fopen ("usersupp", "r");
360       while ((fp != NULL)
361        && (fread ((char *) &usersupp, sizeof (struct usersupp), 1, fp) > 0))
362         {
363           fprintf (sortpipe, "%9.2f %-30s\n",
364                    ((float) usersupp.posted / (float) usersupp.timescalled),
365                    usersupp.fullname);
366         }
367       fclose (fp);
368       pclose (sortpipe);
369       exit (0);
370     }
371 }