2 * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
16 SM_RCSID("@(#)$Id: stats.c,v 8.55 2002/05/21 22:28:52 gshapiro Exp $")
18 #include <sendmail/mailstats.h>
20 static struct statistics Stat
;
22 static bool GotStats
= false; /* set when we have stats to merge */
24 /* See http://physics.nist.gov/cuu/Units/binary.html */
25 #define ONE_K 1000 /* one thousand (twenty-four?) */
26 #define KBYTES(x) (((x) + (ONE_K - 1)) / ONE_K)
28 ** MARKSTATS -- mark statistics
33 ** type -- type of stats this represents.
39 ** changes static Stat structure
43 markstats(e
, to
, type
)
51 case STATS_QUARANTINE
:
52 if (e
->e_from
.q_mailer
!= NULL
)
53 Stat
.stat_nq
[e
->e_from
.q_mailer
->m_mno
]++;
55 #endif /* _FFR_QUARANTINE */
58 if (e
->e_from
.q_mailer
!= NULL
)
60 if (bitset(EF_DISCARD
, e
->e_flags
))
61 Stat
.stat_nd
[e
->e_from
.q_mailer
->m_mno
]++;
63 Stat
.stat_nr
[e
->e_from
.q_mailer
->m_mno
]++;
78 if (e
->e_from
.q_mailer
!= NULL
)
80 Stat
.stat_nf
[e
->e_from
.q_mailer
->m_mno
]++;
81 Stat
.stat_bf
[e
->e_from
.q_mailer
->m_mno
] +=
87 Stat
.stat_nt
[to
->q_mailer
->m_mno
]++;
88 Stat
.stat_bt
[to
->q_mailer
->m_mno
] += KBYTES(e
->e_msgsize
);
93 /* Silently ignore bogus call */
101 ** CLEARSTATS -- clear statistics structure
110 ** clears the Stat structure.
116 /* clear the structure to avoid future disappointment */
117 memset(&Stat
, '\0', sizeof Stat
);
121 ** POSTSTATS -- post statistics in the statistics file
124 ** sfile -- the name of the statistics file.
130 ** merges the Stat structure with the sfile file.
138 static bool entered
= false;
139 long sff
= SFF_REGONLY
|SFF_OPENASROOT
;
140 struct statistics stats
;
141 extern off_t
lseek();
143 if (sfile
== NULL
|| *sfile
== '\0' || !GotStats
|| entered
)
147 (void) time(&Stat
.stat_itime
);
148 Stat
.stat_size
= sizeof Stat
;
149 Stat
.stat_magic
= STAT_MAGIC
;
150 Stat
.stat_version
= STAT_VERSION
;
152 if (!bitnset(DBS_WRITESTATSTOSYMLINK
, DontBlameSendmail
))
154 if (!bitnset(DBS_WRITESTATSTOHARDLINK
, DontBlameSendmail
))
157 fd
= safeopen(sfile
, O_RDWR
, 0600, sff
);
161 sm_syslog(LOG_INFO
, NOQID
, "poststats: %s: %s",
162 sfile
, sm_errstring(errno
));
167 if (read(fd
, (char *) &stats
, sizeof stats
) == sizeof stats
&&
168 stats
.stat_size
== sizeof stats
&&
169 stats
.stat_magic
== Stat
.stat_magic
&&
170 stats
.stat_version
== Stat
.stat_version
)
172 /* merge current statistics into statfile */
175 for (i
= 0; i
< MAXMAILERS
; i
++)
177 stats
.stat_nf
[i
] += Stat
.stat_nf
[i
];
178 stats
.stat_bf
[i
] += Stat
.stat_bf
[i
];
179 stats
.stat_nt
[i
] += Stat
.stat_nt
[i
];
180 stats
.stat_bt
[i
] += Stat
.stat_bt
[i
];
181 stats
.stat_nr
[i
] += Stat
.stat_nr
[i
];
182 stats
.stat_nd
[i
] += Stat
.stat_nd
[i
];
184 stats
.stat_nq
[i
] += Stat
.stat_nq
[i
];
185 #endif /* _FFR_QUARANTINE */
187 stats
.stat_cr
+= Stat
.stat_cr
;
188 stats
.stat_ct
+= Stat
.stat_ct
;
189 stats
.stat_cf
+= Stat
.stat_cf
;
192 memmove((char *) &stats
, (char *) &Stat
, sizeof stats
);
194 /* write out results */
195 (void) lseek(fd
, (off_t
) 0, 0);
196 (void) write(fd
, (char *) &stats
, sizeof stats
);
199 /* clear the structure to avoid future disappointment */