From ab43fce1af68c68b5e28d8c99f6af15d079e3b7f Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Thu, 14 Jul 2011 21:35:54 +0000 Subject: [PATCH] Monotone-Parent: fd90ae60f7879a303cc5d6b24e64a0a382068323 Monotone-Revision: edd6ac7b0fdcca99066a8097eefc5e8b36ff52fa Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2011-07-14T21:35:54 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 2 + OpenChange/MAPIStoreContext.h | 62 +-- OpenChange/MAPIStoreContext.m | 700 ++-------------------------------- OpenChange/MAPIStoreFolder.h | 31 ++ OpenChange/MAPIStoreFolder.m | 427 +++++++++++++++++++-- OpenChange/MAPIStoreSOGo.h | 37 -- OpenChange/MAPIStoreSOGo.m | 451 ++++++++++------------ 7 files changed, 663 insertions(+), 1047 deletions(-) delete mode 100644 OpenChange/MAPIStoreSOGo.h diff --git a/ChangeLog b/ChangeLog index 7026806e5..62633c708 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2011-07-14 Wolfgang Sourdeau + * OpenChange/MAPIStoreSOGo.m: finalized the new API. + * OpenChange/MAPIStoreTable.m: added memory debugging output. * OpenChange/NSArray+MAPIStore.m (-asFoldersListInCtx:) removed diff --git a/OpenChange/MAPIStoreContext.h b/OpenChange/MAPIStoreContext.h index 882d9dbda..e9bdfba26 100644 --- a/OpenChange/MAPIStoreContext.h +++ b/OpenChange/MAPIStoreContext.h @@ -56,7 +56,6 @@ struct mapistore_connection_info *connInfo; NSURL *contextUrl; - uint64_t contextFid; MAPIStoreMapping *mapping; @@ -64,26 +63,14 @@ WOContext *woContext; MAPIStoreFolder *baseFolder; - - /* for active folders (NSDictionary instances) */ - NSMutableDictionary *folders; - - /* hackish table cache */ - MAPIStoreTable *cachedTable; - MAPIStoreFolder *cachedFolder; - uint64_t cachedTableFID; - uint8_t cachedTableType; } -+ (id) contextFromURI: (const char *) newUri - withConnectionInfo: (struct mapistore_connection_info *) newConnInfo - andFID: (uint64_t) fid - inMemCtx: (struct mapistore_context *) newMemCtx; ++ (int) openContext: (MAPIStoreContext **) contextPtr + withURI: (const char *) newUri + andConnectionInfo: (struct mapistore_connection_info *) newConnInfo; - (id) initFromURL: (NSURL *) newUri - withConnectionInfo: (struct mapistore_connection_info *) newConnInfo - andFID: (uint64_t) fid - inMemCtx: (struct mapistore_context *) newMemCtx; + withConnectionInfo: (struct mapistore_connection_info *) newConnInfo; - (void) setAuthenticator: (MAPIStoreAuthenticator *) newAuthenticator; - (MAPIStoreAuthenticator *) authenticator; @@ -102,39 +89,9 @@ /* backend methods */ - (int) getPath: (char **) path ofFMID: (uint64_t) fmid - withTableType: (uint8_t) tableType inMemCtx: (TALLOC_CTX *) memCtx; - -- (int) mkDir: (struct SRow *) aRow - withFID: (uint64_t) fid - inParentFID: (uint64_t) parentFID; -- (int) rmDirWithFID: (uint64_t) fid - inParentFID: (uint64_t) parentFid; -- (int) openDir: (uint64_t) fid; -- (int) closeDir; -- (int) readCount: (uint32_t *) rowCount - ofTableType: (uint8_t) tableType - inFID: (uint64_t) fid; -- (int) openMessage: (MAPIStoreMessage **) messagePtr - andMessageData: (struct mapistore_message **) dataPtr - withMID: (uint64_t) mid - inFID: (uint64_t) fid - inMemCtx: (TALLOC_CTX *) memCtx; -- (int) createMessage: (MAPIStoreMessage **) messagePtr - withMID: (uint64_t) mid - inFID: (uint64_t) fid - isAssociated: (BOOL) isAssociated; -- (int) getProperties: (struct SPropTagArray *) SPropTagArray - ofTableType: (uint8_t) tableType - inRow: (struct SRow *) aRow - withMID: (uint64_t) fmid - inMemCtx: (TALLOC_CTX *) memCtx; -- (int) setPropertiesWithFMID: (uint64_t) fmid - ofTableType: (uint8_t) tableType - inRow: (struct SRow *) aRow; -- (int) deleteMessageWithMID: (uint64_t) mid - inFID: (uint64_t) fid - withFlags: (uint8_t) flags; +- (int) getRootFolder: (MAPIStoreFolder **) folderPtr + withFID: (uint64_t) fmid; /* util methods */ - (NSString *) extractChildNameFromURL: (NSString *) childURL @@ -147,13 +104,6 @@ + (NSString *) MAPIModuleName; - (void) setupBaseFolder: (NSURL *) newURL; -/* proof of concept */ -- (int) getTable: (MAPIStoreTable **) tablePtr - andRowCount: (uint32_t *) count - withFID: (uint64_t) fid - tableType: (uint8_t) tableType - andHandleId: (uint32_t) handleId; - @end #endif /* MAPISTORECONTEXT_H */ diff --git a/OpenChange/MAPIStoreContext.m b/OpenChange/MAPIStoreContext.m index 6d05e6bbb..607437fba 100644 --- a/OpenChange/MAPIStoreContext.m +++ b/OpenChange/MAPIStoreContext.m @@ -104,10 +104,8 @@ static NSMutableDictionary *userMAPIStoreMapping; } static inline MAPIStoreContext * -_prepareContextClass (struct mapistore_context *newMemCtx, - Class contextClass, - struct mapistore_connection_info *connInfo, - NSURL *url, uint64_t fid) +_prepareContextClass (Class contextClass, + struct mapistore_connection_info *connInfo, NSURL *url) { static NSMutableDictionary *registration = nil; MAPIStoreContext *context; @@ -121,9 +119,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx, forKey: contextClass]; context = [[contextClass alloc] initFromURL: url - withConnectionInfo: connInfo - andFID: fid - inMemCtx: newMemCtx]; + withConnectionInfo: connInfo]; [context autorelease]; authenticator = [MAPIStoreAuthenticator new]; @@ -134,22 +130,20 @@ _prepareContextClass (struct mapistore_context *newMemCtx, [context setupRequest]; [context setupBaseFolder: url]; - [context->folders setObject: context->baseFolder - forKey: [NSNumber numberWithUnsignedLongLong: fid]]; [context tearDownRequest]; return context; } -+ (id) contextFromURI: (const char *) newUri - withConnectionInfo: (struct mapistore_connection_info *) connInfo - andFID: (uint64_t) fid - inMemCtx: (struct mapistore_context *) newMemCtx ++ (int) openContext: (MAPIStoreContext **) contextPtr + withURI: (const char *) newUri + andConnectionInfo: (struct mapistore_connection_info *) newConnInfo { MAPIStoreContext *context; Class contextClass; NSString *module, *completeURLString, *urlString; NSURL *baseURL; + int rc = MAPISTORE_ERR_NOT_FOUND; NSLog (@"METHOD '%s' (%d) -- uri: '%s'", __FUNCTION__, __LINE__, newUri); @@ -169,11 +163,16 @@ _prepareContextClass (struct mapistore_context *newMemCtx, { contextClass = [contextClassMapping objectForKey: module]; if (contextClass) - context = _prepareContextClass (newMemCtx, - contextClass, - connInfo, - baseURL, - fid); + { + context = _prepareContextClass (contextClass, + newConnInfo, + baseURL); + if (context) + { + *contextPtr = context; + rc = MAPISTORE_SUCCESS; + } + } else NSLog (@"ERROR: unrecognized module name '%@'", module); } @@ -184,20 +183,17 @@ _prepareContextClass (struct mapistore_context *newMemCtx, else NSLog (@"ERROR: url is an invalid UTF-8 string"); - return context; + return rc; } - (id) init { if ((self = [super init])) { - folders = [NSMutableDictionary new]; woContext = [WOContext contextWithRequest: nil]; [woContext retain]; baseFolder = nil; contextUrl = nil; - cachedTable = nil; - cachedFolder = nil; } return self; @@ -205,8 +201,6 @@ _prepareContextClass (struct mapistore_context *newMemCtx, - (id) initFromURL: (NSURL *) newUrl withConnectionInfo: (struct mapistore_connection_info *) newConnInfo - andFID: (uint64_t) newFid - inMemCtx: (struct mapistore_context *) newMemCtx { NSString *username; @@ -223,10 +217,6 @@ _prepareContextClass (struct mapistore_context *newMemCtx, mapping = [MAPIStoreMapping mappingWithIndexing: newConnInfo->indexing]; [userMAPIStoreMapping setObject: mapping forKey: username]; } - if (![mapping urlFromID: newFid]) - [mapping registerURL: [newUrl absoluteString] - withID: newFid]; - contextFid = newFid; mstoreCtx = newConnInfo->mstore_ctx; connInfo = newConnInfo; @@ -237,10 +227,6 @@ _prepareContextClass (struct mapistore_context *newMemCtx, - (void) dealloc { - [folders release]; - [cachedTable release]; - [cachedFolder release]; - [baseFolder release]; [woContext release]; [authenticator release]; @@ -298,340 +284,6 @@ _prepareContextClass (struct mapistore_context *newMemCtx, [MAPIApp setMAPIStoreContext: nil]; } -- (MAPIStoreObject *) _lookupObjectWithParts: (NSArray *) parts -{ - NSUInteger count, max; - NSString *currentPart; - MAPIStoreObject *currentObject; - - currentObject = baseFolder; - max = [parts count]; - for (count = 0; count < max; count++) - { - currentPart = [parts objectAtIndex: count]; - if ([currentPart length] > 0) - currentObject = [currentObject lookupChild: currentPart]; - } - - return currentObject; -} - -- (id) lookupObject: (NSString *) childURL -{ - NSString *baseURL, *subURL; - MAPIStoreObject *foundObject; - NSArray *parts; - - baseURL = [contextUrl absoluteString]; - if (![baseURL hasSuffix: @"/"]) - baseURL = [NSString stringWithFormat: @"%@/", baseURL]; - if (![childURL hasSuffix: @"/"]) - childURL = [NSString stringWithFormat: @"%@/", childURL]; - if ([childURL isEqualToString: baseURL]) - foundObject = baseFolder; - else if ([childURL hasPrefix: baseURL]) - { - subURL = [childURL substringFromIndex: [baseURL length]]; - parts = [subURL componentsSeparatedByString: @"/"]; - foundObject = [self _lookupObjectWithParts: parts]; - [self logWithFormat: @"returning object '%@'", childURL]; - } - else - { - [self errorWithFormat: @"url '%@' is not a child of this context (%@)", - childURL, baseURL]; - foundObject = nil; - } - - /* TODO hierarchy */ - return foundObject; -} - -- (id) lookupFolderWithFID: (uint64_t) fid -{ - MAPIStoreFolder *folder; - NSNumber *fidKey; - NSString *folderURL; - - fidKey = [NSNumber numberWithUnsignedLongLong: fid]; - folder = [folders objectForKey: fidKey]; - if (!folder) - { - /* TODO: should handle folder hierarchies */ - folderURL = [mapping urlFromID: fid]; - if (folderURL) - { - folder = [self lookupObject: folderURL]; - if (folder) - [folders setObject: folder forKey: fidKey]; - } - else - [self errorWithFormat: @"folder with url '%@' not found", folderURL]; - } - [folder setMAPIRetainCount: [folder mapiRetainCount] + 1]; - - return folder; -} - -- (void) releaseFolderWithFID: (uint64_t) fid -{ - MAPIStoreFolder *folder; - NSNumber *fidKey; - uint32_t retainCount; - - fidKey = [NSNumber numberWithUnsignedLongLong: fid]; - folder = [folders objectForKey: fidKey]; - if (folder) - { - retainCount = [folder mapiRetainCount]; - if (retainCount == 1) - [folders removeObjectForKey: fidKey]; - else - [folder setMAPIRetainCount: retainCount - 1]; - } -} - -/** - \details Create a folder in the sogo backend - - \param private_data pointer to the current sogo context - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR -*/ - -- (int) mkDir: (struct SRow *) aRow - withFID: (uint64_t) fid - inParentFID: (uint64_t) parentFID -{ - NSString *folderURL, *folderKey; - MAPIStoreFolder *parentFolder, *newFolder; - NSNumber *fidKey; - int rc; - - [self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__]; - - folderURL = [mapping urlFromID: fid]; - if (folderURL) - rc = MAPISTORE_ERR_EXIST; - else - { - fidKey = [NSNumber numberWithUnsignedLongLong: parentFID]; - parentFolder = [folders objectForKey: fidKey]; - if (parentFolder) - { - folderKey = [parentFolder createFolder: aRow withFID: fid]; - if (folderKey) - { - [parentFolder cleanupCaches]; - folderURL = [NSString stringWithFormat: @"%@%@", - [parentFolder url], folderKey]; - [mapping registerURL: folderURL withID: fid]; - newFolder = [parentFolder lookupChild: folderKey]; - if (newFolder) - [newFolder setProperties: aRow]; - else - [NSException raise: @"MAPIStoreIOException" - format: @"unable to fetch created folder"]; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERROR; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - } - - return rc; -} - - -/** - \details Delete a folder from the sogo backend - - \param private_data pointer to the current sogo context - \param parentFID the FID for the parent of the folder to delete - \param fid the FID for the folder to delete - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR -*/ -- (int) rmDirWithFID: (uint64_t) fid - inParentFID: (uint64_t) parentFid -{ - [self logWithFormat: @"UNIMPLEMENTED METHOD '%s' (%d)", __FUNCTION__, __LINE__]; - - return MAPISTORE_ERROR; -} - - -/** - \details Open a folder from the sogo backend - - \param private_data pointer to the current sogo context - \param parentFID the parent folder identifier - \param fid the identifier of the colder to open - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR -*/ -- (int) openDir: (uint64_t) fid -{ - MAPIStoreFolder *folder; - int rc; - - folder = [self lookupFolderWithFID: fid]; - if (folder) - rc = MAPISTORE_SUCCESS; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -/** - \details Close a folder from the sogo backend - - \param private_data pointer to the current sogo context - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR -*/ -- (int) closeDir -{ - // MAPIStoreFolder *folder; - // NSNumber *fidKey; - // uint32_t retainCount; - - // fidKey = [NSNumber numberWithUnsignedLongLong: fid]; - // folder = [folders objectForKey: fidKey]; - // if (folder) - // { - // rc = MAPISTORE_SUCCESS; - // retainCount = [folder mapiRetainCount]; - // if (retainCount == 0) - // { - // [self logWithFormat: @"folder with fid %.16x successfully removed" - // @" from folder cache", - // fmid]; - // [folders removeObjectForKey: midKey]; - // } - // else - // [folder setMAPIRetainCount: retainCount - 1]; - // } - // else - // rc = MAPISTORE_ERR_NOT_FOUND; - - [self logWithFormat: @"UNIMNPLEMENTED METHOD '%s' -- leak ahead (%d)", __FUNCTION__, __LINE__]; - - return MAPISTORE_SUCCESS; -} - -- (MAPIStoreTable *) _tableForFID: (uint64_t) fid - andTableType: (uint8_t) tableType -{ - MAPIStoreFolder *folder; - MAPIStoreTable *table; - NSNumber *fidKey; - - if (fid == cachedTableFID && tableType == cachedTableType) - table = cachedTable; - else - { - [cachedTable release]; - cachedTable = nil; - [cachedFolder release]; - cachedFolder = nil; - cachedTableFID = 0; - cachedTableType = 0; - - fidKey = [NSNumber numberWithUnsignedLongLong: fid]; - folder = [folders objectForKey: fidKey]; - if (folder) - { - if (tableType == MAPISTORE_MESSAGE_TABLE) - table = [folder messageTable]; - else if (tableType == MAPISTORE_FAI_TABLE) - table = [folder faiMessageTable]; - else if (tableType == MAPISTORE_FOLDER_TABLE) - table = [folder folderTable]; - else - { - table = nil; - [NSException raise: @"MAPIStoreIOException" - format: @"unsupported table type: %d", tableType]; - } - - if (table) - { - cachedTableFID = fid; - cachedTableType = tableType; - ASSIGN (cachedTable, table); - ASSIGN (cachedFolder, folder); - } - } - else - { - table = nil; - [self errorWithFormat: @"folder with fid %Lu not found", - (unsigned long long) fid]; - } - } - - return table; -} - -/** - \details Read directory content from the sogo backend - - \param private_data pointer to the current sogo context - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR -*/ -- (int) readCount: (uint32_t *) rowCount - ofTableType: (uint8_t) tableType - inFID: (uint64_t) fid -{ - NSArray *keys; - NSString *url; - NSNumber *fidKey; - MAPIStoreFolder *folder; - int rc; - - /* WARNING: make sure this method is no longer invoked for counting - table elements */ - [self logWithFormat: @"METHOD '%s' (%d) -- tableType: %d", - __FUNCTION__, __LINE__, tableType]; - - url = [mapping urlFromID: fid]; - if (url) - { - fidKey = [NSNumber numberWithUnsignedLongLong: fid]; - folder = [folders objectForKey: fidKey]; - if (folder) - { - if (tableType == MAPISTORE_MESSAGE_TABLE) - keys = [folder messageKeys]; - else if (tableType == MAPISTORE_FOLDER_TABLE) - keys = [folder folderKeys]; - else if (tableType == MAPISTORE_FAI_TABLE) - keys = [folder faiMessageKeys]; - *rowCount = [keys count]; - rc = MAPI_E_SUCCESS; - } - else - { - [self errorWithFormat: @"No folder found for URL: %@", url]; - rc = MAPISTORE_ERR_NOT_FOUND; - } - } - else - { - [self errorWithFormat: @"No url found for FID: %lld", fid]; - rc = MAPISTORE_ERR_NOT_FOUND; - } - // } - [self logWithFormat: @"result: count = %d, rc = %d", *rowCount, rc]; - - return rc; -} - // - (void) logRestriction: (struct mapi_SRestriction *) res // withState: (MAPIRestrictionState) state // { @@ -642,165 +294,8 @@ _prepareContextClass (struct mapistore_context *newMemCtx, // [self logWithFormat: @"%@ --> %@", resStr, MAPIStringForRestrictionState (state)]; // } -- (int) openMessage: (MAPIStoreMessage **) messagePtr - andMessageData: (struct mapistore_message **) dataPtr - withMID: (uint64_t) mid - inFID: (uint64_t) fid - inMemCtx: (TALLOC_CTX *) memCtx; -{ - NSString *messageKey, *messageURL; - MAPIStoreMessage *message; - MAPIStoreFolder *folder; - NSNumber *fidKey; - int rc = MAPISTORE_ERR_NOT_FOUND; - - messageURL = [mapping urlFromID: mid]; - if (messageURL) - { - fidKey = [NSNumber numberWithUnsignedLongLong: fid]; - folder = [folders objectForKey: fidKey]; - messageKey = [self extractChildNameFromURL: messageURL - andFolderURLAt: NULL]; - message = [folder lookupChild: messageKey]; - if (message) - { - [message getMessageData: dataPtr inMemCtx: memCtx]; - *messagePtr = message; - rc = MAPISTORE_SUCCESS; - } - } - - return rc; -} - -- (int) createMessage: (MAPIStoreMessage **) messagePtr - withMID: (uint64_t) mid - inFID: (uint64_t) fid - isAssociated: (BOOL) isAssociated -{ - NSNumber *fidKey; - NSString *childURL; - MAPIStoreMessage *message; - MAPIStoreFolder *folder; - int rc; - - [self logWithFormat: @"METHOD '%s' -- mid: 0x%.16x, fid: 0x%.16x, associated: %d", - __FUNCTION__, mid, fid, isAssociated]; - - if ([mapping urlFromID: mid]) - rc = MAPISTORE_ERR_EXIST; - else - { - fidKey = [NSNumber numberWithUnsignedLongLong: fid]; - folder = [folders objectForKey: fidKey]; - if (folder) - { - message = [folder createMessage: isAssociated]; - if (message) - { - childURL = [NSString stringWithFormat: @"%@%@", - [folder url], [message nameInContainer]]; - [mapping registerURL: childURL withID: mid]; - *messagePtr = message; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERROR; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - } - - return rc; -} - -- (int) getProperties: (struct SPropTagArray *) sPropTagArray - ofTableType: (uint8_t) tableType - inRow: (struct SRow *) aRow - withMID: (uint64_t) fmid - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSNumber *fidKey; - MAPIStoreObject *child; - NSInteger count; - void *propValue; - const char *propName; - enum MAPITAGS tag; - enum MAPISTATUS propRc; - struct mapistore_property_data *data; - int rc; - - [self logWithFormat: @"METHOD '%s' -- fmid: 0x%.16x, tableType: %d", - __FUNCTION__, fmid, tableType]; - - fidKey = [NSNumber numberWithUnsignedLongLong: fmid]; - child = [folders objectForKey: fidKey]; - if (child) - { - data = talloc_array (memCtx, struct mapistore_property_data, - sPropTagArray->cValues); - memset (data, 0, - sizeof (struct mapistore_property_data) * sPropTagArray->cValues); - rc = [child getProperties: data - withTags: sPropTagArray->aulPropTag - andCount: sPropTagArray->cValues - inMemCtx: memCtx]; - if (rc == MAPISTORE_SUCCESS) - { - aRow->lpProps = talloc_array (aRow, struct SPropValue, - sPropTagArray->cValues); - aRow->cValues = sPropTagArray->cValues; - for (count = 0; count < sPropTagArray->cValues; count++) - { - tag = sPropTagArray->aulPropTag[count]; - propValue = data[count].data; - propRc = data[count].error; - // propName = get_proptag_name (tag); - // if (!propName) - // propName = ""; - // [self logWithFormat: @" lookup of property %s (%.8x) returned %d", - // propName, tag, propRc]; - - if (propRc == MAPI_E_SUCCESS && !propValue) - { - propName = get_proptag_name (tag); - if (!propName) - propName = ""; - [self errorWithFormat: @"both 'success' and NULL data" - @" returned for proptag %s(0x%.8x)", - propName, tag]; - propRc = MAPI_E_NOT_FOUND; - } - - if (propRc != MAPI_E_SUCCESS) - { - if (propRc == MAPISTORE_ERR_NOT_FOUND) - propRc = MAPI_E_NOT_FOUND; - // else if (propRc == MAPISTORE_ERR_NO_MEMORY) - // propRc = MAPI_E_NOT_ENOUGH_MEMORY; - if (propValue) - talloc_free (propValue); - propValue = MAPILongValue (memCtx, propRc); - tag = (tag & 0xffff0000) | 0x000a; - } - set_SPropValue_proptag (aRow->lpProps + count, tag, propValue); - } - } - talloc_free (data); - } - else - { - [self errorWithFormat: @"no message/folder found for fmid %lld", fmid]; - abort(); - rc = MAPI_E_INVALID_OBJECT; - } - - return rc; -} - - (int) getPath: (char **) path ofFMID: (uint64_t) fmid - withTableType: (uint8_t) tableType inMemCtx: (TALLOC_CTX *) memCtx { int rc; @@ -846,140 +341,15 @@ _prepareContextClass (struct mapistore_context *newMemCtx, return rc; } -- (int) setPropertiesWithFMID: (uint64_t) fmid - ofTableType: (uint8_t) tableType - inRow: (struct SRow *) aRow +- (int) getRootFolder: (MAPIStoreFolder **) folderPtr + withFID: (uint64_t) newFid { - MAPIStoreFolder *folder; - NSNumber *fidKey; - int rc; + if (![mapping urlFromID: newFid]) + [mapping registerURL: [contextUrl absoluteString] + withID: newFid]; + *folderPtr = baseFolder; - [self logWithFormat: @"METHOD '%s' -- fid: 0x%.16x, tableType: %d", - __FUNCTION__, fmid, tableType]; - - fidKey = [NSNumber numberWithUnsignedLongLong: fmid]; - switch (tableType) - { - case MAPISTORE_FOLDER: - folder = [folders objectForKey: fidKey]; - if (folder) - rc = [folder setProperties: aRow]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - break; - default: - [self errorWithFormat: @"%s: value of tableType not handled: %d", - __FUNCTION__, tableType]; - [NSException raise: @"MAPIStoreIOException" - format: @"unsupported object type"]; - rc = MAPISTORE_ERROR; - } - - return rc; -} - -- (int) deleteMessageWithMID: (uint64_t) mid - inFID: (uint64_t) fid - withFlags: (uint8_t) flags -{ - NSString *childURL, *childKey; - NSNumber *fidKey; - MAPIStoreFolder *folder; - MAPIStoreMessage *message; - NSArray *activeTables; - NSUInteger count, max; - struct mapistore_object_notification_parameters *notif_parameters; - int rc; - - [self logWithFormat: @"-deleteMessageWithMID: mid: 0x%.16x flags: %d", mid, flags]; - - childURL = [mapping urlFromID: mid]; - if (childURL) - { - [self logWithFormat: @"-deleteMessageWithMID: url (%@) found for object", childURL]; - - childKey = [self extractChildNameFromURL: childURL - andFolderURLAt: NULL]; - - fidKey = [NSNumber numberWithUnsignedLongLong: fid]; - folder = [folders objectForKey: fidKey]; - - message = [folder lookupChild: childKey]; - if (message) - { - /* we ensure the table caches are loaded so that old and new state - can be compared */ - /* we ensure the table caches are loaded so that old and new state - can be compared */ - activeTables = ([message isKindOfClass: MAPIStoreFAIMessageK] - ? [folder activeFAIMessageTables] - : [folder activeMessageTables]); - max = [activeTables count]; - for (count = 0; count < max; count++) - [[activeTables objectAtIndex: count] restrictedChildKeys]; - - if ([[message sogoObject] delete]) - { - rc = MAPISTORE_ERROR; - [self logWithFormat: @"ERROR deleting object at URL: %@", childURL]; - } - else - { - if (![message isNew]) - { - /* folder notification */ - notif_parameters - = talloc_zero(NULL, - struct mapistore_object_notification_parameters); - notif_parameters->object_id = fid; - notif_parameters->tag_count = 5; - notif_parameters->tags = talloc_array (notif_parameters, - enum MAPITAGS, 5); - notif_parameters->tags[0] = PR_CONTENT_COUNT; - notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL; - notif_parameters->tags[2] = PR_MESSAGE_SIZE; - notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE; - notif_parameters->tags[4] = PR_DELETED_MSG_COUNT; - notif_parameters->new_message_count = true; - notif_parameters->message_count = [[folder messageKeys] - count] - 1; - mapistore_push_notification (connInfo->mstore_ctx, - MAPISTORE_FOLDER, - MAPISTORE_OBJECT_MODIFIED, - notif_parameters); - talloc_free(notif_parameters); - - /* message notification */ - notif_parameters - = talloc_zero(NULL, - struct mapistore_object_notification_parameters); - notif_parameters->object_id = mid; - notif_parameters->folder_id = fid; - /* Exchange sends a fnevObjectCreated!! */ - mapistore_push_notification (connInfo->mstore_ctx, - MAPISTORE_MESSAGE, - MAPISTORE_OBJECT_CREATED, - notif_parameters); - talloc_free(notif_parameters); - - /* table notification */ - for (count = 0; count < max; count++) - [[activeTables objectAtIndex: count] - notifyChangesForChild: message]; - } - [self logWithFormat: @"successfully deleted object at URL: %@", childURL]; - [mapping unregisterURLWithID: mid]; - [folder cleanupCaches]; - rc = MAPISTORE_SUCCESS; - } - } - else - rc = MAPI_E_INVALID_OBJECT; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; + return (baseFolder) ? MAPISTORE_SUCCESS: MAPISTORE_ERROR; } /* utils */ @@ -1016,6 +386,7 @@ _prepareContextClass (struct mapistore_context *newMemCtx, NSString *childURL; uint64_t mappingId; uint32_t contextId; + void *rootObject; if (key) childURL = [NSString stringWithFormat: @"%@%@", folderURL, key]; @@ -1029,30 +400,13 @@ _prepareContextClass (struct mapistore_context *newMemCtx, [mapping registerURL: childURL withID: mappingId]; contextId = 0; mapistore_search_context_by_uri (mstoreCtx, [folderURL UTF8String] + 7, - &contextId); + &contextId, &rootObject); mapistore_indexing_record_add_mid (mstoreCtx, contextId, mappingId); } return mappingId; } -/* proof of concept */ -- (int) getTable: (MAPIStoreTable **) tablePtr - andRowCount: (uint32_t *) countPtr - withFID: (uint64_t) fid - tableType: (uint8_t) tableType - andHandleId: (uint32_t) handleId -{ - MAPIStoreTable *table; - - table = [self _tableForFID: fid andTableType: tableType]; - [table setHandleId: handleId]; - *countPtr = [[table childKeys] count]; - *tablePtr = table; - - return MAPISTORE_SUCCESS; -} - /* subclasses */ + (NSString *) MAPIModuleName diff --git a/OpenChange/MAPIStoreFolder.h b/OpenChange/MAPIStoreFolder.h index 4f663441f..3185ef1a3 100644 --- a/OpenChange/MAPIStoreFolder.h +++ b/OpenChange/MAPIStoreFolder.h @@ -62,6 +62,11 @@ - (id) initWithURL: (NSURL *) newURL inContext: (MAPIStoreContext *) newContext; +- (id) lookupFolder: (NSString *) folderKey; +- (id) lookupFolderByURL: (NSString *) folderURL; +- (id) lookupMessage: (NSString *) messageKey; +- (id) lookupMessageByURL: (NSString *) messageURL; + - (NSArray *) activeMessageTables; - (NSArray *) activeFAIMessageTables; @@ -78,6 +83,32 @@ - (NSString *) createFolder: (struct SRow *) aRow withFID: (uint64_t) newFID; +/* backend interface */ + +- (int) openFolder: (MAPIStoreFolder **) childFolderPtr + withFID: (uint64_t) fid; +- (int) createFolder: (MAPIStoreFolder **) childFolderPtr + withRow: (struct SRow *) aRow + andFID: (uint64_t) fid; +- (int) deleteFolderWithFID: (uint64_t) fid; +- (int) getChildCount: (uint32_t *) rowCount + ofTableType: (uint8_t) tableType; + +- (int) createMessage: (MAPIStoreMessage **) messagePtr + withMID: (uint64_t) mid + isAssociated: (BOOL) isAssociated; +- (int) openMessage: (MAPIStoreMessage **) messagePtr + andMessageData: (struct mapistore_message **) dataPtr + withMID: (uint64_t) mid + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) deleteMessageWithMID: (uint64_t) mid + andFlags: (uint8_t) flags; + +- (int) getTable: (MAPIStoreTable **) tablePtr + andRowCount: (uint32_t *) count + tableType: (uint8_t) tableType + andHandleId: (uint32_t) handleId; + /* helpers */ - (uint64_t) idForObjectWithKey: (NSString *) childKey; diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index 3d9e9c660..83fa33b4f 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -35,6 +35,8 @@ #import "MAPIStoreFAIMessage.h" #import "MAPIStoreFAIMessageTable.h" #import "MAPIStoreFolder.h" +#import "MAPIStoreFolderTable.h" +#import "MAPIStoreMapping.h" #import "MAPIStoreMessage.h" #import "MAPIStoreTypes.h" #import "NSDate+MAPIStore.h" @@ -50,13 +52,14 @@ #include #include -Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStoreFolderTableK; +Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStoreFolderTableK; @implementation MAPIStoreFolder + (void) initialize { NSExceptionK = [NSException class]; + MAPIStoreFAIMessageTableK = [MAPIStoreFAIMessage class]; MAPIStoreMessageTableK = [MAPIStoreMessageTable class]; MAPIStoreFAIMessageTableK = [MAPIStoreFAIMessageTable class]; MAPIStoreFolderTableK = [MAPIStoreFolderTable class]; @@ -135,6 +138,388 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore return self; } +/* backend interface */ +- (id) lookupFolder: (NSString *) folderKey +{ + MAPIStoreFolder *childFolder = nil; + SOGoFolder *sogoFolder; + + if ([[self folderKeys] containsObject: folderKey]) + { + sogoFolder = [sogoObject lookupName: folderKey + inContext: nil + acquire: NO]; + if (sogoFolder && ![sogoFolder isKindOfClass: NSExceptionK]) + childFolder = [isa mapiStoreObjectWithSOGoObject: sogoFolder + inContainer: self]; + } + + return childFolder; +} + +- (id) lookupFolderByURL: (NSString *) childURL +{ + MAPIStoreObject *foundObject = nil; + NSString *baseURL, *subURL; + NSArray *parts; + NSUInteger partsCount; + + baseURL = [self url]; + if (![baseURL hasSuffix: @"/"]) + baseURL = [NSString stringWithFormat: @"%@/", baseURL]; + if ([childURL hasPrefix: baseURL]) + { + subURL = [childURL substringFromIndex: [baseURL length]]; + if ([subURL length] > 0) + { + parts = [subURL componentsSeparatedByString: @"/"]; + partsCount = [parts count]; + if ((partsCount == 1) + || (partsCount == 2 && [[parts objectAtIndex: 1] length] == 0)) + foundObject = [self lookupFolder: [parts objectAtIndex: 0]]; + } + } + + return foundObject; +} + +- (id) lookupMessage: (NSString *) messageKey +{ + MAPIStoreObject *childMessage = nil; + SOGoObject *msgObject; + + if (messageKey) + { + [self faiMessageKeys]; + if ([faiMessageKeys containsObject: messageKey]) + { + msgObject = [faiFolder lookupName: messageKey + inContext: nil + acquire: NO]; + childMessage + = [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: msgObject + inContainer: self]; + } + else + { + msgObject = [sogoObject lookupName: messageKey + inContext: nil + acquire: NO]; + if (msgObject && ![msgObject isKindOfClass: NSExceptionK]) + childMessage + = [[self messageClass] mapiStoreObjectWithSOGoObject: msgObject + inContainer: self]; + } + } + + return childMessage; +} + +- (id) lookupMessageByURL: (NSString *) childURL +{ + MAPIStoreObject *foundObject = nil; + NSString *baseURL, *subURL; + NSArray *parts; + NSUInteger partsCount; + + baseURL = [self url]; + if (![baseURL hasSuffix: @"/"]) + baseURL = [NSString stringWithFormat: @"%@/", baseURL]; + if ([childURL hasPrefix: baseURL]) + { + subURL = [childURL substringFromIndex: [baseURL length]]; + if ([subURL length] > 0) + { + parts = [subURL componentsSeparatedByString: @"/"]; + partsCount = [parts count]; + if (partsCount == 1) + foundObject = [self lookupMessage: [parts objectAtIndex: 0]]; + } + } + + return foundObject; +} + +- (int) openFolder: (MAPIStoreFolder **) childFolderPtr + withFID: (uint64_t) fid +{ + int rc = MAPISTORE_ERR_NOT_FOUND; + MAPIStoreFolder *childFolder; + MAPIStoreMapping *mapping; + NSString *childURL; + + [self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__]; + + mapping = [[self context] mapping]; + childURL = [mapping urlFromID: fid]; + if (childURL) + { + childFolder = [self lookupFolderByURL: childURL]; + if (childFolder) + { + *childFolderPtr = childFolder; + rc = MAPISTORE_SUCCESS; + } + } + + return rc; +} + +- (int) createFolder: (MAPIStoreFolder **) childFolderPtr + withRow: (struct SRow *) aRow + andFID: (uint64_t) fid +{ + int rc; + MAPIStoreMapping *mapping; + NSString *baseURL, *childURL, *folderKey; + MAPIStoreFolder *childFolder; + + [self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__]; + + mapping = [[self context] mapping]; + childURL = [mapping urlFromID: fid]; + if (childURL) + rc = MAPISTORE_ERR_EXIST; + else + { + folderKey = [self createFolder: aRow withFID: fid]; + if (folderKey) + { + [self cleanupCaches]; + baseURL = [self url]; + if (![baseURL hasSuffix: @"/"]) + baseURL = [NSString stringWithFormat: @"%@/", baseURL]; + childURL = [NSString stringWithFormat: @"%@%@", + baseURL, folderKey]; + [mapping registerURL: childURL withID: fid]; + childFolder = [self lookupFolder: folderKey]; + if (childFolder) + [childFolder setProperties: aRow]; + else + [NSException raise: @"MAPIStoreIOException" + format: @"unable to fetch created folder"]; + rc = MAPISTORE_SUCCESS; + } + else + rc = MAPISTORE_ERROR; + } + + return rc; +} + +- (int) deleteFolderWithFID: (uint64_t) fid +{ + [self logWithFormat: @"UNIMPLEMENTED METHOD '%s' (%d)", __FUNCTION__, __LINE__]; + + return MAPISTORE_ERROR; +} + +- (int) getChildCount: (uint32_t *) rowCount + ofTableType: (uint8_t) tableType +{ + NSArray *keys; + int rc; + + [self logWithFormat: @"METHOD '%s' (%d) -- tableType: %d", + __FUNCTION__, __LINE__, tableType]; + + if (tableType == MAPISTORE_MESSAGE_TABLE) + keys = [self messageKeys]; + else if (tableType == MAPISTORE_FOLDER_TABLE) + keys = [self folderKeys]; + else if (tableType == MAPISTORE_FAI_TABLE) + keys = [self faiMessageKeys]; + *rowCount = [keys count]; + rc = MAPI_E_SUCCESS; + + return rc; +} + +- (int) openMessage: (MAPIStoreMessage **) messagePtr + andMessageData: (struct mapistore_message **) dataPtr + withMID: (uint64_t) mid + inMemCtx: (TALLOC_CTX *) memCtx; +{ + NSString *messageURL; + MAPIStoreMapping *mapping; + MAPIStoreMessage *message; + int rc = MAPISTORE_ERR_NOT_FOUND; + + mapping = [[self context] mapping]; + messageURL = [mapping urlFromID: mid]; + if (messageURL) + { + message = [self lookupMessageByURL: messageURL]; + if (message) + { + [message getMessageData: dataPtr inMemCtx: memCtx]; + *messagePtr = message; + rc = MAPISTORE_SUCCESS; + } + } + + return rc; +} + +- (int) createMessage: (MAPIStoreMessage **) messagePtr + withMID: (uint64_t) mid + isAssociated: (BOOL) isAssociated +{ + int rc; + MAPIStoreMessage *message; + NSString *baseURL, *childURL; + MAPIStoreMapping *mapping; + + [self logWithFormat: @"METHOD '%s' -- mid: 0x%.16x, associated: %d", + __FUNCTION__, mid, isAssociated]; + + mapping = [[self context] mapping]; + if ([mapping urlFromID: mid]) + rc = MAPISTORE_ERR_EXIST; + else + { + message = [self createMessage: isAssociated]; + if (message) + { + baseURL = [self url]; + if (![baseURL hasSuffix: @"/"]) + baseURL = [NSString stringWithFormat: @"%@/", baseURL]; + childURL = [NSString stringWithFormat: @"%@%@", + baseURL, [message nameInContainer]]; + [mapping registerURL: childURL withID: mid]; + *messagePtr = message; + rc = MAPISTORE_SUCCESS; + } + else + rc = MAPISTORE_ERROR; + } + + return rc; +} + +- (int) deleteMessageWithMID: (uint64_t) mid + andFlags: (uint8_t) flags +{ + NSString *childURL; + MAPIStoreMapping *mapping; + MAPIStoreMessage *message; + NSArray *activeTables; + NSUInteger count, max; + struct mapistore_connection_info *connInfo; + struct mapistore_object_notification_parameters *notif_parameters; + int rc; + + [self logWithFormat: @"-deleteMessageWithMID: mid: 0x%.16x flags: %d", mid, flags]; + + mapping = [[self context] mapping]; + childURL = [mapping urlFromID: mid]; + if (childURL) + { + message = [self lookupMessageByURL: childURL]; + if (message) + { + /* we ensure the table caches are loaded so that old and new state + can be compared */ + /* we ensure the table caches are loaded so that old and new state + can be compared */ + activeTables = ([message isKindOfClass: MAPIStoreFAIMessageK] + ? [self activeFAIMessageTables] + : [self activeMessageTables]); + max = [activeTables count]; + for (count = 0; count < max; count++) + [[activeTables objectAtIndex: count] restrictedChildKeys]; + + if ([[message sogoObject] delete]) + { + rc = MAPISTORE_ERROR; + [self logWithFormat: @"ERROR deleting object at URL: %@", childURL]; + } + else + { + if (![message isNew]) + { + /* folder notification */ + notif_parameters + = talloc_zero(NULL, + struct mapistore_object_notification_parameters); + notif_parameters->object_id = [self objectId]; + notif_parameters->tag_count = 5; + notif_parameters->tags = talloc_array (notif_parameters, + enum MAPITAGS, 5); + notif_parameters->tags[0] = PR_CONTENT_COUNT; + notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL; + notif_parameters->tags[2] = PR_MESSAGE_SIZE; + notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE; + notif_parameters->tags[4] = PR_DELETED_MSG_COUNT; + notif_parameters->new_message_count = true; + notif_parameters->message_count = [[self messageKeys] + count] - 1; + connInfo = [[self context] connectionInfo]; + mapistore_push_notification (connInfo->mstore_ctx, + MAPISTORE_FOLDER, + MAPISTORE_OBJECT_MODIFIED, + notif_parameters); + talloc_free(notif_parameters); + + /* message notification */ + notif_parameters + = talloc_zero(NULL, + struct mapistore_object_notification_parameters); + notif_parameters->object_id = mid; + notif_parameters->folder_id = [self objectId]; + /* Exchange sends a fnevObjectCreated!! */ + mapistore_push_notification (connInfo->mstore_ctx, + MAPISTORE_MESSAGE, + MAPISTORE_OBJECT_CREATED, + notif_parameters); + talloc_free(notif_parameters); + + /* table notification */ + for (count = 0; count < max; count++) + [[activeTables objectAtIndex: count] + notifyChangesForChild: message]; + } + [self logWithFormat: @"successfully deleted object at URL: %@", childURL]; + [mapping unregisterURLWithID: mid]; + [self cleanupCaches]; + rc = MAPISTORE_SUCCESS; + } + } + else + rc = MAPI_E_INVALID_OBJECT; + } + else + rc = MAPISTORE_ERR_NOT_FOUND; + + return rc; +} + +- (int) getTable: (MAPIStoreTable **) tablePtr + andRowCount: (uint32_t *) countPtr + tableType: (uint8_t) tableType + andHandleId: (uint32_t) handleId +{ + MAPIStoreTable *table; + + if (tableType == MAPISTORE_MESSAGE_TABLE) + table = [self messageTable]; + else if (tableType == MAPISTORE_FAI_TABLE) + table = [self faiMessageTable]; + else if (tableType == MAPISTORE_FOLDER_TABLE) + table = [self folderTable]; + else + { + table = nil; + [NSException raise: @"MAPIStoreIOException" + format: @"unsupported table type: %d", tableType]; + } + [table setHandleId: handleId]; + *tablePtr = table; + *countPtr = [[table childKeys] count]; + + return MAPISTORE_SUCCESS; +} + - (int) setProperties: (struct SRow *) aRow { static enum MAPITAGS bannedProps[] = { PR_MID, PR_FID, PR_PARENT_FID, @@ -266,41 +651,7 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore - (id) lookupChild: (NSString *) childKey { - MAPIStoreObject *newChild; - SOGoObject *msgObject; - - if (childKey) - { - [self faiMessageKeys]; - if ([faiMessageKeys containsObject: childKey]) - { - msgObject = [faiFolder lookupName: childKey - inContext: nil - acquire: NO]; - newChild - = [MAPIStoreFAIMessage mapiStoreObjectWithSOGoObject: msgObject - inContainer: self]; - } - else - { - msgObject = [sogoObject lookupName: childKey - inContext: nil - acquire: NO]; - if ([msgObject isKindOfClass: NSExceptionK]) - msgObject = nil; - - if (msgObject) - newChild - = [[self messageClass] mapiStoreObjectWithSOGoObject: msgObject - inContainer: self]; - else - newChild = nil; - } - } - else - newChild = nil; - - return newChild; + return [self lookupMessage: childKey]; } - (int) getPrParentFid: (void **) data @@ -436,8 +787,8 @@ Class NSExceptionK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStore newKey = [NSString stringWithFormat: @"%@.plist", [SOGoObject globallyUniqueObjectId]]; fsObject = [SOGoMAPIFSMessage objectWithName: newKey inContainer: faiFolder]; - newMessage = [MAPIStoreFAIMessage mapiStoreObjectWithSOGoObject: fsObject - inContainer: self]; + newMessage = [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: fsObject + inContainer: self]; return newMessage; diff --git a/OpenChange/MAPIStoreSOGo.h b/OpenChange/MAPIStoreSOGo.h deleted file mode 100644 index 1fae02c8c..000000000 --- a/OpenChange/MAPIStoreSOGo.h +++ /dev/null @@ -1,37 +0,0 @@ -/* MAPIStoreSOGo.h - this file is part of SOGo - * - * Copyright (C) 2010 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#ifndef __MAPISTORE_SOGO_H -#define __MAPISTORE_SOGO_H - -@class MAPIStoreContext; - -typedef struct { - MAPIStoreContext *objcContext; -} sogo_context; - -__BEGIN_DECLS - -int mapistore_init_backend(void); - -__END_DECLS - -#endif /* !__MAPISTORE_SOGO_H */ diff --git a/OpenChange/MAPIStoreSOGo.m b/OpenChange/MAPIStoreSOGo.m index de44c50e1..784af8741 100644 --- a/OpenChange/MAPIStoreSOGo.m +++ b/OpenChange/MAPIStoreSOGo.m @@ -34,13 +34,12 @@ #import "MAPIStoreAttachment.h" #import "MAPIStoreContext.h" #import "MAPIStoreDraftsMessage.h" +#import "MAPIStoreFolder.h" #import "MAPIStoreMessage.h" #import "MAPIStoreObject.h" #import "MAPIStoreTable.h" #import "NSObject+MAPIStore.h" -#import "MAPIStoreSOGo.h" - #undef DEBUG #include #include @@ -101,13 +100,11 @@ sogo_backend_init (void) static int sogo_backend_create_context(TALLOC_CTX *mem_ctx, struct mapistore_connection_info *conn_info, - const char *uri, uint64_t fid, - void **private_data) + const char *uri, void **context_object) { NSAutoreleasePool *pool; - sogo_context *cContext; Class MAPIStoreContextK; - id context; + MAPIStoreContext *context; int rc; DEBUG(0, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); @@ -117,18 +114,11 @@ sogo_backend_create_context(TALLOC_CTX *mem_ctx, MAPIStoreContextK = NSClassFromString (@"MAPIStoreContext"); if (MAPIStoreContextK) { - context = [MAPIStoreContextK contextFromURI: uri - withConnectionInfo: conn_info - andFID: fid - inMemCtx: mem_ctx]; - [context retain]; - - cContext = talloc_zero(mem_ctx, sogo_context); - cContext->objcContext = context; - - *private_data = cContext; - - rc = MAPISTORE_SUCCESS; + rc = [MAPIStoreContextK openContext: &context + withURI: uri + andConnectionInfo: conn_info]; + if (rc == MAPISTORE_SUCCESS) + *context_object = [context tallocWrapper: mem_ctx]; } else rc = MAPISTORE_ERROR; @@ -138,6 +128,10 @@ sogo_backend_create_context(TALLOC_CTX *mem_ctx, return rc; } +// andFID: fid +// uint64_t fid, +// void **private_data) + /** \details return the mapistore path associated to a given message or folder ID @@ -150,27 +144,60 @@ sogo_backend_create_context(TALLOC_CTX *mem_ctx, \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ static int -sogo_backend_get_path(void *private_data, TALLOC_CTX *mem_ctx, - uint64_t fmid, uint8_t type, char **path) +sogo_context_get_path(void *backend_object, TALLOC_CTX *mem_ctx, + uint64_t fmid, char **path) { + struct MAPIStoreTallocWrapper *wrapper; NSAutoreleasePool *pool; - sogo_context *cContext; MAPIStoreContext *context; int rc; DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); - pool = [NSAutoreleasePool new]; + if (backend_object) + { + wrapper = backend_object; + context = wrapper->MAPIStoreSOGoObject; + pool = [NSAutoreleasePool new]; + rc = [context getPath: path ofFMID: fmid inMemCtx: mem_ctx]; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); + rc = MAPI_E_NOT_FOUND; + } - cContext = private_data; - context = cContext->objcContext; - [context setupRequest]; + return rc; +} - rc = [context getPath: path ofFMID: fmid withTableType: type inMemCtx: mem_ctx]; +static int +sogo_context_get_root_folder(void *backend_object, TALLOC_CTX *mem_ctx, + uint64_t fid, void **folder_object) +{ + struct MAPIStoreTallocWrapper *wrapper; + NSAutoreleasePool *pool; + MAPIStoreContext *context; + MAPIStoreFolder *folder; + int rc; - [context tearDownRequest]; + DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); - [pool release]; + if (backend_object) + { + wrapper = backend_object; + context = wrapper->MAPIStoreSOGoObject; + pool = [NSAutoreleasePool new]; + rc = [context getRootFolder: &folder withFID: fid]; + if (rc == MAPISTORE_SUCCESS) + *folder_object = [folder tallocWrapper: mem_ctx]; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); + rc = MAPI_E_NOT_FOUND; + } return rc; } @@ -185,25 +212,31 @@ sogo_backend_get_path(void *private_data, TALLOC_CTX *mem_ctx, \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ static int -sogo_folder_open_folder(void *private_data, uint64_t fid) +sogo_folder_open_folder(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t fid, void **childfolder_object) { + struct MAPIStoreTallocWrapper *wrapper; NSAutoreleasePool *pool; - sogo_context *cContext; - MAPIStoreContext *context; + MAPIStoreFolder *folder, *childFolder; int rc; DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); - pool = [NSAutoreleasePool new]; - - cContext = private_data; - context = cContext->objcContext; - [context setupRequest]; - - rc = [context openDir: fid]; - - [context tearDownRequest]; - [pool release]; + if (folder_object) + { + wrapper = folder_object; + folder = wrapper->MAPIStoreSOGoObject; + pool = [NSAutoreleasePool new]; + rc = [folder openFolder: &childFolder withFID: fid]; + if (rc == MAPISTORE_SUCCESS) + *childfolder_object = [childFolder tallocWrapper: mem_ctx]; + // [context tearDownRequest]; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); + rc = MAPI_E_NOT_FOUND; + } return rc; } @@ -216,26 +249,32 @@ sogo_folder_open_folder(void *private_data, uint64_t fid) \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ static int -sogo_folder_create_folder(void *private_data, uint64_t parent_fid, uint64_t fid, - struct SRow *aRow) +sogo_folder_create_folder(void *folder_object, TALLOC_CTX *mem_ctx, + uint64_t fid, struct SRow *aRow, + void **childfolder_object) { + struct MAPIStoreTallocWrapper *wrapper; NSAutoreleasePool *pool; - sogo_context *cContext; - MAPIStoreContext *context; + MAPIStoreFolder *folder, *childFolder; int rc; DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); - pool = [NSAutoreleasePool new]; - - cContext = private_data; - context = cContext->objcContext; - [context setupRequest]; - - rc = [context mkDir: aRow withFID: fid inParentFID: parent_fid]; - - [context tearDownRequest]; - [pool release]; + if (folder_object) + { + wrapper = folder_object; + folder = wrapper->MAPIStoreSOGoObject; + pool = [NSAutoreleasePool new]; + rc = [folder createFolder: &childFolder withRow: aRow andFID: fid]; + if (rc == MAPISTORE_SUCCESS) + *childfolder_object = [childFolder tallocWrapper: mem_ctx]; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); + rc = MAPI_E_NOT_FOUND; + } return rc; } @@ -250,194 +289,184 @@ sogo_folder_create_folder(void *private_data, uint64_t parent_fid, uint64_t fid, \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ static int -sogo_folder_delete_folder(void *private_data, uint64_t parent_fid, uint64_t fid) +sogo_folder_delete_folder(void *folder_object, uint64_t fid) { + struct MAPIStoreTallocWrapper *wrapper; NSAutoreleasePool *pool; - sogo_context *cContext; - MAPIStoreContext *context; + MAPIStoreFolder *folder; int rc; DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); - pool = [NSAutoreleasePool new]; - - cContext = private_data; - context = cContext->objcContext; - [context setupRequest]; - - rc = [context rmDirWithFID: fid inParentFID: parent_fid]; - - [context tearDownRequest]; - [pool release]; - - return rc; -} - -/** - \details Read directory content from the sogo backend - - \param private_data pointer to the current sogo context - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR -*/ -static int -sogo_folder_get_child_count(void *private_data, - uint64_t fid, - uint8_t table_type, - uint32_t *RowCount) -{ - 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; - [context setupRequest]; - - rc = [context readCount: RowCount ofTableType: table_type inFID: fid]; - - [context tearDownRequest]; - [pool release]; + if (folder_object) + { + wrapper = folder_object; + folder = wrapper->MAPIStoreSOGoObject; + pool = [NSAutoreleasePool new]; + rc = [folder deleteFolderWithFID: fid]; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); + rc = MAPI_E_NOT_FOUND; + } return rc; } static int -sogo_folder_create_message(void *private_data, - TALLOC_CTX *mem_ctx, - uint64_t fid, - uint64_t mid, - uint8_t associated, - void **message_object) +sogo_folder_get_child_count(void *folder_object, uint8_t table_type, uint32_t *child_count) { + struct MAPIStoreTallocWrapper *wrapper; NSAutoreleasePool *pool; - sogo_context *cContext; - MAPIStoreContext *context; - MAPIStoreMessage *message; + MAPIStoreFolder *folder; int rc; DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); - pool = [NSAutoreleasePool new]; - - cContext = private_data; - context = cContext->objcContext; - [context setupRequest]; - - rc = [context createMessage: &message - withMID: mid inFID: fid - isAssociated: associated]; - if (!rc) - *message_object = [message tallocWrapper: mem_ctx]; - - [context tearDownRequest]; - [pool release]; + if (folder_object) + { + wrapper = folder_object; + folder = wrapper->MAPIStoreSOGoObject; + pool = [NSAutoreleasePool new]; + rc = [folder getChildCount: child_count ofTableType: table_type]; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); + rc = MAPI_E_NOT_FOUND; + } return rc; } static int -sogo_folder_open_message(void *private_data, +sogo_folder_open_message(void *folder_object, TALLOC_CTX *mem_ctx, - uint64_t fid, uint64_t mid, void **message_object, struct mapistore_message **msgp) { + struct MAPIStoreTallocWrapper *wrapper; NSAutoreleasePool *pool; - sogo_context *cContext; - MAPIStoreContext *context; + MAPIStoreFolder *folder; MAPIStoreMessage *message; int rc; DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); - pool = [NSAutoreleasePool new]; - - cContext = private_data; - context = cContext->objcContext; - [context setupRequest]; - - if (!context) - DEBUG (5, (" context data is empty, failure ahead...")); - rc = [context openMessage: &message andMessageData: msgp withMID: mid inFID: fid inMemCtx: mem_ctx]; - if (rc) - DEBUG (5, (" failure opening message\n")); + if (folder_object) + { + wrapper = folder_object; + folder = wrapper->MAPIStoreSOGoObject; + pool = [NSAutoreleasePool new]; + rc = [folder openMessage: &message andMessageData: msgp withMID: mid inMemCtx: mem_ctx]; + if (rc == MAPISTORE_SUCCESS) + *message_object = [message tallocWrapper: mem_ctx]; + [pool release]; + } else - *message_object = [message tallocWrapper: mem_ctx]; - - [context tearDownRequest]; - [pool release]; + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); + rc = MAPI_E_NOT_FOUND; + } return rc; } static int -sogo_folder_delete_message(void *private_data, - uint64_t fid, +sogo_folder_create_message(void *folder_object, + TALLOC_CTX *mem_ctx, uint64_t mid, - uint8_t flags) + uint8_t associated, + void **message_object) { + struct MAPIStoreTallocWrapper *wrapper; NSAutoreleasePool *pool; - sogo_context *cContext; - MAPIStoreContext *context; + MAPIStoreFolder *folder; + MAPIStoreMessage *message; int rc; DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); - pool = [NSAutoreleasePool new]; - - cContext = private_data; - context = cContext->objcContext; - [context setupRequest]; - - rc = [context deleteMessageWithMID: mid inFID: fid withFlags: flags]; - - [context tearDownRequest]; - [pool release]; + if (folder_object) + { + wrapper = folder_object; + folder = wrapper->MAPIStoreSOGoObject; + pool = [NSAutoreleasePool new]; + rc = [folder createMessage: &message + withMID: mid isAssociated: associated]; + if (rc == MAPISTORE_SUCCESS) + *message_object = [message tallocWrapper: mem_ctx]; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); + rc = MAPI_E_NOT_FOUND; + } return rc; } static int -sogo_folder_open_table(void *private_data, TALLOC_CTX *mem_ctx, - uint64_t fid, uint8_t table_type, - uint32_t handle_id, +sogo_folder_delete_message(void *folder_object, uint64_t mid, uint8_t flags) +{ + struct MAPIStoreTallocWrapper *wrapper; + NSAutoreleasePool *pool; + MAPIStoreFolder *folder; + int rc; + + DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); + + if (folder_object) + { + wrapper = folder_object; + folder = wrapper->MAPIStoreSOGoObject; + pool = [NSAutoreleasePool new]; + rc = [folder deleteMessageWithMID: mid andFlags: flags]; + [pool release]; + } + else + { + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); + rc = MAPI_E_NOT_FOUND; + } + + return rc; +} + +static int +sogo_folder_open_table(void *folder_object, TALLOC_CTX *mem_ctx, + uint8_t table_type, uint32_t handle_id, void **table_object, uint32_t *row_count) { + struct MAPIStoreTallocWrapper *wrapper; NSAutoreleasePool *pool; - sogo_context *cContext; - MAPIStoreContext *context; + MAPIStoreFolder *folder; MAPIStoreTable *table; int rc; DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); - pool = [NSAutoreleasePool new]; - - cContext = private_data; - context = cContext->objcContext; - if (context) + if (folder_object) { - [context setupRequest]; - rc = [context getTable: &table - andRowCount: row_count - withFID: fid - tableType: table_type - andHandleId: handle_id]; + wrapper = folder_object; + folder = wrapper->MAPIStoreSOGoObject; + pool = [NSAutoreleasePool new]; + rc = [folder getTable: &table + andRowCount: row_count + tableType: table_type + andHandleId: handle_id]; if (rc == MAPISTORE_SUCCESS) *table_object = [table tallocWrapper: mem_ctx]; - [context tearDownRequest]; [pool release]; } else { - NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO CONTEXT"); + NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); rc = MAPI_E_NOT_FOUND; } @@ -896,68 +925,6 @@ sogo_properties_set_properties (void *object, struct SRow *aRow) return rc; } -/* obsolete */ -static int -sogo_getprops(void *private_data, - TALLOC_CTX *mem_ctx, - uint64_t fmid, - uint8_t type, - struct SPropTagArray *SPropTagArray, - struct SRow *aRow) -{ - 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; - [context setupRequest]; - - rc = [context getProperties: SPropTagArray - ofTableType: type - inRow: aRow - withMID: fmid - inMemCtx: mem_ctx]; - - [context tearDownRequest]; - [pool release]; - - return rc; -} - - -static int -sogo_setprops(void *private_data, - uint64_t fmid, - uint8_t type, - struct SRow *aRow) -{ - 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; - [context setupRequest]; - - rc = [context setPropertiesWithFMID: fmid ofTableType: type inRow: aRow]; - - [context tearDownRequest]; - [pool release]; - - return rc; -} - /** \details Entry point for mapistore SOGO backend @@ -975,16 +942,14 @@ int mapistore_init_backend(void) { registered = YES; - backend.setprops = sogo_setprops; - backend.getprops = sogo_getprops; - /* Fill in our name */ backend.backend.name = "SOGo"; backend.backend.description = "mapistore SOGo backend"; backend.backend.namespace = "sogo://"; backend.backend.init = sogo_backend_init; backend.backend.create_context = sogo_backend_create_context; - backend.backend.get_path = sogo_backend_get_path; + backend.context.get_path = sogo_context_get_path; + backend.context.get_root_folder = sogo_context_get_root_folder; backend.folder.open_folder = sogo_folder_open_folder; backend.folder.create_folder = sogo_folder_create_folder; backend.folder.delete_folder = sogo_folder_delete_folder;