Fuss fuss fuss.
[samba.git] / source3 / utils / debug2html.c
1 /* ========================================================================== **
2  *                                debug2html.c
3  *
4  * Copyright (C) 1998 by Christopher R. Hertel
5  *
6  * Email: crh@ubiqx.mn.org
7  *
8  * -------------------------------------------------------------------------- **
9  * Parse Samba debug logs (2.0 & greater) and output the results as HTML.
10  * -------------------------------------------------------------------------- **
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  *
26  * -------------------------------------------------------------------------- **
27  * This program provides an example of the use of debugparse.c, and also
28  * does a decent job of converting Samba logs into HTML.
29  * -------------------------------------------------------------------------- **
30  *
31  * $Revision: 1.8 $
32  *
33  * ========================================================================== **
34  */
35
36 #include "includes.h"
37
38 /* -------------------------------------------------------------------------- **
39  * Global values.
40  */
41
42 FILE *infile  = stdin;
43 FILE *outfile = stdout;
44
45 /* -------------------------------------------------------------------------- **
46  * The size of the read buffer.
47  */
48
49 #define DBG_BSIZE 1024
50
51 /* -------------------------------------------------------------------------- **
52  * Functions...
53  */
54
55 static dbg_Token modechange( dbg_Token new, dbg_Token mode )
56   /* ------------------------------------------------------------------------ **
57    * Handle a switch between header and message printing.
58    *
59    *  Input:  new   - The token value of the current token.  This indicates
60    *                  the lexical item currently being recognized.
61    *          mode  - The current mode.  This is either dbg_null or
62    *                  dbg_message.  It could really be any toggle
63    *                  (true/false, etc.)
64    *
65    *  Output: The new mode.  This will be the same as the input mode unless
66    *          there was a transition in or out of message processing.
67    *
68    *  Notes:  The purpose of the mode value is to mark the beginning and end
69    *          of the message text block.  In order to show the text in its
70    *          correct format, it must be included within a <PRE></PRE> block.
71    *
72    * ------------------------------------------------------------------------ **
73    */
74   {
75   switch( new )
76     {
77     case dbg_null:
78     case dbg_ignore:
79       return( mode );
80     case dbg_message:
81       if( dbg_message != mode )
82         {
83         /* Switching to message mode. */
84         (void)fprintf( outfile, "<PRE>\n" );
85         return( dbg_message );
86         }
87       break;
88     default:
89       if( dbg_message == mode )
90         {
91         /* Switching out of message mode. */
92         (void)fprintf( outfile, "</PRE>\n\n" );
93         return( dbg_null );
94         }
95     }
96
97   return( mode );
98   } /* modechange */
99
100 static void newblock( dbg_Token old, dbg_Token new )
101   /* ------------------------------------------------------------------------ **
102    * Handle the transition between tokens.
103    *
104    *  Input:  old - The previous token.
105    *          new - The current token.
106    *
107    *  Output: none.
108    *
109    *  Notes:  This is called whenever there is a transition from one token
110    *          type to another.  It first prints the markup tags that close
111    *          the previous token, and then the markup tags for the new
112    *          token.
113    *
114    * ------------------------------------------------------------------------ **
115    */
116   {
117   switch( old )
118     {
119     case dbg_timestamp:
120       (void)fprintf( outfile, ",</B>" );
121       break;
122     case dbg_level:
123       (void)fprintf( outfile, "</FONT>]</B>\n   " );
124       break;
125     case dbg_sourcefile:
126       (void)fprintf( outfile, ":" );
127       break;
128     case dbg_lineno:
129       (void)fprintf( outfile, ")" );
130       break;
131     default:
132       break;
133     }
134
135   switch( new )
136     {
137     case dbg_timestamp:
138       (void)fprintf( outfile, "<B>[" );
139       break;
140     case dbg_level:
141       (void)fprintf( outfile, " <B><FONT COLOR=MAROON>" );
142       break;
143     case dbg_lineno:
144       (void)fprintf( outfile, "(" );
145       break;
146     default:
147       break;
148     }
149   } /* newblock */
150
151 static void charprint( dbg_Token tok, int c )
152   /* ------------------------------------------------------------------------ **
153    * Filter the input characters to determine what goes to output.
154    *
155    *  Input:  tok - The token value of the current character.
156    *          c   - The current character.
157    *
158    *  Output: none.
159    *
160    * ------------------------------------------------------------------------ **
161    */
162   {
163   switch( tok )
164     {
165     case dbg_ignore:
166     case dbg_header:
167       break;
168     case dbg_null:
169     case dbg_eof:
170       (void)putc( '\n', outfile );
171       break;
172     default:
173       switch( c )
174         {
175         case '<':
176           (void)fprintf( outfile, "&lt;" );
177           break;
178         case '>':
179           (void)fprintf( outfile, "&gt;" );
180           break;
181         case '&':
182           (void)fprintf( outfile, "&amp;" );
183           break;
184         case '\"':
185           (void)fprintf( outfile, "&#34;" );
186           break;
187         default:
188           (void)putc( c, outfile );
189           break;
190         }
191     }
192   } /* charprint */
193
194 static void convert( void )
195   /* ------------------------------------------------------------------------ **
196    * Read the input logfile, converting the entries to HTML.
197    *
198    *  Input:  none.
199    *  output: none.
200    *  Notes:  Reads from the global infile, writes to the global outfile.
201    *          These default to stdin and stdout, respectively.
202    *
203    * ------------------------------------------------------------------------ **
204    */
205   {
206   int       i;
207   int       len;
208   char      bufr[DBG_BSIZE];
209   dbg_Token old   = dbg_null,
210             new   = dbg_null,
211             state = dbg_null,
212             mode  = dbg_null;
213
214   while( (!feof( infile ))
215       && ((len = fread( bufr, 1, DBG_BSIZE, infile )) > 0) )
216     {
217     for( i = 0; i < len; i++ )
218       {
219       old = new;
220       new = dbg_char2token( &state, bufr[i] );
221       if( new != old )
222         {
223         mode = modechange( new, mode );
224         newblock( old, new );
225         }
226       charprint( new, bufr[i] );
227       }
228     }
229   (void)modechange( dbg_eof, mode );
230
231   } /* convert */
232
233 static void usage( void )
234   /* ------------------------------------------------------------------------ **
235    * Prints a usage message on stderr, then gently exits.
236    *
237    *  Input:  none.
238    *  Output: none.  Exits with return code of 0.
239    *
240    * ------------------------------------------------------------------------ **
241    */
242   {
243   fprintf( stderr, "This utility converts Samba log files " );
244   fprintf( stderr, "into HTML documents.\n" );
245   fprintf( stderr, "Usage:\n" );
246   fprintf( stderr, "  debug2html <infile> <outfile>\n" );
247   exit( 0 );
248   } /* usage */
249
250 static FILE *carefull_fopen( const char *path, const char *type )
251   /* ------------------------------------------------------------------------ **
252    * Checks for leading '-' characters, which are generically regarded as
253    * flags.  Also exits the program gracefully should the file fail to open.
254    *
255    *  Input:  path  - pathname of the file to open.
256    *          type  - open mode.  See fopen(3S).
257    *
258    *  Output: Pointer to open file.
259    *
260    * ------------------------------------------------------------------------ **
261    */
262   {
263   FILE *tmp;
264
265   if( '-' == path[0] || '\0' == path[0] )
266     usage();
267
268   tmp = sys_fopen( path, type );
269   if( NULL == tmp )
270     {
271     fprintf( stderr, "Error opening file %s: %s\n", path, strerror(errno) );
272     exit( 1 );
273     }
274   return( tmp );
275   } /* carefull_fopen */
276
277 int main( int argc, char *argv[] )
278   /* ------------------------------------------------------------------------ **
279    * This simple program scans and parses Samba debug logs, and produces HTML
280    * output.
281    *
282    *  Input:  argc    - Argument count.
283    *          argv[1] - Input file name.
284    *          argv[2] - Output file name.
285    *                    A '-' character by itself means use defaults (i.e.,
286    *                    <stdin> or <stdout> depending upon the argument.
287    *                    A string beginning with '-' and containing more than
288    *                    that one character will generate a usage message.
289    *
290    *  Output: An exit value of 1 is returned if an error was encountered
291    *          while opening a file, else 0.
292    *
293    *  Notes:  The HTML output is sent to stdout.
294    *
295    * ------------------------------------------------------------------------ **
296    */
297   {
298   if( argc > 3 )
299     usage();
300
301   if( argc > 1 && 0 != strcmp( argv[1], "-" ) )
302     infile = carefull_fopen( argv[1], "r" );
303
304   if( argc > 2 && 0 != strcmp( argv[2], "-" ) )
305     infile = carefull_fopen( argv[2], "w" );
306
307   (void)fprintf( outfile,
308                  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n" );
309   (void)fprintf( outfile, "<HTML>\n<HEAD>\n" );
310   (void)fprintf( outfile,
311                  "  <TITLE>Samba Log</TITLE>\n</HEAD>\n\n<BODY>\n" );
312
313   convert();
314
315   (void)fprintf( outfile, "</BODY>\n</HTML>\n" );
316
317   return( 0 );
318   } /* main */