/* * 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 #endif #include "secstdio.h" #include /* 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); }