📄 mta_sendmail.c
字号:
/* * MTA-MIB implementation for sendmail - mibII/mta_sendmail.c * Christoph Mammitzsch <Christoph.Mammitzsch@tu-clausthal.de> * * 05.04.2000: * * - supports sendmail 8.10.0 statistics files now * - function read_option has been removed * * 12.04.2000: * * - renamed configuration tokens: * sendmail config -> sendmail_config * sendmail stats -> sendmail_stats * sendmail queue -> sendmail_queue * sendmail index -> sendmail_index * sendmail statcachetime -> sendmail_stats_t * sendmail dircacetime -> sendmail_queue_t * * - now using snmpd_register_config_handler instead of config_parse_dot_conf * * 15.04.2000: * * - introduced new function print_error * - changed open_sendmailst and read_sendmailcf to use the new function * - changed calls to open_sendmailst and read_sendmailcf * - added some error handling to calls to chdir(), close() and closedir() * *//** "include files" */#ifdef __lint# define SNMP_NO_DEBUGGING 1 /* keeps lint from complaining about the DEBUGMSG* macros */#endif#include <config.h>#include "mibincl.h"#include "mta_sendmail.h"#include <sys/types.h>#include <stdio.h>#include <ctype.h>#ifdef HAVE_STRING_H# include <string.h>#else# include <strings.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef HAVE_FCNTL_H# include <fcntl.h>#endif#if HAVE_DIRENT_H#include <dirent.h>#else# define dirent direct# if HAVE_SYS_NDIR_H# include <sys/ndir.h># endif# if HAVE_SYS_DIR_H# include <sys/dir.h># endif# if HAVE_NDIR_H# include <ndir.h># endif#endif#ifdef HAVE_SYS_STAT_H# include <sys/stat.h>#endif#if TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#if HAVE_STDARG_H#include <stdarg.h>#else#include <varargs.h>#endif#include <errno.h>/**//** "macros and variables for registering the OID tree" *//* prefix for all OIDs */static oid mta_variables_oid[] = { 1,3,6,1,2,1,28 };/* bits that indicate what's needed to compute the value */#define NEEDS_STATS (1 << 6)#define NEEDS_DIR (1 << 7)#define NEEDS (NEEDS_STATS | NEEDS_DIR)/* symbolic names for the magic values */#define MTARECEIVEDMESSAGES 3 | NEEDS_STATS#define MTASTOREDMESSAGES 4 | NEEDS_DIR#define MTATRANSMITTEDMESSAGES 5 | NEEDS_STATS#define MTARECEIVEDVOLUME 6 | NEEDS_STATS#define MTASTOREDVOLUME 7 | NEEDS_DIR#define MTATRANSMITTEDVOLUME 8 | NEEDS_STATS#define MTAGROUPRECEIVEDMESSAGES 19 | NEEDS_STATS#define MTAGROUPREJECTEDMESSAGES 20 | NEEDS_STATS#define MTAGROUPTRANSMITTEDMESSAGES 22 | NEEDS_STATS#define MTAGROUPRECEIVEDVOLUME 23 | NEEDS_STATS#define MTAGROUPTRANSMITTEDVOLUME 25 | NEEDS_STATS#define MTAGROUPNAME 43#define MTAGROUPHIERARCHY 49/* structure that tells the agent, which function returns what values */static struct variable4 mta_variables[] = { { MTARECEIVEDMESSAGES , ASN_COUNTER , RONLY, var_mtaEntry , 3, { 1, 1, 1 } }, { MTASTOREDMESSAGES , ASN_GAUGE , RONLY, var_mtaEntry , 3, { 1, 1, 2 } }, { MTATRANSMITTEDMESSAGES , ASN_COUNTER , RONLY, var_mtaEntry , 3, { 1, 1, 3 } }, { MTARECEIVEDVOLUME , ASN_COUNTER , RONLY, var_mtaEntry , 3, { 1, 1, 4 } }, { MTASTOREDVOLUME , ASN_GAUGE , RONLY, var_mtaEntry , 3, { 1, 1, 5 } }, { MTATRANSMITTEDVOLUME , ASN_COUNTER , RONLY, var_mtaEntry , 3, { 1, 1, 6 } }, { MTAGROUPRECEIVEDMESSAGES , ASN_COUNTER , RONLY, var_mtaGroupEntry, 3, { 2, 1, 2 } }, { MTAGROUPREJECTEDMESSAGES , ASN_COUNTER , RONLY, var_mtaGroupEntry, 3, { 2, 1, 3 } }, { MTAGROUPTRANSMITTEDMESSAGES, ASN_COUNTER , RONLY, var_mtaGroupEntry, 3, { 2, 1, 5 } }, { MTAGROUPRECEIVEDVOLUME , ASN_COUNTER , RONLY, var_mtaGroupEntry, 3, { 2, 1, 6 } }, { MTAGROUPTRANSMITTEDVOLUME , ASN_COUNTER , RONLY, var_mtaGroupEntry, 3, { 2, 1, 8 } }, { MTAGROUPNAME , ASN_OCTET_STR, RONLY, var_mtaGroupEntry, 3, { 2, 1, 25 } }, { MTAGROUPHIERARCHY , ASN_INTEGER , RONLY, var_mtaGroupEntry, 3, { 2, 1, 31 } },};/**//** "other macros and structures" *//* for boolean values */#ifndef FALSE#define FALSE 0#endif#ifndef TRUE#define TRUE 1#endif#ifndef BOOL#define BOOL short#endif/* important constants */#define FILENAMELEN 200 /* maximum length for filenames */#define MAXMAILERS 25 /* maximum number of mailers (copied from the sendmail sources) */#define MNAMELEN 20 /* maximum length of mailernames (copied from the sendmail sources) */#define STAT_VERSION_8_9 2 /* version of sendmail V8.9.x statistics files (copied from the sendmail sources) */#define STAT_VERSION_8_10 3 /* version of sendmail V8.10.x statistics files (copied from the sendmail sources) */#define STAT_MAGIC 0x1B1DE /* magic value to identify statistics files from sendmail V8.9.x or higher (copied from the sendmail sources) *//* structure of sendmail.st file from sendmail V8.10.x (copied from the sendmail sources) */struct statisticsV8_10{ int stat_magic; /* magic number */ int stat_version; /* stat file version */ time_t stat_itime; /* file initialization time */ short stat_size; /* size of this structure */ long stat_cf; /* # from connections */ long stat_ct; /* # to connections */ long stat_cr; /* # rejected connections */ 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 */ long stat_nr[MAXMAILERS]; /* # rejects by each mailer */ long stat_nd[MAXMAILERS]; /* # discards by each mailer */};/* structure of sendmail.st file from sendmail V8.9.x (copied from the sendmail sources) */struct statisticsV8_9{ int stat_magic; /* magic number */ int stat_version; /* stat file version */ 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 */ long stat_nr[MAXMAILERS]; /* # rejects by each mailer */ long stat_nd[MAXMAILERS]; /* # discards by each mailer */};/* structure of sendmail.st file from sendmail V8.8.x (copied from the sendmail sources) */struct statisticsV8_8{ 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 */};/**//** "static variables" */static char sendmailst_fn[FILENAMELEN+1]; /* name of statistics file */static int sendmailst_fh = -1; /* filehandle for statistics file */static char sendmailcf_fn[FILENAMELEN+1]; /* name of sendmails config file */static char mqueue_dn[FILENAMELEN+1]; /* name of the queue directory */static DIR *mqueue_dp = NULL; /* directoryhandle for the queue directory */static char mailernames[MAXMAILERS][MNAMELEN+1]; /* array of mailer names */static int mailers = MAXMAILERS; /* number of mailer names in array */static long *stat_nf; /* pointer to stat_nf array within the statistics structure */static long *stat_bf; /* pointer to stat_bf array within the statistics structure */static long *stat_nt; /* pointer to stat_nt array within the statistics structure */static long *stat_bt; /* pointer to stat_bt array within the statistics structure */static long *stat_nr; /* pointer to stat_nr array within the statistics structure, only valid for statistics files from sendmail >=V8.9.0 */static long *stat_nd; /* pointer to stat_nd array within the statistics structure, only valid for statistics files from sendmail >=V8.9.0 */static int stats_size; /* size of statistics structure */static long stats[sizeof (struct statisticsV8_10) / sizeof (long) + 1]; /* buffer for statistics structure */static time_t lastreadstats; /* time stats file has been read */static long mqueue_count; /* number of messages in queue */static long mqueue_size; /* total size of messages in queue */static time_t lastreaddir; /* time queue directory has been read */static long applindex = 1; /* ApplIndex value for OIDs */static long stat_cache_time = 5; /* time (in seconds) to wait before reading stats file again */static long dir_cache_time = 10; /* time (in seconds) to wait before scanning queue directoy again *//**//** static void print_error(int priority, BOOL config, BOOL config_only, char *function, char *format, ...) * * Description: * * Called to print errors. It uses the config_perror or the snmp_log function * depending on whether the config parameter is TRUE or FALSE. * * Parameters: * * priority: priority to be used when calling the snmp_log function * * config: indicates whether this function has been called during the * configuration process or not. If set to TRUE, the function * config_perror will be used to report the error. * * config_only: if set to TRUE, the error will only be printed when function * has been called during the configuration process. * * function: name of the calling function. Used when printing via snmp_log. * * format: format string for the error message * * ...: additional parameters to insert into the error message string * */#if HAVE_STDARG_Hstatic void print_error(int priority, BOOL config, BOOL config_only, const char *function, const char *format, ...)#elsestatic void print_error(va_alist) va_dcl#endif{ va_list ap; char buffer[2*FILENAMELEN+200]; /* I know, that's not perfectly safe, but since I don't use more than two filenames in one error message, that should be enough */#if HAVE_STDARG_H va_start(ap, format);#else int priority; BOOL config; BOOL config_only; const char *function; const char *format; va_start(ap); priority = va_arg(ap, int); config = va_arg(ap, BOOL); config_only = va_arg(ap, BOOL); function = va_arg(ap, char *); format = va_arg(ap, char *);#endif vsprintf(buffer, format, ap); if (config) { config_perror(buffer); } else if (!config_only) { snmp_log(priority, "%s: %s\n", function, buffer); } va_end(ap);}/**//** static void open_sendmailst(BOOL config) * * Description: * * Closes old sendmail.st file, then tries to open the new sendmail.st file * and guess it's version. If it succeeds, it initializes the stat_* * pointers and the stats_size variable. * * Parameters: * * config: TRUE if function has been called during the configuration process * * Returns: * * nothing * */static void open_sendmailst(BOOL config){ int filelen; if (sendmailst_fh != -1) { while (close(sendmailst_fh) == -1 && errno == EINTR) { /* do nothing */ } } sendmailst_fh = open(sendmailst_fn, O_RDONLY); if (sendmailst_fh == -1) { print_error(LOG_ERR, config, TRUE, "mibII/mta_sendmail.c:open_sendmailst","could not open file \"%s\"\n", sendmailst_fn); return; } filelen = read(sendmailst_fh, (void *)&stats, sizeof stats); if (((struct statisticsV8_10 *)stats)->stat_magic == STAT_MAGIC) { if (((struct statisticsV8_10 *)stats)->stat_version == STAT_VERSION_8_10 && ((struct statisticsV8_10 *)stats)->stat_size == sizeof (struct statisticsV8_10) && filelen == sizeof (struct statisticsV8_10)) { DEBUGMSGTL(("mibII/mta_sendmail.c:open_sendmailst", "looks like file \"%s\" has been created by sendmail V8.10.0 or newer\n", sendmailst_fn)); stat_nf = (((struct statisticsV8_10 *)stats)->stat_nf); stat_bf = (((struct statisticsV8_10 *)stats)->stat_bf); stat_nt = (((struct statisticsV8_10 *)stats)->stat_nt); stat_bt = (((struct statisticsV8_10 *)stats)->stat_bt); stat_nr = (((struct statisticsV8_10 *)stats)->stat_nr); stat_nd = (((struct statisticsV8_10 *)stats)->stat_nd); stats_size = sizeof (struct statisticsV8_10); } else if (((struct statisticsV8_9 *)stats)->stat_version == STAT_VERSION_8_9 && ((struct statisticsV8_9 *)stats)->stat_size == sizeof (struct statisticsV8_9) && filelen == sizeof (struct statisticsV8_9)) { DEBUGMSGTL(("mibII/mta_sendmail.c:open_sendmailst", "looks like file \"%s\" has been created by sendmail V8.9.x\n", sendmailst_fn)); stat_nf = (((struct statisticsV8_9 *)stats)->stat_nf); stat_bf = (((struct statisticsV8_9 *)stats)->stat_bf); stat_nt = (((struct statisticsV8_9 *)stats)->stat_nt); stat_bt = (((struct statisticsV8_9 *)stats)->stat_bt); stat_nr = (((struct statisticsV8_9 *)stats)->stat_nr); stat_nd = (((struct statisticsV8_9 *)stats)->stat_nd); stats_size = sizeof (struct statisticsV8_9); } else { print_error(LOG_WARNING, config, FALSE, "mibII/mta_sendmail.c:open_sendmailst", "could not guess version of statistics file \"%s\"\n", sendmailst_fn); while (close(sendmailst_fh) == -1 && errno == EINTR) { /* do nothing */ } sendmailst_fh = -1; } } else { if (((struct statisticsV8_8 *)stats)->stat_size == sizeof (struct statisticsV8_8) && filelen == sizeof (struct statisticsV8_8)) { DEBUGMSGTL(("mibII/mta_sendmail.c:open_sendmailst", "looks like file \"%s\" has been created by sendmail V8.8.x\n", sendmailst_fn)); stat_nf = (((struct statisticsV8_8 *)stats)->stat_nf); stat_bf = (((struct statisticsV8_8 *)stats)->stat_bf); stat_nt = (((struct statisticsV8_8 *)stats)->stat_nt); stat_bt = (((struct statisticsV8_8 *)stats)->stat_bt); stat_nr = (long *) NULL; stat_nd = (long *) NULL; stats_size = sizeof (struct statisticsV8_8); } else { print_error(LOG_WARNING, config, FALSE, "mibII/mta_sendmail.c:open_sendmailst", "could not guess version of statistics file \"%s\"\n", sendmailst_fn); while (close(sendmailst_fh) == -1 && errno == EINTR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -