diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2013-10-25 18:58:11 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2013-10-25 18:58:11 +0000 |
commit | c916cfb2bbc330d4419049d33e5888b3f427e48e (patch) | |
tree | 41a6a46c58262b70e4de44ceaafa404dacc1bdb5 /usr.sbin/smtpd/smtpctl.c | |
parent | bee20e9a4e2f481f6762d7a8ccc33627df1c9893 (diff) |
Improve reporting in smtpctl and a few fixes.
When sending a request to the scheduler, wait for the success/failure
report from the scheduler. Simplify the code by introducing generic
functions for interruptible iteration over envelopes. Report the total
number of affected envelopes for schedule, pause, resume and remove
envelope operations.
Diffstat (limited to 'usr.sbin/smtpd/smtpctl.c')
-rw-r--r-- | usr.sbin/smtpd/smtpctl.c | 260 |
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; } |