2 * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
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.
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.
16 SM_RCSID("@(#)$Id: stats.c,v 8.57 2006/08/15 23:24:58 ca Exp $")
18 #include <sendmail/mailstats.h>
20 static struct statistics Stat
;
22 static bool GotStats
= false; /* set when we have stats to merge */
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)
28 ** MARKSTATS -- mark statistics
33 ** type -- type of stats this represents.
39 ** changes static Stat structure
43 markstats(e
, to
, type
)
50 case STATS_QUARANTINE
:
51 if (e
->e_from
.q_mailer
!= NULL
)
52 Stat
.stat_nq
[e
->e_from
.q_mailer
->m_mno
]++;
56 if (e
->e_from
.q_mailer
!= NULL
)
58 if (bitset(EF_DISCARD
, e
->e_flags
))
59 Stat
.stat_nd
[e
->e_from
.q_mailer
->m_mno
]++;
61 Stat
.stat_nr
[e
->e_from
.q_mailer
->m_mno
]++;
76 if (e
->e_from
.q_mailer
!= NULL
)
78 Stat
.stat_nf
[e
->e_from
.q_mailer
->m_mno
]++;
79 Stat
.stat_bf
[e
->e_from
.q_mailer
->m_mno
] +=
85 Stat
.stat_nt
[to
->q_mailer
->m_mno
]++;
86 Stat
.stat_bt
[to
->q_mailer
->m_mno
] += KBYTES(e
->e_msgsize
);
91 /* Silently ignore bogus call */
99 ** CLEARSTATS -- clear statistics structure
108 ** clears the Stat structure.
114 /* clear the structure to avoid future disappointment */
115 memset(&Stat
, '\0', sizeof(Stat
));
119 ** POSTSTATS -- post statistics in the statistics file
122 ** sfile -- the name of the statistics file.
128 ** merges the Stat structure with the sfile file.
136 static bool entered
= false;
137 long sff
= SFF_REGONLY
|SFF_OPENASROOT
;
138 struct statistics stats
;
139 extern off_t
lseek();
141 if (sfile
== NULL
|| *sfile
== '\0' || !GotStats
|| entered
)
145 (void) time(&Stat
.stat_itime
);
146 Stat
.stat_size
= sizeof(Stat
);
147 Stat
.stat_magic
= STAT_MAGIC
;
148 Stat
.stat_version
= STAT_VERSION
;
150 if (!bitnset(DBS_WRITESTATSTOSYMLINK
, DontBlameSendmail
))
152 if (!bitnset(DBS_WRITESTATSTOHARDLINK
, DontBlameSendmail
))
155 fd
= safeopen(sfile
, O_RDWR
, 0600, sff
);
159 sm_syslog(LOG_INFO
, NOQID
, "poststats: %s: %s",
160 sfile
, sm_errstring(errno
));
165 if (read(fd
, (char *) &stats
, sizeof(stats
)) == sizeof(stats
) &&
166 stats
.stat_size
== sizeof(stats
) &&
167 stats
.stat_magic
== Stat
.stat_magic
&&
168 stats
.stat_version
== Stat
.stat_version
)
170 /* merge current statistics into statfile */
173 for (i
= 0; i
< MAXMAILERS
; i
++)
175 stats
.stat_nf
[i
] += Stat
.stat_nf
[i
];
176 stats
.stat_bf
[i
] += Stat
.stat_bf
[i
];
177 stats
.stat_nt
[i
] += Stat
.stat_nt
[i
];
178 stats
.stat_bt
[i
] += Stat
.stat_bt
[i
];
179 stats
.stat_nr
[i
] += Stat
.stat_nr
[i
];
180 stats
.stat_nd
[i
] += Stat
.stat_nd
[i
];
181 stats
.stat_nq
[i
] += Stat
.stat_nq
[i
];
183 stats
.stat_cr
+= Stat
.stat_cr
;
184 stats
.stat_ct
+= Stat
.stat_ct
;
185 stats
.stat_cf
+= Stat
.stat_cf
;
188 memmove((char *) &stats
, (char *) &Stat
, sizeof(stats
));
190 /* write out results */
191 (void) lseek(fd
, (off_t
) 0, 0);
192 (void) write(fd
, (char *) &stats
, sizeof(stats
));
195 /* clear the structure to avoid future disappointment */