Initial Active Sync Support!

pull/17/merge
Ludovic Marcotte 2014-01-10 14:12:53 -05:00
parent 7355eae1dc
commit e5bc46710c
33 changed files with 3908 additions and 0 deletions

View File

@ -0,0 +1,30 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import <Foundation/NSObject.h>
@interface ActiveSyncProduct : NSObject
{
}
@end
@implementation ActiveSyncProduct
@end /* ActiveSyncProduct */

View File

@ -0,0 +1,37 @@
# GNUstep makefile
include common.make
BUNDLE_NAME = ActiveSync
ActiveSync_PRINCIPAL_CLASS = ActiveSyncProduct
ActiveSync_OBJC_FILES = \
ActiveSyncProduct.m \
iCalEvent+ActiveSync.m \
iCalTimeZone+ActiveSync.m \
iCalToDo+ActiveSync.m \
NSData+ActiveSync.m \
NSDate+ActiveSync.m \
NGDOMElement+ActiveSync.m \
NGMimeMessage+ActiveSync.m \
NGVCard+ActiveSync.m \
NSString+ActiveSync.m \
SOGoActiveSyncDispatcher.m \
SOGoActiveSyncDispatcher+Sync.m \
SOGoMailObject+ActiveSync.m \
SoObjectWebDAVDispatcher+ActiveSync.m
ActiveSync_RESOURCE_FILES += \
product.plist
ADDITIONAL_OBJCFLAGS += -Wno-deprecated-declarations
ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/ -I../SoObjects/
ADDITIONAL_LIB_DIRS += -L../../SOPE/GDLContentStore/obj/
ADDITIONAL_INCLUDE_DIRS += -I/usr/local/include/libwbxml-1.0/wbxml/
ADDITIONAL_LDFLAGS += -Wl,--no-as-needed -lwbxml2
-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/bundle.make
-include GNUmakefile.postamble

View File

@ -0,0 +1 @@
# compilation settings

12
ActiveSync/LICENSE 100644
View File

@ -0,0 +1,12 @@
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.

View File

@ -0,0 +1,34 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __NGDOMELEMENTACTIVESYNC_H__
#define __NGDOMELEMENTACTIVESYNC_H__
#import <DOM/DOMElement.h>
#import <DOM/DOMProtocols.h>
@class NSDictionary;
@interface NGDOMElement (ActiveSync)
- (NSDictionary *) applicationData;
@end
#endif // NGDOMELEMENTACTIVESYNC

View File

@ -0,0 +1,73 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#include "NGDOMElement+ActiveSync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
@implementation NGDOMElement (ActiveSync)
//
// We must handle "inner data" like this:
//
// <ApplicationData>
// <Flag xmlns="Email:">
// <FlagStatus>2</FlagStatus>
// <FlagType>Flag for follow up</FlagType>
// </Flag>
// </ApplicationData>
//
- (NSDictionary *) applicationData
{
NSMutableDictionary *data;
id <DOMNodeList> children;
id <DOMElement> element;
int i;
data = [NSMutableDictionary dictionary];
children = [self childNodes];
for (i = 0; i < [children length]; i++)
{
element = [children objectAtIndex: i];
if ([element nodeType] == DOM_ELEMENT_NODE)
{
NSString *tag;
id value;
tag = [element tagName];
// Handle inner data
if ([(NSArray *)[element childNodes] count] > 2)
value = [(NGDOMElement *)element applicationData];
else
value = [[element firstChild] nodeValue];
if (value && tag)
[data setObject: value forKey: tag];
}
}
return data;
}
@end

View File

@ -0,0 +1,33 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __NGMIMEMESSAGEACTIVESYNC_H__
#define __NGMIMEMESSAGEACTIVESYNC_H__
#import <NGMail/NGMimeMessage.h>
@class NSArray;
@interface NGMimeMessage (ActiveSync)
- (NSArray *) allRecipients;
@end
#endif

View File

@ -0,0 +1,52 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import "NGMimeMessage+ActiveSync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <SOGo/NSString+Utilities.h>
@implementation NGMimeMessage (ActiveSync)
- (NSArray *) allRecipients
{
NSMutableArray *recipients;
NSEnumerator *enumerator;
NSString *s;
recipients = [NSMutableArray array];
enumerator = [[self headersForKey: @"to"] objectEnumerator];
while ((s = [enumerator nextObject]))
{
[recipients addObject: [s pureEMailAddress]];
}
enumerator = [[self headersForKey: @"cc"] objectEnumerator];
while ((s = [enumerator nextObject]))
{
[recipients addObject: [s pureEMailAddress]];
}
return recipients;
}
@end

View File

@ -0,0 +1,35 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __NGVCARDACTIVESYNC_H__
#define __NGVCARDACTIVESYNC_H__
#import <NGCards/NGVCard.h>
@class NSDictionary;
@class NSString;
@interface NGVCard (ActiveSync)
- (NSString *) activeSyncRepresentation;
- (void) takeActiveSyncValues: (NSDictionary *) theValues;
@end
#endif

View File

@ -0,0 +1,92 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import "NGVCard+ActiveSync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGCards/CardElement.h>
@implementation NGVCard (ActiveSync)
- (NSString *) activeSyncRepresentation
{
NSString *firstName, *lastName;
NSMutableString *s;
CardElement *n;
s = [NSMutableString string];
n = [self n];
lastName = [n flattenedValueAtIndex: 0 forKey: @""];
[s appendFormat: @"<LastName xmlns=\"Contacts:\">%@</LastName>", lastName];
firstName = [n flattenedValueAtIndex: 1 forKey: @""];
[s appendFormat: @"<FirstName xmlns=\"Contacts:\">%@</FirstName>", firstName];
return s;
}
- (void) takeActiveSyncValues: (NSDictionary *) theValues
{
id o;
if ((o = [theValues objectForKey: @"CompanyName"]))
{
[self setOrg: o units: nil];
}
if ((o = [theValues objectForKey: @"Email1Address"]))
{
[self addEmail: o types: [NSArray arrayWithObject: @"pref"]];
}
if ((o = [theValues objectForKey: @"Email2Address"]))
{
[self addEmail: o types: nil];
}
if ((o = [theValues objectForKey: @"Email3Address"]))
{
[self addEmail: o types: nil];
}
[self setNWithFamily: [theValues objectForKey: @"LastName"]
given: [theValues objectForKey: @"FirstName"]
additional: nil prefixes: nil suffixes: nil];
if ((o = [theValues objectForKey: @"MobilePhoneNumber"]))
{
}
if ((o = [theValues objectForKey: @"Title"]))
{
[self setTitle: o];
}
if ((o = [theValues objectForKey: @"WebPage"]))
{
}
}
@end

View File

@ -0,0 +1,32 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __NSDATAACTIVESYNC_H__
#define __NSDATAACTIVESYNC_H__
#import <Foundation/NSData.h>
@interface NSData (ActiveSync)
- (NSData *) wbxml2xml;
- (NSData *) xml2wbxml;
@end
#endif

View File

@ -0,0 +1,111 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import "NSData+ActiveSync.h"
#import <Foundation/NSString.h>
#include <wbxml.h>
#include <wbxml_conv.h>
#include <wbxml_errors.h>
@implementation NSData (ActiveSync)
- (NSData *) wbxml2xml
{
WBXMLGenXMLParams params;
NSData *data;
unsigned int wbxml_len, xml_len, ret;
unsigned char *wbxml, *xml;
wbxml = (unsigned char*)[self bytes];
wbxml_len = [self length];
xml = NULL;
xml_len = 0;
params.lang = WBXML_LANG_ACTIVESYNC;
params.gen_type = WBXML_GEN_XML_INDENT;
params.indent = 1;
params.keep_ignorable_ws = FALSE;
ret = wbxml_conv_wbxml2xml_withlen(wbxml, wbxml_len, &xml, &xml_len, &params);
if (ret != WBXML_OK)
{
NSLog(@"wbxml2xmlFromContent: failed: %s\n", wbxml_errors_string(ret));
return nil;
}
data = [[NSData alloc] initWithBytes: xml length: xml_len];
[data writeToFile: @"/tmp/protocol.decoded" atomically: YES];
free(xml);
return AUTORELEASE(data);
}
- (NSData *) xml2wbxml
{
WBXMLConvXML2WBXML *conv;
NSData *data;
unsigned int wbxml_len, xml_len, ret;
unsigned char *wbxml, *xml;
xml = (unsigned char*)[self bytes];
xml_len = [self length];
wbxml = NULL;
wbxml_len = 0;
conv = NULL;
ret = wbxml_conv_xml2wbxml_create(&conv);
if (ret != WBXML_OK)
{
NSLog(@"xml2wbxmlFromContent: failed: %s\n", wbxml_errors_string(ret));
return nil;
}
wbxml_conv_xml2wbxml_enable_preserve_whitespaces(conv);
// From libwbxml's changelog in v0.11.0: "The public ID is set to unknown and the DTD is not included. This is required for Microsoft ActiveSync."
wbxml_conv_xml2wbxml_disable_public_id(conv);
wbxml_conv_xml2wbxml_disable_string_table(conv);
ret = wbxml_conv_xml2wbxml_run(conv, xml, xml_len, &wbxml, &wbxml_len);
if (ret != WBXML_OK)
{
NSLog(@"xml2wbxmlFromContent: failed: %s\n", wbxml_errors_string(ret));
free(wbxml);
wbxml_conv_xml2wbxml_destroy(conv);
return nil;
}
data = [[NSData alloc] initWithBytes: wbxml length: wbxml_len];
[data writeToFile: @"/tmp/protocol.encoded" atomically: YES];
free(wbxml);
wbxml_conv_xml2wbxml_destroy(conv);
return AUTORELEASE(data);
}
@end

View File

@ -0,0 +1,33 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __NSDATEACTIVESYNC_H__
#define __NSDATEACTIVESYNC_H__
#import <Foundation/NSDate.h>
@class NSString;
@interface NSDate (ActiveSync)
- (NSString *) activeSyncRepresentation;
@end
#endif

View File

@ -0,0 +1,32 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import "NSDate+ActiveSync.h"
#import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>
@implementation NSDate (ActiveSync)
- (NSString *) activeSyncRepresentation
{
return [self descriptionWithCalendarFormat: @"%Y%m%dT%H%M%SZ" timeZone: [NSTimeZone timeZoneWithName: @"GMT"] locale: nil];
}
@end

View File

@ -0,0 +1,38 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __NSSTRINGACTIVESYNC_H__
#define __NSSTRINGACTIVESYNC_H__
#import <Foundation/NSString.h>
#include "SOGoActiveSyncConstants.h"
@class NSCalendarDate;
@interface NSString (ActiveSync)
- (int) activeSyncFolderType;
- (NSString *) realCollectionIdWithFolderType: (SOGoMicrosoftActiveSyncFolderType *) folderType;
- (NSCalendarDate *) calendarDate;
- (NSString *) deviceId;
@end
#endif

View File

@ -0,0 +1,113 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#include "NSString+ActiveSync.h"
#include <Foundation/NSArray.h>
#include <Foundation/NSCalendarDate.h>
#include <Foundation/NSDate.h>
@implementation NSString (ActiveSync)
- (int) activeSyncFolderType
{
if ([self isEqualToString: @"inbox"])
return 2;
else if ([self isEqualToString: @"draft"])
return 3;
else if ([self isEqualToString: @"sent"])
return 5;
else if ([self isEqualToString: @"trash"])
return 4;
return 12;
}
- (NSString *) realCollectionIdWithFolderType: (SOGoMicrosoftActiveSyncFolderType *) folderType;
{
NSString *realCollectionId;
*folderType = ActiveSyncGenericFolder;
if ([self hasPrefix: @"vevent/"])
{
realCollectionId = [self substringFromIndex: 7];
*folderType = ActiveSyncEventFolder;
}
else if ([self hasPrefix: @"vtodo/"])
{
realCollectionId = [self substringFromIndex: 6];
*folderType = ActiveSyncTaskFolder;
}
else if ([self hasPrefix: @"vcard/"])
{
realCollectionId = [self substringFromIndex: 6];
*folderType = ActiveSyncContactFolder;
}
else
{
// mail/
realCollectionId = [self substringFromIndex: 5];
*folderType = ActiveSyncMailFolder;
}
return realCollectionId;
}
//
// 2014-01-16T05:00:00.000Z
//
// See http://www.gnustep.org/resources/documentation/Developer/Base/Reference/NSCalendarDate.html#method$NSCalendarDate-initWithString$calendarFormat$ for the format details.
//
- (NSCalendarDate *) calendarDate
{
id o;
o = [NSCalendarDate dateWithString: self calendarFormat: @"%Y%m%dT%H%M%SZ"];
if (!o)
o = [NSCalendarDate dateWithString: self calendarFormat: @"%Y-%m-%dT%H:%M:%S.%FZ"];
return o;
}
//
// This method extracts the "DeviceId" from a URI:
//
// /SOGo/Microsoft-Server-ActiveSync?Cmd=FolderSync&User=sogo10&DeviceId=SEC17CD1A3E9E3F2&DeviceType=SAMSUNGSGHI317M
//
- (NSString *) deviceId
{
NSArray *components;
NSString *s;
int i;
components = [[[self componentsSeparatedByString: @"/"] lastObject] componentsSeparatedByString: @"&"];
for (i = 0; i < [components count]; i++)
{
s = [components objectAtIndex: i];
if ([[s uppercaseString] hasPrefix: @"DEVICEID="])
return [s substringFromIndex: 9];
}
return @"Unknown";
}
@end

View File

@ -0,0 +1,6 @@
In order to use this software in production environments, you need to
get a proper usage license from Microsoft. Please contact them directly
to negotiate the fees associated to your user base.
Inverse inc. provides this software for free, but is not responsible
for anything related to its usage.

View File

@ -0,0 +1,32 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __SOGOACTIVESYNCCONSTANTS_H__
#define __SOGOACTIVESYNCCONSTANTS_H__
typedef enum
{
ActiveSyncGenericFolder = 0,
ActiveSyncMailFolder = 1,
ActiveSyncContactFolder = 2,
ActiveSyncEventFolder = 3,
ActiveSyncTaskFolder = 4,
} SOGoMicrosoftActiveSyncFolderType;
#endif

View File

@ -0,0 +1,37 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __SOGOACTIVESYNCDISPATCHERSYNC_H__
#define __SOGOACTIVESYNCDISPATCHERSYNC_H__
#import "SOGoActiveSyncDispatcher.h"
#import <DOM/DOMElement.h>
#import <DOM/DOMProtocols.h>
@class WOResponse;
@interface SOGoActiveSyncDispatcher (Sync)
- (void) processSync: (id <DOMElement>) theDocumentElement
inResponse: (WOResponse *) theResponse;
@end
#endif // SOGOACTIVESYNCDISPATCHERSYNC

View File

@ -0,0 +1,910 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import "SOGoActiveSyncDispatcher+Sync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSTimeZone.h>
#import <Foundation/NSURL.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoApplication.h>
#import <NGObjWeb/SoObject.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WOCookie.h>
#import <NGObjWeb/WODirectAction.h>
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
#import <NGCards/iCalEntityObject.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalToDo.h>
#import <NGCards/NGVCard.h>
#import <NGExtensions/NSCalendarDate+misc.h>
#import <NGExtensions/NSString+misc.h>
#import <NGImap4/NSString+Imap4.h>
#import <NGMime/NGMimeBodyPart.h>
#import <NGMime/NGMimeMultipartBody.h>
#import <NGMail/NGMimeMessageParser.h>
#import <NGMail/NGMimeMessage.h>
#import <NGMail/NGMimeMessageGenerator.h>
#import <DOM/DOMElement.h>
#import <DOM/DOMProtocols.h>
#import <EOControl/EOQualifier.h>
#import <SOGo/NSArray+DAV.h>
#import <SOGo/NSDictionary+DAV.h>
#import <SOGo/SOGoDAVAuthenticator.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoMailer.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserSettings.h>
#import <Appointments/SOGoAppointmentObject.h>
#import <Appointments/SOGoAppointmentFolder.h>
#import <Appointments/SOGoAppointmentFolders.h>
#import <Appointments/SOGoTaskObject.h>
#import <Contacts/SOGoContactGCSEntry.h>
#import <Contacts/SOGoContactGCSFolder.h>
#import <Contacts/SOGoContactFolders.h>
#import <Contacts/SOGoContactSourceFolder.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailAccounts.h>
#import <Mailer/SOGoMailObject.h>
#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#include "iCalEvent+ActiveSync.h"
#include "iCalToDo+ActiveSync.h"
#include "NGDOMElement+ActiveSync.h"
#include "NGVCard+ActiveSync.h"
#include "NSData+ActiveSync.h"
#include "NSString+ActiveSync.h"
#include "SOGoActiveSyncConstants.h"
#include "SOGoMailObject+ActiveSync.h"
@implementation SOGoActiveSyncDispatcher (Sync)
- (id) collectionFromId: (NSString *) theCollectionId
type: (SOGoMicrosoftActiveSyncFolderType) theFolderType
{
id collection;
collection = nil;
switch (theFolderType)
{
case ActiveSyncContactFolder:
{
collection = [[context activeUser] personalContactsFolderInContext: context];
}
break;
case ActiveSyncEventFolder:
case ActiveSyncTaskFolder:
{
collection = [[context activeUser] personalCalendarFolderInContext: context];
}
break;
case ActiveSyncMailFolder:
default:
{
SOGoMailAccounts *accountsFolder;
SOGoMailFolder *currentFolder;
SOGoUserFolder *userFolder;
userFolder = [[context activeUser] homeFolderInContext: context];
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];
collection = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", theCollectionId]
inContext: context
acquire: NO];
}
}
return collection;
}
//
// <?xml version="1.0"?>
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
// <Sync xmlns="AirSync:">
// <Collections>
// <Collection>
// <SyncKey>1388757902</SyncKey>
// <CollectionId>vcard/personal</CollectionId>
// <GetChanges/>
// <WindowSize>25</WindowSize>
// <Options>
// <BodyPreference xmlns="AirSyncBase:">
// <Type>1</Type>
// <TruncationSize>32768</TruncationSize>
// </BodyPreference>
// </Options>
// <Commands>
// <Add>
// <ClientId>16</ClientId>
// <ApplicationData>
// <Body xmlns="AirSyncBase:">
// <Type>1</Type>
// <Data/>
// </Body>
// <CompanyName xmlns="Contacts:">Goo Inc.</CompanyName>
// <Email1Address xmlns="Contacts:">annie@broccoli.com</Email1Address>
// <FileAs xmlns="Contacts:">Broccoli, Annie</FileAs>
// <FirstName xmlns="Contacts:">Annie</FirstName>
// <LastName xmlns="Contacts:">Broccoli</LastName>
// <Picture xmlns="Contacts:"/>
// </ApplicationData>
// </Add>
// </Commands>
// </Collection>
// </Collections>
// </Sync>
//
- (void) processSyncAddCommand: (id <DOMElement>) theDocumentElement
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
{
NSArray *additions;
NSString *clientId, *serverId;
NSDictionary *allValues;
id anAddition, sogoObject, o;
int i;
additions = (id)[theDocumentElement getElementsByTagName: @"Add"];
if ([additions count])
{
for (i = 0; i < [additions count]; i++)
{
anAddition = [additions objectAtIndex: i];
clientId = [[(id)[anAddition getElementsByTagName: @"CientId"] lastObject] textValue];
allValues = [[(id)[anAddition getElementsByTagName: @"ApplicationData"] lastObject] applicationData];
switch (theFolderType)
{
case ActiveSyncContactFolder:
{
serverId = [NSString stringWithFormat: @"%@.vcf", [theCollection globallyUniqueObjectId]];
sogoObject = [[SOGoContactGCSEntry alloc] initWithName: serverId
inContainer: theCollection];
o = [sogoObject vCard];
}
break;
case ActiveSyncEventFolder:
{
serverId = [NSString stringWithFormat: @"%@.ics", [theCollection globallyUniqueObjectId]];
sogoObject = [[SOGoAppointmentObject alloc] initWithName: serverId
inContainer: theCollection];
o = [sogoObject component: YES secure: NO];
}
break;
case ActiveSyncTaskFolder:
{
serverId = [NSString stringWithFormat: @"%@.ics", [theCollection globallyUniqueObjectId]];
sogoObject = [[SOGoTaskObject alloc] initWithName: serverId
inContainer: theCollection];
o = [sogoObject component: YES secure: NO];
}
break;
case ActiveSyncMailFolder:
default:
{
// FIXME
continue;
}
}
[o takeActiveSyncValues: allValues];
[sogoObject saveComponent: o];
// Everything is fine, lets generate our response
[theBuffer appendString: @"<Add>"];
[theBuffer appendFormat: @"<ClientId>%@</ClientId>", clientId];
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", serverId];
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
[theBuffer appendString: @"</Add>"];
}
}
}
//
// <?xml version="1.0"?>
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
// <Sync xmlns="AirSync:">
// <Collections>
// <Collection>
// <SyncKey>1387546048</SyncKey>
// <CollectionId>vtodo/personal</CollectionId>
// <GetChanges/>
// <WindowSize>25</WindowSize>
// <Options>
// <BodyPreference xmlns="AirSyncBase:">
// <Type>1</Type>
// <TruncationSize>32768</TruncationSize>
// </BodyPreference>
// </Options>
// <Commands>
// <Change>
// <ServerId>36C5-52B36280-1-27B38F40.ics</ServerId>
// <ApplicationData>
// <Body xmlns="AirSyncBase:">
// <Type>1</Type>
// <Data/>
// </Body>
// <Subject xmlns="Tasks:">foobar1</Subject>
// <Importance xmlns="Tasks:">1</Importance>
// <Complete xmlns="Tasks:">0</Complete>
// <Sensitivity xmlns="Tasks:">0</Sensitivity>
// <ReminderSet xmlns="Tasks:">0</ReminderSet>
// </ApplicationData>
// </Change>
// </Commands>
// </Collection>
// </Collections>
// </Sync>
//
- (void) processSyncChangeCommand: (id <DOMElement>) theDocumentElement
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
{
NSDictionary *allChanges;
NSString *serverId;
NSArray *changes;
id aChange, o, sogoObject;
int i;
changes = (id)[theDocumentElement getElementsByTagName: @"Change"];
if ([changes count])
{
for (i = 0; i < [changes count]; i++)
{
aChange = [changes objectAtIndex: i];
serverId = [[(id)[aChange getElementsByTagName: @"ServerId"] lastObject] textValue];
allChanges = [[(id)[aChange getElementsByTagName: @"ApplicationData"] lastObject] applicationData];
// Fetch the object and apply the changes
sogoObject = [theCollection lookupName: serverId
inContext: context
acquire: NO];
switch (theFolderType)
{
case ActiveSyncContactFolder:
{
o = [sogoObject vCard];
[o takeActiveSyncValues: allChanges];
[sogoObject saveComponent: o];
}
break;
case ActiveSyncEventFolder:
case ActiveSyncTaskFolder:
{
o = [sogoObject component: NO secure: NO];
[o takeActiveSyncValues: allChanges];
[sogoObject saveComponent: o];
}
break;
case ActiveSyncMailFolder:
default:
{
[sogoObject takeActiveSyncValues: allChanges];
}
}
}
}
}
//
// <?xml version="1.0"?>
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
// <Sync xmlns="AirSync:">
// <Collections>
// <Collection>
// <SyncKey>1388764784</SyncKey>
// <CollectionId>vtodo/personal</CollectionId>
// <GetChanges/>
// <WindowSize>25</WindowSize>
// <Options>
// <BodyPreference xmlns="AirSyncBase:">
// <Type>1</Type>
// <TruncationSize>32768</TruncationSize>
// </BodyPreference>
// </Options>
// <Commands>
// <Delete>
// <ServerId>2CB5-52B36080-1-1C1D0240.ics</ServerId>
// </Delete>
// </Commands>
// </Collection>
// </Collections>
// </Sync>
//
- (void) processSyncDeleteCommand: (id <DOMElement>) theDocumentElement
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
{
NSArray *deletions;
NSString *serverId;
id aDelete, sogoObject;
int i;
deletions = (id)[theDocumentElement getElementsByTagName: @"Delete"];
if ([deletions count])
{
for (i = 0; i < [deletions count]; i++)
{
aDelete = [deletions objectAtIndex: i];
serverId = [[(id)[aDelete getElementsByTagName: @"ServerId"] lastObject] textValue];
sogoObject = [theCollection lookupName: serverId
inContext: context
acquire: NO];
[sogoObject delete];
}
}
}
//
// <Fetch>
// <ServerId>91</ServerId>
// </Fetch>
//
- (void) processSyncFetchCommand: (id <DOMElement>) theDocumentElement
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
{
NSString *serverId;
id o;
serverId = [[(id)[theDocumentElement getElementsByTagName: @"ServerId"] lastObject] textValue];
o = [theCollection lookupName: serverId
inContext: context
acquire: NO];
// FIXME - error handling
[theBuffer appendString: @"<Fetch>"];
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", serverId];
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
[theBuffer appendString: @"<ApplicationData>"];
[theBuffer appendString: [o activeSyncRepresentation]];
[theBuffer appendString: @"</ApplicationData>"];
[theBuffer appendString: @"</Fetch>"];
}
//
// The method handles <GetChanges/>
//
- (void) processSyncGetChanges: (id <DOMElement>) theDocumentElement
inCollection: (id) theCollection
withSyncKey: (NSString *) theSyncKey
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
{
int i;
//
// No changes in the collection - 2.2.2.19.1.1 Empty Sync Request.
// We check this and we don't generate any commands if we don't have to.
//
if ([theSyncKey isEqualToString: [theCollection davCollectionTag]])
return;
[theBuffer appendString: @"<Commands>"];
switch (theFolderType)
{
case ActiveSyncContactFolder:
{
NSArray *allContacts;
NGVCard *card;
id contact;
allContacts = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey];
for (i = 0; i < [allContacts count]; i++)
{
contact = [theCollection lookupName: [[allContacts objectAtIndex: i] objectForKey: @"c_name"]
inContext: context
acquire: NO];
if (![[[allContacts objectAtIndex: i] objectForKey: @"c_component"] isEqualToString: @"vcard"])
continue;
// FIXME: we skip list right now
if ([contact respondsToSelector: @selector (vCard)])
{
card = [contact vCard];
[theBuffer appendString: @"<Add xmlns=\"AirSync:\">"];
[theBuffer appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", [contact nameInContainer]];
[theBuffer appendString: @"<ApplicationData xmlns=\"AirSync:\">"];
[theBuffer appendString: [card activeSyncRepresentation]];
[theBuffer appendString: @"</ApplicationData>"];
[theBuffer appendString: @"</Add>"];
}
}
}
break;
case ActiveSyncEventFolder:
{
NSArray *allEvents;
NSDictionary *d;
id eventObject;
allEvents = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey];
for (i = 0; i < [allEvents count]; i++)
{
NSString *serverId;
iCalEvent *event;
d = [allEvents objectAtIndex: i];
if (![[d objectForKey: @"c_component"] isEqualToString: @"vevent"])
continue;
serverId = [d objectForKey: @"c_name"];
[theBuffer appendString: @"<Add xmlns=\"AirSync:\">"];
[theBuffer appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", serverId];
[theBuffer appendString: @"<ApplicationData xmlns=\"AirSync:\">"];
eventObject = [theCollection lookupName: serverId inContext: self->context acquire: 0];
event = [eventObject component: NO secure: NO];
[theBuffer appendString: [event activeSyncRepresentation]];
[theBuffer appendString: @"</ApplicationData>"];
[theBuffer appendString: @"</Add>"];
} // for (i = 0; i < [allEvents count]; i++)
}
break;
case ActiveSyncTaskFolder:
{
NSArray *allTasks;
NSDictionary *task;
id taskObject;
allTasks = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey];
for (i = 0; i < [allTasks count]; i++)
{
int deleted;
task = [allTasks objectAtIndex: i];
deleted = [[task objectForKey: @"c_deleted"] intValue];
if (!deleted && ![[task objectForKey: @"c_component"] isEqualToString: @"vtodo"])
continue;
NSString *uid;
uid = [task objectForKey: @"c_name"];
if (deleted)
{
[theBuffer appendString: @"<Delete xmlns=\"AirSync:\">"];
[theBuffer appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", uid];
[theBuffer appendString: @"</Delete>"];
}
else
{
iCalToDo *todo;
BOOL updated;
updated = YES;
if ([[task objectForKey: @"c_creationdate"] intValue] > [theSyncKey intValue])
updated = NO;
if (updated)
[theBuffer appendString: @"<Change xmlns=\"AirSync:\">"];
else
[theBuffer appendString: @"<Add xmlns=\"AirSync:\">"];
[theBuffer appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", uid];
[theBuffer appendString: @"<ApplicationData xmlns=\"AirSync:\">"];
taskObject = [theCollection lookupName: uid inContext: self->context acquire: 0];
todo = [taskObject component: NO secure: NO];
[theBuffer appendString: [todo activeSyncRepresentation]];
[theBuffer appendString: @"</ApplicationData>"];
if (updated)
[theBuffer appendString: @"</Change>"];
else
[theBuffer appendString: @"</Add>"];
}
} // for ...
}
break;
case ActiveSyncMailFolder:
default:
{
NSDictionary *aMessage;
NSArray *allMessages;
NSString *uid, *command;
SOGoMailObject *mailObject;
allMessages = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey];
for (i = 0; i < [allMessages count]; i++)
{
aMessage = [allMessages objectAtIndex: i];
uid = [[[aMessage allKeys] lastObject] stringValue];
command = [[aMessage allValues] lastObject];
if ([command isEqualToString: @"deleted"])
{
[theBuffer appendString: @"<Delete xmlns=\"AirSync:\">"];
[theBuffer appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", uid];
[theBuffer appendString: @"</Delete>"];
}
else
{
if ([command isEqualToString: @"added"])
[theBuffer appendString: @"<Add xmlns=\"AirSync:\">"];
else
[theBuffer appendString: @"<Change xmlns=\"AirSync:\">"];
mailObject = [theCollection lookupName: uid
inContext: context
acquire: 0];
[theBuffer appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", uid];
[theBuffer appendString: @"<ApplicationData xmlns=\"AirSync:\">"];
[theBuffer appendString: [mailObject activeSyncRepresentation]];
[theBuffer appendString: @"</ApplicationData>"];
if ([command isEqualToString: @"added"])
[theBuffer appendString: @"</Add>"];
else
[theBuffer appendString: @"</Change>"];
}
}
}
break;
} // switch (folderType) ...
[theBuffer appendString: @"</Commands>"];
}
//
// We have something like this:
//
// <Commands>
// <Fetch>
// <ServerId>91</ServerId>
// </Fetch>
// </Commands>
//
- (void) processSyncCommands: (id <DOMElement>) theDocumentElement
inCollection: (id) theCollection
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
processed: (BOOL *) processed
{
id <DOMNodeList> aCommandDetails;
id <DOMElement> aCommand, element;
NSArray *allCommands;
int i, j;
allCommands = (id)[theDocumentElement getElementsByTagName: @"Commands"];
for (i = 0; i < [allCommands count]; i++)
{
aCommand = [allCommands objectAtIndex: i];
aCommandDetails = [aCommand childNodes];
for (j = 0; j < [(id)aCommandDetails count]; j++)
{
element = [aCommandDetails objectAtIndex: j];
if ([element nodeType] == DOM_ELEMENT_NODE)
{
if ([[element tagName] isEqualToString: @"Add"])
{
// Add
[self processSyncAddCommand: aCommand
inCollection: theCollection
withType: theFolderType
inBuffer: theBuffer];
*processed = YES;
}
else if ([[element tagName] isEqualToString: @"Change"])
{
// Change
[self processSyncChangeCommand: aCommand
inCollection: theCollection
withType: theFolderType
inBuffer: theBuffer];
*processed = YES;
}
else if ([[element tagName] isEqualToString: @"Delete"])
{
// Delete
[self processSyncDeleteCommand: aCommand
inCollection: theCollection
withType: theFolderType
inBuffer: theBuffer];
}
else if ([[element tagName] isEqualToString: @"Fetch"])
{
// Fetch
[self processSyncFetchCommand: aCommand
inCollection: theCollection
withType: theFolderType
inBuffer: theBuffer];
}
}
}
}
}
//
//
//
- (void) processSyncCollection: (id <DOMElement>) theDocumentElement
inBuffer: (NSMutableString *) theBuffer
{
NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType;
SOGoMicrosoftActiveSyncFolderType folderType;
id collection;
BOOL getChanges, first_sync;
collectionId = [[(id)[theDocumentElement getElementsByTagName: @"CollectionId"] lastObject] textValue];
realCollectionId = [collectionId realCollectionIdWithFolderType: &folderType];
collection = [self collectionFromId: realCollectionId type: folderType];
syncKey = [[(id)[theDocumentElement getElementsByTagName: @"SyncKey"] lastObject] textValue];
davCollectionTag = [collection davCollectionTag];
getChanges = ([(id)[theDocumentElement getElementsByTagName: @"GetChanges"] count] ? YES : NO);
first_sync = NO;
if ([syncKey isEqualToString: @"0"])
{
davCollectionTag = @"-1";
first_sync = YES;
}
// We check our sync preferences and we stash them
bodyPreferenceType = [[(id)[[(id)[theDocumentElement getElementsByTagName: @"BodyPreference"] lastObject] getElementsByTagName: @"Type"] lastObject] textValue];
if (!bodyPreferenceType)
bodyPreferenceType = @"1";
[context setObject: bodyPreferenceType forKey: @"BodyPreferenceType"];
[theBuffer appendString: @"<Collection>"];
[theBuffer appendFormat: @"<SyncKey>%@</SyncKey>", davCollectionTag];
[theBuffer appendFormat: @"<CollectionId>%@</CollectionId>", collectionId];
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
// We generate the commands, if any, for the response. We might also have
// generated some in processSyncCommand:inResponse: as we could have
// received a Fetch command
if (getChanges && !first_sync)
{
[self processSyncGetChanges: theDocumentElement
inCollection: collection
withSyncKey: syncKey
withType: folderType
inBuffer: theBuffer];
}
//
// We process the commands from the request
//
if (!first_sync)
{
NSMutableString *s;
BOOL processed;
s = [NSMutableString string];
processed = NO;
[self processSyncCommands: theDocumentElement
inCollection: collection
withType: folderType
inBuffer: s
processed: &processed];
if (processed)
[theBuffer appendFormat: @"<Responses>%@</Responses>", s];
else
[theBuffer appendString: s];
}
[theBuffer appendString: @"</Collection>"];
}
//
// Initial folder sync:
//
// <?xml version="1.0"?>
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
// <Sync xmlns="AirSync:">
// <Collections>
// <Collection>
// <SyncKey>0</SyncKey>
// <CollectionId>folderINBOX</CollectionId>
// </Collection>
// </Collections>
// </Sync>
//
//
// Following this will be a GetItemEstimate call. Following our response to the GetItemEstimate, we'll
// have a new Sync call like this:
//
// <?xml version="1.0"?>
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
// <Sync xmlns="AirSync:">
// <Collections>
// <Collection>
// <SyncKey>1</SyncKey>
// <CollectionId>folderINBOX</CollectionId>
// <DeletesAsMoves>1</DeletesAsMoves>
// <GetChanges/>
// <WindowSize>50</WindowSize>
// <Options>
// <FilterType>5</FilterType> -- http://msdn.microsoft.com/en-us/library/gg709713(v=exchg.80).aspx
// <BodyPreference xmlns="AirSyncBase:"> -- http://msdn.microsoft.com/en-us/library/ee218197(v=exchg.80).aspx
// <Type>2</Type> --
// <TruncationSize>51200</TruncationSize>
// </BodyPreference>
// <BodyPreference xmlns="AirSyncBase:">
// <Type>4</Type>
// </BodyPreference>
// </Options>
// </Collection>
// </Collections>
// </Sync>
//
//
//
// When adding a new task, we might have something like this:
//
// <?xml version="1.0"?>
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
// <Sync xmlns="AirSync:">
// <Collections>
// <Collection>
// <SyncKey>1</SyncKey>
// <CollectionId>personal</CollectionId>
// <DeletesAsMoves/>
// <GetChanges/> -- http://msdn.microsoft.com/en-us/library/gg675447(v=exchg.80).aspx
// <WindowSize>5</WindowSize> -- http://msdn.microsoft.com/en-us/library/gg650865(v=exchg.80).aspx
// <Options>
// <BodyPreference xmlns="AirSyncBase:"> -- http://msdn.microsoft.com/en-us/library/ee218197(v=exchg.80).aspx
// <Type>1</Type>
// <TruncationSize>400000</TruncationSize>
// </BodyPreference>
// </Options>
// <Commands>
// <Add>
// <ClientId>new_task_1386614771261</ClientId>
// <ApplicationData>
// <Body xmlns="AirSyncBase:">
// <Type>1</Type>
// <EstimatedDataSize>6</EstimatedDataSize>
// <Data>tomate</Data>
// </Body>
// <Subject xmlns="Tasks:">test 1</Subject>
// <Importance xmlns="Tasks:">1</Importance>
// <UTCDueDate xmlns="Tasks:">2013-12-09T19:00:00.000Z</UTCDueDate>
// <Complete xmlns="Tasks:">0</Complete>
// <ReminderSet xmlns="Tasks:">0</ReminderSet>
// <DueDate xmlns="Tasks:">2013-12-09T19:00:00.000Z</DueDate>
// </ApplicationData>
// </Add>
// </Commands>
// </Collection>
// </Collections>
// </Sync>
//
// The algorithm here is pretty simple:
//
// 1. extract the list of collections
// 2. for each collection
// 2.1. extract the metadata (id, synckey, etc.)
// 2.2. extract the list of commands
// 2.3. for each command
// 2.3.1 process the command (add/change/delete/fetch)
// 2.3.2 build a response during the processsing
//
//
- (void) processSync: (id <DOMElement>) theDocumentElement
inResponse: (WOResponse *) theResponse
{
id <DOMElement> aCollection;
NSArray *allCollections;
NSMutableString *s;
NSData *d;
int i;
// We initialize our output buffer
s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<Sync xmlns=\"AirSync:\"><Collections>"];
allCollections = (id)[theDocumentElement getElementsByTagName: @"Collections"];
for (i = 0; i < [allCollections count]; i++)
{
aCollection = [allCollections objectAtIndex: i];
[self processSyncCollection: aCollection inBuffer: s];
}
[s appendString: @"</Collections></Sync>"];
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
[theResponse setContent: d];
}
@end

View File

@ -0,0 +1,33 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import <Foundation/NSObject.h>
@class NSException;
@interface SOGoActiveSyncDispatcher : NSObject
{
id context;
}
- (NSException *) dispatchRequest: (id) theRequest
inResponse: (id) theResponse
context: (id) theContext;
@end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __SOGOMAILOBJECTACTIVESYNC_H__
#define __SOGOMAILOBJECTACTIVESYNC_H__
#import <Mailer/SOGoMailObject.h>
@class NSDictionary;
@interface SOGoMailObject (ActiveSync)
- (NSString *) activeSyncRepresentation;
- (void) takeActiveSyncValues: (NSDictionary *) theValues;
@end
#endif

View File

@ -0,0 +1,296 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#include "SOGoMailObject+ActiveSync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGExtensions/NGBase64Coding.h>
#import <NGExtensions/NSString+misc.h>
#import <NGExtensions/NSString+Encoding.h>
#import <NGImap4/NGImap4Envelope.h>
#import <NGImap4/NGImap4EnvelopeAddress.h>
#include "NSDate+ActiveSync.h"
#include "../SoObjects/Mailer/NSString+Mail.h"
@implementation SOGoMailObject (ActiveSync)
- (NSString *) _baseEmailAddressesFrom: (NSArray *) enveloppeAddresses
{
NSMutableArray *addresses;
NSString *rc;
NGImap4EnvelopeAddress *address;
NSString *email;
int i, max;
rc = nil;
max = [enveloppeAddresses count];
if (max > 0)
{
addresses = [NSMutableArray array];
for (i = 0; i < max; i++)
{
address = [enveloppeAddresses objectAtIndex: i];
email = [NSString stringWithFormat: @"%@", [address baseEMail]];
[addresses addObject: email];
}
rc = [addresses componentsJoinedByString: @", "];
}
return rc;
}
//
//
//
- (NSData *) _preferredBodyDataInMultipartUsingType: (int) theType
{
NSString *key, *plainKey, *htmlKey, *type, *subtype;
NSDictionary *textParts, *part;
NSEnumerator *e;
NSData *d;
textParts = [self fetchPlainTextParts];
e = [textParts keyEnumerator];
plainKey = nil;
htmlKey = nil;
d = nil;
while ((key = [e nextObject]))
{
part = [self lookupInfoForBodyPart: key];
type = [part valueForKey: @"type"];
subtype = [part valueForKey: @"subtype"];
if ([type isEqualToString: @"text"] && [subtype isEqualToString: @"html"])
htmlKey = key;
else if ([type isEqualToString: @"text"] && [subtype isEqualToString: @"plain"])
plainKey = key;
}
if (theType == 2)
{
d = [[self fetchPlainTextParts] objectForKey: htmlKey];
}
else if (theType == 1)
{
d = [[self fetchPlainTextParts] objectForKey: plainKey];
}
return d;
}
//
//
//
- (NSData *) _preferredBodyDataUsingType: (int) theType
{
NSString *type, *subtype;
NSData *d;
type = [[[self bodyStructure] valueForKey: @"type"] lowercaseString];
subtype = [[[self bodyStructure] valueForKey: @"subtype"] lowercaseString];
d = nil;
if (theType == 1 || theType == 2)
{
if ([type isEqualToString: @"text"])
{
d = [[self fetchPlainTextParts] objectForKey: @""];
// Check if we must convert html->plain
if (theType == 1 && [subtype isEqualToString: @"html"])
{
NSString *s;
s = [[NSString alloc] initWithData: d encoding: NSUTF8StringEncoding];
AUTORELEASE(s);
s = [s htmlToText];
d = [s dataUsingEncoding: NSUTF8StringEncoding];
}
}
else if ([type isEqualToString: @"multipart"])
{
d = [self _preferredBodyDataInMultipartUsingType: theType];
}
}
else if (theType == 4)
{
d = [self content];
}
return d;
}
//
//
//
- (NSString *) activeSyncRepresentation
{
NSMutableString *s;
NSData *d;
id value;
int preferredBodyType;
s = [NSMutableString string];
// From
value = [self _baseEmailAddressesFrom: [[self envelope] from]];
if (value)
[s appendFormat: @"<From xmlns=\"Email:\">%@</From>", value];
// To - "The value of this element contains one or more e-mail addresses.
// If there are multiple e-mail addresses, they are separated by commas."
value = [self _baseEmailAddressesFrom: [[self envelope] to]];
if (value)
[s appendFormat: @"<To xmlns=\"Email:\">%@</To>", value];
// Cc - same syntax as the To field
value = [self _baseEmailAddressesFrom: [[self envelope] cc]];
if (value)
[s appendFormat: @"<Cc xmlns=\"Email:\">%@</Cc>", value];
// Subject
value = [self decodedSubject];
if (value)
[s appendFormat: @"<Subject xmlns=\"Email:\">%@</Subject>", value];
// DateReceived
value = [self date];
if (value)
[s appendFormat: @"<DateReceived xmlns=\"Email:\">%@</DateReceived>", [value activeSyncRepresentation]];;
// DisplayTo
//[s appendFormat: @"<DisplayTo xmlns=\"Email:\">\"%@\"</DisplayTo>", [[context activeUser] login]];
// Importance - FIXME
[s appendFormat: @"<Importance xmlns=\"Email:\">%@</Importance>", @"1"];
// Read
[s appendFormat: @"<Read xmlns=\"Email:\">%d</Read>", ([self read] ? 1 : 0)];
// MesssageClass
[s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note"];
// Reply-To - FIXME
//NSArray *replyTo = [[message objectForKey: @"envelope"] replyTo];
//if ([replyTo count])
// [s appendFormat: @"<Reply-To xmlns=\"Email:\">%@</Reply-To>", [addressFormatter stringForArray: replyTo]];
// InternetCPID - FIXME
[s appendFormat: @"<InternetCPID xmlns=\"Email:\">%@</InternetCPID>", @"65001"];
// Body - namespace 17
preferredBodyType = [[context objectForKey: @"BodyPreferenceType"] intValue];
d = [self _preferredBodyDataUsingType: preferredBodyType];
if (d)
{
NSString *content;
int len;
content = [[NSString alloc] initWithData: d encoding: NSUTF8StringEncoding];
AUTORELEASE(content);
content = [content stringByEscapingHTMLString];
len = [content length];
[s appendString: @"<Body xmlns=\"AirSyncBase:\">"];
[s appendFormat: @"<Type>%d</Type>", preferredBodyType];
[s appendFormat: @"<EstimatedDataSize>%d</EstimatedDataSize>", len];
[s appendFormat: @"<Truncated>%d</Truncated>", 0];
[s appendFormat: @"<Data>%@</Data>", content];
[s appendString: @"</Body>"];
}
// Attachments -namespace 16
NSArray *attachmentKeys = [self fetchFileAttachmentKeys];
if ([attachmentKeys count])
{
int i;
[s appendString: @"<Attachments xmlns=\"AirSyncBase:\">"];
for (i = 0; i < [attachmentKeys count]; i++)
{
value = [attachmentKeys objectAtIndex: i];
[s appendString: @"<Attachment>"];
[s appendFormat: @"<DisplayName>%@</DisplayName>", [value objectForKey: @"filename"]];
// FileReference must be a unique identifier across the whole store. We use the following structure:
// mail/<foldername>/<message UID/<pathofpart>
// mail/INBOX/2
[s appendFormat: @"<FileReference>mail/%@/%@/%@</FileReference>", [[self container] relativeImap4Name], [self nameInContainer], [value objectForKey: @"path"]];
[s appendFormat: @"<Method>%d</Method>", 1]; // See: http://msdn.microsoft.com/en-us/library/ee160322(v=exchg.80).aspx
[s appendFormat: @"<EstimatedDataSize>%d</EstimatedDataSize>", [[value objectForKey: @"size"] intValue]];
//[s appendFormat: @"<IsInline>%d</IsInline>", 1];
[s appendString: @"</Attachment>"];
}
[s appendString: @"</Attachments>"];
}
// ContentClass
[s appendFormat: @"<ContentClass xmlns=\"Email:\">%@</ContentClass>", @"urn:content-classes:message"];
// Flags
[s appendString: @"<Flag xmlns=\"Email:\">"];
[s appendFormat: @"<FlagStatus>%d</FlagStatus>", 0];
[s appendString: @"</Flag>"];
// NativeBodyType -- http://msdn.microsoft.com/en-us/library/ee218276(v=exchg.80).aspx
// This is a required child element.
// 1 -> plain/text, 2 -> HTML and 3 -> RTF
[s appendFormat: @"<NativeBodyType xmlns=\"AirSyncBase:\">%d</NativeBodyType>", preferredBodyType];
return s;
}
//
//
//
- (void) takeActiveSyncValues: (NSDictionary *) theValues
{
id o;
if ((o = [theValues objectForKey: @"Flag"]))
{
o = [o objectForKey: @"FlagStatus"];
if ([o intValue])
[self addFlags: @"\\Flagged"];
else
[self removeFlags: @"\\Flagged"];
}
}
@end

View File

@ -0,0 +1,91 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import <NGObjWeb/SoObjectWebDAVDispatcher.h>
#include <NGObjWeb/SoObject+SoDAV.h>
#include <NGObjWeb/WEClientCapabilities.h>
#include <NGObjWeb/WOContext.h>
#include <NGObjWeb/WORequest.h>
#include <NGObjWeb/WOResponse.h>
#import <Foundation/NSArray.h>
@interface SoObjectWebDAVDispatcher (ActiveSync)
- (id)_callObjectMethod:(NSString *)_method inContext:(WOContext *)_ctx;
- (id) doOPTIONS:(WOContext *)_ctx;
@end
@implementation SoObjectWebDAVDispatcher (ActiveSync)
- (id) doOPTIONS:(WOContext *)_ctx
{
WOResponse *response;
/*
See example: http://msdn.microsoft.com/en-us/library/ee204257(v=exchg.80).aspx
*/
if ([[[_ctx request] requestHandlerKey] isEqualToString: @"Microsoft-Server-ActiveSync"])
{
response = [_ctx response];
[response setStatus: 200];
[response setHeader: @"private" forKey: @"Cache-Control"];
[response setHeader: @"OPTIONS, POST" forKey: @"Allow"];
[response setHeader: @"14.00.0536.000" forKey: @"MS-Server-ActiveSync"];
[response setHeader: @"2.0,2.1,2.5,12.0,12.1,14.0" forKey: @"MS-ASProtocolVersions"];
[response setHeader: @"Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,Provision,ResolveRecipients,ValidateCert" forKey: @"MS-ASProtocolCommands"];
[response setHeader: @"OPTIONS, POST" forKey: @"Public"];
}
else
{
NSArray *tmp;
id result;
/* this checks whether the object provides a specific OPTIONS method */
if ((result = [self _callObjectMethod:@"OPTIONS" inContext:_ctx]) != nil)
return result;
response = [_ctx response];
[response setStatus:200 /* OK */];
if ((tmp = [self->object davAllowedMethodsInContext:_ctx]) != nil)
[response setHeader:[tmp componentsJoinedByString:@", "] forKey:@"allow"];
if ([[[_ctx request] clientCapabilities] isWebFolder]) {
/*
As described over here:
http://teyc.editthispage.com/2005/06/02
This page also says that: "MS-Auth-Via header is not required to work
with Web Folders".
*/
[response setHeader:[tmp componentsJoinedByString:@", "] forKey:@"public"];
}
if ((tmp = [self->object davComplianceClassesInContext:_ctx]) != nil)
[response setHeader:[tmp componentsJoinedByString:@", "] forKey:@"dav"];
}
return response;
}
@end

View File

@ -0,0 +1,36 @@
# common make file for SoObject bundles
include ../config.make
include $(GNUSTEP_MAKEFILES)/common.make
include ../Version
NEEDS_GUI=no
BUNDLE_EXTENSION = .SOGo
BUNDLE_INSTALL_DIR = $(SOGO_LIBDIR)
WOBUNDLE_EXTENSION = $(BUNDLE_EXTENSION)
WOBUNDLE_INSTALL_DIR = $(BUNDLE_INSTALL_DIR)
# SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib
ADDITIONAL_INCLUDE_DIRS += \
-I.. \
-I../.. \
-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/usr/local/lib
BUNDLE_LIBS += \
-lSOGo \
-lGDLContentStore \
-lGDLAccess \
-lNGObjWeb \
-lNGCards -lNGMime -lNGLdap \
-lNGStreams -lNGExtensions -lEOControl \
-lDOM -lSaxObjC -lSBJson
ADDITIONAL_BUNDLE_LIBS += $(BUNDLE_LIBS)

View File

@ -0,0 +1,35 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __ICALEVENTACTIVESYNC_H__
#define __ICALEVENTACTIVESYNC_H__
#import <NGCards/iCalEvent.h>
@class NSString;
@interface iCalEvent (ActiveSync)
- (NSString *) activeSyncRepresentation;
- (void) takeActiveSyncValues: (NSDictionary *) theValues;
@end
#endif

View File

@ -0,0 +1,113 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import "iCalEvent+ActiveSync.h"
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGCards/iCalDateTime.h>
#include "iCalTimeZone+ActiveSync.h"
#include "NSDate+ActiveSync.h"
#include "NSString+ActiveSync.h"
@implementation iCalEvent (ActiveSync)
- (NSString *) activeSyncRepresentation
{
NSMutableString *s;
iCalTimeZone *tz;
s = [NSMutableString string];
// DTStamp -- http://msdn.microsoft.com/en-us/library/ee219470(v=exchg.80).aspx
if ([self timeStampAsDate])
[s appendFormat: @"<DTStamp xmlns=\"Calendar:\">%@</DTStamp>", [[self timeStampAsDate] activeSyncRepresentation]];
else if ([self created])
[s appendFormat: @"<DTStamp xmlns=\"Calendar:\">%@</DTStamp>", [[self created] activeSyncRepresentation]];
// StartTime -- http://msdn.microsoft.com/en-us/library/ee157132(v=exchg.80).aspx
if ([self startDate])
[s appendFormat: @"<StartTime xmlns=\"Calendar:\">%@</StartTime>", [[self startDate] activeSyncRepresentation]];
// EndTime -- http://msdn.microsoft.com/en-us/library/ee157945(v=exchg.80).aspx
if ([self endDate])
[s appendFormat: @"<EndTime xmlns=\"Calendar:\">%@</EndTime>", [[self endDate] activeSyncRepresentation]];
// Timezone
tz = [(iCalDateTime *)[self firstChildWithTag: @"dtstart"] timeZone];
if (!tz)
tz = [iCalTimeZone timeZoneForName: @"Europe/London"];
[s appendFormat: @"<TimeZone xmlns=\"Calendar:\">%@</TimeZone>", [[tz activeSyncRepresentation] stringByReplacingString: @"\n" withString: @""]];;
// Subject -- http://msdn.microsoft.com/en-us/library/ee157192(v=exchg.80).aspx
if ([[self summary] length])
[s appendFormat: @"<Subject xmlns=\"Calendar:\">%@</Subject>", [self summary]];
// UID -- http://msdn.microsoft.com/en-us/library/ee159919(v=exchg.80).aspx
if ([[self uid] length])
[s appendFormat: @"<UID xmlns=\"Calendar:\">%@</UID>", [self uid]];
// Sensitivity - FIXME
[s appendFormat: @"<Sensitivity xmlns=\"Calendar:\">%d</Sensitivity>", 0];
// BusyStatus -- http://msdn.microsoft.com/en-us/library/ee202290(v=exchg.80).aspx
[s appendFormat: @"<BusyStatus xmlns=\"Calendar:\">%d</BusyStatus>", 0];
// Reminder -- http://msdn.microsoft.com/en-us/library/ee219691(v=exchg.80).aspx
return s;
}
//
//
//
- (void) takeActiveSyncValues: (NSDictionary *) theValues
{
id o;
if ((o = [theValues objectForKey: @"UID"]))
[self setUid: o];
if ((o = [theValues objectForKey: @"Subject"]))
[self setSummary: o];
if ([[theValues objectForKey: @"AllDayEvent"] intValue])
{
}
if ((o = [[theValues objectForKey: @"Body"] objectForKey: @"Data"]))
[self setComment: o];
if ((o = [theValues objectForKey: @"Location"]))
[self setLocation: o];
if ((o = [theValues objectForKey: @"StartTime"]))
[self setStartDate: [o calendarDate]];
if ((o = [theValues objectForKey: @"EndTime"]))
[self setEndDate: [o calendarDate]];
}
@end

View File

@ -0,0 +1,33 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __ICALTIMEZONEACTIVESYNC_H__
#define __ICALTIMEZONEACTIVESYNC_H__
#import <NGCards/iCalTimeZone.h>
@class NSString;
@interface iCalTimeZone (ActiveSync)
- (NSString *) activeSyncRepresentation;
@end
#endif

View File

@ -0,0 +1,153 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import "iCalTimeZone+ActiveSync.h"
#include <Foundation/NSArray.h>
#include <Foundation/NSCalendarDate.h>
#include <Foundation/NSData.h>
#include <Foundation/NSDate.h>
#include <Foundation/NSString.h>
#import <NGCards/iCalByDayMask.h>
#import <NGCards/iCalTimeZonePeriod.h>
#import <NGCards/iCalRecurrenceRule.h>
#import <NGExtensions/NGBase64Coding.h>
struct SYSTEMTIME {
uint16_t wYear;
uint16_t wMonth;
uint16_t wDayOfWeek;
uint16_t wDay;
uint16_t wHour;
uint16_t wMinute;
uint16_t wSecond;
uint16_t wMilliseconds;
};
@interface iCalTimeZonePeriod (ActiveSync)
- (void) _fillTZDate: (struct SYSTEMTIME *) tzData;
@end
@implementation iCalTimeZonePeriod (ActiveSync)
//
// FIXME - combine with iCalTimeZone+MAPIStore.m
//
- (void) _fillTZDate: (struct SYSTEMTIME *) tzData
{
iCalRecurrenceRule *rrule;
NSArray *byMonth;
iCalByDayMask *mask;
NSCalendarDate *dateValue;
rrule = [self recurrenceRule];
byMonth = [rrule byMonth];
if ([byMonth count] > 0)
{
tzData->wMonth = [[byMonth objectAtIndex: 0] intValue];
mask = [rrule byDayMask];
tzData->wDayOfWeek = [mask firstDay];
tzData->wDay = [mask firstOccurrence];
dateValue = [self startDate];
tzData->wHour = [dateValue hourOfDay];
tzData->wMinute = [dateValue minuteOfHour];
tzData->wSecond = [dateValue secondOfMinute];
}
}
@end
@implementation iCalTimeZone (ActiveSync)
//
// FIXME - combine with iCalTimeZone+MAPIStore.m
//
- (iCalTimeZonePeriod *) _mostRecentPeriodWithName: (NSString *) periodName
{
NSArray *periods;
iCalTimeZonePeriod *period;
NSUInteger max;
periods = [self childrenWithTag: periodName];
max = [periods count];
if (max > 0)
{
periods = [periods sortedArrayUsingSelector: @selector (compare:)];
period = (iCalTimeZonePeriod *) [periods objectAtIndex: (max - 1)];
}
else
period = nil;
return period;
}
- (NSString *) activeSyncRepresentation
{
iCalTimeZonePeriod *period;
NSMutableData *bytes;
uint32_t lBias;
uint32_t lStandardBias;
uint32_t lDaylightBias;
//uint16_t wStandardYear;
struct SYSTEMTIME stStandardDate;
//uint16_t wDaylightYear;
struct SYSTEMTIME stDaylightDate;
char standardName[64], daylightName[64];
bytes = [NSMutableData data];
memset(standardName, 0, 64);
memset(daylightName, 0, 64);
lStandardBias = 0;
period = [self _mostRecentPeriodWithName: @"STANDARD"];
lBias = -[period secondsOffsetFromGMT] / 60;
[period _fillTZDate: &stStandardDate];
period = [self _mostRecentPeriodWithName: @"DAYLIGHT"];
if (!period)
stStandardDate.wMonth = 0;
lDaylightBias = (uint32_t) -([period secondsOffsetFromGMT] / 60) - lBias;
[period _fillTZDate: &stDaylightDate];
//wStandardYear = stStandardDate.wYear;
//wDaylightYear = stDaylightDate.wYear;
// We build the timezone
[bytes appendBytes: &lBias length: 4];
[bytes appendBytes: standardName length: 64];
[bytes appendBytes: &stStandardDate length: 16];
[bytes appendBytes: &lStandardBias length: 4];
[bytes appendBytes: daylightName length: 64];
[bytes appendBytes: &stDaylightDate length: 16];
[bytes appendBytes: &lDaylightBias length: 4];
return [bytes stringByEncodingBase64];
}
@end

View File

@ -0,0 +1,34 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __ICALTODOACTIVESYNC_H__
#define __ICALTODOACTIVESYNC_H__
#import <NGCards/iCalToDo.h>
@class NSString;
@interface iCalToDo (ActiveSync)
- (NSString *) activeSyncRepresentation;
- (void) takeActiveSyncValues: (NSDictionary *) theValues;
@end
#endif

View File

@ -0,0 +1,85 @@
/*
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:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#import "iCalToDo+ActiveSync.h"
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#include "NSDate+ActiveSync.h"
@implementation iCalToDo (ActiveSync)
- (NSString *) activeSyncRepresentation
{
NSMutableString *s;
int v;
s = [NSMutableString string];
// Complete
NSCalendarDate *completed;
completed = [self completed];
[s appendFormat: @"<Complete xmlns=\"Tasks:\">%d</Complete>", (completed ? 1 : 0)];
// DateCompleted
[s appendFormat: @"<DateCompleted xmlns=\"Tasks:\">%@</DateCompleted>", [completed activeSyncRepresentation]];
// Due date
NSCalendarDate *due;
due = [self due];
if (due)
[s appendFormat: @"<DueDate xmlns=\"Tasks:\">%@</DueDate>", [due activeSyncRepresentation]];
// Importance
NSString *priority;
priority = [self priority];
if ([priority isEqualToString: @"9"])
v = 0;
else if ([priority isEqualToString: @"1"])
v = 2;
else
v = 1;
[s appendFormat: @"<Importance xmlns=\"Tasks:\">%d</Importance>", v];
// Reminder - FIXME
[s appendFormat: @"<ReminderSet xmlns=\"Tasks:\">%d</ReminderSet>", 0];
// Sensitivity - FIXME
[s appendFormat: @"<Sensitivity xmlns=\"Tasks:\">%d</Sensitivity>", 0];
// UTCStartDate - FIXME
if ([self startDate])
[s appendFormat: @"<UTCStartDate xmlns=\"Tasks:\">%@</UTCStartDate>", [[self startDate] activeSyncRepresentation]];
// Subject
[s appendFormat: @"<Subject xmlns=\"Tasks:\">%@</Subject>", [self summary]];
return s;
}
- (void) takeActiveSyncValues: (NSDictionary *) theValues
{
id o;
if ((o = [theValues objectForKey: @"Subject"]))
[self setSummary: o];
}
@end

View File

@ -0,0 +1,3 @@
{
requires = ( MAIN, Appointments, Contacts, Mailer );
}