diff options
Diffstat (limited to 'src/postkick')
l--------- | src/postkick/.indent.pro | 1 | ||||
-rw-r--r-- | src/postkick/.printfck | 25 | ||||
-rw-r--r-- | src/postkick/Makefile.in | 83 | ||||
-rw-r--r-- | src/postkick/postkick.c | 216 |
4 files changed, 325 insertions, 0 deletions
diff --git a/src/postkick/.indent.pro b/src/postkick/.indent.pro new file mode 120000 index 0000000..5c837ec --- /dev/null +++ b/src/postkick/.indent.pro @@ -0,0 +1 @@ +../../.indent.pro
\ No newline at end of file diff --git a/src/postkick/.printfck b/src/postkick/.printfck new file mode 100644 index 0000000..66016ed --- /dev/null +++ b/src/postkick/.printfck @@ -0,0 +1,25 @@ +been_here_xt 2 0 +bounce_append 5 0 +cleanup_out_format 1 0 +defer_append 5 0 +mail_command 1 0 +mail_print 1 0 +msg_error 0 0 +msg_fatal 0 0 +msg_info 0 0 +msg_panic 0 0 +msg_warn 0 0 +opened 4 0 +post_mail_fprintf 1 0 +qmgr_message_bounce 2 0 +rec_fprintf 2 0 +sent 4 0 +smtp_cmd 1 0 +smtp_mesg_fail 2 0 +smtp_printf 1 0 +smtp_rcpt_fail 3 0 +smtp_site_fail 2 0 +udp_syslog 1 0 +vstream_fprintf 1 0 +vstream_printf 0 0 +vstring_sprintf 1 0 diff --git a/src/postkick/Makefile.in b/src/postkick/Makefile.in new file mode 100644 index 0000000..a0c7271 --- /dev/null +++ b/src/postkick/Makefile.in @@ -0,0 +1,83 @@ +SHELL = /bin/sh +SRCS = postkick.c +OBJS = postkick.o +HDRS = +TESTSRC = +DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) +CFLAGS = $(DEBUG) $(OPT) $(DEFS) +TESTPROG= +PROG = postkick +INC_DIR = ../../include +LIBS = ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \ + ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX) + +.c.o:; $(CC) $(CFLAGS) -c $*.c + +$(PROG): $(OBJS) $(LIBS) + $(CC) $(CFLAGS) $(SHLIB_RPATH) -o $@ $(OBJS) $(LIBS) $(SYSLIBS) + +$(OBJS): ../../conf/makedefs.out + +Makefile: Makefile.in + cat ../../conf/makedefs.out $? >$@ + +test: $(TESTPROG) + +tests: + +root_tests: + +update: ../../bin/$(PROG) + +../../bin/$(PROG): $(PROG) + cp $(PROG) ../../bin + +printfck: $(OBJS) $(PROG) + rm -rf printfck + mkdir printfck + sed '1,/^# do not edit/!d' Makefile >printfck/Makefile + set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done + cd printfck; make "INC_DIR=../../../include" `cd ..; ls *.o` + +lint: + lint $(DEFS) $(SRCS) $(LINTFIX) + +clean: + rm -f *.o *core $(PROG) $(TESTPROG) junk + rm -rf printfck + +tidy: clean + +depend: $(MAKES) + (sed '1,/^# do not edit/!d' Makefile.in; \ + set -e; for i in [a-z][a-z0-9]*.c; do \ + $(CC) -E $(DEFS) $(INCL) $$i | grep -v '[<>]' | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \ + -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' \ + -e 's/o: \.\//o: /' -e p -e '}' ; \ + done | LANG=C sort -u) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in + @$(EXPORT) make -f Makefile.in Makefile 1>&2 + +# do not edit below this line - it is generated by 'make depend' +postkick.o: ../../include/argv.h +postkick.o: ../../include/attr.h +postkick.o: ../../include/check_arg.h +postkick.o: ../../include/clean_env.h +postkick.o: ../../include/events.h +postkick.o: ../../include/htable.h +postkick.o: ../../include/iostuff.h +postkick.o: ../../include/mail_conf.h +postkick.o: ../../include/mail_params.h +postkick.o: ../../include/mail_parm_split.h +postkick.o: ../../include/mail_proto.h +postkick.o: ../../include/mail_version.h +postkick.o: ../../include/msg.h +postkick.o: ../../include/msg_vstream.h +postkick.o: ../../include/mymalloc.h +postkick.o: ../../include/nvtable.h +postkick.o: ../../include/safe.h +postkick.o: ../../include/sys_defs.h +postkick.o: ../../include/vbuf.h +postkick.o: ../../include/vstream.h +postkick.o: ../../include/vstring.h +postkick.o: ../../include/warn_stat.h +postkick.o: postkick.c diff --git a/src/postkick/postkick.c b/src/postkick/postkick.c new file mode 100644 index 0000000..dde3dbf --- /dev/null +++ b/src/postkick/postkick.c @@ -0,0 +1,216 @@ +/*++ +/* NAME +/* postkick 1 +/* SUMMARY +/* kick a Postfix service +/* SYNOPSIS +/* .fi +/* \fBpostkick\fR [\fB-c \fIconfig_dir\fR] [\fB-v\fR] +/* \fIclass service request\fR +/* DESCRIPTION +/* The \fBpostkick\fR(1) command sends \fIrequest\fR to the +/* specified \fIservice\fR over a local transport channel. +/* This command makes Postfix private IPC accessible +/* for use in, for example, shell scripts. +/* +/* Options: +/* .IP "\fB-c\fR \fIconfig_dir\fR" +/* Read the \fBmain.cf\fR configuration file in the named directory +/* instead of the default configuration directory. +/* .IP \fB-v\fR +/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR +/* options make the software increasingly verbose. +/* .PP +/* Arguments: +/* .IP \fIclass\fR +/* Name of a class of local transport channel endpoints, +/* either \fBpublic\fR (accessible by any local user) or +/* \fBprivate\fR (administrative access only). +/* .IP \fIservice\fR +/* The name of a local transport endpoint within the named class. +/* .IP \fIrequest\fR +/* A string. The list of valid requests is service-specific. +/* DIAGNOSTICS +/* Problems and transactions are logged to the standard error +/* stream. +/* ENVIRONMENT +/* .ad +/* .fi +/* .IP \fBMAIL_CONFIG\fR +/* Directory with Postfix configuration files. +/* .IP \fBMAIL_VERBOSE\fR +/* Enable verbose logging for debugging purposes. +/* CONFIGURATION PARAMETERS +/* .ad +/* .fi +/* The following \fBmain.cf\fR parameters are especially relevant to +/* this program. +/* The text below provides only a parameter summary. See +/* \fBpostconf\fR(5) for more details including examples. +/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR" +/* The default location of the Postfix main.cf and master.cf +/* configuration files. +/* .IP "\fBapplication_event_drain_time (100s)\fR" +/* How long the \fBpostkick\fR(1) command waits for a request to enter the +/* Postfix daemon process input buffer before giving up. +/* .IP "\fBimport_environment (see 'postconf -d' output)\fR" +/* The list of environment parameters that a privileged Postfix +/* process will import from a non-Postfix parent process, or name=value +/* environment overrides. +/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR" +/* The location of the Postfix top-level queue directory. +/* FILES +/* /var/spool/postfix/private, private class endpoints +/* /var/spool/postfix/public, public class endpoints +/* SEE ALSO +/* qmgr(8), queue manager trigger protocol +/* pickup(8), local pickup daemon +/* postconf(5), configuration parameters +/* 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 +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA +/*--*/ + +/* System library. */ + +#include <sys_defs.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> + +/* Utility library. */ + +#include <msg.h> +#include <mymalloc.h> +#include <vstream.h> +#include <msg_vstream.h> +#include <safe.h> +#include <events.h> +#include <warn_stat.h> +#include <clean_env.h> + +/* Global library. */ + +#include <mail_proto.h> +#include <mail_params.h> +#include <mail_version.h> +#include <mail_conf.h> +#include <mail_parm_split.h> + +static NORETURN usage(char *myname) +{ + msg_fatal("usage: %s [-c config_dir] [-v] class service request", myname); +} + +MAIL_VERSION_STAMP_DECLARE; + +int main(int argc, char **argv) +{ + char *class; + char *service; + char *request; + int fd; + struct stat st; + char *slash; + int c; + ARGV *import_env; + + /* + * Fingerprint executables and core dumps. + */ + MAIL_VERSION_STAMP_ALLOCATE; + + /* + * To minimize confusion, make sure that the standard file descriptors + * 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 + && (close(fd), open("/dev/null", O_RDWR, 0)) != fd) + msg_fatal("open /dev/null: %m"); + + /* + * Process environment options as early as we can. + */ + if (safe_getenv(CONF_ENV_VERB)) + msg_verbose = 1; + + /* + * Initialize. Set up logging. Read the global configuration file after + * parsing command-line arguments. + */ + if ((slash = strrchr(argv[0], '/')) != 0 && slash[1]) + argv[0] = slash + 1; + msg_vstream_init(argv[0], VSTREAM_ERR); + set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0])); + + /* + * Parse JCL. + */ + while ((c = GETOPT(argc, argv, "c:v")) > 0) { + switch (c) { + default: + usage(argv[0]); + case 'c': + if (setenv(CONF_ENV_PATH, optarg, 1) < 0) + msg_fatal("out of memory"); + break; + case 'v': + msg_verbose++; + break; + } + } + if (argc != optind + 3) + usage(argv[0]); + class = argv[optind]; + service = argv[optind + 1]; + request = argv[optind + 2]; + + /* + * Finish initializations. + */ + mail_conf_read(); + /* Enforce consistent operation of different Postfix parts. */ + import_env = mail_parm_split(VAR_IMPORT_ENVIRON, var_import_environ); + update_env(import_env->argv); + argv_free(import_env); + if (chdir(var_queue_dir)) + msg_fatal("chdir %s: %m", var_queue_dir); + + /* + * Kick the service. + */ + if (mail_trigger(class, service, request, strlen(request)) < 0) { + msg_warn("Cannot contact class %s service %s - perhaps the mail system is down", + class, service); + exit(1); + } + + /* + * Problem: With triggers over full duplex (i.e. non-FIFO) channels, we + * must avoid closing the channel before the server has received the + * request. Otherwise some hostile kernel may throw away the request. + * + * Solution: The trigger routine registers a read event handler that runs + * when the server closes the channel. The event_drain() routine waits + * for the event handler to run, but gives up when it takes too long. + */ + else { + event_drain(var_event_drain); + exit(0); + } +} |