1 /* -*- mode: c; c-file-style: "gnu" -*-
2  * mod_exim.c -- Exim log-coloriser module for CCZE
3  * Copyright (C) 2002, 2003 Gergely Nagy <algernon@bonehunter.rulez.org>
4  *
5  * This file is part of ccze.
6  *
7  * ccze is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * ccze is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15  * License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 
22 #include <ccze.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 static void ccze_exim_setup (void);
27 static void ccze_exim_shutdown (void);
28 static int ccze_exim_handle (const char *str, size_t length, char **rest);
29 
30 static pcre *reg_exim, *reg_exim_actiontype, *reg_exim_uniqn;
31 static pcre_extra *hints_exim;
32 
33 static char *
ccze_exim_process(const char * str,int * offsets,int match)34 ccze_exim_process (const char *str, int *offsets, int match)
35 {
36   char *date, *msg=NULL, *action=NULL, *uniqn=NULL, *msgfull;
37   int match2, offsets2[99];
38   ccze_color_t color = CCZE_COLOR_UNKNOWN;
39 
40   pcre_get_substring (str, offsets, match, 1, (const char **)&date);
41   pcre_get_substring (str, offsets, match, 2, (const char **)&msgfull);
42 
43   if ((match2 = pcre_exec (reg_exim_actiontype, NULL, msgfull,
44 			   strlen (msgfull), 0, 0, offsets2, 99)) >= 0)
45     {
46       pcre_get_substring (msgfull, offsets2, match2, 1,
47 			  (const char **)&uniqn);
48       pcre_get_substring (msgfull, offsets2, match2, 2,
49 			  (const char **)&action);
50       pcre_get_substring (msgfull, offsets2, match2, 3,
51 			  (const char **)&msg);
52       if (action[0] == '<')
53 	color = CCZE_COLOR_INCOMING;
54       else if (action[1] == '>')
55 	color = CCZE_COLOR_OUTGOING;
56       else if (action[0] == '=' || action[0] == '*')
57 	color = CCZE_COLOR_ERROR;
58     }
59   else if ((match2 = pcre_exec (reg_exim_uniqn, NULL, msgfull,
60 				strlen (msgfull), 0, 0, offsets2, 99)) >= 0)
61     {
62       pcre_get_substring (msgfull, offsets2, match2, 1,
63 			  (const char **)&uniqn);
64       pcre_get_substring (msgfull, offsets2, match2, 2,
65 			  (const char **)&msg);
66     }
67   else
68     msg = strdup (msgfull);
69 
70   ccze_print_date (date);
71   ccze_space ();
72 
73   if (uniqn && uniqn[0])
74     {
75       ccze_addstr (CCZE_COLOR_UNIQN, uniqn);
76       ccze_space();
77     }
78 
79   if (action && action[0])
80     {
81       ccze_addstr (color, action);
82       ccze_space();
83     }
84 
85   return msg;
86 }
87 
88 static void
ccze_exim_setup(void)89 ccze_exim_setup (void)
90 {
91   const char *error;
92   int errptr;
93 
94   reg_exim = pcre_compile
95     ("^(\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2})\\s(.*)$", 0,
96      &error, &errptr, NULL);
97   hints_exim = pcre_study (reg_exim, 0, &error);
98 
99   reg_exim_actiontype = pcre_compile
100     ("^(\\S{16})\\s([<=\\*][=>\\*])\\s(\\S+.*)$", 0, &error,
101      &errptr, NULL);
102   reg_exim_uniqn = pcre_compile ("^(\\S{16})\\s(.*)$", 0, &error,
103 				 &errptr, NULL);
104 }
105 
106 static void
ccze_exim_shutdown(void)107 ccze_exim_shutdown (void)
108 {
109   free (reg_exim);
110   free (hints_exim);
111   free (reg_exim_actiontype);
112   free (reg_exim_uniqn);
113 }
114 
115 static int
ccze_exim_handle(const char * str,size_t length,char ** rest)116 ccze_exim_handle (const char *str, size_t length, char **rest)
117 {
118   int match, offsets[99];
119 
120   if ((match = pcre_exec (reg_exim, hints_exim, str, length,
121 			  0, 0, offsets, 99)) >= 0)
122     {
123       *rest = ccze_exim_process (str, offsets, match);
124       return 1;
125     }
126 
127   return 0;
128 }
129 
130 CCZE_DEFINE_PLUGIN (exim, FULL, "Coloriser for exim logs.");
131