Skip to content

Commit

Permalink
Merge to 2.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
cgx committed Apr 3, 2014
2 parents ae0c5ea + 378f2b5 commit 48f98ef
Show file tree
Hide file tree
Showing 68 changed files with 1,207 additions and 676 deletions.
3 changes: 2 additions & 1 deletion ActiveSync/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ ActiveSync_PRINCIPAL_CLASS = ActiveSyncProduct

ActiveSync_OBJC_FILES = \
ActiveSyncProduct.m \
iCalAlarm+ActiveSync.m \
iCalEvent+ActiveSync.m \
iCalRecurrenceRule+ActiveSync.m \
iCalTimeZone+ActiveSync.m \
Expand All @@ -30,7 +31,7 @@ ActiveSync_RESOURCE_FILES += \

ADDITIONAL_OBJCFLAGS += -Wno-deprecated-declarations
ADDITIONAL_INCLUDE_DIRS += -I../SOPE/ -I../SoObjects/
ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/
ADDITIONAL_LIB_DIRS += -L../SOPE/GDLContentStore/obj/ -L../SOPE/NGCards/obj/
ADDITIONAL_INCLUDE_DIRS += -I/usr/include/libwbxml-1.0/
ADDITIONAL_LDFLAGS += -Wl,--no-as-needed -lwbxml2

Expand Down
183 changes: 97 additions & 86 deletions ActiveSync/SOGoActiveSyncDispatcher.m
Original file line number Diff line number Diff line change
Expand Up @@ -868,105 +868,116 @@ - (void) processMoveItems: (id <DOMElement>) theDocumentElement
{
NSString *srcMessageId, *srcFolderId, *dstFolderId, *dstMessageId;
SOGoMicrosoftActiveSyncFolderType srcFolderType, dstFolderType;
id <DOMElement> aMoveOperation;
NSArray *moveOperations;
NSMutableString *s;
NSData *d;
int i;

moveOperations = (id)[theDocumentElement getElementsByTagName: @"Move"];

srcMessageId = [[(id)[theDocumentElement getElementsByTagName: @"SrcMsgId"] lastObject] textValue];
srcFolderId = [[[(id)[theDocumentElement getElementsByTagName: @"SrcFldId"] lastObject] textValue] realCollectionIdWithFolderType: &srcFolderType];
dstFolderId = [[[(id)[theDocumentElement getElementsByTagName: @"DstFldId"] lastObject] textValue] realCollectionIdWithFolderType: &dstFolderType];
s = [NSMutableString string];

// FIXME
if (srcFolderType == ActiveSyncMailFolder && dstFolderType == ActiveSyncMailFolder)
{
NGImap4Client *client;
id currentCollection;
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<MoveItems xmlns=\"Move:\">"];

NSDictionary *response;
NSString *v;
for (i = 0; i < [moveOperations count]; i++)
{
aMoveOperation = [moveOperations objectAtIndex: i];

currentCollection = [self collectionFromId: srcFolderId type: srcFolderType];

// [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", srcFolderId]
// inContext: context
// acquire: NO];

client = [[currentCollection imap4Connection] client];
[client select: srcFolderId];
response = [client copyUid: [srcMessageId intValue]
toFolder: [NSString stringWithFormat: @"/%@", dstFolderId]];

// We extract the destionation message id
dstMessageId = nil;

if ([[response objectForKey: @"result"] boolValue]
&& (v = [[[response objectForKey: @"RawResponse"] objectForKey: @"ResponseResult"] objectForKey: @"flag"])
&& [v hasPrefix: @"COPYUID "])
{
dstMessageId = [[v componentsSeparatedByString: @" "] lastObject];

// We mark the original message as deleted
response = [client storeFlags: [NSArray arrayWithObject: @"Deleted"]
forUIDs: [NSArray arrayWithObject: srcMessageId]
addOrRemove: YES];

if ([[response valueForKey: @"result"] boolValue])
[(SOGoMailFolder *)currentCollection expunge];

}
srcMessageId = [[(id)[aMoveOperation getElementsByTagName: @"SrcMsgId"] lastObject] textValue];
srcFolderId = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] realCollectionIdWithFolderType: &srcFolderType];
dstFolderId = [[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] realCollectionIdWithFolderType: &dstFolderType];

[s appendString: @"<Response>"];

if (!dstMessageId)
{
[theResponse setStatus: 500];
[theResponse appendContentString: @"Unable to move message"];
}
else
// FIXME - we should support moving events between calendars, for example, or
// or contacts between address books.
if (srcFolderType == ActiveSyncMailFolder && dstFolderType == ActiveSyncMailFolder)
{
NSMutableString *s;
NSData *d;
NGImap4Client *client;
id currentCollection;

//
// If the MoveItems operation is initiated by an Outlook client, we save the "deviceType+dstMessageId" to use it later in order to
// modify the Sync command from "add" to "change" (see SOGoActiveSyncDispatcher+Sync.m: -processSyncGetChanges: ...).
// This is to avoid Outlook creating dupes when moving messages across folfers.
//
if ([[context objectForKey: @"DeviceType"] isEqualToString: @"WindowsOutlook15"])
{
NSString *key;

// The key must be pretty verbose. We use the <uid>+<DeviceType>+<target folder>+<DstMsgId>
key = [NSString stringWithFormat: @"%@+%@+%@+%@",
[[context activeUser] login],
[context objectForKey: @"DeviceType"],
dstFolderId,
dstMessageId];


[[SOGoCache sharedCache] setValue: @"MovedItem"
forKey: key];
}

NSDictionary *response;
NSString *v;

// Everything is alright, lets return the proper response. "Status == 3" means success.
s = [NSMutableString string];
currentCollection = [self collectionFromId: srcFolderId type: srcFolderType];

[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<MoveItems xmlns=\"Move:\">"];
[s appendString: @"<Response>"];
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
[s appendFormat: @"<DstMsgId>%@</DstMsgId>", dstMessageId];
[s appendFormat: @"<Status>%d</Status>", 3];
[s appendString: @"</Response>"];
[s appendString: @"</MoveItems>"];
client = [[currentCollection imap4Connection] client];
[client select: srcFolderId];
response = [client copyUid: [srcMessageId intValue]
toFolder: [NSString stringWithFormat: @"/%@", dstFolderId]];

d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
// We extract the destionation message id
dstMessageId = nil;

[theResponse setContent: d];
if ([[response objectForKey: @"result"] boolValue]
&& (v = [[[response objectForKey: @"RawResponse"] objectForKey: @"ResponseResult"] objectForKey: @"flag"])
&& [v hasPrefix: @"COPYUID "])
{
dstMessageId = [[v componentsSeparatedByString: @" "] lastObject];

// We mark the original message as deleted
response = [client storeFlags: [NSArray arrayWithObject: @"Deleted"]
forUIDs: [NSArray arrayWithObject: srcMessageId]
addOrRemove: YES];

if ([[response valueForKey: @"result"] boolValue])
[(SOGoMailFolder *)currentCollection expunge];

}

if (!dstMessageId)
{
// FIXME: should we return 1 or 2 here?
[s appendFormat: @"<Status>%d</Status>", 2];
}
else
{
//
// If the MoveItems operation is initiated by an Outlook client, we save the "deviceType+dstMessageId" to use it later in order to
// modify the Sync command from "add" to "change" (see SOGoActiveSyncDispatcher+Sync.m: -processSyncGetChanges: ...).
// This is to avoid Outlook creating dupes when moving messages across folfers.
//
if ([[context objectForKey: @"DeviceType"] isEqualToString: @"WindowsOutlook15"])
{
NSString *key;

// The key must be pretty verbose. We use the <uid>+<DeviceType>+<target folder>+<DstMsgId>
key = [NSString stringWithFormat: @"%@+%@+%@+%@",
[[context activeUser] login],
[context objectForKey: @"DeviceType"],
dstFolderId,
dstMessageId];


[[SOGoCache sharedCache] setValue: @"MovedItem"
forKey: key];
}

// Everything is alright, lets return the proper response. "Status == 3" means success.
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
[s appendFormat: @"<DstMsgId>%@</DstMsgId>", dstMessageId];
[s appendFormat: @"<Status>%d</Status>", 3];
}

}
else
{
// Non-mail move operations - unsupported for now.
[s appendFormat: @"<Status>%d</Status>", 1];
}

[s appendString: @"</Response>"];
}
else
{
[theResponse setStatus: 500];
[theResponse appendContentString: @"Unsupported move operation"];
}


[s appendString: @"</MoveItems>"];

d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];

[theResponse setContent: d];
}

//
Expand Down
18 changes: 18 additions & 0 deletions ActiveSync/SOGoMailObject+ActiveSync.m
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,16 @@ - (NSString *) activeSyncRepresentationInContext: (WOContext *) _context
//
//
//
// Exemple for a message being marked as read:
//
// <Change>
// <ServerId>607</ServerId>
// <ApplicationData>
// <Read xmlns="Email:">1</Read>
// </ApplicationData>
// </Change>
// </Commands>
//
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) _context
{
Expand All @@ -776,6 +786,14 @@ - (void) takeActiveSyncValues: (NSDictionary *) theValues
else
[self removeFlags: @"\\Flagged"];
}

if ((o = [theValues objectForKey: @"Read"]))
{
if ([o intValue])
[self addFlags: @"seen"];
else
[self removeFlags: @"seen"];;
}
}

@end
10 changes: 4 additions & 6 deletions ActiveSync/common.make
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# common make file for SoObject bundles

include ../config.make
include $(GNUSTEP_MAKEFILES)/common.make
include ../Version
Expand All @@ -18,10 +16,10 @@ ADDITIONAL_INCLUDE_DIRS += \
-I../../SOPE

ADDITIONAL_LIB_DIRS += \
-L../SOGo/SOGo.framework/ \
-L../../SOGo/$(GNUSTEP_OBJ_DIR)/ \
-L../../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ \
-L../../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \
-L../SoObjects/SOGo/SOGo.framework/ \
-L../SoObjects/SOGo/$(GNUSTEP_OBJ_DIR)/ \
-L../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ \
-L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \
-L/usr/local/lib

BUNDLE_LIBS += \
Expand Down
46 changes: 46 additions & 0 deletions ActiveSync/iCalAlarm+ActiveSync.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright (c) 2014, Inverse inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Inverse inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ICALALARMACTIVESYNC_H__
#define __ICALALARMACTIVESYNC_H__

#import <NGCards/iCalAlarm.h>

@class NSString;
@class WOContext;

@interface iCalAlarm (ActiveSync)

- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
- (void) takeActiveSyncValues: (NSDictionary *) theValues
inContext: (WOContext *) context;

@end

#endif
Loading

0 comments on commit 48f98ef

Please sign in to comment.