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