/* This file is part of gacopyz. Copyright (C) 2006, 2007 Sergey Poznyakoff 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; either version 3, or (at your option) any later version. 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 . */ #include void (*__gacopyz_log_printer)(int, char *, va_list) = gacopyz_syslog_log_printer; /* Logging */ void gacopyz_syslog_log_printer(int level, char *fmt, va_list ap) { switch (level) { case SMI_LOG_DEBUG: level = LOG_DEBUG; break; case SMI_LOG_INFO: level = LOG_INFO; break; case SMI_LOG_WARN: level = LOG_WARNING; break; case SMI_LOG_ERR: level = LOG_ERR; break; case SMI_LOG_FATAL: default: level = LOG_EMERG; } vsyslog(level, fmt, ap); /* FIXME: if absent? */ } static char *level_name[] = { "DEBUG", "INFO", "WARN", "ERR", "FATAL" }; int gacopyz_string_to_log_level(const char *str) { int i; for (i = 0; i < sizeof level_name / sizeof level_name[0]; i++) if (strcasecmp (str, level_name[i]) == 0) return i; return -1; } const char * gacopyz_log_level_to_string(int level) { if (level < 0 || level > sizeof level_name / sizeof level_name[0]) return NULL; return level_name[level]; } void gacopyz_stderr_log_printer(int level, char *fmt, va_list ap) { fprintf(stderr, "Gacopyz %s: ", gacopyz_log_level_to_string(level)); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); } void gacopyz_logmsg(int level, char *fmt, ...) { va_list ap; va_start(ap, fmt); __gacopyz_log_printer(level, fmt, ap); va_end(ap); } void gacopyz_log(gacopyz_conn_t conn, int level, char *fmt, ...) { if (conn->logmask & SMI_LOG_MASK(level)) { va_list ap; va_start(ap, fmt); __gacopyz_log_printer(level, fmt, ap); va_end(ap); } } void gacopyz_io_log(gacopyz_iod_t iod, int level, char *fmt, ...) { if (iod->logmask & SMI_LOG_MASK(level)) { va_list ap; va_start(ap, fmt); __gacopyz_log_printer(level, fmt, ap); va_end(ap); } } size_t gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], const char *buf, size_t size) { char *p = vbuf; char *q = vbuf + 51; int i; size_t j = 0; for (i = 0; i < 16; i++) { unsigned c; if (j < size) { c = *(const unsigned char*)buf++; j++; } else c = 0; sprintf(p, "%02X ", c); p += 3; *q++ = isprint(c) ? c : '.'; if (i == 7) { *p++ = ' '; *q++ = ' '; } } *p++ = ' '; *p = ' '; *q = 0; return j; } void _gacopyz_logdump(int logmask, int level, const char *pfx, const char *buf, size_t size) { if (logmask & SMI_LOG_MASK(level)) { char vbuf[GACOPYZ_VBUFSIZE]; while (size) { size_t rd = gacopyz_format_vbuf(vbuf, buf, size); gacopyz_logmsg(level, "%s: %s", pfx, vbuf); size -= rd; buf += rd; } } } void gacopyz_logdump(gacopyz_conn_t conn, int level, const char *pfx, const char *buf, size_t size) { return _gacopyz_logdump(conn->logmask, level, pfx, buf, size); } void gacopyz_io_logdump(gacopyz_iod_t iod, int level, const char *pfx, const char *buf, size_t size) { return _gacopyz_logdump(iod->logmask, level, pfx, buf, size); } void gacopyz_set_logger(void (*logger)(int, char *, va_list)) { __gacopyz_log_printer = logger; }