1/*++ 2/* NAME 3/* postkick 1 4/* SUMMARY 5/* kick a Postfix service 6/* SYNOPSIS 7/* .fi 8/* \fBpostkick\fR [\fB-c \fIconfig_dir\fR] [\fB-v\fR] 9/* \fIclass service request\fR 10/* DESCRIPTION 11/* The \fBpostkick\fR(1) command sends \fIrequest\fR to the 12/* specified \fIservice\fR over a local transport channel. 13/* This command makes Postfix private IPC accessible 14/* for use in, for example, shell scripts. 15/* 16/* Options: 17/* .IP "\fB-c\fR \fIconfig_dir\fR" 18/* Read the \fBmain.cf\fR configuration file in the named directory 19/* instead of the default configuration directory. 20/* .IP \fB-v\fR 21/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR 22/* options make the software increasingly verbose. 23/* .PP 24/* Arguments: 25/* .IP \fIclass\fR 26/* Name of a class of local transport channel endpoints, 27/* either \fBpublic\fR (accessible by any local user) or 28/* \fBprivate\fR (administrative access only). 29/* .IP \fIservice\fR 30/* The name of a local transport endpoint within the named class. 31/* .IP \fIrequest\fR 32/* A string. The list of valid requests is service-specific. 33/* DIAGNOSTICS 34/* Problems and transactions are logged to the standard error 35/* stream. 36/* ENVIRONMENT 37/* .ad 38/* .fi 39/* .IP \fBMAIL_CONFIG\fR 40/* Directory with Postfix configuration files. 41/* .IP \fBMAIL_VERBOSE\fR 42/* Enable verbose logging for debugging purposes. 43/* CONFIGURATION PARAMETERS 44/* .ad 45/* .fi 46/* The following \fBmain.cf\fR parameters are especially relevant to 47/* this program. 48/* The text below provides only a parameter summary. See 49/* \fBpostconf\fR(5) for more details including examples. 50/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR" 51/* The default location of the Postfix main.cf and master.cf 52/* configuration files. 53/* .IP "\fBapplication_event_drain_time (100s)\fR" 54/* How long the \fBpostkick\fR(1) command waits for a request to enter the 55/* Postfix daemon process input buffer before giving up. 56/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR" 57/* The location of the Postfix top-level queue directory. 58/* FILES 59/* /var/spool/postfix/private, private class endpoints 60/* /var/spool/postfix/public, public class endpoints 61/* SEE ALSO 62/* qmgr(8), queue manager trigger protocol 63/* pickup(8), local pickup daemon 64/* postconf(5), configuration parameters 65/* LICENSE 66/* .ad 67/* .fi 68/* The Secure Mailer license must be distributed with this software. 69/* AUTHOR(S) 70/* Wietse Venema 71/* IBM T.J. Watson Research 72/* P.O. Box 704 73/* Yorktown Heights, NY 10598, USA 74/*--*/ 75 76/* System library. */ 77 78#include <sys_defs.h> 79#include <sys/stat.h> 80#include <fcntl.h> 81#include <unistd.h> 82#include <syslog.h> 83#include <string.h> 84#include <stdlib.h> 85 86/* Utility library. */ 87 88#include <msg.h> 89#include <mymalloc.h> 90#include <vstream.h> 91#include <msg_vstream.h> 92#include <safe.h> 93#include <events.h> 94#include <warn_stat.h> 95 96/* Global library. */ 97 98#include <mail_proto.h> 99#include <mail_params.h> 100#include <mail_version.h> 101#include <mail_conf.h> 102 103static NORETURN usage(char *myname) 104{ 105 msg_fatal("usage: %s [-c config_dir] [-v] class service request", myname); 106} 107 108MAIL_VERSION_STAMP_DECLARE; 109 110int main(int argc, char **argv) 111{ 112 char *class; 113 char *service; 114 char *request; 115 int fd; 116 struct stat st; 117 char *slash; 118 int c; 119 120 /* 121 * Fingerprint executables and core dumps. 122 */ 123 MAIL_VERSION_STAMP_ALLOCATE; 124 125 /* 126 * To minimize confusion, make sure that the standard file descriptors 127 * are open before opening anything else. XXX Work around for 44BSD where 128 * fstat can return EBADF on an open file descriptor. 129 */ 130 for (fd = 0; fd < 3; fd++) 131 if (fstat(fd, &st) == -1 132 && (close(fd), open("/dev/null", O_RDWR, 0)) != fd) 133 msg_fatal("open /dev/null: %m"); 134 135 /* 136 * Process environment options as early as we can. 137 */ 138 if (safe_getenv(CONF_ENV_VERB)) 139 msg_verbose = 1; 140 141 /* 142 * Initialize. Set up logging, read the global configuration file and 143 * extract configuration information. 144 */ 145 if ((slash = strrchr(argv[0], '/')) != 0 && slash[1]) 146 argv[0] = slash + 1; 147 msg_vstream_init(argv[0], VSTREAM_ERR); 148 set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0])); 149 150 /* 151 * Parse JCL. 152 */ 153 while ((c = GETOPT(argc, argv, "c:v")) > 0) { 154 switch (c) { 155 default: 156 usage(argv[0]); 157 case 'c': 158 if (setenv(CONF_ENV_PATH, optarg, 1) < 0) 159 msg_fatal("out of memory"); 160 break; 161 case 'v': 162 msg_verbose++; 163 break; 164 } 165 } 166 if (argc != optind + 3) 167 usage(argv[0]); 168 class = argv[optind]; 169 service = argv[optind + 1]; 170 request = argv[optind + 2]; 171 172 /* 173 * Finish initializations. 174 */ 175 mail_conf_read(); 176 if (chdir(var_queue_dir)) 177 msg_fatal("chdir %s: %m", var_queue_dir); 178 179 /* 180 * Kick the service. 181 */ 182 if (mail_trigger(class, service, request, strlen(request)) < 0) { 183 msg_warn("Cannot contact class %s service %s - perhaps the mail system is down", 184 class, service); 185 exit(1); 186 } 187 188 /* 189 * Problem: With triggers over full duplex (i.e. non-FIFO) channels, we 190 * must avoid closing the channel before the server has received the 191 * request. Otherwise some hostile kernel may throw away the request. 192 * 193 * Solution: The trigger routine registers a read event handler that runs 194 * when the server closes the channel. The event_drain() routine waits 195 * for the event handler to run, but gives up when it takes too long. 196 */ 197 else { 198 event_drain(var_event_drain); 199 exit(0); 200 } 201} 202