Merge pull request #146 from Zentyal/merge-from-upstream
Merge from upstream
This commit is contained in:
commit
c0a22ead1d
11
.tx/config
11
.tx/config
|
@ -12,6 +12,7 @@ trans.da_DK = UI/MailerUI/Danish.lproj/Localizable.strings
|
|||
trans.de = UI/MailerUI/German.lproj/Localizable.strings
|
||||
trans.es_AR = UI/MailerUI/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = UI/MailerUI/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = UI/MailerUI/Basque.lproj/Localizable.strings
|
||||
trans.fi = UI/MailerUI/Finnish.lproj/Localizable.strings
|
||||
trans.fr = UI/MailerUI/French.lproj/Localizable.strings
|
||||
trans.hu = UI/MailerUI/Hungarian.lproj/Localizable.strings
|
||||
|
@ -38,6 +39,7 @@ trans.da_DK = UI/PreferencesUI/Danish.lproj/Localizable.strings
|
|||
trans.de = UI/PreferencesUI/German.lproj/Localizable.strings
|
||||
trans.es_AR = UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = UI/PreferencesUI/Basque.lproj/Localizable.strings
|
||||
trans.fi = UI/PreferencesUI/Finnish.lproj/Localizable.strings
|
||||
trans.fr = UI/PreferencesUI/French.lproj/Localizable.strings
|
||||
trans.hu = UI/PreferencesUI/Hungarian.lproj/Localizable.strings
|
||||
|
@ -64,6 +66,7 @@ trans.da_DK = UI/Scheduler/Danish.lproj/Localizable.strings
|
|||
trans.de = UI/Scheduler/German.lproj/Localizable.strings
|
||||
trans.es_AR = UI/Scheduler/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = UI/Scheduler/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = UI/Scheduler/Basque.lproj/Localizable.strings
|
||||
trans.fi = UI/Scheduler/Finnish.lproj/Localizable.strings
|
||||
trans.fr = UI/Scheduler/French.lproj/Localizable.strings
|
||||
trans.hu = UI/Scheduler/Hungarian.lproj/Localizable.strings
|
||||
|
@ -90,6 +93,7 @@ trans.da_DK = UI/Contacts/Danish.lproj/Localizable.strings
|
|||
trans.de = UI/Contacts/German.lproj/Localizable.strings
|
||||
trans.es_AR = UI/Contacts/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = UI/Contacts/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = UI/Contacts/Basque.lproj/Localizable.strings
|
||||
trans.fi = UI/Contacts/Finnish.lproj/Localizable.strings
|
||||
trans.fr = UI/Contacts/French.lproj/Localizable.strings
|
||||
trans.hu = UI/Contacts/Hungarian.lproj/Localizable.strings
|
||||
|
@ -116,6 +120,7 @@ trans.da_DK = UI/MainUI/Danish.lproj/Localizable.strings
|
|||
trans.de = UI/MainUI/German.lproj/Localizable.strings
|
||||
trans.es_AR = UI/MainUI/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = UI/MainUI/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = UI/MainUI/Basque.lproj/Localizable.strings
|
||||
trans.fi = UI/MainUI/Finnish.lproj/Localizable.strings
|
||||
trans.fr = UI/MainUI/French.lproj/Localizable.strings
|
||||
trans.hu = UI/MainUI/Hungarian.lproj/Localizable.strings
|
||||
|
@ -142,6 +147,7 @@ trans.da_DK = UI/Common/Danish.lproj/Localizable.strings
|
|||
trans.de = UI/Common/German.lproj/Localizable.strings
|
||||
trans.es_AR = UI/Common/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = UI/Common/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = UI/Common/Basque.lproj/Localizable.strings
|
||||
trans.fi = UI/Common/Finnish.lproj/Localizable.strings
|
||||
trans.fr = UI/Common/French.lproj/Localizable.strings
|
||||
trans.hu = UI/Common/Hungarian.lproj/Localizable.strings
|
||||
|
@ -168,6 +174,7 @@ trans.da_DK = UI/AdministrationUI/Danish.lproj/Localizable.strings
|
|||
trans.de = UI/AdministrationUI/German.lproj/Localizable.strings
|
||||
trans.es_AR = UI/AdministrationUI/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = UI/AdministrationUI/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = UI/AdministrationUI/Basque.lproj/Localizable.strings
|
||||
trans.fi = UI/AdministrationUI/Finnish.lproj/Localizable.strings
|
||||
trans.fr = UI/AdministrationUI/French.lproj/Localizable.strings
|
||||
trans.hu = UI/AdministrationUI/Hungarian.lproj/Localizable.strings
|
||||
|
@ -194,6 +201,7 @@ trans.da_DK = SoObjects/Appointments/Danish.lproj/Localizable.strings
|
|||
trans.de = SoObjects/Appointments/German.lproj/Localizable.strings
|
||||
trans.es_AR = SoObjects/Appointments/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = SoObjects/Appointments/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = SoObjects/Appointments/Basque.lproj/Localizable.strings
|
||||
trans.fi = SoObjects/Appointments/Finnish.lproj/Localizable.strings
|
||||
trans.fr = SoObjects/Appointments/French.lproj/Localizable.strings
|
||||
trans.hu = SoObjects/Appointments/Hungarian.lproj/Localizable.strings
|
||||
|
@ -220,6 +228,7 @@ trans.da_DK = SoObjects/Contacts/Danish.lproj/Localizable.strings
|
|||
trans.de = SoObjects/Contacts/German.lproj/Localizable.strings
|
||||
trans.es_AR = SoObjects/Contacts/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = SoObjects/Contacts/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = SoObjects/Contacts/Basque.lproj/Localizable.strings
|
||||
trans.fi = SoObjects/Contacts/Finnish.lproj/Localizable.strings
|
||||
trans.fr = SoObjects/Contacts/French.lproj/Localizable.strings
|
||||
trans.hu = SoObjects/Contacts/Hungarian.lproj/Localizable.strings
|
||||
|
@ -246,6 +255,7 @@ trans.da_DK = SoObjects/Mailer/Danish.lproj/Localizable.strings
|
|||
trans.de = SoObjects/Mailer/German.lproj/Localizable.strings
|
||||
trans.es_AR = SoObjects/Mailer/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = SoObjects/Mailer/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = SoObjects/Mailer/Basque.lproj/Localizable.strings
|
||||
trans.fi = SoObjects/Mailer/Finnish.lproj/Localizable.strings
|
||||
trans.fr = SoObjects/Mailer/French.lproj/Localizable.strings
|
||||
trans.hu = SoObjects/Mailer/Hungarian.lproj/Localizable.strings
|
||||
|
@ -272,6 +282,7 @@ trans.da_DK = UI/MailPartViewers/Danish.lproj/Localizable.strings
|
|||
trans.de = UI/MailPartViewers/German.lproj/Localizable.strings
|
||||
trans.es_AR = UI/MailPartViewers/SpanishArgentina.lproj/Localizable.strings
|
||||
trans.es_ES = UI/MailPartViewers/SpanishSpain.lproj/Localizable.strings
|
||||
trans.eu = UI/MailPartViewers/Basque.lproj/Localizable.strings
|
||||
trans.fi = UI/MailPartViewers/Finnish.lproj/Localizable.strings
|
||||
trans.fr = UI/MailPartViewers/French.lproj/Localizable.strings
|
||||
trans.hu = UI/MailPartViewers/Hungarian.lproj/Localizable.strings
|
||||
|
|
|
@ -32,6 +32,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#import <Foundation/NSProcessInfo.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
|
||||
#import <NGExtensions/NGBase64Coding.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
|
@ -45,11 +47,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
- (void) _dumpToFile
|
||||
{
|
||||
NSString *path;
|
||||
BOOL debugOn;
|
||||
|
||||
path = [NSString stringWithFormat: @"/tmp/%@.data", [[NSProcessInfo processInfo] globallyUniqueString]];
|
||||
[self writeToFile: path atomically: YES];
|
||||
[self errorWithFormat: @"Original data written to: %@", path];
|
||||
debugOn = [[SOGoSystemDefaults sharedSystemDefaults] easDebugEnabled];
|
||||
|
||||
if (debugOn)
|
||||
{
|
||||
NSString *path;
|
||||
|
||||
path = [NSString stringWithFormat: @"/tmp/%@.data", [[NSProcessInfo processInfo] globallyUniqueString]];
|
||||
[self writeToFile: path atomically: YES];
|
||||
[self errorWithFormat: @"Original data written to: %@", path];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2014, Inverse inc.
|
||||
Copyright (c) 2014-2015, Inverse inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@ -51,6 +51,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
- (NSString *) command;
|
||||
- (NSString *) collectionid;
|
||||
- (NSString *) itemid;
|
||||
- (BOOL) acceptsMultiPart;
|
||||
- (NSData *) convertHexStringToBytes;
|
||||
|
||||
@end
|
||||
|
|
|
@ -322,6 +322,18 @@ static NSArray *easCommandParameters = nil;
|
|||
return s;
|
||||
}
|
||||
|
||||
- (BOOL) acceptsMultiPart
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [self _valueForParameter: @"OPTIONS="];
|
||||
|
||||
if (s && [s rangeOfString: @"AcceptMultiPart" options: NSCaseInsensitiveSearch].location != NSNotFound)
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FIXME: combine with our OpenChange code.
|
||||
|
|
|
@ -131,6 +131,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
|
||||
[[o properties] addEntriesFromDictionary: values];
|
||||
|
@ -1068,14 +1069,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
changeDetected: (BOOL *) changeDetected
|
||||
maxSyncResponseSize: (int) theMaxSyncResponseSize
|
||||
{
|
||||
NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *lastServerKey, *syncKeyInCache;
|
||||
NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *mimeSupport, *lastServerKey, *syncKeyInCache;
|
||||
SOGoMicrosoftActiveSyncFolderType folderType;
|
||||
id collection, value;
|
||||
|
||||
NSMutableString *changeBuffer, *commandsBuffer;
|
||||
BOOL getChanges, first_sync;
|
||||
unsigned int windowSize, v, status;
|
||||
NSMutableDictionary *folderMetadata;
|
||||
NSMutableDictionary *folderMetadata, *folderOptions;
|
||||
|
||||
changeBuffer = [NSMutableString string];
|
||||
commandsBuffer = [NSMutableString string];
|
||||
|
@ -1124,20 +1125,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
first_sync = NO;
|
||||
|
||||
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]];
|
||||
|
||||
if ([syncKey isEqualToString: @"0"])
|
||||
{
|
||||
davCollectionTag = @"-1";
|
||||
first_sync = YES;
|
||||
*changeDetected = YES;
|
||||
}
|
||||
else if ((![syncKey isEqualToString: @"-1"]) && !([[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"SyncCache"]))
|
||||
else if ((![syncKey isEqualToString: @"-1"]) && !([folderMetadata objectForKey: @"SyncCache"]))
|
||||
{
|
||||
//NSLog(@"Reset folder: %@", [collection nameInContainer]);
|
||||
davCollectionTag = @"0";
|
||||
first_sync = YES;
|
||||
*changeDetected = YES;
|
||||
|
||||
if (!([[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"displayName"]))
|
||||
if (!([folderMetadata objectForKey: @"displayName"]))
|
||||
status = 12; // need folderSync
|
||||
else
|
||||
status = 3; // do a complete resync
|
||||
|
@ -1147,7 +1150,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
bodyPreferenceType = [[(id)[[(id)[theDocumentElement getElementsByTagName: @"BodyPreference"] lastObject] getElementsByTagName: @"Type"] lastObject] textValue];
|
||||
|
||||
if (!bodyPreferenceType)
|
||||
bodyPreferenceType = @"1";
|
||||
{
|
||||
bodyPreferenceType = [[folderMetadata objectForKey: @"FolderOptions"] objectForKey: @"BodyPreferenceType"];
|
||||
|
||||
// By default, send MIME mails. See #3146 for details.
|
||||
if (!bodyPreferenceType)
|
||||
bodyPreferenceType = @"4";
|
||||
}
|
||||
else
|
||||
{
|
||||
mimeSupport = [[(id)[theDocumentElement getElementsByTagName: @"MIMESupport"] lastObject] textValue];
|
||||
|
||||
if (!mimeSupport)
|
||||
mimeSupport = [[folderMetadata objectForKey: @"FolderOptions"] objectForKey: @"MIMESupport"];
|
||||
|
||||
if (!mimeSupport)
|
||||
mimeSupport = @"0";
|
||||
|
||||
if ([mimeSupport isEqualToString: @"1"] && [bodyPreferenceType isEqualToString: @"4"])
|
||||
bodyPreferenceType = @"2";
|
||||
else if ([mimeSupport isEqualToString: @"2"] && [bodyPreferenceType isEqualToString: @"4"])
|
||||
bodyPreferenceType = @"4";
|
||||
else if ([mimeSupport isEqualToString: @"0"] && [bodyPreferenceType isEqualToString: @"4"])
|
||||
bodyPreferenceType = @"2";
|
||||
|
||||
|
||||
// Avoid writing to cache if there is nothing to change.
|
||||
if (![[[folderMetadata objectForKey: @"FolderOptions"] objectForKey: @"BodyPreferenceType"] isEqualToString: bodyPreferenceType] ||
|
||||
![[[folderMetadata objectForKey: @"FolderOptions"] objectForKey: @"MIMESupport"] isEqualToString: mimeSupport])
|
||||
{
|
||||
folderOptions = [[NSDictionary alloc] initWithObjectsAndKeys: mimeSupport, @"MIMESupport", bodyPreferenceType, @"BodyPreferenceType", nil];
|
||||
[folderMetadata setObject: folderOptions forKey: @"FolderOptions"];
|
||||
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: collection withType: folderType]];
|
||||
}
|
||||
}
|
||||
|
||||
[context setObject: bodyPreferenceType forKey: @"BodyPreferenceType"];
|
||||
|
||||
|
@ -1416,6 +1452,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
inBuffer: s
|
||||
changeDetected: &changeDetected
|
||||
maxSyncResponseSize: maxSyncResponseSize];
|
||||
|
||||
if (maxSyncResponseSize > 0 && [s length] >= maxSyncResponseSize)
|
||||
break;
|
||||
}
|
||||
|
||||
if (changeDetected)
|
||||
|
|
|
@ -61,6 +61,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#import <NGExtensions/NGHashMap.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
#import <NGExtensions/NSString+Encoding.h>
|
||||
|
||||
#import <NGImap4/NGImap4Client.h>
|
||||
#import <NGImap4/NGImap4Connection.h>
|
||||
|
@ -95,6 +96,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#import <SOGo/GCSSpecialQueries+SOGoCacheObject.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <SOGo/WORequest+SOGo.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
|
@ -110,6 +112,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#import <Mailer/SOGoMailBodyPart.h>
|
||||
#import <Mailer/SOGoMailFolder.h>
|
||||
#import <Mailer/SOGoMailObject.h>
|
||||
#import <Mailer/SOGoMailObject+Draft.h>
|
||||
#import <Mailer/NSString+Mail.h>
|
||||
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
@ -138,10 +143,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
@implementation SOGoActiveSyncDispatcher
|
||||
|
||||
static BOOL debugOn = NO;
|
||||
|
||||
- (id) init
|
||||
{
|
||||
[super init];
|
||||
|
||||
debugOn = [[SOGoSystemDefaults sharedSystemDefaults] easDebugEnabled];
|
||||
folderTableURL = nil;
|
||||
return self;
|
||||
}
|
||||
|
@ -917,6 +925,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
[o save];
|
||||
|
||||
|
@ -1001,6 +1010,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
}
|
||||
|
||||
|
@ -1023,6 +1033,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
}
|
||||
|
||||
|
@ -1451,6 +1462,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
appointmentObject = [collection lookupName: [NSString stringWithFormat: @"%@.ics", [event uid]]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
|
||||
// Create the appointment if it is not added to calendar yet
|
||||
if ([appointmentObject isKindOfClass: [NSException class]])
|
||||
{
|
||||
appointmentObject = [[SOGoAppointmentObject alloc] initWithName: [NSString stringWithFormat: @"%@.ics", [event uid]]
|
||||
inContainer: collection];
|
||||
[appointmentObject saveComponent: event];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1486,7 +1505,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
}
|
||||
else
|
||||
{
|
||||
[theResponse setStatus: 500];
|
||||
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
|
||||
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
|
||||
[s appendString: @"<MeetingResponse xmlns=\"MeetingResponse:\">"];
|
||||
[s appendString: @"<Result>"];
|
||||
[s appendFormat: @"<RequestId>%@</RequestId>", requestId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 2];
|
||||
[s appendString: @"</Result>"];
|
||||
[s appendString: @"</MeetingResponse>"];
|
||||
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
|
||||
|
||||
[theResponse setContent: d];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1600,10 +1629,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
//
|
||||
// See http://msdn.microsoft.com/en-us/library/gg651088(v=exchg.80).aspx for Status response codes.
|
||||
//
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
if ([prevSuccessfulMoveItemsOps objectForKey: srcMessageId])
|
||||
{
|
||||
// Previous move failed operation but we can recover the dstMessageId from previous request
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<DstMsgId>%@</DstMsgId>", [prevSuccessfulMoveItemsOps objectForKey: srcMessageId]];
|
||||
[s appendFormat: @"<Status>%d</Status>", 3];
|
||||
[newSuccessfulMoveItemsOps setObject: [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] forKey: srcMessageId];
|
||||
|
@ -2088,13 +2117,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
SOGoContactSourceFolder *currentFolder;
|
||||
NSArray *allKeys, *allContacts, *mails;
|
||||
NSDictionary *systemSources, *contact;
|
||||
NSString *name, *query, *current_mail;
|
||||
SOGoContactFolders *contactFolders;
|
||||
NSArray *allKeys, *allContacts;
|
||||
SOGoUserFolder *userFolder;
|
||||
NSString *name, *query;
|
||||
NSMutableString *s;
|
||||
NSData *d;
|
||||
id o;
|
||||
|
||||
int i, j, total;
|
||||
|
||||
|
@ -2145,18 +2175,50 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
// We get the LDIF entry of our record, for easier processing
|
||||
contact = [[currentFolder lookupName: [contact objectForKey: @"c_name"] inContext: context acquire: NO] ldifRecord];
|
||||
|
||||
[s appendString: @"<Result xmlns=\"Search:\">"];
|
||||
[s appendString: @"<Properties>"];
|
||||
[s appendFormat: @"<DisplayName xmlns=\"Gal:\">%@</DisplayName>", [contact objectForKey: @"displayname"]];
|
||||
[s appendFormat: @"<FirstName xmlns=\"Gal:\">%@</FirstName>", [contact objectForKey: @"givenname"]];
|
||||
[s appendFormat: @"<LastName xmlns=\"Gal:\">%@</LastName>", [contact objectForKey: @"sn"]];
|
||||
[s appendFormat: @"<EmailAddress xmlns=\"Gal:\">%@</EmailAddress>", [contact objectForKey: @"mail"]];
|
||||
[s appendFormat: @"<Phone xmlns=\"Gal:\">%@</Phone>", [contact objectForKey: @"telephonenumber"]];
|
||||
[s appendFormat: @"<Company xmlns=\"Gal:\">%@</Company>", [contact objectForKey: @"o"]];
|
||||
[s appendString: @"</Properties>"];
|
||||
[s appendString: @"</Result>"];
|
||||
total++;
|
||||
|
||||
o = [contact objectForKey: @"mail"];
|
||||
if ([o isKindOfClass: [NSArray class]])
|
||||
mails = o;
|
||||
else
|
||||
mails = [NSArray arrayWithObjects: o ? o : @"", nil];
|
||||
|
||||
for (total = 0; total < [mails count]; total++)
|
||||
{
|
||||
current_mail = [mails objectAtIndex: total];
|
||||
|
||||
[s appendString: @"<Result xmlns=\"Search:\">"];
|
||||
[s appendString: @"<Properties>"];
|
||||
|
||||
if ((o = [contact objectForKey: @"displayname"]))
|
||||
[s appendFormat: @"<DisplayName xmlns=\"Gal:\">%@</DisplayName>", o];
|
||||
|
||||
if ((o = [contact objectForKey: @"title"]))
|
||||
[s appendFormat: @"<Title xmlns=\"Gal:\">%@</Title>", o];
|
||||
|
||||
if ((o = [contact objectForKey: @"givenname"]))
|
||||
[s appendFormat: @"<FirstName xmlns=\"Gal:\">%@</FirstName>", o];
|
||||
|
||||
if ((o = [contact objectForKey: @"sn"]))
|
||||
[s appendFormat: @"<LastName xmlns=\"Gal:\">%@</LastName>", o];
|
||||
|
||||
if ([current_mail length] > 0)
|
||||
[s appendFormat: @"<EmailAddress xmlns=\"Gal:\">%@</EmailAddress>", current_mail];
|
||||
|
||||
if ((o = [contact objectForKey: @"telephonenumber"]))
|
||||
[s appendFormat: @"<Phone xmlns=\"Gal:\">%@</Phone>", o];
|
||||
|
||||
if ((o = [contact objectForKey: @"homephone"]))
|
||||
[s appendFormat: @"<HomePhone xmlns=\"Gal:\">%@</HomePhone>", o];
|
||||
|
||||
if ((o = [contact objectForKey: @"mobile"]))
|
||||
[s appendFormat: @"<MobilePhone xmlns=\"Gal:\">%@</MobilePhone>", o];
|
||||
|
||||
if ((o = [contact objectForKey: @"o"]))
|
||||
[s appendFormat: @"<Company xmlns=\"Gal:\">%@</Company>", o];
|
||||
|
||||
[s appendString: @"</Properties>"];
|
||||
[s appendString: @"</Result>"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2332,26 +2394,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// <?xml version="1.0"?>
|
||||
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
|
||||
// <SmartForward xmlns="ComposeMail:">
|
||||
// <ClientId>C9FF94FE-EA40-473A-B3E2-AAEE94F753A4</ClientId>
|
||||
// <SaveInSentItems/>
|
||||
// <ReplaceMime/>
|
||||
// <Source>
|
||||
// <FolderId>mail/INBOX</FolderId>
|
||||
// <ItemId>82</ItemId>
|
||||
// </Source>
|
||||
// <MIME>... the data ...</MIME>
|
||||
// </SmartForward>
|
||||
//
|
||||
- (void) processSmartForward: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
- (void) _processSmartCommand: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
isSmartForward: (BOOL ) isSmartForward
|
||||
{
|
||||
NSString *folderId, *itemId, *realCollectionId;
|
||||
SOGoMicrosoftActiveSyncFolderType folderType;
|
||||
SOGoUserDefaults *ud;
|
||||
|
||||
BOOL htmlComposition, isHTML;
|
||||
id value;
|
||||
|
||||
isHTML = NO;
|
||||
ud = [[context activeUser] userDefaults];
|
||||
|
||||
folderId = [[(id)[theDocumentElement getElementsByTagName: @"FolderId"] lastObject] textValue];
|
||||
|
||||
|
@ -2400,11 +2455,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
NGMutableHashMap *map;
|
||||
NGMimeFileData *fdata;
|
||||
NSException *error;
|
||||
NSArray *attachmentKeys;
|
||||
NSMutableArray *attachments;
|
||||
|
||||
id body, bodyFromSmartForward;
|
||||
NSString *fullName, *email;
|
||||
id body, bodyFromSmartForward, htmlPart, textPart;
|
||||
NSString *fullName, *email, *charset, *s;
|
||||
NSDictionary *identity;
|
||||
|
||||
int a;
|
||||
|
||||
userFolder = [[context activeUser] homeFolderInContext: context];
|
||||
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
|
||||
currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];
|
||||
|
@ -2415,7 +2474,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
mailObject = [currentCollection lookupName: itemId inContext: context acquire: NO];
|
||||
|
||||
|
||||
parser = [[NGMimeMessageParser alloc] init];
|
||||
data = [[[[(id)[theDocumentElement getElementsByTagName: @"MIME"] lastObject] textValue] stringByDecodingBase64] dataUsingEncoding: NSUTF8StringEncoding];
|
||||
messageFromSmartForward = [parser parsePartFromData: data];
|
||||
|
@ -2436,6 +2494,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
else
|
||||
[map setObject: email forKey: @"from"];
|
||||
|
||||
if ([mailObject messageId])
|
||||
[map setObject: [mailObject messageId] forKey: @"in-reply-to"];
|
||||
|
||||
messageToSend = [[[NGMimeMessage alloc] initWithHeader: map] autorelease];
|
||||
body = [[[NGMimeMultipartBody alloc] initWithPart: messageToSend] autorelease];
|
||||
|
||||
|
@ -2443,12 +2504,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
// we take the first part text/* part we see.
|
||||
map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease];
|
||||
bodyFromSmartForward = nil;
|
||||
textPart = nil;
|
||||
htmlPart = nil;
|
||||
|
||||
attachments = [NSMutableArray array];
|
||||
|
||||
if ([[messageFromSmartForward body] isKindOfClass: [NGMimeMultipartBody class]])
|
||||
{
|
||||
NGMimeBodyPart *part;
|
||||
NSArray *parts;
|
||||
int i;
|
||||
NGMimeBodyPart *part, *apart;
|
||||
NSArray *parts, *aparts;
|
||||
int i, j;
|
||||
|
||||
parts = [[messageFromSmartForward body] parts];
|
||||
|
||||
|
@ -2456,37 +2521,159 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
{
|
||||
part = [parts objectAtIndex: i];
|
||||
|
||||
if ([[[part contentType] type] isEqualToString: @"text"])
|
||||
if ([[[part contentType] type] isEqualToString: @"multipart"] && [[[part contentType] subType] isEqualToString: @"alternative"])
|
||||
{
|
||||
[map setObject: [[part contentType] stringValue] forKey: @"content-type"];
|
||||
bodyFromSmartForward = [part body];
|
||||
break;
|
||||
aparts = [[part body] parts];
|
||||
for (j = 0; j < [aparts count]; j++)
|
||||
{
|
||||
apart = [aparts objectAtIndex: j];
|
||||
if ([[[apart contentType] type] isEqualToString: @"text"] && [[[apart contentType] subType] isEqualToString: @"html"])
|
||||
htmlPart = apart;
|
||||
if ([[[apart contentType] type] isEqualToString: @"text"] && [[[apart contentType] subType] isEqualToString: @"plain"])
|
||||
textPart = apart;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([[[part contentType] type] isEqualToString: @"text"] && [[[part contentType] subType] isEqualToString: @"html"])
|
||||
htmlPart = part;
|
||||
else if ([[[part contentType] type] isEqualToString: @"text"] && [[[part contentType] subType] isEqualToString: @"plain"])
|
||||
textPart = part;
|
||||
else
|
||||
[attachments addObject: part];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[map setObject: [[messageFromSmartForward contentType] stringValue] forKey: @"content-type"];
|
||||
bodyFromSmartForward = [messageFromSmartForward body];
|
||||
if ([[[messageFromSmartForward contentType] type] isEqualToString: @"text"] && [[[messageFromSmartForward contentType] subType] isEqualToString: @"html"])
|
||||
htmlPart = messageFromSmartForward;
|
||||
else
|
||||
textPart = messageFromSmartForward;
|
||||
}
|
||||
|
||||
htmlComposition = [[ud mailComposeMessageType] isEqualToString: @"html"];
|
||||
|
||||
if (htmlComposition && htmlPart)
|
||||
{
|
||||
bodyFromSmartForward = [htmlPart body];
|
||||
charset = [[htmlPart contentType] valueOfParameter: @"charset"];
|
||||
isHTML = YES;
|
||||
}
|
||||
else if (!htmlComposition && !textPart)
|
||||
{
|
||||
bodyFromSmartForward = [htmlPart body];
|
||||
charset = [[htmlPart contentType] valueOfParameter: @"charset"];
|
||||
isHTML = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
bodyFromSmartForward = [textPart body];
|
||||
charset = [[textPart contentType] valueOfParameter: @"charset"];
|
||||
}
|
||||
|
||||
// We make sure everything is encoded in UTF-8.
|
||||
if ([bodyFromSmartForward isKindOfClass: [NSData class]])
|
||||
{
|
||||
if (![charset length])
|
||||
charset = @"utf-8";
|
||||
|
||||
s = [NSString stringWithData: bodyFromSmartForward usingEncodingNamed: charset];
|
||||
|
||||
// We fallback to ISO-8859-1 string encoding. We avoid #3103.
|
||||
if (!s)
|
||||
s = [[[NSString alloc] initWithData: bodyFromSmartForward encoding: NSISOLatin1StringEncoding] autorelease];
|
||||
|
||||
bodyFromSmartForward = s;
|
||||
}
|
||||
|
||||
if (htmlComposition && !isHTML)
|
||||
{
|
||||
[map setObject: @"text/html; charset=utf-8" forKey: @"content-type"];
|
||||
bodyFromSmartForward = [[bodyFromSmartForward stringByEscapingHTMLString] stringByConvertingCRLNToHTML];
|
||||
}
|
||||
else if (!htmlComposition && isHTML)
|
||||
{
|
||||
[map setObject: @"text/plain; charset=utf-8" forKey: @"content-type"];
|
||||
bodyFromSmartForward = [bodyFromSmartForward htmlToText];
|
||||
}
|
||||
else if (htmlComposition && isHTML)
|
||||
{
|
||||
[map setObject: @"text/html; charset=utf-8" forKey: @"content-type"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[map setObject: @"text/plain; charset=utf-8" forKey: @"content-type"];
|
||||
}
|
||||
|
||||
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease];
|
||||
[bodyPart setBody: bodyFromSmartForward];
|
||||
|
||||
if (isSmartForward && [[ud mailMessageForwarding] isEqualToString: @"attached"])
|
||||
[bodyPart setBody: [bodyFromSmartForward dataUsingEncoding: NSUTF8StringEncoding]];
|
||||
else
|
||||
[bodyPart setBody: [[NSString stringWithFormat: @"%@%@", bodyFromSmartForward, [mailObject contentForEditing]] dataUsingEncoding: NSUTF8StringEncoding]];
|
||||
|
||||
[body addBodyPart: bodyPart];
|
||||
|
||||
// Second part
|
||||
map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease];
|
||||
[map setObject: @"message/rfc822" forKey: @"content-type"];
|
||||
[map setObject: @"8bit" forKey: @"content-transfer-encoding"];
|
||||
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease];
|
||||
|
||||
data = [mailObject content];
|
||||
fdata = [[NGMimeFileData alloc] initWithBytes:[data bytes]
|
||||
length:[data length]];
|
||||
// Add attachments
|
||||
for (a = 0; a < [attachments count]; a++)
|
||||
{
|
||||
[body addBodyPart: [attachments objectAtIndex: a]];
|
||||
}
|
||||
|
||||
// For a forward decide whether do it inline or as an attachment.
|
||||
if (isSmartForward)
|
||||
{
|
||||
if ([[ud mailMessageForwarding] isEqualToString: @"attached"])
|
||||
{
|
||||
map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease];
|
||||
[map setObject: @"message/rfc822" forKey: @"content-type"];
|
||||
[map setObject: @"8bit" forKey: @"content-transfer-encoding"];
|
||||
[map addObject: [NSString stringWithFormat: @"attachment; filename=\"%@\"", [mailObject filenameForForward]] forKey: @"content-disposition"];
|
||||
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader: map] autorelease];
|
||||
|
||||
data = [mailObject content];
|
||||
fdata = [[NGMimeFileData alloc] initWithBytes: [data bytes] length: [data length]];
|
||||
|
||||
[bodyPart setBody: fdata];
|
||||
RELEASE(fdata);
|
||||
[body addBodyPart: bodyPart];
|
||||
}
|
||||
else
|
||||
{
|
||||
attachmentKeys = [mailObject fetchFileAttachmentKeys];
|
||||
if ([attachmentKeys count])
|
||||
{
|
||||
id currentAttachment;
|
||||
NGHashMap *response;
|
||||
NSData *bodydata;
|
||||
NSArray *paths;
|
||||
|
||||
paths = [attachmentKeys keysWithFormat: @"BODY[%{path}]"];
|
||||
response = [[mailObject fetchParts: paths] objectForKey: @"RawResponse"];
|
||||
|
||||
for (a = 0; a < [attachmentKeys count]; a++)
|
||||
{
|
||||
currentAttachment = [attachmentKeys objectAtIndex: a];
|
||||
bodydata = [[[response objectForKey: @"fetch"] objectForKey: [NSString stringWithFormat: @"body[%@]", [currentAttachment objectForKey: @"path"]]] valueForKey: @"data"];
|
||||
|
||||
map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease];
|
||||
[map setObject: [currentAttachment objectForKey: @"mimetype"] forKey: @"content-type"];
|
||||
[map setObject: [currentAttachment objectForKey: @"encoding"] forKey: @"content-transfer-encoding"];
|
||||
[map addObject: [NSString stringWithFormat: @"attachment; filename=\"%@\"", [currentAttachment objectForKey: @"filename"]] forKey: @"content-disposition"];
|
||||
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader: map] autorelease];
|
||||
|
||||
fdata = [[NGMimeFileData alloc] initWithBytes:[bodydata bytes] length:[bodydata length]];
|
||||
|
||||
[bodyPart setBody: fdata];
|
||||
RELEASE(fdata);
|
||||
[body addBodyPart: bodyPart];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[bodyPart setBody: fdata];
|
||||
RELEASE(fdata);
|
||||
[body addBodyPart: bodyPart];
|
||||
[messageToSend setBody: body];
|
||||
|
||||
generator = [[[NGMimeMessageGenerator alloc] init] autorelease];
|
||||
|
@ -2510,6 +2697,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// <?xml version="1.0"?>
|
||||
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
|
||||
// <SmartForward xmlns="ComposeMail:">
|
||||
// <ClientId>C9FF94FE-EA40-473A-B3E2-AAEE94F753A4</ClientId>
|
||||
// <SaveInSentItems/>
|
||||
// <ReplaceMime/>
|
||||
// <Source>
|
||||
// <FolderId>mail/INBOX</FolderId>
|
||||
// <ItemId>82</ItemId>
|
||||
// </Source>
|
||||
// <MIME>... the data ...</MIME>
|
||||
// </SmartForward>
|
||||
//
|
||||
- (void) processSmartForward: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
[self _processSmartCommand: theDocumentElement
|
||||
inResponse: theResponse
|
||||
isSmartForward: YES];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// <?xml version="1.0"?>
|
||||
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
|
||||
|
@ -2527,11 +2737,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
- (void) processSmartReply: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
[self processSmartForward: theDocumentElement inResponse: theResponse];
|
||||
[self _processSmartCommand: theDocumentElement
|
||||
inResponse: theResponse
|
||||
isSmartForward: NO];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
@ -2550,7 +2760,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
ASSIGN(context, theContext);
|
||||
|
||||
|
||||
// Get the device ID, device type and "stash" them
|
||||
deviceId = [[theRequest uri] deviceId];
|
||||
[context setObject: deviceId forKey: @"DeviceId"];
|
||||
|
@ -2613,6 +2823,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
if (d)
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - request for device %@: %@", [context objectForKey: @"DeviceId"], [[[NSString alloc] initWithData: d encoding: NSUTF8StringEncoding] autorelease]];
|
||||
|
||||
builder = [[[NSClassFromString(@"DOMSaxBuilder") alloc] init] autorelease];
|
||||
dom = [builder buildFromData: d];
|
||||
documentElement = [dom documentElement];
|
||||
|
@ -2630,7 +2843,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
aSelector = NSSelectorFromString(cmdName);
|
||||
|
||||
// The -processItemOperations: method will generate a multipart response when Content-Type is application/vnd.ms-sync.multipart
|
||||
if ([[theRequest headerForKey: @"MS-ASAcceptMultiPart"] isEqualToString:@"T"])
|
||||
if (([cmdName rangeOfString: @"ItemOperations" options: NSCaseInsensitiveSearch].location != NSNotFound) &&
|
||||
([[theRequest headerForKey: @"MS-ASAcceptMultiPart"] isEqualToString:@"T"] || [[theRequest uri] acceptsMultiPart]))
|
||||
[theResponse setHeader: @"application/vnd.ms-sync.multipart" forKey: @"Content-Type"];
|
||||
else
|
||||
[theResponse setHeader: @"application/vnd.ms-sync.wbxml" forKey: @"Content-Type"];
|
||||
|
@ -2641,6 +2855,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
[theResponse setHeader: @"Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,ResolveRecipients,ValidateCert" forKey: @"MS-ASProtocolCommands"];
|
||||
[theResponse setHeader: @"2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"];
|
||||
|
||||
if (debugOn && [[theResponse content] length])
|
||||
[self logWithFormat: @"EAS - response for device %@: %@", [context objectForKey: @"DeviceId"], [[[NSString alloc] initWithData: [[theResponse content] wbxml2xml] encoding: NSUTF8StringEncoding] autorelease]];
|
||||
|
||||
RELEASE(context);
|
||||
RELEASE(pool);
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
||||
#import <NGImap4/NSString+Imap4.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WOApplication.h>
|
||||
|
||||
#import <NGMime/NGMimeBodyPart.h>
|
||||
#import <NGMime/NGMimeFileData.h>
|
||||
|
@ -74,6 +75,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <SOGo/SOGoUser.h>
|
||||
#include <SOGo/NSString+Utilities.h>
|
||||
|
||||
#import <Appointments/SOGoAptMailNotification.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t dwLowDateTime;
|
||||
uint32_t dwHighDateTime;
|
||||
|
@ -216,6 +219,8 @@ struct GlobalObjectId {
|
|||
NSEnumerator *e;
|
||||
NSData *d;
|
||||
|
||||
BOOL ignore;
|
||||
|
||||
textParts = [self fetchPlainTextParts];
|
||||
e = [textParts keyEnumerator];
|
||||
plainKey = nil;
|
||||
|
@ -224,6 +229,27 @@ struct GlobalObjectId {
|
|||
|
||||
while ((key = [e nextObject]))
|
||||
{
|
||||
// Walk the hierarchy up and check whether parents are of type mulipart - i.e. ignore message/rfc822
|
||||
if ([key countOccurrencesOfString: @"."] > 0)
|
||||
{
|
||||
NSMutableArray *a;
|
||||
|
||||
a = [[[key componentsSeparatedByString: @"."] mutableCopy] autorelease];
|
||||
ignore = NO;
|
||||
|
||||
while ([a count] > 0)
|
||||
{
|
||||
[a removeLastObject];
|
||||
part = [self lookupInfoForBodyPart: [a componentsJoinedByString: @"."]];
|
||||
|
||||
if (![[part valueForKey: @"type"] isEqualToString: @"multipart"])
|
||||
ignore = YES;
|
||||
}
|
||||
|
||||
if (ignore)
|
||||
continue;
|
||||
}
|
||||
|
||||
part = [self lookupInfoForBodyPart: key];
|
||||
type = [part valueForKey: @"type"];
|
||||
subtype = [part valueForKey: @"subtype"];
|
||||
|
@ -440,7 +466,7 @@ struct GlobalObjectId {
|
|||
// We get the right part based on the preference
|
||||
if (theType == 1 || theType == 2)
|
||||
{
|
||||
if ([type isEqualToString: @"text"])
|
||||
if ([type isEqualToString: @"text"] && ![subtype isEqualToString: @"calendar"])
|
||||
{
|
||||
NSString *s, *charset;
|
||||
|
||||
|
@ -499,9 +525,37 @@ struct GlobalObjectId {
|
|||
- (iCalCalendar *) calendarFromIMIPMessage
|
||||
{
|
||||
NSDictionary *part;
|
||||
NSString *type, *subtype;
|
||||
NSArray *parts;
|
||||
int i;
|
||||
|
||||
type = [[[self bodyStructure] valueForKey: @"type"] lowercaseString];
|
||||
subtype = [[[self bodyStructure] valueForKey: @"subtype"] lowercaseString];
|
||||
|
||||
// process mail of type text/calendar
|
||||
if ([type isEqualToString: @"text"] && [subtype isEqualToString: @"calendar"])
|
||||
{
|
||||
iCalCalendar *calendar;
|
||||
NSString *encoding;
|
||||
NSData *calendarData;
|
||||
|
||||
encoding = [[[self bodyStructure] valueForKey: @"encoding"] lowercaseString];
|
||||
calendarData = [[self fetchPlainTextParts] objectForKey: @""];
|
||||
|
||||
if ([encoding caseInsensitiveCompare: @"base64"] == NSOrderedSame)
|
||||
calendarData = [calendarData dataByDecodingBase64];
|
||||
else if ([encoding caseInsensitiveCompare: @"quoted-printable"] == NSOrderedSame)
|
||||
calendarData = [calendarData dataByDecodingQuotedPrintableTransferEncoding];
|
||||
|
||||
NS_DURING
|
||||
calendar = [iCalCalendar parseSingleFromSource: calendarData];
|
||||
NS_HANDLER
|
||||
calendar = nil;
|
||||
NS_ENDHANDLER
|
||||
|
||||
return calendar;
|
||||
}
|
||||
|
||||
// We check if we have at least 2 parts and if one of them is a text/calendar
|
||||
parts = [[self bodyStructure] objectForKey: @"parts"];
|
||||
|
||||
|
@ -596,7 +650,11 @@ struct GlobalObjectId {
|
|||
|
||||
// Importance
|
||||
v = 0x1;
|
||||
p = [[self mailHeaders] objectForKey: @"x-priority"];
|
||||
value = [[self mailHeaders] objectForKey: @"x-priority"];
|
||||
if ([value isKindOfClass: [NSArray class]])
|
||||
p = [value lastObject];
|
||||
else
|
||||
p = value;
|
||||
|
||||
if (p)
|
||||
{
|
||||
|
@ -607,7 +665,12 @@ struct GlobalObjectId {
|
|||
}
|
||||
else
|
||||
{
|
||||
p = [[self mailHeaders] objectForKey: @"importance"];
|
||||
value = [[self mailHeaders] objectForKey: @"importance"];
|
||||
if ([value isKindOfClass: [NSArray class]])
|
||||
p = [value lastObject];
|
||||
else
|
||||
p = value;
|
||||
|
||||
if ([p hasPrefix: @"High"]) v = 0x2;
|
||||
else if ([p hasPrefix: @"Low"]) v = 0x0;
|
||||
}
|
||||
|
@ -676,18 +739,18 @@ struct GlobalObjectId {
|
|||
|
||||
[s appendFormat: @"<AllDayEvent xmlns=\"Email:\">%d</AllDayEvent>", ([event isAllDay] ? 1 : 0)];
|
||||
|
||||
// StartTime -- http://msdn.microsoft.com/en-us/library/ee157132(v=exchg.80).aspx
|
||||
// StartTime -- https://msdn.microsoft.com/en-us/library/ee203365%28v=exchg.80%29.aspx
|
||||
if ([event startDate])
|
||||
[s appendFormat: @"<StartTime xmlns=\"Email:\">%@</StartTime>", [[event startDate] activeSyncRepresentationWithoutSeparatorsInContext: context]];
|
||||
[s appendFormat: @"<StartTime xmlns=\"Email:\">%@</StartTime>", [[event startDate] activeSyncRepresentationInContext: context]];
|
||||
|
||||
if ([event timeStampAsDate])
|
||||
[s appendFormat: @"<DTStamp xmlns=\"Email:\">%@</DTStamp>", [[event timeStampAsDate] activeSyncRepresentationWithoutSeparatorsInContext: context]];
|
||||
[s appendFormat: @"<DTStamp xmlns=\"Email:\">%@</DTStamp>", [[event timeStampAsDate] activeSyncRepresentationInContext: context]];
|
||||
else if ([event created])
|
||||
[s appendFormat: @"<DTStamp xmlns=\"Email:\">%@</DTStamp>", [[event created] activeSyncRepresentationWithoutSeparatorsInContext: context]];
|
||||
[s appendFormat: @"<DTStamp xmlns=\"Email:\">%@</DTStamp>", [[event created] activeSyncRepresentationInContext: context]];
|
||||
|
||||
// EndTime -- http://msdn.microsoft.com/en-us/library/ee157945(v=exchg.80).aspx
|
||||
// EndTime -- https://msdn.microsoft.com/en-us/library/ee158628(v=exchg.80).aspx
|
||||
if ([event endDate])
|
||||
[s appendFormat: @"<EndTime xmlns=\"Email:\">%@</EndTime>", [[event endDate] activeSyncRepresentationWithoutSeparatorsInContext: context]];
|
||||
[s appendFormat: @"<EndTime xmlns=\"Email:\">%@</EndTime>", [[event endDate] activeSyncRepresentationInContext: context]];
|
||||
|
||||
// FIXME: Single appointment - others are not supported right now
|
||||
[s appendFormat: @"<InstanceType xmlns=\"Email:\">%d</InstanceType>", 0];
|
||||
|
@ -735,7 +798,9 @@ struct GlobalObjectId {
|
|||
[s appendFormat: @"<GlobalObjId xmlns=\"Email:\">%@</GlobalObjId>", [globalObjId activeSyncRepresentationInContext: context]];
|
||||
|
||||
// We set the right message type - we must set AS version to 14.1 for this
|
||||
[s appendFormat: @"<MeetingMessageType xmlns=\"Email2:\">%d</MeetingMessageType>", 1];
|
||||
if ([[[context request] headerForKey: @"MS-ASProtocolVersion"] isEqualToString: @"14.1"])
|
||||
[s appendFormat: @"<MeetingMessageType xmlns=\"Email2:\">%d</MeetingMessageType>", 1];
|
||||
|
||||
[s appendString: @"</MeetingRequest>"];
|
||||
|
||||
// ContentClass
|
||||
|
@ -762,6 +827,42 @@ struct GlobalObjectId {
|
|||
|
||||
nativeBodyType = 1;
|
||||
d = [self _preferredBodyDataUsingType: preferredBodyType nativeType: &nativeBodyType];
|
||||
|
||||
if (calendar && !d)
|
||||
{
|
||||
WOApplication *app;
|
||||
SOGoAptMailNotification *p;
|
||||
NSString *pageName;
|
||||
|
||||
nativeBodyType = 2;
|
||||
|
||||
/* get WOApplication instance */
|
||||
app = [WOApplication application];
|
||||
|
||||
/* create page name */
|
||||
pageName = [NSString stringWithFormat: @"SOGoAptMail%@", @"Invitation"];
|
||||
/* construct message content */
|
||||
p = [app pageWithName: pageName inContext: context];
|
||||
[p setApt: (iCalEvent *) [[calendar events] lastObject]];
|
||||
|
||||
if ([[ [[calendar events] lastObject] organizer] cn] && [[[ [[calendar events] lastObject] organizer] cn] length])
|
||||
{
|
||||
[p setOrganizerName: [[ [[calendar events] lastObject] organizer] cn]];
|
||||
}
|
||||
else
|
||||
{
|
||||
[p setOrganizerName: [[SOGoUser userWithLogin: owner] cn]];
|
||||
}
|
||||
|
||||
if (preferredBodyType == 1 && nativeBodyType == 2)
|
||||
d = [[[p getBody] htmlToText] dataUsingEncoding: NSUTF8StringEncoding];
|
||||
else
|
||||
{
|
||||
preferredBodyType = 2;
|
||||
d = [[p getBody] dataUsingEncoding: NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (d)
|
||||
{
|
||||
|
@ -883,9 +984,18 @@ struct GlobalObjectId {
|
|||
[s appendFormat: @"</Categories>"];
|
||||
}
|
||||
|
||||
if ([[[context request] headerForKey: @"MS-ASProtocolVersion"] isEqualToString: @"14.0"] ||
|
||||
[[[context request] headerForKey: @"MS-ASProtocolVersion"] isEqualToString: @"14.1"])
|
||||
{
|
||||
if ([self inReplyTo])
|
||||
[s appendFormat: @"<ConversationId xmlns=\"Email2:\">%@</ConversationId>", [[[self inReplyTo] dataUsingEncoding: NSUTF8StringEncoding] activeSyncRepresentationInContext: context]];
|
||||
else if ([self messageId])
|
||||
[s appendFormat: @"<ConversationId xmlns=\"Email2:\">%@</ConversationId>", [[[self messageId] dataUsingEncoding: NSUTF8StringEncoding] activeSyncRepresentationInContext: context]];
|
||||
}
|
||||
|
||||
// FIXME - support these in the future
|
||||
//[s appendString: @"<ConversationId xmlns=\"Email2:\">foobar</ConversationId>"];
|
||||
//[s appendString: @"<ConversationIndex xmlns=\"Email2:\">zot=</ConversationIndex>"];
|
||||
|
||||
|
||||
// NativeBodyType -- http://msdn.microsoft.com/en-us/library/ee218276(v=exchg.80).aspx
|
||||
// This is a required child element.
|
||||
|
|
|
@ -167,9 +167,9 @@ Operating System Requirements
|
|||
The following 32-bit and 64-bit operating systems are currently
|
||||
supported by SOGo:
|
||||
|
||||
* Red Hat Enterprise Linux (RHEL) Server 5 and 6
|
||||
* Community ENTerprise Operating System (CentOS) 5 and 6
|
||||
* Debian GNU/Linux 5.0 (Lenny) to 7.0 (Wheezy)
|
||||
* Red Hat Enterprise Linux (RHEL) Server 5, 6 and 7
|
||||
* Community ENTerprise Operating System (CentOS) 5, 6 and 7
|
||||
* Debian GNU/Linux 6.0 (Squeeze) to 8.0 (Jessie)
|
||||
* Ubuntu 10.04 (Lucid) to 14.04 (Trusty)
|
||||
|
||||
Make sure the required components are started automatically at boot time
|
||||
|
@ -194,7 +194,8 @@ Installation
|
|||
|
||||
This section will guide you through the installation of SOGo together
|
||||
with its dependencies. The steps described here apply to an RPM-based
|
||||
installation for a Red Hat or CentOS distribution.
|
||||
installation for a Red Hat or CentOS 6 distribution. Most of these steps
|
||||
should apply to all supported operating systems.
|
||||
|
||||
Software Downloads
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
@ -566,17 +567,29 @@ usernames like this: `SOGoSuperUsernames = (<username1>[, <username2>, ...]);`
|
|||
for SOGo. Possible values are:
|
||||
|
||||
[options="compact"]
|
||||
* `Arabic`
|
||||
* `Basque`
|
||||
* `BrazilianPortuguese`
|
||||
* `Catalan`
|
||||
* `Czech`
|
||||
* `Danish`
|
||||
* `Dutch`
|
||||
* `English`
|
||||
* `Finnish`
|
||||
* `French`
|
||||
* `German`
|
||||
* `Hungarian`
|
||||
* `Icelandic`
|
||||
* `Italian`
|
||||
* `NorwegianBokmal`
|
||||
* `NorwegianNynorsk`
|
||||
* `Polish`
|
||||
* `Russian`
|
||||
* `Spanish`
|
||||
* `Slovak`
|
||||
* `SpanishSpain`
|
||||
* `SpanishArgentina`
|
||||
* `Swedish`
|
||||
* `Ukrainian`
|
||||
* `Welsh`
|
||||
|
||||
|D |SOGoNotifyOnPersonalModifications
|
||||
|
@ -649,7 +662,7 @@ of 1 day by default.
|
|||
|Parameter used to configure which languages are available from SOGo's
|
||||
Web interface. Available languages are specified as an array of string.
|
||||
|
||||
The default value is: `( "Czech", "Welsh", "English", "Spanish", "French", "German", "Italian", "Hungarian", "Dutch", "BrazilianPortuguese", "Polish", "Russian", Ukrainian", "Swedish" )`
|
||||
The default value is: `( "Arabic", "Basque", "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English", "SpanishSpain", "SpanishArgentina", "Finnish", "French", "German", "Icelandic", "Italian", "Hungarian", "BrazilianPortuguese", "NorwegianBokmal", "NorwegianNynorsk", "Polish", "Russian", "Slovak", "Ukrainian", "Swedish" )`
|
||||
|
||||
|D |SOGoHideSystemEMail
|
||||
|Parameter used to control if SOGo should hide or not the system email
|
||||
|
@ -843,7 +856,7 @@ source:
|
|||
|
||||
[cols="^3,>47,50a"]
|
||||
|=======================================================================
|
||||
.33+|D <|SOGoUserSources
|
||||
.34+|D <|SOGoUserSources
|
||||
|Parameter used to set the LDAP and/or SQL sources used for
|
||||
authentication and global address books. Multiple sources can be
|
||||
specified as an array of dictionaries. A dictionary that defines an LDAP
|
||||
|
@ -2439,6 +2452,11 @@ Defaults to `0`, which means no overwrite is performed.
|
|||
|
||||
Setting this parameter to a value greater than `512` will
|
||||
have unexpected behaviour with various ActiveSync clients.
|
||||
|S |SOGoEASDebugEnabled
|
||||
|Parameter used to log the complete request and response of every single
|
||||
EAS command.
|
||||
|
||||
Defaults to `NO`, which means no logging is performed.
|
||||
|=======================================================================
|
||||
|
||||
Please be aware of the following limitations:
|
||||
|
@ -2693,6 +2711,13 @@ current version of SOGo from the previous release.
|
|||
|
||||
[cols="100a"]
|
||||
|=======================================================================
|
||||
h|2.3.0
|
||||
|Run the shell script `sql-update-2.2.17_to_2.3.0.sh` or
|
||||
`sql-update-2.2.17_to_2.3.0-mysql.sh` (if you use MySQL).
|
||||
|
||||
This will grow the "participant states" field of calendar quick tables to a larger
|
||||
size and add the the "c_description" column to calendar quick tables.
|
||||
|
||||
h|2.2.8
|
||||
|The configuration configuration parameters were renamed:
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ Red Hat Enterprise Linux v6 x86_64
|
|||
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.
|
||||
http://www.sogo.nu/english/downloads/backend.html.
|
||||
|
||||
In order to satisfy certain dependencies, you should also add the EPEL
|
||||
source corresponding to your distribution and architecture. More
|
||||
|
@ -266,32 +266,30 @@ from this guide.
|
|||
|
||||
[NOTE]
|
||||
Samba4/OpenChange are not available for now on CentOS 5 i386/x86_64,
|
||||
CentOS 6 i386 and CentOS 7.
|
||||
and CentOS 7. On Debian-based systems, packages are available only on
|
||||
the x86_64 platform.
|
||||
|
||||
Debian 7.0 (Wheezy) and Ubuntu 12.04 (Precise Pangolin)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Debian 7 (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.html to setup your
|
||||
apt sources.
|
||||
|
||||
For Samba 4, you need to use the _wheezy-backports_ repository. To do so, create
|
||||
`/etc/apt/sources.list.d/backports.list`:
|
||||
On Debian7, for some Samba 4 dependencies, you need to use the
|
||||
_wheezy-backports_ repository. To do so, create
|
||||
`/etc/apt/sources.list.d/backports.list` with the following
|
||||
content:
|
||||
|
||||
deb http://http.debian.net/debian wheezy-backports main
|
||||
|
||||
On Ubuntu 12.04, you will also have to add the Wheezy sources:
|
||||
|
||||
deb http://ftp.us.debian.org/debian wheezy main
|
||||
deb http://security.debian.org/ wheezy/updates main
|
||||
|
||||
Then install Samba 4 on top of an existing SOGo
|
||||
installation:
|
||||
|
||||
----
|
||||
apt-get update
|
||||
apt-get -t wheezy-backports install samba samba-dev
|
||||
apt-get install samba samba-dev
|
||||
----
|
||||
|
||||
Once completed, install the packages related to OpenChange and the SOGo
|
||||
|
@ -303,7 +301,12 @@ apt-get install openchangeserver \
|
|||
openchangeproxy \
|
||||
python-ocsmanager \
|
||||
mysql-server \
|
||||
python-mysqldb
|
||||
python-mysqldb \
|
||||
openchange-ocsmanager \
|
||||
openchange-rpcproxy \
|
||||
python-sievelib \
|
||||
python-spyne \
|
||||
python-rpclib
|
||||
----
|
||||
|
||||
Once the packages are installed, refer to the _Configuration_ chapter
|
||||
|
@ -315,10 +318,8 @@ 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.
|
||||
Debian 8 (Jessie) and Ubuntu 14.04 (Trusty Tahr)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Please follow the instructions from
|
||||
http://www.sogo.nu/english/downloads/backend.html to setup your
|
||||
|
@ -341,12 +342,26 @@ apt-get install openchangeserver \
|
|||
openchangeproxy \
|
||||
python-ocsmanager \
|
||||
mysql-server \
|
||||
python-mysqldb
|
||||
python-mysqldb \
|
||||
openchange-ocsmanager \
|
||||
openchange-rpcproxy \
|
||||
python-sievelib \
|
||||
python-spyne \
|
||||
python-rpclib
|
||||
----
|
||||
|
||||
Once the packages are installed, refer to the _Configuration_ chapter
|
||||
from this guide.
|
||||
|
||||
[NOTE]
|
||||
The `ocsmanager.conf` and `rpcproxy.conf` are currently located in
|
||||
`/etc/apache2/conf.d`. These should be moved to `/etc/apache2/conf-available`.
|
||||
This is a packaging error that will soon be fixed.
|
||||
|
||||
[NOTE]
|
||||
You might have to adjust the `rpcproxy.conf` configuration file to add the
|
||||
`Require all granted` permission if you get Apache errors such as
|
||||
`client denied by server configuration`.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
@ -390,6 +405,7 @@ Add the following parameters to the `[global]` section of the
|
|||
|
||||
----
|
||||
### Configuration required by OpenChange server ###
|
||||
dsdb:schema update allowed = true
|
||||
dcerpc endpoint servers = epmapper, mapiproxy, dnsserver
|
||||
dcerpc_mapiproxy:server = true
|
||||
dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
|
||||
|
@ -407,6 +423,7 @@ Your Samba 4 configuration file should look like this:
|
|||
netbios name = sogo
|
||||
passdb backend = samba4
|
||||
### Configuration required by OpenChange server ###
|
||||
dsdb:schema update allowed = true
|
||||
dcerpc endpoint servers = +epmapper, +mapiproxy
|
||||
dcerpc_mapiproxy:server = true
|
||||
dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
|
||||
|
@ -533,7 +550,7 @@ services can be found in `/etc/httpd/conf.d/ocsmanager.conf` and
|
|||
`/etc/httpd/conf.d/rpcproxy.conf`.
|
||||
|
||||
For Debian-based distributions, these files can be found
|
||||
in `/etc/apache2/conf.d/`.
|
||||
in `/etc/apache2/conf.d/` or `/etc/apache2/conf-available`.
|
||||
|
||||
The configuration requires three Apache modules: _mod_proxy_,
|
||||
_mod_proxy_http_ and _mod_wsgi_. These are usually already installed but
|
||||
|
@ -541,13 +558,17 @@ might need to be activated on Debian-based installations:
|
|||
|
||||
a2enmod proxy proxy_http wsgi
|
||||
|
||||
The OCS Manager and RPC Proxy configuration module can be enabled using:
|
||||
|
||||
a2enconf ocsmanager
|
||||
a2enconf rpcproxy
|
||||
|
||||
On RHEL-based distributions, make sure the `LoadModule` directive is
|
||||
uncommented in `/etc/httpd/conf.d/wsgi.conf` (or
|
||||
`python26-mod_wsgi.conf` on RHELv5).
|
||||
uncommented in `/etc/httpd/conf.d/wsgi.conf`.
|
||||
|
||||
The _reqtimeout_ apache module is known to cause problems when using the
|
||||
default configuration shipped with Debian-based systems. On such
|
||||
distributions, apache will close (HTTP/1.1 500) any HTTP request for
|
||||
distributions, Apache will close (HTTP/1.1 500) any HTTP request for
|
||||
which the HTTP body hasn't arrived in 10 seconds.
|
||||
|
||||
While this is arguably good practice with regular HTTP, it will disrupt
|
||||
|
@ -567,9 +588,102 @@ 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.
|
||||
Finally, you must adjust the OCS Manager configuration file, which is
|
||||
located in `/etc/ocsmanager/ocsmanager.ini`. You should enable LDAP-based
|
||||
authentication in the `main` section and configure it accordingly. You should
|
||||
also enable rpcproxy. You file should be similar to this one:
|
||||
|
||||
----
|
||||
[DEFAULT]
|
||||
debug = true
|
||||
email_to = you@yourdomain.com
|
||||
smtp_server = localhost
|
||||
error_email_from = paste@localhost
|
||||
|
||||
[main]
|
||||
auth = ldap
|
||||
mapistore_root = /var/lib/samba/private
|
||||
mapistore_data = /var/lib/samba/private/mapistore
|
||||
debug = yes
|
||||
|
||||
[auth:file]
|
||||
|
||||
[auth:ldap]
|
||||
host = ldap://127.0.0.1
|
||||
port = 389
|
||||
bind_dn = cn=administrator,cn=Users,dc=example,dc=com
|
||||
bind_pw = %1OpenChange
|
||||
basedn = cn=Users,dc=example,dc=com
|
||||
|
||||
[auth:single]
|
||||
username = openchange
|
||||
password = {SSHA}I6Hy5Wv0wuxyXvMBFWFQDVVN12_CLaX9
|
||||
|
||||
[server:main]
|
||||
use = egg:Paste#http
|
||||
host = 127.0.0.1
|
||||
port = 5000
|
||||
protocol_version = HTTP/1.1
|
||||
|
||||
[app:main]
|
||||
use = egg:ocsmanager
|
||||
full_stack = true
|
||||
static_files = true
|
||||
cache_dir = %(here)s/data
|
||||
beaker.session.key = ocsmanager
|
||||
beaker.session.secret = SDyKK3dKyDgW0mlpqttTMGU1f
|
||||
app_instance_uuid = {ee533ebc-f266-49d1-ae10-d017ee6aa98c}
|
||||
NTLMAUTHHANDLER_WORKDIR = /var/cache/ntlmauthhandler
|
||||
SAMBA_HOST = 127.0.0.1
|
||||
|
||||
[rpcproxy:ldap]
|
||||
host = localhost
|
||||
port = 389
|
||||
basedn = CN=Users,DC=example,DC=com
|
||||
set debug = true
|
||||
----
|
||||
|
||||
----
|
||||
[autodiscover]
|
||||
|
||||
[autodiscover:rpcproxy]
|
||||
enabled = true
|
||||
|
||||
[outofoffice]
|
||||
|
||||
[outofoffice:file]
|
||||
sieve_script_path = /var/vmail/$domain/$user/sieve-script
|
||||
sieve_script_path_mkdir = false
|
||||
|
||||
[outofoffice:managesieve]
|
||||
secret = secret
|
||||
|
||||
[loggers]
|
||||
keys = root
|
||||
|
||||
[handlers]
|
||||
keys = console
|
||||
|
||||
[formatters]
|
||||
keys = generic
|
||||
|
||||
[logger_root]
|
||||
level = INFO
|
||||
handlers = console
|
||||
|
||||
[handler_console]
|
||||
class = StreamHandler
|
||||
args = (sys.stderr,)
|
||||
level = NOTSET
|
||||
formatter = generic
|
||||
|
||||
[formatter_generic]
|
||||
format = %(asctime)s %(levelname)-5.5s [%(name)s] [%(threadName)s] %(message)s
|
||||
----
|
||||
|
||||
Once completed, start the OCS Manager service:
|
||||
|
||||
/etc/init.d/openchange-ocsmanager start
|
||||
|
||||
Name Service Configuration for Web Services
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!-- TODO have the build system take care of this -->
|
||||
<releaseinfo>Version 2.2.17a - March 2015</releaseinfo>
|
||||
<subtitle>for version 2.2.17a</subtitle>
|
||||
<date>2015-03-26</date>
|
||||
<releaseinfo>Version 2.3.0 - June 2015</releaseinfo>
|
||||
<subtitle>for version 2.3.0</subtitle>
|
||||
<date>2015-06-01</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>
|
||||
|
|
BIN
Documentation/images/note.png
Normal file
BIN
Documentation/images/note.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
|
@ -13,6 +13,6 @@
|
|||
|
||||
// TODO have the build system take care of this
|
||||
|
||||
:release_version: 2.2.17a
|
||||
:release_version: 2.3.0
|
||||
|
||||
// vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab:
|
||||
|
|
105
NEWS
105
NEWS
|
@ -1,18 +1,64 @@
|
|||
master
|
||||
------
|
||||
2.3.0 (2015-06-01)
|
||||
-------------------
|
||||
|
||||
New features
|
||||
- Internet headers are now shown in Outlook (Zentyal)
|
||||
|
||||
Enhancements
|
||||
- Synchronize events, contacts and tasks in reverse chronological order
|
||||
- improved multipart handling using EAS
|
||||
- added systemd startup script (PR#76)
|
||||
- added Basque translation - thanks to Gorka Gonzalez
|
||||
- updated Brazilian (Portuguese), Dutch, Norwegian (Bokmal), Polish, Russian, and Spanish (Spain) translations
|
||||
- calendar sharing request support among different Outlook versions (Zentyal)
|
||||
- improved sync speed from Outlook by non-reprocessing already downloaded unread mails (Zentyal)
|
||||
- added support for sharing calendar invitations
|
||||
- missing contact fields are now saved and available when sharing it (Office, Profession, Manager's name, Assistant's name, Spouse/Partner, Anniversary) (Zentyal)
|
||||
- appointment color and importance work now between Outlooks (Zentyal)
|
||||
- synchronize events, contacts and tasks in reverse chronological order (Zentyal)
|
||||
- during login, we now extract the domain from the user to accelerate authentication requests on sources
|
||||
- make sure sure email invitations can always be read by EAS clients
|
||||
- now able to print event/task's description (new components only) in the list view (#2881)
|
||||
- now possible to log EAS commands using the SOGoEASDebugEnabled system defaults
|
||||
- many improvements to EAS SmartReply/SmartForward commands
|
||||
- event invitation response mails from Outlook are now sent
|
||||
- mail subfolders created in WebMail are created when Outlook synchronises
|
||||
- mail root folder created in WebMail (same level INBOX) are created on Outlook logon
|
||||
|
||||
Bug fixes
|
||||
- Outlook clients can use reply all functionality on multidomain environment
|
||||
- Optional attendes on events are now shown properly
|
||||
|
||||
2.2.17a-zentyal1 (2015-04-15)
|
||||
--------------------
|
||||
|
||||
Bug fixes
|
||||
- Do not share Outlook metadata between users with the same name and different domain
|
||||
- now keep the BodyPreference for future EAS use and default to MIME if none set (#3146)
|
||||
- EAS reply fix when message/rfc822 parts are included in the original mail (#3153)
|
||||
- fixed yet an other potential crash during freebusy lookups during timezone changes
|
||||
- fixed display of freebusy information in event attendees editor during timezone changes
|
||||
- fixed timezone of MSExchange freebusy information
|
||||
- fixed a potential EAS error with multiple email priority flags
|
||||
- fixed paragraphs margins in HTML messages (#3163)
|
||||
- fixed regression when loading the inbox for the first time
|
||||
- fixed serialization of the PreventInvitationsWhitelist settings
|
||||
- fixed md4 support (for NTLM password changes) with GNU TLS
|
||||
- fixed edition of attachment URL in event/task editor
|
||||
- sent mails are not longer in Drafts folder using Outlook (Zentyal)
|
||||
- deleted mails are properly synced between Outlook profiles from the same account (Zentyal)
|
||||
- does not create a mail folder in other user's mailbox (Zentyal)
|
||||
- fix server-side crash with invalid events (Zentyal)
|
||||
- fix setting permissions for a folder with several users (Zentyal)
|
||||
- fix reception of calendar event invitations on optional attendees (Zentyal)
|
||||
- fix server side crash parsing rtf without color table (Zentyal)
|
||||
- weekly recurring events created in SOGo web interface are now shown in Outlook (Zentyal)
|
||||
- fix exception modifications import in recurrence series (Zentyal)
|
||||
- fix server side crash parsing rtf emails with images (with word97 format) (Zentyal)
|
||||
- fix sender on importing email messages like event invitations (Zentyal)
|
||||
- fix Outlook crashes when modifying the view of a folder (Zentyal)
|
||||
- fix server side crash when reading some recurrence appointments (Zentyal)
|
||||
- Outlook clients can use reply all functionality on multidomain environment (Zentyal)
|
||||
- optional attendes on events are now shown properly (Zentyal)
|
||||
- fixed the EAS maximum response size being per-folder, and not global
|
||||
- now set MeetingMessageType only for EAS 14.1
|
||||
- now correctly handle external invitations using EAS
|
||||
- now correctly handle multiple email addresses in the GAL over EAS (#3102)
|
||||
- now handle very large amount of participants correctly (#3175)
|
||||
- fix message bodies not shown on some EAS devices (#3173)
|
||||
- avoid appending the domain unconditionally when SOGoEnableDomainBasedUID is set to YES
|
||||
- recurrent all day events are now shown properly in Outlook
|
||||
|
||||
2.2.17a (2015-03-15)
|
||||
--------------------
|
||||
|
@ -51,6 +97,7 @@ Bug fixes
|
|||
- prevent potential freebusy lookup crashes during timezone changes with repetitive events
|
||||
- improved GetItemEstimate to count all vasnished/deleted mails too
|
||||
- improvements to EAS SyncKey handling to avoid missing mails (#3048, #3058)
|
||||
- fixed EAS replies decoding from Outlook (#3123)
|
||||
|
||||
2.2.16 (2015-02-12)
|
||||
-------------------
|
||||
|
@ -73,42 +120,6 @@ Bug fixes
|
|||
- fixed plain/text mails showing on one line on Android/EAS (#3055)
|
||||
- fixed exception in sogo-tool when parsing arguments of a set operation
|
||||
|
||||
2.2.15-zentyal3 (2015-04-14)
|
||||
------
|
||||
|
||||
New features
|
||||
- Internet headers are now shown in Outlook
|
||||
|
||||
Enhancements
|
||||
- Sharing request among different Outlook versions
|
||||
- Improve sync speed from Outlook by non-reprocessing already downloaded unread mails
|
||||
|
||||
Bug fixes
|
||||
- Sent mails are not longer in Drafts folder using Outlook
|
||||
- Deleted mails are properly synced between Outlook profiles from the same account
|
||||
- Does not create a mail folder in other user's mailbox
|
||||
- Fix server-side crash with invalid events
|
||||
- Fix setting permissions for a folder with several users
|
||||
- Fix reception of calendar event invitations on optional attendees
|
||||
- Fix server side crash parsing rtf without color table
|
||||
- Weekly recurring events created in SOGo web interface are now shown in Outlook
|
||||
- Fix exception modifications import in recurrence series
|
||||
- Fix server side crash parsing rtf emails with images (with word97 format)
|
||||
|
||||
2.2.15-zentyal2 (2015-03-16)
|
||||
----------------------------
|
||||
|
||||
Enhancements
|
||||
- Give support to calendar sharing invitations
|
||||
- Missing contact fields are now saved and available when sharing it
|
||||
(Office, Profession, Manager's name, Assistant's name, Spouse/Partner, Anniversary)
|
||||
- Appointment color and importance work now between Outlooks
|
||||
|
||||
Bug fixes
|
||||
- Fix sender on importing email messages like event invitations
|
||||
- Fix Outlook crashes when modifying the view of a folder
|
||||
- Fix server side crash when reading some recurrence appointments
|
||||
|
||||
2.2.15 (2015-01-30)
|
||||
-------------------
|
||||
|
||||
|
|
|
@ -125,9 +125,7 @@ $(SOGOBACKEND)_OBJC_FILES += \
|
|||
\
|
||||
RTFHandler.m \
|
||||
\
|
||||
Codepages.m \
|
||||
\
|
||||
NGImap4Connection+Monkeypatching.m
|
||||
Codepages.m
|
||||
|
||||
|
||||
$(SOGOBACKEND)_RESOURCE_FILES += \
|
||||
|
@ -178,7 +176,7 @@ $(SOGOBACKEND)_LIB_DIRS += \
|
|||
$(LIBMAPISTORE_LIBS)
|
||||
|
||||
ADDITIONAL_INCLUDE_DIRS += \
|
||||
-Werror -Wall \
|
||||
-Wall \
|
||||
-DSAMBA_PRIVATE_DIR=@"\"$(SAMBA_PRIVATE_DIR)\"" \
|
||||
$(LIBMAPI_CFLAGS) \
|
||||
$(LIBMAPISTORE_CFLAGS) \
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/* NGImap4Connection+Monkeypatching.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2014 Jesús García Sáez
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __OpenChange_NGImap4Connection_Monkeypatching_H__
|
||||
#define __OpenChange_NGImap4Connection_Monkeypatching_H__
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <NGImap4/NGImap4Client.h>
|
||||
#import <NGImap4/NGImap4Connection.h>
|
||||
#import <NGExtensions/NGHashMap.h>
|
||||
|
||||
|
||||
@interface NGImap4Connection (Monkeypatching)
|
||||
|
||||
- (NSArray *) fetchUIDs: (NSArray *) _uids
|
||||
inURL: (NSURL *) _url
|
||||
parts: (NSArray *) _parts;
|
||||
|
||||
- (void) _mergeDict: (NSDictionary *) source
|
||||
into: (NSMutableDictionary *) target;
|
||||
|
||||
- (void) _mergeNGHashMap: (NGMutableHashMap *) source
|
||||
into: (NGMutableHashMap *) target;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#endif // __OpenChange_NGImap4Connection_Monkeypatching_H__
|
|
@ -1,153 +0,0 @@
|
|||
/* NGImap4Connection+Monkeypatching.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2014 Jesús García Sáez
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "NGImap4Connection+Monkeypatching.h"
|
||||
|
||||
#import <Foundation/NSValue.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
|
||||
@implementation NGImap4Connection (Monkeypatching)
|
||||
|
||||
- (NSArray *) fetchUIDs: (NSArray *) _uids
|
||||
inURL: (NSURL *) _url
|
||||
parts: (NSArray *) _parts
|
||||
{
|
||||
// currently returns a dict?!
|
||||
/*
|
||||
Allowed fetch keys:
|
||||
UID
|
||||
BODY.PEEK[<section>]<<partial>>
|
||||
BODY [this is the bodystructure, supported]
|
||||
BODYSTRUCTURE [not supported yet!]
|
||||
ENVELOPE [this is a parsed header, but does not include type]
|
||||
FLAGS
|
||||
INTERNALDATE
|
||||
RFC822
|
||||
RFC822.HEADER
|
||||
RFC822.SIZE
|
||||
RFC822.TEXT
|
||||
*/
|
||||
NSMutableDictionary *result = nil;
|
||||
NSUInteger i, total, step = 1000;
|
||||
|
||||
if (_uids == nil || [_uids count] == 0)
|
||||
return nil;
|
||||
|
||||
/* select folder */
|
||||
|
||||
if (![self selectFolder:_url])
|
||||
return nil;
|
||||
|
||||
/* fetch parts */
|
||||
|
||||
total = [_uids count];
|
||||
for (i = 0; i < total; i += step) {
|
||||
NSRange range;
|
||||
NSArray *partial_uids;
|
||||
NSDictionary *partial_result;
|
||||
|
||||
range = NSMakeRange(i, (i + step) > total ? (total - i) : step);
|
||||
partial_uids = [_uids subarrayWithRange: range];
|
||||
|
||||
/* We will only fetch "step" uids each time */
|
||||
partial_result = [[self client] fetchUids:partial_uids parts:_parts];
|
||||
|
||||
if (![[partial_result valueForKey:@"result"] boolValue]) {
|
||||
[self errorWithFormat: @"Error fetching %u uids for url: %@",
|
||||
total, _url];
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (result == nil) {
|
||||
/* First iteration, first result */
|
||||
result = [[partial_result mutableCopy] autorelease];
|
||||
} else {
|
||||
/* Merge partial_result into previous result */
|
||||
[self _mergeDict: partial_result into: result];
|
||||
}
|
||||
}
|
||||
|
||||
return (id)result;
|
||||
}
|
||||
|
||||
- (void) _mergeDict: (NSDictionary *) source
|
||||
into: (NSMutableDictionary *) target
|
||||
{
|
||||
for (id key in [source keyEnumerator]) {
|
||||
id obj, current_obj;
|
||||
|
||||
current_obj = [target objectForKey: key];
|
||||
if (current_obj == nil) {
|
||||
/* This should never happen but just in case... */
|
||||
[self errorWithFormat: @"Error merging fetchUids results: "
|
||||
@"nonexistent key %@ on current target", key];
|
||||
continue;
|
||||
}
|
||||
|
||||
obj = [source objectForKey: key];
|
||||
if ([obj isKindOfClass: [NSArray class]]) {
|
||||
NSArray *data, *current_data, *new_data;
|
||||
data = obj;
|
||||
current_data = current_obj;
|
||||
new_data = [current_data arrayByAddingObjectsFromArray: data];
|
||||
[target setObject: new_data forKey: key];
|
||||
} else if ([obj isKindOfClass: [NGMutableHashMap class]]) {
|
||||
[self _mergeNGHashMap: obj into: current_obj];
|
||||
} else if ([obj isKindOfClass: [NSNumber class]]) {
|
||||
if (obj != current_obj) {
|
||||
[self errorWithFormat: @"Error merging fetchUids results: "
|
||||
@"incorrect value for key %@: %@ != %@",
|
||||
key, obj, current_obj];
|
||||
}
|
||||
} else {
|
||||
[self errorWithFormat: @"Error merging fetchUids results: "
|
||||
@"ignored %@ (%@) key", key, [key class]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _mergeNGHashMap: (NGMutableHashMap *) source
|
||||
into: (NGMutableHashMap *) target
|
||||
{
|
||||
for (id key in [source keyEnumerator]) {
|
||||
NSArray *obj, *current_obj;
|
||||
|
||||
current_obj = [target objectsForKey: key];
|
||||
if (current_obj == nil) {
|
||||
/* This should never happen but just in case... */
|
||||
[self errorWithFormat: @"Error merging fetchUids results: "
|
||||
@"nonexistent key %@ on current target", key];
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([current_obj count] == 1) {
|
||||
/* Merge only results, that means fields with more than 1 object */
|
||||
continue;
|
||||
}
|
||||
|
||||
obj = [source objectsForKey: key];
|
||||
[target addObjects: obj forKey: key];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
|
@ -885,16 +885,16 @@ const unsigned short ansicpg874[256] = {
|
|||
char *v = NULL;
|
||||
if (fontInfo && fontInfo->name)
|
||||
{
|
||||
if (fontInfo->name.length < 128)
|
||||
if ([fontInfo->name length] < 128)
|
||||
{
|
||||
int tag_size = 15 + fontInfo->name.length;
|
||||
int tag_size = 15 + [fontInfo->name length];
|
||||
v = calloc(tag_size, sizeof(char));
|
||||
snprintf(v, tag_size, "<font face=\"%s\">", [fontInfo->name UTF8String]);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"RTFHandler: Font %u has %d chars length, parse error? "
|
||||
"Ignored", font_index, fontInfo->name.length);
|
||||
"Ignored", font_index, [fontInfo->name length]);
|
||||
v = calloc(7, sizeof(char));
|
||||
sprintf(v, "<font>");
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
},
|
||||
{
|
||||
columnName = c_partstates;
|
||||
sqlType = "VARCHAR2(255)";
|
||||
sqlType = "CLOB";
|
||||
allowsNull = YES;
|
||||
},
|
||||
{
|
||||
|
@ -154,5 +154,10 @@
|
|||
sqlType = "INTEGER";
|
||||
allowsNull = YES;
|
||||
},
|
||||
{
|
||||
columnName = c_description;
|
||||
sqlType = "CLOB";
|
||||
allowsNull = YES;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
},
|
||||
{
|
||||
columnName = c_partstates;
|
||||
sqlType = "VARCHAR(255)";
|
||||
sqlType = "TEXT";
|
||||
allowsNull = YES;
|
||||
},
|
||||
{
|
||||
|
@ -153,6 +153,11 @@
|
|||
columnName = c_nextalarm;
|
||||
sqlType = "INT";
|
||||
allowsNull = YES;
|
||||
},
|
||||
{
|
||||
columnName = c_description;
|
||||
sqlType = "TEXT";
|
||||
allowsNull = YES;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1075,6 +1075,12 @@ static NSCharacterSet *whitespaceCharSet = nil;
|
|||
// FIXME: Data is not always utf-8.....
|
||||
source = [[[NSString alloc] initWithData: _data encoding: encoding]
|
||||
autorelease];
|
||||
|
||||
// We fallback to ISO-8859-1 string encoding
|
||||
if (!source)
|
||||
source = [[[NSString alloc] initWithData: _data encoding: NSISOLatin1StringEncoding]
|
||||
autorelease];
|
||||
|
||||
if (!source)
|
||||
{
|
||||
e = (id)[SaxParseException exceptionWithName: @"SaxIOException"
|
||||
|
|
14
Scripts/sogo-systemd-redhat
Normal file
14
Scripts/sogo-systemd-redhat
Normal file
|
@ -0,0 +1,14 @@
|
|||
[Unit]
|
||||
Description=SOGo is a groupware server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Environment="PREFORK=3"
|
||||
EnvironmentFile=-/etc/sysconfig/sogo
|
||||
Type=forking
|
||||
ExecStart=/usr/sbin/sogod -WOWorkersCount ${PREFORK} -WOPidFile /var/run/sogo/sogo.pid -WOLogFile /var/log/sogo/sogo.log
|
||||
PIDFile=/var/run/sogo/sogo.pid
|
||||
User=sogo
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
59
Scripts/sql-update-2.1.17_to_2.3.0-mysql.sh
Executable file
59
Scripts/sql-update-2.1.17_to_2.3.0-mysql.sh
Executable file
|
@ -0,0 +1,59 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# This script only works with MySQL
|
||||
# updates c_partstates to mediumtext
|
||||
# adds c_description to Calendar quick tables
|
||||
# http://www.sogo.nu/bugs/view.php?id=3175
|
||||
# the field length was actually changed in v2.2.18
|
||||
|
||||
defaultusername=$USER
|
||||
defaulthostname=127.0.0.1
|
||||
defaultdatabase=$USER
|
||||
indextable=$(sogo-tool dump-defaults -f /etc/sogo/sogo.conf | awk -F\" '/ OCSFolderInfoURL =/ {print $2}' | awk -F/ '{print $NF}')
|
||||
if [ -z "$indextable" ]; then
|
||||
echo "Couldn't fetch OCSFolderInfoURL value, aborting" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -p "Username ($defaultusername): " username
|
||||
read -p "Hostname ($defaulthostname): " hostname
|
||||
read -p "Database ($defaultdatabase): " database
|
||||
|
||||
if [ -z "$username" ]
|
||||
then
|
||||
username=$defaultusername
|
||||
fi
|
||||
|
||||
if [ -z "$hostname" ]
|
||||
then
|
||||
hostname=$defaulthostname
|
||||
fi
|
||||
|
||||
if [ -z "$database" ]
|
||||
then
|
||||
database=$defaultdatabase
|
||||
fi
|
||||
|
||||
sqlscript=""
|
||||
|
||||
function adjustSchema() {
|
||||
oldIFS="$IFS"
|
||||
IFS=" "
|
||||
part1="`echo -e \"ALTER TABLE $table MODIFY c_partstates mediumtext;\\n\"`";
|
||||
part2="`echo -e \"ALTER TABLE $table ADD COLUMN c_description mediumtext;\\n\"`";
|
||||
sqlscript="$sqlscript$part1$part2"
|
||||
IFS="$oldIFS"
|
||||
}
|
||||
|
||||
echo "This script will ask for the sql password twice" >&2
|
||||
echo "Converting c_partstates from VARCHAR(255) to mediumtext in calendar quick tables" >&2
|
||||
tables=`mysql -p -s -u $username -h $hostname $database -e "select SUBSTRING_INDEX(c_quick_location, '/', -1) from $indextable where c_path3 = 'Calendar';"`
|
||||
|
||||
for table in $tables;
|
||||
do
|
||||
adjustSchema
|
||||
done
|
||||
|
||||
echo "$sqlscript" | mysql -p -s -u $username -h $hostname $database
|
56
Scripts/sql-update-2.1.17_to_2.3.0.sh
Executable file
56
Scripts/sql-update-2.1.17_to_2.3.0.sh
Executable file
|
@ -0,0 +1,56 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
# This script only works with PostgreSQL
|
||||
# updates c_partstates to text
|
||||
# adds c_description to Calendar quick tables
|
||||
# http://www.sogo.nu/bugs/view.php?id=3175
|
||||
# the field length was actually changed in v2.2.18
|
||||
|
||||
defaultusername=$USER
|
||||
defaulthostname=localhost
|
||||
defaultdatabase=$USER
|
||||
#indextable=sogo_folder_info
|
||||
indextable=$(sogo-tool dump-defaults -f /etc/sogo/sogo.conf | awk -F\" '/ OCSFolderInfoURL =/ {print $2}' | awk -F/ '{print $NF}')
|
||||
if [ -z "$indextable" ]; then
|
||||
echo "Couldn't fetch OCSFolderInfoURL value, aborting" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -p "Username ($defaultusername): " username
|
||||
read -p "Hostname ($defaulthostname): " hostname
|
||||
read -p "Database ($defaultdatabase): " database
|
||||
|
||||
if [ -z "$username" ]
|
||||
then
|
||||
username=$defaultusername
|
||||
fi
|
||||
if [ -z "$hostname" ]
|
||||
then
|
||||
hostname=$defaulthostname
|
||||
fi
|
||||
if [ -z "$database" ]
|
||||
then
|
||||
database=$defaultdatabase
|
||||
fi
|
||||
|
||||
sqlscript=""
|
||||
|
||||
function adjustSchema() {
|
||||
oldIFS="$IFS"
|
||||
IFS=" "
|
||||
part1="`echo -e \"ALTER TABLE $table ALTER COLUMN c_partstates TYPE TEXT;\\n\"`";
|
||||
part2="`echo -e \"ALTER TABLE $table ADD COLUMN c_description TEXT;\\n\"`";
|
||||
sqlscript="$sqlscript$part1$part2"
|
||||
IFS="$oldIFS"
|
||||
}
|
||||
|
||||
echo "Converting c_cycleinfo from VARCHAR(255) to TEXT in calendar quick tables" >&2
|
||||
tables=`psql -t -U $username -h $hostname $database -c "select split_part(c_quick_location, '/', 5) from $indextable where c_path3 = 'Calendar';"`
|
||||
|
||||
for table in $tables;
|
||||
do
|
||||
adjustSchema
|
||||
done
|
||||
|
||||
echo "$sqlscript" | psql -q -e -U $username -h $hostname $database
|
67
SoObjects/Appointments/Basque.lproj/Localizable.strings
Normal file
67
SoObjects/Appointments/Basque.lproj/Localizable.strings
Normal file
|
@ -0,0 +1,67 @@
|
|||
"Inviting the following persons is prohibited:" = "Ondorengo pertsonak gonbidatzea debekatuta dago:";
|
||||
"Personal Calendar" = "Egutegi pertsonala";
|
||||
vevent_class0 = "(Ekitaldi publikoa)";
|
||||
vevent_class1 = "(Ekitaldi pribatua)";
|
||||
vevent_class2 = "(Isilpeko ekitaldia)";
|
||||
|
||||
vtodo_class0 = "(Zeregin publikoa)";
|
||||
vtodo_class1 = "(Zeregin pribatua)";
|
||||
vtodo_class2 = "(Isilpeko egitekoa)";
|
||||
|
||||
/* Receipts */
|
||||
"The event \"%{Summary}\" was created" = "\"%{Summary}\" ekitaldia sortu da";
|
||||
"The event \"%{Summary}\" was deleted" = "\"%{Summary}\" ekitaldia ezabatu da";
|
||||
"The event \"%{Summary}\" was updated" = "\"%{Summary}\" ekitaldia eguneratu da";
|
||||
"The following attendees(s) were notified:" = "Ondorengo partaidea(k) jakinarazi d(ir)a:";
|
||||
"The following attendees(s) were added:" = "Ondorengo partaidea(k) gehitu d(ir)a:";
|
||||
"The following attendees(s) were removed:" = "Ondorengo partaidea(k) ezabatu d(ir)a:";
|
||||
|
||||
/* IMIP messages */
|
||||
"calendar_label" = "Egutegia";
|
||||
"startDate_label" = "Hasi:";
|
||||
"endDate_label" = "Amaitu:";
|
||||
"due_label" = "Epemuga:";
|
||||
"location_label" = "Kokapena:";
|
||||
"summary_label" = "Laburpena:";
|
||||
"comment_label" = "Iruzkina:";
|
||||
|
||||
/* Invitation */
|
||||
"Event Invitation: \"%{Summary}\"" = "Ekitaldirako gonbidapena: \"%{Summary}\"";
|
||||
"(sent by %{SentBy}) " = "(%{SentBy}-k bidalia) ";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}-k gonbidatu zaitu %{Summary}.-ra\n\nHasiera: %{StartDate}\nAmaiera: %{EndDate}\nDeskribapena: %{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}-k gonbidatu zaitu %{Summary}-ra \n\nHasiera: %{StartDate}-an, %{StartTime}-tan\nEnd: %{EndDate}-an, %{EndTime}-tan\nDeskribapena: %{Description}";
|
||||
|
||||
/* Deletion */
|
||||
"Event Cancelled: \"%{Summary}\"" = "Ekitaldia bertan behera utzi da: \"%{Summary}\"";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText} ekitaldi hau bertan behera utzi du: %{Summary}.\n\nHasiera: %{StartDate}\nAmaiera: %{EndDate}\nDEskribapena: %{Description}";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText}-k honako ekitaldia bertan behera utzi du: %{Summary}.\n\nHasiera: %{StartDate}-an, %{StartTime}-tan\nAmaiera: %{EndDate}-an %{EndTime}-tan\nDeskribapena: %{Description}";
|
||||
|
||||
/* Update */
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
|
||||
= "%{OldStartDate} eguneko \"%{Summary}\" hitzordua aldatu da";
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
|
||||
= "%{OldStartDate} eguneko eta %{OldStartTime} orduko \"%{Summary}\" hitzordua aldatu da";
|
||||
"The following parameters have changed in the \"%{Summary}\" meeting:"
|
||||
= " \"%{Summary}\" bilerako ondorengo parametroak aldatu dira:";
|
||||
"Please accept or decline those changes."
|
||||
= "Mesedez, onartu edo ezetsi ondorengo aldaketak.";
|
||||
|
||||
/* Reply */
|
||||
"Accepted invitation: \"%{Summary}\"" = "Gonbidapena onartua: \"%{Summary}\"";
|
||||
"Declined invitation: \"%{Summary}\"" = "Ezetzitako gonbidapena: \"%{Summary}\"";
|
||||
"Delegated invitation: \"%{Summary}\"" = "Delegatutako gonbidapena: \"%{Summary}\"";
|
||||
"Not yet decided on invitation: \"%{Summary}\"" = "\"%{Summary}\" gonbidapenari buruz erabaki gabe";
|
||||
"%{Attendee} %{SentByText}has accepted your event invitation."
|
||||
= "%{Attendee} %{SentByText} -k zure gonbidapena onartu du.";
|
||||
"%{Attendee} %{SentByText}has declined your event invitation."
|
||||
= "%{Attendee} %{SentByText}-k zure gonbidapenari uko egin dio.";
|
||||
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
|
||||
= "%{Attendee} %{SentByText}-k zure gonbidapena %{Delegate}-ri delegatu dio.";
|
||||
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
|
||||
= "%{Attendee} %{SentByText}-k ez du oraindik zure gonbidapenari buruz erabakirik hartu.";
|
||||
|
||||
/* Resources */
|
||||
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Ezin da honako baliabidea atzitu: \"%{Cn} %{SystemEmail}\"";
|
||||
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "\"%{Cn} %{SystemEmail}\" baliabidearentzako gehienezko erreserba kopurura (%{NumberOfSimultaneousBookings}) iritsi gara. Gatazka sortu duen ekitaldia \"%{EventTitle}\" da, eta %{StartDate}-n hasten da.";
|
|
@ -56,7 +56,7 @@ vtodo_class2 = "(Tarefa Confidencial)";
|
|||
"%{Attendee} %{SentByText}has accepted your event invitation."
|
||||
= "%{Attendee} %{SentByText}foi aceitado seu convite ao evento.";
|
||||
"%{Attendee} %{SentByText}has declined your event invitation."
|
||||
= "%{Attendee} %{SentByText}foi declinado seu convite ao evento.";
|
||||
= "%{Attendee} %{SentByText}recusou seu convite para o evento.";
|
||||
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
|
||||
= "%{Attendee} %{SentByText} delegou o convite para %{Delegate}.";
|
||||
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
|
||||
|
|
|
@ -54,7 +54,7 @@ Appointments_RESOURCE_FILES += \
|
|||
MSExchangeFreeBusySOAPResponseMap.plist \
|
||||
MSExchangeFreeBusySOAPRequest.wo
|
||||
|
||||
Appointments_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
Appointments_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
Appointments_LOCALIZED_RESOURCE_FILES = Localizable.strings
|
||||
|
||||
|
|
|
@ -70,11 +70,27 @@
|
|||
to: (NSCalendarDate *) newEndDate
|
||||
{
|
||||
ASSIGN(address, newAddress);
|
||||
ASSIGN(startDate, newStartDate);
|
||||
ASSIGN(endDate, newEndDate);
|
||||
|
||||
startDate = [NSCalendarDate dateWithYear: [newStartDate yearOfCommonEra]
|
||||
month: [newStartDate monthOfYear]
|
||||
day: [newStartDate dayOfMonth]
|
||||
hour: [newStartDate hourOfDay]
|
||||
minute: [newStartDate minuteOfHour]
|
||||
second: [newStartDate secondOfMinute]
|
||||
timeZone: [newStartDate timeZone]];
|
||||
endDate = [NSCalendarDate dateWithYear: [newEndDate yearOfCommonEra]
|
||||
month: [newEndDate monthOfYear]
|
||||
day: [newEndDate dayOfMonth]
|
||||
hour: [newEndDate hourOfDay]
|
||||
minute: [newEndDate minuteOfHour]
|
||||
second: [newEndDate secondOfMinute]
|
||||
timeZone: [newEndDate timeZone]];
|
||||
|
||||
[startDate setTimeZone: timeZone];
|
||||
[endDate setTimeZone: timeZone];
|
||||
|
||||
[startDate retain];
|
||||
[endDate retain];
|
||||
}
|
||||
|
||||
- (NSString *) serverVersion
|
||||
|
|
|
@ -502,12 +502,12 @@ static Class iCalEventK = nil;
|
|||
BOOL is_owner;
|
||||
|
||||
userLogin = [[context activeUser] login];
|
||||
is_owner = [userLogin isEqualToString: [self ownerInContext: context]];
|
||||
is_owner = [userLogin isEqualToString: self->owner];
|
||||
|
||||
// Check if the owner (not the active user) has excluded the calendar from her/his free busy data.
|
||||
excludeFromFreeBusy
|
||||
= [self folderPropertyValueInCategory: @"FreeBusyExclusions"
|
||||
forUser: [SOGoUser userWithLogin: userLogin]];
|
||||
forUser: [context activeUser]];
|
||||
|
||||
if ([self isSubscription])
|
||||
{
|
||||
|
@ -800,7 +800,7 @@ static Class iCalEventK = nil;
|
|||
|
||||
/**
|
||||
* Set the timezone of the event start and end dates to the user's timezone.
|
||||
* @param theRecord a dictionnary with the attributes of the event.
|
||||
* @param theRecord a dictionary with the attributes of the event.
|
||||
* @return a copy of theRecord with adjusted dates.
|
||||
*/
|
||||
- (NSMutableDictionary *) _fixupRecord: (NSDictionary *) theRecord
|
||||
|
@ -2814,7 +2814,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
|||
@"c_category", @"c_classification", @"c_isallday",
|
||||
@"c_isopaque", @"c_participants", @"c_partmails",
|
||||
@"c_partstates", @"c_sequence", @"c_priority",
|
||||
@"c_cycleinfo", @"c_iscycle", @"c_nextalarm", nil];
|
||||
@"c_cycleinfo", @"c_iscycle", @"c_nextalarm", @"c_description", nil];
|
||||
|
||||
return [self fetchFields: infos from: _startDate to: _endDate title: title
|
||||
component: _component
|
||||
|
|
|
@ -421,11 +421,14 @@
|
|||
SOGoUserSettings *us;
|
||||
NSMutableArray *unavailableAttendees;
|
||||
NSEnumerator *enumerator;
|
||||
NSString *currentUID, *ownerUID, *whiteListString;
|
||||
NSString *currentUID, *ownerUID;
|
||||
NSMutableString *reason;
|
||||
NSDictionary *values;
|
||||
NSMutableDictionary *value, *moduleSettings, *whiteList;
|
||||
NSMutableDictionary *value, *moduleSettings;
|
||||
id whiteList;
|
||||
|
||||
int i, count;
|
||||
|
||||
i = count = 0;
|
||||
|
||||
// Build list of the attendees uids without ressources
|
||||
|
@ -447,8 +450,11 @@
|
|||
if (![user isResource] && [[moduleSettings objectForKey:@"PreventInvitations"] boolValue])
|
||||
{
|
||||
// Check if the user have a whiteList
|
||||
whiteListString = [moduleSettings objectForKey:@"PreventInvitationsWhitelist"];
|
||||
whiteList = [whiteListString objectFromJSONString];
|
||||
whiteList = [moduleSettings objectForKey:@"PreventInvitationsWhitelist"];
|
||||
|
||||
// For backward <= 2.2.17 compatibility
|
||||
if ([whiteList isKindOfClass: [NSString class]])
|
||||
whiteList = [whiteList objectFromJSONString];
|
||||
|
||||
// If the filter have a hit, do not add the currentUID to the unavailableAttendees array
|
||||
if (![whiteList objectForKey:ownerUID])
|
||||
|
|
|
@ -248,6 +248,12 @@
|
|||
else
|
||||
[row setObject: [NSNull null] forKey: @"c_category"];
|
||||
|
||||
/* handle description */
|
||||
if ([self comment])
|
||||
[row setObject: [self comment] forKey: @"c_description"];
|
||||
else
|
||||
[row setObject: [NSNull null] forKey: @"c_description"];
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
|
|
|
@ -177,6 +177,12 @@
|
|||
[row setObject: [categories componentsJoinedByString: @","]
|
||||
forKey: @"c_category"];
|
||||
|
||||
/* handle description */
|
||||
if ([self comment])
|
||||
[row setObject: [self comment] forKey: @"c_description"];
|
||||
else
|
||||
[row setObject: [NSNull null] forKey: @"c_description"];
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
|
|
2
SoObjects/Contacts/Basque.lproj/Localizable.strings
Normal file
2
SoObjects/Contacts/Basque.lproj/Localizable.strings
Normal file
|
@ -0,0 +1,2 @@
|
|||
"Personal Address Book" = "Helbide liburu pertsonala";
|
||||
"Collected Address Book" = "Bildutako helbide liburua";
|
|
@ -1,2 +1,2 @@
|
|||
"Personal Address Book" = "Livro de Endereços Pessoais";
|
||||
"Personal Address Book" = "Livro de Endereço Pessoal";
|
||||
"Collected Address Book" = "Catálogos Coletados";
|
||||
|
|
|
@ -27,7 +27,7 @@ Contacts_OBJC_FILES = \
|
|||
Contacts_RESOURCE_FILES += \
|
||||
product.plist \
|
||||
|
||||
Contacts_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
Contacts_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
Contacts_LOCALIZED_RESOURCE_FILES = Localizable.strings
|
||||
|
||||
|
|
2
SoObjects/Mailer/Basque.lproj/Localizable.strings
Normal file
2
SoObjects/Mailer/Basque.lproj/Localizable.strings
Normal file
|
@ -0,0 +1,2 @@
|
|||
"OtherUsersFolderName" = "Beste erabiltzaileak";
|
||||
"SharedFoldersName" = "Partekatutako karpetak";
|
|
@ -92,7 +92,7 @@ Mailer_RESOURCE_FILES += \
|
|||
SOGoMailWelshReply.wo
|
||||
|
||||
|
||||
Mailer_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
Mailer_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
Mailer_LOCALIZED_RESOURCE_FILES = Localizable.strings
|
||||
|
||||
|
|
16
SoObjects/Mailer/SOGoMailBasqueForward.wo/SOGoMailBasqueForward.html
Executable file
16
SoObjects/Mailer/SOGoMailBasqueForward.wo/SOGoMailBasqueForward.html
Executable file
|
@ -0,0 +1,16 @@
|
|||
<#newLine/>
|
||||
<#newLine/>
|
||||
<#signaturePlacementOnTop><#newLine/>
|
||||
<#signature/><#newLine/></#signaturePlacementOnTop>
|
||||
-------- Original Message --------<#newLine/>
|
||||
Gaia: <#subject/><#newLine/>
|
||||
Data: <#date/><#newLine/>
|
||||
Nork: <#from/><#newLine/>
|
||||
<#hasReplyTo>Erantzun-honi: <#replyTo/></#hasReplyTo><#hasOrganization>Erakundea: <#organization/></#hasOrganization>Nori: <#to/><#newLine/>
|
||||
<#hasCc>Kopia: <#cc/></#hasCc><#hasNewsGroups>Berri-taldeak: <#newsgroups/></#hasNewsGroups><#hasReferences>Erreferentziak: <#references/></#hasReferences><#newLine/>
|
||||
<#newLine/>
|
||||
<#messageBody/><#newLine/>
|
||||
<#signaturePlacementOnBottom><#newLine/>
|
||||
<#newLine/>
|
||||
<#signature/></#signaturePlacementOnBottom>
|
||||
<#newLine/>
|
97
SoObjects/Mailer/SOGoMailBasqueForward.wo/SOGoMailBasqueForward.wod
Executable file
97
SoObjects/Mailer/SOGoMailBasqueForward.wo/SOGoMailBasqueForward.wod
Executable file
|
@ -0,0 +1,97 @@
|
|||
subject: WOString {
|
||||
value = subject;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
date: WOString {
|
||||
value = date;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
from: WOString {
|
||||
value = from;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
newLine: WOString {
|
||||
value = newLine;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasReplyTo: WOConditional {
|
||||
condition = hasReplyTo;
|
||||
}
|
||||
|
||||
replyTo: WOString {
|
||||
value = replyTo;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasOrganization: WOConditional {
|
||||
condition = hasOrganization;
|
||||
}
|
||||
|
||||
organization: WOString {
|
||||
value = organization;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
to: WOString {
|
||||
value = to;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasCc: WOConditional {
|
||||
condition = hasCc;
|
||||
}
|
||||
|
||||
cc: WOString {
|
||||
value = cc;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasNewsGroups: WOConditional {
|
||||
condition = hasNewsGroups;
|
||||
}
|
||||
|
||||
newsgroups: WOString {
|
||||
value = newsgroups;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasReferences: WOConditional {
|
||||
condition = hasReferences;
|
||||
}
|
||||
|
||||
references: WOString {
|
||||
value = references;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
messageBody: WOString {
|
||||
value = messageBody;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
signature: WOString {
|
||||
value = signature;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
signaturePlacementOnTop: WOConditional {
|
||||
condition = signaturePlacementOnTop;
|
||||
}
|
||||
|
||||
signaturePlacementOnBottom: WOConditional {
|
||||
condition = signaturePlacementOnTop;
|
||||
negate = YES;
|
||||
}
|
||||
|
||||
signaturePlacementOnTop: WOConditional {
|
||||
condition = signaturePlacementOnTop;
|
||||
}
|
||||
|
||||
signaturePlacementOnBottom: WOConditional {
|
||||
condition = signaturePlacementOnTop;
|
||||
negate = YES;
|
||||
}
|
16
SoObjects/Mailer/SOGoMailBasqueReply.wo/SOGoMailBasqueReply.html
Executable file
16
SoObjects/Mailer/SOGoMailBasqueReply.wo/SOGoMailBasqueReply.html
Executable file
|
@ -0,0 +1,16 @@
|
|||
<#replyPlacementOnTop><#newLine/>
|
||||
<#newLine/>
|
||||
</#replyPlacementOnTop><#signaturePlacementOnTop><#newLine/>
|
||||
<#signature/><#newLine/>
|
||||
</#signaturePlacementOnTop><#outlookMode>-------- Jatorrizko Mezua --------<#newLine/>
|
||||
Gaia: <#subject/><#newLine/>
|
||||
Data: <#date/><#newLine/>
|
||||
Nork: <#from/><#newLine/>
|
||||
<#hasReplyTo>Erantzun-honi: <#replyTo/></#hasReplyTo><#hasOrganization>Erakundea: <#organization/></#hasOrganization>Nori: <#to/><#newLine/>
|
||||
<#hasCc>Kopia: <#cc/></#hasCc><#hasNewsGroups>Berri-taldeak: <#newsgroups/></#hasNewsGroups><#hasReferences>Erreferentziak: <#references/></#hasReferences></#outlookMode><#newLine/>
|
||||
<#standardMode><#date/>-an, <#from/>-k idatzi zuen:</#standardMode><#newLine/>
|
||||
<#newLine/>
|
||||
<#messageBody/><#newLine/>
|
||||
<#replyPlacementOnBottom><#newLine/>
|
||||
<#newLine/>
|
||||
</#replyPlacementOnBottom><#signaturePlacementOnBottom><#signature/></#signaturePlacementOnBottom><#newLine/>
|
106
SoObjects/Mailer/SOGoMailBasqueReply.wo/SOGoMailBasqueReply.wod
Executable file
106
SoObjects/Mailer/SOGoMailBasqueReply.wo/SOGoMailBasqueReply.wod
Executable file
|
@ -0,0 +1,106 @@
|
|||
outlookMode: WOConditional {
|
||||
condition = outlookMode;
|
||||
}
|
||||
|
||||
standardMode: WOConditional {
|
||||
condition = outlookMode;
|
||||
negate = YES;
|
||||
}
|
||||
|
||||
subject: WOString {
|
||||
value = subject;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
date: WOString {
|
||||
value = date;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
from: WOString {
|
||||
value = from;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
newLine: WOString {
|
||||
value = newLine;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasReplyTo: WOConditional {
|
||||
condition = hasReplyTo;
|
||||
}
|
||||
|
||||
replyTo: WOString {
|
||||
value = replyTo;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasOrganization: WOConditional {
|
||||
condition = hasOrganization;
|
||||
}
|
||||
|
||||
organization: WOString {
|
||||
value = organization;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
to: WOString {
|
||||
value = to;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasCc: WOConditional {
|
||||
condition = hasCc;
|
||||
}
|
||||
|
||||
cc: WOString {
|
||||
value = cc;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasNewsGroups: WOConditional {
|
||||
condition = hasNewsGroups;
|
||||
}
|
||||
|
||||
newsgroups: WOString {
|
||||
value = newsgroups;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
hasReferences: WOConditional {
|
||||
condition = hasReferences;
|
||||
}
|
||||
|
||||
references: WOString {
|
||||
value = references;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
messageBody: WOString {
|
||||
value = messageBody;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
signature: WOString {
|
||||
value = signature;
|
||||
escapeHTML = NO;
|
||||
}
|
||||
|
||||
replyPlacementOnTop: WOConditional {
|
||||
condition = replyPlacementOnTop;
|
||||
}
|
||||
|
||||
replyPlacementOnBottom: WOConditional {
|
||||
condition = replyPlacementOnTop;
|
||||
negate = YES;
|
||||
}
|
||||
|
||||
signaturePlacementOnTop: WOConditional {
|
||||
condition = signaturePlacementOnTop;
|
||||
}
|
||||
|
||||
signaturePlacementOnBottom: WOConditional {
|
||||
condition = signaturePlacementOnTop;
|
||||
negate = YES;
|
||||
}
|
|
@ -384,6 +384,11 @@ static BOOL debugSoParts = NO;
|
|||
_path = [_path componentsSeparatedByString: @"."];
|
||||
}
|
||||
|
||||
// deal with mails of type text/calendar
|
||||
if ([[[info valueForKey: @"type"] lowercaseString] isEqualToString: @"text"] &&
|
||||
[[[info valueForKey: @"subtype"] lowercaseString] isEqualToString: @"calendar"])
|
||||
return info;
|
||||
|
||||
/*
|
||||
For each path component, eg 1,1,3
|
||||
|
||||
|
@ -772,6 +777,8 @@ static BOOL debugSoParts = NO;
|
|||
filename = [NSString stringWithFormat: @"unknown_%@", path];
|
||||
else if ([mimeType isEqualToString: @"message/rfc822"])
|
||||
filename = [NSString stringWithFormat: @"email_%@.eml", path];
|
||||
else if ([mimeType isEqualToString: @"text/calendar"])
|
||||
filename = [NSString stringWithFormat: @"calendar_%@.ics", path];
|
||||
|
||||
|
||||
if (filename)
|
||||
|
|
2
SoObjects/SOGo/.gitignore
vendored
2
SoObjects/SOGo/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
config.h
|
||||
md4.c
|
|
@ -159,7 +159,7 @@ SOGo_OBJC_FILES = \
|
|||
\
|
||||
SOGoCredentialsFile.m
|
||||
|
||||
SOGo_C_FILES = lmhash.c
|
||||
SOGo_C_FILES += lmhash.c
|
||||
|
||||
SOGo_RESOURCE_FILES = \
|
||||
SOGoDefaults.plist \
|
||||
|
|
|
@ -30,8 +30,7 @@ SOGo_LIBRARIES_DEPEND_UPON += \
|
|||
ifeq ($(HAS_LIBRARY_gnutls),yes)
|
||||
ADDITIONAL_CPPFLAGS += -DHAVE_GNUTLS=1
|
||||
SOGo_LIBRARIES_DEPEND_UPON += -lgnutls
|
||||
ADDITIONAL_INCLUDE_DIRS += -I$(GNULIB_INCLUDE)
|
||||
SOGo_C_FILES += $(GNULIB_FILES)
|
||||
SOGo_C_FILES += md4.c
|
||||
else
|
||||
ifeq ($(HAS_LIBRARY_ssl),yes)
|
||||
ADDITIONAL_CPPFLAGS += -DHAVE_OPENSSL=1
|
||||
|
|
|
@ -737,7 +737,7 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
|
|||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
if ([[localException name] isEqual: @"LDAPException"] &&
|
||||
if ([[localException name] isEqual: @"LDAPException"] &&
|
||||
([[[localException userInfo] objectForKey: @"error_code"] intValue] == LDAP_CONSTRAINT_VIOLATION))
|
||||
{
|
||||
*perr = PolicyInsufficientPasswordQuality;
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include <stdint.h>
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/crypto.h>
|
||||
#include <md4.h>
|
||||
#include "md4.h"
|
||||
#define MD4_DIGEST_LENGTH 16
|
||||
#define MD5_DIGEST_LENGTH 16
|
||||
#define SHA_DIGEST_LENGTH 20
|
||||
|
@ -54,6 +54,8 @@
|
|||
#error this module requires either gnutls or openssl
|
||||
#endif
|
||||
|
||||
#include "lmhash.h"
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <NGExtensions/NGBase64Coding.h>
|
||||
#import "NSData+Crypto.h"
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
SOGoLoginModule = "Mail";
|
||||
SOGoLanguage = "English";
|
||||
SOGoSupportedLanguages = ( "Arabic", "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English",
|
||||
SOGoSupportedLanguages = ( "Arabic", "Basque", "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English",
|
||||
"SpanishSpain", "SpanishArgentina", "Finnish", "French", "German",
|
||||
"Icelandic", "Italian", "Hungarian", "BrazilianPortuguese",
|
||||
"NorwegianBokmal", "NorwegianNynorsk", "Polish", "Russian", "Slovak",
|
||||
|
|
|
@ -262,9 +262,7 @@
|
|||
// The domain is probably appended to the username;
|
||||
// make sure it is defined as a domain in the configuration.
|
||||
*theDomain = [*theLogin substringFromIndex: (r.location + r.length)];
|
||||
if ([[sd domainIds] containsObject: *theDomain])
|
||||
*theLogin = [*theLogin substringToIndex: r.location];
|
||||
else
|
||||
if (![[sd domainIds] containsObject: *theDomain])
|
||||
*theDomain = nil;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SOGoSystemDefaults.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009-2014 Inverse inc.
|
||||
* Copyright (C) 2009-2015 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -64,6 +64,8 @@
|
|||
- (BOOL) uixAdditionalPreferences;
|
||||
|
||||
- (BOOL) uixDebugEnabled;
|
||||
- (BOOL) easDebugEnabled;
|
||||
|
||||
- (NSString *) pageTitle;
|
||||
|
||||
- (NSArray *) supportedLanguages;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SOGoSystemDefaults.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009-2014 Inverse inc.
|
||||
* Copyright (C) 2009-2015 Inverse inc.
|
||||
* Copyright (C) 2012 Jeroen Dekkers <jeroen@dekkers.ch>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
|
@ -427,6 +427,11 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict,
|
|||
return [self boolForKey: @"SOGoUIxDebugEnabled"];
|
||||
}
|
||||
|
||||
- (BOOL) easDebugEnabled
|
||||
{
|
||||
return [self boolForKey: @"SOGoEASDebugEnabled"];
|
||||
}
|
||||
|
||||
- (NSString *) pageTitle
|
||||
{
|
||||
return [self stringForKey: @"SOGoPageTitle"];
|
||||
|
|
|
@ -504,16 +504,49 @@ static Class NSNullK;
|
|||
SOGoSystemDefaults *dd;
|
||||
BOOL checkOK;
|
||||
|
||||
if (*_domain && [_login rangeOfString: @"@"].location == NSNotFound)
|
||||
username = [NSString stringWithFormat: @"%@@%@", _login, *_domain];
|
||||
dd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
|
||||
username = _login;
|
||||
|
||||
if (*_domain)
|
||||
{
|
||||
if ([_login rangeOfString: @"@"].location == NSNotFound)
|
||||
username = [NSString stringWithFormat: @"%@@%@", _login, *_domain];
|
||||
}
|
||||
else
|
||||
username = _login;
|
||||
{
|
||||
NSRange r;
|
||||
|
||||
// We try to extract the domain in use in order to avoid pounding all the authentication
|
||||
// sources if SOGoLoginDomains isn't specified. This is also true if the user is
|
||||
// using DAV or EAS.
|
||||
r = [username rangeOfString: @"@"];
|
||||
|
||||
if (r.location != NSNotFound)
|
||||
{
|
||||
NSArray *allDomains;
|
||||
int i;
|
||||
|
||||
*_domain = [username substringFromIndex: r.location+1];
|
||||
|
||||
allDomains = [[dd dictionaryForKey: @"domains"] allValues];
|
||||
|
||||
for (i = 0; i < [allDomains count]; i++)
|
||||
{
|
||||
if ([*_domain isEqualToString: [[allDomains objectAtIndex: i] objectForKey: @"SOGoMailDomain"]])
|
||||
break;
|
||||
}
|
||||
|
||||
// We haven't found one
|
||||
if (i == [allDomains count])
|
||||
*_domain = nil;
|
||||
}
|
||||
}
|
||||
|
||||
// We check the fail count per user in memcache (per server). If the
|
||||
// fail count reaches X in Y minutes, we deny immediately the
|
||||
// authentications for Z minutes
|
||||
failedCount = [[SOGoCache sharedCache] failedCountForLogin: username];
|
||||
dd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
if (failedCount)
|
||||
{
|
||||
unsigned int current_time, start_time, delta, block_time;
|
||||
|
|
381
SoObjects/SOGo/md4.c
Normal file
381
SoObjects/SOGo/md4.c
Normal file
|
@ -0,0 +1,381 @@
|
|||
/* Functions to compute MD4 message digest of files or memory blocks.
|
||||
according to the definition of MD4 in RFC 1320 from April 1992.
|
||||
Copyright (C) 1995-1997, 1999-2003, 2005-2006, 2008-2011 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program 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 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program 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; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* Adapted by Simon Josefsson from gnulib md5.? and Libgcrypt
|
||||
cipher/md4.c . */
|
||||
|
||||
#include "md4.h"
|
||||
|
||||
#include <stdalign.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if USE_UNLOCKED_IO
|
||||
# include "unlocked-io.h"
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define SWAP(n) \
|
||||
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
|
||||
#else
|
||||
# define SWAP(n) (n)
|
||||
#endif
|
||||
|
||||
#define BLOCKSIZE 32768
|
||||
#if BLOCKSIZE % 64 != 0
|
||||
# error "invalid BLOCKSIZE"
|
||||
#endif
|
||||
|
||||
/* This array contains the bytes used to pad the buffer to the next
|
||||
64-byte boundary. (RFC 1320, 3.1: Step 1) */
|
||||
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
|
||||
|
||||
|
||||
/* Initialize structure containing state of computation.
|
||||
(RFC 1320, 3.3: Step 3) */
|
||||
void
|
||||
md4_init_ctx (struct md4_ctx *ctx)
|
||||
{
|
||||
ctx->A = 0x67452301;
|
||||
ctx->B = 0xefcdab89;
|
||||
ctx->C = 0x98badcfe;
|
||||
ctx->D = 0x10325476;
|
||||
|
||||
ctx->total[0] = ctx->total[1] = 0;
|
||||
ctx->buflen = 0;
|
||||
}
|
||||
|
||||
/* Copy the 4 byte value from v into the memory location pointed to by *cp,
|
||||
If your architecture allows unaligned access this is equivalent to
|
||||
* (uint32_t *) cp = v */
|
||||
static inline void
|
||||
set_uint32 (char *cp, uint32_t v)
|
||||
{
|
||||
memcpy (cp, &v, sizeof v);
|
||||
}
|
||||
|
||||
/* Put result from CTX in first 16 bytes following RESBUF. The result
|
||||
must be in little endian byte order. */
|
||||
void *
|
||||
md4_read_ctx (const struct md4_ctx *ctx, void *resbuf)
|
||||
{
|
||||
char *r = resbuf;
|
||||
set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A));
|
||||
set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B));
|
||||
set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C));
|
||||
set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D));
|
||||
|
||||
return resbuf;
|
||||
}
|
||||
|
||||
/* Process the remaining bytes in the internal buffer and the usual
|
||||
prolog according to the standard and write the result to RESBUF. */
|
||||
void *
|
||||
md4_finish_ctx (struct md4_ctx *ctx, void *resbuf)
|
||||
{
|
||||
/* Take yet unprocessed bytes into account. */
|
||||
uint32_t bytes = ctx->buflen;
|
||||
size_t pad;
|
||||
|
||||
/* Now count remaining bytes. */
|
||||
ctx->total[0] += bytes;
|
||||
if (ctx->total[0] < bytes)
|
||||
++ctx->total[1];
|
||||
|
||||
pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
|
||||
memcpy (&((char*)ctx->buffer)[bytes], fillbuf, pad);
|
||||
|
||||
/* Put the 64-bit file length in *bits* at the end of the buffer. */
|
||||
ctx->buffer[(bytes + pad) / 4] = SWAP (ctx->total[0] << 3);
|
||||
ctx->buffer[(bytes + pad) / 4 + 1] = SWAP ((ctx->total[1] << 3) |
|
||||
(ctx->total[0] >> 29));
|
||||
|
||||
/* Process last bytes. */
|
||||
md4_process_block (ctx->buffer, bytes + pad + 8, ctx);
|
||||
|
||||
return md4_read_ctx (ctx, resbuf);
|
||||
}
|
||||
|
||||
/* Compute MD4 message digest for bytes read from STREAM. The
|
||||
resulting message digest number will be written into the 16 bytes
|
||||
beginning at RESBLOCK. */
|
||||
int
|
||||
md4_stream (FILE * stream, void *resblock)
|
||||
{
|
||||
struct md4_ctx ctx;
|
||||
size_t sum;
|
||||
|
||||
char *buffer = malloc (BLOCKSIZE + 72);
|
||||
if (!buffer)
|
||||
return 1;
|
||||
|
||||
/* Initialize the computation context. */
|
||||
md4_init_ctx (&ctx);
|
||||
|
||||
/* Iterate over full file contents. */
|
||||
while (1)
|
||||
{
|
||||
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
|
||||
computation function processes the whole buffer so that with the
|
||||
next round of the loop another block can be read. */
|
||||
size_t n;
|
||||
sum = 0;
|
||||
|
||||
/* Read block. Take care for partial reads. */
|
||||
while (1)
|
||||
{
|
||||
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
|
||||
|
||||
sum += n;
|
||||
|
||||
if (sum == BLOCKSIZE)
|
||||
break;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
/* Check for the error flag IFF N == 0, so that we don't
|
||||
exit the loop after a partial read due to e.g., EAGAIN
|
||||
or EWOULDBLOCK. */
|
||||
if (ferror (stream))
|
||||
{
|
||||
free (buffer);
|
||||
return 1;
|
||||
}
|
||||
goto process_partial_block;
|
||||
}
|
||||
|
||||
/* We've read at least one byte, so ignore errors. But always
|
||||
check for EOF, since feof may be true even though N > 0.
|
||||
Otherwise, we could end up calling fread after EOF. */
|
||||
if (feof (stream))
|
||||
goto process_partial_block;
|
||||
}
|
||||
|
||||
/* Process buffer with BLOCKSIZE bytes. Note that
|
||||
BLOCKSIZE % 64 == 0
|
||||
*/
|
||||
md4_process_block (buffer, BLOCKSIZE, &ctx);
|
||||
}
|
||||
|
||||
process_partial_block:;
|
||||
|
||||
/* Process any remaining bytes. */
|
||||
if (sum > 0)
|
||||
md4_process_bytes (buffer, sum, &ctx);
|
||||
|
||||
/* Construct result in desired memory. */
|
||||
md4_finish_ctx (&ctx, resblock);
|
||||
free (buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute MD4 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
void *
|
||||
md4_buffer (const char *buffer, size_t len, void *resblock)
|
||||
{
|
||||
struct md4_ctx ctx;
|
||||
|
||||
/* Initialize the computation context. */
|
||||
md4_init_ctx (&ctx);
|
||||
|
||||
/* Process whole buffer but last len % 64 bytes. */
|
||||
md4_process_bytes (buffer, len, &ctx);
|
||||
|
||||
/* Put result in desired memory area. */
|
||||
return md4_finish_ctx (&ctx, resblock);
|
||||
}
|
||||
|
||||
void
|
||||
md4_process_bytes (const void *buffer, size_t len, struct md4_ctx *ctx)
|
||||
{
|
||||
/* When we already have some bits in our internal buffer concatenate
|
||||
both inputs first. */
|
||||
if (ctx->buflen != 0)
|
||||
{
|
||||
size_t left_over = ctx->buflen;
|
||||
size_t add = 128 - left_over > len ? len : 128 - left_over;
|
||||
|
||||
memcpy (&((char*)ctx->buffer)[left_over], buffer, add);
|
||||
ctx->buflen += add;
|
||||
|
||||
if (ctx->buflen > 64)
|
||||
{
|
||||
md4_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
|
||||
|
||||
ctx->buflen &= 63;
|
||||
/* The regions in the following copy operation cannot overlap. */
|
||||
memcpy (ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~63],
|
||||
ctx->buflen);
|
||||
}
|
||||
|
||||
buffer = (const char *) buffer + add;
|
||||
len -= add;
|
||||
}
|
||||
|
||||
/* Process available complete blocks. */
|
||||
if (len >= 64)
|
||||
{
|
||||
#if !_STRING_ARCH_unaligned
|
||||
# define UNALIGNED_P(p) ((uintptr_t) (p) % alignof (uint32_t) != 0)
|
||||
if (UNALIGNED_P (buffer))
|
||||
while (len > 64)
|
||||
{
|
||||
md4_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
|
||||
buffer = (const char *) buffer + 64;
|
||||
len -= 64;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
md4_process_block (buffer, len & ~63, ctx);
|
||||
buffer = (const char *) buffer + (len & ~63);
|
||||
len &= 63;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move remaining bytes in internal buffer. */
|
||||
if (len > 0)
|
||||
{
|
||||
size_t left_over = ctx->buflen;
|
||||
|
||||
memcpy (&((char*)ctx->buffer)[left_over], buffer, len);
|
||||
left_over += len;
|
||||
if (left_over >= 64)
|
||||
{
|
||||
md4_process_block (ctx->buffer, 64, ctx);
|
||||
left_over -= 64;
|
||||
memcpy (ctx->buffer, &ctx->buffer[16], left_over);
|
||||
}
|
||||
ctx->buflen = left_over;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Code below is the primary difference between md5.c and md4.c --- */
|
||||
|
||||
/* MD4 round constants */
|
||||
#define K1 0x5a827999
|
||||
#define K2 0x6ed9eba1
|
||||
|
||||
/* Round functions. */
|
||||
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n))))
|
||||
#define R1(a,b,c,d,k,s) a=rol(a+F(b,c,d)+x[k],s);
|
||||
#define R2(a,b,c,d,k,s) a=rol(a+G(b,c,d)+x[k]+K1,s);
|
||||
#define R3(a,b,c,d,k,s) a=rol(a+H(b,c,d)+x[k]+K2,s);
|
||||
|
||||
/* Process LEN bytes of BUFFER, accumulating context into CTX.
|
||||
It is assumed that LEN % 64 == 0. */
|
||||
|
||||
void
|
||||
md4_process_block (const void *buffer, size_t len, struct md4_ctx *ctx)
|
||||
{
|
||||
const uint32_t *words = buffer;
|
||||
size_t nwords = len / sizeof (uint32_t);
|
||||
const uint32_t *endp = words + nwords;
|
||||
uint32_t x[16];
|
||||
uint32_t A = ctx->A;
|
||||
uint32_t B = ctx->B;
|
||||
uint32_t C = ctx->C;
|
||||
uint32_t D = ctx->D;
|
||||
|
||||
/* First increment the byte count. RFC 1320 specifies the possible
|
||||
length of the file up to 2^64 bits. Here we only compute the
|
||||
number of bytes. Do a double word increment. */
|
||||
ctx->total[0] += len;
|
||||
if (ctx->total[0] < len)
|
||||
++ctx->total[1];
|
||||
|
||||
/* Process all bytes in the buffer with 64 bytes in each round of
|
||||
the loop. */
|
||||
while (words < endp)
|
||||
{
|
||||
int t;
|
||||
for (t = 0; t < 16; t++)
|
||||
{
|
||||
x[t] = SWAP (*words);
|
||||
words++;
|
||||
}
|
||||
|
||||
/* Round 1. */
|
||||
R1 (A, B, C, D, 0, 3);
|
||||
R1 (D, A, B, C, 1, 7);
|
||||
R1 (C, D, A, B, 2, 11);
|
||||
R1 (B, C, D, A, 3, 19);
|
||||
R1 (A, B, C, D, 4, 3);
|
||||
R1 (D, A, B, C, 5, 7);
|
||||
R1 (C, D, A, B, 6, 11);
|
||||
R1 (B, C, D, A, 7, 19);
|
||||
R1 (A, B, C, D, 8, 3);
|
||||
R1 (D, A, B, C, 9, 7);
|
||||
R1 (C, D, A, B, 10, 11);
|
||||
R1 (B, C, D, A, 11, 19);
|
||||
R1 (A, B, C, D, 12, 3);
|
||||
R1 (D, A, B, C, 13, 7);
|
||||
R1 (C, D, A, B, 14, 11);
|
||||
R1 (B, C, D, A, 15, 19);
|
||||
|
||||
/* Round 2. */
|
||||
R2 (A, B, C, D, 0, 3);
|
||||
R2 (D, A, B, C, 4, 5);
|
||||
R2 (C, D, A, B, 8, 9);
|
||||
R2 (B, C, D, A, 12, 13);
|
||||
R2 (A, B, C, D, 1, 3);
|
||||
R2 (D, A, B, C, 5, 5);
|
||||
R2 (C, D, A, B, 9, 9);
|
||||
R2 (B, C, D, A, 13, 13);
|
||||
R2 (A, B, C, D, 2, 3);
|
||||
R2 (D, A, B, C, 6, 5);
|
||||
R2 (C, D, A, B, 10, 9);
|
||||
R2 (B, C, D, A, 14, 13);
|
||||
R2 (A, B, C, D, 3, 3);
|
||||
R2 (D, A, B, C, 7, 5);
|
||||
R2 (C, D, A, B, 11, 9);
|
||||
R2 (B, C, D, A, 15, 13);
|
||||
|
||||
/* Round 3. */
|
||||
R3 (A, B, C, D, 0, 3);
|
||||
R3 (D, A, B, C, 8, 9);
|
||||
R3 (C, D, A, B, 4, 11);
|
||||
R3 (B, C, D, A, 12, 15);
|
||||
R3 (A, B, C, D, 2, 3);
|
||||
R3 (D, A, B, C, 10, 9);
|
||||
R3 (C, D, A, B, 6, 11);
|
||||
R3 (B, C, D, A, 14, 15);
|
||||
R3 (A, B, C, D, 1, 3);
|
||||
R3 (D, A, B, C, 9, 9);
|
||||
R3 (C, D, A, B, 5, 11);
|
||||
R3 (B, C, D, A, 13, 15);
|
||||
R3 (A, B, C, D, 3, 3);
|
||||
R3 (D, A, B, C, 11, 9);
|
||||
R3 (C, D, A, B, 7, 11);
|
||||
R3 (B, C, D, A, 15, 15);
|
||||
|
||||
A = ctx->A += A;
|
||||
B = ctx->B += B;
|
||||
C = ctx->C += C;
|
||||
D = ctx->D += D;
|
||||
}
|
||||
}
|
91
SoObjects/SOGo/md4.h
Normal file
91
SoObjects/SOGo/md4.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* Declarations of functions and data types used for MD4 sum
|
||||
library functions.
|
||||
Copyright (C) 2000-2001, 2003, 2005, 2008-2011 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program 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 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program 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; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef MD4_H
|
||||
# define MD4_H 1
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdint.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# define MD4_DIGEST_SIZE 16
|
||||
|
||||
/* Structure to save state of computation between the single steps. */
|
||||
struct md4_ctx
|
||||
{
|
||||
uint32_t A;
|
||||
uint32_t B;
|
||||
uint32_t C;
|
||||
uint32_t D;
|
||||
|
||||
uint32_t total[2];
|
||||
uint32_t buflen;
|
||||
uint32_t buffer[32];
|
||||
};
|
||||
|
||||
|
||||
/* Initialize structure containing state of computation. */
|
||||
extern void md4_init_ctx (struct md4_ctx *ctx);
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is necessary that LEN is a multiple of 64!!! */
|
||||
extern void md4_process_block (const void *buffer, size_t len,
|
||||
struct md4_ctx *ctx);
|
||||
|
||||
/* Starting with the result of former calls of this function (or the
|
||||
initialization function update the context for the next LEN bytes
|
||||
starting at BUFFER.
|
||||
It is NOT required that LEN is a multiple of 64. */
|
||||
extern void md4_process_bytes (const void *buffer, size_t len,
|
||||
struct md4_ctx *ctx);
|
||||
|
||||
/* Process the remaining bytes in the buffer and put result from CTX
|
||||
in first 16 bytes following RESBUF. The result is always in little
|
||||
endian byte order, so that a byte-wise output yields to the wanted
|
||||
ASCII representation of the message digest. */
|
||||
extern void *md4_finish_ctx (struct md4_ctx *ctx, void *resbuf);
|
||||
|
||||
|
||||
/* Put result from CTX in first 16 bytes following RESBUF. The result is
|
||||
always in little endian byte order, so that a byte-wise output yields
|
||||
to the wanted ASCII representation of the message digest. */
|
||||
extern void *md4_read_ctx (const struct md4_ctx *ctx, void *resbuf);
|
||||
|
||||
|
||||
/* Compute MD4 message digest for bytes read from STREAM. The
|
||||
resulting message digest number will be written into the 16 bytes
|
||||
beginning at RESBLOCK. */
|
||||
extern int md4_stream (FILE * stream, void *resblock);
|
||||
|
||||
/* Compute MD4 message digest for LEN bytes beginning at BUFFER. The
|
||||
result is always in little endian byte order, so that a byte-wise
|
||||
output yields to the wanted ASCII representation of the message
|
||||
digest. */
|
||||
extern void *md4_buffer (const char *buffer, size_t len, void *resblock);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
13
TODO
13
TODO
|
@ -1,13 +0,0 @@
|
|||
Rendering of multi-status responses is suboptimal in SOPE:
|
||||
PROPPATCH "subresponses" indicates either complete failure or success
|
||||
REPORT responses are handled by SOGo
|
||||
Therefore it would be nice to refactor those things a little bit and maybe put
|
||||
some code from SOGo up into SOPE.
|
||||
-- wsourdeau@inverse.ca, Tue, 22 Apr 2008 15:21:32 -0400
|
||||
|
||||
ACL:
|
||||
- the "default user" concept in the SOGo ACL paradigm should probably match
|
||||
the "authenticated" role in SOGo/SOPE. Also, we should reconsider the handling
|
||||
of the DAV:authenticated principal wrt the DAV ACL interface.
|
||||
- we should add support for DAV privilege descriptions
|
||||
-- wsourdeau@inverse.ca, Tue, 29 Apr 2008 12:05:17 -0400
|
|
@ -10,7 +10,7 @@ import sogoLogin
|
|||
|
||||
# must be kept in sync with SoObjects/SOGo/SOGoDefaults.plist
|
||||
# this should probably be fetched magically...
|
||||
SOGoSupportedLanguages = [ "Arabic", "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English", "Finnish",
|
||||
SOGoSupportedLanguages = [ "Arabic", "Basque", "Catalan", "Czech", "Dutch", "Danish", "Welsh", "English", "Finnish",
|
||||
"SpanishSpain", "SpanishArgentina", "French", "German",
|
||||
"Icelandic", "Italian", "Hungarian", "BrazilianPortuguese",
|
||||
"NorwegianBokmal", "NorwegianNynorsk", "Polish", "Russian", "Slovak",
|
||||
|
|
|
@ -46,7 +46,7 @@ class preferencesTest(unittest.TestCase):
|
|||
|
||||
def testPreventInvitationsWhiteList(self):
|
||||
"""Add to the PreventInvitations Whitelist"""
|
||||
self.prefs.set("whiteList", white_listed_attendee)
|
||||
self.prefs.set("whiteList", simplejson.dumps(white_listed_attendee))
|
||||
whitelist = self.prefs.get_settings('Calendar')['PreventInvitationsWhitelist']
|
||||
self.assertEqual(whitelist, white_listed_attendee)
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ class preventInvitationsTest(unittest.TestCase):
|
|||
""" Set PreventInvitation add to WhiteList and accept the Invitation"""
|
||||
#- First, add the Organiser to the Attendee's whitelist
|
||||
self.prefs.set('enablePreventInvitations', '0')
|
||||
self.prefs.set("whiteList", white_listed_attendee)
|
||||
self.prefs.set("whiteList", simplejson.dumps(white_listed_attendee))
|
||||
whitelist = self.prefs.get_settings('Calendar')['PreventInvitationsWhitelist']
|
||||
self.assertEqual(whitelist, white_listed_attendee)
|
||||
|
||||
|
|
15
UI/AdministrationUI/Basque.lproj/Localizable.strings
Normal file
15
UI/AdministrationUI/Basque.lproj/Localizable.strings
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* this file is in UTF-8 format! */
|
||||
|
||||
"Help" = "Laguntza";
|
||||
"Close" = "Itxi";
|
||||
|
||||
"Modules" = "Moduluak";
|
||||
|
||||
/* Modules short names */
|
||||
"ACLs" = "ACL-ak";
|
||||
|
||||
/* Modules titles */
|
||||
"ACLs_title" = "Erabiltzaileen karpeten ACL-en kudeaketa";
|
||||
|
||||
/* Modules descriptions */
|
||||
"ACLs_description" = "<p>\"Access Control List\" administrazio moduluak erabiltzaile bakoitzaren egutegi eta helbide liburuen ACL-ak aldatzea baimentzen du.</p><p>Erabiltzaile baten karpetaren ACL-ak aldatzeko idatzi erabiltzailearen izena leihoaren gainaldeko bilaketa eremuan eta klik bikoitza egin gogoko karpetan.</p>";
|
|
@ -6,7 +6,7 @@ BUNDLE_NAME = AdministrationUI
|
|||
|
||||
AdministrationUI_PRINCIPAL_CLASS = AdministrationUIProduct
|
||||
|
||||
AdministrationUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
AdministrationUI_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
AdministrationUI_OBJC_FILES = \
|
||||
AdministrationUIProduct.m \
|
||||
|
|
118
UI/Common/Basque.lproj/Localizable.strings
Normal file
118
UI/Common/Basque.lproj/Localizable.strings
Normal file
|
@ -0,0 +1,118 @@
|
|||
/* this file is in UTF-8 format! */
|
||||
|
||||
/* toolbars */
|
||||
"Save" = "Gorde";
|
||||
"Close" = "Itxi";
|
||||
"Edit User Rights" = "Erabiltzailearen baimenak aldatu";
|
||||
|
||||
"Home" = "Hasiera";
|
||||
"Calendar" = "Egutegia";
|
||||
"Address Book" = "Helbide liburua";
|
||||
"Mail" = "Emaila";
|
||||
"Preferences" = "Hoberespenak";
|
||||
"Administration" = "Administrazio";
|
||||
"Disconnect" = "Deskonektatu";
|
||||
"Right Administration" = "Baimenen kudeaketa";
|
||||
"Log Console (dev.)" = "Erregistro kontsola (garap.)";
|
||||
|
||||
"User" = "Erabiltzailea";
|
||||
"Vacation message is enabled" = "\"Oporretan nago\" mezua gaituta dago";
|
||||
|
||||
"Help" = "Laguntza";
|
||||
|
||||
"noJavascriptError" = "SOGo-k javascript beharrezkoa du. Mesedez ziurtatu zure nabigatzailearen aukeratan aktibatua dagoela.";
|
||||
"noJavascriptRetry" = "Berriz saiatu";
|
||||
|
||||
"Owner:" = "Jabea:";
|
||||
"Publish the Free/Busy information" = "Argitaratu Libre/Lanpetu informazioa";
|
||||
|
||||
"Add..." = "Gehitu...";
|
||||
"Remove" = "Ezabatu";
|
||||
|
||||
"Subscribe User" = "Erabiltzailea harpidetu";
|
||||
|
||||
"Any Authenticated User" = "Autentifikatutako edozein erabiltzaile";
|
||||
"Public Access" = "Atzipen publikoa";
|
||||
"Any user not listed above" = "Goian zerrendatu gabeko edozein erabiltzaile";
|
||||
"Anybody accessing this resource from the public area" = "Eremu publikotik baliabidea atzitzen duen edonork";
|
||||
|
||||
"Sorry, the user rights can not be configured for that object." = "Barkatu, erabiltzailearen baimenak ezin dira objetu horretarako konfiguratu.";
|
||||
|
||||
"Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?"
|
||||
= "Sistema honetan kontua daukan edonor zure \"%{0}\" postontzia atzitzeko gai izango da. Ziur zaude hori nahi duzula? ";
|
||||
"Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?"
|
||||
= "Sistema honetan kontua daukan edonor zure \"%{0}\" egutegia atzitzeko gai izango da. Ziur zaude hori nahi duzula? ";
|
||||
"Potentially anyone on the Internet will be able to access your calendar \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
|
||||
= "Internet-eko edonor zure \"%{0}\" egutegia atzitzeko gai izango da, naiz eta sistema honetan konturik ez eduki. Informazio hau egokia da internet publikorako?";
|
||||
"Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?"
|
||||
= "Sistemako edozein erabiltzaile zure \"%{0}\" helbide liburua atzitzeko gai izango da. Ziur zaude hori nahi duzula?";
|
||||
"Potentially anyone on the Internet will be able to access your address book \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
|
||||
= "Internet-eko edonor zure \"%{0}\" helbide liburua atzitzeko gai izango da, naiz eta sistema honetan konturik ez eduki. Informazio hau egokia da internet publikorako?";
|
||||
"Give Access" = "Baimendu atzipena";
|
||||
"Keep Private" = "Pribatua mantendu";
|
||||
|
||||
/* generic.js */
|
||||
"Unable to subscribe to that folder!"
|
||||
= "Ezin da karpeta hori harpidetu!";
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
= "Ezin duzu zure karpeta bat harpidetu!";
|
||||
"Unable to unsubscribe from that folder!"
|
||||
= "Ezin da karpetaren harpidetza kendu!";
|
||||
"You cannot unsubscribe from a folder that you own!"
|
||||
= "Ezin duzu zure karpeta baten harpidetza kendu!";
|
||||
"Unable to rename that folder!" = "Karpetaren izena ezin da aldatu!";
|
||||
"You have already subscribed to that folder!"
|
||||
= "Karpeta hau dagoeneko harpidetuta daukazu!";
|
||||
"The user rights cannot be edited for this object!"
|
||||
= "Objetu honen erabiltzaile baimenak ezin dira editatu!";
|
||||
"A folder by that name already exists." = "Izen hori daukan karpeta existitzen da dagoeneko.";
|
||||
"You cannot create a list in a shared address book."
|
||||
= "Ezin duzu zerrenda bat sortu partekatutako helbide liburu batean";
|
||||
"Warning" = "Oharra";
|
||||
"Can't contact server" = "Errore gertatu da zerbitzariarekin konektatzerakoan. Mesedez saiatu beranduago.";
|
||||
|
||||
"You are not allowed to access this module or this system. Please contact your system administrator."
|
||||
= "Ez daukazu modulu edo sistema honetarako atzipen baimenik. Mesedez, jarri harremanetan sistemaren administratzailearekin.";
|
||||
"You don't have the required privileges to perform the operation."
|
||||
= "Ez daukazu eragiketa egiteko beharrezko baimenik.";
|
||||
|
||||
"noEmailForDelegation" = "Zure gonbidapena delegatu nahi duzun email helbidea zehaztu behar duzu.";
|
||||
"delegate is organizer" = "Delegatua antolatzailea da. Mesedez, aukeratu beste delegatu bat.";
|
||||
"delegate is a participant" = "DElegatua parte-hartzailea da jada.";
|
||||
"delegate is a group" = "Zehaztutako helbidea talde bati dagokio. Pertsona baten gain bakarrik delega dezakezu.";
|
||||
|
||||
"Snooze for " = "Errepikatu ";
|
||||
"5 minutes" = "5 minutu";
|
||||
"10 minutes" = "10 minutu";
|
||||
"15 minutes" = "15 minutu";
|
||||
"30 minutes" = "30 minutu";
|
||||
"45 minutes" = "45 minutu";
|
||||
"1 hour" = "1 ordu";
|
||||
"1 day" = "1 egun";
|
||||
|
||||
/* common buttons */
|
||||
"OK" = "Onartu";
|
||||
"Cancel" = "Ezeztatu";
|
||||
"Yes" = "Bai";
|
||||
"No" = "Ez";
|
||||
|
||||
/* alarms */
|
||||
"Reminder:" = "Ohartarazpena:";
|
||||
"Start:" = "Hasi:";
|
||||
"Due Date:" = "Epemuga:";
|
||||
"Location:" = "Kokapen";
|
||||
|
||||
/* mail labels */
|
||||
"Important" = "Garrantzitsua";
|
||||
"Work" = "Lana";
|
||||
"Personal" = "Pertsonala";
|
||||
"To Do" = "Egitekoa";
|
||||
"Later" = "Beranduago";
|
||||
|
||||
"a2_Sunday" = "Ig";
|
||||
"a2_Monday" = "Al";
|
||||
"a2_Tuesday" = "As";
|
||||
"a2_Wednesday" = "Az";
|
||||
"a2_Thursday" = "Os";
|
||||
"a2_Friday" = "Or";
|
||||
"a2_Saturday" = "Lr";
|
|
@ -94,7 +94,7 @@
|
|||
"OK" = "OK";
|
||||
"Cancel" = "Cancelar";
|
||||
"Yes" = "Sim";
|
||||
"No" = "No";
|
||||
"No" = "Não";
|
||||
|
||||
/* alarms */
|
||||
"Reminder:" = "Lembrete:";
|
||||
|
@ -109,10 +109,10 @@
|
|||
"To Do" = "Tarefa";
|
||||
"Later" = "Adiar";
|
||||
|
||||
"a2_Sunday" = "Do";
|
||||
"a2_Monday" = "Se";
|
||||
"a2_Tuesday" = "Te";
|
||||
"a2_Wednesday" = "Qu";
|
||||
"a2_Thursday" = "Qu";
|
||||
"a2_Friday" = "Se";
|
||||
"a2_Saturday" = "Sa";
|
||||
"a2_Sunday" = "Dom";
|
||||
"a2_Monday" = "Seg";
|
||||
"a2_Tuesday" = "Ter";
|
||||
"a2_Wednesday" = "Qua";
|
||||
"a2_Thursday" = "Qui";
|
||||
"a2_Friday" = "Sex";
|
||||
"a2_Saturday" = "Sab";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* this file is in UTF-8 format! */
|
||||
|
||||
/* toolbars */
|
||||
"Save" = "Sauver";
|
||||
"Save" = "Enregistrer";
|
||||
"Close" = "Fermer";
|
||||
"Edit User Rights" = "Édition des droits";
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ BUNDLE_NAME = CommonUI
|
|||
|
||||
CommonUI_PRINCIPAL_CLASS = CommonUIProduct
|
||||
|
||||
CommonUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
CommonUI_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
CommonUI_OBJC_FILES += \
|
||||
CommonUIProduct.m \
|
||||
|
|
215
UI/Contacts/Basque.lproj/Localizable.strings
Normal file
215
UI/Contacts/Basque.lproj/Localizable.strings
Normal file
|
@ -0,0 +1,215 @@
|
|||
/* this file is in UTF-8 format! */
|
||||
|
||||
"Contact" = "Kontaktua";
|
||||
"Address" = "Helbidea";
|
||||
"Photos" = "Argazkiak";
|
||||
"Other" = "Bestelakoak";
|
||||
|
||||
"Address Books" = "Helbide Liburuak";
|
||||
"Addressbook" = "helbideliburua";
|
||||
"Addresses" = "Helbideak";
|
||||
"Update" = "Eguneratu";
|
||||
"Cancel" = "Ezeztatu";
|
||||
"Common" = "Arrunta";
|
||||
"Contact editor" = "Kontaktuen editorea";
|
||||
"Contact viewer" = "Kontaktuen ikuskatzailea";
|
||||
"Email" = "Emaila";
|
||||
"Screen Name" = "Pantailaren izena";
|
||||
"Extended" = "Luzatua";
|
||||
"Fax" = "Fax";
|
||||
"Firstname" = "Izena";
|
||||
"Home" = "Hasiera";
|
||||
"HomePhone" = "EtxekoTelefonoa";
|
||||
"Lastname" = "Abizena";
|
||||
"Location" = "Kokapena";
|
||||
"MobilePhone" = "Telefono mugikorra";
|
||||
"Name" = "Izena";
|
||||
"OfficePhone" = "BulegokoTelefonoa";
|
||||
"Organization" = "Erakundea";
|
||||
"Work Phone" = "Laneko telefonoa";
|
||||
"Phone" = "Telefonoa";
|
||||
"Phones" = "Telefonoak";
|
||||
"Postal" = "Posta";
|
||||
"Save" = "Gorde";
|
||||
"Internet" = "Internet";
|
||||
"Unit" = "Unitatea";
|
||||
"delete" = "ezabatu";
|
||||
"edit" = "aldatu";
|
||||
"invalidemailwarn" = "Idatzitako posta elektronikoa baliogabea da";
|
||||
"new" = "berria";
|
||||
"Preferred Phone" = "Hobetsitako telefonoa";
|
||||
|
||||
"Move To" = "Mugitu hona";
|
||||
"Copy To" = "Kopiatu hona";
|
||||
"Add to:" = "Gehitu hona:";
|
||||
|
||||
/* Tooltips */
|
||||
|
||||
"Create a new address book card" = "Sortu helbide liburu txartel berria";
|
||||
"Create a new list" = "Sortu zerrenda berria";
|
||||
"Edit the selected card" = "Aldatu aukeratutako txartela";
|
||||
"Send a mail message" = "Bidali mezua";
|
||||
"Delete selected card or address book" = "Ezabatu hautatutako txartela edo helbide liburua";
|
||||
"Reload all contacts" = "Kontaktu guztiak birkargatu";
|
||||
|
||||
"htmlMailFormat_UNKNOWN" = "Ezezaguna";
|
||||
"htmlMailFormat_FALSE" = "Testu hutsa";
|
||||
"htmlMailFormat_TRUE" = "HTML";
|
||||
|
||||
"Name or Email" = "Izena edo email helbidea";
|
||||
"Category" = "Kategoria";
|
||||
"Personal Addressbook" = "Helbide-liburu pertsonala";
|
||||
"Search in Addressbook" = "Bilatu Helbide-liburuan";
|
||||
|
||||
"New Card" = "Txartel berria";
|
||||
"New List" = "Zerrenda berria";
|
||||
"Edit" = "Aldatu";
|
||||
"Properties" = "Ezaugarriak";
|
||||
"Sharing..." = "Partekatzen...";
|
||||
"Write" = "Idatzi";
|
||||
"Delete" = "Ezabatu";
|
||||
"Instant Message" = "Berehalako mezua";
|
||||
"Add..." = "Gehitu...";
|
||||
"Remove" = "Ezabatu";
|
||||
|
||||
"Please wait..." = "Mesedez itxaron...";
|
||||
"No possible subscription" = "Ez dago harpidetzarako aukerarik";
|
||||
|
||||
"Preferred" = "Hobetsitakoa";
|
||||
"Display:" = "Bistaratzea:";
|
||||
"Display Name:" = "Erakusteko izena:";
|
||||
"Email:" = "Emaila:";
|
||||
"Additional Email:" = "Beste emaila:";
|
||||
|
||||
"Phone Number:" = "Telefono zenbakia";
|
||||
"Prefers to receive messages formatted as:" = "Nahiago du mezuak honako formatuan jasotzea:";
|
||||
"Screen Name:" = "Pantailaren izena";
|
||||
"Categories:" = "Kategoriak:";
|
||||
|
||||
"First:" = "Lehenengoa:";
|
||||
"Last:" = "Azkena:";
|
||||
"Nickname:" = "Goitizena:";
|
||||
|
||||
"Telephone" = "Telefonoa:";
|
||||
"Work:" = "Lana:";
|
||||
"Home:" = "Etxea:";
|
||||
"Fax:" = "Fax-a:";
|
||||
"Mobile:" = "Mugikorra:";
|
||||
"Pager:" = "Orrikatzailea:";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Lankide, Lehiakide, Bezero, Lagun, Familia, Negoziokidea, Hornitzailea, Prentsa, VIP";
|
||||
"Categories" = "Kategoriak";
|
||||
"New category" = "Kategoria berria";
|
||||
|
||||
/* adresses */
|
||||
"Title:" = "Izenburua";
|
||||
"Service:" = "Zerbitzua:";
|
||||
"Company:" = "Enpresa";
|
||||
"Department:" = "Saila";
|
||||
"Organization:" = "Saila:";
|
||||
"Address:" = "Helbidea";
|
||||
"City:" = "Herria";
|
||||
"State_Province:" = "Estatua / Probintzia";
|
||||
"ZIP_Postal Code:" = "Posta kodea";
|
||||
"Country:" = "Herrialdea";
|
||||
"Web Page:" = "Web orria";
|
||||
|
||||
"Work" = "Lana";
|
||||
"Other Infos" = "Bestelako informazioak";
|
||||
|
||||
"Note:" = "Ohar:";
|
||||
"Timezone:" = "Ordu-zona:";
|
||||
"Birthday:" = "Jaiotze data:";
|
||||
"Birthday (yyyy-mm-dd):" = "Jaiotze data (uuuu-hh-ee):";
|
||||
"Freebusy URL:" = "LibreLanpetu URL-a:";
|
||||
|
||||
"Add as..." = "Gehitu honela...";
|
||||
"Recipient" = "Jasotzailea";
|
||||
"Carbon Copy" = "Kopia";
|
||||
"Blind Carbon Copy" = "Ezkutuko kopia";
|
||||
|
||||
"New Addressbook..." = "Helbideliburu berria";
|
||||
"Subscribe to an Addressbook..." = "Harpidetu helbide liburu bat...";
|
||||
"Remove the selected Addressbook" = "Ezabatu aukeratutako helbide-liburua";
|
||||
|
||||
"Name of the Address Book" = "Helbide-liburuaren izena";
|
||||
"Are you sure you want to delete the selected address book?"
|
||||
= "Ziur zaude aukeratutako helbide-lburua ezabatu nahi duzula?";
|
||||
"You cannot remove nor unsubscribe from a public addressbook."
|
||||
= "Helbide-liburu publiko bat ezin duzu ezabatu edo harpidetza kendu.";
|
||||
"You cannot remove nor unsubscribe from your personal addressbook."
|
||||
= "Ezin duzu ezabatu edo harpidetza kendu zure helbide-liburu pertsonala.";
|
||||
|
||||
"Are you sure you want to delete the selected contacts?"
|
||||
= "Ziur zaude aukeratutako kontaktuak ezabatu nahi dituzula?";
|
||||
|
||||
"You cannot delete the card of \"%{0}\"."
|
||||
= "Ezin duzu \"%{0}\"-en txartela ezabatu.";
|
||||
|
||||
|
||||
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
= "Ezin duzu zure karpeta bat harpidetu.";
|
||||
"Unable to subscribe to that folder!"
|
||||
= "Ezin da karpeta hori harpidetu.";
|
||||
|
||||
/* acls */
|
||||
"Access rights to" = "Atzipen baimenak honi";
|
||||
"For user" = "Erabiltzailearentzat";
|
||||
|
||||
"Any Authenticated User" = "Autentifikatutako edozein erabiltzaile";
|
||||
"Public Access" = "Atzipen publikoa";
|
||||
|
||||
"This person can add cards to this addressbook."
|
||||
= "Pertsona honek txartelak gehitu ditzake helbide liburu honetan.";
|
||||
"This person can edit the cards of this addressbook."
|
||||
= "Pertsona honek helbide liburu honetako txartelak aldatu ditzake.";
|
||||
"This person can list the content of this addressbook."
|
||||
= "Pertsona honek helbide-liburu honetako edukiak zerrendatu ditzake.";
|
||||
"This person can read the cards of this addressbook."
|
||||
= "Pertsona honek helbide-liburu honetako txartelak irakurri ditzake.";
|
||||
"This person can erase cards from this addressbook."
|
||||
= "Pertsona honek helbide-liburu honetako txartelak ezabatu ditzake.";
|
||||
|
||||
"The selected contact has no email address."
|
||||
= "Aukeratutako kontaktuak ez dauka email helbiderik.";
|
||||
|
||||
"Please select a contact." = "Mesedez, aukeratu kontaktu bat.";
|
||||
|
||||
/* Error messages for move and copy */
|
||||
|
||||
"SoAccessDeniedException" = "Ezin duzu helbide liburu honetan idatzi.";
|
||||
"Forbidden" = "Ezin duzu helbide liburu honetan idatzi.";
|
||||
"Invalid Contact" = "Aukeratutako kontaktua jada ez da existitzen.";
|
||||
"Unknown Destination Folder" = "Aukeratutako helburu helbide-liburua jada ez da existitzen.";
|
||||
|
||||
/* Lists */
|
||||
"List details" = "Zerrendaren xehetasunak";
|
||||
"List name:" = "Zerrendaren izena:";
|
||||
"List nickname:" = "Zerrendaren goitizena:";
|
||||
"List description:" = "Zerrendaren deskribapena:";
|
||||
"Members" = "Kideak";
|
||||
"Contacts" = "Kontaktuak";
|
||||
"Add" = "Gehitu";
|
||||
"Lists can't be moved or copied." = "Zerrendak ezin dira kopiatu edo mugitu.";
|
||||
"Export" = "Esportatu";
|
||||
"Export Address Book..." = "Esportatu helbide liburua...";
|
||||
"View Raw Source" = "Ikusi Raw iturburua";
|
||||
"Import Cards" = "Inportatu txartelak";
|
||||
"Select a vCard or LDIF file." = "Aukeratu vCard edo LDIF fitxategia";
|
||||
"Upload" = "Kargatu";
|
||||
"Uploading" = "Kargatzen";
|
||||
"Done" = "Eginda";
|
||||
"An error occured while importing contacts." = "Errorea gertatu da txartelak inportatzean.";
|
||||
"No card was imported." = "Ez da txartelik inportatu.";
|
||||
"A total of %{0} cards were imported in the addressbook." = "Guztira %{0} txartel inportatu dira helbide liburuan.";
|
||||
|
||||
"Reload" = "Birkargatu";
|
||||
|
||||
/* Properties window */
|
||||
"Address Book Name:" = "Helbide-Liburuaren izena:";
|
||||
"Links to this Address Book" = "Helbide liburu honetarako estekak";
|
||||
"Authenticated User Access" = "Autentifikatutako erabiltzaileentzako atzipena";
|
||||
"CardDAV URL: " = "CardDAV URL-a:";
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
/* this file is in UTF-8 format! */
|
||||
|
||||
"Contact" = "Contact";
|
||||
"Address" = "Address";
|
||||
"Photos" = "Photos";
|
||||
"Other" = "Other";
|
||||
"Contact" = "Contato";
|
||||
"Address" = "Catálogo";
|
||||
"Photos" = "Fotos";
|
||||
"Other" = "Outros";
|
||||
|
||||
"Address Books" = "Addressbooks";
|
||||
"Address Books" = "Catálogo de Endereços";
|
||||
"Addressbook" = "Catálogo";
|
||||
"Addresses" = "Contato";
|
||||
"Addresses" = "Endereços";
|
||||
"Update" = "Atualizar";
|
||||
"Cancel" = "Cancelar";
|
||||
"Common" = "Comum";
|
||||
"Contact editor" = "Editor de Contatos";
|
||||
"Contact viewer" = "Visualizador de Contatos";
|
||||
"Email" = "Email";
|
||||
"Screen Name" = "Nome Apresentação";
|
||||
"Screen Name" = "Nome de Exibição";
|
||||
"Extended" = "Extendido";
|
||||
"Fax" = "Fax";
|
||||
"Firstname" = "Primeiro Nome";
|
||||
|
@ -32,16 +32,16 @@
|
|||
"Postal" = "CEP";
|
||||
"Save" = "Salvar";
|
||||
"Internet" = "Internet";
|
||||
"Unit" = "Setor";
|
||||
"Unit" = "Unidade";
|
||||
"delete" = "apagar";
|
||||
"edit" = "editar";
|
||||
"invalidemailwarn" = "O email informado é inválido";
|
||||
"new" = "novo";
|
||||
"Preferred Phone" = "Telefone Preferencial";
|
||||
|
||||
"Move To" = "Move To";
|
||||
"Copy To" = "Copy To";
|
||||
"Add to:" = "Add to:";
|
||||
"Move To" = "Mover para";
|
||||
"Copy To" = "Copiar para";
|
||||
"Add to:" = "Adicionar em:";
|
||||
|
||||
/* Tooltips */
|
||||
|
||||
|
@ -50,14 +50,14 @@
|
|||
"Edit the selected card" = "Edita o contato selecionado";
|
||||
"Send a mail message" = "Envia uma mensagem de email";
|
||||
"Delete selected card or address book" = "Apaga o contato ou catálogo selecionado";
|
||||
"Reload all contacts" = "Reload all contacts";
|
||||
"Reload all contacts" = "Recarregar todos os contatos";
|
||||
|
||||
"htmlMailFormat_UNKNOWN" = "Desconhecido";
|
||||
"htmlMailFormat_FALSE" = "Texto Puro";
|
||||
"htmlMailFormat_TRUE" = "HTML";
|
||||
|
||||
"Name or Email" = "Nome ou Email";
|
||||
"Category" = "Category";
|
||||
"Category" = "Categoria";
|
||||
"Personal Addressbook" = "Catálogo Pessoal";
|
||||
"Search in Addressbook" = "Localizar no Catálogo";
|
||||
|
||||
|
@ -76,15 +76,15 @@
|
|||
"No possible subscription" = "Sem possibilidades de inscrição";
|
||||
|
||||
"Preferred" = "Preferido";
|
||||
"Display:" = "Display:";
|
||||
"Display:" = "Exibição:";
|
||||
"Display Name:" = "Exibir Nome:";
|
||||
"Email:" = "Endereço de Email:";
|
||||
"Additional Email:" = "Additional Email:";
|
||||
"Additional Email:" = "Email Adicional:";
|
||||
|
||||
"Phone Number:" = "Phone Number:";
|
||||
"Prefers to receive messages formatted as:" = "Prefers to receive messages formatted as:";
|
||||
"Screen Name:" = "Screen Name:";
|
||||
"Categories:" = "Categories:";
|
||||
"Phone Number:" = "Telefone:";
|
||||
"Prefers to receive messages formatted as:" = "Prefere receber mensagens formatadas como:";
|
||||
"Screen Name:" = "Nome de Exibição:";
|
||||
"Categories:" = "Categorias:";
|
||||
|
||||
"First:" = "Primeiro Nome:";
|
||||
"Last:" = "Último Nome:";
|
||||
|
@ -98,22 +98,22 @@
|
|||
"Pager:" = "Pager:";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Colleague, Competitor, Customer, Friend, Family, Business Partner, Provider, Press, VIP";
|
||||
"Categories" = "Categories";
|
||||
"New category" = "New category";
|
||||
"contacts_category_labels" = "Colega, Concorrente, Cliente, Amigo, Família, Parceiro de Negócios, Provedor, Press, VIP";
|
||||
"Categories" = "Categorias";
|
||||
"New category" = "Nova categoria";
|
||||
|
||||
/* adresses */
|
||||
"Title:" = "Título:";
|
||||
"Service:" = "Serviço:";
|
||||
"Company:" = "Empresa:";
|
||||
"Department:" = "Department:";
|
||||
"Organization:" = "Organization:";
|
||||
"Department:" = "Departamento";
|
||||
"Organization:" = "Organização";
|
||||
"Address:" = "Endereço:";
|
||||
"City:" = "Cidade:";
|
||||
"State_Province:" = "Estado:";
|
||||
"ZIP_Postal Code:" = "CEP:";
|
||||
"Country:" = "País:";
|
||||
"Web Page:" = "Web Page:";
|
||||
"Web Page:" = "Página Web:";
|
||||
|
||||
"Work" = "Comercial";
|
||||
"Other Infos" = "Outras Informações";
|
||||
|
@ -125,7 +125,7 @@
|
|||
"Freebusy URL:" = "URL Livre/Ocupado:";
|
||||
|
||||
"Add as..." = "Adicionar como...";
|
||||
"Recipient" = "Recipient";
|
||||
"Recipient" = "Destinatário";
|
||||
"Carbon Copy" = "Cópia Carbono";
|
||||
"Blind Carbon Copy" = "Cópia Carbono Oculta";
|
||||
|
||||
|
@ -158,8 +158,8 @@
|
|||
"Access rights to" = "Direitos de acesso para";
|
||||
"For user" = "Para usuário";
|
||||
|
||||
"Any Authenticated User" = "Any Authenticated User";
|
||||
"Public Access" = "Public Access";
|
||||
"Any Authenticated User" = "Qualquer Usuário Autenticado";
|
||||
"Public Access" = "Acesso Público";
|
||||
|
||||
"This person can add cards to this addressbook."
|
||||
= "Essa pessoa pode adicionar contatos ao meu catálogo.";
|
||||
|
@ -185,25 +185,25 @@
|
|||
"Unknown Destination Folder" = "O catálogo de destino selecionado não existe.";
|
||||
|
||||
/* Lists */
|
||||
"List details" = "List details";
|
||||
"List name:" = "List name:";
|
||||
"List nickname:" = "List nickname:";
|
||||
"List description:" = "List description:";
|
||||
"Members" = "Members";
|
||||
"Contacts" = "Contacts";
|
||||
"Add" = "Add";
|
||||
"Lists can't be moved or copied." = "Lists can't be moved or copied.";
|
||||
"Export" = "Export";
|
||||
"Export Address Book..." = "Export Address Book...";
|
||||
"List details" = "Detalhes da lista";
|
||||
"List name:" = "Lista nome:";
|
||||
"List nickname:" = "Lista Apelido:";
|
||||
"List description:" = "Lista descrição:";
|
||||
"Members" = "Membros";
|
||||
"Contacts" = "Contatos";
|
||||
"Add" = "Adicionar";
|
||||
"Lists can't be moved or copied." = "As listas não podem ser movidos ou copiados.";
|
||||
"Export" = "Exportar";
|
||||
"Export Address Book..." = "Exportar Catálogo de Endereço...";
|
||||
"View Raw Source" = "Visualizar Fonte";
|
||||
"Import Cards" = "Import Cards";
|
||||
"Select a vCard or LDIF file." = "Select a vCard or LDIF file.";
|
||||
"Upload" = "Upload";
|
||||
"Import Cards" = "Importar cartões";
|
||||
"Select a vCard or LDIF file." = "Selecione um arquivo vCard ou LDIF.";
|
||||
"Upload" = "Carregar";
|
||||
"Uploading" = "Carregando";
|
||||
"Done" = "Done";
|
||||
"An error occured while importing contacts." = "An error occured while importing contacts.";
|
||||
"No card was imported." = "No card was imported.";
|
||||
"A total of %{0} cards were imported in the addressbook." = "A total of %{0} cards were imported in the addressbook.";
|
||||
"Done" = "Pronto";
|
||||
"An error occured while importing contacts." = "Ocorreu um erro ao importar contatos.";
|
||||
"No card was imported." = "Nenhum cartão foi importado.";
|
||||
"A total of %{0} cards were imported in the addressbook." = "Um total de %{0} cartões foram importados no catálogo de endereços.";
|
||||
|
||||
"Reload" = "Atualizar";
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ BUNDLE_NAME = ContactsUI
|
|||
|
||||
ContactsUI_PRINCIPAL_CLASS = ContactsUIProduct
|
||||
|
||||
ContactsUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
ContactsUI_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
ContactsUI_OBJC_FILES = \
|
||||
UIxContactsUserFolders.m \
|
||||
|
|
48
UI/MailPartViewers/Basque.lproj/Localizable.strings
Normal file
48
UI/MailPartViewers/Basque.lproj/Localizable.strings
Normal file
|
@ -0,0 +1,48 @@
|
|||
ACCEPTED = "onartua";
|
||||
COMPLETED = "amaitua";
|
||||
DECLINED = "gaitzetsia";
|
||||
DELEGATED = "delegatua";
|
||||
"IN-PROCESS" = "prozesuan";
|
||||
"NEEDS-ACTION" = "ekintza behar du";
|
||||
TENTATIVE = "behin-behineko";
|
||||
organized_by_you = "zuk antolatua";
|
||||
you_are_an_attendee = "Partaidea zera";
|
||||
add_info_text = "SOGo-k ez du iMIP 'ADD' eskaerarik onartzen";
|
||||
publish_info_text = "Bidaltzaileak atxikitutako ekitaldiari buruz jakinarazten zaitu.";
|
||||
cancel_info_text = "Zure gonbidapena edo ekitaldi osoa bertan behera utzi da.";
|
||||
request_info_no_attendee = "partaideei topaketa bat proposatzen die. Email hau jakinarazpen bezala jasotzen duzu, ez zaude partaide bezala programatua";
|
||||
Appointment = "Hitzordua";
|
||||
"Status Update" = "Egoera eguneraketa";
|
||||
was = "zen";
|
||||
|
||||
Organizer = "Antolatzailea";
|
||||
Time = "Ordua";
|
||||
Attendees = "Partaideak";
|
||||
request_info = "bileran parte-hartzera gonbidatzen zaitu.";
|
||||
"Add to calendar" = "Egutegira gehitu";
|
||||
"Delete from calendar" = "Egutegitik ezabatu";
|
||||
"Update status" = "Egoera eguneratu";
|
||||
Accept = "Onartu";
|
||||
Decline = "Uko egin";
|
||||
Tentative = "Behin-behineko";
|
||||
"Delegate ..." = "Delegatu ...";
|
||||
"Delegated to" = "Beste honen esku utzia";
|
||||
"Update status in calendar" = "Egoera egunerartu egutegian";
|
||||
"delegated from" = "Beste honek zure esku utzia";
|
||||
|
||||
reply_info_no_attendee = "Ekitaldi planifikazio bati erantzuna jaso duzu baina erantzunaren bidaltzailea ez da parte-hartzailea.";
|
||||
reply_info = "Zuk egindako gonbidapen bati erantzuna da hau.";
|
||||
|
||||
"to" = "nori";
|
||||
|
||||
"Untitled" = "Izenburu-gabea";
|
||||
|
||||
"Size" = "Tamaina";
|
||||
|
||||
"Digital signature is not valid" = "Sinadura digitala ez da baliozkoa";
|
||||
"Message is signed" = "Mezua sinatua dago";
|
||||
"Subject" = "Gaia";
|
||||
"From" = "Nork";
|
||||
"Date" = "Data";
|
||||
"To" = "Nori";
|
||||
"Issuer" = "jaulkitzailea";
|
|
@ -10,7 +10,7 @@ you_are_an_attendee = "você é um participante";
|
|||
add_info_text = "As solicitações iMIP 'ADD' ainda não são suportadas pelo SOGo.";
|
||||
publish_info_text = "O solicitante lhe informa sobre um evento anexo.";
|
||||
cancel_info_text = "Seu convite ou evento foi cancelado.";
|
||||
request_info_no_attendee = "está propondo um reunião aos participantes. Você está recebendo este email como uma notificação, você não está agendado como um particiopante.";
|
||||
request_info_no_attendee = "está propondo uma reunião aos participantes. Você está recebendo este email como uma notificação, você não está agendado como um particiopante.";
|
||||
Appointment = "Apontamento";
|
||||
"Status Update" = "Status da Atualização";
|
||||
was = "foi";
|
||||
|
|
|
@ -6,7 +6,7 @@ BUNDLE_NAME = MailPartViewers
|
|||
|
||||
MailPartViewers_PRINCIPAL_CLASS = MailPartViewersProduct
|
||||
|
||||
MailPartViewers_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
MailPartViewers_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
MailPartViewers_OBJC_FILES += \
|
||||
MailPartViewersProduct.m \
|
||||
|
|
308
UI/MailerUI/Basque.lproj/Localizable.strings
Normal file
308
UI/MailerUI/Basque.lproj/Localizable.strings
Normal file
|
@ -0,0 +1,308 @@
|
|||
/* this file is in UTF-8 format! */
|
||||
|
||||
/* Icon's label */
|
||||
"Create" = "Sortu";
|
||||
"Empty Trash" = "Hustu zakarrontzia";
|
||||
"Delete" = "Ezabatu";
|
||||
"Expunge" = "Suntsitu";
|
||||
"Forward" = "Birbidali";
|
||||
"Get Mail" = "Eskuratu mezuak";
|
||||
"Junk" = "Zaborra";
|
||||
"Reply" = "Erantzun";
|
||||
"Reply All" = "Erantzun denei";
|
||||
"Print" = "Inprimatu";
|
||||
"Stop" = "Gelditu";
|
||||
"Write" = "Idatzi";
|
||||
"Search" = "Bilatu";
|
||||
|
||||
"Send" = "Bidali";
|
||||
"Contacts" = "Kontaktuak";
|
||||
"Attach" = "Erantsi";
|
||||
"Save" = "Gorde";
|
||||
"Options" = "Aukerak";
|
||||
"Close" = "Itxi";
|
||||
"Size" = "Tamaina";
|
||||
|
||||
/* Tooltips */
|
||||
|
||||
"Send this message now" = "Bidali mezu hau orain";
|
||||
"Select a recipient from an Address Book" = "Aukeratu jasotzailea Helbide-liburu batetik";
|
||||
"Include an attachment" = "Erantsi eranskin bat";
|
||||
"Save this message" = "Gorde mezu hau";
|
||||
"Get new messages" = "Eskuratu mezu berriak";
|
||||
"Create a new message" = "Sortu mezu berria";
|
||||
"Go to address book" = "Joan helbide liburura";
|
||||
"Reply to the message" = "Erantzun mezuari";
|
||||
"Reply to sender and all recipients" = "Erantzun bidaltzaile eta jasotzaile guztiei";
|
||||
"Forward selected message" = "Birbidali aukeratutako mezua";
|
||||
"Delete selected message or folder" = "Ezabatu aukeratutako mezu edo karpeta";
|
||||
"Mark the selected messages as junk" = "Markatu aukeratutako mezua zabor-posta gisa";
|
||||
"Print this message" = "Inprimatu mezu hau";
|
||||
"Stop the current transfer" = "Gelditu uneko transferentzia";
|
||||
"Attachment" = "Eranskina";
|
||||
"Unread" = "Irakurri-gabea";
|
||||
"Flagged" = "Bandera dauka";
|
||||
"Search multiple mailboxes" = "Bilatu postontzi anitzetan";
|
||||
|
||||
/* Main Frame */
|
||||
|
||||
"Home" = "Hasiera";
|
||||
"Calendar" = "Egutegia";
|
||||
"Addressbook" = "Helbide liburua";
|
||||
"Mail" = "Emaila";
|
||||
"Right Administration" = "Eskubideen kudeaketa";
|
||||
|
||||
"Help" = "Laguntza";
|
||||
|
||||
/* Mail account main windows */
|
||||
|
||||
"Welcome to the SOGo Mailer. Use the folder tree on the left to browse your mail accounts!" = "Ongi etorria SOGo webmail-era. Erabili ezkerreko zuhaitza zure email kontuak arakatzeko ";
|
||||
|
||||
"Read messages" = "Irakurri mezuak";
|
||||
"Write a new message" = "Idatzi mezu berria";
|
||||
|
||||
"Share: " = "Partekatu:";
|
||||
"Account: " = "Kontua:";
|
||||
"Shared Account: " = "Partekatutako kontua:";
|
||||
|
||||
/* acls */
|
||||
"Access rights to" = "Atzipen baimenak honi";
|
||||
"For user" = "Erabiltzailearentzat";
|
||||
|
||||
"Any Authenticated User" = "Autentifikatutako edozein erabiltzaile";
|
||||
|
||||
"List and see this folder" = "Zerrendatu eta ikuskatu karpeta hau";
|
||||
"Read mails from this folder" = "Irakurri karpeta honetako mezuak";
|
||||
"Mark mails read and unread" = "Markatu mezuak irakurrita eta irakurri gabeko gisa";
|
||||
"Modify the flags of the mails in this folder" = "Karpeta honetako mezuen banderak aldatu.";
|
||||
"Insert, copy and move mails into this folder" = "Txertatu, kopiatu eta mugitu mezuak karpeta honetara";
|
||||
"Post mails" = "Bidali emailak";
|
||||
"Add subfolders to this folder" = "Sortu azpikarpetak karpeta honetan";
|
||||
"Remove this folder" = "Ezabatu karpeta hau";
|
||||
"Erase mails from this folder" = "Ezabatu karpeta honetako mezuak";
|
||||
"Expunge this folder" = "Suntsitu karpeta honetako mezuak";
|
||||
"Export This Folder" = "Esportatu karpeta hau";
|
||||
"Modify the acl of this folder" = "Karpeta honen ACL-ak aldatu";
|
||||
|
||||
"Saved Messages.zip" = "Gorde Messages.zip";
|
||||
|
||||
"Update" = "Eguneratu";
|
||||
"Cancel" = "Ezeztatu";
|
||||
|
||||
/* Mail edition */
|
||||
|
||||
"From" = "Nork";
|
||||
"Subject" = "Gaia";
|
||||
"To" = "Nori";
|
||||
"Cc" = "Kopia";
|
||||
"Bcc" = "Izkutuko kopia";
|
||||
"Reply-To" = "Erantzun-honi";
|
||||
"Add address" = "Gehitu helbidea";
|
||||
"Body" = "Gorputza";
|
||||
|
||||
"Open" = "Ireki";
|
||||
"Select All" = "Denak aukeratu";
|
||||
"Attach Web Page..." = "Erantsi Web Orria ...";
|
||||
"file" = "fitxategia";
|
||||
"files" = "fitxategiak";
|
||||
"Save all" = "Dena gorde";
|
||||
|
||||
"to" = "Nori";
|
||||
"cc" = "Kopia";
|
||||
"bcc" = "Izkutuko kopia";
|
||||
|
||||
"Edit Draft..." = "Aldatu zirriborroa...";
|
||||
"Load Images" = "Kargatu irudiak";
|
||||
|
||||
"Return Receipt" = "Jasotze agiria";
|
||||
"The sender of this message has asked to be notified when you read this message. Do you with to notify the sender?" = "Mezu honen bidaltzaileak mezua irakurtzen duzunean jakinarazia izan nahi du. Jakinarazpena bidali nahi diozu?";
|
||||
"Return Receipt (displayed) - %@"= "Jasotze agiria (bistaratua) - %@";
|
||||
"This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents." = "Honako hau zuk %@-ri bidalitako mezuaren jasotze-agiria da.\n\nOharra: Jasotze agiri honek mezua jasotzailearen ordenagailuan bistaratu dela bakarrik ziurtatzen du. Ezin da ziurtatu jasotzaileak mezuaren edukia irakurri edota ulertu duenik.";
|
||||
|
||||
"Priority" = "Lehentasuna";
|
||||
"highest" = "Altuena";
|
||||
"high" = "Altua";
|
||||
"normal" = "Arrunta";
|
||||
"low" = "Baxua";
|
||||
"lowest" = "Baxuena";
|
||||
|
||||
"This mail is being sent from an unsecure network!" = "Mezu hau sare ez-seguru bat erabiliz hari zara bidaltzen!";
|
||||
|
||||
"Address Book:" = "Helbide Liburua";
|
||||
"Search For:" = "Bilatu hau:";
|
||||
|
||||
/* Popup "show" */
|
||||
|
||||
"all" = "denak";
|
||||
"read" = "irakurria";
|
||||
"unread" = "irakurri-gabea";
|
||||
"deleted" = "ezabatua";
|
||||
"flagged" = "bandera dauka";
|
||||
|
||||
/* MailListView */
|
||||
|
||||
"Sender" = "Bidaltzailea";
|
||||
"Subject or Sender" = "Gaia edo Bidaltzailea";
|
||||
"To or Cc" = "Nori edo kopia";
|
||||
"Entire Message" = "Mezu osoa";
|
||||
|
||||
"Date" = "Data";
|
||||
"View" = "Ikuskatu";
|
||||
"All" = "Denak";
|
||||
"No message" = "Mezurik ez";
|
||||
"messages" = "mezuak";
|
||||
|
||||
"first" = "Lehenengoa";
|
||||
"previous" = "Aurrekoa";
|
||||
"next" = "Hurrengoa";
|
||||
"last" = "Azkena";
|
||||
|
||||
"msgnumber_to" = "nori";
|
||||
"msgnumber_of" = "nork";
|
||||
|
||||
"Mark Unread" = "Markatu irakurri-gabeko gisa";
|
||||
"Mark Read" = "Markatu irakurri gisa";
|
||||
|
||||
"Untitled" = "Izenburu gabe";
|
||||
|
||||
/* Tree */
|
||||
|
||||
"SentFolderName" = "Bidalia";
|
||||
"TrashFolderName" = "Zakarrontzia";
|
||||
"InboxFolderName" = "Sarrera";
|
||||
"DraftsFolderName" = "Zirriborroak";
|
||||
"SieveFolderName" = "Iragazkiak";
|
||||
"Folders" = "Karpetak"; /* title line */
|
||||
|
||||
/* MailMoveToPopUp */
|
||||
|
||||
"MoveTo" = "Mugitu …";
|
||||
|
||||
/* Address Popup menu */
|
||||
"Add to Address Book..." = "Gehitu helbide liburuan...";
|
||||
"Compose Mail To" = "Idatzi mezua honi";
|
||||
"Create Filter From Message..." = "Sortu iragazkia mezua erabiliz...";
|
||||
|
||||
/* Image Popup menu */
|
||||
"Save Image" = "Gorde mezua";
|
||||
"Save Attachment" = "Gorde eranskina";
|
||||
|
||||
/* Mailbox popup menus */
|
||||
"Open in New Mail Window" = "Ireki \"mezu berri\" leihoan";
|
||||
"Copy Folder Location" = "Kopiatu karpetaren kokapena";
|
||||
"Subscribe..." = "Harpidetu...";
|
||||
"Mark Folder Read" = "Markatu karpeta irakurri gisa";
|
||||
"New Folder..." = "karpeta berria";
|
||||
"Compact This Folder" = "Trinkotu karpeta hau";
|
||||
"Search Messages..." = "Bilatu mezuak...";
|
||||
"Sharing..." = "Partekatzea....";
|
||||
"New Subfolder..." = "Azpikarpeta berria...";
|
||||
"Rename Folder..." = "Karpeta berrizendatu...";
|
||||
"Delete Folder" = "Ezabatu karpeta";
|
||||
"Use This Folder For" = "Erabili karpeta hau ";
|
||||
"Get Messages for Account" = "Eskuratu kontu honen mezuak";
|
||||
"Properties..." = "Ezaugarriak...";
|
||||
"Delegation..." = "Ordezkaritza ...";
|
||||
|
||||
/* Use This Folder menu */
|
||||
"Sent Messages" = "Bidalitako mezuak";
|
||||
"Drafts" = "Zirriborroak";
|
||||
"Deleted Messages" = "Ezabatutako mezuak";
|
||||
|
||||
/* Message list popup menu */
|
||||
"Open Message In New Window" = "Ireki mezua leiho berrian";
|
||||
"Reply to Sender Only" = "Erantzun bidaltzaileari soilik";
|
||||
"Reply to All" = "Erantzun denei";
|
||||
"Edit As New..." = "Editatu mezu berri bezala...";
|
||||
"Move To" = "Mugitu hona";
|
||||
"Copy To" = "Kopiatu hona";
|
||||
"Label" = "Etiketa";
|
||||
"Mark" = "Markatu";
|
||||
"Save As..." = "Gorde honela...";
|
||||
"Print Preview" = "Inprimatzeko aurrebista";
|
||||
"View Message Source" = "Ikusi mezuaren iturburua";
|
||||
"Print..." = "Inprimatu...";
|
||||
"Delete Message" = "Ezabatu mezua";
|
||||
"Delete Selected Messages" = "Ezabatu aukeratutako mezuak";
|
||||
|
||||
"This Folder" = "Karpeta hau";
|
||||
|
||||
/* Label popup menu */
|
||||
"None" = "Bat ere ez";
|
||||
|
||||
/* Mark popup menu */
|
||||
"As Read" = "Irakurri gisa";
|
||||
"Thread As Read" = "Haria irakurri gisa";
|
||||
"As Read By Date..." = "Data bidez irakurritako gisa...";
|
||||
"All Read" = "Denak irakurrita";
|
||||
"Flag" = "Bandera";
|
||||
"As Junk" = "Zabor-posta gisa";
|
||||
"As Not Junk" = "ez zaborra gisa";
|
||||
"Run Junk Mail Controls" = "Exekutatu zabor-posta kontrolak";
|
||||
|
||||
"Search messages in:" = "Bilatu mezuak hemen:";
|
||||
"Search" = "Bilatu";
|
||||
"Search subfolders" = "Bilatu azpikarpetak";
|
||||
"Match any of the following" = "Irizpide hauetako edozein betetzen dituztenak";
|
||||
"Match all of the following" = "Irizpide guzti hauek betetzen dituztenak";
|
||||
"contains" = "dauka";
|
||||
"does not contain" = "ez dauka";
|
||||
"No matches found" = "Ez da emaitzarik aurkitu";
|
||||
"results found" = "emaitza topatu dira";
|
||||
"result found" = "emaitza topatu da";
|
||||
"Please specify at least one filter" = "Mesedez, zehaztu gutxienez iragazki bat";
|
||||
|
||||
/* Folder operations */
|
||||
"Name :" = "Izena:";
|
||||
"Enter the new name of your folder :"
|
||||
= "Idatzi zure karpetaren izen berria:";
|
||||
"Do you really want to move this folder into the trash ?"
|
||||
= "Ziur zaude karpeta hau zakarrontzira mugitu nahi duzula?";
|
||||
"Operation failed" = "Eragiketak huts egin du";
|
||||
|
||||
"Quota" = "Kuota";
|
||||
"quotasFormat" = "%{0}% erabilia %{1}-n MB ";
|
||||
|
||||
"Please select a message." = "Mesedez, aukeratu mezu bat.";
|
||||
"Please select a message to print." = "Mesedez, aukeratu inprimatzeko mezu bat.";
|
||||
"Please select only one message to print." = "Mesdez, aukeratu inprimatzekom mezu bakarra.";
|
||||
"The message you have selected doesn't exist anymore." = "Aukertutako mezua jada ez da existitzen";
|
||||
|
||||
"The folder with name \"%{0}\" could not be created."
|
||||
= "\"%{0}\" izeneko karpeta ezin izan da sortu";
|
||||
"This folder could not be renamed to \"%{0}\"."
|
||||
= "Karpeta hau ezin izan da \"%{0}\"-ra berrizendatu.";
|
||||
"The folder could not be deleted."
|
||||
= "Karpeta ezin izan da ezabatu.";
|
||||
"The trash could not be emptied."
|
||||
= "Zakarrontzia ezin izan da hustu.";
|
||||
"The folder functionality could not be changed."
|
||||
= "Karpetaren funtzionalitatea ezin izan da aldatu.";
|
||||
|
||||
"You need to choose a non-virtual folder!" = "Karpeta ez-birtual bat aukeratu behar duzu!";
|
||||
|
||||
"Moving a message into its own folder is impossible!"
|
||||
= "Mezu bat bere karpeta berera ezin da mugitu!";
|
||||
"Copying a message into its own folder is impossible!"
|
||||
= "Mezu bat ezin da bere karpetara kopiatu!";
|
||||
|
||||
/* Message operations */
|
||||
"The messages could not be moved to the trash folder. Would you like to delete them immediately?"
|
||||
= "Mezuak ezin izan dira zakarrontzira mugitu. Berehala ezabatu nahi dituzu?";
|
||||
|
||||
/* Message editing */
|
||||
"error_missingsubject" = "Mezuak ez dauka gairik. Ziur zaude horrela bidali nahi duzula?";
|
||||
"error_missingrecipients" = "Mesedez, zehaztu gutxienez jasotzaile bat.";
|
||||
"Send Anyway" = "Bidali hala ere";
|
||||
"Error while saving the draft:" = "Errorea zirriborroa gordetzerakoan:";
|
||||
"Error while uploading the file \"%{0}\":" = "Errorea \"%{0}\" fitxategia igotzerakoan:";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Fitxategi igoera aktibo bat dago. Leihoa ixteak etengo du.";
|
||||
|
||||
/* Message sending */
|
||||
"cannot send message: (smtp) all recipients discarded" = "Ezin izan da mezua bidali: jasotzaile guztiak baliogabeak dira.";
|
||||
"cannot send message (smtp) - recipients discarded:" = "Ezin izan da mezua bidali. Ondorengo jasotzaileak ez dira baliozkoak:";
|
||||
"cannot send message: (smtp) error when connecting" = "Ezin izan da mezua bidali: errorea SMTP zerbitzarira konektatzean.";
|
||||
|
||||
/* Contacts list in mail editor */
|
||||
"Email" = "Emaila";
|
||||
"Name" = "Izena";
|
|
@ -26,7 +26,7 @@
|
|||
/* Tooltips */
|
||||
|
||||
"Send this message now" = "Envia esta mensagem agora";
|
||||
"Select a recipient from an Address Book" = "Seleciona um destinatário de a partir de um Catálogo";
|
||||
"Select a recipient from an Address Book" = "Seleciona um destinatário de catálogo de endereços";
|
||||
"Include an attachment" = "Inclui um anexo";
|
||||
"Save this message" = "Salva esta mensagem";
|
||||
"Get new messages" = "Receber novas mensagens";
|
||||
|
@ -95,7 +95,7 @@
|
|||
"Subject" = "Assunto";
|
||||
"To" = "Para";
|
||||
"Cc" = "Cc";
|
||||
"Bcc" = "Bcc";
|
||||
"Bcc" = "Cco";
|
||||
"Reply-To" = "Responder-Para";
|
||||
"Add address" = "Adicionar endereço";
|
||||
"Body" = "Corpo";
|
||||
|
@ -109,7 +109,7 @@
|
|||
|
||||
"to" = "Para";
|
||||
"cc" = "Cc";
|
||||
"bcc" = "Bcc";
|
||||
"bcc" = "Cco";
|
||||
|
||||
"Edit Draft..." = "Editar Rascunho...";
|
||||
"Load Images" = "Carregar Imagens";
|
||||
|
@ -180,7 +180,7 @@
|
|||
|
||||
/* Address Popup menu */
|
||||
"Add to Address Book..." = "Adicionar ao Catálogo...";
|
||||
"Compose Mail To" = "Escrever Mensagem Parana";
|
||||
"Compose Mail To" = "Escrever Mensagem Para";
|
||||
"Create Filter From Message..." = "Criar Filtro Da Mensagem...";
|
||||
|
||||
/* Image Popup menu */
|
||||
|
@ -261,7 +261,7 @@
|
|||
"Operation failed" = "Falha na Operação";
|
||||
|
||||
"Quota" = "Quota:";
|
||||
"quotasFormat" = "%{0}% usedo em %{1} MB";
|
||||
"quotasFormat" = "%{0}% usado em %{1} MB";
|
||||
|
||||
"Please select a message." = "Por favor, selecione uma mensagem.";
|
||||
"Please select a message to print." = "Por favor, selecione a mensagem para imprimir.";
|
||||
|
|
|
@ -6,7 +6,7 @@ BUNDLE_NAME = MailerUI
|
|||
|
||||
MailerUI_PRINCIPAL_CLASS = MailerUIProduct
|
||||
|
||||
MailerUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
MailerUI_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
MailerUI_OBJC_FILES += \
|
||||
MailerUIProduct.m \
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
"Send" = "Send";
|
||||
"Contacts" = "Kontakter";
|
||||
"Attach" = "Vedlegg ved";
|
||||
"Attach" = "Vedlegg";
|
||||
"Save" = "Lagre";
|
||||
"Options" = "Innstillinger";
|
||||
"Close" = "Lukk";
|
||||
|
|
|
@ -163,7 +163,7 @@
|
|||
co = [self clientObject];
|
||||
us = [[context activeUser] userSettings];
|
||||
if (!(moduleSettings = [us objectForKey: @"Mail"]))
|
||||
[us setObject:[NSMutableDictionary dictionnary] forKey: @"Mail"];
|
||||
[us setObject:[NSMutableDictionary dictionary] forKey: @"Mail"];
|
||||
|
||||
if (isCollapsing)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "اللغة:";
|
||||
"choose" = "إختار ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
35
UI/MainUI/Basque.lproj/Locale
Normal file
35
UI/MainUI/Basque.lproj/Locale
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* English */
|
||||
{
|
||||
NSLanguageName = "Basque";
|
||||
NSFormalName = "Euskara";
|
||||
NSLocaleCode = "eu"; /* ISO 639-1 */
|
||||
NSLanguageCode = "eus"; /* ISO 639-2 */
|
||||
NSParentContext = "";
|
||||
|
||||
NSAMPMDesignation = (AM, PM);
|
||||
NSCurrencySymbol = " €";
|
||||
NSDateFormatString = "%A, %B %e, %Y";
|
||||
NSDateTimeOrdering = YMDH;
|
||||
NSDecimalDigits = ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
|
||||
NSDecimalSeparator = ",";
|
||||
NSEarlierTimeDesignations = ("aurreko", "azken", "joan den", "duela");
|
||||
NSHourNameDesignations = ((0, gauerdia), (10, goiza), (12, eguerdia), (14, arratsaldea), (19, gaua));
|
||||
NSInternationalCurrencyString = EUR; /* ISO 4217 */
|
||||
NSLaterTimeDesignations = ("hurrengo", "ondorengo", "datorren");
|
||||
NSMonthNameArray = (Urtarrila, Otsaila, Martxoa, Apirila, Maiatza, Ekaina, Uztaila, Abuztua, Iraila, Urria, Azaroa, Abendua);
|
||||
NSNextDayDesignations = (bihar);
|
||||
NSNextNextDayDesignations = ("hurrengo eguna");
|
||||
NSPriorDayDesignations = (atzo);
|
||||
NSShortDateFormatString = "%y/%m/%e";
|
||||
NSShortMonthNameArray = (Urt, Ots, Mar, Apr, Mai, Eka, Uzt, Abu, Ira, Urr, Aza, Abe);
|
||||
NSShortTimeDateFormatString = "%/%m/%e %I:%M %p";
|
||||
NSShortWeekDayNameArray = (Ig, Al, As, Az, Os, Or, Ig);
|
||||
NSThisDayDesignations = (gaur);
|
||||
NSThousandsSeparator = ".";
|
||||
NSTimeDateFormatString = "%A, %B %e, %Y %I:%M:%S %p %Z";
|
||||
NSTimeFormatString = "%I:%M:%S %p";
|
||||
NSWeekDayNameArray = (Igandea, Astelehena, Asteartea, Asteazkena, Osteguna, Ostirala, Larunbata);
|
||||
NSYearMonthWeekDesignations = (urtea, hilabetea, astea);
|
||||
NSPositiveCurrencyFormatString = "9.999,00$";
|
||||
NSNegativeCurrencyFormatString = "-9.999,00$";
|
||||
}
|
78
UI/MainUI/Basque.lproj/Localizable.strings
Normal file
78
UI/MainUI/Basque.lproj/Localizable.strings
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* this file is in UTF-8 format! */
|
||||
|
||||
"title" = "SOGo";
|
||||
|
||||
"Username:" = "Erabiltzailea:";
|
||||
"Password:" = "Pasahitza:";
|
||||
"Domain:" = "Domeinua";
|
||||
"Remember username" = "Gogoratu erabiltzaile-izena";
|
||||
|
||||
"Connect" = "Konektatu";
|
||||
|
||||
"Wrong username or password." = "Erabiltzaile edo pasahitz okerrak";
|
||||
"cookiesNotEnabled" = "Ezin zara sartu zure arakatzailearen 'cookie'-ak desgaituta daudelako. Mesedez, gaitu 'cookie'-ak zure arakatzailearen ezarpenetan.";
|
||||
|
||||
"browserNotCompatible" = "Zure arakatzailearen bertsioa ez da onartzen webgune honetan. Gure gomendioa Firefox erabiltzea da. Klikatu ondorengo estekan arakatzaile honen bertsio berriena jeisteko.";
|
||||
"alternativeBrowsers" = "Aukeran, honako beste arakatzaileak erabili ditzakezu";
|
||||
"alternativeBrowserSafari" = "Aukeran, Safari arakatzailea erabili dezakezu ere.";
|
||||
"Download" = "Deskargatu";
|
||||
|
||||
"Language:" = "Hizkuntza";
|
||||
"choose" = "Aukeratu ...";
|
||||
"Arabic" = "العربية";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
"Dutch" = "Nederlands";
|
||||
"English" = "English";
|
||||
"Finnish" = "Suomi";
|
||||
"French" = "Français";
|
||||
"German" = "Deutsch";
|
||||
"Hungarian" = "Magyar";
|
||||
"Icelandic" = "Íslenska";
|
||||
"Italian" = "Italiano";
|
||||
"NorwegianBokmal" = "Norsk bokmål";
|
||||
"NorwegianNynorsk" = "Norsk nynorsk";
|
||||
"Polish" = "Polski";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Slovak" = "Slovensky";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
"SpanishArgentina" = "Español (Argentina)";
|
||||
"Swedish" = "Svenska";
|
||||
"Ukrainian" = "Українська";
|
||||
"Welsh" = "Cymraeg";
|
||||
|
||||
"About" = "Honi buruz";
|
||||
"AboutBox" = "Inverse-k garatua. SOGo ezaugarri guztidun groupware zerbitzaria da, eskalagarritasunean eta simpletasunean bideratzen dena.<br/><br/>\nSOGo-k AJAX-ean oinarritutako web interfaze aberatsa eskeintzen du eta jatorrizko bezero anitz onartzen ditu ValDAv eta CardDAV bezalako protokolo estandarrak erabiliz. <br/><br/>\nSOGo <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> 2. bertsio edo berriago lizentziapean dago banatua, eta honen zatiak GNU LGPL 2. bertsio lizentziapean. Software librea da: Askatasun osoa daukazu aldatu eta banatzeko. EZ dago inolako GARANTIARIK, legeak onartzen duen neurrian.<br/><br/>\nLaguntza aukera ezberdinak ikusteko klikatu <a href=\"http://www.sogo.nu/en/support/community.html\">hemen</a> ";
|
||||
|
||||
"Your account was locked due to too many failed attempts." = "Zure kontua blokeatuta dago saiakera oker gehiegi egiteagatik.";
|
||||
"Your account was locked due to an expired password." = "Zure kontua blokeatuta dago pasahitza iraungita dagoelako.";
|
||||
"Login failed due to unhandled error case: " = "Login-ak hutsegin du landu gabeko akats-kasu batengatik:";
|
||||
"Change your Password" = "Aldatu zure pasahitza";
|
||||
"The password was changed successfully." = "Pasahitza ondo aldatu da.";
|
||||
"Your password has expired, please enter a new one below:" = "Zure pasahitza iraungita dago, mesedez sartu pasahitz berria:";
|
||||
"Password must not be empty." = "Pasahitza ezin da hutsa izan.";
|
||||
"The passwords do not match. Please try again." = "Pasahaitzak ez datoz bat. Mesedez, saiatu berriz.";
|
||||
"Password Grace Period" = "Pasahitzaren graziazko aldia";
|
||||
"You have %{0} logins remaining before your account is locked. Please change your password in the preference dialog." = "%{0} saiakera geratzen zaizkizu zure kontua blokeatu aurretik. Mesedez, aldatu pasahitza hoberespenen elkarrizketa-koadroan.";
|
||||
"Password about to expire" = "Pasahitza iraungitzear dago";
|
||||
"Your password is going to expire in %{0} %{1}." = "Zure pasahitza %{0} %{1}-n iraungiko da.";
|
||||
"days" = "egun";
|
||||
"hours" = "ordu";
|
||||
"minutes" = "minutu";
|
||||
"seconds" = "segundu";
|
||||
"Password change failed" = "Pasahitz aldaketak hutsegin du";
|
||||
"Password change failed - Permission denied" = "Pasahitz aldaketak hutsegin du - Baimena ukatua";
|
||||
"Password change failed - Insufficient password quality" = "Pasahitz aldaketak hutsegin du - Pasahitzaren kalitate eskasa";
|
||||
"Password change failed - Password is too short" = "Pasahitz aldaketak hutsegin du - Pasahitz motzegia";
|
||||
"Password change failed - Password is too young" = "Pasahitz aldaketak hutsegin du - Pasahitza berriegia da";
|
||||
"Password change failed - Password is in history" = "Pasahitz aldaketak hutsegin du - Pasahitza historikoan dago";
|
||||
"Unhandled policy error: %{0}" = "Landu gabeko politika errorea: %{0}";
|
||||
"Unhandled error response" = "Landu gabeko errore erantzuna";
|
||||
"Password change is not supported." = "Pasahitz aldaketa ez dago onartua.";
|
||||
"Unhandled HTTP error code: %{0}" = "Landu gabeko HTTP errore kodea: %{0}";
|
||||
"New password:" = "Pasahitz berria";
|
||||
"Confirmation:" = "Berrespena:";
|
||||
"Cancel" = "Ezeztatu";
|
||||
"Please wait..." = "Itxaron mesedez...";
|
|
@ -10,7 +10,7 @@
|
|||
"Connect" = "Conectar";
|
||||
|
||||
"Wrong username or password." = "Usuário ou Senha Inválido.";
|
||||
"cookiesNotEnabled" = "Você não pode logar por a opção cookies está desabilitada. Por favor, habilite os cookies nas configurações de seu navegador e tente novamente.";
|
||||
"cookiesNotEnabled" = "Você não pode logar porque a opção cookies está desabilitada. Por favor, habilite os cookies nas configurações de seu navegador e tente novamente.";
|
||||
|
||||
"browserNotCompatible" = "Foi detectado que a atual versão de seu navegador não é suportado neste site. Recomentamos que use o Firefox. Clique no link abaixo para baixar a versão atual deste navegador.";
|
||||
"alternativeBrowsers" = "Alternativamente, você pode usar os seguinte navegadores compatíveis";
|
||||
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Idioma:";
|
||||
"choose" = "Escolha ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
@ -44,7 +45,7 @@
|
|||
"Welsh" = "Cymraeg";
|
||||
|
||||
"About" = "Sobre";
|
||||
"AboutBox" = "Developed by Inverse, SOGo is a fully-featured groupware server with a focus on scalability and simplicity.<br/><br/>⏎ \nSOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV and CardDAV.<br/><br/>⏎ \nSOGo is distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2 or later and parts are distributed under the GNU LGPL version 2. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.<br/><br/>⏎ \nSee <a href=\"http://www.sogo.nu/en/support/community.html\">this page</a> for various support options.";
|
||||
"AboutBox" = "Desenvolvido por Inverse, Sogo é um servidor de groupware cheio de recursos com foco em escalabilidade e simplicidade.\nSogo fornece uma interface Web baseada em AJAX ricos e suporta vários clientes nativos através da utilização de protocolos padrão como CalDAV e CardDAV.\nSogo é distribuído sob a GNU GPL <a href=\"http://gnu.org/licenses/gpl.html\"> </a> versão 2 ou posterior e as partes são distribuídos sob a GNU LGPL versão 2. Este é um software livre: você é livre para mudar e redistribuí-lo. Não há NENHUMA GARANTIA, até o limite permitido por lei.\nVeja <a href=\"http://www.sogo.nu/en/support/community.html\"> desta página</a> para várias opções de suporte.";
|
||||
|
||||
"Your account was locked due to too many failed attempts." = "Sua conta foi bloqueada devido a muitas tentativas fracassadas.";
|
||||
"Your account was locked due to an expired password." = "Sua conta foi bloqueada devido a uma senha expirada.";
|
||||
|
@ -67,7 +68,7 @@
|
|||
"Password change failed - Insufficient password quality" = "Alteração da senha falhou - Senha muito fraca";
|
||||
"Password change failed - Password is too short" = "Alteração da senha falhou - Senha muito curta";
|
||||
"Password change failed - Password is too young" = "Alteração da senha falhou - Senha usada recentemente";
|
||||
"Password change failed - Password is in history" = "Password is too young - Senha está no histórico";
|
||||
"Password change failed - Password is in history" = "Alteração de senha falhou - Password está no histórico";
|
||||
"Unhandled policy error: %{0}" = "Política de erro não tratada: %{0}";
|
||||
"Unhandled error response" = "Erro de resposta não tratado";
|
||||
"Password change is not supported." = "Alteração da senha não suportada.";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Llengua:";
|
||||
"choose" = "Triar ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Jazyk:";
|
||||
"choose" = "Vybrat ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Sprog:";
|
||||
"choose" = "Vælg ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Taal:";
|
||||
"choose" = "Kies...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Language:";
|
||||
"choose" = "Choose ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Kieli:";
|
||||
"choose" = "Valitse ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Langue:";
|
||||
"choose" = "Choisir ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -6,7 +6,7 @@ BUNDLE_NAME = MainUI
|
|||
|
||||
MainUI_PRINCIPAL_CLASS = MainUIProduct
|
||||
|
||||
MainUI_LANGUAGES = Arabic BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
MainUI_LANGUAGES = Arabic Basque BrazilianPortuguese Catalan Czech Danish Dutch English Finnish French German Hungarian Icelandic Italian NorwegianBokmal NorwegianNynorsk Polish Russian Slovak SpanishSpain SpanishArgentina Swedish Ukrainian Welsh
|
||||
|
||||
MainUI_OBJC_FILES += \
|
||||
MainUIProduct.m \
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Sprache:";
|
||||
"choose" = "Auswählen ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Nyelv:";
|
||||
"choose" = "Válasszon ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"Language:" = "Tungumál:";
|
||||
"choose" = "Velja...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Lingua:";
|
||||
"choose" = "Scegli...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Språk:";
|
||||
"choose" = "Velg ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Språk:";
|
||||
"choose" = "Velg ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Język:";
|
||||
"choose" = "Wybierz ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Язык:";
|
||||
"choose" = "Выбрать ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -52,7 +52,9 @@
|
|||
|
||||
#import <SBJson/NSObject+SBJSON.h>
|
||||
|
||||
#define intervalSeconds 900 /* 15 minutes */
|
||||
#define INTERVALSECONDS 900 /* 15 minutes */
|
||||
#define PADDING 8
|
||||
#define HALFPADDING PADDING/2
|
||||
|
||||
@interface SOGoUserHomePage : UIxComponent
|
||||
|
||||
|
@ -151,23 +153,23 @@
|
|||
startInterval = 0;
|
||||
else
|
||||
startInterval = ([currentDate timeIntervalSinceDate: startDate]
|
||||
/ intervalSeconds);
|
||||
/ INTERVALSECONDS);
|
||||
|
||||
delta = [[currentDate timeZoneDetail] timeZoneSecondsFromGMT] - [[startDate timeZoneDetail] timeZoneSecondsFromGMT];
|
||||
startInterval += (delta/60/15);
|
||||
startInterval = (startInterval < -4 ? -4 : startInterval);
|
||||
startInterval += (delta/INTERVALSECONDS);
|
||||
startInterval = (startInterval < -(HALFPADDING) ? -(HALFPADDING) : startInterval);
|
||||
|
||||
currentDate = [record objectForKey: @"endDate"];
|
||||
if ([currentDate earlierDate: endDate] == endDate)
|
||||
endInterval = itemCount - 1;
|
||||
else
|
||||
endInterval = ([currentDate timeIntervalSinceDate: startDate]
|
||||
/ intervalSeconds);
|
||||
/ INTERVALSECONDS);
|
||||
|
||||
delta = [[currentDate timeZoneDetail] timeZoneSecondsFromGMT] - [[startDate timeZoneDetail] timeZoneSecondsFromGMT];
|
||||
endInterval += (delta/60/15);
|
||||
endInterval += (delta/INTERVALSECONDS);
|
||||
endInterval = (endInterval < 0 ? 0 : endInterval);
|
||||
endInterval = (endInterval > itemCount+4 ? itemCount+4 : endInterval);
|
||||
endInterval = (endInterval > itemCount+HALFPADDING ? itemCount+HALFPADDING : endInterval);
|
||||
|
||||
// Update bit string representation
|
||||
// If the user is a resource with restristed amount of bookings, keep the sum of overlapping events
|
||||
|
@ -230,19 +232,19 @@
|
|||
// Slices of 15 minutes. The +8 is to take into account that we can
|
||||
// have a timezone change during the freebusy lookup. We have +4 at the
|
||||
// beginning and +4 at the end.
|
||||
intervals = interval / intervalSeconds + 8;
|
||||
intervals = interval / INTERVALSECONDS + PADDING;
|
||||
|
||||
// Build a bit string representation of the freebusy data for the period
|
||||
freeBusyItems = calloc(intervals, sizeof (unsigned int));
|
||||
[self _fillFreeBusyItems: (freeBusyItems+4)
|
||||
count: (intervals-4)
|
||||
[self _fillFreeBusyItems: (freeBusyItems+HALFPADDING)
|
||||
count: (intervals-PADDING)
|
||||
withRecords: [fb fetchFreeBusyInfosFrom: start to: end forContact: uid]
|
||||
fromStartDate: startDate
|
||||
toEndDate: endDate];
|
||||
|
||||
// Convert bit string to a NSArray. We also skip by the default the non-requested information.
|
||||
freeBusy = [NSMutableArray arrayWithCapacity: intervals];
|
||||
for (count = 4; count < (intervals-4); count++)
|
||||
for (count = HALFPADDING; count < (intervals-HALFPADDING); count++)
|
||||
{
|
||||
[freeBusy addObject: [NSString stringWithFormat: @"%d", *(freeBusyItems + count)]];
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Idioma:";
|
||||
"choose" = "Elija ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Idioma:";
|
||||
"choose" = "Elija ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"Language:" = "Språk:";
|
||||
"choose" = "Välj ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"Language:" = "Мова:";
|
||||
"choose" = "Вибрати ...";
|
||||
"Arabic" = "العربية";
|
||||
"Basque" = "Euskara";
|
||||
"Catalan" = "Català";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue