Replace existing OCPF recipients implementation with a SRowSet
authorjkerihuel <jkerihuel@71d39326-ef09-db11-b2a4-00e04c779ad1>
Mon, 28 Feb 2011 18:02:34 +0000 (18:02 +0000)
committerjkerihuel <jkerihuel@71d39326-ef09-db11-b2a4-00e04c779ad1>
Mon, 28 Feb 2011 18:02:34 +0000 (18:02 +0000)
Use PT_UNICODE instead of PT_STRING8 for most string properties (except MNID_ID specifically tagged as PT_STRING8)
Use Recipient blocks instead of strings similar to:

RECIPIENT {
TO {
prop1 = propvalue
prop2 = propvalue2
};

CC {
[...]
};

BCC {
[...]
};
};

Works with internal/external recipients too.

git-svn-id: https://svn.openchange.org/openchange@2709 71d39326-ef09-db11-b2a4-00e04c779ad1

trunk/libmapi/IMessage.c
trunk/libocpf/examples/sample_appointment.ocpf
trunk/libocpf/ocpf.y
trunk/libocpf/ocpf_api.c
trunk/libocpf/ocpf_api.h
trunk/libocpf/ocpf_context.c
trunk/libocpf/ocpf_dump.c
trunk/libocpf/ocpf_private.h
trunk/libocpf/ocpf_public.c
trunk/libocpf/ocpf_write.c
trunk/pyopenchange/tests/mapistore_test.py

index 64a1931e06c8d78e897d9aeeba430d9221552c98..2a76a521b151f730523706a2522cd32b1b013468 100644 (file)
@@ -499,7 +499,7 @@ _PUBLIC_ enum MAPISTATUS SetRecipientType(struct SRow *aRow, enum ulRecipClass R
        enum MAPISTATUS         retval;
        struct SPropValue       lpProp;
 
-       lpProp.ulPropTag = PR_RECIPIENT_TYPE;
+       lpProp.ulPropTag = PidTagRecipientType;
        lpProp.value.l = RecipClass;
 
        retval = SRow_addprop(aRow, lpProp);
index d88d0564480f327de450d4a0520f581aa09cc356..3b18056d32c44ae6640b1fd840186e6f08b97f9c 100644 (file)
@@ -27,7 +27,7 @@ OLEGUID       PSETID_Appointment      "00062002-0000-0000-c000-000000000046"
 OLEGUID        PSETID_Common           "00062008-0000-0000-c000-000000000046"
 OLEGUID        PS_PUBLIC_STRINGS       "00020329-0000-0000-c000-000000000046"
 
-SET $subject = "[OCPF] Julien Kerihuel Birthday"
+SET $subject = W"[OCPF] Julien Kerihuel Birthday"
 SET $start_date = T2008-03-06 22:00:00
 SET $end_date = T2008-03-06 23:45:00
 SET $reminder = 45
@@ -36,12 +36,12 @@ SET $private = B"true"
 SET $wrong = 0
 
 PROPERTY {
-        PR_CONVERSATION_TOPIC = $subject
-        PR_NORMALIZED_SUBJECT = $subject
-        PR_BODY = "Another year, another pleasure"      
-        PR_START_DATE = $start_date
-        PR_END_DATE = $end_date
-        PR_SENSITIVITY = 2
+        PidTagConversationTopic = $subject
+        PidTagNormalizedSubject = $subject
+        PidTagBody = W"Another year, another pleasure"  
+        PidTagStartDate = $start_date
+        PidTagEndDate = $end_date
+        PidTagSensitivity = 2
 };
 
 NPROPERTY {
@@ -63,5 +63,5 @@ NPROPERTY {
          MNID_ID:0x8501:PT_LONG:PSETID_Common = $reminder
 
          /* Add categories */
-         MNID_STRING:"Keywords":PS_PUBLIC_STRINGS = $keywords
+         MNID_STRING:"Categories":PS_PUBLIC_STRINGS = $keywords
 };
\ No newline at end of file
index 180500e1723d9edc53574c298982ac5f8c0139b3..28aa8ae626aaa9c9b3f5e197e8586b17feefce00 100644 (file)
@@ -1,7 +1,7 @@
 /*
    OpenChange OCPF (OpenChange Property File) implementation.
 
-   Copyright (C) Julien Kerihuel 2008-2010.
+   Copyright (C) Julien Kerihuel 2008-2011.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -183,6 +183,56 @@ Set                :
                }
                ;
 
+Recipient      :
+               kw_RECIPIENT OBRACE recipients EBRACE SEMICOLON
+               {
+               }
+
+recipients     : | recipients recipient
+
+recipient      :
+               kw_TO OBRACE rpcontent EBRACE SEMICOLON
+               {
+                       ocpf_recipient_set_class(ctx, MAPI_TO);
+                       ocpf_new_recipient(ctx);
+               }
+               | kw_CC OBRACE rpcontent EBRACE SEMICOLON
+               {
+                       ocpf_recipient_set_class(ctx, MAPI_CC);
+                       ocpf_new_recipient(ctx);
+               }
+               | kw_BCC OBRACE rpcontent EBRACE SEMICOLON
+               {
+                       ocpf_recipient_set_class(ctx, MAPI_BCC);
+                       ocpf_new_recipient(ctx);
+               }
+               ;
+
+rpcontent      : | rpcontent rcontent
+               {
+                       memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR));
+               }
+
+rcontent       :
+               IDENTIFIER EQUAL propvalue
+               {
+                       ocpf_propvalue_s(ctx, $1, ctx->lpProp, ctx->ltype, true, kw_RECIPIENT);
+                       ocpf_propvalue_free(ctx->lpProp, ctx->ltype);
+               }
+               | INTEGER EQUAL propvalue
+               {
+                       ocpf_propvalue(ctx, $1, ctx->lpProp, ctx->ltype, true, kw_RECIPIENT);
+                       ocpf_propvalue_free(ctx->lpProp, ctx->ltype);
+               }
+               | IDENTIFIER EQUAL VAR
+               {
+                       ocpf_propvalue_var(ctx, $1, 0x0, $3, true, kw_RECIPIENT);
+               }
+               | INTEGER EQUAL VAR
+               {
+                       ocpf_propvalue_var(ctx, NULL, $1, $3, true, kw_RECIPIENT);
+               };
+
 Property       :
                kw_PROPERTY OBRACE pcontent EBRACE SEMICOLON
                {
@@ -197,21 +247,21 @@ pcontent          : | pcontent content
 content                :
                IDENTIFIER EQUAL propvalue
                {
-                       ocpf_propvalue_s(ctx, $1, ctx->lpProp, ctx->ltype, true);
+                       ocpf_propvalue_s(ctx, $1, ctx->lpProp, ctx->ltype, true, kw_PROPERTY);
                        ocpf_propvalue_free(ctx->lpProp, ctx->ltype);
                }
                | INTEGER EQUAL propvalue
                {
-                       ocpf_propvalue(ctx, $1, ctx->lpProp, ctx->ltype, true);
+                       ocpf_propvalue(ctx, $1, ctx->lpProp, ctx->ltype, true, kw_PROPERTY);
                        ocpf_propvalue_free(ctx->lpProp, ctx->ltype);
                }
                | IDENTIFIER EQUAL VAR
                {
-                       ocpf_propvalue_var(ctx, $1, 0x0, $3, true);
+                       ocpf_propvalue_var(ctx, $1, 0x0, $3, true, kw_PROPERTY);
                }
                | INTEGER EQUAL VAR
                {
-                       ocpf_propvalue_var(ctx, NULL, $1, $3, true);
+                       ocpf_propvalue_var(ctx, NULL, $1, $3, true, kw_PROPERTY);
                }
                ;
 
@@ -566,44 +616,6 @@ known_kind : kw_MNID_ID COLON INTEGER COLON IDENTIFIER
                }
                ;
 
-Recipient      : 
-               kw_RECIPIENT recipClass recipients STRING
-               {
-                       char    *recipient = NULL;
-
-                       recipient = talloc_strdup(ctx, $4);
-                       ocpf_recipient_add(ctx, ctx->recip_type, recipient);
-                       talloc_free(recipient);
-
-                       ctx->recip_type = 0;
-               }
-               ;
-
-recipClass     : kw_TO
-               {
-                       ctx->recip_type = MAPI_TO;
-               }
-               | kw_CC
-               {
-                       ctx->recip_type = MAPI_CC;
-               }
-               | kw_BCC
-               {
-                       ctx->recip_type = MAPI_BCC;
-               }
-               ;
-
-recipients     : | recipients recipient
-
-recipient      : STRING SEMICOLON
-               {
-                       char    *recipient = NULL;
-
-                       recipient = talloc_strdup(ctx, $1);
-                       ocpf_recipient_add(ctx, ctx->recip_type, recipient);
-                       talloc_free(recipient);
-               }
-
 %%
 
 void yyerror(struct ocpf_context *ctx, void *scanner, char *s)
index d591157a401920830bcb6cb69f8905bfa4d0ca93..7a26778cd100f570751bdf4d979c3d7d1d88c7e3 100644 (file)
@@ -1,7 +1,7 @@
 /*
    OpenChange OCPF (OpenChange Property File) implementation.
 
-   Copyright (C) Julien Kerihuel 2008-2010.
+   Copyright (C) Julien Kerihuel 2008-2011.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
 
 #include "libocpf/ocpf.h"
 #include "libocpf/ocpf_api.h"
+#include "libocpf/ocpf_private.h"
 
 /**
    \file ocpf_api.c
@@ -61,11 +62,17 @@ int ocpf_propvalue_var(struct ocpf_context *ctx,
                       const char *propname, 
                       uint32_t proptag, 
                       const char *variable, 
-                      bool unescape)
+                      bool unescape,
+                      int scope)
 {
        struct ocpf_var         *vel;
        struct ocpf_property    *element;
        uint32_t                aulPropTag;
+       uint32_t                cRows;
+       struct SRow             aRow;
+       struct SPropValue       lpProps;
+       void                    *value;
+       int                     i;
 
        if (!ocpf || !ocpf->mem_ctx) return -1;
        if (!propname && !proptag) return -1;
@@ -78,25 +85,62 @@ int ocpf_propvalue_var(struct ocpf_context *ctx,
                aulPropTag = get_proptag_value(propname);
        }
 
-       for (element = ctx->props; element->next; element = element->next) {
-               OCPF_RETVAL_IF(element->aulPropTag == aulPropTag, ctx, OCPF_WARN_PROP_REGISTERED, NULL);
-       }
+       switch (scope) {
+       case kw_PROPERTY:
+               for (element = ctx->props; element->next; element = element->next) {
+                       OCPF_RETVAL_IF(element->aulPropTag == aulPropTag, ctx, OCPF_WARN_PROP_REGISTERED, NULL);
+               }
+               for (vel = ctx->vars; vel->next; vel = vel->next) {
+                       if (vel->name && !strcmp(vel->name, variable)) {
+                               OCPF_RETVAL_IF(vel->propType != (aulPropTag & 0xFFFF), ctx, OCPF_WARN_PROPVALUE_MISMATCH, NULL);
+                               element = NULL;
+                               element = talloc_zero(ctx->vars, struct ocpf_property);
+                               element->aulPropTag = aulPropTag;
+                               if (unescape && (((aulPropTag & 0xFFFF) == PT_STRING8) || 
+                                                ((aulPropTag & 0xFFFF) == PT_UNICODE))) {
+                                       element->value = ocpf_write_unescape_string(ctx, vel->value);
+                               } else {
+                                       element->value = vel->value;
+                               }
+                               DLIST_ADD(ctx->props, element);
+                               return OCPF_SUCCESS;
+                       }
+               }
+               break;
+       case kw_RECIPIENT:
+               cRows = ctx->recipients->cRows;
+               aRow = ctx->recipients->aRow[cRows];
+               for (i = 0; i < aRow.cValues; i++) {
+                       OCPF_RETVAL_IF(aRow.lpProps[i].ulPropTag == aulPropTag, ctx, OCPF_WARN_PROP_REGISTERED, NULL);
+               }
+               for (vel = ctx->vars; vel->next; vel = vel->next) {
+                       if (vel->name && !strcmp(vel->name, variable)) {
+                               OCPF_RETVAL_IF(vel->propType != (aulPropTag & 0xFFFF), ctx, OCPF_WARN_PROPVALUE_MISMATCH, NULL);
+                               lpProps.ulPropTag = aulPropTag;
+                               lpProps.dwAlignPad = 0;
+                               if (unescape && (((aulPropTag & 0xFFFF) == PT_STRING8) ||
+                                                ((aulPropTag & 0xFFFF) == PT_UNICODE))) {
+                                       value = ocpf_write_unescape_string(ctx, vel->value);
+                               } else {
+                                       value = (void *)vel->value;
+                               }
+                               set_SPropValue(&lpProps, value);
 
-       for (vel = ctx->vars; vel->next; vel = vel->next) {
-               if (vel->name && !strcmp(vel->name, variable)) {
-                       OCPF_RETVAL_IF(vel->propType != (aulPropTag & 0xFFFF), ctx, OCPF_WARN_PROPVALUE_MISMATCH, NULL);
-                       element = NULL;
-                       element = talloc_zero(ctx->vars, struct ocpf_property);
-                       element->aulPropTag = aulPropTag;
-                       if (unescape && (((aulPropTag & 0xFFFF) == PT_STRING8) || 
-                                        ((aulPropTag & 0xFFFF) == PT_UNICODE))) {
-                               element->value = ocpf_write_unescape_string(ctx, vel->value);
-                       } else {
-                               element->value = vel->value;
+                               if (!aRow.cValues) {
+                                       aRow.lpProps = talloc_array((TALLOC_CTX *)ctx->recipients->aRow, struct SPropValue, 2);
+                               } else {
+                                       aRow.lpProps = talloc_realloc(aRow.lpProps, aRow.lpProps, 
+                                                                     struct SPropValue, aRow.cValues + 2);
+                               }
+                               aRow.lpProps[aRow.cValues] = lpProps;
+                               aRow.cValues += 1;
+                               ctx->recipients->aRow[cRows] = aRow;
+                               return OCPF_SUCCESS;
                        }
-                       DLIST_ADD(ctx->props, element);
-                       return OCPF_SUCCESS;
                }
+               break;
+       default:
+               break;
        }
 
        OCPF_RETVAL_IF(1, ctx, OCPF_WARN_VAR_NOT_REGISTERED, NULL);
@@ -257,43 +301,144 @@ int ocpf_propvalue(struct ocpf_context *ctx,
                   uint32_t aulPropTag, 
                   union SPropValue_CTR lpProp, 
                   uint16_t proptype, 
-                  bool unescape)
+                  bool unescape,
+                  int scope)
 {
        struct ocpf_property    *element;
        int                     ret;
+       uint32_t                cRows;
+       struct SRow             aRow;
+       struct SPropValue       lpProps;
+       void                    *value;
+       int                     i;
 
        if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR;
+       if (!ctx) return OCPF_ERROR;
 
-       /* Sanity check: do not insert the same property twice */
-       for (element = ctx->props; element->next; element = element->next) {
-               OCPF_RETVAL_IF(element->aulPropTag == aulPropTag, ctx, OCPF_WARN_PROP_REGISTERED, NULL);
-       }
+       switch (scope) {
+       case kw_PROPERTY:
+               /* Sanity check: do not insert the same property twice */
+               for (element = ctx->props; element->next; element = element->next) {
+                       OCPF_RETVAL_IF(element->aulPropTag == aulPropTag, ctx, OCPF_WARN_PROP_REGISTERED, NULL);
+               }
 
-       element = NULL;
-       element = talloc_zero(ctx->props, struct ocpf_property);
-       element->aulPropTag = aulPropTag;
-       ret = ocpf_set_propvalue((TALLOC_CTX *)element, ctx, &element->value, 
-                                (uint16_t)aulPropTag & 0xFFFF, proptype, lpProp, unescape);
-       if (ret == -1) {
-               talloc_free(element);
-               return OCPF_ERROR;
+               element = NULL;
+               element = talloc_zero(ctx->props, struct ocpf_property);
+               if ((aulPropTag & 0xFFFF) == PT_STRING8) {
+                       element->aulPropTag = (aulPropTag & 0xFFFF0000) + PT_UNICODE;
+               } else {
+                       element->aulPropTag = aulPropTag;
+               }
+               ret = ocpf_set_propvalue((TALLOC_CTX *)element, ctx, &element->value, 
+                                        (uint16_t)aulPropTag & 0xFFFF, proptype, lpProp, unescape);
+               if (ret == -1) {
+                       talloc_free(element);
+                       return OCPF_ERROR;
+               }
+
+               DLIST_ADD(ctx->props, element);
+               break;
+       case kw_RECIPIENT:
+               cRows = ctx->recipients->cRows;
+               aRow = ctx->recipients->aRow[cRows];
+               for (i = 0; i < aRow.cValues; i++) {
+                       OCPF_RETVAL_IF(aRow.lpProps[i].ulPropTag == aulPropTag, ctx, OCPF_WARN_PROP_REGISTERED, NULL);
+               }
+
+               lpProps.ulPropTag = aulPropTag;
+               ret = ocpf_set_propvalue((TALLOC_CTX *)ctx->recipients->aRow, ctx, (const void **)&value, 
+                                        (uint16_t)aulPropTag & 0xFFFF, proptype, lpProp, unescape);
+               if (ret == -1) {
+                       return OCPF_ERROR;
+               }
+               set_SPropValue(&lpProps, value);
+
+               if (!aRow.cValues) {
+                       aRow.lpProps = talloc_array((TALLOC_CTX *)ctx->recipients->aRow, struct SPropValue, 2);
+               } else {
+                       aRow.lpProps = talloc_realloc(aRow.lpProps, aRow.lpProps, struct SPropValue, aRow.cValues + 2);
+               }
+               aRow.lpProps[aRow.cValues] = lpProps;
+               aRow.cValues += 1;
+               ctx->recipients->aRow[cRows] = aRow;
+               break;
+       default:
+               break;
        }
 
-       DLIST_ADD(ctx->props, element);
        return OCPF_SUCCESS;
 }
 
+int ocpf_new_recipient(struct ocpf_context *ctx)
+{
+       uint32_t        cRows;
+       
+       if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR;
+       if (!ctx->recipients || !ctx->recipients->aRow) return OCPF_ERROR;
+
+       ctx->recipients->cRows += 1;
+       cRows = ctx->recipients->cRows;
+
+       ctx->recipients->aRow = talloc_realloc(ctx->recipients->aRow, ctx->recipients->aRow, struct SRow, cRows + 2);
+       ctx->recipients->aRow[cRows].ulAdrEntryPad = 0;
+       ctx->recipients->aRow[cRows].lpProps = NULL;
+       ctx->recipients->aRow[cRows].cValues = 0;
+
+       return OCPF_SUCCESS;
+}
+
+int ocpf_recipient_set_class(struct ocpf_context *ctx, enum ulRecipClass class)
+{
+       struct SPropValue       lpProps;
+       uint32_t                cRows;
+       struct SRow             aRow;
+       int                     i;
+
+       if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR;
+       if (!ctx->recipients || !ctx->recipients->aRow) return OCPF_ERROR;
+
+       cRows = ctx->recipients->cRows;
+       aRow = ctx->recipients->aRow[cRows];
+
+       /* Check if PidTagRecipientType has not been declared as a block property */
+       for (i = 0; i < aRow.cValues; i++) {
+               if (aRow.lpProps[i].ulPropTag == PidTagRecipientType) {
+                       if (aRow.lpProps[i].value.l == class) {
+                               return OCPF_SUCCESS;
+                       } else {
+                               OCPF_RETVAL_IF(1, ctx, OCPF_WARN_PROP_REGISTERED, NULL);
+                       }
+               }
+       }
+
+       lpProps.ulPropTag = PidTagRecipientType;
+       lpProps.dwAlignPad = 0;
+       set_SPropValue(&lpProps, (void *)&class);
+       
+       if (!aRow.cValues) {
+               aRow.lpProps = talloc_array((TALLOC_CTX *)ctx->recipients->aRow, struct SPropValue, 2);
+       } else {
+               aRow.lpProps = talloc_realloc(aRow.lpProps, aRow.lpProps, struct SPropValue, aRow.cValues + 2);
+       }
+
+       aRow.lpProps[aRow.cValues] = lpProps;
+       aRow.cValues += 1;
+       ctx->recipients->aRow[cRows] = aRow;
+
+       return OCPF_SUCCESS;
+}
 
 void ocpf_propvalue_s(struct ocpf_context *ctx,
                      const char *propname, 
                      union SPropValue_CTR lpProp, 
                      uint16_t proptype, 
-                     bool unescape)
+                     bool unescape,
+                     int scope)
 {
        uint32_t        aulPropTag;
 
        aulPropTag = get_proptag_value(propname);
-       ocpf_propvalue(ctx, aulPropTag, lpProp, proptype, unescape);
+       ocpf_propvalue(ctx, aulPropTag, lpProp, proptype, unescape, scope);
 }
 
 
@@ -415,7 +560,6 @@ int ocpf_nproperty_add(struct ocpf_context *ctx,
        return OCPF_SUCCESS;
 }
 
-
 /**
    \details Register OCPF message type
    
@@ -660,19 +804,3 @@ int ocpf_binary_add(struct ocpf_context *ctx, const char *filename, struct Binar
 
        return OCPF_SUCCESS;
 }
-
-int ocpf_recipient_add(struct ocpf_context *ctx, uint8_t recipClass, char *recipient)
-{
-       struct ocpf_recipients  *element;
-
-       if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR;
-       if (!recipient) return OCPF_ERROR;
-
-       element = talloc_zero(ctx->recipients, struct ocpf_recipients);
-       element->name = talloc_strdup((TALLOC_CTX *)element, recipient);
-       element->class = recipClass;
-
-       DLIST_ADD(ctx->recipients, element);
-
-       return OCPF_SUCCESS;
-}
index 6a4d05ba5d0181f2b3589c74e929f6e09a35f6c9..b8be178850f6ae81fb57b0b6139459f44b7b23fb 100644 (file)
@@ -76,14 +76,6 @@ struct ocpf_nproperty
        const void              *value;
 };
 
-struct ocpf_recipients
-{
-       struct ocpf_recipients  *prev;
-       struct ocpf_recipients  *next;
-       char                    *name;
-       enum ocpf_recipClass    class;
-};
-
 struct ocpf_olfolder
 {
        int                     id;
@@ -108,7 +100,7 @@ struct ocpf_context
        struct ocpf_oleguid     *oleguid;
        struct ocpf_property    *props;
        struct ocpf_nproperty   *nprops;
-       struct ocpf_recipients  *recipients;
+       struct SRowSet          *recipients;
        struct SPropValue       *lpProps;
        uint32_t                cValues;
        uint64_t                folder;
@@ -208,14 +200,16 @@ do {                                                              \
 #define        OCPF_INVALID_PROPARRAY          "Invalid property array"
 #define        OCPF_INVALID_FILEHANDLE         "Invalid file handle"
 
+#define        OCPF_INVALID_RECIPIENTS         "Invalid recipients"
 
 #define        OCPF_PROPERTY_BEGIN             "PROPERTY {\n"
 #define        OCPF_NPROPERTY_BEGIN            "NPROPERTY {\n"
 #define        OCPF_END                        "};\n"
 #define        OCPF_NEWLINE                    "\n"
-#define        OCPF_RECIPIENT_TO               "RECIPIENT TO "
-#define        OCPF_RECIPIENT_CC               "RECIPIENT CC "
-#define        OCPF_RECIPIENT_BCC              "RECIPIENT BCC "
+#define        OCPF_RECIPIENT_BEGIN            "RECIPIENT {\n"
+#define        OCPF_RECIPIENT_TO               "TO {\n"
+#define        OCPF_RECIPIENT_CC               "CC {\n"
+#define        OCPF_RECIPIENT_BCC              "BCC {\n"
 
 #define        DATE_FORMAT     "%Y-%m-%d %H:%M:%S"
 
index 721bc17b4f0bb3149280c6fc87bf9d424cdfc43d..ca0cc9019088bdb0a63814c667d5f0f931eb3b8a 100644 (file)
@@ -73,7 +73,12 @@ struct ocpf_context *ocpf_context_init(TALLOC_CTX *mem_ctx,
        ctx->oleguid = talloc_zero(ctx, struct ocpf_oleguid);
        ctx->props = talloc_zero(ctx, struct ocpf_property);
        ctx->nprops = talloc_zero(ctx, struct ocpf_nproperty);
-       ctx->recipients = talloc_zero(ctx, struct ocpf_recipients);
+
+       ctx->recipients = talloc_zero(ctx, struct SRowSet);
+       ctx->recipients->aRow = talloc_array(ctx->recipients, struct SRow, 2);
+       ctx->recipients->aRow[0].lpProps = talloc_array(ctx->recipients->aRow, struct SPropValue, 2);
+       ctx->recipients->cRows = 0;
+
        ctx->lpProps = NULL;
        ctx->cValues = 0;
        ctx->folder = 0;
index 99b9f9e5db801cfaa4fd5b07f22cb8d8fe5857f7..6a557b3ca36d498f15d46aadda29cd2aa7db1405 100644 (file)
@@ -1,7 +1,7 @@
 /*
    OpenChange OCPF (OpenChange Property File) implementation.
 
-   Copyright (C) Julien Kerihuel 2008-2010.
+   Copyright (C) Julien Kerihuel 2008-2011.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -96,7 +96,9 @@ _PUBLIC_ void ocpf_dump_folder(uint32_t context_id)
 _PUBLIC_ void ocpf_dump_recipients(uint32_t context_id)
 {
        struct ocpf_context     *ctx;
-       struct ocpf_recipients  *element;
+       uint32_t                i;
+       struct SPropValue       *lpProps;
+       uint32_t                *RecipClass;
 
        ctx = ocpf_context_search_by_context_id(ocpf->context, context_id);
        if (!ctx) return;
@@ -104,31 +106,28 @@ _PUBLIC_ void ocpf_dump_recipients(uint32_t context_id)
        OCPF_DUMP_TITLE(indent, "RECIPIENTS", OCPF_DUMP_TOPLEVEL);
        indent++;
 
-       INDENT();
-       printf("* To: ");
-       for (element = ctx->recipients; element->next; element = element->next) {
-               if (element->class == OCPF_MAPI_TO) {
-                       printf("%s;", element->name);
+       for (i = 0; i < ctx->recipients->cRows; i++) {
+               lpProps = get_SPropValue_SRow(&(ctx->recipients->aRow[i]), PidTagRecipientType);
+               if (lpProps) {
+                       RecipClass = (uint32_t *)get_SPropValue_data(lpProps);
+                       if (RecipClass) {
+                               switch (*RecipClass) {
+                               case MAPI_TO:
+                                       OCPF_DUMP_TITLE(indent, "TO", OCPF_DUMP_SUBLEVEL);
+                                       break;
+                               case MAPI_CC:
+                                       OCPF_DUMP_TITLE(indent, "CC", OCPF_DUMP_SUBLEVEL);
+                                       break;
+                               case MAPI_BCC:
+                                       OCPF_DUMP_TITLE(indent, "BCC", OCPF_DUMP_SUBLEVEL);
+                                       break;
+                               }
+                               mapidump_SRow(&ctx->recipients->aRow[i], "\t * ");
+                       }
                }
        }
-       printf("\n");
 
-       INDENT();
-       printf("* Cc: ");
-       for (element = ctx->recipients; element->next; element = element->next) {
-               if (element->class == OCPF_MAPI_CC) {
-                       printf("%s;", element->name);
-               }
-       }
-       printf("\n");
-
-       INDENT();
-       printf("* Bcc: ");
-       for (element = ctx->recipients; element->next; element = element->next) {
-               if (element->class == OCPF_MAPI_BCC) {
-                       printf("%s;", element->name);
-               }
-       }
+       indent--;
        printf("\n");
 }
 
index d15abe1b04366fa48cf22f9ffbcc98a1e7dcab77..a6e906707a00dd842edfa77a9acd83a278d5c544 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 #include <stdlib.h>
+#include <libocpf/ocpf.tab.h>
 
 #ifndef HAVE_COMPARISON_FN_T
 #define HAVE_COMPARISON_FN_T
@@ -49,11 +50,13 @@ __BEGIN_DECLS
 
 /* The following private definitions from from libocpf/ocpf_api.c */
 void ocpf_do_debug(struct ocpf_context *, const char *, ...);
-int ocpf_propvalue_var(struct ocpf_context *, const char *, uint32_t, const char *, bool);
+int ocpf_propvalue_var(struct ocpf_context *, const char *, uint32_t, const char *, bool, int);
 int ocpf_set_propvalue(TALLOC_CTX *, struct ocpf_context *, const void **, uint16_t, uint16_t, union SPropValue_CTR, bool);
 int ocpf_propvalue_free(union SPropValue_CTR, uint16_t);
-int ocpf_propvalue(struct ocpf_context *, uint32_t, union SPropValue_CTR, uint16_t, bool);
-void ocpf_propvalue_s(struct ocpf_context *, const char *, union SPropValue_CTR, uint16_t, bool);
+int ocpf_propvalue(struct ocpf_context *, uint32_t, union SPropValue_CTR, uint16_t, bool, int);
+void ocpf_propvalue_s(struct ocpf_context *, const char *, union SPropValue_CTR, uint16_t, bool, int);
+int ocpf_new_recipient(struct ocpf_context *);
+int ocpf_recipient_set_class(struct ocpf_context *, enum ulRecipClass);
 int ocpf_nproperty_add(struct ocpf_context *, struct ocpf_nprop *, union SPropValue_CTR, const char *, uint16_t, bool);
 int ocpf_type_add(struct ocpf_context *, const char *);
 int ocpf_folder_add(struct ocpf_context *, const char *, uint64_t, const char *);
@@ -62,7 +65,6 @@ int ocpf_oleguid_check(struct ocpf_context *, const char *, const char **);
 int ocpf_add_filetime(const char *, struct FILETIME *);
 int ocpf_variable_add(struct ocpf_context *, const char *, union SPropValue_CTR, uint16_t, bool);
 int ocpf_binary_add(struct ocpf_context *, const char *, struct Binary_r *);
-int ocpf_recipient_add(struct ocpf_context *, uint8_t, char *);
 
 /* The following private definitions come from libocpf/ocpf_write.c */
 char *ocpf_write_unescape_string(TALLOC_CTX *, const char *);
index 643dc537428e81d6a2e63be38ee9f76ed2c97f8b..ecac411031c58022b1d1f5e092b1b999018994d8 100644 (file)
@@ -1,7 +1,7 @@
 /*
    OpenChange OCPF (OpenChange Property File) implementation.
 
-   Copyright (C) Julien Kerihuel 2008-2010.
+   Copyright (C) Julien Kerihuel 2008-2011.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -226,62 +226,6 @@ static enum MAPISTATUS ocpf_stream(TALLOC_CTX *mem_ctx,
 }
 
 
-/**
-   \details Build a SRowSet array with recipients from ocpf context
-
-   This function builds s SRowSet structure of recipient names and
-   type from the ocpf context and information stored.
-
-   \param mem_ctx pointer to the memory context to use for memory
-   allocation
-   \param context_id identifier of the context to use for building a
-   SRowSet array of recipients
-
-   \return Pointer to an allocated SRowSet structure on success,
-   otherwise NULL
- */
-_PUBLIC_ struct SRowSet *ocpf_get_recipients(TALLOC_CTX *mem_ctx,
-                                         uint32_t context_id)
-{
-       struct SRowSet          *SRowSet;
-       struct ocpf_context     *ctx;
-       struct ocpf_recipients  *recipient;
-       int                     i;
-
-       /* Sanity checks */
-       if (!ocpf) return NULL;
-
-       /* Step 1. Search for the context */
-       ctx = ocpf_context_search_by_context_id(ocpf->context, context_id);
-       if (!ctx) return NULL;
-
-       /* Step 2. Allocate SRow */
-       SRowSet = talloc_zero(mem_ctx, struct SRowSet);
-       SRowSet->cRows = 0;
-
-       /* Count the number of recipients and allocate memory for aRow */
-       for (recipient = ctx->recipients; recipient->next; recipient = recipient->next) {
-               SRowSet->cRows += 1;
-       }
-       SRowSet->aRow = talloc_array(SRowSet, struct SRow, SRowSet->cRows + 1);
-
-       for (i = 0, recipient = ctx->recipients; recipient->next; recipient = recipient->next, i++) {
-               SRowSet->aRow[i].ulAdrEntryPad = 0;
-               SRowSet->aRow[i].cValues = 2;
-               SRowSet->aRow[i].lpProps = talloc_array(SRowSet->aRow, struct SPropValue, 3);
-               
-               SRowSet->aRow[i].lpProps[0].ulPropTag = PR_RECIPIENT_TYPE;
-               SRowSet->aRow[i].lpProps[0].value.l = recipient->class;
-               
-               SRowSet->aRow[i].lpProps[1].ulPropTag = PR_DISPLAY_NAME;
-               SRowSet->aRow[i].lpProps[1].value.lpszA = talloc_strdup(SRowSet->aRow[i].lpProps, 
-                                                                       recipient->name);
-       }
-
-       return SRowSet;
-}
-
-
 /**
    \details Build a SPropValue array from ocpf context
 
@@ -386,6 +330,9 @@ _PUBLIC_ enum MAPISTATUS ocpf_set_SPropValue(TALLOC_CTX *mem_ctx,
                                                     (struct Binary_r *)pel->value);
                                MAPI_RETVAL_IF(retval, retval, NULL);
                        } else {
+                               if ((pel->aulPropTag & 0xFFFF) == PT_STRING8) {
+                                       pel->aulPropTag = (pel->aulPropTag & 0xFFFF) + PT_UNICODE;
+                               }
                                ctx->lpProps = add_SPropValue(mem_ctx, ctx->lpProps, &ctx->cValues, 
                                                               pel->aulPropTag, pel->value);
                        }
@@ -587,38 +534,38 @@ static bool set_external_recipients(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet
        SRowSet->aRow[last].lpProps = talloc_zero(mem_ctx, struct SPropValue);
        
        /* PR_OBJECT_TYPE */
-       SPropValue.ulPropTag = PR_OBJECT_TYPE;
+       SPropValue.ulPropTag = PidTagObjectType;
        SPropValue.value.l = MAPI_MAILUSER;
        SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
 
        /* PR_DISPLAY_TYPE */
-       SPropValue.ulPropTag = PR_DISPLAY_TYPE;
+       SPropValue.ulPropTag = PidTagDisplayType;
        SPropValue.value.l = 0;
        SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
 
        /* PR_GIVEN_NAME */
-       SPropValue.ulPropTag = PR_GIVEN_NAME;
-       SPropValue.value.lpszA = username;
+       SPropValue.ulPropTag = PidTagGivenName;
+       SPropValue.value.lpszW = username;
        SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
 
        /* PR_DISPLAY_NAME */
-       SPropValue.ulPropTag = PR_DISPLAY_NAME;
-       SPropValue.value.lpszA = username;
+       SPropValue.ulPropTag = PidTagDisplayName;
+       SPropValue.value.lpszW = username;
        SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
 
        /* PR_7BIT_DISPLAY_NAME */
-       SPropValue.ulPropTag = PR_7BIT_DISPLAY_NAME;
-       SPropValue.value.lpszA = username;
+       SPropValue.ulPropTag = PidTag7BitDisplayName;
+       SPropValue.value.lpszW = username;
        SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
 
        /* PR_SMTP_ADDRESS */
-       SPropValue.ulPropTag = PR_SMTP_ADDRESS;
-       SPropValue.value.lpszA = username;
+       SPropValue.ulPropTag = PidTagPrimarySmtpAddress;
+       SPropValue.value.lpszW = username;
        SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
 
        /* PR_ADDRTYPE */
-       SPropValue.ulPropTag = PR_ADDRTYPE;
-       SPropValue.value.lpszA = "SMTP";
+       SPropValue.ulPropTag = PidTagAddressType;
+       SPropValue.value.lpszW = "SMTP";
        SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
 
        SetRecipientType(&(SRowSet->aRow[last]), RecipClass);
@@ -649,16 +596,16 @@ _PUBLIC_ enum MAPISTATUS ocpf_set_Recipients(TALLOC_CTX *mem_ctx,
 {
        enum MAPISTATUS                 retval;
        struct ocpf_context             *ctx;
-       struct ocpf_recipients          *element;
        struct SPropTagArray            *SPropTagArray;
        struct SPropValue               SPropValue;
-       struct SRowSet                  *SRowSet = NULL;
+       struct SPropValue               *lpProps;
+       struct SRowSet                  *SRowSet;
        struct PropertyTagArray_r       *flaglist = NULL;
        char                            **usernames = NULL;
        int                             *recipClass = NULL;
-       uint32_t                        count;
        uint32_t                        counter;
        uint32_t                        i;
+       const void                      *propdata;
 
        MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL);
        MAPI_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
@@ -667,30 +614,33 @@ _PUBLIC_ enum MAPISTATUS ocpf_set_Recipients(TALLOC_CTX *mem_ctx,
        ctx = ocpf_context_search_by_context_id(ocpf->context, context_id);
        MAPI_RETVAL_IF(!ctx, MAPI_E_INVALID_PARAMETER, NULL);
 
-       MAPI_RETVAL_IF(!ctx->recipients->next, MAPI_E_NOT_FOUND, NULL);
+       MAPI_RETVAL_IF(!ctx->recipients->cRows, MAPI_E_NOT_FOUND, NULL);
 
        SPropTagArray = set_SPropTagArray(mem_ctx, 0x8,
-                                         PR_OBJECT_TYPE,
-                                         PR_DISPLAY_TYPE,
-                                         PR_7BIT_DISPLAY_NAME,
-                                         PR_DISPLAY_NAME,
-                                         PR_SMTP_ADDRESS,
-                                         PR_GIVEN_NAME,
-                                         PR_EMAIL_ADDRESS,
-                                         PR_ADDRTYPE);
+                                         PidTagObjectType,
+                                         PidTagDisplayName,
+                                         PidTag7BitDisplayName,
+                                         PidTagDisplayName,
+                                         PidTagPrimarySmtpAddress,
+                                         PidTagGivenName,
+                                         PidTagEmailAddress,
+                                         PidTagAddressType);
 
        /* Step 1. Group recipients and run ResolveNames */
-       usernames = talloc_array(mem_ctx, char *, 2);
-       recipClass = talloc_array(mem_ctx, int, 2);
-       for (element = ctx->recipients, count = 0; element->next; element = element->next, count ++) {
-               usernames = talloc_realloc(mem_ctx, usernames, char *, count + 2);
-               recipClass = talloc_realloc(mem_ctx, recipClass, int, count + 2);
-               usernames[count] = talloc_strdup((TALLOC_CTX *)usernames, element->name);
-               recipClass[count] = element->class;
+       usernames = talloc_array(mem_ctx, char *, ctx->recipients->cRows + 1);
+       recipClass = talloc_array(mem_ctx, int, ctx->recipients->cRows + 1);
+       for (i = 0; i < ctx->recipients->cRows; i++) {
+               lpProps = get_SPropValue_SRow(&(ctx->recipients->aRow[i]), PidTag7BitDisplayName);
+               propdata = get_SPropValue(lpProps, PidTag7BitDisplayName);
+               usernames[i] = talloc_strdup((TALLOC_CTX *)usernames, (const char *) propdata);
+
+               lpProps = get_SPropValue_SRow(&(ctx->recipients->aRow[i]), PidTagRecipientType);
+               propdata = get_SPropValue(lpProps, PidTagRecipientType);
+               recipClass[i] = *((uint32_t *)propdata);
        }
-       usernames[count] = 0;
+       usernames[i] = NULL;
 
-       retval = ResolveNames(mapi_object_get_session(obj_message), (const char **)usernames, 
+       retval = ResolveNames(mapi_object_get_session(obj_message), (const char **)usernames,
                              SPropTagArray, &SRowSet, &flaglist, 0);
        MAPIFreeBuffer(SPropTagArray);
        MAPI_RETVAL_IF(retval, retval, usernames);
@@ -700,17 +650,15 @@ _PUBLIC_ enum MAPISTATUS ocpf_set_Recipients(TALLOC_CTX *mem_ctx,
                SRowSet = talloc_zero(mem_ctx, struct SRowSet);
        }
 
-       count = 0;
        counter = 0;
        for (i = 0; usernames[i]; i++) {
-               if (flaglist->aulPropTag[count] == MAPI_UNRESOLVED) {
-                       set_external_recipients(mem_ctx, SRowSet, usernames[i], recipClass[i]);
+               if (flaglist->aulPropTag[i] == MAPI_UNRESOLVED) {
+                       set_external_recipients(mem_ctx, SRowSet, usernames[i], recipClass[i]);                 
                }
-               if (flaglist->aulPropTag[count] == MAPI_RESOLVED) {
+               if (flaglist->aulPropTag[i] == MAPI_RESOLVED) {
                        SetRecipientType(&(SRowSet->aRow[counter]), recipClass[i]);
                        counter++;
                }
-               count++;
        }
 
        /* Step3. Finish to build the ModifyRecipients SRowSet */
@@ -720,9 +668,6 @@ _PUBLIC_ enum MAPISTATUS ocpf_set_Recipients(TALLOC_CTX *mem_ctx,
 
        /* Step4. Call ModifyRecipients */
        retval = ModifyRecipients(obj_message, SRowSet);
-       MAPIFreeBuffer(SRowSet);
-       MAPIFreeBuffer(flaglist);
-       MAPIFreeBuffer(usernames);
        MAPI_RETVAL_IF(retval, retval, NULL);
 
        return MAPI_E_SUCCESS;
index b1bfbaeab2e7dd3d5ec5f24e045bb53e110242d9..d78bfbba38092297c0eee41755ad430e51f7ecc2 100644 (file)
@@ -1,7 +1,7 @@
 /*
    OpenChange OCPF (OpenChange Property File) implementation.
 
-   Copyright (C) Julien Kerihuel 2008-2010.
+   Copyright (C) Julien Kerihuel 2008-2011.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -411,49 +411,66 @@ static char *ocpf_write_property(struct ocpf_context *ctx, bool *found, uint32_t
 }
 
 
-static char *ocpf_write_recipients(struct ocpf_context *ctx, enum ocpf_recipClass recipClass)
+static int ocpf_write_recipients(struct ocpf_context *ctx, 
+                                FILE *fp,
+                                enum ulRecipClass recipClass)
 {
-       struct ocpf_recipients  *element;
+       int                     ret;
+       ssize_t                 len;
+       int                     i;
+       int                     j;
        char                    *line = NULL;
+       const void              *value_data;
        bool                    found = false;
+       uint32_t                *RecipClass;
+       enum MAPITAGS           ulPropTag;
+       struct SPropValue       *lpProps;
 
        line = talloc_zero(ctx, char);
-       for (element = ctx->recipients, found = false; element->next; element = element->next) {
-               if (found && element->class == recipClass) {
-                       line = talloc_asprintf_append(line, ";");
-                       found = false;
-               }
-               if (element->class == recipClass) {
-                       line = talloc_asprintf_append(line, "\"%s\"", element->name);
-                       found = true;
-               }
-       }
-       return line;
-}
-
 
-static int ocpf_write_add_recipients(struct ocpf_context *ctx,
-                                    enum ocpf_recipClass recipClass, 
-                                    const char *recipients)
-{
-       char            *tmp = NULL;
-       uint32_t        i = 0;
-
-       if (!recipients) return OCPF_ERROR;
-
-       if ((tmp = strtok((char *)recipients, ";")) == NULL) {
-               return OCPF_ERROR;
-       }
+       for (i = 0; i < ctx->recipients->cRows; i++) {
+               lpProps = get_SPropValue_SRow(&(ctx->recipients->aRow[i]), PidTagRecipientType);
+               if (lpProps) {
+                       RecipClass = (uint32_t *)get_SPropValue_data(lpProps);
+                       if (RecipClass && *RecipClass == recipClass) {
+                               switch (recipClass) {
+                               case MAPI_TO:
+                                       ret = fwrite(OCPF_RECIPIENT_TO, strlen(OCPF_RECIPIENT_TO), 1, fp);
+                                       break;
+                               case MAPI_CC:
+                                       ret = fwrite(OCPF_RECIPIENT_CC, strlen(OCPF_RECIPIENT_CC), 1, fp);
+                                       break;
+                               case MAPI_BCC:
+                                       ret = fwrite(OCPF_RECIPIENT_BCC, strlen(OCPF_RECIPIENT_BCC), 1, fp);
+                                       break;
+                               default:
+                                       break;
+                               }
 
-       ocpf_recipient_add(ctx, recipClass, tmp);
+                               for (j = 0; j < ctx->recipients->aRow[i].cValues; j++) {
+                                       ulPropTag = ctx->recipients->aRow[i].lpProps[j].ulPropTag;
+                                       value_data = get_SPropValue_data(&(ctx->recipients->aRow[i].lpProps[j]));
+                                       if (value_data) {
+                                               line = ocpf_write_property(ctx, &found, ulPropTag, (void *)value_data);
+                                               if (found == true) {
+                                                       ocpf_write_propname(ctx, fp, ulPropTag);
+                                                       len = fwrite(line, strlen(line), 1, fp);
+                                                       talloc_free(line);
+                                                       found = false;
+                                               }
+                                       }
+                               }
 
-       for (i = 1; (tmp = strtok(NULL, ";")) != NULL; i++) {
-               ocpf_recipient_add(ctx, recipClass, tmp);
+                               ret = fwrite(OCPF_END, strlen(OCPF_END), 1, fp);
+                               ret = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
+                       }
+               }
        }
 
        return OCPF_SUCCESS;
 }
 
+
 static bool ocpf_write_exclude_property(uint32_t ulPropTag)
 {
        uint32_t        i;
@@ -528,8 +545,8 @@ _PUBLIC_ int ocpf_write_auto(uint32_t context_id,
        uint32_t                i;
        uint16_t                propID;
        struct SPropValue       lpProps;
+       struct SPropTagArray    SPropTagArray;
        const char              *type;
-       const char              *recipient;
        char                    *tmp_guid;
        const char              *guid;
        struct MAPINAMEID       *nameid;
@@ -549,14 +566,8 @@ _PUBLIC_ int ocpf_write_auto(uint32_t context_id,
        ocpf_type_add(ctx, type);
 
        /* store recipients */
-       recipient = (const char *) find_mapi_SPropValue_data(mapi_lpProps, PR_DISPLAY_TO);
-       ocpf_write_add_recipients(ctx, OCPF_MAPI_TO, recipient);
-
-       recipient = (const char *) find_mapi_SPropValue_data(mapi_lpProps, PR_DISPLAY_CC);
-       ocpf_write_add_recipients(ctx, OCPF_MAPI_CC, recipient);
-
-       recipient = (const char *) find_mapi_SPropValue_data(mapi_lpProps, PR_DISPLAY_BCC);
-       ocpf_write_add_recipients(ctx, OCPF_MAPI_BCC, recipient);
+       retval = GetRecipientTable(obj_message, ctx->recipients, &SPropTagArray);
+       OCPF_RETVAL_IF(retval, ctx, OCPF_INVALID_RECIPIENTS, NULL);
 
        /* store properties and OLEGUID in OCPF context */
        for (i = 0; i < mapi_lpProps->cValues; i++) {
@@ -569,11 +580,11 @@ _PUBLIC_ int ocpf_write_auto(uint32_t context_id,
                                if (lpProps.ulPropTag == PR_CONVERSATION_TOPIC) {
                                        lpProps.ulPropTag = PR_SUBJECT;
                                        ocpf_propvalue(ctx, lpProps.ulPropTag, lpProps.value, 
-                                                      lpProps.ulPropTag & 0xFFFF, false);
+                                                      lpProps.ulPropTag & 0xFFFF, false, kw_PROPERTY);
                                        cast_SPropValue(ctx, &mapi_lpProps->lpProps[i], &lpProps);
                                }
                                ocpf_propvalue(ctx, mapi_lpProps->lpProps[i].ulPropTag, 
-                                              lpProps.value, mapi_lpProps->lpProps[i].ulPropTag & 0xFFFF, false);
+                                              lpProps.value, mapi_lpProps->lpProps[i].ulPropTag & 0xFFFF, false, kw_PROPERTY);
                        }
                } else {
                        nameid = talloc_zero(ctx, struct MAPINAMEID);
@@ -665,33 +676,13 @@ _PUBLIC_ int ocpf_write_commit(uint32_t context_id)
        }
        len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
 
-       /* RECIPIENT TO */
-       line = ocpf_write_recipients(ctx, OCPF_MAPI_TO);
-       if (line && strlen(line)) {
-               len = fwrite(OCPF_RECIPIENT_TO, strlen(OCPF_RECIPIENT_TO), 1, fp);
-               len = fwrite(line, strlen(line), 1, fp);
-               len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
-               talloc_free(line);
-       }
-
-       /* RECIPIENT CC */
-       line = ocpf_write_recipients(ctx, OCPF_MAPI_CC);
-       if (line && strlen(line)) {
-               len = fwrite(OCPF_RECIPIENT_CC, strlen(OCPF_RECIPIENT_CC), 1, fp);
-               len = fwrite(line, strlen(line), 1, fp);
-               len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
-               talloc_free(line);
-       }
-
-       /* RECIPIENT BCC */
-       line = ocpf_write_recipients(ctx, OCPF_MAPI_BCC);
-       if (line && strlen(line)) {
-               len = fwrite(OCPF_RECIPIENT_BCC, strlen(OCPF_RECIPIENT_BCC), 1, fp);
-               len = fwrite(line, strlen(line), 1, fp);
-               len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
-               talloc_free(line);
-       }
+       /* RECIPIENT */
+       len = fwrite(OCPF_RECIPIENT_BEGIN, strlen(OCPF_RECIPIENT_BEGIN), 1, fp);
+       ocpf_write_recipients(ctx, fp, MAPI_TO);
+       ocpf_write_recipients(ctx, fp, MAPI_CC);
+       ocpf_write_recipients(ctx, fp, MAPI_BCC);
 
+       len = fwrite(OCPF_END, strlen(OCPF_END), 1, fp);
        len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
 
        /* known properties */
index 754fa91c98d3d1ebc20b373539c9bf233df4bd79..e276d6f86d390ce5fb51e8792a97532912704904 100755 (executable)
@@ -56,14 +56,14 @@ SPropParent.add(mapi.PidTagComment, "Test comment")
 SPropParent.add(mapi.PidTagFolderType, 1)
 MAPIStore.setprops(ctx_id, mailbox_fid, mapistore.MAPISTORE_FOLDER, SPropParent)
 
-SPropValue = mapi.SPropValue()
-SPropValue.add(mapi.PR_PARENT_FID, 0x0000000000010001)
-SPropValue.add(mapi.PR_DISPLAY_NAME, "test")
-SPropValue.add(mapi.PR_COMMENT, "test folder")
-SPropValue.add(mapi.PR_FOLDER_TYPE, 1)
-
-MAPIStore.mkdir(ctx_id, 0x0000000000010001, 0x0000000000020001, SPropValue)
-MAPIStore.rmdir(ctx_id, 0x0000000000010001, 0x0000000000020001, mapistore.DEL_FOLDERS)
+#SPropValue = mapi.SPropValue()
+#SPropValue.add(mapi.PR_PARENT_FID, 0x0000000000010001)
+#SPropValue.add(mapi.PR_DISPLAY_NAME, "test")
+#SPropValue.add(mapi.PR_COMMENT, "test folder")
+#SPropValue.add(mapi.PR_FOLDER_TYPE, 1)
+
+#MAPIStore.mkdir(ctx_id, 0x0000000000010001, 0x0000000000020001, SPropValue)
+#MAPIStore.rmdir(ctx_id, 0x0000000000010001, 0x0000000000020001, mapistore.DEL_FOLDERS)
 
 MAPIStore.del_context(ctx_id)