diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | doc/mailfromd.texi | 50 | ||||
-rw-r--r-- | gacopyz/gacopyz.h | 7 | ||||
-rw-r--r-- | gacopyz/log.c | 20 | ||||
-rw-r--r-- | gacopyz/smfi.c | 14 | ||||
-rw-r--r-- | src/engine.c | 5 | ||||
-rw-r--r-- | src/gram.y | 19 | ||||
-rw-r--r-- | src/main.c | 22 | ||||
-rw-r--r-- | src/mu_dbm.c | 19 |
9 files changed, 124 insertions, 48 deletions
@@ -1,3 +1,19 @@ +2007-04-28 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/mu_dbm.c: Use F_SETLKW + * src/engine.c (priv_get, filter_cleanup): Add missing env_init + * src/gram.y: Reset state_tag after reducing prog rules + (sendmail_action, header_action): Additional checks + * src/main.c: New option --gacopyz-log + * doc/mailfromd.texi: Document --gacopyz-log + + * gacopyz/smfi.c (smfi_setlogmask): Do what it name suggests. + * gacopyz/gacopyz.h (SMI_LOG_UPTO, SMI_LOG_FROM): New macros + (gacopyz_string_to_log_level, gacopyz_log_level_to_string): New + functions + * gacopyz/log.c (gacopyz_string_to_log_level) + (gacopyz_log_level_to_string): New functions. + 2007-04-27 Sergey Poznyakoff <gray@gnu.org.ua> * src/mailfromd.h (smtp_state_begin,smtp_state_end): New diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi index 1e88bb19..890def01 100644 --- a/doc/mailfromd.texi +++ b/doc/mailfromd.texi @@ -9196,12 +9196,50 @@ Overrides @code{#pragma option stack-trace}, which you are advised to use instead (@pxref{pragma stack-trace}). @xref{tracing runtime errors}, for the detailed description of this feature. -@opsummary{gacopyz-debug} -@item --gacopyz-debug -Instruct @command{gacopyz} library to produce a trace of its -interaction with the @acronym{MTA}. This option is meant to assist in -developing @command{gacopyz}. It issues huge amounts of information -to log files. +@opsummary{gacopyz-log} +@item --gacopyz-log=@var{level} +Set desired logging level for @command{gacopyz} library +(@pxref{Gacopyz}). There are five logging levels. The following +table lists them in order of decreasing priority: + +@table @asis +@item fatal +Log fatal errors. + +@item err +Log error messages. + +@item warn +Log warning messages. + +@item info +Log informational messages. In particular, this enables printing +messages on each subprocess startup and termination, which look like +that: + +@smallexample +Apr 28 09:00:11 host mailfromd[9411]: connect from 192.168.10.1:50398 +Apr 28 09:00:11 host mailfromd[9411]: finishing connection +@end smallexample + +This level can be useful for debugging your scripts. + +@item debug +Log debugging information. This level prints huge amounts of +information, in particular it displays dumps of each Milter packet +sent and received. + +@end table + +Although it is possible to set these levels independently of each +other, it is seldom practical. Therefore, the option +@option{--gacopyz-log=@var{level}} enables all logging levels from +@var{level} up. For example, @option{--gacopyz-log=warn} enables +log levels @samp{warn}, @samp{err} and @samp{fatal}. It is the +default. If you need to trace each subprocess startup and shutdown, +set @option{--gacopyz-log=info}. Setting the logging level to +@samp{debug} can be needed only for @command{Gacopyz} developers, to +debug the protocol. @xref{Testing Filter Scripts}. diff --git a/gacopyz/gacopyz.h b/gacopyz/gacopyz.h index 578f25d4..0e40e171 100644 --- a/gacopyz/gacopyz.h +++ b/gacopyz/gacopyz.h @@ -127,7 +127,9 @@ extern "C" { #define SMI_LOG_FATAL 4 #define SMI_LOG_MASK(n) (1<<(n)) - +#define SMI_LOG_UPTO(n) ((1 << ((n)+1))-1) /* all levels through n */ +#define SMI_LOG_FROM(n) (SMI_LOG_UPTO(SMI_LOG_FATAL) & ~SMI_LOG_UPTO(n-1)) + #define SMI_DEFAULT_LOG_MASK SMI_LOG_MASK(SMI_LOG_INFO) \ | SMI_LOG_MASK(SMI_LOG_WARN) \ | SMI_LOG_MASK(SMI_LOG_ERR) \ @@ -310,6 +312,9 @@ void gacopyz_set_logger(void (*)(int, char *, va_list)); void gacopyz_stderr_log_printer(int level, char *fmt, va_list ap); void gacopyz_syslog_log_printer(int level, char *fmt, va_list ap); +int gacopyz_string_to_log_level(const char *str); +const char *gacopyz_log_level_to_string(int level); + /* Server */ typedef struct gacopyz_srv *gacopyz_srv_t; diff --git a/gacopyz/log.c b/gacopyz/log.c index 05144568..b1dd2348 100644 --- a/gacopyz/log.c +++ b/gacopyz/log.c @@ -54,10 +54,28 @@ static char *level_name[] = { "FATAL" }; +int +gacopyz_string_to_log_level(const char *str) +{ + int i; + for (i = 0; i < sizeof level_name / sizeof level_name[0]; i++) + if (strcasecmp (str, level_name[i]) == 0) + return i; + return -1; +} + +const char * +gacopyz_log_level_to_string(int level) +{ + if (level < 0 || level > sizeof level_name / sizeof level_name[0]) + return NULL; + return level_name[level]; +} + void gacopyz_stderr_log_printer(int level, char *fmt, va_list ap) { - fprintf(stderr, "Gacopyz %s: ", level_name[level]); + fprintf(stderr, "Gacopyz %s: ", gacopyz_log_level_to_string(level)); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); } diff --git a/gacopyz/smfi.c b/gacopyz/smfi.c index 72889436..60fb8439 100644 --- a/gacopyz/smfi.c +++ b/gacopyz/smfi.c @@ -36,18 +36,8 @@ smfi_setdbg(int level) int smfi_setlogmask(int logmask) { - switch (logmask) { - case SMI_LOG_DEBUG: - case SMI_LOG_INFO: - case SMI_LOG_WARN: - case SMI_LOG_ERR: - case SMI_LOG_FATAL: - __smfi_logmask = SMI_LOG_MASK(logmask); - return MI_SUCCESS; - - default: - return MI_FAILURE; - } + __smfi_logmask = logmask; + return MI_SUCCESS; } int diff --git a/src/engine.c b/src/engine.c index c4d28a2a..de567272 100644 --- a/src/engine.c +++ b/src/engine.c @@ -90,6 +90,7 @@ priv_get(SMFICTX *ctx) test_data = md; else gacopyz_setpriv(ctx, md); + env_init(md->env); xeval(md->env, smtp_state_begin); } } @@ -868,6 +869,7 @@ filter_cleanup(SMFICTX *ctx) struct message_data *md = priv_get(ctx); debug(100,"cleaning up"); if (md) { + env_init(md->env); xeval(md->env, smtp_state_end); free(md->helostr); destroy_environment(md->env); @@ -1169,7 +1171,7 @@ static int child_start() { signal(SIGPIPE, SIG_IGN); - signal(SIGUSR1, SIG_IGN); + signal(SIGALRM, SIG_IGN); return 0; } @@ -1364,7 +1366,6 @@ mailfromd_daemon() signal(SIGQUIT, sig_stop); signal(SIGHUP, sig_stop); signal(SIGINT, sig_stop); - signal(SIGUSR1, SIG_IGN); if (!foreground) { if (daemon(0, 0) == -1) { @@ -439,6 +439,7 @@ decl : PROG state_ident DO stmtlist DONE $$->v.progdecl.tree = $4.head; outer_context = inner_context = context_none; + state_tag = smtp_state_none; } | progspecial DO stmtlist DONE { @@ -463,6 +464,7 @@ decl : PROG state_ident DO stmtlist DONE np->v.progdecl.auto_count = forget_autos(PARMCOUNT(), np->v.progdecl.auto_count); outer_context = inner_context = context_none; + state_tag = smtp_state_none; } | FUNC fundecl DO stmtlist DONE { @@ -765,16 +767,19 @@ autodcl : TYPE IDENTIFIER action : sendmail_action { - if (state_tag == smtp_state_begin) - parse_error("sendmail action is not allowed " - "in a begin block"); - else if (state_tag == smtp_state_end) - parse_error("sendmail action is not allowed " - "in an end block"); + if (outer_context == context_handler) { + if (state_tag == smtp_state_begin) + parse_error("sendmail action is not " + "allowed in a begin block"); + else if (state_tag == smtp_state_end) + parse_error("sendmail action is not " + "allowed in an end block"); + } } | header_action { - if (state_tag == smtp_state_end) + if (outer_context == context_handler + && state_tag == smtp_state_end) parse_error("header action is not allowed " "in an end block"); } @@ -805,7 +805,7 @@ enum mailfromd_option { OPTION_DUMP_XREF, OPTION_EXPIRE, OPTION_FOREGROUND, - OPTION_DEBUG_GACOPYZ, + OPTION_GACOPYZ_LOG, OPTION_IGNORE_FAILED_READS, OPTION_LINT, OPTION_LOG_TAG, @@ -958,8 +958,8 @@ static struct argp_option options[] = { { "xref", OPTION_DUMP_XREF, NULL, 0, N_("Produce a cross-reference listing"), GRP+1 }, { "dump-xref", 0, NULL, OPTION_ALIAS, NULL, GRP+1 }, - { "gacopyz-debug", OPTION_DEBUG_GACOPYZ, NULL, 0, - N_("Milter protocol trace"), GRP+1 }, + { "gacopyz-log", OPTION_GACOPYZ_LOG, N_("LEVEL"), 0, + N_("Set Gacopyz log level"), GRP+1 }, { "stderr", 's', NULL, 0, N_("Log to stderr"), GRP+1 }, { "syslog", OPTION_SYSLOG, NULL, 0, @@ -1201,9 +1201,15 @@ parse_opt (int key, char *arg, struct argp_state *state) foreground = 1; break; - case OPTION_DEBUG_GACOPYZ: - smfi_setdbg(1); + case OPTION_GACOPYZ_LOG: + { + int lev = gacopyz_string_to_log_level(arg); + if (lev == -1) + argp_error(state, "%s: invalid Gacopyz log level", + arg); + smfi_setlogmask(SMI_LOG_FROM(lev)); break; + } case OPTION_LIST: need_config = 0; @@ -1259,7 +1265,11 @@ parse_opt (int key, char *arg, struct argp_state *state) case OPTION_TRACE_PROGRAM: enable_prog_trace(arg ? arg: "all"); break; - + + case ARGP_KEY_INIT: + smfi_setlogmask(SMI_LOG_FROM(SMI_LOG_WARN)); + break; + case ARGP_KEY_FINI: if (validate_options()) exit(EX_USAGE); diff --git a/src/mu_dbm.c b/src/mu_dbm.c index 2d7e23c9..4977ae43 100644 --- a/src/mu_dbm.c +++ b/src/mu_dbm.c @@ -219,21 +219,15 @@ int mu_dbm_errno; static int try_lock (int fd, int type, struct flock *fl) { - int i; -#if 0 - signal(SIGALRM, SIG_IGN); - alarm(lock_retry_count_option); - i = fcntl (fd, F_SETLKW, fl); - alarm(0); - return i ? errno : 0; -#endif + int i, rc; + for (i = 0; i < lock_retry_count_option; i++) { - if (fcntl (fd, F_SETLK, fl) == 0) + alarm (lock_retry_timeout_option); + rc = fcntl (fd, F_SETLKW, fl); + alarm (0); + if (rc == 0) return 0; - if (!(errno == EAGAIN || errno == EACCES)) - break; - sleep (lock_retry_timeout_option); } return errno; } @@ -268,7 +262,6 @@ lock_file (const char *name, int fd, int type) rc = try_lock (fd, type, &fl); if (rc == 0) { - kill(0, SIGUSR1); if (type == F_UNLCK) yield (0, 100); } |