]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-19990321
authorWietse Venema <wietse@porcupine.org>
Sun, 21 Mar 1999 05:00:00 +0000 (00:00 -0500)
committerWietse Venema <wietse@porcupine.org>
Thu, 17 Jan 2013 03:23:50 +0000 (22:23 -0500)
47 files changed:
postfix/HISTORY
postfix/PCRE_README
postfix/global/Makefile.in
postfix/global/mail_connect.c
postfix/global/mail_params.c
postfix/global/mail_params.h
postfix/global/mail_trigger.c
postfix/global/mail_version.h
postfix/local/Makefile.in
postfix/local/local.h
postfix/local/recipient.c
postfix/master/Makefile.in
postfix/master/master.c
postfix/master/master_listen.c
postfix/master/master_wakeup.c
postfix/master/multi_server.c
postfix/master/single_server.c
postfix/master/trigger_server.c
postfix/pickup/Makefile.in
postfix/postalias/postalias.c
postfix/postcat/postcat.c
postfix/postconf/postconf.c
postfix/postdrop/postdrop.c
postfix/postfix/postfix.c
postfix/postkick/postkick.c
postfix/postlock/postlock.c
postfix/postlog/postlog.c
postfix/postmap/postmap.c
postfix/postsuper/postsuper.c
postfix/qmgr/qmgr_deliver.c
postfix/qmgr/qmgr_transport.c
postfix/sendmail/sendmail.c
postfix/smtpstone/Makefile.in
postfix/util/Makefile.in
postfix/util/connect.h
postfix/util/inet_listen.c
postfix/util/listen.h
postfix/util/sane_accept.c
postfix/util/sendfd_test [new file with mode: 0755]
postfix/util/sendfd_test.c [new file with mode: 0644]
postfix/util/stream_connect.c [new file with mode: 0644]
postfix/util/stream_listen.c [new file with mode: 0644]
postfix/util/stream_trigger.c [new file with mode: 0644]
postfix/util/sys_defs.h
postfix/util/trigger.h
postfix/util/unix_listen.c
postfix/util/writable.c

index befee96ddcd966e33f5e9e19cbfa76826dae7698..136a2c58c050ceb6efd68e2bd03048afd5850950 100644 (file)
@@ -2346,6 +2346,31 @@ Apologies for any names omitted.
        recipients to a master.cf entry called "cyrus", allowing
        you to have both UNIX and non-UNIX mailboxes side by side.
 
+19990319
+
+       Workaround: on 4.4 BSD derivatives, fstat() can return
+       EBADF on an open file descriptor. Now, that was a surprise.
+       This caused std{out,err} from cron commands to not be
+       delivered.
+
+       Bugfix: "local -v" stopped working.
+
+       Workaround: more watchdog timers for postfix-unfriendly
+       systems. By now every Postfix daemon has one. Call it life
+       insurance. 
+
+       Robustness: increased the maximal time to receive or deliver
+       mail from $ipc_timeout (default: 3600 seconds) to the more
+       generous $daemon_timeout (default: 18000 seconds). We don't
+       want false alarms.
+
+       Portability: IRIX 5.2 does not have usleep().
+
+19990320
+
+       Bugfix: \username was broken. Frank Dziuba was the first
+       to notice.
+
 Future:
 
        Planned: must be able to list the same hash table in
index d407d5ef9dc7274eaea671fd71bf557880858669..1c743b7ca14cc1350131a66bca3bf437a688d4f2 100644 (file)
@@ -22,6 +22,8 @@ and add the path to the PCRE library to AUXLIBS, for example:
    make -f Makefile.init makefiles 'CCARGS=-DHAS_PCRE -I../../pcre-2.04' \
       'AUXLIBS=../../pcre-2.04/libpcre.a'
 
+[note: earlier pcre versions have problems -- Wietse]
+
 One possible use is to add a line to main.cf:
 
    smtpd_recipient_restrictions = pcre:/opt/postfix/etc/smtprecipient
index 2eb474973ea06ee34ec600bea814cfe6b957bb9e..34b2be57da1063ae22d1f37703f6796d3c7d9a9e 100644 (file)
@@ -577,6 +577,7 @@ mail_trigger.o: mail_params.h
 mail_trigger.o: mail_proto.h
 mail_trigger.o: ../include/vstream.h
 mail_trigger.o: ../include/vbuf.h
+mail_version.o: mail_version.c
 maps.o: maps.c
 maps.o: ../include/sys_defs.h
 maps.o: ../include/argv.h
index 8b9223a5a0bc1c730a4cb8d98f401d44205cbf25..3de429326e14809efff738dcabcdc96f72d8d5de 100644 (file)
@@ -81,7 +81,7 @@ VSTREAM *mail_connect(const char *class, const char *name, int block_mode)
     int     fd;
 
     path = mail_pathname(class, name);
-    if ((fd = unix_connect(path, block_mode, 0)) < 0) {
+    if ((fd = LOCAL_CONNECT(path, block_mode, 0)) < 0) {
        if (msg_verbose)
            msg_info("connect to subsystem %s: %m", path);
        stream = 0;
index 0191de98bd7ad6d7bfe9448e2a88497adde2ff97..7acf5e6778650c33c403dc315cc01a6f4dc30b18 100644 (file)
 /*     int     var_soft_bounce;
 /*     time_t  var_starttime;
 /*     int     var_ownreq_special;
-/*
-/*     char    *var_ldap_server_host;
-/*     char    *var_ldap_search_base;
-/*     int     var_ldap_timeout;
+/*     int     var_daemon_timeout;
 /*
 /*     void    mail_params_init()
 /* DESCRIPTION
@@ -160,14 +157,7 @@ int     var_disable_dns;
 int     var_soft_bounce;
 time_t  var_starttime;
 int     var_ownreq_special;
-
-#ifdef HAS_LDAP
-
-char   *var_ldap_server_host;
-char   *var_ldap_search_base;
-int     var_ldap_timeout;
-
-#endif
+int     var_daemon_timeout;
 
 /* check_myhostname - lookup hostname and validate */
 
@@ -259,10 +249,6 @@ void    mail_params_init()
        VAR_MAIL_VERSION, DEF_MAIL_VERSION, &var_mail_version, 1, 0,
        VAR_DB_TYPE, DEF_DB_TYPE, &var_db_type, 1, 0,
        VAR_HASH_QUEUE_NAMES, DEF_HASH_QUEUE_NAMES, &var_hash_queue_names, 1, 0,
-#ifdef HAS_LDAP
-       VAR_LDAP_SERVER, DEF_LDAP_SERVER, &var_ldap_server_host, 0, 0,
-       VAR_LDAP_SEARCH, DEF_LDAP_SEARCH, &var_ldap_search_base, 0, 0,
-#endif
        VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim, 0, 1,
        0,
     };
@@ -279,15 +265,13 @@ void    mail_params_init()
        VAR_MESSAGE_LIMIT, DEF_MESSAGE_LIMIT, &var_message_limit, 0, 0,
        VAR_IPC_IDLE, DEF_IPC_IDLE, &var_ipc_idle_limit, 1, 0,
        VAR_HASH_QUEUE_DEPTH, DEF_HASH_QUEUE_DEPTH, &var_hash_queue_depth, 1, 0,
-#ifdef HAS_LDAP
-       VAR_LDAP_TIMEOUT, DEF_LDAP_TIMEOUT, &var_ldap_timeout, 1, 0,
-#endif
        VAR_TRIGGER_TIMEOUT, DEF_TRIGGER_TIMEOUT, &var_trigger_timeout, 1, 0,
        VAR_FORK_TRIES, DEF_FORK_TRIES, &var_fork_tries, 1, 0,
        VAR_FORK_DELAY, DEF_FORK_DELAY, &var_fork_delay, 1, 0,
        VAR_FLOCK_TRIES, DEF_FLOCK_TRIES, &var_flock_tries, 1, 0,
        VAR_FLOCK_DELAY, DEF_FLOCK_DELAY, &var_flock_delay, 1, 0,
        VAR_FLOCK_STALE, DEF_FLOCK_STALE, &var_flock_stale, 1, 0,
+       VAR_DAEMON_TIMEOUT, DEF_DAEMON_TIMEOUT, &var_daemon_timeout, 1, 0,
        0,
     };
     static CONFIG_BOOL_TABLE bool_defaults[] = {
index 61978087a671e376e5440e6380b5ffe1c012e85f..420267830672594fda6623da4195dd09fb14bc6b 100644 (file)
@@ -234,21 +234,6 @@ extern bool var_append_dot_mydomain;
 #define DEF_PERCENT_HACK       1
 extern bool var_percent_hack;
 
- /*
-  * LDAP lookups. Preliminary code, interface subject to change.
-  */
-#define VAR_LDAP_SERVER                "ldap_server_host"
-#define DEF_LDAP_SERVER                ""
-extern char *var_ldap_server;
-
-#define VAR_LDAP_SEARCH                "ldap_search_base"
-#define DEF_LDAP_SEARCH                ""
-extern char *var_ldap_search;
-
-#define VAR_LDAP_TIMEOUT       "ldap_lookup_timeout"
-#define DEF_LDAP_TIMEOUT       10
-extern int var_ldap_timeout;
-
  /*
   * Local delivery: alias databases.
   */
@@ -623,6 +608,14 @@ extern int var_flock_delay;
 #define DEF_FLOCK_STALE                500
 extern int var_flock_stale;
 
+ /*
+  * How long a daemon command may take to receive or deliver a message etc.
+  * before we assume it is wegded (should never happen).
+  */
+#define VAR_DAEMON_TIMEOUT     "daemon_timeout"
+#define DEF_DAEMON_TIMEOUT     18000
+extern int var_daemon_timeout;
+
  /*
   * How long an intra-mail command may take before we assume the mail system
   * is in deadlock (should never happen).
index 66710b145a0a9e38890c720064dda6bea3c3168e..4d4d61c3f8b345d0e4527bd1f8dd79c26c634b77 100644 (file)
@@ -83,9 +83,9 @@ int     mail_trigger(const char *class, const char *service,
     } else if (S_ISFIFO(st.st_mode)) {
        status = fifo_trigger(path, req_buf, req_len, var_trigger_timeout);
        if (status < 0 && S_ISSOCK(st.st_mode))
-           status = unix_trigger(path, req_buf, req_len, var_trigger_timeout);
+           status = LOCAL_TRIGGER(path, req_buf, req_len, var_trigger_timeout);
     } else if (S_ISSOCK(st.st_mode)) {
-       status = unix_trigger(path, req_buf, req_len, var_trigger_timeout);
+       status = LOCAL_TRIGGER(path, req_buf, req_len, var_trigger_timeout);
     } else {
        msg_warn("%s is not a socket or a fifo", path);
        status = -1;
index fb32eac8768c844ac6deedb6a61e9e65e4eb9c03..028e1e36becf7ce2b6bdbd788927e14e94a6736b 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Beta-19990317"
+#define DEF_MAIL_VERSION       "Snapshot-19990321"
 extern char *var_mail_version;
 
 /* LICENSE
index 487b63d30852e39005fd2d0a923b066b534890cc..a1436e0ca60077f0fad77cdd2b8a4e38a238e6db 100644 (file)
@@ -81,6 +81,8 @@ alias.o: local.h
 alias.o: ../include/been_here.h
 alias.o: ../include/tok822.h
 alias.o: ../include/resolve_clnt.h
+alias.o: ../include/deliver_request.h
+alias.o: ../include/recipient_list.h
 biff_notify.o: biff_notify.c
 biff_notify.o: ../include/sys_defs.h
 biff_notify.o: ../include/msg.h
@@ -103,6 +105,8 @@ command.o: ../include/mail_copy.h
 command.o: local.h
 command.o: ../include/tok822.h
 command.o: ../include/resolve_clnt.h
+command.o: ../include/deliver_request.h
+command.o: ../include/recipient_list.h
 deliver_attr.o: deliver_attr.c
 deliver_attr.o: ../include/sys_defs.h
 deliver_attr.o: ../include/msg.h
@@ -114,6 +118,8 @@ deliver_attr.o: ../include/vstring.h
 deliver_attr.o: ../include/been_here.h
 deliver_attr.o: ../include/tok822.h
 deliver_attr.o: ../include/resolve_clnt.h
+deliver_attr.o: ../include/deliver_request.h
+deliver_attr.o: ../include/recipient_list.h
 delivered.o: delivered.c
 delivered.o: ../include/sys_defs.h
 delivered.o: ../include/msg.h
@@ -132,6 +138,8 @@ delivered.o: local.h
 delivered.o: ../include/been_here.h
 delivered.o: ../include/tok822.h
 delivered.o: ../include/resolve_clnt.h
+delivered.o: ../include/deliver_request.h
+delivered.o: ../include/recipient_list.h
 dotforward.o: dotforward.c
 dotforward.o: ../include/sys_defs.h
 dotforward.o: ../include/msg.h
@@ -151,6 +159,8 @@ dotforward.o: ../include/mail_params.h
 dotforward.o: local.h
 dotforward.o: ../include/tok822.h
 dotforward.o: ../include/resolve_clnt.h
+dotforward.o: ../include/deliver_request.h
+dotforward.o: ../include/recipient_list.h
 feature.o: feature.c
 feature.o: ../include/sys_defs.h
 feature.o: ../include/msg.h
@@ -165,6 +175,8 @@ feature.o: ../include/vstring.h
 feature.o: ../include/been_here.h
 feature.o: ../include/tok822.h
 feature.o: ../include/resolve_clnt.h
+feature.o: ../include/deliver_request.h
+feature.o: ../include/recipient_list.h
 file.o: file.c
 file.o: ../include/sys_defs.h
 file.o: ../include/msg.h
@@ -183,6 +195,8 @@ file.o: ../include/mail_params.h
 file.o: local.h
 file.o: ../include/tok822.h
 file.o: ../include/resolve_clnt.h
+file.o: ../include/deliver_request.h
+file.o: ../include/recipient_list.h
 forward.o: forward.c
 forward.o: ../include/sys_defs.h
 forward.o: ../include/msg.h
@@ -208,6 +222,8 @@ forward.o: local.h
 forward.o: ../include/been_here.h
 forward.o: ../include/tok822.h
 forward.o: ../include/resolve_clnt.h
+forward.o: ../include/deliver_request.h
+forward.o: ../include/recipient_list.h
 include.o: include.c
 include.o: ../include/sys_defs.h
 include.o: ../include/msg.h
@@ -227,6 +243,8 @@ include.o: local.h
 include.o: ../include/vstring.h
 include.o: ../include/tok822.h
 include.o: ../include/resolve_clnt.h
+include.o: ../include/deliver_request.h
+include.o: ../include/recipient_list.h
 indirect.o: indirect.c
 indirect.o: ../include/sys_defs.h
 indirect.o: ../include/msg.h
@@ -241,6 +259,8 @@ indirect.o: ../include/vbuf.h
 indirect.o: ../include/vstring.h
 indirect.o: ../include/tok822.h
 indirect.o: ../include/resolve_clnt.h
+indirect.o: ../include/deliver_request.h
+indirect.o: ../include/recipient_list.h
 local.o: local.c
 local.o: ../include/sys_defs.h
 local.o: ../include/msg.h
@@ -283,9 +303,13 @@ mailbox.o: ../include/sent.h
 mailbox.o: ../include/mypwd.h
 mailbox.o: ../include/been_here.h
 mailbox.o: ../include/mail_params.h
+mailbox.o: ../include/mail_proto.h
+mailbox.o: ../include/iostuff.h
 mailbox.o: local.h
 mailbox.o: ../include/tok822.h
 mailbox.o: ../include/resolve_clnt.h
+mailbox.o: ../include/deliver_request.h
+mailbox.o: ../include/recipient_list.h
 mailbox.o: biff_notify.h
 maildir.o: maildir.c
 maildir.o: ../include/sys_defs.h
@@ -307,6 +331,8 @@ maildir.o: ../include/htable.h
 maildir.o: ../include/been_here.h
 maildir.o: ../include/tok822.h
 maildir.o: ../include/resolve_clnt.h
+maildir.o: ../include/deliver_request.h
+maildir.o: ../include/recipient_list.h
 recipient.o: recipient.c
 recipient.o: ../include/sys_defs.h
 recipient.o: ../include/msg.h
@@ -325,6 +351,8 @@ recipient.o: ../include/vstring.h
 recipient.o: ../include/been_here.h
 recipient.o: ../include/tok822.h
 recipient.o: ../include/resolve_clnt.h
+recipient.o: ../include/deliver_request.h
+recipient.o: ../include/recipient_list.h
 resolve.o: resolve.c
 resolve.o: ../include/sys_defs.h
 resolve.o: ../include/msg.h
@@ -340,6 +368,8 @@ resolve.o: ../include/tok822.h
 resolve.o: ../include/mail_params.h
 resolve.o: local.h
 resolve.o: ../include/been_here.h
+resolve.o: ../include/deliver_request.h
+resolve.o: ../include/recipient_list.h
 token.o: token.c
 token.o: ../include/sys_defs.h
 token.o: ../include/msg.h
@@ -355,6 +385,8 @@ token.o: ../include/resolve_clnt.h
 token.o: ../include/mail_params.h
 token.o: local.h
 token.o: ../include/been_here.h
+token.o: ../include/deliver_request.h
+token.o: ../include/recipient_list.h
 unknown.o: unknown.c
 unknown.o: ../include/sys_defs.h
 unknown.o: ../include/msg.h
@@ -362,11 +394,15 @@ unknown.o: ../include/stringops.h
 unknown.o: ../include/mymalloc.h
 unknown.o: ../include/been_here.h
 unknown.o: ../include/mail_params.h
+unknown.o: ../include/mail_proto.h
+unknown.o: ../include/vstream.h
+unknown.o: ../include/vbuf.h
+unknown.o: ../include/iostuff.h
 unknown.o: ../include/bounce.h
 unknown.o: local.h
 unknown.o: ../include/htable.h
-unknown.o: ../include/vstream.h
-unknown.o: ../include/vbuf.h
 unknown.o: ../include/vstring.h
 unknown.o: ../include/tok822.h
 unknown.o: ../include/resolve_clnt.h
+unknown.o: ../include/deliver_request.h
+unknown.o: ../include/recipient_list.h
index ee4a884888c469c7d362dc0ea713fc387575a470..3461d0bdc5fc1d17853f8d3e3cabae032549b76f 100644 (file)
@@ -126,7 +126,9 @@ typedef struct LOCAL_STATE {
 
 #define MSG_LOG_STATE(m, s) \
        msg_info("%s[%d]: local %s recip %s exten %s deliver %s", m, \
-                s.level, s.msg_attr.local, s.msg_attr.recipient, \
+                s.level, \
+               s.msg_attr.local ? s.msg_attr.local : "" , \
+               s.msg_attr.recipient ? s.msg_attr.recipient : "", \
                s.msg_attr.extension ? s.msg_attr.extension : "", \
                s.msg_attr.delivered ? s.msg_attr.delivered : "")
 
index 8456b72fdf030abf74d0807bb3b0d97393111412..17271b28b91480a0082a0d2652a216073ba52fdc 100644 (file)
@@ -105,7 +105,7 @@ static int deliver_switch(LOCAL_STATE state, USER_ATTR usr_attr)
      * \user is special: it means don't do any alias or forward expansion.
      */
     if (state.msg_attr.recipient[0] == '\\') {
-       state.msg_attr.recipient++;
+       state.msg_attr.recipient++, state.msg_attr.local++;
        if (*var_rcpt_delim)
            state.msg_attr.extension =
                split_addr(state.msg_attr.local, *var_rcpt_delim);
index dcf254d15670ef1df8795e2d4ef388a5efb7c768..f66a542eab49b2d9591da6cdd74f92122bad47ee 100644 (file)
@@ -225,6 +225,7 @@ single_server.o: ../include/stringops.h
 single_server.o: ../include/sane_accept.h
 single_server.o: ../include/myflock.h
 single_server.o: ../include/safe_open.h
+single_server.o: ../include/listen.h
 single_server.o: ../include/mail_params.h
 single_server.o: ../include/mail_task.h
 single_server.o: ../include/debug_process.h
@@ -249,6 +250,7 @@ trigger_server.o: ../include/stringops.h
 trigger_server.o: ../include/sane_accept.h
 trigger_server.o: ../include/myflock.h
 trigger_server.o: ../include/safe_open.h
+trigger_server.o: ../include/listen.h
 trigger_server.o: ../include/mail_params.h
 trigger_server.o: ../include/mail_task.h
 trigger_server.o: ../include/debug_process.h
index 2f78b3d1c3ed57f9718de44fad9eb1ede4698ce6..2343e3ae51e7a4e26a61f20885fccaaef760ceb8 100644 (file)
 
 #include "master.h"
 
+/* master_watchdog - something got stuck */
+
+static NORETURN master_watchdog(int unused_sig)
+{
+
+    /*
+     * This runs as a signal handler. We should not do anything that could
+     * involve memory managent, but exiting without explanation would be
+     * worse.
+     */
+    msg_fatal("watchdog timer");
+}
+
 int     main(int argc, char **argv)
 {
     static VSTREAM *lock_fp;
@@ -316,7 +329,9 @@ int     main(int argc, char **argv)
      * multiple things at the same time, it really is all a single thread, so
      * that there are no concurrency conflicts within the master process.
      */
+    signal(SIGALRM, master_watchdog);
     for (;;) {
+       alarm(1000);                            /* same as trigger servers */
        event_loop(-1);
        if (master_gotsighup) {
            msg_info("reload configuration");
index 14b8ed5f48b0b9cc27a931e60f2bdf7eb24682a9..d7020ac42ab30f6791a21a6e3f60ef69c06506af 100644 (file)
@@ -80,13 +80,13 @@ void    master_listen_init(MASTER_SERV *serv)
     switch (serv->type) {
 
        /*
-        * UNIX-domain listener endpoints always come as singlets.
+        * UNIX-domain or stream listener endpoints always come as singlets.
         */
     case MASTER_SERV_TYPE_UNIX:
        set_eugid(var_owner_uid, var_owner_gid);
        serv->listen_fd[0] =
-           unix_listen(serv->name, serv->max_proc > var_proc_limit ?
-                       serv->max_proc : var_proc_limit, NON_BLOCKING);
+           LOCAL_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
+                        serv->max_proc : var_proc_limit, NON_BLOCKING);
        close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
        set_eugid(getuid(), getgid());
        break;
index 7070d84d6b5fca022fe9806ea18eddcec8b6ee3c..c0f9edf7c3a70c648a8620d1c24d230cb5fc6bb1 100644 (file)
@@ -99,7 +99,7 @@ static void master_wakeup_timer_event(int unused_event, char *context)
            status = inet_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
            break;
        case MASTER_SERV_TYPE_UNIX:
-           status = unix_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
+           status = LOCAL_TRIGGER(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
            break;
        case MASTER_SERV_TYPE_FIFO:
            status = fifo_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
index a3d04b48ea18307aecf9fc81cd74ce11f258f6b7..4fcad413ce4ec3888a6366a23905579a502211ec 100644 (file)
 #include <myflock.h>
 #include <safe_open.h>
 #endif
+#include <listen.h>
 
 /* Global library. */
 
@@ -164,6 +165,7 @@ static int use_count;
 static void (*multi_server_service) (VSTREAM *, char *, char **);
 static char *multi_server_name;
 static char **multi_server_argv;
+static void (*multi_server_accept) (int, char *);
 static void (*multi_server_onexit) (void);
 
 #ifndef NO_SELECT_COLLISION
@@ -180,6 +182,19 @@ static NORETURN multi_server_exit(void)
     exit(0);
 }
 
+/* multi_server_watchdog - something got stuck */
+
+static NORETURN multi_server_watchdog(int unused_sig)
+{
+
+    /*
+     * This runs as a signal handler. We should not do anything that could
+     * involve memory managent, but exiting without explanation would be
+     * worse.
+     */
+    msg_fatal("watchdog timer");
+}
+
 /* multi_server_abort - terminate after abnormal master exit */
 
 static void multi_server_abort(int unused_event, char *unused_context)
@@ -234,20 +249,76 @@ static void multi_server_execute(int unused_event, char *context)
        event_request_timer(multi_server_timeout, (char *) 0, var_idle_limit);
 }
 
-/* multi_server_accept - accept client connection request */
+/* multi_server_wakeup - wake up application */
+
+static void multi_server_wakeup(int fd)
+{
+    VSTREAM *stream;
+
+    if (msg_verbose)
+       msg_info("connection established fd %d", fd);
+    non_blocking(fd, BLOCKING);
+    close_on_exec(fd, CLOSE_ON_EXEC);
+    client_count++;
+    stream = vstream_fdopen(fd, O_RDWR);
+    timed_ipc_setup(stream);
+    event_enable_read(fd, multi_server_execute, (char *) stream);
+}
+
+/* multi_server_accept_local - accept client connection request */
 
-static void multi_server_accept(int unused_event, char *context)
+static void multi_server_accept_local(int unused_event, char *context)
 {
     int     listen_fd = (int) context;
     int     time_left = -1;
     int     fd;
-    VSTREAM *stream;
 
+    /*
+     * Some buggy systems cause Postfix to lock up.
+     */
+    signal(SIGALRM, multi_server_watchdog);
+    alarm(var_daemon_timeout);
+
+    /*
+     * Be prepared for accept() to fail because some other process already
+     * got the connection (the number of processes competing for clients is
+     * kept small, so this is not a "thundering herd" problem). If the
+     * accept() succeeds, be sure to disable non-blocking I/O, in order to
+     * minimize confusion.
+     */
+    if (client_count == 0 && var_idle_limit > 0)
+       time_left = event_cancel_timer(multi_server_timeout, (char *) 0);
+
+    fd = LOCAL_ACCEPT(listen_fd);
 #ifndef NO_SELECT_COLLISION
     if (multi_server_lock != 0
        && myflock(vstream_fileno(multi_server_lock), MYFLOCK_NONE) < 0)
        msg_fatal("select unlock: %m");
 #endif
+    if (fd < 0) {
+       if (errno != EAGAIN)
+           msg_fatal("accept connection: %m");
+       if (time_left >= 0)
+           event_request_timer(multi_server_timeout, (char *) 0, time_left);
+       return;
+    }
+    multi_server_wakeup(fd);
+}
+
+/* multi_server_accept_inet - accept client connection request */
+
+static void multi_server_accept_inet(int unused_event, char *context)
+{
+    int     listen_fd = (int) context;
+    int     time_left = -1;
+    int     fd;
+    VSTREAM *stream;
+
+    /*
+     * Some buggy systems cause Postfix to lock up.
+     */
+    signal(SIGALRM, multi_server_watchdog);
+    alarm(var_daemon_timeout);
 
     /*
      * Be prepared for accept() to fail because some other process already
@@ -258,21 +329,21 @@ static void multi_server_accept(int unused_event, char *context)
      */
     if (client_count == 0 && var_idle_limit > 0)
        time_left = event_cancel_timer(multi_server_timeout, (char *) 0);
-    if ((fd = sane_accept(listen_fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0)) < 0) {
+
+    fd = inet_accept(listen_fd);
+#ifndef NO_SELECT_COLLISION
+    if (multi_server_lock != 0
+       && myflock(vstream_fileno(multi_server_lock), MYFLOCK_NONE) < 0)
+       msg_fatal("select unlock: %m");
+#endif
+    if (fd < 0) {
        if (errno != EAGAIN)
            msg_fatal("accept connection: %m");
        if (time_left >= 0)
            event_request_timer(multi_server_timeout, (char *) 0, time_left);
        return;
     }
-    if (msg_verbose)
-       msg_info("connection established fd %d", fd);
-    non_blocking(fd, BLOCKING);
-    close_on_exec(fd, CLOSE_ON_EXEC);
-    client_count++;
-    stream = vstream_fdopen(fd, O_RDWR);
-    timed_ipc_setup(stream);
-    event_enable_read(fd, multi_server_execute, (char *) stream);
+    multi_server_wakeup(fd);
 }
 
 /* multi_server_main - the real main program */
@@ -428,8 +499,11 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
     if (stream == 0) {
        if (transport == 0)
            msg_fatal("no transport type specified");
-       if (strcasecmp(transport, MASTER_XPORT_NAME_INET) != 0
-           && strcasecmp(transport, MASTER_XPORT_NAME_UNIX) != 0)
+       if (strcasecmp(transport, MASTER_XPORT_NAME_INET) == 0)
+           multi_server_accept = multi_server_accept_inet;
+       else if (strcasecmp(transport, MASTER_XPORT_NAME_UNIX) == 0)
+           multi_server_accept = multi_server_accept_local;
+       else
            msg_fatal("unsupported transport type: %s", transport);
     }
 
index 4976ae02cf1b3f38f096f4fb6f4a63f36ad47a40..eca04871d41716177f437144a9ab5d186c6fbfec 100644 (file)
 #include <myflock.h>
 #include <safe_open.h>
 #endif
+#include <listen.h>
 
 /* Global library. */
 
@@ -154,6 +155,7 @@ static int use_count;
 static void (*single_server_service) (VSTREAM *, char *, char **);
 static char *single_server_name;
 static char **single_server_argv;
+static void (*single_server_accept) (int, char *);
 static void (*single_server_onexit) (void);
 
 #ifndef NO_SELECT_COLLISION
@@ -170,6 +172,19 @@ static NORETURN single_server_exit(void)
     exit(0);
 }
 
+/* single_server_watchdog - something got stuck */
+
+static NORETURN single_server_watchdog(int unused_sig)
+{
+
+    /*
+     * This runs as a signal handler. We should not do anything that could
+     * involve memory managent, but exiting without explanation would be
+     * worse.
+     */
+    msg_fatal("watchdog timer");
+}
+
 /* single_server_abort - terminate after abnormal master exit */
 
 static void single_server_abort(int unused_event, char *unused_context)
@@ -188,37 +203,11 @@ static void single_server_timeout(int unused_event, char *unused_context)
     single_server_exit();
 }
 
-/* single_server_accept - accept client connection request */
+/* single_server_wakeup - wake up application */
 
-static void single_server_accept(int unused_event, char *context)
+static void single_server_wakeup(int fd)
 {
-    int     listen_fd = (int) context;
     VSTREAM *stream;
-    int     time_left = -1;
-    int     fd;
-
-#ifndef NO_SELECT_COLLISION
-    if (single_server_lock != 0
-       && myflock(vstream_fileno(single_server_lock), MYFLOCK_NONE) < 0)
-       msg_fatal("select unlock: %m");
-#endif
-
-    /*
-     * Be prepared for accept() to fail because some other process already
-     * got the connection. We use select() + accept(), instead of simply
-     * blocking in accept(), because we must be able to detect that the
-     * master process has gone away unexpectedly.
-     */
-    if (var_idle_limit > 0)
-       time_left = event_cancel_timer(single_server_timeout, (char *) 0);
-
-    if ((fd = sane_accept(listen_fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0)) < 0) {
-       if (errno != EAGAIN)
-           msg_fatal("accept connection: %m");
-       if (time_left >= 0)
-           event_request_timer(single_server_timeout, (char *) 0, time_left);
-       return;
-    }
 
     /*
      * If the accept() succeeds, be sure to disable non-blocking I/O, because
@@ -245,6 +234,84 @@ static void single_server_accept(int unused_event, char *context)
        event_request_timer(single_server_timeout, (char *) 0, var_idle_limit);
 }
 
+/* single_server_accept_local - accept client connection request */
+
+static void single_server_accept_local(int unused_event, char *context)
+{
+    int     listen_fd = (int) context;
+    int     time_left = -1;
+    int     fd;
+
+    /*
+     * Some buggy systems cause Postfix to lock up.
+     */
+    signal(SIGALRM, single_server_watchdog);
+    alarm(var_daemon_timeout);
+
+    /*
+     * Be prepared for accept() to fail because some other process already
+     * got the connection. We use select() + accept(), instead of simply
+     * blocking in accept(), because we must be able to detect that the
+     * master process has gone away unexpectedly.
+     */
+    if (var_idle_limit > 0)
+       time_left = event_cancel_timer(single_server_timeout, (char *) 0);
+
+    fd = LOCAL_ACCEPT(listen_fd);
+#ifndef NO_SELECT_COLLISION
+    if (single_server_lock != 0
+       && myflock(vstream_fileno(single_server_lock), MYFLOCK_NONE) < 0)
+       msg_fatal("select unlock: %m");
+#endif
+    if (fd < 0) {
+       if (errno != EAGAIN)
+           msg_fatal("accept connection: %m");
+       if (time_left >= 0)
+           event_request_timer(single_server_timeout, (char *) 0, time_left);
+       return;
+    }
+    single_server_wakeup(fd);
+}
+
+/* single_server_accept_inet - accept client connection request */
+
+static void single_server_accept_inet(int unused_event, char *context)
+{
+    int     listen_fd = (int) context;
+    int     time_left = -1;
+    int     fd;
+
+    /*
+     * Some buggy systems cause Postfix to lock up.
+     */
+    signal(SIGALRM, single_server_watchdog);
+    alarm(var_daemon_timeout);
+
+    /*
+     * Be prepared for accept() to fail because some other process already
+     * got the connection. We use select() + accept(), instead of simply
+     * blocking in accept(), because we must be able to detect that the
+     * master process has gone away unexpectedly.
+     */
+    if (var_idle_limit > 0)
+       time_left = event_cancel_timer(single_server_timeout, (char *) 0);
+
+    fd = inet_accept(listen_fd);
+#ifndef NO_SELECT_COLLISION
+    if (single_server_lock != 0
+       && myflock(vstream_fileno(single_server_lock), MYFLOCK_NONE) < 0)
+       msg_fatal("select unlock: %m");
+#endif
+    if (fd < 0) {
+       if (errno != EAGAIN)
+           msg_fatal("accept connection: %m");
+       if (time_left >= 0)
+           event_request_timer(single_server_timeout, (char *) 0, time_left);
+       return;
+    }
+    single_server_wakeup(fd);
+}
+
 /* single_server_main - the real main program */
 
 NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
@@ -398,8 +465,11 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
     if (stream == 0) {
        if (transport == 0)
            msg_fatal("no transport type specified");
-       if (strcasecmp(transport, MASTER_XPORT_NAME_INET) != 0
-           && strcasecmp(transport, MASTER_XPORT_NAME_UNIX) != 0)
+       if (strcasecmp(transport, MASTER_XPORT_NAME_INET) == 0)
+           single_server_accept = single_server_accept_inet;
+       else if (strcasecmp(transport, MASTER_XPORT_NAME_UNIX) == 0)
+           single_server_accept = single_server_accept_local;
+       else
            msg_fatal("unsupported transport type: %s", transport);
     }
 
index 651adac313bb133c1b427103f917f637a8921eaa..261a9dabc512b9d79075fc74d03d44e8f5c54419 100644 (file)
 #include <myflock.h>
 #include <safe_open.h>
 #endif
+#include <listen.h>
 
 /* Global library. */
 
@@ -231,7 +232,7 @@ static void trigger_server_wakeup(int fd)
     use_count++;
 }
 
-/* trigger_server_accept_fifo - accept socket client request */
+/* trigger_server_accept_fifo - accept fifo client request */
 
 static void trigger_server_accept_fifo(int unused_event, char *context)
 {
@@ -260,20 +261,15 @@ static void trigger_server_accept_fifo(int unused_event, char *context)
     trigger_server_wakeup(listen_fd);
 }
 
-/* trigger_server_accept_socket - accept socket client request */
+/* trigger_server_accept_local - accept socket client request */
 
-static void trigger_server_accept_socket(int unused_event, char *context)
+static void trigger_server_accept_local(int unused_event, char *context)
 {
-    char   *myname = "trigger_server_accept_socket";
+    char   *myname = "trigger_server_accept_local";
     int     listen_fd = (int) context;
     int     time_left = 0;
     int     fd;
 
-#ifndef NO_SELECT_COLLISION
-    if (trigger_server_lock != 0
-       && myflock(vstream_fileno(trigger_server_lock), MYFLOCK_NONE) < 0)
-       msg_fatal("select unlock: %m");
-#endif
 
     if (msg_verbose)
        msg_info("%s: trigger arrived", myname);
@@ -281,6 +277,7 @@ static void trigger_server_accept_socket(int unused_event, char *context)
     /*
      * Some buggy systems cause Postfix to lock up.
      */
+    signal(SIGALRM, trigger_server_watchdog);
     alarm(1000);
 
     /*
@@ -292,7 +289,14 @@ static void trigger_server_accept_socket(int unused_event, char *context)
      */
     if (var_idle_limit > 0)
        time_left = event_cancel_timer(trigger_server_timeout, (char *) 0);
-    if ((fd = sane_accept(listen_fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0)) < 0) {
+
+    fd = LOCAL_ACCEPT(listen_fd);
+#ifndef NO_SELECT_COLLISION
+    if (trigger_server_lock != 0
+       && myflock(vstream_fileno(trigger_server_lock), MYFLOCK_NONE) < 0)
+       msg_fatal("select unlock: %m");
+#endif
+    if (fd < 0) {
        if (errno != EAGAIN)
            msg_fatal("accept connection: %m");
        if (time_left >= 0)
@@ -469,14 +473,15 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
      * problems, witness the workarounds in the fifo_listen() routine.
      * Therefore we support both FIFOs and UNIX-domain sockets, so that the
      * user can choose whatever works best.
+     * 
+     * Well, I give up. Solaris UNIX-domain sockets still don't work properly,
+     * so it will have to limp along with a streams-specific alternative.
      */
     if (stream == 0) {
        if (transport == 0)
            msg_fatal("no transport type specified");
-       if (strcasecmp(transport, MASTER_XPORT_NAME_INET) == 0)
-           trigger_server_accept = trigger_server_accept_socket;
        if (strcasecmp(transport, MASTER_XPORT_NAME_UNIX) == 0)
-           trigger_server_accept = trigger_server_accept_socket;
+           trigger_server_accept = trigger_server_accept_local;
        else if (strcasecmp(transport, MASTER_XPORT_NAME_FIFO) == 0)
            trigger_server_accept = trigger_server_accept_fifo;
        else
index fcb0c1c7bc6e37cb23ad2a3f20cd215603ff3892..1edbf8c3b4f74a16994d9d8dd1a5f5ccca48e3d6 100644 (file)
@@ -53,7 +53,6 @@ depend: $(MAKES)
        @make -f Makefile.in Makefile
 
 # do not edit below this line - it is generated by 'make depend'
-cleanup_extra.o: cleanup_extra.c
 pickup.o: pickup.c
 pickup.o: ../include/sys_defs.h
 pickup.o: ../include/msg.h
index 83c28cfb349ca98463047ec9fa8a9a02ba800f25..7c3e6a9d4eb8550e9469d23b421038d355145c69 100644 (file)
@@ -282,10 +282,12 @@ int     main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open before opening anything else.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index 0f77e54212b7f307e70735ee5498e6ba34fce9f5..c86e3f6224d56f46dae7d6321835b0dcd95a3941 100644 (file)
@@ -146,10 +146,12 @@ int     main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open before opening anything else.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index cbf755dc76d77dc3f4ecd8d28a3312b25b4c5193..9cee72ab8015ec38482406582138d8e3aeb67619 100644 (file)
@@ -450,10 +450,12 @@ int     main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open before opening anything else.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index d2267db61aa1d555b87bb9e49d23987890b1b391..3dffaf04d3a556501df75093a82920e034c78a7d 100644 (file)
@@ -161,10 +161,12 @@ int     main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open before opening anything else.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index a6e469bf062ec1bd70c318a0c931fc904c92cfd2..d88f6e4d86e62defb8a60e001f4939fced33b94e 100644 (file)
@@ -147,10 +147,12 @@ int     main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index f6ad75a54fc8a3b51588fb5b3046c829c4ebafb1..044a0839005c0469bf861ce528b774e1be966dfb 100644 (file)
@@ -104,10 +104,12 @@ int     main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open before opening anything else.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index c908791192f4b13f77b962643be8f4bb8de6757a..558f8f78005c4fd5ee8a486d71b79c1d296472ed 100644 (file)
@@ -5,7 +5,7 @@
 /*     lock mail folder and execute command
 /* SYNOPSIS
 /* .fi
-/*     \fBpostlock\fR [\fB-c \fIconfig_dir\fB] [\fB-v\fR] 
+/*     \fBpostlock\fR [\fB-c \fIconfig_dir\fB] [\fB-v\fR]
 /*             \fIfile command...\fR
 /* DESCRIPTION
 /*     The \fBpostlock\fR command locks \fIfile\fR for exclusive
 /*
 /*     Options:
 /* .IP "\fB-c \fIconfig_dir\fR"
-/*     Read configuration information from \fBmain.cf\fR in the named 
+/*     Read configuration information from \fBmain.cf\fR in the named
 /*     configuration directory.
 /* .IP \fB-v\fR
-/*     Enable verbose mode for debugging purposes. Multiple \fB-v\fR 
+/*     Enable verbose mode for debugging purposes. Multiple \fB-v\fR
 /*     options make the software increasingly verbose.
 /* .PP
 /*     Arguments:
 /* .IP \fIfile\fR
 /*     A mailbox file. The user should have read/write permission.
 /* .IP \fIcommand...\fR
-/*     The command to execute while \fIfile\fR is locked for exclusive 
+/*     The command to execute while \fIfile\fR is locked for exclusive
 /*     access.  The command is executed directly, i.e. without
 /*     interpretation by a shell command interpreter.
 /* DIAGNOSTICS
@@ -50,7 +50,7 @@
 /*      and for default values.
 /* .SH "Locking controls"
 /* .ad
-/* .fi 
+/* .fi
 /* .IP \fBdeliver_lock_attempts\fR
 /*     Limit the number of attempts to acquire an exclusive lock.
 /* .IP \fBdeliver_lock_delay\fR
@@ -137,10 +137,12 @@ int     main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open before opening anything else.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index 2ae1551f7800f4fcd2f06274c693a0767bf1e25e..ece9daf509fdf48ea3045aa06f9d6005738f06dc 100644 (file)
@@ -29,7 +29,7 @@
 /*     Specifies the logging tag, that is, the identifying name that
 /*     appears at the beginning of each logging record.
 /* .IP \fB-v\fR
-/*     Enable verbose logging for debugging purposes. Multiple \fB-v\fR 
+/*     Enable verbose logging for debugging purposes. Multiple \fB-v\fR
 /*     options make the software increasingly verbose.
 /* SEE ALSO
 /*     syslogd(8) syslog daemon.
@@ -151,10 +151,12 @@ int     main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index 1ace8e16b24a61e6fd535d391ea89f7bf6974dff..9cd698ebc9cd159e11f714f0247cb35cd2ac4ca1 100644 (file)
@@ -247,10 +247,12 @@ int     main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open before opening anything else.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index 5d575cee1a5ff3a44fa4f4f0bdf2b13cec70e54b..9ebd498cd9b142611b8736cf4463493c5de3e21e 100644 (file)
@@ -297,10 +297,12 @@ main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open before opening anything else.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index 8aefffceb33653b44aba0418304371762fb6932f..1ff2f350e1f372382afca72c6d7c80e451ccbe9c 100644 (file)
@@ -290,5 +290,5 @@ void    qmgr_deliver(QMGR_TRANSPORT *transport, VSTREAM *stream)
     /*
      * Guard against broken systems.
      */
-    event_request_timer(qmgr_deliver_abort, (char *) entry, var_ipc_timeout);
+    event_request_timer(qmgr_deliver_abort, (char *) entry, var_daemon_timeout);
 }
index cf3a0d6c8c095ae687bb4989d767e7bfb14666dd..fcaa95c398eb50471b79e9bd9e890f7b0447eb4e 100644 (file)
@@ -299,7 +299,8 @@ void    qmgr_transport_alloc(QMGR_TRANSPORT *transport, QMGR_TRANSPORT_ALLOC_NOT
     /*
      * Guard against broken systems.
      */
-    event_request_timer(qmgr_transport_abort, (char *) alloc, var_ipc_timeout);
+    event_request_timer(qmgr_transport_abort, (char *) alloc,
+                       var_daemon_timeout);
 }
 
 /* qmgr_transport_create - create transport instance */
index 6c1535aaed0eec6eec9f3c2fdeddf87490533de3..33736e36fb39e51bf5a2ce881699fc244740ed3c 100644 (file)
@@ -564,10 +564,12 @@ int     main(int argc, char **argv)
 
     /*
      * To minimize confusion, make sure that the standard file descriptors
-     * are open before opening anything else.
+     * are open before opening anything else. XXX Work around for 44BSD where
+     * fstat can return EBADF on an open file descriptor.
      */
     for (fd = 0; fd < 3; fd++)
-       if (fstat(fd, &st) == -1 && open("/dev/null", 2) != fd)
+       if (fstat(fd, &st) == -1
+           && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
            msg_fatal("open /dev/null: %m");
 
     /*
index c7e8eb6af720b252acfbb7bac0ceac8c6c5c30f0..d96d099205bed129a423231d77bc789ff67736a3 100644 (file)
@@ -78,9 +78,10 @@ smtp-sink.o: ../include/smtp_stream.h
 smtp-source.o: smtp-source.c
 smtp-source.o: ../include/sys_defs.h
 smtp-source.o: ../include/msg.h
-smtp-source.o: ../include/vstring.h
-smtp-source.o: ../include/vbuf.h
+smtp-source.o: ../include/msg_vstream.h
 smtp-source.o: ../include/vstream.h
+smtp-source.o: ../include/vbuf.h
+smtp-source.o: ../include/vstring.h
 smtp-source.o: ../include/vstring_vstream.h
 smtp-source.o: ../include/get_hostname.h
 smtp-source.o: ../include/split_at.h
index 04c65102ef2e4ac4c8adc36b060985f8b06879b2..0c332472c43201ea2af9503ba81b56ebd5c26213 100644 (file)
@@ -18,7 +18,8 @@ SRCS  = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \
        translit.c trimblanks.c unix_connect.c unix_listen.c unix_trigger.c \
        unsafe.c username.c valid_hostname.c vbuf.c vbuf_print.c \
        vstream.c vstream_popen.c vstring.c vstring_vstream.c writable.c \
-       write_buf.c write_wait.c dict_unix.c dict_pcre.c
+       write_buf.c write_wait.c dict_unix.c dict_pcre.c stream_listen.c \
+       stream_connect.c stream_trigger.c
 OBJS   = argv.o argv_split.o attr.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_ni.o dict_nis.o \
@@ -38,7 +39,8 @@ OBJS  = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
        translit.o trimblanks.o unix_connect.o unix_listen.o unix_trigger.o \
        unsafe.o username.o valid_hostname.o vbuf.o vbuf_print.o \
        vstream.o vstream_popen.o vstring.o vstring_vstream.o writable.o \
-       write_buf.o write_wait.o dict_unix.o dict_pcre.o
+       write_buf.o write_wait.o dict_unix.o dict_pcre.o stream_listen.o \
+       stream_connect.o stream_trigger.o
 HDRS   = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
        dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_ni.h dict_nis.h \
        dict_nisplus.h dir_forest.h events.h exec_command.h find_inet.h \
@@ -478,6 +480,7 @@ inet_listen.o: find_inet.h
 inet_listen.o: inet_util.h
 inet_listen.o: iostuff.h
 inet_listen.o: listen.h
+inet_listen.o: sane_accept.h
 inet_trigger.o: inet_trigger.c
 inet_trigger.o: sys_defs.h
 inet_trigger.o: msg.h
@@ -661,6 +664,15 @@ select_bug.o: msg.h
 select_bug.o: vstream.h
 select_bug.o: vbuf.h
 select_bug.o: msg_vstream.h
+sendfd_test.o: sendfd_test.c
+sendfd_test.o: sys_defs.h
+sendfd_test.o: sendfd_test.c
+sendfd_test.o: iostuff.h
+sendfd_test.o: msg.h
+sendfd_test.o: msg_vstream.h
+sendfd_test.o: vstream.h
+sendfd_test.o: vbuf.h
+sendfd_test.o: listen.h
 set_eugid.o: set_eugid.c
 set_eugid.o: sys_defs.h
 set_eugid.o: msg.h
@@ -685,6 +697,22 @@ stat_as.o: sys_defs.h
 stat_as.o: msg.h
 stat_as.o: set_eugid.h
 stat_as.o: stat_as.h
+stream_connect.o: stream_connect.c
+stream_connect.o: sys_defs.h
+stream_connect.o: msg.h
+stream_connect.o: connect.h
+stream_connect.o: iostuff.h
+stream_listen.o: stream_listen.c
+stream_listen.o: sys_defs.h
+stream_listen.o: msg.h
+stream_listen.o: listen.h
+stream_listen.o: iostuff.h
+stream_trigger.o: stream_trigger.c
+stream_trigger.o: sys_defs.h
+stream_trigger.o: msg.h
+stream_trigger.o: connect.h
+stream_trigger.o: iostuff.h
+stream_trigger.o: trigger.h
 sys_compat.o: sys_compat.c
 sys_compat.o: sys_defs.h
 timed_connect.o: timed_connect.c
@@ -714,6 +742,7 @@ unix_listen.o: sys_defs.h
 unix_listen.o: msg.h
 unix_listen.o: iostuff.h
 unix_listen.o: listen.h
+unix_listen.o: sane_accept.h
 unix_trigger.o: unix_trigger.c
 unix_trigger.o: sys_defs.h
 unix_trigger.o: msg.h
index 5fc5e0413486080934550cc37c14a1e0d6ba7309..080b99c064a37826cb6ada39bb5ea36479889da8 100644 (file)
@@ -21,6 +21,7 @@
   */
 extern int unix_connect(const char *, int, int);
 extern int inet_connect(const char *, int, int);
+extern int stream_connect(const char *, int, int);
 
 /* LICENSE
 /* .ad
index 81e3d2a12ed7388cfb6cd48bc89ff0b0930277b3..91347c95ab44bbf06a98a4401edbba48858cc711 100644 (file)
 /*     const char *addr;
 /*     int     backlog;
 /*     int     block_mode;
+/*
+/*     int     inet_accept(fd)
+/*     int     fd;
 /* DESCRIPTION
 /*     The \fBinet_listen\fR routine starts a listener in the INET domain
 /*     on the specified address, with the specified backlog, and returns
 /*     the resulting file descriptor.
 /*
+/*     inet_accept() accepts a connection and sanitizes error results.
+/*
 /*     Arguments:
 /* .IP addr
 /*     The communication endpoint to listen on. The syntax is "host:port".
 /* .IP block_mode
 /*     Either NON_BLOCKING for a non-blocking socket, or BLOCKING for
 /*     blocking mode.
+/* .IP fd
+/*     File descriptor returned by inet_listen().
 /* DIAGNOSTICS
-/*     Fatal errors: all errors are fatal.
+/*     Fatal errors: inet_listen() aborts upon any system call failure.
+/*     inet_accept() leaves all error handling up to the caller.
 /* LICENSE
 /* .ad
 /* .fi
@@ -59,6 +67,7 @@
 #include "inet_util.h"
 #include "iostuff.h"
 #include "listen.h"
+#include "sane_accept.h"
 
 /* Application-specific stuff. */
 
@@ -102,3 +111,10 @@ int     inet_listen(const char *addr, int backlog, int block_mode)
        msg_fatal("listen: %m");
     return (sock);
 }
+
+/* inet_accept - accept connection */
+
+int     inet_accept(int fd)
+{
+    return (sane_accept(fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0));
+}
index 7cd873e0dea60ea1bb960713e778d2dca364bd2b..81c5389c0e6c66d2464dd8329e333c420be2fc8c 100644 (file)
 extern int unix_listen(const char *, int, int);
 extern int inet_listen(const char *, int, int);
 extern int fifo_listen(const char *, int, int);
+extern int stream_listen(const char *, int, int);
+
+extern int inet_accept(int);
+extern int unix_accept(int);
+extern int stream_accept(int);
 
 /* LICENSE
 /* .ad
index b1e2a53093a9254044510fd3435d302c5814a231..d9d8464d0adf6fd41a6cf04799c13f338ad29f67 100644 (file)
@@ -9,7 +9,7 @@
 /*     int     sane_accept(sock, buf, len)
 /*     int     sock;
 /*     struct sockaddr *buf;
-/*     int     len;
+/*     SOCKADDR_SIZE *len;
 /* DESCRIPTION
 /*     sane_accept() implements the accept(2) socket call, and maps
 /*     known harmless error results to EAGAIN.
diff --git a/postfix/util/sendfd_test b/postfix/util/sendfd_test
new file mode 100755 (executable)
index 0000000..2090064
Binary files /dev/null and b/postfix/util/sendfd_test differ
diff --git a/postfix/util/sendfd_test.c b/postfix/util/sendfd_test.c
new file mode 100644 (file)
index 0000000..d7b1481
--- /dev/null
@@ -0,0 +1,105 @@
+#include "sys_defs.h"
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stropts.h>
+#include "iostuff.h"
+
+#include "msg.h"
+#include "msg_vstream.h"
+#include "listen.h"
+
+#define FIFO   "/tmp/test-fifo"
+
+static const char *progname;
+
+static  print_fstat(int fd)
+{
+    struct stat st;
+
+    if (fstat(fd, &st) < 0)
+       msg_fatal("fstat: %m");
+    vstream_printf("fd %d\n", fd);
+    vstream_printf("dev        %d\n", st.st_dev);
+    vstream_printf("ino        %d\n", st.st_ino);
+    vstream_fflush(VSTREAM_OUT);
+}
+
+static NORETURN usage(void)
+{
+    msg_fatal("usage: %s [-p] [-n count] [-v]", progname);
+}
+
+main(int argc, char **argv)
+{
+    struct strrecvfd fdinfo;
+    int     server_fd;
+    int     client_fd;
+    int     print_fstats = 0;
+    int     count = 1;
+    int     ch;
+    int     i;
+
+    progname = argv[0];
+    msg_vstream_init(argv[0], VSTREAM_ERR);
+
+    /*
+     * Parse JCL.
+     */
+    while ((ch = GETOPT(argc, argv, "pn:v")) > 0) {
+       switch (ch) {
+       default:
+           usage();
+       case 'p':
+           print_fstats = 1;
+           break;
+       case 'n':
+           if ((count = atoi(optarg)) < 1)
+               usage();
+           break;
+       case 'v':
+           msg_verbose++;
+           break;
+       }
+    }
+    server_fd = fifo_listen(FIFO, 0600, NON_BLOCKING);
+    if (readable(server_fd))
+       msg_fatal("server fd is readable after create");
+
+    /*
+     * Connect in client.
+     */
+    if ((client_fd = open(FIFO, O_RDWR, NON_BLOCKING)) < 0)
+       msg_fatal("open %s as client: %m", FIFO);
+    if (readable(server_fd))
+       msg_warn("server fd is readable after client open");
+    if (print_fstats)
+       print_fstat(0);
+       if (ioctl(client_fd, I_RECVFD, &fdinfo) < 0)
+           msg_fatal("receive fd: %m");
+    for (i = 0; i < count; i++) {
+       msg_info("send attempt %d", i);
+       while (!writable(client_fd))
+           msg_info("wait for client fd to become writable");
+       if (ioctl(client_fd, I_SENDFD, 0) < 0)
+           msg_fatal("send fd to server: %m");
+    }
+    if (close(client_fd) < 0)
+       msg_fatal("close client fd: %m");
+
+    /*
+     * Accept in server.
+     */
+    for (i = 0; i < count; i++) {
+       msg_info("receive attempt %d", i);
+       while (!readable(server_fd))
+           msg_info("wait for server fd to become writable");
+       if (ioctl(server_fd, I_RECVFD, &fdinfo) < 0)
+           msg_fatal("receive fd: %m");
+       if (print_fstats)
+           print_fstat(fdinfo.fd);
+       if (close(fdinfo.fd) < 0)
+           msg_fatal("close received fd: %m");
+    }
+}
diff --git a/postfix/util/stream_connect.c b/postfix/util/stream_connect.c
new file mode 100644 (file)
index 0000000..f15dea5
--- /dev/null
@@ -0,0 +1,102 @@
+/*++
+/* NAME
+/*     stream_connect 3
+/* SUMMARY
+/*     connect to stream listener
+/* SYNOPSIS
+/*     #include <connect.h>
+/*
+/*     int     stream_connect(path, block_mode, timeout)
+/*     const char *path;
+/*     int     block_mode;
+/*     int     timeout;
+/* DESCRIPTION
+/*     stream_connect() connects to a stream listener for the specified
+/*     pathname, and returns the resulting file descriptor.
+/*
+/*     Arguments:
+/* .IP path
+/*     Null-terminated string with listener endpoint name.
+/* .IP block_mode
+/*     Either NON_BLOCKING for a non-blocking stream, or BLOCKING for
+/*     blocking mode. However, a stream connection succeeds or fails
+/*     immediately.
+/* .IP timeout
+/*     This argument is ignored; it is present for compatibility with
+/*     other interfaces. Stream connections succeed or fail immediately.
+/* DIAGNOSTICS
+/*     The result is -1 in case the connection could not be made.
+/*     Fatal errors: other system call failures.
+/* 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 <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <connect.h>
+
+/* stream_connect - connect to stream listener */
+
+int     stream_connect(const char *path, int block_mode, int unused_timeout)
+{
+#ifdef STREAM_CONNECTIONS
+    char   *myname = "stream_connect";
+    struct stat st;
+    int     fd;
+    int     flags;
+
+    /*
+     * The requested file system object must exist, otherwise we can't reach
+     * the server.
+     */
+    if (block_mode == NON_BLOCKING)
+       flags = O_RDWR | O_NONBLOCK;
+    else
+       flags = O_RDWR;
+    if ((fd = open(path, flags, 0)) < 0)
+       return (-1);
+
+    /*
+     * XXX Horror. If the open() result is a regular file, no server was
+     * listening. In this case we simulate what would have happened with
+     * UNIX-domain sockets.
+     */
+    if (fstat(fd, &st) < 0)
+       msg_fatal("%s: fstat: %m", myname);
+    if (S_ISREG(st.st_mode)) {
+       close(fd);
+       errno = ECONNREFUSED;
+       return (-1);
+    }
+
+    /*
+     * This is for {unix,inet}_connect() compatibility.
+     */
+    if (block_mode == NON_BLOCKING)
+       non_blocking(fd, NON_BLOCKING);
+
+    /*
+     * No trouble detected, so far.
+     */
+    return (fd);
+#else
+    msg_fatal("stream connections are not implemented");
+#endif
+}
+
diff --git a/postfix/util/stream_listen.c b/postfix/util/stream_listen.c
new file mode 100644 (file)
index 0000000..0c71c84
--- /dev/null
@@ -0,0 +1,136 @@
+/*++
+/* NAME
+/*     stream_listen 3
+/* SUMMARY
+/*     start stream listener
+/* SYNOPSIS
+/*     #include <listen.h>
+/*
+/*     int     stream_listen(path, backlog, block_mode)
+/*     const char *path;
+/*     int     backlog;
+/*     int     block_mode;
+/*
+/*     int     stream_accept(fd)
+/*     int     fd;
+/* DESCRIPTION
+/*     This module implements a substitute local IPC for systems that do
+/*     not have properly-working UNIX-domain sockets.
+/*
+/*     stream_listen() creates a listener endpoint with the specified
+/*     permissions, and returns a file descriptor to be used for accepting
+/*     connections.
+/*
+/*     stream_accept() accepts a connection.
+/*
+/*     Arguments:
+/* .IP path
+/*     Null-terminated string with connection destination.
+/* .IP backlog
+/*     This argument exists for compatibility and is ignored.
+/* .IP block_mode
+/*     This argument exists for compatibility and is ignored.
+/*     blocking mode.
+/* .IP fd
+/*     File descriptor returned by stream_listen().
+/* DIAGNOSTICS
+/*     Fatal errors: stream_listen() aborts upon any system call failure.
+/*     stream_accept() leaves all error handling up to the caller.
+/* BUGS
+/*     This implementation leaks one file descriptor. This is fixed when
+/*     endpoints become objects rather than file descriptors.
+/* 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 interfaces. */
+
+#include <sys_defs.h>
+
+#ifdef STREAM_CONNECTIONS
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stropts.h>
+#include <fcntl.h>
+
+#endif
+
+/* Utility library. */
+
+#include "msg.h"
+#include "listen.h"
+
+/* stream_listen - create stream listener */
+
+int     stream_listen(const char *path, int unused_backlog, 
+int unused_block_mode)
+{
+#ifdef STREAM_CONNECTIONS
+    char   *myname = "stream_listen";
+    static int pair[2];
+    int     fd;
+
+    /*
+     * Initialize: create the specified endpoint with the right permissions.
+     */
+#define PERMS 0666
+    if (unlink(path) && errno != ENOENT)
+       msg_fatal("%s: remove %s: %m", myname, path);
+    if ((fd = open(path, PERMS, O_CREAT | O_TRUNC | O_WRONLY)) < 0)
+       msg_fatal("%s: create file %s: %m", myname, path);
+    if (fchmod(fd, PERMS) < 0)
+       msg_fatal("%s: chmod 0%o: %m", myname, PERMS);
+    if (close(fd) < 0)
+       msg_fatal("%s: close file %s:  %m", myname, path);
+
+    /*
+     * Associate one pipe end with the file just created. See: Richard
+     * Stevens, Advanced Programming in the UNIX Environment Ch. 15.5.1
+     * 
+     * On Solaris 2.4/SPARC, this gives us a "listen queue" of some 460
+     * connections.
+     */
+    if (pipe(pair) < 0)
+       msg_fatal("%s: create pipe: %m", myname);
+    if (ioctl(pair[1], I_PUSH, "connld") < 0)
+       msg_fatal("%s: push connld module: %m", myname);
+    if (fattach(pair[1], path) < 0)
+       msg_fatal("%s: fattach %s: %m", myname, path);
+
+    /*
+     * Return one end, and leak the other. This will be fixed when all
+     * endpoints are objects instead of bare file descriptors.
+     */
+    return (pair[0]);
+#else
+    msg_fatal("stream connections are not implemented");
+#endif
+}
+
+/* stream_accept - accept stream connection */
+
+int     stream_accept(int fd)
+{
+#ifdef STREAM_CONNECTIONS
+    struct strrecvfd fdinfo;
+
+    /*
+     * This will return EAGAIN on a non-blocking stream when someone else
+     * snatched the connection from us.
+     */
+    if (ioctl(fd, I_RECVFD, &fdinfo) < 0)
+       return (-1);
+    return (fdinfo.fd);
+#else
+             msg_fatal("stream connections are not implemented");
+#endif
+}
diff --git a/postfix/util/stream_trigger.c b/postfix/util/stream_trigger.c
new file mode 100644 (file)
index 0000000..585f392
--- /dev/null
@@ -0,0 +1,89 @@
+/*++
+/* NAME
+/*     stream_trigger 3
+/* SUMMARY
+/*     wakeup stream server
+/* SYNOPSIS
+/*     #include <trigger.h>
+/*
+/*     int     stream_trigger(service, buf, len, timeout)
+/*     const char *service;
+/*     const char *buf;
+/*     int     len;
+/*     int     timeout;
+/* DESCRIPTION
+/*     stream_trigger() wakes up the named stream server by making
+/*     a brief connection to it and writing the named buffer.
+/*
+/*     Arguments:
+/* .IP service
+/*     Name of the communication endpoint.
+/* .IP buf
+/*     Address of data to be written.
+/* .IP len
+/*     Amount of data to be written.
+/* .IP timeout
+/*     Deadline in seconds. Specify a value <= 0 to disable
+/*     the time limit.
+/* DIAGNOSTICS
+/*     The result is zero in case of success, -1 in case of problems.
+/* SEE ALSO
+/*     stream_connect(3), stream client
+/* 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 <unistd.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <connect.h>
+#include <iostuff.h>
+#include <trigger.h>
+
+/* stream_trigger - wakeup stream server */
+
+int     stream_trigger(const char *service, const char *buf, int len, int timeout)
+{
+    char   *myname = "stream_trigger";
+    int     fd;
+
+    if (msg_verbose > 1)
+       msg_info("%s: service %s", myname, service);
+
+    /*
+     * Connect...
+     */
+    if ((fd = stream_connect(service, BLOCKING, timeout)) < 0) {
+       if (msg_verbose)
+           msg_warn("%s: connect to %s: %m", myname, service);
+       return (-1);
+    }
+
+    /*
+     * Write the request...
+     */
+    if (write_buf(fd, buf, len, timeout) < 0)
+       if (msg_verbose)
+           msg_warn("%s: write to %s: %m", myname, service);
+
+    /*
+     * Disconnect.
+     */
+    if (close(fd) < 0)
+       if (msg_verbose)
+           msg_warn("%s: close %s: %m", myname, service);
+    return (0);
+}
index 21b0e0151f0c74571feda9845f3734b2fe31c4ef..1dc87ee8fd643f4bbac7caabedade0500d2ad3e0 100644 (file)
@@ -151,7 +151,11 @@ extern int opterr;
 #define DBM_NO_TRAILING_NULL
 #define USE_STATVFS
 #define STATVFS_IN_SYS_STATVFS_H
-#define UNIX_DOMAIN_CONNECT_BLOCKS_FOR_ACCEPT  /* Solaris 2.5.1, reportedly */
+#define STREAM_CONNECTIONS             /* connld module */
+#define LOCAL_LISTEN   stream_listen
+#define LOCAL_ACCEPT   stream_accept
+#define LOCAL_CONNECT  stream_connect
+#define LOCAL_TRIGGER  stream_trigger
 #endif
 
 #ifdef UW7             /* UnixWare 7 */
@@ -261,6 +265,10 @@ extern int initgroups(const char *, int);
 #define STATVFS_IN_SYS_STATVFS_H
 #endif
 
+#if defined(IRIX5)
+#define usleep doze
+#endif
+
 #ifdef LINUX2
 #define SUPPORTED
 #include <sys/types.h>
@@ -503,6 +511,13 @@ extern int opterr;
 #define SOCKOPT_SIZE   int
 #endif
 
+#ifndef LOCAL_LISTEN
+#define LOCAL_LISTEN   unix_listen
+#define LOCAL_ACCEPT   unix_accept
+#define LOCAL_CONNECT  unix_connect
+#define LOCAL_TRIGGER  unix_trigger
+#endif
+
 #if !defined (HAVE_SYS_NDIR_H) && !defined (HAVE_SYS_DIR_H) \
        && !defined (HAVE_NDIR_H)
 #define HAVE_DIRENT_H
index 1f266a74771bd393c1c4bd79835e0e3ae8fd0cbd..ffcf63c5272df502d8c8e633a166de4d00b6581e 100644 (file)
@@ -17,6 +17,7 @@
 extern int unix_trigger(const char *, const char *, int, int);
 extern int inet_trigger(const char *, const char *, int, int);
 extern int fifo_trigger(const char *, const char *, int, int);
+extern int stream_trigger(const char *, const char *, int, int);
 
 /* LICENSE
 /* .ad
index 9c00710f24688e36f4d9062545e52c2a0ca29c63..36d3d10661e0d250beb0eda27d95f88acd147bc2 100644 (file)
 /*     const char *addr;
 /*     int     backlog;
 /*     int     block_mode;
+/*
+/*     int     unix_accept(fd)
+/*     int     fd;
 /* DESCRIPTION
 /*     The \fBunix_listen\fR() routine starts a listener in the UNIX domain
 /*     on the specified address, with the specified backlog, and returns
 /*     the resulting file descriptor.
 /*
+/*     unix_accept() accepts a connection and sanitizes error results.
+/*
 /*     Arguments:
 /* .IP addr
 /*     Null-terminated string with connection destination.
 /* .IP block_mode
 /*     Either NON_BLOCKING for a non-blocking socket, or BLOCKING for
 /*     blocking mode.
+/* .IP fd
+/*     File descriptor returned by unix_listen().
 /* DIAGNOSTICS
-/*     Fatal errors: all errors are fatal.
+/*     Fatal errors: unix_listen() aborts upon any system call failure.
+/*     unix_accept() leaves all error handling up to the caller.
 /* LICENSE
 /* .ad
 /* .fi
@@ -50,6 +58,7 @@
 #include "msg.h"
 #include "iostuff.h"
 #include "listen.h"
+#include "sane_accept.h"
 
 /* unix_listen - create UNIX-domain listener */
 
@@ -93,3 +102,10 @@ int     unix_listen(const char *addr, int backlog, int block_mode)
        msg_fatal("listen: %m");
     return (sock);
 }
+
+/* unix_accept - accept connection */
+
+int     unix_accept(int fd)
+{
+    return (sane_accept(fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0));
+}
index 3e1da8c86eba8020ad09ce40183f0787156342bd..53af93cbb104c6fb26554cb6b32adb2b406b2b8c 100644 (file)
@@ -77,7 +77,7 @@ int     writable(int fd)
        switch (select(fd + 1, (fd_set *) 0, &write_fds, &except_fds, &tv)) {
        case -1:
            if (errno != EINTR)
-               msg_fatal("select");
+               msg_fatal("select: %m");
            continue;
        default:
            return (FD_ISSET(fd, &write_fds));