Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / inet_trigger.c
blobaa6e5dd4e3657be412c87055ddda72c08520a8ff
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* inet_trigger 3
6 /* SUMMARY
7 /* wakeup INET-domain server
8 /* SYNOPSIS
9 /* #include <trigger.h>
11 /* int inet_trigger(service, buf, len, timeout)
12 /* char *service;
13 /* const char *buf;
14 /* ssize_t len;
15 /* int timeout;
16 /* DESCRIPTION
17 /* inet_trigger() wakes up the named INET-domain server by making
18 /* a brief connection to it and by writing the contents of the
19 /* named buffer.
21 /* The connection is closed by a background thread. Some kernels
22 /* cannot handle client-side disconnect before the server has
23 /* received the message.
25 /* Arguments:
26 /* .IP service
27 /* Name of the communication endpoint.
28 /* .IP buf
29 /* Address of data to be written.
30 /* .IP len
31 /* Amount of data to be written.
32 /* .IP timeout
33 /* Deadline in seconds. Specify a value <= 0 to disable
34 /* the time limit.
35 /* DIAGNOSTICS
36 /* The result is zero in case of success, -1 in case of problems.
37 /* BUGS
38 /* SEE ALSO
39 /* inet_connect(3), INET-domain client
40 /* LICENSE
41 /* .ad
42 /* .fi
43 /* The Secure Mailer license must be distributed with this software.
44 /* AUTHOR(S)
45 /* Wietse Venema
46 /* IBM T.J. Watson Research
47 /* P.O. Box 704
48 /* Yorktown Heights, NY 10598, USA
49 /*--*/
51 /* System library. */
53 #include <sys_defs.h>
54 #include <sys/socket.h>
55 #include <unistd.h>
56 #include <string.h>
58 /* Utility library. */
60 #include <msg.h>
61 #include <connect.h>
62 #include <iostuff.h>
63 #include <mymalloc.h>
64 #include <events.h>
65 #include <trigger.h>
67 struct inet_trigger {
68 int fd;
69 char *service;
72 /* inet_trigger_event - disconnect from peer */
74 static void inet_trigger_event(int event, char *context)
76 struct inet_trigger *ip = (struct inet_trigger *) context;
77 static const char *myname = "inet_trigger_event";
80 * Disconnect.
82 if (event == EVENT_TIME)
83 msg_warn("%s: read timeout for service %s", myname, ip->service);
84 event_disable_readwrite(ip->fd);
85 event_cancel_timer(inet_trigger_event, context);
86 if (close(ip->fd) < 0)
87 msg_warn("%s: close %s: %m", myname, ip->service);
88 myfree(ip->service);
89 myfree((char *) ip);
93 /* inet_trigger - wakeup INET-domain server */
95 int inet_trigger(const char *service, const char *buf, ssize_t len, int timeout)
97 const char *myname = "inet_trigger";
98 struct inet_trigger *ip;
99 int fd;
101 if (msg_verbose > 1)
102 msg_info("%s: service %s", myname, service);
105 * Connect...
107 if ((fd = inet_connect(service, BLOCKING, timeout)) < 0) {
108 if (msg_verbose)
109 msg_warn("%s: connect to %s: %m", myname, service);
110 return (-1);
112 close_on_exec(fd, CLOSE_ON_EXEC);
113 ip = (struct inet_trigger *) mymalloc(sizeof(*ip));
114 ip->fd = fd;
115 ip->service = mystrdup(service);
118 * Write the request...
120 if (write_buf(fd, buf, len, timeout) < 0
121 || write_buf(fd, "", 1, timeout) < 0)
122 if (msg_verbose)
123 msg_warn("%s: write to %s: %m", myname, service);
126 * Wakeup when the peer disconnects, or when we lose patience.
128 if (timeout > 0)
129 event_request_timer(inet_trigger_event, (char *) ip, timeout + 100);
130 event_enable_read(fd, inet_trigger_event, (char *) ip);
131 return (0);