mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-04-13 17:28:52 +00:00
Monotone-Parent: bde45b38158c1c9e5e5c05c00ef16e0ceb81c789
Monotone-Revision: 6cff836762bb35cb6c26ae5eb215e6ff131d480d Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-12-03T22:31:56 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
28
ChangeLog
28
ChangeLog
@@ -1,5 +1,33 @@
|
||||
2010-12-03 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreContext.m
|
||||
(-setRestrictions:withFMID:andTableType:getTableStatus:): new
|
||||
backend method that accepts a struct mapi_SRestriction * in order
|
||||
to filter the table rows.
|
||||
(-evaluateRestriction:intoQualifier:)
|
||||
(-evaluateNotRestriction:intoQualifier:)
|
||||
(-evaluateAndRestriction:intoQualifier:)
|
||||
(-evaluateOrRestriction:intoQualifier:): new low-level restriction
|
||||
handlers for converting MAPI restrictions into EOQualifier
|
||||
equivalents.
|
||||
(-evaluateContentRestriction:intoQualifier:)
|
||||
(-evaluatePropertyRestriction:intoQualifier:)
|
||||
(-evaluateBitmaskRestriction:intoQualifier:)
|
||||
(-evaluateExistRestriction:intoQualifier:) new overridable
|
||||
restriction handlers.
|
||||
(-backendIdentifierForProperty:): new overridable restriction
|
||||
helper for converting restriction attributes into database or IMAP
|
||||
fields, depending on the module in use. Used by the topmost
|
||||
version of -evaluatePropertyRestriction:intoQualifier: for
|
||||
handling "needs eval" restriction types.
|
||||
(-saveOrSubmitChangesInMessageWithMID:andFlags:save:) prevent any
|
||||
creation or modification of messages with a type attribute of
|
||||
"IPM.Microsoft.FolderDesign.NamedView", at least for now, because
|
||||
no module is able to handle those view-related messages.
|
||||
|
||||
* OpenChange/MAPIStoreSpoolerContext.m: new experimental subclass
|
||||
of MAPIStoreOutboxContext.
|
||||
|
||||
* OpenChange/MAPIStoreTypes.m (NSObjectFromMAPISPropValue): new
|
||||
helper function, similar in semantics to NSObjectFromSPropValue
|
||||
but taking a struct mapi_SPropValue * as parameter.
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
@@ -201,4 +203,16 @@
|
||||
// return rc;
|
||||
// }
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
static NSMutableDictionary *knownProperties = nil;
|
||||
|
||||
if (!knownProperties)
|
||||
{
|
||||
knownProperties = [NSMutableDictionary new];
|
||||
}
|
||||
|
||||
return [knownProperties objectForKey: MAPIPropertyNumber (property)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
@@ -319,4 +320,58 @@
|
||||
// return rc;
|
||||
// }
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
static NSMutableDictionary *knownProperties = nil;
|
||||
|
||||
if (!knownProperties)
|
||||
{
|
||||
knownProperties = [NSMutableDictionary new];
|
||||
[knownProperties setObject: @"c_mail"
|
||||
forKey: MAPIPropertyNumber (0x81ae001f)];
|
||||
[knownProperties setObject: @"c_mail"
|
||||
forKey: MAPIPropertyNumber (0x81b3001f)];
|
||||
[knownProperties setObject: @"c_mail"
|
||||
forKey: MAPIPropertyNumber (PR_EMS_AB_GROUP_BY_ATTR_2_UNICODE)];
|
||||
[knownProperties setObject: @"c_cn"
|
||||
forKey: MAPIPropertyNumber (PR_DISPLAY_NAME_UNICODE)];
|
||||
}
|
||||
|
||||
return [knownProperties objectForKey: MAPIPropertyNumber (property)];
|
||||
}
|
||||
|
||||
/* restrictions */
|
||||
|
||||
- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
MAPIRestrictionState rc;
|
||||
id value;
|
||||
|
||||
value = NSObjectFromMAPISPropValue (&res->lpProp);
|
||||
switch (res->ulPropTag)
|
||||
{
|
||||
case PR_MESSAGE_CLASS_UNICODE:
|
||||
if ([value isKindOfClass: [NSString class]]
|
||||
&& [value isEqualToString: @"IPM.Contact"])
|
||||
rc = MAPIRestrictionStateAlwaysTrue;
|
||||
else
|
||||
rc = MAPIRestrictionStateAlwaysFalse;
|
||||
break;
|
||||
case PR_EMS_AB_RAS_ACCOUNT_UNICODE:
|
||||
case 0x81b2001f:
|
||||
case PR_EMS_AB_GROUP_BY_ATTR_1_UNICODE:
|
||||
if ([value isEqualToString: @"SMTP"])
|
||||
rc = MAPIRestrictionStateAlwaysTrue;
|
||||
else
|
||||
rc = MAPIRestrictionStateAlwaysFalse;
|
||||
break;
|
||||
|
||||
default:
|
||||
rc = [super evaluatePropertyRestriction: res intoQualifier: qualifier];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -37,9 +37,12 @@
|
||||
|
||||
@class NSArray;
|
||||
@class NSFileHandle;
|
||||
@class NSMutableArray;
|
||||
@class NSMutableDictionary;
|
||||
@class NSString;
|
||||
|
||||
@class EOQualifier;
|
||||
|
||||
@class WOContext;
|
||||
|
||||
@class SOGoFolder;
|
||||
@@ -48,6 +51,13 @@
|
||||
@class MAPIStoreAuthenticator;
|
||||
@class MAPIStoreMapping;
|
||||
|
||||
typedef enum {
|
||||
MAPIRestrictionStateAlwaysFalse = NO,
|
||||
MAPIRestrictionStateAlwaysTrue = YES,
|
||||
MAPIRestrictionStateNeedsEval, /* needs passing of qualifier to underlying
|
||||
database */
|
||||
} MAPIRestrictionState;
|
||||
|
||||
@interface MAPIStoreContext : NSObject
|
||||
{
|
||||
struct mapistore_context *memCtx;
|
||||
@@ -66,6 +76,9 @@
|
||||
NSMutableDictionary *messageCache;
|
||||
NSMutableDictionary *subfolderCache;
|
||||
id moduleFolder;
|
||||
|
||||
MAPIRestrictionState restrictionState;
|
||||
EOQualifier *restriction;
|
||||
}
|
||||
|
||||
+ (id) contextFromURI: (const char *) newUri
|
||||
@@ -93,6 +106,11 @@
|
||||
byName: (const char *) foldername
|
||||
inParentFID: (uint64_t) parent_fid;
|
||||
|
||||
- (int) setRestrictions: (struct mapi_SRestriction *) res
|
||||
withFMID: (uint64_t) fmid
|
||||
andTableType: (uint8_t) type
|
||||
getTableStatus: (uint8_t *) tableStatus;
|
||||
|
||||
- (enum MAPISTATUS) getTableProperty: (void **) data
|
||||
withTag: (enum MAPITAGS) proptag
|
||||
atPosition: (uint32_t) pos
|
||||
@@ -146,6 +164,18 @@
|
||||
asProperty: (enum MAPITAGS) property
|
||||
forURL: (NSString *) url;
|
||||
|
||||
|
||||
/* restrictions */
|
||||
|
||||
- (MAPIRestrictionState) evaluateRestriction: (struct mapi_SRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier;
|
||||
- (MAPIRestrictionState) evaluateNotRestriction: (struct mapi_SNotRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifierPtr;
|
||||
- (MAPIRestrictionState) evaluateAndRestriction: (struct mapi_SAndRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifierPtr;
|
||||
- (MAPIRestrictionState) evaluateOrRestriction: (struct mapi_SOrRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifierPtr;
|
||||
|
||||
/* subclass methods */
|
||||
+ (NSString *) MAPIModuleName;
|
||||
+ (void) registerFixedMappings: (MAPIStoreMapping *) storeMapping;
|
||||
@@ -180,6 +210,18 @@
|
||||
inRow: (struct SRow *) aRow
|
||||
atURL: (NSString *) childURL;
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property;
|
||||
|
||||
/* restrictions */
|
||||
- (MAPIRestrictionState) evaluateContentRestriction: (struct mapi_SContentRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier;
|
||||
- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier;
|
||||
- (MAPIRestrictionState) evaluateBitmaskRestriction: (struct mapi_SBitmaskRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier;
|
||||
- (MAPIRestrictionState) evaluateExistRestriction: (struct mapi_SExistRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* MAPISTORECONTEXT_H */
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#import <Foundation/NSThread.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import <EOControl/EOQualifier.h>
|
||||
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
|
||||
@@ -73,6 +75,202 @@
|
||||
|
||||
@end
|
||||
|
||||
/* restriction helpers */
|
||||
static NSString *
|
||||
MAPIStringForRestrictionState (MAPIRestrictionState state)
|
||||
{
|
||||
NSString *stateStr;
|
||||
|
||||
if (state == MAPIRestrictionStateAlwaysTrue)
|
||||
stateStr = @"true";
|
||||
else if (state == MAPIRestrictionStateAlwaysFalse)
|
||||
stateStr = @"false";
|
||||
else
|
||||
stateStr = @"needs eval";
|
||||
|
||||
return stateStr;
|
||||
}
|
||||
|
||||
static NSString *
|
||||
MAPIStringForRestriction (struct mapi_SRestriction *resPtr);
|
||||
|
||||
// static NSString *
|
||||
// _MAPIIndentString(int indent)
|
||||
// {
|
||||
// NSString *spaces;
|
||||
// char *buffer;
|
||||
|
||||
// if (indent > 0)
|
||||
// {
|
||||
// buffer = malloc (indent + 1);
|
||||
// memset (buffer, 32, indent);
|
||||
// *(buffer+indent) = 0;
|
||||
// spaces = [NSString stringWithFormat: @"%s", buffer];
|
||||
// free (buffer);
|
||||
// }
|
||||
// else
|
||||
// spaces = @"";
|
||||
|
||||
// return spaces;
|
||||
// }
|
||||
|
||||
static NSString *
|
||||
MAPIStringForAndRestriction (struct mapi_SAndRestriction *resAnd)
|
||||
{
|
||||
NSMutableArray *restrictions;
|
||||
uint16_t count;
|
||||
|
||||
restrictions = [NSMutableArray arrayWithCapacity: 8];
|
||||
for (count = 0; count < resAnd->cRes; count++)
|
||||
[restrictions addObject: MAPIStringForRestriction ((struct mapi_SRestriction *) resAnd->res + count)];
|
||||
|
||||
return [NSString stringWithFormat: @"(%@)", [restrictions componentsJoinedByString: @" && "]];
|
||||
}
|
||||
|
||||
static NSString *
|
||||
MAPIStringForOrRestriction (struct mapi_SOrRestriction *resOr)
|
||||
{
|
||||
NSMutableArray *restrictions;
|
||||
uint16_t count;
|
||||
|
||||
restrictions = [NSMutableArray arrayWithCapacity: 8];
|
||||
for (count = 0; count < resOr->cRes; count++)
|
||||
[restrictions addObject: MAPIStringForRestriction ((struct mapi_SRestriction *) resOr->res + count)];
|
||||
|
||||
return [NSString stringWithFormat: @"(%@)", [restrictions componentsJoinedByString: @" || "]];
|
||||
}
|
||||
|
||||
static NSString *
|
||||
MAPIStringForNotRestriction (struct mapi_SNotRestriction *resNot)
|
||||
{
|
||||
return [NSString stringWithFormat: @"!(%@)",
|
||||
MAPIStringForRestriction ((struct mapi_SRestriction *) &resNot->res)];
|
||||
}
|
||||
|
||||
static NSString *
|
||||
MAPIStringForContentRestriction (struct mapi_SContentRestriction *resContent)
|
||||
{
|
||||
NSString *eqMatch, *caseMatch;
|
||||
id value;
|
||||
const char *propName;
|
||||
|
||||
switch (resContent->fuzzy & 0xf)
|
||||
{
|
||||
case 0: eqMatch = @"eq"; break;
|
||||
case 1: eqMatch = @"substring"; break;
|
||||
case 2: eqMatch = @"prefix"; break;
|
||||
default: eqMatch = @"[unknown]";
|
||||
}
|
||||
|
||||
switch (((resContent->fuzzy) >> 16) & 0xf)
|
||||
{
|
||||
case 0: caseMatch = @"fl"; break;
|
||||
case 1: caseMatch = @"nc"; break;
|
||||
case 2: caseMatch = @"ns"; break;
|
||||
case 4: caseMatch = @"lo"; break;
|
||||
default: caseMatch = @"[unknown]";
|
||||
}
|
||||
|
||||
propName = get_proptag_name (resContent->ulPropTag);
|
||||
if (!propName)
|
||||
propName = "<unknown>";
|
||||
|
||||
value = NSObjectFromMAPISPropValue (&resContent->lpProp);
|
||||
|
||||
return [NSString stringWithFormat: @"%s(0x%.8x) %@,%@ %@",
|
||||
propName, resContent->ulPropTag, eqMatch, caseMatch, value];
|
||||
}
|
||||
|
||||
static NSString *
|
||||
MAPIStringForExistRestriction (struct mapi_SExistRestriction *resExist)
|
||||
{
|
||||
const char *propName;
|
||||
|
||||
propName = get_proptag_name (resExist->ulPropTag);
|
||||
if (!propName)
|
||||
propName = "<unknown>";
|
||||
|
||||
return [NSString stringWithFormat: @"%s(0x%.8x) IS NOT NULL", propName, resExist->ulPropTag];
|
||||
}
|
||||
|
||||
static NSString *
|
||||
MAPIStringForPropertyRestriction (struct mapi_SPropertyRestriction *resProperty)
|
||||
{
|
||||
static NSString *operators[] = { @"<", @"<=", @">", @">=", @"==", @"!=",
|
||||
@"=~" };
|
||||
NSString *operator;
|
||||
id value;
|
||||
const char *propName;
|
||||
|
||||
propName = get_proptag_name (resProperty->ulPropTag);
|
||||
if (!propName)
|
||||
propName = "<unknown>";
|
||||
|
||||
if (resProperty->relop > 0 && resProperty->relop < 6)
|
||||
operator = operators[resProperty->relop];
|
||||
else
|
||||
operator = [NSString stringWithFormat: @"<invalid op %d>", resProperty->relop];
|
||||
value = NSObjectFromMAPISPropValue (&resProperty->lpProp);
|
||||
|
||||
return [NSString stringWithFormat: @"%s(0x%.8x) %@ %@",
|
||||
propName, resProperty->ulPropTag, operator, value];
|
||||
}
|
||||
|
||||
static NSString *
|
||||
MAPIStringForBitmaskRestriction (struct mapi_SBitmaskRestriction *resBitmask)
|
||||
{
|
||||
NSString *format;
|
||||
const char *propName;
|
||||
|
||||
propName = get_proptag_name (resBitmask->ulPropTag);
|
||||
if (!propName)
|
||||
propName = "<unknown>";
|
||||
|
||||
if (resBitmask->relMBR == 0)
|
||||
format = @"((%s(0x%.8x) & 0x%.8x))";
|
||||
else
|
||||
format = @"((^%s(0x%.8x) & 0x%.8x))";
|
||||
|
||||
return [NSString stringWithFormat: format,
|
||||
propName, resBitmask->ulPropTag, resBitmask->ulMask];
|
||||
}
|
||||
|
||||
static NSString *
|
||||
MAPIStringForRestriction (struct mapi_SRestriction *resPtr)
|
||||
{
|
||||
NSString *restrictionStr;
|
||||
|
||||
if (resPtr)
|
||||
{
|
||||
switch (resPtr->rt)
|
||||
{
|
||||
// RES_CONTENT=(int)(0x3),
|
||||
// RES_BITMASK=(int)(0x6),
|
||||
// RES_EXIST=(int)(0x8),
|
||||
|
||||
case 0: restrictionStr = MAPIStringForAndRestriction(&resPtr->res.resAnd); break;
|
||||
case 1: restrictionStr = MAPIStringForOrRestriction(&resPtr->res.resOr); break;
|
||||
case 2: restrictionStr = MAPIStringForNotRestriction(&resPtr->res.resNot); break;
|
||||
case 3: restrictionStr = MAPIStringForContentRestriction(&resPtr->res.resContent); break;
|
||||
case 4: restrictionStr = MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break;
|
||||
case 6: restrictionStr = MAPIStringForBitmaskRestriction(&resPtr->res.resBitmask); break;
|
||||
case 8: restrictionStr = MAPIStringForExistRestriction(&resPtr->res.resExist); break;
|
||||
// case 5: MAPIStringForComparePropsRestriction(&resPtr->res.resCompareProps); break;
|
||||
// case 7: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break;
|
||||
// case 9: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break;
|
||||
// case 10: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break;
|
||||
default:
|
||||
restrictionStr
|
||||
= [NSString stringWithFormat: @"[unhandled restriction type: %d]",
|
||||
resPtr->rt];
|
||||
}
|
||||
}
|
||||
else
|
||||
restrictionStr = @"[unrestricted]";
|
||||
|
||||
return restrictionStr;
|
||||
}
|
||||
|
||||
@implementation MAPIStoreContext : NSObject
|
||||
|
||||
/* sogo://username:password@{contacts,calendar,tasks,journal,notes,mail}/dossier/id */
|
||||
@@ -212,6 +410,9 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
moduleFolder = nil;
|
||||
uri = nil;
|
||||
baseContextSet = NO;
|
||||
|
||||
restrictionState = MAPIRestrictionStateAlwaysTrue;
|
||||
restriction = nil;
|
||||
}
|
||||
|
||||
[self logWithFormat: @"-init"];
|
||||
@@ -224,6 +425,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
[self logWithFormat: @"-dealloc: %@", self];
|
||||
|
||||
[parentFoldersBag release];
|
||||
[restriction release];
|
||||
|
||||
[messageCache release];
|
||||
[subfolderCache release];
|
||||
@@ -479,7 +681,11 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
- (int) openDir: (uint64_t) fid
|
||||
inParentFID: (uint64_t) parentFID
|
||||
{
|
||||
[self logWithFormat: @"UNIMPLEMENTED METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
[self logWithFormat:
|
||||
@"UNIMPLEMENTED METHOD '%s' (%d):\n fid=0x%.16x, parentFID=0x%.16x",
|
||||
__FUNCTION__, __LINE__,
|
||||
(unsigned long long) fid,
|
||||
(unsigned long long) parentFID];
|
||||
|
||||
return MAPISTORE_ERROR;
|
||||
}
|
||||
@@ -565,36 +771,50 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
|
||||
[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__];
|
||||
|
||||
url = [mapping urlFromID: fid];
|
||||
if (url)
|
||||
[self logWithFormat: @"context restriction state is: %@",
|
||||
MAPIStringForRestrictionState (restrictionState)];
|
||||
if (restriction)
|
||||
[self logWithFormat: @" active qualifier: %@", restriction];
|
||||
|
||||
|
||||
if (restrictionState == MAPIRestrictionStateAlwaysFalse)
|
||||
{
|
||||
switch (tableType)
|
||||
{
|
||||
case MAPISTORE_FOLDER_TABLE:
|
||||
ids = [self _subfolderKeysForFolderURL: url];
|
||||
break;
|
||||
case MAPISTORE_MESSAGE_TABLE:
|
||||
ids = [self _messageKeysForFolderURL: url];
|
||||
break;
|
||||
default:
|
||||
[self errorWithFormat: @"%s: value of tableType not handled: %d",
|
||||
__FUNCTION__, tableType];
|
||||
rc = MAPISTORE_ERR_INVALID_PARAMETER;
|
||||
ids = nil;
|
||||
}
|
||||
|
||||
if ([ids isKindOfClass: NSArrayK])
|
||||
{
|
||||
rc = MAPI_E_SUCCESS;
|
||||
*rowCount = [ids count];
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_NO_DIRECTORY;
|
||||
*rowCount = 0;
|
||||
rc = MAPI_E_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self errorWithFormat: @"No url found for FID: %lld", fid];
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
url = [mapping urlFromID: fid];
|
||||
if (url)
|
||||
{
|
||||
switch (tableType)
|
||||
{
|
||||
case MAPISTORE_FOLDER_TABLE:
|
||||
ids = [self _subfolderKeysForFolderURL: url];
|
||||
break;
|
||||
case MAPISTORE_MESSAGE_TABLE:
|
||||
ids = [self _messageKeysForFolderURL: url];
|
||||
break;
|
||||
default:
|
||||
[self errorWithFormat: @"%s: value of tableType not handled: %d",
|
||||
__FUNCTION__, tableType];
|
||||
rc = MAPISTORE_ERR_INVALID_PARAMETER;
|
||||
ids = nil;
|
||||
}
|
||||
|
||||
if ([ids isKindOfClass: NSArrayK])
|
||||
{
|
||||
rc = MAPI_E_SUCCESS;
|
||||
*rowCount = [ids count];
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_NO_DIRECTORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self errorWithFormat: @"No url found for FID: %lld", fid];
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -842,6 +1062,273 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (void) logRestriction: (struct mapi_SRestriction *) res
|
||||
withState: (MAPIRestrictionState) state
|
||||
{
|
||||
NSString *resStr;
|
||||
|
||||
resStr = MAPIStringForRestriction (res);
|
||||
|
||||
[self logWithFormat: @"%@ --> %@", resStr, MAPIStringForRestrictionState (state)];
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluateRestriction: (struct mapi_SRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
MAPIRestrictionState state;
|
||||
|
||||
switch (res->rt)
|
||||
{
|
||||
/* basic operators */
|
||||
case 0: state = [self evaluateAndRestriction: &res->res.resAnd
|
||||
intoQualifier: qualifier];
|
||||
break;
|
||||
case 1: state = [self evaluateOrRestriction: &res->res.resOr
|
||||
intoQualifier: qualifier];
|
||||
break;
|
||||
case 2: state = [self evaluateNotRestriction: &res->res.resNot
|
||||
intoQualifier: qualifier];
|
||||
break;
|
||||
|
||||
/* content restrictions */
|
||||
case 3: state = [self evaluateContentRestriction: &res->res.resContent
|
||||
intoQualifier: qualifier];
|
||||
break;
|
||||
case 4: state = [self evaluatePropertyRestriction: &res->res.resProperty
|
||||
intoQualifier: qualifier];
|
||||
break;
|
||||
case 6: state = [self evaluateBitmaskRestriction: &res->res.resBitmask
|
||||
intoQualifier: qualifier];
|
||||
break;
|
||||
case 8: state = [self evaluateExistRestriction: &res->res.resExist
|
||||
intoQualifier: qualifier];
|
||||
break;
|
||||
// case 5: MAPIStringForComparePropsRestriction(&resPtr->res.resCompareProps); break;
|
||||
// case 7: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break;
|
||||
// case 9: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break;
|
||||
// case 10: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break;
|
||||
default:
|
||||
[NSException raise: @"MAPIStoreRestrictionException"
|
||||
format: @"unhandled restriction type"];
|
||||
state = MAPIRestrictionStateAlwaysTrue;
|
||||
}
|
||||
|
||||
[self logRestriction: res withState: state];
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluateNotRestriction: (struct mapi_SNotRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifierPtr
|
||||
{
|
||||
MAPIRestrictionState state, subState;
|
||||
EONotQualifier *qualifier;
|
||||
EOQualifier *subQualifier;
|
||||
|
||||
subState = [self evaluateRestriction: (struct mapi_SRestriction *)&res->res
|
||||
intoQualifier: &subQualifier];
|
||||
if (subState == MAPIRestrictionStateAlwaysTrue)
|
||||
state = MAPIRestrictionStateAlwaysFalse;
|
||||
else if (subState == MAPIRestrictionStateAlwaysFalse)
|
||||
state = MAPIRestrictionStateAlwaysTrue;
|
||||
else
|
||||
{
|
||||
state = MAPIRestrictionStateNeedsEval;
|
||||
qualifier = [[EONotQualifier alloc] initWithQualifier: subQualifier];
|
||||
[qualifier autorelease];
|
||||
*qualifierPtr = qualifier;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluateAndRestriction: (struct mapi_SAndRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifierPtr
|
||||
{
|
||||
MAPIRestrictionState state, subState;
|
||||
EOAndQualifier *qualifier;
|
||||
EOQualifier *subQualifier;
|
||||
NSMutableArray *subQualifiers;
|
||||
uint16_t count;
|
||||
|
||||
state = MAPIRestrictionStateNeedsEval;
|
||||
|
||||
subQualifiers = [NSMutableArray arrayWithCapacity: 8];
|
||||
for (count = 0;
|
||||
state == MAPIRestrictionStateNeedsEval && count < res->cRes;
|
||||
count++)
|
||||
{
|
||||
subState = [self evaluateRestriction: (struct mapi_SRestriction *) res->res + count
|
||||
intoQualifier: &subQualifier];
|
||||
if (subState == MAPIRestrictionStateNeedsEval)
|
||||
[subQualifiers addObject: subQualifier];
|
||||
else if (subState == MAPIRestrictionStateAlwaysFalse)
|
||||
state = MAPIRestrictionStateAlwaysFalse;
|
||||
}
|
||||
|
||||
if (state == MAPIRestrictionStateNeedsEval)
|
||||
{
|
||||
if ([subQualifiers count] == 0)
|
||||
state = MAPIRestrictionStateAlwaysTrue;
|
||||
else
|
||||
{
|
||||
qualifier = [[EOAndQualifier alloc]
|
||||
initWithQualifierArray: subQualifiers];
|
||||
[qualifier autorelease];
|
||||
*qualifierPtr = qualifier;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluateOrRestriction: (struct mapi_SOrRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifierPtr
|
||||
{
|
||||
MAPIRestrictionState state, subState;
|
||||
EOOrQualifier *qualifier;
|
||||
EOQualifier *subQualifier;
|
||||
NSMutableArray *subQualifiers;
|
||||
uint16_t count, falseCount;
|
||||
|
||||
state = MAPIRestrictionStateNeedsEval;
|
||||
|
||||
falseCount = 0;
|
||||
subQualifiers = [NSMutableArray arrayWithCapacity: 8];
|
||||
for (count = 0;
|
||||
state == MAPIRestrictionStateNeedsEval && count < res->cRes;
|
||||
count++)
|
||||
{
|
||||
subState = [self evaluateRestriction: (struct mapi_SRestriction *) res->res + count
|
||||
intoQualifier: &subQualifier];
|
||||
if (subState == MAPIRestrictionStateNeedsEval)
|
||||
[subQualifiers addObject: subQualifier];
|
||||
else if (subState == MAPIRestrictionStateAlwaysTrue)
|
||||
state = MAPIRestrictionStateAlwaysTrue;
|
||||
else
|
||||
falseCount++;
|
||||
}
|
||||
|
||||
if (falseCount == res->cRes)
|
||||
state = MAPIRestrictionStateAlwaysFalse;
|
||||
else if ([subQualifiers count] == 0)
|
||||
state = MAPIRestrictionStateAlwaysTrue;
|
||||
|
||||
if (state == MAPIRestrictionStateNeedsEval)
|
||||
{
|
||||
qualifier = [[EOOrQualifier alloc]
|
||||
initWithQualifierArray: subQualifiers];
|
||||
[qualifier autorelease];
|
||||
*qualifierPtr = qualifier;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluateContentRestriction: (struct mapi_SContentRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return MAPIRestrictionStateAlwaysTrue;
|
||||
}
|
||||
|
||||
- (void) _raiseUnhandledPropertyException: (enum MAPITAGS) property
|
||||
{
|
||||
const char *propName;
|
||||
|
||||
propName = get_proptag_name (property);
|
||||
if (!propName)
|
||||
propName = "<unknown>";
|
||||
[NSException raise: @"MAPIStoreUnhandledPropertyException"
|
||||
format: @"property %s (%.8x) has no matching field name (%@)",
|
||||
propName, property, self];
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
static SEL operators[] = { EOQualifierOperatorLessThan,
|
||||
EOQualifierOperatorLessThanOrEqualTo,
|
||||
EOQualifierOperatorGreaterThan,
|
||||
EOQualifierOperatorGreaterThanOrEqualTo,
|
||||
EOQualifierOperatorEqual,
|
||||
EOQualifierOperatorNotEqual,
|
||||
EOQualifierOperatorContains };
|
||||
SEL operator;
|
||||
id value;
|
||||
NSString *property;
|
||||
|
||||
property = [self backendIdentifierForProperty: res->ulPropTag];
|
||||
if (!property)
|
||||
[self _raiseUnhandledPropertyException: res->ulPropTag];
|
||||
|
||||
if (res->relop > 0 && res->relop < 6)
|
||||
operator = operators[res->relop];
|
||||
else
|
||||
{
|
||||
operator = NULL;
|
||||
[NSException raise: @"MAPIStoreRestrictionException"
|
||||
format: @"unhandled operator type"];
|
||||
}
|
||||
|
||||
value = NSObjectFromMAPISPropValue (&res->lpProp);
|
||||
*qualifier = [[EOKeyValueQualifier alloc] initWithKey: property
|
||||
operatorSelector: operator
|
||||
value: value];
|
||||
[*qualifier autorelease];
|
||||
|
||||
return MAPIRestrictionStateNeedsEval;
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluateBitmaskRestriction: (struct mapi_SBitmaskRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return MAPIRestrictionStateAlwaysTrue;
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluateExistRestriction: (struct mapi_SExistRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return MAPIRestrictionStateAlwaysTrue;
|
||||
}
|
||||
|
||||
- (int) setRestrictions: (struct mapi_SRestriction *) res
|
||||
withFMID: (uint64_t) fmid
|
||||
andTableType: (uint8_t) type
|
||||
getTableStatus: (uint8_t *) tableStatus
|
||||
{
|
||||
NSLog (@"set restriction to (table type: %d): %@",
|
||||
type, MAPIStringForRestriction (res));
|
||||
|
||||
[restriction release];
|
||||
if (res)
|
||||
restrictionState = [self evaluateRestriction: res
|
||||
intoQualifier: &restriction];
|
||||
else
|
||||
restrictionState = MAPIRestrictionStateAlwaysTrue;
|
||||
|
||||
if (restrictionState == MAPIRestrictionStateNeedsEval)
|
||||
[restriction retain];
|
||||
else
|
||||
restriction = nil;
|
||||
|
||||
[self logWithFormat: @" resulting EOQualifier: %@", restriction];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (enum MAPISTATUS) getTableProperty: (void **) data
|
||||
withTag: (enum MAPITAGS) proptag
|
||||
atPosition: (uint32_t) pos
|
||||
@@ -853,76 +1340,87 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
SOGoFolder *folder;
|
||||
int rc;
|
||||
|
||||
// [self logWithFormat: @"METHOD '%s' (%d) -- proptag: 0x%.8x, pos: %ld, tableType: %d, fid: %lld",
|
||||
// __FUNCTION__, __LINE__, proptag, pos, tableType, fid];
|
||||
[self logWithFormat: @"METHOD '%s' (%d) -- proptag: 0x%.8x, pos: %ld, tableType: %d, fid: %lld",
|
||||
__FUNCTION__, __LINE__, proptag, pos, tableType, fid];
|
||||
|
||||
folderURL = [mapping urlFromID: fid];
|
||||
if (folderURL)
|
||||
{
|
||||
folder = [self lookupObject: folderURL];
|
||||
switch (tableType)
|
||||
{
|
||||
case MAPISTORE_FOLDER_TABLE:
|
||||
children = [self _subfolderKeysForFolderURL: folderURL];
|
||||
break;
|
||||
case MAPISTORE_MESSAGE_TABLE:
|
||||
children = [self _messageKeysForFolderURL: folderURL];
|
||||
break;
|
||||
default:
|
||||
[self errorWithFormat: @"%s: value of tableType not handled: %d",
|
||||
__FUNCTION__, tableType];
|
||||
children = nil;
|
||||
break;
|
||||
}
|
||||
[self logWithFormat: @"context restriction state is: %@",
|
||||
MAPIStringForRestrictionState (restrictionState)];
|
||||
if (restriction)
|
||||
[self logWithFormat: @" active qualifier: %@", restriction];
|
||||
|
||||
if ([children count] > pos)
|
||||
{
|
||||
childName = [children objectAtIndex: pos];
|
||||
childURL = [folderURL stringByAppendingFormat: @"/%@",
|
||||
[childName stringByEscapingURL]];
|
||||
|
||||
if (tableType == MAPISTORE_FOLDER_TABLE)
|
||||
{
|
||||
[self logWithFormat: @" querying child folder at URL: %@", childURL];
|
||||
rc = [self getFolderTableChildproperty: data
|
||||
atURL: childURL
|
||||
withTag: proptag
|
||||
inFolder: folder
|
||||
withFID: fid];
|
||||
}
|
||||
else
|
||||
{
|
||||
// [self logWithFormat: @" querying child message at URL: %@", childURL];
|
||||
rc = [self getMessageTableChildproperty: data
|
||||
atURL: childURL
|
||||
withTag: proptag
|
||||
inFolder: folder
|
||||
withFID: fid];
|
||||
}
|
||||
/* Unhandled: */
|
||||
// #define PR_EXPIRY_TIME PROP_TAG(PT_SYSTIME , 0x0015) /* 0x00150040 */
|
||||
// #define PR_REPLY_TIME PROP_TAG(PT_SYSTIME , 0x0030) /* 0x00300040 */
|
||||
// #define PR_SENSITIVITY PROP_TAG(PT_LONG , 0x0036) /* 0x00360003 */
|
||||
// #define PR_MESSAGE_DELIVERY_TIME PROP_TAG(PT_SYSTIME , 0x0e06) /* 0x0e060040 */
|
||||
// #define PR_FOLLOWUP_ICON PROP_TAG(PT_LONG , 0x1095) /* 0x10950003 */
|
||||
// #define PR_ITEM_TEMPORARY_FLAGS PROP_TAG(PT_LONG , 0x1097) /* 0x10970003 */
|
||||
// #define PR_SEARCH_KEY PROP_TAG(PT_BINARY , 0x300b) /* 0x300b0102 */
|
||||
// #define PR_CONTENT_COUNT PROP_TAG(PT_LONG , 0x3602) /* 0x36020003 */
|
||||
// #define PR_CONTENT_UNREAD PROP_TAG(PT_LONG , 0x3603) /* 0x36030003 */
|
||||
// #define PR_FID PROP_TAG(PT_I8 , 0x6748) /* 0x67480014 */
|
||||
// unknown 36de0003 http://social.msdn.microsoft.com/Forums/en-US/os_exchangeprotocols/thread/17c68add-1f62-4b68-9d83-f9ec7c1c6c9b
|
||||
// unknown 819d0003
|
||||
// unknown 81f80003
|
||||
// unknown 81fa000b
|
||||
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERROR;
|
||||
}
|
||||
if (restrictionState == MAPIRestrictionStateAlwaysFalse
|
||||
|| restrictionState == MAPIRestrictionStateNeedsEval) /* TODO: tmp hack */
|
||||
rc = MAPI_E_NOT_FOUND;
|
||||
else
|
||||
{
|
||||
[self errorWithFormat: @"No url found for FID: %lld", fid];
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
folderURL = [mapping urlFromID: fid];
|
||||
if (folderURL)
|
||||
{
|
||||
folder = [self lookupObject: folderURL];
|
||||
switch (tableType)
|
||||
{
|
||||
case MAPISTORE_FOLDER_TABLE:
|
||||
children = [self _subfolderKeysForFolderURL: folderURL];
|
||||
break;
|
||||
case MAPISTORE_MESSAGE_TABLE:
|
||||
children = [self _messageKeysForFolderURL: folderURL];
|
||||
break;
|
||||
default:
|
||||
[self errorWithFormat: @"%s: value of tableType not handled: %d",
|
||||
__FUNCTION__, tableType];
|
||||
children = nil;
|
||||
break;
|
||||
}
|
||||
|
||||
if ([children count] > pos)
|
||||
{
|
||||
childName = [children objectAtIndex: pos];
|
||||
childURL = [folderURL stringByAppendingFormat: @"/%@",
|
||||
[childName stringByEscapingURL]];
|
||||
|
||||
if (tableType == MAPISTORE_FOLDER_TABLE)
|
||||
{
|
||||
[self logWithFormat: @" querying child folder at URL: %@", childURL];
|
||||
rc = [self getFolderTableChildproperty: data
|
||||
atURL: childURL
|
||||
withTag: proptag
|
||||
inFolder: folder
|
||||
withFID: fid];
|
||||
}
|
||||
else
|
||||
{
|
||||
// [self logWithFormat: @" querying child message at URL: %@", childURL];
|
||||
rc = [self getMessageTableChildproperty: data
|
||||
atURL: childURL
|
||||
withTag: proptag
|
||||
inFolder: folder
|
||||
withFID: fid];
|
||||
}
|
||||
/* Unhandled: */
|
||||
// #define PR_EXPIRY_TIME PROP_TAG(PT_SYSTIME , 0x0015) /* 0x00150040 */
|
||||
// #define PR_REPLY_TIME PROP_TAG(PT_SYSTIME , 0x0030) /* 0x00300040 */
|
||||
// #define PR_SENSITIVITY PROP_TAG(PT_LONG , 0x0036) /* 0x00360003 */
|
||||
// #define PR_MESSAGE_DELIVERY_TIME PROP_TAG(PT_SYSTIME , 0x0e06) /* 0x0e060040 */
|
||||
// #define PR_FOLLOWUP_ICON PROP_TAG(PT_LONG , 0x1095) /* 0x10950003 */
|
||||
// #define PR_ITEM_TEMPORARY_FLAGS PROP_TAG(PT_LONG , 0x1097) /* 0x10970003 */
|
||||
// #define PR_SEARCH_KEY PROP_TAG(PT_BINARY , 0x300b) /* 0x300b0102 */
|
||||
// #define PR_CONTENT_COUNT PROP_TAG(PT_LONG , 0x3602) /* 0x36020003 */
|
||||
// #define PR_CONTENT_UNREAD PROP_TAG(PT_LONG , 0x3603) /* 0x36030003 */
|
||||
// #define PR_FID PROP_TAG(PT_I8 , 0x6748) /* 0x67480014 */
|
||||
// unknown 36de0003 http://social.msdn.microsoft.com/Forums/en-US/os_exchangeprotocols/thread/17c68add-1f62-4b68-9d83-f9ec7c1c6c9b
|
||||
// unknown 819d0003
|
||||
// unknown 81f80003
|
||||
// unknown 81fa000b
|
||||
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self errorWithFormat: @"No url found for FID: %lld", fid];
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -1023,31 +1521,44 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
|
||||
NSMutableDictionary *messageProperties;
|
||||
NSString *messageURL;
|
||||
uint64_t fid;
|
||||
BOOL viewMessage;
|
||||
|
||||
viewMessage = NO;
|
||||
messageProperties = [messages objectForKey:
|
||||
[NSNumber numberWithUnsignedLongLong: mid]];
|
||||
if (messageProperties)
|
||||
{
|
||||
messageURL = [mapping urlFromID: mid];
|
||||
if (messageURL)
|
||||
message = [self lookupObject: messageURL];
|
||||
if ([[messageProperties
|
||||
objectForKey: MAPIPropertyNumber (PR_MESSAGE_CLASS_UNICODE)]
|
||||
isEqualToString: @"IPM.Microsoft.FolderDesign.NamedView"])
|
||||
{
|
||||
[self logWithFormat: @"ignored message with view data:"];
|
||||
MAPIStoreDumpMessageProperties (messageProperties);
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
fid = [[messageProperties objectForKey: @"fid"]
|
||||
unsignedLongLongValue];
|
||||
message = [self _createMessageWithMID: mid inFID: fid];
|
||||
}
|
||||
if (message)
|
||||
{
|
||||
[message setMAPIProperties: messageProperties];
|
||||
if (isSave)
|
||||
[message MAPISave];
|
||||
else
|
||||
[message MAPISubmit];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERROR;
|
||||
{
|
||||
messageURL = [mapping urlFromID: mid];
|
||||
if (messageURL)
|
||||
message = [self lookupObject: messageURL];
|
||||
else
|
||||
{
|
||||
fid = [[messageProperties objectForKey: @"fid"]
|
||||
unsignedLongLongValue];
|
||||
message = [self _createMessageWithMID: mid inFID: fid];
|
||||
}
|
||||
if (message)
|
||||
{
|
||||
[message setMAPIProperties: messageProperties];
|
||||
if (isSave)
|
||||
[message MAPISave];
|
||||
else
|
||||
[message MAPISubmit];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
|
||||
@@ -117,7 +118,7 @@
|
||||
withFID: (uint64_t) fid
|
||||
{
|
||||
id child;
|
||||
NSCalendarDate *offsetDate;
|
||||
// NSCalendarDate *offsetDate;
|
||||
enum MAPISTATUS rc;
|
||||
|
||||
rc = MAPI_E_SUCCESS;
|
||||
@@ -145,10 +146,10 @@
|
||||
case PR_LATEST_DELIVERY_TIME: // DOUBT
|
||||
case PR_MESSAGE_DELIVERY_TIME:
|
||||
child = [self lookupObject: childURL];
|
||||
offsetDate = [[child date] addYear: -1 month: 0 day: 0
|
||||
hour: 0 minute: 0 second: 0];
|
||||
*data = [offsetDate asFileTimeInMemCtx: memCtx];
|
||||
// *data = [[child date] asFileTimeInMemCtx: memCtx];
|
||||
// offsetDate = [[child date] addYear: -1 month: 0 day: 0
|
||||
// hour: 0 minute: 0 second: 0];
|
||||
// *data = [offsetDate asFileTimeInMemCtx: memCtx];
|
||||
*data = [[child date] asFileTimeInMemCtx: memCtx];
|
||||
break;
|
||||
case PR_MESSAGE_FLAGS: // TODO
|
||||
// NSDictionary *coreInfos;
|
||||
@@ -534,4 +535,62 @@
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
static NSMutableDictionary *knownProperties = nil;
|
||||
|
||||
if (!knownProperties)
|
||||
{
|
||||
knownProperties = [NSMutableDictionary new];
|
||||
[knownProperties setObject: @"DATE"
|
||||
forKey: MAPIPropertyNumber (PR_MESSAGE_DELIVERY_TIME)];
|
||||
}
|
||||
|
||||
return [knownProperties objectForKey: MAPIPropertyNumber (property)];
|
||||
}
|
||||
|
||||
/* restrictions */
|
||||
|
||||
- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
MAPIRestrictionState rc;
|
||||
id value;
|
||||
|
||||
value = NSObjectFromMAPISPropValue (&res->lpProp);
|
||||
switch (res->ulPropTag)
|
||||
{
|
||||
case PR_MESSAGE_CLASS_UNICODE:
|
||||
if ([value isEqualToString: @"IPM.Note"])
|
||||
rc = MAPIRestrictionStateAlwaysTrue;
|
||||
else
|
||||
rc = MAPIRestrictionStateAlwaysFalse;
|
||||
break;
|
||||
default:
|
||||
rc = [super evaluatePropertyRestriction: res intoQualifier: qualifier];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (MAPIRestrictionState) evaluateExistRestriction: (struct mapi_SExistRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
MAPIRestrictionState rc;
|
||||
|
||||
switch (res->ulPropTag)
|
||||
{
|
||||
case PR_MESSAGE_CLASS_UNICODE:
|
||||
rc = MAPIRestrictionStateAlwaysFalse;
|
||||
break;
|
||||
case PR_MESSAGE_DELIVERY_TIME:
|
||||
rc = MAPIRestrictionStateAlwaysTrue;
|
||||
break;
|
||||
default:
|
||||
rc = [super evaluateExistRestriction: res intoQualifier: qualifier];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -44,8 +44,9 @@
|
||||
\details Initialize sogo mapistore backend
|
||||
|
||||
\return MAPISTORE_SUCCESS on success
|
||||
*/
|
||||
static int sogo_init (void)
|
||||
*/
|
||||
static int
|
||||
sogo_init (void)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
SOGoProductLoader *loader;
|
||||
@@ -90,7 +91,8 @@ static int sogo_init (void)
|
||||
\param private_data pointer to the private backend context
|
||||
*/
|
||||
|
||||
static int sogo_create_context(TALLOC_CTX *mem_ctx, const char *uri, void **private_data)
|
||||
static int
|
||||
sogo_create_context(TALLOC_CTX *mem_ctx, const char *uri, void **private_data)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -106,7 +108,7 @@ static int sogo_create_context(TALLOC_CTX *mem_ctx, const char *uri, void **priv
|
||||
if (MAPIStoreContextK)
|
||||
{
|
||||
context = [MAPIStoreContextK contextFromURI: uri
|
||||
inMemCtx: mem_ctx];
|
||||
inMemCtx: mem_ctx];
|
||||
[context retain];
|
||||
|
||||
cContext = talloc_zero(mem_ctx, sogo_context);
|
||||
@@ -132,7 +134,8 @@ static int sogo_create_context(TALLOC_CTX *mem_ctx, const char *uri, void **priv
|
||||
|
||||
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
|
||||
*/
|
||||
static int sogo_delete_context(void *private_data)
|
||||
static int
|
||||
sogo_delete_context(void *private_data)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -158,7 +161,8 @@ static int sogo_delete_context(void *private_data)
|
||||
|
||||
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
|
||||
*/
|
||||
static int sogo_release_record(void *private_data, uint64_t fmid, uint8_t type)
|
||||
static int
|
||||
sogo_release_record(void *private_data, uint64_t fmid, uint8_t type)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
|
||||
@@ -190,8 +194,9 @@ static int sogo_release_record(void *private_data, uint64_t fmid, uint8_t type)
|
||||
|
||||
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
|
||||
*/
|
||||
static int sogo_get_path(void *private_data, uint64_t fmid,
|
||||
uint8_t type, char **path)
|
||||
static int
|
||||
sogo_get_path(void *private_data, uint64_t fmid,
|
||||
uint8_t type, char **path)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -215,7 +220,8 @@ static int sogo_get_path(void *private_data, uint64_t fmid,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sogo_op_get_fid_by_name(void *private_data, uint64_t parent_fid, const char* foldername, uint64_t *fid)
|
||||
static int
|
||||
sogo_op_get_fid_by_name(void *private_data, uint64_t parent_fid, const char* foldername, uint64_t *fid)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -246,8 +252,9 @@ static int sogo_op_get_fid_by_name(void *private_data, uint64_t parent_fid, cons
|
||||
|
||||
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
|
||||
*/
|
||||
static int sogo_op_mkdir(void *private_data, uint64_t parent_fid, uint64_t fid,
|
||||
struct SRow *aRow)
|
||||
static int
|
||||
sogo_op_mkdir(void *private_data, uint64_t parent_fid, uint64_t fid,
|
||||
struct SRow *aRow)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -280,7 +287,8 @@ static int sogo_op_mkdir(void *private_data, uint64_t parent_fid, uint64_t fid,
|
||||
|
||||
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
|
||||
*/
|
||||
static int sogo_op_rmdir(void *private_data, uint64_t parent_fid, uint64_t fid)
|
||||
static int
|
||||
sogo_op_rmdir(void *private_data, uint64_t parent_fid, uint64_t fid)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -313,7 +321,8 @@ static int sogo_op_rmdir(void *private_data, uint64_t parent_fid, uint64_t fid)
|
||||
|
||||
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
|
||||
*/
|
||||
static int sogo_op_opendir(void *private_data, uint64_t parent_fid, uint64_t fid)
|
||||
static int
|
||||
sogo_op_opendir(void *private_data, uint64_t parent_fid, uint64_t fid)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -344,7 +353,8 @@ static int sogo_op_opendir(void *private_data, uint64_t parent_fid, uint64_t fid
|
||||
|
||||
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
|
||||
*/
|
||||
static int sogo_op_closedir(void *private_data)
|
||||
static int
|
||||
sogo_op_closedir(void *private_data)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -375,10 +385,11 @@ static int sogo_op_closedir(void *private_data)
|
||||
|
||||
\return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR
|
||||
*/
|
||||
static int sogo_op_readdir_count(void *private_data,
|
||||
uint64_t fid,
|
||||
uint8_t table_type,
|
||||
uint32_t *RowCount)
|
||||
static int
|
||||
sogo_op_readdir_count(void *private_data,
|
||||
uint64_t fid,
|
||||
uint8_t table_type,
|
||||
uint32_t *RowCount)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -402,12 +413,13 @@ static int sogo_op_readdir_count(void *private_data,
|
||||
}
|
||||
|
||||
|
||||
static int sogo_op_get_table_property(void *private_data,
|
||||
uint64_t fid,
|
||||
uint8_t table_type,
|
||||
uint32_t pos,
|
||||
uint32_t proptag,
|
||||
void **data)
|
||||
static int
|
||||
sogo_op_get_table_property(void *private_data,
|
||||
uint64_t fid,
|
||||
uint8_t table_type,
|
||||
uint32_t pos,
|
||||
uint32_t proptag,
|
||||
void **data)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -423,7 +435,7 @@ static int sogo_op_get_table_property(void *private_data,
|
||||
[context setupRequest];
|
||||
|
||||
rc = [context getTableProperty: data withTag: proptag atPosition: pos
|
||||
withTableType: table_type inFID: fid];
|
||||
withTableType: table_type inFID: fid];
|
||||
|
||||
[context tearDownRequest];
|
||||
[pool release];
|
||||
@@ -431,10 +443,11 @@ static int sogo_op_get_table_property(void *private_data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sogo_op_openmessage(void *private_data,
|
||||
uint64_t fid,
|
||||
uint64_t mid,
|
||||
struct mapistore_message *msg)
|
||||
static int
|
||||
sogo_op_openmessage(void *private_data,
|
||||
uint64_t fid,
|
||||
uint64_t mid,
|
||||
struct mapistore_message *msg)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -458,9 +471,10 @@ static int sogo_op_openmessage(void *private_data,
|
||||
}
|
||||
|
||||
|
||||
static int sogo_op_createmessage(void *private_data,
|
||||
uint64_t fid,
|
||||
uint64_t mid)
|
||||
static int
|
||||
sogo_op_createmessage(void *private_data,
|
||||
uint64_t fid,
|
||||
uint64_t mid)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -483,9 +497,10 @@ static int sogo_op_createmessage(void *private_data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sogo_op_savechangesmessage(void *private_data,
|
||||
uint64_t mid,
|
||||
uint8_t flags)
|
||||
static int
|
||||
sogo_op_savechangesmessage(void *private_data,
|
||||
uint64_t mid,
|
||||
uint8_t flags)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -508,9 +523,10 @@ static int sogo_op_savechangesmessage(void *private_data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sogo_op_submitmessage(void *private_data,
|
||||
uint64_t mid,
|
||||
uint8_t flags)
|
||||
static int
|
||||
sogo_op_submitmessage(void *private_data,
|
||||
uint64_t mid,
|
||||
uint8_t flags)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -533,11 +549,12 @@ static int sogo_op_submitmessage(void *private_data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sogo_op_getprops(void *private_data,
|
||||
uint64_t fmid,
|
||||
uint8_t type,
|
||||
struct SPropTagArray *SPropTagArray,
|
||||
struct SRow *aRow)
|
||||
static int
|
||||
sogo_op_getprops(void *private_data,
|
||||
uint64_t fmid,
|
||||
uint8_t type,
|
||||
struct SPropTagArray *SPropTagArray,
|
||||
struct SRow *aRow)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -563,10 +580,11 @@ static int sogo_op_getprops(void *private_data,
|
||||
}
|
||||
|
||||
|
||||
static int sogo_op_setprops(void *private_data,
|
||||
uint64_t fmid,
|
||||
uint8_t type,
|
||||
struct SRow *aRow)
|
||||
static int
|
||||
sogo_op_setprops(void *private_data,
|
||||
uint64_t fmid,
|
||||
uint8_t type,
|
||||
struct SRow *aRow)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -589,9 +607,10 @@ static int sogo_op_setprops(void *private_data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sogo_op_set_property_from_fd(void *private_data,
|
||||
uint64_t fmid, uint8_t type,
|
||||
uint32_t property, int fd)
|
||||
static int
|
||||
sogo_op_set_property_from_fd(void *private_data,
|
||||
uint64_t fmid, uint8_t type,
|
||||
uint32_t property, int fd)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -619,9 +638,10 @@ static int sogo_op_set_property_from_fd(void *private_data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sogo_op_get_property_into_fd(void *private_data,
|
||||
uint64_t fmid, uint8_t type,
|
||||
uint32_t property, int fd)
|
||||
static int
|
||||
sogo_op_get_property_into_fd(void *private_data,
|
||||
uint64_t fmid, uint8_t type,
|
||||
uint32_t property, int fd)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -649,10 +669,11 @@ static int sogo_op_get_property_into_fd(void *private_data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sogo_op_modifyrecipients(void *private_data,
|
||||
uint64_t mid,
|
||||
struct ModifyRecipientRow *rows,
|
||||
uint16_t count)
|
||||
static int
|
||||
sogo_op_modifyrecipients(void *private_data,
|
||||
uint64_t mid,
|
||||
struct ModifyRecipientRow *rows,
|
||||
uint16_t count)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -677,9 +698,10 @@ static int sogo_op_modifyrecipients(void *private_data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sogo_op_deletemessage(void *private_data,
|
||||
uint64_t mid,
|
||||
uint8_t flags)
|
||||
static int
|
||||
sogo_op_deletemessage(void *private_data,
|
||||
uint64_t mid,
|
||||
uint8_t flags)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -702,9 +724,10 @@ static int sogo_op_deletemessage(void *private_data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sogo_op_get_folders_list(void *private_data,
|
||||
uint64_t fmid,
|
||||
struct indexing_folders_list **folders_list)
|
||||
static int
|
||||
sogo_op_get_folders_list(void *private_data,
|
||||
uint64_t fmid,
|
||||
struct indexing_folders_list **folders_list)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
@@ -727,6 +750,41 @@ static int sogo_op_get_folders_list(void *private_data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
sogo_op_set_restrictions (void *private_data, uint64_t fmid, uint8_t type,
|
||||
struct mapi_SRestriction *res, uint8_t *tableStatus)
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
sogo_context *cContext;
|
||||
MAPIStoreContext *context;
|
||||
int rc;
|
||||
|
||||
DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__));
|
||||
|
||||
pool = [NSAutoreleasePool new];
|
||||
|
||||
cContext = private_data;
|
||||
context = cContext->objcContext;
|
||||
if (context)
|
||||
{
|
||||
[context setupRequest];
|
||||
|
||||
rc = [context setRestrictions: res
|
||||
withFMID: fmid andTableType: type
|
||||
getTableStatus: tableStatus];
|
||||
|
||||
[context tearDownRequest];
|
||||
[pool release];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO CONTEXT");
|
||||
rc = MAPI_E_NOT_FOUND;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
\details Entry point for mapistore SOGO backend
|
||||
|
||||
@@ -751,12 +809,13 @@ int mapistore_init_backend(void)
|
||||
backend.description = "mapistore SOGo backend";
|
||||
backend.namespace = "sogo://";
|
||||
|
||||
/* Fill in all the operations */
|
||||
backend.init = sogo_init;
|
||||
backend.create_context = sogo_create_context;
|
||||
backend.delete_context = sogo_delete_context;
|
||||
backend.release_record = sogo_release_record;
|
||||
|
||||
backend.get_path = sogo_get_path;
|
||||
backend.op_get_fid_by_name = sogo_op_get_fid_by_name;
|
||||
|
||||
backend.op_mkdir = sogo_op_mkdir;
|
||||
backend.op_rmdir = sogo_op_rmdir;
|
||||
@@ -764,18 +823,19 @@ int mapistore_init_backend(void)
|
||||
backend.op_closedir = sogo_op_closedir;
|
||||
backend.op_readdir_count = sogo_op_readdir_count;
|
||||
backend.op_get_table_property = sogo_op_get_table_property;
|
||||
backend.op_get_folders_list = sogo_op_get_folders_list;
|
||||
backend.op_set_restrictions = sogo_op_set_restrictions;
|
||||
backend.op_openmessage = sogo_op_openmessage;
|
||||
backend.op_createmessage = sogo_op_createmessage;
|
||||
backend.op_modifyrecipients = sogo_op_modifyrecipients;
|
||||
backend.op_savechangesmessage = sogo_op_savechangesmessage;
|
||||
backend.op_submitmessage = sogo_op_submitmessage;
|
||||
backend.op_getprops = sogo_op_getprops;
|
||||
backend.op_get_fid_by_name = sogo_op_get_fid_by_name;
|
||||
backend.op_deletemessage = sogo_op_deletemessage;
|
||||
|
||||
backend.op_setprops = sogo_op_setprops;
|
||||
backend.op_getprops = sogo_op_getprops;
|
||||
backend.op_set_property_from_fd = sogo_op_set_property_from_fd;
|
||||
backend.op_get_property_into_fd = sogo_op_get_property_into_fd;
|
||||
backend.op_modifyrecipients = sogo_op_modifyrecipients;
|
||||
backend.op_deletemessage = sogo_op_deletemessage;
|
||||
backend.op_get_folders_list = sogo_op_get_folders_list;
|
||||
|
||||
/* Register ourselves with the MAPISTORE subsystem */
|
||||
ret = mapistore_backend_register(&backend);
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
|
||||
#import <NGCards/iCalToDo.h>
|
||||
@@ -176,4 +178,42 @@
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
||||
static NSMutableDictionary *knownProperties = nil;
|
||||
|
||||
if (!knownProperties)
|
||||
{
|
||||
knownProperties = [NSMutableDictionary new];
|
||||
}
|
||||
|
||||
return [knownProperties objectForKey: MAPIPropertyNumber (property)];
|
||||
}
|
||||
|
||||
/* restrictions */
|
||||
|
||||
- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res
|
||||
intoQualifier: (EOQualifier **) qualifier
|
||||
{
|
||||
MAPIRestrictionState rc;
|
||||
id value;
|
||||
|
||||
value = NSObjectFromMAPISPropValue (&res->lpProp);
|
||||
switch (res->ulPropTag)
|
||||
{
|
||||
case PR_MESSAGE_CLASS_UNICODE:
|
||||
if ([value isKindOfClass: [NSString class]]
|
||||
&& [value isEqualToString: @"IPM.Task"])
|
||||
rc = MAPIRestrictionStateAlwaysTrue;
|
||||
else
|
||||
rc = MAPIRestrictionStateAlwaysFalse;
|
||||
break;
|
||||
|
||||
default:
|
||||
rc = [super evaluatePropertyRestriction: res intoQualifier: qualifier];
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user