/* * log.c: Miscellaneous logging functions * * Copyright (C) 2001, 2002 Juha Yrjölä * Copyright (C) 2003 Antti Tapaninen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "internal.h" #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_IO_H #include #endif #include /* Although not used, we need this for consistent exports */ void _sc_debug(sc_context_t *ctx, const char *format, ...) { va_list ap; va_start(ap, format); sc_do_log_va(ctx, SC_LOG_TYPE_DEBUG, NULL, 0, NULL, format, ap); va_end(ap); } void sc_do_log(sc_context_t *ctx, int type, const char *file, int line, const char *func, const char *format, ...) { va_list ap; va_start(ap, format); sc_do_log_va(ctx, type, file, line, func, format, ap); va_end(ap); } /* * Default debug/error message output */ static int use_color(sc_context_t *ctx, FILE * outf) { static const char *terms[] = { "linux", "xterm", "Eterm", "rxvt", "rxvt-unicode" }; static char *term = NULL; int term_count = sizeof(terms) / sizeof(terms[0]); int do_color, i; if (!isatty(fileno(outf))) return 0; if (term == NULL) { term = getenv("TERM"); if (term == NULL) return 0; } do_color = 0; for (i = 0; i < term_count; i++) { if (strcmp(terms[i], term) == 0) { do_color = 1; break; } } return do_color; } void sc_do_log_va(sc_context_t *ctx, int type, const char *file, int line, const char *func, const char *format, va_list args) { char buf[1836], *p; int r; size_t left; #ifdef _WIN32 SYSTEMTIME st; #else struct tm *tm; struct timeval tv; char time_string[40]; #endif const char *color_pfx = "", *color_sfx = ""; FILE *outf = NULL; int n; assert(ctx != NULL); if (type != SC_LOG_TYPE_DEBUG) return; if (ctx->debug == 0) return; p = buf; left = sizeof(buf); #ifdef _WIN32 GetLocalTime(&st); r = snprintf(p, left, "%i-%02i-%02i %02i:%02i:%02i.%03i ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); #else gettimeofday (&tv, NULL); tm = localtime (&tv.tv_sec); strftime (time_string, sizeof(time_string), "%H:%M:%S", tm); r = snprintf(p, left, "0x%lx %s.%03ld ", (unsigned long)pthread_self(), time_string, tv.tv_usec / 1000); #endif p += r; left -= r; if (file != NULL) { r = snprintf(p, left, "[%s] %s:%d:%s: ", ctx->app_name, file, line, func ? func : ""); if (r < 0 || (unsigned int)r > sizeof(buf)) return; } else { r = 0; } p += r; left -= r; r = vsnprintf(p, left, format, args); if (r < 0) return; p += r; left -= r; outf = ctx->debug_file; if (outf == NULL) return; if (use_color(ctx, outf)) { color_sfx = "\33[0m"; color_pfx = "\33[00;32m"; } fprintf(outf, "%s%s%s", color_pfx, buf, color_sfx); n = strlen(buf); if (n == 0 || buf[n-1] != '\n') fprintf(outf, "\n"); fflush(outf); return; } void sc_hex_dump(sc_context_t *ctx, const u8 * in, size_t count, char *buf, size_t len) { char *p = buf; int lines = 0; assert(buf != NULL && in != NULL); buf[0] = 0; if ((count * 5) > len) return; while (count) { char ascbuf[17]; size_t i; for (i = 0; i < count && i < 16; i++) { sprintf(p, "%02X ", *in); if (isprint(*in)) ascbuf[i] = *in; else ascbuf[i] = '.'; p += 3; in++; } count -= i; ascbuf[i] = 0; for (; i < 16 && lines; i++) { strcat(p, " "); p += 3; } strcat(p, ascbuf); p += strlen(p); sprintf(p, "\n"); p++; lines++; } } char * sc_dump_hex(const u8 * in, size_t count) { static char dump_buf[0x1000]; size_t ii, size = sizeof(dump_buf) - 0x10; size_t offs = 0; memset(dump_buf, 0, sizeof(dump_buf)); if (in == NULL) return dump_buf; for (ii=0; ii size) break; } if (ii