Cleanup: simplify the LMDB error recovery code. File:
util/slmdb.c.
+
+20210623
+
+ Cleanup: the known_tcp_ports parameter was not hyperlinked.
+ File: mantools/postlink.
+
+ Bugfix: some strtou?l() calls had no 'errno=0' statement
+ before the call. Fixed with strtou?l() wrapper functions
+ that reset errno before calling strtou?l(), and calling
+ these from code that did not explicitly reset errno. Other
+ strtou?l() can be migrated later. Problem reported by David
+ Bohman. Files: util/sane_strtol.[hc], global/compat_level.c,
+ postscreen/postscreen_tests.c, util/mac_expand.c.
Available in Postfix 3.6 and later:
- <b>known_tcp_ports (lmtp=24, smtp=25, smtps=submissions=465, submis-</b>
+ <b><a href="postconf.5.html#known_tcp_ports">known_tcp_ports</a> (lmtp=24, smtp=25, smtps=submissions=465, submis-</b>
<b>sion=587)</b>
Optional setting that avoids lookups in the <b>services</b>(5) data-
base.
<blockquote>
<p>
-known_tcp_ports = empty | name-to-port *("," name-to-port) <br>
+<a href="postconf.5.html#known_tcp_ports">known_tcp_ports</a> = empty | name-to-port *("," name-to-port) <br>
name-to-port = 1*(service-name "=') port-number
</p>
</blockquote>
-<p> Whitespace is optional but it cannot appear inside a service
-name or port number. </p>
+<p> The comma is required. Whitespace is optional but it cannot appear
+inside a service name or port number. </p>
<p> This feature is available in Postfix 3.6 and later. </p>
name\-to\-port = 1*(service\-name "=') port\-number
.in -4
.PP
-Whitespace is optional but it cannot appear inside a service
-name or port number.
+The comma is required. Whitespace is optional but it cannot appear
+inside a service name or port number.
.PP
This feature is available in Postfix 3.6 and later.
.SH line_length_limit (default: 2048)
s;\breset_owner_alias\b;<a href="postconf.5.html#reset_owner_alias">$&</a>;g;
s;\benable_long_queue_ids\b;<a href="postconf.5.html#enable_long_queue_ids">$&</a>;g;
s;\benable_threaded_bounces\b;<a href="postconf.5.html#enable_threaded_bounces">$&</a>;g;
+ s;\bknown_tcp_ports\b;<a href="postconf.5.html#known_tcp_ports">$&</a>;g;
# Transport-dependent magical parameters.
s/[<bB>]*vir[-<\/bB>]*\n*[ <bB>]*tual[<\/bB>]*\(8\)/<a href="virtual.8.html">$&<\/a>/g;
s/[<bB>]*cidr_ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="cidr_table.5.html">$&<\/a>/g;
s/[<bB>]*tcp_ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="tcp_table.5.html">$&<\/a>/g;
+
# Workaround...
s/<b><a href="postconf.5.html#body_checks">body_checks<\/a><\/b>\(5\)/<b>body_checks<\/b>(5)/;
s/<b><a href="postconf.5.html#header_checks">header_checks<\/a><\/b>\(5\)/<b>header_checks<\/b>(5)/;
s;\bmail[-</bB>]*\n*[ <bB>]*log_file_rotate_suffix\b;<a href="postconf.5.html#maillog_file_rotate_suffix">$&</a>;g;
s;\bpostlog_service_name\b;<a href="postconf.5.html#postlog_service_name">$&</a>;g;
s;\bpostlogd_watchdog_timeout\b;<a href="postconf.5.html#postlogd_watchdog_timeout">$&</a>;g;
+
s;\blocal_login_sender_maps\b;<a href="postconf.5.html#local_login_sender_maps">$&</a>;g;
s;\bempty_address_local_login_sender_maps_lookup_key\b;<a href="postconf.5.html#empty_address_local_login_sender_maps_lookup_key">$&</a>;g;
</p>
</blockquote>
-<p> Whitespace is optional but it cannot appear inside a service
-name or port number. </p>
+<p> The comma is required. Whitespace is optional but it cannot appear
+inside a service name or port number. </p>
<p> This feature is available in Postfix 3.6 and later. </p>
compat_level.o: ../../include/mac_expand.h
compat_level.o: ../../include/mac_parse.h
compat_level.o: ../../include/msg.h
+compat_level.o: ../../include/sane_strtol.h
compat_level.o: ../../include/sys_defs.h
compat_level.o: ../../include/vbuf.h
compat_level.o: ../../include/vstring.h
*/
#include <mac_expand.h>
#include <msg.h>
+#include <sane_strtol.h>
/*
* For easy comparison we convert a three-number compatibility level into
char *remainder;
start = str;
- major = strtol(start, &remainder, 10);
+ major = sane_strtol(start, &remainder, 10);
if (start < remainder && (*remainder == 0 || *remainder == '.')
&& errno != ERANGE && GOOD_MAJOR(major)) {
res = ENCODE_MAJOR(major);
if (*remainder == 0)
return res;
start = remainder + 1;
- minor = strtol(start, &remainder, 10);
+ minor = sane_strtol(start, &remainder, 10);
if (start < remainder && (*remainder == 0 || *remainder == '.')
&& errno != ERANGE && GOOD_MINOR(minor)) {
res |= ENCODE_MINOR(minor);
if (*remainder == 0)
return (res);
start = remainder + 1;
- patch = strtol(start, &remainder, 10);
+ patch = sane_strtol(start, &remainder, 10);
if (start < remainder && *remainder == 0 && errno != ERANGE
&& GOOD_PATCH(patch)) {
return (res | ENCODE_PATCH(patch));
msg_warn)) < 0)
continue;
msg_info("%s -> 0x%lx", vstring_str(buf), compat_level);
+ errno = ERANGE;
if ((as_string = compat_level_to_string(compat_level,
msg_warn)) == 0)
continue;
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20210615"
+#define MAIL_RELEASE_DATE "20210627"
#define MAIL_VERSION_NUMBER "3.7"
#ifdef SNAPSHOT
postscreen_tests.o: ../../include/myaddrinfo.h
postscreen_tests.o: ../../include/myflock.h
postscreen_tests.o: ../../include/name_code.h
+postscreen_tests.o: ../../include/sane_strtol.h
postscreen_tests.o: ../../include/server_acl.h
postscreen_tests.o: ../../include/string_list.h
postscreen_tests.o: ../../include/sys_defs.h
#include <sys_defs.h>
#include <stdio.h> /* sscanf */
-#include <stdlib.h> /* strtoul */
/* Utility library. */
#include <msg.h>
#include <name_code.h>
+#include <sane_strtol.h>
/* Global library. */
* at the time that the cache entry was written.
*/
for (sp = time_stamps; sp < time_stamps + PSC_TINDX_COUNT; sp++) {
- *sp = strtoul(start, &cp, 10);
+ *sp = sane_strtoul(start, &cp, 10);
if (*start == 0 || (*cp != '\0' && *cp != ';') || errno == ERANGE)
*sp = PSC_TIME_STAMP_DISABLED;
if (msg_verbose)
extpar.c dict_inline.c casefold.c dict_utf8.c strcasecmp_utf8.c \
split_qnameval.c argv_attr_print.c argv_attr_scan.c dict_file.c \
msg_logger.c logwriter.c unix_dgram_connect.c unix_dgram_listen.c \
- byte_mask.c known_tcp_ports.c argv_split_at.c dict_stream.c
+ byte_mask.c known_tcp_ports.c argv_split_at.c dict_stream.c \
+ sane_strtol.c
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
extpar.o dict_inline.o casefold.o dict_utf8.o strcasecmp_utf8.o \
split_qnameval.o argv_attr_print.o argv_attr_scan.o dict_file.o \
msg_logger.o logwriter.o unix_dgram_connect.o unix_dgram_listen.o \
- byte_mask.o known_tcp_ports.o argv_split_at.o dict_stream.o
+ byte_mask.o known_tcp_ports.o argv_split_at.o dict_stream.o \
+ sane_strtol.o
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
# otherwise it sets the PLUGIN_* macros.
slmdb.h compat_va_copy.h dict_pipe.h dict_random.h \
valid_utf8_hostname.h midna_domain.h dict_union.h dict_inline.h \
check_arg.h argv_attr.h msg_logger.h logwriter.h byte_mask.h \
- known_tcp_ports.h
+ known_tcp_ports.h sane_strtol.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
DEFS = -I. -D$(SYSTYPE)
mac_expand.o: msg.h
mac_expand.o: mymalloc.h
mac_expand.o: name_code.h
+mac_expand.o: sane_strtol.h
mac_expand.o: stringops.h
mac_expand.o: sys_defs.h
mac_expand.o: vbuf.h
sane_socketpair.o: sane_socketpair.c
sane_socketpair.o: sane_socketpair.h
sane_socketpair.o: sys_defs.h
+sane_strtol.o: sane_strtol.c
+sane_strtol.o: sane_strtol.h
+sane_strtol.o: sys_defs.h
sane_time.o: msg.h
sane_time.o: sane_time.c
sane_time.o: sane_time.h
#include <mymalloc.h>
#include <stringops.h>
#include <name_code.h>
+#include <sane_strtol.h>
#include <mac_parse.h>
#include <mac_expand.h>
long result;
char *remainder;
- result = strtol(strval, &remainder, 10);
+ result = sane_strtol(strval, &remainder, 10);
if (*strval == 0 /* can't happen */ || *remainder != 0 || errno == ERANGE)
msg_fatal("mac_exp_eval: bad conversion: %s", strval);
return (result);
--- /dev/null
+/*++
+/* NAME
+/* sane_strtol 3
+/* SUMMARY
+/* strtol() with mandatory errno reset
+/* SYNOPSIS
+/* #include <sane_strtol.h>
+/*
+/* long sane_strtol(
+/* const char *start,
+/* char **restrict end,
+/* int base)
+/*
+/* unsigned long sane_strtoul(
+/* const char *start,
+/* char **restrict end,
+/* int base)
+/* DESCRIPTION
+/* These functions are wrappers around the strtol() and strtoul()
+/* standard library functions that reset errno first, so that a
+/* prior ERANGE error won't cause false errors.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*--*/
+
+ /*
+ * System library.
+ */
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <errno.h>
+
+ /*
+ * Utility library.
+ */
+#include <sane_strtol.h>
+
+/* sane_strtol - strtol() with mandatory initialization */
+
+long sane_strtol(const char *start, char **end, int base)
+{
+ errno = 0;
+ return (strtol(start, end, base));
+}
+
+/* sane_strtoul - strtoul() with mandatory initialization */
+
+unsigned long sane_strtoul(const char *start, char **end, int base)
+{
+ errno = 0;
+ return (strtoul(start, end, base));
+}
--- /dev/null
+/*++
+/* NAME
+/* sane_strtol 3h
+/* SUMMARY
+/* strtol() with mandatory errno reset
+/* SYNOPSIS
+/* #include <sane_strtol.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * External API.
+ */
+extern long sane_strtol(const char *start, char **end, int);
+extern unsigned long sane_strtoul(const char *start, char **end, int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*--*/
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
/*