aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2006-11-27 18:23:13 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2006-11-27 18:23:13 +0000
commit295ff01a3353fa69202103bae567890d9cb759e6 (patch)
tree766979ba45a2e9b2f645bb4cf4176965ca15da3b /src/main.c
parentadd6b8e2be4c3d828a0587a80a6a9072032171eb (diff)
downloadmailfromd-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.c186
1 files changed, 163 insertions, 23 deletions
diff --git a/src/main.c b/src/main.c
index c016c77c..80496fc7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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();

Return to:

Send suggestions and report system problems to the System administrator.