/* * sma -- Sendmail log analyser * * Copyright (c) 2000, 2001, 2002 Jarkko Turkulainen. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY JARKKO TURKULAINEN ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JARKKO TURKULAINEN BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Date: 2003/04/03 12:43:33 $ */ #include "conf.h" #include #include #include #include #include #ifdef USE_REGEXP #include #if defined _WIN32 #include "regex/regex.h" #else /* defined _WIN32 */ #include #endif /* defined _WIN32 */ #endif /* defined USE_REGEXP */ #if !defined _WIN32 #include #endif #define VERSION "1.4" #define FORMAT_ASCII 3 #define FORMAT_HTML 2 #define FORMAT_CLOG 5 /* pointer to program name: */ char *pname; /* current time: */ time_t tval; struct tm *curr; struct tm tp; /* * Command line arguments * xflag sets argument x on/off * xchar is pointer to argument string if x requires an argument */ int aflag; int cflag; int dflag; int hflag; int nflag; int sflag; int qflag; int lflag; int vflag; int wflag; unsigned int lnum; unsigned int lrnum; int rflag; unsigned int rnum; unsigned int rrnum; int bflag; const char *bchar; int fflag; const char *fchar; int oflag; const char *ochar; int Lflag; const char *Lchar; int Oflag; const char *Ochar; int Dflag; const char *Dchar; int pflag; int iflag; int tflag; int dcaddrflag; const char *tchar; /* Configuration file parameters: */ int Hflag; const char *Hchar; int Cflag; const char *Cchar; int Fflag; const char *tbchar; int pgflag; const char *bechar; const char *cfchar; const char *puchar; const char *pachar; const char *plchar; const char *ppchar; const char *htchar; const char *ftchar; int csflag; int lrflag; int rrflag; int clsflag; unsigned int stnum; unsigned int rsnum; unsigned int rsrnum; unsigned int epnum; unsigned int rpnum; /* Start and end times: */ char *sstring; char *estring; char *tstring; time_t sstime; time_t eetime; int syear; int smonth; int sday; int shour; int sminute; int ssecond; int eyear; int emonth; int eday; int ehour; int eminute; int esecond; /* hash table sizes: */ int asize; int rsize; char *hsstring; char *hastring; char *hrstring; /* sender structure: */ struct in { /* next struct: */ struct in *next; /* name of the entry: */ char *name; /* total number of msgs: */ unsigned int num; /* total size: */ long double size; }; /* receiver structure: */ struct out { /* next struct: */ struct out *next; /* name of the entry: */ char *name; /* total number of msgs: */ unsigned int num; /* total size: */ long double size; }; /* input relay struct: */ struct rin { /* next */ struct rin *next; /* name: */ char *name; /* total number: */ unsigned int num; /* total size: */ long double size; }; /* output relay struct: */ struct rout { /* next */ struct rout *next; /* name: */ char *name; /* total number: */ unsigned int num; /* total size: */ long double size; }; /* message id structure: */ struct msgid { /* next */ struct msgid *next; /* message id */ char *id; /* msgid */ char *msgid; /* sender */ char *sender; /* relay */ char *relay; /* hour and day */ int hh; int day; /* size of the msg */ long double size; /* number of msgs */ int num; /* flags */ int flag; }; /* * Structure for out-of-order messages, that is for * messages without "to=" line in log (unknown local user etc.) */ struct omsgid { /* next */ struct omsgid *next; /* message id */ char *id; /* flags */ int flags; }; /* Relay structure for rulesets: */ struct rrelay { /* next */ struct rrelay *next; /* name: */ char *name; /* total number: */ unsigned int num; }; /* Structure for ruleset based rejections */ struct rule { /* next */ struct rule *next; /* Relay structure for rulesets: */ struct rrelay *rrelaytab; struct rrelay **srrelaytab; unsigned int reldif; /* name: */ char *name; /* total number: */ unsigned int num; }; /* Status structure */ struct status { /* next */ struct status *next; /* name: */ char *name; /* total number: */ unsigned int num; }; /* Envelope pair structure */ struct envpair { /* next */ struct envpair *next; /* pairs: */ char *fname; char *tname; /* total number: */ unsigned int num; /* total size: */ long double size; }; /* Relay pair structure */ struct relpair { /* next */ struct relpair *next; /* pairs: */ char *fname; char *tname; /* total number: */ unsigned int num; /* total size: */ long double size; }; /* host structure: */ struct host { /* next struct: */ struct host *next; /* name of the entry: */ char *name; /* envelope pair structures: */ struct envpair **etab; struct envpair **setab; /* pointers to in -and out addresses: */ struct in **itab; struct out **otab; struct in **sitab; struct out **sotab; /* relay pair structures: */ struct relpair **rtab; struct relpair **srtab; /* pointers to in -and out relays: */ struct rin **ritab; struct rout **rotab; struct rin **rsitab; struct rout **rsotab; /* ruleset structures */ struct rule **ruletab; struct rule **sruletab; /* status structures */ struct status **sttab; struct status **ssttab; /* pointer to message id table: */ struct msgid *msgidtab; /* pointer to out-of-order msg ids: */ struct omsgid *omsgidtab; /* start and end times: */ time_t ftime; time_t ltime; time_t cdtime; double dtime; int fday; int lday; int fhour; /* alias table rebuilds: */ int alias; /* SYSERR: */ int hopc; int lcerror; int oserror; /* daemon starts: */ int dstart; /* time tables: */ int ihh[24]; float fihh[24]; int idd[7]; float fidd[7]; int ohh[24]; float fohh[24]; int odd[7]; float fodd[7]; /* total number of msgs: */ unsigned long inum; unsigned long onum; unsigned long rinum; unsigned long ronum; unsigned long gonum; /* stat-fields: Sent, queued, Host unknown, Deferred ...*/ int sent; int queu; int hunk; int uunk; int defe; int rule; int service; int other; /* total size of msgs: */ long double size; long double isize; long double osize; int lsize; int fhost; /* total number of different messages: */ unsigned int edif; /* envelope pairs */ unsigned int rrdif; /* relay pairs */ unsigned int idif; /* input envelope */ unsigned int odif; /* output envelope */ unsigned int ridif; /* input relay */ unsigned int rodif; /* output relay */ unsigned int sdif; /* status messages */ unsigned int rdif; /* rejected messages */ }; /* Filters */ char *sef; char *ref; char *srf; char *rrf; #ifdef USE_REGEXP regex_t csef; regex_t cref; regex_t csrf; regex_t crrf; #endif /* Output file handle: */ FILE *ofp; /* total number of hosts: */ int hosts; /* inital host structure: */ struct host first; /* function definitions: */ void usage(void); void error_memory(void); void parse(FILE *, const char *); time_t conv_time(int, int, int, int, int); int conv_mon(const char *); void copying(void); const char * get_name(char *); const char * get_relay_name(char *); unsigned hash(const char *,int); struct host *init_host(const char *); void update_in(struct host *, const char *, int); void remove_in(struct host *, const char *, int); void update_out(struct host *, const char *, int); void update_rin(struct host *, const char *, int); void remove_rin(struct host *, const char *, int); void update_rout(struct host *, const char *, int); int comp_env(const void *, const void *); int comp_in(const void *, const void *); int comp_out(const void *, const void *); int comp_rel(const void *, const void *); int comp_rin(const void *, const void *); int comp_rout(const void *, const void *); int comp_s(const void *, const void *); int comp_r(const void *, const void *); int comp_rrel(const void *, const void *); void sort(struct host *); void average(struct host *, int *, float *, int *, float *); void html(FILE *); void ascii(FILE *); void init(FILE *); int update_msgid(struct host *, const char *, const char *, const char *, int, int, int, int, const char *); int update_omsgid(struct host *, const char *, int); void check_msgid(struct host *, const char *, int); void remove_msgid(struct host *, const char *); int check_omsgid(struct host *, const char *); struct msgid *get_msgid(struct host *, const char *); char * stripn(char *); char * get_string(char *); void printclog(time_t, const char *, int, const char *, const char *, const char *, const char *, const char *, int); void update_status(struct host *, const char *); void update_ruleset(struct host *, const char *, const char *); void update_envpair(struct host *, const char *, const char *, int); void update_relpair(struct host *, const char *, const char *, int); void scan_time(time_t *, char *); void dump_config(FILE *); /* macros */ #define MIN(a,b) (a > b) ? b : a