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