/*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#ifdef USE_REGEXP
#include <sys/types.h>
#if defined _WIN32
#include "regex/regex.h"
#else /* defined _WIN32 */
#include <regex.h>
#endif /* defined _WIN32 */
#endif /* defined USE_REGEXP */
#if !defined _WIN32
#include <unistd.h>
#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
syntax highlighted by Code2HTML, v. 0.9.1