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