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