diff options
author | Didier Raboud <odyx@debian.org> | 2017-07-23 10:09:07 +0200 |
---|---|---|
committer | Didier Raboud <odyx@debian.org> | 2017-07-23 10:09:07 +0200 |
commit | 0f983307b0dcfbc041c8f5f95f58d5fdcdd6c307 (patch) | |
tree | 66996e1a8b1ad790b09c0890ac7986873b7d435a /bjnp-debug.c |
Import cups-bjnp_2.0.orig.tar.gz
[dgit import orig cups-bjnp_2.0.orig.tar.gz]
Diffstat (limited to 'bjnp-debug.c')
-rw-r--r-- | bjnp-debug.c | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/bjnp-debug.c b/bjnp-debug.c new file mode 100644 index 0000000..a1da85d --- /dev/null +++ b/bjnp-debug.c @@ -0,0 +1,268 @@ +/* + * debug support code + * Part of: + * bjnp backend for the Common UNIX Printing System (CUPS). + * Copyright 2008-2014 by Louis Lagendijk + * + * 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; version 2 only. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + + +#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 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[1024]; + struct timeb timebuf; + int sec; + int msec; + + if (level <= debug_level) { + /* 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 */ + + if (level <= LOG_WARN) { + fprintf(stderr, "%s: %s", level2str(level), printbuf); + } + + /* all log messages may go to the own logfile */ + + if (debug_file != NULL) { + 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); + fflush(debug_file); + } + } +} + +void +bjnp_set_debug_level(const char *level, const char *filename) +{ + /* + * set debug level to level (string) + */ + + struct timeb timebuf; + char loglevel[16]; + + ftime(&timebuf); + start_sec = timebuf.time; + start_msec = timebuf.millitm; + + /* + * Set log level + */ + + if (level == NULL) { + debug_level = LOG_ERROR; + } else { + strncpy(loglevel, level, 15); + loglevel[15] = '\0'; + debug_level = str2level(loglevel); + } + + if (filename == NULL) { + filename = CUPS_LOGDIR "/" LOGFILE; + } + + if ((debug_file = fopen(filename, "w")) == NULL) { + bjnp_debug(LOG_WARN, + "Cannot open logfile: %s - %s\n", + filename, strerror(errno)); + return; + } + + bjnp_debug(LOG_WARN, "BJNP logging to %s, debug level = %s\n", filename, level2str(debug_level)); +} |