From 8cbe8f862ed7a49b11a0bf20eb3aba66d4d5a6f1 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 3 Feb 2012 14:55:19 +0000 Subject: [PATCH 1/5] Monotone-Parent: 638f19a902b772b34bc553dda4b8925b5d0639df Monotone-Revision: 599ccb5bc0882492dab453f5e9af28f0342e6a87 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-02-03T14:55:19 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 5 +++++ SoObjects/Mailer/SOGoMailFolder.h | 2 ++ SoObjects/Mailer/SOGoMailFolder.m | 13 +++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index a2ba604f4..e40b7f3cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2012-02-03 Wolfgang Sourdeau + + * SoObjects/Mailer/SOGoMailFolder.m (-exists): new method that + returns whether an IMAP folder exists or not yet. + 2012-02-01 Wolfgang Sourdeau * OpenChange/MAPIStoreUserContext.m (-destroy): dont't release diff --git a/SoObjects/Mailer/SOGoMailFolder.h b/SoObjects/Mailer/SOGoMailFolder.h index f1a9e15cd..98bc94c85 100644 --- a/SoObjects/Mailer/SOGoMailFolder.h +++ b/SoObjects/Mailer/SOGoMailFolder.h @@ -82,6 +82,8 @@ - (void) markForExpunge; - (void) expungeLastMarkedFolder; +- (BOOL) exists; + - (BOOL) create; - (NSException *) expunge; diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m index 03e7b9b15..87cece7d8 100644 --- a/SoObjects/Mailer/SOGoMailFolder.m +++ b/SoObjects/Mailer/SOGoMailFolder.m @@ -248,7 +248,7 @@ static NSString *defaultUserID = @"anyone"; if (!filenames) { filenames = [NSMutableArray new]; - if ([[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]]) + if ([self exists]) { uids = [self fetchUIDsMatchingQualifier: nil sortOrdering: @"DATE"]; if (![uids isKindOfClass: [NSException class]]) @@ -555,7 +555,7 @@ static NSString *defaultUserID = @"anyone"; NSString *archiveName; EOQualifier *notDeleted; - if ([[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]]) + if ([self exists]) { notDeleted = [EOQualifier qualifierWithQualifierFormat: @"(not (flags = %@))", @"deleted"]; @@ -722,7 +722,7 @@ static NSString *defaultUserID = @"anyone"; { // We check for the existence of the IMAP folder (likely to be the // Sent mailbox) prior to appending messages to it. - if ([[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]] + if ([self exists] || ![[self imap4Connection] createMailbox: [[self imap4Connection] imap4FolderNameForURL: [self imap4URL]] atURL: [[self mailAccountFolder] imap4URL]]) return [[self imap4Connection] postData: _data flags: _flags @@ -835,7 +835,7 @@ static NSString *defaultUserID = @"anyone"; inContainer: self]; } else if (isdigit ([_key characterAtIndex: 0]) - && [[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]]) + && [self exists]) { obj = [SOGoMailObject objectWithName: _key inContainer: self]; if ([_key hasSuffix: @".eml"]) @@ -863,6 +863,11 @@ static NSString *defaultUserID = @"anyone"; return [[self imap4Connection] createMailbox:_name atURL:[self imap4URL]]; } +- (BOOL) exists +{ + return [[self imap4Connection] doesMailboxExistAtURL: [self imap4URL]]; +} + - (BOOL) create { NSException *error; From dff90f588acbbba5b23aad46dd448452639d60d2 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 3 Feb 2012 14:58:33 +0000 Subject: [PATCH 2/5] Monotone-Parent: 599ccb5bc0882492dab453f5e9af28f0342e6a87 Monotone-Revision: aff6a2cc9b4208ab638ccf2f17af6bb0874f5f5b Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-02-03T14:58:33 Monotone-Branch: ca.inverse.sogo --- OpenChange/MAPIStoreCalendarContext.m | 2 +- OpenChange/MAPIStoreContactsContext.m | 2 +- OpenChange/MAPIStoreGCSBaseContext.m | 7 +------ OpenChange/MAPIStoreTasksContext.m | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/OpenChange/MAPIStoreCalendarContext.m b/OpenChange/MAPIStoreCalendarContext.m index 9e02b19a4..16018ce85 100644 --- a/OpenChange/MAPIStoreCalendarContext.m +++ b/OpenChange/MAPIStoreCalendarContext.m @@ -46,7 +46,7 @@ static Class MAPIStoreCalendarFolderK; return @"calendar"; } -+ (enum mapistore_context_role) MAPIModuleRole ++ (enum mapistore_context_role) MAPIContextRole { return MAPISTORE_CALENDAR_ROLE; } diff --git a/OpenChange/MAPIStoreContactsContext.m b/OpenChange/MAPIStoreContactsContext.m index 831ca0538..967b1ccd3 100644 --- a/OpenChange/MAPIStoreContactsContext.m +++ b/OpenChange/MAPIStoreContactsContext.m @@ -46,7 +46,7 @@ static Class MAPIStoreContactsFolderK; return @"contacts"; } -+ (enum mapistore_context_role) MAPIModuleRole ++ (enum mapistore_context_role) MAPIContextRole { return MAPISTORE_CONTACTS_ROLE; } diff --git a/OpenChange/MAPIStoreGCSBaseContext.m b/OpenChange/MAPIStoreGCSBaseContext.m index d155200bd..5b8344f1c 100644 --- a/OpenChange/MAPIStoreGCSBaseContext.m +++ b/OpenChange/MAPIStoreGCSBaseContext.m @@ -43,11 +43,6 @@ return nil; } -+ (enum mapistore_context_role) MAPIModuleRole -{ - return -1; -} - + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx @@ -83,7 +78,7 @@ context->name = [[currentFolder displayName] asUnicodeInMemCtx: context]; context->main_folder = [nameInContainer isEqualToString: @"personal"]; - context->role = [self MAPIModuleRole]; + context->role = [self MAPIContextRole]; context->tag = "tag"; DLIST_ADD_END (firstContext, context, void); } diff --git a/OpenChange/MAPIStoreTasksContext.m b/OpenChange/MAPIStoreTasksContext.m index cf95fb736..c8714c469 100644 --- a/OpenChange/MAPIStoreTasksContext.m +++ b/OpenChange/MAPIStoreTasksContext.m @@ -45,7 +45,7 @@ static Class MAPIStoreTasksFolderK; return @"tasks"; } -+ (enum mapistore_context_role) MAPIModuleRole ++ (enum mapistore_context_role) MAPIContextRole { return MAPISTORE_TASKS_ROLE; } From 3bf138283b88e8ae61a25ec8b4a58a8db8fb3982 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 3 Feb 2012 15:01:23 +0000 Subject: [PATCH 3/5] Monotone-Parent: aff6a2cc9b4208ab638ccf2f17af6bb0874f5f5b Monotone-Revision: 425bfc2f774ffc6abc9a76908ac1b2fcf7d6ad14 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-02-03T15:01:23 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 2 ++ OpenChange/MAPIStoreMailFolder.m | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/ChangeLog b/ChangeLog index e40b7f3cb..3a3077043 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2012-02-03 Wolfgang Sourdeau + * OpenChange/MAPIStoreMailFolder.m (-deleteFolder): overriden method. + * SoObjects/Mailer/SOGoMailFolder.m (-exists): new method that returns whether an IMAP folder exists or not yet. diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 0541c6beb..a5e3483bd 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -158,6 +158,32 @@ static Class SOGoMailFolderK; return nameInContainer; } +- (int) deleteFolder +{ + int rc; + NSException *error; + NSString *name; + + name = [self nameInContainer]; + if ([name isEqualToString: @"folderINBOX"]) + rc = MAPISTORE_ERR_DENIED; + else + { + error = [(SOGoMailFolder *) sogoObject delete]; + if (error) + rc = MAPISTORE_ERROR; + else + { + if (![versionsMessage delete]) + rc = MAPISTORE_SUCCESS; + else + rc = MAPISTORE_ERROR; + } + } + + return (rc == MAPISTORE_SUCCESS) ? [super deleteFolder] : rc; +} + - (int) getPrContentUnread: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { From d64c7164d72a03da3e3acbdd97740e2100418bc8 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 3 Feb 2012 15:05:19 +0000 Subject: [PATCH 4/5] Monotone-Parent: 425bfc2f774ffc6abc9a76908ac1b2fcf7d6ad14 Monotone-Revision: 82a617e3ad7bb1a96e181c9d1c240bc2c89de7f7 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-02-03T15:05:19 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 4 ++++ OpenChange/MAPIStoreFSFolder.m | 12 ++++++------ OpenChange/MAPIStoreFolder.h | 5 +++-- OpenChange/MAPIStoreFolder.m | 13 ++++++------- OpenChange/MAPIStoreMailFolder.m | 16 +++++++++++----- 5 files changed, 30 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a3077043..3e1e4651e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2012-02-03 Wolfgang Sourdeau + * OpenChange/MAPIStoreFolder.m (-createFolder:withFID:andKey:): + modified method to return a enum mapistore_error, in order to + better determine of the failures that occur. + * OpenChange/MAPIStoreMailFolder.m (-deleteFolder): overriden method. * SoObjects/Mailer/SOGoMailFolder.m (-exists): new method that diff --git a/OpenChange/MAPIStoreFSFolder.m b/OpenChange/MAPIStoreFSFolder.m index 684ab5a7b..145781383 100644 --- a/OpenChange/MAPIStoreFSFolder.m +++ b/OpenChange/MAPIStoreFSFolder.m @@ -42,9 +42,7 @@ #undef DEBUG #include -// #include -// #include -// #include +#include static Class EOKeyValueQualifierK; @@ -75,8 +73,9 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact"; return [MAPIStoreFSFolderTable tableForContainer: self]; } -- (NSString *) createFolder: (struct SRow *) aRow - withFID: (uint64_t) newFID +- (enum mapistore_error) createFolder: (struct SRow *) aRow + withFID: (uint64_t) newFID + andKey: (NSString **) newKeyP { NSString *newKey, *urlString; NSURL *childURL; @@ -89,8 +88,9 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact"; childFolder = [SOGoMAPIFSFolder folderWithURL: childURL andTableType: MAPISTORE_MESSAGE_TABLE]; [childFolder ensureDirectory]; + *newKeyP = newKey; - return newKey; + return MAPISTORE_SUCCESS; } - (MAPIStoreMessage *) createMessage diff --git a/OpenChange/MAPIStoreFolder.h b/OpenChange/MAPIStoreFolder.h index 178bb36fd..b327e8d6d 100644 --- a/OpenChange/MAPIStoreFolder.h +++ b/OpenChange/MAPIStoreFolder.h @@ -145,8 +145,9 @@ andCN: (NSNumber **) cnNbr inTableType: (enum mapistore_table_type) tableType; -- (NSString *) createFolder: (struct SRow *) aRow - withFID: (uint64_t) newFID; +- (enum mapistore_error) createFolder: (struct SRow *) aRow + withFID: (uint64_t) newFID + andKey: (NSString **) newKeyP; - (NSCalendarDate *) lastMessageModificationTime; diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index 20670225d..912c766a6 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -354,8 +354,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe rc = MAPISTORE_ERR_EXIST; else { - folderKey = [self createFolder: aRow withFID: fid]; - if (folderKey) + rc = [self createFolder: aRow withFID: fid andKey: &folderKey]; + if (rc == MAPISTORE_SUCCESS) { [self cleanupCaches]; baseURL = [self url]; @@ -374,8 +374,6 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe [NSException raise: @"MAPIStoreIOException" format: @"unable to fetch created folder"]; } - else - rc = MAPISTORE_ERROR; } } else @@ -1299,12 +1297,13 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe return newMessage; } -- (NSString *) createFolder: (struct SRow *) aRow - withFID: (uint64_t) newFID +- (enum mapistore_error) createFolder: (struct SRow *) aRow + withFID: (uint64_t) newFID + andKey: (NSString **) newKeyP { [self errorWithFormat: @"new folders cannot be created in this context"]; - return nil; + return MAPISTORE_ERR_DENIED; } /* helpers */ diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index a5e3483bd..cd5c40371 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -127,9 +127,11 @@ static Class SOGoMailFolderK; return [MAPIStoreMailMessageTable tableForContainer: self]; } -- (NSString *) createFolder: (struct SRow *) aRow - withFID: (uint64_t) newFID +- (enum mapistore_error) createFolder: (struct SRow *) aRow + withFID: (uint64_t) newFID + andKey: (NSString **) newKeyP { + enum mapistore_error rc; NSString *folderName, *nameInContainer; SOGoMailFolder *newFolder; int i; @@ -151,11 +153,15 @@ static Class SOGoMailFolderK; [folderName asCSSIdentifier]]; newFolder = [SOGoMailFolderK objectWithName: nameInContainer inContainer: sogoObject]; - if (![newFolder create]) - nameInContainer = nil; + if ([newFolder create]) + *newKeyP = nameInContainer; + else if ([newFolder exists]) + rc = MAPISTORE_ERR_EXIST; + else + rc = MAPISTORE_ERR_DENIED; } - return nameInContainer; + return rc; } - (int) deleteFolder From f1a3bdd884004ef6262f02509de7650383dcd3b7 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 3 Feb 2012 15:05:55 +0000 Subject: [PATCH 5/5] Monotone-Parent: 82a617e3ad7bb1a96e181c9d1c240bc2c89de7f7 Monotone-Revision: fdb9e758160f3e3509c45bb379d9169a3eb0118a Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-02-03T15:05:55 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 3 + OpenChange/MAPIStoreContext.h | 12 ++++ OpenChange/MAPIStoreContext.m | 85 ++++++++++++++++++++++++++- OpenChange/MAPIStoreFallbackContext.m | 19 +++++- OpenChange/MAPIStoreGCSBaseContext.m | 24 ++++++++ OpenChange/MAPIStoreMailContext.m | 37 +++++++++++- OpenChange/MAPIStoreSOGo.m | 39 ++++++++++++ 7 files changed, 213 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3e1e4651e..e578ce025 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2012-02-03 Wolfgang Sourdeau + * OpenChange/MAPIStoreSOGo.m (sogo_backend_create_root_folder): + new backend method. + * OpenChange/MAPIStoreFolder.m (-createFolder:withFID:andKey:): modified method to return a enum mapistore_error, in order to better determine of the failures that occur. diff --git a/OpenChange/MAPIStoreContext.h b/OpenChange/MAPIStoreContext.h index 1ff8dc609..3d41985ad 100644 --- a/OpenChange/MAPIStoreContext.h +++ b/OpenChange/MAPIStoreContext.h @@ -68,6 +68,12 @@ + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx; ++ (enum mapistore_error) createRootFolder: (NSString **) mapistoreUriP + withFID: (uint64_t ) fid + andName: (NSString *) folderName + forUser: (NSString *) username + withRole: (enum mapistore_context_role) role + andTDBIndexing: (struct tdb_wrap *) indexingTdb; + (int) openContext: (MAPIStoreContext **) contextPtr withURI: (const char *) newUri @@ -104,6 +110,12 @@ /* subclass methods */ + (NSString *) MAPIModuleName; ++ (enum mapistore_context_role) MAPIContextRole; ++ (NSString *) + createRootSecondaryFolderWithFID: (uint64_t) fid + andName: (NSString *) folderName + forUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb; - (Class) MAPIStoreFolderClass; /* the top-most parent of the context folder: SOGoMailAccount, diff --git a/OpenChange/MAPIStoreContext.m b/OpenChange/MAPIStoreContext.m index 921aaafef..376e5e63b 100644 --- a/OpenChange/MAPIStoreContext.m +++ b/OpenChange/MAPIStoreContext.m @@ -35,6 +35,7 @@ #import "MAPIStoreAttachment.h" // #import "MAPIStoreAttachmentTable.h" +#import "MAPIStoreFallbackContext.h" #import "MAPIStoreFolder.h" #import "MAPIStoreFolderTable.h" #import "MAPIStoreMapping.h" @@ -66,7 +67,7 @@ /* sogo://username:password@{contacts,calendar,tasks,journal,notes,mail}/dossier/id */ -static Class NSExceptionK; +static Class NSExceptionK, MAPIStoreFallbackContextK; static NSMutableDictionary *contextClassMapping; @@ -89,11 +90,13 @@ static NSMutableDictionary *contextClassMapping; if (moduleName) { [contextClassMapping setObject: currentClass - forKey: moduleName]; + forKey: moduleName]; NSLog (@" registered class '%@' as handler of '%@' contexts", NSStringFromClass (currentClass), moduleName); } } + + MAPIStoreFallbackContextK = [MAPIStoreFallbackContext class]; } + (struct mapistore_contexts_list *) listAllContextsForUser: (NSString *) userName @@ -127,13 +130,73 @@ static NSMutableDictionary *contextClassMapping; return list; } -+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName ++ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx { return NULL; } +static Class +MAPIStoreLookupContextClassByRole (Class self, enum mapistore_context_role role) +{ + static NSMutableDictionary *classMapping = nil; + Class currentClass; + enum mapistore_context_role classRole; + NSNumber *roleNbr; + NSArray *classes; + NSUInteger count, max; + + if (!classMapping) + { + classMapping = [NSMutableDictionary new]; + classes = GSObjCAllSubclassesOfClass (self); + max = [classes count]; + for (count = 0; count < max; count++) + { + currentClass = [classes objectAtIndex: count]; + classRole = [currentClass MAPIContextRole]; + if (classRole != -1) + { + roleNbr = [NSNumber numberWithUnsignedInt: classRole]; + [classMapping setObject: currentClass + forKey: roleNbr]; + } + } + } + + roleNbr = [NSNumber numberWithUnsignedInt: role]; + + return [classMapping objectForKey: roleNbr]; +} + ++ (enum mapistore_error) createRootFolder: (NSString **) mapistoreUriP + withFID: (uint64_t) fid + andName: (NSString *) folderName + forUser: (NSString *) userName + withRole: (enum mapistore_context_role) role + andTDBIndexing: (struct tdb_wrap *) indexingTdb +{ + Class contextClass; + NSString *mapistoreURI; + enum mapistore_error rc = MAPISTORE_SUCCESS; + + contextClass = MAPIStoreLookupContextClassByRole (self, role); + if (!contextClass) + contextClass = MAPIStoreFallbackContextK; + + mapistoreURI = [contextClass createRootSecondaryFolderWithFID: fid + andName: (NSString *) folderName + forUser: userName + withTDBIndexing: indexingTdb]; + if (mapistoreURI) + *mapistoreUriP = mapistoreURI; + else + rc = MAPISTORE_ERROR; + + return rc; +} + static inline NSURL *CompleteURLFromMapistoreURI (const char *uri) { NSString *urlString; @@ -474,6 +537,22 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri) return nil; } ++ (enum mapistore_context_role) MAPIContextRole +{ + return -1; +} + ++ (NSString *) + createRootSecondaryFolderWithFID: (uint64_t) fid + andName: (NSString *) folderName + forUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb +{ + [self subclassResponsibility: _cmd]; + + return nil; +} + - (Class) MAPIStoreFolderClass { [self subclassResponsibility: _cmd]; diff --git a/OpenChange/MAPIStoreFallbackContext.m b/OpenChange/MAPIStoreFallbackContext.m index c234e1f84..c3ff666bb 100644 --- a/OpenChange/MAPIStoreFallbackContext.m +++ b/OpenChange/MAPIStoreFallbackContext.m @@ -24,10 +24,12 @@ #import #import -#import "MAPIStoreFallbackContext.h" +#import "MAPIStoreUserContext.h" #import "NSString+MAPIStore.h" #import "SOGoMAPIFSFolder.h" +#import "MAPIStoreFallbackContext.h" + #undef DEBUG #include @@ -38,6 +40,11 @@ return @"fallback"; } ++ (enum mapistore_context_role) MAPIContextRole +{ + return MAPISTORE_MAIL_ROLE; +} + + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx @@ -82,4 +89,14 @@ return firstContext; } ++ (NSString *) + createRootSecondaryFolderWithFID: (uint64_t) fid + andName: (NSString *) folderName + forUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb +{ + return [NSString stringWithFormat: @"sogo://%@@fallback/0x%.16"PRIx64"/", + userName, (unsigned long long) fid]; +} + @end diff --git a/OpenChange/MAPIStoreGCSBaseContext.m b/OpenChange/MAPIStoreGCSBaseContext.m index 5b8344f1c..a8e552e9c 100644 --- a/OpenChange/MAPIStoreGCSBaseContext.m +++ b/OpenChange/MAPIStoreGCSBaseContext.m @@ -88,6 +88,30 @@ return firstContext; } ++ (NSString *) + createRootSecondaryFolderWithFID: (uint64_t) fid + andName: (NSString *) folderName + forUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb +{ + NSString *mapistoreURI, *nameInContainer, *moduleName; + MAPIStoreUserContext *userContext; + SOGoParentFolder *parentFolder; + + userContext = [MAPIStoreUserContext userContextWithUsername: userName + andTDBIndexing: indexingTdb]; + moduleName = [self MAPIModuleName]; + parentFolder = [[userContext rootFolders] objectForKey: moduleName]; + if (![parentFolder newFolderWithName: folderName + nameInContainer: &nameInContainer]) + mapistoreURI = [NSString stringWithFormat: @"sogo://%@@%@/%@/", + userName, moduleName, nameInContainer]; + else + mapistoreURI = nil; + + return mapistoreURI; +} + - (id) rootSOGoFolder { return [[userContext rootFolders] objectForKey: [isa MAPIModuleName]]; diff --git a/OpenChange/MAPIStoreMailContext.m b/OpenChange/MAPIStoreMailContext.m index 58825e166..84d4c935a 100644 --- a/OpenChange/MAPIStoreMailContext.m +++ b/OpenChange/MAPIStoreMailContext.m @@ -31,6 +31,7 @@ #import "MAPIStoreUserContext.h" #import "NSString+MAPIStore.h" +#import #import "MAPIStoreMailContext.h" #include @@ -51,6 +52,11 @@ static Class MAPIStoreMailFolderK; return @"mail"; } ++ (enum mapistore_context_role) MAPIContextRole +{ + return MAPISTORE_MAIL_ROLE; +} + + (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName withTDBIndexing: (struct tdb_wrap *) indexingTdb inMemCtx: (TALLOC_CTX *) memCtx @@ -93,7 +99,7 @@ static Class MAPIStoreMailFolderK; folderName[count]]; context->url = [stringData asUnicodeInMemCtx: context]; /* remove "folder" prefix */ - stringData = [folderName[count] substringFromIndex: 6]; + stringData = [[folderName[count] substringFromIndex: 6] fromCSSIdentifier]; context->name = [stringData asUnicodeInMemCtx: context]; context->main_folder = true; context->role = role[count]; @@ -116,7 +122,7 @@ static Class MAPIStoreMailFolderK; currentName = [secondaryFolders objectAtIndex: count]; stringData = [NSString stringWithFormat: @"%@%@", urlBase, currentName]; context->url = [stringData asUnicodeInMemCtx: context]; - stringData = [currentName substringFromIndex: 6]; + stringData = [[currentName substringFromIndex: 6] fromCSSIdentifier]; context->name = [stringData asUnicodeInMemCtx: context]; context->main_folder = false; context->role = MAPISTORE_MAIL_ROLE; @@ -127,6 +133,33 @@ static Class MAPIStoreMailFolderK; return firstContext; } ++ (NSString *) + createRootSecondaryFolderWithFID: (uint64_t) fid + andName: (NSString *) newFolderName + forUser: (NSString *) userName + withTDBIndexing: (struct tdb_wrap *) indexingTdb +{ + NSString *mapistoreURI, *folderName; + MAPIStoreUserContext *userContext; + SOGoMailAccount *accountFolder; + SOGoMailFolder *newFolder; + + userContext = [MAPIStoreUserContext userContextWithUsername: userName + andTDBIndexing: indexingTdb]; + accountFolder = [[userContext rootFolders] objectForKey: @"mail"]; + folderName = [NSString stringWithFormat: @"folder%@", + [newFolderName asCSSIdentifier]]; + newFolder = [SOGoMailFolder objectWithName: folderName + inContainer: accountFolder]; + if ([newFolder create]) + mapistoreURI = [NSString stringWithFormat: @"sogo://%@:%@@mail/%@/", + userName, userName, folderName]; + else + mapistoreURI = nil; + + return mapistoreURI; +} + - (Class) MAPIStoreFolderClass { return MAPIStoreMailFolderK; diff --git a/OpenChange/MAPIStoreSOGo.m b/OpenChange/MAPIStoreSOGo.m index 1c8bc75a9..7f6767eb6 100644 --- a/OpenChange/MAPIStoreSOGo.m +++ b/OpenChange/MAPIStoreSOGo.m @@ -42,6 +42,7 @@ #import "MAPIStoreObject.h" #import "MAPIStoreTable.h" #import "NSObject+MAPIStore.h" +#import "NSString+MAPIStore.h" #include #include @@ -147,6 +148,43 @@ sogo_backend_create_context(TALLOC_CTX *mem_ctx, return rc; } +static enum mapistore_error +sogo_backend_create_root_folder (const char *username, + enum mapistore_context_role role, + uint64_t fid, const char *name, + struct tdb_wrap *indexingTdb, + TALLOC_CTX *mem_ctx, char **mapistore_urip) +{ + NSAutoreleasePool *pool; + NSString *userName, *folderName; + NSString *mapistoreUri; + int rc; + + DEBUG(0, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__)); + + pool = [NSAutoreleasePool new]; + + if (MAPIStoreContextK) + { + userName = [NSString stringWithUTF8String: username]; + folderName = [NSString stringWithUTF8String: name]; + rc = [MAPIStoreContextK createRootFolder: &mapistoreUri + withFID: fid + andName: folderName + forUser: userName + withRole: role + andTDBIndexing: indexingTdb]; + if (rc == MAPISTORE_SUCCESS) + *mapistore_urip = [mapistoreUri asUnicodeInMemCtx: mem_ctx]; + } + else + rc = MAPISTORE_ERROR; + + [pool release]; + + return rc; +} + static enum mapistore_error sogo_backend_list_contexts(const char *username, struct tdb_wrap *indexingTdb, TALLOC_CTX *mem_ctx, @@ -1239,6 +1277,7 @@ int mapistore_init_backend(void) backend.backend.namespace = "sogo://"; backend.backend.init = sogo_backend_init; backend.backend.create_context = sogo_backend_create_context; + backend.backend.create_root_folder = sogo_backend_create_root_folder; backend.backend.list_contexts = sogo_backend_list_contexts; backend.context.get_path = sogo_context_get_path; backend.context.get_root_folder = sogo_context_get_root_folder;