mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-31 06:05:37 +00:00
snapshot-19990321
This commit is contained in:
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -55,10 +55,7 @@
|
||||
/* 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[] = {
|
||||
|
@@ -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).
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 : "")
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -152,6 +152,19 @@
|
||||
|
||||
#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");
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -137,6 +137,7 @@
|
||||
#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,35 @@ 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_accept(int unused_event, char *context)
|
||||
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_local(int unused_event, char *context)
|
||||
{
|
||||
int listen_fd = (int) context;
|
||||
int time_left = -1;
|
||||
int fd;
|
||||
VSTREAM *stream;
|
||||
|
||||
#ifndef NO_SELECT_COLLISION
|
||||
if (multi_server_lock != 0
|
||||
&& myflock(vstream_fileno(multi_server_lock), MYFLOCK_NONE) < 0)
|
||||
msg_fatal("select unlock: %m");
|
||||
#endif
|
||||
/*
|
||||
* 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 +288,62 @@ 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 = 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;
|
||||
}
|
||||
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_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
|
||||
* 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 = 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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
@@ -128,6 +128,7 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
|
@@ -136,6 +136,7 @@
|
||||
#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
|
||||
|
@@ -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
|
||||
|
@@ -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");
|
||||
|
||||
/*
|
||||
|
@@ -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");
|
||||
|
||||
/*
|
||||
|
@@ -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");
|
||||
|
||||
/*
|
||||
|
@@ -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");
|
||||
|
||||
/*
|
||||
|
@@ -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");
|
||||
|
||||
/*
|
||||
|
@@ -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");
|
||||
|
||||
/*
|
||||
|
@@ -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
|
||||
@@ -14,17 +14,17 @@
|
||||
/*
|
||||
/* 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");
|
||||
|
||||
/*
|
||||
|
@@ -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");
|
||||
|
||||
/*
|
||||
|
@@ -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");
|
||||
|
||||
/*
|
||||
|
@@ -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");
|
||||
|
||||
/*
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
@@ -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");
|
||||
|
||||
/*
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -10,11 +10,16 @@
|
||||
/* 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".
|
||||
@@ -25,8 +30,11 @@
|
||||
/* .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));
|
||||
}
|
||||
|
@@ -22,6 +22,11 @@
|
||||
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
|
||||
|
@@ -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.
|
||||
|
BIN
postfix/util/sendfd_test
Executable file
BIN
postfix/util/sendfd_test
Executable file
Binary file not shown.
105
postfix/util/sendfd_test.c
Normal file
105
postfix/util/sendfd_test.c
Normal file
@@ -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");
|
||||
}
|
||||
}
|
102
postfix/util/stream_connect.c
Normal file
102
postfix/util/stream_connect.c
Normal file
@@ -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
|
||||
}
|
||||
|
136
postfix/util/stream_listen.c
Normal file
136
postfix/util/stream_listen.c
Normal file
@@ -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
|
||||
}
|
89
postfix/util/stream_trigger.c
Normal file
89
postfix/util/stream_trigger.c
Normal file
@@ -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);
|
||||
}
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -10,11 +10,16 @@
|
||||
/* 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.
|
||||
@@ -23,8 +28,11 @@
|
||||
/* .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));
|
||||
}
|
||||
|
@@ -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));
|
||||
|
Reference in New Issue
Block a user