1 /* 2 ** Sendmail 3 ** Copyright (c) 1983 Eric P. Allman 4 ** Berkeley, California 5 ** 6 ** Copyright (c) 1983 Regents of the University of California. 7 ** All rights reserved. The Berkeley software License Agreement 8 ** specifies the terms and conditions for redistribution. 9 */ 10 11 #ifndef lint 12 static char SccsId[] = "@(#)stats.c 5.6 (Berkeley) 09/19/85"; 13 #endif not lint 14 15 # include "sendmail.h" 16 17 /* 18 ** Statistics structure. 19 */ 20 21 struct statistics 22 { 23 time_t stat_itime; /* file initialization time */ 24 short stat_size; /* size of this structure */ 25 long stat_nf[MAXMAILERS]; /* # msgs from each mailer */ 26 long stat_bf[MAXMAILERS]; /* kbytes from each mailer */ 27 long stat_nt[MAXMAILERS]; /* # msgs to each mailer */ 28 long stat_bt[MAXMAILERS]; /* kbytes to each mailer */ 29 }; 30 31 struct statistics Stat; 32 33 #define ONE_K 1000 /* one thousand (twenty-four?) */ 34 #define KBYTES(x) (((x) + (ONE_K - 1)) / ONE_K) 35 /* 36 ** MARKSTATS -- mark statistics 37 */ 38 39 markstats(e, to) 40 register ENVELOPE *e; 41 register ADDRESS *to; 42 { 43 if (to == NULL) 44 { 45 Stat.stat_bf[e->e_from.q_mailer->m_mno] += KBYTES(CurEnv->e_msgsize); 46 47 /* 48 ** If is possible to get mail from an unparseable address, 49 ** in this case, the q_mailer field is null, so that the 50 ** indirection below causes a dereference of a NULL pointer. 51 */ 52 53 if (e->e_from.q_mailer != NULL ) 54 { 55 Stat.stat_nf[e->e_from.q_mailer->m_mno]++; 56 Stat.stat_bf[e->e_from.q_mailer->m_mno] += 57 KBYTES(CurEnv->e_msgsize); 58 } 59 } 60 else 61 { 62 Stat.stat_nt[to->q_mailer->m_mno]++; 63 Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(CurEnv->e_msgsize); 64 } 65 } 66 /* 67 ** POSTSTATS -- post statistics in the statistics file 68 ** 69 ** Parameters: 70 ** sfile -- the name of the statistics file. 71 ** 72 ** Returns: 73 ** none. 74 ** 75 ** Side Effects: 76 ** merges the Stat structure with the sfile file. 77 */ 78 79 poststats(sfile) 80 char *sfile; 81 { 82 register int fd; 83 struct statistics stat; 84 extern off_t lseek(); 85 86 if (sfile == NULL) 87 return; 88 89 (void) time(&Stat.stat_itime); 90 Stat.stat_size = sizeof Stat; 91 92 fd = open(sfile, 2); 93 if (fd < 0) 94 { 95 errno = 0; 96 return; 97 } 98 if (read(fd, (char *) &stat, sizeof stat) == sizeof stat && 99 stat.stat_size == sizeof stat) 100 { 101 /* merge current statistics into statfile */ 102 register int i; 103 104 for (i = 0; i < MAXMAILERS; i++) 105 { 106 stat.stat_nf[i] += Stat.stat_nf[i]; 107 stat.stat_bf[i] += Stat.stat_bf[i]; 108 stat.stat_nt[i] += Stat.stat_nt[i]; 109 stat.stat_bt[i] += Stat.stat_bt[i]; 110 } 111 } 112 else 113 bcopy((char *) &Stat, (char *) &stat, sizeof stat); 114 115 /* write out results */ 116 (void) lseek(fd, (off_t) 0, 0); 117 (void) write(fd, (char *) &stat, sizeof stat); 118 (void) close(fd); 119 } 120