In both cases, the program being executed is not the program that
was supposed to be executed, so anything can happen.
+There is a third possibility:
+
+3 - Bugs in system software (kernel or libraries).
+
Hardware-related failures happen erratically, and they usually do
not reproduce after power cycling and rebooting the system. There's
little I can do about bad hardware. Be sure to use hardware that
delivery agent no longer appends a blank line to mail that
is delivered to external command. Files: pipe/pipe.c,
global/mail_copy.[hc].
+
+20000708
+
+ Portability: support for NEXT/OPENSTEP requires extra
+ include file in util/watchdog.c (Masaki Murase).
+
+20000715
+
+ Added macros to turn on vstream/vstring/etc. format string
+ checking by gcc, in addition to the checking that was
+ already implemented with printfck. File: util/sys_defs.h,
+ the macros for PRINTFLIKE and SCANFLIKE. Problem - unlike
+ the printfck tool, this gcc finds mismatches only in code
+ that isn't #ifdef-ed out.
+
+20000718
+
+ Robustness: make_dirs() now continues when a missing
+ directory is created by another process.
Reliant UNIX 5.x
Rhapsody 5.x
SunOS 4.1.x
- SunOS 5.4..5.7 (Solaris 2.4..7)
+ SunOS 5.4..5.8 (Solaris 2.4..8)
Ultrix 4.x
or something closely resemblant.
SHELL = /bin/sh
-WARN = -Wmissing-prototypes
+WARN = -Wmissing-prototypes -Wformat
OPTS = "CC=$(CC)"
DIRS = util global dns master postfix smtpstone sendmail error \
pickup cleanup smtpd local lmtp trivial-rewrite qmgr smtp bounce pipe \
*/
extern void cleanup_out(CLEANUP_STATE *, int, char *, int);
extern void cleanup_out_string(CLEANUP_STATE *, int, char *);
-extern void cleanup_out_format(CLEANUP_STATE *, int, char *,...);
+extern void PRINTFLIKE(3, 4) cleanup_out_format(CLEANUP_STATE *, int, char *,...);
#define CLEANUP_OUT_BUF(s, t, b) \
cleanup_out((s), (t), vstring_str((b)), VSTRING_LEN((b)))
if ((state->headers_seen & (1 << (state->resent[0] ?
HDR_RESENT_FROM : HDR_FROM))) == 0) {
- quote_822_local(state->temp1, state->sender);
+ quote_822_local(state->temp1, *state->sender ?
+ state->sender : MAIL_ADDR_MAIL_DAEMON);
vstring_sprintf(state->temp2, "%sFrom: %s",
state->resent, vstring_str(state->temp1));
- if (state->fullname && *state->fullname) {
+ if (*state->sender && state->fullname && *state->fullname) {
vstring_sprintf(state->temp1, "(%s)", state->fullname);
token = tok822_parse(vstring_str(state->temp1));
vstring_strcat(state->temp2, " ");
# or networks obtained by stripping octets.
# Reject if result is REJECT or "[45]xx text"
# Permit otherwise.
-# reject_maps_rbl: reject if the client is listed under $maps_rbl_domains.
+# reject_maps_rbl: reject if the reverse client network address
+# is listed under $maps_rbl_domains.
# reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction.
smtpd_etrn_restrictions =
LIB = libglobal.a
TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
mail_addr_map mail_date maps mynetworks mypwd namadr_list \
- off_cvt quote_822_local rec2stream recdump resolve_clnt \
+ off_cvt peer_name quote_822_local rec2stream recdump resolve_clnt \
resolve_local rewrite_clnt stream2rec string_list tok822_parse \
quote_821_local
quote_821_local: quote_821_local.c $(LIBS)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIBS) $(SYSLIBS)
+peer_name: $(LIB)
+ mv $@.o junk
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
+ mv junk $@.o
+
tests: tok822_test
tok822_test: tok822_parse tok822_parse.in tok822_parse.ref
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(BH_TABLE *, const char *,...);
+extern int PRINTFLIKE(2, 3) been_here(BH_TABLE *, const char *,...);
extern int been_here_check_fixed(BH_TABLE *, const char *);
-extern int been_here_check(BH_TABLE *, const char *,...);
+extern int PRINTFLIKE(2, 3) been_here_check(BH_TABLE *, const char *,...);
/* LICENSE
/* .ad
/*
* Client interface.
*/
-extern int bounce_append(int, const char *, const char *, const char *,
- time_t, const char *,...);
+extern int PRINTFLIKE(6, 7) bounce_append(int, const char *, const char *,
+ const char *, time_t,
+ const char *,...);
extern int vbounce_append(int, const char *, const char *, const char *,
time_t, const char *, va_list);
extern int bounce_flush(int, const char *, const char *, const char *);
-extern int bounce_recip(int, const char *, const char *, const char *,
- const char *, const char *, time_t,
- const char *,...);
+extern int PRINTFLIKE(8, 9) bounce_recip(int, const char *, const char *,
+ const char *, const char *,
+ const char *, time_t,
+ const char *,...);
extern int vbounce_recip(int, const char *, const char *, const char *,
const char *, const char *, time_t,
const char *, va_list);
*/
#define BOUNCE_CMD_APPEND 0 /* append log */
#define BOUNCE_CMD_FLUSH 1 /* send log */
-#define BOUNCE_CMD_WARN 2 /* send warning bounce, don't delete log */
+#define BOUNCE_CMD_WARN 2 /* send warning bounce, don't delete
+ * log */
#define BOUNCE_CMD_RECIP 3 /* immediate bounce, no logfile */
/*
/*
* External interface.
*/
-extern int defer_append(int, const char *, const char *, const char *,
- time_t, const char *,...);
+extern int PRINTFLIKE(6, 7) defer_append(int, const char *, const char *,
+ const char *, time_t, const char *,...);
extern int vdefer_append(int, const char *, const char *, const char *,
time_t, const char *, va_list);
extern int defer_flush(int, const char *, const char *, const char *);
&request->flags,
queue_name, queue_id, &request->data_offset,
&request->data_size, nexthop, address,
- errors_to, return_receipt, &request->arrival_time) != 9)
+ errors_to, return_receipt, &request->arrival_time) != 10)
return (-1);
if (mail_open_ok(vstring_str(queue_name),
vstring_str(queue_id), &st, &path) == 0)
#define DEF_MAIL_NAME "Postfix"
extern char *var_mail_name;
+ /*
+ * Logging facility. Configurable so you can distinguish a limited number of
+ * Postfix instances.
+ */
+#define VAR_LOG_FACILITY "logging_facility"
+#define DEF_LOG_FACILITY "mail"
+extern char *var_log_facility;
+
/*
* What problem classes should be reported to the postmaster via email.
* Default is bad problems only. See mail_error(3). Even when mail notices
extern int mail_scan(VSTREAM *, const char *,...);
extern void mail_scan_register(int, const char *, MAIL_SCAN_FN);
extern void mail_print_register(int, const char *, MAIL_PRINT_FN);
-extern int mail_print(VSTREAM *, const char *,...);
-extern int mail_command_write(const char *, const char *, const char *,...);
+extern int PRINTFLIKE(2, 3) mail_print(VSTREAM *, const char *,...);
+extern int PRINTFLIKE(3, 4) mail_command_write(const char *, const char *, const char *,...);
extern int mail_command_read(VSTREAM *, char *,...);
extern int mail_trigger(const char *, const char *, const char *, int);
extern char *mail_pathname(const char *, const char *);
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20000625"
+#define DEF_MAIL_VERSION "Snapshot-20000718"
extern char *var_mail_version;
/* LICENSE
/*
* External interface.
*/
-extern void opened(const char *, const char *, long, const char *,...);
+extern void PRINTFLIKE(4, 5) opened(const char *, const char *, long,
+ const char *,...);
extern void vopened(const char *, const char *, long, const char *, va_list);
/* LICENSE
extern VSTREAM *post_mail_fopen(const char *, const char *, int, const char *);
extern VSTREAM *post_mail_fopen_nowait(const char *, const char *,
int, const char *);
-extern int post_mail_fprintf(VSTREAM *, const char *,...);
+extern int PRINTFLIKE(2, 3) post_mail_fprintf(VSTREAM *, const char *,...);
extern int post_mail_fputs(VSTREAM *, const char *);
extern int post_mail_buffer(VSTREAM *, const char *, int);
extern int post_mail_fclose(VSTREAM *);
extern int rec_get(VSTREAM *, VSTRING *, int);
extern int rec_put(VSTREAM *, int, const char *, int);
extern int rec_put_type(VSTREAM *, int, long);
-extern int rec_fprintf(VSTREAM *, int, const char *,...);
+extern int PRINTFLIKE(3, 4) rec_fprintf(VSTREAM *, int, const char *,...);
extern int rec_fputs(VSTREAM *, int, const char *);
#define REC_PUT_BUF(v, t, b) rec_put((v), (t), vstring_str(b), VSTRING_LEN(b))
/*
* External interface.
*/
-extern int sent(const char *, const char *, const char *,
- time_t, const char *,...);
+extern int PRINTFLIKE(5, 6) sent(const char *, const char *, const char *,
+ time_t, const char *,...);
extern int vsent(const char *, const char *, const char *,
time_t, const char *, va_list);
#define SMTP_ERR_TIME 2 /* time out */
extern void smtp_timeout_setup(VSTREAM *, int);
-extern void smtp_printf(VSTREAM *, const char *,...);
+extern void PRINTFLIKE(2, 3) smtp_printf(VSTREAM *, const char *,...);
extern int smtp_get(VSTRING *, VSTREAM *, int);
extern void smtp_fputs(const char *, int len, VSTREAM *);
extern void smtp_fwrite(const char *, int len, VSTREAM *);
<li><a href="#sendmail_incompatibility">Sendmail incompatibility</a>
+<li><a href="#performance">Postfix performance</a>
+
<li><a href="#receiving">Receiving mail via the network</a>
<li><a href="#relaying">Mail relaying</a>
</ul>
+<a name="performance"><h3>Postfix performance</h3>
+
+<ul>
+
+<li><a href="#incoming">Too much mail in the incoming queue</a>
+
+</ul>
+
<a name="receiving"><h3>Receiving mail via the network</h3>
<ul>
<ul>
+<li><a href="#dns-again">All remote mail stays queued with: Host not found, try again</a>
+
<li><a href="#timeouts">Mail fails consistently with timeout or lost connection</a>
<li><a href="#skip_greeting">Postfix does not try all the MX addresses</a>
<li><a href="#db">Using third-party DB libraries</a>
+<li><a href="#sgistruct">IRIX problems translating IP address to string</a>
+
</ul>
<hr>
<p>
-Specify <b>dbm:/etc/postfix/transport</b> if your system uses
+Specify <b>dbm</b> instead of <b>hash</b> if your system uses
<b>dbm</b> files instead of <b>db</b>. To find out what map types
Postfix supports, use the command <b>postconf -m</b>.
<p>
-Specify <b>dbm:/etc/postfix/transport</b> if your system uses
+Specify <b>dbm</b> instead of <b>hash</b> if your system uses
<b>dbm</b> files instead of <b>db</b>. To find out what map types
Postfix supports, use the command <b>postconf -m</b>.
<hr>
+<a name="incoming"><h3>Too much mail in the incoming queue</h3></a>
+
+<blockquote>
+
+I have lots if mail in the incoming queue, but Postfix only runs
+a few outbound SMTP deliveries. Why is it not running more SMTP
+clients?
+
+</blockquote>
+
+<p>
+
+Your problem is that the disk is saturated with I/O from receiving
+mail, so that the Postfix queue manager gets insufficient chance
+to process the requests (many SMTP server processes against one
+poor queue manager).
+
+<p>
+
+You solve the problem by getting faster disks.
+
+<p>
+
+I am still solving the scheduling problem from the software side.
+
+<p>
+
+Currently, the workaround is to configure multiple IP addresses
+per machine, and to run one Postfix instance per IP address. The
+Postfix instances can't share queue directories, but sharing mailbox
+directories is OK.
+
+<p>
+
+Just start each Postfix instance with a different configuration
+directory:
+
+<p>
+
+<pre>
+ # postfix -c config_directory start
+</pre>
+
+<p>
+
+Each main.cf file has a different <b>$myhostname</b> setting,
+depending on the interface that it is supposed to handle.
+
+<p>
+
+<pre>
+ myhostname = foo1.my.domain
+ inet_interfaces = $myhostname
+</pre>
+
+<hr>
+
<a name="delay"><h3>Postfix responds slowly to incoming SMTP connections</h3></a>
<dl>
<hr>
+<a name="dns-again"><h3>All remote mail stays queued with: Host not found, try again</h3></a>
+
+<blockquote>
+
+When I connect send mail to a remote address, the following happens:
+
+<p>
+
+<pre>
+ Jul 14 12:45:38 myhostname postfix/qmgr[2246]: 74FBF30501:
+ from=<sender@sender.domain> size=309 (queue active)
+ Jul 14 12:45:39 myhostname postfix/smtp[2349]: 74FBF30501:
+ to=<recip@recip.domain> relay=none, delay=3944, status=deferred (Name
+ service error for domain recip.domain: Host not found, try again)
+</pre>
+
+</blockquote>
+
+<p>
+
+Check out your Postfix <b>master.cf</b> file. If the SMTP client
+runs chrooted, then it needs a bunch of files inside the Postfix
+queue directory. Examples are in the source distribution in the
+<b>examples</b> subdirectory.
+
+<hr>
+
<a name="timeouts"><h3>Mail fails consistently with timeout or lost connection</h3></a>
Every now and then, mail fails with "timed out while sending end
</pre>
</ul>
+
+<hr>
+
+<a name="sgistruct">
+
+<h3>IRIX problems translating IP address to string</h3>
+
+<dl>
+
+<dt>Question: <dd> While installing IRIX 6.5.7m on a clean disk
+and no special options or software I stumbled upon the following
+problem; the inet_ntoa() function seems to return INADDR_NONE
+(malformed request?) for every call to it.
+
+<p>
+
+<dt>Answer: <dd>There is an incompatibility between gcc and system
+libraries compiled with SGI's cc. See a description in <a
+href="http://freeware.sgi.com/shared/howto.html">
+http://freeware.sgi.com/shared/howto.html</a>.
+
+<p>If you must use gcc, a possible workaround is to use the
+inet_ntoa() routine from the BIND source code at <a
+href="http://www.isc.org/"> http://www.isc.org/</a>.
+
+</dl>
+
<hr>
<a href="index.html">Up one level</a> | Postfix FAQ
<p>
Postfix is a direct competitor to the <a href="http://www.qmail.org">
-qmail </a> by Dan Bernstein. That's competitor, not enemy. I'm sure
-that friendly competition will help to improve both programs.
+qmail </a> software by Dan Bernstein. That's competitor, not enemy.
+I'm sure that friendly competition will help to improve both
+programs.
<hr>
This macro expands to the envelope sender
address.
+ <b>${size</b>}
+ This macro expands to Postfix's idea of the
+ message size, which is an approximation of
+ the size of the message as delivered.
+
<b>${user</b>}
This macro expands to the username part of a
recipient address. For example, with an
<i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
Limit the number of parallel deliveries to the same
destination, for delivery via the named <i>transport</i>.
- The default limit is taken from the <b>default</b><i>_</i><b>desti-</b>
- <b>nation</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter. The limit is
- enforced by the Postfix queue manager.
-
- <i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
- Limit the number of recipients per message
+ The default limit is taken from the
PIPE(8) PIPE(8)
- delivery, for delivery via the named <i>transport</i>. The
- default limit is taken from the <b>default</b><i>_</i><b>destina-</b>
- <b>tion</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter. The limit is
+ <b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter.
+ The limit is enforced by the Postfix queue manager.
+
+ <i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
+ Limit the number of recipients per message deliv-
+ ery, for delivery via the named <i>transport</i>. The
+ default limit is taken from the <b>default</b><i>_</i><b>destina-</b>
+ <b>tion</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter. The limit is
enforced by the Postfix queue manager.
<i>transport_</i><b>time</b><i>_</i><b>limit</b>
- Limit the time for delivery to external command,
- for delivery via the named <b>transport</b>. The default
- limit is taken from the <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b> parame-
- ter. The limit is enforced by the Postfix queue
+ Limit the time for delivery to external command,
+ for delivery via the named <b>transport</b>. The default
+ limit is taken from the <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b> parame-
+ ter. The limit is enforced by the Postfix queue
manager.
<b>SEE</b> <b>ALSO</b>
syslogd(8) system logging
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
-
-
-
-
-
<a name="reject_maps_rbl">
-<dt> <b>reject_maps_rbl</b> <dd> Reject the request when the client
-network address is listed under any of the domains listed in <a
-href="#maps_rbl_domains">$maps_rbl_domains</a>. The <b>
+<dt> <b>reject_maps_rbl</b> <dd> Reject the request when the reversed
+client network address is listed under any of the domains listed
+in <a href="#maps_rbl_domains">$maps_rbl_domains</a>. The <b>
maps_rbl_reject_code</b> parameter specifies the response code for
rejected requests (default: <b>554</b>).
VSTRING *buf; /* origin of text */
} LMTP_RESP;
-extern void lmtp_chat_cmd(LMTP_STATE *, char *,...);
+extern void PRINTFLIKE(2, 3) lmtp_chat_cmd(LMTP_STATE *, char *,...);
extern LMTP_RESP *lmtp_chat_resp(LMTP_STATE *);
extern void lmtp_chat_reset(LMTP_STATE *);
extern void lmtp_chat_notify(LMTP_STATE *);
/*
* lmtp_trouble.c
*/
-extern int lmtp_conn_fail(LMTP_STATE *, int, char *,...);
-extern int lmtp_site_fail(LMTP_STATE *, int, char *,...);
-extern int lmtp_mesg_fail(LMTP_STATE *, int, char *,...);
-extern void lmtp_rcpt_fail(LMTP_STATE *, int, RECIPIENT *, char *,...);
+extern int PRINTFLIKE(3, 4) lmtp_conn_fail(LMTP_STATE *, int, char *,...);
+extern int PRINTFLIKE(3, 4) lmtp_site_fail(LMTP_STATE *, int, char *,...);
+extern int PRINTFLIKE(3, 4) lmtp_mesg_fail(LMTP_STATE *, int, char *,...);
+extern void PRINTFLIKE(4, 5) lmtp_rcpt_fail(LMTP_STATE *, int, RECIPIENT *, char *,...);
extern int lmtp_stream_except(LMTP_STATE *, int, char *);
/*
expands into as many command-line arguments as there are recipients.
.IP \fB${\fBsender\fR}\fR
This macro expands to the envelope sender address.
+.IP \fB${\fBsize\fR}\fR
+This macro expands to Postfix's idea of the message size, which
+is an approximation of the size of the message as delivered.
.IP \fB${\fBuser\fR}\fR
This macro expands to the username part of a recipient address.
For example, with an address \fIuser+foo@domain\fR the username
/*
* qmgr_bounce.c
*/
-extern void qmgr_bounce_recipient(QMGR_MESSAGE *, QMGR_RCPT *, const char *,...);
+extern void PRINTFLIKE(3, 4) qmgr_bounce_recipient(QMGR_MESSAGE *, QMGR_RCPT *, const char *,...);
/*
* qmgr_deliver.c
/* expands into as many command-line arguments as there are recipients.
/* .IP \fB${\fBsender\fR}\fR
/* This macro expands to the envelope sender address.
+/* .IP \fB${\fBsize\fR}\fR
+/* This macro expands to Postfix's idea of the message size, which
+/* is an approximation of the size of the message as delivered.
/* .IP \fB${\fBuser\fR}\fR
/* This macro expands to the username part of a recipient address.
/* For example, with an address \fIuser+foo@domain\fR the username
#define PIPE_DICT_USER "user" /* key */
#define PIPE_DICT_EXTENSION "extension" /* key */
#define PIPE_DICT_MAILBOX "mailbox" /* key */
+#define PIPE_DICT_SIZE "size" /* key */
/*
* Flags used to pass back the type of special parameter found by
#define PIPE_FLAG_USER (1<<1)
#define PIPE_FLAG_EXTENSION (1<<2)
#define PIPE_FLAG_MAILBOX (1<<3)
+#define PIPE_FLAG_SIZE (1<<4)
/*
* Tunable parameters. Values are taken from the config file, after
*expand_flag |= PIPE_FLAG_EXTENSION;
else if (strcmp(vstring_str(buf), PIPE_DICT_MAILBOX) == 0)
*expand_flag |= PIPE_FLAG_MAILBOX;
+ else if (strcmp(vstring_str(buf), PIPE_DICT_SIZE) == 0)
+ *expand_flag |= PIPE_FLAG_SIZE;
}
return (0);
}
/* expand_argv - expand macros in the argument vector */
-static ARGV *expand_argv(char **argv, RECIPIENT_LIST *rcpt_list)
+static ARGV *expand_argv(char **argv, RECIPIENT_LIST *rcpt_list, long data_size)
{
VSTRING *buf = vstring_alloc(100);
ARGV *result;
lowercase(STR(buf));
dict_update(PIPE_DICT_TABLE, PIPE_DICT_MAILBOX, STR(buf));
}
+
+ /*
+ * This argument contains $size.
+ */
+ if (expand_flag & PIPE_FLAG_SIZE) {
+ vstring_sprintf(buf, "%ld", data_size);
+ dict_update(PIPE_DICT_TABLE, PIPE_DICT_SIZE, STR(buf));
+ }
+
+ /*
+ * Done.
+ */
argv_add(result, dict_eval(PIPE_DICT_TABLE, *cpp, NO), ARGV_END);
}
}
dict_update(PIPE_DICT_TABLE, PIPE_DICT_SENDER, request->sender);
dict_update(PIPE_DICT_TABLE, PIPE_DICT_NEXTHOP, request->nexthop);
- expanded_argv = expand_argv(attr.command, rcpt_list);
+ expanded_argv = expand_argv(attr.command, rcpt_list, request->data_size);
command_status = pipe_command(request->fp, why,
PIPE_CMD_UID, attr.uid,
/*
* qmgr_bounce.c
*/
-extern void qmgr_bounce_recipient(QMGR_MESSAGE *, QMGR_RCPT *, const char *,...);
+extern void PRINTFLIKE(3, 4) qmgr_bounce_recipient(QMGR_MESSAGE *, QMGR_RCPT *, const char *,...);
/*
* qmgr_deliver.c
VSTRING *buf; /* origin of text */
} SMTP_RESP;
-extern void smtp_chat_cmd(SMTP_STATE *, char *,...);
+extern void PRINTFLIKE(2, 3) smtp_chat_cmd(SMTP_STATE *, char *,...);
extern SMTP_RESP *smtp_chat_resp(SMTP_STATE *);
extern void smtp_chat_reset(SMTP_STATE *);
extern void smtp_chat_notify(SMTP_STATE *);
/*
* smtp_trouble.c
*/
-extern int smtp_conn_fail(SMTP_STATE *, int, char *,...);
-extern int smtp_site_fail(SMTP_STATE *, int, char *,...);
-extern int smtp_mesg_fail(SMTP_STATE *, int, char *,...);
-extern void smtp_rcpt_fail(SMTP_STATE *, int, RECIPIENT *, char *,...);
+extern int PRINTFLIKE(3, 4) smtp_conn_fail(SMTP_STATE *, int, char *,...);
+extern int PRINTFLIKE(3, 4) smtp_site_fail(SMTP_STATE *, int, char *,...);
+extern int PRINTFLIKE(3, 4) smtp_mesg_fail(SMTP_STATE *, int, char *,...);
+extern void PRINTFLIKE(4, 5) smtp_rcpt_fail(SMTP_STATE *, int, RECIPIENT *, char *,...);
extern int smtp_stream_except(SMTP_STATE *, int, char *);
/*
*/
extern void smtpd_chat_reset(SMTPD_STATE *);
extern void smtpd_chat_query(SMTPD_STATE *);
-extern void smtpd_chat_reply(SMTPD_STATE *, char *, ...);
+extern void PRINTFLIKE(2, 3) smtpd_chat_reply(SMTPD_STATE *, char *, ...);
extern void smtpd_chat_notify(SMTPD_STATE *);
/* LICENSE
/* Look up the resolved recipient address in the named access table,
/* any parent domains of the recipient domain, and the localpart@.
/* .IP reject_maps_rbl
-/* Look up the client network address in the real-time blackhole
+/* Look up the reversed client network address in the real-time blackhole
/* DNS zones below the domains listed in the "maps_rbl_domains"
/* configuration parameter. The \fImaps_rbl_reject_code\fR
/* configuration parameter specifies the reject status code
TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
fifo_rdonly_bug fifo_rdwr_bug fifo_trigger fsspace fullname \
inet_addr_host inet_addr_local mac_parse make_dirs msg_syslog \
- mystrtok peer_name sigdelay translit valid_hostname vstream_popen \
+ mystrtok sigdelay translit valid_hostname vstream_popen \
vstring vstring_vstream doze select_bug stream_test mac_expand \
watchdog unescape
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o
-peer_name: $(LIB)
- mv $@.o junk
- $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
- mv junk $@.o
-
doze: $(LIB)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
--- /dev/null
+/*++
+/* NAME
+/* dup2_pass_on_exec 1
+/* SUMMARY
+/* dup2 close-on-exec behaviour test program
+/* SYNOPSIS
+/* dup2_pass_on_exec
+/* DESCRIPTION
+/* dup2_pass_on_exec sets the close-on-exec flag on its
+/* standard input and then dup2() to duplicate it.
+/* Posix-1003.1 specifies in section 6.2.1.2 that dup2(o,n) should behave
+/* as: close(n); n = fcntl(o, F_DUPFD, n); as long as o is a valid
+/* file-descriptor, n!=o, and 0<=n<=[OPEN_MAX].
+/* Section 6.5.2.2 states that the close-on-exec flag of the result of a
+/* successful fcntl(o, F_DUPFD, n) is cleared.
+/*
+/* At least Ultrix4.3a does not clear the close-on-exec flag of n on
+/* dup2(o, n).
+/* DIAGNOSTICS
+/* Problems are reported to the standard error stream.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Christian von Roques <roques@pond.sub.org>
+/* Forststrasse 71
+/* 76131 Karlsruhe, GERMANY
+/*--*/
+
+#include <stdio.h>
+#include <fcntl.h>
+
+#define DO(s) if (s < 0) { perror(#s); exit(1); }
+
+int main(int unused_argc, char **unused_argv)
+{
+ int res;
+
+ printf("Setting the close-on-exec flag of file-descriptor 0.\n");
+ DO(fcntl(0, F_SETFD, 1));
+
+ printf("Duplicating file-descriptor 0 to 3.\n");
+ DO(dup2(0, 3));
+
+ printf("Testing if the close-on-exec flag of file-descriptor 3 is set.\n");
+ DO((res = fcntl(3, F_GETFD, 0)));
+ if (res & 1)
+ printf("Yes, a newly dup2()ed file-descriptor has the close-on-exec "
+ "flag cloned.\n"
+ "THIS VIOLATES Posix1003.1 section 6.2.1.2 or 6.5.2.2!\n"
+ "You should #define DUP2_DUPS_CLOSE_ON_EXEC in sys_defs.h "
+ "for your OS.\n");
+ else
+ printf("No, a newly dup2()ed file-descriptor has the close-on-exec "
+ "flag cleared.\n"
+ "This complies with Posix1003.1 section 6.2.1.2 and 6.5.2.2!\n");
+
+ return 0;
+}
printf("%c", *context);
fflush(stdout);
*context = (ISUPPER(*context) ? TOLOWER(*context) : TOUPPER(*context));
- event_request_timer(dingdong, context, DELAY);
+ event_request_timer(dingdong, context, (char *) DELAY);
}
/* echo - echo text received on stdin */
char *cp;
for (cp = text; *cp; cp++)
- event_request_timer(dingdong, cp, 0);
+ event_request_timer(dingdong, cp, (char *) 0);
event_enable_read(fileno(stdin), echo, (char *) 0);
for (;;)
event_loop(-1);
ret = -1;
break;
}
- } else if (errno != ENOENT || (ret = mkdir(saved_path, perms)) < 0)
- break;
+ } else {
+ if (errno != ENOENT)
+ break;
+ if ((ret = mkdir(saved_path, perms)) < 0 && errno != EEXIST)
+ break;
+ }
if (saved_ch != 0)
*cp = saved_ch;
SKIP_WHILE(*cp == '/', cp);
extern int msg_verbose;
-extern void msg_info(const char *,...);
-extern void msg_warn(const char *,...);
-extern void msg_error(const char *,...);
-extern NORETURN msg_fatal(const char *,...);
-extern NORETURN msg_panic(const char *,...);
+extern void PRINTFLIKE(1, 2) msg_info(const char *,...);
+extern void PRINTFLIKE(1, 2) msg_warn(const char *,...);
+extern void PRINTFLIKE(1, 2) msg_error(const char *,...);
+extern NORETURN PRINTFLIKE(1, 2) msg_fatal(const char *,...);
+extern NORETURN PRINTFLIKE(1, 2) msg_panic(const char *,...);
extern int msg_error_limit(int);
extern void msg_error_clear(void);
*/
typedef void (*MSG_OUTPUT_FN) (int, const char *);
extern void msg_output(MSG_OUTPUT_FN);
-extern void msg_printf(int, const char *,...);
+extern void PRINTFLIKE(2, 3) msg_printf(int, const char *,...);
extern void msg_vprintf(int, const char *, va_list);
extern void msg_text(int, const char *);
#ifndef NORETURN
#define NORETURN void
+#endif
+
+ /*
+ * Turn on format string argument checking. This is more accurate than
+ * printfck, but it misses #ifdef-ed code. XXX I am just guessing at what
+ * gcc versions support this. In order to turn this off for some platforms,
+ * specify #define PRINTFLIKE and #define SCANFLIKE in the system-dependent
+ * sections above.
+ */
+#ifndef PRINTFLIKE
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7
+#define PRINTFLIKE(x,y) __attribute__ ((format (printf, (x), (y))))
+#else
+#define PRINTFLIKE
+#endif
+#endif
+
+#ifndef SCANFLIKE
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7
+#define SCANFLIKE(x,y) __attribute__ ((format (scanf, (x), (y))))
+#else
+#define SCANFLIKE
+#endif
#endif
/*
#define VSTREAM_CTL_EXCEPT 9
#define VSTREAM_CTL_CONTEXT 10
-extern VSTREAM *vstream_printf(const char *,...);
-extern VSTREAM *vstream_fprintf(VSTREAM *, const char *,...);
+extern VSTREAM *PRINTFLIKE(1, 2) vstream_printf(const char *,...);
+extern VSTREAM *PRINTFLIKE(2, 3) vstream_fprintf(VSTREAM *, const char *,...);
extern VSTREAM *vstream_popen(const char *, int);
extern VSTREAM *vstream_popen_vargs(int,...);
extern VSTRING *vstring_strncpy(VSTRING *, const char *, int);
extern VSTRING *vstring_strcat(VSTRING *, const char *);
extern VSTRING *vstring_strncat(VSTRING *, const char *, int);
-extern VSTRING *vstring_sprintf(VSTRING *, const char *,...);
-extern VSTRING *vstring_sprintf_append(VSTRING *, const char *,...);
+extern VSTRING *PRINTFLIKE(2, 3) vstring_sprintf(VSTRING *, const char *,...);
+extern VSTRING *PRINTFLIKE(2, 3) vstring_sprintf_append(VSTRING *, const char *,...);
extern char *vstring_export(VSTRING *);
extern VSTRING *vstring_import(char *);
#include <sys_defs.h>
#include <unistd.h>
#include <signal.h>
+#include <posix_signals.h>
/* Utility library. */