Logo Search packages:      
Sourcecode: tcpreen version File versions  Download package

output.c

/*
 * output.c - log output function for various formats
 * $Id: output.c 188 2006-03-18 20:00:19Z remi $
 */

/***********************************************************************
 *  Copyright (C) 2002-2005 Remi Denis-Courmont.                       *
 *  This program is free software; you can redistribute and/or modify  *
 *  it under the terms of the GNU General Public License as published  *
 *  by the Free Software Foundation; version 2 of the license.         *
 *                                                                     *
 *  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, you can get it from:              *
 *  http://www.gnu.org/copyleft/gpl.html                               *
 ***********************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "secstdio.h"
#include <ctype.h> /* isprint() */

#include "gettext.h"

#include "output.h"

int fwrite_count (const void *buf, int len, FILE *stream)
{
      (void)buf;
      fprintf (stream, "%d %s\n", len, ngettext ("byte", "bytes", len));
      return len;
}


/*
 * Displays non-readable and extended characters in C string-like form.
 */
static int
fputc_C (int c, FILE *stream)
{
      unsigned char b;
      int errflag;
      b = (unsigned char)c;

      if (b > 127)
            errflag = fprintf (stream, "\\0x%02X", (unsigned int)b) != 5;
      else if (b == '\\')
            errflag = fputs ("\\\\", stream) < 0;
      else if (b >= 32)
            errflag = fputc(c, stream) != b;
      else switch (b) {
            case 0:
                  errflag = fputs ("\\0", stream) < 0;
                  break;
                  
            case '\r':
                  errflag = fputs ("\\r", stream) < 0;
                  break;
                  
            case '\n':
                  errflag = fputs ("\\n", stream) < 0;
                  break;
                  
            case 27:
                  errflag = fputs ("\\E", stream) < 0;
                  break;
                  
            default:
                  errflag = fprintf (stream, "\\0x%02X", (unsigned int)b) != 5;
      }
      return errflag ? EOF : b;

}


int fwrite_C (const void *buf, int len, FILE *stream)
{
      int i;
      for (i = 0; i < len; i++)
            if (fputc_C (((const unsigned char *)buf)[i], stream) == EOF)
                  return i;
      fputs ("\n", stream);
      return len;
}


/*
 * Displays only printable ASCII characters.
 */
static int
fputc_strip (int c, FILE *stream)
{
      return (fputc (isprint (c) ? c : '.', stream) != EOF)
            ? (unsigned char)c : EOF;
}


int fwrite_strip (const void *buf, int len, FILE *stream)
{
      int i;
      unsigned char c;

      for (i = 0; i < len; i++)
      {
            c = ((const unsigned char *)buf)[i];
            if (c != '\r')
            {
                  if (((c != '\n') ? fputc_strip (c, stream)
                              : fputc ('\n', stream)) == EOF)
                        return i;
            }
      }
      return len;
}


/*
 * Displays any characters in hexadecimal form
 * (for binary protocols).
 */
#define HEX_DIGIT( n ) ((n) < 10) ? ('0' + (n)) : ('A' + (n) - 10)
static int
fputc_hex (int c, FILE *stream)
{
      unsigned char b;
      b = (unsigned char)c;

      if ((fputc (HEX_DIGIT(b >> 4), stream) == EOF)
       || (fputc (HEX_DIGIT(b & 0x0f), stream) == EOF))
            return EOF;
      return b;
}
#undef HEX_DIGIT


int fwrite_hex (const void *buf, int len, FILE *stream)
{
      int i = 0, j = 0;

      if (fputs ("   |  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F |\n"
               "-------+-------------------------------------------------+"
               "----------------\n", stream) == EOF)
            return 0;

      while (i < len)
      {
            if (fprintf (stream, "0x%04x | ", i) != 9)
                  return 0;
            do
            {
                  if ((fputc_hex (((const unsigned char *)buf)[j],
                        stream) == EOF)
                   || (fputc (' ', stream) == EOF))
                        return i;
                  j++;
            }
            while ((j & 0xf) && (j < len));

            /* fills extra space at end of packet */
            while (j & 0xf)
            {
                  if (fwrite("   ", 3, 1, stream) != 1)
                        return i;
                  j++;
            }

            if (fwrite ("| ", 2, 1, stream) != 1)
                  return i;
            do
            {
                  if (fputc_strip (((const unsigned char *)buf)[i],
                              stream) == EOF)
                        return i;
                  i++;
            }
            while ((i & 0xf) && (i < len));

            if (fputc ('\n', stream) == EOF)
                  return i;
      }
      fprintf (stream, ("Packet length: 0x%04x (%5d) %s\n\n"), len, len,
               ngettext ("byte", "bytes", len));
      return len;
}

/*
 * Displays any characters without encoding
 * (for pure 7-bit clean protocols mainly).
 * USE IS DISCOURAGED.
 */
int fwrite_raw (const void *buf, int len, FILE *stream)
{
      return fwrite (buf, 1, len, stream);
}


Generated by  Doxygen 1.6.0   Back to index