summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2009-02-24 12:07:48 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2009-02-24 12:07:48 +0000
commit0c89a3940f4f8cf8eec242b429efdb56d5dd0d9c (patch)
tree29fda27767efe0824b69dd9cc07f9e8dd30655a0
parentdb0fede20cc5ec4218ba8e31beb66d6950ff87bb (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.c33
-rw-r--r--usr.sbin/smtpd/parser.c25
-rw-r--r--usr.sbin/smtpd/parser.h4
-rw-r--r--usr.sbin/smtpd/queue_shared.c4
-rw-r--r--usr.sbin/smtpd/runner.c66
-rw-r--r--usr.sbin/smtpd/smtpctl.c14
-rw-r--r--usr.sbin/smtpd/smtpd.h12
-rw-r--r--usr.sbin/smtpd/util.c2
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>