Sophie

Sophie

distrib > Mandriva > cs4.0 > x86_64 > by-pkgid > c919e73e89042c823ded3ad64347498f > files > 8

cyrus-imapd-2.2.13-2mdv2007.0.src.rpm


http://wiki.kolab.org/index.php/Kolab-major-app-patches

Patch description:

    There is an imap extension for adding "annotations" (eg. metadata) to imap folders in the form of key/value 
    pairs. The key is typically something like /vendor/<vendorname>/<attributename>. Cyrus imapd only supports a 
    few special annotation keys for internal use (such as being able to mark a folder for indexing etc.). The 
    patch extends cyrus imapd to allow any annotation. 
    
Impact:
    
    The annotation patch is critical to kolab. Without the patch, the clients will not know which folder is for 
    calender, tasks etc. 

--- imap/annotate.c	2005-10-31 18:08:59.000000000 +0100
+++ imap/annotate.c.oden	2006-06-01 16:51:14.000000000 +0200
@@ -1667,6 +1667,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,
@@ -1679,6 +1684,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));
@@ -1700,37 +1706,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;
@@ -1740,7 +1764,7 @@
 		    goto cleanup;
 		}
 		value = annotate_canon_value(av->value,
-					     entries[entrycount].type);
+					     working_entry->type);
 		if (!value) {
 		    r = IMAP_ANNOTATION_BADVALUE;
 		    goto cleanup;
@@ -1766,7 +1790,7 @@
 		    goto cleanup;
 		}
 		value = annotate_canon_value(av->value,
-					     entries[entrycount].type);
+					     working_entry->type);
 		if (!value) {
 		    r = IMAP_ANNOTATION_BADVALUE;
 		    goto cleanup;
@@ -1868,6 +1892,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);
     }