aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--doc/mailfromd.texi50
-rw-r--r--gacopyz/gacopyz.h7
-rw-r--r--gacopyz/log.c20
-rw-r--r--gacopyz/smfi.c14
-rw-r--r--src/engine.c5
-rw-r--r--src/gram.y19
-rw-r--r--src/main.c22
-rw-r--r--src/mu_dbm.c19
9 files changed, 124 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index 0ff8ad50..3850f723 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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) {
diff --git a/src/gram.y b/src/gram.y
index afe12291..fe3c0504 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -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");
}
diff --git a/src/main.c b/src/main.c
index 56aa2af2..d389ec46 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
}

Return to:

Send suggestions and report system problems to the System administrator.