In preparation for RFC6131 (draft-ietf-sieve-vacation-seconds) change the vacation time from days to seconds.
Signed-off-by: Philipp Hahn <h...@univention.de> --- imap/lmtp_sieve.c | 6 +++--- lib/times.h | 3 +++ sieve/bc_dump.c | 4 +++- sieve/bc_emit.c | 4 ++-- sieve/bc_generate.c | 4 ++-- sieve/bytecode.h | 9 ++++++--- sieve/interp.c | 7 ++++--- sieve/message.c | 4 ++-- sieve/message.h | 2 +- sieve/sieve.y | 21 +++++++++++---------- sieve/sieve_interface.h | 6 +++--- sieve/sieved.c | 9 ++++++--- sieve/test.c | 3 ++- sieve/tree.h | 2 +- 14 files changed, 49 insertions(+), 35 deletions(-) diff --git a/imap/lmtp_sieve.c b/imap/lmtp_sieve.c index d6a8846..9ebedb8 100644 --- a/imap/lmtp_sieve.c +++ b/imap/lmtp_sieve.c @@ -607,7 +607,7 @@ static int autorespond(void *ac, } if (ret == SIEVE_OK) { - duplicate_mark(&dkey, now + arc->days * (24 * 60 * 60), 0); + duplicate_mark(&dkey, now + arc->seconds, 0); } free(id); @@ -706,8 +706,8 @@ static int send_response(void *ac, /* vacation support */ sieve_vacation_t vacation = { - 1, /* min response */ - 31, /* max response */ + 1 * DAY2SEC, /* min response */ + 31 * DAY2SEC, /* max response */ &autorespond, /* autorespond() */ &send_response, /* send_response() */ }; diff --git a/lib/times.h b/lib/times.h index b2a27ed..ba7e363 100644 --- a/lib/times.h +++ b/lib/times.h @@ -45,6 +45,9 @@ #include <time.h> +/* Factor for converting days to seconds. */ +#define DAY2SEC (24 * 60 * 60) + /* * RFC822 datetime format */ diff --git a/sieve/bc_dump.c b/sieve/bc_dump.c index 94801dd..a3cf00e 100644 --- a/sieve/bc_dump.c +++ b/sieve/bc_dump.c @@ -314,14 +314,16 @@ void dump(bytecode_info_t *d, int level) i+=3; break; + case B_VACATION_ORIG: case B_VACATION: printf("%d:VACATION\n",i); i++; i=dump_sl(d,i,level); - printf("SUBJ({%d}%s) MESG({%d}%s)\n DAYS(%d) MIME(%d)\n" + printf("SUBJ({%d}%s) MESG({%d}%s)\n %s(%d) MIME(%d)\n" " FROM({%d}%s) HANDLE({%d}%s)\n", d->data[i+1].len, (d->data[i+1].len == -1 ? "[nil]" : d->data[i+2].str), d->data[i+3].len, (d->data[i+3].len == -1 ? "[nil]" : d->data[i+4].str), + d->data[i].op == B_VACATION_ORIG ? "DAYS" : "SECONDS", d->data[i+5].value, d->data[i+6].value, d->data[i+7].len, (d->data[i+7].len == -1 ? "[nil]" : d->data[i+8].str), d->data[i+9].len, (d->data[i+9].len == -1 ? "[nil]" : d->data[i+10].str)); diff --git a/sieve/bc_emit.c b/sieve/bc_emit.c index f30f188..e0bb236 100644 --- a/sieve/bc_emit.c +++ b/sieve/bc_emit.c @@ -669,7 +669,7 @@ static int bc_action_emit(int fd, int codep, int stopcodep, break; case B_VACATION: /* Address list, Subject String, Message String, - Days (word), Mime (word), From String, Handle String */ + Seconds (word), Mime (word), From String, Handle String */ /*new code-this might be broken*/ ret = bc_stringlist_emit(fd, &codep, bc); @@ -705,7 +705,7 @@ static int bc_action_emit(int fd, int codep, int stopcodep, } } - /* Days*/ + /* Seconds*/ if(write_int(fd,bc->data[codep].value) == -1) return -1; codep++; diff --git a/sieve/bc_generate.c b/sieve/bc_generate.c index 39948f5..5c070e7 100644 --- a/sieve/bc_generate.c +++ b/sieve/bc_generate.c @@ -651,7 +651,7 @@ static int bc_action_generate(int codep, bytecode_info_t *retval, STRINGLIST addresses STRING subject (if len is -1, then subject was NULL) STRING message (again, len == -1 means message was NULL) - VALUE days + VALUE seconds VALUE mime STRING from (if len is -1, then from was NULL) STRING handle (again, len == -1 means handle was NULL) @@ -684,7 +684,7 @@ static int bc_action_generate(int codep, bytecode_info_t *retval, } if (!atleast(retval, codep+2)) return -1; - retval->data[codep++].value = c->u.v.days; + retval->data[codep++].value = c->u.v.seconds; retval->data[codep++].value = c->u.v.mime; if (!atleast(retval, codep+2)) return -1; diff --git a/sieve/bytecode.h b/sieve/bytecode.h index 5b5e262..37954e0 100644 --- a/sieve/bytecode.h +++ b/sieve/bytecode.h @@ -96,8 +96,9 @@ typedef union * version 0x03 scripts implemented short-circuiting of testlists (recompile) * version 0x04 scripts implemented BODY, INCLUDE and COPY extensions * version 0x05 scripts implemented updated VACATION (:from and :handle) + * version 0x06 scripts implemented updated VACATION (:seconds) */ -#define BYTECODE_VERSION 0x05 +#define BYTECODE_VERSION 0x06 #define BYTECODE_MIN_VERSION 0x03 /* minimum supported version */ #define BYTECODE_MAGIC "CyrSBytecode" #define BYTECODE_MAGIC_LEN 12 /* Should be multiple of 4 */ @@ -127,7 +128,7 @@ enum bytecode { B_NOTIFY, /* require notify */ B_DENOTIFY, /* require notify */ - B_VACATION, /* require vacation */ + B_VACATION_ORIG, /* legacy vacation w/o support for :seconds */ B_NULL, B_JUMP, @@ -135,7 +136,9 @@ enum bytecode { B_RETURN, /* require include */ B_FILEINTO, /* require fileinto */ - B_REDIRECT + B_REDIRECT, + + B_VACATION, /* require vacation */ }; enum bytecode_comps { diff --git a/sieve/interp.c b/sieve/interp.c index cd99dda..3c4b8bf 100644 --- a/sieve/interp.c +++ b/sieve/interp.c @@ -56,6 +56,7 @@ #include "sieve_interface.h" #include "interp.h" #include "libconfig.h" +#include "times.h" #define EXT_LEN 4096 @@ -255,9 +256,9 @@ int sieve_register_vacation(sieve_interp_t *interp, sieve_vacation_t *v) return SIEVE_NOT_FINALIZED; /* we need envelope for vacation! */ } - if (v->min_response == 0) v->min_response = 3; - if (v->max_response == 0) v->max_response = 90; - if (v->min_response < 0 || v->max_response < 7 || !v->autorespond + if (v->min_response == 0) v->min_response = 3 * DAY2SEC; + if (v->max_response == 0) v->max_response = 90 * DAY2SEC; + if (v->min_response < 0 || v->max_response < 7 * DAY2SEC || !v->autorespond || !v->send_response) { return SIEVE_FAIL; } diff --git a/sieve/message.c b/sieve/message.c index 86af6dc..f992609 100644 --- a/sieve/message.c +++ b/sieve/message.c @@ -235,7 +235,7 @@ static int makehash(unsigned char hash[], } int do_vacation(action_list_t *a, char *addr, char *fromaddr, - char *subj, const char *msg, int days, + char *subj, const char *msg, int seconds, int mime, const char *handle) { action_list_t *b = NULL; @@ -264,7 +264,7 @@ int do_vacation(action_list_t *a, char *addr, char *fromaddr, makehash(a->u.vac.autoresp.hash, addr, handle, NULL); else makehash(a->u.vac.autoresp.hash, addr, fromaddr, msg); - a->u.vac.autoresp.days = days; + a->u.vac.autoresp.seconds = seconds; a->next = NULL; b->next = a; return 0; diff --git a/sieve/message.h b/sieve/message.h index fb7504e..5b0613b 100644 --- a/sieve/message.h +++ b/sieve/message.h @@ -124,7 +124,7 @@ int do_redirect(action_list_t *m, const char *addr, int cancel_keep); int do_keep(action_list_t *m, strarray_t *imapflags); int do_discard(action_list_t *m); int do_vacation(action_list_t *m, char *addr, char *fromaddr, - char *subj, const char *msg, int days, int mime, + char *subj, const char *msg, int seconds, int mime, const char *handle); int do_setflag(action_list_t *m, const char *flag); int do_addflag(action_list_t *m, const char *flag); diff --git a/sieve/sieve.y b/sieve/sieve.y index cc2ead4..84542d8 100644 --- a/sieve/sieve.y +++ b/sieve/sieve.y @@ -62,6 +62,7 @@ #include "util.h" #include "imparse.h" #include "libconfig.h" +#include "times.h" #define ERR_BUF_SIZE 1024 @@ -71,7 +72,7 @@ char errbuf[ERR_BUF_SIZE]; extern int addrparse(void); struct vtags { - int days; + int seconds; strarray_t *addresses; char *subject; char *from; @@ -412,9 +413,9 @@ priority: LOW { $$ = LOW; } ; vtags: /* empty */ { $$ = new_vtags(); } - | vtags DAYS NUMBER { if ($$->days != -1) { + | vtags DAYS NUMBER { if ($$->seconds != -1) { yyerror("duplicate :days"); YYERROR; } - else { $$->days = $3; } } + else { $$->seconds = $3 * DAY2SEC; } } | vtags ADDRESSES stringlist { if ($$->addresses != NULL) { yyerror("duplicate :addresses"); YYERROR; @@ -831,7 +832,7 @@ static commandlist_t *build_vacation(int t, struct vtags *v, char *reason) ret->u.v.subject = v->subject; v->subject = NULL; ret->u.v.from = v->from; v->from = NULL; ret->u.v.handle = v->handle; v->handle = NULL; - ret->u.v.days = v->days; + ret->u.v.seconds = v->seconds; ret->u.v.mime = v->mime; ret->u.v.addresses = v->addresses; v->addresses = NULL; free_vtags(v); @@ -996,7 +997,7 @@ static struct vtags *new_vtags(void) { struct vtags *r = (struct vtags *) xmalloc(sizeof(struct vtags)); - r->days = -1; + r->seconds = -1; r->addresses = NULL; r->subject = NULL; r->from = NULL; @@ -1010,11 +1011,11 @@ static struct vtags *canon_vtags(struct vtags *v) { assert(parse_script->interp.vacation != NULL); - if (v->days == -1) { v->days = 7; } - if (v->days < parse_script->interp.vacation->min_response) - { v->days = parse_script->interp.vacation->min_response; } - if (v->days > parse_script->interp.vacation->max_response) - { v->days = parse_script->interp.vacation->max_response; } + if (v->seconds == -1) { v->seconds = 7 * DAY2SEC; } + if (v->seconds < parse_script->interp.vacation->min_response) + { v->seconds = parse_script->interp.vacation->min_response; } + if (v->seconds > parse_script->interp.vacation->max_response) + { v->seconds = parse_script->interp.vacation->max_response; } if (v->mime == -1) { v->mime = 0; } return v; diff --git a/sieve/sieve_interface.h b/sieve/sieve_interface.h index 61b0410..35bb88f 100644 --- a/sieve/sieve_interface.h +++ b/sieve/sieve_interface.h @@ -84,8 +84,8 @@ typedef int sieve_get_body(void *message_context, const char **content_types, sieve_bodypart_t ***parts); typedef struct sieve_vacation { - int min_response; /* 0 -> defaults to 3 */ - int max_response; /* 0 -> defaults to 90 */ + int min_response; /* 0 -> defaults to 3 days */ + int max_response; /* 0 -> defaults to 90 days */ /* given a hash, say whether we've already responded to it in the last days days. return SIEVE_OK if we SHOULD autorespond (have not already) @@ -127,7 +127,7 @@ typedef struct sieve_notify_context { typedef struct sieve_autorespond_context { unsigned char hash[SIEVE_HASHLEN]; - int days; + int seconds; } sieve_autorespond_context_t; typedef struct sieve_send_response_context { diff --git a/sieve/sieved.c b/sieve/sieved.c index 0727ddf..965c7b1 100644 --- a/sieve/sieved.c +++ b/sieve/sieved.c @@ -356,11 +356,13 @@ static void dump2(bytecode_input_t *d, int bc_len) for(i++; i<bc_len;) { + int op; int copy = 0; printf("%d: ",i); - switch(ntohl(d[i++].op)) { + op = ntohl(d[i++].op); + switch (op) { case B_STOP:/*0*/ printf("STOP\n"); @@ -459,7 +461,8 @@ static void dump2(bytecode_input_t *d, int bc_len) break; - case B_VACATION:/*14*/ + case B_VACATION_ORIG:/*14*/ + case B_VACATION:/*22*/ printf("VACATION\n"); /*add address list here!*/ i=write_list(ntohl(d[i].len),i+1,d); @@ -472,7 +475,7 @@ static void dump2(bytecode_input_t *d, int bc_len) printf("%d MESG({%d}%s) \n", i, len, (!data ? "[nil]" : data)); - printf("DAYS(%d) MIME(%d)\n", ntohl(d[i].value), ntohl(d[i+1].value)); + printf("%s(%d) MIME(%d)\n", op == B_VACATION_ORIG ? "DAYS" : "SECONDS", ntohl(d[i].value), ntohl(d[i+1].value)); i+=2; if (version >= 0x05) { diff --git a/sieve/test.c b/sieve/test.c index c88bd0d..bdabc14 100644 --- a/sieve/test.c +++ b/sieve/test.c @@ -74,6 +74,7 @@ #include "xstrlcpy.h" #include "strarray.h" #include "hash.h" +#include "times.h" char vacation_answer; @@ -467,7 +468,7 @@ static int autorespond(void *ac, void *ic __attribute__((unused)), for (i = 0; i < SIEVE_HASHLEN; i++) { printf("%x", arc->hash[i]); } - printf("' in %d days? ", arc->days); + printf("' in %d days? ", arc->seconds / DAY2SEC); scanf(" %c", &yn); } diff --git a/sieve/tree.h b/sieve/tree.h index 6f5c205..ef70721 100644 --- a/sieve/tree.h +++ b/sieve/tree.h @@ -136,7 +136,7 @@ struct Commandlist { } r; struct { /* it's a vacation action */ char *subject; - int days; + int seconds; strarray_t *addresses; char *message; char *from; -- 1.7.1