Index: ossp-pkg/fsl/TODO RCS File: /v/ossp/cvs/ossp-pkg/fsl/Attic/TODO,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/fsl/Attic/TODO,v' 2>/dev/null --- TODO 2002/07/29 11:41:47 1.2 +++ TODO 2002/07/29 14:42:05 1.3 @@ -1,6 +1,5 @@ - is readfileorallfiles() really reasonable? - what about HAVE_VSYSLOG_USVALIST - allow syslog() without previous openlog()?! -- support "default" ident handling - cfg_destroy fixing and use it - runtime version check for sub libraries Index: ossp-pkg/fsl/fsl.c RCS File: /v/ossp/cvs/ossp-pkg/fsl/fsl.c,v rcsdiff -q -kk '-r1.35' '-r1.36' -u '/v/ossp/cvs/ossp-pkg/fsl/fsl.c,v' 2>/dev/null --- fsl.c 2002/07/29 13:07:05 1.35 +++ fsl.c 2002/07/29 14:42:05 1.36 @@ -76,10 +76,12 @@ /* general return codes */ typedef enum { FSL_OK = 0, /* everything ok */ + FSL_NOIDENT, /* ok but no "ident" directive found or none matched */ FSL_ERR_ARG, /* invalid argument */ FSL_ERR_USE, /* invalid use */ FSL_ERR_MEM, /* no more memory available */ - FSL_ERR_SYS /* operating system error, see errno */ + FSL_ERR_SYS, /* operating system error, see errno */ + FSL_ERR_CUS /* error handled and logged, just run clean up sequence and goodbye */ } fsl_rc_t; /* file buffer handling sub-API */ @@ -426,6 +428,212 @@ return n; } +/* process OSSP cfg node tree directives + mode=0 processes map/ident, + mode=1 processes default + */ +static fsl_rc_t processcfg(cfg_t *cfg, char *cpISF, int mode) +{ + fsl_rc_t rc; + cfg_rc_t cfgrv; + cfg_node_t *cfgseq; + cfg_node_t *cfgdir; + cfg_node_t *cfgarg; + cfg_node_type_t cfgtype; + int cfgnumc; + int cfgnume; + char *cfgargtoka[3]; + char *cfgargtok; + char *argident; + char *argmatch; + char *argl2spec; + char *cp; /* scratch variable */ + int i; /* scratch variable */ + int n; /* scratch variable */ + int ovec[OVECSIZE]; + const char **acpMatch; + l2_channel_t *ch; /* scratch variable */ + l2_result_t l2rv; + int matchcount = 0; + + if ((cfg == NULL) || (cpISF == NULL) || (strlen(cpISF) < 3) || (mode < 0) || (mode > 1)) + return FSL_ERR_ARG; + + fsldebug(L2_LEVEL_TRACE, "processcfg() ident/facility=\"%s\", mode=%s", cpISF, mode == 0 ? "map/ident" : "default"); + + /* find configuration root node and check if it is a sequence and has one or more directives below it */ + if ((cfgrv = cfg_node_root(cfg, &cfgseq)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_root() failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + + /* only dump once */ + if (mode == 0) + traverse(cfg, cfgseq); + + if ((cfgrv = cfg_node_get(cfg, cfgseq, CFG_NODE_ATTR_TYPE, &cfgtype)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_TYPE) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + if (cfgtype != CFG_NODE_TYPE_SEQ) { + fsldebug(L2_LEVEL_ERROR, "processcfg: expected sequence"); CU(FSL_ERR_CUS); } + if ((cfgrv = cfg_node_get(cfg, cfgseq, CFG_NODE_ATTR_CHILDS, &cfgnumc)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_CHILDS) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + if (cfgnumc < 1) { + fsldebug(L2_LEVEL_ERROR, "processcfg: sequence is missing directives, expected 1, got %d", cfgnumc); CU(FSL_ERR_CUS); } + + /* get first directive below sequence */ + if ((cfgrv = cfg_node_get(cfg, cfgseq, CFG_NODE_ATTR_CHILD1, &cfgdir)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_CHILD1) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + while (cfgdir != NULL) { + /* check if operating on a directive */ + if ((cfgrv = cfg_node_get(cfg, cfgdir, CFG_NODE_ATTR_TYPE, &cfgtype)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_TYPE) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + if (cfgtype != CFG_NODE_TYPE_DIR) { + fsldebug(L2_LEVEL_ERROR, "processcfg: expected directive"); CU(FSL_ERR_CUS); } + if ((cfgrv = cfg_node_get(cfg, cfgdir, CFG_NODE_ATTR_CHILDS, &cfgnumc)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_CHILDS) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + + /* process first child of directive, check if it is an argument and has a valid token attached */ + if ((cfgrv = cfg_node_get(cfg, cfgdir, CFG_NODE_ATTR_CHILD1, &cfgarg)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_CHILD1) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + if (cfgarg == NULL) { + fsldebug(L2_LEVEL_ERROR, "processcfg: first argument is NULL"); CU(FSL_ERR_CUS); } + if ((cfgrv = cfg_node_get(cfg, cfgarg, CFG_NODE_ATTR_TYPE, &cfgtype)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_TYPE) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + if (cfgtype != CFG_NODE_TYPE_ARG) { + fsldebug(L2_LEVEL_ERROR, "processcfg: expected first argument, got %d", cfgtype); CU(FSL_ERR_CUS); } + if ((cfgrv = cfg_node_get(cfg, cfgarg, CFG_NODE_ATTR_TOKEN, &cfgargtok)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_TOKEN) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + if (cfgargtok == NULL) { + fsldebug(L2_LEVEL_ERROR, "processcfg: first argument has NULL data"); CU(FSL_ERR_CUS); } + cfgargtoka[0] = cfgargtok; + + cfgnume = 0; + if (strcmp(cfgargtoka[0], "ident") == 0) + cfgnume = 3; + if (strcmp(cfgargtoka[0], "default") == 0) + cfgnume = 3; + if (strcmp(cfgargtoka[0], "map") == 0) + cfgnume = 3; + if (cfgnume == 0) { + fsldebug(L2_LEVEL_ERROR, "processcfg: syntax error, invalid argument \"%s\"", cfgargtoka[0]); CU(FSL_ERR_CUS); } + if (cfgnume != cfgnumc) { + fsldebug(L2_LEVEL_ERROR, "processcfg: directive missing arguments, expected %d, got %d", cfgnume, cfgnumc); CU(FSL_ERR_CUS); } + + for (i = 1; i < cfgnume; i++) { + /* process right brother of argument, check if it is an argument and has a valid token attached */ + if ((cfgrv = cfg_node_get(cfg, cfgarg, CFG_NODE_ATTR_RBROTH, &cfgarg)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_RBROTH) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + if (cfgarg == NULL) { + fsldebug(L2_LEVEL_ERROR, "processcfg: argument %d is NULL", i); CU(FSL_ERR_CUS); } + if ((cfgrv = cfg_node_get(cfg, cfgarg, CFG_NODE_ATTR_TYPE, &cfgtype)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_TYPE) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + if (cfgtype != CFG_NODE_TYPE_ARG) { + fsldebug(L2_LEVEL_ERROR, "processcfg: expected argument %d", i); CU(FSL_ERR_CUS); } + if ((cfgrv = cfg_node_get(cfg, cfgarg, CFG_NODE_ATTR_TOKEN, &cfgargtok)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "processcfg: cfg_node_get(CFG_NODE_ATTR_TOKEN) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + if (cfgargtok == NULL) { + fsldebug(L2_LEVEL_ERROR, "processcfg: argument %d has NULL data", i); CU(FSL_ERR_CUS); } + cfgargtoka[i] = cfgargtok; + } + + if ((strcmp(cfgargtoka[0], "ident") == 0) || (strcmp(cfgargtoka[0], "default") == 0)) { + argident = cfgargtoka[0]; + argmatch = cfgargtoka[1]; + argl2spec = cfgargtoka[2]; + + if ( ((mode == 0) && (strcmp(cfgargtoka[0], "ident") == 0)) + || ((mode == 1) && (strcmp(cfgargtoka[0], "default") == 0)) + ) { + /* process the directive using the three arguments found */ + fsldebug(L2_LEVEL_DEBUG, "processcfg: argident=%s, argmatch=%s, argl2spec=%s", argident, argmatch, argl2spec); + { + pcre *pcreRegex; + pcre_extra *pcreExtra; + const char *cpError; + int iError; + int nMatch; + + /* compile regular expression into finite state machine and optimize */ + if ((pcreRegex = pcre_compile(argmatch, PCRE_CASELESS, &cpError, &iError, NULL)) == NULL) { + fsldebug(L2_LEVEL_ERROR, "processcfg: pcre_compile() failed with error %s (%d)", cpError, iError); CU(FSL_ERR_CUS); } + pcreExtra = pcre_study(pcreRegex, 0, &cpError); + if (cpError != NULL) { + fsldebug(L2_LEVEL_ERROR, "processcfg: pcre_study() failed with error %s", cpError); CU(FSL_ERR_CUS); } + + nMatch = pcre_exec(pcreRegex, pcreExtra, cpISF, strlen(cpISF), 0, 0, ovec, OVECSIZE); + if (nMatch < 0) + fsldebug(L2_LEVEL_TRACE, "processcfg: matching ident/facility \"%s\" against section \"%s\" failed.", cpISF, argmatch); + else + if (nMatch == 0) + fsldebug(L2_LEVEL_TRACE, "processcfg: matching ident/facility \"%s\" against section \"%s\" succeeded, found $0", cpISF, argmatch); + else + fsldebug(L2_LEVEL_TRACE, "processcfg: matching ident/facility \"%s\" against section \"%s\" succeeded, found $0...$%d", cpISF, argmatch, (nMatch-1) > 9 ? 9 : (nMatch-1)); + if (nMatch >= 1) { + pcre_get_substring_list(cpISF, ovec, nMatch, &acpMatch); + if (acpMatch != NULL) + for (i = 0; i < nMatch; i++) + fsldebug(L2_LEVEL_DEBUG, "processcfg: regex reference[%d]=\'%s\'", i, acpMatch[i] == NULL ? "(UNDEFINED)" : acpMatch[i]); + n = substcapture(argl2spec, strlen(argl2spec), acpMatch, nMatch, NULL); + if ((cp = (char *)malloc(n + 1)) == NULL) { + fsldebug(L2_LEVEL_ERROR, "processcfg: malloc() failed"); CU(FSL_ERR_CUS); } + if (substcapture(argl2spec, strlen(argl2spec), acpMatch, nMatch, cp) != n) { + fsldebug(L2_LEVEL_ERROR, "processcfg: substcapture() failed"); CU(FSL_ERR_CUS); } + argl2spec = cp; + fsldebug(L2_LEVEL_DEBUG, "processcfg: argident=%s, argmatch=%s, argl2spec=%s", argident, argmatch, argl2spec); + + /* create L2 channel throuh spec and link into root channel */ + if ((l2rv = l2_spec(&ch, ctx.l2_env, "%s", argl2spec)) != L2_OK) { + cp = l2_env_strerror(ctx.l2_env, l2rv); fsldebug(L2_LEVEL_ERROR, "processcfg: logging failed to create stream from spec %s(%d)", cp, l2rv); CU(FSL_ERR_CUS); } + if ((l2rv = l2_channel_link(ctx.l2_nch, L2_LINK_CHILD, ch, NULL)) != L2_OK) { + cp = l2_env_strerror(ctx.l2_env, l2rv); fsldebug(L2_LEVEL_ERROR, "processcfg: logging failed to link child channel %s(%d)", cp, l2rv); CU(FSL_ERR_CUS); } + matchcount++; + free(argl2spec); + } + } + } + else + fsldebug(L2_LEVEL_DEBUG, "processcfg: ignoring %s in mode %d", cfgargtoka[0], mode); + } + else if (strcmp(cfgargtoka[0], "map") == 0) { + if (mode == 0) { + int mapfrom; + int mapto; + + for (i = 0, mapfrom = -1; (mapfrom == -1) && (sysloglevel2string[i].string != NULL); i++) { + if (strcmp(sysloglevel2string[i].string, cfgargtoka[1]) == 0) + mapfrom = i; + } + if (mapfrom == -1) { + fsldebug(L2_LEVEL_ERROR, "processcfg: trying to map from unknown syslog level \"%s\"", cfgargtoka[1]); CU(FSL_ERR_CUS); } + + for (i = 0, mapto = -1; (mapto == -1) && (l2level2string[i].string != NULL); i++) { + if (strcmp(l2level2string[i].string, cfgargtoka[2]) == 0) + mapto = i; + } + if (mapto == -1) { + fsldebug(L2_LEVEL_ERROR, "processcfg: trying to map to unknown l2 level \"%s\"", cfgargtoka[2]); CU(FSL_ERR_CUS); } + + ctx.levelmap[mapfrom].l2 = l2level2string[mapto].level; + fsldebug(L2_LEVEL_DEBUG, "processcfg: map levelmap[%10s/%d].l2 = l2level2string[%10s/%d].level = 0x%.8lx", cfgargtoka[1], mapfrom, cfgargtoka[2], mapto, (unsigned long)l2level2string[mapto].level); + } + else + fsldebug(L2_LEVEL_DEBUG, "processcfg: ignoring %s in mode %d", cfgargtoka[0], mode); + } + else { + fsldebug(L2_LEVEL_ERROR, "processcfg: internal, argument \"%s\" not implemented", cfgargtoka[0]); CU(FSL_ERR_CUS); } + + /* get right brother of current directive */ + if ((cfgrv = cfg_node_get(cfg, cfgdir, CFG_NODE_ATTR_RBROTH, &cfgdir)) != CFG_OK) { + (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "cfg_node_get(CFG_NODE_ATTR_RBROTH) failed with error %s (%d)", cp, cfgrv); CU(FSL_ERR_CUS); } + } + + fsldebug(L2_LEVEL_TRACE, "processcfg: matched %d sections while looking for %s sections", matchcount, mode == 0 ? "ident" : "default"); + if (matchcount == 0) + CU(FSL_NOIDENT); + else + CU(FSL_OK); +CUS: + return rc; +} + /* POSIX API function openlog(3) */ void openlog(const char *ident, int logopt, int facility) { @@ -434,25 +642,12 @@ fsl_rc_t rv; cfg_t *cfg; cfg_rc_t cfgrv; - cfg_node_t *cfgseq; - cfg_node_t *cfgdir; - cfg_node_t *cfgarg; - cfg_node_type_t cfgtype; - int cfgnumc; - int cfgnume; - char *cfgargtoka[3]; - char *cfgargtok; - char *argident; - char *argmatch; char *argl2spec; char *cp; /* scratch variable */ int i; /* scratch variable */ - int n; /* scratch variable */ char *cpIdent; char *cpFacility; char *cpISF; - int ovec[OVECSIZE]; - const char **acpMatch; l2_channel_t *ch; /* scratch variable */ l2_result_t l2rv; @@ -550,7 +745,7 @@ strcat(cpISF, "/"); strcat(cpISF, cpFacility); - /* read in configuration file(s) */ + /* read configuration file(s) into buffer */ if ((rv = readfileorallfiles(&buf, ident)) != FSL_OK) { fsldebug(L2_LEVEL_ERROR, "openlog: readfileorallfiles(buf, \"%s\") returned %d, system error: %s(%d)", ident, rv, strerror(errno), errno); CU(1); } @@ -560,157 +755,15 @@ if ((cfgrv = cfg_import(cfg, NULL, CFG_FMT_CFG, buf.base, buf.size)) != CFG_OK) { (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_import() failed with error %s (%d)", cp, cfgrv); CU(1); } - /* find configuration root node and check if it is a sequence and has one or more directives below it */ - if ((cfgrv = cfg_node_root(cfg, &cfgseq)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_root() failed with error %s (%d)", cp, cfgrv); CU(1); } - traverse(cfg, cfgseq); - if ((cfgrv = cfg_node_get(cfg, cfgseq, CFG_NODE_ATTR_TYPE, &cfgtype)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_TYPE) failed with error %s (%d)", cp, cfgrv); CU(1); } - if (cfgtype != CFG_NODE_TYPE_SEQ) { - fsldebug(L2_LEVEL_ERROR, "openlog: expected sequence"); CU(1); } - if ((cfgrv = cfg_node_get(cfg, cfgseq, CFG_NODE_ATTR_CHILDS, &cfgnumc)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_CHILDS) failed with error %s (%d)", cp, cfgrv); CU(1); } - if (cfgnumc < 1) { - fsldebug(L2_LEVEL_ERROR, "openlog: sequence is missing directives, expected 1, got %d", cfgnumc); CU(1); } - - /* get first directive below sequence */ - if ((cfgrv = cfg_node_get(cfg, cfgseq, CFG_NODE_ATTR_CHILD1, &cfgdir)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_CHILD1) failed with error %s (%d)", cp, cfgrv); CU(1); } - while (cfgdir != NULL) { - /* check if operating on a directive */ - if ((cfgrv = cfg_node_get(cfg, cfgdir, CFG_NODE_ATTR_TYPE, &cfgtype)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_TYPE) failed with error %s (%d)", cp, cfgrv); CU(1); } - if (cfgtype != CFG_NODE_TYPE_DIR) { - fsldebug(L2_LEVEL_ERROR, "openlog: expected directive"); CU(1); } - if ((cfgrv = cfg_node_get(cfg, cfgdir, CFG_NODE_ATTR_CHILDS, &cfgnumc)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_CHILDS) failed with error %s (%d)", cp, cfgrv); CU(1); } - - /* process first child of directive, check if it is an argument and has a valid token attached */ - if ((cfgrv = cfg_node_get(cfg, cfgdir, CFG_NODE_ATTR_CHILD1, &cfgarg)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_CHILD1) failed with error %s (%d)", cp, cfgrv); CU(1); } - if (cfgarg == NULL) { - fsldebug(L2_LEVEL_ERROR, "openlog: first argument is NULL"); CU(1); } - if ((cfgrv = cfg_node_get(cfg, cfgarg, CFG_NODE_ATTR_TYPE, &cfgtype)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_TYPE) failed with error %s (%d)", cp, cfgrv); CU(1); } - if (cfgtype != CFG_NODE_TYPE_ARG) { - fsldebug(L2_LEVEL_ERROR, "openlog: expected first argument, got %d", cfgtype); CU(1); } - if ((cfgrv = cfg_node_get(cfg, cfgarg, CFG_NODE_ATTR_TOKEN, &cfgargtok)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_TOKEN) failed with error %s (%d)", cp, cfgrv); CU(1); } - if (cfgargtok == NULL) { - fsldebug(L2_LEVEL_ERROR, "openlog: first argument has NULL data"); CU(1); } - cfgargtoka[0] = cfgargtok; - - cfgnume = 0; - if (strcmp(cfgargtoka[0], "ident") == 0) - cfgnume = 3; - if (strcmp(cfgargtoka[0], "default") == 0) - cfgnume = 3; - if (strcmp(cfgargtoka[0], "map") == 0) - cfgnume = 3; - if (cfgnume == 0) { - fsldebug(L2_LEVEL_ERROR, "openlog: syntax error, invalid argument \"%s\"", cfgargtoka[0]); CU(1); } - if (cfgnume != cfgnumc) { - fsldebug(L2_LEVEL_ERROR, "openlog: directive missing arguments, expected %d, got %d", cfgnume, cfgnumc); CU(1); } - - for (i = 1; i < cfgnume; i++) { - /* process right brother of argument, check if it is an argument and has a valid token attached */ - if ((cfgrv = cfg_node_get(cfg, cfgarg, CFG_NODE_ATTR_RBROTH, &cfgarg)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_RBROTH) failed with error %s (%d)", cp, cfgrv); CU(1); } - if (cfgarg == NULL) { - fsldebug(L2_LEVEL_ERROR, "openlog: argument %d is NULL", i); CU(1); } - if ((cfgrv = cfg_node_get(cfg, cfgarg, CFG_NODE_ATTR_TYPE, &cfgtype)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_TYPE) failed with error %s (%d)", cp, cfgrv); CU(1); } - if (cfgtype != CFG_NODE_TYPE_ARG) { - fsldebug(L2_LEVEL_ERROR, "openlog: expected argument %d", i); CU(1); } - if ((cfgrv = cfg_node_get(cfg, cfgarg, CFG_NODE_ATTR_TOKEN, &cfgargtok)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "openlog: cfg_node_get(CFG_NODE_ATTR_TOKEN) failed with error %s (%d)", cp, cfgrv); CU(1); } - if (cfgargtok == NULL) { - fsldebug(L2_LEVEL_ERROR, "openlog: argument %d has NULL data", i); CU(1); } - cfgargtoka[i] = cfgargtok; - } - - if ((strcmp(cfgargtoka[0], "ident") == 0) || (strcmp(cfgargtoka[0], "default") == 0)) { /*FIXME currently default and ident are identical*/ - argident = cfgargtoka[0]; - argmatch = cfgargtoka[1]; - argl2spec = cfgargtoka[2]; - - /* process the directive using the three arguments found */ - fsldebug(L2_LEVEL_DEBUG, "openlog: argident=%s, argmatch=%s, argl2spec=%s", argident, argmatch, argl2spec); - { - pcre *pcreRegex; - pcre_extra *pcreExtra; - const char *cpError; - int iError; - int nMatch; - - /* compile regular expression into finite state machine and optimize */ - if ((pcreRegex = pcre_compile(argmatch, PCRE_CASELESS, &cpError, &iError, NULL)) == NULL) { - fsldebug(L2_LEVEL_ERROR, "openlog: pcre_compile() failed with error %s (%d)", cpError, iError); CU(1); } - pcreExtra = pcre_study(pcreRegex, 0, &cpError); - if (cpError != NULL) { - fsldebug(L2_LEVEL_ERROR, "openlog: pcre_study() failed with error %s", cpError); CU(1); } - - nMatch = pcre_exec(pcreRegex, pcreExtra, cpISF, strlen(cpISF), 0, 0, ovec, OVECSIZE); - if (nMatch < 0) - fsldebug(L2_LEVEL_TRACE, "openlog: matching ident/facility \"%s\" against section \"%s\" failed.", cpISF, argmatch); - else - if (nMatch == 0) - fsldebug(L2_LEVEL_TRACE, "openlog: matching ident/facility \"%s\" against section \"%s\" succeeded, found $0", cpISF, argmatch); - else - fsldebug(L2_LEVEL_TRACE, "openlog: matching ident/facility \"%s\" against section \"%s\" succeeded, found $0...$%d", cpISF, argmatch, (nMatch-1) > 9 ? 9 : (nMatch-1)); - if (nMatch >= 1) { - pcre_get_substring_list(cpISF, ovec, nMatch, &acpMatch); - if (acpMatch != NULL) - for (i = 0; i < nMatch; i++) - fsldebug(L2_LEVEL_DEBUG, "openlog: regex reference[%d]=\'%s\'", i, acpMatch[i] == NULL ? "(UNDEFINED)" : acpMatch[i]); - n = substcapture(argl2spec, strlen(argl2spec), acpMatch, nMatch, NULL); - if ((cp = (char *)malloc(n + 1)) == NULL) { - fsldebug(L2_LEVEL_ERROR, "openlog: malloc() failed"); CU(1); } - if (substcapture(argl2spec, strlen(argl2spec), acpMatch, nMatch, cp) != n) { - fsldebug(L2_LEVEL_ERROR, "openlog: substcapture() failed"); CU(1); } - argl2spec = cp; - fsldebug(L2_LEVEL_DEBUG, "openlog: argident=%s, argmatch=%s, argl2spec=%s", argident, argmatch, argl2spec); - - /* create L2 channel throuh spec and link into root channel */ - if ((l2rv = l2_spec(&ch, ctx.l2_env, "%s", argl2spec)) != L2_OK) { - cp = l2_env_strerror(ctx.l2_env, l2rv); fsldebug(L2_LEVEL_ERROR, "openlog: logging failed to create stream from spec %s(%d)", cp, l2rv); CU(1); } - if ((l2rv = l2_channel_link(ctx.l2_nch, L2_LINK_CHILD, ch, NULL)) != L2_OK) { - cp = l2_env_strerror(ctx.l2_env, l2rv); fsldebug(L2_LEVEL_ERROR, "openlog: logging failed to link child channel %s(%d)", cp, l2rv); CU(1); } - - free(argl2spec); - } - } - } - else if (strcmp(cfgargtoka[0], "map") == 0) { - - int mapfrom; - int mapto; - - for (i = 0, mapfrom = -1; (mapfrom == -1) && (sysloglevel2string[i].string != NULL); i++) { - if (strcmp(sysloglevel2string[i].string, cfgargtoka[1]) == 0) - mapfrom = i; - } - if (mapfrom == -1) { - fsldebug(L2_LEVEL_ERROR, "openlog: trying to map from unknown syslog level \"%s\"", cfgargtoka[1]); CU(1); } - - for (i = 0, mapto = -1; (mapto == -1) && (l2level2string[i].string != NULL); i++) { - if (strcmp(l2level2string[i].string, cfgargtoka[2]) == 0) - mapto = i; - } - if (mapto == -1) { - fsldebug(L2_LEVEL_ERROR, "openlog: trying to map to unknown l2 level \"%s\"", cfgargtoka[2]); CU(1); } - - ctx.levelmap[mapfrom].l2 = l2level2string[mapto].level; - fsldebug(L2_LEVEL_DEBUG, "openlog: map levelmap[%10s/%d].l2 = l2level2string[%10s/%d].level = 0x%.8lx", cfgargtoka[1], mapfrom, cfgargtoka[2], mapto, (unsigned long)l2level2string[mapto].level); - } - else { - fsldebug(L2_LEVEL_ERROR, "openlog: internal, argument \"%s\" not implemented", cfgargtoka[0]); CU(1); } - - /* get right brother of current directive */ - if ((cfgrv = cfg_node_get(cfg, cfgdir, CFG_NODE_ATTR_RBROTH, &cfgdir)) != CFG_OK) { - (void)cfg_error(cfg, cfgrv, &cp); fsldebug(L2_LEVEL_ERROR, "cfg_node_get(CFG_NODE_ATTR_RBROTH) failed with error %s (%d)", cp, cfgrv); CU(1); } - } + /* process OSSP cfg node tree "map" and "ident" directives */ + if ((rv = processcfg(cfg, cpISF, 0)) != FSL_OK && (rv != FSL_NOIDENT)) { + fsldebug(L2_LEVEL_ERROR, "openlog: processcfg() failed with an unrecoverable error (%d)", rv); CU(1); } + + /* optionally process OSSP cfg node tree "default" directives */ + if ((rv == FSL_NOIDENT) && ((rv = processcfg(cfg, cpISF, 1)) != FSL_OK)) { + fsldebug(L2_LEVEL_ERROR, "openlog: processcfg() failed with an unrecoverable error (%d)", rv); CU(1); } + /* open logging now or prepare for delayed open */ if (logopt & LOG_NDELAY) { ctx.delayopen = TRUE; fsldebug(L2_LEVEL_TRACE, "openlog: logopt LOG_NDELAY delays open of L2 channel tree until first message is being logged");