/* ========================================================================== ** * debug2html.c * * Copyright (C) 1998 by Christopher R. Hertel * * Email: crh@ubiqx.mn.org * * -------------------------------------------------------------------------- ** * Parse Samba debug logs (2.0 & greater) and output the results as HTML. * -------------------------------------------------------------------------- ** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * -------------------------------------------------------------------------- ** * This program provides an example of the use of debugparse.c, and also * does a decent job of converting Samba logs into HTML. * -------------------------------------------------------------------------- ** * * $Revision: 1.9 $ * * ========================================================================== ** */ #include "includes.h" /* -------------------------------------------------------------------------- ** * Global values. */ FILE *infile; FILE *outfile; /* -------------------------------------------------------------------------- ** * The size of the read buffer. */ #define DBG_BSIZE 1024 /* -------------------------------------------------------------------------- ** * Functions... */ static dbg_Token modechange( dbg_Token new, dbg_Token mode ) /* ------------------------------------------------------------------------ ** * Handle a switch between header and message printing. * * Input: new - The token value of the current token. This indicates * the lexical item currently being recognized. * mode - The current mode. This is either dbg_null or * dbg_message. It could really be any toggle * (true/false, etc.) * * Output: The new mode. This will be the same as the input mode unless * there was a transition in or out of message processing. * * Notes: The purpose of the mode value is to mark the beginning and end * of the message text block. In order to show the text in its * correct format, it must be included within a
 block.
   *
   * ------------------------------------------------------------------------ **
   */
  {
  switch( new )
    {
    case dbg_null:
    case dbg_ignore:
      return( mode );
    case dbg_message:
      if( dbg_message != mode )
        {
        /* Switching to message mode. */
        (void)fprintf( outfile, "
\n" );
        return( dbg_message );
        }
      break;
    default:
      if( dbg_message == mode )
        {
        /* Switching out of message mode. */
        (void)fprintf( outfile, "
\n\n" ); return( dbg_null ); } } return( mode ); } /* modechange */ static void newblock( dbg_Token old, dbg_Token new ) /* ------------------------------------------------------------------------ ** * Handle the transition between tokens. * * Input: old - The previous token. * new - The current token. * * Output: none. * * Notes: This is called whenever there is a transition from one token * type to another. It first prints the markup tags that close * the previous token, and then the markup tags for the new * token. * * ------------------------------------------------------------------------ ** */ { switch( old ) { case dbg_timestamp: (void)fprintf( outfile, "," ); break; case dbg_level: (void)fprintf( outfile, "]\n " ); break; case dbg_sourcefile: (void)fprintf( outfile, ":" ); break; case dbg_lineno: (void)fprintf( outfile, ")" ); break; default: break; } switch( new ) { case dbg_timestamp: (void)fprintf( outfile, "[" ); break; case dbg_level: (void)fprintf( outfile, " " ); break; case dbg_lineno: (void)fprintf( outfile, "(" ); break; default: break; } } /* newblock */ static void charprint( dbg_Token tok, int c ) /* ------------------------------------------------------------------------ ** * Filter the input characters to determine what goes to output. * * Input: tok - The token value of the current character. * c - The current character. * * Output: none. * * ------------------------------------------------------------------------ ** */ { switch( tok ) { case dbg_ignore: case dbg_header: break; case dbg_null: case dbg_eof: (void)putc( '\n', outfile ); break; default: switch( c ) { case '<': (void)fprintf( outfile, "<" ); break; case '>': (void)fprintf( outfile, ">" ); break; case '&': (void)fprintf( outfile, "&" ); break; case '\"': (void)fprintf( outfile, """ ); break; default: (void)putc( c, outfile ); break; } } } /* charprint */ static void convert( void ) /* ------------------------------------------------------------------------ ** * Read the input logfile, converting the entries to HTML. * * Input: none. * output: none. * Notes: Reads from the global infile, writes to the global outfile. * These default to stdin and stdout, respectively. * * ------------------------------------------------------------------------ ** */ { int i; int len; char bufr[DBG_BSIZE]; dbg_Token old = dbg_null, new = dbg_null, state = dbg_null, mode = dbg_null; while( (!feof( infile )) && ((len = fread( bufr, 1, DBG_BSIZE, infile )) > 0) ) { for( i = 0; i < len; i++ ) { old = new; new = dbg_char2token( &state, bufr[i] ); if( new != old ) { mode = modechange( new, mode ); newblock( old, new ); } charprint( new, bufr[i] ); } } (void)modechange( dbg_eof, mode ); } /* convert */ static void usage( void ) /* ------------------------------------------------------------------------ ** * Prints a usage message on stderr, then gently exits. * * Input: none. * Output: none. Exits with return code of 0. * * ------------------------------------------------------------------------ ** */ { fprintf( stderr, "This utility converts Samba log files " ); fprintf( stderr, "into HTML documents.\n" ); fprintf( stderr, "Usage:\n" ); fprintf( stderr, " debug2html \n" ); exit( 0 ); } /* usage */ static FILE *carefull_fopen( const char *path, const char *type ) /* ------------------------------------------------------------------------ ** * Checks for leading '-' characters, which are generically regarded as * flags. Also exits the program gracefully should the file fail to open. * * Input: path - pathname of the file to open. * type - open mode. See fopen(3S). * * Output: Pointer to open file. * * ------------------------------------------------------------------------ ** */ { FILE *tmp; if( '-' == path[0] || '\0' == path[0] ) usage(); tmp = sys_fopen( path, type ); if( NULL == tmp ) { fprintf( stderr, "Error opening file %s: %s\n", path, strerror(errno) ); exit( 1 ); } return( tmp ); } /* carefull_fopen */ int main( int argc, char *argv[] ) /* ------------------------------------------------------------------------ ** * This simple program scans and parses Samba debug logs, and produces HTML * output. * * Input: argc - Argument count. * argv[1] - Input file name. * argv[2] - Output file name. * A '-' character by itself means use defaults (i.e., * or depending upon the argument. * A string beginning with '-' and containing more than * that one character will generate a usage message. * * Output: An exit value of 1 is returned if an error was encountered * while opening a file, else 0. * * Notes: The HTML output is sent to stdout. * * ------------------------------------------------------------------------ ** */ { if( argc > 3 ) usage(); infile = stdin; outfile = stdout; if( argc > 1 && 0 != strcmp( argv[1], "-" ) ) infile = carefull_fopen( argv[1], "r" ); if( argc > 2 && 0 != strcmp( argv[2], "-" ) ) infile = carefull_fopen( argv[2], "w" ); (void)fprintf( outfile, "\n" ); (void)fprintf( outfile, "\n\n" ); (void)fprintf( outfile, " Samba Log\n\n\n\n" ); convert(); (void)fprintf( outfile, "\n\n" ); return( 0 ); } /* main */