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.3 (Berkeley) 06/08/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 (void) time(&Stat.stat_itime); 73 Stat.stat_size = sizeof Stat; 74 75 fd = open(sfile, 2); 76 if (fd < 0) 77 { 78 errno = 0; 79 return; 80 } 81 if (read(fd, (char *) &stat, sizeof stat) == sizeof stat && 82 stat.stat_size == sizeof stat) 83 { 84 /* merge current statistics into statfile */ 85 register int i; 86 87 for (i = 0; i < MAXMAILERS; i++) 88 { 89 stat.stat_nf[i] += Stat.stat_nf[i]; 90 stat.stat_bf[i] += Stat.stat_bf[i]; 91 stat.stat_nt[i] += Stat.stat_nt[i]; 92 stat.stat_bt[i] += Stat.stat_bt[i]; 93 } 94 } 95 else 96 bcopy((char *) &Stat, (char *) &stat, sizeof stat); 97 98 /* write out results */ 99 (void) lseek(fd, (off_t) 0, 0); 100 (void) write(fd, (char *) &stat, sizeof stat); 101 (void) close(fd); 102 } 103 /* 104 ** KBYTES -- given a number, returns the number of Kbytes. 105 ** 106 ** Used in statistics gathering of message sizes to try to avoid 107 ** wraparound (at least for a while.....) 108 ** 109 ** Parameters: 110 ** bytes -- actual number of bytes. 111 ** 112 ** Returns: 113 ** number of kbytes. 114 ** 115 ** Side Effects: 116 ** none. 117 ** 118 ** Notes: 119 ** This function is actually a ceiling function to 120 ** the nearest K. 121 ** Honestly folks, floating point might be better. 122 ** Or perhaps a "statistical" log method. 123 */ 124 125 long 126 kbytes(bytes) 127 long bytes; 128 { 129 return ((bytes + 999) / 1000); 130 } 131