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 | } |
---|