enum MAPISTATUS retval;
struct SPropValue lpProp;
- lpProp.ulPropTag = PR_RECIPIENT_TYPE;
+ lpProp.ulPropTag = PidTagRecipientType;
lpProp.value.l = RecipClass;
retval = SRow_addprop(aRow, lpProp);
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
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 {
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
/*
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
}
;
+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
{
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);
}
;
}
;
-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)
/*
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
#include "libocpf/ocpf.h"
#include "libocpf/ocpf_api.h"
+#include "libocpf/ocpf_private.h"
/**
\file ocpf_api.c
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;
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);
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);
}
return OCPF_SUCCESS;
}
-
/**
\details Register OCPF message type
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;
-}
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;
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;
#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"
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;
/*
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
_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;
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");
}
#include "config.h"
#include <stdlib.h>
+#include <libocpf/ocpf.tab.h>
#ifndef HAVE_COMPARISON_FN_T
#define HAVE_COMPARISON_FN_T
/* 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 *);
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 *);
/*
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
}
-/**
- \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
(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);
}
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);
{
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);
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);
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 */
/* Step4. Call ModifyRecipients */
retval = ModifyRecipients(obj_message, SRowSet);
- MAPIFreeBuffer(SRowSet);
- MAPIFreeBuffer(flaglist);
- MAPIFreeBuffer(usernames);
MAPI_RETVAL_IF(retval, retval, NULL);
return MAPI_E_SUCCESS;
/*
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
}
-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;
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;
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++) {
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);
}
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 */
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)