1 /* -*- mode: c; c-file-style: "gnu" -*-
2  * mod_postfix.c -- Postfix colorizer for CCZE
3  * Copyright (C) 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 <string.h>
24 #include <stdlib.h>
25 
26 #include "ccze-compat.h"
27 
28 static void ccze_postfix_setup (void);
29 static void ccze_postfix_shutdown (void);
30 static int ccze_postfix_handle (const char *str, size_t length, char **rest);
31 
32 static pcre *reg_postfix;
33 
34 static int
_ccze_postfix_process_one(const char * s,char ** rest)35 _ccze_postfix_process_one (const char *s, char **rest)
36 {
37   char *field, *value;
38   size_t i;
39 
40   if (!strchr (s, '='))
41     return 1;
42 
43   field = strndup (s, strchr (s, '=') - s);
44   i = strlen (s);
45   i -= strlen (field) + 1;
46   value = strndup (&s[strlen (field) + 1], i);
47 
48   ccze_addstr (CCZE_COLOR_FIELD, field);
49   ccze_addstr (CCZE_COLOR_DEFAULT, "=");
50   ccze_wordcolor_process_one (value, 1);
51 
52   return 0;
53 }
54 
55 static char *
ccze_postfix_process(const char * str,int * offsets,int match)56 ccze_postfix_process (const char *str, int *offsets, int match)
57 {
58   char *spoolid, *s, *rest, *tmp;
59   int r;
60 
61   pcre_get_substring (str, offsets, match, 1, (const char **)&spoolid);
62   pcre_get_substring (str, offsets, match, 2, (const char **)&s);
63   pcre_get_substring (str, offsets, match, 4, (const char **)&rest);
64 
65   ccze_addstr (CCZE_COLOR_UNIQN, spoolid);
66   ccze_addstr (CCZE_COLOR_DEFAULT, ": ");
67 
68   tmp = ccze_strbrk (s, ',');
69 
70   do
71     {
72       r = _ccze_postfix_process_one (tmp, &rest);
73       if (r)
74 	ccze_addstr (CCZE_COLOR_DEFAULT, tmp);
75       else
76 	tmp = ccze_strbrk (NULL, ',');
77       if (tmp)
78 	ccze_addstr (CCZE_COLOR_DEFAULT, ",");
79     } while (!r && (tmp != NULL));
80 
81   return NULL;
82 }
83 
84 static void
ccze_postfix_setup(void)85 ccze_postfix_setup (void)
86 {
87   const char *error;
88   int errptr;
89 
90   reg_postfix = pcre_compile
91     ("^([\\dA-F]+): ((client|to|message-id|uid|resent-message-id|from)(=.*))",
92      0, &error, &errptr, NULL);
93 }
94 
95 static void
ccze_postfix_shutdown(void)96 ccze_postfix_shutdown (void)
97 {
98   free (reg_postfix);
99 }
100 
101 static int
ccze_postfix_handle(const char * str,size_t length,char ** rest)102 ccze_postfix_handle (const char *str, size_t length, char **rest)
103 {
104   int match, offsets[99];
105 
106   if ((match = pcre_exec (reg_postfix, NULL, str, length,
107 			  0, 0, offsets, 99)) >= 0)
108     {
109       if (rest)
110 	*rest = ccze_postfix_process (str, offsets, match);
111       else
112 	ccze_postfix_process (str, offsets, match);
113 
114       return 1;
115     }
116 
117   return 0;
118 }
119 
120 CCZE_DEFINE_PLUGIN (postfix, PARTIAL, "Coloriser for postfix(1) sub-logs.");
121