Projects
Kolab:3.4
cyrus-imapd
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 93
View file
cyrus-imapd.spec
Changed
@@ -38,13 +38,13 @@ Name: cyrus-imapd Summary: A high-performance mail server with IMAP, POP3, NNTP and SIEVE support Version: 2.5 -Release: 0.1.dev20140813.git3d45146a%{?dist} +Release: 0.1.dev20140829.gitb2ef80be%{?dist} License: BSD Group: System Environment/Daemons URL: http://www.cyrusimap.org # Upstream sources -# From 3d45146a7befa1651d46a4db381fb10be40e53ee +# From b2ef80bee2102d0eadf280c6c23b5759920d1752 Source0: ftp://ftp.andrew.cmu.edu/pub/cyrus/%{_name}-%{real_version}%{?dot_snapshot_version}.tar.gz Source1: cyrus-imapd.imap-2.3.x-conf Source2: cyrus-imapd.cvt_cyrusdb_all @@ -744,6 +744,10 @@ %{_libdir}/*.la %changelog +* Fri Aug 29 2014 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 2.5-9.git +- Snapshot of (b2ef80be) +- Merge enhanced Sieve Date and Index extension + * Mon Mar 3 2014 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 2.5-8.git - Fix shared folder deleted namespace prefix
View file
cyrus-imapd-2.5.tar.gz/cunit/sieve.testc
Changed
@@ -502,7 +502,7 @@ "partition-"PARTITION": "DBDIR"/data\n" "sievenotifier: mailto\n" "sieve_extensions: fileinto reject vacation imapflags notify" \ - " envelope body relational regex subaddress copy date\n" + " envelope body relational regex subaddress copy date index\n" ); libcyrus_init(); return 0; @@ -946,16 +946,180 @@ context_cleanup(&ctx); } +static void test_address_index(void) +{ + static const char SCRIPT = + "require \"index\";\n" + "if address :index 2 :is \"from\" \"zme@true.com\"\n" + "{redirect \"me@blah.com\";}\n" + ; + + static const char SCRIPT_LAST = + "require \"index\";\n" + "if address :index 3 :last :is \"from\" \"zme@true.com\"\n" + "{redirect \"me@blah.com\";}\n" + ; + + static const char MSG_TRUE = + "Date: Mon, 25 Jan 2003 08:51:06 -0500\r\n" + "From: zme@false.com\r\n" + "From: zme@true.com\r\n" + "From: zme@false.com\r\n" + "From: zme@false.com\r\n" + "To: you\r\n" + "Subject: simple address test\r\n" + "\r\n" + "blah\n" + ; + static const char MSG_FALSE = + "Date: Mon, 25 Jan 2003 08:51:06 -0500\r\n" + "From: zme@true.com\r\n" + "From: zme@false.com\r\n" + "From: zme@true.com\r\n" + "From: zme@true.com\r\n" + "To: you\r\n" + "Subject: simple address test\r\n" + "\r\n" + "blah\n" + ; + sieve_test_context_t ctx; + + /* Test :index */ + context_setup(&ctx, SCRIPT); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + + run_message(&ctx, MSG_TRUE); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + CU_ASSERT_EQUAL(ctx.stats.actions, 1); + CU_ASSERT_EQUAL(ctx.stats.redirects, 1); + CU_ASSERT_EQUAL(ctx.stats.keeps, 0); + CU_ASSERT_STRING_EQUAL(ctx.redirected_to, "me@blah.com"); + + run_message(&ctx, MSG_FALSE); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + CU_ASSERT_EQUAL(ctx.stats.actions, 2); + CU_ASSERT_EQUAL(ctx.stats.redirects, 1); + CU_ASSERT_EQUAL(ctx.stats.keeps, 1); + CU_ASSERT_STRING_EQUAL(ctx.redirected_to, "me@blah.com"); + + context_cleanup(&ctx); + + /* Test :index :last */ + context_setup(&ctx, SCRIPT_LAST); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + + run_message(&ctx, MSG_TRUE); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + CU_ASSERT_EQUAL(ctx.stats.actions, 1); + CU_ASSERT_EQUAL(ctx.stats.redirects, 1); + CU_ASSERT_EQUAL(ctx.stats.keeps, 0); + CU_ASSERT_STRING_EQUAL(ctx.redirected_to, "me@blah.com"); + + run_message(&ctx, MSG_FALSE); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + CU_ASSERT_EQUAL(ctx.stats.actions, 2); + CU_ASSERT_EQUAL(ctx.stats.redirects, 1); + CU_ASSERT_EQUAL(ctx.stats.keeps, 1); + CU_ASSERT_STRING_EQUAL(ctx.redirected_to, "me@blah.com"); + + context_cleanup(&ctx); +} + +static void test_header_index(void) +{ + static const char SCRIPT = + "require \"index\";\n" + "if header :index 3 :is \"X-Virus-Status\" \"Clean\"\n" + "{redirect \"me@blah.com\";}\n" + ; + + static const char SCRIPT_LAST = + "require \"index\";\n" + "if header :index 2 :last :is \"X-Virus-Status\" \"Clean\"\n" + "{redirect \"me@blah.com\";}\n" + ; + + static const char MSG_TRUE = + "Date: Mon, 25 Jan 2003 08:51:06 -0500\r\n" + "From: zme@true.com\r\n" + "To: you\r\n" + "Subject: simple address test\r\n" + "X-Virus-Status: *****\r\n" + "X-Virus-Status: *****\r\n" + "X-Virus-Status: Clean\r\n" + "X-Virus-Status: *****\r\n" + "\r\n" + "blah\n" + ; + static const char MSG_FALSE = + "Date: Mon, 25 Jan 2003 08:51:06 -0500\r\n" + "From: zme@false.com\r\n" + "To: you\r\n" + "Subject: simple address test\r\n" + "X-Virus-Status: Clean\r\n" + "X-Virus-Status: Clean\r\n" + "X-Virus-Status: *****\r\n" + "X-Virus-Status: Clean\r\n" + "\r\n" + "blah\n" + ; + sieve_test_context_t ctx; + + /* Test :index */ + context_setup(&ctx, SCRIPT); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + + run_message(&ctx, MSG_TRUE); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + CU_ASSERT_EQUAL(ctx.stats.actions, 1); + CU_ASSERT_EQUAL(ctx.stats.redirects, 1); + CU_ASSERT_EQUAL(ctx.stats.keeps, 0); + CU_ASSERT_STRING_EQUAL(ctx.redirected_to, "me@blah.com"); + + run_message(&ctx, MSG_FALSE); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + CU_ASSERT_EQUAL(ctx.stats.actions, 2); + CU_ASSERT_EQUAL(ctx.stats.redirects, 1); + CU_ASSERT_EQUAL(ctx.stats.keeps, 1); + CU_ASSERT_STRING_EQUAL(ctx.redirected_to, "me@blah.com"); + + context_cleanup(&ctx); + + /* Test :index :last */ + context_setup(&ctx, SCRIPT_LAST); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + + run_message(&ctx, MSG_TRUE); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + CU_ASSERT_EQUAL(ctx.stats.actions, 1); + CU_ASSERT_EQUAL(ctx.stats.redirects, 1); + CU_ASSERT_EQUAL(ctx.stats.keeps, 0); + CU_ASSERT_STRING_EQUAL(ctx.redirected_to, "me@blah.com"); + + run_message(&ctx, MSG_FALSE); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + CU_ASSERT_EQUAL(ctx.stats.actions, 2); + CU_ASSERT_EQUAL(ctx.stats.redirects, 1); + CU_ASSERT_EQUAL(ctx.stats.keeps, 1); + CU_ASSERT_STRING_EQUAL(ctx.redirected_to, "me@blah.com"); + + context_cleanup(&ctx); +} + static void test_date_year(void) { static const char SCRIPT = - "if date :is \"received\" \"year\" \"1983\", \"1993\", \"2003\", \"2013\" \n" + "require \"date\", \"index\";\n" + "if date :index 1 :last :is \"received\" \"year\" \"1983\", \"1993\", \"2003\", \"2013\" \n" "{redirect \"me@blah.com\";}\n" ; static const char MSG_TRUE = "Date: Sat, 16 Nov 2013 12:46:49 +1100\r\n" "Received: from localhost (localhost 127.0.0.1)\r\n" " by mail.com (Cyrus v2.3.16) with LMTPA;\r\n" + " Tue, 16 Nov 2010 12:50:12 +1100\r\n" + "Received: from localhost (localhost 127.0.0.1)\r\n" + " by mail.com (Cyrus v2.3.16) with LMTPA;\r\n" " Tue, 16 Nov 2013 12:50:12 +1100\r\n" "From: zme@true.com\r\n" "To: you\r\n" @@ -967,6 +1131,9 @@ "Date: Tue, 16 Nov 2010 12:46:49 +1100\r\n" "Received: from localhost (localhost 127.0.0.1)\r\n" " by mail.com (Cyrus v2.3.16) with LMTPA;\r\n" + " Tue, 16 Nov 2013 12:50:12 +1100\r\n" + "Received: from localhost (localhost 127.0.0.1)\r\n" + " by mail.com (Cyrus v2.3.16) with LMTPA;\r\n" " Tue, 16 Nov 2010 12:50:12 +1100\r\n" "From: yme@false.com\r\n" "To: you\r\n" @@ -999,6 +1166,7 @@ static void test_date_zone_month(void) { static const char SCRIPT = + "require \"date\";\n" "if date :is :zone \"-0800\" \"date\" \"month\" \"11\"\n" "{redirect \"me@blah.com\";}\n" ; @@ -1043,6 +1211,7 @@ static void test_date_date(void) { static const char SCRIPT = + "require \"date\";\n" "if date :is :originalzone \"date\" \"date\" \"2013-11-02\"\n" "{redirect \"me@blah.com\";}\n" ; @@ -1087,6 +1256,7 @@ static void test_date_time(void) { static const char SCRIPT = + "require \"date\";\n" "if date :is :originalzone \"date\" \"time\" \"19:46:49\"\n" "{redirect \"me@blah.com\";}\n" ; @@ -1131,6 +1301,7 @@ static void test_date_originalzone_day(void) { static const char SCRIPT = + "require \"date\";\n" "if date :is :originalzone \"date\" \"day\" \"16\"\n" "{redirect \"me@blah.com\";}\n" ; @@ -1175,6 +1346,7 @@ static void test_date_weekend_weekday(void) { static const char SCRIPT = + "require \"date\";\n" "if anyof(date :is :zone \"-0800\" \"date\" \"weekday\" \"0\",\n" " date :is :zone \"-0800\" \"date\" \"weekday\" \"6\")\n" "{redirect \"me@blah.com\";}\n" @@ -1220,6 +1392,7 @@ static void test_date_zone(void) { static const char SCRIPT = + "require \"date\";\n" "if date :is :originalzone \"date\" \"zone\" \"+1100\"\n" "{redirect \"me@blah.com\";}\n" ; @@ -1261,6 +1434,68 @@ context_cleanup(&ctx); } +static void test_currentdate_true(void) +{ + static const char SCRIPT = + "require \"date\", \"relational\";\n" + "if allof(currentdate :zone \"+0000\" :value \"ge\" \"date\" \"2014-01-01\",\n" + " currentdate :zone \"+0000\" :value \"le\" \"date\" \"2114-01-01\")\n" + "{redirect \"me@blah.com\";}\n" + ; + static const char MSG_TRUE = + "Date: Tue, 16 Nov 2010 12:46:49 +1100\r\n" + "From: yme@true.com\r\n" + "To: you\r\n" + "Subject: simple address test\r\n" + "\r\n" + "blah\n" + ; + sieve_test_context_t ctx; + + context_setup(&ctx, SCRIPT); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + + run_message(&ctx, MSG_TRUE); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + CU_ASSERT_EQUAL(ctx.stats.actions, 1); + CU_ASSERT_EQUAL(ctx.stats.redirects, 1); + CU_ASSERT_EQUAL(ctx.stats.keeps, 0); + CU_ASSERT_STRING_EQUAL(ctx.redirected_to, "me@blah.com"); + + context_cleanup(&ctx); +} + +static void test_currentdate_false(void) +{ + static const char SCRIPT = + "require \"date\", \"relational\";\n" + "if allof(currentdate :zone \"+0000\" :value \"ge\" \"date\" \"1970-01-01\",\n" + " currentdate :zone \"+0000\" :value \"le\" \"date\" \"2014-01-01\")\n" + "{redirect \"me@blah.com\";}\n" + ; + static const char MSG_FALSE = + "Date: Tue, 16 Nov 2010 12:46:49 +1100\r\n" + "From: yme@false.com\r\n" + "To: you\r\n" + "Subject: simple address test\r\n" + "\r\n" + "blah\n" + ; + sieve_test_context_t ctx; + + context_setup(&ctx, SCRIPT); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + + run_message(&ctx, MSG_FALSE); + CU_ASSERT_EQUAL(ctx.stats.errors, 0); + CU_ASSERT_EQUAL(ctx.stats.actions, 1); + CU_ASSERT_EQUAL(ctx.stats.redirects, 0); + CU_ASSERT_EQUAL(ctx.stats.keeps, 1); + CU_ASSERT_STRING_EQUAL(ctx.redirected_to, NULL); + + context_cleanup(&ctx); +} + // TODO: test // if size :over 10K { redirect "me@blah.com"; } // TODO: test
View file
cyrus-imapd-2.5.tar.gz/lib/imapoptions
Changed
@@ -1311,7 +1311,7 @@ user's scripts reside on a remote server (in a Murder). Otherwise, timsieved will proxy traffic to the remote server. */ -{ "sieve_extensions", "fileinto reject vacation vacation-seconds imapflags notify envelope relational regex subaddress copy date", BITFIELD("fileinto", "reject", "vacation", "vacation-seconds", "imapflags", "notify", "include", "envelope", "body", "relational", "regex", "subaddress", "copy", "date") } +{ "sieve_extensions", "fileinto reject vacation vacation-seconds imapflags notify envelope relational regex subaddress copy date index", BITFIELD("fileinto", "reject", "vacation", "vacation-seconds", "imapflags", "notify", "include", "envelope", "body", "relational", "regex", "subaddress", "copy", "date", "index") } /* Space-separated list of Sieve extensions allowed to be used in sieve scripts, enforced at submission by timsieved(8). Any previously installed script will be unaffected by this option and
View file
cyrus-imapd-2.5.tar.gz/sieve/bc_dump.c
Changed
@@ -140,6 +140,8 @@ case BC_HEADER: printf("%d: HEADER (\n",ip++); print_spaces(level); + printf(" INDEX %d\n" , d->dataip++.value); + print_spaces(level); if (d->dataip.value == B_COUNT || d->dataip.value == B_VALUE) { printf(" MATCH:%d RELATION:%d COMP:%d HEADERS:\n", @@ -157,8 +159,15 @@ case BC_ADDRESS: case BC_ENVELOPE: - printf("%d: %s (\n",ip, - d->dataip++.op == BC_ADDRESS ? "ADDRESS" : "ENVELOPE"); + if (d->dataip.op == BC_ADDRESS) { + printf("%d: ADDRESS (\n",ip++); + print_spaces(level); + printf(" INDEX %d\n" , d->dataip++.value); + } + else { + printf("%d: ENVELOPE (\n",ip++); + } + print_spaces(level); if (d->dataip.value == B_COUNT || d->dataip.value == B_VALUE) {
View file
cyrus-imapd-2.5.tar.gz/sieve/bc_emit.c
Changed
@@ -186,17 +186,18 @@ * emitted bytecode on success */ static int bc_test_emit(int fd, int *codep, bytecode_info_t *bc) { + int opcode; int wrote=0;/* Relative offset to account for interleaved strings */ - int ret; /* Temporary Return Value Variable */ /* Output this opcode */ - if(write_int(fd, bc->data(*codep).op) == -1) + opcode = bc->data(*codep)++.op; + if(write_int(fd, opcode) == -1) return -1; wrote += sizeof(int); - switch(bc->data(*codep)++.op) { + switch(opcode) { case BC_TRUE: case BC_FALSE: /* No parameter opcodes */ @@ -247,6 +248,11 @@ case BC_HEADER: { int ret; + /* drop index */ + if(write_int(fd, bc->data(*codep).value) == -1) + return -1; + wrote += sizeof(int); + (*codep)++; /* Drop match type */ if(write_int(fd, bc->data(*codep).value) == -1) return -1; @@ -274,6 +280,13 @@ } case BC_ADDRESS: + /* drop index */ + if(write_int(fd, bc->data(*codep).value) == -1) + return -1; + wrote += sizeof(int); + (*codep)++; + + /* fall-through */ case BC_ENVELOPE: { int ret; @@ -354,6 +367,12 @@ int datalen; int tmp; + /* drop index */ + if(write_int(fd, bc->data(*codep).value) == -1) + return -1; + wrote += sizeof(int); + (*codep)++; + /* drop zone tag */ tmp = bc->data(*codep).value; if(write_int(fd, bc->data(*codep).value) == -1) @@ -393,8 +412,8 @@ wrote += sizeof(int); (*codep)++; - /* drop header-name */ - { + if (BC_DATE == opcode) { + /* drop header-name */ datalen = bc->data(*codep)++.len; if(write_int(fd, datalen) == -1) return -1;
View file
cyrus-imapd-2.5.tar.gz/sieve/bc_eval.c
Changed
@@ -468,7 +468,7 @@ const struct address *a; char *addr; - int headersi=i+5;/* the i value for the begining of the headers */ + int headersi=address+i+5;/* the i value for the begining of the headers */ int datai=(ntohl(bcheadersi+1.value)/4); int numheaders=ntohl(bcheadersi.len); @@ -476,10 +476,12 @@ int currh, currd; /* current header, current data */ - int match=ntohl(bci+1.value); - int relation=ntohl(bci+2.value); - int comparator=ntohl(bci+3.value); - int apart=ntohl(bci+4.value); + int header_count; + int index=address ? ntohl(bci+1.value) : 0; // used for address only + int match=ntohl(bcaddress+i+1.value); + int relation=ntohl(bcaddress+i+2.value); + int comparator=ntohl(bcaddress+i+3.value); + int apart=ntohl(bcaddress+i+4.value); int count=0; int isReg = (match==B_REGEX); int ctag = 0; @@ -532,11 +534,34 @@ continue; } + /* count results */ + header_count = 0; + while (valheader_count != NULL) { + ++header_count; + } + + /* convert index argument value to array index */ + if (index > 0) { + --index; + if (index >= header_count) { + res = SIEVE_FAIL; + goto alldone; + } + header_count = index + 1; + } + else if (index < 0) { + index += header_count; + if (index < 0) { + res = SIEVE_FAIL; + goto alldone; + } + header_count = index + 1; + } + /*header exists, now to test it*/ /*search through all the headers that match*/ - for (y=0; valy!=NULL && !res; y++) { - + for (y = index; y < header_count && !res; y++) { #if VERBOSE printf("about to parse %s\n", valy); #endif @@ -643,7 +668,7 @@ { const char** val; - int headersi=i+4;/*the i value for the begining of hte headers*/ + int headersi=i+5;/*the i value for the begining of hte headers*/ int datai=(ntohl(bcheadersi+1.value)/4); int numheaders=ntohl(bcheadersi.len); @@ -651,9 +676,11 @@ int currh, currd; /*current header, current data*/ - int match=ntohl(bci+1.value); - int relation=ntohl(bci+2.value); - int comparator=ntohl(bci+3.value); + int header_count; + int index=ntohl(bci+1.value); + int match=ntohl(bci+2.value); + int relation=ntohl(bci+3.value); + int comparator=ntohl(bci+4.value); int count=0; int isReg = (match==B_REGEX); int ctag = 0; @@ -697,10 +724,34 @@ #if VERBOSE printf ("val %s %s %s\n", val0, val1, val2); #endif - + + /* count results */ + header_count = 0; + while (valheader_count != NULL) { + ++header_count; + } + + /* convert index argument value to array index */ + if (index > 0) { + --index; + if (index >= header_count) { + res = SIEVE_FAIL; + goto alldone; + } + header_count = index + 1; + } + else if (index < 0) { + index += header_count; + if (index < 0) { + res = SIEVE_FAIL; + goto alldone; + } + header_count = index + 1; + } + /* search through all the headers that match */ - for (y = 0; valy && !res; y++) + for (y = index; y < header_count && !res; y++) { if (match == B_COUNT) { count++; @@ -895,6 +946,7 @@ const char *header_name = NULL; int comparator; int date_part; + int header_count; int index; int match; int relation; @@ -903,7 +955,10 @@ struct tm *tm; time_t t; - ++i; /* BC_DATE */ + ++i; /* BC_DATE | BC_CURRENTDATE */ + + /* index */ + index = ntohl(bci++.value); /* zone tag */ zone = ntohl(bci++.value); @@ -928,28 +983,40 @@ /* date-part */ date_part = ntohl(bci++.value); - /* header name */ - i = unwrap_string(bc, i, &header_name, NULL); + if (BC_DATE == op) { + /* header name */ + i = unwrap_string(bc, i, &header_name, NULL); + /* + * Process header + */ - /* - * Process header - */ + if (interp->getheader(m, header_name, &headers) != SIEVE_OK) { + res = SIEVE_FAIL; + goto alldone; + } - /* TODO: implement index extension */ - index = 0; + /* count results */ + header_count = 0; + while (headersheader_count != NULL) { + ++header_count; + } - if (interp->getheader(m, header_name, &headers) != SIEVE_OK - || headersindex == NULL) { - res = SIEVE_FAIL; - goto alldone; - } - header = headersindex; + /* convert index argument value to array index */ + if (index > 0) { + --index; + } + else { + index += header_count; + } + + /* check if index is out of bounds */ + if (index < 0 || index >= header_count) { + res = SIEVE_FAIL; + goto alldone; + } + header = headersindex; - if (BC_CURRENTDATE == op) { - t = time(NULL); - } - else { /* look for separator */ header_data = strrchr(header, ';'); if (header_data) { @@ -965,23 +1032,26 @@ res = SIEVE_FAIL; goto alldone; } - } - /* timezone offset */ - if (zone == B_ORIGINALZONE) { - char *zone; - char sign; - int hours; - int minutes; - - zone = strrchr(header, ' '); - if (!zone || - 3 != sscanf(zone + 1, "%c%02d%02d", &sign, &hours, &minutes)) { - res = SIEVE_FAIL; - goto alldone; - } + /* timezone offset */ + if (zone == B_ORIGINALZONE) { + char *zone; + char sign; + int hours; + int minutes; + + zone = strrchr(header, ' '); + if (!zone || + 3 != sscanf(zone + 1, "%c%02d%02d", &sign, &hours, &minutes)) { + res = SIEVE_FAIL; + goto alldone; + } - timezone_offset = (sign == '-' ? -1 : 1) * ((hours * 60) + (minutes)); + timezone_offset = (sign == '-' ? -1 : 1) * ((hours * 60) + (minutes)); + } + } + else { /* CURRENTDATE */ + t = interp->time; } /* apply timezone_offset (if any) */
View file
cyrus-imapd-2.5.tar.gz/sieve/bc_generate.c
Changed
@@ -337,6 +337,10 @@ if(!atleast(retval,codep + 1)) return -1; retval->datacodep++.op = BC_HEADER; + /* index */ + if(!atleast(retval,codep + 1)) return -1; + retval->datacodep++.value = t->u.ae.index; + /* comparator */ codep = bc_comparator_generate(codep, retval, t->u.h.comptag, @@ -363,6 +367,12 @@ retval->datacodep++.op = (t->type == ADDRESS) ? BC_ADDRESS : BC_ENVELOPE; + /* index */ + if (t->type == ADDRESS) { + if(!atleast(retval,codep+1)) return -1; + retval->datacodep++.value = t->u.ae.index; + } + codep = bc_comparator_generate(codep, retval,t->u.ae.comptag, t->u.ae.relation, t->u.ae.comparator); @@ -449,11 +459,18 @@ /* BC_DATE { time-zone: string} { c: comparator } * { header-name : string } { date-part: string } * { key-list : string list } + * + * BC_CURRENTDATE { time-zone: string} { c: comparator } + * { date-part: string } { key-list : string list } */ if(!atleast(retval,codep + 1)) return -1; retval->datacodep++.op = (DATE == t->type) ? BC_DATE : BC_CURRENTDATE; + /* index */ + if(!atleast(retval,codep + 1)) return -1; + retval->datacodep++.value = t->u.dt.index; + /* zone */ codep = bc_zone_generate(codep, retval, t->u.dt.zonetag, @@ -511,10 +528,12 @@ break; } - /* header-name */ - if(!atleast(retval,codep + 2)) return -1; - retval->datacodep++.len = strlen(t->u.dt.header_name); - retval->datacodep++.str = t->u.dt.header_name; + if (DATE == t->type) { + /* header-name */ + if(!atleast(retval,codep + 2)) return -1; + retval->datacodep++.len = strlen(t->u.dt.header_name); + retval->datacodep++.str = t->u.dt.header_name; + } /* keywords */ codep = bc_stringlist_generate(codep, retval, t->u.dt.kl);
View file
cyrus-imapd-2.5.tar.gz/sieve/interp.c
Changed
@@ -87,6 +87,8 @@ i->lastitem = NULL; i->extensions0 = '\0'; + i->time = time(NULL); + return i; }
View file
cyrus-imapd-2.5.tar.gz/sieve/interp.h
Changed
@@ -70,6 +70,9 @@ /* context to pass along */ void *interp_context; char extensions4096;//the number comes from interp.c EXT_LEN + + /* time when allocated */ + time_t time; }; int interp_verify(sieve_interp_t *interp);
View file
cyrus-imapd-2.5.tar.gz/sieve/script.c
Changed
@@ -184,6 +184,10 @@ (config_sieve_extensions & IMAP_ENUM_SIEVE_EXTENSIONS_DATE)) { s->support.date = 1; return 1; + } else if (!strcmp("index", req) && + (config_sieve_extensions & IMAP_ENUM_SIEVE_EXTENSIONS_INDEX)) { + s->support.index = 1; + return 1; } return 0; }
View file
cyrus-imapd-2.5.tar.gz/sieve/script.h
Changed
@@ -69,6 +69,7 @@ int include : 1; int copy : 1; int date : 1; + int index : 1; int vacation_seconds: 1; } support;
View file
cyrus-imapd-2.5.tar.gz/sieve/sieve-lex.l
Changed
@@ -173,6 +173,8 @@ <INITIAL>:copy return COPY; <INITIAL>date return DATE; <INITIAL>currentdate return CURRENTDATE; +<INITIAL>:index return INDEX; +<INITIAL>:last return LAST; <INITIAL>:zone return ZONE; <INITIAL>:originalzone return ORIGINALZONE; <INITIAL> \t\n\r ; /* ignore whitespace */
View file
cyrus-imapd-2.5.tar.gz/sieve/sieve.y
Changed
@@ -82,12 +82,14 @@ }; struct htags { + int index; char *comparator; int comptag; int relation; }; struct aetags { + int index; int addrtag; char *comparator; int comptag; @@ -125,6 +127,7 @@ }; struct dttags { + int index; int zonetag; char *zone; int comptag; @@ -228,8 +231,8 @@ %token METHOD ID OPTIONS LOW NORMAL HIGH ANY MESSAGE %token INCLUDE PERSONAL GLOBAL RETURN OPTIONAL ONCE %token COPY -%token DATE CURRENTDATE ZONE ORIGINALZONE -%token YEAR MONTH DAY JULIAN HOUR MINUTE SECOND TIME ISO8601 STD11 ZONE WEEKDAY +%token DATE CURRENTDATE INDEX LAST ZONE ORIGINALZONE +%token YEAR MONTH DAY JULIAN HOUR MINUTE SECOND TIME ISO8601 STD11 WEEKDAY %type <cl> commands command action elsif block %type <sl> stringlist strings @@ -606,7 +609,10 @@ | SIZE sizetag NUMBER { $$ = new_test(SIZE); $$->u.sz.t = $2; $$->u.sz.n = $3; } | DATE dttags STRING STRING stringlist - { + {if (!parse_script->support.date) + { yyerror(parse_script, "date MUST be enabled with \"require\""); + YYERROR; } + $2->date_part = verify_date_part(parse_script, $4); if ($2->date_part == -1) { YYERROR; /*vr called yyerror()*/ } @@ -618,15 +624,22 @@ yyerror(parse_script, "unable to find a compatible comparator"); YYERROR; } } - | CURRENTDATE dttags STRING STRING stringlist - { - $2->date_part = verify_date_part(parse_script, $4); + | CURRENTDATE dttags STRING stringlist + {if (!parse_script->support.date) + { yyerror(parse_script, "date MUST be enabled with \"require\""); + YYERROR; } + + if ($2->zonetag == ORIGINALZONE) { + yyerror(parse_script, "originalzone argument is not allowed in currentdate"); + YYERROR; } + + $2->date_part = verify_date_part(parse_script, $3); if ($2->date_part == -1) { YYERROR; /*vr called yyerror()*/ } $2 = canon_dttags($2); - $$ = build_date(CURRENTDATE, $2, $3, $5); + $$ = build_date(CURRENTDATE, $2, NULL, $4); if ($$ == NULL) { yyerror(parse_script, "unable to find a compatible comparator"); YYERROR; } @@ -668,6 +681,24 @@ yyerror(parse_script, "comparator-i;ascii-numeric MUST be enabled with \"require\""); YYERROR; } else { $$->comparator = $3; } } + | aetags INDEX NUMBER { $$ = $1; + if (!parse_script->support.index) + { yyerror(parse_script, "index MUST be enabled with \"require\""); + YYERROR; } + if ($$->index != 0) { + yyerror(parse_script, "duplicate index argument"); YYERROR; } + if ($3 <= 0) { + yyerror(parse_script, "invalid index value"); YYERROR; } + else { $$->index = $3; } } + | aetags LAST { $$ = $1; + if (!parse_script->support.index) + { yyerror(parse_script, "index MUST be enabled with \"require\""); + YYERROR; } + if ($$->index == 0) { + yyerror(parse_script, "index argument is required"); YYERROR; } + else if ($$->index < 0) { + yyerror(parse_script, "duplicate last argument"); YYERROR; } + else { $$->index *= -1; } } ; htags: /* empty */ { $$ = new_htags(); } @@ -691,7 +722,25 @@ yyerror(parse_script, "comparator-i;ascii-numeric MUST be enabled with \"require\""); YYERROR; } else { $$->comparator = $3; } } - ; + | htags INDEX NUMBER { $$ = $1; + if (!parse_script->support.index) + { yyerror(parse_script, "index MUST be enabled with \"require\""); + YYERROR; } + if ($$->index != 0) { + yyerror(parse_script, "duplicate index argument"); YYERROR; } + if ($3 <= 0) { + yyerror(parse_script, "invalid index value"); YYERROR; } + else { $$->index = $3; } } + | htags LAST { $$ = $1; + if (!parse_script->support.index) + { yyerror(parse_script, "index MUST be enabled with \"require\""); + YYERROR; } + if ($$->index == 0) { + yyerror(parse_script, "index argument is required"); YYERROR; } + else if ($$->index < 0) { + yyerror(parse_script, "duplicate last argument"); YYERROR; } + else { $$->index *= -1; } } + ; btags: /* empty */ { $$ = new_btags(); } | btags RAW { $$ = $1; @@ -757,6 +806,26 @@ yyerror(parse_script, "comparator-i;ascii-numeric MUST be enabled with \"require\""); YYERROR; } else { $$->comparator = $3; } } + | dttags INDEX NUMBER { $$ = $1; + if (!parse_script->support.index) + { yyerror(parse_script, "index MUST be enabled with \"require\""); + YYERROR; } + if ($$->index != 0) { + yyerror(parse_script, "duplicate index argument"); YYERROR; } + if ($3 <= 0) { + yyerror(parse_script, "invalid index value"); YYERROR; } + else { $$->index = $3; } } + + | dttags LAST { $$ = $1; + if (!parse_script->support.index) + { yyerror(parse_script, "index MUST be enabled with \"require\""); + YYERROR; } + if ($$->index == 0) { + yyerror(parse_script, "index argument is required"); YYERROR; } + else if ($$->index < 0) { + yyerror(parse_script, "duplicate last argument"); YYERROR; } + else { $$->index *= -1; } } + | dttags ZONE STRING { $$ = $1; if ($$->zonetag != -1) { yyerror(parse_script, "duplicate zone tag"); YYERROR; } @@ -873,6 +942,7 @@ assert((t == ADDRESS) || (t == ENVELOPE)); if (ret) { + ret->u.ae.index = ae->index; ret->u.ae.comptag = ae->comptag; ret->u.ae.relation=ae->relation; ret->u.ae.comparator=xstrdup(ae->comparator); @@ -893,6 +963,7 @@ assert(t == HEADER); if (ret) { + ret->u.h.index = h->index; ret->u.h.comptag = h->comptag; ret->u.h.relation=h->relation; ret->u.h.comparator=xstrdup(h->comparator); @@ -1033,13 +1104,14 @@ assert(t == DATE || t == CURRENTDATE); if (ret) { + ret->u.dt.index = dt->index; ret->u.dt.zone = (dt->zone ? xstrdup(dt->zone) : NULL); ret->u.dt.comparator = xstrdup(dt->comparator); ret->u.dt.zonetag = dt->zonetag; ret->u.dt.comptag = dt->comptag; ret->u.dt.relation = dt->relation; ret->u.dt.date_part = dt->date_part; - ret->u.dt.header_name = hn; + ret->u.dt.header_name = (hn ? xstrdup(hn) : NULL); ret->u.dt.kl = kl; free_dttags(dt); } @@ -1051,6 +1123,7 @@ { struct aetags *r = (struct aetags *) xmalloc(sizeof(struct aetags)); + r->index = 0; r->addrtag = r->comptag = r->relation=-1; r->comparator=NULL; @@ -1077,6 +1150,7 @@ { struct htags *r = (struct htags *) xmalloc(sizeof(struct htags)); + r->index = 0; r->comptag = r->relation= -1; r->comparator = NULL; @@ -1185,6 +1259,7 @@ { struct dttags *dt = (struct dttags *) xmalloc(sizeof(struct dttags)); dt->comptag = -1; + dt->index = 0; dt->zonetag = -1; dt->relation = -1; dt->comparator = NULL; @@ -1205,10 +1280,13 @@ if (dt->comparator == NULL) { dt->comparator = xstrdup("i;ascii-casemap"); } + if (dt->index == 0) { + dt->index = 1; + } if (dt->zonetag == -1) { t = time(NULL); tm = localtime(&t); - gmoffset = gmtoff_of(tm, t) / 60; + gmoffset = gmtoff_of(tm, &t) / 60; hours = abs(gmoffset) / 60; minutes = abs(gmoffset) % 60; snprintf(zone, 6, "%c%02d%02d", (gmoffset >= 0 ? '+' : '-'), hours, minutes);
View file
cyrus-imapd-2.5.tar.gz/sieve/sieved.c
Changed
@@ -200,8 +200,11 @@ static int dump2_test(bytecode_input_t * d, int i) { - int l,x; - switch(ntohl(di.value)) { + int l,x,index; + int opcode; + + opcode = ntohl(di.value); + switch(opcode) { case BC_FALSE: printf("false"); i++; @@ -264,6 +267,7 @@ break; case BC_ADDRESS:/*7*/ printf("Address "); + index = ntohl(d++i.value); i=printComparison(d, i+1); printf(" type: "); switch(ntohl(di++.value)) @@ -274,6 +278,11 @@ case B_USER:printf("user"); break; case B_DETAIL:printf("detail"); break; } + printf("\n"); + if (index != 0) { + printf(" Index: %d %s\n", + abs(index), index < 0 ? "LAST" : ""); + } printf(" Headers:"); i=write_list(ntohl(di.len), i+1, d); printf(" Data:"); @@ -300,7 +309,12 @@ break; case BC_HEADER:/*9*/ printf("Header "); + index = ntohl(d++i.value); i= printComparison(d, i+1); + if (index != 0) { + printf(" Index: %d %s\n", + abs(index), index < 0 ? "LAST" : ""); + } printf(" Headers: "); i=write_list(ntohl(di.len), i+1, d); printf(" Data: "); @@ -326,14 +340,20 @@ break; case BC_DATE:/*11*/ case BC_CURRENTDATE:/*12*/ - /* current date */ - if (BC_DATE == ntohl(di++.value)) { + ++i; /* skip opcode */ + + if (BC_DATE == opcode) { printf("date "); } else { printf("currentdate "); } + /* index */ + index = ntohl(di++.value); + printf(" Index: %d %s\n", + abs(index), index < 0 ? "LAST" : ""); + /* zone tag */ { int zone; @@ -372,7 +392,7 @@ } /* header name */ - { + if (BC_DATE == opcode) { const char *data; int len; i = unwrap_string(d, i, &data, &len);
View file
cyrus-imapd-2.5.tar.gz/sieve/tests/testExtension/uberExtensionTestScript.s
Changed
@@ -1,4 +1,4 @@ -require "regex", "relational", "comparator-i;ascii-numeric", "subaddress", "envelope", "date"; +require "regex", "relational", "comparator-i;ascii-numeric", "subaddress", "envelope", "date", "index"; #this is for the extra thigns we have added to sieve #test extensions @@ -166,6 +166,16 @@ if date :is "received" "year" "1983", "1993", "2003", "2013" {redirect "me+yearsofthree@blah.com";} -if currentdate :value "ge" :originalzone "received" "year" "2013" -{redirect "me+yearsofthree@blah.com";} +if date :is :index 2 "received" "day" "01" +{redirect "me+firstofthemonth@blah.com";} + +if date :is :index 1 :last "received" "day" "01" +{redirect "me+firstofthemonth@blah.com";} + +if currentdate :zone "-0800" :is "year" "2003", "2013", "2023" +{redirect "me+currentdateis@blah.com";} + +if allof(currentdate :value "ge" "date" "2014-01-01", + currentdate :value "lt" "date" "2015-01-01") +{redirect "me+cd2014@blah.com";}
View file
cyrus-imapd-2.5.tar.gz/sieve/tree.c
Changed
@@ -161,6 +161,8 @@ break; case DATE: + free(t->u.dt.header_name); + /* fall-through */ case CURRENTDATE: free(t->u.dt.comparator); free(t->u.dt.zone);
View file
cyrus-imapd-2.5.tar.gz/sieve/tree.h
Changed
@@ -70,6 +70,7 @@ testlist_t *tl; /* anyof, allof */ strarray_t *sl; /* exists */ struct { /* it's a header test */ + int index; int comptag; char * comparator; int relation; @@ -78,6 +79,7 @@ strarray_t *pl; } h; struct { /* it's an address or envelope test */ + int index; int comptag; char * comparator; int relation; @@ -102,6 +104,7 @@ int n; /* param */ } sz; struct { /* it's a date test */ + int index; int zonetag; char *zone; int comptag;
View file
cyrus-imapd.dsc
Changed
@@ -2,7 +2,7 @@ Source: cyrus-imapd Binary: cyrus-imapd Architecture: any -Version: 2.5~dev2014082101-0~kolab1 +Version: 2.5~dev2014082901-0~kolab1 Maintainer: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Uploaders: Paul Klos <kolab@klos2day.nl> Homepage: http://www.cyrusimap.org/
View file
debian.changelog
Changed
@@ -1,3 +1,11 @@ +cyrus-imapd (2.5~dev2014082901-0~kolab1) unstable; urgency=low + + * Ship a GIT development snapshot from git.cyrusimap.org + b2ef80bee2102d0eadf280c6c23b5759920d1752 + * Merge enhanced Sieve Date and Index extension + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Fri, 29 Aug 2014 11:30:13 +0100 + cyrus-imapd (2.5~dev2014081301-0~kolab1) unstable; urgency=low * Ship a GIT development snapshot from git.cyrusimap.org
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.