fixed crashes, refactored the context class in subclasses, started AB functionality
authorwsourdeau <wsourdeau@71d39326-ef09-db11-b2a4-00e04c779ad1>
Sat, 25 Sep 2010 01:26:14 +0000 (01:26 +0000)
committerwsourdeau <wsourdeau@71d39326-ef09-db11-b2a4-00e04c779ad1>
Sat, 25 Sep 2010 01:26:14 +0000 (01:26 +0000)
git-svn-id: https://svn.openchange.org/openchange@2175 71d39326-ef09-db11-b2a4-00e04c779ad1

12 files changed:
branches/sogo/configure.ac
branches/sogo/mapiproxy/libmapistore/backends/mapistore_sogo/MAPIApplication.m
branches/sogo/mapiproxy/libmapistore/backends/mapistore_sogo/MAPIStoreAuthenticator.h
branches/sogo/mapiproxy/libmapistore/backends/mapistore_sogo/MAPIStoreAuthenticator.m
branches/sogo/mapiproxy/libmapistore/backends/mapistore_sogo/MAPIStoreContext.h
branches/sogo/mapiproxy/libmapistore/backends/mapistore_sogo/MAPIStoreContext.m
branches/sogo/mapiproxy/libmapistore/backends/mapistore_sogo/MAPIStoreMapping.m
branches/sogo/mapiproxy/servers/default/emsmdb/oxcmsg.c
branches/sogo/ndr_mapi.c
branches/sogo/pyopenchange/tests/mapistore_test.py
branches/sogo/pyopenchange/tests/sogo_readdir.py
branches/sogo/script/installsamba4.sh

index 64902ef66c27e4a257c0564fd3599f295ec704ce..a9a4d13fc6ed547f9be57bd184ed9ae7c9ebd2f9 100644 (file)
@@ -228,7 +228,7 @@ dnl Sun Studio Compiler
     LDFLAGS="$LDFLAGS -z ignore -R '\$\$ORIGIN/../lib'"
 elif test x"$ac_cv_c_compiler_icc" = x"yes"; then
 dnl Intel Compiler
-    COMPILER_OPTIONS_SHARED="-O3 -Wall -g3 -fstrict-aliasing -Wmissing-prototypes -Wstrict-prototypes -wd2259,188,593,869,981,181,1419,2218"
+    COMPILER_OPTIONS_SHARED="-O0 -Wall -g3 -fstrict-aliasing -Wmissing-prototypes -Wstrict-prototypes -wd2259,188,593,869,981,181,1419,2218"
     COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED"
     COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_SHARED"
 else
@@ -237,7 +237,7 @@ dnl GNU Compiler
     if test "x$use_cov" = "xyes"; then
         COMPILER_OPTIONS_SHARED="-O0 $COMPILER_OPTIONS_SHARED"
     else
-        COMPILER_OPTIONS_SHARED="-O3 $COMPILER_OPTIONS_SHARED"
+        COMPILER_OPTIONS_SHARED="-O0 $COMPILER_OPTIONS_SHARED"
     fi
     COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED -Wmissing-prototypes -Wstrict-prototypes"
     if test "x$use_cov" = "xyes"; then
index 8176dc57744d65835966ec8ceccac5f7fa9279f6..92744e3f7984211a82aa54a5722e7128dc4d8594 100644 (file)
 
 MAPIApplication *MAPIApp = nil;
 
+@interface UnixSignalHandler : NSObject
+
++ sharedHandler;
+
+- (void)removeObserver:(id)observer;
+
+@end
+
 @implementation MAPIApplication
 
 - (id) init
@@ -68,6 +76,11 @@ MAPIApplication *MAPIApp = nil;
 
                 MAPIApp = [super init];
                 [MAPIApp retain];
+
+                /* This is a hack to revert what is done in [WOCoreApplication
+                   init] */
+                [[NSClassFromString(@"UnixSignalHandler") sharedHandler]
+                  removeObserver: self];
         }
 
         return MAPIApp;
index 8339e0569e1dbdb6b874a17c4ba4f5c77f96b235..eda741095b7834a1e5b8809a5b245af1c600c6e6 100644 (file)
@@ -36,6 +36,8 @@
 }
 
 - (void) setUsername: (NSString *) newUsername;
+- (NSString *) username;
+
 - (void) setPassword: (NSString *) newPassword;
 
 - (NSString *) imapPasswordInContext: (WOContext *) context
index 9c23d4a55665dd547513f67934259a88a386fd75..ffb1937e8908e6d1c3bfef989b5e4f4257f62393 100644 (file)
         ASSIGN (username, newUsername);
 }
 
+- (NSString *) username
+{
+  return username;
+}
+
 - (void) setPassword: (NSString *) newPassword
 {
         ASSIGN (password, newPassword);
index 58ef14cc74a10c3f128d66644403ff6881e1b4ab..260d036d421f5801d41efca000fba6cee3d8e4fc 100644 (file)
 @class WOContext;
 
 @class SOGoFolder;
+@class SOGoObject;
+
+@class MAPIStoreAuthenticator;
 
 @interface MAPIStoreContext : NSObject
 {
-        NSString *uri;
         NSMutableDictionary *objectCache;
+        MAPIStoreAuthenticator *authenticator;
         WOContext *woContext;
         NSMutableDictionary *messageCache;
         NSMutableDictionary *subfolderCache;
+        SOGoFolder *moduleFolder;
         void *memCtx;
 }
 
-- (void) setURI: (const char *) newUri;
+- (void) setupModuleFolder;
+
 - (void) setMemCtx: (void *) newMemCtx;
-- (id) authenticator;
+
+- (void) setAuthenticator: (MAPIStoreAuthenticator *) newAuthenticator;
+- (MAPIStoreAuthenticator *) authenticator;
+
+- (void) setupRequest;
+- (void) tearDownRequest;
 
 @end
 
index 46902b11d96cc3021b73e800759f3c043532b3c1..28ec8b38428aa991dedffb7e9f4a58b27eec8664 100644 (file)
 @interface SOGoObject (MAPIStoreProtocol)
 
 - (NSString *) davContentLength;
-- (NSString *) decodedSubject;
+
+@end
+
+@interface MAPIStoreMailContext : MAPIStoreContext
+
+@end
+
+@interface MAPIStoreContactsContext : MAPIStoreContext
 
 @end
 
 
 /* sogo://username:password@{contacts,calendar,tasks,journal,notes,mail}/dossier/id */
 
+Class NSNullK;
 Class SOGoMailAccountsK, SOGoMailAccountK, SOGoMailFolderK, SOGoUserFolderK, SOGoObjectK;
 static MAPIStoreMapping *mapping = nil;
 
 + (void) initialize
 {
+        NSNullK = NSClassFromString (@"NSNull");
+
         SOGoMailAccountsK = NSClassFromString (@"SOGoMailAccounts");
         SOGoMailAccountK = NSClassFromString (@"SOGoMailAccount");
         SOGoMailFolderK = NSClassFromString (@"SOGoMailFolder");
         SOGoUserFolderK = NSClassFromString (@"SOGoUserFolder");
         SOGoObjectK = NSClassFromString (@"SOGoObject");
+
         mapping = [MAPIStoreMapping new];
 }
 
 + (id) contextFromURI: (const char *) newUri
 {
         MAPIStoreContext *context;
+        MAPIStoreAuthenticator *authenticator;
+        NSString *contextClass, *module, *completeURLString, *urlString;
+        NSURL *baseURL;
 
        NSLog (@"METHOD '%s' (%d) -- uri: '%s'", __FUNCTION__, __LINE__, newUri);
 
-        context = [self new];
-        [context setURI: newUri];
-        [context autorelease];
+        context = nil;
+
+        urlString = [NSString stringWithUTF8String: newUri];
+        if (urlString) {
+                completeURLString = [@"sogo://" stringByAppendingString: urlString];
+                baseURL = [NSURL URLWithString: completeURLString];
+                if (baseURL) {
+                        module = [baseURL host];
+                        if (module) {
+                                if ([module isEqualToString: @"mail"])
+                                        contextClass = @"MAPIStoreMailContext";
+                                else if ([module isEqualToString: @"contacts"])
+                                        contextClass = @"MAPIStoreContactsContext";
+                                else {
+                                        NSLog (@"ERROR: unrecognized module name '%@'", module);
+                                        contextClass = nil;
+                                }
+                                
+                                if (contextClass) {
+                                        [mapping registerURL: completeURLString];
+                                        context = [NSClassFromString (contextClass) new];
+                                        [context autorelease];
+
+                                        authenticator = [MAPIStoreAuthenticator new];
+                                        [authenticator setUsername: [baseURL user]];
+                                        [authenticator setPassword: [baseURL password]];
+                                        [context setAuthenticator: authenticator];
+                                        [authenticator release];
+
+                                        [context setupRequest];
+                                        [context setupModuleFolder];
+                                        [context tearDownRequest];
+                                }
+                        }
+                }
+                else
+                        NSLog (@"ERROR: url could not be parsed");
+        }
+        else
+                NSLog (@"ERROR: url is an invalid UTF-8 string");
 
         return context;
 }
@@ -91,12 +142,12 @@ static MAPIStoreMapping *mapping = nil;
 - (id) init
 {
         if ((self = [super init])) {
-                uri = nil;
-                objectCache = [NSMutableDictionary new];
+                // objectCache = [NSMutableDictionary new];
                 messageCache = [NSMutableDictionary new];
                 subfolderCache = [NSMutableDictionary new];
                 woContext = [WOContext contextWithRequest: nil];
                 [woContext retain];
+                moduleFolder = nil;
         }
 
         [self logWithFormat: @"-init"];
@@ -107,39 +158,25 @@ static MAPIStoreMapping *mapping = nil;
 - (void) dealloc
 {
         [self logWithFormat: @"-dealloc"];
-        [uri release];
-        [objectCache release];
+
+        // [objectCache release];
         [messageCache release];
         [subfolderCache release];
+
+        [moduleFolder release];
         [woContext release];
+        [authenticator release];
         [super dealloc];
 }
 
-- (id) authenticator
+- (void) setAuthenticator: (MAPIStoreAuthenticator *) newAuthenticator
 {
-        MAPIStoreAuthenticator *authenticator;
-        NSURL *url;
-
-        url = [NSURL URLWithString: uri];
-        if (!url)
-                [self errorWithFormat: @"url string gave nil NSURL: '%@'", uri];
-
-        authenticator = [MAPIStoreAuthenticator new];
-        [authenticator setUsername: [url user]];
-        [authenticator setPassword: [url password]];
-        [authenticator autorelease];
-
-        return authenticator;
+        ASSIGN (authenticator, newAuthenticator);
 }
 
-- (void) setURI: (const char *) newUri
+- (MAPIStoreAuthenticator *) authenticator
 {
-        uri = [NSString stringWithFormat: @"sogo://%@",
-                        [NSString stringWithCString: newUri
-                                           encoding: NSUTF8StringEncoding]];
-        [uri retain];
-
-        [mapping registerURL: uri];
+        return authenticator;
 }
 
 - (void) setMemCtx: (void *) newMemCtx
@@ -165,38 +202,9 @@ static MAPIStoreMapping *mapping = nil;
         [MAPIApp setMAPIStoreContext: nil];
 }
 
-- (id) _moduleFromURL: (NSURL *) moduleURL
+- (void) setupModuleFolder
 {
-        id userFolder, moduleFolder, accountsFolder;
-        NSString *userName, *mapiModule;
-
-        userName = [moduleURL user];
-        userFolder = [objectCache objectForKey: userName];
-        if (!userFolder) {
-                userFolder = [SOGoUserFolderK objectWithName: userName
-                                                 inContainer: MAPIApp];
-                /* Potential crash here as the username might be invalid and
-                 * unknown from SOGo and hence the userFolder be nil. */
-                [objectCache setObject: userFolder forKey: userName];
-                [woContext setClientObject: userFolder];
-        }
-
-        mapiModule = [moduleURL host];
-        if ([mapiModule isEqualToString: @"mail"]) {
-                accountsFolder = [userFolder lookupName: @"Mail"
-                                              inContext: woContext
-                                                acquire: NO];
-                moduleFolder = [accountsFolder lookupName: @"0"
-                                                inContext: woContext
-                                                  acquire: NO];
-        }
-        else {
-                [self errorWithFormat: @"module name not handled: '%@'",
-                      mapiModule];
-                moduleFolder = nil;
-        }
-
-        return moduleFolder;
+        [self subclassResponsibility: _cmd];
 }
 
 - (id) _lookupObject: (NSString *) objectURLString
@@ -212,7 +220,7 @@ static MAPIStoreMapping *mapping = nil;
         objectURL = [NSURL URLWithString: objectURLString];
         if (!objectURL)
                 [self errorWithFormat: @"url string gave nil NSURL: '%@'", objectURLString];
-        object = [self _moduleFromURL: objectURL];
+        object = moduleFolder;
         
         pathString = [objectURL path];
         if ([pathString hasPrefix: @"/"])
@@ -221,23 +229,31 @@ static MAPIStoreMapping *mapping = nil;
                 path = [pathString componentsSeparatedByString: @"/"];
                 max = [path count];
                 if (max > 0) {
-                        for (count = 0; count < max; count++) {
+                        for (count = 0;
+                             object && count < max;
+                             count++) {
                                 nameInContainer = [[path objectAtIndex: count]
                                                           stringByUnescapingURL];
                                 object = [object lookupName: nameInContainer
                                                   inContext: woContext
                                                     acquire: NO];
-                                [woContext setClientObject: object];
+                                if ([object isKindOfClass: SOGoObjectK])
+                                        [woContext setClientObject: object];
+                                else
+                                        object = nil;
                         }
                 }
-        }
-        if (object && [object isKindOfClass: SOGoObjectK])
-                [objectCache setObject: object
-                                forKey: objectURLString];
-        else {
+        } else
                 object = nil;
-                [woContext setClientObject: nil];
-        }
+
+        [woContext setClientObject: object];
+        // if (object && [object isKindOfClass: SOGoObjectK])
+        //         [objectCache setObject: object
+        //                         forKey: objectURLString];
+        // else {
+        //         object = nil;
+        //         [woContext setClientObject: nil];
+        // }
         
         return object;
 }
@@ -401,8 +417,11 @@ static MAPIStoreMapping *mapping = nil;
         keys = [subfolderCache objectForKey: folderURL];
         if (!keys) {
                 folder = [self _lookupObject: folderURL];
-                if (folder)
+                if (folder) {
                         keys = [folder toManyRelationshipKeys];
+                        if (!keys)
+                                keys = (NSArray *) [NSNull null];
+                }
                 else
                         keys = (NSArray *) [NSNull null];
                 [subfolderCache setObject: keys forKey: folderURL];
@@ -454,54 +473,33 @@ static MAPIStoreMapping *mapping = nil;
         return rc;
 }
 
-- (int) _getCommonTableChildproperty: (void **) data
-                               atURL: (NSString *) childURL
-                             withTag: (uint32_t) proptag
-                            inFolder: (SOGoFolder *) folder
-                             withFID: (uint64_t) fid
+- (int) getCommonTableChildproperty: (void **) data
+                              atURL: (NSString *) childURL
+                            withTag: (uint32_t) proptag
+                           inFolder: (SOGoFolder *) folder
+                            withFID: (uint64_t) fid
 {
         NSString *stringData;
         id child;
-        uint64_t *llongValue;
-        uint32_t *longValue;
+        // uint64_t *llongValue;
+        // uint32_t *longValue;
         int rc;
 
         rc = MAPI_E_SUCCESS;
         switch (proptag) {
-        case PR_PARENT_FID:
-                llongValue = talloc_zero(memCtx, uint64_t);
-                *llongValue = fid;
-                *data = llongValue;
-                break;
-        case PR_INST_ID: // TODO: DOUBT
-                llongValue = talloc_zero(memCtx, uint64_t);
-                *llongValue = [mapping idFromURL: childURL];
-                if (*llongValue == NSNotFound) {
-                        [mapping registerURL: childURL];
-                        *llongValue = [mapping idFromURL: childURL];
-                }
-                *data = llongValue;
-                break;
-        case PR_INSTANCE_NUM: // TODO: DOUBT
-                longValue = talloc_zero(memCtx, uint32_t);
-                *longValue = [childURL hash]; /* we return a unique id based on the url */
-                *data = longValue;
-                break;
         case PR_DISPLAY_NAME_UNICODE:
                 child = [self _lookupObject: childURL];
-                if ([child respondsToSelector: @selector (displayName)])
-                        stringData = [child displayName];
-                else
-                        stringData = [child nameInContainer];
+                stringData = [child displayName];
                 *data = talloc_strdup(memCtx,
                                       [stringData UTF8String]);
                 break;
-        case PR_DEPTH: // TODO: DOUBT
-                longValue = talloc_zero(memCtx, uint32_t);
-                *longValue = 1;
-                *data = longValue;
-                break;
         default:
+                // if ((proptag & 0x001F) == 0x001F) {
+                //         stringValue = [NSString stringWithFormat: @"Unhandled unicode value: 0x%x", proptag];
+                //         *data = talloc_strdup(memCtx, [stringValue UTF8String]);
+                //         break;
+                // }
+                // else
                 [self errorWithFormat: @"Unknown proptag: %.8x for child '%@'",
                       proptag, childURL];
                 *data = NULL;
@@ -511,97 +509,53 @@ static MAPIStoreMapping *mapping = nil;
         return rc;
 }
 
-- (int) _getMessageTableChildproperty: (void **) data
-                                atURL: (NSString *) childURL
-                              withTag: (uint32_t) proptag
-                             inFolder: (SOGoFolder *) folder
-                              withFID: (uint64_t) fid
+- (int) getMessageTableChildproperty: (void **) data
+                               atURL: (NSString *) childURL
+                             withTag: (uint32_t) proptag
+                            inFolder: (SOGoFolder *) folder
+                             withFID: (uint64_t) fid
 {
-        NSString *stringData;
-        id child;
-        uint64_t *llongValue;
-        uint8_t *boolValue;
         uint32_t *longValue;
+        uint64_t *llongValue;
         int rc;
 
         rc = MAPI_E_SUCCESS;
         switch (proptag) {
-        case PR_MID:
+        case PR_INST_ID: // TODO: DOUBT
                 llongValue = talloc_zero(memCtx, uint64_t);
-                *llongValue = [mapping idFromURL: childURL];
-                if (*llongValue == NSNotFound) {
-                        [mapping registerURL: childURL];
-                        *llongValue = [mapping idFromURL: childURL];
-                }
+                // *llongValue = 1;
+                *llongValue = [childURL hash]; /* we return a unique id based on the url */
                 *data = llongValue;
                 break;
-        case PR_ROW_TYPE: // TODO: DOUBT
-                longValue = talloc_zero(memCtx, uint32_t);
-                *longValue = 1;
-                *data = longValue;
-                break;
-        case PR_FLAG_STATUS: // TODO
-                longValue = talloc_zero(memCtx, uint32_t);
-                *longValue = 0;
-                *data = longValue;
-                break;
-        case PR_MSG_STATUS: // TODO
-                longValue = talloc_zero(memCtx, uint32_t);
-                *longValue = 0;
-                *data = longValue;
-                break;
-        case PR_MESSAGE_FLAGS: // TODO
+                // case PR_INST_ID: // TODO: DOUBT
+        case PR_INSTANCE_NUM: // TODO: DOUBT
                 longValue = talloc_zero(memCtx, uint32_t);
                 *longValue = 0;
                 *data = longValue;
                 break;
-        case PR_ICON_INDEX: // TODO
-                longValue = talloc_zero(memCtx, uint32_t);
-                *longValue = 0x00000100; /* read mail, see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
-                *data = longValue;
-                break;
-        case PR_SUBJECT_UNICODE:
-                child = [self _lookupObject: childURL];
-                stringData = [child decodedSubject];
-                *data = talloc_strdup(memCtx,
-                                      [stringData UTF8String]);
-                break;
-        case PR_MESSAGE_CLASS_UNICODE:
-                *data = talloc_strdup(memCtx, "IPM.Note");
-                break;
-        case PR_MESSAGE_SIZE:
-                child = [self _lookupObject: childURL];
+        case PR_VD_VERSION:
                 longValue = talloc_zero(memCtx, uint32_t);
-                /* TODO: choose another name for that method */
-                *longValue = [[child davContentLength] intValue];
+                *longValue = 8; /* mandatory value... wtf? */
                 *data = longValue;
                 break;
-        case PR_HASATTACH:
-                boolValue = talloc_zero(memCtx, uint8_t);
-                *boolValue = NO;
-                *data = boolValue;
+        // case PR_DEPTH: // TODO: DOUBT
+        //         longValue = talloc_zero(memCtx, uint32_t);
+        //         *longValue = 1;
+        //         *data = longValue;
+        //         break;
+        case PR_FID:
+                llongValue = talloc_zero(memCtx, uint64_t);
+                *llongValue = fid;
+                *data = llongValue;
+        case PR_MID:
+                llongValue = talloc_zero(memCtx, uint64_t);
+                *llongValue = [mapping idFromURL: childURL];
+                if (*llongValue == NSNotFound) {
+                        [mapping registerURL: childURL];
+                        *llongValue = [mapping idFromURL: childURL];
+                }
+                *data = llongValue;
                 break;
-                // case PR_MESSAGE_DELIVERY_TIME:
-                //         llongValue = talloc_zero(memCtx, int64_t);
-                //         child = [self _lookupObject: childURL];
-
-                //         refDate = [NSCalendarDate dateWithYear: 1601 month: 1 day: 1
-                //                                           hour: 0 minute: 0 second: 0
-                //                                       timeZone: [NSTimeZone timeZoneWithName: @"UTC"]];
-                //         *llongValue = (uint64_t) [[child date] timeIntervalSinceDate: refDate];
-                //         // timeValue->dwLowDateTime = (uint32_t) (timeCompValue & 0xffffffff);
-                //         // timeValue->dwHighDateTime = (uint32_t) ((timeCompValue >> 32) & 0xffffffff);
-                //         *data = llongValue;
-                //         break;
-// #define PR_REPLY_TIME                                       PROP_TAG(PT_SYSTIME   , 0x0030) /* 0x00300040 */
-// #define PR_EXPIRY_TIME                                      PROP_TAG(PT_SYSTIME   , 0x0015) /* 0x00150040 */
-// #define PR_MESSAGE_DELIVERY_TIME                            PROP_TAG(PT_SYSTIME   , 0x0e06) /* 0x0e060040 */
-// #define PR_IMPORTANCE                                       PROP_TAG(PT_LONG      , 0x0017) /* 0x00170003 */
-// #define PR_SENSITIVITY                                      PROP_TAG(PT_LONG      , 0x0036) /* 0x00360003 */
-// #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 */
-
 
                 /* those are queried while they really pertain to the
                    addressbook module */
@@ -612,41 +566,50 @@ static MAPIStoreMapping *mapping = nil;
 // 0x68420102  PidTagScheduleInfoDelegatorWantsCopy (BOOL)
 
 
-        case PR_SENT_REPRESENTING_NAME_UNICODE:
-                *data = talloc_strdup(memCtx, "PR_SENT_REPRESENTING_NAME_UNICODE");
-                // child = [self _lookupObject: childURL];
-                // stringData = [child from];
-                // *data = talloc_strdup(memCtx,
-                //                       [stringData UTF8String]);
-                break;
-        case PR_INTERNET_MESSAGE_ID_UNICODE:
-                *data = talloc_strdup(memCtx, "PR_INTERNET_MESSAGE_ID_UNICODE");
-                break;
         default:
-                rc = [self _getCommonTableChildproperty: data
-                                                  atURL: childURL
-                                                withTag: proptag
-                                               inFolder: folder
-                                                withFID: fid];
+                rc = [self getCommonTableChildproperty: data
+                                                 atURL: childURL
+                                               withTag: proptag
+                                              inFolder: folder
+                                               withFID: fid];
         }
 
         return rc;
 }
 
-- (int) _getFolderTableChildproperty: (void **) data
-                               atURL: (NSString *) childURL
-                             withTag: (uint32_t) proptag
-                            inFolder: (SOGoFolder *) folder
-                             withFID: (uint64_t) fid
+- (NSString *) _parentURLFromURL: (NSString *) urlString
 {
-        id child;
+        NSString *newURL;
+        NSArray *parts;
+        NSMutableArray *newParts;
+
+        parts = [urlString componentsSeparatedByString: @"/"];
+        if ([parts count] > 3) {
+                newParts = [parts mutableCopy];
+                [newParts autorelease];
+                [newParts removeLastObject];
+                newURL = [newParts componentsJoinedByString: @"/"];
+        }
+        else
+                newURL = nil;
+
+        return newURL;
+}
+
+- (int) getFolderTableChildproperty: (void **) data
+                              atURL: (NSString *) childURL
+                            withTag: (uint32_t) proptag
+                           inFolder: (SOGoFolder *) folder
+                            withFID: (uint64_t) fid
+{
+        // id child;
         uint64_t *llongValue;
         uint8_t *boolValue;
         uint32_t *longValue;
         struct Binary_r *binaryValue;
         int rc;
+        NSString *parentURL;
 
-        [self logWithFormat: @"  querying child folder at URL: %@", childURL];
         rc = MAPI_E_SUCCESS;
         switch (proptag) {
         case PR_FID:
@@ -658,6 +621,22 @@ static MAPIStoreMapping *mapping = nil;
                 }
                 *data = llongValue;
                 break;
+        case PR_PARENT_FID:
+                llongValue = talloc_zero(memCtx, uint64_t);
+                parentURL = [self _parentURLFromURL: childURL];
+                if (parentURL) {
+                        *llongValue = [mapping idFromURL: childURL];
+                        if (*llongValue == NSNotFound) {
+                                [mapping registerURL: childURL];
+                                *llongValue = [mapping idFromURL: childURL];
+                        }
+                        *data = llongValue;
+                }
+                else {
+                        *data = NULL;
+                        rc = MAPISTORE_ERR_NOT_FOUND;
+                }
+                break;
         case PR_ATTR_HIDDEN:
         case PR_ATTR_SYSTEM:
         case PR_ATTR_READONLY:
@@ -667,24 +646,14 @@ static MAPIStoreMapping *mapping = nil;
                 break;
         case PR_SUBFOLDERS:
                 boolValue = talloc_zero(memCtx, uint8_t);
-                child = [self _lookupObject: childURL];
-                *boolValue = ([[child toManyRelationshipKeys]
-                                      count]
-                              > 0);
+                *boolValue = ([[self _subfolderKeysForFolderURL: childURL]
+                                      count] > 0);
                 *data = boolValue;
                 break;
         case PR_CONTENT_COUNT:
                 longValue = talloc_zero(memCtx, uint32_t);
-                child = [self _lookupObject: childURL];
-                *longValue = ([[child toOneRelationshipKeys]
-                                      count]
-                              > 0);
-                *data = longValue;
-                break;
-        // case 0x36de0003: http://social.msdn.microsoft.com/Forums/en-US/os_exchangeprotocols/thread/17c68add-1f62-4b68-9d83-f9ec7c1c6c9b
-        case PR_CONTENT_UNREAD:
-                longValue = talloc_zero(memCtx, uint32_t);
-                *longValue = 0;
+                *longValue = ([[self _messageKeysForFolderURL: childURL]
+                                      count] > 0);
                 *data = longValue;
                 break;
         case PR_EXTENDED_FOLDER_FLAGS: // TODO: DOUBT: how to indicate the
@@ -692,15 +661,12 @@ static MAPIStoreMapping *mapping = nil;
                 binaryValue = talloc_zero(memCtx, struct Binary_r);
                 *data = binaryValue;
                 break;
-        case PR_CONTAINER_CLASS_UNICODE:
-                *data = talloc_strdup(memCtx, "IPF.Note");
-                break;
         default:
-                rc = [self _getCommonTableChildproperty: data
-                                                  atURL: childURL
-                                                withTag: proptag
-                                               inFolder: folder
-                                                withFID: fid];
+                rc = [self getCommonTableChildproperty: data
+                                                 atURL: childURL
+                                               withTag: proptag
+                                              inFolder: folder
+                                               withFID: fid];
         }
 
         return rc;
@@ -739,24 +705,25 @@ static MAPIStoreMapping *mapping = nil;
                         childName = [children objectAtIndex: pos];
                         childURL = [folderURL stringByAppendingFormat: @"/%@",
                                               [childName stringByEscapingURL]];
-                        [self logWithFormat: @"  querying child message at URL: %@", childURL];
 
-                        if (tableType == MAPISTORE_FOLDER_TABLE)
-                                rc = [self _getFolderTableChildproperty: data
+                        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];
-                        else
-                                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_IMPORTANCE                                       PROP_TAG(PT_LONG      , 0x0017) /* 0x00170003 */
 // #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 */
@@ -766,7 +733,7 @@ static MAPIStoreMapping *mapping = nil;
 // #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
+// unknown 36de0003 http://social.msdn.microsoft.com/Forums/en-US/os_exchangeprotocols/thread/17c68add-1f62-4b68-9d83-f9ec7c1c6c9b
 // unknown 819d0003
 // unknown 81f80003
 // unknown 81fa000b
@@ -870,3 +837,451 @@ static MAPIStoreMapping *mapping = nil;
 }
 
 @end
+
+#import <Mailer/SOGoMailFolder.h>
+#import <Mailer/SOGoMailObject.h>
+
+@implementation MAPIStoreMailContext
+
+- (void) setupModuleFolder
+{
+        id userFolder, accountsFolder;
+
+        userFolder = [SOGoUserFolderK objectWithName: [authenticator username]
+                                         inContainer: MAPIApp];
+        [woContext setClientObject: userFolder];
+        [userFolder retain]; // LEAK
+
+        accountsFolder = [userFolder lookupName: @"Mail"
+                                      inContext: woContext
+                                        acquire: NO];
+        [woContext setClientObject: accountsFolder];
+        [accountsFolder retain]; // LEAK
+
+        moduleFolder = [accountsFolder lookupName: @"0"
+                                        inContext: woContext
+                                          acquire: NO];
+        [moduleFolder retain];
+}
+
+// - (int) getCommonTableChildproperty: (void **) data
+//                               atURL: (NSString *) childURL
+//                             withTag: (uint32_t) proptag
+//                            inFolder: (SOGoFolder *) folder
+//                             withFID: (uint64_t) fid
+// {
+//         int rc;
+
+//         rc = MAPI_E_SUCCESS;
+//         switch (proptag) {
+//         default:
+//                 rc = [super getCommonTableChildproperty: data
+//                                                   atURL: childURL
+//                                                 withTag: proptag
+//                                                inFolder: folder
+//                                                 withFID: fid];
+//         }
+
+//         return rc;
+// }
+
+- (int) getMessageTableChildproperty: (void **) data
+                               atURL: (NSString *) childURL
+                             withTag: (uint32_t) proptag
+                            inFolder: (SOGoFolder *) folder
+                             withFID: (uint64_t) fid
+{
+        NSCalendarDate *refDate;
+        uint64_t timeCompValue;
+        struct FILETIME *timeValue;
+
+        uint8_t *boolValue;
+        uint32_t *longValue;
+        NSString *stringData;
+        SOGoMailObject *child;
+        int rc;
+
+        rc = MAPI_E_SUCCESS;
+        switch (proptag) {
+        case PR_ICON_INDEX: // TODO
+                longValue = talloc_zero(memCtx, uint32_t);
+                *longValue = 0x00000100; /* read mail, see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
+                *data = longValue;
+                break;
+        case PR_SUBJECT_UNICODE:
+                child = [self _lookupObject: childURL];
+                stringData = [child decodedSubject];
+                *data = talloc_strdup(memCtx,
+                                      [stringData UTF8String]);
+                break;
+        case PR_MESSAGE_CLASS_UNICODE:
+                *data = talloc_strdup(memCtx, "IPM.Note");
+                break;
+        case PR_HASATTACH:
+                boolValue = talloc_zero(memCtx, uint8_t);
+                *boolValue = NO;
+                *data = boolValue;
+                break;
+        case PR_MESSAGE_DELIVERY_TIME:
+                // llongValue = talloc_zero(memCtx, int64_t);
+                // child = [self _lookupObject: childURL];
+                
+                // refDate = [NSCalendarDate dateWithYear: 1601 month: 1 day: 1
+                //                                   hour: 0 minute: 0 second: 0
+                //                               timeZone: [NSTimeZone timeZoneWithName: @"UTC"]];
+                // *llongValue = (uint64_t) [[child date] timeIntervalSinceDate:
+                //                                   refDate];
+
+                child = [self _lookupObject: childURL];
+                refDate = [NSCalendarDate dateWithYear: 1601 month: 1 day: 1
+                                                  hour: 0 minute: 0 second: 0
+                                              timeZone: [NSTimeZone timeZoneWithName: @"UTC"]];
+                timeCompValue = (((uint64_t) [[child date] timeIntervalSinceDate: refDate] + (86400 * -365))
+                                 * 10000000);
+                // timeCompValue = ((uint64_t) 86400 * 31 );
+                timeValue = talloc_zero(memCtx, struct FILETIME);
+                timeValue->dwLowDateTime = (uint32_t) (timeCompValue & 0xffffffff);
+                timeValue->dwHighDateTime = (uint32_t) ((timeCompValue >> 32) & 0xffffffff);
+                NSLog (@"%@ -> %lld", [child date], timeCompValue);
+                NSLog (@"time conversion: %llx  -> %lx, %lx", timeCompValue,
+                       timeValue->dwHighDateTime, timeValue->dwLowDateTime);
+                *data = timeValue;
+                break;
+        // case PR_ROW_TYPE: // TODO: DOUBT
+        //         longValue = talloc_zero(memCtx, uint32_t);
+        //         *longValue = 1;
+        //         *data = longValue;
+        //         break;
+        case PR_FLAG_STATUS: // TODO
+        case PR_MSG_STATUS: // TODO
+        case PR_MESSAGE_FLAGS: // TODO
+        case PR_SENSITIVITY: // TODO
+                longValue = talloc_zero(memCtx, uint32_t);
+                *longValue = 0;
+                *data = longValue;
+                break;
+        case PR_IMPORTANCE:
+                longValue = talloc_zero(memCtx, uint32_t);
+                *longValue = 1;
+                *data = longValue;
+                break;
+        case PR_MESSAGE_SIZE: // TODO
+                child = [self _lookupObject: childURL];
+                longValue = talloc_zero(memCtx, uint32_t);
+                /* TODO: choose another name for that method */
+                *longValue = [[child davContentLength] intValue];
+                *data = longValue;
+                break;
+// #define PR_REPLY_TIME                                       PROP_TAG(PT_SYSTIME   , 0x0030) /* 0x00300040 */
+// #define PR_EXPIRY_TIME                                      PROP_TAG(PT_SYSTIME   , 0x0015) /* 0x00150040 */
+// #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 */
+
+
+
+        case PR_SENT_REPRESENTING_NAME_UNICODE:
+                child = [self _lookupObject: childURL];
+                stringData = [child from];
+                *data = talloc_strdup(memCtx, [stringData UTF8String]);
+                break;
+        case PR_INTERNET_MESSAGE_ID_UNICODE:
+                child = [self _lookupObject: childURL];
+                stringData = [child messageId];
+                *data = talloc_strdup(memCtx, [stringData UTF8String]);
+                break;
+        default:
+                rc = [super getMessageTableChildproperty: data
+                                                   atURL: childURL
+                                                 withTag: proptag
+                                                inFolder: folder
+                                                 withFID: fid];
+        }
+        
+        return rc;
+}
+
+- (int) getFolderTableChildproperty: (void **) data
+                              atURL: (NSString *) childURL
+                            withTag: (uint32_t) proptag
+                           inFolder: (SOGoFolder *) folder
+                            withFID: (uint64_t) fid
+{
+        uint32_t *longValue;
+        int rc;
+
+        rc = MAPI_E_SUCCESS;
+        switch (proptag) {
+        case PR_CONTENT_UNREAD:
+                longValue = talloc_zero(memCtx, uint32_t);
+                *longValue = 0;
+                *data = longValue;
+                break;
+        case PR_CONTAINER_CLASS_UNICODE:
+                *data = talloc_strdup(memCtx, "IPF.Note");
+                break;
+        default:
+                rc = [super getFolderTableChildproperty: data
+                                          atURL: childURL
+                                                withTag: proptag
+                                               inFolder: folder
+                                                withFID: fid];
+        }
+        
+        return rc;
+}
+
+@end
+
+#import <Contacts/SOGoContactObject.h>
+#import <NGCards/NGVCard.h>
+
+@implementation MAPIStoreContactsContext
+
+- (void) setupModuleFolder
+{
+        id userFolder;
+
+        userFolder = [SOGoUserFolderK objectWithName: [authenticator username]
+                                         inContainer: MAPIApp];
+        [woContext setClientObject: userFolder];
+        [userFolder retain]; // LEAK
+
+        moduleFolder = [userFolder lookupName: @"Contacts"
+                                    inContext: woContext
+                                      acquire: NO];
+        [moduleFolder retain];
+}
+
+// - (int) getCommonTableChildproperty: (void **) data
+//                               atURL: (NSString *) childURL
+//                             withTag: (uint32_t) proptag
+//                            inFolder: (SOGoFolder *) folder
+//                             withFID: (uint64_t) fid
+// {
+//         int rc;
+
+//         rc = MAPI_E_SUCCESS;
+//         switch (proptag) {
+//         default:
+//                 rc = [super getCommonTableChildproperty: data
+//                                                   atURL: childURL
+//                                                 withTag: proptag
+//                                                inFolder: folder
+//                                                 withFID: fid];
+//         }
+
+//         return rc;
+// }
+
+- (NSString *) _phoneOfType: (NSString *) aType
+                  excluding: (NSString *) aTypeToExclude
+                     inCard: (NGVCard *) card
+{
+  NSArray *elements;
+  NSArray *phones;
+  NSString *phone;
+
+  phones = [card childrenWithTag: @"tel"];
+
+  elements = [phones cardElementsWithAttribute: @"type"
+                     havingValue: aType];
+
+  phone = nil;
+
+  if ([elements count] > 0)
+    {
+      CardElement *ce;
+      int i;
+
+      for (i = 0; i < [elements count]; i++)
+       {
+         ce = [elements objectAtIndex: i];
+         phone = [ce value: 0];
+
+         if (!aTypeToExclude)
+           break;
+         
+         if (![ce hasAttribute: @"type" havingValue: aTypeToExclude])
+           break;
+
+         phone = nil;
+       }
+    }
+
+  if (!phone)
+          phone = @"";
+
+  return phone;
+}
+
+- (int) getMessageTableChildproperty: (void **) data
+                               atURL: (NSString *) childURL
+                             withTag: (uint32_t) proptag
+                            inFolder: (SOGoFolder *) folder
+                             withFID: (uint64_t) fid
+{
+        NSString *stringValue;
+        uint32_t *longValue;
+        id child;
+        int rc;
+
+        rc = MAPI_E_SUCCESS;
+        switch (proptag) {
+        case PR_ICON_INDEX: // TODO
+                longValue = talloc_zero(memCtx, uint32_t);
+                *longValue = 0x00000200; /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */
+                *data = longValue;
+                break;
+        case PR_MESSAGE_CLASS_UNICODE:
+                *data = talloc_strdup(memCtx, "IPM.Contact");
+                break;
+        // case PR_VD_NAME_UNICODE:
+        //         *data = talloc_strdup(memCtx, "PR_VD_NAME_UNICODE");
+        //         break;
+        // case PR_EMS_AB_DXA_REMOTE_CLIENT_UNICODE: "Home:" ???
+        //         *data = talloc_strdup(memCtx, "PR_EMS...");
+        //         break;
+        case PR_SUBJECT_UNICODE:
+                *data = talloc_strdup(memCtx, "PR_SUBJECT...");
+                break;
+        case PR_OAB_NAME_UNICODE:
+                *data = talloc_strdup(memCtx, "PR_OAB_NAME_UNICODE");
+                break;
+        case PR_OAB_LANGID:
+                longValue = talloc_zero(memCtx, uint32_t);
+                *longValue = 1033; /* English US */
+                *data = longValue;
+                break;
+
+        case PR_TITLE_UNICODE:
+                child = [self _lookupObject: childURL];
+                stringValue = [[child vCard] title];
+                *data = talloc_strdup(memCtx, [stringValue UTF8String]);
+                break;
+
+        case PR_COMPANY_NAME_UNICODE:
+                child = [self _lookupObject: childURL];
+                /* that's buggy but it's for the demo */
+                stringValue = [[[child vCard] org] componentsJoinedByString: @", "];
+                *data = talloc_strdup(memCtx, [stringValue UTF8String]);
+                break;
+
+        case 0x3001001f: // Full Name
+        case 0x81c2001f: // contact block title name
+                rc = [super getMessageTableChildproperty: data
+                                                   atURL: childURL
+                                                 withTag: PR_DISPLAY_NAME_UNICODE
+                                                inFolder: folder
+                                                 withFID: fid];
+                break;
+        case 0x81b0001f: // E-mail
+                child = [self _lookupObject: childURL];
+                stringValue = [[child vCard] preferredEMail];
+                *data = talloc_strdup(memCtx, [stringValue UTF8String]);
+                break;
+        case PR_BODY_UNICODE:
+                child = [self _lookupObject: childURL];
+                stringValue = [[child vCard] note];
+                *data = talloc_strdup(memCtx, [stringValue UTF8String]);
+                break;
+
+        case PR_OFFICE_TELEPHONE_NUMBER_UNICODE:
+                child = [self _lookupObject: childURL];
+                stringValue = [self _phoneOfType: @"work"
+                                       excluding: @"fax"
+                                          inCard: [child vCard]];
+                *data = talloc_strdup(memCtx, [stringValue UTF8String]);
+                break;
+        case PR_HOME_TELEPHONE_NUMBER_UNICODE:
+                child = [self _lookupObject: childURL];
+                stringValue = [self _phoneOfType: @"home"
+                                       excluding: @"fax"
+                                          inCard: [child vCard]];
+                *data = talloc_strdup(memCtx, [stringValue UTF8String]);
+                break;
+        case PR_MOBILE_TELEPHONE_NUMBER_UNICODE:
+                child = [self _lookupObject: childURL];
+                stringValue = [self _phoneOfType: @"cell"
+                                       excluding: nil
+                                          inCard: [child vCard]];
+                *data = talloc_strdup(memCtx, [stringValue UTF8String]);
+                break;
+        case PR_PRIMARY_TELEPHONE_NUMBER_UNICODE:
+                child = [self _lookupObject: childURL];
+                stringValue = [self _phoneOfType: @"pref"
+                                       excluding: nil
+                                          inCard: [child vCard]];
+                *data = talloc_strdup(memCtx, [stringValue UTF8String]);
+                break;
+
+        // case PR_POSTAL_ADDRESS_UNICODE:
+        // case PR_INTERNET_MESSAGE_ID_UNICODE:
+        // case PR_CAR_TELEPHONE_NUMBER_UNICODE:
+        // case PR_OTHER_TELEPHONE_NUMBER_UNICODE:
+        // case PR_BUSINESS_FAX_NUMBER_UNICODE:
+        // case PR_HOME_FAX_NUMBER_UNICODE:
+        // case PR_COMPANY_MAIN_PHONE_NUMBER_UNICODE:
+        // case PR_EMS_AB_GROUP_BY_ATTR_4_UNICODE:
+        // case PR_CALLBACK_TELEPHONE_NUMBER_UNICODE:
+        // case PR_DEPARTMENT_NAME_UNICODE:
+        // case PR_OFFICE2_TELEPHONE_NUMBER_UNICODE:
+        // case PR_RADIO_TELEPHONE_NUMBER_UNICODE:
+        // case PR_PAGER_TELEPHONE_NUMBER_UNICODE:
+        // case PR_PRIMARY_FAX_NUMBER_UNICODE:
+        // case PR_TELEX_NUMBER_UNICODE:
+        // case PR_ISDN_NUMBER_UNICODE:
+        // case PR_ASSISTANT_TELEPHONE_NUMBER_UNICODE:
+        // case PR_HOME2_TELEPHONE_NUMBER_UNICODE:
+        // case PR_TTYTDD_PHONE_NUMBER_UNICODE:
+        // case PR_BUSINESS_HOME_PAGE_UNICODE:
+        //         *data = talloc_strdup(memCtx, "[Generic and fake unicode value]");
+        //         break;
+
+// (18:54:45) Wolfgang-: 0x80a7001f (  Business: ) -> don't ask me which "business"
+// (18:55:05) Wolfgang-: 0x809c001f   (  Other: )
+// (18:55:58) Wolfgang-: 0x81b5001f: E-mail  2
+
+
+// #define PR_REPLY_TIME                                       PROP_TAG(PT_SYSTIME   , 0x0030) /* 0x00300040 */
+// #define PR_SENSITIVITY                                      PROP_TAG(PT_LONG      , 0x0036) /* 0x00360003 */
+// #define PR_FOLLOWUP_ICON                                    PROP_TAG(PT_LONG      , 0x1095) /* 0x10950003 */
+// #define PR_SEARCH_KEY                                       PROP_TAG(PT_BINARY    , 0x300b) /* 0x300b0102 */
+// #define PR_VIEW_STYLE                                       PROP_TAG(PT_LONG      , 0x6834) /* 0x68340003 */
+// #define PR_VD_VERSION                                       PROP_TAG(PT_LONG      , 0x7007) /* 0x70070003 */
+
+        default:
+                rc = [super getMessageTableChildproperty: data
+                                                   atURL: childURL
+                                                 withTag: proptag
+                                                inFolder: folder
+                                                 withFID: fid];
+        }
+        
+        return rc;
+}
+
+- (int) getFolderTableChildproperty: (void **) data
+                              atURL: (NSString *) childURL
+                            withTag: (uint32_t) proptag
+                           inFolder: (SOGoFolder *) folder
+                            withFID: (uint64_t) fid
+{
+        int rc;
+
+        [self logWithFormat: @"XXXXX unexpected!!!!!!!!!"];
+        rc = MAPI_E_SUCCESS;
+        switch (proptag) {
+        default:
+                rc = [super getFolderTableChildproperty: data
+                                          atURL: childURL
+                                                withTag: proptag
+                                               inFolder: folder
+                                                withFID: fid];
+        }
+        
+        return rc;
+}
+
+@end
index 8e4980014e31f280dbb612a41432117db566a311..96d0078605f61632ea5fa25503659f39809ccb22 100644 (file)
@@ -28,8 +28,8 @@
 
 #import "MAPIStoreMapping.h"
 
-static uint64_t idCounter = 0x160001;
-static const uint64_t idIncrement = 0x010000;
+static const uint64_t idIncrement = 0x010000; /* we choose a high enough id to avoid any clash with system folders */
+static uint64_t idCounter = 0x200001;
 
 @implementation MAPIStoreMapping
 
@@ -86,7 +86,6 @@ static const uint64_t idIncrement = 0x010000;
                 rc = NO;
         }
         else {
-                idKey = [NSNumber numberWithUnsignedLongLong: idNbr];
                 [mapping setObject: urlString forKey: idKey];
                 [reverseMapping setObject: idKey forKey: urlString];
                 rc = YES;
@@ -99,12 +98,31 @@ static const uint64_t idIncrement = 0x010000;
 
 - (void) registerURL: (NSString *) urlString
 {
-        // uint64_t newID;
+        uint64_t idNbr;
 
         // newID = openchangedb_get_new_folderID();
         if (![reverseMapping objectForKey: urlString]) {
-                while (![self registerURL: urlString withID: idCounter])
+                if ([urlString isEqualToString: @"sogo://openchange:openchange@mail/folderINBOX"]) {
+                        idNbr = 0x160001;
+                        if (![self registerURL: urlString withID: idNbr])
+                                [self errorWithFormat: @"Unable to register root folder: %@",
+                                      urlString];
+                }
+                // else if ([urlString isEqualToString: @"sogo://openchange:openchange@mail/folderSent"]) {
+                //         idNbr = 0x140001;
+                //         idCounter = idNbr;
+                // }
+                else if ([urlString isEqualToString: @"sogo://openchange:openchange@contacts/personal"]) {
+                        idNbr = 0x1a0001;
+                        if (![self registerURL: urlString withID: idNbr])
+                                [self errorWithFormat: @"Unable to register root folder: %@",
+                                      urlString];
+                }
+                else {
                         idCounter += idIncrement;
+                        while (![self registerURL: urlString withID: idCounter])
+                                idCounter += idIncrement;
+                }
                 // [self _registerURL: urlString withID: newID];
         }
 }
index bfc5f9810c147a39ae5028d1c7d462599c9bc767..a2bf7c67fcc0b667000704daa947df1d98c182cb 100644 (file)
@@ -104,9 +104,14 @@ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenMessage(TALLOC_CTX *mem_ctx,
 
        switch (object->type) {
        case EMSMDBP_OBJECT_MAILBOX:
+               folderID = object->object.folder->folderID;
+               contextID = object->object.folder->contextID;
+               break;
+
+                flist = NULL;
                ret = mapistore_indexing_get_folder_list(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username,
                                                         messageID, &flist);
-               if (ret || !flist->count) {
+               if (ret || !flist || !flist->count) {
                        DEBUG(0, ("No parent folder found for 0x%.16"PRIx64"\n", messageID));
                }
                /* If last element in the list doesn't match folderID, that's incorrect */
index 9dff2ab0b1ea7ac7d541d46da2f245cc8f84046b..a51b902e73e96f5e9fd4b083459b95bc26fce2f6 100644 (file)
@@ -1348,22 +1348,19 @@ _PUBLIC_ void ndr_print_EcDoConnectEx(struct ndr_print *ndr, const char *name, i
                ndr->depth--;
                ndr_print_ptr(ndr, "szDNPrefix", r->out.szDNPrefix);
                ndr->depth++;
-               ndr_print_ptr(ndr, "szDNPrefix", *r->out.szDNPrefix);
-               ndr->depth++;
-               if (*r->out.szDNPrefix) {
-                       ndr_print_string(ndr, "szDNPrefix", *r->out.szDNPrefix);
-               }
+                if (r->out.szDNPrefix) {
+                  ndr_print_ptr(ndr, "szDNPrefix", *r->out.szDNPrefix);
+                  ndr->depth++;
+                }
                ndr->depth--;
                ndr->depth--;
                ndr_print_ptr(ndr, "szDisplayName", r->out.szDisplayName);
-               ndr->depth++;
-               ndr_print_ptr(ndr, "szDisplayName", *r->out.szDisplayName);
-               ndr->depth++;
-               if (*r->out.szDisplayName) {
+               if (r->out.szDisplayName) {
+                        ndr->depth++;
                        ndr_print_string(ndr, "szDisplayName", *r->out.szDisplayName);
+                        ndr->depth--;
                }
                ndr->depth--;
-               ndr->depth--;
                ndr->print(ndr, "%s: ARRAY(%d)", "rgwServerVersion", (int)3);
                ndr->depth++;
                for (cntr_rgwServerVersion_0=0;cntr_rgwServerVersion_0<3;cntr_rgwServerVersion_0++) {
@@ -1385,14 +1382,18 @@ _PUBLIC_ void ndr_print_EcDoConnectEx(struct ndr_print *ndr, const char *name, i
                }
                ndr->depth--;
                ndr_print_ptr(ndr, "pulTimeStamp", r->out.pulTimeStamp);
-               ndr->depth++;
-               ndr_print_uint32(ndr, "pulTimeStamp", *r->out.pulTimeStamp);
-               ndr->depth--;
+                if (r->out.pulTimeStamp) {
+                        ndr->depth++;
+                        ndr_print_uint32(ndr, "pulTimeStamp", *r->out.pulTimeStamp);
+                        ndr->depth--;
+                }
                ndr_print_mapi2k7_AuxInfo(ndr, "rgbAuxOut", r->out.rgbAuxOut);
                ndr_print_ptr(ndr, "pcbAuxOut", r->out.pcbAuxOut);
-               ndr->depth++;
-               ndr_print_uint32(ndr, "pcbAuxOut", *r->out.pcbAuxOut);
-               ndr->depth--;
+                if (r->out.pcbAuxOut) {
+                        ndr->depth++;
+                        ndr_print_uint32(ndr, "pcbAuxOut", *r->out.pcbAuxOut);
+                        ndr->depth--;
+                }
                ndr_print_MAPISTATUS(ndr, "result", r->out.result);
                ndr->depth--;
        }
index 286239f2e90e011283c48b4c62a9f0216b677d56..259e301e0fa0a9be615e2ceb880d3eb40cc50907 100755 (executable)
@@ -9,18 +9,20 @@ import openchange
 import openchange.mapistore as mapistore
 from openchange import mapi
 
-#os.mkdir("/tmp/mapistore")
+dirname = "/tmp/mapistore"
+if not os.path.exists(dirname):
+    os.mkdir("/tmp/mapistore")
 
 mapistore.set_mapping_path("/tmp/mapistore")
 MAPIStore = mapistore.mapistore()
-ctx_id = MAPIStore.add_context("fsocpf:///tmp/mapistore/0x0000000000010001")
+ctx_id = MAPIStore.add_context("sogo://openchange:openchange@mail/")
 
 SPropParent = mapi.SPropValue()
-SPropParent.add(mapi.PR_FID, 0x0000000000010001)
+SPropParent.add(mapi.PR_FID, 0x0000000000160001)
 SPropParent.add(mapi.PR_DISPLAY_NAME, "parent")
 SPropParent.add(mapi.PR_COMMENT, "test parent")
 SPropParent.add(mapi.PR_FOLDER_TYPE, 1)
-MAPIStore.setprops(ctx_id, 0x0000000000010001, mapistore.MAPISTORE_FOLDER, SPropParent)
+MAPIStore.setprops(ctx_id, 0x0000000000160001, mapistore.MAPISTORE_FOLDER, SPropParent)
 
 SPropValue = mapi.SPropValue()
 SPropValue.add(mapi.PR_PARENT_FID, 0x0000000000010001)
@@ -28,12 +30,12 @@ SPropValue.add(mapi.PR_DISPLAY_NAME, "test")
 SPropValue.add(mapi.PR_COMMENT, "test folder")
 SPropValue.add(mapi.PR_FOLDER_TYPE, 1)
 
-MAPIStore.mkdir(ctx_id, 0x0000000000010001, 0x0000000000020001, SPropValue)
+MAPIStore.mkdir(ctx_id, 0x0000000000160001, 0x0000000000020001, SPropValue)
 
 count = MAPIStore.get_folder_count(ctx_id, 0x0000000000010001, mapistore.MAPISTORE_FOLDER)
 print "After mkdir: %d" % (count)
 
-MAPIStore.rmdir(ctx_id, 0x0000000000010001, 0x0000000000020001, mapistore.DEL_FOLDERS)
+MAPIStore.rmdir(ctx_id, 0x0000000000160001, 0x0000000000020001, mapistore.DEL_FOLDERS)
 
 count = MAPIStore.get_folder_count(ctx_id, 0x0000000000010001, mapistore.MAPISTORE_FOLDER)
 print "After rmdir: %d" % (count)
index 1f7e97bec9cd1d8fd3ca6dd643824e1b23ed80ac..83014d32417b6f89701357d0191c06f2e11c7cd8 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/python
+# -*- coding: utf-8 -*-
 
 import sys
 
@@ -9,15 +10,30 @@ import openchange
 import openchange.mapistore as mapistore
 from openchange import mapi
 
-os.mkdir("/tmp/mapistore")
+dirname = "/tmp/mapistore"
+if not os.path.exists(dirname):
+    os.mkdir("/tmp/mapistore")
 
 mapistore.set_mapping_path("/tmp/mapistore")
 MAPIStore = mapistore.mapistore()
-ctx_id = MAPIStore.add_context("sogo://openchange:openchange@mail/INBOX")
+ctx_id = MAPIStore.add_context("sogo://openchange:openchange@mail/")
 
 count = MAPIStore.get_folder_count(ctx_id, 0x0000000000160001, 
-                                   mapistore.MAPISTORE_MESSAGE)
+                                   mapistore.MAPISTORE_FOLDER)
 
-print "Number of messages in INBOX: %d" % (count)
+print "Number of folders in INBOX: %d" % (count)
+
+SPropValue = mapi.SPropValue()
+SPropValue.add(mapi.PR_PARENT_FID, 0x0000000000160001)
+SPropValue.add(mapi.PR_DISPLAY_NAME, "testé")
+SPropValue.add(mapi.PR_COMMENT, "test folder")
+SPropValue.add(mapi.PR_FOLDER_TYPE, 1)
+
+MAPIStore.mkdir(ctx_id, 0x0000000000160001, 0x00000000001620001, SPropValue)
+
+count = MAPIStore.get_folder_count(ctx_id, 0x0000000000160001, 
+                                   mapistore.MAPISTORE_FOLDER)
+
+print "Number of folders in INBOX: %d" % (count)
 
 MAPIStore.del_context(ctx_id)
index 39f7796557f1935aa4f8047743d29c1a7ce93c3c..5dcf407c85b93c0389a0e4c72d3914b1bdbcc081 100755 (executable)
@@ -253,7 +253,7 @@ packages() {
        ./autogen-waf.sh
        error_check $? "$lib autogen"
 
-       ./configure --prefix=$SAMBA_PREFIX --enable-developer --bundled-libraries=NONE
+       ./configure --prefix=$SAMBA_PREFIX --enable-developer --abi-check-disable --bundled-libraries=NONE
        error_check $? "$lib configure"
 
        make