detection of self-referential entries was flawed. File:
cleanup/cleanup_map1n.c.
+20011031
+
+ Bugfix: mail_date() mis-formatted negative time zone offsets
+ with fractional hours (-03-30 instead of -0330). Fix by
+ Chad House, greyfirst.ca.
+
Open problems:
Medium: need in-process caching for map lookups.
install_root - prefix for installed file names (for package building)
- tempdir - where to write scratch files
+ tempdir - where to write scratch files while installing Postfix
config_directory - directory with Postfix configuration files.
daemon_directory - directory with Postfix daemon programs.
timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
- verp_sender.c been_here_level.c
+ verp_sender.c
OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
debug_peer.o debug_process.o defer.o deliver_completed.o \
deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
- verp_sender.o been_here_level.o
+ verp_sender.o
HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
#define BH_FLAG_NONE 0 /* no special processing */
#define BH_FLAG_FOLD (1<<0) /* fold case */
- /*
- * been_here.c
- */
extern BH_TABLE *been_here_init(int, int);
extern void been_here_free(BH_TABLE *);
extern int been_here_fixed(BH_TABLE *, const char *);
extern int been_here_check_fixed(BH_TABLE *, const char *);
extern int PRINTFLIKE(2, 3) been_here_check(BH_TABLE *, const char *,...);
- /*
- * been_here_level.c
- */
-extern int been_here_level_fixed(BH_TABLE *, int, const char *);
-extern int PRINTFLIKE(3, 4) been_here_level(BH_TABLE *, int, const char *,...);
-extern int been_here_level_check_fixed(BH_TABLE *, const char *);
-extern int PRINTFLIKE(2, 3) been_here_level_check(BH_TABLE *, const char *,...);
-
/* LICENSE
/* .ad
/* .fi
+++ /dev/null
-/*++
-/* NAME
-/* been_here_level 3
-/* SUMMARY
-/* detect repeated occurrence of string
-/* SYNOPSIS
-/* #include <been_here.h>
-/*
-/* int been_here_level_fixed(dup_filter, level, string)
-/* BH_TABLE *dup_filter;
-/* int level;
-/* char *string;
-/*
-/* int been_here_level(dup_filter, level, format, ...)
-/* BH_TABLE *dup_filter;
-/* int level;
-/* char *format;
-/*
-/* int been_here_level_check_fixed(dup_filter, level, string)
-/* BH_TABLE *dup_filter;
-/* int level;
-/* char *string;
-/*
-/* int been_here_level_check(dup_filter, level, format, ...)
-/* BH_TABLE *dup_filter;
-/* int level;
-/* char *format;
-/* DESCRIPTION
-/* This module implements a simple filter to detect repeated
-/* occurrences of character strings. Each string has associated with
-/* an integer level, the meaning of which is left up to the application.
-/* Otherwise the code is like been_here(3).
-/*
-/* been_here_level_fixed() looks up a fixed string in the given table, and
-/* makes an entry in the table if the string was not found. The result
-/* is >= 0 if the string was found, -1 otherwise.
-/*
-/* been_here_level() formats its arguments, looks up the result in the
-/* given table, and makes an entry in the table if the string was
-/* not found. The result is >= 0 if the formatted result was
-/* found, -1 otherwise.
-/*
-/* been_here_level_check_fixed() and been_here_level_check() are similar
-/* but do not update the duplicate filter.
-/*
-/* Arguments:
-/* .IP size
-/* Upper bound on the table size; at most \fIsize\fR strings will
-/* be remembered. Specify a value <= 0 to disable the upper bound.
-/* .IP flags
-/* Requests for special processing. Specify the bitwise OR of zero
-/* or more flags:
-/* .RS
-/* .IP BH_FLAG_FOLD
-/* Enable case-insensitive lookup.
-/* .IP BH_FLAG_NONE
-/* A manifest constant that requests no special processing.
-/* .RE
-/* .IP dup_filter
-/* The table with remembered names
-/* .IP level
-/* The value that will be returned when the string is found by either
-/* been_here_level() or been_here_check_level(). This value must be
-/* >= 0.
-/* .IP string
-/* Fixed search string.
-/* .IP format
-/* Format for building the search string.
-/* LICENSE
-/* .ad
-/* .fi
-/* The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/* Wietse Venema
-/* IBM T.J. Watson Research
-/* P.O. Box 704
-/* Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include "sys_defs.h"
-#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
-#include <stdarg.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <mymalloc.h>
-#include <htable.h>
-#include <vstring.h>
-#include <stringops.h>
-
-/* Global library. */
-
-#include "been_here.h"
-
-/* been_here_level - duplicate detector with finer control */
-
-int been_here_level(BH_TABLE *dup_filter, int level, const char *fmt,...)
-{
- VSTRING *buf = vstring_alloc(100);
- int status;
- va_list ap;
-
- /*
- * Construct the string to be checked.
- */
- va_start(ap, fmt);
- vstring_vsprintf(buf, fmt, ap);
- va_end(ap);
-
- /*
- * Do the duplicate check.
- */
- status = been_here_level_fixed(dup_filter, level, vstring_str(buf));
-
- /*
- * Cleanup.
- */
- vstring_free(buf);
- return (status);
-}
-
-/* been_here_level_fixed - duplicate detector */
-
-int been_here_level_fixed(BH_TABLE *dup_filter, int level, const char *string)
-{
- char *folded_string;
- const char *lookup_key;
- int status;
- HTABLE_INFO *info;
-
- /*
- * Sanity check.
- */
- if (level < 0)
- msg_panic("been_here_level_fixed: bad level %d", level);
-
- /*
- * Special processing: case insensitive lookup.
- */
- if (dup_filter->flags & BH_FLAG_FOLD) {
- folded_string = mystrdup(string);
- lookup_key = lowercase(folded_string);
- } else {
- folded_string = 0;
- lookup_key = string;
- }
-
- /*
- * Do the duplicate check.
- */
- if ((info = htable_locate(dup_filter->table, lookup_key)) != 0) {
- status = CAST_CHAR_PTR_TO_INT(info->value);
- } else {
- if (dup_filter->limit <= 0
- || dup_filter->limit > dup_filter->table->used)
- htable_enter(dup_filter->table, lookup_key,
- CAST_INT_TO_CHAR_PTR(level));
- status = -1;
- }
- if (msg_verbose)
- msg_info("been_here_level: %s: %d", string, status);
-
- /*
- * Cleanup.
- */
- if (folded_string)
- myfree(folded_string);
-
- return (status);
-}
-
-/* been_here_level_check - query duplicate detector with finer control */
-
-int been_here_level_check(BH_TABLE *dup_filter, const char *fmt,...)
-{
- VSTRING *buf = vstring_alloc(100);
- int status;
- va_list ap;
-
- /*
- * Construct the string to be checked.
- */
- va_start(ap, fmt);
- vstring_vsprintf(buf, fmt, ap);
- va_end(ap);
-
- /*
- * Do the duplicate check.
- */
- status = been_here_level_check_fixed(dup_filter, vstring_str(buf));
-
- /*
- * Cleanup.
- */
- vstring_free(buf);
- return (status);
-}
-
-/* been_here_level_check_fixed - query duplicate detector */
-
-int been_here_level_check_fixed(BH_TABLE *dup_filter, const char *string)
-{
- char *folded_string;
- const char *lookup_key;
- int status;
- HTABLE_INFO *info;
-
- /*
- * Special processing: case insensitive lookup.
- */
- if (dup_filter->flags & BH_FLAG_FOLD) {
- folded_string = mystrdup(string);
- lookup_key = lowercase(folded_string);
- } else {
- folded_string = 0;
- lookup_key = string;
- }
-
- /*
- * Do the duplicate check.
- */
- if ((info = htable_locate(dup_filter->table, lookup_key)) != 0)
- status = (-1);
- else
- status = CAST_CHAR_PTR_TO_INT(info->value);
- if (msg_verbose)
- msg_info("been_here_level_check: %s: %d", string, status);
-
- /*
- * Cleanup.
- */
- if (folded_string)
- myfree(folded_string);
-
- return (status);
-}
+++ /dev/null
-#ifndef _MAIL_ATTR_H_INCLUDED_
-#define _MAIL_ATTR_H_INCLUDED_
-
-/*++
-/* NAME
-/* mail_attr 3h
-/* SUMMARY
-/* mail internal IPC support
-/* SYNOPSIS
-/* #include <mail_attr.h>
-/* DESCRIPTION
-/* .nf
-
- /*
- * Request attribute. Values are defined by individual applications.
- */
-#define MAIL_REQUEST "request"
-
- /*
- * Request completion status.
- */
-#define MAIL_STATUS "status"
-#define MAIL_STAT_OK "success"
-#define MAIL_STAT_FAIL "failed"
-#define MAIL_STAT_RETRY "retry"
-#define MAIL_STAT_REJECT "reject"
-
-/* LICENSE
-/* .ad
-/* .fi
-/* The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/* Wietse Venema
-/* IBM T.J. Watson Research
-/* P.O. Box 704
-/* Yorktown Heights, NY 10598, USA
-/*--*/
-
-#endif
if (gmtoff < -DAY_MIN || gmtoff > DAY_MIN)
msg_panic("UTC time offset %d is larger than one day", gmtoff);
vstring_sprintf_append(vp, "%+03d%02d", (int) (gmtoff / HOUR_MIN),
- (int) (gmtoff % HOUR_MIN));
+ (int) (abs(gmtoff) % HOUR_MIN));
/*
* Finally, add the time zone name.
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20011030"
+#define DEF_MAIL_VERSION "Snapshot-20011101"
extern char *var_mail_version;
/* LICENSE
REC_TYPE_FILT, "content_filter",
REC_TYPE_FROM, "sender",
REC_TYPE_DONE, "done",
- REC_TYPE_ORCP, "envelope-to-recipient",
REC_TYPE_RCPT, "recipient",
REC_TYPE_WARN, "warning_message_time",
REC_TYPE_MESG, "message_content",
#define REC_TYPE_FILT 'L' /* loop filter transport */
#define REC_TYPE_FROM 'S' /* sender, required */
#define REC_TYPE_DONE 'D' /* delivered recipient, optional */
-#define REC_TYPE_ORCP 'O' /* envelope-to recipient */
#define REC_TYPE_RCPT 'R' /* todo recipient, optional */
#define REC_TYPE_WARN 'W' /* warning message time */
* record groups. The first member in each set is the record type that
* indicates the end of that record group.
*/
-#define REC_TYPE_ENVELOPE "MCTFILSDORWV"
+#define REC_TYPE_ENVELOPE "MCTFILSDRWV"
#define REC_TYPE_CONTENT "XLN"
-#define REC_TYPE_EXTRACT "EDORPre"
+#define REC_TYPE_EXTRACT "EDRPre"
#define REC_TYPE_NOEXTRACT "E"
/*
if (been_here(state.dup_filter, "command %ld %s", (long) usr_attr.uid, command))
return (0);
- /*
- * DELIVERY POLICY
- *
- * Do we permit mail to shell commands? Allow delivery via mailbox_command.
- */
- if (command != var_mailbox_command
- && command != map_command /* XXX */
- && (local_cmd_deliver_mask & state.msg_attr.exp_type) == 0)
- return (bounce_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
- "mail to command is restricted"));
-
/*
* DELIVERY RIGHTS
*
extern int deliver_maildir(LOCAL_STATE, USER_ATTR, char *);
extern int deliver_unknown(LOCAL_STATE, USER_ATTR);
-extern const char *map_command; /* XXX */
-
/*
* Restrictions on delivery to sensitive destinations.
*/
#define YES 1
#define NO 0
-const char *map_command; /* XXX */
-
/* deliver_mailbox_file - deliver to recipient mailbox */
static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr)
struct mypasswd *mbox_pwd;
char *path;
static MAPS *cmd_maps;
+ const char *map_command;
/*
* Make verbose logging easier to understand.
} else if (*STR(addr_buf) == '~') {
status = deliver_token_home(state, usr_attr, STR(addr_buf));
} else if (*STR(addr_buf) == '|') {
- status = deliver_command(state, usr_attr, STR(addr_buf) + 1);
+ if ((local_cmd_deliver_mask & state.msg_attr.exp_type) == 0)
+ status = bounce_append(BOUNCE_FLAG_KEEP,
+ BOUNCE_ATTR(state.msg_attr),
+ "mail to command is restricted");
+ else
+ status = deliver_command(state, usr_attr, STR(addr_buf) + 1);
} else if (strncasecmp(STR(addr_buf), include, sizeof(include) - 1) == 0) {
path = STR(addr_buf) + sizeof(include) - 1;
status = deliver_include(state, usr_attr, path);
*/
if (status == DELIVER_STAT_CRASH) {
message->flags |= DELIVER_STAT_DEFER;
- qmgr_transport_throttle(transport, "unknown mail transport error -- see a previous warning/fatal/panic record for the problem description");
+ qmgr_transport_throttle(transport, "unknown mail transport error");
+ msg_warn("transport %s failure -- see a previous warning/fatal/panic logfile record for the problem description",
+ transport->name);
qmgr_defer_transport(transport, transport->reason);
}
*/
if (status == DELIVER_STAT_CRASH) {
message->flags |= DELIVER_STAT_DEFER;
- qmgr_transport_throttle(transport, "unknown mail transport error -- see a previous warning/fatal/panic record for the problem description");
+ qmgr_transport_throttle(transport, "unknown mail transport error");
+ msg_warn("transport %s failure -- see a previous warning/fatal/panic logfile record for the problem description",
+ transport->name);
qmgr_defer_transport(transport, transport->reason);
}
SHELL = /bin/sh
-SRCS = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \
+SRCS = argv.c argv_split.c basename.c binhash.c chroot_uid.c \
close_on_exec.c concatenate.c dict.c dict_db.c dict_dbm.c \
dict_env.c dict_ht.c dict_ldap.c dict_mysql.c dict_ni.c dict_nis.c \
dict_nisplus.c dict_open.c dir_forest.c doze.c environ.c \
hex_quote.c dict_alloc.c rand_sleep.c sane_time.c dict_debug.c \
sane_socketpair.c myrand.c netstring.c ctable.c attr_print.c intv.c \
attr_scan.c base64_code.c
-OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
+OBJS = argv.o argv_split.o basename.o binhash.o chroot_uid.o \
close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
dict_nisplus.o dict_open.o dir_forest.o doze.o environ.o \
+++ /dev/null
-/*++
-/* NAME
-/* attr 3
-/* SUMMARY
-/* simple attribute list manager
-/* SYNOPSIS
-/* #include <attr.h>
-/*
-/* void attr_enter(table, flags, name, value, ..., (char *) 0)
-/* HTABLE *table;
-/* int flags;
-/* const char *name;
-/* const char *value;
-/*
-/* int attr_find(table, flags, name, value, ..., (char *) 0)
-/* HTABLE *table;
-/* int flags;
-/* const char *name;
-/* const char **vptr;
-/* DESCRIPTION
-/* This module maintains open attribute lists of string-valued
-/* names and values. The module is built on top of the generic
-/* htable(3) hash table manager.
-/*
-/* attr_enter() adds or updates zero or more attribute-value pairs.
-/* Both the name and the value are copied. The argument list is
-/* terminated with a null character pointer.
-/*
-/* attr_find() looks up zero or more named attribute values. The
-/* result value is the number of attributes found; the search
-/* stops at the first error. The values are not copied out; it
-/* is up to the caller to save copies of values where needed.
-/*
-/* Arguments:
-/* .IP table
-/* Pointer to hash table.
-/* .IP flags
-/* Bit-wise OR of the following:
-/* .RS
-/* .IP ATTR_FLAG_MISSING
-/* Log a warning when attr_find() cannot find an attribute. The
-/* search always terminates when a request cannot be satisfied.
-/* .IP ATTR_FLAG_EXTRA
-/* Log a warning and return immediately when attr_enter() finds
-/* that a specified attribute already exists in the table.
-/* By default, attr_enter() replaces an existing attribute value
-/* by the specified one.
-/* .IP ATTR_FLAG_NONE
-/* For convenience, this value requests none of the above.
-/* .RE
-/* .IP name
-/* Attribute name. Specify a null character pointer to terminate
-/* the argument list.
-/* .IP value
-/* Attribute value. attr_enter() makes a copy.
-/* .IP vptr
-/* Pointer to character pointer. attr_find() makes no copy of the
-/* value.
-/* LICENSE
-/* .ad
-/* .fi
-/* The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/* Wietse Venema
-/* IBM T.J. Watson Research
-/* P.O. Box 704
-/* Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <stdarg.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <mymalloc.h>
-#include <htable.h>
-#include <attr.h>
-
-/* attr_enter - add or update attribute values */
-
-void attr_enter(HTABLE *table, int flags,...)
-{
- const char *myname = "attr_enter";
- HTABLE_INFO *ht;
- va_list ap;
- const char *name;
- const char *value;
-
- va_start(ap, flags);
- while ((name = va_arg(ap, char *)) != 0) {
- value = va_arg(ap, char *);
- if ((ht = htable_locate(table, name)) != 0) { /* replace */
- if ((flags & ATTR_FLAG_EXTRA) != 0) {
- msg_warn("%s: duplicate attribute %s in table", myname, name);
- break;
- }
- myfree(ht->value);
- ht->value = mystrdup(value);
- } else { /* add attribute */
- (void) htable_enter(table, name, mystrdup(value));
- }
- }
- va_end(ap);
-}
-
-/* attr_enter - look up attribute values */
-
-int attr_find(HTABLE *table, int flags,...)
-{
- const char *myname = "attr_find";
- va_list ap;
- const char *name;
- const char **vptr;
- int attr_count;
-
- va_start(ap, flags);
- for (attr_count = 0; (name = va_arg(ap, char *)) != 0; attr_count++) {
- vptr = va_arg(ap, const char **);
- if ((*vptr = htable_find(table, name)) == 0) {
- if ((flags & ATTR_FLAG_MISSING) != 0)
- msg_warn("%s: missing attribute %s in table", myname, name);
- break;
- }
- }
- return (attr_count);
-}
extern int attr_scan(VSTREAM *, int,...);
extern int attr_vscan(VSTREAM *, int, va_list);
- /*
- * attr.c.
- */
-extern void attr_enter(HTABLE *, int,...);
-extern int attr_find(HTABLE *, int,...);
-
/*
* Attribute names for testing the compatibility of the read and write
* routines.
HTABLE *table = htable_create(1);
msg_vstream_init(argv[0], VSTREAM_ERR);
- htable_enter(table, "foo-name", "foo-value");
- htable_enter(table, "bar-name", "bar-value");
+ htable_enter(table, "foo-name", mystrdup("foo-value"));
+ htable_enter(table, "bar-name", mystrdup("bar-value"));
attr_print(VSTREAM_OUT, ATTR_FLAG_NONE,
ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
ATTR_TYPE_END);
if (vstream_fflush(VSTREAM_OUT) != 0)
msg_fatal("write error: %m");
+
+ htable_free(table, myfree);
return (0);
}