summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd/smtpctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/smtpd/smtpctl.c')
-rw-r--r--usr.sbin/smtpd/smtpctl.c260
1 files changed, 136 insertions, 124 deletions
diff --git a/usr.sbin/smtpd/smtpctl.c b/usr.sbin/smtpd/smtpctl.c
index 7d453410690..006fed00cac 100644
--- a/usr.sbin/smtpd/smtpctl.c
+++ b/usr.sbin/smtpd/smtpctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpctl.c,v 1.108 2013/07/19 21:14:52 eric Exp $ */
+/* $OpenBSD: smtpctl.c,v 1.109 2013/10/25 18:58:10 eric Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@@ -49,6 +49,8 @@
#define PATH_CAT "/bin/cat"
#define PATH_QUEUE "/queue"
+int srv_connect(void);
+
void usage(void);
static void show_queue_envelope(struct envelope *, int);
static void getflag(uint *, int, char *, char *, size_t);
@@ -96,7 +98,7 @@ void stat_decrement(const char *k, size_t v)
{
}
-static int
+int
srv_connect(void)
{
struct sockaddr_un sun;
@@ -189,20 +191,23 @@ srv_end(void)
}
static int
-srv_check_result(void)
+srv_check_result(int verbose_)
{
srv_recv(-1);
srv_end();
switch (imsg.hdr.type) {
case IMSG_CTL_OK:
- printf("command succeeded\n");
+ if (verbose_)
+ printf("command succeeded\n");
return (0);
case IMSG_CTL_FAIL:
- if (rlen)
- printf("command failed: %s\n", rdata);
- else
- printf("command failed\n");
+ if (verbose_) {
+ if (rlen)
+ printf("command failed: %s\n", rdata);
+ else
+ printf("command failed\n");
+ }
return (1);
default:
errx(1, "wrong message in response: %u", imsg.hdr.type);
@@ -294,12 +299,100 @@ srv_iter_envelopes(uint32_t msgid, struct envelope *evp)
}
static int
+srv_iter_evpids(uint32_t msgid, uint64_t *evpid, int *offset)
+{
+ static uint64_t *evpids = NULL;
+ static int n, alloc = 0;
+ struct envelope evp;
+
+ if (evpids == NULL) {
+ alloc = 1000;
+ evpids = malloc(alloc * sizeof(*evpids));
+ if (evpids == NULL)
+ err(1, "malloc");
+ }
+
+ if (*offset == 0) {
+ n = 0;
+ while (srv_iter_envelopes(msgid, &evp)) {
+ if (n == alloc) {
+ alloc += 256;
+ evpids = realloc(evpids, alloc * sizeof(*evpids));
+ if (evpids == NULL)
+ err(1, "realloc");
+ }
+ evpids[n++] = evp.id;
+ }
+ }
+
+ if (*offset >= n)
+ return (0);
+ *evpid = evpids[*offset];
+ *offset += 1;
+ return (1);
+}
+
+static void
+srv_foreach_envelope(struct parameter *argv, int ctl, size_t *total, size_t *ok)
+{
+ uint32_t msgid;
+ uint64_t evpid;
+ int i;
+
+ *total = 0;
+ *ok = 0;
+
+ if (argv == NULL) {
+ while (srv_iter_messages(&msgid)) {
+ i = 0;
+ while (srv_iter_evpids(msgid, &evpid, &i)) {
+ *total += 1;
+ srv_send(ctl, &evpid, sizeof(evpid));
+ if (srv_check_result(0) == 0)
+ *ok += 1;
+ }
+ }
+ } else if (argv->type == P_MSGID) {
+ i = 0;
+ while (srv_iter_evpids(argv->u.u_msgid, &evpid, &i)) {
+ srv_send(ctl, &evpid, sizeof(evpid));
+ if (srv_check_result(0) == 0)
+ *ok += 1;
+ }
+ } else {
+ *total += 1;
+ srv_send(ctl, &argv->u.u_evpid, sizeof(evpid));
+ if (srv_check_result(0) == 0)
+ *ok += 1;
+ }
+}
+
+static void
+srv_show_cmd(int cmd, const void *data, size_t len)
+{
+ int done = 0;
+
+ srv_send(cmd, data, len);
+
+ do {
+ srv_recv(cmd);
+ if (rlen) {
+ printf("%s\n", rdata);
+ srv_read(NULL, rlen);
+ }
+ else
+ done = 1;
+ srv_end();
+ } while (!done);
+}
+
+static int
do_log_brief(int argc, struct parameter *argv)
{
int v = 0;
srv_send(IMSG_CTL_VERBOSE, &v, sizeof(v));
- return srv_check_result();
+ return srv_check_result(1);
}
static int
@@ -308,7 +401,7 @@ do_log_verbose(int argc, struct parameter *argv)
int v = TRACE_DEBUG;
srv_send(IMSG_CTL_VERBOSE, &v, sizeof(v));
- return srv_check_result();
+ return srv_check_result(1);
}
static int
@@ -370,26 +463,10 @@ do_monitor(int argc, struct parameter *argv)
static int
do_pause_envelope(int argc, struct parameter *argv)
{
- struct envelope evp;
- uint32_t msgid;
+ size_t total, ok;
- if (argc == 0) {
- while (srv_iter_messages(&msgid)) {
- while (srv_iter_envelopes(msgid, &evp)) {
- srv_send(IMSG_CTL_PAUSE_EVP, &evp.id,
- sizeof(evp.id));
- srv_check_result();
- }
- }
- } else if (argv[0].type == P_MSGID) {
- while (srv_iter_envelopes(argv[0].u.u_msgid, &evp)) {
- srv_send(IMSG_CTL_PAUSE_EVP, &evp.id, sizeof(evp.id));
- srv_check_result();
- }
- } else {
- srv_send(IMSG_CTL_PAUSE_EVP, &argv[0].u.u_evpid, sizeof(evp.id));
- srv_check_result();
- }
+ srv_foreach_envelope(argv, IMSG_CTL_PAUSE_EVP, &total, &ok);
+ printf("%zu envelope%s paused\n", ok, (ok > 1) ? "s" : "");
return (0);
}
@@ -398,21 +475,21 @@ static int
do_pause_mda(int argc, struct parameter *argv)
{
srv_send(IMSG_CTL_PAUSE_MDA, NULL, 0);
- return srv_check_result();
+ return srv_check_result(1);
}
static int
do_pause_mta(int argc, struct parameter *argv)
{
srv_send(IMSG_CTL_PAUSE_MTA, NULL, 0);
- return srv_check_result();
+ return srv_check_result(1);
}
static int
do_pause_smtp(int argc, struct parameter *argv)
{
srv_send(IMSG_CTL_PAUSE_SMTP, NULL, 0);
- return srv_check_result();
+ return srv_check_result(1);
}
static int
@@ -423,32 +500,16 @@ do_profile(int argc, struct parameter *argv)
v = str_to_profile(argv[0].u.u_str);
srv_send(IMSG_CTL_PROFILE, &v, sizeof(v));
- return srv_check_result();
+ return srv_check_result(1);
}
static int
do_remove(int argc, struct parameter *argv)
{
- struct envelope evp;
- uint32_t msgid;
+ size_t total, ok;
- if (argc == 0) {
- while (srv_iter_messages(&msgid)) {
- while (srv_iter_envelopes(msgid, &evp)) {
- srv_send(IMSG_CTL_REMOVE, &evp.id,
- sizeof(evp.id));
- srv_check_result();
- }
- }
- } else if (argv[0].type == P_MSGID) {
- while (srv_iter_envelopes(argv[0].u.u_msgid, &evp)) {
- srv_send(IMSG_CTL_REMOVE, &evp.id, sizeof(evp.id));
- srv_check_result();
- }
- } else {
- srv_send(IMSG_CTL_REMOVE, &argv[0].u.u_evpid, sizeof(evp.id));
- srv_check_result();
- }
+ srv_foreach_envelope(argv, IMSG_CTL_REMOVE, &total, &ok);
+ printf("%zu envelope%s removed\n", ok, (ok > 1) ? "s" : "");
return (0);
}
@@ -456,26 +517,10 @@ do_remove(int argc, struct parameter *argv)
static int
do_resume_envelope(int argc, struct parameter *argv)
{
- struct envelope evp;
- uint32_t msgid;
+ size_t total, ok;
- if (argc == 0) {
- while (srv_iter_messages(&msgid)) {
- while (srv_iter_envelopes(msgid, &evp)) {
- srv_send(IMSG_CTL_RESUME_EVP, &evp.id,
- sizeof(evp.id));
- srv_check_result();
- }
- }
- } else if (argv[0].type == P_MSGID) {
- while (srv_iter_envelopes(argv[0].u.u_msgid, &evp)) {
- srv_send(IMSG_CTL_RESUME_EVP, &evp.id, sizeof(evp.id));
- srv_check_result();
- }
- } else {
- srv_send(IMSG_CTL_RESUME_EVP, &argv[0].u.u_evpid, sizeof(evp.id));
- srv_check_result();
- }
+ srv_foreach_envelope(argv, IMSG_CTL_RESUME_EVP, &total, &ok);
+ printf("%zu envelope%s resumed\n", ok, (ok > 1) ? "s" : "");
return (0);
}
@@ -484,14 +529,14 @@ static int
do_resume_mda(int argc, struct parameter *argv)
{
srv_send(IMSG_CTL_RESUME_MDA, NULL, 0);
- return srv_check_result();
+ return srv_check_result(1);
}
static int
do_resume_mta(int argc, struct parameter *argv)
{
srv_send(IMSG_CTL_RESUME_MTA, NULL, 0);
- return srv_check_result();
+ return srv_check_result(1);
}
static int
@@ -505,40 +550,23 @@ do_resume_route(int argc, struct parameter *argv)
v = argv[0].u.u_routeid;
srv_send(IMSG_CTL_RESUME_ROUTE, &v, sizeof(v));
- return srv_check_result();
+ return srv_check_result(1);
}
static int
do_resume_smtp(int argc, struct parameter *argv)
{
srv_send(IMSG_CTL_RESUME_SMTP, NULL, 0);
- return srv_check_result();
+ return srv_check_result(1);
}
static int
do_schedule(int argc, struct parameter *argv)
{
- struct envelope evp;
- uint32_t msgid;
+ size_t total, ok;
- if (argc == 0) {
- while (srv_iter_messages(&msgid)) {
- while (srv_iter_envelopes(msgid, &evp)) {
- srv_send(IMSG_CTL_SCHEDULE, &evp.id,
- sizeof(evp.id));
- srv_check_result();
- }
- }
-
- } else if (argv[0].type == P_MSGID) {
- while (srv_iter_envelopes(argv[0].u.u_msgid, &evp)) {
- srv_send(IMSG_CTL_SCHEDULE, &evp.id, sizeof(evp.id));
- srv_check_result();
- }
- } else {
- srv_send(IMSG_CTL_SCHEDULE, &argv[0].u.u_evpid, sizeof(evp.id));
- srv_check_result();
- }
+ srv_foreach_envelope(argv, IMSG_CTL_SCHEDULE, &total, &ok);
+ printf("%zu envelope%s scheduled\n", ok, (ok > 1) ? "s" : "");
return (0);
}
@@ -564,16 +592,7 @@ do_show_envelope(int argc, struct parameter *argv)
static int
do_show_hoststats(int argc, struct parameter *argv)
{
- srv_send(IMSG_CTL_MTA_SHOW_HOSTSTATS, NULL, 0);
-
- do {
- srv_recv(IMSG_CTL_MTA_SHOW_HOSTSTATS);
- if (rlen) {
- printf("%s\n", rdata);
- srv_read(NULL, rlen);
- }
- srv_end();
- } while (rlen);
+ srv_show_cmd(IMSG_CTL_MTA_SHOW_HOSTSTATS, NULL, 0);
return (0);
}
@@ -662,16 +681,7 @@ do_show_queue(int argc, struct parameter *argv)
static int
do_show_routes(int argc, struct parameter *argv)
{
- srv_send(IMSG_CTL_MTA_SHOW_ROUTES, NULL, 0);
-
- do {
- srv_recv(IMSG_CTL_MTA_SHOW_ROUTES);
- if (rlen) {
- printf("%s\n", rdata);
- srv_read(NULL, rlen);
- }
- srv_end();
- } while (rlen);
+ srv_show_cmd(IMSG_CTL_MTA_SHOW_ROUTES, NULL, 0);
return (0);
}
@@ -732,7 +742,7 @@ static int
do_stop(int argc, struct parameter *argv)
{
srv_send(IMSG_CTL_SHUTDOWN, NULL, 0);
- return srv_check_result();
+ return srv_check_result(1);
}
static int
@@ -743,7 +753,7 @@ do_trace(int argc, struct parameter *argv)
v = str_to_trace(argv[0].u.u_str);
srv_send(IMSG_CTL_TRACE, &v, sizeof(v));
- return srv_check_result();
+ return srv_check_result(1);
}
static int
@@ -754,7 +764,7 @@ do_unprofile(int argc, struct parameter *argv)
v = str_to_profile(argv[0].u.u_str);
srv_send(IMSG_CTL_UNPROFILE, &v, sizeof(v));
- return srv_check_result();
+ return srv_check_result(1);
}
static int
@@ -765,7 +775,7 @@ do_untrace(int argc, struct parameter *argv)
v = str_to_trace(argv[0].u.u_str);
srv_send(IMSG_CTL_UNTRACE, &v, sizeof(v));
- return srv_check_result();
+ return srv_check_result(1);
}
static int
@@ -774,7 +784,7 @@ do_update_table(int argc, struct parameter *argv)
const char *name = argv[0].u.u_str;
srv_send(IMSG_LKA_UPDATE_TABLE, name, strlen(name) + 1);
- return srv_check_result();
+ return srv_check_result(1);
}
int
@@ -937,9 +947,10 @@ show_offline_envelope(uint64_t evpid)
if (fp == NULL)
goto end;
- buflen = fread(buffer, 1, sizeof buffer, fp);
+ buflen = fread(buffer, 1, sizeof (buffer) - 1, fp);
p = buffer;
plen = buflen;
+ buffer[buflen] = '\0';
if (is_encrypted_buffer(p)) {
warnx("offline encrypted queue is not supported yet");
@@ -1003,10 +1014,11 @@ display(const char *s)
fclose(fp);
fp = ofp;
- fseek(fp, SEEK_SET, 0);
+ fseek(fp, 0, SEEK_SET);
}
gzipped = is_gzip_fp(fp);
+ lseek(fileno(fp), 0, SEEK_SET);
(void)dup2(fileno(fp), STDIN_FILENO);
if (gzipped)
execl(PATH_GZCAT, gzcat_argv0, NULL);
@@ -1080,7 +1092,7 @@ is_gzip_fp(FILE *fp)
ret = is_gzip_buffer((const char *)&magic);
end:
- fseek(fp, SEEK_SET, 0);
+ fseek(fp, 0, SEEK_SET);
return ret;
}
@@ -1114,6 +1126,6 @@ is_encrypted_fp(FILE *fp)
ret = is_encrypted_buffer((const char *)&magic);
end:
- fseek(fp, SEEK_SET, 0);
+ fseek(fp, 0, SEEK_SET);
return ret;
}