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.4 (Berkeley) 06/17/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 extern long kbytes(); /* for _bf, _bt */ 33 /* 34 ** MARKSTATS -- mark statistics 35 */ 36 37 markstats(e, to) 38 register ENVELOPE *e; 39 register ADDRESS *to; 40 { 41 if (to == NULL) 42 { 43 Stat.stat_nf[e->e_from.q_mailer->m_mno]++; 44 Stat.stat_bf[e->e_from.q_mailer->m_mno] += kbytes(CurEnv->e_msgsize); 45 } 46 else 47 { 48 Stat.stat_nt[to->q_mailer->m_mno]++; 49 Stat.stat_bt[to->q_mailer->m_mno] += kbytes(CurEnv->e_msgsize); 50 } 51 } 52 /* 53 ** POSTSTATS -- post statistics in the statistics file 54 ** 55 ** Parameters: 56 ** sfile -- the name of the statistics file. 57 ** 58 ** Returns: 59 ** none. 60 ** 61 ** Side Effects: 62 ** merges the Stat structure with the sfile file. 63 */ 64 65 poststats(sfile) 66 char *sfile; 67 { 68 register int fd; 69 struct statistics stat; 70 extern off_t lseek(); 71 72 if (sfile == NULL) 73 return; 74 75 (void) time(&Stat.stat_itime); 76 Stat.stat_size = sizeof Stat; 77 78 fd = open(sfile, 2); 79 if (fd < 0) 80 { 81 errno = 0; 82 return; 83 } 84 if (read(fd, (char *) &stat, sizeof stat) == sizeof stat && 85 stat.stat_size == sizeof stat) 86 { 87 /* merge current statistics into statfile */ 88 register int i; 89 90 for (i = 0; i < MAXMAILERS; i++) 91 { 92 stat.stat_nf[i] += Stat.stat_nf[i]; 93 stat.stat_bf[i] += Stat.stat_bf[i]; 94 stat.stat_nt[i] += Stat.stat_nt[i]; 95 stat.stat_bt[i] += Stat.stat_bt[i]; 96 } 97 } 98 else 99 bcopy((char *) &Stat, (char *) &stat, sizeof stat); 100 101 /* write out results */ 102 (void) lseek(fd, (off_t) 0, 0); 103 (void) write(fd, (char *) &stat, sizeof stat); 104 (void) close(fd); 105 } 106 /* 107 ** KBYTES -- given a number, returns the number of Kbytes. 108 ** 109 ** Used in statistics gathering of message sizes to try to avoid 110 ** wraparound (at least for a while.....) 111 ** 112 ** Parameters: 113 ** bytes -- actual number of bytes. 114 ** 115 ** Returns: 116 ** number of kbytes. 117 ** 118 ** Side Effects: 119 ** none. 120 ** 121 ** Notes: 122 ** This function is actually a ceiling function to 123 ** the nearest K. 124 ** Honestly folks, floating point might be better. 125 ** Or perhaps a "statistical" log method. 126 */ 127 128 long 129 kbytes(bytes) 130 long bytes; 131 { 132 return ((bytes + 999) / 1000); 133 } 134