14286Seric # include "sendmail.h" 24286Seric 3*9383Seric SCCSID(@(#)stats.c 3.5 11/28/82); 44286Seric 54286Seric /* 6*9383Seric ** Statistics structure. 7*9383Seric */ 8*9383Seric 9*9383Seric struct statistics 10*9383Seric { 11*9383Seric time_t stat_itime; /* file initialization time */ 12*9383Seric short stat_size; /* size of this structure */ 13*9383Seric long stat_nf[MAXMAILERS]; /* # msgs from each mailer */ 14*9383Seric long stat_bf[MAXMAILERS]; /* kbytes from each mailer */ 15*9383Seric long stat_nt[MAXMAILERS]; /* # msgs to each mailer */ 16*9383Seric long stat_bt[MAXMAILERS]; /* kbytes to each mailer */ 17*9383Seric }; 18*9383Seric 19*9383Seric struct statistics Stat; 20*9383Seric extern long kbytes(); /* for _bf, _bt */ 21*9383Seric /* 22*9383Seric ** MARKSTATS -- mark statistics 23*9383Seric */ 24*9383Seric 25*9383Seric markstats(e, to) 26*9383Seric register ENVELOPE *e; 27*9383Seric register ADDRESS *to; 28*9383Seric { 29*9383Seric if (to == NULL) 30*9383Seric { 31*9383Seric Stat.stat_nf[e->e_from.q_mailer->m_mno]++; 32*9383Seric Stat.stat_bf[e->e_from.q_mailer->m_mno] += kbytes(CurEnv->e_msgsize); 33*9383Seric } 34*9383Seric else 35*9383Seric { 36*9383Seric Stat.stat_nt[to->q_mailer->m_mno]++; 37*9383Seric Stat.stat_bt[to->q_mailer->m_mno] += kbytes(CurEnv->e_msgsize); 38*9383Seric } 39*9383Seric } 40*9383Seric /* 414286Seric ** POSTSTATS -- post statistics in the statistics file 424286Seric ** 434286Seric ** Parameters: 444286Seric ** sfile -- the name of the statistics file. 454286Seric ** 464286Seric ** Returns: 474286Seric ** none. 484286Seric ** 494286Seric ** Side Effects: 504286Seric ** merges the Stat structure with the sfile file. 514286Seric */ 524286Seric 534286Seric struct statistics Stat; 544286Seric 554286Seric poststats(sfile) 564286Seric char *sfile; 574286Seric { 584286Seric register int fd; 594286Seric struct statistics stat; 604319Seric extern long lseek(); 614286Seric 624319Seric (void) time(&Stat.stat_itime); 634286Seric Stat.stat_size = sizeof Stat; 644286Seric 654286Seric fd = open(sfile, 2); 664286Seric if (fd < 0) 674286Seric return; 684319Seric if (read(fd, (char *) &stat, sizeof stat) == sizeof stat && 694286Seric stat.stat_size == sizeof stat) 704286Seric { 714286Seric /* merge current statistics into statfile */ 724286Seric register int i; 734286Seric 744286Seric for (i = 0; i < MAXMAILERS; i++) 754286Seric { 764286Seric stat.stat_nf[i] += Stat.stat_nf[i]; 774286Seric stat.stat_bf[i] += Stat.stat_bf[i]; 784286Seric stat.stat_nt[i] += Stat.stat_nt[i]; 794286Seric stat.stat_bt[i] += Stat.stat_bt[i]; 804286Seric } 814286Seric } 824286Seric else 834319Seric bmove((char *) &Stat, (char *) &stat, sizeof stat); 844286Seric 854286Seric /* write out results */ 864319Seric (void) lseek(fd, 0L, 0); 874319Seric (void) write(fd, (char *) &stat, sizeof stat); 884319Seric (void) close(fd); 894286Seric } 904286Seric /* 914286Seric ** KBYTES -- given a number, returns the number of Kbytes. 924286Seric ** 934286Seric ** Used in statistics gathering of message sizes to try to avoid 944286Seric ** wraparound (at least for a while.....) 954286Seric ** 964286Seric ** Parameters: 974286Seric ** bytes -- actual number of bytes. 984286Seric ** 994286Seric ** Returns: 1004286Seric ** number of kbytes. 1014286Seric ** 1024286Seric ** Side Effects: 1034286Seric ** none. 1044286Seric ** 1054286Seric ** Notes: 1064286Seric ** This function is actually a ceiling function to 1074286Seric ** the nearest K. 1084286Seric ** Honestly folks, floating point might be better. 1094286Seric ** Or perhaps a "statistical" log method. 1104286Seric */ 1114286Seric 1124286Seric long 1134286Seric kbytes(bytes) 1144286Seric long bytes; 1154286Seric { 1164286Seric return ((bytes + 999) / 1000); 1174286Seric } 118