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

Revision 19204, 4.3 KB checked in by zacheiss, 21 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, 1995-1997 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#include <sendmail.h>
15
16SM_RCSID("@(#)$Id: stats.c,v 1.1.1.1 2003-04-08 15:07:32 zacheiss Exp $")
17
18#include <sendmail/mailstats.h>
19
20static struct statistics        Stat;
21
22static bool     GotStats = false;       /* set when we have stats to merge */
23
24/* See http://physics.nist.gov/cuu/Units/binary.html */
25#define ONE_K           1000            /* one thousand (twenty-four?) */
26#define KBYTES(x)       (((x) + (ONE_K - 1)) / ONE_K)
27/*
28**  MARKSTATS -- mark statistics
29**
30**      Parameters:
31**              e -- the envelope.
32**              to -- to address.
33**              type -- type of stats this represents.
34**
35**      Returns:
36**              none.
37**
38**      Side Effects:
39**              changes static Stat structure
40*/
41
42void
43markstats(e, to, type)
44        register ENVELOPE *e;
45        register ADDRESS *to;
46        int type;
47{
48        switch (type)
49        {
50#if _FFR_QUARANTINE
51          case STATS_QUARANTINE:
52                if (e->e_from.q_mailer != NULL)
53                        Stat.stat_nq[e->e_from.q_mailer->m_mno]++;
54                break;
55#endif /* _FFR_QUARANTINE */
56
57          case STATS_REJECT:
58                if (e->e_from.q_mailer != NULL)
59                {
60                        if (bitset(EF_DISCARD, e->e_flags))
61                                Stat.stat_nd[e->e_from.q_mailer->m_mno]++;
62                        else
63                                Stat.stat_nr[e->e_from.q_mailer->m_mno]++;
64                }
65                Stat.stat_cr++;
66                break;
67
68          case STATS_CONNECT:
69                if (to == NULL)
70                        Stat.stat_cf++;
71                else
72                        Stat.stat_ct++;
73                break;
74
75          case STATS_NORMAL:
76                if (to == NULL)
77                {
78                        if (e->e_from.q_mailer != NULL)
79                        {
80                                Stat.stat_nf[e->e_from.q_mailer->m_mno]++;
81                                Stat.stat_bf[e->e_from.q_mailer->m_mno] +=
82                                        KBYTES(e->e_msgsize);
83                        }
84                }
85                else
86                {
87                        Stat.stat_nt[to->q_mailer->m_mno]++;
88                        Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(e->e_msgsize);
89                }
90                break;
91
92          default:
93                /* Silently ignore bogus call */
94                return;
95        }
96
97
98        GotStats = true;
99}
100/*
101**  CLEARSTATS -- clear statistics structure
102**
103**      Parameters:
104**              none.
105**
106**      Returns:
107**              none.
108**
109**      Side Effects:
110**              clears the Stat structure.
111*/
112
113void
114clearstats()
115{
116        /* clear the structure to avoid future disappointment */
117        memset(&Stat, '\0', sizeof Stat);
118        GotStats = false;
119}
120/*
121**  POSTSTATS -- post statistics in the statistics file
122**
123**      Parameters:
124**              sfile -- the name of the statistics file.
125**
126**      Returns:
127**              none.
128**
129**      Side Effects:
130**              merges the Stat structure with the sfile file.
131*/
132
133void
134poststats(sfile)
135        char *sfile;
136{
137        int fd;
138        static bool entered = false;
139        long sff = SFF_REGONLY|SFF_OPENASROOT;
140        struct statistics stats;
141        extern off_t lseek();
142
143        if (sfile == NULL || *sfile == '\0' || !GotStats || entered)
144                return;
145        entered = true;
146
147        (void) time(&Stat.stat_itime);
148        Stat.stat_size = sizeof Stat;
149        Stat.stat_magic = STAT_MAGIC;
150        Stat.stat_version = STAT_VERSION;
151
152        if (!bitnset(DBS_WRITESTATSTOSYMLINK, DontBlameSendmail))
153                sff |= SFF_NOSLINK;
154        if (!bitnset(DBS_WRITESTATSTOHARDLINK, DontBlameSendmail))
155                sff |= SFF_NOHLINK;
156
157        fd = safeopen(sfile, O_RDWR, 0600, sff);
158        if (fd < 0)
159        {
160                if (LogLevel > 12)
161                        sm_syslog(LOG_INFO, NOQID, "poststats: %s: %s",
162                                  sfile, sm_errstring(errno));
163                errno = 0;
164                entered = false;
165                return;
166        }
167        if (read(fd, (char *) &stats, sizeof stats) == sizeof stats &&
168            stats.stat_size == sizeof stats &&
169            stats.stat_magic == Stat.stat_magic &&
170            stats.stat_version == Stat.stat_version)
171        {
172                /* merge current statistics into statfile */
173                register int i;
174
175                for (i = 0; i < MAXMAILERS; i++)
176                {
177                        stats.stat_nf[i] += Stat.stat_nf[i];
178                        stats.stat_bf[i] += Stat.stat_bf[i];
179                        stats.stat_nt[i] += Stat.stat_nt[i];
180                        stats.stat_bt[i] += Stat.stat_bt[i];
181                        stats.stat_nr[i] += Stat.stat_nr[i];
182                        stats.stat_nd[i] += Stat.stat_nd[i];
183#if _FFR_QUARANTINE
184                        stats.stat_nq[i] += Stat.stat_nq[i];
185#endif /* _FFR_QUARANTINE */
186                }
187                stats.stat_cr += Stat.stat_cr;
188                stats.stat_ct += Stat.stat_ct;
189                stats.stat_cf += Stat.stat_cf;
190        }
191        else
192                memmove((char *) &stats, (char *) &Stat, sizeof stats);
193
194        /* write out results */
195        (void) lseek(fd, (off_t) 0, 0);
196        (void) write(fd, (char *) &stats, sizeof stats);
197        (void) close(fd);
198
199        /* clear the structure to avoid future disappointment */
200        clearstats();
201        entered = false;
202}
Note: See TracBrowser for help on using the repository browser.