138032Speter/* 2261370Sgshapiro * Copyright (c) 1998-2002 Proofpoint, Inc. and its suppliers. 364562Sgshapiro * All rights reserved. 438032Speter * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 538032Speter * Copyright (c) 1988, 1993 638032Speter * The Regents of the University of California. All rights reserved. 738032Speter * 838032Speter * By using this file, you agree to the terms and conditions set 938032Speter * forth in the LICENSE file which can be found at the top level of 1038032Speter * the sendmail distribution. 1138032Speter * 1238032Speter */ 1338032Speter 1490792Sgshapiro#include <sendmail.h> 1538032Speter 16266711SgshapiroSM_RCSID("@(#)$Id: stats.c,v 8.58 2013-11-22 20:51:56 ca Exp $") 1790792Sgshapiro 1864562Sgshapiro#include <sendmail/mailstats.h> 1938032Speter 2064562Sgshapirostatic struct statistics Stat; 2138032Speter 2290792Sgshapirostatic bool GotStats = false; /* set when we have stats to merge */ 2364562Sgshapiro 2464562Sgshapiro/* See http://physics.nist.gov/cuu/Units/binary.html */ 2538032Speter#define ONE_K 1000 /* one thousand (twenty-four?) */ 2638032Speter#define KBYTES(x) (((x) + (ONE_K - 1)) / ONE_K) 2790792Sgshapiro/* 2838032Speter** MARKSTATS -- mark statistics 2964562Sgshapiro** 3064562Sgshapiro** Parameters: 3164562Sgshapiro** e -- the envelope. 3264562Sgshapiro** to -- to address. 3390792Sgshapiro** type -- type of stats this represents. 3464562Sgshapiro** 3564562Sgshapiro** Returns: 3664562Sgshapiro** none. 3764562Sgshapiro** 3864562Sgshapiro** Side Effects: 3964562Sgshapiro** changes static Stat structure 4038032Speter*/ 4138032Speter 4238032Spetervoid 4390792Sgshapiromarkstats(e, to, type) 4438032Speter register ENVELOPE *e; 4538032Speter register ADDRESS *to; 4690792Sgshapiro int type; 4738032Speter{ 4890792Sgshapiro switch (type) 4938032Speter { 5090792Sgshapiro case STATS_QUARANTINE: 5138032Speter if (e->e_from.q_mailer != NULL) 5290792Sgshapiro Stat.stat_nq[e->e_from.q_mailer->m_mno]++; 5390792Sgshapiro break; 5490792Sgshapiro 5590792Sgshapiro case STATS_REJECT: 5690792Sgshapiro if (e->e_from.q_mailer != NULL) 5738032Speter { 5838032Speter if (bitset(EF_DISCARD, e->e_flags)) 5938032Speter Stat.stat_nd[e->e_from.q_mailer->m_mno]++; 6038032Speter else 6138032Speter Stat.stat_nr[e->e_from.q_mailer->m_mno]++; 6238032Speter } 6364562Sgshapiro Stat.stat_cr++; 6490792Sgshapiro break; 6590792Sgshapiro 6694334Sgshapiro case STATS_CONNECT: 6794334Sgshapiro if (to == NULL) 6894334Sgshapiro Stat.stat_cf++; 6994334Sgshapiro else 7094334Sgshapiro Stat.stat_ct++; 7194334Sgshapiro break; 7294334Sgshapiro 7390792Sgshapiro case STATS_NORMAL: 7490792Sgshapiro if (to == NULL) 7538032Speter { 7690792Sgshapiro if (e->e_from.q_mailer != NULL) 7790792Sgshapiro { 7890792Sgshapiro Stat.stat_nf[e->e_from.q_mailer->m_mno]++; 7990792Sgshapiro Stat.stat_bf[e->e_from.q_mailer->m_mno] += 8090792Sgshapiro KBYTES(e->e_msgsize); 8190792Sgshapiro } 8238032Speter } 8390792Sgshapiro else 8490792Sgshapiro { 8590792Sgshapiro Stat.stat_nt[to->q_mailer->m_mno]++; 8690792Sgshapiro Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(e->e_msgsize); 8790792Sgshapiro } 8890792Sgshapiro break; 8990792Sgshapiro 9090792Sgshapiro default: 9190792Sgshapiro /* Silently ignore bogus call */ 9290792Sgshapiro return; 9338032Speter } 9464562Sgshapiro 9564562Sgshapiro 9690792Sgshapiro GotStats = true; 9738032Speter} 9890792Sgshapiro/* 9964562Sgshapiro** CLEARSTATS -- clear statistics structure 10064562Sgshapiro** 10164562Sgshapiro** Parameters: 10264562Sgshapiro** none. 10364562Sgshapiro** 10464562Sgshapiro** Returns: 10564562Sgshapiro** none. 10664562Sgshapiro** 10764562Sgshapiro** Side Effects: 10864562Sgshapiro** clears the Stat structure. 10964562Sgshapiro*/ 11064562Sgshapiro 11164562Sgshapirovoid 11264562Sgshapiroclearstats() 11364562Sgshapiro{ 11464562Sgshapiro /* clear the structure to avoid future disappointment */ 115168515Sgshapiro memset(&Stat, '\0', sizeof(Stat)); 11690792Sgshapiro GotStats = false; 11764562Sgshapiro} 11890792Sgshapiro/* 11938032Speter** POSTSTATS -- post statistics in the statistics file 12038032Speter** 12138032Speter** Parameters: 12238032Speter** sfile -- the name of the statistics file. 12338032Speter** 12438032Speter** Returns: 12538032Speter** none. 12638032Speter** 12738032Speter** Side Effects: 12838032Speter** merges the Stat structure with the sfile file. 12938032Speter*/ 13038032Speter 13138032Spetervoid 13238032Speterpoststats(sfile) 13338032Speter char *sfile; 13438032Speter{ 13590792Sgshapiro int fd; 13690792Sgshapiro static bool entered = false; 13764562Sgshapiro long sff = SFF_REGONLY|SFF_OPENASROOT; 13864562Sgshapiro struct statistics stats; 13938032Speter extern off_t lseek(); 14038032Speter 14190792Sgshapiro if (sfile == NULL || *sfile == '\0' || !GotStats || entered) 14238032Speter return; 14390792Sgshapiro entered = true; 14438032Speter 14538032Speter (void) time(&Stat.stat_itime); 146168515Sgshapiro Stat.stat_size = sizeof(Stat); 14738032Speter Stat.stat_magic = STAT_MAGIC; 14838032Speter Stat.stat_version = STAT_VERSION; 14938032Speter 15064562Sgshapiro if (!bitnset(DBS_WRITESTATSTOSYMLINK, DontBlameSendmail)) 15138032Speter sff |= SFF_NOSLINK; 15264562Sgshapiro if (!bitnset(DBS_WRITESTATSTOHARDLINK, DontBlameSendmail)) 15338032Speter sff |= SFF_NOHLINK; 15438032Speter 15598121Sgshapiro fd = safeopen(sfile, O_RDWR, 0600, sff); 15638032Speter if (fd < 0) 15738032Speter { 15838032Speter if (LogLevel > 12) 15938032Speter sm_syslog(LOG_INFO, NOQID, "poststats: %s: %s", 16090792Sgshapiro sfile, sm_errstring(errno)); 16138032Speter errno = 0; 16290792Sgshapiro entered = false; 16338032Speter return; 16438032Speter } 165168515Sgshapiro if (read(fd, (char *) &stats, sizeof(stats)) == sizeof(stats) && 166168515Sgshapiro stats.stat_size == sizeof(stats) && 16764562Sgshapiro stats.stat_magic == Stat.stat_magic && 16864562Sgshapiro stats.stat_version == Stat.stat_version) 16938032Speter { 17038032Speter /* merge current statistics into statfile */ 17138032Speter register int i; 17238032Speter 17338032Speter for (i = 0; i < MAXMAILERS; i++) 17438032Speter { 17564562Sgshapiro stats.stat_nf[i] += Stat.stat_nf[i]; 17664562Sgshapiro stats.stat_bf[i] += Stat.stat_bf[i]; 17764562Sgshapiro stats.stat_nt[i] += Stat.stat_nt[i]; 17864562Sgshapiro stats.stat_bt[i] += Stat.stat_bt[i]; 17964562Sgshapiro stats.stat_nr[i] += Stat.stat_nr[i]; 18064562Sgshapiro stats.stat_nd[i] += Stat.stat_nd[i]; 18190792Sgshapiro stats.stat_nq[i] += Stat.stat_nq[i]; 18238032Speter } 18364562Sgshapiro stats.stat_cr += Stat.stat_cr; 18464562Sgshapiro stats.stat_ct += Stat.stat_ct; 18564562Sgshapiro stats.stat_cf += Stat.stat_cf; 18638032Speter } 18738032Speter else 188168515Sgshapiro memmove((char *) &stats, (char *) &Stat, sizeof(stats)); 18938032Speter 19038032Speter /* write out results */ 19138032Speter (void) lseek(fd, (off_t) 0, 0); 192168515Sgshapiro (void) write(fd, (char *) &stats, sizeof(stats)); 19338032Speter (void) close(fd); 19438032Speter 19538032Speter /* clear the structure to avoid future disappointment */ 19664562Sgshapiro clearstats(); 19790792Sgshapiro entered = false; 19838032Speter} 199