[PATCHv3 2/4] Change vacation day to seconds

Philipp Hahn hahn at univention.de
Mon May 7 12:27:33 EDT 2012


In preparation for RFC6131 (draft-ietf-sieve-vacation-seconds) change
the vacation time from days to seconds.

Signed-off-by: Philipp Hahn <hahn at univention.de>
---
 imap/lmtp_sieve.c       |    6 +++---
 lib/times.h             |    3 +++
 sieve/bc_dump.c         |    4 +++-
 sieve/bc_emit.c         |    4 ++--
 sieve/bc_eval.c         |   14 +++++++++++---
 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 +-
 15 files changed, 60 insertions(+), 38 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_eval.c b/sieve/bc_eval.c
index 03512ce..a822a24 100644
--- a/sieve/bc_eval.c
+++ b/sieve/bc_eval.c
@@ -60,6 +60,7 @@
 #include "xstrlcpy.h"
 #include "xstrlcat.h"
 #include "util.h"
+#include "times.h"
 
 #include <string.h>
 #include <ctype.h>
@@ -1267,6 +1268,7 @@ int sieve_eval_bc(sieve_execute_t *exe, int is_incl, sieve_interp_t *i,
 	    
 	    break;
 	}
+	case B_VACATION_ORIG:
 	case B_VACATION:
 	{
 	    int respond;
@@ -1274,7 +1276,7 @@ int sieve_eval_bc(sieve_execute_t *exe, int is_incl, sieve_interp_t *i,
 	    char *toaddr = NULL; /* relative to message we send */
 	    const char *handle = NULL;
 	    const char *message = NULL;
-	    int days, mime;
+	    int seconds, mime;
 	    char buf[128];
 	    char subject[1024];
 	    int x;
@@ -1311,7 +1313,13 @@ int sieve_eval_bc(sieve_execute_t *exe, int is_incl, sieve_interp_t *i,
 
 		ip = unwrap_string(bc, ip, &message, NULL);
 
-		days = ntohl(bc[ip].value);
+		if (op == B_VACATION_ORIG) {
+		    int days;
+		    days = ntohl(bc[ip].value);
+		    seconds = days * DAY2SEC;
+		} else {
+		    seconds = ntohl(bc[ip].value);
+		}
 		mime = ntohl(bc[ip+1].value);
 
 		ip+=2;
@@ -1334,7 +1342,7 @@ int sieve_eval_bc(sieve_execute_t *exe, int is_incl, sieve_interp_t *i,
 		}
 
 		res = do_vacation(actions, toaddr, fromaddr, xstrdup(subject),
-				  message, days, mime, handle);
+				  message, seconds, mime, handle);
 
 		if (res == SIEVE_RUN_ERROR)
 		    *errmsg = "Vacation can not be used with Reject or Vacation";
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



More information about the Cyrus-devel mailing list