diff options
Diffstat (limited to 'net-mail/cyrus-imapd/files/kolab/2.3.12/annotations2.patch')
-rw-r--r-- | net-mail/cyrus-imapd/files/kolab/2.3.12/annotations2.patch | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/net-mail/cyrus-imapd/files/kolab/2.3.12/annotations2.patch b/net-mail/cyrus-imapd/files/kolab/2.3.12/annotations2.patch new file mode 100644 index 0000000..87fa920 --- /dev/null +++ b/net-mail/cyrus-imapd/files/kolab/2.3.12/annotations2.patch @@ -0,0 +1,356 @@ +Provides a new version of annotation support for the cyrus imapd server [Version: 2.3.9] + +diff -r 321cda1d6136 imap/annotate.c +--- a/imap/annotate.c Tue Apr 22 10:44:56 2008 +0200 ++++ b/imap/annotate.c Tue Apr 22 10:47:04 2008 +0200 +@@ -90,6 +90,8 @@ int (*proxy_fetch_func)(const char *serv + struct strlist *attribute_pat) = NULL; + int (*proxy_store_func)(const char *server, const char *mbox_pat, + struct entryattlist *entryatts) = NULL; ++ ++void init_annotation_definitions(); + + /* String List Management */ + /* +@@ -237,6 +239,8 @@ void annotatemore_init(int myflags, + if (store_func) { + proxy_store_func = store_func; + } ++ ++ init_annotation_definitions(); + } + + void annotatemore_open(char *fname) +@@ -1832,6 +1836,224 @@ const struct annotate_st_entry mailbox_r + { NULL, 0, ANNOTATION_PROXY_T_INVALID, 0, 0, NULL, NULL } + }; + ++struct annotate_st_entry_list *server_entries_list = NULL; ++struct annotate_st_entry_list *mailbox_rw_entries_list = NULL; ++ ++enum { ++ ANNOTATION_SCOPE_SERVER = 1, ++ ANNOTATION_SCOPE_MAILBOX = 2 ++}; ++ ++const struct annotate_attrib annotation_scope_names[] = ++{ ++ { "server", ANNOTATION_SCOPE_SERVER }, ++ { "mailbox", ANNOTATION_SCOPE_MAILBOX }, ++ { NULL, 0 } ++}; ++ ++const struct annotate_attrib annotation_proxy_type_names[] = ++{ ++ { "proxy", PROXY_ONLY }, ++ { "backend", BACKEND_ONLY }, ++ { "proxy_and_backend", PROXY_AND_BACKEND }, ++ { NULL, 0 } ++}; ++ ++const struct annotate_attrib attribute_type_names[] = ++{ ++ { "content-type", ATTRIB_TYPE_CONTENTTYPE }, ++ { "string", ATTRIB_TYPE_STRING }, ++ { "boolean", ATTRIB_TYPE_BOOLEAN }, ++ { "uint", ATTRIB_TYPE_UINT }, ++ { "int", ATTRIB_TYPE_INT }, ++ { NULL, 0 } ++}; ++ ++#define ANNOT_DEF_MAXLINELEN 1024 ++ ++int table_lookup(const struct annotate_attrib *table, ++ char* name, ++ size_t namelen, ++ char* errmsg) ++/* search in table for the value given by name and namelen (name is null-terminated, ++ but possibly more than just the key). errmsg is used to hint the user where we failed */ ++{ ++ char errbuf[ANNOT_DEF_MAXLINELEN*2]; ++ int entry; ++ ++ for (entry = 0; table[entry].name && ++ (strncasecmp(table[entry].name, name, namelen) ++ || table[entry].name[namelen] != '\0'); entry++); ++ ++ if (! table[entry].name) { ++ sprintf(errbuf, "invalid %s at '%s'", errmsg, name); ++ fatal(errbuf, EC_CONFIG); ++ } ++ return table[entry].entry; ++} ++ ++char *consume_comma(char* p) ++ /* advance beyond the next ',', skipping whitespace, fail if next non-space is no comma */ ++{ ++ char errbuf[ANNOT_DEF_MAXLINELEN*2]; ++ ++ for (; *p && isspace(*p); p++); ++ if (*p != ',') { ++ sprintf(errbuf, "',' expected, '%s' found parsing annotation definition", ++ p); ++ fatal(errbuf, EC_CONFIG); ++ } ++ p++; ++ for (; *p && isspace(*p); p++); ++ ++ return p; ++} ++ ++int parse_table_lookup_bitmask(const struct annotate_attrib *table, ++ char** s, ++ char* errmsg) ++ /* parses strings of the form value1 [ value2 [ ... ]] ++ value1 is mapped via table to ints and the result ored ++ whitespace is allowed between value names and punctuation ++ the field must end in '\0' or ',' ++ s is advanced to '\0' or ',' ++ on error errmsg is used to identify item to be parsed ++ */ ++{ ++ char errbuf[ANNOT_DEF_MAXLINELEN*2]; ++ int result = 0; ++ char *p, *p2; ++ ++ p = *s; ++ do { ++ p2 = p; ++ for (; *p && (isalnum(*p) || *p=='.' || *p=='-' || *p=='_' || *p=='/');p++); ++ result |= table_lookup(table, p2, p-p2, errmsg); ++ for (; *p && isspace(*p); p++); ++ } while (*p && *p != ','); ++ ++ *s = p; ++ return result; ++} ++ ++void init_annotation_definitions() ++{ ++ char *p, *p2, *tmp; ++ const char *filename; ++ char aline[ANNOT_DEF_MAXLINELEN]; ++ char errbuf[ANNOT_DEF_MAXLINELEN*2]; ++ struct annotate_st_entry_list *se, *me; ++ struct annotate_st_entry *ae; ++ int i; ++ FILE* f; ++ ++ /* NOTE: we assume # static entries > 0 */ ++ server_entries_list = xmalloc(sizeof(struct annotate_st_entry_list)); ++ mailbox_rw_entries_list = xmalloc(sizeof(struct annotate_st_entry_list)); ++ se = server_entries_list; ++ me = mailbox_rw_entries_list; ++ /* copy static entries into list */ ++ for (i = 0; server_entries[i].name;i++) { ++ se->entry = &server_entries[i]; ++ if (server_entries[i+1].name) { ++ se->next = xmalloc(sizeof(struct annotate_st_entry_list)); ++ se = se->next; ++ } ++ } ++ /* copy static entries into list */ ++ for (i = 0; mailbox_rw_entries[i].name;i++) { ++ me->entry = &mailbox_rw_entries[i]; ++ if (mailbox_rw_entries[i+1].name) { ++ me->next = xmalloc(sizeof(struct annotate_st_entry_list)); ++ me = me->next; ++ } ++ } ++ ++ /* parse config file */ ++ filename = config_getstring(IMAPOPT_ANNOTATION_DEFINITIONS); ++ ++ if (! filename) { ++ se->next = NULL; ++ me->next = NULL; ++ return; ++ } ++ ++ f = fopen(filename,"r"); ++ if (! f) { ++ sprintf(errbuf, "could not open annotation definiton %s", filename); ++ fatal(errbuf, EC_CONFIG); ++ } ++ ++ while (fgets(aline, sizeof(aline), f)) { ++ // remove leading space, skip blank lines and comments ++ for (p = aline; *p && isspace(*p); p++); ++ if (!*p || *p == '#') continue; ++ ++ // note, we only do the most basic validity checking and may ++ // be more restrictive than neccessary ++ ++ ae = xmalloc(sizeof(struct annotate_st_entry)); ++ ++ p2 = p; ++ for (; *p && (isalnum(*p) || *p=='.' || *p=='-' || *p=='_' || *p=='/');p++); ++ // TV-TODO: should test for empty ++ ae->name = xstrndup(p2, p-p2); ++ ++ p = consume_comma(p); ++ ++ p2 = p; ++ for (; *p && (isalnum(*p) || *p=='.' || *p=='-' || *p=='_' || *p=='/');p++); ++ ++ if (table_lookup(annotation_scope_names, p2, p-p2, ++ "annotation scope")==ANNOTATION_SCOPE_SERVER) { ++ se->next = xmalloc(sizeof(struct annotate_st_entry_list)); ++ se = se->next; ++ se->entry = ae; ++ } ++ else { ++ me->next = xmalloc(sizeof(struct annotate_st_entry_list)); ++ me = me->next; ++ me->entry = ae; ++ } ++ ++ p = consume_comma(p); ++ p2 = p; ++ for (; *p && (isalnum(*p) || *p=='.' || *p=='-' || *p=='_' || *p=='/');p++); ++ ae->type = table_lookup(attribute_type_names, p2, p-p2, ++ "attribute type"); ++ ++ p = consume_comma(p); ++ ae->proxytype = parse_table_lookup_bitmask(annotation_proxy_type_names, ++ &p, ++ "annotation proxy type"); ++ ++ p = consume_comma(p); ++ ae->attribs = parse_table_lookup_bitmask(annotation_attributes, ++ &p, ++ "annotation attributes"); ++ ++ p = consume_comma(p); ++ p2 = p; ++ for (; *p && (isalnum(*p) || *p=='.' || *p=='-' || *p=='_' || *p=='/');p++); ++ tmp = xstrndup(p2, p-p2); ++ ae->acl = cyrus_acl_strtomask(tmp); ++ free(tmp); ++ ++ for (; *p && isspace(*p); p++); ++ if (*p) { ++ sprintf(errbuf, "junk at end of line: '%s'", p); ++ fatal(errbuf, EC_CONFIG); ++ } ++ ++ ae->set = annotation_set_todb; ++ ae->rock = NULL; ++ } ++ ++ fclose(f); ++ se->next = NULL; ++ me->next = NULL; ++} ++ + int annotatemore_store(char *mailbox, + struct entryattlist *l, + struct namespace *namespace, +@@ -1843,7 +2065,7 @@ int annotatemore_store(char *mailbox, + struct entryattlist *e = l; + struct attvaluelist *av; + struct storedata sdata; +- const struct annotate_st_entry *entries; ++ const struct annotate_st_entry_list *entries, *currententry; + time_t now = time(0); + + memset(&sdata, 0, sizeof(struct storedata)); +@@ -1854,45 +2076,45 @@ int annotatemore_store(char *mailbox, + + if (!mailbox[0]) { + /* server annotations */ +- entries = server_entries; ++ entries = server_entries_list; + } + else { + /* mailbox annotation(s) */ +- entries = mailbox_rw_entries; ++ entries = mailbox_rw_entries_list; + } + + /* Build a list of callbacks for storing the annotations */ + while (e) { +- int entrycount, attribs; ++ int attribs; + struct annotate_st_entry_list *nentry = NULL; + + /* See if we support this entry */ +- for (entrycount = 0; +- entries[entrycount].name; +- entrycount++) { +- if (!strcmp(e->entry, entries[entrycount].name)) { ++ for (currententry = entries; ++ currententry; ++ currententry = currententry->next) { ++ if (!strcmp(e->entry, currententry->entry->name)) { + break; + } + } +- if (!entries[entrycount].name) { ++ if (!currententry) { + /* unknown annotation */ + return IMAP_PERMISSION_DENIED; + } + + /* Add this entry to our list only if it + applies to our particular server type */ +- if ((entries[entrycount].proxytype != PROXY_ONLY) ++ if ((currententry->entry->proxytype != PROXY_ONLY) + || proxy_store_func) { + nentry = xzmalloc(sizeof(struct annotate_st_entry_list)); + nentry->next = sdata.entry_list; +- nentry->entry = &(entries[entrycount]); ++ nentry->entry = currententry->entry; + nentry->shared.modifiedsince = now; + nentry->priv.modifiedsince = now; + sdata.entry_list = nentry; + } + + /* See if we are allowed to set the given attributes. */ +- attribs = entries[entrycount].attribs; ++ attribs = currententry->entry->attribs; + av = e->attvalues; + while (av) { + const char *value; +@@ -1902,7 +2124,7 @@ int annotatemore_store(char *mailbox, + goto cleanup; + } + value = annotate_canon_value(av->value, +- entries[entrycount].type); ++ currententry->entry->type); + if (!value) { + r = IMAP_ANNOTATION_BADVALUE; + goto cleanup; +@@ -1928,7 +2150,7 @@ int annotatemore_store(char *mailbox, + goto cleanup; + } + value = annotate_canon_value(av->value, +- entries[entrycount].type); ++ currententry->entry->type); + if (!value) { + r = IMAP_ANNOTATION_BADVALUE; + goto cleanup; +@@ -2110,3 +2332,10 @@ int annotatemore_delete(const char *mbox + + return annotatemore_rename(mboxname, NULL, NULL, NULL); + } ++ ++/* This file contains code Copyright (c) 2006 by Thomas Viehmann. ++ * You may distribute source code or binaries under the conditions ++ * conditions given in the CMU license, provided this note stays intact ++ * in the distributed source. If you want to distribute my code without ++ * this notice, do contact me at <tv@beamnet.de>. ++ */ +diff -r 321cda1d6136 lib/imapoptions +--- a/lib/imapoptions Tue Apr 22 10:44:56 2008 +0200 ++++ b/lib/imapoptions Tue Apr 22 10:47:04 2008 +0200 +@@ -172,6 +172,9 @@ are listed with ``<none>''. + /* Should non-admin users be allowed to set ACLs for the 'anyone' + user on their mailboxes? In a large organization this can cause + support problems, but it's enabled by default. */ ++ ++{ "annotation_definitions", NULL, STRING } ++/* File containing annotation definitions. */ + + { "auth_mech", "unix", STRINGLIST("unix", "pts", "krb", "krb5")} + /* The authorization mechanism to use. */ |