source: trunk/third/sendmail/mailstats/mailstats.c @ 19204

Revision 19204, 9.1 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
3 *      All rights reserved.
4 * Copyright (c) 1983 Eric P. Allman.  All rights reserved.
5 * Copyright (c) 1988, 1993
6 *      The Regents of the University of California.  All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 *
13 */
14
15#include <sm/gen.h>
16
17SM_IDSTR(copyright,
18"@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\
19        All rights reserved.\n\
20     Copyright (c) 1988, 1993\n\
21        The Regents of the University of California.  All rights reserved.\n")
22
23SM_IDSTR(id, "@(#)$Id: mailstats.c,v 1.1.1.2 2003-04-08 15:07:39 zacheiss Exp $")
24
25#include <unistd.h>
26#include <stddef.h>
27#include <stdlib.h>
28#include <ctype.h>
29#include <string.h>
30#include <time.h>
31#ifdef EX_OK
32# undef EX_OK           /* unistd.h may have another use for this */
33#endif /* EX_OK */
34#include <sysexits.h>
35
36#include <sm/errstring.h>
37#include <sm/limits.h>
38#include <sendmail/sendmail.h>
39#include <sendmail/mailstats.h>
40#include <sendmail/pathnames.h>
41
42
43#define MNAMELEN        20      /* max length of mailer name */
44
45int
46main(argc, argv)
47        int argc;
48        char **argv;
49{
50        register int i;
51        int mno;
52        int save_errno;
53        int ch, fd;
54        char *sfile;
55        char *cfile;
56        SM_FILE_T *cfp;
57        bool mnames;
58        bool progmode;
59        bool trunc;
60        long frmsgs = 0, frbytes = 0, tomsgs = 0, tobytes = 0, rejmsgs = 0;
61        long dismsgs = 0;
62#if _FFR_QUARANTINE
63        long quarmsgs = 0;
64#endif /* _FFR_QUARANTINE */
65        time_t now;
66        char mtable[MAXMAILERS][MNAMELEN + 1];
67        char sfilebuf[MAXPATHLEN];
68        char buf[MAXLINE];
69        struct statistics stats;
70        extern char *ctime();
71        extern char *optarg;
72        extern int optind;
73
74        cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
75        sfile = NULL;
76        mnames = true;
77        progmode = false;
78        trunc = false;
79        while ((ch = getopt(argc, argv, "cC:f:opP")) != -1)
80        {
81                switch (ch)
82                {
83                  case 'c':
84                        cfile = getcfname(0, 0, SM_GET_SUBMIT_CF, NULL);
85                        break;
86
87                  case 'C':
88                        cfile = optarg;
89                        break;
90
91                  case 'f':
92                        sfile = optarg;
93                        break;
94
95                  case 'o':
96                        mnames = false;
97                        break;
98
99                  case 'p':
100                        trunc = true;
101                        /* FALLTHROUGH */
102
103                  case 'P':
104                        progmode = true;
105                        break;
106
107                  case '?':
108                  default:
109  usage:
110                        (void) sm_io_fputs(smioerr, SM_TIME_DEFAULT,
111                            "usage: mailstats [-C cffile] [-c] [-P] [-f stfile] [-o] [-p]\n");
112                        exit(EX_USAGE);
113                }
114        }
115        argc -= optind;
116        argv += optind;
117
118        if (argc != 0)
119                goto usage;
120
121        if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
122                              NULL)) == NULL)
123        {
124                save_errno = errno;
125                (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "mailstats: ");
126                errno = save_errno;
127                sm_perror(cfile);
128                exit(EX_NOINPUT);
129        }
130
131        mno = 0;
132        (void) sm_strlcpy(mtable[mno++], "prog", MNAMELEN + 1);
133        (void) sm_strlcpy(mtable[mno++], "*file*", MNAMELEN + 1);
134        (void) sm_strlcpy(mtable[mno++], "*include*", MNAMELEN + 1);
135
136        while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL)
137        {
138                register char *b;
139                char *s;
140                register char *m;
141
142                b = strchr(buf, '#');
143                if (b == NULL)
144                        b = strchr(buf, '\n');
145                if (b == NULL)
146                        b = &buf[strlen(buf)];
147                while (isascii(*--b) && isspace(*b))
148                        continue;
149                *++b = '\0';
150
151                b = buf;
152                switch (*b++)
153                {
154                  case 'M':             /* mailer definition */
155                        break;
156
157                  case 'O':             /* option -- see if .st file */
158                        if (sm_strncasecmp(b, " StatusFile", 11) == 0 &&
159                            !(isascii(b[11]) && isalnum(b[11])))
160                        {
161                                /* new form -- find value */
162                                b = strchr(b, '=');
163                                if (b == NULL)
164                                        continue;
165                                while (isascii(*++b) && isspace(*b))
166                                        continue;
167                        }
168                        else if (*b++ != 'S')
169                        {
170                                /* something else boring */
171                                continue;
172                        }
173
174                        /* this is the S or StatusFile option -- save it */
175                        if (sm_strlcpy(sfilebuf, b, sizeof sfilebuf) >=
176                            sizeof sfilebuf)
177                        {
178                                (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
179                                                     "StatusFile filename too long: %.30s...\n",
180                                                     b);
181                                exit(EX_CONFIG);
182                        }
183                        if (sfile == NULL)
184                                sfile = sfilebuf;
185
186                  default:
187                        continue;
188                }
189
190                if (mno >= MAXMAILERS)
191                {
192                        (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
193                                             "Too many mailers defined, %d max.\n",
194                                             MAXMAILERS);
195                        exit(EX_SOFTWARE);
196                }
197                m = mtable[mno];
198                s = m + MNAMELEN;               /* is [MNAMELEN + 1] */
199                while (*b != ',' && !(isascii(*b) && isspace(*b)) &&
200                       *b != '\0' && m < s)
201                        *m++ = *b++;
202                *m = '\0';
203                for (i = 0; i < mno; i++)
204                {
205                        if (strcmp(mtable[i], mtable[mno]) == 0)
206                                break;
207                }
208                if (i == mno)
209                        mno++;
210        }
211        (void) sm_io_close(cfp, SM_TIME_DEFAULT);
212        for (; mno < MAXMAILERS; mno++)
213                mtable[mno][0] = '\0';
214
215        if (sfile == NULL)
216        {
217                (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
218                                     "mailstats: no statistics file located\n");
219                exit(EX_OSFILE);
220        }
221
222        fd = open(sfile, O_RDONLY, 0600);
223        if ((fd < 0) || (i = read(fd, &stats, sizeof stats)) < 0)
224        {
225                save_errno = errno;
226                (void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, "mailstats: ");
227                errno = save_errno;
228                sm_perror(sfile);
229                exit(EX_NOINPUT);
230        }
231        if (i == 0)
232        {
233                (void) sleep(1);
234                if ((i = read(fd, &stats, sizeof stats)) < 0)
235                {
236                        save_errno = errno;
237                        (void) sm_io_fputs(smioerr, SM_TIME_DEFAULT,
238                                           "mailstats: ");
239                        errno = save_errno;
240                        sm_perror(sfile);
241                        exit(EX_NOINPUT);
242                }
243                else if (i == 0)
244                {
245                        memset((ARBPTR_T) &stats, '\0', sizeof stats);
246                        (void) time(&stats.stat_itime);
247                }
248        }
249        if (i != 0)
250        {
251                if (stats.stat_magic != STAT_MAGIC)
252                {
253                        (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
254                                             "mailstats: incorrect magic number in %s\n",
255                                             sfile);
256                        exit(EX_OSERR);
257                }
258                else if (stats.stat_version != STAT_VERSION)
259                {
260                        (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
261                                             "mailstats version (%d) incompatible with %s version (%d)\n",
262                                             STAT_VERSION, sfile,
263                                             stats.stat_version);
264
265                        exit(EX_OSERR);
266                }
267                else if (i != sizeof stats || stats.stat_size != sizeof(stats))
268                {
269                        (void) sm_io_fputs(smioerr, SM_TIME_DEFAULT,
270                                           "mailstats: file size changed.\n");
271                        exit(EX_OSERR);
272                }
273        }
274
275        if (progmode)
276        {
277                (void) time(&now);
278                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%ld %ld\n",
279                                     (long) stats.stat_itime, (long) now);
280        }
281        else
282        {
283                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
284                                     "Statistics from %s",
285                                     ctime(&stats.stat_itime));
286                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
287                                     " M   msgsfr  bytes_from   msgsto    bytes_to  msgsrej msgsdis");
288#if _FFR_QUARANTINE
289                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " msgsqur");
290#endif /* _FFR_QUARANTINE */
291                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s\n",
292                                     mnames ? "  Mailer" : "");
293        }
294        for (i = 0; i < MAXMAILERS; i++)
295        {
296                if (stats.stat_nf[i] || stats.stat_nt[i] ||
297#if _FFR_QUARANTINE
298                    stats.stat_nq[i] ||
299#endif /* _FFR_QUARANTINE */
300                    stats.stat_nr[i] || stats.stat_nd[i])
301                {
302                        char *format;
303
304                        if (progmode)
305                                format = "%2d %8ld %10ld %8ld %10ld   %6ld  %6ld";
306                        else
307                                format = "%2d %8ld %10ldK %8ld %10ldK   %6ld  %6ld";
308                        (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
309                                             format, i,
310                                             stats.stat_nf[i],
311                                             stats.stat_bf[i],
312                                             stats.stat_nt[i],
313                                             stats.stat_bt[i],
314                                             stats.stat_nr[i],
315                                             stats.stat_nd[i]);
316#if _FFR_QUARANTINE
317                        (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
318                                             "  %6ld", stats.stat_nq[i]);
319#endif /* _FFR_QUARANTINE */
320                        if (mnames)
321                                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
322                                                     "  %s",
323                                                      mtable[i]);
324                        (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n");
325                        frmsgs += stats.stat_nf[i];
326                        frbytes += stats.stat_bf[i];
327                        tomsgs += stats.stat_nt[i];
328                        tobytes += stats.stat_bt[i];
329                        rejmsgs += stats.stat_nr[i];
330                        dismsgs += stats.stat_nd[i];
331#if _FFR_QUARANTINE
332                        quarmsgs += stats.stat_nq[i];
333#endif /* _FFR_QUARANTINE */
334                }
335        }
336        if (progmode)
337        {
338                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
339                                     " T %8ld %10ld %8ld %10ld   %6ld  %6ld",
340                                     frmsgs, frbytes, tomsgs, tobytes, rejmsgs,
341                                     dismsgs);
342#if _FFR_QUARANTINE
343                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
344                                     "  %6ld", quarmsgs);
345#endif /* _FFR_QUARANTINE */
346                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n");
347                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
348                                     " C %8ld %8ld %6ld\n",
349                                     stats.stat_cf, stats.stat_ct,
350                                     stats.stat_cr);
351                (void) close(fd);
352                if (trunc)
353                {
354                        fd = open(sfile, O_RDWR | O_TRUNC, 0600);
355                        if (fd >= 0)
356                                (void) close(fd);
357                }
358        }
359        else
360        {
361                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
362                                     "=============================================================");
363#if _FFR_QUARANTINE
364                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "========");
365#endif /* _FFR_QUARANTINE */
366                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n");
367                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
368                                     " T %8ld %10ldK %8ld %10ldK   %6ld  %6ld",
369                                     frmsgs, frbytes, tomsgs, tobytes, rejmsgs,
370                                     dismsgs);
371#if _FFR_QUARANTINE
372                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
373                                     "  %6ld", quarmsgs);
374#endif /* _FFR_QUARANTINE */
375                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n");
376                (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
377                                     " C %8ld %10s  %8ld %10s    %6ld\n",
378                                     stats.stat_cf, "", stats.stat_ct, "",
379                                     stats.stat_cr);
380        }
381        exit(EX_OK);
382        /* NOTREACHED */
383        return EX_OK;
384}
Note: See TracBrowser for help on using the repository browser.