diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2006-11-27 18:23:13 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2006-11-27 18:23:13 +0000 |
commit | 295ff01a3353fa69202103bae567890d9cb759e6 (patch) | |
tree | 766979ba45a2e9b2f645bb4cf4176965ca15da3b /src/main.c | |
parent | add6b8e2be4c3d828a0587a80a6a9072032171eb (diff) | |
download | mailfromd-295ff01a3353fa69202103bae567890d9cb759e6.tar.gz mailfromd-295ff01a3353fa69202103bae567890d9cb759e6.tar.bz2 |
(disable_prog_trace,debug_level_p,enable_debug)
(enable_debug_list,disable_debug_list): New functions
The option --debug can take a comma-separated list of debug
specifications.
The option --trace-program takes as an optional argument a
comma-separated list of modules to trace
git-svn-id: file:///svnroot/mailfromd/trunk@977 7a8a7f39-df28-0410-adc6-e0d955640f24
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 186 |
1 files changed, 163 insertions, 23 deletions
@@ -58,7 +58,6 @@ int do_transcript; /* Enable session transript */ int do_trace; /* Enable tracing configuration */ int debug_level; /* Debugging level */ unsigned optimization_level = 1; /* Optimization level */ -int prog_trace_option; /* Trace program execution */ int log_to_stderr; /* Use stderr for logging */ char *smtp_domain; /* Default SMTP domain for EHLO command */ char *portspec = DEFAULT_SOCKET; /* Communication socket specification */ @@ -191,6 +190,165 @@ log_status(sfsistat status, SMFICTX *ctx) } } +struct file_debug_level { + struct file_debug_level *next; + char *name; + size_t namelen; + int level; +}; + +struct file_debug_level *debug_level_list; + +#define FILE_TO_MODULE_NAME(s,p,l) do { \ + char *q; \ + p = strrchr(s, '/'); \ + if (p) \ + p++; \ + else \ + p = s; \ + q = strrchr(p, '.'); \ + if (q) \ + l = q - s; \ + else \ + l = strlen(p); \ + if (l > 3 && memcmp(p, "bi_", 3) == 0) { \ + p += 3; \ + l -= 3; \ + } \ +} while (0); + +int +debug_level_p(const char *file, int level) +{ + struct file_debug_level *dlev; + const char *name; + size_t len; + + if (debug_level >= level) + return 1; + + FILE_TO_MODULE_NAME(file, name, len); + for (dlev = debug_level_list; dlev; dlev = dlev->next) + if (dlev->namelen == len + && memcmp(dlev->name, name, len) == 0 + && dlev->level >= level) + return 1; + return 0; +} + +void +enable_debug(const char *file) +{ + struct file_debug_level *dlev; + const char *p, *spec; + char *q; + size_t len; + int level = 100; + + if (isdigit(*file)) { + debug_level = strtoul(file, &q, 0); + if (*q) + error(0, 0, "%s: wrong debug spec near %s", file, q); + if (debug_level >= 100) + enable_prog_trace("all"); + return; + } + + FILE_TO_MODULE_NAME(file, spec, len); + p = strchr(spec, '='); + if (p) { + len -= strlen(p); + level = strtoul(p + 1, &q, 0); + if (*q) { + error(0, 0, "%s: wrong debug spec near %s", file, q); + return; + } + } + + dlev = xmalloc(sizeof *dlev); + dlev->name = xmalloc(len + 1); + memcpy(dlev->name, spec, len); + dlev->name[len] = 0; + dlev->namelen = len; + dlev->next = debug_level_list; + dlev->level = level; + if (level == 100) + enable_prog_trace(dlev->name); + debug_level_list = dlev; +} + +void +disable_debug(const char *file) +{ + struct file_debug_level *dlev, *prev; + const char *p, *spec; + char *q; + size_t len; + int level = 100; + + if (isdigit(*file)) { + debug_level = strtoul(file, &q, 0); + if (*q) + error(0, 0, "%s: wrong debug spec near %s", file, q); + return; + } + + FILE_TO_MODULE_NAME(file, spec, len); + p = strchr(spec, '='); + if (p) { + len -= strlen(p); + level = strtoul(p + 1, &q, 0); + if (*q) { + error(0, 0, "%s: wrong debug spec near %s", file, q); + return; + } + } + + dlev = debug_level_list; + prev = NULL; + while (dlev) { + struct file_debug_level *next = dlev->next; + if (dlev->namelen == len + && memcmp(dlev->name, spec, len) == 0 + && dlev->level == level) { + if (prev) + prev->next = next; + else + debug_level_list = next; + if (level == 100) + disable_prog_trace(dlev->name); + free(dlev->name); + free(dlev); + break; + } + prev = dlev; + dlev = next; + } + debug_level_list = dlev; +} + +void +enable_debug_list(const char *spec) +{ + char *copy = xstrdup(spec); + char *s; + + for (s = strtok(copy,","); s; s = strtok(NULL, ",")) + enable_debug(s); + free(copy); +} + +void +disable_debug_list(const char *spec) +{ + char *copy = xstrdup(spec); + char *s; + + for (s = strtok(copy,","); s; s = strtok(NULL, ",")) + disable_debug(s); + free(copy); +} + /* Sendmail class file support */ @@ -304,22 +462,10 @@ set_ehlo(void *value) smtp_domain = value; } -int -decode_debug(char *arg, int set) -{ - char *p; - debug_level = strtol(arg, &p, 0); - if (*p) { - mu_error("Debug level must be numeric"); - return 1; - } - return 0; -} - void set_debug(void *value) { - decode_debug(value, 1); + enable_debug_list(value); } void @@ -527,10 +673,6 @@ option_boolean(char *opt, void **pval, char *newval) int option_debug(char *opt, void **pval, char *newval) { - if (decode_debug(newval, 0)) { - errno = EINVAL; - return 1; - } return option_string(opt, pval, newval); } @@ -849,7 +991,8 @@ static struct argp_option options[] = { N_("Enable transcript"), GRP+1 }, { "trace", OPTION_TRACE, NULL, 0, N_("Enable tracing configuration"), GRP+1 }, - { "trace-program", OPTION_TRACE_PROGRAM, NULL, 0, + { "trace-program", OPTION_TRACE_PROGRAM, N_("MODULES"), + OPTION_ARG_OPTIONAL, N_("Enable program tracing"), GRP+1 }, { "debug", 'd', N_("LEVEL"), 0, N_("Set debugging level"), GRP+1 }, @@ -1106,7 +1249,7 @@ parse_opt (int key, char *arg, struct argp_state *state) break; case OPTION_TRACE_PROGRAM: - prog_trace_option = 1; + enable_prog_trace(arg ? arg: "all"); break; case ARGP_KEY_FINI: @@ -1477,9 +1620,6 @@ main(int argc, char **argv) #endif builtin_post_setup(); - - if (debug_level >= 100) - prog_trace_option = 1; if (config_dump_tree) print_config(); |