summaryrefslogtreecommitdiffstats
path: root/sendmail/src/stats.c
diff options
context:
space:
mode:
Diffstat (limited to 'sendmail/src/stats.c')
-rw-r--r--sendmail/src/stats.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/sendmail/src/stats.c b/sendmail/src/stats.c
new file mode 100644
index 0000000..16a9c6d
--- /dev/null
+++ b/sendmail/src/stats.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
+ * All rights reserved.
+ * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ *
+ */
+
+#include <sendmail.h>
+
+SM_RCSID("@(#)$Id: stats.c,v 8.57 2006/08/15 23:24:58 ca Exp $")
+
+#include <sendmail/mailstats.h>
+
+static struct statistics Stat;
+
+static bool GotStats = false; /* set when we have stats to merge */
+
+/* See http://physics.nist.gov/cuu/Units/binary.html */
+#define ONE_K 1000 /* one thousand (twenty-four?) */
+#define KBYTES(x) (((x) + (ONE_K - 1)) / ONE_K)
+/*
+** MARKSTATS -- mark statistics
+**
+** Parameters:
+** e -- the envelope.
+** to -- to address.
+** type -- type of stats this represents.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** changes static Stat structure
+*/
+
+void
+markstats(e, to, type)
+ register ENVELOPE *e;
+ register ADDRESS *to;
+ int type;
+{
+ switch (type)
+ {
+ case STATS_QUARANTINE:
+ if (e->e_from.q_mailer != NULL)
+ Stat.stat_nq[e->e_from.q_mailer->m_mno]++;
+ break;
+
+ case STATS_REJECT:
+ if (e->e_from.q_mailer != NULL)
+ {
+ if (bitset(EF_DISCARD, e->e_flags))
+ Stat.stat_nd[e->e_from.q_mailer->m_mno]++;
+ else
+ Stat.stat_nr[e->e_from.q_mailer->m_mno]++;
+ }
+ Stat.stat_cr++;
+ break;
+
+ case STATS_CONNECT:
+ if (to == NULL)
+ Stat.stat_cf++;
+ else
+ Stat.stat_ct++;
+ break;
+
+ case STATS_NORMAL:
+ if (to == NULL)
+ {
+ if (e->e_from.q_mailer != NULL)
+ {
+ Stat.stat_nf[e->e_from.q_mailer->m_mno]++;
+ Stat.stat_bf[e->e_from.q_mailer->m_mno] +=
+ KBYTES(e->e_msgsize);
+ }
+ }
+ else
+ {
+ Stat.stat_nt[to->q_mailer->m_mno]++;
+ Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(e->e_msgsize);
+ }
+ break;
+
+ default:
+ /* Silently ignore bogus call */
+ return;
+ }
+
+
+ GotStats = true;
+}
+/*
+** CLEARSTATS -- clear statistics structure
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** clears the Stat structure.
+*/
+
+void
+clearstats()
+{
+ /* clear the structure to avoid future disappointment */
+ memset(&Stat, '\0', sizeof(Stat));
+ GotStats = false;
+}
+/*
+** POSTSTATS -- post statistics in the statistics file
+**
+** Parameters:
+** sfile -- the name of the statistics file.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** merges the Stat structure with the sfile file.
+*/
+
+void
+poststats(sfile)
+ char *sfile;
+{
+ int fd;
+ static bool entered = false;
+ long sff = SFF_REGONLY|SFF_OPENASROOT;
+ struct statistics stats;
+ extern off_t lseek();
+
+ if (sfile == NULL || *sfile == '\0' || !GotStats || entered)
+ return;
+ entered = true;
+
+ (void) time(&Stat.stat_itime);
+ Stat.stat_size = sizeof(Stat);
+ Stat.stat_magic = STAT_MAGIC;
+ Stat.stat_version = STAT_VERSION;
+
+ if (!bitnset(DBS_WRITESTATSTOSYMLINK, DontBlameSendmail))
+ sff |= SFF_NOSLINK;
+ if (!bitnset(DBS_WRITESTATSTOHARDLINK, DontBlameSendmail))
+ sff |= SFF_NOHLINK;
+
+ fd = safeopen(sfile, O_RDWR, 0600, sff);
+ if (fd < 0)
+ {
+ if (LogLevel > 12)
+ sm_syslog(LOG_INFO, NOQID, "poststats: %s: %s",
+ sfile, sm_errstring(errno));
+ errno = 0;
+ entered = false;
+ return;
+ }
+ if (read(fd, (char *) &stats, sizeof(stats)) == sizeof(stats) &&
+ stats.stat_size == sizeof(stats) &&
+ stats.stat_magic == Stat.stat_magic &&
+ stats.stat_version == Stat.stat_version)
+ {
+ /* merge current statistics into statfile */
+ register int i;
+
+ for (i = 0; i < MAXMAILERS; i++)
+ {
+ stats.stat_nf[i] += Stat.stat_nf[i];
+ stats.stat_bf[i] += Stat.stat_bf[i];
+ stats.stat_nt[i] += Stat.stat_nt[i];
+ stats.stat_bt[i] += Stat.stat_bt[i];
+ stats.stat_nr[i] += Stat.stat_nr[i];
+ stats.stat_nd[i] += Stat.stat_nd[i];
+ stats.stat_nq[i] += Stat.stat_nq[i];
+ }
+ stats.stat_cr += Stat.stat_cr;
+ stats.stat_ct += Stat.stat_ct;
+ stats.stat_cf += Stat.stat_cf;
+ }
+ else
+ memmove((char *) &stats, (char *) &Stat, sizeof(stats));
+
+ /* write out results */
+ (void) lseek(fd, (off_t) 0, 0);
+ (void) write(fd, (char *) &stats, sizeof(stats));
+ (void) close(fd);
+
+ /* clear the structure to avoid future disappointment */
+ clearstats();
+ entered = false;
+}
OpenPOWER on IntegriCloud