static const char version[] = "1.2.1"; /* * rc.c * * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved. * * See the COPYING file for the terms of usage and distribution. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include static log4c_rc_t __log4c_rc = { { 0, 0, 0, 0 } }; log4c_rc_t* const log4c_rc = &__log4c_rc; /******************************************************************************/ static long parse_byte_size (const char *astring) { /* Parse size in bytes depending on the suffix. Valid suffixes are KB, MB and GB */ size_t sz = strlen (astring); long res = strtol(astring, (char **) NULL, 10); if (res <= 0) return 0; if (astring[ sz - 1 ] == 'B') { switch (astring[ sz - 2 ]) { case 'K': res *= 1024; break; case 'M': res *= 1024 * 1024; break; case 'G': res *= 1024 * 1024 * 1024; break; default: sd_debug("Wrong suffix parsing size in bytes for string %s, ignoring suffix", astring); } } sd_debug("Parsed size parameter %s to value %ld",astring, res); return (res); } /******************************************************************************/ static int config_load(log4c_rc_t* this, sd_domnode_t* anode) { sd_list_iter_t* i = NULL; for (i = sd_list_begin(anode->children); i != sd_list_end(anode->children); i = sd_list_iter_next(i)) { sd_domnode_t* node = i->data; if (!strcmp(node->name, "nocleanup")) { this->config.nocleanup = atoi(node->value); if (this->config.nocleanup) sd_debug("deactivating log4c cleanup"); } if (!strcmp(node->name, "bufsize")) { this->config.bufsize = parse_byte_size(node->value); if (this->config.bufsize) sd_debug("using fixed buffer size of %d bytes", this->config.bufsize); else sd_debug("using dynamic allocated buffer"); } if (!strcmp(node->name, "debug")) { sd_domnode_t* level = sd_domnode_attrs_get(node, "level"); if (level) { this->config.debug = atoi(level->value); sd_debug("activating log4c debugging. level = %d", this->config.debug); } } if (!strcmp(node->name, "reread")) { this->config.reread = atoi(node->value); sd_debug("log4crc reread is %d",this->config.reread); if (0 == this->config.reread) sd_debug("deactivating log4crc reread"); } } return 0; } /******************************************************************************/ static int category_load(log4c_rc_t* this, sd_domnode_t* anode) { sd_domnode_t* name = sd_domnode_attrs_get(anode, "name"); sd_domnode_t* priority = sd_domnode_attrs_get(anode, "priority"); sd_domnode_t* additivity = sd_domnode_attrs_get(anode, "additivity"); sd_domnode_t* appender = sd_domnode_attrs_get(anode, "appender"); log4c_category_t* cat = NULL; if (!name) { sd_error("attribute \"name\" is missing"); return -1; } cat = log4c_category_get(name->value); if (priority) log4c_category_set_priority( cat, log4c_priority_to_int(priority->value)); if (additivity) { if (!strcasecmp(additivity->value, "false")) { log4c_category_set_additivity(cat, 0); } else if (!strcasecmp(additivity->value, "true")) { log4c_category_set_additivity(cat, 1); } else { sd_error("additivity value is invalid : %s", additivity->value); } } if (appender) log4c_category_set_appender( cat, log4c_appender_get(appender->value)); return 0; } /******************************************************************************/ static int appender_load(log4c_rc_t* this, sd_domnode_t* anode) { sd_domnode_t* name = sd_domnode_attrs_get(anode, "name"); sd_domnode_t* type = sd_domnode_attrs_get(anode, "type"); sd_domnode_t* layout = sd_domnode_attrs_get(anode, "layout"); log4c_appender_t* app = NULL; if (!name) { sd_error("attribute \"name\" is missing"); return -1; } sd_debug("appender_load[name='%s'", (name->value ? name->value :"(not set)")); app = log4c_appender_get(name->value); if (type){ sd_debug("appender type is '%s'",(type->value ? type->value: "(not set)")); log4c_appender_set_type(app, log4c_appender_type_get(type->value)); #ifdef WITH_ROLLINGFILE if ( !strcasecmp(type->value, "rollingfile")) { rollingfile_udata_t *rfup = NULL; log4c_rollingpolicy_t *rollingpolicyp = NULL; sd_domnode_t* logdir = sd_domnode_attrs_get(anode,"logdir"); sd_domnode_t* logprefix = sd_domnode_attrs_get(anode,"prefix"); sd_domnode_t* logext = sd_domnode_attrs_get(anode,"ext"); sd_domnode_t* rollingpolicy_name = sd_domnode_attrs_get(anode,"rollingpolicy"); sd_debug("logdir='%s', prefix='%s', rollingpolicy='%s'", (logdir && logdir->value ? name->value :"(not set)"), (logprefix && logprefix->value ? logprefix->value :"(not set)"), (logext && logext->value ? logext->value :"txt"), (rollingpolicy_name && rollingpolicy_name->value ? rollingpolicy_name->value :"(not set)")); rfup = rollingfile_make_udata(); rollingfile_udata_set_logdir(rfup, (char *)logdir->value); rollingfile_udata_set_files_prefix(rfup, (char *)logprefix->value); rollingfile_udata_set_files_ext(rfup, (char *)logext->value); if (rollingpolicy_name){ /* recover a rollingpolicy instance with this name */ rollingpolicyp = log4c_rollingpolicy_get(rollingpolicy_name->value); /* connect that policy to this rollingfile appender conf */ rollingfile_udata_set_policy(rfup, rollingpolicyp); log4c_appender_set_udata(app, rfup); /* allow the policy to initialize itself */ log4c_rollingpolicy_init(rollingpolicyp, rfup); } else { /* no rollingpolicy specified, default to default sizewin */ sd_debug("no rollingpolicy name specified--will default"); } } #endif } if (layout) log4c_appender_set_layout(app, log4c_layout_get(layout->value)); sd_debug("]"); return 0; } /******************************************************************************/ static int layout_load(log4c_rc_t* this, sd_domnode_t* anode) { sd_domnode_t* name = sd_domnode_attrs_get(anode, "name"); sd_domnode_t* type = sd_domnode_attrs_get(anode, "type"); log4c_layout_t* layout = NULL; if (!name) { sd_error("attribute \"name\" is missing"); return -1; } layout = log4c_layout_get(name->value); if (type) log4c_layout_set_type(layout, log4c_layout_type_get(type->value)); return 0; } #ifdef WITH_ROLLINGFILE /******************************************************************************/ static int rollingpolicy_load(log4c_rc_t* this, sd_domnode_t* anode) { sd_domnode_t* name = sd_domnode_attrs_get(anode, "name"); sd_domnode_t* type = sd_domnode_attrs_get(anode, "type"); log4c_rollingpolicy_t* rpolicyp = NULL; long a_maxsize; sd_debug("rollingpolicy_load["); if (!name) { sd_error("attribute \"name\" is missing"); return -1; } rpolicyp = log4c_rollingpolicy_get(name->value); if (type){ log4c_rollingpolicy_set_type(rpolicyp, log4c_rollingpolicy_type_get(type->value)); if (!strcasecmp(type->value, "sizewin")){ sd_domnode_t* maxsize = sd_domnode_attrs_get(anode, "maxsize"); sd_domnode_t* maxnum = sd_domnode_attrs_get(anode, "maxnum"); rollingpolicy_sizewin_udata_t *sizewin_udatap = NULL; sd_debug("type='sizewin', maxsize='%s', maxnum='%s', " "rpolicyname='%s'", (maxsize && maxsize->value ? maxsize->value :"(not set)"), (maxnum && maxnum->value ? maxnum->value :"(not set)"), (name && name->value ? name->value :"(not set)")); /* * Get a new sizewin policy type and configure it. * Then attach it to the policy object. * Check to see if this policy already has a sw udata object. If so, leave as is except update the params */ if ( !(sizewin_udatap = log4c_rollingpolicy_get_udata(rpolicyp))){ sd_debug("creating new sizewin udata for this policy"); sizewin_udatap = sizewin_make_udata(); log4c_rollingpolicy_set_udata(rpolicyp,sizewin_udatap); a_maxsize = parse_byte_size(maxsize->value); if (a_maxsize) sizewin_udata_set_file_maxsize(sizewin_udatap, a_maxsize); else{ sd_debug("When parsing %s a size of 0 was returned. Default size %d will be used", maxsize->value, ROLLINGPOLICY_SIZE_DEFAULT_MAX_FILE_SIZE); sizewin_udata_set_file_maxsize(sizewin_udatap, ROLLINGPOLICY_SIZE_DEFAULT_MAX_FILE_SIZE); } sizewin_udata_set_max_num_files(sizewin_udatap, atoi(maxnum->value)); }else{ sd_debug("policy already has a sizewin udata--just updating params"); sizewin_udata_set_file_maxsize(sizewin_udatap, parse_byte_size(maxsize->value)); sizewin_udata_set_max_num_files(sizewin_udatap, atoi(maxnum->value)); /* allow the policy to initialize itself */ log4c_rollingpolicy_init(rpolicyp, log4c_rollingpolicy_get_rfudata(rpolicyp)); } } } sd_debug("]"); return 0; } #endif /******************************************************************************/ extern int log4c_rc_load(log4c_rc_t* this, const char* a_filename) { sd_list_iter_t* i = NULL; sd_domnode_t* node = NULL; sd_domnode_t* root_node = NULL; sd_debug("parsing file '%s'\n", a_filename); if (!this) return -1; root_node = sd_domnode_new(NULL, NULL); if (sd_domnode_load(root_node, a_filename) == -1) { sd_domnode_delete(root_node); return -1; } /* Check configuration file root node */ if (strcmp(root_node->name, "log4c")) { sd_error("invalid root name %s", root_node->name); sd_domnode_delete(root_node); return -1; } /* Check configuration file revision */ if ( (node = sd_domnode_attrs_get(root_node, "version")) != NULL) { if (strcmp(version, node->value)) { sd_error("version mismatch: %s != %s", version, node->value); sd_domnode_delete(root_node); return -1; } } /* backward compatibility. */ if ( (node = sd_domnode_attrs_get(root_node, "cleanup")) != NULL) { sd_debug("attribute \"cleanup\" is deprecated"); this->config.nocleanup = !atoi(node->value); } /* load configuration elements */ for (i = sd_list_begin(root_node->children); i != sd_list_end(root_node->children); i = sd_list_iter_next(i)) { sd_domnode_t* node = i->data; if (!strcmp(node->name, "category")) category_load(this, node); if (!strcmp(node->name, "appender")) appender_load(this, node); #ifdef WITH_ROLLINGFILE if (!strcmp(node->name, "rollingpolicy"))rollingpolicy_load(this, node); #endif if (!strcmp(node->name, "layout")) layout_load(this, node); if (!strcmp(node->name, "config")) config_load(this, node); } sd_domnode_delete(root_node); return 0; } /******************************************************************************/ extern int log4c_load(const char* a_filename) { return log4c_rc_load(&__log4c_rc, a_filename); }