diff --git a/ActiveSync/NGVCard+ActiveSync.m b/ActiveSync/NGVCard+ActiveSync.m
index aaf6c8581..3f246c8d1 100644
--- a/ActiveSync/NGVCard+ActiveSync.m
+++ b/ActiveSync/NGVCard+ActiveSync.m
@@ -193,11 +193,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if ((o = [self note]))
{
+ // It is very important here to NOT set 0 in the response,
+ // otherwise it'll prevent WP8 phones from sync'ing. See #3028 for details.
o = [o activeSyncRepresentationInContext: context];
[s appendString: @"
"];
[s appendFormat: @"%d", 1];
[s appendFormat: @"%d", [o length]];
- [s appendFormat: @"%d", 0];
[s appendFormat: @"%@", o];
[s appendString: @""];
}
diff --git a/ActiveSync/NSString+ActiveSync.m b/ActiveSync/NSString+ActiveSync.m
index 8317f8fe9..01f593352 100644
--- a/ActiveSync/NSString+ActiveSync.m
+++ b/ActiveSync/NSString+ActiveSync.m
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
#include
#include
+#include
#include
#include
@@ -127,13 +128,17 @@ static NSArray *easCommandParameters = nil;
//
- (NSCalendarDate *) calendarDate
{
+ NSString *s;
id o;
- o = [NSCalendarDate dateWithString: self calendarFormat: @"%Y%m%dT%H%M%SZ"];
+ // We force parsing in the GMT timezone. If we don't do that, the date will be parsed
+ // in the default timezone.
+ s = [NSString stringWithFormat: @"%@ GMT", self];
+ o = [NSCalendarDate dateWithString: s calendarFormat: @"%Y%m%dT%H%M%SZ %Z"];
if (!o)
- o = [NSCalendarDate dateWithString: self calendarFormat: @"%Y-%m-%dT%H:%M:%S.%FZ"];
-
+ o = [NSCalendarDate dateWithString: s calendarFormat: @"%Y-%m-%dT%H:%M:%S.%FZ %Z"];
+
return o;
}
diff --git a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
index db70bde32..100c85807 100644
--- a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
+++ b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
@@ -531,6 +531,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (void) processSyncGetChanges: (id ) theDocumentElement
inCollection: (id) theCollection
withWindowSize: (unsigned int) theWindowSize
+ withMaxSyncResponseSize: (unsigned int) theMaxSyncResponseSize
withSyncKey: (NSString *) theSyncKey
withFolderType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
withFilterType: (NSCalendarDate *) theFilterType
@@ -562,7 +563,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dateCache = [folderMetadata objectForKey: @"DateCache"];
if ((theFolderType == ActiveSyncMailFolder || theFolderType == ActiveSyncEventFolder || theFolderType == ActiveSyncTaskFolder) &&
- !([folderMetadata objectForKey: @"MoreAvailable"]) && // previous sync operation reached the windowSize
+ !([folderMetadata objectForKey: @"MoreAvailable"]) && // previous sync operation reached the windowSize or maximumSyncReponseSize
!([theSyncKey isEqualToString: @"-1"]) && // new sync operation
theFilterType)
{
@@ -590,7 +591,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
softdelete_count++;
}
- if (softdelete_count >= theWindowSize)
+ if (softdelete_count >= theWindowSize || (theMaxSyncResponseSize > 0 && [s length] >= theMaxSyncResponseSize))
{
[folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"];
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
@@ -653,7 +654,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pool = [[NSAutoreleasePool alloc] init];
// Check for the WindowSize and slice accordingly
- if (return_count >= theWindowSize)
+ if (return_count >= theWindowSize || (theMaxSyncResponseSize > 0 && [s length] >= theMaxSyncResponseSize))
{
more_available = YES;
@@ -668,7 +669,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
deleted = [[component objectForKey: @"c_deleted"] intValue];
if (!deleted && ![[component objectForKey: @"c_component"] isEqualToString: component_name])
- continue;
+ {
+ DESTROY(pool);
+ continue;
+ }
uid = [[component objectForKey: @"c_name"] sanitizedServerIdWithType: theFolderType];
@@ -692,10 +696,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if (![syncCache objectForKey: uid])
updated = NO;
else if ([[component objectForKey: @"c_lastmodified"] intValue] == [[syncCache objectForKey: uid] intValue])
- continue;
+ {
+ DESTROY(pool);
+ continue;
+ }
return_count++;
-
+
sogoObject = [theCollection lookupName: [uid sanitizedServerIdWithType: theFolderType]
inContext: context
acquire: 0];
@@ -705,7 +712,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
else
componentObject = [sogoObject component: NO secure: NO];
-
//
// We do NOT synchronize NEW events that are in fact, invitations
// to events. This is due to the fact that Outlook 2013 creates
@@ -732,17 +738,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
[syncCache setObject: [component objectForKey: @"c_lastmodified"] forKey: uid];
+
+ // No need to set dateCache for Contacts
+ if ((theFolderType == ActiveSyncEventFolder || theFolderType == ActiveSyncTaskFolder))
+ {
+ NSCalendarDate *d;
+
+ if ([[component objectForKey: @"c_cycleenddate"] intValue])
+ d = [NSCalendarDate dateWithTimeIntervalSince1970: [[component objectForKey: @"c_cycleenddate"] intValue]];
+ else if ([[component objectForKey: @"c_enddate"] intValue])
+ d = [NSCalendarDate dateWithTimeIntervalSince1970: [[component objectForKey: @"c_enddate"] intValue]];
+ else
+ d = [NSCalendarDate distantFuture];
+
+ [dateCache setObject: d forKey: uid];
+ }
if (updated)
[s appendString: @""];
else
- {
- // no need to set dateCache for Contacts
- if ((theFolderType == ActiveSyncEventFolder || theFolderType == ActiveSyncTaskFolder))
- [dateCache setObject: [componentObject startDate] ? [componentObject startDate] : [NSCalendarDate date] forKey: uid]; // FIXME: need to set proper date for recurring events - softDelete
-
[s appendString: @""];
- }
[s appendFormat: @"%@", uid];
[s appendString: @""];
@@ -829,7 +844,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
else
found_in_cache = NO;
-
if (found_in_cache)
k = j+1;
else
@@ -847,7 +861,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pool = [[NSAutoreleasePool alloc] init];
// Check for the WindowSize and slice accordingly
- if (return_count >= theWindowSize)
+ if (return_count >= theWindowSize || (theMaxSyncResponseSize > 0 && [s length] >= theMaxSyncResponseSize))
{
NSString *lastSequence;
more_available = YES;
@@ -1047,6 +1061,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (void) processSyncCollection: (id ) theDocumentElement
inBuffer: (NSMutableString *) theBuffer
changeDetected: (BOOL *) changeDetected
+ maxSyncResponseSize: (int) theMaxSyncResponseSize
{
NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *lastServerKey;
SOGoMicrosoftActiveSyncFolderType folderType;
@@ -1076,7 +1091,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//[theBuffer appendFormat: @"%@", collectionId];
//[theBuffer appendFormat: @"%d", 8];
//[theBuffer appendString: @""];
-
return;
}
@@ -1139,6 +1153,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self processSyncGetChanges: theDocumentElement
inCollection: collection
withWindowSize: windowSize
+ withMaxSyncResponseSize: theMaxSyncResponseSize
withSyncKey: syncKey
withFolderType: folderType
withFilterType: [NSCalendarDate dateFromFilterType: [[(id)[theDocumentElement getElementsByTagName: @"FilterType"] lastObject] textValue]]
@@ -1324,15 +1339,32 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
NSArray *allCollections;
NSData *d;
- int i, j, defaultInterval, heartbeatInterval, internalInterval;
+ int i, j, defaultInterval, heartbeatInterval, internalInterval, maxSyncResponseSize;
BOOL changeDetected;
+ changeDetected = NO;
+
+ maxSyncResponseSize = [[SOGoSystemDefaults sharedSystemDefaults] maximumSyncResponseSize];
+
// We initialize our output buffer
output = [[NSMutableString alloc] init];
[output appendString: @""];
[output appendString: @""];
[output appendString: @""];
+
+ //
+ // We don't support yet empty Sync requests. See: http://msdn.microsoft.com/en-us/library/ee203280(v=exchg.80).aspx
+ // We return '13' - see http://msdn.microsoft.com/en-us/library/gg675457(v=exchg.80).aspx
+ //
+ if (!theDocumentElement || [[(id)[theDocumentElement getElementsByTagName: @"Partial"] lastObject] textValue])
+ {
+ [output appendString: @"13"];
+ [output appendString: @""];
+ d = [[output dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
+ [theResponse setContent: d];
+ return;
+ }
defaults = [SOGoSystemDefaults sharedSystemDefaults];
heartbeatInterval = [[[(id)[theDocumentElement getElementsByTagName: @"HeartbeatInterval"] lastObject] textValue] intValue];
@@ -1363,7 +1395,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
aCollection = [allCollections objectAtIndex: j];
- [self processSyncCollection: aCollection inBuffer: s changeDetected: &changeDetected];
+ [self processSyncCollection: aCollection
+ inBuffer: s
+ changeDetected: &changeDetected
+ maxSyncResponseSize: maxSyncResponseSize];
}
if (changeDetected)
@@ -1378,21 +1413,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
}
- // We always return the last generated response.
- // If we only return ,
- // iOS powered devices will simply crash.
- [output appendString: s];
+ // Only send a response if there are changes otherwise send an empty response.
+ if (changeDetected)
+ {
+ // We always return the last generated response.
+ // If we only return ,
+ // iOS powered devices will simply crash.
+ [output appendString: s];
- [output appendString: @""];
+ [output appendString: @""];
+
+ d = [output dataUsingEncoding: NSUTF8StringEncoding];
+ d = [d xml2wbxml];
+ [theResponse setContent: d];
+ }
// Avoid overloading the autorelease pool here, as Sync command can
// generate fairly large responses.
- d = [output dataUsingEncoding: NSUTF8StringEncoding];
RELEASE(output);
-
- d = [d xml2wbxml];
-
- [theResponse setContent: d];
}
@end
diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m
index 9ac964b0e..4ddd1427b 100644
--- a/ActiveSync/SOGoActiveSyncDispatcher.m
+++ b/ActiveSync/SOGoActiveSyncDispatcher.m
@@ -793,10 +793,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
cKey = [allKeys objectAtIndex: i];
- // ignore invalid folder in cache caused by fs code bugs
- if ([cKey isEqualToString:@"(null)"])
- continue;
-
// if a cache entry is not found in imapGUIDs its either an imap which has been deleted or its an other folder type which can be checked via lookupName.
if (![imapGUIDs allKeysForObject: cKey])
{
@@ -807,7 +803,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[o setTableUrl: [self folderTableURL]];
[o reloadIfNeeded];
- if ([cKey hasPrefix: @"folder"])
+ if ([cKey hasPrefix: @"folder"] || [cKey isEqualToString:@"(null)"])
{
[commands appendFormat: @"%@", [[NSString stringWithFormat: @"mail/%@", [cKey substringFromIndex: 6]] stringByEscapingURL]] ;
command_count++;
@@ -849,6 +845,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
folderMetadata = [allFoldersMetadata objectAtIndex: i];
nameInCache = [NSString stringWithFormat: @"folder%@", [[folderMetadata objectForKey: @"path"] substringFromIndex: 1]];
+
+ // we have no guid - ignore the folder
+ if (![imapGUIDs objectForKey: nameInCache])
+ continue;
+
serverId = [NSString stringWithFormat: @"mail/%@", [[imapGUIDs objectForKey: nameInCache] substringFromIndex: 6]];
name = [folderMetadata objectForKey: @"displayName"];
@@ -2480,8 +2481,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
// We check if it's a Ping command with no body.
// See http://msdn.microsoft.com/en-us/library/ee200913(v=exchg.80).aspx for details
- if ([cmdName caseInsensitiveCompare: @"Ping"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"GetAttachment"] != NSOrderedSame)
- return [NSException exceptionWithHTTPStatus: 500];
+ if ([cmdName caseInsensitiveCompare: @"Ping"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"GetAttachment"] != NSOrderedSame && [cmdName caseInsensitiveCompare: @"Sync"] != NSOrderedSame)
+ {
+ RELEASE(context);
+ RELEASE(pool);
+ return [NSException exceptionWithHTTPStatus: 500];
+ }
}
if (d)
diff --git a/ActiveSync/SOGoSyncCacheObject.m b/ActiveSync/SOGoSyncCacheObject.m
index ab973348d..63c545b34 100644
--- a/ActiveSync/SOGoSyncCacheObject.m
+++ b/ActiveSync/SOGoSyncCacheObject.m
@@ -55,7 +55,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[o setUID: theUID];
[o setSequence: theSequence];
- return o;
+ return [o autorelease];
}
- (void) dealloc
diff --git a/ActiveSync/iCalEvent+ActiveSync.m b/ActiveSync/iCalEvent+ActiveSync.m
index dc996f381..d1a4b6f8a 100644
--- a/ActiveSync/iCalEvent+ActiveSync.m
+++ b/ActiveSync/iCalEvent+ActiveSync.m
@@ -332,7 +332,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
iCalTimeZone *tz;
id o;
- NSInteger tzOffset;
BOOL isAllDay;
if ((o = [theValues objectForKey: @"UID"]))
@@ -384,10 +383,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Some Windows devices don't send during event updates.
//if ((o = [theValues objectForKey: @"TimeZone"]))
// {
- userTimeZone = [[[context activeUser] userDefaults] timeZone];
- tz = [iCalTimeZone timeZoneForName: [userTimeZone name]];
- [(iCalCalendar *) parent addTimeZone: tz];
- //}
+ // }
+ //else
+ {
+ // We haven't received a timezone, let's use the user's timezone
+ // specified in SOGo for now.
+ userTimeZone = [[[context activeUser] userDefaults] timeZone];
+ tz = [iCalTimeZone timeZoneForName: [userTimeZone name]];
+ [(iCalCalendar *) parent addTimeZone: tz];
+ }
// FIXME: merge with iCalToDo
if ((o = [[theValues objectForKey: @"Body"] objectForKey: @"Data"]))
@@ -402,21 +406,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
start = (iCalDateTime *) [self uniqueChildWithTag: @"dtstart"];
[start setTimeZone: tz];
- if (isAllDay)
- {
- tzOffset = [userTimeZone secondsFromGMTForDate: o];
- o = [o dateByAddingYears: 0 months: 0 days: 0
- hours: 0 minutes: 0
- seconds: tzOffset];
+ if (isAllDay)
+ {
[start setDate: o];
[start setTimeZone: nil];
}
else
{
- tzOffset = [userTimeZone secondsFromGMTForDate: o];
- o = [o dateByAddingYears: 0 months: 0 days: 0
- hours: 0 minutes: 0
- seconds: tzOffset];
[start setDateTime: o];
}
}
@@ -429,19 +425,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if (isAllDay)
{
- tzOffset = [userTimeZone secondsFromGMTForDate: o];
- o = [o dateByAddingYears: 0 months: 0 days: 0
- hours: 0 minutes: 0
- seconds: tzOffset];
[end setDate: o];
[end setTimeZone: nil];
}
else
{
- tzOffset = [userTimeZone secondsFromGMTForDate: o];
- o = [o dateByAddingYears: 0 months: 0 days: 0
- hours: 0 minutes: 0
- seconds: tzOffset];
[end setDateTime: o];
}
}
diff --git a/ActiveSync/iCalToDo+ActiveSync.m b/ActiveSync/iCalToDo+ActiveSync.m
index 58b0d4c04..5f237a31b 100644
--- a/ActiveSync/iCalToDo+ActiveSync.m
+++ b/ActiveSync/iCalToDo+ActiveSync.m
@@ -143,8 +143,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
iCalTimeZone *tz;
id o;
- NSInteger tzOffset;
-
userTimeZone = [[[context activeUser] userDefaults] timeZone];
tz = [iCalTimeZone timeZoneForName: [userTimeZone name]];
[(iCalCalendar *) parent addTimeZone: tz];
@@ -165,10 +163,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
o = [o calendarDate];
completed = (iCalDateTime *) [self uniqueChildWithTag: @"completed"];
- //tzOffset = [[o timeZone] secondsFromGMTForDate: o];
- //o = [o dateByAddingYears: 0 months: 0 days: 0
- // hours: 0 minutes: 0
- // seconds: -tzOffset];
[completed setDate: o];
[self setStatus: @"COMPLETED"];
}
@@ -177,15 +171,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
iCalDateTime *due;
-
o = [o calendarDate];
due = (iCalDateTime *) [self uniqueChildWithTag: @"due"];
[due setTimeZone: tz];
-
- tzOffset = [userTimeZone secondsFromGMTForDate: o];
- o = [o dateByAddingYears: 0 months: 0 days: 0
- hours: 0 minutes: 0
- seconds: tzOffset];
[due setDateTime: o];
}
diff --git a/ChangeLog b/ChangeLog
index 942c03d5f..f8728b5e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,122 @@
+commit ead665de85e2202dbde926c316cbba927d38dfa7
+Author: Ludovic Marcotte
+Date: Mon Dec 29 16:19:10 2014 -0500
+
+ fix tz issue when the user one was different from the system one with EAS
+
+M ActiveSync/NSString+ActiveSync.m
+M ActiveSync/iCalEvent+ActiveSync.m
+M ActiveSync/iCalToDo+ActiveSync.m
+M NEWS
+
+commit a0c1ce8f3b7c22002661d40c24e95a1233b6a6e8
+Author: Ludovic Marcotte
+Date: Mon Dec 29 12:43:20 2014 -0500
+
+ Improved handling of non-existant vs. subscribed folders over EAS
+
+M ActiveSync/SOGoActiveSyncDispatcher.m
+M SoObjects/Mailer/SOGoMailAccount.m
+M SoObjects/Mailer/SOGoMailFolder.m
+
+commit 204a62aa6ac8feb5a13d5a2ee162bb26cc495a50
+Author: Ludovic Marcotte
+Date: Tue Dec 23 10:25:53 2014 -0500
+
+ Improved comments in the code
+
+M SoObjects/Appointments/SOGoAppointmentFolder.m
+
+commit 31cffdffd34429d1f4873d07d67e822bff82b7cf
+Author: Ludovic Marcotte
+Date: Tue Dec 23 10:24:16 2014 -0500
+
+ Fix freebusy info not always returned
+
+M NEWS
+M SoObjects/Appointments/SOGoAppointmentFolder.m
+M SoObjects/SOGo/SOGoFolder.h
+M SoObjects/SOGo/SOGoFolder.m
+
+commit 255bcbe92fa6b4610edf5f4d05c97b74537ecb6e
+Author: Ludovic Marcotte
+Date: Mon Dec 22 19:59:33 2014 -0500
+
+ Fixed memory leaks in SOGoSyncCacheObject and correctly kill the cache upon each EAS iteration
+
+M ActiveSync/SOGoSyncCacheObject.m
+M SoObjects/Mailer/SOGoMailBaseObject.m
+M SoObjects/SOGo/NSObject+Utilities.m
+M UI/MainUI/SOGoMicrosoftActiveSyncActions.m
+
+commit 72732879fafe8ef928593c0cf3e39d962b096ec9
+Author: Ludovic Marcotte
+Date: Mon Dec 22 19:32:17 2014 -0500
+
+ Added memory statistics - set SOGoDebugLeaks = YES and call [[self class] memoryStatistics]
+
+M SoObjects/SOGo/NSObject+Utilities.h
+M SoObjects/SOGo/NSObject+Utilities.m
+
+commit 24a934275f5678f7ab86cb706aa817dfb5ef8991
+Author: Ludovic Marcotte
+Date: Mon Dec 22 16:12:26 2014 -0500
+
+ Fix small memory leak incase of errors
+
+M ActiveSync/SOGoActiveSyncDispatcher.m
+
+commit 58f634bffe35b3a1f6a02072ba0103fea2155a45
+Author: Ludovic Marcotte
+Date: Mon Dec 22 15:26:22 2014 -0500
+
+ Cosmetic improvements to the code
+
+M SoObjects/Appointments/SOGoAppointmentObject.m
+M SoObjects/SOGo/SOGoMailer.h
+M SoObjects/SOGo/SOGoMailer.m
+
+commit ca4a754f2c12784ff437df34c255d3dccbf5c6f2
+Author: Ludovic Marcotte
+Date: Mon Dec 22 12:39:58 2014 -0500
+
+ Use the right cutoff date
+
+M ActiveSync/SOGoActiveSyncDispatcher+Sync.m
+M NEWS
+M SoObjects/SOGo/SOGoGCSFolder.m
+
+commit 8015688df31a3e3254093b260851d4664d725ea6
+Author: Ludovic Marcotte
+Date: Mon Dec 22 11:50:51 2014 -0500
+
+ Added SOGoMaximumSyncResponseSize to support memory-limited EAS syncs
+
+M ActiveSync/SOGoActiveSyncDispatcher+Sync.m
+M Documentation/SOGoInstallationGuide.asciidoc
+M NEWS
+M SoObjects/SOGo/SOGoSystemDefaults.h
+M SoObjects/SOGo/SOGoSystemDefaults.m
+
+commit b07913d66d4a47919e09cbcd0c41d92bd97ea0a3
+Author: Ludovic Marcotte
+Date: Mon Dec 22 08:36:55 2014 -0500
+
+ See NEWS file
+
+M ActiveSync/NGVCard+ActiveSync.m
+M ActiveSync/SOGoActiveSyncDispatcher+Sync.m
+M ActiveSync/SOGoActiveSyncDispatcher.m
+M NEWS
+
+commit df8a0d8715d97873e782ccfbfaab8b580c88c66e
+Author: Ludovic Marcotte
+Date: Fri Dec 19 09:03:37 2014 -0500
+
+ Update ChangeLog
+
+M ChangeLog
+
commit e6cc56dca1126e09cb8336bdbd4e5dabc7b83cf1
Author: Ludovic Marcotte
Date: Fri Dec 19 09:03:19 2014 -0500
@@ -15,6 +134,24 @@ Date: Fri Dec 19 09:01:39 2014 -0500
M NEWS
M SoObjects/Mailer/SOGoDraftObject.m
+commit 0e56527e05566e78ac8fe4687d19423de78b0276
+Author: Chris Rosenhain
+Date: Fri Dec 19 11:04:05 2014 +1030
+
+ Change ACL modification text to non-gender specific terms
+
+M SoObjects/Appointments/SOGoAppointmentObject.m
+M SoObjects/Appointments/SOGoCalendarComponent.m
+M SoObjects/SOGo/SOGoGCSFolder.m
+M SoObjects/SOGo/SOGoUserFolder.h
+M UI/MainUI/SOGoRootPage.m
+M UI/Templates/SOGoACLDanishModificationAdvisory.wox
+M UI/Templates/SOGoACLDanishRemovalAdvisory.wox
+M UI/Templates/SOGoACLDutchModificationAdvisory.wox
+M UI/Templates/SOGoACLDutchRemovalAdvisory.wox
+M UI/Templates/SOGoACLEnglishModificationAdvisory.wox
+M UI/Templates/SOGoACLEnglishRemovalAdvisory.wox
+
commit db911f323d23f263f5fa9c5fb02d8234127687b3
Author: Ludovic Marcotte
Date: Thu Dec 18 08:56:23 2014 -0500
diff --git a/Documentation/SOGoInstallationGuide.asciidoc b/Documentation/SOGoInstallationGuide.asciidoc
index 36e6e65ba..08c819154 100644
--- a/Documentation/SOGoInstallationGuide.asciidoc
+++ b/Documentation/SOGoInstallationGuide.asciidoc
@@ -2390,6 +2390,15 @@ _SOGoMaximumPingInterval_.
If not set, it defaults to `10` seconds.
+|S |SOGoMaximumSyncResponseSize
+|Parameter used to overwrite the maximum response size during
+a Sync operation. The value is in kilobytes. Setting this to 512
+means the response size will be of 524288 bytes or less. Note that
+if you set the value too low and a mail message (or any other object)
+surpasses it, it will still be synced but only this item will be.
+
+Defaults to `0`, which means no overwrite is performed.
+
|S |SOGoMaximumSyncWindowSize
|Parameter used to overwrite the maximum number of items returned during
a Sync operation.
diff --git a/Documentation/docinfo.xml b/Documentation/docinfo.xml
index 247cd8a9b..aa1164747 100644
--- a/Documentation/docinfo.xml
+++ b/Documentation/docinfo.xml
@@ -1,7 +1,7 @@
-Version 2.2.12 - December 2014
-for version 2.2.12
-2014-12-18
+Version 2.2.13 - December 2014
+for version 2.2.13
+2014-12-30
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".
diff --git a/Documentation/includes/global-attributes.asciidoc b/Documentation/includes/global-attributes.asciidoc
index 064ce5b49..0bce4709c 100644
--- a/Documentation/includes/global-attributes.asciidoc
+++ b/Documentation/includes/global-attributes.asciidoc
@@ -13,6 +13,6 @@
// TODO have the build system take care of this
-:release_version: 2.2.12
+:release_version: 2.2.13
// vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab:
diff --git a/NEWS b/NEWS
index e0fbbe3a0..e6aeb7c61 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,17 @@
+2.2.13 (2014-12-30)
+-------------------
+
+Bug fixes
+ - fix contact description truncation on WP8 phones (#3028)
+ - fix freebusy information not always returned
+ - fix tz issue when the user one was different from the system one with EAS
+
+Enhancements
+ - initial support for empty sync request/response for EAS
+ - added the SOGoMaximumSyncResponseSize EAS configuration parameter to
+ support memory-limited sync response sizes
+ - we now not only use the creation date for event's cutoff date (EAS)
+
2.2.12a (2014-12-19)
--------------------
diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m
index a01c10c62..c3e29c9ca 100644
--- a/SoObjects/Appointments/SOGoAppointmentFolder.m
+++ b/SoObjects/Appointments/SOGoAppointmentFolder.m
@@ -492,6 +492,9 @@ static Class iCalEventK = nil;
//
// If the user is NOT the owner of the calendar, by default we exclude the freebusy information.
//
+// We must include the freebusy information of other users if we are actually looking at their freebusy information
+// but we aren't necessarily subscribed to their calendars.
+//
- (BOOL) includeInFreeBusy
{
NSNumber *excludeFromFreeBusy;
@@ -500,16 +503,31 @@ static Class iCalEventK = nil;
userLogin = [[context activeUser] login];
is_owner = [userLogin isEqualToString: [self ownerInContext: context]];
-
+
// Check if the owner (not the active user) has excluded the calendar from her/his free busy data.
excludeFromFreeBusy
= [self folderPropertyValueInCategory: @"FreeBusyExclusions"
forUser: [SOGoUser userWithLogin: userLogin]];
- if (!excludeFromFreeBusy && !is_owner)
- return NO;
-
- return ![excludeFromFreeBusy boolValue];
+ if ([self isSubscription])
+ {
+ // If the user has not yet set an include/not include fb information let's EXCLUDE it.
+ if (!excludeFromFreeBusy)
+ return NO;
+ else
+ return ![excludeFromFreeBusy boolValue];
+ }
+ else if (is_owner)
+ {
+ // We are the owner but we haven't included/excluded freebusy info, let's INCLUDE it.
+ if (!excludeFromFreeBusy)
+ return YES;
+ else
+ return ![excludeFromFreeBusy boolValue];
+ }
+
+ // It's not a subscribtion and we aren't the owner. Let's INCLUDE the freebusy info.
+ return YES;
}
- (void) setIncludeInFreeBusy: (BOOL) newInclude
diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m
index f4ece14de..1d7538da1 100644
--- a/SoObjects/Appointments/SOGoAppointmentObject.m
+++ b/SoObjects/Appointments/SOGoAppointmentObject.m
@@ -400,9 +400,9 @@
{
currentUID = [currentAttendee uid];
if (currentUID)
- [self _addOrUpdateEvent: newEvent
- forUID: currentUID
- owner: owner];
+ [self _addOrUpdateEvent: newEvent
+ forUID: currentUID
+ owner: owner];
}
[self sendEMailUsingTemplateNamed: @"Update"
@@ -443,7 +443,7 @@
us = [user userSettings];
moduleSettings = [us objectForKey:@"Calendar"];
- // Check if the user prevented his account from beeing invited to events
+ // Check if the user prevented their account from beeing invited to events
if (![user isResource] && [[moduleSettings objectForKey:@"PreventInvitations"] boolValue])
{
// Check if the user have a whiteList
@@ -734,7 +734,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
// the modification was actually NOT made on the master event
if ([theEvent recurrenceId])
return;
-
+
events = [[theEvent parent] events];
for (i = 0; i < [events count]; i++)
@@ -743,12 +743,12 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
if ([e recurrenceId])
for (j = 0; j < [theAttendees count]; j++)
if (shouldAdd)
- [e addToAttendees: [theAttendees objectAtIndex: j]];
- else
- [e removeFromAttendees: [theAttendees objectAtIndex: j]];
+ [e addToAttendees: [theAttendees objectAtIndex: j]];
+ else
+ [e removeFromAttendees: [theAttendees objectAtIndex: j]];
}
}
-
+
//
//
//
@@ -803,14 +803,17 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
// We insert the attendees in all exception occurences, if
// the attendees were added to the master event.
[self _addOrDeleteAttendees: addedAttendees
- inRecurrenceExceptionsForEvent: newEvent
- add: YES];
+ inRecurrenceExceptionsForEvent: newEvent
+ add: YES];
if ([changes sequenceShouldBeIncreased])
{
[newEvent increaseSequence];
+
// Update attendees calendars and send them an update
- // notification by email
+ // notification by email. We ignore the newly added
+ // attendees as we don't want to send them invitation
+ // update emails
[self _handleSequenceUpdateInEvent: newEvent
ignoringAttendees: addedAttendees
fromOldEvent: oldEvent];
@@ -1093,7 +1096,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
else
{
// We must REMOVE any SENT-BY here. This is important since if A accepted
- // the event for B and then, B changes by himself his participation status,
+ // the event for B and then, B changes by theirself their participation status,
// we don't want to keep the previous SENT-BY attribute there.
[(NSMutableDictionary *)[otherAttendee attributes] removeObjectForKey: @"SENT-BY"];
}
@@ -1191,7 +1194,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
else
{
// We must REMOVE any SENT-BY here. This is important since if A accepted
- // the event for B and then, B changes by himself his participation status,
+ // the event for B and then, B changes by theirself their participation status,
// we don't want to keep the previous SENT-BY attribute there.
[(NSMutableDictionary *)[attendee attributes] removeObjectForKey: @"SENT-BY"];
}
@@ -1208,7 +1211,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
delegatedUID = [otherDelegate uid];
if (delegatedUID)
- // Delegate attendee is a local user; remove event from his calendar
+ // Delegate attendee is a local user; remove event from their calendar
[self _removeEventFromUID: delegatedUID
owner: [theOwnerUser login]
withRecurrenceId: [event recurrenceId]];
@@ -1240,7 +1243,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
[event addToAttendees: delegate];
if (delegatedUID)
- // Delegate attendee is a local user; add event to his calendar
+ // Delegate attendee is a local user; add event to their calendar
[self _addOrUpdateEvent: event
forUID: delegatedUID
owner: [theOwnerUser login]];
diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m
index f8822c061..ce600715b 100644
--- a/SoObjects/Appointments/SOGoCalendarComponent.m
+++ b/SoObjects/Appointments/SOGoCalendarComponent.m
@@ -644,8 +644,8 @@
// As much as we can, we try to use c_name == c_uid in order
// to avoid tricky scenarios with some CalDAV clients. For example,
// if Alice invites Bob (both use SOGo) and Bob accepts the invitation
- // using Lightning before having refreshed his calendar, he'll end up
- // with a duplicate of the event in his database tables.
+ // using Lightning before having refreshed their calendar, they'll end up
+ // with a duplicate of the event in their database tables.
if (isNew)
{
newUid = nameInContainer;
diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m
index 772c49ecd..97057a1c4 100644
--- a/SoObjects/Mailer/SOGoMailAccount.m
+++ b/SoObjects/Mailer/SOGoMailAccount.m
@@ -40,6 +40,7 @@
#import
#import
#import
+#import
#import
#import
@@ -667,19 +668,14 @@ static NSString *inboxFolderName = @"INBOX";
NSDictionary *result, *nresult, *namespaceDict;
NSMutableDictionary *folders;
NGImap4Client *client;
- SOGoUserDefaults *ud;
NSArray *folderList;
NSEnumerator *e;
NSString *guid;
id object;
- BOOL subscribedOnly, hasAnnotatemore;
+ BOOL hasAnnotatemore;
- ud = [[context activeUser] userDefaults];
- subscribedOnly = [ud mailShowSubscribedFoldersOnly];
-
- folderList = [[self imap4Connection] allFoldersForURL: [self imap4URL]
- onlySubscribedFolders: subscribedOnly];
+ folderList = [self allFolderPaths];
folders = [NSMutableDictionary dictionary];
@@ -688,19 +684,19 @@ static NSString *inboxFolderName = @"INBOX";
hasAnnotatemore = [self hasCapability: @"annotatemore"];
if (hasAnnotatemore)
- result = [client annotation: @"*" entryName: @"/comment" attributeName: @"value.priv"];
+ result = [client annotation: @"*" entryName: @"/comment" attributeName: @"value.priv"];
else
- result = [client lstatus: @"*" flags: [NSArray arrayWithObjects: @"x-guid", nil]];
-
+ result = [client lstatus: @"*" flags: [NSArray arrayWithObjects: @"x-guid", nil]];
+
e = [folderList objectEnumerator];
-
+
while ((object = [e nextObject]))
{
if (hasAnnotatemore)
- guid = [[[[result objectForKey: @"FolderList"] objectForKey: [object substringFromIndex: 1]] objectForKey: @"/comment"] objectForKey: @"value.priv"];
+ guid = [[[[result objectForKey: @"FolderList"] objectForKey: [object substringFromIndex: 1]] objectForKey: @"/comment"] objectForKey: @"value.priv"];
else
- guid = [[[result objectForKey: @"status"] objectForKey: [object substringFromIndex: 1]] objectForKey: @"x-guid"];
-
+ guid = [[[result objectForKey: @"status"] objectForKey: [object substringFromIndex: 1]] objectForKey: @"x-guid"];
+
if (!guid)
{
// Don't generate a GUID for "Other users" and "Shared" namespace folders - user foldername instead
@@ -710,18 +706,28 @@ static NSString *inboxFolderName = @"INBOX";
[folders setObject: [NSString stringWithFormat: @"folder%@", [object substringFromIndex: 1]] forKey: [NSString stringWithFormat: @"folder%@", [object substringFromIndex: 1]]];
continue;
}
-
- guid = [[NSProcessInfo processInfo] globallyUniqueString];
- nresult = [client annotation: [object substringFromIndex: 1] entryName: @"/comment" attributeName: @"value.priv" attributeValue: guid];
- if (![[nresult objectForKey: @"result"] boolValue])
- guid = [NSString stringWithFormat: @"%@", [object substringFromIndex: 1]];
+ // if folder doesn't exists - ignore it
+ nresult = [client status: [object substringFromIndex: 1]
+ flags: [NSArray arrayWithObject: @"UIDVALIDITY"]];
+ if (![[nresult valueForKey: @"result"] boolValue])
+ continue;
+
+ if (hasAnnotatemore)
+ {
+ guid = [[NSProcessInfo processInfo] globallyUniqueString];
+ nresult = [client annotation: [object substringFromIndex: 1] entryName: @"/comment" attributeName: @"value.priv" attributeValue: guid];
+ }
+
+ // setannotation failed or annotatemore is not available
+ if (![[nresult objectForKey: @"result"] boolValue] || !hasAnnotatemore)
+ guid = [NSString stringWithFormat: @"%@", [object substringFromIndex: 1]];
}
-
+
[folders setObject: [NSString stringWithFormat: @"folder%@", guid] forKey: [NSString stringWithFormat: @"folder%@", [object substringFromIndex: 1]]];
-
+
}
-
+
return folders;
}
diff --git a/SoObjects/Mailer/SOGoMailBaseObject.m b/SoObjects/Mailer/SOGoMailBaseObject.m
index 73967efe0..863491e2e 100644
--- a/SoObjects/Mailer/SOGoMailBaseObject.m
+++ b/SoObjects/Mailer/SOGoMailBaseObject.m
@@ -43,10 +43,6 @@
@implementation SOGoMailBaseObject
-#if 0
-static BOOL debugOn = YES;
-#endif
-
- (id) initWithImap4URL: (NSURL *) _url
inContainer: (id) _container
{
diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m
index 3607b9dd2..d83ca78a6 100644
--- a/SoObjects/Mailer/SOGoMailFolder.m
+++ b/SoObjects/Mailer/SOGoMailFolder.m
@@ -1069,7 +1069,11 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
NSException *error;
if ([self imap4Connection])
- error = [imap4 deleteMailboxAtURL: [self imap4URL]];
+ {
+ error = [imap4 deleteMailboxAtURL: [self imap4URL]];
+ if (!error)
+ [[imap4 client] unsubscribe: [[self imap4URL] path]];
+ }
else
error = [NSException exceptionWithName: @"SOGoMailException"
reason: @"IMAP connection is invalid"
diff --git a/SoObjects/SOGo/NSObject+Utilities.h b/SoObjects/SOGo/NSObject+Utilities.h
index 469eab8b9..102ab7ef3 100644
--- a/SoObjects/SOGo/NSObject+Utilities.h
+++ b/SoObjects/SOGo/NSObject+Utilities.h
@@ -40,6 +40,8 @@
- (NSString *) labelForKey: (NSString *) key
inContext: (WOContext *) context;
++ (void) memoryStatistics;
+
@end
#endif /* NSOBJECT+UTILITIES_H */
diff --git a/SoObjects/SOGo/NSObject+Utilities.m b/SoObjects/SOGo/NSObject+Utilities.m
index 2f9ed96cd..3dca1f0f5 100644
--- a/SoObjects/SOGo/NSObject+Utilities.m
+++ b/SoObjects/SOGo/NSObject+Utilities.m
@@ -22,6 +22,7 @@
#import
#import
+#import
#import
#import
@@ -122,4 +123,33 @@
return label;
}
+//
+// Set SOGoDebugLeaks = YES in your defaults to enable.
+//
++ (void) memoryStatistics
+{
+ Class *classList = GSDebugAllocationClassList ();
+ Class *pointer;
+ int i, count, total, peak;
+ NSString *className;
+
+ pointer = classList;
+ i = 0;
+
+ printf("Class count total peak\n");
+ while (pointer[i] != NULL)
+ {
+ className = NSStringFromClass (pointer[i]);
+ count = GSDebugAllocationCount (pointer[i]);
+ total = GSDebugAllocationTotal (pointer[i]);
+ peak = GSDebugAllocationPeak (pointer[i]);
+
+ printf("%s %d %d %d\n", [className UTF8String], count, total, peak);
+ i++;
+ }
+ NSZoneFree(NSDefaultMallocZone(), classList);
+
+ printf("Done!\n");
+}
+
@end
diff --git a/SoObjects/SOGo/SOGoFolder.h b/SoObjects/SOGo/SOGoFolder.h
index 186036db3..018cfe7e0 100644
--- a/SoObjects/SOGo/SOGoFolder.h
+++ b/SoObjects/SOGo/SOGoFolder.h
@@ -1,6 +1,6 @@
/* SOGoFolder.h - this file is part of SOGo
*
- * Copyright (C) 2007-2013 Inverse inc.
+ * Copyright (C) 2007-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m
index a27466cdd..a390b9267 100644
--- a/SoObjects/SOGo/SOGoFolder.m
+++ b/SoObjects/SOGo/SOGoFolder.m
@@ -1,8 +1,6 @@
/* SOGoFolder.m - this file is part of SOGo
*
- * Copyright (C) 2007-2011 Inverse inc.
- *
- * Author: Wolfgang Sourdeau
+ * Copyright (C) 2007-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m
index 921d312c0..9f77359e9 100644
--- a/SoObjects/SOGo/SOGoGCSFolder.m
+++ b/SoObjects/SOGo/SOGoGCSFolder.m
@@ -302,7 +302,7 @@ static NSArray *childRecordFields = nil;
}
/* This method fetches the display name defined by the owner, but is also the
- fallback when a subscriber has not redefined the display name yet in his
+ fallback when a subscriber has not redefined the display name yet in their
environment. */
- (NSString *) _displayNameFromOwner
{
@@ -895,7 +895,7 @@ static NSArray *childRecordFields = nil;
allUsers = [NSMutableArray arrayWithArray: [aGroup members]];
// We remove the active user from the group (if present) in order to
- // not subscribe him to his own resource!
+ // not subscribe him to their own resource!
[allUsers removeObject: [context activeUser]];
}
else
@@ -1165,7 +1165,14 @@ static NSArray *childRecordFields = nil;
int syncTokenInt;
fields = [NSMutableArray arrayWithObjects: @"c_name", @"c_component",
- @"c_creationdate", @"c_lastmodified", nil];
+ @"c_creationdate", @"c_lastmodified", nil];
+
+ if ([[self folderType] isEqualToString: @"Appointment"])
+ {
+ [fields addObject: @"c_enddate"];
+ [fields addObject: @"c_cycleenddate"];
+ }
+
addFields = [[properties allValues] objectEnumerator];
while ((currentField = [addFields nextObject]))
if ([currentField length])
@@ -1181,7 +1188,9 @@ static NSArray *childRecordFields = nil;
if (theStartDate)
{
EOQualifier *sinceDateQualifier = [EOQualifier qualifierWithQualifierFormat:
- @"c_creationdate > %d", (int)[theStartDate timeIntervalSince1970]];
+ @"(c_enddate > %d OR c_enddate = NULL) OR (c_iscycle = 1 and (c_cycleenddate > %d OR c_cycleenddate = NULL))",
+ (int)[theStartDate timeIntervalSince1970],
+ (int)[theStartDate timeIntervalSince1970]];
qualifier = [[EOAndQualifier alloc] initWithQualifiers: sinceDateQualifier, qualifier,
nil];
@@ -1211,7 +1220,9 @@ static NSArray *childRecordFields = nil;
if (theStartDate)
{
EOQualifier *sinceDateQualifier = [EOQualifier qualifierWithQualifierFormat:
- @"c_creationdate > %d", (int)[theStartDate timeIntervalSince1970]];
+ @"(c_enddate > %d OR c_enddate = NULL) OR (c_iscycle = 1 and (c_cycleenddate > %d OR c_cycleenddate = NULL))",
+ (int)[theStartDate timeIntervalSince1970],
+ (int)[theStartDate timeIntervalSince1970]];
qualifier = [[EOAndQualifier alloc] initWithQualifiers: sinceDateQualifier, qualifier,
nil];
diff --git a/SoObjects/SOGo/SOGoMailer.h b/SoObjects/SOGo/SOGoMailer.h
index 6ebc0ef7d..6f82092e2 100644
--- a/SoObjects/SOGo/SOGoMailer.h
+++ b/SoObjects/SOGo/SOGoMailer.h
@@ -1,8 +1,6 @@
/* SOGoMailer.h - this file is part of SOGo
*
- * Copyright (C) 2007 Inverse inc.
- *
- * Author: Wolfgang Sourdeau
+ * Copyright (C) 2007-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/SoObjects/SOGo/SOGoMailer.m b/SoObjects/SOGo/SOGoMailer.m
index bbf59540d..413c29a96 100644
--- a/SoObjects/SOGo/SOGoMailer.m
+++ b/SoObjects/SOGo/SOGoMailer.m
@@ -1,8 +1,6 @@
/* SOGoMailer.m - this file is part of SOGo
*
- * Copyright (C) 2007-2013 Inverse inc.
- *
- * Author: Wolfgang Sourdeau
+ * Copyright (C) 2007-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/SoObjects/SOGo/SOGoSystemDefaults.h b/SoObjects/SOGo/SOGoSystemDefaults.h
index de5a140fa..7f811f208 100644
--- a/SoObjects/SOGo/SOGoSystemDefaults.h
+++ b/SoObjects/SOGo/SOGoSystemDefaults.h
@@ -99,6 +99,7 @@
- (int) maximumSyncInterval;
- (int) internalSyncInterval;
- (int) maximumSyncWindowSize;
+- (int) maximumSyncResponseSize;
@end
diff --git a/SoObjects/SOGo/SOGoSystemDefaults.m b/SoObjects/SOGo/SOGoSystemDefaults.m
index f9aa5fcc2..9fbb9ef48 100644
--- a/SoObjects/SOGo/SOGoSystemDefaults.m
+++ b/SoObjects/SOGo/SOGoSystemDefaults.m
@@ -636,4 +636,16 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict,
return [self integerForKey: @"SOGoMaximumSyncWindowSize"];
}
+- (int) maximumSyncResponseSize
+{
+ int v;
+
+ v = [self integerForKey: @"SOGoMaximumSyncResponseSize"];
+
+ if (v > 0)
+ v = v * 1024;
+
+ return v;
+}
+
@end
diff --git a/SoObjects/SOGo/SOGoUserFolder.h b/SoObjects/SOGo/SOGoUserFolder.h
index 4ee6bdd65..0621728a7 100644
--- a/SoObjects/SOGo/SOGoUserFolder.h
+++ b/SoObjects/SOGo/SOGoUserFolder.h
@@ -31,7 +31,7 @@
Child objects:
'Calendar': SOGoAppointmentFolder
- The SOGoUserFolder is the "home directory" of the user where all his
+ The SOGoUserFolder is the "home directory" of the user where all their
processing starts. It is the 'znek' in such a path:
/SOGo/so/znek/Calendar
*/
diff --git a/UI/MainUI/SOGoMicrosoftActiveSyncActions.m b/UI/MainUI/SOGoMicrosoftActiveSyncActions.m
index a00344fba..c487d5cce 100644
--- a/UI/MainUI/SOGoMicrosoftActiveSyncActions.m
+++ b/UI/MainUI/SOGoMicrosoftActiveSyncActions.m
@@ -21,6 +21,8 @@
#import
+#import
+#import
#import
#import
@@ -54,13 +56,17 @@
ex = [dispatcher dispatchRequest: request inResponse: response context: context];
+ //[[self class] memoryStatistics];
+
if (ex)
{
return [NSException exceptionWithHTTPStatus: 500];
}
RELEASE(dispatcher);
-
+
+ [[SOGoCache sharedCache] killCache];
+
return response;
}
diff --git a/UI/MainUI/SOGoRootPage.m b/UI/MainUI/SOGoRootPage.m
index d8e32c1db..df3e944b1 100644
--- a/UI/MainUI/SOGoRootPage.m
+++ b/UI/MainUI/SOGoRootPage.m
@@ -361,7 +361,7 @@
if (login)
{
- /* We redirect the user to his "homepage" when newLocation could not be
+ /* We redirect the user to their "homepage" when newLocation could not be
deduced from the "cas-location" cookie and the current action is not a
login callback (ticket != nil). */
if (!newLocation || !ticket)
diff --git a/UI/Templates/SOGoACLDanishModificationAdvisory.wox b/UI/Templates/SOGoACLDanishModificationAdvisory.wox
index 20b7dbb0a..929552839 100644
--- a/UI/Templates/SOGoACLDanishModificationAdvisory.wox
+++ b/UI/Templates/SOGoACLDanishModificationAdvisory.wox
@@ -12,7 +12,7 @@
- has modified your access rights for his folder.
+ has modified your access rights for their folder.