diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-02-24 12:07:48 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-02-24 12:07:48 +0000 |
commit | 0c89a3940f4f8cf8eec242b429efdb56d5dd0d9c (patch) | |
tree | 29fda27767efe0824b69dd9cc07f9e8dd30655a0 | |
parent | db0fede20cc5ec4218ba8e31beb66d6950ff87bb (diff) |
teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>
introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.
F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue
-rw-r--r-- | usr.sbin/smtpd/control.c | 33 | ||||
-rw-r--r-- | usr.sbin/smtpd/parser.c | 25 | ||||
-rw-r--r-- | usr.sbin/smtpd/parser.h | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_shared.c | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/runner.c | 66 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpctl.c | 14 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 12 | ||||
-rw-r--r-- | usr.sbin/smtpd/util.c | 2 |
8 files changed, 150 insertions, 10 deletions
diff --git a/usr.sbin/smtpd/control.c b/usr.sbin/smtpd/control.c index 56e70fcb40a..ccc7a5155b8 100644 --- a/usr.sbin/smtpd/control.c +++ b/usr.sbin/smtpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.15 2009/02/22 19:07:33 chl Exp $ */ +/* $OpenBSD: control.c,v 1.16 2009/02/24 12:07:47 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -361,6 +361,21 @@ control_dispatch_ext(int fd, short event, void *arg) break; } + case IMSG_RUNNER_SCHEDULE: { + struct sched s; + + s = *(struct sched *)imsg.data; + s.fd = fd; + + if (! valid_message_id(s.mid) && ! valid_message_uid(s.mid)) { + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, + NULL, 0); + break; + } + + imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_RUNNER_SCHEDULE, 0, 0, -1, &s, sizeof(s)); + break; + } case IMSG_CTL_SHUTDOWN: /* NEEDS_FIX */ log_debug("received shutdown request"); @@ -847,6 +862,22 @@ control_dispatch_runner(int sig, short event, void *p) break; } + case IMSG_RUNNER_SCHEDULE: { + struct sched *s; + struct ctl_conn *c; + + s = imsg.data; + if ((c = control_connbyfd(s->fd)) == NULL) { + log_warn("control_dispatch_runner: fd %d not found", s->fd); + return; + } + + if (s->ret) + imsg_compose(&c->ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + else + imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); + break; + } default: log_debug("control_dispatch_runner: unexpected imsg %d", imsg.hdr.type); diff --git a/usr.sbin/smtpd/parser.c b/usr.sbin/smtpd/parser.c index 54386cb678d..d160df08966 100644 --- a/usr.sbin/smtpd/parser.c +++ b/usr.sbin/smtpd/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.6 2009/01/29 21:59:15 jacekm Exp $ */ +/* $OpenBSD: parser.c,v 1.7 2009/02/24 12:07:47 gilles Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -44,7 +44,8 @@ enum token_type { NOTOKEN, ENDTOKEN, - KEYWORD + KEYWORD, + VARIABLE }; struct token { @@ -58,6 +59,7 @@ static const struct token t_main[]; static const struct token t_show[]; static const struct token t_pause[]; static const struct token t_resume[]; +static const struct token t_schedule[]; static const struct token t_main[] = { {KEYWORD, "show", NONE, t_show}, @@ -66,6 +68,7 @@ static const struct token t_main[] = { {KEYWORD, "reload", RELOAD, NULL}, {KEYWORD, "resume", NONE, t_resume}, {KEYWORD, "stop", SHUTDOWN, NULL}, + {KEYWORD, "schedule", SCHEDULE, t_schedule}, {ENDTOKEN, "", NONE, NULL} }; @@ -90,6 +93,11 @@ static const struct token t_resume[] = { {ENDTOKEN, "", NONE, NULL} }; +static const struct token t_schedule[] = { + {VARIABLE, "message id/uid", SCHEDULE, NULL}, + {ENDTOKEN, "", NONE, NULL} +}; + static struct parse_result res; struct parse_result * @@ -149,6 +157,16 @@ match_token(const char *word, const struct token table[]) res.action = t->value; } break; + case VARIABLE: + if (word != NULL && strlen(word) != 0) { + match++; + t = &table[i]; + if (t->value) { + res.action = t->value; + res.data = word; + } + } + break; case ENDTOKEN: break; } @@ -180,6 +198,9 @@ show_valid_args(const struct token table[]) case KEYWORD: fprintf(stderr, " %s\n", table[i].keyword); break; + case VARIABLE: + 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 index 21d4e517b1b..bdee8ddfbbe 100644 --- a/usr.sbin/smtpd/parser.h +++ b/usr.sbin/smtpd/parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.h,v 1.6 2009/01/29 21:59:15 jacekm Exp $ */ +/* $OpenBSD: parser.h,v 1.7 2009/02/24 12:07:47 gilles Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -21,6 +21,7 @@ enum actions { SHUTDOWN, RELOAD, MONITOR, + SCHEDULE, SHOW_QUEUE, SHOW_RUNQUEUE, SHOW_STATS, @@ -35,6 +36,7 @@ enum actions { struct parse_result { struct ctl_id id; enum actions action; + const char *data; }; struct parse_result *parse(int, char *[]); diff --git a/usr.sbin/smtpd/queue_shared.c b/usr.sbin/smtpd/queue_shared.c index bd707445c7c..2687c0a6c3c 100644 --- a/usr.sbin/smtpd/queue_shared.c +++ b/usr.sbin/smtpd/queue_shared.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_shared.c,v 1.13 2009/02/23 00:51:32 chl Exp $ */ +/* $OpenBSD: queue_shared.c,v 1.14 2009/02/24 12:07:47 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -702,6 +702,8 @@ display_envelope(struct message *envelope, int flags) status, sizeof(status)); getflag(&envelope->flags, F_MESSAGE_SCHEDULED, "SCHEDULED", status, sizeof(status)); + getflag(&envelope->flags, F_MESSAGE_ENQUEUED, "ENQUEUED", + status, sizeof(status)); if (envelope->flags) errx(1, "%s: unexpected flags 0x%04x", envelope->message_uid, diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c index 378eec8b154..38425e0efca 100644 --- a/usr.sbin/smtpd/runner.c +++ b/usr.sbin/smtpd/runner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: runner.c,v 1.32 2009/02/22 23:29:54 jacekm Exp $ */ +/* $OpenBSD: runner.c,v 1.33 2009/02/24 12:07:47 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -77,6 +77,9 @@ int runner_check_loop(struct message *); struct batch *batch_record(struct smtpd *, struct message *); struct batch *batch_lookup(struct smtpd *, struct message *); +int runner_force_envelope_schedule(char *); +int runner_force_message_schedule(char *); + struct s_runner s_runner; void @@ -148,6 +151,20 @@ runner_dispatch_control(int sig, short event, void *p) imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, s, sizeof(*s)); break; } + case IMSG_RUNNER_SCHEDULE: { + struct sched *s; + + s = imsg.data; + + s->ret = 0; + if (valid_message_uid(s->mid)) + s->ret = runner_force_envelope_schedule(s->mid); + else if (valid_message_id(s->mid)) + s->ret = runner_force_message_schedule(s->mid); + + imsg_compose(ibuf, IMSG_RUNNER_SCHEDULE, 0, 0, -1, s, sizeof(*s)); + break; + } default: log_debug("queue_dispatch_control: unexpected imsg %d", imsg.hdr.type); @@ -519,6 +536,7 @@ runner_process_queue(struct smtpd *env) runner_check_loop(&message); message.flags |= F_MESSAGE_SCHEDULED; + message.flags &= ~F_MESSAGE_FORCESCHEDULE; queue_update_envelope(&message); if (! bsnprintf(rqpath, sizeof(rqpath), "%s/%s", PATH_RUNQUEUE, @@ -710,6 +728,9 @@ runner_message_schedule(struct message *messagep, time_t tm) if (messagep->flags & (F_MESSAGE_SCHEDULED|F_MESSAGE_PROCESSING)) return 0; + if (messagep->flags & F_MESSAGE_FORCESCHEDULE) + return 1; + /* Batch has been in the queue for too long and expired */ if (tm - messagep->creation >= SMTPD_QUEUE_EXPIRY) { queue_remove_envelope(messagep); @@ -752,6 +773,49 @@ runner_message_schedule(struct message *messagep, time_t tm) return 0; } +int +runner_force_envelope_schedule(char *mid) +{ + struct message message; + + if (! queue_load_envelope(&message, mid)) + return 0; + + if (! message.flags & (F_MESSAGE_PROCESSING|F_MESSAGE_SCHEDULED)) + return 1; + + message.flags |= F_MESSAGE_FORCESCHEDULE; + + if (! queue_update_envelope(&message)) + return 0; + + return 1; +} + +int +runner_force_message_schedule(char *mid) +{ + char path[MAXPATHLEN]; + DIR *dirp; + struct dirent *dp; + + if (! bsnprintf(path, MAXPATHLEN, "%s/%d/%s/envelopes", + PATH_QUEUE, queue_hash(mid), mid)) + return 0; + + dirp = opendir(path); + if (dirp == NULL) + return 0; + + while ((dp = readdir(dirp)) != NULL) { + if (valid_message_uid(dp->d_name)) + runner_force_envelope_schedule(dp->d_name); + } + closedir(dirp); + + return 1; +} + void runner_purge_run(void) { diff --git a/usr.sbin/smtpd/smtpctl.c b/usr.sbin/smtpd/smtpctl.c index be79ed772c4..9f684dc6679 100644 --- a/usr.sbin/smtpd/smtpctl.c +++ b/usr.sbin/smtpd/smtpctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpctl.c,v 1.14 2009/02/17 22:49:22 jacekm Exp $ */ +/* $OpenBSD: smtpctl.c,v 1.15 2009/02/24 12:07:47 gilles Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -47,6 +47,7 @@ int show_command_output(struct imsg*); int show_stats_output(struct imsg *); int enqueue(int, char **); +/* struct imsgname { int type; char *name; @@ -61,6 +62,7 @@ struct imsgname imsgs[] = { struct imsgname imsgunknown = { -1, "<unknown>", NULL }; +*/ int proctype; struct imsgbuf *ibuf; @@ -172,6 +174,15 @@ connected: case SHOW_STATS: imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, NULL, 0); break; + case SCHEDULE: { + struct sched s; + + s.fd = -1; + bzero(s.mid, sizeof (s.mid)); + strlcpy(s.mid, res->data, sizeof (s.mid)); + imsg_compose(ibuf, IMSG_RUNNER_SCHEDULE, 0, 0, -1, &s, sizeof (s)); + break; + } case MONITOR: /* XXX */ break; @@ -197,6 +208,7 @@ connected: switch(res->action) { case RELOAD: case SHUTDOWN: + case SCHEDULE: case PAUSE_MDA: case PAUSE_MTA: case PAUSE_SMTP: diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 22b007aa6b5..03a25282a46 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.76 2009/02/23 22:59:40 gilles Exp $ */ +/* $OpenBSD: smtpd.h,v 1.77 2009/02/24 12:07:47 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -189,6 +189,7 @@ enum imsg_type { IMSG_RUNNER_UPDATE_ENVELOPE, IMSG_RUNNER_STATS, + IMSG_RUNNER_SCHEDULE, IMSG_BATCH_CREATE, IMSG_BATCH_APPEND, @@ -415,7 +416,8 @@ enum message_flags { F_MESSAGE_SCHEDULED = 0x2, F_MESSAGE_PROCESSING = 0x4, F_MESSAGE_AUTHENTICATED = 0x8, - F_MESSAGE_ENQUEUED = 0x10 + F_MESSAGE_ENQUEUED = 0x10, + F_MESSAGE_FORCESCHEDULE = 0x20 }; struct message { @@ -681,6 +683,12 @@ struct stats { } u; }; +struct sched { + int fd; + char mid[MAX_ID_SIZE]; + int ret; +}; + struct submit_status { u_int64_t id; int code; diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c index 803b1bf821e..05c5c7bc74e 100644 --- a/usr.sbin/smtpd/util.c +++ b/usr.sbin/smtpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.14 2009/02/23 22:59:40 gilles Exp $ */ +/* $OpenBSD: util.c,v 1.15 2009/02/24 12:07:47 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> |