# include "sendmail.h" SCCSID(@(#)stats.c 4.1 7/25/83); /* ** Statistics structure. */ struct statistics { time_t stat_itime; /* file initialization time */ short stat_size; /* size of this structure */ long stat_nf[MAXMAILERS]; /* # msgs from each mailer */ long stat_bf[MAXMAILERS]; /* kbytes from each mailer */ long stat_nt[MAXMAILERS]; /* # msgs to each mailer */ long stat_bt[MAXMAILERS]; /* kbytes to each mailer */ }; struct statistics Stat; extern long kbytes(); /* for _bf, _bt */ /* ** MARKSTATS -- mark statistics */ markstats(e, to) register ENVELOPE *e; register ADDRESS *to; { if (to == NULL) { Stat.stat_nf[e->e_from.q_mailer->m_mno]++; Stat.stat_bf[e->e_from.q_mailer->m_mno] += kbytes(CurEnv->e_msgsize); } else { Stat.stat_nt[to->q_mailer->m_mno]++; Stat.stat_bt[to->q_mailer->m_mno] += kbytes(CurEnv->e_msgsize); } } /* ** POSTSTATS -- post statistics in the statistics file ** ** Parameters: ** sfile -- the name of the statistics file. ** ** Returns: ** none. ** ** Side Effects: ** merges the Stat structure with the sfile file. */ poststats(sfile) char *sfile; { register int fd; struct statistics stat; extern long lseek(); (void) time(&Stat.stat_itime); Stat.stat_size = sizeof Stat; fd = open(sfile, 2); if (fd < 0) { errno = 0; return; } if (read(fd, (char *) &stat, sizeof stat) == sizeof stat && stat.stat_size == sizeof stat) { /* merge current statistics into statfile */ register int i; for (i = 0; i < MAXMAILERS; i++) { stat.stat_nf[i] += Stat.stat_nf[i]; stat.stat_bf[i] += Stat.stat_bf[i]; stat.stat_nt[i] += Stat.stat_nt[i]; stat.stat_bt[i] += Stat.stat_bt[i]; } } else bmove((char *) &Stat, (char *) &stat, sizeof stat); /* write out results */ (void) lseek(fd, 0L, 0); (void) write(fd, (char *) &stat, sizeof stat); (void) close(fd); } /* ** KBYTES -- given a number, returns the number of Kbytes. ** ** Used in statistics gathering of message sizes to try to avoid ** wraparound (at least for a while.....) ** ** Parameters: ** bytes -- actual number of bytes. ** ** Returns: ** number of kbytes. ** ** Side Effects: ** none. ** ** Notes: ** This function is actually a ceiling function to ** the nearest K. ** Honestly folks, floating point might be better. ** Or perhaps a "statistical" log method. */ long kbytes(bytes) long bytes; { return ((bytes + 999) / 1000); }