From 5ebf67efee2893c4d3dc60ec31a0efeb0894d245 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 5 Feb 2010 15:33:39 +0100 Subject: Added logging flag to log_append() to change log behaviour Valid flags are: * LOGFL_NORMAL Log all messages to the log context, and send log message to stderr on errors * LOGFL_NODUPS Log only unique messages. Duplicated messages will be removed * LOGFL_NOSTDERR Don't write to stderr, even if errors occur --- src/dmidecode.c | 11 +++---- src/dmidecodemodule.c | 13 +++++---- src/dmilog.c | 79 +++++++++++++++++++++++++++------------------------ src/dmilog.h | 10 ++++++- src/dmixml.c | 6 ++-- src/efi.c | 5 ++-- src/util.c | 12 ++++---- src/xmlpythonizer.c | 12 ++++---- 8 files changed, 83 insertions(+), 65 deletions(-) diff --git a/src/dmidecode.c b/src/dmidecode.c index 0fd8f1b..a29a743 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -4866,7 +4866,7 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver } if((buf = mem_chunk(logp, base, len, devmem)) == NULL) { - log_append(logp, LOG_WARNING, "Table is unreachable, sorry." + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Table is unreachable, sorry." #ifndef USE_MMAP "Try compiling dmidecode with -DUSE_MMAP." #endif @@ -4889,8 +4889,9 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver ** table is broken. */ if(h.length < 4) { - log_append(logp, LOG_WARNING, "Invalid entry length (%i). DMI table is broken! Stop.", - (unsigned int)h.length); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, + "Invalid entry length (%i). DMI table is broken! Stop.", + (unsigned int)h.length); break; } @@ -4955,10 +4956,10 @@ static void dmi_table(Log_t *logp, int type, u32 base, u16 len, u16 num, u16 ver } if(i != num) - log_append(logp, LOG_WARNING, + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Wrong DMI structures count: %d announced, only %d decoded.\n", num, i); if(data - buf != len) - log_append(logp, LOG_WARNING, + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.\n", len, (unsigned int)(data - buf)); diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index 93a956b..dc00279 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -66,7 +66,8 @@ static void init(options *opt) /* sanity check */ if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) { - log_append(opt->logdata, LOG_WARNING, "%s: compiler incompatibility\n", "dmidecodemodule"); + log_append(opt->logdata, LOGFL_NORMAL, LOG_WARNING, + "%s: compiler incompatibility\n", "dmidecodemodule"); } } @@ -78,11 +79,11 @@ int parse_opt_type(Log_t *logp, const char *arg) val = strtoul(arg, &next, 0); if(next == arg) { - log_append(logp, LOG_ERR, "Invalid type keyword: %s\n", arg); + log_append(logp, LOGFL_NODUPS, LOG_ERR, "Invalid type keyword: %s\n", arg); return -1; } if(val > 0xff) { - log_append(logp, LOG_ERR, "Invalid type number: %i\n", val); + log_append(logp, LOGFL_NODUPS, LOG_ERR, "Invalid type number: %i\n", val); return -1; } @@ -164,7 +165,8 @@ xmlNode *dmidecode_get_version(options *opt) free(buf); } if( !found ) { - log_append(opt->logdata, LOG_WARNING, "No SMBIOS nor DMI entry point found, sorry."); + log_append(opt->logdata, LOGFL_NODUPS, LOG_WARNING, + "No SMBIOS nor DMI entry point found, sorry."); } return ver_n; } @@ -185,7 +187,8 @@ int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) const char *f = opt->dumpfile ? opt->dumpfile : opt->devmem; if(access(f, R_OK) < 0) { - log_append(opt->logdata, LOG_WARNING, "Permission denied to memory file/device (%s)", f); + log_append(opt->logdata, LOGFL_NORMAL, + LOG_WARNING, "Permission denied to memory file/device (%s)", f); return 0; } diff --git a/src/dmilog.c b/src/dmilog.c index e9b89e8..f7ade5d 100644 --- a/src/dmilog.c +++ b/src/dmilog.c @@ -59,51 +59,56 @@ Log_t * log_init() * Registers a new log entry * * @param logp Pointer to an allocated Log_t record. New records will be appended to the end + * @param flags Log flags, to specify logging behaviour * @param level syslog log level values. LOG_ERR and LOG_WARNING are allowed * @param fmt stdarg based string with the log contents * * @return Returns 1 on successful registration of log entry, otherwise -1 and error is printed to stderr + * unless LOGFL_NOSTDERR is set in flags. */ -int log_append(Log_t *logp, int level, const char *fmt, ...) +int log_append(Log_t *logp, Log_f flags, int level, const char *fmt, ...) { - Log_t *ptr = NULL; - va_list ap; - - // Go the end of the record chain - ptr = logp; - while( ptr && ptr->next ) { - ptr = ptr->next; - } - - - if( ptr && ((level == LOG_ERR) || (level == LOG_WARNING)) ) { - ptr->next = log_init(); - if( ptr->next ) { - ptr->next->message = (char *) calloc(1, 4098); - } - } + Log_t *ptr = NULL; + va_list ap; + char logmsg[4098]; + // Prepare log message + memset(&logmsg, 0, 4098); va_start(ap, fmt); - if( !ptr || !ptr->next || !ptr->next->message ) { - if( logp ) { - // Only print this if we logp is pointing somewhere. - // If it is NULL, the caller did not establish a log - // buffer on purpose (like dmidump.c) - thus this is - // not an error with saving the log entry. - fprintf(stderr, "** ERROR ** Failed to save log entry\n"); - } - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - return -1; - } - - ptr->next->level = level; - vsnprintf(ptr->next->message, 4096, fmt, ap); - ptr->next->message = realloc(ptr->next->message, strlen(ptr->next->message)+2); - va_end(ap); - - return 1; + vsnprintf(logmsg, 4096, fmt, ap); + va_end(ap); + + // Go the end of the record chain + ptr = logp; + while( ptr && ptr->next ) { + // Ignore duplicated messages if LOGFL_NODUPS is set + if( (flags & LOGFL_NODUPS) && ptr->next && ptr->next->message + && (strcmp(ptr->next->message, logmsg) == 0) ) { + return 1; + } + ptr = ptr->next; + } + + if( ptr && ((level == LOG_ERR) || (level == LOG_WARNING)) ) { + ptr->next = log_init(); + if( ptr->next ) { + ptr->next->level = level; + ptr->next->message = strdup(logmsg); + return 1; + } + } + + if( !(flags & LOGFL_NOSTDERR) ) { + if( logp ) { + // Only print this if we logp is pointing somewhere. + // If it is NULL, the caller did not establish a log + // buffer on purpose (like dmidump.c) - thus this is + // not an error with saving the log entry. + fprintf(stderr, "** ERROR ** Failed to save log entry\n"); + } + fprintf(stderr, "%s\n", logmsg); + } + return -1; } diff --git a/src/dmilog.h b/src/dmilog.h index 98d0780..76c87b6 100644 --- a/src/dmilog.h +++ b/src/dmilog.h @@ -46,8 +46,16 @@ struct _Log_t { }; typedef struct _Log_t Log_t; +/** + * Log flags. These flags can be OR'ed together + */ +typedef enum { LOGFL_NORMAL = 1, /**< Normal behaviour, log everything and use stderr on errors */ + LOGFL_NODUPS = 2, /**< Don't log messages we already have logged */ + LOGFL_NOSTDERR = 4 /**< Don't use stderr even if log functions fails */ +} Log_f; + Log_t * log_init(); -int log_append(Log_t *logp, int level, const char *fmt, ...); +int log_append(Log_t *logp, Log_f flags, int level, const char *fmt, ...); char * log_retrieve(Log_t *logp, int level); size_t log_clear_partial(Log_t *logp, int level, int unread); void log_close(Log_t *logp); diff --git a/src/dmixml.c b/src/dmixml.c index 6f1fd77..6f6aa60 100644 --- a/src/dmixml.c +++ b/src/dmixml.c @@ -352,9 +352,9 @@ char *dmixml_GetXPathContent(Log_t *logp, char *buf, size_t buflen, xmlXPathObje break; default: - log_append(logp, LOG_WARNING, "dmixml_GetXPathContent(...):: " - "Do not know how to handle XPath type %i\n", - xpo->type); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "dmixml_GetXPathContent(...):: " + "Do not know how to handle XPath type %i\n", + xpo->type); return NULL; } return buf; diff --git a/src/efi.c b/src/efi.c index af0a813..171ae30 100644 --- a/src/efi.c +++ b/src/efi.c @@ -76,8 +76,9 @@ int address_from_efi(Log_t *logp, size_t * address) if(fclose(efi_systab) != 0) perror(filename); - if(ret == EFI_NO_SMBIOS) - log_append(logp, LOG_WARNING, "%s: SMBIOS entry point missing\n", filename); + if(ret == EFI_NO_SMBIOS) { + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "%s: SMBIOS entry point missing\n", filename); + } return ret; } diff --git a/src/util.c b/src/util.c index ba1a89a..f0d9f93 100644 --- a/src/util.c +++ b/src/util.c @@ -69,7 +69,7 @@ static int myread(Log_t *logp, int fd, u8 * buf, size_t count, const char *prefi if(r2 != count) { close(fd); - log_append(logp, LOG_WARNING, "%s: Unexpected end of file\n", prefix); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s: Unexpected end of file\n", prefix); return -1; } @@ -102,12 +102,12 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) #endif if((fd = open(devmem, O_RDONLY)) == -1) { - log_append(logp, LOG_WARNING, "%s: %s", devmem, strerror(errno)); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s: %s", devmem, strerror(errno)); return NULL; } if((p = malloc(len)) == NULL) { - log_append(logp, LOG_WARNING, "malloc: %s", strerror(errno)); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "malloc: %s", strerror(errno)); return NULL; } #ifdef USE_MMAP @@ -123,7 +123,7 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) */ mmp = mmap(0, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset); if(mmp == MAP_FAILED) { - log_append(logp, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); free(p); return NULL; } @@ -131,11 +131,11 @@ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) memcpy(p, (u8 *) mmp + mmoffset, len); if(munmap(mmp, mmoffset + len) == -1) { - log_append(logp, LOG_WARNING, "%s (munmap): %s", devmem, strerror(errno)); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (munmap): %s", devmem, strerror(errno)); } #else /* USE_MMAP */ if(lseek(fd, base, SEEK_SET) == -1) { - log_append(logp, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno)); + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno)); free(p); return NULL; } diff --git a/src/xmlpythonizer.c b/src/xmlpythonizer.c index 8596a9d..5342bac 100644 --- a/src/xmlpythonizer.c +++ b/src/xmlpythonizer.c @@ -304,7 +304,7 @@ inline ptzTYPES _convert_maptype(Log_t *logp, const char *str) { } else if( strcmp(str, "list:dict") == 0 ) { return ptzLIST_DICT; } else { - log_append(logp, LOG_WARNING, + log_append(logp, LOGFL_NORMAL, LOG_WARNING, "Unknown field type: %s - defaulting to 'constant'\n", str); return ptzCONST; } @@ -463,7 +463,7 @@ ptzMAP *_dmimap_parse_mapping_node_typeid(Log_t *logp, xmlNode *mapnode, const c node = dmixml_FindNodeByAttr_NoCase(mapnode, "TypeMap", "id", typeid); if( node == NULL ) { // No exception handling possible here, as we don't return PyObject - log_append(logp, LOG_WARNING, "** WARNING: Could not find any XML->Python " + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "** WARNING: Could not find any XML->Python " "mapping for type ID '%s'", typeid); return NULL; } @@ -665,7 +665,7 @@ inline PyObject *StringToPyObj(Log_t *logp, ptzMAP *val_m, const char *instr) { break; default: - log_append(logp, LOG_WARNING, + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Invalid type '%i' for value '%s'\n", val_m->type_value, instr); value = Py_None; @@ -737,7 +737,7 @@ char *_get_key_value(Log_t *logp, char *key, size_t buflen, break; default: - log_append(logp, LOG_WARNING, "Unknown key type: %i\n", map_p->type_key); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Unknown key type: %i\n", map_p->type_key); return NULL; } // We consider to have a key, if the first byte is a readable @@ -999,7 +999,7 @@ PyObject *_deep_pythonize(Log_t *logp, PyObject *retdata, break; default: - log_append(logp, LOG_WARNING, "Unknown value type: %i\n", map_p->type_value); + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Unknown value type: %i\n", map_p->type_value); break; } @@ -1070,7 +1070,7 @@ PyObject *pythonizeXMLnode(Log_t *logp, ptzMAP *in_map, xmlNode *data_n) { } #ifdef DEBUG else { - log_append(logp, LOG_WARNING, + log_append(logp, LOGFL_NODUPS, LOG_WARNING, "** pythonizeXMLnode :: Could not locate node for key value: " "root path '%s', key '%s'\n", map_p->rootpath, map_p->key); } -- cgit