Merge to 2.2.10

Conflicts:
	NEWS
	Version
This commit is contained in:
Ludovic Marcotte
2014-11-21 09:17:28 -05:00
588 changed files with 5358 additions and 2554 deletions
+1 -1
View File
@@ -222,7 +222,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self setNote: o];
// Categories
if ((o = [theValues objectForKey: @"Categories"]))
if ((o = [theValues objectForKey: @"Categories"]) && [o length])
[self setCategories: o];
// Birthday
+76 -4
View File
@@ -35,9 +35,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <Foundation/NSDate.h>
#include <SOGo/NSString+Utilities.h>
#include <SOGo/NSData+Crypto.h>
#include <NGExtensions/NGBase64Coding.h>
#include <NGExtensions/NSString+misc.h>
static NSArray *easCommandCodes = nil;
static NSArray *easCommandParameters = nil;
@implementation NSString (ActiveSync)
- (NSString *) sanitizedServerIdWithType: (SOGoMicrosoftActiveSyncFolderType) folderType
@@ -61,9 +66,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
NSString *s;
s = [self stringByEscapingHTMLString];
s = [self safeString];
return [s safeString];
return [s stringByEscapingHTMLString];
}
- (int) activeSyncFolderType
@@ -134,11 +139,78 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- (NSString *) _valueForParameter: (NSString *) theParameter
{
NSArray *components;
NSMutableArray *components;
NSString *s;
int i;
components = [[[self componentsSeparatedByString: @"?"] lastObject] componentsSeparatedByString: @"&"];
components = [NSMutableArray arrayWithArray: [[[self componentsSeparatedByString: @"?"] lastObject] componentsSeparatedByString: @"&"]];
// We handle BASE64 encoded queryStrings. See http://msdn.microsoft.com/en-us/library/ee160227%28v=exchg.80%29.aspx for details.
if ([components count] == 1)
{
NSString *deviceType, *parameterValue;
NSData *queryString;
int cmd_code, deviceid_length, policy_length, devicetype_length, parameter_code, parameter_length, i;
const char* qs_bytes;
queryString = [[components objectAtIndex: 0] dataByDecodingBase64];
qs_bytes = (const char*)[queryString bytes];
if (!easCommandCodes)
{
easCommandCodes = [NSArray arrayWithObjects:@"Sync", @"SendMail", @"SmartForward", @"SmartReply", @"GetAttachment", @"na", @"na", @"na", @"na",
@"FolderSync", @"FolderCreate", @"FolderDelete", @"FolderUpdate", @"MoveItems", @"GetItemEstimate", @"MeetingResponse",
@"Search", @"Settings", @"Ping", @"ItemOperations", @"Provision", @"ResolveRecipients", @"ValidateCert", nil];
RETAIN(easCommandCodes);
}
if (!easCommandParameters)
{
easCommandParameters = [NSArray arrayWithObjects:@"AttachmentName", @"CollectionId", @"na", @"ItemId", @"LongId", @"na", @"Occurrence", @"Options", @"User", nil];
RETAIN(easCommandParameters);
}
// Command code, 1 byte, ie.: cmd=
cmd_code = qs_bytes[1];
[components addObject: [NSString stringWithFormat: @"cmd=%@", [easCommandCodes objectAtIndex: cmd_code]]];
// Device ID length and Device ID (variable)
deviceid_length = qs_bytes[4];
[components addObject: [NSString stringWithFormat: @"deviceId=%@", [[NSData encodeDataAsHexString: [queryString subdataWithRange: NSMakeRange(5, deviceid_length)]] uppercaseString]]];
// Device type length and type (variable)
policy_length = qs_bytes[5+deviceid_length];
devicetype_length = qs_bytes[5+deviceid_length+1+policy_length];
deviceType = [[NSString alloc] initWithData: [queryString subdataWithRange: NSMakeRange(5+deviceid_length+1+policy_length+1, devicetype_length)]
encoding: NSASCIIStringEncoding];
AUTORELEASE(deviceType);
[components addObject: [NSString stringWithFormat: @"deviceType=%@", deviceType]];
// Command Parameters
i = 5+deviceid_length+1+policy_length+1+devicetype_length;
while (i < [queryString length])
{
parameter_code = qs_bytes[i];
parameter_length = qs_bytes[i+1];
parameterValue = [[NSString alloc] initWithData: [queryString subdataWithRange: NSMakeRange(i+1+1, parameter_length)]
encoding: NSASCIIStringEncoding];
AUTORELEASE(parameterValue);
// parameter_code 7 == Options
// http://msdn.microsoft.com/en-us/library/ee237789(v=exchg.80).aspx
if (parameter_code == 7)
[components addObject: [NSString stringWithFormat: @"%@=%@", [easCommandParameters objectAtIndex: parameter_code],
([parameterValue isEqualToString: @"\001"]) ? @"SaveInSent" : @"AcceptMultiPart"]];
else
[components addObject: [NSString stringWithFormat: @"%@=%@", [easCommandParameters objectAtIndex: parameter_code], parameterValue]];
i = i + 1 + 1 + parameter_length;
}
}
for (i = 0; i < [components count]; i++)
{
+180 -61
View File
@@ -29,11 +29,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "SOGoActiveSyncDispatcher+Sync.h"
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSNull.h>
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSSortDescriptor.h>
#import <Foundation/NSTimeZone.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSValue.h>
@@ -122,7 +122,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[o setObjectType: ActiveSyncFolderCacheObject];
[o setTableUrl: [self folderTableURL]];
[o reloadIfNeeded];
[[o properties] removeObjectForKey: @"SyncKey"];
[[o properties] removeObjectForKey: @"SyncCache"];
[[o properties] removeObjectForKey: @"DateCache"];
@@ -147,6 +147,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
return [o properties];
}
- (NSString *) _getNameInCache: (id) theCollection withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
{
NSString *nameInCache;
if (theFolderType == ActiveSyncMailFolder)
nameInCache= [[[theCollection mailAccountFolder] imapFolderGUIDs] objectForKey: [theCollection nameInContainer]];
else
{
NSString *component_name;
if (theFolderType == ActiveSyncContactFolder)
component_name = @"vcard";
else if (theFolderType == ActiveSyncEventFolder)
component_name = @"vevent";
else
component_name = @"vtodo";
nameInCache= [NSString stringWithFormat: @"%@/%@", component_name, [theCollection nameInContainer]];
}
return nameInCache;
}
//
// <?xml version="1.0"?>
@@ -190,7 +213,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
inBuffer: (NSMutableString *) theBuffer
{
NSMutableDictionary *allValues;
NSMutableDictionary *folderMetadata, *dateCache, *syncCache, *allValues;
NSString *clientId, *serverId;
NSArray *additions;
@@ -276,6 +299,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", serverId];
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
[theBuffer appendString: @"</Add>"];
// Update syncCache
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
syncCache = [folderMetadata objectForKey: @"SyncCache"];
dateCache = [folderMetadata objectForKey: @"DateCache"];
[syncCache setObject: [folderMetadata objectForKey: @"SyncKey"] forKey: serverId];
[dateCache setObject: [NSCalendarDate date] forKey: serverId];
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
}
}
}
@@ -375,6 +409,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
}
[theBuffer appendString: @"<Change>"];
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", serverId];
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
[theBuffer appendString: @"</Change>"];
}
}
}
@@ -431,6 +469,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if (![sogoObject isKindOfClass: [NSException class]])
[sogoObject delete];
[theBuffer appendString: @"<Delete>"];
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", serverId];
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
[theBuffer appendString: @"</Delete>"];
// update syncCache
NSMutableDictionary *folderMetadata, *dateCache, *syncCache;
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
syncCache = [folderMetadata objectForKey: @"SyncCache"];
dateCache = [folderMetadata objectForKey: @"DateCache"];
[syncCache removeObjectForKey: serverId];
[dateCache removeObjectForKey: serverId];
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
}
}
}
@@ -488,18 +543,30 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
more_available = NO;
if (theFolderType == ActiveSyncMailFolder && !([theSyncKey isEqualToString: @"-1"]) && theFilterType)
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
// If this is a new sync operation, DateCache and SyncCache needs to be deleted
if ([theSyncKey isEqualToString: @"-1"])
{
[folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"SyncCache"];
[folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"DateCache"];
}
syncCache = [folderMetadata objectForKey: @"SyncCache"];
dateCache = [folderMetadata objectForKey: @"DateCache"];
if ((theFolderType == ActiveSyncMailFolder || theFolderType == ActiveSyncEventFolder || theFolderType == ActiveSyncTaskFolder) &&
!([folderMetadata objectForKey: @"MoreAvailable"]) && // previous sync operation reached the windowSize
!([theSyncKey isEqualToString: @"-1"]) && // new sync operation
theFilterType)
{
NSArray *allKeys;
NSString *key;
int softdelete_count;
softdelete_count = 0;
folderMetadata = [self _folderMetadataForKey: [theCollection nameInContainer]];
dateCache = [folderMetadata objectForKey: @"DateCache"];
syncCache = [folderMetadata objectForKey: @"SyncCache"];
allKeys = [dateCache allKeys];
for (i = 0; i < [allKeys count]; i++)
{
@@ -510,7 +577,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendString: @"<SoftDelete xmlns=\"AirSync:\">"];
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", key];
[s appendString: @"</SoftDelete>"];
[syncCache removeObjectForKey: key];
[dateCache removeObjectForKey: key];
@@ -520,7 +587,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if (softdelete_count >= theWindowSize)
{
[folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"];
[self _setFolderMetadata: folderMetadata forKey: [theCollection nameInContainer]];
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
more_available = YES;
*theLastServerKey = theSyncKey;
@@ -532,7 +599,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
[folderMetadata removeObjectForKey: @"MoreAvailable"];
[self _setFolderMetadata: folderMetadata forKey: [theCollection nameInContainer]];
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
}
//
@@ -557,7 +624,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
NSArray *allComponents;
BOOL updated;
int deleted;
int deleted, return_count;
if (theFolderType == ActiveSyncContactFolder)
component_name = @"vcard";
@@ -567,19 +634,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
component_name = @"vtodo";
allComponents = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey fromDate: theFilterType];
allComponents = [allComponents sortedArrayUsingDescriptors: [NSArray arrayWithObjects: [[NSSortDescriptor alloc] initWithKey: @"c_lastmodified" ascending:YES], nil]];
// Check for the WindowSize
max = [allComponents count];
// Disabled for now for GCS folders.
// if (max > theWindowSize)
// {
// max = theWindowSize;
// more_available = YES;
// }
return_count = 0;
for (i = 0; i < max; i++)
{
// Check for the WindowSize and slice accordingly
if (return_count >= theWindowSize)
{
more_available = YES;
// -1 to make sure that we miss no event in case there are more with the same c_lastmodified
*theLastServerKey = [NSString stringWithFormat: @"%d", [[component objectForKey: @"c_lastmodified"] intValue] - 1];
break;
}
component = [allComponents objectAtIndex: i];
deleted = [[component objectForKey: @"c_deleted"] intValue];
@@ -590,17 +664,28 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if (deleted)
{
[s appendString: @"<Delete xmlns=\"AirSync:\">"];
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", uid];
[s appendString: @"</Delete>"];
if ([syncCache objectForKey: uid])
{
[s appendString: @"<Delete xmlns=\"AirSync:\">"];
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", uid];
[s appendString: @"</Delete>"];
[syncCache removeObjectForKey: uid];
[dateCache removeObjectForKey: uid];
return_count++;
}
}
else
{
updated = YES;
if ([[component objectForKey: @"c_creationdate"] intValue] > [theSyncKey intValue])
if (![syncCache objectForKey: uid])
updated = NO;
else if ([[component objectForKey: @"c_lastmodified"] intValue] == [[syncCache objectForKey: uid] intValue])
continue;
return_count++;
sogoObject = [theCollection lookupName: [uid sanitizedServerIdWithType: theFolderType]
inContext: context
acquire: 0];
@@ -635,11 +720,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
continue;
}
}
[syncCache setObject: [component objectForKey: @"c_lastmodified"] forKey: uid];
if (updated)
[s appendString: @"<Change xmlns=\"AirSync:\">"];
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: @"<Add xmlns=\"AirSync:\">"];
}
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", uid];
[s appendString: @"<ApplicationData xmlns=\"AirSync:\">"];
@@ -652,11 +745,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendString: @"</Change>"];
else
[s appendString: @"</Add>"];
return_count++;
}
} // for ...
folderMetadata = [NSDictionary dictionaryWithObject: [theCollection davCollectionTag]
forKey: @"SyncKey"];
if (more_available)
{
[folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"];
[folderMetadata setObject: *theLastServerKey forKey: @"SyncKey"];
}
else
{
[folderMetadata removeObjectForKey: @"MoreAvailable"];
[folderMetadata setObject: [theCollection davCollectionTag] forKey: @"SyncKey"];
}
[self _setFolderMetadata: folderMetadata
forKey: [NSString stringWithFormat: @"%@/%@", component_name, [theCollection nameInContainer]]];
}
@@ -685,27 +789,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
sequence: [[[allMessages objectAtIndex: i] allValues] lastObject]]];
}
// If it's a new Sync operation, DateCache and SyncCache need to be deleted
// but GUID stored by folderSync shouldn't be touched
folderMetadata = [self _folderMetadataForKey: [theCollection nameInContainer]];
if ([theSyncKey isEqualToString: @"-1"])
{
[folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"SyncCache"];
[folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"DateCache"];
}
// Check whether GUID in cache is equal to the GUID from imap - this is to avoid cache corruptions if a folder has been renamed and a new folder
// with the same name has been created but folderSync has not yet updated the cache
if (!([[theCollection nameInContainer] isEqualToString:
[NSString stringWithFormat: @"folder%@", [self globallyUniqueIDToIMAPFolderName: [folderMetadata objectForKey: @"GUID"] type: theFolderType]]]))
{
NSLog(@"GUID mismatch don't sync now!");
return;
}
syncCache = [folderMetadata objectForKey: @"SyncCache"];
dateCache = [folderMetadata objectForKey: @"DateCache"];
sortedBySequence = [[NSMutableArray alloc] initWithDictionary: syncCache];
[sortedBySequence sortUsingSelector: @selector(compareSequence:)];
[sortedBySequence autorelease];
@@ -849,8 +932,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[folderMetadata setObject: [theCollection davCollectionTag] forKey: @"SyncKey"];
}
[self _setFolderMetadata: folderMetadata
forKey: [theCollection nameInContainer]];
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
} // default:
break;
} // switch (folderType) ...
@@ -862,9 +944,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[theBuffer appendString: @"<Commands>"];
[theBuffer appendString: s];
[theBuffer appendString: @"</Commands>"];
if (more_available)
[theBuffer appendString: @"<MoreAvailable/>"];
}
}
@@ -926,6 +1005,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
inCollection: theCollection
withType: theFolderType
inBuffer: theBuffer];
*processed = YES;
}
else if ([[element tagName] isEqualToString: @"Fetch"])
{
@@ -954,7 +1034,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
NSMutableString *changeBuffer, *commandsBuffer;
BOOL getChanges, first_sync;
unsigned int windowSize, v;
unsigned int windowSize, v, status;
changeBuffer = [NSMutableString string];
commandsBuffer = [NSMutableString string];
@@ -965,6 +1045,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
collection = [self collectionFromId: realCollectionId type: folderType];
syncKey = davCollectionTag = [[(id)[theDocumentElement getElementsByTagName: @"SyncKey"] lastObject] textValue];
if (collection == nil)
{
// Collection not found - next folderSync will do the cleanup
//NSLog(@"Sync Collection not found %@ %@", collectionId, realCollectionId);
[theBuffer appendString: @"<Collection>"];
[theBuffer appendFormat: @"<SyncKey>%@</SyncKey>", syncKey];
[theBuffer appendFormat: @"<CollectionId>%@</CollectionId>", collectionId];
[theBuffer appendFormat: @"<Status>%d</Status>", 8];
[theBuffer appendString: @"</Collection>"];
return;
}
// We check for a window size, default to 100 if not specfied or out of bounds
windowSize = [[[(id)[theDocumentElement getElementsByTagName: @"WindowSize"] lastObject] textValue] intValue];
@@ -978,6 +1071,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
windowSize = v;
lastServerKey = nil;
status = 1;
// From the documention, if GetChanges is missing, we must assume it's a YES.
// See http://msdn.microsoft.com/en-us/library/gg675447(v=exchg.80).aspx for all details.
@@ -995,6 +1089,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
first_sync = YES;
*changeDetected = YES;
}
else if ((![syncKey isEqualToString: @"-1"]) && !([[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"SyncCache"]))
{
//NSLog(@"Reset folder: %@", [collection nameInContainer]);
davCollectionTag = @"0";
first_sync = YES;
*changeDetected = YES;
if (!([[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"displayName"]))
status = 13; // need folderSync
else
status = 3; // do a complete resync
}
// We check our sync preferences and we stash them
bodyPreferenceType = [[(id)[[(id)[theDocumentElement getElementsByTagName: @"BodyPreference"] lastObject] getElementsByTagName: @"Type"] lastObject] textValue];
@@ -1004,7 +1110,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[context setObject: bodyPreferenceType forKey: @"BodyPreferenceType"];
// 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
@@ -1013,9 +1118,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self processSyncGetChanges: theDocumentElement
inCollection: collection
withWindowSize: windowSize
//withWindowSize: 5
withSyncKey: syncKey
withFolderType: folderType
withFilterType: [NSCalendarDate dateFromFilterType: [[(id)[theDocumentElement getElementsByTagName: @"FilterType"] lastObject] textValue]]
//withFilterType: [NSCalendarDate dateFromFilterType: @"7"]
inBuffer: changeBuffer
lastServerKey: &lastServerKey];
}
@@ -1037,10 +1144,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
inBuffer: s
processed: &processed];
if (processed)
// Windows phons don't empty Responses tags - such as: <Responses></Responses>.
// We onnly generate this tag when the command has generated a response.
if (processed && [s length])
[commandsBuffer appendFormat: @"<Responses>%@</Responses>", s];
else
[commandsBuffer appendString: s];
}
// If we got any changes or if we have applied any commands
@@ -1049,9 +1156,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
if (lastServerKey)
davCollectionTag = lastServerKey;
else if (![[self _folderMetadataForKey: [collection nameInContainer]] objectForKey: @"MoreAvailable"])
davCollectionTag = [collection davCollectionTag];
else
{
// Use the SyncKey saved by processSyncGetChanges - if processSyncGetChanges is not called (because of getChanges=false)
// SyncKey has the value of the previous sync operation.
davCollectionTag = [[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"SyncKey"];
if (!davCollectionTag)
davCollectionTag = [collection davCollectionTag];
}
*changeDetected = YES;
}
else
@@ -1074,10 +1188,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[theBuffer appendFormat: @"<SyncKey>%@</SyncKey>", davCollectionTag];
[theBuffer appendFormat: @"<CollectionId>%@</CollectionId>", collectionId];
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
[theBuffer appendFormat: @"<Status>%d</Status>", status];
// MoreAvailable breaks Windows Mobile devices if not between <Status> and <Commands>
// https://social.msdn.microsoft.com/Forums/en-US/040b254e-f47e-4cc1-a397-6d8393cdb819/airsyncmoreavailable-breaks-windows-mobile-devices-what-am-i-doing-wrong?forum=os_exchangeprotocols
if ([[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"MoreAvailable"])
[theBuffer appendString: @"<MoreAvailable/>"];
[theBuffer appendString: changeBuffer];
[theBuffer appendString: commandsBuffer];
[theBuffer appendString: changeBuffer];
[theBuffer appendString: @"</Collection>"];
}
File diff suppressed because it is too large Load Diff
+6 -1
View File
@@ -67,8 +67,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <Appointments/iCalPerson+SOGo.h>
#include <Mailer/NSString+Mail.h>
#include <Mailer/SOGoMailBodyPart.h>
#include <SOGo/SOGoUser.h>
#include <SOGo/NSString+Utilities.h>
typedef struct {
uint32_t dwLowDateTime;
@@ -323,6 +323,11 @@ struct GlobalObjectId {
if (s)
{
// We sanitize the content immediately, in case we have non-UNICODE safe
// characters that would be re-encoded later in HTML entities and thus,
// ignore afterwards.
s = [s safeString];
body = [s dataUsingEncoding: NSUTF8StringEncoding];
}
+3 -2
View File
@@ -16,10 +16,11 @@ ADDITIONAL_INCLUDE_DIRS += \
-I../../SOPE
ADDITIONAL_LIB_DIRS += \
-L../SoObjects/SOGo/SOGo.framework/ \
-L../SoObjects/SOGo/SOGo.framework/Versions/Current/sogo \
-L../SoObjects/SOGo/$(GNUSTEP_OBJ_DIR)/ \
-L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \
-L/usr/local/lib
-L/usr/local/lib \
-Wl,-rpath,$(GNUSTEP_SYSTEM_LIBRARIES)/sogo
BUNDLE_LIBS += \
-lSOGo \
+33 -18
View File
@@ -127,7 +127,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
tz = [(iCalDateTime *)[self firstChildWithTag: @"dtstart"] timeZone];
if (!tz)
tz = [iCalTimeZone timeZoneForName: @"Europe/London"];
tz = [iCalTimeZone timeZoneForName: [userTimeZone name]];
[s appendFormat: @"<TimeZone xmlns=\"Calendar:\">%@</TimeZone>", [tz activeSyncRepresentationInContext: context]];
@@ -334,14 +334,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[o intValue];
}
//
//
//
if ((o = [theValues objectForKey: @"MeetingStatus"]))
{
[o intValue];
}
//
// 0- normal, 1- personal, 2- private and 3-confidential
//
@@ -361,14 +353,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self setAccessClass: @"PUBLIC"];
}
}
if ((o = [theValues objectForKey: @"TimeZone"]))
{
// Ugh, we ignore it for now.
userTimeZone = [[[context activeUser] userDefaults] timeZone];
tz = [iCalTimeZone timeZoneForName: [userTimeZone name]];
[(iCalCalendar *) parent addTimeZone: tz];
}
// We ignore TimeZone sent by mobile devices for now.
// 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];
//}
// FIXME: merge with iCalToDo
if ((o = [[theValues objectForKey: @"Body"] objectForKey: @"Data"]))
@@ -481,11 +474,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self setOrganizer: person];
}
//
// iOS is plain stupid here. It seends event invitations with no Organizer.
// We check this corner-case and if MeetingStatus == 1 (see http://msdn.microsoft.com/en-us/library/ee219342(v=exchg.80).aspx or details)
// and there's no organizer, we fake one.
//
if ((o = [theValues objectForKey: @"MeetingStatus"]))
{
if ([o intValue] == 1 && ![theValues objectForKey: @"Organizer_Email"])
{
iCalPerson *person;
person = [iCalPerson elementWithTag: @"organizer"];
[person setEmail: [[[context activeUser] primaryIdentity] objectForKey: @"email"]];
[person setCn: [[context activeUser] cn]];
[person setPartStat: @"ACCEPTED"];
[self setOrganizer: person];
}
}
// Attendees - we don't touch the values if we're an attendee. This is gonna
// be done automatically by the ActiveSync client when invoking MeetingResponse.
if (![self userIsAttendee: [context activeUser]])
{
if ((o = [theValues objectForKey: @"Attendees"]))
// Windows phones sens sometimes an empty Attendees tag.
// We check it's an array before processing it.
if ((o = [theValues objectForKey: @"Attendees"])&& [o isKindOfClass: [NSArray class]])
{
NSMutableArray *attendees;
NSDictionary *attendee;
+3 -1
View File
@@ -76,15 +76,17 @@ struct SYSTEMTIME {
byMonth = [rrule byMonth];
if ([byMonth count] > 0)
{
tzData->wYear = 0;
tzData->wMonth = [[byMonth objectAtIndex: 0] intValue];
mask = [rrule byDayMask];
tzData->wDayOfWeek = [mask firstDay];
tzData->wDay = [mask firstOccurrence];
tzData->wDay = ([mask firstOccurrence] == -1) ? 5 : [mask firstOccurrence];
dateValue = [self startDate];
tzData->wHour = [dateValue hourOfDay];
tzData->wMinute = [dateValue minuteOfHour];
tzData->wSecond = [dateValue secondOfMinute];
tzData->wMilliseconds = 0;
}
}
+1863
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,7 +1,7 @@
all: $(patsubst %.asciidoc,%.pdf,$(wildcard *.asciidoc))
%.pdf : %.asciidoc
asciidoc -a docinfo1 -b docbook -d book -d book -o $<.docbook $<
asciidoc -a docinfo1 -b docbook -d book -o $<.docbook $<
fop -c fonts/fop-config.xml -xsl docbook/xsl/sogo-fo.xsl -xml $<.docbook -pdf $@
clean:
+21 -10
View File
@@ -193,7 +193,7 @@ installation for a Red Hat or CentOS distribution.
Software Downloads
~~~~~~~~~~~~~~~~~~
SOGo can be installed using the+yum+utility. To do so, first create
SOGo can be installed using the `yum` utility. To do so, first create
the `/etc/yum.repos.d/inverse.repo` configuration file with the following
content:
@@ -258,13 +258,13 @@ In SOGo, the user's applications settings are stored
in `/etc/sogo/sogo.conf`. You can use your favourite text editor to
modify the file.
The +sogo.conf+ file is a serialized _property list_. This simple format
The `sogo.conf` file is a serialized _property list_. This simple format
encapsulates four basic data types: arrays, dictionaries (or hashes),
strings and numbers. Numbers are represented as-is, except for booleans
which can take the unquoted values `YES` and `NO`. Strings are not
mandatorily quoted, but doing so will avoid you many problems. A
dictionary is a sequence of key and value pairs separated in their
middle with a `=` sign. It starts with a `\{` and ends with a
middle with a `=` sign. It starts with a `{` and ends with a
corresponding `}`. Each value definition in a dictionary ends with a
semicolon. An array is a chain of values starting with `(` and ending
with `)`, where the values are separated with a `,`. Also, the file
@@ -1167,7 +1167,7 @@ keytool -import -keystore /etc/ssl/certs/java/cacerts \
*The certificate used by the CAS server must also be trusted by SOGo.*
In case of a self-signed certificate, this means exporting tomcat's
certificate using the +keytool+utility, converting it to PEM format and
certificate using the `keytool` utility, converting it to PEM format and
appending it to the `ca-certificates.crt` file (the name and location of
that file differs between distributions). Basically:
@@ -1581,8 +1581,8 @@ Note that TLS is supported but SSL is not.
|D |SOGoSieveFolderEncoding
|Parameter used to specify which encoding is used for IMAP folder names
in Sieve filters. Defaults to "UTF-7". The other possible value is
"UTF-8".
in Sieve filters. Defaults to `UTF-7`. The other possible value is
`UTF-8`.
|U |SOGoMailShowSubscribedFoldersOnly
|Parameter used to specify if the Web interface should only show
@@ -1632,6 +1632,12 @@ cronjob `sogo-tmpwatch`.
Defaults to `/var/spool/sogo`.
|S |NGImap4DisableIMAP4Pooling
|Disables IMAP pooling when set to `YES`. Enable pooling by setting to
`NO` or using a caching proxy like imapproxy.
The default value is `YES`.
|S |NGImap4ConnectionStringSeparator
|Parameter used to set the IMAP mailbox separator. Setting this will
also have an impact on the mailbox separator used by Sieve filters.
@@ -1644,7 +1650,7 @@ SASL mechanism. Please note that feature might be limited at this time.
|D |NGImap4ConnectionGroupIdPrefix
|Prefix to prepend to names in IMAP ACL transactions, to indicate the
name is a group name not a user name.
name is a group name, not a user name.
RFC4314 gives examples where group names are prefixed with `$`. Dovecot,
for one, follows this scheme, and will, for example, apply permissions
@@ -1993,7 +1999,7 @@ Defaults to `NO` when unset.
SOGo Configuration Summary
~~~~~~~~~~~~~~~~~~~~~~~~~~
The complete SOGo configuration file+/etc/sogo/sogo.conf+should look
The complete SOGo configuration file `/etc/sogo/sogo.conf` should look
like this:
----
@@ -2325,7 +2331,7 @@ ActiveSync:
|Parameter used to set the maximum amount of time, in seconds, SOGo will
wait before replying to a Ping command.
If not set, it defaults to `5` seconds.
If not set, it defaults to `10` seconds.
|S |SOGoMaximumSyncInterval
|Parameter used to set the maximum amount of time, in seconds, SOGo will
@@ -2336,7 +2342,8 @@ If not set, it defaults to `30` seconds.
|S |SOGoInternalSyncInterval
|Parameter used to set the maximum amount of time, in seconds, SOGo will
wait before doing an internal check for data changes (add, delete, and
update). This parameter must be lower than _SOGoMaximumSyncInterval_.
update). This parameter must be lower than _SOGoMaximumSyncInterval_ and
_SOGoMaximumPingInterval_.
If not set, it defaults to `10` seconds.
@@ -2379,6 +2386,10 @@ see http://support.microsoft.com/kb/291621 for configuration
instructions. On the SOGo side, _SOGoEnablePublicAccess_ must be set to
`YES` and the URL to use must be of the following format:
`http://<hostname>/SOGo/dav/public/%NAME%/freebusy.ifb`
* If you have very large mail folders (thousands of messages), you will
need to adjust the word size of your IMAP server. In Dovecot, the parameter
to increase is "imap_max_line_length" while under Cyrus IMAP Server, the
parameter is "maxword". We suggest a buffer of 2MB.
In order to use the SOGo ActiveSync support code in production
environments, you need to get a proper usage license from Microsoft.
@@ -233,13 +233,12 @@ Installation
This section will guide you through the installation of the native
Microsoft Outlook compatibility layer SOGo offers.
Red Hat Enterprise Linux v5 and v6
Red Hat Enterprise Linux v6 x86_64
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you are using Red Hat Enterprise Linux (or CentOS) version 5 or
version 6, packages for Samba 4, OpenChange and SOGo and the SOGo
OpenChange backend are available from SOGo's web site. Please follow the
instructions from
If you are using Red Hat Enterprise Linux version 6 x86_64, packages
for Samba 4, OpenChange and SOGo and the SOGo OpenChange backend are
available from SOGo's web site. Please follow the instructions from
http://www.sogo.nu/english/downloads/backend_nightly.html.
In order to satisfy certain dependencies, you should also add the EPEL
@@ -253,53 +252,48 @@ installation:
----
yum clean all && yum makecache
yum install samba4 \
yum install samba \
openchange \
sogo-openchange-backend \
openchange-ocsmanager \
openchange-rpcproxy
openchange-rpcproxy \
mysql-server \
MySQL-python
----
Once the packages are installed, refer to the _Configuration_ chapter
from this guide.
Debian 6.0 (Squeeze) and Ubuntu 12.04 (Precise Pangolin)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[NOTE]
Samba4/OpenChange are not available for now on CentOS 5 i386/x86_64,
CentOS 6 i386 and CentOS 7.
Samba 4, OpenChange, SOGo and the SOGo OpenChange backend are now
Debian 7.0 (Wheezy) and Ubuntu 12.04 (Precise Pangolin)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SOGo, OpenChange and the SOGo OpenChange backend are now
available from SOGo's web site. Please follow the instructions from
http://www.sogo.nu/english/downloads/backend_nightly.html to setup your
http://www.sogo.nu/english/downloads/backend.html to setup your
apt sources.
Debian Squeeze ships an older version of some libraries required by
Samba 4. In order to workaround this, users of this distribution will
have to use the _squeeze-backports_ repository. To do so, create
For Samba 4, you need to use the _wheezy-backports_ repository. To do so, create
`/etc/apt/sources.list.d/backports.list`:
deb http://backports.debian.org/debian-backports squeeze-backports main
deb http://http.debian.net/debian wheezy-backports main
Then install the dependencies on Debian Squeeze, do:
On Ubuntu 12.04, you will also have to add the Wheezy sources:
----
apt-get update
apt-get install -t squeeze-backports libwbclient-dev samba-common smbclient libsmbclient libsmbclient-dev
----
deb http://ftp.us.debian.org/debian wheezy main
deb http://security.debian.org/ wheezy/updates main
Once ready, install the `samba4` package on top of an existing SOGo
Then install Samba 4 on top of an existing SOGo
installation:
----
apt-get update
apt-get install samba4
apt-get -t wheezy-backports install samba samba-dev
----
The current post installation script shipped with the Samba 4 package is
far from perfect and might fail even on a fresh install. The following
command is needed to let dpkg know that everything is fine about Samba 4
if the post install script fails.
sed --in-place 'N; s/Package: samba4\nStatus: install ok half-configured/Package: samba4\nStatus: install ok installed/;' /var/lib/dpkg/status
Once completed, install the packages related to OpenChange and the SOGo
provider:
@@ -307,13 +301,53 @@ provider:
apt-get install openchangeserver \
sogo-openchange \
openchangeproxy \
openchange-ocsmanager \
openchange-rpcproxy
python-ocsmanager \
mysql-server \
python-mysqldb
----
Once the packages are installed, refer to the _Configuration_ chapter
from this guide.
[NOTE]
On Ubuntu 12.04, the Samba init scripts need to be modified to
disable the upstart check. For more details, refer to:
https://wiki.samba.org/index.php/Samba4/InitScript
Ubuntu 14.04 (Trusty Tahr)
~~~~~~~~~~~~~~~~~~~~~~~~~~
For Ubuntu 14.04, you must not use the Debian Wheezy backports.
Please follow the instructions from
http://www.sogo.nu/english/downloads/backend.html to setup your
apt sources.
Then install Samba 4 on top of an existing SOGo
installation:
----
apt-get update
apt-get install samba samba-dev
----
Once completed, install the packages related to OpenChange and the SOGo
provider:
----
apt-get install openchangeserver \
sogo-openchange \
openchangeproxy \
python-ocsmanager \
mysql-server \
python-mysqldb
----
Once the packages are installed, refer to the _Configuration_ chapter
from this guide.
Configuration
-------------
@@ -349,16 +383,14 @@ You might consider changing the realm and domain used, to suit your
enviroment.
You might also have to
remove `/etc/samba4/smb.conf` (or `/etc/samba/smb.conf` on Debian-based
distributions) prior running this command.
remove `/etc/samba/smb.conf` prior running this command.
Add the following parameters to the `[global]` section of the
`/etc/samba4/smb.conf` (`/samba/smb.conf` if you use a Debian-based
distribution) configuration file:
`/etc/samba/smb.conf` configuration file:
----
### Configuration required by OpenChange server ###
dcerpc endpoint servers = +epmapper, +mapiproxy
dcerpc endpoint servers = epmapper, mapiproxy, dnsserver
dcerpc_mapiproxy:server = true
dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
### Configuration required by OpenChange server ###
@@ -392,11 +424,22 @@ Your Samba 4 configuration file should look like this:
OpenChange Configuration
~~~~~~~~~~~~~~~~~~~~~~~~
OpenChange 2.2 stores its metadata in MySQL so you need to have it installed.
First, create the OpenChange MySQL user:
----
$ mysql -u root -p
mysql> CREATE USER 'openchange-user'@'localhost' IDENTIFIED BY 'openchange$123';
mysql> GRANT ALL PRIVILEGES ON `openchange`.* TO 'openchange-user'@'localhost' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
----
The Samba AD schema needs to be filled with additional object
definitions by running the following commands: 
----
openchange_provision
openchange_provision --standalone
NOTE: This operation can take several minutes
[+] Step 1: Register Exchange OIDs
@@ -410,38 +453,59 @@ NOTE: This operation can take several minutes
[+] Step 9: Add Exchange classes to Samba schema
[+] Step 10: Add possSuperior attributes to Exchange classes
[+] Step 11: Extend existing Samba classes and attributes
[+] Step 12: Exchange Samba with Exchange configuration objects
[+] Step 12: Generic Exchange configuration objects
[+] Step 13: Finalize generic Exchange configuration objects
[SUCCESS] Done!
[+] Step 1: Exchange Samba registration
[SUCCESS] Done!
[+] Step 1: Register Exchange Samba as the main server
[SUCCESS] Done!
----
You can safely ignore the "`ERROR: no subClassOf 'serviceAdministrationPoint' for 'rRASAdministrationConnectionPoint'`" message when running the `openchange_provision` command.
Provision the OpenChange database: 
Create the OpenChange database: 
----
openchange_provision --openchangedb
openchange_provision --openchangedb --openchangedb-uri 'mysql://openchange-user:openchange$123@localhost/openchange'
Setting up openchange db
[+] Public Folders
===================
* Public Folder Root 0x0100000000000001
* IPM_SUBTREE 0x0200000000000001
* NON_IPM_SUBTREE 0x0300000000000001
* EFORMS REGISTRY 0x0400000000000001
* OFFLINE ADDRESS BOOK 0x0500000000000001
* /o=First Organization/cn=addrlists/cn=oabs/cn=Default Offline Address Book 0x0600000000000001
* SCHEDULE+ FREE BUSY 0x0700000000000001
* EX:/o=First Organization/ou=Exchange Administrative Group (UBUNTU-OC) 0x0800000000000001
* Events Root 0x0900000000000001
* Public Folder Root : 0x0100000000000001 (72057594037927937)
* IPM_SUBTREE : 0x0200000000000001 (144115188075855873)
* NON_IPM_SUBTREE : 0x0300000000000001 (216172782113783809)
* EFORMS REGISTRY : 0x0400000000000001 (288230376151711745)
* OFFLINE ADDRESS BOOK : 0x0500000000000001 (360287970189639681)
* /o=First Organization/cn=addrlists/cn=oabs/cn=Default Offline Address Book: 0x0600000000000001 (432345564227567617)
* SCHEDULE+ FREE BUSY : 0x0700000000000001 (504403158265495553)
* EX:/o=first organization/ou=first administrative group: 0x0800000000000001 (576460752303423489)
* Events Root : 0x0900000000000001 (648518346341351425)
----
Finally, modify `/etc/samba/smb.conf` to specify OpenChange connection information
for its indexing database. Add the following at the end of the `[global]` section:
----
mapistore:namedproperties = mysql
namedproperties:mysql_user = openchange-user
namedproperties:mysql_pass = openchange$123
namedproperties:mysql_host = localhost
namedproperties:mysql_db = openchange
mapistore:indexing_backend = mysql://openchange-user:openchange$123@localhost/openchange
mapiproxy:openchangedb = mysql://openchange-user:openchange$123@localhost/openchange
----
On RHEL, make sure SELinux is disabled:
setenforce 0
Next, you can start Samba using the usual command :
Next, you can start Samba using the usual command:
/etc/init.d/samba4 start
/etc/init.d/samba start
On upstart-based distributions, use:
start samba-ad-dc
You can also launch the OpenChange web services:
@@ -503,6 +567,10 @@ On Debian-based distributions, do:
update-rc.d apache2 defaults && /etc/init.d/apache2 restart
[NOTE]
Debian-based distributions are not supported anymore for
OCSManager/rpcproxy. Support will soon resume.
Name Service Configuration for Web Services
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -540,14 +608,13 @@ samba-tool domain passwordsettings set --complexity=off
samba-tool domain passwordsettings set --min-pwd-length=1
samba-tool user add <username>
samba-tool user setexpiry <username> --noexpiry
# create user in openchange+ +openchange_newuser --create <username>
# create user in openchange
openchange_newuser --create <username>
----
If you don't have a trust between your IMAP server and SOGo, you must at
this point set the cleartext password of the newly created user in
`/var/lib/samba4/private/mapistore/<username/password` (or
`/var/lib/samba/private/mapistore/<username/password` on Debian-based
distributions).
`/var/lib/samba/private/mapistore/<username/password`.
This per-user file contains the cleartext password of the user as a
UTF-8 string, on a single line. This password will be used to
@@ -1,193 +0,0 @@
<?xml version='1.0'?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<!-- ********************************************************************
SOGo Documentation Docbook FO Parameters
This file is part of the SOGo project.
Authors:
- Inverse inc. <info@inverse.ca>
Copyright (C) 2011-2014 Inverse inc.
License: GFDL 1.2 or later. http://www.gnu.org/licenses/fdl.html
******************************************************************** -->
<!--
Global Tasks
TODO prettier revhistory
TODO prettier Table of Contents
TODO generate PDF table of contents (like OSX's Preview shows on the right hand side)
TODO title 2
- align with text?
- more above whitespace
TODO change the bullet for a prettier one
TODO title 3 and 4
- align with text?
- should be easier to differentiate (check network guide)
TODO icon on line wrap in monospace boxes
TODO caution, notes, warnings, etc.
- box around it
- sexy icon
TODO -> is converted into an arrow but it's not pretty (is it font or docbook-thingy?)
-->
<!--
Load default values
Real upstream schema is at:
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
but we decided to load all sensible local xsd since it only produce a warning on missing imports.
-->
<!-- CentOS / RHEL -->
<xsl:import href="/usr/share/sgml/docbook/xsl-stylesheets/fo/docbook.xsl"/>
<!-- Debian / Ubuntu -->
<xsl:import href="/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl"/>
<!-- OSX through mac ports -->
<xsl:import href="/opt/local/share/xsl/docbook-xsl/fo/docbook.xsl"/>
<!-- title page extra styling -->
<xsl:import href="titlepage-fo.xsl"/>
<!-- header / footer extra styling -->
<xsl:import href="headerfooter-fo.xsl"/>
<!-- attaching an image to the verso legalnotice component -->
<xsl:template match="legalnotice" mode="book.titlepage.verso.mode">
<xsl:apply-templates mode="titlepage.mode"/>
<fo:block text-align="right">
<fo:external-graphic src="url('images/inverse-logo.jpg')" width="3in" content-width="scale-to-fit"/>
</fo:block>
</xsl:template>
<!-- stylesheet options -->
<xsl:param name="title.font.family">Lato-Medium</xsl:param>
<xsl:param name="chapter.autolabel" select="0"/>
<xsl:attribute-set name="component.title.properties">
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
<xsl:attribute name="border-bottom">solid 2px</xsl:attribute>
<xsl:attribute name="margin-bottom">1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level1.properties">
<xsl:attribute name="border-bottom">solid 1px</xsl:attribute>
<xsl:attribute name="margin-top">1em</xsl:attribute>
<xsl:attribute name="margin-bottom">1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level2.properties">
<xsl:attribute name="margin-top">1em</xsl:attribute>
<xsl:attribute name="margin-bottom">1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level3.properties">
<xsl:attribute name="margin-top">1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level4.properties">
<xsl:attribute name="margin-top">1em</xsl:attribute>
</xsl:attribute-set>
<!-- paragraph spacing -->
<xsl:attribute-set name="normal.para.spacing">
<xsl:attribute name="space-before.optimum">1.5em</xsl:attribute>
<xsl:attribute name="space-before.minimum">1.5em</xsl:attribute>
<xsl:attribute name="space-before.maximum">2.2em</xsl:attribute>
</xsl:attribute-set>
<!-- default fonts -->
<xsl:param name="body.font.family">Lato-Light</xsl:param>
<xsl:param name="body.font.master">10</xsl:param>
<xsl:param name="monospace.font.family">Incosolata</xsl:param>
<!-- revision table layout -->
<xsl:attribute-set name="revhistory.title.properties">
<xsl:attribute name="font-size">12pt</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
<xsl:attribute name="text-align">center</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="revhistory.table.properties">
<xsl:attribute name="break-before">page</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="revhistory.table.cell.properties">
<xsl:attribute name="border-bottom">1px solid</xsl:attribute>
</xsl:attribute-set>
<!-- Table Of Contents (TOC) options -->
<!-- We only want 2 level of ToC depth -->
<xsl:param name="toc.section.depth" select="2"/>
<!-- titles left margin -->
<xsl:attribute-set name="section.title.properties">
<xsl:attribute name="start-indent"><xsl:value-of select="$body.start.indent"/></xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="list.item.spacing">
<xsl:attribute name="space-before.optimum">0em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.2em</xsl:attribute>
</xsl:attribute-set>
<!-- lists type -->
<xsl:template name="itemizedlist.label.markup">
<xsl:param name="itemsymbol" select="'square'"/>
<xsl:choose>
<xsl:when test="$itemsymbol='square'"><fo:inline font-family="Lato">&#x220f;</fo:inline></xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="next.itemsymbol">
<xsl:param name="itemsymbol" select="'default'"/>
<xsl:choose>
<xsl:otherwise>square</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- admonition -->
<xsl:param name="admon.graphics" select="1"></xsl:param>
<xsl:param name="admon.graphics.path">images/</xsl:param>
<xsl:param name="admon.graphics.extension">.png</xsl:param>
<xsl:attribute-set name="graphical.admonition.properties">
<xsl:attribute name="border-top">1px solid</xsl:attribute>
<xsl:attribute name="border-bottom">1px solid</xsl:attribute>
<xsl:attribute name="padding-top">0.5em</xsl:attribute>
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
<xsl:attribute name="margin-left">2em</xsl:attribute>
</xsl:attribute-set>
<!-- grey boxes around code (screen, programlisting) -->
<xsl:param name="shade.verbatim" select="1"/>
<xsl:attribute-set name="shade.verbatim.style">
<xsl:attribute name="background-color">#E0E0E0</xsl:attribute>
<xsl:attribute name="border">thin #9F9F9F solid</xsl:attribute>
<xsl:attribute name="margin">0pt</xsl:attribute>
<xsl:attribute name="padding">0.5em</xsl:attribute>
<!-- prevent page breaks in screen and programlisting tags -->
<xsl:attribute name="keep-together.within-column">always</xsl:attribute>
</xsl:attribute-set>
<!-- breaking long lines in code (screen, programlisting) -->
<xsl:attribute-set name="monospace.verbatim.properties">
<xsl:attribute name="wrap-option">wrap</xsl:attribute>
</xsl:attribute-set>
<!-- don't show raw links in [ .. ] after a link -->
<xsl:param name="ulink.show" select="0"/>
<!-- blue underlined hyperlink -->
<xsl:attribute-set name="xref.properties">
<xsl:attribute name="color">blue</xsl:attribute>
<xsl:attribute name="text-decoration">underline</xsl:attribute>
</xsl:attribute-set>
<!-- copyright in range instead of seperated years -->
<xsl:param name="make.year.ranges" select="1" />
<!-- variablelist behavior (asciidoc's term:: lists) -->
<!-- <xsl:param name="variablelist.term.break.after" select="1" /> -->
</xsl:stylesheet>
<!-- vim: set shiftwidth=2 tabstop=2 expandtab: -->
+7
View File
@@ -165,6 +165,13 @@
<xsl:attribute name="text-decoration">underline</xsl:attribute>
</xsl:attribute-set>
<!-- strong emphasis in bold -->
<xsl:template match="emphasis[@role='strong']">
<fo:inline font-family="Lato" font-weight="normal">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
<!-- copyright in range instead of seperated years -->
<xsl:param name="make.year.ranges" select="1" />
+3 -3
View File
@@ -1,7 +1,7 @@
<!-- TODO have the build system take care of this -->
<releaseinfo>Version 2.2.9 - September 2014</releaseinfo>
<subtitle>for version 2.2.9</subtitle>
<date>2014-09-26</date>
<releaseinfo>Version 2.2.10 - November 2014</releaseinfo>
<subtitle>for version 2.2.10</subtitle>
<date>2014-11-21</date>
<legalnotice>
<para>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".</para>
@@ -13,6 +13,6 @@
// TODO have the build system take care of this
:release_version: 2.2.9
:release_version: 2.2.10
// vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab:
+1 -2
View File
@@ -6,8 +6,7 @@ include ../Version
ADDITIONAL_OBJCFLAGS += -fPIE
ADDITIONAL_INCLUDE_DIRS +=
ADDITIONAL_LIB_DIRS += -L../SOPE/GDLContentStore/obj/
ADDITIONAL_LDFLAGS += -Wl,--no-as-needed -fPIE -pie
ADDITIONAL_LDFLAGS += -Wl,--no-as-needed -fPIE -pie -Wl,--rpath,$(GNUSTEP_SYSTEM_LIBRARIES)/sogo
SOGOD = sogod
TOOL_NAME = $(SOGOD)
+3 -4
View File
@@ -9,10 +9,9 @@ ADDITIONAL_INCLUDE_DIRS += \
-I..
ADDITIONAL_LIB_DIRS += \
-L../SoObjects/SOGo/SOGo.framework \
-L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/
SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib
-L../SoObjects/SOGo/SOGo.framework/sogo \
-L../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \
-L../SOPE/GDLContentStore/$(GNUSTEP_OBJ_DIR)/
$(SOGOD)_TOOL_LIBS += \
-lSOGo \
+33 -2
View File
@@ -1,3 +1,34 @@
2.2.10 (2014-11-21)
-------------------
Enhancements
- no longer leaking database passwords in the logs (#2953)
- added support for multiple calendars and address books over ActiveSync
- updated timezone information (#2968)
- updated Brazilian Portuguese, Czech, Dutch, Finnish, French, German, Hungarian, Polish,
Russian, Spanish (Argentina), and Spanish (Spain) translations
- updated CKEditor to version 4.4.5
Bug fixes
- fixed freebusy lookup with "Show time as busy" (#2930)
- don't escape <br>'s in a card's note field
- fixed folder's display name when subscribing to a folder
- fixed folder's display name when the active user subscribes another user to one of her/his folders
- fixed error with new user default sorting value for the mailer module (#2952)
- fixed ActiveSync PING command flooding the server (#2940)
- fixed many interop issues with Windows Phones over ActiveSync
- fixed automatic return receipts crash when not in the recepient list (#2965)
- fixed support for Sieve folder encoding parameter (#2622)
- fixed rename of subscribed addressbooks
- sanitize strings before escaping them when using EAS
- fixed handling of event invitations on iOS/EAS with no organizer (#2978)
- fixed corrupted png files (#2975)
- improved dramatically the BSON decoding speed
- added WindowSize support for GCS collections when using EAS
- fixed IMAP search with non-ASCII folder names
- fixed extraction of email addresses when pasting text with tabs (#2945)
- fixed Outlook attachment corruption issues when using AES (#2957)
2.2.9a (2014-09-29)
-------------------
@@ -11,7 +42,7 @@ New features
- support for recurrent tasks (#2160)
- support for alarms on recurrent events / tasks
Enchancements
Enhancements
- alarms can now be snoozed for 1 day
- better iOS/Mac OS X Calendar compability regarding alarms (#1920)
- force default classification over CalDAV if none is set (#2326)
@@ -36,7 +67,7 @@ New features
- new user settings for threads collapsing
- IMAP global search support (#2670)
Enchancements
Enhancements
- major refactoring of the GCS component saving code (dropped OGoContentStore)
- printing calendars in colors is now possible in all views; list, daily, weekly and multicolumns
- new option to print calendars events and tasks with a background color or with a border color
+7 -4
View File
@@ -133,10 +133,11 @@ $(PLREADER_TOOL)_OBJC_FILES += \
DBMSGREADER_TOOL = dbmsgreader
$(DBMSGREADER_TOOL)_OBJC_FILES += \
dbmsgreader.m
dbmsgreader.m \
NSObject+PropertyList.m
$(DBMSGREADER_TOOL)_LIB_DIRS += \
-L../SoObjects/SOGo/SOGo.framework/ -lSOGo \
-L../SoObjects/SOGo/SOGo.framework/sogo -lSOGo \
-L../SOPE/GDLContentStore/obj/ -lGDLContentStore \
-L../SOPE/NGCards/obj/ -lNGCards \
-lNGObjWeb
@@ -160,12 +161,12 @@ LIBMAPISTORE_LIBS = $(shell pkg-config libmapistore --libs) -lmapiproxy -lWEExte
$(MAPISTORESOGO)_INSTALL_DIR = $(DESTDIR)/$(SAMBA_LIB_DIR)/mapistore_backends
$(MAPISTORESOGO)_LIB_DIRS += \
-L../SoObjects/SOGo/SOGo.framework/ -lSOGo -lgnustep-base -lobjc -lNGObjWeb \
-L../SoObjects/SOGo/SOGo.framework/sogo/ -lSOGo -lgnustep-base -lobjc -lNGObjWeb \
$(LIBMAPI_LIBS) \
$(LIBMAPISTORE_LIBS)
$(SOGOBACKEND)_LIB_DIRS += \
-L../SoObjects/SOGo/SOGo.framework/ -lSOGo \
-L../SoObjects/SOGo/SOGo.framework/sogo/ -lSOGo \
$(LIBMAPI_LIBS) \
$(LIBMAPISTORE_LIBS)
@@ -178,6 +179,8 @@ ADDITIONAL_INCLUDE_DIRS += \
-DBACKEND_BUNDLE_NAME="@\"$(BUNDLE_NAME)$(BUNDLE_EXTENSION)\"" \
-DSOGO_BUNDLES_DIR="@\"$(BUNDLE_INSTALL_DIR)\""
ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo
-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/bundle.make
include $(GNUSTEP_MAKEFILES)/library.make
+10
View File
@@ -1218,7 +1218,9 @@ static NSCharacterSet *hexCharacterSet = nil;
inMemCtx: (TALLOC_CTX *) memCtx
{
int rc;
NSRange range;
NSString *stringValue;
NSString *trimingString = @"\r\n\n";
/* FIXME: there is a confusion in NGCards around "comment" and "description" */
stringValue = [event comment];
@@ -1226,6 +1228,14 @@ static NSCharacterSet *hexCharacterSet = nil;
&& ![stringValue isEqualToString: @"\r\n"]
&& ![stringValue isEqualToString: @"\n"])
{
/* Avoiding those trail weird characters at event description */
range = [stringValue rangeOfString: trimingString
options: NSBackwardsSearch];
if (range.location > 0)
{
stringValue = [stringValue substringToIndex: (NSMaxRange(range) -1)];
}
rc = MAPISTORE_SUCCESS;
*data = [stringValue asUnicodeInMemCtx: memCtx];
}
+4 -4
View File
@@ -61,10 +61,10 @@
}
+ (struct mapistore_contexts_list *) listAllContextsForUser: (NSString *) userName
withTDBIndexing: (struct tdb_wrap *) indexingTdb
withIndexing: (struct indexing_context *) indexing
inMemCtx: (TALLOC_CTX *) memCtx;
+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName
withTDBIndexing: (struct tdb_wrap *) indexingTdb
withIndexing: (struct indexing_context *) indexing
inMemCtx: (TALLOC_CTX *) memCtx;
+ (enum mapistore_error) createRootFolder: (NSString **) mapistoreUriP
withFID: (uint64_t ) fid
@@ -75,11 +75,11 @@
+ (int) openContext: (MAPIStoreContext **) contextPtr
withURI: (const char *) newUri
connectionInfo: (struct mapistore_connection_info *) newConnInfo
andTDBIndexing: (struct tdb_wrap *) indexingTdb;
andTDBIndexing: (struct indexing_context *) indexing;
- (id) initFromURL: (NSURL *) newUri
withConnectionInfo: (struct mapistore_connection_info *) newConnInfo
andTDBIndexing: (struct tdb_wrap *) indexingTdb;
andTDBIndexing: (struct indexing_context *) indexing;
- (NSURL *) url;
- (struct mapistore_connection_info *) connectionInfo;
+16 -19
View File
@@ -100,7 +100,7 @@ static NSMutableDictionary *contextClassMapping;
}
+ (struct mapistore_contexts_list *) listAllContextsForUser: (NSString *) userName
withTDBIndexing: (struct tdb_wrap *) indexingTdb
withIndexing: (struct indexing_context *) indexing
inMemCtx: (TALLOC_CTX *) memCtx
{
struct mapistore_contexts_list *list, *current;
@@ -112,7 +112,7 @@ static NSMutableDictionary *contextClassMapping;
list = NULL;
userContext = [MAPIStoreUserContext userContextWithUsername: userName
andTDBIndexing: indexingTdb];
andTDBIndexing: indexing];
[userContext activateWithUser: [userContext sogoUser]];
classes = GSObjCAllSubclassesOfClass (self);
@@ -121,7 +121,7 @@ static NSMutableDictionary *contextClassMapping;
{
currentClass = [classes objectAtIndex: count];
current = [currentClass listContextsForUser: userName
withTDBIndexing: indexingTdb
withIndexing: indexing
inMemCtx: memCtx];
if (current)
DLIST_CONCATENATE(list, current, void);
@@ -131,7 +131,7 @@ static NSMutableDictionary *contextClassMapping;
}
+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName
withTDBIndexing: (struct tdb_wrap *) indexingTdb
withIndexing: (struct indexing_context *) indexing
inMemCtx: (TALLOC_CTX *) memCtx
{
return NULL;
@@ -216,7 +216,7 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
+ (int) openContext: (MAPIStoreContext **) contextPtr
withURI: (const char *) newUri
connectionInfo: (struct mapistore_connection_info *) newConnInfo
andTDBIndexing: (struct tdb_wrap *) indexingTdb
andTDBIndexing: (struct indexing_context *) indexing
{
MAPIStoreContext *context;
Class contextClass;
@@ -239,7 +239,7 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
{
context = [[contextClass alloc] initFromURL: baseURL
withConnectionInfo: newConnInfo
andTDBIndexing: indexingTdb];
andTDBIndexing: indexing];
if (context)
{
[context autorelease];
@@ -272,7 +272,7 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
- (id) initFromURL: (NSURL *) newUrl
withConnectionInfo: (struct mapistore_connection_info *) newConnInfo
andTDBIndexing: (struct tdb_wrap *) indexingTdb
andTDBIndexing: (struct indexing_context *) indexing
{
NSString *username;
@@ -291,7 +291,7 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
ASSIGN (userContext,
[MAPIStoreUserContext userContextWithUsername: username
andTDBIndexing: indexingTdb]);
andTDBIndexing: indexing]);
#if 0
mapistore_mgmt_backend_register_user (newConnInfo,
@@ -374,17 +374,14 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
{
if ([objectURL hasPrefix: url])
{
*path = [[objectURL substringFromIndex: 7]
asUnicodeInMemCtx: memCtx];
[self logWithFormat: @"found path '%s' for fmid %.16x",
*path, fmid];
*path = [[objectURL substringFromIndex: 7] asUnicodeInMemCtx: memCtx];
[self logWithFormat: @"found path '%s' for fmid 0x%.16"PRIx64"", *path, fmid];
rc = MAPISTORE_SUCCESS;
}
else
{
[self logWithFormat: @"context (%@, %@) does not contain"
@" found fmid: 0x%.16x",
objectURL, url, fmid];
[self logWithFormat: @"context (%@, %@) does not contain "
@"found fmid: 0x%.16"PRIx64"", objectURL, url, fmid];
*path = NULL;
rc = MAPISTORE_SUCCESS;
}
@@ -534,7 +531,7 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
{
//[self warnWithFormat: @"no id exist yet for '%@', requesting one...",
// childURL];
openchangedb_get_new_folderID (connInfo->oc_ctx, &mappingId);
mapistore_indexing_get_new_folderID (connInfo->mstore_ctx, &mappingId);
[mapping registerURL: childURL withID: mappingId];
contextId = 0;
@@ -597,9 +594,9 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
memCtx = talloc_zero(NULL, TALLOC_CTX);
newFMIDs = [NSMutableArray arrayWithCapacity: max];
if (openchangedb_get_new_folderIDs (connInfo->oc_ctx,
memCtx, max, &numbers)
!= MAPI_E_SUCCESS || numbers->cValues != max)
if (mapistore_indexing_get_new_folderIDs (connInfo->mstore_ctx,
memCtx, max, &numbers)
!= MAPISTORE_SUCCESS || numbers->cValues != max)
abort ();
for (count = 0; count < max; count++)
{
+2 -2
View File
@@ -45,7 +45,7 @@
}
+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName
withTDBIndexing: (struct tdb_wrap *) indexingTdb
withIndexing: (struct indexing_context *) indexing
inMemCtx: (TALLOC_CTX *) memCtx
{
struct mapistore_contexts_list *firstContext = NULL, *context;
@@ -72,7 +72,7 @@
inContainer: nil];
[root setOwner: userName];
userContext = [MAPIStoreUserContext userContextWithUsername: userName
andTDBIndexing: indexingTdb];
andTDBIndexing: indexing];
[userContext ensureFolderTableExists];
[root setTableUrl: [userContext folderTableURL]];
names = [root toManyRelationshipKeys];
+8 -2
View File
@@ -433,10 +433,16 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
return rc;
}
- (int) deleteFolder
- (void) deleteFolderImpl
{
// TODO: raise exception in case underlying delete fails?
// [propsMessage delete];
[dbFolder delete];
}
- (int) deleteFolder
{
[self deleteFolderImpl];
[self cleanupCaches];
@@ -890,7 +896,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
{
fmid = [mapping idFromURL: [self url]];
[mapping unregisterURLWithID: fmid];
[self deleteFolder];
[self deleteFolderImpl];
[mapping registerURL: [newFolder url]
withID: fmid];
}
+2 -2
View File
@@ -64,7 +64,7 @@
}
+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName
withTDBIndexing: (struct tdb_wrap *) indexingTdb
withIndexing: (struct indexing_context *) indexing
inMemCtx: (TALLOC_CTX *) memCtx
{
struct mapistore_contexts_list *firstContext = NULL, *context;
@@ -79,7 +79,7 @@
if (moduleName)
{
userContext = [MAPIStoreUserContext userContextWithUsername: userName
andTDBIndexing: indexingTdb];
andTDBIndexing: indexing];
parentFolder = [[userContext rootFolders] objectForKey: moduleName];
baseUrl = [NSString stringWithFormat: @"sogo://%@@%@/",
userName, moduleName];
+4 -4
View File
@@ -83,7 +83,7 @@ MakeDisplayFolderName (NSString *folderName)
}
+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName
withTDBIndexing: (struct tdb_wrap *) indexingTdb
withIndexing: (struct indexing_context *) indexing
inMemCtx: (TALLOC_CTX *) memCtx
{
struct mapistore_contexts_list *firstContext = NULL, *context;
@@ -100,7 +100,7 @@ MakeDisplayFolderName (NSString *folderName)
WOContext *woContext;
userContext = [MAPIStoreUserContext userContextWithUsername: userName
andTDBIndexing: indexingTdb];
andTDBIndexing: indexing];
accountFolder = [[userContext rootFolders] objectForKey: @"mail"];
woContext = [userContext woContext];
@@ -245,7 +245,7 @@ MakeDisplayFolderName (NSString *folderName)
}
+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName
withTDBIndexing: (struct tdb_wrap *) indexingTdb
withIndexing: (struct indexing_context *) indexing
inMemCtx: (TALLOC_CTX *) memCtx
{
struct mapistore_contexts_list *context;
@@ -256,7 +256,7 @@ MakeDisplayFolderName (NSString *folderName)
WOContext *woContext;
userContext = [MAPIStoreUserContext userContextWithUsername: userName
andTDBIndexing: indexingTdb];
andTDBIndexing: indexing];
accountFolder = [[userContext rootFolders] objectForKey: @"mail"];
woContext = [userContext woContext];
+7 -7
View File
@@ -367,7 +367,7 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
msgData->recipients_count = max;
msgData->recipients = talloc_array (msgData, struct mapistore_message_recipient, max);
current = 0;
for (type = 0; type < 4; type++)
for (type = MAPI_ORIG; type <= MAPI_BCC; type++)
{
recipients = [allRecipients objectForKey: recTypes[type]];
recipientsMax = [recipients count];
@@ -541,7 +541,7 @@ FillMessageHeadersFromProperties (NGMutableHashMap *headers,
NSArray *list;
NSCalendarDate *date;
NSDictionary *recipients;
NSUInteger type, bccLimit;
enum ulRecipClass type, bccLimit;
SOGoUser *activeUser;
NSNumber *priority;
@@ -561,8 +561,8 @@ FillMessageHeadersFromProperties (NGMutableHashMap *headers,
bccLimit = MAPI_BCC;
else
bccLimit = MAPI_CC;
bccLimit++;
for (type = MAPI_TO; type < bccLimit; type++)
for (type = MAPI_TO; type <= bccLimit; type++)
{
recId = recTypes[type];
list = MakeRecipientsList ([recipients objectForKey: recId]);
@@ -865,7 +865,7 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, NS
NSMutableArray *recipientEmails;
NSArray *list;
NSString *recId, *from, *msgClass;
NSUInteger count;
enum ulRecipClass type;
SOGoUser *activeUser;
SOGoDomainDefaults *dd;
NSException *error;
@@ -881,9 +881,9 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, NS
recipientEmails = [NSMutableArray arrayWithCapacity: 32];
recipients = [properties objectForKey: @"recipients"];
for (count = 0; count < 3; count++)
for (type = MAPI_ORIG; type <= MAPI_BCC; type++)
{
recId = recTypes[count];
recId = recTypes[type];
list = [recipients objectForKey: recId];
[recipientEmails
addObjectsFromArray: [list objectsForKey: @"email"
+3 -5
View File
@@ -32,17 +32,15 @@
{
void *memCtx;
NSString *username;
struct tdb_wrap *indexing;
NSMutableDictionary *mapping; /* FID/MID -> url */
NSMutableDictionary *reverseMapping; /* url -> FID/MID */
struct indexing_context *indexing;
NSUInteger useCount;
}
+ (id) mappingForUsername: (NSString *) username
withIndexing: (struct tdb_wrap *) indexing;
withIndexing: (struct indexing_context *) indexing;
- (id) initForUsername: (NSString *) username
withIndexing: (struct tdb_wrap *) indexing;
withIndexing: (struct indexing_context *) indexing;
- (void) increaseUseCount;
+67 -172
View File
@@ -33,16 +33,15 @@
#import <SOGo/NSString+Utilities.h>
#undef DEBUG
#include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h>
#import "MAPIStoreTypes.h"
#import "MAPIStoreMapping.h"
#include <talloc.h>
#include <tdb.h>
struct tdb_wrap {
struct tdb_context *tdb;
};
static NSMutableDictionary *mappingRegistry = nil;
@@ -59,51 +58,9 @@ MAPIStoreMappingKeyFromId (uint64_t idNbr)
return [NSString stringWithUnsignedLongLong: idNbr];
}
static int
MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
void *data)
{
NSMutableDictionary *mapping;
id idKey;
NSString *uri;
char *idStr, *uriStr;
uint64_t idNbr;
// get the key
// key examples : key(18) = "0x6900000000000001"
// key(31) = "SOFT_DELETED:0xb100020000000001"
//
idStr = (char *) data1.dptr;
idKey = nil;
if (strncmp(idStr, "SOFT_DELETED:", 13) != 0)
{
// It's very important here to use strtoull and NOT strtoll as
// the latter will overflow a long long with typical key values.
idNbr = strtoull(idStr, NULL, 0);
// idKey = [NSNumber numberWithUnsignedLongLong: idNbr];
idKey = MAPIStoreMappingKeyFromId(idNbr);
}
// get the value and null-terminate it
uriStr = (char *)malloc(sizeof(char *) * data2.dsize+1);
memset(uriStr, 0, data2.dsize+1);
memcpy(uriStr, (const char *) data2.dptr, data2.dsize);
uri = [NSString stringWithUTF8String: uriStr];
free (uriStr);
mapping = data;
if (uri && idKey)
{
[mapping setObject: uri forKey: idKey];
}
return 0;
}
+ (id) mappingForUsername: (NSString *) username
withIndexing: (struct tdb_wrap *) indexing
withIndexing: (struct indexing_context *) indexing
{
id mapping;
@@ -123,8 +80,6 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
if ((self = [super init]))
{
memCtx = talloc_zero (NULL, TALLOC_CTX);
mapping = [NSMutableDictionary new];
reverseMapping = [NSMutableDictionary new];
indexing = NULL;
useCount = 0;
}
@@ -153,29 +108,12 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
}
- (id) initForUsername: (NSString *) newUsername
withIndexing: (struct tdb_wrap *) newIndexing
withIndexing: (struct indexing_context *) newIndexing
{
NSString *idNbr, *uri;
NSArray *keys;
NSUInteger count, max;
if ((self = [self init]))
{
ASSIGN (username, newUsername);
indexing = newIndexing;
(void) talloc_reference (memCtx, newIndexing);
tdb_traverse_read (indexing->tdb, MAPIStoreMappingTDBTraverse, mapping);
keys = [mapping allKeys];
max = [keys count];
for (count = 0; count < max; count++)
{
idNbr = [keys objectAtIndex: count];
uri = [mapping objectForKey: idNbr];
//[self logWithFormat: @"preregistered id '%@' for url '%@'", idNbr, uri];
[reverseMapping setObject: idNbr forKey: uri];
}
//[self logWithFormat: @"Complete mapping: %@ \nComplete reverse mapping: %@", mapping, reverseMapping];
}
return self;
@@ -184,83 +122,72 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
- (void) dealloc
{
[username release];
[mapping release];
[reverseMapping release];
talloc_free (memCtx);
[super dealloc];
}
- (NSString *) urlFromID: (uint64_t) idNbr
{
return [mapping objectForKey: MAPIStoreMappingKeyFromId (idNbr)];
char* url = NULL;
enum mapistore_error ret;
bool soft_delete = false;
ret = indexing->get_uri(indexing, [username UTF8String],
memCtx, idNbr, &url, &soft_delete);
if (ret != MAPISTORE_SUCCESS)
return NULL;
NSString *res = [[[NSString alloc] initWithUTF8String:url] autorelease];
talloc_free(url);
return res;
}
- (uint64_t) idFromURL: (NSString *) url
{
id key;
enum mapistore_error ret;
uint64_t idNbr;
bool softDeleted;
key = [reverseMapping objectForKey: url];
if (key)
idNbr = [key unsignedLongLongValue];
ret = indexing->get_fmid(indexing, [username UTF8String], [url UTF8String],
false, &idNbr, &softDeleted);
if (ret == MAPISTORE_SUCCESS && !softDeleted)
return idNbr;
else
idNbr = NSNotFound;
return idNbr;
return NSNotFound;
}
- (void) _updateFolderWithURL: (NSString *) oldURL
withURL: (NSString *) urlString
{
NSArray *allKeys;
NSUInteger count, max;
NSString *currentKey, *newKey;
id idKey;
TDB_DATA key, dbuf;
const char *searchURL;
uint64_t idNbr;
bool softDeleted;
NSString *current;
NSString *newURL;
[oldURL retain];
if ([oldURL isEqualToString: urlString]) return;
allKeys = [reverseMapping allKeys];
max = [allKeys count];
for (count = 0; count < max; count++)
{
currentKey = [allKeys objectAtIndex: count];
if ([currentKey hasPrefix: oldURL])
{
newKey = [currentKey stringByReplacingPrefix: oldURL
withPrefix: urlString];
searchURL = [[oldURL stringByAppendingString:@"*"] UTF8String];
idKey = [reverseMapping objectForKey: currentKey];
[mapping setObject: newKey forKey: idKey];
[reverseMapping setObject: idKey forKey: newKey];
[reverseMapping removeObjectForKey: currentKey];
while (indexing->get_fmid(indexing, [username UTF8String],
searchURL,true, &idNbr, &softDeleted) == MAPISTORE_SUCCESS)
{
// Ignore deleted
if (softDeleted) continue;
/* update the record in the indexing database */
key.dptr = (unsigned char *) talloc_asprintf (NULL, "0x%.16"PRIx64,
(uint64_t) [idKey unsignedLongLongValue]);
key.dsize = strlen ((const char *) key.dptr);
dbuf.dptr = (unsigned char *) talloc_strdup (NULL,
[newKey UTF8String]);
dbuf.dsize = strlen ((const char *) dbuf.dptr);
tdb_store (indexing->tdb, key, dbuf, TDB_MODIFY);
talloc_free (key.dptr);
talloc_free (dbuf.dptr);
}
}
[oldURL release];
current = [self urlFromID:idNbr];
newURL = [current stringByReplacingPrefix: oldURL withPrefix: urlString];
indexing->update_fmid(indexing, [username UTF8String], idNbr, [newURL UTF8String]);
}
}
- (void) updateID: (uint64_t) idNbr
withURL: (NSString *) urlString
{
NSString *oldURL;
id idKey;
TDB_DATA key, dbuf;
idKey = MAPIStoreMappingKeyFromId (idNbr);
oldURL = [mapping objectForKey: idKey];
oldURL = [self urlFromID: idNbr];
if (oldURL)
{
if ([oldURL hasSuffix: @"/"]) /* is container ? */
@@ -268,28 +195,16 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
if (![urlString hasSuffix: @"/"])
[NSException raise: NSInvalidArgumentException
format: @"a container url must have an ending '/'"];
tdb_transaction_start (indexing->tdb);
[self _updateFolderWithURL: oldURL withURL: urlString];
tdb_transaction_commit (indexing->tdb);
}
else
{
if ([urlString hasSuffix: @"/"])
[NSException raise: NSInvalidArgumentException
format: @"a leaf url must not have an ending '/'"];
[mapping setObject: urlString forKey: idKey];
[reverseMapping setObject: idKey forKey: urlString];
[reverseMapping removeObjectForKey: oldURL];
/* update the record in the indexing database */
key.dptr = (unsigned char *) talloc_asprintf(NULL, "0x%.16"PRIx64, idNbr);
key.dsize = strlen((const char *) key.dptr);
dbuf.dptr = (unsigned char *) talloc_strdup (NULL, [urlString UTF8String]);
dbuf.dsize = strlen((const char *) dbuf.dptr);
tdb_store (indexing->tdb, key, dbuf, TDB_MODIFY);
talloc_free (key.dptr);
talloc_free (dbuf.dptr);
indexing->update_fmid(indexing, [username UTF8String],
idNbr, [urlString UTF8String]);
}
}
}
@@ -297,37 +212,37 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
- (BOOL) registerURL: (NSString *) urlString
withID: (uint64_t) idNbr
{
id idKey;
BOOL rc;
TDB_DATA key, dbuf;
NSString *oldURL;
uint64_t oldIdNbr;
bool rc;
idKey = MAPIStoreMappingKeyFromId (idNbr);
if ([mapping objectForKey: idKey]
|| [reverseMapping objectForKey: urlString])
oldURL = [self urlFromID: idNbr];
if (oldURL != NULL)
{
[self errorWithFormat:
@"attempt to double register an entry ('%@', %lld,"
@" 0x%.16"PRIx64")",
urlString, idNbr, idNbr];
rc = NO;
@"url with idNbr already registered: (oldUrl='%@', newUrl='%@', id=x%.16"PRIx64")",
oldURL, urlString, idNbr];
return NO;
}
oldIdNbr = [self idFromURL: urlString];
if (oldIdNbr != NSNotFound)
{
[self errorWithFormat:
@"attempt to double register an entry with idNbr ('%@', %lld,"
@" 0x%.16"PRIx64", oldid=0x%.16"PRIx64")",
urlString, idNbr, idNbr, oldIdNbr];
return NO;
}
else
{
[mapping setObject: urlString forKey: idKey];
[reverseMapping setObject: idKey forKey: urlString];
rc = YES;
// [self logWithFormat: @"registered url '%@' with id %lld (0x%.16"PRIx64")",
// urlString, idNbr, idNbr];
/* Add the record given its fid and mapistore_uri */
key.dptr = (unsigned char *) talloc_asprintf(NULL, "0x%.16"PRIx64, idNbr);
key.dsize = strlen((const char *) key.dptr);
dbuf.dptr = (unsigned char *) talloc_strdup(NULL, [urlString UTF8String]);
dbuf.dsize = strlen((const char *) dbuf.dptr);
tdb_store (indexing->tdb, key, dbuf, TDB_INSERT);
talloc_free (key.dptr);
talloc_free (dbuf.dptr);
indexing->add_fmid(indexing, [username UTF8String],
idNbr, [urlString UTF8String]);
}
return rc;
@@ -341,7 +256,6 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
max = [urlStrings count];
if (max == [idNbrs count])
{
tdb_transaction_start (indexing->tdb);
for (count = 0; count < max; count++)
{
newID = [[idNbrs objectAtIndex: count]
@@ -349,7 +263,6 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
[self registerURL: [urlStrings objectAtIndex: count]
withID: newID];
}
tdb_transaction_commit (indexing->tdb);
}
else
[NSException raise: NSInvalidArgumentException
@@ -358,26 +271,8 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
- (void) unregisterURLWithID: (uint64_t) idNbr
{
NSString *urlString;
id idKey;
TDB_DATA key;
idKey = MAPIStoreMappingKeyFromId (idNbr);
urlString = [mapping objectForKey: idKey];
if (urlString)
{
// [self logWithFormat: @"unregistering url '%@' with id %lld (0x%.16"PRIx64")",
// urlString, idNbr, idNbr];
[reverseMapping removeObjectForKey: urlString];
[mapping removeObjectForKey: idKey];
/* We hard-delete the entry from the indexing database */
key.dptr = (unsigned char *) talloc_asprintf(NULL, "0x%.16"PRIx64, idNbr);
key.dsize = strlen((const char *) key.dptr);
tdb_delete(indexing->tdb, key);
talloc_free(key.dptr);
}
indexing->del_fmid(indexing, [username UTF8String],
idNbr, MAPISTORE_PERMANENT_DELETE);
}
@end
+1 -1
View File
@@ -38,7 +38,7 @@
}
+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName
withTDBIndexing: (struct tdb_wrap *) indexingTdb
withIndexing: (struct indexing_context *) indexing
inMemCtx: (TALLOC_CTX *) memCtx
{
struct mapistore_contexts_list *context;
+302 -92
View File
@@ -49,9 +49,32 @@
#include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h>
#include <execinfo.h>
static Class MAPIStoreContextK = Nil;
static BOOL leakDebugging = NO;
static BOOL initialization_done = NO;
#define NS_CURRENT_THREAD_REGISTER() \
BOOL __nsrct_thread_registered = GSRegisterCurrentThread(); \
if (!initialization_done) { \
DEBUG(5, ("[SOGo: %s:%d] You should call sogo_backend_init() first. Current thread: %p, pid: %d\n", \
__FUNCTION__, __LINE__, GSCurrentThread(), getpid())); \
}
#define NS_CURRENT_THREAD_TRY_UNREGISTER() \
if (__nsrct_thread_registered) { \
GSUnregisterCurrentThread(); \
}
#define TRYCATCH_START @try {
#define TRYCATCH_END(pool) \
} @catch (NSException * e) { \
enum mapistore_error ret = sogo_backend_handle_objc_exception(e, __PRETTY_FUNCTION__, __LINE__); \
[pool release]; \
NS_CURRENT_THREAD_TRY_UNREGISTER(); \
return ret; \
}
static enum mapistore_error
sogo_backend_unexpected_error()
@@ -61,6 +84,35 @@ sogo_backend_unexpected_error()
return MAPISTORE_SUCCESS;
}
static enum mapistore_error
sogo_backend_handle_objc_exception(NSException *e, const char *fn_name, const int line_no)
{
NSString *callStackSymbols = nil;
if ([e respondsToSelector:@selector(callStackSymbols)])
{
callStackSymbols = [[e callStackSymbols] componentsJoinedByString:@"\n\t"];
}
NSLog(@"[SOGo: %s:%d] - EXCEPTION: %@, reason: %@, backtrace: \n\t%@\n",
fn_name, line_no, [e name], [e reason], callStackSymbols);
// Another point of view on the stack trace
{
void *frames[128];
int i, len = backtrace(frames, 128);
char **symbols = backtrace_symbols(frames, len);
NSLog(@"Backtrace using execinfo.h:\n");
for (i = 0; i < len; ++i)
NSLog(@"\t%s", symbols[i]);
free(symbols);
}
if ([[e name] isEqual:@"NotImplementedException"])
{
return MAPISTORE_ERR_NOT_IMPLEMENTED;
}
return MAPISTORE_ERROR;
}
static void
sogo_backend_atexit (void)
{
@@ -73,6 +125,7 @@ sogo_backend_atexit (void)
GSUnregisterCurrentThread ();
}
/**
\details Initialize sogo mapistore backend
@@ -88,7 +141,13 @@ sogo_backend_init (void)
SoProductRegistry *registry;
char *argv[] = { SAMBA_PREFIX "/sbin/samba", NULL };
GSRegisterCurrentThread ();
GSRegisterCurrentThread();
if (initialization_done) {
DEBUG(0, ("SOGo backend already initialized.\n"));
return MAPISTORE_SUCCESS;
}
pool = [NSAutoreleasePool new];
/* Here we work around a bug in GNUstep which decodes XML user
@@ -130,6 +189,9 @@ sogo_backend_init (void)
[pool release];
DEBUG(0, ("[SOGo: %s:%d] backend init SUCCESS. Current thread: %p, pid: %d\n", __FUNCTION__, __LINE__, GSCurrentThread(), getpid()));
initialization_done = YES;
return MAPISTORE_SUCCESS;
}
@@ -144,7 +206,7 @@ sogo_backend_init (void)
static enum mapistore_error
sogo_backend_create_context(TALLOC_CTX *mem_ctx,
struct mapistore_connection_info *conn_info,
struct tdb_wrap *indexingTdb,
struct indexing_context *indexing,
const char *uri, void **context_object)
{
NSAutoreleasePool *pool;
@@ -153,23 +215,25 @@ sogo_backend_create_context(TALLOC_CTX *mem_ctx,
DEBUG(0, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__));
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
if (MAPIStoreContextK)
{
TRYCATCH_START
rc = [MAPIStoreContextK openContext: &context
withURI: uri
connectionInfo: conn_info
andTDBIndexing: indexingTdb];
andTDBIndexing: indexing];
if (rc == MAPISTORE_SUCCESS)
*context_object = [context tallocWrapper: mem_ctx];
TRYCATCH_END(pool)
}
else
rc = MAPISTORE_ERROR;
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
return rc;
}
@@ -178,7 +242,7 @@ static enum mapistore_error
sogo_backend_create_root_folder (const char *username,
enum mapistore_context_role role,
uint64_t fid, const char *name,
// struct tdb_wrap *indexingTdb,
// struct indexing_context *indexing,
TALLOC_CTX *mem_ctx, char **mapistore_urip)
{
NSAutoreleasePool *pool;
@@ -188,11 +252,12 @@ sogo_backend_create_root_folder (const char *username,
DEBUG(0, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__));
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
if (MAPIStoreContextK)
{
TRYCATCH_START
userName = [NSString stringWithUTF8String: username];
folderName = [NSString stringWithUTF8String: name];
rc = [MAPIStoreContextK createRootFolder: &mapistoreUri
@@ -202,18 +267,19 @@ sogo_backend_create_root_folder (const char *username,
withRole: role];
if (rc == MAPISTORE_SUCCESS)
*mapistore_urip = [mapistoreUri asUnicodeInMemCtx: mem_ctx];
TRYCATCH_END(pool)
}
else
rc = MAPISTORE_ERROR;
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
return rc;
}
static enum mapistore_error
sogo_backend_list_contexts(const char *username, struct tdb_wrap *indexingTdb,
sogo_backend_list_contexts(const char *username, struct indexing_context *indexing,
TALLOC_CTX *mem_ctx,
struct mapistore_contexts_list **contexts_listp)
{
@@ -223,22 +289,24 @@ sogo_backend_list_contexts(const char *username, struct tdb_wrap *indexingTdb,
DEBUG(0, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__));
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
if (MAPIStoreContextK)
{
TRYCATCH_START
userName = [NSString stringWithUTF8String: username];
*contexts_listp = [MAPIStoreContextK listAllContextsForUser: userName
withTDBIndexing: indexingTdb
withIndexing: indexing
inMemCtx: mem_ctx];
rc = MAPISTORE_SUCCESS;
TRYCATCH_END(pool)
}
else
rc = MAPISTORE_ERROR;
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
return rc;
}
@@ -273,11 +341,15 @@ sogo_context_get_path(void *backend_object, TALLOC_CTX *mem_ctx,
{
wrapper = backend_object;
context = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [context getPath: path ofFMID: fmid inMemCtx: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -303,13 +375,17 @@ sogo_context_get_root_folder(void *backend_object, TALLOC_CTX *mem_ctx,
{
wrapper = backend_object;
context = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [context getRootFolder: &folder withFID: fid];
if (rc == MAPISTORE_SUCCESS)
*folder_object = [folder tallocWrapper: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -342,14 +418,18 @@ sogo_folder_open_folder(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t fid,
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder openFolder: &childFolder withFID: fid];
if (rc == MAPISTORE_SUCCESS)
*childfolder_object = [childFolder tallocWrapper: mem_ctx];
// [context tearDownRequest];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -382,13 +462,17 @@ sogo_folder_create_folder(void *folder_object, TALLOC_CTX *mem_ctx,
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder createFolder: &childFolder withRow: aRow andFID: fid];
if (rc == MAPISTORE_SUCCESS)
*childfolder_object = [childFolder tallocWrapper: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -421,11 +505,15 @@ sogo_folder_delete(void *folder_object)
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder deleteFolder];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -449,11 +537,15 @@ sogo_folder_get_child_count(void *folder_object, enum mapistore_table_type table
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder getChildCount: child_count ofTableType: table_type];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -481,16 +573,20 @@ sogo_folder_open_message(void *folder_object,
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder openMessage: &message
withMID: mid
forWriting: write_access
inMemCtx: mem_ctx];
if (rc == MAPISTORE_SUCCESS)
*message_object = [message tallocWrapper: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -519,15 +615,19 @@ sogo_folder_create_message(void *folder_object,
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder createMessage: &message
withMID: mid
isAssociated: associated];
if (rc == MAPISTORE_SUCCESS)
*message_object = [message tallocWrapper: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -551,11 +651,15 @@ sogo_folder_delete_message(void *folder_object, uint64_t mid, uint8_t flags)
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder deleteMessageWithMID: mid andFlags: flags];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -589,8 +693,10 @@ sogo_folder_move_copy_messages(void *folder_object,
wrapper = source_folder_object;
sourceFolder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [targetFolder moveCopyMessagesWithMIDs: src_mids
andCount: mid_count
fromFolder: sourceFolder
@@ -598,8 +704,10 @@ sogo_folder_move_copy_messages(void *folder_object,
andChangeKeys: target_change_keys
wantCopy: want_copy
inMemCtx: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -632,7 +740,7 @@ sogo_folder_move_folder(void *folder_object, void *target_folder_object,
else
targetFolder = nil;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
if (new_folder_name)
@@ -640,14 +748,16 @@ sogo_folder_move_folder(void *folder_object, void *target_folder_object,
else
newFolderName = nil;
TRYCATCH_START
rc = [moveFolder moveCopyToFolder: targetFolder
withNewName: newFolderName
isMove: YES
isRecursive: YES
inMemCtx: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -677,19 +787,21 @@ sogo_folder_copy_folder(void *folder_object, void *target_folder_object, TALLOC_
wrapper = target_folder_object;
targetFolder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
newFolderName = [NSString stringWithUTF8String: new_folder_name];
TRYCATCH_START
rc = [copyFolder moveCopyToFolder: targetFolder
withNewName: newFolderName
isMove: NO
isRecursive: recursive
inMemCtx: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -715,15 +827,19 @@ sogo_folder_get_deleted_fmids(void *folder_object, TALLOC_CTX *mem_ctx,
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder getDeletedFMIDs: fmidsp
andCN: cnp
fromChangeNumber: change_num
inTableType: table_type
inMemCtx: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -750,16 +866,20 @@ sogo_folder_open_table(void *folder_object, TALLOC_CTX *mem_ctx,
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder getTable: &table
andRowCount: row_count
tableType: table_type
andHandleId: handle_id];
if (rc == MAPISTORE_SUCCESS)
*table_object = [table tallocWrapper: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -785,13 +905,17 @@ sogo_folder_modify_permissions(void *folder_object, uint8_t flags,
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder modifyPermissions: permissions
withCount: pcount
andFlags: flags];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -815,12 +939,16 @@ sogo_folder_preload_message_bodies(void *folder_object, enum mapistore_table_typ
{
wrapper = folder_object;
folder = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [folder preloadMessageBodiesWithMIDs: mids
ofTableType: table_type];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -846,12 +974,16 @@ sogo_message_get_message_data(void *message_object,
{
wrapper = message_object;
message = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
[message getMessageData: msg_dataP
inMemCtx: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
rc = MAPISTORE_SUCCESS;
}
else
@@ -877,14 +1009,18 @@ sogo_message_create_attachment (void *message_object, TALLOC_CTX *mem_ctx, void
{
wrapper = message_object;
message = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [message createAttachment: &attachment inAID: aidp];
if (rc == MAPISTORE_SUCCESS)
*attachment_object = [attachment tallocWrapper: mem_ctx];
// [context tearDownRequest];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -910,14 +1046,18 @@ sogo_message_open_attachment (void *message_object, TALLOC_CTX *mem_ctx,
{
wrapper = message_object;
message = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [message getAttachment: &attachment withAID: aid];
if (rc == MAPISTORE_SUCCESS)
*attachment_object = [attachment tallocWrapper: mem_ctx];
// [context tearDownRequest];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -942,15 +1082,19 @@ sogo_message_get_attachment_table (void *message_object, TALLOC_CTX *mem_ctx, vo
{
wrapper = message_object;
message = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [message getAttachmentTable: &table
andRowCount: row_count];
if (rc == MAPISTORE_SUCCESS)
*table_object = [table tallocWrapper: mem_ctx];
// [context tearDownRequest];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -977,14 +1121,18 @@ sogo_message_modify_recipients (void *message_object,
{
wrapper = message_object;
message = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [message modifyRecipientsWithRecipients: recipients
andCount: count
andColumns: columns];
// [context tearDownRequest];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1008,12 +1156,16 @@ sogo_message_set_read_flag (void *message_object, uint8_t flag)
{
wrapper = message_object;
message = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [message setReadFlag: flag];
// [context tearDownRequest];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1037,12 +1189,16 @@ sogo_message_save (void *message_object, TALLOC_CTX *mem_ctx)
{
wrapper = message_object;
message = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [message saveMessage: mem_ctx];
// [context tearDownRequest];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1066,12 +1222,16 @@ sogo_message_submit (void *message_object, enum SubmitFlags flags)
{
wrapper = message_object;
message = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [message submitWithFlags: flags];
// [context tearDownRequest];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1100,16 +1260,20 @@ sogo_message_attachment_open_embedded_message (void *attachment_object,
{
wrapper = attachment_object;
attachment = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [attachment openEmbeddedMessage: &message
withMID: midP
withMAPIStoreMsg: msg
inMemCtx: mem_ctx];
if (rc == MAPISTORE_SUCCESS)
*message_object = [message tallocWrapper: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1137,15 +1301,19 @@ sogo_message_attachment_create_embedded_message (void *attachment_object,
{
wrapper = attachment_object;
attachment = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
rc = [attachment createEmbeddedMessage: &message
withMAPIStoreMsg: msg
inMemCtx: mem_ctx];
if (rc == MAPISTORE_SUCCESS)
*message_object = [message tallocWrapper: mem_ctx];
TRYCATCH_START
rc = [attachment createEmbeddedMessage: &message
withMAPIStoreMsg: msg
inMemCtx: mem_ctx];
if (rc == MAPISTORE_SUCCESS)
*message_object = [message tallocWrapper: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1169,11 +1337,15 @@ static enum mapistore_error sogo_table_get_available_properties(void *table_obje
{
wrapper = table_object;
table = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [table getAvailableProperties: propertiesP inMemCtx: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1197,12 +1369,16 @@ sogo_table_set_columns (void *table_object, uint16_t count, enum MAPITAGS *prope
{
wrapper = table_object;
table = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [table setColumns: properties
withCount: count];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1226,14 +1402,18 @@ sogo_table_set_restrictions (void *table_object, struct mapi_SRestriction *restr
{
wrapper = table_object;
table = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
[table setRestrictions: restrictions];
//[table cleanupCaches];
rc = MAPISTORE_SUCCESS;
*table_status = TBLSTAT_COMPLETE;
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1257,14 +1437,18 @@ sogo_table_set_sort_order (void *table_object, struct SSortOrderSet *sort_order,
{
wrapper = table_object;
table = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
[table setSortOrder: sort_order];
[table cleanupCaches];
rc = MAPISTORE_SUCCESS;
*table_status = TBLSTAT_COMPLETE;
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1290,12 +1474,16 @@ sogo_table_get_row (void *table_object, TALLOC_CTX *mem_ctx,
{
wrapper = table_object;
table = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [table getRow: data withRowID: row_id andQueryType: query_type
inMemCtx: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1321,12 +1509,16 @@ sogo_table_get_row_count (void *table_object,
{
wrapper = table_object;
table = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [table getRowCount: row_countp
withQueryType: query_type];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1350,11 +1542,15 @@ sogo_table_handle_destructor (void *table_object, uint32_t handle_id)
{
wrapper = table_object;
table = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
[table destroyHandle: handle_id];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
rc = MAPISTORE_SUCCESS;
}
else
@@ -1380,11 +1576,15 @@ static enum mapistore_error sogo_properties_get_available_properties(void *objec
{
wrapper = object;
propObject = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [propObject getAvailableProperties: propertiesP inMemCtx: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1411,13 +1611,17 @@ sogo_properties_get_properties (void *object,
{
wrapper = object;
propObject = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [propObject getProperties: data withTags: properties
andCount: count
inMemCtx: mem_ctx];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1441,11 +1645,15 @@ sogo_properties_set_properties (void *object, struct SRow *aRow)
{
wrapper = object;
propObject = wrapper->instance;
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
rc = [propObject addPropertiesFromRow: aRow];
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
}
else
{
@@ -1472,9 +1680,10 @@ sogo_manager_generate_uri (TALLOC_CTX *mem_ctx,
/* This fixes a crash occurring during the instantiation of the
NSAutoreleasePool below. */
GSRegisterCurrentThread ();
NS_CURRENT_THREAD_REGISTER();
pool = [NSAutoreleasePool new];
TRYCATCH_START
// printf("rootURI = %s\n", rootURI);
if (rootURI)
partialURLString = [NSString stringWithUTF8String: rootURI];
@@ -1494,9 +1703,10 @@ sogo_manager_generate_uri (TALLOC_CTX *mem_ctx,
// printf("uri = %s\n", [partialURLString UTF8String]);
*uri = talloc_strdup (mem_ctx, [partialURLString UTF8String]);
TRYCATCH_END(pool)
[pool release];
GSUnregisterCurrentThread ();
NS_CURRENT_THREAD_TRY_UNREGISTER();
return MAPISTORE_SUCCESS;
}
+2 -2
View File
@@ -63,10 +63,10 @@
}
+ (id) userContextWithUsername: (NSString *) username
andTDBIndexing: (struct tdb_wrap *) indexingTdb;
andTDBIndexing: (struct indexing_context *) indexing;
- (id) initWithUsername: (NSString *) newUsername
andTDBIndexing: (struct tdb_wrap *) indexingTdb;
andTDBIndexing: (struct indexing_context *) indexing;
- (NSString *) username;
- (SOGoUser *) sogoUser;
+26 -12
View File
@@ -60,7 +60,7 @@ static NSMapTable *contextsTable = nil;
}
+ (id) userContextWithUsername: (NSString *) username
andTDBIndexing: (struct tdb_wrap *) indexingTdb;
andTDBIndexing: (struct indexing_context *) indexing;
{
id userContext;
@@ -68,7 +68,7 @@ static NSMapTable *contextsTable = nil;
if (!userContext)
{
userContext = [[self alloc] initWithUsername: username
andTDBIndexing: indexingTdb];
andTDBIndexing: indexing];
[userContext autorelease];
[contextsTable setObject: userContext forKey: username];
}
@@ -100,16 +100,12 @@ static NSMapTable *contextsTable = nil;
return self;
}
- (NSString *) _readUserPassword: (NSString *) newUsername
- (NSString *) _readPasswordFile: (NSString *) path
{
NSString *password, *path;
NSString *password;
NSData *content;
password = nil;
path = [NSString stringWithFormat: SAMBA_PRIVATE_DIR
@"/mapistore/%@/password", newUsername];
password = nil;
content = [NSData dataWithContentsOfFile: path];
if (content)
@@ -124,8 +120,26 @@ static NSMapTable *contextsTable = nil;
return password;
}
- (NSString *) _readUserPassword: (NSString *) newUsername
{
NSString *password, *path;
path = [NSString stringWithFormat: SAMBA_PRIVATE_DIR
@"/mapistore/%@/password", newUsername];
password = [self _readPasswordFile: path];
if (password == nil)
{
// Try to get master password
path = [NSString stringWithFormat: SAMBA_PRIVATE_DIR @"/mapistore/master.password"];
password = [self _readPasswordFile: path];
}
return password;
}
- (id) initWithUsername: (NSString *) newUsername
andTDBIndexing: (struct tdb_wrap *) indexingTdb
andTDBIndexing: (struct indexing_context *) indexing
{
NSString *userPassword;
@@ -133,9 +147,9 @@ static NSMapTable *contextsTable = nil;
{
/* "username" will be retained by table */
username = newUsername;
if (indexingTdb)
if (indexing)
ASSIGN (mapping, [MAPIStoreMapping mappingForUsername: username
withIndexing: indexingTdb]);
withIndexing: indexing]);
authenticator = [MAPIStoreAuthenticator new];
[authenticator setUsername: username];
+2 -2
View File
@@ -47,13 +47,13 @@ MAPIStoreTallocWrapperDestroy (void *data)
struct MAPIStoreTallocWrapper *wrapper;
NSAutoreleasePool *pool;
GSRegisterCurrentThread ();
// GSRegisterCurrentThread ();
pool = [NSAutoreleasePool new];
wrapper = data;
//NSLog (@"destroying wrapped object (wrapper: %p; object: %p (%@))...\n", wrapper, wrapper->instance, NSStringFromClass([wrapper->instance class]));
[wrapper->instance release];
[pool release];
GSUnregisterCurrentThread ();
// GSUnregisterCurrentThread ();
return 0;
}
+64
View File
@@ -0,0 +1,64 @@
/* dbmsgdump.m - this file is part of SOGo
*
* Copyright (C) 2014 Kamen Mazdrashki <kmazdrashki@zentyal.com>
*
* Based on implementation done by Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* 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
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* A format-agnostic dump extensions for:
* NSArray
* NSObject
* NSDictionary
*/
#ifndef NSOBJECT_PROPERTYLIST_H
#define NSOBJECT_PROPERTYLIST_H
#import <Foundation/NSObject.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
@interface NSObject (plext)
- (void) displayWithIndentation: (NSInteger) anInt;
@end
@interface NSDictionary (plext)
- (void) displayKey: (NSString *) key
withIndentation: (NSInteger) anInt;
- (void) displayWithIndentation: (NSInteger) anInt;
@end
@interface NSArray (plext)
- (void) displayCount: (NSUInteger) count
withIndentation: (NSInteger) anInt;
- (void) displayWithIndentation: (NSInteger) anInt;
@end
#endif /* NSOBJECT_PROPERTYLIST_H */
+1 -48
View File
@@ -32,14 +32,10 @@
#import <NGExtensions/NSNull+misc.h>
#import <SOGo/BSONCodec.h>
#import "NSObject+PropertyList.h"
const char *indentationStep = " ";
@interface NSObject (plext)
- (void) displayWithIndentation: (NSInteger) anInt;
@end
@implementation NSObject (plext)
@@ -139,46 +135,3 @@ const char *indentationStep = " ";
@end
static void
OCDumpPListData (NSData *content)
{
//NSDictionary *d;
//NSPropertyListFormat format;
//NSString *error = nil;
//const char *formatName;
//d = [NSPropertyListSerialization propertyListFromData: content
// mutabilityOption: NSPropertyListImmutable
// format: &format
// errorDescription: &error];
//d = [content BSONValue];
// if (d)
// {
// switch (format)
// {
// case NSPropertyListOpenStepFormat:
// formatName = "OpenStep";
// break;
// case NSPropertyListXMLFormat_v1_0:
// formatName = "XML";
// break;
// case NSPropertyListBinaryFormat_v1_0:
// formatName = "Binary";
// break;
// case NSPropertyListGNUstepFormat:
// formatName = "GNUstep";
// break;
// case NSPropertyListGNUstepBinaryFormat:
// formatName = "GNUstep binary";
// break;
// default: formatName = "unknown";
// }
// printf ("File format is: %s\n", formatName);
// [d displayWithIndentation: 0];
// printf ("\n");
// }
// else
// printf ("an error occurred: %s\n", [error UTF8String]);
}
+17 -3
View File
@@ -36,10 +36,20 @@
#import "MAPIStoreUserContext.h"
#import <SOGo/SOGoCacheGCSObject.h>
#import "NSObject+PropertyList.m"
#import <SOGo/BSONCodec.h>
#import "NSObject+PropertyList.h"
Class MAPIStoreUserContextK, SOGoMAPIDBObjectK;
static void
DumpBSONData(NSData *data)
{
NSDictionary *dvalue;
dvalue = [data BSONValue];
[dvalue displayWithIndentation:0];
printf("\n");
}
static void
DbDumpObject (NSString *username, NSString *path)
{
@@ -55,8 +65,9 @@ DbDumpObject (NSString *username, NSString *path)
record = [dbobject lookupRecord: path newerThanVersion: -1];
if (record)
{
printf("record found: %p\n", record);
content = [[record objectForKey: @"c_content"] dataByDecodingBase64];
OCDumpPListData (content);
DumpBSONData(content);
}
else
NSLog (@"record not found");
@@ -99,9 +110,12 @@ int main (int argc, char *argv[], char *envp[])
SOGoMAPIDBObjectK = NSClassFromString (@"SOGoMAPIDBObject");
arguments = [[NSProcessInfo processInfo] arguments];
if ([arguments count] > 2)
if ([arguments count] > 2) {
DbDumpObject ([arguments objectAtIndex: 1],
[arguments objectAtIndex: 2]);
} else if ([arguments count] > 1) {
DumpBSONData([[arguments objectAtIndex:1] dataByDecodingBase64]);
}
[pool release];
+18
View File
@@ -228,6 +228,15 @@
[start setTimeZone: tz];
if (isAllDay)
{
/* when user TZ is positive (East) all-day events were not
shown properly in SOGo UI. This day delay fixes it */
tzOffset = [userTimeZone secondsFromGMTForDate: value];
if (tzOffset > 0)
{
value = [value dateByAddingYears: 0 months: 0 days: 1
hours: 0 minutes: 0
seconds: 0];
}
[start setDate: value];
[start setTimeZone: nil];
}
@@ -251,6 +260,15 @@
[end setTimeZone: tz];
if (isAllDay)
{
/* when user TZ is positive (East) all-day events were not
shown properly in SOGo UI. This day delay fixes it */
tzOffset = [userTimeZone secondsFromGMTForDate: value];
if (tzOffset > 0)
{
value = [value dateByAddingYears: 0 months: 0 days: 1
hours: 0 minutes: 0
seconds: 0];
}
[end setDate: value];
[end setTimeZone: nil];
}
+44
View File
@@ -29,6 +29,50 @@
#import "NSObject+PropertyList.m"
static void
OCDumpPListData (NSData *content)
{
//NSDictionary *d;
//NSPropertyListFormat format;
//NSString *error = nil;
//const char *formatName;
//d = [NSPropertyListSerialization propertyListFromData: content
// mutabilityOption: NSPropertyListImmutable
// format: &format
// errorDescription: &error];
//d = [content BSONValue];
// if (d)
// {
// switch (format)
// {
// case NSPropertyListOpenStepFormat:
// formatName = "OpenStep";
// break;
// case NSPropertyListXMLFormat_v1_0:
// formatName = "XML";
// break;
// case NSPropertyListBinaryFormat_v1_0:
// formatName = "Binary";
// break;
// case NSPropertyListGNUstepFormat:
// formatName = "GNUstep";
// break;
// case NSPropertyListGNUstepBinaryFormat:
// formatName = "GNUstep binary";
// break;
// default: formatName = "unknown";
// }
// printf ("File format is: %s\n", formatName);
// [d displayWithIndentation: 0];
// printf ("\n");
// }
// else
// printf ("an error occurred: %s\n", [error UTF8String]);
}
static void
PLReaderDumpPListFile (NSString *filename)
{
+5 -7
View File
@@ -276,7 +276,7 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
EOAdaptorChannel *channel;
GCSChannelHandle *handle;
NSCalendarDate *now, *lastFailure;
NSString *urlId;
NSString *urlId, *url;
channel = nil;
urlId = [_url gcsURLId];
@@ -304,10 +304,10 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
}
else
{
url = [NSString stringWithFormat: @"%@://%@%@", [_url scheme], [_url host], [_url path]];
if (debugPools)
{
[self logWithFormat: @"DBPOOL: create new DB channel for URL: %@",
[_url absoluteString]];
[self logWithFormat: @"DBPOOL: create new DB channel for %@", url];
}
/* create channel */
@@ -330,15 +330,13 @@ static NSTimeInterval ChannelCollectionTimer = 5 * 60;
if (lastFailure)
{
[self logWithFormat: @"db for %@ is now back up",
[_url absoluteString]];
[self logWithFormat: @"db for %@ is now back up", url];
[lastFailures removeObjectForKey: urlId];
}
}
else
{
[self errorWithFormat: @"could not open channel %@ for URL: %@",
channel, [_url absoluteString]];
[self errorWithFormat: @"could not open channel %@ for %@", channel, url];
channel = nil;
[lastFailures setObject: now forKey: urlId];
[self warnWithFormat: @" will prevent opening of this"
+1
View File
@@ -74,6 +74,7 @@ ifneq ($(frameworks),yes)
ifneq ($(FHS_INSTALL_ROOT),)
GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include
endif
GNUSTEP_TARGET_LDIR=sogo
include $(GNUSTEP_MAKEFILES)/library.make
else
include $(GNUSTEP_MAKEFILES)/framework.make
+1
View File
@@ -131,6 +131,7 @@ ifneq ($(frameworks),yes)
ifneq ($(FHS_INSTALL_ROOT),)
GNUSTEP_HEADERS=$(DESTDIR)$(FHS_INSTALL_ROOT)/include
endif
GNUSTEP_TARGET_LDIR=sogo
include $(GNUSTEP_MAKEFILES)/library.make
else
include $(GNUSTEP_MAKEFILES)/framework.make
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Abidjan
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Accra
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Addis_Ababa
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Algiers
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Asmara
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bamako
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bangui
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Banjul
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bissau
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Blantyre
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Brazzaville
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Bujumbura
+11 -3
View File
@@ -1,14 +1,22 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Cairo
X-LIC-LOCATION:Africa/Cairo
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETFROM:+0300
TZOFFSETTO:+0200
TZNAME:EET
DTSTART:19700101T000000
DTSTART:19700924T235959
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1TH
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+0300
TZOFFSETTO:+0300
TZNAME:EEST
DTSTART:19700424T010000
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=-1FR
END:DAYLIGHT
END:VTIMEZONE
END:VCALENDAR
+10 -10
View File
@@ -1,22 +1,22 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Casablanca
X-LIC-LOCATION:Africa/Casablanca
BEGIN:DAYLIGHT
TZOFFSETFROM:+0000
TZOFFSETTO:+0100
TZNAME:WEST
DTSTART:19700426T020000
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0100
TZOFFSETTO:+0000
TZNAME:WET
DTSTART:19700927T030000
RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0100
TZNAME:WEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
END:VTIMEZONE
END:VCALENDAR
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Ceuta
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Conakry
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Dakar
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Dar_es_Salaam
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Djibouti
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Douala
+11 -3
View File
@@ -1,14 +1,22 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/El_Aaiun
X-LIC-LOCATION:Africa/El_Aaiun
BEGIN:STANDARD
TZOFFSETFROM:+0000
TZOFFSETFROM:+0100
TZOFFSETTO:+0000
TZNAME:WET
DTSTART:19700101T000000
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0100
TZNAME:WEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
END:VTIMEZONE
END:VCALENDAR
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Freetown
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Gaborone
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Harare
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Johannesburg
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Juba
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Kampala
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Khartoum
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Kigali
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Kinshasa
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lagos
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Libreville
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lome
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Luanda
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lubumbashi
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Lusaka
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Malabo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Maputo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Maseru
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Mbabane
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Mogadishu
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Monrovia
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Nairobi
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Ndjamena
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Niamey
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Nouakchott
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Ouagadougou
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Porto-Novo
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Sao_Tome
+4 -12
View File
@@ -1,22 +1,14 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Tripoli
X-LIC-LOCATION:Africa/Tripoli
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700327T010000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1FR
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701030T020000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1FR
TZOFFSETTO:+0200
TZNAME:EET
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
END:VCALENDAR
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Tunis
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Africa/Windhoek
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Adak
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Anchorage
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Anguilla
+1 -1
View File
@@ -1,5 +1,5 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Antigua
+2 -10
View File
@@ -1,22 +1,14 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc.//NONSGML Olson 2012j//EN
PRODID:-//Inverse inc.//NONSGML Olson 2014g//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/Araguaina
X-LIC-LOCATION:America/Araguaina
BEGIN:DAYLIGHT
TZOFFSETFROM:-0300
TZOFFSETTO:-0200
TZNAME:BRST
DTSTART:19701018T000000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=3SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
TZNAME:BRT
DTSTART:19700215T000000
RRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=3SU
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
END:VCALENDAR

Some files were not shown because too many files have changed in this diff Show More