Monotone-Parent: a9886e6c9acfb5c097b185a254e620a6a0094f1f

Monotone-Revision: 9109f0600492701322f24fb53d86a39821e26dc4

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2011-09-30T20:01:50
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Wolfgang Sourdeau 2011-09-30 20:01:50 +00:00
parent 18686beb11
commit 01e387b7b9
8 changed files with 554 additions and 172 deletions

View File

@ -1,5 +1,19 @@
2011-09-30 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/MAPIStoreMailMessage.m (-getMessageData:inMemCtx:):
same as below.
* OpenChange/MAPIStoreCalendarMessage.m
(-getMessageData:inMemCtx:): delegated code to
MAPIStoreAppointmentWrapper so that organizers and invitees are
properly reported both in invitation emails and events.
* OpenChange/MAPIStoreMessage.m (MAPIStoreInternalEntryId)
(MAPIStoreExternalEntryId): new helper functions that return an
NSData with the entry id for the requested user or contact.
(-getMessageData:inMemCtx:): adapted to the new mapistore_message
struct and column handling.
* OpenChange/NSData+MAPIStore.m (-appendUInt16): new method.
* OpenChange/EOQualifier+MAPIFS.m (-[EOKeyValueQUalifier

View File

@ -47,6 +47,9 @@ extern NSTimeZone *utcTZ;
inTimeZone: (NSTimeZone *) newTimeZone;
/* getters */
- (void) fillMessageData: (struct mapistore_message *) dataPtr
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrIconIndex: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrOwnerApptId: (void **) data

View File

@ -24,6 +24,7 @@
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSCharacterSet.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSTimeZone.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGCards/iCalDateTime.h>
@ -31,7 +32,9 @@
#import <NGCards/iCalRecurrenceRule.h>
#import <NGCards/iCalTimeZone.h>
#import <NGCards/iCalPerson.h>
#import <SOGo/SOGoUserManager.h>
#import "MAPIStoreMessage.h"
#import "MAPIStoreRecurrenceUtils.h"
#import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h"
@ -118,6 +121,229 @@ static NSCharacterSet *hexCharacterSet = nil;
[super dealloc];
}
- (void) fillMessageData: (struct mapistore_message *) msgData
inMemCtx: (TALLOC_CTX *) memCtx
{
NSString *username, *cn, *email;
NSData *entryId;
NSArray *attendees;
iCalPerson *person;
iCalPersonPartStat partStat;
uint32_t partStatValue;
SOGoUserManager *mgr;
NSDictionary *contactInfos;
struct mapistore_message_recipient *recipient;
int count, max, p;
msgData->columns = set_SPropTagArray (msgData, 9,
PR_OBJECT_TYPE,
PR_DISPLAY_TYPE,
PR_7BIT_DISPLAY_NAME_UNICODE,
PR_SMTP_ADDRESS_UNICODE,
PR_SEND_INTERNET_ENCODING,
PR_RECIPIENT_DISPLAY_NAME_UNICODE,
PR_RECIPIENT_FLAGS,
PR_RECIPIENT_ENTRYID,
PR_RECIPIENT_TRACKSTATUS);
// ,
// PR_RECORD_KEY);
attendees = [event attendees];
max = [attendees count];
if (max > 0)
{
mgr = [SOGoUserManager sharedUserManager];
msgData->recipients_count = max + 1;
msgData->recipients = talloc_array (msgData, struct mapistore_message_recipient *, max + 1);
for (count = 0; count < max; count++)
{
msgData->recipients[count]
= talloc_zero (msgData, struct mapistore_message_recipient);
recipient = msgData->recipients[count];
person = [attendees objectAtIndex: count];
cn = [person cn];
email = [person rfc822Email];
if ([cn length] == 0)
cn = email;
contactInfos = [mgr contactInfosForUserWithUIDorEmail: email];
if (contactInfos)
{
username = [contactInfos objectForKey: @"c_uid"];
recipient->username = [username asUnicodeInMemCtx: msgData];
entryId = MAPIStoreInternalEntryId (username);
}
else
entryId = MAPIStoreExternalEntryId (cn, email);
recipient->type = MAPI_TO;
/* properties */
p = 0;
recipient->data = talloc_array (msgData, void *, msgData->columns->cValues);
memset (recipient->data, 0, msgData->columns->cValues * sizeof (void *));
// PR_OBJECT_TYPE = MAPI_MAILUSER (see MAPI_OBJTYPE)
recipient->data[p] = MAPILongValue (msgData, MAPI_MAILUSER);
p++;
// PR_DISPLAY_TYPE = DT_MAILUSER (see MS-NSPI)
recipient->data[p] = MAPILongValue (msgData, 0);
p++;
// PR_7BIT_DISPLAY_NAME_UNICODE
recipient->data[p] = [cn asUnicodeInMemCtx: msgData];
p++;
// PR_SMTP_ADDRESS_UNICODE
recipient->data[p] = [email asUnicodeInMemCtx: msgData];
p++;
// PR_SEND_INTERNET_ENCODING = 0x00060000 (plain text, see OXCMAIL)
recipient->data[p] = MAPILongValue (msgData, 0x00060000);
p++;
// PR_RECIPIENT_DISPLAY_NAME_UNICODE
recipient->data[p] = [cn asUnicodeInMemCtx: msgData];
p++;
// PR_RECIPIENT_FLAGS
recipient->data[p] = MAPILongValue (msgData, 1);
p++;
// PR_RECIPIENT_ENTRYID
recipient->data[p] = [entryId asBinaryInMemCtx: msgData];
p++;
// PR_RECIPIENT_TRACKSTATUS
/*
respNone 0x00000000
No response is required for this object. This is the case for Appointment objects and Meeting Response objects.
respOrganized 0x00000001
This Meeting object belongs to the organizer.
respTentative 0x00000002
This value on the attendee's Meeting object indicates that the
attendee has tentatively accepted the Meeting Request object.
respAccepted 0x00000003
This value on the attendee's Meeting object indicates that the
attendee has accepted the Meeting Request object.
respDeclined 0x00000004
This value on the attendee's Meeting object indicates that the attendee has declined the Meeting Request
object.
respNotResponded 0x00000005
This value on the attendee's Meeting object indicates that the attendee has
not yet responded. This value is on the Meet
*/
partStat = [person participationStatus];
switch (partStat)
{
case iCalPersonPartStatAccepted:
partStatValue = 3;
break;
case iCalPersonPartStatDeclined:
partStatValue = 4;
break;
case iCalPersonPartStatTentative:
partStatValue = 2;
break;
default:
partStatValue = 5;
}
recipient->data[p] = MAPILongValue (msgData, partStatValue);
p++;
// // PR_RECORD_KEY
// recipient->data[p] = [entryId asBinaryInMemCtx: msgData];
// p++;
}
/* On with the organizer: */
{
msgData->recipients[max]
= talloc_zero (msgData, struct mapistore_message_recipient);
recipient = msgData->recipients[max];
person = [event organizer];
cn = [person cn];
email = [person rfc822Email];
contactInfos = [mgr contactInfosForUserWithUIDorEmail: email];
if (contactInfos)
{
username = [contactInfos objectForKey: @"c_uid"];
recipient->username = [username asUnicodeInMemCtx: msgData];
entryId = MAPIStoreInternalEntryId (username);
}
else
entryId = MAPIStoreExternalEntryId (cn, email);
recipient->type = MAPI_TO;
p = 0;
recipient->data = talloc_array (msgData, void *, msgData->columns->cValues);
memset (recipient->data, 0, msgData->columns->cValues * sizeof (void *));
// PR_OBJECT_TYPE = MAPI_MAILUSER (see MAPI_OBJTYPE)
recipient->data[p] = MAPILongValue (msgData, MAPI_MAILUSER);
p++;
// PR_DISPLAY_TYPE = DT_MAILUSER (see MS-NSPI)
recipient->data[p] = MAPILongValue (msgData, 0);
p++;
// PR_7BIT_DISPLAY_NAME_UNICODE
recipient->data[p] = [cn asUnicodeInMemCtx: msgData];
p++;
// PR_SMTP_ADDRESS_UNICODE
recipient->data[p] = [email asUnicodeInMemCtx: msgData];
p++;
// PR_SEND_INTERNET_ENCODING = 0x00060000 (plain text, see OXCMAIL)
recipient->data[p] = MAPILongValue (msgData, 0x00060000);
p++;
// PR_RECIPIENT_DISPLAY_NAME_UNICODE
recipient->data[p] = [cn asUnicodeInMemCtx: msgData];
p++;
// PR_RECIPIENT_FLAGS
recipient->data[p] = MAPILongValue (msgData, 3);
p++;
// PR_RECIPIENT_ENTRYID = NULL
recipient->data[p] = [entryId asBinaryInMemCtx: msgData];
p++;
// PR_RECIPIENT_TRACKSTATUS
/*
respNone 0x00000000
No response is required for this object. This is the case for Appointment objects and Meeting Response objects.
respOrganized 0x00000001
This Meeting object belongs to the organizer.
respTentative 0x00000002
This value on the attendee's Meeting object indicates that the
attendee has tentatively accepted the Meeting Request object.
respAccepted 0x00000003
This value on the attendee's Meeting object indicates that the
attendee has accepted the Meeting Request object.
respDeclined 0x00000004
This value on the attendee's Meeting object indicates that the attendee has declined the Meeting Request
object.
respNotResponded 0x00000005
This value on the attendee's Meeting object indicates that the attendee has
not yet responded. This value is on the Meet
*/
recipient->data[p] = MAPILongValue (msgData, 1);
p++;
// // PR_RECORD_KEY
// recipient->data[p] = [entryId asBinaryInMemCtx: msgData];
// p++;
}
}
}
- (int) getPrIconIndex: (void **) data // TODO
inMemCtx: (TALLOC_CTX *) memCtx
{

View File

@ -255,58 +255,11 @@
- (void) getMessageData: (struct mapistore_message **) dataPtr
inMemCtx: (TALLOC_CTX *) memCtx
{
NSString *text;
NSArray *attendees;
iCalPerson *person;
struct SRowSet *recipients;
int count, max;
iCalEvent *event;
struct mapistore_message *msgData;
[super getMessageData: &msgData inMemCtx: memCtx];
event = [sogoObject component: NO secure: NO];
attendees = [event attendees];
max = [attendees count];
recipients = talloc_zero (msgData, struct SRowSet);
recipients->cRows = max;
recipients->aRow = talloc_array (recipients, struct SRow, max);
for (count = 0; count < max; count++)
{
recipients->aRow[count].ulAdrEntryPad = 0;
recipients->aRow[count].cValues = 3;
recipients->aRow[count].lpProps = talloc_array (recipients->aRow,
struct SPropValue,
4);
// TODO (0x01 = primary recipient)
set_SPropValue_proptag (recipients->aRow[count].lpProps,
PR_RECIPIENT_TYPE,
MAPILongValue (recipients->aRow[count].lpProps, 0x01));
set_SPropValue_proptag (recipients->aRow[count].lpProps + 1,
PR_ADDRTYPE_UNICODE,
[@"SMTP" asUnicodeInMemCtx: recipients->aRow]);
person = [attendees objectAtIndex: count];
text = [person rfc822Email];
if (!text)
text = @"";
set_SPropValue_proptag (recipients->aRow[count].lpProps + 2,
PR_EMAIL_ADDRESS_UNICODE,
[text asUnicodeInMemCtx: recipients->aRow]);
text = [person cn];
if ([text length] > 0)
{
recipients->aRow[count].cValues++;
set_SPropValue_proptag (recipients->aRow[count].lpProps + 3,
PR_DISPLAY_NAME_UNICODE,
[text asUnicodeInMemCtx: recipients->aRow]);
}
}
msgData->recipients = recipients;
[[self appointmentWrapper] fillMessageData: msgData
inMemCtx: memCtx];
*dataPtr = msgData;
}

View File

@ -28,11 +28,13 @@
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserManager.h>
#import <Mailer/SOGoDraftObject.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import "MAPIStoreContext.h"
#import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h"
#import "NSObject+MAPIStore.h"
#import "NSString+MAPIStore.h"
@ -92,14 +94,17 @@ typedef void (*getMessageData_inMemCtx_) (MAPIStoreMessage *, SEL,
- (void) getMessageData: (struct mapistore_message **) dataPtr
inMemCtx: (TALLOC_CTX *) memCtx
{
struct SRowSet *recipients;
NSArray *to;
NSInteger count, max;
NSString *text;
NSInteger count, max, p;
NSString *username, *cn, *email;
NSData *entryId;
NSDictionary *contactInfos;
SOGoUserManager *mgr;
NSDictionary *headers;
NGMailAddress *currentAddress;
NGMailAddressParser *parser;
struct mapistore_message *msgData;
struct mapistore_message_recipient *recipient;
getMessageData_inMemCtx_ superMethod;
if ([sogoObject isKindOfClass: SOGoDraftObjectK])
@ -117,53 +122,99 @@ typedef void (*getMessageData_inMemCtx_) (MAPIStoreMessage *, SEL,
to = [headers objectForKey: @"to"];
max = [to count];
recipients = talloc_zero (msgData, struct SRowSet);
recipients->cRows = max;
recipients->aRow = talloc_array (recipients, struct SRow, max);
for (count = 0; count < max; count++)
msgData->columns = set_SPropTagArray (msgData, 9,
PR_OBJECT_TYPE,
PR_DISPLAY_TYPE,
PR_7BIT_DISPLAY_NAME_UNICODE,
PR_SMTP_ADDRESS_UNICODE,
PR_SEND_INTERNET_ENCODING,
PR_RECIPIENT_DISPLAY_NAME_UNICODE,
PR_RECIPIENT_FLAGS,
PR_RECIPIENT_ENTRYID,
PR_RECIPIENT_TRACKSTATUS);
if (max > 0)
{
recipients->aRow[count].ulAdrEntryPad = 0;
recipients->aRow[count].cValues = 3;
recipients->aRow[count].lpProps = talloc_array (recipients->aRow,
struct SPropValue,
4);
// TODO (0x01 = primary recipient)
set_SPropValue_proptag (recipients->aRow[count].lpProps + 0,
PR_RECIPIENT_TYPE,
MAPILongValue (recipients->aRow, 0x01));
set_SPropValue_proptag (recipients->aRow[count].lpProps + 1,
PR_ADDRTYPE_UNICODE,
[@"SMTP" asUnicodeInMemCtx: recipients->aRow]);
parser = [NGMailAddressParser
mailAddressParserWithString: [to objectAtIndex: count]];
currentAddress = [parser parse];
if ([currentAddress isKindOfClass: NGMailAddressK])
mgr = [SOGoUserManager sharedUserManager];
msgData->recipients_count = max;
msgData->recipients = talloc_array (msgData, struct mapistore_message_recipient *, max);
for (count = 0; count < max; count++)
{
// text = [currentAddress personalName];
// if (![text length])
text = [currentAddress address];
if (!text)
text = @"";
set_SPropValue_proptag (recipients->aRow[count].lpProps + 2,
PR_EMAIL_ADDRESS_UNICODE,
[text asUnicodeInMemCtx: recipients->aRow]);
text = [currentAddress displayName];
if ([text length] > 0)
msgData->recipients[count]
= talloc_zero (msgData, struct mapistore_message_recipient);
recipient = msgData->recipients[count];
recipient->data = talloc_array (msgData, void *, msgData->columns->cValues);
memset (recipient->data, 0, msgData->columns->cValues * sizeof (void *));
email = nil;
cn = nil;
parser = [NGMailAddressParser
mailAddressParserWithString: [to objectAtIndex: count]];
currentAddress = [parser parse];
if ([currentAddress isKindOfClass: NGMailAddressK])
{
recipients->aRow[count].cValues++;
set_SPropValue_proptag (recipients->aRow[count].lpProps + 3,
PR_DISPLAY_NAME_UNICODE,
[text asUnicodeInMemCtx: recipients->aRow]);
email = [currentAddress address];
cn = [currentAddress displayName];
contactInfos = [mgr contactInfosForUserWithUIDorEmail: email];
// PR_ACCOUNT_UNICODE
if (contactInfos)
{
username = [contactInfos objectForKey: @"c_uid"];
recipient->username = [username asUnicodeInMemCtx: msgData];
entryId = MAPIStoreInternalEntryId (username);
}
else
entryId = MAPIStoreExternalEntryId (cn, email);
}
else
{
entryId = nil;
[self warnWithFormat: @"address could not be parsed"
@" properly (ignored)"];
}
recipient->type = MAPI_TO;
/* properties */
p = 0;
recipient->data = talloc_array (msgData, void *, msgData->columns->cValues);
memset (recipient->data, 0, msgData->columns->cValues * sizeof (void *));
// PR_OBJECT_TYPE = MAPI_MAILUSER (see MAPI_OBJTYPE)
recipient->data[p] = MAPILongValue (msgData, MAPI_MAILUSER);
p++;
// PR_DISPLAY_TYPE = DT_MAILUSER (see MS-NSPI)
recipient->data[p] = MAPILongValue (msgData, 0);
p++;
// PR_7BIT_DISPLAY_NAME_UNICODE
recipient->data[p] = [cn asUnicodeInMemCtx: msgData];
p++;
// PR_SMTP_ADDRESS_UNICODE
recipient->data[p] = [email asUnicodeInMemCtx: msgData];
p++;
// PR_SEND_INTERNET_ENCODING = 0x00060000 (plain text, see OXCMAIL)
recipient->data[p] = MAPILongValue (msgData, 0x00060000);
p++;
// PR_RECIPIENT_DISPLAY_NAME_UNICODE
recipient->data[p] = [cn asUnicodeInMemCtx: msgData];
p++;
// PR_RECIPIENT_FLAGS
recipient->data[p] = NULL;
p++;
// PR_RECIPIENT_ENTRYID
recipient->data[p] = [entryId asShortBinaryInMemCtx: msgData];
p++;
}
else
[self warnWithFormat: @"address could not be parsed properly (ignored)"];
}
msgData->recipients = recipients;
*dataPtr = msgData;
}
else

View File

@ -31,6 +31,7 @@
#import <NGCards/iCalCalendar.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoUserManager.h>
#import <Mailer/NSData+Mail.h>
#import <Mailer/SOGoMailBodyPart.h>
#import <Mailer/SOGoMailObject.h>
@ -1175,57 +1176,113 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
- (void) getMessageData: (struct mapistore_message **) dataPtr
inMemCtx: (TALLOC_CTX *) memCtx
{
struct SRowSet *recipients;
NSArray *to;
NSInteger count, max;
NSInteger count, max, p;
NGImap4EnvelopeAddress *currentAddress;
NSString *text;
NSString *username, *cn, *email;
NSData *entryId;
NSDictionary *contactInfos;
SOGoUserManager *mgr;
struct mapistore_message *msgData;
struct mapistore_message_recipient *recipient;
[super getMessageData: &msgData inMemCtx: memCtx];
/* Retrieve recipients from the message */
to = [sogoObject toEnvelopeAddresses];
max = [to count];
recipients = talloc_zero (msgData, struct SRowSet);
recipients->cRows = max;
recipients->aRow = talloc_array (recipients, struct SRow, max);
for (count = 0; count < max; count++)
if (!headerSetup)
[self _fetchHeaderData];
if (mailIsEvent)
[[self _appointmentWrapper] fillMessageData: msgData
inMemCtx: memCtx];
else
{
recipients->aRow[count].ulAdrEntryPad = 0;
recipients->aRow[count].cValues = 3;
recipients->aRow[count].lpProps = talloc_array (recipients->aRow,
struct SPropValue,
4);
/* Retrieve recipients from the message */
to = [sogoObject toEnvelopeAddresses];
max = [to count];
// TODO (0x01 = primary recipient)
set_SPropValue_proptag (recipients->aRow[count].lpProps + 0,
PR_RECIPIENT_TYPE,
MAPILongValue (recipients->aRow, 0x01));
set_SPropValue_proptag (recipients->aRow[count].lpProps + 1,
PR_ADDRTYPE_UNICODE,
[@"SMTP" asUnicodeInMemCtx: recipients->aRow]);
msgData->columns = set_SPropTagArray (msgData, 9,
PR_OBJECT_TYPE,
PR_DISPLAY_TYPE,
PR_7BIT_DISPLAY_NAME_UNICODE,
PR_SMTP_ADDRESS_UNICODE,
PR_SEND_INTERNET_ENCODING,
PR_RECIPIENT_DISPLAY_NAME_UNICODE,
PR_RECIPIENT_FLAGS,
PR_RECIPIENT_ENTRYID,
PR_RECIPIENT_TRACKSTATUS);
currentAddress = [to objectAtIndex: count];
// text = [currentAddress personalName];
// if (![text length])
text = [currentAddress baseEMail];
if (!text)
text = @"";
set_SPropValue_proptag (recipients->aRow[count].lpProps + 2,
PR_EMAIL_ADDRESS_UNICODE,
[text asUnicodeInMemCtx: recipients->aRow]);
text = [currentAddress personalName];
if ([text length] > 0)
if (max > 0)
{
recipients->aRow[count].cValues++;
set_SPropValue_proptag (recipients->aRow[count].lpProps + 3,
PR_DISPLAY_NAME_UNICODE,
[text asUnicodeInMemCtx: recipients->aRow]);
mgr = [SOGoUserManager sharedUserManager];
msgData->recipients_count = max;
msgData->recipients = talloc_array (msgData, struct mapistore_message_recipient *, max);
for (count = 0; count < max; count++)
{
msgData->recipients[count]
= talloc_zero (msgData, struct mapistore_message_recipient);
recipient = msgData->recipients[count];
currentAddress = [to objectAtIndex: count];
cn = [currentAddress personalName];
email = [currentAddress baseEMail];
if ([cn length] == 0)
cn = email;
contactInfos = [mgr contactInfosForUserWithUIDorEmail: email];
if (contactInfos)
{
username = [contactInfos objectForKey: @"c_uid"];
// recipient->username = [username asUnicodeInMemCtx: msgData];
// entryId = MAPIStoreInternalEntryId (username);
entryId = MAPIStoreExternalEntryId (cn, email);
}
else
entryId = MAPIStoreExternalEntryId (cn, email);
recipient->type = MAPI_TO;
/* properties */
p = 0;
recipient->data = talloc_array (msgData, void *, msgData->columns->cValues);
memset (recipient->data, 0, msgData->columns->cValues * sizeof (void *));
// PR_OBJECT_TYPE = MAPI_MAILUSER (see MAPI_OBJTYPE)
recipient->data[p] = MAPILongValue (msgData, MAPI_MAILUSER);
p++;
// PR_DISPLAY_TYPE = DT_MAILUSER (see MS-NSPI)
recipient->data[p] = MAPILongValue (msgData, 0);
p++;
// PR_7BIT_DISPLAY_NAME_UNICODE
recipient->data[p] = [cn asUnicodeInMemCtx: msgData];
p++;
// PR_SMTP_ADDRESS_UNICODE
recipient->data[p] = [email asUnicodeInMemCtx: msgData];
p++;
// PR_SEND_INTERNET_ENCODING = 0x00060000 (plain text, see OXCMAIL)
recipient->data[p] = MAPILongValue (msgData, 0x00060000);
p++;
// PR_RECIPIENT_DISPLAY_NAME_UNICODE
recipient->data[p] = [cn asUnicodeInMemCtx: msgData];
p++;
// PR_RECIPIENT_FLAGS
recipient->data[p] = MAPILongValue (msgData, 0x01);
p++;
// PR_RECIPIENT_ENTRYID
recipient->data[p] = [entryId asBinaryInMemCtx: msgData];
p++;
// PR_RECIPIENT_TRACKSTATUS
recipient->data[p] = MAPILongValue (msgData, 0x00);
p++;
}
}
}
msgData->recipients = recipients;
*dataPtr = msgData;
}

View File

@ -37,6 +37,9 @@
#import "MAPIStoreObject.h"
extern NSData *MAPIStoreInternalEntryId (NSString *username);
extern NSData *MAPIStoreExternalEntryId (NSString *cn, NSString *email);
@interface MAPIStoreMessage : MAPIStoreObject
{
NSArray *attachmentKeys;

View File

@ -21,6 +21,7 @@
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
@ -33,7 +34,9 @@
#import "MAPIStoreAttachmentTable.h"
#import "MAPIStoreContext.h"
#import "MAPIStoreFolder.h"
#import "MAPIStorePropertySelectors.h"
#import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h"
#import "NSObject+MAPIStore.h"
#import "NSString+MAPIStore.h"
@ -46,6 +49,102 @@
#include <mapistore/mapistore_errors.h>
#include <mapistore/mapistore_nameid.h>
NSData *MAPIStoreInternalEntryId (NSString *username)
{
NSMutableData *entryId;
static uint8_t providerUid[] = { 0xdc, 0xa7, 0x40, 0xc8,
0xc0, 0x42, 0x10, 0x1a,
0xb4, 0xb9, 0x08, 0x00,
0x2b, 0x2f, 0xe1, 0x82 };
NSString *x500dn;
/* structure:
flags: 32
provideruid: 32 * 4
version: 32
type: 32
X500DN: variable */
entryId = [NSMutableData dataWithCapacity: 256];
[entryId appendUInt32: 0]; // flags
[entryId appendBytes: providerUid length: 16]; // provideruid
[entryId appendUInt32: 1]; // version
[entryId appendUInt32: 0]; // type (local mail user)
/* X500DN */
/* FIXME: the DN will likely work on DEMO installations for now but we
really should get the dn prefix from the server */
x500dn = [NSString stringWithFormat: @"/O=FIRST ORGANIZATION"
@"/OU=FIRST ADMINISTRATIVE GROUP"
@"/CN=RECIPIENTS/CN=%@", username];
[entryId appendData: [x500dn dataUsingEncoding: NSISOLatin1StringEncoding]];
[entryId appendUInt8: 0];
return entryId;
}
NSData *MAPIStoreExternalEntryId (NSString *cn, NSString *email)
{
NSMutableData *entryId;
static uint8_t providerUid[] = { 0x81, 0x2b, 0x1f, 0xa4,
0xbe, 0xa3, 0x10, 0x19,
0x9d, 0x6e, 0x00, 0xdd,
0x01, 0x0f, 0x54, 0x02 };
uint8_t flags21, flags22;
/* structure:
flags: 32
provideruid: 32 * 4
version: 16
{
PaD: 1
MAE: 2
Format: 4
M: 1
U: 1
R: 2
L: 1
Pad: 4
}
DisplayName: variable
AddressType: variable
EmailAddress: variable */
entryId = [NSMutableData dataWithCapacity: 256];
[entryId appendUInt32: 0]; // flags
[entryId appendBytes: providerUid length: 16]; // provideruid
[entryId appendUInt16: 0]; // version
flags21 = 0; /* PaD, MAE, R, Pad = 0 */
flags21 |= 0x16; /* Format: text and HTML */
flags21 |= 0x01; /* M: mime format */
flags22 = 0x90; /* U: unicode, L: no lookup */
[entryId appendUInt8: flags21];
[entryId appendUInt8: flags22];
/* DisplayName */
if (!cn)
cn = @"";
[entryId
appendData: [cn dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
[entryId appendUInt16: 0];
/* AddressType */
[entryId
appendData: [@"SMTP" dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
[entryId appendUInt16: 0];
/* EMailAddress */
if (!email)
email = @"";
[entryId
appendData: [email dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
[entryId appendUInt16: 0];
return entryId;
}
@interface SOGoObject (MAPIStoreProtocol)
- (NSString *) davEntityTag;
@ -77,12 +176,6 @@
- (void) getMessageData: (struct mapistore_message **) dataPtr
inMemCtx: (TALLOC_CTX *) memCtx
{
static enum MAPITAGS tags[] = { PR_SUBJECT_PREFIX_UNICODE,
PR_NORMALIZED_SUBJECT_UNICODE };
struct SRowSet *recipients;
struct SRow *properties;
NSInteger count, max;
const char *propName;
void *propValue;
struct mapistore_message *msgData;
@ -91,40 +184,22 @@
msgData = talloc_zero (memCtx, struct mapistore_message);
recipients = talloc_zero (msgData, struct SRowSet);
recipients->cRows = 0;
recipients->aRow = NULL;
msgData->recipients = recipients;
if ([self getPrSubjectPrefix: &propValue
inMemCtx: msgData] == MAPISTORE_SUCCESS
&& propValue)
msgData->subject_prefix = propValue;
else
msgData->subject_prefix = "";
max = 2;
properties = talloc_zero (msgData, struct SRow);
properties->cValues = 0;
properties->ulAdrEntryPad = 0;
properties->lpProps = talloc_array (properties, struct SPropValue, max);
for (count = 0; count < max; count++)
{
if ([self getProperty: &propValue withTag: tags[count] inMemCtx: msgData]
== MAPISTORE_SUCCESS)
{
if (propValue == NULL)
{
propName = get_proptag_name (tags[count]);
if (!propName)
propName = "<unknown>";
[self errorWithFormat: @"both 'success' and NULL data"
@" returned for proptag %s(0x%.8x)",
propName, tags[count]];
}
else
{
set_SPropValue_proptag (properties->lpProps + properties->cValues,
tags[count],
propValue);
properties->cValues++;
}
}
}
msgData->properties = properties;
if ([self getPrNormalizedSubject: &propValue
inMemCtx: msgData] == MAPISTORE_SUCCESS
&& propValue)
msgData->normalized_subject = propValue;
else
msgData->normalized_subject = "";
msgData->columns = talloc_zero(msgData, struct SPropTagArray);
msgData->recipients_count = 0;
*dataPtr = msgData;
}