Projects
Kolab:3.4
cyrus-imapd
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 76
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\n" + " envelope body relational regex subaddress copy date\n" ); libcyrus_init(); return 0; @@ -946,6 +946,321 @@ context_cleanup(&ctx); } +static void test_date_year(void) +{ + static const char SCRIPT[] = + "if date :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 2013 12:50:12 +1100\r\n" + "From: zme@true.com\r\n" + "To: you\r\n" + "Subject: simple address test\r\n" + "\r\n" + "blah\n" + ; + static const char MSG_FALSE[] = + "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 2010 12:50:12 +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_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_zone_month(void) +{ + static const char SCRIPT[] = + "if date :is :zone \"-0800\" \"date\" \"month\" \"11\"\n" + "{redirect \"me@blah.com\";}\n" + ; + static const char MSG_TRUE[] = + "Date: Fri, 1 Nov 2013 19:46:49 +1100\r\n" + "From: zme@true.com\r\n" + "To: you\r\n" + "Subject: simple address test\r\n" + "\r\n" + "blah\n" + ; + static const char MSG_FALSE[] = + "Date: Fri, 1 Nov 2013 11: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_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_date(void) +{ + static const char SCRIPT[] = + "if date :is :originalzone \"date\" \"date\" \"2013-11-02\"\n" + "{redirect \"me@blah.com\";}\n" + ; + static const char MSG_TRUE[] = + "Date: Sat, 2 Nov 2013 19:46:49 +1100\r\n" + "From: zme@true.com\r\n" + "To: you\r\n" + "Subject: simple address test\r\n" + "\r\n" + "blah\n" + ; + static const char MSG_FALSE[] = + "Date: Fri, 1 Nov 2013 19:45: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_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_time(void) +{ + static const char SCRIPT[] = + "if date :is :originalzone \"date\" \"time\" \"19:46:49\"\n" + "{redirect \"me@blah.com\";}\n" + ; + static const char MSG_TRUE[] = + "Date: Sat, 2 Nov 2013 19:46:49 +1100\r\n" + "From: zme@true.com\r\n" + "To: you\r\n" + "Subject: simple address test\r\n" + "\r\n" + "blah\n" + ; + static const char MSG_FALSE[] = + "Date: Sat, 2 Nov 2013 19:45: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_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_originalzone_day(void) +{ + static const char SCRIPT[] = + "if date :is :originalzone \"date\" \"day\" \"16\"\n" + "{redirect \"me@blah.com\";}\n"
View file
cyrus-imapd-2.5.tar.gz/imap/arbitron.c
Changed
@@ -98,7 +98,7 @@ static struct namespace arb_namespace; /* forward declarations */ -static void usage(void); +static void usage(void) __attribute__((noreturn)); static void run_users(void); static void make_report(const char *key, void *data, void *rock); static void process_seen(const char *path, const char *user);
View file
cyrus-imapd-2.5.tar.gz/imap/ctl_mboxlist.c
Changed
@@ -370,13 +370,17 @@ /* No need to update mupdate NOW, we'll get it when we * untag the mailbox */ skip_flag = 1; - } else if (act_head->acl && - !strcmp(realpart, act_head->location) && - !strcmp(acl, act_head->acl)) { - /* Do not update if location does match, and there is an acl, - * and the acl matches */ + } else if (act_head->acl) { + if ( + !strcmp(realpart, act_head->location) && + !strcmp(acl, act_head->acl) + ) { - skip_flag = 1; + /* Do not update if location does match, and there is an acl, + * and the acl matches */ + + skip_flag = 1; + } } else { skip_flag = 0; }
View file
cyrus-imapd-2.5.tar.gz/imap/imapd.c
Changed
@@ -5921,9 +5921,10 @@ /* * Perform a RENAME command */ -static void cmd_rename(char *tag, char *oldname, char *newname, char *partition) +static void cmd_rename(char *tag, char *oldname, char *newname, char *location) { int r = 0; + char *c; char oldmailboxname[MAX_MAILBOX_BUFFER]; char newmailboxname[MAX_MAILBOX_BUFFER]; char oldmailboxname2[MAX_MAILBOX_BUFFER]; @@ -5938,23 +5939,50 @@ char acl_olduser[128], acl_newuser[128]; mbentry_t *mbentry = NULL; - if (partition && !imapd_userisadmin) { - r = IMAP_PERMISSION_DENIED; + if (location && !imapd_userisadmin) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_PERMISSION_DENIED)); + return; } /* canonicalize names */ - if (!r) r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, oldname, - imapd_userid, oldmailboxname); - if (!r) r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, newname, - imapd_userid, newmailboxname); + r = (*imapd_namespace.mboxname_tointernal)( + &imapd_namespace, + oldname, + imapd_userid, + oldmailboxname + ); + + // This really shouldn't happen, but here we go. + if (r) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); + return; + } + + r = (*imapd_namespace.mboxname_tointernal)( + &imapd_namespace, + newname, + imapd_userid, + newmailboxname + ); + + // This really shouldn't happen, but here we go. + if (r) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); + return; + } /* Keep temporary copy: master is trashed */ strcpy(oldmailboxname2, oldmailboxname); strcpy(newmailboxname2, newmailboxname); - if (!r) r = mlookup(NULL, NULL, oldmailboxname, &mbentry); + r = mlookup(NULL, NULL, oldmailboxname, &mbentry); - if (!r && (mbentry->mbtype & MBTYPE_REMOTE)) { + if (r) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); + return; + } + + if (mbentry->mbtype & MBTYPE_REMOTE) { /* remote mailbox */ struct backend *s = NULL; int res; @@ -5962,92 +5990,73 @@ s = proxy_findserver(mbentry->server, &imap_protocol, proxy_userid, &backend_cached, &backend_current, &backend_inbox, imapd_in); - if (!s) r = IMAP_SERVER_UNAVAILABLE; + if (!s) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_SERVER_UNAVAILABLE)); + goto done; + } - /* xxx start of separate proxy-only code - (remove when we move to a unified environment) */ - - /* Cross Server Rename */ - if (!r && partition) { - char *destpart; - - if (strcmp(oldname, newname)) { - prot_printf(imapd_out, - "%s NO Cross-server or cross-partition move w/rename not supported\r\n", - tag); - goto done; + // Server or partition is going to change + if (location) { + char *destserver = NULL; + char *destpart = NULL; + + destserver = xstrdupnull(location); + c = strchr(location, '!'); + if (c) { + *c++ = '\0'; + destpart = xstrdupnull(c); + } else { + destpart = xstrdup(location); + free(destserver); } - /* dest partition? */ + if (destserver) { + if (destpart && !strcmp(destserver,config_servername)) { + // XFER + prot_printf(s->out, + "%s XFER \"%s\" \"%s\" %s\r\n", + tag, + oldname, + newname, + location + ); - destpart = strchr(partition,'!'); - if (destpart) { - char newserver[MAX_MAILBOX_BUFFER]; - if (strlen(partition) >= sizeof(newserver)) { - prot_printf(imapd_out, - "%s NO Partition name too long\r\n", tag); - goto done; - } - strcpy(newserver, partition); - newserver[destpart-partition] = '\0'; - destpart++; - - if (!strcmp(mbentry->server, newserver)) { - /* Same Server, different partition */ - /* xxx this would require administrative access to the - * backend, which we won't get */ - prot_printf(imapd_out, - "%s NO Can't move across partitions via a proxy\r\n", - tag); - goto done; } else { - /* Cross Server */ - /* <tag> XFER <name> <dest server> <dest partition> */ + // RENAME prot_printf(s->out, - "%s XFER {" SIZE_T_FMT "+}\r\n%s" - " {" SIZE_T_FMT "+}\r\n%s" - " {" SIZE_T_FMT "+}\r\n%s\r\n", - tag, strlen(oldname), oldname, - strlen(newserver), newserver, - strlen(destpart), destpart); + "%s RENAME \"%s\" \"%s\" %s\r\n", + tag, + oldname, + newname, + location + ); } - - } else { - /* <tag> XFER <name> <dest server> */ - prot_printf(s->out, "%s XFER {" SIZE_T_FMT "+}\r\n%s" - " {" SIZE_T_FMT "+}\r\n%s\r\n", - tag, strlen(oldname), oldname, - strlen(partition), partition); - } + } // (destserver) - res = pipe_including_tag(s, tag, 0); + res = pipe_until_tag(s, tag, 0); /* make sure we've seen the update */ if (ultraparanoid && res == PROXY_OK) kick_mupdate(); - goto done; - } - /* xxx end of separate proxy-only code */ - - if (!r) { - if (!CAPA(s, CAPA_MUPDATE)) { - /* do MUPDATE create operations for new mailbox */ + } else { // (location) + // a simple rename, old name and new name must not be the same + if (strcmp(oldname, newname)) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_SERVER_UNAVAILABLE)); + goto done; } - prot_printf(s->out, "%s RENAME {" SIZE_T_FMT "+}\r\n%s" - " {" SIZE_T_FMT "+}\r\n%s\r\n", - tag, strlen(oldname), oldname, - strlen(newname), newname); + prot_printf(s->out, + "%s RENAME \"%s\" \"%s\" %s\r\n", + tag, + oldname, + newname + ); +
View file
cyrus-imapd-2.5.tar.gz/imap/lmtp_sieve.c
Changed
@@ -324,11 +324,10 @@ smbuf[0] = "sendmail"; smbuf[1] = "-i"; /* ignore dots */ + smbuf[2] = "-f"; if (return_path && *return_path) { - smbuf[2] = "-f"; smbuf[3] = return_path; } else { - smbuf[2] = "-f"; smbuf[3] = "<>"; } smbuf[4] = "--";
View file
cyrus-imapd-2.5.tar.gz/imap/lmtpengine.c
Changed
@@ -553,8 +553,7 @@ * from string pointed to by 'buf'. Does not handle continuation header * lines. */ -static void -clean822space(char *buf) +static void clean822space(char *buf) { char *from=buf, *to=buf; int c;
View file
cyrus-imapd-2.5.tar.gz/imap/mboxlist.c
Changed
@@ -1371,7 +1371,6 @@ mboxent = mboxlist_entry_cstring(newmbentry); r = cyrusdb_store(mbdb, newname, strlen(newname), mboxent, strlen(mboxent), &tid); - mboxlist_entry_free(&newmbentry); if (r) goto done; /* skip ahead to the commit */
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", BITFIELD("fileinto", "reject", "vacation", "vacation-seconds", "imapflags", "notify", "include", "envelope", "body", "relational", "regex", "subaddress", "copy") } +{ "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") } /* 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/lib/imclient.c
Changed
@@ -181,12 +181,11 @@ static struct imclient_cmdcallback *cmdcallback_freelist; /* Forward declarations */ -static int imclient_writeastring P((struct imclient *imclient, - const char *str)); -static void imclient_writebase64 P((struct imclient *imclient, - const char *output, size_t len)); -static void imclient_eof P((struct imclient *imclient)); -static int imclient_decodebase64 P((char *input)); +static int imclient_writeastring(struct imclient *imclient, const char *str); +static void imclient_writebase64(struct imclient *imclient, + const char *output, size_t len); +static void imclient_eof(struct imclient *imclient); +static int imclient_decodebase64(char *input); /* callbacks we support */ static const sasl_callback_t callbacks[] = {
View file
cyrus-imapd-2.5.tar.gz/lib/nonblock.h
Changed
@@ -43,16 +43,8 @@ #ifndef INCLUDED_NONBLOCK_H #define INCLUDED_NONBLOCK_H -#ifndef P -#ifdef __STDC__ -#define P(x) x -#else -#define P(x) () -#endif -#endif - extern const char *nonblock_method_desc; -extern void nonblock P((int fd, int mode)); +extern void nonblock(int fd, int mode); #endif /* INCLUDED_NONBLOCK_H */
View file
cyrus-imapd-2.5.tar.gz/lib/nonblock_ioctl.c
Changed
@@ -56,8 +56,7 @@ * 'mode' is nonzero, sets non-blocking mode, if 'mode' is zero * clears non-blocking mode. */ -EXPORTED void -nonblock(int fd, int mode) +EXPORTED void nonblock(int fd, int mode) { mode = mode ? 1 : 0;
View file
cyrus-imapd-2.5.tar.gz/sieve/bc_emit.c
Changed
@@ -347,6 +347,76 @@ break; } + case BC_DATE: + case BC_CURRENTDATE: + { + int ret; + int datalen; + int tmp; + + /* drop zone tag */ + tmp = bc->data[(*codep)].value; + if(write_int(fd, bc->data[(*codep)].value) == -1) + return -1; + wrote += sizeof(int); + (*codep)++; + + /* drop timezone offset */ + if (tmp == B_TIMEZONE) { + 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; + wrote += sizeof(int); + (*codep)++; + + /* drop relation */ + if(write_int(fd, bc->data[(*codep)].value) == -1) + return -1; + wrote += sizeof(int); + (*codep)++; + + /* drop comparator */ + if(write_int(fd, bc->data[(*codep)].value) == -1) + return -1; + wrote += sizeof(int); + (*codep)++; + + /* drop date-part */ + if(write_int(fd, bc->data[(*codep)].value) == -1) + return -1; + wrote += sizeof(int); + (*codep)++; + + /* drop header-name */ + { + datalen = bc->data[(*codep)++].len; + + if(write_int(fd, datalen) == -1) return -1; + wrote += sizeof(int); + + if(write(fd, bc->data[(*codep)++].str, datalen) == -1) return -1; + wrote += datalen; + + ret = align_string(fd,datalen); + if(ret == -1) return -1; + + wrote+=ret; + } + + /* drop keywords */ + ret = bc_stringlist_emit(fd, codep, bc); + if(ret < 0) return -1; + wrote+=ret; + + break; + } + default: /* Unknown testcode? */ return -1;
View file
cyrus-imapd-2.5.tar.gz/sieve/bc_eval.c
Changed
@@ -883,6 +883,195 @@ break; } + case BC_DATE:/*11*/ + case BC_CURRENTDATE:/*12*/ + { + char buffer[64]; + const char **headers = NULL; + const char **key; + const char **keylist = NULL; + const char *header = NULL; + const char *header_data; + const char *header_name = NULL; + int comparator; + int date_part; + int index; + int match; + int relation; + int timezone_offset = 0; + int zone; + struct tm *tm; + time_t t; + + ++i; /* BC_DATE */ + + /* zone tag */ + zone = ntohl(bc[i++].value); + + /* timezone offset */ + if (zone == B_TIMEZONE) { + timezone_offset = ntohl(bc[i++].value); + } + + /* comparator */ + match = ntohl(bc[i++].value); + relation = ntohl(bc[i++].value); + comparator = ntohl(bc[i++].value); + + /* find comparator function */ + comp = lookup_comp(comparator, match, relation, &comprock); + if(!comp) { + res = SIEVE_RUN_ERROR; + break; + } + + /* date-part */ + date_part = ntohl(bc[i++].value); + + /* header name */ + i = unwrap_string(bc, i, &header_name, NULL); + + + /* + * Process header + */ + + /* TODO: implement index extension */ + index = 0; + + if (interp->getheader(m, header_name, &headers) != SIEVE_OK + || headers[index] == NULL) { + res = SIEVE_FAIL; + goto alldone; + } + header = headers[index]; + + if (BC_CURRENTDATE == op) { + t = time(NULL); + } + else { + /* look for separator */ + header_data = strrchr(header, ';'); + if (header_data) { + /* separator found, skip character and continue */ + ++header_data; + } + else { + /* separator not found, use full header */ + header_data = header; + } + + if (-1 == time_from_rfc822(header_data, &t)) { + 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)); + } + + /* apply timezone_offset (if any) */ + t += timezone_offset * 60; + + /* get tm struct */ + tm = gmtime(&t); + + + /* + * Tests + */ + + if (match == B_COUNT) { + res = SIEVE_OK; + goto alldone; + } + + keylist = bc_makeArray(bc, &i); + for (key = keylist; *key; ++key) { + switch (date_part) { + case B_YEAR: + snprintf(buffer, sizeof(buffer), "%04d", 1900 + tm->tm_year); + break; + case B_MONTH: + snprintf(buffer, sizeof(buffer), "%02d", 1 + tm->tm_mon); + break; + case B_DAY: + snprintf(buffer, sizeof(buffer), "%02d", tm->tm_mday); + break; + case B_DATE: + snprintf(buffer, sizeof(buffer), "%04d-%02d-%02d", + 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday); + break; + case B_JULIAN: { + int month, year; + int c, ya; + + month = 1 + tm->tm_mon; + year = 1900 + tm->tm_year; + + if (month > 2) { + month -= 3; + } + else { + month += 9; + --year; + } + c = year / 100; + ya = year - c * 100; + + snprintf(buffer, sizeof(buffer), "%d", + (c * 146097 / 4 + ya * 1461 / 4 + + (month * 153 + 2) / 5 + tm->tm_mday + 1721119)); + } break; + case B_HOUR: + snprintf(buffer, sizeof(buffer), "%02d", tm->tm_hour); + break; + case B_MINUTE: + snprintf(buffer, sizeof(buffer), "%02d", tm->tm_min); + break; + case B_SECOND: + snprintf(buffer, sizeof(buffer), "%02d", tm->tm_sec); + break; + case B_TIME: + snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + break; + case B_ISO8601: + time_to_iso8601(t, buffer, sizeof(buffer)); + break; + case B_STD11: + time_to_rfc822(t, buffer, sizeof(buffer)); + break; + case B_ZONE: + snprintf(buffer, sizeof(buffer), "%c%02d%02d", + timezone_offset >= 0 ? '+' : '-', + abs(timezone_offset) / 60, + abs(timezone_offset) % 60); + break; + case B_WEEKDAY: + snprintf(buffer, sizeof(buffer), "%1d", tm->tm_wday); + break; + } + + res |= comp(buffer, strlen(buffer), *key, comprock); + } + free(keylist); + break; + } default: #if VERBOSE printf("WERT, can't evaluate if statement. %d is not a valid command",
View file
cyrus-imapd-2.5.tar.gz/sieve/bc_generate.c
Changed
@@ -249,6 +249,40 @@ return codep; } +static int bc_zone_generate(int codep, bytecode_info_t *retval, + int zonetag, const char *zone) +{ + unsigned hours; + unsigned minutes; + char sign; + + assert(retval != NULL); + + /* zonetag */ + if (!atleast(retval, codep + 1)) return -1; + + switch (zonetag) { + case ZONE: + retval->data[codep++].value = B_TIMEZONE; + + /* time-zone offset in minutes */ + if (!atleast(retval, codep + 1) || + sscanf(zone, "%c%02u%02u", &sign, &hours, &minutes) != 3) + return -1; + + retval->data[codep++].value = (sign == '-' ? -1 : 1) * (hours * 60) + minutes; + break; + case ORIGINALZONE: + retval->data[codep++].value = B_ORIGINALZONE; + break; + default: + return -1; + } + + return codep; +} + + /* writes a single test into almost-flat form starting at codep. @@ -410,6 +444,83 @@ if (codep == -1) return -1; break; + case DATE: + case CURRENTDATE: + /* BC_DATE { time-zone: string} { c: comparator } + * { header-name : string } { date-part: string } + * { key-list : string list } + */ + + if(!atleast(retval,codep + 1)) return -1; + retval->data[codep++].op = (DATE == t->type) ? BC_DATE : BC_CURRENTDATE; + + /* zone */ + codep = bc_zone_generate(codep, retval, + t->u.dt.zonetag, + t->u.dt.zone); + if (codep == -1) return -1; + + /* comparator */ + codep = bc_comparator_generate(codep, retval, + t->u.dt.comptag, + t->u.dt.relation, + t->u.dt.comparator); + if (codep == -1) return -1; + + /* date-part */ + if(!atleast(retval,codep + 1)) return -1; + switch (t->u.dt.date_part) { + case YEAR: + retval->data[codep++].value = B_YEAR; + break; + case MONTH: + retval->data[codep++].value = B_MONTH; + break; + case DAY: + retval->data[codep++].value = B_DAY; + break; + case DATE: + retval->data[codep++].value = B_DATE; + break; + case JULIAN: + retval->data[codep++].value = B_JULIAN; + break; + case HOUR: + retval->data[codep++].value = B_HOUR; + break; + case MINUTE: + retval->data[codep++].value = B_MINUTE; + break; + case SECOND: + retval->data[codep++].value = B_SECOND; + break; + case TIME: + retval->data[codep++].value = B_TIME; + break; + case ISO8601: + retval->data[codep++].value = B_ISO8601; + break; + case STD11: + retval->data[codep++].value = B_STD11; + break; + case ZONE: + retval->data[codep++].value = B_ZONE; + break; + case WEEKDAY: + retval->data[codep++].value = B_WEEKDAY; + break; + } + + /* header-name */ + if(!atleast(retval,codep + 2)) return -1; + retval->data[codep++].len = strlen(t->u.dt.header_name); + retval->data[codep++].str = t->u.dt.header_name; + + /* keywords */ + codep = bc_stringlist_generate(codep, retval, t->u.dt.kl); + if (codep == -1) return -1; + + break; default: return -1;
View file
cyrus-imapd-2.5.tar.gz/sieve/bytecode.h
Changed
@@ -158,7 +158,9 @@ BC_ADDRESS, BC_ENVELOPE, /* require envelope */ BC_HEADER, - BC_BODY /* require body */ + BC_BODY, /* require body */ + BC_DATE, /* require date */ + BC_CURRENTDATE /* require date */ }; /* currently one enum so as to help determine where values are being misused. @@ -246,8 +248,34 @@ B_LOCATION_PLACEHOLDER_1, B_LOCATION_PLACEHOLDER_2, B_LOCATION_PLACEHOLDER_3, - B_LOCATION_PLACEHOLDER_4 - + B_LOCATION_PLACEHOLDER_4, + + /* Zones */ + B_TIMEZONE, + B_ORIGINALZONE, + + B_ZONE_PLACEHOLDER_1, + B_ZONE_PLACEHOLDER_2, + + /* Date Parts */ + B_YEAR, + B_MONTH, + B_DAY, + B_DATE, + B_JULIAN, + B_HOUR, + B_MINUTE, + B_SECOND, + B_TIME, + B_ISO8601, + B_STD11, + B_ZONE, + B_WEEKDAY, + + B_DATEPART_PLACEHOLDER_1, + B_DATEPART_PLACEHOLDER_2, + B_DATEPART_PLACEHOLDER_3, + B_DATEPART_PLACEHOLDER_4 }; #endif
View file
cyrus-imapd-2.5.tar.gz/sieve/script.c
Changed
@@ -180,6 +180,10 @@ (config_sieve_extensions & IMAP_ENUM_SIEVE_EXTENSIONS_COPY)) { s->support.copy = 1; return 1; + } else if (!strcmp("date", req) && + (config_sieve_extensions & IMAP_ENUM_SIEVE_EXTENSIONS_DATE)) { + s->support.date = 1; + return 1; } return 0; }
View file
cyrus-imapd-2.5.tar.gz/sieve/script.h
Changed
@@ -68,6 +68,7 @@ int i_ascii_numeric: 1; int include : 1; int copy : 1; + int date : 1; int vacation_seconds: 1; } support;
View file
cyrus-imapd-2.5.tar.gz/sieve/sieve-lex.l
Changed
@@ -171,6 +171,10 @@ <INITIAL>:once return ONCE; <INITIAL>return return RETURN; <INITIAL>:copy return COPY; +<INITIAL>date return DATE; +<INITIAL>currentdate return CURRENTDATE; +<INITIAL>:zone return ZONE; +<INITIAL>:originalzone return ORIGINALZONE; <INITIAL>[ \t\n\r] ; /* ignore whitespace */ <INITIAL>#.* ; /* ignore hash comments */ <INITIAL>"/*"([^\*]|\*[^\/])*\*?"*/" ; /* ignore bracket comments */
View file
cyrus-imapd-2.5.tar.gz/sieve/sieve.y
Changed
@@ -123,12 +123,22 @@ int optional; }; +struct dttags { + int zonetag; + char *zone; + int comptag; + int relation; + char *comparator; + int date_part; +}; + static char *check_reqs(sieve_script_t *script, strarray_t *sl); static test_t *build_address(int t, struct aetags *ae, strarray_t *sl, strarray_t *pl); static test_t *build_header(int t, struct htags *h, strarray_t *sl, strarray_t *pl); static test_t *build_body(int t, struct btags *b, strarray_t *pl); +static test_t *build_date(int t, struct dttags *dt, char *hn, strarray_t *kl); static commandlist_t *build_vacation(int t, struct vtags *h, char *s); static commandlist_t *build_notify(int t, struct ntags *n); static commandlist_t *build_denotify(int t, struct dtags *n); @@ -154,6 +164,9 @@ static struct dtags *canon_dtags(struct dtags *d); static void free_dtags(struct dtags *d); static struct itags *new_itags(void); +static struct dttags *new_dttags(void); +static struct dttags *canon_dttags(struct dttags *dt); +static void free_dttags(struct dttags *b); static int verify_stringlist(sieve_script_t*, strarray_t *sl, int (*verify)(sieve_script_t*, char *)); static int verify_mailbox(sieve_script_t*, char *s); @@ -163,6 +176,8 @@ static int verify_envelope(sieve_script_t*, char *s); static int verify_flag(sieve_script_t*, char *s); static int verify_relat(sieve_script_t*, char *s); +static int verify_zone(sieve_script_t*, char *s); +static int verify_date_part(sieve_script_t *parse_script, char *dp); #ifdef ENABLE_REGEX static int verify_regex(sieve_script_t*, char *s, int cflags); static int verify_regexs(sieve_script_t*,const strarray_t *sl, char *comp); @@ -194,6 +209,7 @@ struct ntags *ntag; struct dtags *dtag; struct itags *itag; + struct dttags *dttag; } %token <nval> NUMBER @@ -211,6 +227,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 %type <cl> commands command action elsif block %type <sl> stringlist strings @@ -224,6 +242,7 @@ %type <ntag> ntags %type <dtag> dtags %type <itag> itags +%type <dttag> dttags %type <nval> priority %name-prefix="sieve" @@ -585,6 +604,32 @@ | NOT test { $$ = new_test(NOT); $$->u.t = $2; } | SIZE sizetag NUMBER { $$ = new_test(SIZE); $$->u.sz.t = $2; $$->u.sz.n = $3; } + | DATE dttags STRING STRING stringlist + { + $2->date_part = verify_date_part(parse_script, $4); + if ($2->date_part == -1) + { YYERROR; /*vr called yyerror()*/ } + + $2 = canon_dttags($2); + + $$ = build_date(DATE, $2, $3, $5); + if ($$ == NULL) { + yyerror(parse_script, "unable to find a compatible comparator"); + YYERROR; } + } + | CURRENTDATE dttags STRING STRING stringlist + { + $2->date_part = verify_date_part(parse_script, $4); + if ($2->date_part == -1) + { YYERROR; /*vr called yyerror()*/ } + + $2 = canon_dttags($2); + + $$ = build_date(CURRENTDATE, $2, $3, $5); + if ($$ == NULL) { + yyerror(parse_script, "unable to find a compatible comparator"); + YYERROR; } + } | error { $$ = NULL; } ; @@ -688,6 +733,43 @@ $$->comparator = $3; } } ; +dttags: /* empty */ { $$ = new_dttags(); } + | dttags comptag { $$ = $1; + if ($$->comptag != -1) { + yyerror(parse_script, "duplicate comparator type tag"); YYERROR; } + else { $$->comptag = $2; } } + + | dttags relcomp STRING { $$ = $1; + if ($$->comptag != -1) { + yyerror(parse_script, "duplicate comparator type tag"); YYERROR; } + else { + $$->comptag = $2; + $$->relation = verify_relat(parse_script, $3); + if ($$->relation == -1) { + YYERROR; /*vr called yyerror()*/ } } } + + | dttags COMPARATOR STRING { $$ = $1; + if ($$->comparator != NULL) { + yyerror(parse_script, "duplicate comparator tag"); YYERROR; } + else if (!strcmp($3, "i;ascii-numeric") && + !parse_script->support.i_ascii_numeric) { + yyerror(parse_script, "comparator-i;ascii-numeric MUST be enabled with \"require\""); YYERROR; } + else { $$->comparator = $3; } } + + | dttags ZONE STRING { $$ = $1; + if ($$->zonetag != -1) { + yyerror(parse_script, "duplicate zone tag"); YYERROR; } + else { + if (verify_zone(parse_script, $3) == -1) { + YYERROR; /*vr called yyerror()*/ } + else { $$->zone = $3; + $$->zonetag = ZONE; } } } + + | dttags ORIGINALZONE { $$ = $1; + if ($$->zonetag != -1) { + yyerror(parse_script, "duplicate zone tag"); YYERROR; } + else { $$->zonetag = ORIGINALZONE; } } + ; addrparttag: ALL { $$ = ALL; } | LOCALPART { $$ = LOCALPART; } @@ -943,6 +1025,27 @@ return ret; } +static test_t *build_date(int t, struct dttags *dt, + char *hn, strarray_t *kl) +{ + test_t *ret = new_test(t); + assert(t == DATE || t == CURRENTDATE); + + if (ret) { + 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.kl = kl; + free_dttags(dt); + } + return ret; +} + + static struct aetags *new_aetags(void) { struct aetags *r = (struct aetags *) xmalloc(sizeof(struct aetags)); @@ -1077,6 +1180,54 @@ return r; } +static struct dttags *new_dttags(void) +{ + struct dttags *dt = (struct dttags *) xmalloc(sizeof(struct dttags)); + dt->comptag = -1; + dt->zonetag = -1; + dt->relation = -1; + dt->comparator = NULL; + dt->zone = NULL; + dt->date_part = -1; + return dt; +} + +static struct dttags *canon_dttags(struct dttags *dt) +{ + char zone[6]; + int gmoffset; + int hours; + int minutes; + struct tm *tm; + time_t t; + + if (dt->comparator == NULL) { + dt->comparator = xstrdup("i;ascii-casemap"); + }
View file
cyrus-imapd-2.5.tar.gz/sieve/sieved.c
Changed
@@ -324,6 +324,65 @@ i=write_list(ntohl(d[i].len), i+1, d); printf(" ]\n"); break; + case BC_DATE:/*11*/ + case BC_CURRENTDATE:/*12*/ + /* current date */ + if (BC_DATE == ntohl(d[i++].value)) { + printf("date ["); + } + else { + printf("currentdate ["); + } + + /* zone tag */ + { + int zone; + int timezone_offset; + + printf("Zone-Tag: "); + zone = ntohl(d[i++].value); + switch (zone) { + case B_TIMEZONE: + timezone_offset = ntohl(d[i++].value); + printf("Specific timezone: offset by %d minutes.\n", timezone_offset); + break; + case B_ORIGINALZONE: + printf("Original zone.\n"); + break; + } + } + + i=printComparison(d, i); + + printf(" Date-Type: "); + switch(ntohl(d[i++].value)) + { + case B_YEAR: printf("year\n"); break; + case B_MONTH: printf("month\n"); break; + case B_DAY: printf("day\n"); break; + case B_JULIAN: printf("julian\n"); break; + case B_HOUR: printf("hour\n"); break; + case B_MINUTE: printf("minute\n"); break; + case B_SECOND: printf("second\n"); break; + case B_TIME: printf("time\n"); break; + case B_ISO8601: printf("iso8601\n"); break; + case B_STD11: printf("std11\n"); break; + case B_ZONE: printf("zone\n"); break; + case B_WEEKDAY: printf("weekday\n"); break; + } + + /* header name */ + { + const char *data; + int len; + i = unwrap_string(d, i, &data, &len); + printf(" Header Name: {%d}%s\n", len, data); + } + + printf(" Key List: "); + i=write_list(ntohl(d[i].len), i+1, d); + printf(" ]\n"); + break; default: printf("WERT %d ", ntohl(d[i].value)); }
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"]; +require ["regex", "relational", "comparator-i;ascii-numeric", "subaddress", "envelope", "date"]; #this is for the extra thigns we have added to sieve #test extensions @@ -145,3 +145,27 @@ if envelope :detail :matches "from" "e*k" {redirect "me+goodedetailmatches@blah.com";} + +###################################################################### +#DATE +###################################################################### + +if allof(header :is "from" "boss@example.com", + date :value "ge" :originalzone "date" "hour" "09", + date :value "lt" :originalzone "date" "hour" "17") +{redirect "me+urgent@blah.com";} + +if anyof(date :is "received" "weekday" "0", + date :is "received" "weekday" "6") +{redirect "me+weekend@blah.com";} + +if anyof(date :is :zone "-0800" "received" "weekday" "0", + date :is :zone "-0800" "received" "weekday" "6") +{redirect "me+weekend(pst)@blah.com";} + +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";} +
View file
cyrus-imapd-2.5.tar.gz/sieve/tree.c
Changed
@@ -159,6 +159,13 @@ case NOT: free_test(t->u.t); break; + + case DATE: + case CURRENTDATE: + free(t->u.dt.comparator); + free(t->u.dt.zone); + strarray_free(t->u.dt.kl); + break; } free(t);
View file
cyrus-imapd-2.5.tar.gz/sieve/tree.h
Changed
@@ -101,6 +101,16 @@ int t; /* tag */ int n; /* param */ } sz; + struct { /* it's a date test */ + int zonetag; + char *zone; + int comptag; + int relation; + char *comparator; + int date_part; + char *header_name; + strarray_t *kl; + } dt; } u; };
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
.