/*
* output.c - log output function for various formats
* $Id: output.c,v 1.3 2004/06/05 15:15:17 rdenisc Exp $
*/
/***********************************************************************
* Copyright (C) 2002-2003 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)
{
fprintf (stream, _("%d byte(s)\n"), 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) byte(s)\n\n"), len, 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);
}
syntax highlighted by Code2HTML, v. 0.9.1