xref: /freebsd/contrib/sendmail/mailstats/mailstats.c (revision e2c0e292e8a7ca00ba99bcfccc9e637f45c3e8b1)
1c2aa98e2SPeter Wemm /*
25dd76dd0SGregory Neil Shapiro  * Copyright (c) 1998-2002, 2013 Proofpoint, Inc. and its suppliers.
33299c2f1SGregory Neil Shapiro  *	All rights reserved.
4c2aa98e2SPeter Wemm  * Copyright (c) 1983 Eric P. Allman.  All rights reserved.
5c2aa98e2SPeter Wemm  * Copyright (c) 1988, 1993
6c2aa98e2SPeter Wemm  *	The Regents of the University of California.  All rights reserved.
7c2aa98e2SPeter Wemm  *
8c2aa98e2SPeter Wemm  * By using this file, you agree to the terms and conditions set
9c2aa98e2SPeter Wemm  * forth in the LICENSE file which can be found at the top level of
10c2aa98e2SPeter Wemm  * the sendmail distribution.
11c2aa98e2SPeter Wemm  *
12c2aa98e2SPeter Wemm  *
13c2aa98e2SPeter Wemm  */
14c2aa98e2SPeter Wemm 
1512ed1c7cSGregory Neil Shapiro #include <sm/gen.h>
1612ed1c7cSGregory Neil Shapiro 
1712ed1c7cSGregory Neil Shapiro SM_IDSTR(copyright,
185dd76dd0SGregory Neil Shapiro "@(#) Copyright (c) 1998-2002 Proofpoint, Inc. and its suppliers.\n\
193299c2f1SGregory Neil Shapiro 	All rights reserved.\n\
203299c2f1SGregory Neil Shapiro      Copyright (c) 1988, 1993\n\
2112ed1c7cSGregory Neil Shapiro 	The Regents of the University of California.  All rights reserved.\n")
22c2aa98e2SPeter Wemm 
234313cc83SGregory Neil Shapiro SM_IDSTR(id, "@(#)$Id: mailstats.c,v 8.103 2013-11-22 20:51:51 ca Exp $")
24c2aa98e2SPeter Wemm 
253299c2f1SGregory Neil Shapiro #include <unistd.h>
263299c2f1SGregory Neil Shapiro #include <stddef.h>
273299c2f1SGregory Neil Shapiro #include <stdlib.h>
283299c2f1SGregory Neil Shapiro #include <ctype.h>
293299c2f1SGregory Neil Shapiro #include <string.h>
303299c2f1SGregory Neil Shapiro #include <time.h>
313299c2f1SGregory Neil Shapiro #ifdef EX_OK
323299c2f1SGregory Neil Shapiro # undef EX_OK		/* unistd.h may have another use for this */
33*5b0945b5SGregory Neil Shapiro #endif
343299c2f1SGregory Neil Shapiro #include <sysexits.h>
353299c2f1SGregory Neil Shapiro 
3612ed1c7cSGregory Neil Shapiro #include <sm/errstring.h>
3712ed1c7cSGregory Neil Shapiro #include <sm/limits.h>
383299c2f1SGregory Neil Shapiro #include <sendmail/sendmail.h>
393299c2f1SGregory Neil Shapiro #include <sendmail/mailstats.h>
403299c2f1SGregory Neil Shapiro #include <sendmail/pathnames.h>
413299c2f1SGregory Neil Shapiro 
42c2aa98e2SPeter Wemm 
43c2aa98e2SPeter Wemm #define MNAMELEN	20	/* max length of mailer name */
44c2aa98e2SPeter Wemm 
45c2aa98e2SPeter Wemm int
46c2aa98e2SPeter Wemm main(argc, argv)
47c2aa98e2SPeter Wemm 	int argc;
48c2aa98e2SPeter Wemm 	char **argv;
49c2aa98e2SPeter Wemm {
50c2aa98e2SPeter Wemm 	register int i;
51c2aa98e2SPeter Wemm 	int mno;
523299c2f1SGregory Neil Shapiro 	int save_errno;
53c2aa98e2SPeter Wemm 	int ch, fd;
54c2aa98e2SPeter Wemm 	char *sfile;
55c2aa98e2SPeter Wemm 	char *cfile;
5612ed1c7cSGregory Neil Shapiro 	SM_FILE_T *cfp;
57c2aa98e2SPeter Wemm 	bool mnames;
5876b7bf71SPeter Wemm 	bool progmode;
5912ed1c7cSGregory Neil Shapiro 	bool trunc;
60c2aa98e2SPeter Wemm 	long frmsgs = 0, frbytes = 0, tomsgs = 0, tobytes = 0, rejmsgs = 0;
61c2aa98e2SPeter Wemm 	long dismsgs = 0;
6212ed1c7cSGregory Neil Shapiro 	long quarmsgs = 0;
633299c2f1SGregory Neil Shapiro 	time_t now;
64c2aa98e2SPeter Wemm 	char mtable[MAXMAILERS][MNAMELEN + 1];
6588ad41d4SGregory Neil Shapiro 	char sfilebuf[MAXPATHLEN];
66c2aa98e2SPeter Wemm 	char buf[MAXLINE];
673299c2f1SGregory Neil Shapiro 	struct statistics stats;
68c2aa98e2SPeter Wemm 	extern char *ctime();
693299c2f1SGregory Neil Shapiro 	extern char *optarg;
703299c2f1SGregory Neil Shapiro 	extern int optind;
71552d4955SGregory Neil Shapiro # define MSOPTS "cC:f:opP"
723299c2f1SGregory Neil Shapiro 
7312ed1c7cSGregory Neil Shapiro 	cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL);
74c2aa98e2SPeter Wemm 	sfile = NULL;
7512ed1c7cSGregory Neil Shapiro 	mnames = true;
7612ed1c7cSGregory Neil Shapiro 	progmode = false;
7712ed1c7cSGregory Neil Shapiro 	trunc = false;
78552d4955SGregory Neil Shapiro 	while ((ch = getopt(argc, argv, MSOPTS)) != -1)
79c2aa98e2SPeter Wemm 	{
80c2aa98e2SPeter Wemm 		switch (ch)
81c2aa98e2SPeter Wemm 		{
8212ed1c7cSGregory Neil Shapiro 		  case 'c':
8312ed1c7cSGregory Neil Shapiro 			cfile = getcfname(0, 0, SM_GET_SUBMIT_CF, NULL);
8412ed1c7cSGregory Neil Shapiro 			break;
8512ed1c7cSGregory Neil Shapiro 
86c2aa98e2SPeter Wemm 		  case 'C':
87c2aa98e2SPeter Wemm 			cfile = optarg;
88c2aa98e2SPeter Wemm 			break;
89c2aa98e2SPeter Wemm 
90c2aa98e2SPeter Wemm 		  case 'f':
91c2aa98e2SPeter Wemm 			sfile = optarg;
92c2aa98e2SPeter Wemm 			break;
93c2aa98e2SPeter Wemm 
94552d4955SGregory Neil Shapiro 
95c2aa98e2SPeter Wemm 		  case 'o':
9612ed1c7cSGregory Neil Shapiro 			mnames = false;
97c2aa98e2SPeter Wemm 			break;
98c2aa98e2SPeter Wemm 
9976b7bf71SPeter Wemm 		  case 'p':
10012ed1c7cSGregory Neil Shapiro 			trunc = true;
10112ed1c7cSGregory Neil Shapiro 			/* FALLTHROUGH */
10212ed1c7cSGregory Neil Shapiro 
10312ed1c7cSGregory Neil Shapiro 		  case 'P':
10412ed1c7cSGregory Neil Shapiro 			progmode = true;
10576b7bf71SPeter Wemm 			break;
10676b7bf71SPeter Wemm 
107552d4955SGregory Neil Shapiro 
108c2aa98e2SPeter Wemm 		  case '?':
109c2aa98e2SPeter Wemm 		  default:
110c2aa98e2SPeter Wemm   usage:
11112ed1c7cSGregory Neil Shapiro 			(void) sm_io_fputs(smioerr, SM_TIME_DEFAULT,
11288ad41d4SGregory Neil Shapiro 			    "usage: mailstats [-C cffile] [-c] [-P] [-f stfile] [-o] [-p]\n");
113c2aa98e2SPeter Wemm 			exit(EX_USAGE);
114c2aa98e2SPeter Wemm 		}
115c2aa98e2SPeter Wemm 	}
116c2aa98e2SPeter Wemm 	argc -= optind;
117c2aa98e2SPeter Wemm 	argv += optind;
118c2aa98e2SPeter Wemm 
119c2aa98e2SPeter Wemm 	if (argc != 0)
120c2aa98e2SPeter Wemm 		goto usage;
121c2aa98e2SPeter Wemm 
12212ed1c7cSGregory Neil Shapiro 	if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
12312ed1c7cSGregory Neil Shapiro 			      NULL)) == NULL)
124c2aa98e2SPeter Wemm 	{
1253299c2f1SGregory Neil Shapiro 		save_errno = errno;
12612ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "mailstats: ");
1273299c2f1SGregory Neil Shapiro 		errno = save_errno;
12812ed1c7cSGregory Neil Shapiro 		sm_perror(cfile);
129c2aa98e2SPeter Wemm 		exit(EX_NOINPUT);
130c2aa98e2SPeter Wemm 	}
131c2aa98e2SPeter Wemm 
132c2aa98e2SPeter Wemm 	mno = 0;
13312ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(mtable[mno++], "prog", MNAMELEN + 1);
13412ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(mtable[mno++], "*file*", MNAMELEN + 1);
13512ed1c7cSGregory Neil Shapiro 	(void) sm_strlcpy(mtable[mno++], "*include*", MNAMELEN + 1);
136c2aa98e2SPeter Wemm 
137552d4955SGregory Neil Shapiro 	while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
138c2aa98e2SPeter Wemm 	{
139c2aa98e2SPeter Wemm 		register char *b;
140c2aa98e2SPeter Wemm 		char *s;
141c2aa98e2SPeter Wemm 		register char *m;
142c2aa98e2SPeter Wemm 
14388ad41d4SGregory Neil Shapiro 		b = strchr(buf, '#');
14488ad41d4SGregory Neil Shapiro 		if (b == NULL)
14588ad41d4SGregory Neil Shapiro 			b = strchr(buf, '\n');
14688ad41d4SGregory Neil Shapiro 		if (b == NULL)
14788ad41d4SGregory Neil Shapiro 			b = &buf[strlen(buf)];
14888ad41d4SGregory Neil Shapiro 		while (isascii(*--b) && isspace(*b))
14988ad41d4SGregory Neil Shapiro 			continue;
15088ad41d4SGregory Neil Shapiro 		*++b = '\0';
15188ad41d4SGregory Neil Shapiro 
152c2aa98e2SPeter Wemm 		b = buf;
153c2aa98e2SPeter Wemm 		switch (*b++)
154c2aa98e2SPeter Wemm 		{
155c2aa98e2SPeter Wemm 		  case 'M':		/* mailer definition */
156c2aa98e2SPeter Wemm 			break;
157c2aa98e2SPeter Wemm 
158c2aa98e2SPeter Wemm 		  case 'O':		/* option -- see if .st file */
15912ed1c7cSGregory Neil Shapiro 			if (sm_strncasecmp(b, " StatusFile", 11) == 0 &&
160c2aa98e2SPeter Wemm 			    !(isascii(b[11]) && isalnum(b[11])))
161c2aa98e2SPeter Wemm 			{
162c2aa98e2SPeter Wemm 				/* new form -- find value */
163c2aa98e2SPeter Wemm 				b = strchr(b, '=');
164c2aa98e2SPeter Wemm 				if (b == NULL)
165c2aa98e2SPeter Wemm 					continue;
166c2aa98e2SPeter Wemm 				while (isascii(*++b) && isspace(*b))
167c2aa98e2SPeter Wemm 					continue;
168c2aa98e2SPeter Wemm 			}
169c2aa98e2SPeter Wemm 			else if (*b++ != 'S')
170c2aa98e2SPeter Wemm 			{
171c2aa98e2SPeter Wemm 				/* something else boring */
172c2aa98e2SPeter Wemm 				continue;
173c2aa98e2SPeter Wemm 			}
174c2aa98e2SPeter Wemm 
175c2aa98e2SPeter Wemm 			/* this is the S or StatusFile option -- save it */
17612ed1c7cSGregory Neil Shapiro 			if (sm_strlcpy(sfilebuf, b, sizeof sfilebuf) >=
1773299c2f1SGregory Neil Shapiro 			    sizeof sfilebuf)
178c2aa98e2SPeter Wemm 			{
17912ed1c7cSGregory Neil Shapiro 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
180c2aa98e2SPeter Wemm 						     "StatusFile filename too long: %.30s...\n",
181c2aa98e2SPeter Wemm 						     b);
182c2aa98e2SPeter Wemm 				exit(EX_CONFIG);
183c2aa98e2SPeter Wemm 			}
184c2aa98e2SPeter Wemm 			if (sfile == NULL)
185c2aa98e2SPeter Wemm 				sfile = sfilebuf;
186c2aa98e2SPeter Wemm 
187c2aa98e2SPeter Wemm 		  default:
188c2aa98e2SPeter Wemm 			continue;
189c2aa98e2SPeter Wemm 		}
190c2aa98e2SPeter Wemm 
191c2aa98e2SPeter Wemm 		if (mno >= MAXMAILERS)
192c2aa98e2SPeter Wemm 		{
19312ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
194c2aa98e2SPeter Wemm 					     "Too many mailers defined, %d max.\n",
195c2aa98e2SPeter Wemm 					     MAXMAILERS);
196c2aa98e2SPeter Wemm 			exit(EX_SOFTWARE);
197c2aa98e2SPeter Wemm 		}
198c2aa98e2SPeter Wemm 		m = mtable[mno];
199c2aa98e2SPeter Wemm 		s = m + MNAMELEN;		/* is [MNAMELEN + 1] */
200c2aa98e2SPeter Wemm 		while (*b != ',' && !(isascii(*b) && isspace(*b)) &&
201c2aa98e2SPeter Wemm 		       *b != '\0' && m < s)
202c2aa98e2SPeter Wemm 			*m++ = *b++;
203c2aa98e2SPeter Wemm 		*m = '\0';
204c2aa98e2SPeter Wemm 		for (i = 0; i < mno; i++)
205c2aa98e2SPeter Wemm 		{
206c2aa98e2SPeter Wemm 			if (strcmp(mtable[i], mtable[mno]) == 0)
207c2aa98e2SPeter Wemm 				break;
208c2aa98e2SPeter Wemm 		}
209c2aa98e2SPeter Wemm 		if (i == mno)
210c2aa98e2SPeter Wemm 			mno++;
211c2aa98e2SPeter Wemm 	}
21212ed1c7cSGregory Neil Shapiro 	(void) sm_io_close(cfp, SM_TIME_DEFAULT);
213c2aa98e2SPeter Wemm 	for (; mno < MAXMAILERS; mno++)
214c2aa98e2SPeter Wemm 		mtable[mno][0] = '\0';
215c2aa98e2SPeter Wemm 
216c2aa98e2SPeter Wemm 	if (sfile == NULL)
217c2aa98e2SPeter Wemm 	{
21812ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
21912ed1c7cSGregory Neil Shapiro 				     "mailstats: no statistics file located\n");
220c2aa98e2SPeter Wemm 		exit(EX_OSFILE);
221c2aa98e2SPeter Wemm 	}
222c2aa98e2SPeter Wemm 
22388ad41d4SGregory Neil Shapiro 	fd = open(sfile, O_RDONLY, 0600);
2243299c2f1SGregory Neil Shapiro 	if ((fd < 0) || (i = read(fd, &stats, sizeof stats)) < 0)
225c2aa98e2SPeter Wemm 	{
2263299c2f1SGregory Neil Shapiro 		save_errno = errno;
22712ed1c7cSGregory Neil Shapiro 		(void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, "mailstats: ");
2283299c2f1SGregory Neil Shapiro 		errno = save_errno;
22912ed1c7cSGregory Neil Shapiro 		sm_perror(sfile);
230c2aa98e2SPeter Wemm 		exit(EX_NOINPUT);
231c2aa98e2SPeter Wemm 	}
232c2aa98e2SPeter Wemm 	if (i == 0)
233c2aa98e2SPeter Wemm 	{
2343299c2f1SGregory Neil Shapiro 		(void) sleep(1);
2353299c2f1SGregory Neil Shapiro 		if ((i = read(fd, &stats, sizeof stats)) < 0)
236c2aa98e2SPeter Wemm 		{
2373299c2f1SGregory Neil Shapiro 			save_errno = errno;
23812ed1c7cSGregory Neil Shapiro 			(void) sm_io_fputs(smioerr, SM_TIME_DEFAULT,
23912ed1c7cSGregory Neil Shapiro 					   "mailstats: ");
2403299c2f1SGregory Neil Shapiro 			errno = save_errno;
24112ed1c7cSGregory Neil Shapiro 			sm_perror(sfile);
242c2aa98e2SPeter Wemm 			exit(EX_NOINPUT);
243c2aa98e2SPeter Wemm 		}
244c2aa98e2SPeter Wemm 		else if (i == 0)
245c2aa98e2SPeter Wemm 		{
2463299c2f1SGregory Neil Shapiro 			memset((ARBPTR_T) &stats, '\0', sizeof stats);
2473299c2f1SGregory Neil Shapiro 			(void) time(&stats.stat_itime);
248c2aa98e2SPeter Wemm 		}
249c2aa98e2SPeter Wemm 	}
250c2aa98e2SPeter Wemm 	if (i != 0)
251c2aa98e2SPeter Wemm 	{
2523299c2f1SGregory Neil Shapiro 		if (stats.stat_magic != STAT_MAGIC)
253c2aa98e2SPeter Wemm 		{
25412ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
255c2aa98e2SPeter Wemm 					     "mailstats: incorrect magic number in %s\n",
256c2aa98e2SPeter Wemm 					     sfile);
257c2aa98e2SPeter Wemm 			exit(EX_OSERR);
258c2aa98e2SPeter Wemm 		}
2593299c2f1SGregory Neil Shapiro 		else if (stats.stat_version != STAT_VERSION)
260c2aa98e2SPeter Wemm 		{
26112ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
262c2aa98e2SPeter Wemm 					     "mailstats version (%d) incompatible with %s version (%d)\n",
26312ed1c7cSGregory Neil Shapiro 					     STAT_VERSION, sfile,
26412ed1c7cSGregory Neil Shapiro 					     stats.stat_version);
26512ed1c7cSGregory Neil Shapiro 
266c2aa98e2SPeter Wemm 			exit(EX_OSERR);
267c2aa98e2SPeter Wemm 		}
2683299c2f1SGregory Neil Shapiro 		else if (i != sizeof stats || stats.stat_size != sizeof(stats))
269c2aa98e2SPeter Wemm 		{
27012ed1c7cSGregory Neil Shapiro 			(void) sm_io_fputs(smioerr, SM_TIME_DEFAULT,
27112ed1c7cSGregory Neil Shapiro 					   "mailstats: file size changed.\n");
272c2aa98e2SPeter Wemm 			exit(EX_OSERR);
273c2aa98e2SPeter Wemm 		}
274c2aa98e2SPeter Wemm 	}
275c2aa98e2SPeter Wemm 
276552d4955SGregory Neil Shapiro 
27776b7bf71SPeter Wemm 	if (progmode)
27876b7bf71SPeter Wemm 	{
2793299c2f1SGregory Neil Shapiro 		(void) time(&now);
28012ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%ld %ld\n",
28112ed1c7cSGregory Neil Shapiro 				     (long) stats.stat_itime, (long) now);
28276b7bf71SPeter Wemm 	}
28376b7bf71SPeter Wemm 	else
28476b7bf71SPeter Wemm 	{
28512ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
28612ed1c7cSGregory Neil Shapiro 				     "Statistics from %s",
28712ed1c7cSGregory Neil Shapiro 				     ctime(&stats.stat_itime));
28812ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
28912ed1c7cSGregory Neil Shapiro 				     " M   msgsfr  bytes_from   msgsto    bytes_to  msgsrej msgsdis");
29012ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " msgsqur");
29112ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s\n",
292c2aa98e2SPeter Wemm 				     mnames ? "  Mailer" : "");
29376b7bf71SPeter Wemm 	}
294c2aa98e2SPeter Wemm 	for (i = 0; i < MAXMAILERS; i++)
295c2aa98e2SPeter Wemm 	{
2963299c2f1SGregory Neil Shapiro 		if (stats.stat_nf[i] || stats.stat_nt[i] ||
29712ed1c7cSGregory Neil Shapiro 		    stats.stat_nq[i] ||
2983299c2f1SGregory Neil Shapiro 		    stats.stat_nr[i] || stats.stat_nd[i])
299c2aa98e2SPeter Wemm 		{
30076b7bf71SPeter Wemm 			char *format;
30176b7bf71SPeter Wemm 
30276b7bf71SPeter Wemm 			if (progmode)
30376b7bf71SPeter Wemm 				format = "%2d %8ld %10ld %8ld %10ld   %6ld  %6ld";
30476b7bf71SPeter Wemm 			else
30576b7bf71SPeter Wemm 				format = "%2d %8ld %10ldK %8ld %10ldK   %6ld  %6ld";
30612ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
30712ed1c7cSGregory Neil Shapiro 					     format, i,
30812ed1c7cSGregory Neil Shapiro 					     stats.stat_nf[i],
30912ed1c7cSGregory Neil Shapiro 					     stats.stat_bf[i],
31012ed1c7cSGregory Neil Shapiro 					     stats.stat_nt[i],
31112ed1c7cSGregory Neil Shapiro 					     stats.stat_bt[i],
31212ed1c7cSGregory Neil Shapiro 					     stats.stat_nr[i],
31312ed1c7cSGregory Neil Shapiro 					     stats.stat_nd[i]);
31412ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
31512ed1c7cSGregory Neil Shapiro 					     "  %6ld", stats.stat_nq[i]);
316c2aa98e2SPeter Wemm 			if (mnames)
31712ed1c7cSGregory Neil Shapiro 				(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
31812ed1c7cSGregory Neil Shapiro 						     "  %s",
31912ed1c7cSGregory Neil Shapiro 						      mtable[i]);
32012ed1c7cSGregory Neil Shapiro 			(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n");
3213299c2f1SGregory Neil Shapiro 			frmsgs += stats.stat_nf[i];
3223299c2f1SGregory Neil Shapiro 			frbytes += stats.stat_bf[i];
3233299c2f1SGregory Neil Shapiro 			tomsgs += stats.stat_nt[i];
3243299c2f1SGregory Neil Shapiro 			tobytes += stats.stat_bt[i];
3253299c2f1SGregory Neil Shapiro 			rejmsgs += stats.stat_nr[i];
3263299c2f1SGregory Neil Shapiro 			dismsgs += stats.stat_nd[i];
32712ed1c7cSGregory Neil Shapiro 			quarmsgs += stats.stat_nq[i];
328c2aa98e2SPeter Wemm 		}
329c2aa98e2SPeter Wemm 	}
33076b7bf71SPeter Wemm 	if (progmode)
33176b7bf71SPeter Wemm 	{
33212ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
33312ed1c7cSGregory Neil Shapiro 				     " T %8ld %10ld %8ld %10ld   %6ld  %6ld",
33412ed1c7cSGregory Neil Shapiro 				     frmsgs, frbytes, tomsgs, tobytes, rejmsgs,
33512ed1c7cSGregory Neil Shapiro 				     dismsgs);
33612ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
33712ed1c7cSGregory Neil Shapiro 				     "  %6ld", quarmsgs);
33812ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n");
33912ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
34012ed1c7cSGregory Neil Shapiro 				     " C %8ld %8ld %6ld\n",
34112ed1c7cSGregory Neil Shapiro 				     stats.stat_cf, stats.stat_ct,
34212ed1c7cSGregory Neil Shapiro 				     stats.stat_cr);
3433299c2f1SGregory Neil Shapiro 		(void) close(fd);
34412ed1c7cSGregory Neil Shapiro 		if (trunc)
34512ed1c7cSGregory Neil Shapiro 		{
34688ad41d4SGregory Neil Shapiro 			fd = open(sfile, O_RDWR | O_TRUNC, 0600);
347e01d6f61SPeter Wemm 			if (fd >= 0)
3483299c2f1SGregory Neil Shapiro 				(void) close(fd);
34976b7bf71SPeter Wemm 		}
35012ed1c7cSGregory Neil Shapiro 	}
35176b7bf71SPeter Wemm 	else
35276b7bf71SPeter Wemm 	{
35312ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
35412ed1c7cSGregory Neil Shapiro 				     "=============================================================");
35512ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "========");
35612ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n");
35712ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
35812ed1c7cSGregory Neil Shapiro 				     " T %8ld %10ldK %8ld %10ldK   %6ld  %6ld",
35912ed1c7cSGregory Neil Shapiro 				     frmsgs, frbytes, tomsgs, tobytes, rejmsgs,
36012ed1c7cSGregory Neil Shapiro 				     dismsgs);
36112ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
36212ed1c7cSGregory Neil Shapiro 				     "  %6ld", quarmsgs);
36312ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n");
36412ed1c7cSGregory Neil Shapiro 		(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
36512ed1c7cSGregory Neil Shapiro 				     " C %8ld %10s  %8ld %10s    %6ld\n",
36612ed1c7cSGregory Neil Shapiro 				     stats.stat_cf, "", stats.stat_ct, "",
36712ed1c7cSGregory Neil Shapiro 				     stats.stat_cr);
36876b7bf71SPeter Wemm 	}
369c2aa98e2SPeter Wemm 	exit(EX_OK);
3703299c2f1SGregory Neil Shapiro 	/* NOTREACHED */
3713299c2f1SGregory Neil Shapiro 	return EX_OK;
372c2aa98e2SPeter Wemm }
373