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