xref: /freebsd-src/contrib/sendmail/src/stats.c (revision 2fb4f839f3fc72ce2bab12f9ba4760f97f73e97f)
1c2aa98e2SPeter Wemm /*
25dd76dd0SGregory Neil Shapiro  * Copyright (c) 1998-2002 Proofpoint, Inc. and its suppliers.
306f25ae9SGregory Neil Shapiro  *	All rights reserved.
4c2aa98e2SPeter Wemm  * Copyright (c) 1983, 1995-1997 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 
1406f25ae9SGregory Neil Shapiro #include <sendmail.h>
15c2aa98e2SPeter Wemm 
164313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: stats.c,v 8.58 2013-11-22 20:51:56 ca Exp $")
1740266059SGregory Neil Shapiro 
1840266059SGregory Neil Shapiro #include <sendmail/mailstats.h>
19c2aa98e2SPeter Wemm 
2006f25ae9SGregory Neil Shapiro static struct statistics	Stat;
21c2aa98e2SPeter Wemm 
2240266059SGregory Neil Shapiro static bool	GotStats = false;	/* set when we have stats to merge */
2306f25ae9SGregory Neil Shapiro 
2406f25ae9SGregory Neil Shapiro /* See http://physics.nist.gov/cuu/Units/binary.html */
25c2aa98e2SPeter Wemm #define ONE_K		1000		/* one thousand (twenty-four?) */
26c2aa98e2SPeter Wemm #define KBYTES(x)	(((x) + (ONE_K - 1)) / ONE_K)
2740266059SGregory Neil Shapiro /*
28c2aa98e2SPeter Wemm **  MARKSTATS -- mark statistics
2906f25ae9SGregory Neil Shapiro **
3006f25ae9SGregory Neil Shapiro **	Parameters:
3106f25ae9SGregory Neil Shapiro **		e -- the envelope.
3206f25ae9SGregory Neil Shapiro **		to -- to address.
3340266059SGregory Neil Shapiro **		type -- type of stats this represents.
3406f25ae9SGregory Neil Shapiro **
3506f25ae9SGregory Neil Shapiro **	Returns:
3606f25ae9SGregory Neil Shapiro **		none.
3706f25ae9SGregory Neil Shapiro **
3806f25ae9SGregory Neil Shapiro **	Side Effects:
3906f25ae9SGregory Neil Shapiro **		changes static Stat structure
40c2aa98e2SPeter Wemm */
41c2aa98e2SPeter Wemm 
42c2aa98e2SPeter Wemm void
markstats(e,to,type)4340266059SGregory Neil Shapiro markstats(e, to, type)
44c2aa98e2SPeter Wemm 	register ENVELOPE *e;
45c2aa98e2SPeter Wemm 	register ADDRESS *to;
4640266059SGregory Neil Shapiro 	int type;
47c2aa98e2SPeter Wemm {
4840266059SGregory Neil Shapiro 	switch (type)
49c2aa98e2SPeter Wemm 	{
5040266059SGregory Neil Shapiro 	  case STATS_QUARANTINE:
5140266059SGregory Neil Shapiro 		if (e->e_from.q_mailer != NULL)
5240266059SGregory Neil Shapiro 			Stat.stat_nq[e->e_from.q_mailer->m_mno]++;
5340266059SGregory Neil Shapiro 		break;
5440266059SGregory Neil Shapiro 
5540266059SGregory Neil Shapiro 	  case STATS_REJECT:
56c2aa98e2SPeter Wemm 		if (e->e_from.q_mailer != NULL)
57c2aa98e2SPeter Wemm 		{
58c2aa98e2SPeter Wemm 			if (bitset(EF_DISCARD, e->e_flags))
59c2aa98e2SPeter Wemm 				Stat.stat_nd[e->e_from.q_mailer->m_mno]++;
60c2aa98e2SPeter Wemm 			else
61c2aa98e2SPeter Wemm 				Stat.stat_nr[e->e_from.q_mailer->m_mno]++;
62c2aa98e2SPeter Wemm 		}
6306f25ae9SGregory Neil Shapiro 		Stat.stat_cr++;
6440266059SGregory Neil Shapiro 		break;
6540266059SGregory Neil Shapiro 
66605302a5SGregory Neil Shapiro 	  case STATS_CONNECT:
67605302a5SGregory Neil Shapiro 		if (to == NULL)
68605302a5SGregory Neil Shapiro 			Stat.stat_cf++;
69605302a5SGregory Neil Shapiro 		else
70605302a5SGregory Neil Shapiro 			Stat.stat_ct++;
71605302a5SGregory Neil Shapiro 		break;
72605302a5SGregory Neil Shapiro 
7340266059SGregory Neil Shapiro 	  case STATS_NORMAL:
7440266059SGregory Neil Shapiro 		if (to == NULL)
75c2aa98e2SPeter Wemm 		{
76c2aa98e2SPeter Wemm 			if (e->e_from.q_mailer != NULL)
77c2aa98e2SPeter Wemm 			{
78c2aa98e2SPeter Wemm 				Stat.stat_nf[e->e_from.q_mailer->m_mno]++;
79c2aa98e2SPeter Wemm 				Stat.stat_bf[e->e_from.q_mailer->m_mno] +=
80c2aa98e2SPeter Wemm 					KBYTES(e->e_msgsize);
81c2aa98e2SPeter Wemm 			}
82c2aa98e2SPeter Wemm 		}
83c2aa98e2SPeter Wemm 		else
84c2aa98e2SPeter Wemm 		{
85c2aa98e2SPeter Wemm 			Stat.stat_nt[to->q_mailer->m_mno]++;
86c2aa98e2SPeter Wemm 			Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(e->e_msgsize);
87c2aa98e2SPeter Wemm 		}
8840266059SGregory Neil Shapiro 		break;
8906f25ae9SGregory Neil Shapiro 
9040266059SGregory Neil Shapiro 	  default:
9140266059SGregory Neil Shapiro 		/* Silently ignore bogus call */
9240266059SGregory Neil Shapiro 		return;
93c2aa98e2SPeter Wemm 	}
9440266059SGregory Neil Shapiro 
9540266059SGregory Neil Shapiro 
9640266059SGregory Neil Shapiro 	GotStats = true;
9740266059SGregory Neil Shapiro }
9840266059SGregory Neil Shapiro /*
9906f25ae9SGregory Neil Shapiro **  CLEARSTATS -- clear statistics structure
10006f25ae9SGregory Neil Shapiro **
10106f25ae9SGregory Neil Shapiro **	Parameters:
10206f25ae9SGregory Neil Shapiro **		none.
10306f25ae9SGregory Neil Shapiro **
10406f25ae9SGregory Neil Shapiro **	Returns:
10506f25ae9SGregory Neil Shapiro **		none.
10606f25ae9SGregory Neil Shapiro **
10706f25ae9SGregory Neil Shapiro **	Side Effects:
10806f25ae9SGregory Neil Shapiro **		clears the Stat structure.
10906f25ae9SGregory Neil Shapiro */
11006f25ae9SGregory Neil Shapiro 
11106f25ae9SGregory Neil Shapiro void
clearstats()11206f25ae9SGregory Neil Shapiro clearstats()
11306f25ae9SGregory Neil Shapiro {
11406f25ae9SGregory Neil Shapiro 	/* clear the structure to avoid future disappointment */
115d0cef73dSGregory Neil Shapiro 	memset(&Stat, '\0', sizeof(Stat));
11640266059SGregory Neil Shapiro 	GotStats = false;
11706f25ae9SGregory Neil Shapiro }
11840266059SGregory Neil Shapiro /*
119c2aa98e2SPeter Wemm **  POSTSTATS -- post statistics in the statistics file
120c2aa98e2SPeter Wemm **
121c2aa98e2SPeter Wemm **	Parameters:
122c2aa98e2SPeter Wemm **		sfile -- the name of the statistics file.
123c2aa98e2SPeter Wemm **
124c2aa98e2SPeter Wemm **	Returns:
125c2aa98e2SPeter Wemm **		none.
126c2aa98e2SPeter Wemm **
127c2aa98e2SPeter Wemm **	Side Effects:
128c2aa98e2SPeter Wemm **		merges the Stat structure with the sfile file.
129c2aa98e2SPeter Wemm */
130c2aa98e2SPeter Wemm 
131c2aa98e2SPeter Wemm void
poststats(sfile)132c2aa98e2SPeter Wemm poststats(sfile)
133c2aa98e2SPeter Wemm 	char *sfile;
134c2aa98e2SPeter Wemm {
13540266059SGregory Neil Shapiro 	int fd;
13640266059SGregory Neil Shapiro 	static bool entered = false;
13706f25ae9SGregory Neil Shapiro 	long sff = SFF_REGONLY|SFF_OPENASROOT;
13806f25ae9SGregory Neil Shapiro 	struct statistics stats;
139*2fb4f839SGregory Neil Shapiro 	extern off_t lseek __P((int, off_t, int));
140c2aa98e2SPeter Wemm 
14140266059SGregory Neil Shapiro 	if (sfile == NULL || *sfile == '\0' || !GotStats || entered)
142c2aa98e2SPeter Wemm 		return;
14340266059SGregory Neil Shapiro 	entered = true;
144c2aa98e2SPeter Wemm 
145c2aa98e2SPeter Wemm 	(void) time(&Stat.stat_itime);
146d0cef73dSGregory Neil Shapiro 	Stat.stat_size = sizeof(Stat);
147c2aa98e2SPeter Wemm 	Stat.stat_magic = STAT_MAGIC;
148c2aa98e2SPeter Wemm 	Stat.stat_version = STAT_VERSION;
149c2aa98e2SPeter Wemm 
15006f25ae9SGregory Neil Shapiro 	if (!bitnset(DBS_WRITESTATSTOSYMLINK, DontBlameSendmail))
151c2aa98e2SPeter Wemm 		sff |= SFF_NOSLINK;
15206f25ae9SGregory Neil Shapiro 	if (!bitnset(DBS_WRITESTATSTOHARDLINK, DontBlameSendmail))
153c2aa98e2SPeter Wemm 		sff |= SFF_NOHLINK;
154c2aa98e2SPeter Wemm 
15594c01205SGregory Neil Shapiro 	fd = safeopen(sfile, O_RDWR, 0600, sff);
156c2aa98e2SPeter Wemm 	if (fd < 0)
157c2aa98e2SPeter Wemm 	{
158c2aa98e2SPeter Wemm 		if (LogLevel > 12)
159c2aa98e2SPeter Wemm 			sm_syslog(LOG_INFO, NOQID, "poststats: %s: %s",
16040266059SGregory Neil Shapiro 				  sfile, sm_errstring(errno));
161c2aa98e2SPeter Wemm 		errno = 0;
16240266059SGregory Neil Shapiro 		entered = false;
163c2aa98e2SPeter Wemm 		return;
164c2aa98e2SPeter Wemm 	}
165d0cef73dSGregory Neil Shapiro 	if (read(fd, (char *) &stats, sizeof(stats)) == sizeof(stats) &&
166d0cef73dSGregory Neil Shapiro 	    stats.stat_size == sizeof(stats) &&
16706f25ae9SGregory Neil Shapiro 	    stats.stat_magic == Stat.stat_magic &&
16806f25ae9SGregory Neil Shapiro 	    stats.stat_version == Stat.stat_version)
169c2aa98e2SPeter Wemm 	{
170c2aa98e2SPeter Wemm 		/* merge current statistics into statfile */
171c2aa98e2SPeter Wemm 		register int i;
172c2aa98e2SPeter Wemm 
173c2aa98e2SPeter Wemm 		for (i = 0; i < MAXMAILERS; i++)
174c2aa98e2SPeter Wemm 		{
17506f25ae9SGregory Neil Shapiro 			stats.stat_nf[i] += Stat.stat_nf[i];
17606f25ae9SGregory Neil Shapiro 			stats.stat_bf[i] += Stat.stat_bf[i];
17706f25ae9SGregory Neil Shapiro 			stats.stat_nt[i] += Stat.stat_nt[i];
17806f25ae9SGregory Neil Shapiro 			stats.stat_bt[i] += Stat.stat_bt[i];
17906f25ae9SGregory Neil Shapiro 			stats.stat_nr[i] += Stat.stat_nr[i];
18006f25ae9SGregory Neil Shapiro 			stats.stat_nd[i] += Stat.stat_nd[i];
18140266059SGregory Neil Shapiro 			stats.stat_nq[i] += Stat.stat_nq[i];
182c2aa98e2SPeter Wemm 		}
18306f25ae9SGregory Neil Shapiro 		stats.stat_cr += Stat.stat_cr;
18406f25ae9SGregory Neil Shapiro 		stats.stat_ct += Stat.stat_ct;
18506f25ae9SGregory Neil Shapiro 		stats.stat_cf += Stat.stat_cf;
186c2aa98e2SPeter Wemm 	}
187c2aa98e2SPeter Wemm 	else
188d0cef73dSGregory Neil Shapiro 		memmove((char *) &stats, (char *) &Stat, sizeof(stats));
189c2aa98e2SPeter Wemm 
190c2aa98e2SPeter Wemm 	/* write out results */
191c2aa98e2SPeter Wemm 	(void) lseek(fd, (off_t) 0, 0);
192d0cef73dSGregory Neil Shapiro 	(void) write(fd, (char *) &stats, sizeof(stats));
193c2aa98e2SPeter Wemm 	(void) close(fd);
194c2aa98e2SPeter Wemm 
195c2aa98e2SPeter Wemm 	/* clear the structure to avoid future disappointment */
19606f25ae9SGregory Neil Shapiro 	clearstats();
19740266059SGregory Neil Shapiro 	entered = false;
198c2aa98e2SPeter Wemm }
199