14286Seric # include "sendmail.h" 24286Seric 3*11937Seric SCCSID(@(#)stats.c 3.7 04/17/83); 44286Seric 54286Seric /* 69383Seric ** Statistics structure. 79383Seric */ 89383Seric 99383Seric struct statistics 109383Seric { 119383Seric time_t stat_itime; /* file initialization time */ 129383Seric short stat_size; /* size of this structure */ 139383Seric long stat_nf[MAXMAILERS]; /* # msgs from each mailer */ 149383Seric long stat_bf[MAXMAILERS]; /* kbytes from each mailer */ 159383Seric long stat_nt[MAXMAILERS]; /* # msgs to each mailer */ 169383Seric long stat_bt[MAXMAILERS]; /* kbytes to each mailer */ 179383Seric }; 189383Seric 199383Seric struct statistics Stat; 209383Seric extern long kbytes(); /* for _bf, _bt */ 219383Seric /* 229383Seric ** MARKSTATS -- mark statistics 239383Seric */ 249383Seric 259383Seric markstats(e, to) 269383Seric register ENVELOPE *e; 279383Seric register ADDRESS *to; 289383Seric { 299383Seric if (to == NULL) 309383Seric { 319383Seric Stat.stat_nf[e->e_from.q_mailer->m_mno]++; 329383Seric Stat.stat_bf[e->e_from.q_mailer->m_mno] += kbytes(CurEnv->e_msgsize); 339383Seric } 349383Seric else 359383Seric { 369383Seric Stat.stat_nt[to->q_mailer->m_mno]++; 379383Seric Stat.stat_bt[to->q_mailer->m_mno] += kbytes(CurEnv->e_msgsize); 389383Seric } 399383Seric } 409383Seric /* 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 poststats(sfile) 544286Seric char *sfile; 554286Seric { 564286Seric register int fd; 574286Seric struct statistics stat; 584319Seric extern long lseek(); 594286Seric 604319Seric (void) time(&Stat.stat_itime); 614286Seric Stat.stat_size = sizeof Stat; 624286Seric 634286Seric fd = open(sfile, 2); 644286Seric if (fd < 0) 65*11937Seric { 66*11937Seric errno = 0; 674286Seric return; 68*11937Seric } 694319Seric if (read(fd, (char *) &stat, sizeof stat) == sizeof stat && 704286Seric stat.stat_size == sizeof stat) 714286Seric { 724286Seric /* merge current statistics into statfile */ 734286Seric register int i; 744286Seric 754286Seric for (i = 0; i < MAXMAILERS; i++) 764286Seric { 774286Seric stat.stat_nf[i] += Stat.stat_nf[i]; 784286Seric stat.stat_bf[i] += Stat.stat_bf[i]; 794286Seric stat.stat_nt[i] += Stat.stat_nt[i]; 804286Seric stat.stat_bt[i] += Stat.stat_bt[i]; 814286Seric } 824286Seric } 834286Seric else 844319Seric bmove((char *) &Stat, (char *) &stat, sizeof stat); 854286Seric 864286Seric /* write out results */ 874319Seric (void) lseek(fd, 0L, 0); 884319Seric (void) write(fd, (char *) &stat, sizeof stat); 894319Seric (void) close(fd); 904286Seric } 914286Seric /* 924286Seric ** KBYTES -- given a number, returns the number of Kbytes. 934286Seric ** 944286Seric ** Used in statistics gathering of message sizes to try to avoid 954286Seric ** wraparound (at least for a while.....) 964286Seric ** 974286Seric ** Parameters: 984286Seric ** bytes -- actual number of bytes. 994286Seric ** 1004286Seric ** Returns: 1014286Seric ** number of kbytes. 1024286Seric ** 1034286Seric ** Side Effects: 1044286Seric ** none. 1054286Seric ** 1064286Seric ** Notes: 1074286Seric ** This function is actually a ceiling function to 1084286Seric ** the nearest K. 1094286Seric ** Honestly folks, floating point might be better. 1104286Seric ** Or perhaps a "statistical" log method. 1114286Seric */ 1124286Seric 1134286Seric long 1144286Seric kbytes(bytes) 1154286Seric long bytes; 1164286Seric { 1174286Seric return ((bytes + 999) / 1000); 1184286Seric } 119