propagate from branch 'ca.inverse.sogo.1_3_15' (head 2718d596001d2e9358dcce09a959434c8f775f9f)

to branch 'ca.inverse.sogo' (head 366adf06b05b4f972813f3e731ae3338140ba86e)

Monotone-Parent: 2718d596001d2e9358dcce09a959434c8f775f9f
Monotone-Parent: 366adf06b05b4f972813f3e731ae3338140ba86e
Monotone-Revision: ba40327d7cdcc284485580a61af95f9056989d40

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2012-04-05T18:50:43
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau 2012-04-05 18:50:43 +00:00
commit fcbc47b234
31 changed files with 323 additions and 119 deletions

View file

@ -21,6 +21,43 @@
* OGoContentStore/OCSContactFieldExtractor.m * OGoContentStore/OCSContactFieldExtractor.m
(-extractQuickFieldsFromVCard): idem. (-extractQuickFieldsFromVCard): idem.
2012-03-30 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/MAPIStoreCalendarMessage.m (-save): remove comment if
content is "\n".
* OpenChange/MAPIStoreTasksMessage.m (-save): do not reset fields
that have not been passed in the properties array, since only
RopDeleteProperties should remove them.
Remove comment if content is "\n".
* OpenChange/MAPIStoreObject.m (-addPropertiesFromRow:): dates are
now all converted to the user's timezone, even though it just
inverts the problem we currently have.
* OpenChange/MAPIApplication.m (-init): utcTZ is now initialized
here.
* OpenChange/MAPIStoreTypes.[hm]: new host module for utcTZ.
* OpenChange/MAPIStoreUserContext.m (-timeZone): new method that
returns the timezone of an owner user.
* OpenChange/MAPIStoreObject.m (-ownerTimeZone): removed method,
replaced with the one above.
2012-03-29 Francis Lachapelle <flachapelle@inverse.ca>
* UI/WebServerResources/UIxPreferences.js (savePreferences): fixed
validation of end date of vacation of message when not using ISO
format (currently limited to French).
* UI/WebServerResources/ContactsUI.js (startDragging): create an
overlapping safety block (div) to avoid possible selection of the
underlying text.
* UI/WebServerResources/MailerUI.js (startDragging): idem.
2012-03-29 Francis Lachapelle <flachapelle@inverse.ca> 2012-03-29 Francis Lachapelle <flachapelle@inverse.ca>
* UI/WebServerResources/UIxPreferences.js (savePreferences): fixed * UI/WebServerResources/UIxPreferences.js (savePreferences): fixed
@ -44,6 +81,42 @@
* SoObjects/SOGo/LDAPSource.m (-allEntryIDs): take the _filter * SoObjects/SOGo/LDAPSource.m (-allEntryIDs): take the _filter
ivar into account. ivar into account.
2012-03-28 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* OpenChange/SOGoMAPIFSMessage.m
(_readFileChangesDataWithDate:andInode:): use the inode number
rather than the filesize as change indicator since a new file is
created each time the dictionary is written to disk, thanks to the
"atomically" flag.
(-save): write the file atomically.
* SoObjects/Contacts/SOGoFolder+CardDAV.m (_isValidFilter:):
accept "email" as filter name.
(_appendObject:withBaseURL:toREPORTResponse:): fixed the ordering
of XML elements as the address*-data props where put outside of
the <D:prop> tree.
* SoObjects/SOGo/LDAPSource.m (-allEntryIDs): take the _filter
ivar into account.
2012-03-27 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/Contacts/SOGoContactFolders.m
(-lookupName:inContext:acquire:): overriden method that enables
the lookup of hidden public sources with iOS devices.
* SoObjects/Contacts/SOGoContactLDIFEntry.m (-davAddressData): new
getter similar to davCalendarData.
* SoObjects/Contacts/SOGoContactSourceFolder.m
(-davAddressbookMultiget): new REPORT handler based on
-[SOGoAppointmentFolder davCalendarMultiget].
* SoObjects/Contacts/SOGoUserFolder+Contacts.m
(-davDirectoryGateway): new getter that returns the url to the
first available directory source.
(-davResourceType): declare resource as "directory" (carddav).
2012-03-27 Wolfgang Sourdeau <wsourdeau@inverse.ca> 2012-03-27 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/Contacts/SOGoContactFolders.m * SoObjects/Contacts/SOGoContactFolders.m

View file

@ -21,6 +21,7 @@
*/ */
#import <Foundation/NSUserDefaults.h> #import <Foundation/NSUserDefaults.h>
#import <Foundation/NSTimeZone.h>
#import <SOGo/SOGoProductLoader.h> #import <SOGo/SOGoProductLoader.h>
#import <SOGo/SOGoSystemDefaults.h> #import <SOGo/SOGoSystemDefaults.h>
@ -28,6 +29,7 @@
#import <Appointments/iCalEntityObject+SOGo.h> #import <Appointments/iCalEntityObject+SOGo.h>
#import "MAPIStoreUserContext.h" #import "MAPIStoreUserContext.h"
#import "MAPIStoreTypes.h"
#import "MAPIApplication.h" #import "MAPIApplication.h"
@ -49,6 +51,9 @@ MAPIApplication *MAPIApp = nil;
MAPIApp = [super init]; MAPIApp = [super init];
[MAPIApp retain]; [MAPIApp retain];
utcTZ = [NSTimeZone timeZoneWithName: @"UTC"];
[utcTZ retain];
} }
return MAPIApp; return MAPIApp;

View file

@ -35,8 +35,6 @@
@class SOGoUser; @class SOGoUser;
extern NSTimeZone *utcTZ;
@interface MAPIStoreAppointmentWrapper : NSObject @interface MAPIStoreAppointmentWrapper : NSObject
{ {
struct mapistore_connection_info *connInfo; struct mapistore_connection_info *connInfo;

View file

@ -59,16 +59,12 @@
#include <mapistore/mapistore_errors.h> #include <mapistore/mapistore_errors.h>
#include <mapistore/mapistore_nameid.h> #include <mapistore/mapistore_nameid.h>
NSTimeZone *utcTZ;
static NSCharacterSet *hexCharacterSet = nil; static NSCharacterSet *hexCharacterSet = nil;
@implementation MAPIStoreAppointmentWrapper @implementation MAPIStoreAppointmentWrapper
+ (void) initialize + (void) initialize
{ {
utcTZ = [NSTimeZone timeZoneWithName: @"UTC"];
[utcTZ retain];
if (!hexCharacterSet) if (!hexCharacterSet)
{ {
hexCharacterSet = [NSCharacterSet characterSetWithCharactersInString: @"1234567890abcdefABCDEF"]; hexCharacterSet = [NSCharacterSet characterSetWithCharactersInString: @"1234567890abcdefABCDEF"];

View file

@ -118,7 +118,7 @@
[MAPIStoreAppointmentWrapper wrapperWithICalEvent: event [MAPIStoreAppointmentWrapper wrapperWithICalEvent: event
andUser: [userContext sogoUser] andUser: [userContext sogoUser]
andSenderEmail: nil andSenderEmail: nil
inTimeZone: [self ownerTimeZone] inTimeZone: [userContext timeZone]
withConnectionInfo: [context connectionInfo]]); withConnectionInfo: [context connectionInfo]]);
} }
@ -766,10 +766,12 @@
isAllDay = [value boolValue]; isAllDay = [value boolValue];
if (!isAllDay) if (!isAllDay)
{ {
tzName = [[self ownerTimeZone] name]; tzName = [[[self userContext] timeZone] name];
tz = [iCalTimeZone timeZoneForName: tzName]; tz = [iCalTimeZone timeZoneForName: tzName];
[vCalendar addTimeZone: tz]; [vCalendar addTimeZone: tz];
} }
else
tz = nil;
// start // start
value = [properties objectForKey: MAPIPropertyKey (PR_START_DATE)]; value = [properties objectForKey: MAPIPropertyKey (PR_START_DATE)];
@ -779,18 +781,18 @@
if (value) if (value)
{ {
start = (iCalDateTime *) [newEvent uniqueChildWithTag: @"dtstart"]; start = (iCalDateTime *) [newEvent uniqueChildWithTag: @"dtstart"];
[start setTimeZone: tz];
if (isAllDay) if (isAllDay)
{
[start setDate: value];
[start setTimeZone: nil];
}
else
{ {
tzOffset = [[value timeZone] secondsFromGMTForDate: value]; tzOffset = [[value timeZone] secondsFromGMTForDate: value];
value = [value dateByAddingYears: 0 months: 0 days: 0 value = [value dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0 hours: 0 minutes: 0
seconds: -tzOffset]; seconds: tzOffset];
[start setTimeZone: nil];
[start setDate: value];
}
else
{
[start setTimeZone: tz];
[start setDateTime: value]; [start setDateTime: value];
} }
} }
@ -802,18 +804,18 @@
if (value) if (value)
{ {
end = (iCalDateTime *) [newEvent uniqueChildWithTag: @"dtend"]; end = (iCalDateTime *) [newEvent uniqueChildWithTag: @"dtend"];
[end setTimeZone: tz];
if (isAllDay) if (isAllDay)
{
[end setDate: value];
[end setTimeZone: nil];
}
else
{ {
tzOffset = [[value timeZone] secondsFromGMTForDate: value]; tzOffset = [[value timeZone] secondsFromGMTForDate: value];
value = [value dateByAddingYears: 0 months: 0 days: 0 value = [value dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: 0 hours: 0 minutes: 0
seconds: -tzOffset]; seconds: tzOffset];
[end setTimeZone: nil];
[end setDate: value];
}
else
{
[end setTimeZone: tz];
[end setDateTime: value]; [end setDateTime: value];
} }
} }
@ -872,10 +874,13 @@
value = [value htmlToText]; value = [value htmlToText];
} }
} }
if (value && [value length] == 0) if (value)
value = nil; {
[newEvent setComment: value]; if ([value length] == 0 || [value isEqualToString: @"\\n"])
value = nil;
[newEvent setComment: value];
}
/* recurrence */ /* recurrence */
value = [properties value = [properties
objectForKey: MAPIPropertyKey (PidLidAppointmentRecur)]; objectForKey: MAPIPropertyKey (PidLidAppointmentRecur)];

View file

@ -35,8 +35,6 @@
#include <mapistore/mapistore_errors.h> #include <mapistore/mapistore_errors.h>
extern NSTimeZone *utcTZ;
/* TODO: handle URL pictures via PidTagAttachMethod = ref ? */ /* TODO: handle URL pictures via PidTagAttachMethod = ref ? */
@implementation MAPIStoreContactsAttachment @implementation MAPIStoreContactsAttachment

View file

@ -55,8 +55,8 @@
{ {
struct mapistore_connection_info *connInfo; struct mapistore_connection_info *connInfo;
NSMutableArray *containersBag; NSMutableArray *containersBag;
SOGoUser *activeUser; SOGoUser *activeUser; /* the user accessing the resource */
MAPIStoreUserContext *userContext; MAPIStoreUserContext *userContext; /* the owner or the resource */
NSURL *contextUrl; NSURL *contextUrl;
} }

View file

@ -28,6 +28,7 @@
#import "MAPIStoreFAIMessage.h" #import "MAPIStoreFAIMessage.h"
#undef DEBUG #undef DEBUG
#include <stdbool.h>
#include <talloc.h> #include <talloc.h>
#include <util/time.h> #include <util/time.h>
#include <mapistore/mapistore.h> #include <mapistore/mapistore.h>

View file

@ -31,6 +31,7 @@
#import "MAPIStoreFallbackContext.h" #import "MAPIStoreFallbackContext.h"
#undef DEBUG #undef DEBUG
#include <inttypes.h>
#include <mapistore/mapistore.h> #include <mapistore/mapistore.h>
@implementation MAPIStoreFallbackContext @implementation MAPIStoreFallbackContext

View file

@ -284,7 +284,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
wrapperWithICalEvent: event wrapperWithICalEvent: event
andUser: [context activeUser] andUser: [context activeUser]
andSenderEmail: senderEmail andSenderEmail: senderEmail
inTimeZone: [self ownerTimeZone] inTimeZone: [[self userContext] timeZone]
withConnectionInfo: [context connectionInfo]]; withConnectionInfo: [context connectionInfo]];
[appointmentWrapper retain]; [appointmentWrapper retain];
} }

View file

@ -29,6 +29,7 @@
#import <Foundation/NSData.h> #import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>
#import <Foundation/NSValue.h> #import <Foundation/NSValue.h>
#import <NGExtensions/NGHashMap.h> #import <NGExtensions/NGHashMap.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
@ -495,7 +496,11 @@ FillMessageHeadersFromProperties (NGMutableHashMap *headers,
date = [mailProperties objectForKey: MAPIPropertyKey (PR_CLIENT_SUBMIT_TIME)]; date = [mailProperties objectForKey: MAPIPropertyKey (PR_CLIENT_SUBMIT_TIME)];
if (date) if (date)
[headers addObject: [date rfc822DateString] forKey: @"date"]; {
date = [date addYear: 0 month: 0 day: 0
hour: 0 minute: 0 second: [[date timeZone] secondsFromGMT]];
[headers addObject: [date rfc822DateString] forKey: @"date"];
}
[headers addObject: @"1.0" forKey: @"MIME-Version"]; [headers addObject: @"1.0" forKey: @"MIME-Version"];
} }

View file

@ -77,8 +77,6 @@
- (uint64_t) objectId; - (uint64_t) objectId;
- (NSString *) url; - (NSString *) url;
- (NSTimeZone *) ownerTimeZone;
/* properties */ /* properties */
- (BOOL) canGetProperty: (enum MAPITAGS) propTag; - (BOOL) canGetProperty: (enum MAPITAGS) propTag;

View file

@ -20,7 +20,9 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSTimeZone.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
#import <SOGo/SOGoObject.h> #import <SOGo/SOGoObject.h>
#import <SOGo/SOGoUser.h> #import <SOGo/SOGoUser.h>
@ -210,21 +212,6 @@ static Class NSExceptionK, MAPIStoreFolderK;
containerURL, [self nameInContainer]]; containerURL, [self nameInContainer]];
} }
- (NSTimeZone *) ownerTimeZone
{
NSString *owner;
SOGoUserDefaults *ud;
NSTimeZone *tz;
WOContext *woContext;
woContext = [[self userContext] woContext];
owner = [sogoObject ownerInContext: woContext];
ud = [[SOGoUser userWithLogin: owner] userDefaults];
tz = [ud timeZone];
return tz;
}
- (void) addProperties: (NSDictionary *) newNewProperties - (void) addProperties: (NSDictionary *) newNewProperties
{ {
[properties addEntriesFromDictionary: newNewProperties]; [properties addEntriesFromDictionary: newNewProperties];
@ -447,16 +434,37 @@ static Class NSExceptionK, MAPIStoreFolderK;
struct SPropValue *cValue; struct SPropValue *cValue;
NSUInteger counter; NSUInteger counter;
NSMutableDictionary *newProperties; NSMutableDictionary *newProperties;
NSTimeZone *tz;
NSInteger tzOffset;
id value;
tz = nil;
newProperties = [NSMutableDictionary dictionaryWithCapacity: aRow->cValues]; newProperties = [NSMutableDictionary dictionaryWithCapacity: aRow->cValues];
for (counter = 0; counter < aRow->cValues; counter++) for (counter = 0; counter < aRow->cValues; counter++)
{ {
cValue = aRow->lpProps + counter; cValue = aRow->lpProps + counter;
if ((cValue->ulPropTag & 0xfff) == PT_STRING8) value = NSObjectFromSPropValue (cValue);
[self warnWithFormat: switch (cValue->ulPropTag & 0xffff)
@"attempting to set string property as PR_STRING8: %.8x", {
cValue->ulPropTag]; case PT_STRING8:
[newProperties setObject: NSObjectFromSPropValue (cValue) case PT_MV_STRING8:
[self warnWithFormat:
@"attempting to set string property as PR_STRING8: %.8x",
cValue->ulPropTag];
break;
case PT_SYSTIME:
if (!tz)
{
tz = [[self userContext] timeZone];
tzOffset = -[tz secondsFromGMT];
}
value = [value addYear: 0 month: 0 day: 0
hour: 0 minute: 0 second: tzOffset];
[value setTimeZone: tz];
break;
}
[newProperties setObject: value
forKey: MAPIPropertyKey (cValue->ulPropTag)]; forKey: MAPIPropertyKey (cValue->ulPropTag)];
} }

View file

@ -21,6 +21,7 @@
*/ */
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <NGExtensions/NSCalendarDate+misc.h> #import <NGExtensions/NSCalendarDate+misc.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
@ -32,6 +33,7 @@
#import "NSDate+MAPIStore.h" #import "NSDate+MAPIStore.h"
#import "MAPIStoreRecurrenceUtils.h" #import "MAPIStoreRecurrenceUtils.h"
#include <stdbool.h>
#include <talloc.h> #include <talloc.h>
#include <util/time.h> #include <util/time.h>
#include <gen_ndr/property.h> #include <gen_ndr/property.h>

View file

@ -329,7 +329,8 @@
iCalToDo *vToDo; iCalToDo *vToDo;
id value; id value;
iCalDateTime *date; iCalDateTime *date;
NSString *status, *priority; iCalTimeZone *tz;
NSString *status, *priority, *tzName;
NSCalendarDate *now; NSCalendarDate *now;
NSInteger tzOffset; NSInteger tzOffset;
double doubleValue; double doubleValue;
@ -338,6 +339,10 @@
vCalendar = [vToDo parent]; vCalendar = [vToDo parent];
[vCalendar setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"]; [vCalendar setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"];
tzName = [[[self userContext] timeZone] name];
tz = [iCalTimeZone timeZoneForName: tzName];
[vCalendar addTimeZone: tz];
// summary // summary
value = [properties value = [properties
objectForKey: MAPIPropertyKey (PR_NORMALIZED_SUBJECT_UNICODE)]; objectForKey: MAPIPropertyKey (PR_NORMALIZED_SUBJECT_UNICODE)];
@ -358,12 +363,12 @@
value = [value htmlToText]; value = [value htmlToText];
} }
} }
if (value && [value length] == 0)
value = nil;
[vToDo setComment: value];
if (value) if (value)
[vToDo setComment: value]; {
if ([value length] == 0 || [value isEqualToString: @"\\n"])
value = nil;
[vToDo setComment: value];
}
// location // location
value = [properties objectForKey: MAPIPropertyKey (PidLidLocation)]; value = [properties objectForKey: MAPIPropertyKey (PidLidLocation)];
@ -388,31 +393,17 @@
if (value) if (value)
{ {
date = (iCalDateTime *) [vToDo uniqueChildWithTag: @"dtstart"]; date = (iCalDateTime *) [vToDo uniqueChildWithTag: @"dtstart"];
tzOffset = [[value timeZone] secondsFromGMTForDate: value]; [date setTimeZone: tz];
value = [value dateByAddingYears: 0 months: 0 days: 0 [date setDateTime: value];
hours: 0 minutes: 0
seconds: -tzOffset];
[date setDate: value];
} }
else
{
[vToDo setStartDate: nil];
}
// due // due
value = [properties objectForKey: MAPIPropertyKey (PidLidTaskDueDate)]; value = [properties objectForKey: MAPIPropertyKey (PidLidTaskDueDate)];
if (value) if (value)
{ {
date = (iCalDateTime *) [vToDo uniqueChildWithTag: @"due"]; date = (iCalDateTime *) [vToDo uniqueChildWithTag: @"due"];
tzOffset = [[value timeZone] secondsFromGMTForDate: value]; [date setTimeZone: tz];
value = [value dateByAddingYears: 0 months: 0 days: 0 [date setDateTime: value];
hours: 0 minutes: 0
seconds: -tzOffset];
[date setDate: value];
}
else
{
[vToDo setDue: nil];
} }
// completed // completed
@ -426,10 +417,6 @@
seconds: -tzOffset]; seconds: -tzOffset];
[date setDate: value]; [date setDate: value];
} }
else
{
[vToDo setCompleted: nil];
}
// status // status
value = [properties objectForKey: MAPIPropertyKey (PidLidTaskStatus)]; value = [properties objectForKey: MAPIPropertyKey (PidLidTaskStatus)];
@ -459,10 +446,8 @@
default: // IMPORTANCE_NORMAL default: // IMPORTANCE_NORMAL
priority = @"5"; priority = @"5";
} }
[vToDo setPriority: priority];
} }
else
priority = @"0"; // None
[vToDo setPriority: priority];
// percent complete // percent complete
// NOTE: this does not seem to work on Outlook 2003. PidLidPercentComplete's value // NOTE: this does not seem to work on Outlook 2003. PidLidPercentComplete's value

View file

@ -32,6 +32,9 @@
@class NSData; @class NSData;
@class NSDictionary; @class NSDictionary;
@class NSTimeZone;
extern NSTimeZone *utcTZ;
uint8_t *MAPIBoolValue (void *memCtx, BOOL value); uint8_t *MAPIBoolValue (void *memCtx, BOOL value);
uint32_t *MAPILongValue (void *memCtx, uint32_t value); uint32_t *MAPILongValue (void *memCtx, uint32_t value);

View file

@ -36,6 +36,8 @@
#include <mapistore/mapistore.h> #include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h> #include <mapistore/mapistore_errors.h>
NSTimeZone *utcTZ;
uint8_t * uint8_t *
MAPIBoolValue (void *memCtx, BOOL value) MAPIBoolValue (void *memCtx, BOOL value)
{ {

View file

@ -27,6 +27,7 @@
@class NSMutableDictionary; @class NSMutableDictionary;
@class NSString; @class NSString;
@class NSTimeZone;
@class WOContext; @class WOContext;
@ -43,6 +44,7 @@
{ {
NSString *username; NSString *username;
SOGoUser *sogoUser; SOGoUser *sogoUser;
NSTimeZone *timeZone;
SOGoUserFolder *userFolder; SOGoUserFolder *userFolder;
NSMutableArray *containersBag; NSMutableArray *containersBag;
@ -63,6 +65,8 @@
- (NSString *) username; - (NSString *) username;
- (SOGoUser *) sogoUser; - (SOGoUser *) sogoUser;
- (NSTimeZone *) timeZone;
- (SOGoUserFolder *) userFolder; - (SOGoUserFolder *) userFolder;
- (NSDictionary *) rootFolders; - (NSDictionary *) rootFolders;

View file

@ -137,6 +137,20 @@ static NSMapTable *contextsTable = nil;
return sogoUser; return sogoUser;
} }
- (NSTimeZone *) timeZone
{
if (!timeZone)
{
SOGoUser *user;
user = [self sogoUser];
timeZone = [[user userDefaults] timeZone];
[timeZone retain];
}
return timeZone;
}
- (SOGoUserFolder *) userFolder - (SOGoUserFolder *) userFolder
{ {
if (!userFolder) if (!userFolder)

View file

@ -29,6 +29,7 @@
#import "NSArray+MAPIStore.h" #import "NSArray+MAPIStore.h"
#undef DEBUG #undef DEBUG
#include <stdbool.h>
#include <talloc.h> #include <talloc.h>
#include <util/time.h> #include <util/time.h>
#include <gen_ndr/exchange.h> #include <gen_ndr/exchange.h>

View file

@ -27,6 +27,7 @@
#import "NSDate+MAPIStore.h" #import "NSDate+MAPIStore.h"
#undef DEBUG #undef DEBUG
#include <stdbool.h>
#include <talloc.h> #include <talloc.h>
#include <util/time.h> #include <util/time.h>
#include <mapistore/mapistore.h> #include <mapistore/mapistore.h>

View file

@ -39,6 +39,7 @@
#import "SOGoMAPIFSFolder.h" #import "SOGoMAPIFSFolder.h"
#undef DEBUG #undef DEBUG
#include <stdbool.h>
#include <talloc.h> #include <talloc.h>
#include <util/time.h> #include <util/time.h>
#include <mapistore/mapistore.h> #include <mapistore/mapistore.h>

View file

@ -31,7 +31,7 @@
@interface SOGoMAPIFSMessage : SOGoMAPIVolatileMessage @interface SOGoMAPIFSMessage : SOGoMAPIVolatileMessage
{ {
NSString *completeFilename; NSString *completeFilename;
NSUInteger fileSize; NSUInteger inode;
NSData *lastModificationTime; NSData *lastModificationTime;
} }

View file

@ -41,7 +41,7 @@
if ((self = [super init])) if ((self = [super init]))
{ {
completeFilename = nil; completeFilename = nil;
fileSize = 0; inode = 0;
lastModificationTime = nil; lastModificationTime = nil;
} }
@ -86,7 +86,7 @@
} }
- (BOOL) _readFileChangesDataWithDate: (NSDate **) newLMTime - (BOOL) _readFileChangesDataWithDate: (NSDate **) newLMTime
andSize: (NSUInteger *) newFileSize andInode: (NSUInteger *) newInode
{ {
BOOL rc; BOOL rc;
NSDictionary *attributes; NSDictionary *attributes;
@ -97,7 +97,7 @@
if (attributes) if (attributes)
{ {
*newLMTime = [attributes fileModificationDate]; *newLMTime = [attributes fileModificationDate];
*newFileSize = [attributes fileSize]; *newInode = [attributes fileSystemFileNumber];
rc = YES; rc = YES;
} }
else else
@ -107,22 +107,22 @@
} }
- (BOOL) _checkFileChangesDataWithDate: (NSDate **) newLMTime - (BOOL) _checkFileChangesDataWithDate: (NSDate **) newLMTime
andSize: (NSUInteger *) newFileSize andInode: (NSUInteger *) newInode
{ {
BOOL hasChanged = NO; BOOL hasChanged = NO;
NSDate *lastLMTime; NSDate *lastLMTime;
NSUInteger lastFileSize; NSUInteger lastInode;
if ([self _readFileChangesDataWithDate: &lastLMTime if ([self _readFileChangesDataWithDate: &lastLMTime
andSize: &lastFileSize]) andInode: &lastInode])
{ {
if (fileSize != lastFileSize if (inode != lastInode
|| ![lastModificationTime isEqual: lastLMTime]) || ![lastModificationTime isEqual: lastLMTime])
{ {
if (lastLMTime) if (lastLMTime)
*newLMTime = lastLMTime; *newLMTime = lastLMTime;
if (newFileSize) if (newInode)
*newFileSize = lastFileSize; *newInode = lastInode;
hasChanged = YES; hasChanged = YES;
} }
} }
@ -136,10 +136,10 @@
NSString *error; NSString *error;
NSPropertyListFormat format; NSPropertyListFormat format;
NSDate *lastLMTime; NSDate *lastLMTime;
NSUInteger lastFileSize; NSUInteger lastInode;
if ([self _checkFileChangesDataWithDate: &lastLMTime if ([self _checkFileChangesDataWithDate: &lastLMTime
andSize: &lastFileSize]) andInode: &lastInode])
{ {
[self logWithFormat: @"file '%@' new or modified: rereading properties", [self logWithFormat: @"file '%@' new or modified: rereading properties",
[self completeFilename]]; [self completeFilename]];
@ -158,7 +158,7 @@
@" of message: '%@'", error]; @" of message: '%@'", error];
} }
ASSIGN (lastModificationTime, lastLMTime); ASSIGN (lastModificationTime, lastLMTime);
fileSize = lastFileSize; inode = lastInode;
} }
return [super properties]; return [super properties];
@ -168,7 +168,7 @@
{ {
NSData *content; NSData *content;
NSDate *lastLMTime; NSDate *lastLMTime;
NSUInteger lastFileSize; NSUInteger lastInode;
[container ensureDirectory]; [container ensureDirectory];
@ -178,14 +178,13 @@
dataFromPropertyList: [self properties] dataFromPropertyList: [self properties]
format: NSPropertyListBinaryFormat_v1_0 format: NSPropertyListBinaryFormat_v1_0
errorDescription: NULL]; errorDescription: NULL];
if (![content writeToFile: [self completeFilename] atomically: NO]) if (![content writeToFile: [self completeFilename] atomically: YES])
[NSException raise: @"MAPIStoreIOException" [NSException raise: @"MAPIStoreIOException"
format: @"could not save message"]; format: @"could not save message"];
[self _readFileChangesDataWithDate: &lastLMTime [self _readFileChangesDataWithDate: &lastLMTime andInode: &lastInode];
andSize: &lastFileSize];
ASSIGN (lastModificationTime, lastLMTime); ASSIGN (lastModificationTime, lastLMTime);
fileSize = lastFileSize; inode = lastInode;
// [self logWithFormat: @"fs message written to '%@'", [self completeFilename]]; // [self logWithFormat: @"fs message written to '%@'", [self completeFilename]];
} }

View file

@ -2,6 +2,6 @@
# This file is included by library makefiles to set the version information # This file is included by library makefiles to set the version information
# of the executable. # of the executable.
MAJOR_VERSION=1 MAJOR_VERSION=2
MINOR_VERSION=3 MINOR_VERSION=0
SUBMINOR_VERSION=15 SUBMINOR_VERSION=0

11
debian/control vendored
View file

@ -22,6 +22,17 @@ Description: a modern and scalable groupware
UI for the users, consistency in look and feel with the Mozilla applications, UI for the users, consistency in look and feel with the Mozilla applications,
and to reduce the load of the transactions on the server. and to reduce the load of the transactions on the server.
Package: sogo-dev
Section: devel
Architecture: any
Depends: sogo (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
Replaces: sogo (<< ${binary:Version})
Description: a modern and scalable groupware - development files
SOGo is a groupware server built around OpenGroupware.org (OGo) and
the SOPE application server with focus on scalability.
.
This package contains the development files for developing SOGo modules.
Package: sogo-dbg Package: sogo-dbg
Section: debug Section: debug
Priority: extra Priority: extra

57
debian/control-squeeze vendored Normal file
View file

@ -0,0 +1,57 @@
Source: sogo
Priority: optional
Maintainer: Inverse Support <support@inverse.ca>
Build-Depends: debhelper (>= 7.0.15), gobjc | objc-compiler, libgnustep-base-dev, libsope-appserver4.9-dev, libsope-core4.9-dev, libsope-gdl1-4.9-dev, libsope-ldap4.9-dev, libsope-mime4.9-dev, libsope-xml4.9-dev, libmemcached-dev, libxml2-dev, libsbjson-dev, libssl-dev, libcurl4-openssl-dev | libcurl4-gnutls-dev, libmapi-dev, libmapistore-dev, libmapiproxy-dev
Section: web
Standards-Version: 3.9.1
Package: sogo
Section: web
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, tmpreaper, sope4.9-libxmlsaxdriver, sope4.9-db-connector, gnustep-make, libcurl3
Suggests: nginx
Description: a modern and scalable groupware
SOGo is a groupware server built around OpenGroupware.org (OGo) and
the SOPE application server with focus on scalability.
The Inverse edition of this project has many feature enhancements:
* CalDAV and GroupDAV compliance
* full handling of vCard as well as vCalendar/iCalendar formats
* support for folder sharing and ACLs
.
The Web interface has been rewritten in an AJAX fashion to provide a faster
UI for the users, consistency in look and feel with the Mozilla applications,
and to reduce the load of the transactions on the server.
Package: sogo-dev
Section: devel
Architecture: any
Depends: sogo (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
Replaces: sogo (<< ${binary:Version})
Description: a modern and scalable groupware - development files
SOGo is a groupware server built around OpenGroupware.org (OGo) and
the SOPE application server with focus on scalability.
.
This package contains the development files for developing SOGo modules.
Package: sogo-openchange
Section: net
Priority: extra
Architecture: any
Depends: sogo (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
Description: a modern and scalable groupware - OpenChange backend
SOGo is a groupware server built around OpenGroupware.org (OGo) and
the SOPE application server with focus on scalability.
.
This package contains the backend plugin for using SOGo as a backend
to OpenChange.
Package: sogo-dbg
Section: debug
Priority: extra
Architecture: any
Depends: sogo (= ${binary:Version}), ${misc:Depends}
Description: a modern and scalable groupware - debugging symbols
SOGo is a groupware server built around OpenGroupware.org (OGo) and
the SOPE application server with focus on scalability.
.
This package contains the debugging symbols for SOGo.

43
debian/rules vendored
View file

@ -3,6 +3,8 @@
export DH_VERBOSE=1 export DH_VERBOSE=1
# export DH_OPTIONS="-p sogo" # export DH_OPTIONS="-p sogo"
DESTDIR=$(CURDIR)/debian/tmp
config.make: configure config.make: configure
dh_testdir dh_testdir
./configure ./configure
@ -14,36 +16,59 @@ build-arch: build-arch-stamp
build-arch-stamp: config.make build-arch-stamp: config.make
# Add here commands to compile the arch part of the package. # Add here commands to compile the arch part of the package.
$(MAKE) $(MAKE)
if pkg-config --atleast-version=1.0 libmapi; \
then (cd OpenChange; $(MAKE)); \
fi
touch $@ touch $@
clean: clean:
dh_testdir dh_testdir
dh_testroot dh_testroot
rm -f build-arch-stamp rm -f build-arch-stamp
if [ -f config.make ]; then make clean; fi if [ -f config.make ]; \
then \
if pkg-config --atleast-version=1.0 libmapi; \
then \
(cd OpenChange; make clean); \
fi; \
make clean; \
fi
dh_clean dh_clean
install: install-arch install: install-arch
dh_testdir dh_testdir
dh_testroot dh_testroot
dh_prep -i # dh_prep -i
dh_installdirs -i # dh_installdirs -i
dh_install -i # dh_install -i
install-arch: build-arch install-arch: build-arch
dh_testdir dh_testdir
dh_testroot dh_testroot
dh_prep -i dh_prep
# dh_installdirs -s # dh_installdirs -s
$(MAKE) DESTDIR=$(CURDIR)/debian/tmp GNUSTEP_INSTALLATION_DOMAIN=SYSTEM install $(MAKE) DESTDIR=$(DESTDIR) GNUSTEP_INSTALLATION_DOMAIN=SYSTEM install
if pkg-config --atleast-version=1.0 libmapi; \
then \
(cd OpenChange; \
$(MAKE) \
DESTDIR=$(DESTDIR) \
GNUSTEP_INSTALLATION_DOMAIN=SYSTEM \
install); \
rm -f $(DESTDIR)/usr/lib/mapistore_backends/libMAPIStoreSOGo.so.1; \
rm -f $(DESTDIR)/usr/lib/mapistore_backends/libMAPIStoreSOGo.so; \
mv -f $(DESTDIR)/usr/lib/mapistore_backends/libMAPIStoreSOGo.so.1.0.0 \
$(DESTDIR)/usr/lib/mapistore_backends/SOGo.so; \
fi
mkdir -p debian/tmp/etc/default mkdir -p debian/tmp/etc/default
cp Scripts/sogo-default debian/tmp/etc/default/sogo cp Scripts/sogo-default debian/tmp/etc/default/sogo
mkdir -p debian/tmp/usr/share/lintian/overrides mkdir -p debian/tmp/usr/share/lintian/overrides
cp debian/sogo.overrides debian/tmp/usr/share/lintian/overrides/sogo cp debian/sogo.overrides debian/tmp/usr/share/lintian/overrides/sogo
mkdir -p debian/tmp/etc/apache2/conf.d mkdir -p debian/tmp/etc/apache2/conf.d
cp Apache/SOGo.conf debian/tmp/etc/apache2/conf.d/SOGo.conf cp Apache/SOGo.conf debian/tmp/etc/apache2/conf.d/SOGo.conf
install -D -m 600 Scripts/sogo.cron debian/tmp/etc/cron.d/sogo install -D -m 644 Scripts/sogo.cron debian/tmp/etc/cron.d/sogo
# Build architecture dependant packages using the common target. # Build architecture dependant packages using the common target.
binary-arch: build-arch install-arch binary-arch: build-arch install-arch
@ -64,8 +89,8 @@ binary-arch: build-arch install-arch
( cd debian/sogo-dbg/usr/lib/debug/usr/lib/; \ ( cd debian/sogo-dbg/usr/lib/debug/usr/lib/; \
ln -s GNUstep/Frameworks/SOGo.framework/Versions/*/libSOGo* ./ ) ln -s GNUstep/Frameworks/SOGo.framework/Versions/*/libSOGo* ./ )
dh_compress dh_compress
dh_fixperms -X/etc/cron.d/sogo dh_fixperms
dh_makeshlibs dh_makeshlibs -X/usr/lib/mapistore_backends
dh_shlibdeps dh_shlibdeps
dh_installdeb dh_installdeb
dh_gencontrol dh_gencontrol

2
debian/sogo-dev.install vendored Normal file
View file

@ -0,0 +1,2 @@
usr/include/GNUstep/*
usr/lib/lib*.so

2
debian/sogo-openchange.install vendored Normal file
View file

@ -0,0 +1,2 @@
usr/lib/mapistore_backends/*
usr/lib/GNUstep/SOGo/SOGoBackend.MAPIStore

13
debian/sogo.install vendored
View file

@ -2,7 +2,14 @@ etc/default/sogo
etc/apache2/conf.d/SOGo.conf etc/apache2/conf.d/SOGo.conf
etc/cron.d/sogo etc/cron.d/sogo
usr/sbin/* usr/sbin/*
usr/lib/GNUstep/* usr/lib/GNUstep/Frameworks/*
usr/lib/lib* usr/lib/GNUstep/Libraries/*
usr/include/GNUstep/* usr/lib/GNUstep/OCSTypeModels/*
usr/lib/GNUstep/SaxDrivers-4.9/*
usr/lib/GNUstep/SaxMappings/*
usr/lib/GNUstep/WOxElemBuilders-4.9/*
usr/lib/GNUstep/SOGo/*.SOGo
usr/lib/GNUstep/SOGo/Templates
usr/lib/GNUstep/SOGo/WebServerResources
usr/lib/lib*.so.*
usr/share/lintian/* usr/share/lintian/*