diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2008-12-05 03:28:38 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2008-12-05 03:28:38 +0000 |
commit | d8212310e46cd4d9b3d172cdb2c77a18241b7f0e (patch) | |
tree | 20663311b7e41c903bf01855418197f14a9937df /usr.sbin | |
parent | 747f62b5dbedca879d99609ee63547c8d6d68e49 (diff) |
- smtpctl utility to control the smtpd, don't expect too much yet as it is
just an empty clone of relayctl with the glue needed to have it
exchange imsg with smtpd correctly. code mostly by pyr@, reviewed
by chl@ and I a while ago.
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/smtpd/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/parser.c | 167 | ||||
-rw-r--r-- | usr.sbin/smtpd/parser.h | 33 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpctl.8 | 50 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpctl.c | 178 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpctl/Makefile | 15 |
6 files changed, 445 insertions, 2 deletions
diff --git a/usr.sbin/smtpd/Makefile b/usr.sbin/smtpd/Makefile index 853eb8a1363..4159055631e 100644 --- a/usr.sbin/smtpd/Makefile +++ b/usr.sbin/smtpd/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.6 2008/12/04 15:16:08 gilles Exp $ +# $OpenBSD: Makefile,v 1.7 2008/12/05 03:28:37 gilles Exp $ .include <bsd.own.mk> -SUBDIR = makemap newaliases smtpd +SUBDIR = makemap newaliases smtpd smtpctl distribution: ${INSTALL} -C -o root -g wheel -m 0644 ${.CURDIR}/smtpd.conf \ diff --git a/usr.sbin/smtpd/parser.c b/usr.sbin/smtpd/parser.c new file mode 100644 index 00000000000..8d2b5d07508 --- /dev/null +++ b/usr.sbin/smtpd/parser.c @@ -0,0 +1,167 @@ +/* $OpenBSD: parser.c,v 1.1 2008/12/05 03:28:37 gilles Exp $ */ + +/* + * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> + * Copyright (c) 2004 Esben Norby <norby@openbsd.org> + * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/queue.h> +#include <sys/tree.h> + +#include <net/if.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <err.h> +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <event.h> + +#include <openssl/ssl.h> + +#include "smtpd.h" + +#include "parser.h" + +enum token_type { + NOTOKEN, + ENDTOKEN, + KEYWORD +}; + +struct token { + enum token_type type; + const char *keyword; + int value; + const struct token *next; +}; + +static const struct token t_main[]; +static const struct token t_show[]; +static const struct token t_rdr[]; +static const struct token t_table[]; +static const struct token t_host[]; +static const struct token t_rdr_id[]; +static const struct token t_table_id[]; +static const struct token t_host_id[]; + +static const struct token t_main[] = { + {KEYWORD, "monitor", MONITOR, NULL}, + {KEYWORD, "reload", RELOAD, NULL}, + {KEYWORD, "stop", SHUTDOWN, NULL}, + {ENDTOKEN, "", NONE, NULL} +}; + +static struct parse_result res; + +struct parse_result * +parse(int argc, char *argv[]) +{ + const struct token *table = t_main; + const struct token *match; + + bzero(&res, sizeof(res)); + + while (argc >= 0) { + if ((match = match_token(argv[0], table)) == NULL) { + fprintf(stderr, "valid commands/args:\n"); + show_valid_args(table); + return (NULL); + } + + argc--; + argv++; + + if (match->type == NOTOKEN || match->next == NULL) + break; + + table = match->next; + } + + if (argc > 0) { + fprintf(stderr, "superfluous argument: %s\n", argv[0]); + return (NULL); + } + + return (&res); +} + +const struct token * +match_token(const char *word, const struct token table[]) +{ + u_int i, match; + const struct token *t = NULL; + + match = 0; + + for (i = 0; table[i].type != ENDTOKEN; i++) { + switch (table[i].type) { + case NOTOKEN: + if (word == NULL || strlen(word) == 0) { + match++; + t = &table[i]; + } + break; + case KEYWORD: + if (word != NULL && strncmp(word, table[i].keyword, + strlen(word)) == 0) { + match++; + t = &table[i]; + if (t->value) + res.action = t->value; + } + break; + case ENDTOKEN: + break; + } + } + + if (match != 1) { + if (word == NULL) + fprintf(stderr, "missing argument:\n"); + else if (match > 1) + fprintf(stderr, "ambiguous argument: %s\n", word); + else if (match < 1) + fprintf(stderr, "unknown argument: %s\n", word); + return (NULL); + } + + return (t); +} + +void +show_valid_args(const struct token table[]) +{ + int i; + + for (i = 0; table[i].type != ENDTOKEN; i++) { + switch (table[i].type) { + case NOTOKEN: + fprintf(stderr, " <cr>\n"); + break; + case KEYWORD: + fprintf(stderr, " %s\n", table[i].keyword); + break; + case ENDTOKEN: + break; + } + } +} diff --git a/usr.sbin/smtpd/parser.h b/usr.sbin/smtpd/parser.h new file mode 100644 index 00000000000..ff3e45b4c1d --- /dev/null +++ b/usr.sbin/smtpd/parser.h @@ -0,0 +1,33 @@ +/* $OpenBSD: parser.h,v 1.1 2008/12/05 03:28:37 gilles Exp $ */ + +/* + * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum actions { + NONE, + SHUTDOWN, + RELOAD, + MONITOR +}; + +struct parse_result { + struct ctl_id id; + enum actions action; +}; + +struct parse_result *parse(int, char *[]); +const struct token *match_token(const char *, const struct token []); +void show_valid_args(const struct token []); diff --git a/usr.sbin/smtpd/smtpctl.8 b/usr.sbin/smtpd/smtpctl.8 new file mode 100644 index 00000000000..e8c9414c6ae --- /dev/null +++ b/usr.sbin/smtpd/smtpctl.8 @@ -0,0 +1,50 @@ +.\" $OpenBSD: smtpctl.8,v 1.1 2008/12/05 03:28:37 gilles Exp $ +.\" +.\" Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: December 5 2008 $ +.Dt SMTPCTL 8 +.Os +.Sh NAME +.Nm smtpctl +.Nd control the smtp daemon +.Sh SYNOPSIS +.Nm +.Ar command +.Op Ar arguments ... +.Sh DESCRIPTION +The +.Nm +program controls the +.Xr smtpd 8 +daemon. +.Pp +The following commands are available: +.Bl -tag -width Ds +.El +.Sh FILES +.Bl -tag -width "/var/run/smtpd.sockXX" -compact +.It /var/run/smtpd.sock +Unix-domain socket used for communication with +.Xr smtpd 8 . +.El +.Sh SEE ALSO +.Xr smtpd 8 +.Sh HISTORY +The +.Nm +program first appeared in +.Ox 4.4 . + diff --git a/usr.sbin/smtpd/smtpctl.c b/usr.sbin/smtpd/smtpctl.c new file mode 100644 index 00000000000..287bb9399de --- /dev/null +++ b/usr.sbin/smtpd/smtpctl.c @@ -0,0 +1,178 @@ +/* $OpenBSD: smtpctl.c,v 1.1 2008/12/05 03:28:37 gilles Exp $ */ + +/* + * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> + * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> + * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> + * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/queue.h> +#include <sys/tree.h> +#include <sys/un.h> + +#include <net/if.h> +#include <net/if_media.h> +#include <net/if_types.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <event.h> + +#include "smtpd.h" +#include "parser.h" + +__dead void usage(void); +int show_command_output(struct imsg*); + +struct imsgname { + int type; + char *name; + void (*func)(struct imsg *); +}; + +struct imsgname imsgs[] = { + { IMSG_CTL_SHUTDOWN, "stop", NULL }, + { IMSG_CONF_RELOAD, "reload", NULL }, + { 0, NULL, NULL } +}; +struct imsgname imsgunknown = { + -1, "<unknown>", NULL +}; + +int proctype; +struct imsgbuf *ibuf; + +__dead void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, "usage: %s <command> [arg [...]]\n", __progname); + exit(1); +} + +/* dummy function so that smtpctl does not need libevent */ +void +imsg_event_add(struct imsgbuf *i) +{ + /* nothing */ +} + +int +main(int argc, char *argv[]) +{ + struct sockaddr_un sun; + struct parse_result *res; + struct imsg imsg; + int ctl_sock; + int done = 0; + int n; + + /* parse options */ + if ((res = parse(argc - 1, argv + 1)) == NULL) + exit(1); + + /* connect to relayd control socket */ + if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + err(1, "socket"); + + bzero(&sun, sizeof(sun)); + sun.sun_family = AF_UNIX; + strlcpy(sun.sun_path, SMTPD_SOCKET, sizeof(sun.sun_path)); + if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) + err(1, "connect: %s", SMTPD_SOCKET); + + if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) + err(1, NULL); + imsg_init(ibuf, ctl_sock, NULL); + done = 0; + + /* process user request */ + switch (res->action) { + case NONE: + usage(); + /* not reached */ + case SHUTDOWN: + imsg_compose(ibuf, IMSG_CTL_SHUTDOWN, 0, 0, -1, NULL, 0); + break; + case RELOAD: + imsg_compose(ibuf, IMSG_CONF_RELOAD, 0, 0, -1, NULL, 0); + break; + case MONITOR: + /* XXX */ + break; + } + + while (ibuf->w.queued) + if (msgbuf_write(&ibuf->w) < 0) + err(1, "write error"); + + while (!done) { + if ((n = imsg_read(ibuf)) == -1) + errx(1, "imsg_read error"); + if (n == 0) + errx(1, "pipe closed"); + + while (!done) { + if ((n = imsg_get(ibuf, &imsg)) == -1) + errx(1, "imsg_get error"); + if (n == 0) + break; + switch(res->action) { + case RELOAD: + case SHUTDOWN: + done = show_command_output(&imsg); + break; + case NONE: + break; + case MONITOR: + break; + } + /* insert imsg replies switch here */ + + imsg_free(&imsg); + } + } + close(ctl_sock); + free(ibuf); + + return (0); +} + +int +show_command_output(struct imsg *imsg) +{ + switch (imsg->hdr.type) { + case IMSG_CTL_OK: + printf("command succeeded\n"); + break; + case IMSG_CTL_FAIL: + printf("command failed\n"); + break; + default: + errx(1, "wrong message in summary: %u", imsg->hdr.type); + } + return (1); +} + diff --git a/usr.sbin/smtpd/smtpctl/Makefile b/usr.sbin/smtpd/smtpctl/Makefile new file mode 100644 index 00000000000..c8dba4072d6 --- /dev/null +++ b/usr.sbin/smtpd/smtpctl/Makefile @@ -0,0 +1,15 @@ +# $OpenBSD: Makefile,v 1.1 2008/12/05 03:28:37 gilles Exp $ + +.PATH: ${.CURDIR}/.. + +PROG= smtpctl +BINOWN= root + +BINMODE?=555 + +BINDIR= /usr/bin +MAN= smtpctl.8 + +SRCS= smtpctl.c parser.c buffer.c imsg.c log.c +LDFLAGS= -lutil +.include <bsd.prog.mk> |