diff options
author | Joe Nahmias <joe@nahmias.net> | 2012-12-07 21:44:43 -0500 |
---|---|---|
committer | Joe Nahmias <joe@nahmias.net> | 2012-12-07 21:44:43 -0500 |
commit | 879e6db06338166657609930768f76d8d7e7afbb (patch) | |
tree | 3018a2ec0a6aca4150250084bdaf4451ec4e1c3b /bjnp-debug.c |
Imported Upstream version 1.2
Diffstat (limited to 'bjnp-debug.c')
-rw-r--r-- | bjnp-debug.c | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/bjnp-debug.c b/bjnp-debug.c new file mode 100644 index 0000000..05c52f4 --- /dev/null +++ b/bjnp-debug.c @@ -0,0 +1,272 @@ +/* + * debug support code + * Part of: + * bjnp backend for the Common UNIX Printing System (CUPS). + * Copyright 2008 by Louis Lagendijk + * + * These coded instructions, statements, and computer programs are the + * property of Louis Lagendijk and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * <to be added> + */ + + +#include <stdio.h> +#include <stdarg.h> +#include <sys/timeb.h> +#include <errno.h> +#include "bjnp.h" + +#ifdef __GNUC__ +# define UNUSED(v) (void) v +#else +# define UNUSED(v) +#endif + + + +typedef struct +{ + bjnp_loglevel_t level; + char string[10]; +} logtable_entry_t; + +static logtable_entry_t logtable[] = { + {LOG_NONE, "NONE"}, + {LOG_EMERG, "EMERG"}, + {LOG_ALERT, "ALERT"}, + {LOG_CRIT, "CRIT"}, + {LOG_ERROR, "ERROR"}, + {LOG_WARN, "WARNING"}, + {LOG_NOTICE,"NOTICE"}, + {LOG_INFO, "INFO"}, + {LOG_DEBUG, "DEBUG"}, + {LOG_DEBUG2,"DEBUG2"}, + {LOG_END, ""} +}; + +/* + * static data + */ + +static bjnp_loglevel_t debug_level = LOG_ERROR; +static int to_cups = 0; +static FILE *debug_file = NULL; +static time_t start_sec = 0; +static int start_msec; + +/* + * local functions + */ + +#ifndef NDEBUG + +static void +u8tohex (uint8_t x, char *str) +{ + static const char hdigit[16] = + { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', + 'e', 'f' + }; + str[0] = hdigit[(x >> 4) & 0xf]; + str[1] = hdigit[x & 0xf]; + str[2] = '\0'; +} + +static void +u8tochar (uint8_t x, char *str) +{ + if ((x > 0x20) && (x < 0x7f)) + str[0] = (char) x; + else + str[0] = (char) '.'; +} + +static void +u32tohex (uint32_t x, char *str) +{ + u8tohex (x >> 24, str); + u8tohex (x >> 16, str + 2); + u8tohex (x >> 8, str + 4); + u8tohex (x, str + 6); +} + +char * +level2str (bjnp_loglevel_t level) +{ + int i; + for (i = 0; logtable[i].level != LOG_END; i++) + { + if (logtable[i].level == level) + return logtable[i].string; + } + return "UNDEF"; +} + +bjnp_loglevel_t +str2level (const char *level) +{ + int i; + + for (i = 0; strlen (logtable[i].string) != 0; i++) + { + if (strncasecmp (level, logtable[i].string, 10) == 0) + return logtable[i].level; + } + return LOG_END; + +} + +void +bjnp_hexdump (bjnp_loglevel_t level, char *header, const void *d_, + unsigned len) +{ + const uint8_t *d = (const uint8_t *) (d_); + unsigned ofs, c; + char line[100]; /* actually only 1+8+1+8*3+1+8*3+1+4+16 = 80 bytes needed */ + + if (level > debug_level) + return; + + + bjnp_debug (level, "%s\n", header); + ofs = 0; + while (ofs < len) + { + char *p; + + memset (line, ' ', sizeof (line)); + + line[0] = ' '; + u32tohex (ofs, line + 1); + line[9] = ':'; + p = line + 10; + for (c = 0; c != 16 && (ofs + c) < len; c++) + { + u8tohex (d[ofs + c], p); + p[2] = ' '; + p += 3; + if (c == 7) + { + p[0] = ' '; + p++; + } + } + p[0] = p[1] = p[2] = ' '; + p = line + 61; + for (c = 0; c != 16 && (ofs + c) < len; c++) + { + u8tochar (d[ofs + c], p); + + p++; + if (c == 7) + { + p[0] = ' '; + p++; + } + } + + p[0] = '\0'; + bjnp_debug (level, "%s\n", line); + ofs += c; + } + bjnp_debug (level, "\n\n"); +} + +#endif /* NDEBUG */ + +void +bjnp_debug (bjnp_loglevel_t level, const char *fmt, ...) +{ + va_list ap; + char printbuf[256]; + struct timeb timebuf; + int sec; + int msec; + + /* print received data into a string */ + va_start (ap, fmt); + vsnprintf (printbuf, sizeof (printbuf), fmt, ap); + va_end (ap); + + /* we only send real errors & warnings to the cups logging facility, unless explicitely asked */ + + if ((level <= LOG_WARN) || to_cups) + fprintf (stderr, "%s: %s", level2str (level), printbuf); + + /* other log messages may go to the own logfile */ + + if ((level <= debug_level) && debug_file) + { + ftime (&timebuf); + if ((msec = timebuf.millitm - start_msec) < 0) + { + msec += 1000; + timebuf.time -= 1; + } + sec = timebuf.time - start_sec; + + fprintf (debug_file, "%8s: %03d.%03d %s", level2str (level), sec, msec, + printbuf); + } +} + +void +bjnp_set_debug_level (const char *level) +{ + /* + * set debug level to level (string) + */ + + struct timeb timebuf; + char loglevel[16]; + char *separator; + + ftime (&timebuf); + start_sec = timebuf.time; + start_msec = timebuf.millitm; + + /* + * Split string into loglevel and optional cupslog string + */ + + to_cups = 0; + + /* + * Set log level + */ + + if (level == NULL) + debug_level = LOG_ERROR; + else + { + strncpy (loglevel, level, 15); + loglevel[15] = '\0'; + + separator = strchr(loglevel, '_'); + if (separator) + { + *separator = '\0'; + separator++; + + /* any input after the _ will set logging to the cups-log */ + + if (strlen(separator) > 0) + to_cups = 1; + } + debug_level = str2level (level); + } + + + if ((debug_file = fopen (CUPS_LOGDIR "/" LOGFILE, "w")) == NULL) + bjnp_debug(LOG_WARN, "Can not open logfile: %s - %s\n", + CUPS_LOGDIR "/" LOGFILE, strerror(errno)); + + bjnp_debug (LOG_INFO, "BJNP debug level = %s\n", level2str (debug_level)); +} |