mailstats.c
上传用户:xu_441
上传日期:2007-01-04
资源大小:1640k
文件大小:7k
源码类别:

Email客户端

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
  3.  * All rights reserved.
  4.  * Copyright (c) 1983 Eric P. Allman.  All rights reserved.
  5.  * Copyright (c) 1988, 1993
  6.  * The Regents of the University of California.  All rights reserved.
  7.  *
  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.
  11.  *
  12.  *
  13.  */
  14. #ifndef lint
  15. static char copyright[] =
  16. "@(#) Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.n
  17. All rights reserved.n
  18.      Copyright (c) 1988, 1993n
  19. The Regents of the University of California.  All rights reserved.n";
  20. #endif /* ! lint */
  21. #ifndef lint
  22. static char id[] = "@(#)$Id: mailstats.c,v 8.53 1999/10/13 05:43:54 gshapiro Exp $";
  23. #endif /* ! lint */
  24. #include <unistd.h>
  25. #include <stddef.h>
  26. #include <stdlib.h>
  27. #include <ctype.h>
  28. #include <string.h>
  29. #include <time.h>
  30. #ifdef EX_OK
  31. # undef EX_OK /* unistd.h may have another use for this */
  32. #endif /* EX_OK */
  33. #include <sysexits.h>
  34. #include <sendmail/sendmail.h>
  35. #include <sendmail/mailstats.h>
  36. #include <sendmail/pathnames.h>
  37. #define MNAMELEN 20 /* max length of mailer name */
  38. int
  39. main(argc, argv)
  40. int argc;
  41. char **argv;
  42. {
  43. register int i;
  44. int mno;
  45. int save_errno;
  46. int ch, fd;
  47. char *sfile;
  48. char *cfile;
  49. FILE *cfp;
  50. bool mnames;
  51. bool progmode;
  52. long frmsgs = 0, frbytes = 0, tomsgs = 0, tobytes = 0, rejmsgs = 0;
  53. long dismsgs = 0;
  54. time_t now;
  55. char mtable[MAXMAILERS][MNAMELEN + 1];
  56. char sfilebuf[MAXLINE];
  57. char buf[MAXLINE];
  58. struct statistics stats;
  59. extern char *ctime();
  60. extern char *optarg;
  61. extern int optind;
  62. cfile = _PATH_SENDMAILCF;
  63. sfile = NULL;
  64. mnames = TRUE;
  65. progmode = FALSE;
  66. while ((ch = getopt(argc, argv, "C:f:op")) != EOF)
  67. {
  68. switch (ch)
  69. {
  70.   case 'C':
  71. cfile = optarg;
  72. break;
  73.   case 'f':
  74. sfile = optarg;
  75. break;
  76.   case 'o':
  77. mnames = FALSE;
  78. break;
  79.   case 'p':
  80. progmode = TRUE;
  81. break;
  82.   case '?':
  83.   default:
  84.   usage:
  85. (void) fputs("usage: mailstats [-C cffile] [-f stfile] -o -pn",
  86.      stderr);
  87. exit(EX_USAGE);
  88. }
  89. }
  90. argc -= optind;
  91. argv += optind;
  92. if (argc != 0)
  93. goto usage;
  94. if ((cfp = fopen(cfile, "r")) == NULL)
  95. {
  96. save_errno = errno;
  97. fprintf(stderr, "mailstats: ");
  98. errno = save_errno;
  99. perror(cfile);
  100. exit(EX_NOINPUT);
  101. }
  102. mno = 0;
  103. (void) strlcpy(mtable[mno++], "prog", MNAMELEN + 1);
  104. (void) strlcpy(mtable[mno++], "*file*", MNAMELEN + 1);
  105. (void) strlcpy(mtable[mno++], "*include*", MNAMELEN + 1);
  106. while (fgets(buf, sizeof(buf), cfp) != NULL)
  107. {
  108. register char *b;
  109. char *s;
  110. register char *m;
  111. b = buf;
  112. switch (*b++)
  113. {
  114.   case 'M': /* mailer definition */
  115. break;
  116.   case 'O': /* option -- see if .st file */
  117. if (strncasecmp(b, " StatusFile", 11) == 0 &&
  118.     !(isascii(b[11]) && isalnum(b[11])))
  119. {
  120. /* new form -- find value */
  121. b = strchr(b, '=');
  122. if (b == NULL)
  123. continue;
  124. while (isascii(*++b) && isspace(*b))
  125. continue;
  126. }
  127. else if (*b++ != 'S')
  128. {
  129. /* something else boring */
  130. continue;
  131. }
  132. /* this is the S or StatusFile option -- save it */
  133. if (strlcpy(sfilebuf, b, sizeof sfilebuf) >=
  134.     sizeof sfilebuf)
  135. {
  136. fprintf(stderr,
  137. "StatusFile filename too long: %.30s...n",
  138. b);
  139. exit(EX_CONFIG);
  140. }
  141. b = strchr(sfilebuf, '#');
  142. if (b == NULL)
  143. b = strchr(sfilebuf, 'n');
  144. if (b == NULL)
  145. b = &sfilebuf[strlen(sfilebuf)];
  146. while (isascii(*--b) && isspace(*b))
  147. continue;
  148. *++b = '';
  149. if (sfile == NULL)
  150. sfile = sfilebuf;
  151.   default:
  152. continue;
  153. }
  154. if (mno >= MAXMAILERS)
  155. {
  156. fprintf(stderr,
  157. "Too many mailers defined, %d max.n",
  158. MAXMAILERS);
  159. exit(EX_SOFTWARE);
  160. }
  161. m = mtable[mno];
  162. s = m + MNAMELEN; /* is [MNAMELEN + 1] */
  163. while (*b != ',' && !(isascii(*b) && isspace(*b)) &&
  164.        *b != '' && m < s)
  165. *m++ = *b++;
  166. *m = '';
  167. for (i = 0; i < mno; i++)
  168. {
  169. if (strcmp(mtable[i], mtable[mno]) == 0)
  170. break;
  171. }
  172. if (i == mno)
  173. mno++;
  174. }
  175. (void) fclose(cfp);
  176. for (; mno < MAXMAILERS; mno++)
  177. mtable[mno][0]='';
  178. if (sfile == NULL)
  179. {
  180. fprintf(stderr, "mailstats: no statistics file locatedn");
  181. exit (EX_OSFILE);
  182. }
  183. if ((fd = open(sfile, O_RDONLY)) < 0 ||
  184.     (i = read(fd, &stats, sizeof stats)) < 0)
  185. {
  186. save_errno = errno;
  187. (void) fputs("mailstats: ", stderr);
  188. errno = save_errno;
  189. perror(sfile);
  190. exit(EX_NOINPUT);
  191. }
  192. if (i == 0)
  193. {
  194. (void) sleep(1);
  195. if ((i = read(fd, &stats, sizeof stats)) < 0)
  196. {
  197. save_errno = errno;
  198. (void) fputs("mailstats: ", stderr);
  199. errno = save_errno;
  200. perror(sfile);
  201. exit(EX_NOINPUT);
  202. }
  203. else if (i == 0)
  204. {
  205. memset((ARBPTR_T) &stats, '', sizeof stats);
  206. (void) time(&stats.stat_itime);
  207. }
  208. }
  209. if (i != 0)
  210. {
  211. if (stats.stat_magic != STAT_MAGIC)
  212. {
  213. fprintf(stderr,
  214. "mailstats: incorrect magic number in %sn",
  215. sfile);
  216. exit(EX_OSERR);
  217. }
  218. else if (stats.stat_version != STAT_VERSION)
  219. {
  220. fprintf(stderr,
  221. "mailstats version (%d) incompatible with %s version (%d)n",
  222. STAT_VERSION, sfile, stats.stat_version);
  223. exit(EX_OSERR);
  224. }
  225. else if (i != sizeof stats || stats.stat_size != sizeof(stats))
  226. {
  227. (void) fputs("mailstats: file size changed.n", stderr);
  228. exit(EX_OSERR);
  229. }
  230. }
  231. if (progmode)
  232. {
  233. (void) time(&now);
  234. printf("%ld %ldn", (long) stats.stat_itime, (long) now);
  235. }
  236. else
  237. {
  238. printf("Statistics from %s", ctime(&stats.stat_itime));
  239. printf(" M   msgsfr  bytes_from   msgsto    bytes_to  msgsrej msgsdis%sn",
  240. mnames ? "  Mailer" : "");
  241. }
  242. for (i = 0; i < MAXMAILERS; i++)
  243. {
  244. if (stats.stat_nf[i] || stats.stat_nt[i] ||
  245.     stats.stat_nr[i] || stats.stat_nd[i])
  246. {
  247. char *format;
  248. if (progmode)
  249. format = "%2d %8ld %10ld %8ld %10ld   %6ld  %6ld";
  250. else
  251. format = "%2d %8ld %10ldK %8ld %10ldK   %6ld  %6ld";
  252. printf(format, i,
  253.     stats.stat_nf[i], stats.stat_bf[i],
  254.     stats.stat_nt[i], stats.stat_bt[i],
  255.     stats.stat_nr[i], stats.stat_nd[i]);
  256. if (mnames)
  257. printf("  %s", mtable[i]);
  258. printf("n");
  259. frmsgs += stats.stat_nf[i];
  260. frbytes += stats.stat_bf[i];
  261. tomsgs += stats.stat_nt[i];
  262. tobytes += stats.stat_bt[i];
  263. rejmsgs += stats.stat_nr[i];
  264. dismsgs += stats.stat_nd[i];
  265. }
  266. }
  267. if (progmode)
  268. {
  269. printf(" T %8ld %10ld %8ld %10ld   %6ld  %6ldn",
  270.        frmsgs, frbytes, tomsgs, tobytes, rejmsgs, dismsgs);
  271. printf(" C %8ld %8ld %6ldn",
  272.        stats.stat_cf, stats.stat_ct, stats.stat_cr);
  273. (void) close(fd);
  274. fd = open(sfile, O_RDWR | O_TRUNC);
  275. if (fd >= 0)
  276. (void) close(fd);
  277. }
  278. else
  279. {
  280. printf("=============================================================n");
  281. printf(" T %8ld %10ldK %8ld %10ldK   %6ld  %6ldn",
  282. frmsgs, frbytes, tomsgs, tobytes, rejmsgs, dismsgs);
  283. printf(" C %8ld %10s  %8ld %10s    %6ldn",
  284.        stats.stat_cf, "", stats.stat_ct, "", stats.stat_cr);
  285. }
  286. exit(EX_OK);
  287. /* NOTREACHED */
  288. return EX_OK;
  289. }