Dear all,

Please find attached two patches for the ANNOTATEMORE facility of Cyrus IMAP.

Patch one adds /vendor/kolab support to Cyrus, I am submitting it on behalf of
the Kolab developers and partners. We will be using ANNOTATEMORE to identify 
folder types, and would greatly appreciate the addition of our vendor tag into
Cyrus IMAP. Our IANA OID is 19414 for reference...

The second patch is optional, and more of a suggestion from the Kolab developers.
This will add support for /vendor/* to ANNOTATEMORE. Maybe it is worthwhile
considering this option, it should not have any foreseeable negative impact on 
the server, and going forward it would add a lot of flexibility to the ANNOTAMORE
function, thus speeding up adoption thereoff.

For any interested parties the work related to this patch is being actively 
discussed at: 
http://www.kolab.org/mailman/listinfo/kolab-format

On behalf of the Kolab developers. (http://www.kolab.org)

Kind regards,
-- 
Stephan  Buys
--- annotate.c.old	2004-07-02 18:13:13.000000000 +0200
+++ annotate.c	2004-07-02 18:17:19.000000000 +0200
@@ -1595,6 +1595,8 @@
     { "/vendor/cmu/cyrus-imapd/news2mail", ATTRIB_TYPE_STRING, BACKEND_ONLY,
       ATTRIB_VALUE_SHARED | ATTRIB_CONTENTTYPE_SHARED,
       ACL_ADMIN, annotation_set_todb, NULL },
+    { "/vendor/kolab/foldertype", ATTRIB_TYPE_STRING, BACKEND_ONLY,
+      ATTRIB_VALUE_SHARED, ACL_ADMIN, annotation_set_todb, NULL },  
     { NULL, 0, ANNOTATION_PROXY_T_INVALID, 0, 0, NULL, NULL }
 };
 
--- annotate.c.old	2004-07-02 18:13:13.000000000 +0200
+++ annotate.c	2004-07-03 10:20:17.000000000 +0200
@@ -1598,6 +1598,11 @@
     { NULL, 0, ANNOTATION_PROXY_T_INVALID, 0, 0, NULL, NULL }
 };
 
+const struct annotate_st_entry vendor_entry =
+    { NULL, ATTRIB_TYPE_STRING, BACKEND_ONLY,
+      ATTRIB_VALUE_SHARED | ATTRIB_VALUE_PRIV,
+      ACL_ADMIN, annotation_set_todb, NULL };
+
 int annotatemore_store(char *mailbox,
 		       struct entryattlist *l,
 		       struct namespace *namespace,
@@ -1610,6 +1615,7 @@
     struct attvaluelist *av;
     struct storedata sdata;
     const struct annotate_st_entry *entries;
+    struct annotate_st_entry * working_entry;
     time_t now = time(0);
 
     memset(&sdata, 0, sizeof(struct storedata));
@@ -1631,37 +1637,55 @@
     while (e) {
 	int entrycount, attribs;
 	struct annotate_st_entry_list *nentry = NULL;
+	struct annotate_st_entry *ientry = NULL;
 
 	/* See if we support this entry */
+	working_entry = NULL;
 	for (entrycount = 0;
 	     entries[entrycount].name;
 	     entrycount++) {
 	    if (!strcmp(e->entry, entries[entrycount].name)) {
+	        working_entry = &(entries[entrycount]);
 		break;
 	    }
 	}
-	if (!entries[entrycount].name) {
-	    /* unknown annotation */
-	    return IMAP_PERMISSION_DENIED;
+	if (working_entry==NULL) {
+	    /* test for generic vendor annotation */
+	    if ((strncmp("/vendor/", e->entry, strlen("/vendor/"))==0) &&
+	        (strlen(e->entry)>strlen("/vendor/"))) {
+	      working_entry = &(vendor_entry);
+	    }
+	    else {
+	        /* 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_AND_BACKEND
+	if (working_entry->proxytype == PROXY_AND_BACKEND
 	    || (proxy_store_func &&
-		entries[entrycount].proxytype == PROXY_ONLY)
+		working_entry->proxytype == PROXY_ONLY)
 	    || (!proxy_store_func &&
-		entries[entrycount].proxytype == BACKEND_ONLY)) {
+		working_entry->proxytype == BACKEND_ONLY)) {
+            ientry = xzmalloc(sizeof(struct annotate_st_entry));
+            ientry->name = e->entry;
+            ientry->type = working_entry->type;
+            ientry->proxytype = working_entry->proxytype;
+            ientry->attribs = working_entry->attribs;
+            ientry->acl = working_entry->acl;
+            ientry->set = working_entry->set;
+            ientry->rock = working_entry->rock;	
 	    nentry = xzmalloc(sizeof(struct annotate_st_entry_list));
 	    nentry->next = sdata.entry_list;
-	    nentry->entry = &(entries[entrycount]);
+	    nentry->entry = ientry;
 	    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 = working_entry->attribs;
 	av = e->attvalues;
 	while (av) {
 	    const char *value;
@@ -1671,7 +1695,7 @@
 		    goto cleanup;
 		}
 		value = annotate_canon_value(av->value,
-					     entries[entrycount].type);
+					     working_entry->type);
 		if (!value) {
 		    r = IMAP_ANNOTATION_BADVALUE;
 		    goto cleanup;
@@ -1697,7 +1721,7 @@
 		    goto cleanup;
 		}
 		value = annotate_canon_value(av->value,
-					     entries[entrycount].type);
+					     working_entry->type);
 		if (!value) {
 		    r = IMAP_ANNOTATION_BADVALUE;
 		    goto cleanup;
@@ -1797,6 +1821,12 @@
     /* Free the entry list */
     while (sdata.entry_list) {
 	struct annotate_st_entry_list *freeme = sdata.entry_list;
+	if (freeme != NULL){
+	    struct annotate_st_entry *freeme2 = freeme->entry;
+	    if (freeme2 != NULL) {
+	        free( freeme2 );
+	    }
+	}
 	sdata.entry_list = sdata.entry_list->next;
 	free(freeme);
     }

Reply via email to