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