1 /* 2 * sma -- Sendmail log analyser 3 * 4 * Copyright (c) 2000, 2001, 2002 Jarkko Turkulainen. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY JARKKO TURKULAINEN ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL JARKKO TURKULAINEN BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $Date: 2003/04/03 12:43:33 $ 30 */ 31 #include "conf.h" 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <time.h> 37 #include <errno.h> 38 39 #ifdef USE_REGEXP 40 #include <sys/types.h> 41 #if defined _WIN32 42 #include "regex/regex.h" 43 #else /* defined _WIN32 */ 44 #include <regex.h> 45 #endif /* defined _WIN32 */ 46 #endif /* defined USE_REGEXP */ 47 48 #if !defined _WIN32 49 #include <unistd.h> 50 #endif 51 52 #define VERSION "1.4" 53 #define FORMAT_ASCII 3 54 #define FORMAT_HTML 2 55 #define FORMAT_CLOG 5 56 57 /* pointer to program name: */ 58 extern char *pname; 59 60 /* current time: */ 61 extern time_t tval; 62 extern struct tm *curr; 63 extern struct tm tp; 64 65 /* 66 * Command line arguments 67 * xflag sets argument x on/off 68 * xchar is pointer to argument string if x requires an argument 69 */ 70 extern int aflag; 71 extern int cflag; 72 extern int dflag; 73 extern int hflag; 74 extern int nflag; 75 extern int sflag; 76 extern int qflag; 77 extern int lflag; 78 extern int vflag; 79 extern int wflag; 80 extern unsigned int lnum; 81 extern unsigned int lrnum; 82 extern int rflag; 83 extern unsigned int rnum; 84 extern unsigned int rrnum; 85 extern int bflag; 86 extern const char *bchar; 87 extern int fflag; 88 extern const char *fchar; 89 extern int oflag; 90 extern const char *ochar; 91 extern int Lflag; 92 extern const char *Lchar; 93 extern int Oflag; 94 extern const char *Ochar; 95 extern int Dflag; 96 extern const char *Dchar; 97 extern int pflag; 98 extern int iflag; 99 extern int tflag; 100 extern int dcaddrflag; 101 extern const char *tchar; 102 103 /* Configuration file parameters: */ 104 extern int Hflag; 105 extern const char *Hchar; 106 extern int Cflag; 107 extern const char *Cchar; 108 extern int Fflag; 109 extern const char *tbchar; 110 extern int pgflag; 111 extern const char *bechar; 112 extern const char *cfchar; 113 extern const char *puchar; 114 extern const char *pachar; 115 extern const char *plchar; 116 extern const char *ppchar; 117 extern const char *htchar; 118 extern const char *ftchar; 119 extern int csflag; 120 extern int lrflag; 121 extern int rrflag; 122 extern int clsflag; 123 extern unsigned int stnum; 124 extern unsigned int rsnum; 125 extern unsigned int rsrnum; 126 extern unsigned int epnum; 127 extern unsigned int rpnum; 128 129 /* Start and end times: */ 130 extern char *sstring; 131 extern char *estring; 132 extern char *tstring; 133 extern time_t sstime; 134 extern time_t eetime; 135 extern int syear; 136 extern int smonth; 137 extern int sday; 138 extern int shour; 139 extern int sminute; 140 extern int ssecond; 141 extern int eyear; 142 extern int emonth; 143 extern int eday; 144 extern int ehour; 145 extern int eminute; 146 extern int esecond; 147 148 /* hash table sizes: */ 149 extern int asize; 150 extern int rsize; 151 extern char *hsstring; 152 extern char *hastring; 153 extern char *hrstring; 154 155 /* sender structure: */ 156 struct in { 157 158 /* next struct: */ 159 struct in *next; 160 161 /* name of the entry: */ 162 char *name; 163 164 /* total number of msgs: */ 165 unsigned int num; 166 167 /* total size: */ 168 long double size; 169 }; 170 171 /* receiver structure: */ 172 struct out { 173 174 /* next struct: */ 175 struct out *next; 176 177 /* name of the entry: */ 178 char *name; 179 180 /* total number of msgs: */ 181 unsigned int num; 182 183 /* total size: */ 184 long double size; 185 186 }; 187 188 /* input relay struct: */ 189 struct rin { 190 191 /* next */ 192 struct rin *next; 193 194 /* name: */ 195 char *name; 196 197 /* total number: */ 198 unsigned int num; 199 200 /* total size: */ 201 long double size; 202 }; 203 204 /* output relay struct: */ 205 struct rout { 206 207 /* next */ 208 struct rout *next; 209 210 /* name: */ 211 char *name; 212 213 /* total number: */ 214 unsigned int num; 215 216 /* total size: */ 217 long double size; 218 }; 219 220 /* message id structure: */ 221 struct msgid { 222 223 /* next */ 224 struct msgid *next; 225 226 /* message id */ 227 char *id; 228 229 /* msgid */ 230 char *msgid; 231 232 /* sender */ 233 char *sender; 234 235 /* relay */ 236 char *relay; 237 238 /* hour and day */ 239 int hh; 240 int day; 241 242 /* size of the msg */ 243 long double size; 244 245 /* number of msgs */ 246 int num; 247 248 /* flags */ 249 int flag; 250 }; 251 252 /* 253 * Structure for out-of-order messages, that is for 254 * messages without "to=" line in log (unknown local user etc.) 255 */ 256 struct omsgid { 257 258 /* next */ 259 struct omsgid *next; 260 261 /* message id */ 262 char *id; 263 264 /* flags */ 265 int flags; 266 }; 267 268 /* Relay structure for rulesets: */ 269 struct rrelay { 270 271 /* next */ 272 struct rrelay *next; 273 274 /* name: */ 275 char *name; 276 277 /* total number: */ 278 unsigned int num; 279 280 }; 281 282 /* Structure for ruleset based rejections */ 283 struct rule { 284 285 /* next */ 286 struct rule *next; 287 288 /* Relay structure for rulesets: */ 289 struct rrelay *rrelaytab; 290 struct rrelay **srrelaytab; 291 unsigned int reldif; 292 293 /* name: */ 294 char *name; 295 296 /* total number: */ 297 unsigned int num; 298 299 }; 300 301 /* Status structure */ 302 struct status { 303 304 /* next */ 305 struct status *next; 306 307 /* name: */ 308 char *name; 309 310 /* total number: */ 311 unsigned int num; 312 }; 313 314 /* Envelope pair structure */ 315 struct envpair { 316 317 /* next */ 318 struct envpair *next; 319 320 /* pairs: */ 321 char *fname; 322 char *tname; 323 324 /* total number: */ 325 unsigned int num; 326 327 /* total size: */ 328 long double size; 329 }; 330 331 /* Relay pair structure */ 332 struct relpair { 333 334 /* next */ 335 struct relpair *next; 336 337 /* pairs: */ 338 char *fname; 339 char *tname; 340 341 /* total number: */ 342 unsigned int num; 343 344 /* total size: */ 345 long double size; 346 }; 347 348 349 /* host structure: */ 350 struct host { 351 352 /* next struct: */ 353 struct host *next; 354 355 /* name of the entry: */ 356 char *name; 357 358 /* envelope pair structures: */ 359 struct envpair **etab; 360 struct envpair **setab; 361 362 /* pointers to in -and out addresses: */ 363 struct in **itab; 364 struct out **otab; 365 struct in **sitab; 366 struct out **sotab; 367 368 /* relay pair structures: */ 369 struct relpair **rtab; 370 struct relpair **srtab; 371 372 /* pointers to in -and out relays: */ 373 struct rin **ritab; 374 struct rout **rotab; 375 struct rin **rsitab; 376 struct rout **rsotab; 377 378 /* ruleset structures */ 379 struct rule **ruletab; 380 struct rule **sruletab; 381 382 /* status structures */ 383 struct status **sttab; 384 struct status **ssttab; 385 386 /* pointer to message id table: */ 387 struct msgid *msgidtab; 388 389 /* pointer to out-of-order msg ids: */ 390 struct omsgid *omsgidtab; 391 392 /* start and end times: */ 393 time_t ftime; 394 time_t ltime; 395 time_t cdtime; 396 double dtime; 397 int fday; 398 int lday; 399 int fhour; 400 401 /* alias table rebuilds: */ 402 int alias; 403 404 /* SYSERR: */ 405 int hopc; 406 int lcerror; 407 int oserror; 408 409 /* daemon starts: */ 410 int dstart; 411 412 /* time tables: */ 413 int ihh[24]; 414 float fihh[24]; 415 int idd[7]; 416 float fidd[7]; 417 int ohh[24]; 418 float fohh[24]; 419 int odd[7]; 420 float fodd[7]; 421 422 /* total number of msgs: */ 423 unsigned long inum; 424 unsigned long onum; 425 unsigned long rinum; 426 unsigned long ronum; 427 unsigned long gonum; 428 429 /* stat-fields: Sent, queued, Host unknown, Deferred ...*/ 430 int sent; 431 int queu; 432 int hunk; 433 int uunk; 434 int defe; 435 int rule; 436 int service; 437 int other; 438 439 /* total size of msgs: */ 440 long double size; 441 long double isize; 442 long double osize; 443 int lsize; 444 int fhost; 445 446 /* total number of different messages: */ 447 unsigned int edif; /* envelope pairs */ 448 unsigned int rrdif; /* relay pairs */ 449 unsigned int idif; /* input envelope */ 450 unsigned int odif; /* output envelope */ 451 unsigned int ridif; /* input relay */ 452 unsigned int rodif; /* output relay */ 453 unsigned int sdif; /* status messages */ 454 unsigned int rdif; /* rejected messages */ 455 456 }; 457 458 /* Filters */ 459 extern char *sef; 460 extern char *ref; 461 extern char *srf; 462 extern char *rrf; 463 #ifdef USE_REGEXP 464 extern regex_t csef; 465 extern regex_t cref; 466 extern regex_t csrf; 467 extern regex_t crrf; 468 #endif 469 470 /* Output file handle: */ 471 extern FILE *ofp; 472 473 /* total number of hosts: */ 474 extern int hosts; 475 476 /* inital host structure: */ 477 extern struct host first; 478 479 /* function definitions: */ 480 void usage(void); 481 void error_memory(void); 482 void parse(FILE *, const char *); 483 time_t conv_time(int, int, int, int, int); 484 int conv_mon(const char *); 485 void copying(void); 486 const char * get_name(char *); 487 const char * get_relay_name(char *); 488 unsigned hash(const char *,int); 489 struct host *init_host(const char *); 490 void update_in(struct host *, const char *, int); 491 void remove_in(struct host *, const char *, int); 492 void update_out(struct host *, const char *, int); 493 void update_rin(struct host *, const char *, int); 494 void remove_rin(struct host *, const char *, int); 495 void update_rout(struct host *, const char *, int); 496 int comp_env(const void *, const void *); 497 int comp_in(const void *, const void *); 498 int comp_out(const void *, const void *); 499 int comp_rel(const void *, const void *); 500 int comp_rin(const void *, const void *); 501 int comp_rout(const void *, const void *); 502 int comp_s(const void *, const void *); 503 int comp_r(const void *, const void *); 504 int comp_rrel(const void *, const void *); 505 void sort(struct host *); 506 void average(struct host *, int *, float *, int *, float *); 507 void html(FILE *); 508 void ascii(FILE *); 509 void init(FILE *); 510 int update_msgid(struct host *, const char *, const char *, const char *, 511 int, int, int, int, const char *); 512 int update_omsgid(struct host *, const char *, int); 513 void check_msgid(struct host *, const char *, int); 514 void remove_msgid(struct host *, const char *); 515 int check_omsgid(struct host *, const char *); 516 struct msgid *get_msgid(struct host *, const char *); 517 char * stripn(char *); 518 char * get_string(char *); 519 void printclog(time_t, const char *, int, const char *, const char *, 520 const char *, const char *, const char *, int); 521 void update_status(struct host *, const char *); 522 void update_ruleset(struct host *, const char *, const char *); 523 void update_envpair(struct host *, const char *, const char *, int); 524 void update_relpair(struct host *, const char *, const char *, int); 525 void scan_time(time_t *, char *); 526 void dump_config(FILE *); 527 528 /* macros */ 529 #define MIN(a,b) (a > b) ? b : a 530