postfix 1.1.11

check following for list of changes:
ftp://ftp.porcupine.org/mirrors/postfix-release/official/postfix-1.1.11.RELEASE_NOTES
This commit is contained in:
itojun 2002-06-08 22:37:07 +00:00
parent d7d4214831
commit 4a4a5f0782
19 changed files with 241 additions and 71 deletions

View File

@ -92,6 +92,7 @@ qmqpd.o: ../../include/namadr_list.h
qmqpd.o: ../../include/match_list.h
qmqpd.o: ../../include/match_ops.h
qmqpd.o: ../../include/quote_822_local.h
qmqpd.o: ../../include/quote_flags.h
qmqpd.o: ../../include/match_parent_style.h
qmqpd.o: ../../include/mail_server.h
qmqpd.o: qmqpd.h

View File

@ -364,7 +364,7 @@ static void qmqpd_write_content(QMQPD_STATE *state)
if (first) {
if (strncmp(start + strspn(start, ">"), "From ", 5) == 0) {
rec_fprintf(state->cleanup, rec_type,
"Mailbox-Line: %*s", len, start);
"X-Mailbox-Line: %*s", len, start);
continue;
}
first = 0;

View File

@ -105,6 +105,10 @@
/* .IP \fB-bs\fR
/* Stand-alone SMTP server mode. Read SMTP commands from
/* standard input, and write responses to standard output.
/* In stand-alone SMTP server mode, UCE restrictions and
/* access controls are disabled by default. To enable them,
/* run the process as the \fBmail_owner\fR user.
/* .sp
/* This mode of operation is implemented by running the
/* \fBsmtpd\fR(8) daemon.
/* .IP "\fB-f \fIsender\fR"
@ -363,6 +367,7 @@ static void enqueue(const int flags, const char *sender, const char *full_name,
uid_t uid = getuid();
int status;
int naddr;
int prev_type;
/*
* Initialize.
@ -453,8 +458,8 @@ static void enqueue(const int flags, const char *sender, const char *full_name,
rec_fprintf(dst, REC_TYPE_MESG, REC_TYPE_MESG_FORMAT, 0L);
skip_from_ = 1;
strip_cr = STRIP_CR_DUNNO;
while ((type = rec_streamlf_get(VSTREAM_IN, buf, var_line_limit))
!= REC_TYPE_EOF) {
for (prev_type = 0; (type = rec_streamlf_get(VSTREAM_IN, buf, var_line_limit))
!= REC_TYPE_EOF; prev_type = type) {
if (strip_cr == STRIP_CR_DUNNO && type == REC_TYPE_NORM) {
if (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\r')
strip_cr = STRIP_CR_DO;
@ -472,7 +477,8 @@ static void enqueue(const int flags, const char *sender, const char *full_name,
if (strip_cr == STRIP_CR_DO && type == REC_TYPE_NORM)
if (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\r')
vstring_truncate(buf, VSTRING_LEN(buf) - 1);
if ((flags & SM_FLAG_AEOF) && VSTRING_LEN(buf) == 1 && *STR(buf) == '.')
if ((flags & SM_FLAG_AEOF) && prev_type != REC_TYPE_CONT
&& VSTRING_LEN(buf) == 1 && *STR(buf) == '.')
break;
if (REC_PUT_BUF(dst, type, buf) < 0)
msg_fatal_status(EX_TEMPFAIL,

View File

@ -75,5 +75,8 @@ showq.o: ../../include/mail_scan_dir.h
showq.o: ../../include/mail_conf.h
showq.o: ../../include/record.h
showq.o: ../../include/rec_type.h
showq.o: ../../include/quote_822_local.h
showq.o: ../../include/quote_flags.h
showq.o: ../../include/mail_addr.h
showq.o: ../../include/bounce_log.h
showq.o: ../../include/mail_server.h

View File

@ -80,6 +80,8 @@
#include <mail_conf.h>
#include <record.h>
#include <rec_type.h>
#include <quote_822_local.h>
#include <mail_addr.h>
#include <bounce_log.h>
/* Single-threaded server skeleton. */
@ -89,6 +91,7 @@
/* Application-specific. */
int var_dup_filter_limit;
char *var_empty_addr;
#define STRING_FORMAT "%-10s %8s %-20s %s\n"
#define DATA_FORMAT "%-10s%c%8ld %20.20s %s\n"
@ -96,10 +99,15 @@ int var_dup_filter_limit;
static void showq_reasons(VSTREAM *, BOUNCE_LOG *, HTABLE *);
#define STR(x) vstring_str(x)
/* showq_report - report status of sender and recipients */
static void showq_report(VSTREAM *client, char *queue, char *id,
VSTREAM *qfile, long size)
{
VSTRING *buf = vstring_alloc(100);
VSTRING *printable_quoted_addr = vstring_alloc(100);
int rec_type;
time_t arrival_time = 0;
char *start;
@ -109,6 +117,13 @@ static void showq_report(VSTREAM *client, char *queue, char *id,
char status = (strcmp(queue, MAIL_QUEUE_ACTIVE) == 0 ? '*' : ' ');
long offset;
/*
* XXX addresses in defer logfiles are in printable quoted form, while
* addresses in message envelope records are in raw unquoted form. This
* may change once we replace the present ad-hoc bounce/defer logfile
* format by one that is transparent for control etc. characters. See
* also: bounce/bounce_append_service.c.
*/
while (!vstream_ferror(client) && (rec_type = rec_get(qfile, buf, 0)) > 0) {
start = vstring_str(buf);
switch (rec_type) {
@ -121,18 +136,23 @@ static void showq_report(VSTREAM *client, char *queue, char *id,
break;
case REC_TYPE_FROM:
if (*start == 0)
start = "(MAILER-DAEMON)";
start = var_empty_addr;
quote_822_local(printable_quoted_addr, start);
printable(STR(printable_quoted_addr), '?');
vstream_fprintf(client, DATA_FORMAT, id, status,
msg_size > 0 ? msg_size : size, arrival_time > 0 ?
asctime(localtime(&arrival_time)) : "??",
printable(start, '?'));
STR(printable_quoted_addr));
break;
case REC_TYPE_RCPT:
if (*start == 0) /* can't happen? */
start = "(MAILER-DAEMON)";
if (dup_filter == 0 || htable_locate(dup_filter, start) == 0)
start = var_empty_addr;
quote_822_local(printable_quoted_addr, start);
printable(STR(printable_quoted_addr), '?');
if (dup_filter == 0
|| htable_locate(dup_filter, STR(printable_quoted_addr)) == 0)
vstream_fprintf(client, STRING_FORMAT,
"", "", "", printable(start, '?'));
"", "", "", STR(printable_quoted_addr));
break;
case REC_TYPE_MESG:
if ((offset = atol(start)) > 0
@ -163,6 +183,7 @@ static void showq_report(VSTREAM *client, char *queue, char *id,
}
}
vstring_free(buf);
vstring_free(printable_quoted_addr);
if (dup_filter)
htable_free(dup_filter, (void (*) (char *)) 0);
}
@ -307,8 +328,13 @@ int main(int argc, char **argv)
VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0,
0,
};
CONFIG_STR_TABLE str_table[] = {
VAR_EMPTY_ADDR, DEF_EMPTY_ADDR, &var_empty_addr, 1, 0,
0,
};
single_server_main(argc, argv, showq_service,
MAIL_SERVER_INT_TABLE, int_table,
MAIL_SERVER_STR_TABLE, str_table,
0);
}

View File

@ -166,6 +166,7 @@ smtp_proto.o: ../../include/rec_type.h
smtp_proto.o: ../../include/off_cvt.h
smtp_proto.o: ../../include/mark_corrupt.h
smtp_proto.o: ../../include/quote_821_local.h
smtp_proto.o: ../../include/quote_flags.h
smtp_proto.o: smtp.h
smtp_proto.o: ../../include/argv.h
smtp_proto.o: smtp_sasl.h

View File

@ -97,8 +97,8 @@
/* Never send EHLO at the start of a connection.
/* .IP \fBsmtp_bind_address\fR
/* Numerical source network address to bind to when making a connection.
/* .IP \fBsmtp_break_lines\fR
/* Break lines > \fB$line_length_limit\fR into multiple shorter lines.
/* .IP \fBsmtp_line_length_limit\fR
/* Length limit for SMTP message content lines. Zero means no limit.
/* Some SMTP servers misbehave on long lines.
/* .IP \fBsmtp_skip_4xx_greeting\fR
/* Skip servers that greet us with a 4xx status code.
@ -113,7 +113,7 @@
/* The time a message must be queued before the CISCO PIX firewall
/* <CR><LF>.<CR><LF> bug workaround is turned on.
/* .SH "Authentication controls"
/* .IP \fBsmtp_enable_sasl_auth\fR
/* .IP \fBsmtp_sasl_auth_enable\fR
/* Enable per-session authentication as per RFC 2554 (SASL).
/* By default, Postfix is built without SASL support.
/* .IP \fBsmtp_sasl_password_maps\fR
@ -259,9 +259,9 @@ char *var_smtp_sasl_passwd;
bool var_smtp_sasl_enable;
char *var_smtp_bind_addr;
bool var_smtp_rand_addr;
bool var_smtp_break_lines;
int var_smtp_pix_thresh;
int var_smtp_pix_delay;
int var_smtp_line_limit;
/*
* Global variables. smtp_errno is set by the address lookup routines and by
@ -429,6 +429,7 @@ int main(int argc, char **argv)
0,
};
static CONFIG_INT_TABLE int_table[] = {
VAR_SMTP_LINE_LIMIT, DEF_SMTP_LINE_LIMIT, &var_smtp_line_limit, 0, 0,
0,
};
static CONFIG_BOOL_TABLE bool_table[] = {
@ -440,7 +441,6 @@ int main(int argc, char **argv)
VAR_SMTP_NEVER_EHLO, DEF_SMTP_NEVER_EHLO, &var_smtp_never_ehlo,
VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable,
VAR_SMTP_RAND_ADDR, DEF_SMTP_RAND_ADDR, &var_smtp_rand_addr,
VAR_SMTP_BREAK_LINES, DEF_SMTP_BREAK_LINES, &var_smtp_break_lines,
0,
};

View File

@ -296,16 +296,27 @@ int smtp_xfer(SMTP_STATE *state)
int sndbuffree;
SOCKOPT_SIZE optlen = sizeof(sndbufsize);
int mail_from_rejected;
int space_left = var_smtp_line_limit;
int data_left;
char *data_start;
/*
* Macros for readability.
*/
#define REWRITE_ADDRESS(addr) do { \
if (*(addr)) { \
quote_821_local(state->scratch, addr); \
smtp_unalias_addr(state->scratch2, vstring_str(state->scratch)); \
myfree(addr); \
addr = mystrdup(vstring_str(state->scratch2)); \
#define REWRITE_ADDRESS(dst, mid, src) do { \
if (*(src)) { \
quote_821_local(mid, src); \
smtp_unalias_addr(dst, vstring_str(mid)); \
} else { \
vstring_strcpy(dst, src); \
} \
} while (0)
#define QUOTE_ADDRESS(dst, src) do { \
if (*(src)) { \
quote_821_local(dst, src); \
} else { \
vstring_strcpy(dst, src); \
} \
} while (0)
@ -396,11 +407,15 @@ int smtp_xfer(SMTP_STATE *state)
* Build the MAIL FROM command.
*/
case SMTP_STATE_MAIL:
if (*request->sender)
if (var_disable_dns == 0)
REWRITE_ADDRESS(request->sender);
vstring_sprintf(next_command, "MAIL FROM:<%s>", request->sender);
if (state->features & SMTP_FEATURE_SIZE)
if (var_disable_dns == 0) {
REWRITE_ADDRESS(state->scratch, state->scratch2,
request->sender);
} else {
QUOTE_ADDRESS(state->scratch, request->sender);
}
vstring_sprintf(next_command, "MAIL FROM:<%s>",
vstring_str(state->scratch));
if (state->features & SMTP_FEATURE_SIZE) /* RFC 1652 */
vstring_sprintf_append(next_command, " SIZE=%lu",
request->data_size);
next_state = SMTP_STATE_RCPT;
@ -412,9 +427,14 @@ int smtp_xfer(SMTP_STATE *state)
*/
case SMTP_STATE_RCPT:
rcpt = request->rcpt_list.info + send_rcpt;
if (var_disable_dns == 0)
REWRITE_ADDRESS(rcpt->address);
vstring_sprintf(next_command, "RCPT TO:<%s>", rcpt->address);
if (var_disable_dns == 0) {
REWRITE_ADDRESS(state->scratch, state->scratch2,
rcpt->address);
} else {
QUOTE_ADDRESS(state->scratch, rcpt->address);
}
vstring_sprintf(next_command, "RCPT TO:<%s>",
vstring_str(state->scratch));
if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
next_state = SMTP_STATE_DATA;
break;
@ -665,16 +685,38 @@ int smtp_xfer(SMTP_STATE *state)
if (prev_type != REC_TYPE_CONT)
if (vstring_str(state->scratch)[0] == '.')
smtp_fputc('.', session->stream);
if (var_smtp_break_lines)
rec_type = REC_TYPE_NORM;
if (rec_type == REC_TYPE_CONT)
smtp_fwrite(vstring_str(state->scratch),
VSTRING_LEN(state->scratch),
session->stream);
else
smtp_fputs(vstring_str(state->scratch),
VSTRING_LEN(state->scratch),
session->stream);
/*
* Deal with an impedance mismatch between Postfix queue
* files (record length <= $message_line_length_limit) and
* SMTP (DATA record length <= $smtp_line_length_limit). The
* code below does a little too much work when the SMTP line
* length limit is disabled, but it avoids code duplication,
* and thus, it avoids testing and maintenance problems.
*/
data_left = VSTRING_LEN(state->scratch);
data_start = vstring_str(state->scratch);
do {
if (var_smtp_line_limit > 0 && data_left >= space_left) {
smtp_fputs(data_start, space_left, session->stream);
data_start += space_left;
data_left -= space_left;
space_left = var_smtp_line_limit;
if (data_left > 0 || rec_type == REC_TYPE_CONT) {
smtp_fputc(' ', session->stream);
space_left -= 1;
}
} else {
if (rec_type == REC_TYPE_CONT) {
smtp_fwrite(data_start, data_left, session->stream);
space_left -= data_left;
} else {
smtp_fputs(data_start, data_left, session->stream);
space_left = var_smtp_line_limit;
}
break;
}
} while (data_left > 0);
prev_type = rec_type;
}

View File

@ -76,6 +76,7 @@ resolve.o: ../../include/rewrite_clnt.h
resolve.o: ../../include/resolve_local.h
resolve.o: ../../include/mail_conf.h
resolve.o: ../../include/quote_822_local.h
resolve.o: ../../include/quote_flags.h
resolve.o: ../../include/tok822.h
resolve.o: ../../include/resolve_clnt.h
resolve.o: trivial-rewrite.h

View File

@ -97,9 +97,17 @@ void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
/*
* The address is in internalized (unquoted) form, so we must externalize
* it first before we can parse it.
*
* But practically, we have to look at the unquoted form so that routing
* characters like @ remain visible, in order to stop user@domain@domain
* relay attempts when forwarding mail to a primary Sendmail MX host.
*/
quote_822_local(addr_buf, addr);
tree = tok822_scan_addr(vstring_str(addr_buf));
if (var_resolve_dequoted) {
tree = tok822_scan_addr(addr);
} else {
quote_822_local(addr_buf, addr);
tree = tok822_scan_addr(vstring_str(addr_buf));
}
/*
* Preliminary resolver: strip off all instances of the local domain.

View File

@ -118,7 +118,8 @@ void rewrite_tree(char *unused_ruleset, TOK822 *tree)
* Strip source route.
*/
if (tree->head->type == '@'
&& (colon = tok822_find_type(tree->head, ':')) != 0)
&& (colon = tok822_find_type(tree->head, ':')) != 0
&& colon != tree->tail)
tok822_free_tree(tok822_sub_keep_after(tree, colon));
/*

View File

@ -64,6 +64,12 @@
/* List of domains that this machine considers local.
/* .IP \fBmyorigin\fR
/* The domain that locally-posted mail appears to come from.
/* .IP \fBresolve_unquoted_address\fR
/* When resolving an address, do not quote the address localpart as
/* per RFC 822, so that additional \fB@\fR, \fB%\fR or \fB!\fR
/* characters remain visible. This is technically incorrect, but
/* allows us to stop relay attacks when forwarding mail to a Sendmail
/* primary MX host.
/* .SH Rewriting
/* .ad
/* .fi
@ -93,9 +99,9 @@
/* Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
/* for details. The :\fInexthop\fR part is optional.
/* .IP \fBparent_domain_matches_subdomains\fR
/* List of Postfix features that use \fIdomain.name\fR patterns
/* to match \fIsub.domain.name\fR (as opposed to
/* requiring \fI.domain.name\fR patterns).
/* List of Postfix features that use \fIdomain.tld\fR patterns
/* to match \fIsub.domain.tld\fR (as opposed to
/* requiring \fI.domain.tld\fR patterns).
/* .IP \fBrelayhost\fR
/* The default host to send non-local mail to when no entry is matched
/* in the \fBtransport\fR(5) table.
@ -167,6 +173,7 @@ bool var_append_dot_mydomain;
bool var_append_at_myorigin;
bool var_percent_hack;
char *var_local_transport;
int var_resolve_dequoted;
/* rewrite_service - read request and send reply */
@ -234,6 +241,7 @@ int main(int argc, char **argv)
VAR_APP_DOT_MYDOMAIN, DEF_APP_DOT_MYDOMAIN, &var_append_dot_mydomain,
VAR_APP_AT_MYORIGIN, DEF_APP_AT_MYORIGIN, &var_append_at_myorigin,
VAR_PERCENT_HACK, DEF_PERCENT_HACK, &var_percent_hack,
VAR_RESOLVE_DEQUOTED, DEF_RESOLVE_DEQUOTED, &var_resolve_dequoted,
0,
};

View File

@ -508,11 +508,11 @@ int dict_changed(void)
ht_info_list = htable_list(dict_table);
for (status = 0, ht = ht_info_list; status == 0 && (h = *ht) != 0; ht++) {
dict = ((DICT_NODE *) h->value)->dict;
if (dict->fd < 0) /* not file-based */
if (dict->stat_fd < 0) /* not file-based */
continue;
if (dict->mtime == 0) /* not bloody likely */
msg_warn("%s: table %s: null time stamp", myname, h->key);
if (fstat(dict->fd, &st) < 0)
if (fstat(dict->stat_fd, &st) < 0)
msg_fatal("%s: fstat: %m", myname);
status = (st.st_mtime != dict->mtime || st.st_nlink == 0);
}

View File

@ -35,7 +35,8 @@ typedef struct DICT {
int (*delete) (struct DICT *, const char *);
int (*sequence) (struct DICT *, int, const char **, const char **);
void (*close) (struct DICT *);
int fd; /* for dict_update() lock */
int lock_fd; /* for dict_update() lock */
int stat_fd; /* change detection */
time_t mtime; /* mod time at open */
} DICT;

View File

@ -116,7 +116,8 @@ DICT *dict_alloc(const char *dict_type, const char *dict_name, int size)
dict->delete = dict_default_delete;
dict->sequence = dict_default_sequence;
dict->close = dict_default_close;
dict->fd = -1;
dict->lock_fd = -1;
dict->stat_fd = -1;
dict->mtime = 0;
return dict;
}

View File

@ -158,7 +158,7 @@ static const char *dict_db_lookup(DICT *dict, const char *name)
* Acquire a shared lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
/*
@ -198,7 +198,7 @@ static const char *dict_db_lookup(DICT *dict, const char *name)
* Release the shared lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
return (result);
@ -246,7 +246,7 @@ static void dict_db_update(DICT *dict, const char *name, const char *value)
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
/*
@ -271,7 +271,7 @@ static void dict_db_update(DICT *dict, const char *name, const char *value)
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
}
@ -289,7 +289,7 @@ static int dict_db_delete(DICT *dict, const char *name)
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
/*
@ -325,7 +325,7 @@ static int dict_db_delete(DICT *dict, const char *name)
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
return status;
@ -367,7 +367,7 @@ static int dict_db_sequence(DICT *dict, const int function,
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
if ((status = db->seq(db, &db_key, &db_value, db_function)) < 0)
@ -377,7 +377,7 @@ static int dict_db_sequence(DICT *dict, const int function,
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
if (status == 0) {
@ -537,8 +537,9 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
dict_db->dict.delete = dict_db_delete;
dict_db->dict.sequence = dict_db_sequence;
dict_db->dict.close = dict_db_close;
dict_db->dict.fd = dbfd;
if (fstat(dict_db->dict.fd, &st) < 0)
dict_db->dict.lock_fd = dbfd;
dict_db->dict.stat_fd = dbfd;
if (fstat(dict_db->dict.stat_fd, &st) < 0)
msg_fatal("dict_db_open: fstat: %m");
dict_db->dict.mtime = st.st_mtime;
@ -552,7 +553,8 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
&& st.st_mtime < time((time_t *) 0) - 100)
msg_warn("database %s is older than source file %s", db_path, path);
close_on_exec(dict_db->dict.fd, CLOSE_ON_EXEC);
close_on_exec(dict_db->dict.lock_fd, CLOSE_ON_EXEC);
close_on_exec(dict_db->dict.stat_fd, CLOSE_ON_EXEC);
dict_db->dict.flags = dict_flags | DICT_FLAG_FIXED;
if ((dict_flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
dict_db->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL);

View File

@ -84,7 +84,7 @@ static const char *dict_dbm_lookup(DICT *dict, const char *name)
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
/*
@ -122,7 +122,7 @@ static const char *dict_dbm_lookup(DICT *dict, const char *name)
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
return (result);
@ -167,7 +167,7 @@ static void dict_dbm_update(DICT *dict, const char *name, const char *value)
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
/*
@ -189,7 +189,7 @@ static void dict_dbm_update(DICT *dict, const char *name, const char *value)
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
}
@ -206,7 +206,7 @@ static int dict_dbm_delete(DICT *dict, const char *name)
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
/*
@ -247,7 +247,7 @@ static int dict_dbm_delete(DICT *dict, const char *name)
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
return (status);
@ -270,7 +270,7 @@ static int dict_dbm_sequence(DICT *dict, const int function,
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
/*
@ -291,7 +291,7 @@ static int dict_dbm_sequence(DICT *dict, const int function,
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
&& myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
if (dbm_key.dptr != 0 && dbm_key.dsize > 0) {
@ -379,7 +379,7 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags)
* time domain) locks while rewriting the entire file.
*/
if (dict_flags & DICT_FLAG_LOCK) {
dbm_path = concatenate(path, ".pag", (char *) 0);
dbm_path = concatenate(path, ".dir", (char *) 0);
if ((lock_fd = open(dbm_path, open_flags, 0644)) < 0)
msg_fatal("open database %s: %m", dbm_path);
if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
@ -404,8 +404,11 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags)
dict_dbm->dict.delete = dict_dbm_delete;
dict_dbm->dict.sequence = dict_dbm_sequence;
dict_dbm->dict.close = dict_dbm_close;
dict_dbm->dict.fd = dbm_pagfno(dbm);
if (fstat(dict_dbm->dict.fd, &st) < 0)
dict_dbm->dict.lock_fd = dbm_dirfno(dbm);
dict_dbm->dict.stat_fd = dbm_pagfno(dbm);
if (dict_dbm->dict.lock_fd == dict_dbm->dict.stat_fd)
msg_fatal("open database %s: cannot support GDBM", path);
if (fstat(dict_dbm->dict.stat_fd, &st) < 0)
msg_fatal("dict_dbm_open: fstat: %m");
dict_dbm->dict.mtime = st.st_mtime;

View File

@ -586,7 +586,7 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
*/
if (*(sub) == '%') {
char *u = vstring_str(escaped_name);
char *p = strchr(u, '@');
char *p = strrchr(u, '@');
switch (*(sub + 1)) {
case 'd':

66
gnu/dist/postfix/src/util/strcasecmp.c vendored Normal file
View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys_defs.h>
#include <ctype.h>
int strcasecmp(const char *s1, const char *s2)
{
const unsigned char *us1 = (const unsigned char *) s1;
const unsigned char *us2 = (const unsigned char *) s2;
while (TOLOWER(*us1) == TOLOWER(*us2++))
if (*us1++ == '\0')
return (0);
return (TOLOWER(*us1) - TOLOWER(*--us2));
}
int strncasecmp(const char *s1, const char *s2, size_t n)
{
if (n != 0) {
const unsigned char *us1 = (const unsigned char *) s1;
const unsigned char *us2 = (const unsigned char *) s2;
do {
if (TOLOWER(*us1) != TOLOWER(*us2++))
return (TOLOWER(*us1) - TOLOWER(*--us2));
if (*us1++ == '\0')
break;
} while (--n != 0);
}
return (0);
}