xref: /freebsd/contrib/sendmail/src/stats.c (revision 7f3dea244c40159a41ab22da77a434d7c5b5e85a)
1 /*
2  * Copyright (c) 1998 Sendmail, Inc.  All rights reserved.
3  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
4  * Copyright (c) 1988, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * By using this file, you agree to the terms and conditions set
8  * forth in the LICENSE file which can be found at the top level of
9  * the sendmail distribution.
10  *
11  */
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)stats.c	8.22 (Berkeley) 5/19/1998";
15 #endif /* not lint */
16 
17 # include "sendmail.h"
18 # include "mailstats.h"
19 
20 struct statistics	Stat;
21 
22 bool	GotStats = FALSE;	/* set when we have stats to merge */
23 
24 #define ONE_K		1000		/* one thousand (twenty-four?) */
25 #define KBYTES(x)	(((x) + (ONE_K - 1)) / ONE_K)
26 /*
27 **  MARKSTATS -- mark statistics
28 */
29 
30 void
31 markstats(e, to, reject)
32 	register ENVELOPE *e;
33 	register ADDRESS *to;
34 	bool reject;
35 {
36 	if (reject == TRUE)
37 	{
38 		if (e->e_from.q_mailer != NULL)
39 		{
40 			if (bitset(EF_DISCARD, e->e_flags))
41 				Stat.stat_nd[e->e_from.q_mailer->m_mno]++;
42 			else
43 				Stat.stat_nr[e->e_from.q_mailer->m_mno]++;
44 		}
45 	}
46 	else if (to == NULL)
47 	{
48 		if (e->e_from.q_mailer != NULL)
49 		{
50 			Stat.stat_nf[e->e_from.q_mailer->m_mno]++;
51 			Stat.stat_bf[e->e_from.q_mailer->m_mno] +=
52 				KBYTES(e->e_msgsize);
53 		}
54 	}
55 	else
56 	{
57 		Stat.stat_nt[to->q_mailer->m_mno]++;
58 		Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(e->e_msgsize);
59 	}
60 	GotStats = TRUE;
61 }
62 /*
63 **  POSTSTATS -- post statistics in the statistics file
64 **
65 **	Parameters:
66 **		sfile -- the name of the statistics file.
67 **
68 **	Returns:
69 **		none.
70 **
71 **	Side Effects:
72 **		merges the Stat structure with the sfile file.
73 */
74 
75 void
76 poststats(sfile)
77 	char *sfile;
78 {
79 	register int fd;
80 	int sff = SFF_REGONLY|SFF_OPENASROOT;
81 	struct statistics stat;
82 	extern off_t lseek();
83 
84 	if (sfile == NULL || !GotStats)
85 		return;
86 
87 	(void) time(&Stat.stat_itime);
88 	Stat.stat_size = sizeof Stat;
89 	Stat.stat_magic = STAT_MAGIC;
90 	Stat.stat_version = STAT_VERSION;
91 
92 	if (!bitset(DBS_WRITESTATSTOSYMLINK, DontBlameSendmail))
93 		sff |= SFF_NOSLINK;
94 	if (!bitset(DBS_WRITESTATSTOHARDLINK, DontBlameSendmail))
95 		sff |= SFF_NOHLINK;
96 
97 	fd = safeopen(sfile, O_RDWR, 0644, sff);
98 	if (fd < 0)
99 	{
100 		if (LogLevel > 12)
101 			sm_syslog(LOG_INFO, NOQID, "poststats: %s: %s",
102 				  sfile, errstring(errno));
103 		errno = 0;
104 		return;
105 	}
106 	if (read(fd, (char *) &stat, sizeof stat) == sizeof stat &&
107 	    stat.stat_size == sizeof stat &&
108 	    stat.stat_magic == Stat.stat_magic &&
109 	    stat.stat_version == Stat.stat_version)
110 	{
111 		/* merge current statistics into statfile */
112 		register int i;
113 
114 		for (i = 0; i < MAXMAILERS; i++)
115 		{
116 			stat.stat_nf[i] += Stat.stat_nf[i];
117 			stat.stat_bf[i] += Stat.stat_bf[i];
118 			stat.stat_nt[i] += Stat.stat_nt[i];
119 			stat.stat_bt[i] += Stat.stat_bt[i];
120 			stat.stat_nr[i] += Stat.stat_nr[i];
121 			stat.stat_nd[i] += Stat.stat_nd[i];
122 		}
123 	}
124 	else
125 		bcopy((char *) &Stat, (char *) &stat, sizeof stat);
126 
127 	/* write out results */
128 	(void) lseek(fd, (off_t) 0, 0);
129 	(void) write(fd, (char *) &stat, sizeof stat);
130 	(void) close(fd);
131 
132 	/* clear the structure to avoid future disappointment */
133 	bzero(&Stat, sizeof stat);
134 	GotStats = FALSE;
135 }
136