propagate from branch 'ca.inverse.sogo.1_3_10' (head ba2ef33fb2014db9241eaddd86c886921a3cf802)
to branch 'ca.inverse.sogo' (head cb6221113308044eac92ed5634a235fa9b8140ef) Monotone-Parent: ba2ef33fb2014db9241eaddd86c886921a3cf802 Monotone-Parent: cb6221113308044eac92ed5634a235fa9b8140ef Monotone-Revision: 703f02d08f0caace5f4f0e96efe038c6207e9f28 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2011-11-24T19:45:21 Monotone-Branch: ca.inverse.sogomaint-2.0.2
commit
a98c947d7e
|
@ -4,9 +4,7 @@ obj
|
|||
err$
|
||||
build\.log
|
||||
imgs-.*
|
||||
diff
|
||||
.*\.bak$
|
||||
.*\.diff$
|
||||
.*\.d$
|
||||
.*\.log$
|
||||
.*\.ifb$
|
||||
|
|
104
ChangeLog
104
ChangeLog
|
@ -4,6 +4,35 @@
|
|||
event listener must be on mousedown since click is already
|
||||
observed by document.body.
|
||||
|
||||
2011-11-23 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreContactsMessageTable.m
|
||||
(-evaluatePropertyRestriction:intoQualifier:): returns
|
||||
"MAPIRestrictionStateAlwaysTrue" for PR_SENSITIVITY.
|
||||
|
||||
* OpenChange/MAPIStoreContactsMessage.m
|
||||
(-getPrSensitivity:inMemCtx:): new getter that always returns 0.
|
||||
|
||||
2011-11-22 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/NSArray+MAPIStore.m (-asMVUnicodeInMemCtx:) renamed
|
||||
from "asArrayOfUnicodeStringsInCtx".
|
||||
(-asMVUnicodeInMemCtx:, -asMVLongInMemCtx:): new conversion
|
||||
methods.
|
||||
|
||||
* OpenChange/MAPIStoreTypes.m (NSObjectFromValuePointer):
|
||||
simplified method by using set_SPropValue_proptag and
|
||||
NSObjectFromSPropValue.
|
||||
|
||||
* OpenChange/NSObject+MAPIStore.m (-getValue:forTag:inMemCtx:):
|
||||
renamed from "getMAPIValue:...".
|
||||
(-arrayFromMAPIMVLong:, +arrayFromMAPIMVUnicode:)
|
||||
(+arrayFromMAPIMVString:, +arrayFromMAPIMVBinary:)
|
||||
(+arrayFromMAPIMVGuid:, +arrayFromMVShort:, +arrayFromMVLong:)
|
||||
(+arrayFromMVI8:, +arrayFromMVUnicode:, +arrayFromMVString:)
|
||||
(+arrayFromMVBinary:, +arrayFromMVGuid:, +arrayFromMVFileTime:)
|
||||
new constructors for multivalue types.
|
||||
|
||||
2011-11-21 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/WORequest+SOGo.m - for now, we consider iCal 4
|
||||
|
@ -24,6 +53,81 @@
|
|||
(-vacationEndDate, -setVacationEndDate:): getters/setters for the
|
||||
new optional vacation end date.
|
||||
|
||||
2011-11-20 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreFolder.m (-lookupFolder:): explicitly set
|
||||
the MAPIStoreContext's woContext as context to the looked up
|
||||
folder, although one could expect it to have been set during the
|
||||
lookup at the SOGo level...
|
||||
|
||||
* OpenChange/MAPIStoreFSFolder.m (-lookupFolder:): removed useless
|
||||
overriding of method.
|
||||
|
||||
* OpenChange/MAPIStoreMailFolder.m (-[MAPIStoreMailFolder
|
||||
lookupFolder:]): removed useless overriding of method.
|
||||
(-[MAPIStoreInboxFolder lookupFolder:]): in altnamespace mode,
|
||||
perform the same association of the woContext to the looked up
|
||||
folder as in MAPIStoreFolder.
|
||||
|
||||
* OpenChange/MAPIStoreContext.m
|
||||
(-initFromURL:withConnectionInfo:andTDBIndexing:): instantiate a
|
||||
SOGoUser corresponding to the username of the new context and
|
||||
associated it to the woContext ivar.
|
||||
|
||||
2011-11-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreFolder.m (-permissionEntries): new public
|
||||
method.
|
||||
(-modifyPermissions:withCount:andFlags:): new backend op public
|
||||
method.
|
||||
(-aclFolder, -rolesForExchangeRights:, -exchangeRightsForRoles:):
|
||||
new mandatory methods.
|
||||
|
||||
* OpenChange/SOGoMAPIFSFolder.m (-defaultUserID, -addUserInAcls:)
|
||||
(-removeAclsForUsers:, -aclUsers, -aclsForUser:)
|
||||
(-setRoles:forUser:): implemented standard ACL methods.
|
||||
|
||||
* OpenChange/MAPIStorePermissionsTable.m
|
||||
(+[MAPIStorePermissionEntry
|
||||
entryWithUserId:andMemberId:forFolder:]): constructor now takes a
|
||||
memberId and the container folder as parameters.
|
||||
(-[MAPIStorePermissionEntry getPrMemberId:inMemCtx:]): now based
|
||||
on the new memberId ivar.
|
||||
(-[MAPIStorePermissionEntry getPrEntryId:inMemCtx:]): now make use
|
||||
of MAPIStoreInternalEntryId for regular member ids and return an
|
||||
empty blob for special ones, as specified in oxcperm.
|
||||
(-[MAPIStorePermissionEntry getPrMemberName:inMemCtx:]): now
|
||||
returns the real CN of the user for regular member ids and return
|
||||
@"" or @"Anonymous" for special ones, as specified in oxcperm.
|
||||
(-[MAPIStorePermissionEntry getPrMemberName:inMemCtx:]): now
|
||||
returns the real member rights, based on the aclFolder of the
|
||||
container, using standard SOGo methods.
|
||||
|
||||
* OpenChange/MAPIStorePermissionsTable.h
|
||||
(MAPIStorePermissionsEntry): made class public.
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m (sogo_folder_modify_permissions): new
|
||||
backend op.
|
||||
(sogo_backend_init): invoke "disableLocalCache" to avoid the
|
||||
caching of ACL.
|
||||
|
||||
* SoObjects/SOGo/SOGoCache.m (-disableLocalCache): new method to
|
||||
disable the local cache altogether (helper for non-WO access).
|
||||
|
||||
2011-11-17 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreSamDBUtils.m: new module containing helpers
|
||||
pertaining to the SamDB.
|
||||
(MAPIStoreSamDBUserAttribute): new function that returns the value
|
||||
of a specified key from a user record matching one simple criteria.
|
||||
(MAPIStoreInternalEntrydId, MAPIStoreExternalEntryId): moved
|
||||
functions from MAPIStoreMessage.m.
|
||||
|
||||
* OpenChange/MAPIStoreMessage.m (MAPIStoreInternalEntryId): now
|
||||
takes a ldb_context * parameter pointing to the samdb, which
|
||||
enables us: 1) to return the real legacyExchangeDN 2) to make use
|
||||
of sAMAccountName as search parameter for the username.
|
||||
|
||||
2011-11-16 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/SOGoSieveManager.m (-updateFiltersForLogin:...)
|
||||
|
|
|
@ -7,6 +7,8 @@ include ../Version
|
|||
|
||||
BACKEND_VERSION = 1.0.0
|
||||
|
||||
UNRTF_VERSION = 0.21.2
|
||||
|
||||
### bootstrap library
|
||||
MAPISTORESOGO = MAPIStoreSOGo
|
||||
LIBRARY_NAME = $(MAPISTORESOGO)
|
||||
|
@ -23,6 +25,12 @@ BUNDLE_NAME = $(SOGOBACKEND)
|
|||
BUNDLE_EXTENSION = .MAPIStore
|
||||
BUNDLE_INSTALL_DIR = $(SOGO_LIBDIR)
|
||||
|
||||
UNRTF_DIR = unrtf-$(UNRTF_VERSION)
|
||||
|
||||
$(SOGOBACKEND)_CPPFLAGS += -I$(UNRTF_DIR)/src
|
||||
|
||||
$(SOGOBACKEND)_SUBPROJECTS = $(UNRTF_DIR)/src
|
||||
|
||||
$(SOGOBACKEND)_PRINCIPAL_CLASS = MAPIApplication
|
||||
|
||||
$(SOGOBACKEND)_OBJC_FILES += \
|
||||
|
@ -33,6 +41,7 @@ $(SOGOBACKEND)_OBJC_FILES += \
|
|||
MAPIStoreMIME.m \
|
||||
MAPIStoreTypes.m \
|
||||
MAPIStorePropertySelectors.m \
|
||||
MAPIStoreSamDBUtils.m \
|
||||
\
|
||||
SOGoMAPIVolatileMessage.m \
|
||||
SOGoMAPIFSFolder.m \
|
||||
|
@ -120,7 +129,28 @@ $(SOGOBACKEND)_OBJC_FILES += \
|
|||
|
||||
|
||||
$(SOGOBACKEND)_RESOURCE_FILES += \
|
||||
product.plist
|
||||
product.plist \
|
||||
$(UNRTF_DIR)/charmaps/SYMBOL.charmap \
|
||||
$(UNRTF_DIR)/outputs/html.conf
|
||||
|
||||
### unrtf
|
||||
all:: $(UNRTF_DIR)/config.h $(UNRTF_DIR)/src/GNUmakefile
|
||||
|
||||
$(UNRTF_DIR): $(UNRTF_DIR).tar.gz $(UNRTF_DIR).diff
|
||||
@echo " Extracting and patching $(UNRTF_DIR)..."
|
||||
@rm -rf $(UNRTF_DIR)
|
||||
@$(TAR) -xvzf $< > /dev/null
|
||||
@(cd $(UNRTF_DIR) && patch -p1 < ../$(UNRTF_DIR).diff) > /dev/null
|
||||
@touch $(UNRTF_DIR)
|
||||
|
||||
$(UNRTF_DIR)-stamp: $(UNRTF_DIR)
|
||||
@touch $@
|
||||
|
||||
$(UNRTF_DIR)/config.h: $(UNRTF_DIR)-stamp unrtf_config_h
|
||||
@cp unrtf_config_h $(UNRTF_DIR)/config.h
|
||||
|
||||
$(UNRTF_DIR)/src/GNUmakefile: $(UNRTF_DIR)-stamp GNUmakefile.unrtf
|
||||
@cp GNUmakefile.unrtf $@
|
||||
|
||||
### pl reader
|
||||
PLREADER_TOOL = plreader
|
||||
|
@ -133,7 +163,7 @@ TEST_TOOL_NAME += $(PLREADER_TOOL)
|
|||
LIBMAPI_CFLAGS = $(shell pkg-config libmapi --cflags)
|
||||
LIBMAPISTORE_CFLAGS = $(shell pkg-config libmapistore --cflags) -DSAMBA_PREFIX="\"$(shell pkg-config libmapistore --variable=prefix)\""
|
||||
|
||||
ifeq ($(LIBMAPISTORE_CFLAGS),)
|
||||
ifeq ($(LIBMAPI_CFLAGS),)
|
||||
all install::
|
||||
@echo "Cannot build the OpenChange SOGo backend (empty CFLAGS for libmapistore)"
|
||||
else
|
||||
|
@ -160,6 +190,7 @@ SAMBA_LIB_DIR = $(shell pkg-config libmapistore --variable=libdir)
|
|||
include $(GNUSTEP_MAKEFILES)/bundle.make
|
||||
include $(GNUSTEP_MAKEFILES)/library.make
|
||||
include $(GNUSTEP_MAKEFILES)/test-tool.make
|
||||
include $(GNUSTEP_MAKEFILES)/aggregate.make
|
||||
-include GNUmakefile.postamble
|
||||
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# -*-makefile-*-
|
||||
|
||||
# GNUstep makefile
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
UNRTF = unrtf
|
||||
|
||||
SUBPROJECT_NAME = $(UNRTF)
|
||||
|
||||
$(UNRTF)_C_FILES = \
|
||||
attr.c \
|
||||
convert.c \
|
||||
error.c \
|
||||
hash.c \
|
||||
malloc.c \
|
||||
my_iconv.c \
|
||||
output.c \
|
||||
parse.c \
|
||||
unicode.c \
|
||||
user.c \
|
||||
util.c \
|
||||
word.c
|
||||
|
||||
$(UNRTF)_CFLAGS = -DHAVE_CONFIG_H=1 -I. -I../
|
||||
|
||||
# Option include to set any additional variables
|
||||
-include GNUmakefile.preamble
|
||||
|
||||
# Include in the rules for making libraries
|
||||
include $(GNUSTEP_MAKEFILES)/subproject.make
|
||||
|
||||
# Option include to define any additional rules
|
||||
-include GNUmakefile.postamble
|
|
@ -39,6 +39,7 @@ extern NSTimeZone *utcTZ;
|
|||
|
||||
@interface MAPIStoreAppointmentWrapper : NSObject
|
||||
{
|
||||
struct mapistore_connection_info *connInfo;
|
||||
iCalCalendar *calendar;
|
||||
iCalEvent *event;
|
||||
NSTimeZone *timeZone;
|
||||
|
@ -56,11 +57,13 @@ extern NSTimeZone *utcTZ;
|
|||
+ (id) wrapperWithICalEvent: (iCalEvent *) newEvent
|
||||
andUser: (SOGoUser *) newUser
|
||||
andSenderEmail: (NSString *) newSenderEmail
|
||||
inTimeZone: (NSTimeZone *) newTimeZone;
|
||||
inTimeZone: (NSTimeZone *) newTimeZone
|
||||
withConnectionInfo: (struct mapistore_connection_info *) newConnInfo;
|
||||
- (id) initWithICalEvent: (iCalEvent *) newEvent
|
||||
andUser: (SOGoUser *) newUser
|
||||
andSenderEmail: (NSString *) newSenderEmail
|
||||
inTimeZone: (NSTimeZone *) newTimeZone;
|
||||
inTimeZone: (NSTimeZone *) newTimeZone
|
||||
withConnectionInfo: (struct mapistore_connection_info *) newConnInfo;
|
||||
|
||||
/* getters */
|
||||
- (void) fillMessageData: (struct mapistore_message *) dataPtr
|
||||
|
@ -92,8 +95,6 @@ extern NSTimeZone *utcTZ;
|
|||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPrMessageClass: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPrBody: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPrStartDate: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPidLidAppointmentStateFlags: (void **) data
|
||||
|
@ -129,6 +130,8 @@ extern NSTimeZone *utcTZ;
|
|||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPrImportance: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPrBody: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPidLidIsRecurring: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPidLidRecurring: (void **) data
|
||||
|
|
|
@ -37,8 +37,8 @@
|
|||
#import <NGCards/NSString+NGCards.h>
|
||||
#import <SOGo/SOGoUserManager.h>
|
||||
|
||||
#import "MAPIStoreMessage.h"
|
||||
#import "MAPIStoreRecurrenceUtils.h"
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSDate+MAPIStore.h"
|
||||
|
@ -53,6 +53,7 @@
|
|||
#include <gen_ndr/exchange.h>
|
||||
#include <gen_ndr/property.h>
|
||||
#include <gen_ndr/ndr_property.h>
|
||||
#include <util/attr.h>
|
||||
#include <libmapi/libmapi.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
@ -79,13 +80,15 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
andUser: (SOGoUser *) newUser
|
||||
andSenderEmail: (NSString *) newSenderEmail
|
||||
inTimeZone: (NSTimeZone *) newTimeZone
|
||||
withConnectionInfo: (struct mapistore_connection_info *) newConnInfo
|
||||
{
|
||||
MAPIStoreAppointmentWrapper *wrapper;
|
||||
|
||||
wrapper = [[self alloc] initWithICalEvent: newEvent
|
||||
andUser: newUser
|
||||
andSenderEmail: newSenderEmail
|
||||
inTimeZone: newTimeZone];
|
||||
inTimeZone: newTimeZone
|
||||
withConnectionInfo: newConnInfo];
|
||||
[wrapper autorelease];
|
||||
|
||||
return wrapper;
|
||||
|
@ -95,6 +98,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
connInfo = NULL;
|
||||
calendar = nil;
|
||||
event = nil;
|
||||
timeZone = nil;
|
||||
|
@ -177,9 +181,11 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
andUser: (SOGoUser *) newUser
|
||||
andSenderEmail: (NSString *) newSenderEmail
|
||||
inTimeZone: (NSTimeZone *) newTimeZone
|
||||
withConnectionInfo: (struct mapistore_connection_info *) newConnInfo
|
||||
{
|
||||
if ((self = [self init]))
|
||||
{
|
||||
connInfo = newConnInfo;
|
||||
ASSIGN (event, newEvent);
|
||||
ASSIGN (calendar, [event parent]);
|
||||
ASSIGN (timeZone, newTimeZone);
|
||||
|
@ -255,7 +261,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
{
|
||||
username = [contactInfos objectForKey: @"c_uid"];
|
||||
recipient->username = [username asUnicodeInMemCtx: msgData];
|
||||
entryId = MAPIStoreInternalEntryId (username);
|
||||
entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, username);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -356,7 +362,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
{
|
||||
username = [contactInfos objectForKey: @"c_uid"];
|
||||
recipient->username = [username asUnicodeInMemCtx: msgData];
|
||||
entryId = MAPIStoreInternalEntryId (username);
|
||||
entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, username);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -628,20 +634,6 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
return [self getYes: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPrBody: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [event comment];
|
||||
if (!stringValue)
|
||||
stringValue = @"";
|
||||
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrStartDate: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -740,7 +732,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
if (contactInfos)
|
||||
{
|
||||
username = [contactInfos objectForKey: @"c_uid"];
|
||||
entryId = MAPIStoreInternalEntryId (username);
|
||||
entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, username);
|
||||
}
|
||||
else
|
||||
entryId = MAPIStoreExternalEntryId (cn, email);
|
||||
|
@ -1034,6 +1026,22 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrBody: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
int rc = MAPISTORE_SUCCESS;
|
||||
NSString *stringValue;
|
||||
|
||||
/* FIXME: there is a confusion in NGCards around "comment" and "description" */
|
||||
stringValue = [event comment];
|
||||
if ([stringValue length] > 0)
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPidLidIsRecurring: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -1402,7 +1410,8 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
|||
{
|
||||
startDate = [event startDate];
|
||||
relation = [[trigger relationType] lowercaseString];
|
||||
interval = [[trigger value] durationAsTimeInterval];
|
||||
interval = [[trigger flattenedValuesForKey: @""]
|
||||
durationAsTimeInterval];
|
||||
if ([relation isEqualToString: @"end"])
|
||||
relationDate = [event endDate];
|
||||
else
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#import <Foundation/NSURL.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
#import <Appointments/SOGoAppointmentObject.h>
|
||||
|
@ -36,6 +37,9 @@
|
|||
|
||||
#import "MAPIStoreCalendarFolder.h"
|
||||
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
||||
@implementation MAPIStoreCalendarFolder
|
||||
|
||||
- (id) initWithURL: (NSURL *) newURL
|
||||
|
@ -106,4 +110,51 @@
|
|||
return newMessage;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
NSMutableArray *roles;
|
||||
|
||||
roles = [NSMutableArray arrayWithCapacity: 6];
|
||||
if (rights & RightsCreateItems)
|
||||
[roles addObject: SOGoRole_ObjectCreator];
|
||||
if (rights & RightsDeleteAll)
|
||||
[roles addObject: SOGoRole_ObjectEraser];
|
||||
if (rights & RightsEditAll)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicModifier];
|
||||
[roles addObject: SOGoCalendarRole_PrivateModifier];
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialModifier];
|
||||
}
|
||||
else if (rights & RightsReadItems)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicViewer];
|
||||
[roles addObject: SOGoCalendarRole_PrivateViewer];
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialViewer];
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
|
||||
if ([roles containsObject: SOGoRole_ObjectCreator])
|
||||
rights |= RightsCreateItems;
|
||||
if ([roles containsObject: SOGoRole_ObjectEraser])
|
||||
rights |= RightsDeleteAll;
|
||||
if ([roles containsObject: SOGoCalendarRole_PublicModifier]
|
||||
&& [roles containsObject: SOGoCalendarRole_PrivateModifier]
|
||||
&& [roles containsObject: SOGoCalendarRole_ConfidentialModifier])
|
||||
rights |= RightsReadItems | RightsEditAll;
|
||||
else if ([roles containsObject: SOGoCalendarRole_PublicViewer]
|
||||
&& [roles containsObject: SOGoCalendarRole_PrivateViewer]
|
||||
&& [roles containsObject: SOGoCalendarRole_ConfidentialViewer])
|
||||
rights |= RightsReadItems;
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
- take the tz definitions from Outlook */
|
||||
|
||||
#include <talloc.h>
|
||||
#include <util/attr.h>
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
|
@ -45,6 +46,7 @@
|
|||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentObject.h>
|
||||
#import <Appointments/iCalEntityObject+SOGo.h>
|
||||
#import <Mailer/NSString+Mail.h>
|
||||
|
||||
#import "MAPIStoreAppointmentWrapper.h"
|
||||
#import "MAPIStoreCalendarAttachment.h"
|
||||
|
@ -102,15 +104,18 @@
|
|||
- (MAPIStoreAppointmentWrapper *) appointmentWrapper
|
||||
{
|
||||
iCalEvent *event;
|
||||
MAPIStoreContext *context;
|
||||
|
||||
if (!appointmentWrapper)
|
||||
{
|
||||
event = [sogoObject component: NO secure: NO];
|
||||
context = [self context];
|
||||
ASSIGN (appointmentWrapper,
|
||||
[MAPIStoreAppointmentWrapper wrapperWithICalEvent: event
|
||||
andUser: [[self context] activeUser]
|
||||
andUser: [context activeUser]
|
||||
andSenderEmail: nil
|
||||
inTimeZone: [self ownerTimeZone]]);
|
||||
inTimeZone: [self ownerTimeZone]
|
||||
withConnectionInfo: [context connectionInfo]]);
|
||||
}
|
||||
|
||||
return appointmentWrapper;
|
||||
|
@ -240,6 +245,12 @@
|
|||
return [[self appointmentWrapper] getPrImportance: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPrBody: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [[self appointmentWrapper] getPrBody: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidLidIsRecurring: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -599,7 +610,9 @@
|
|||
[alarm setAction: @"DISPLAY"];
|
||||
trigger = [iCalTrigger elementWithTag: @"trigger"];
|
||||
[trigger setValueType: @"DURATION"];
|
||||
[trigger setValue: [NSString stringWithFormat: @"-PT%@M", delta]];
|
||||
[trigger
|
||||
setSingleValue: [NSString stringWithFormat: @"-PT%@M", delta]
|
||||
forKey: @""];
|
||||
[alarm setTrigger: trigger];
|
||||
[newEvent addToAlarms: alarm];
|
||||
[alarm release];
|
||||
|
@ -610,6 +623,7 @@
|
|||
- (void) save
|
||||
{
|
||||
iCalCalendar *vCalendar;
|
||||
BOOL isAllDay;
|
||||
iCalDateTime *start, *end;
|
||||
iCalTimeZone *tz;
|
||||
NSCalendarDate *now;
|
||||
|
@ -711,9 +725,16 @@
|
|||
if (value)
|
||||
[newEvent setLocation: value];
|
||||
|
||||
tzName = [[self ownerTimeZone] name];
|
||||
tz = [iCalTimeZone timeZoneForName: tzName];
|
||||
[vCalendar addTimeZone: tz];
|
||||
isAllDay = [[properties
|
||||
objectForKey: MAPIPropertyKey (PidLidAppointmentSubType)]
|
||||
boolValue];
|
||||
|
||||
if (!isAllDay)
|
||||
{
|
||||
tzName = [[self ownerTimeZone] name];
|
||||
tz = [iCalTimeZone timeZoneForName: tzName];
|
||||
[vCalendar addTimeZone: tz];
|
||||
}
|
||||
|
||||
// start
|
||||
value = [properties objectForKey: MAPIPropertyKey (PR_START_DATE)];
|
||||
|
@ -723,8 +744,13 @@
|
|||
if (value)
|
||||
{
|
||||
start = (iCalDateTime *) [newEvent uniqueChildWithTag: @"dtstart"];
|
||||
[start setTimeZone: tz];
|
||||
[start setDateTime: value];
|
||||
if (isAllDay)
|
||||
[start setDate: value];
|
||||
else
|
||||
{
|
||||
[start setTimeZone: tz];
|
||||
[start setDateTime: value];
|
||||
}
|
||||
}
|
||||
|
||||
/* end */
|
||||
|
@ -734,8 +760,13 @@
|
|||
if (value)
|
||||
{
|
||||
end = (iCalDateTime *) [newEvent uniqueChildWithTag: @"dtend"];
|
||||
[end setTimeZone: tz];
|
||||
[end setDateTime: value];
|
||||
if (isAllDay)
|
||||
[end setDate: value];
|
||||
else
|
||||
{
|
||||
[end setTimeZone: tz];
|
||||
[end setDateTime: value];
|
||||
}
|
||||
}
|
||||
|
||||
/* priority */
|
||||
|
@ -778,6 +809,22 @@
|
|||
[newEvent setTransparency: @"OPAQUE"];
|
||||
}
|
||||
}
|
||||
|
||||
/* Comment */
|
||||
value = [properties objectForKey: MAPIPropertyKey (PR_BODY_UNICODE)];
|
||||
if (!value)
|
||||
{
|
||||
value = [properties objectForKey: MAPIPropertyKey (PR_HTML)];
|
||||
if (value)
|
||||
{
|
||||
value = [[NSString alloc] initWithData: value
|
||||
encoding: NSUTF8StringEncoding];
|
||||
[value autorelease];
|
||||
value = [value htmlToText];
|
||||
}
|
||||
}
|
||||
if (value)
|
||||
[newEvent setComment: value];
|
||||
|
||||
/* recurrence */
|
||||
value = [properties
|
||||
|
@ -793,75 +840,101 @@
|
|||
/* alarm */
|
||||
[self _setupAlarmDataInEvent: newEvent];
|
||||
|
||||
// Organizer
|
||||
value = [properties objectForKey: @"recipients"];
|
||||
if (value)
|
||||
if ([[properties objectForKey: MAPIPropertyKey (PidLidAppointmentStateFlags)] intValue]
|
||||
!= 0)
|
||||
{
|
||||
NSArray *recipients;
|
||||
NSDictionary *dict;
|
||||
iCalPerson *person;
|
||||
iCalPersonPartStat newPartStat;
|
||||
NSNumber *flags, *trackStatus;
|
||||
int i;
|
||||
|
||||
/* We must set the organizer preliminarily here because, unlike what
|
||||
the doc states, Outlook does not always pass the real organizer
|
||||
in the recipients list. */
|
||||
dict = [activeUser primaryIdentity];
|
||||
person = [iCalPerson new];
|
||||
[person setCn: [dict objectForKey: @"fullName"]];
|
||||
[person setEmail: [dict objectForKey: @"email"]];
|
||||
[newEvent setOrganizer: person];
|
||||
[person release];
|
||||
|
||||
recipients = [value objectForKey: @"to"];
|
||||
|
||||
for (i = 0; i < [recipients count]; i++)
|
||||
// Organizer
|
||||
value = [properties objectForKey: @"recipients"];
|
||||
if (value)
|
||||
{
|
||||
dict = [recipients objectAtIndex: i];
|
||||
flags = [dict objectForKey: MAPIPropertyKey (PR_RECIPIENT_FLAGS)];
|
||||
if (!flags)
|
||||
{
|
||||
[self logWithFormat: @"no recipient flags specified"];
|
||||
break;
|
||||
}
|
||||
NSArray *recipients;
|
||||
NSDictionary *dict;
|
||||
NSString *orgEmail, *attEmail;
|
||||
iCalPerson *person;
|
||||
iCalPersonPartStat newPartStat;
|
||||
NSNumber *flags, *trackStatus;
|
||||
int i, effective;
|
||||
|
||||
/* We must set the organizer preliminarily here because, unlike what
|
||||
the doc states, Outlook does not always pass the real organizer
|
||||
in the recipients list. */
|
||||
dict = [activeUser primaryIdentity];
|
||||
person = [iCalPerson new];
|
||||
[person setCn: [dict objectForKey: @"fullName"]];
|
||||
[person setEmail: [dict objectForKey: @"email"]];
|
||||
orgEmail = [dict objectForKey: @"email"];
|
||||
[person setEmail: orgEmail];
|
||||
[newEvent setOrganizer: person];
|
||||
[person release];
|
||||
|
||||
if (([flags unsignedIntValue] & 0x0002)) /* recipOrganizer */
|
||||
[newEvent setOrganizer: person];
|
||||
else
|
||||
recipients = [value objectForKey: @"to"];
|
||||
effective = 0;
|
||||
for (i = 0; i < [recipients count]; i++)
|
||||
{
|
||||
trackStatus
|
||||
= [dict
|
||||
objectForKey: MAPIPropertyKey (PR_RECIPIENT_TRACKSTATUS)];
|
||||
dict = [recipients objectAtIndex: i];
|
||||
|
||||
/* FIXME: we should provide a data converter between OL
|
||||
partstats and SOGo */
|
||||
switch ([trackStatus unsignedIntValue])
|
||||
flags = [dict objectForKey: MAPIPropertyKey (PR_RECIPIENT_FLAGS)];
|
||||
if (!flags)
|
||||
{
|
||||
case 0x02: /* respTentative */
|
||||
newPartStat = iCalPersonPartStatTentative;
|
||||
break;
|
||||
case 0x03: /* respAccepted */
|
||||
newPartStat = iCalPersonPartStatAccepted;
|
||||
break;
|
||||
case 0x04: /* respDeclined */
|
||||
newPartStat = iCalPersonPartStatDeclined;
|
||||
break;
|
||||
default:
|
||||
newPartStat = iCalPersonPartStatNeedsAction;
|
||||
[self logWithFormat:
|
||||
@"no recipient flags specified: skipping recipient"];
|
||||
continue;
|
||||
}
|
||||
|
||||
[person setParticipationStatus: newPartStat];
|
||||
[person setRsvp: @"TRUE"];
|
||||
[person setRole: @"REQ-PARTICIPANT"];
|
||||
[newEvent addToAttendees: person];
|
||||
person = [iCalPerson new];
|
||||
[person setCn: [dict objectForKey: @"fullName"]];
|
||||
attEmail = [dict objectForKey: @"email"];
|
||||
[person setEmail: attEmail];
|
||||
|
||||
if (([flags unsignedIntValue] & 0x0002)) /* recipOrganizer */
|
||||
[newEvent setOrganizer: person];
|
||||
else
|
||||
{
|
||||
/* Work-around: it happens that Outlook still passes the
|
||||
organizer as a recipient, maybe because of a feature
|
||||
documented in a pre-mesozoic PDF still buried in a
|
||||
cavern... In that case we remove it, and we keep the
|
||||
number of effective recipients in "effective". If the
|
||||
total is 0, we remove the "ORGANIZER" too. */
|
||||
if ([attEmail isEqualToString: orgEmail])
|
||||
{
|
||||
[self logWithFormat:
|
||||
@"avoiding setting organizer as recipient"];
|
||||
continue;
|
||||
}
|
||||
|
||||
trackStatus
|
||||
= [dict
|
||||
objectForKey: MAPIPropertyKey (PR_RECIPIENT_TRACKSTATUS)];
|
||||
|
||||
/* FIXME: we should provide a data converter between OL
|
||||
partstats and SOGo */
|
||||
switch ([trackStatus unsignedIntValue])
|
||||
{
|
||||
case 0x02: /* respTentative */
|
||||
newPartStat = iCalPersonPartStatTentative;
|
||||
break;
|
||||
case 0x03: /* respAccepted */
|
||||
newPartStat = iCalPersonPartStatAccepted;
|
||||
break;
|
||||
case 0x04: /* respDeclined */
|
||||
newPartStat = iCalPersonPartStatDeclined;
|
||||
break;
|
||||
default:
|
||||
newPartStat = iCalPersonPartStatNeedsAction;
|
||||
}
|
||||
|
||||
[person setParticipationStatus: newPartStat];
|
||||
[person setRsvp: @"TRUE"];
|
||||
[person setRole: @"REQ-PARTICIPANT"];
|
||||
[newEvent addToAttendees: person];
|
||||
effective++;
|
||||
}
|
||||
|
||||
[person release];
|
||||
}
|
||||
|
||||
[person release];
|
||||
if (effective == 0) /* See work-around above */
|
||||
[newEvent setOrganizer: nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,7 +142,8 @@ extern NSTimeZone *utcTZ;
|
|||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
if (!photoData)
|
||||
ASSIGN (photoData, [[photo value: 0] dataByDecodingBase64]);
|
||||
ASSIGN (photoData,
|
||||
[[photo flattenedValuesForKey: @""] dataByDecodingBase64]);
|
||||
|
||||
*data = [photoData asBinaryInMemCtx: memCtx];
|
||||
|
||||
|
@ -153,7 +154,8 @@ extern NSTimeZone *utcTZ;
|
|||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
if (!photoData)
|
||||
ASSIGN (photoData, [[photo value: 0] dataByDecodingBase64]);
|
||||
ASSIGN (photoData,
|
||||
[[photo flattenedValuesForKey: @""] dataByDecodingBase64]);
|
||||
|
||||
*data = MAPILongValue (memCtx, [photoData length]);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#import <Foundation/NSURL.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <Contacts/SOGoContactGCSEntry.h>
|
||||
#import <Contacts/SOGoContactFolders.h>
|
||||
|
||||
|
@ -33,6 +34,9 @@
|
|||
|
||||
#import "MAPIStoreContactsFolder.h"
|
||||
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
||||
@implementation MAPIStoreContactsFolder
|
||||
|
||||
- (id) initWithURL: (NSURL *) newURL
|
||||
|
@ -103,4 +107,39 @@
|
|||
return newMessage;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
NSMutableArray *roles;
|
||||
|
||||
roles = [NSMutableArray arrayWithCapacity: 6];
|
||||
if (rights & RightsCreateItems)
|
||||
[roles addObject: SOGoRole_ObjectCreator];
|
||||
if (rights & RightsDeleteAll)
|
||||
[roles addObject: SOGoRole_ObjectEraser];
|
||||
if (rights & RightsEditAll)
|
||||
[roles addObject: SOGoRole_ObjectEditor];
|
||||
if (rights & RightsReadItems)
|
||||
[roles addObject: SOGoRole_ObjectViewer];
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
|
||||
if ([roles containsObject: SOGoRole_ObjectCreator])
|
||||
rights |= RightsCreateItems;
|
||||
if ([roles containsObject: SOGoRole_ObjectEraser])
|
||||
rights |= RightsDeleteAll;
|
||||
if ([roles containsObject: SOGoRole_ObjectEditor])
|
||||
rights |= RightsEditAll;
|
||||
if ([roles containsObject: SOGoRole_ObjectViewer])
|
||||
rights |= RightsReadItems;
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -27,10 +27,12 @@
|
|||
#import <Foundation/NSString.h>
|
||||
#import <NGExtensions/NGBase64Coding.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGCards/NSArray+NGCards.h>
|
||||
#import <NGCards/NGVCard.h>
|
||||
#import <NGCards/NGVCardPhoto.h>
|
||||
#import <NGCards/NSArray+NGCards.h>
|
||||
#import <NGCards/NSString+NGCards.h>
|
||||
#import <Contacts/SOGoContactGCSEntry.h>
|
||||
#import <Mailer/NSString+Mail.h>
|
||||
|
||||
#import "MAPIStoreContactsAttachment.h"
|
||||
#import "MAPIStoreContactsFolder.h"
|
||||
|
@ -147,18 +149,11 @@
|
|||
- (int) getPrCompanyName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSArray *values;
|
||||
NSString *stringValue;
|
||||
CardElement *org;
|
||||
|
||||
values = [[sogoObject vCard] org];
|
||||
stringValue = nil;
|
||||
|
||||
if ([values count] > 0)
|
||||
stringValue = [values objectAtIndex: 0];
|
||||
else
|
||||
stringValue = @"";
|
||||
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
org = [[sogoObject vCard] org];
|
||||
*data = [[org flattenedValueAtIndex: 0 forKey: @""]
|
||||
asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -166,18 +161,11 @@
|
|||
- (int) getPrDepartmentName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSArray *values;
|
||||
NSString *stringValue;
|
||||
CardElement *org;
|
||||
|
||||
values = [[sogoObject vCard] org];
|
||||
stringValue = nil;
|
||||
|
||||
if ([values count] > 1)
|
||||
stringValue = [values objectAtIndex: 1];
|
||||
else
|
||||
stringValue = @"";
|
||||
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
org = [[sogoObject vCard] org];
|
||||
*data = [[org flattenedValueAtIndex: 1 forKey: @""]
|
||||
asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -257,7 +245,7 @@
|
|||
if (!stringValue)
|
||||
stringValue = @"";
|
||||
*data = [[NSArray arrayWithObject: stringValue]
|
||||
asArrayOfUnicodeStringsInCtx: memCtx];
|
||||
asMVUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -312,7 +300,7 @@
|
|||
max = [emails count];
|
||||
for (count = 0; !stringValue && count < max; count++)
|
||||
{
|
||||
email = [[emails objectAtIndex: count] value: 0];
|
||||
email = [[emails objectAtIndex: count] flattenedValuesForKey: @""];
|
||||
|
||||
if ([email caseInsensitiveCompare: [card preferredEMail]] != NSOrderedSame)
|
||||
stringValue = email;
|
||||
|
@ -372,7 +360,7 @@
|
|||
ce = [elements objectAtIndex: count];
|
||||
if (!aTypeToExclude
|
||||
|| ![ce hasAttribute: @"type" havingValue: aTypeToExclude])
|
||||
stringValue = [ce value: pos];
|
||||
stringValue = [ce flattenedValueAtIndex: pos forKey: @""];
|
||||
}
|
||||
|
||||
if (!stringValue)
|
||||
|
@ -463,7 +451,7 @@
|
|||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-aim"]
|
||||
value: 0];
|
||||
flattenedValuesForKey: @""];
|
||||
if (!stringValue)
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
@ -697,7 +685,9 @@
|
|||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] value: 0];
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"]
|
||||
flattenedValueAtIndex: 0
|
||||
forKey: @""];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -708,7 +698,9 @@
|
|||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] value: 1];
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"]
|
||||
flattenedValueAtIndex: 1
|
||||
forKey: @""];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -719,7 +711,9 @@
|
|||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] value: 2];
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"]
|
||||
flattenedValueAtIndex: 2
|
||||
forKey: @""];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -730,7 +724,9 @@
|
|||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] value: 3];
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"]
|
||||
flattenedValueAtIndex: 3
|
||||
forKey: @""];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -741,12 +737,20 @@
|
|||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] value: 4];
|
||||
stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"]
|
||||
flattenedValueAtIndex: 4
|
||||
forKey: @""];
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPrSensitivity: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getLongZero: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
/* attachments (photos) */
|
||||
- (void) _fetchAttachmentParts
|
||||
{
|
||||
|
@ -836,9 +840,9 @@
|
|||
to: photoType];
|
||||
[photo setValue: 0 ofAttribute: @"encoding"
|
||||
to: @"b"];
|
||||
[photo setValue: 0
|
||||
to: [content stringByReplacingString: @"\n"
|
||||
withString: @""]];
|
||||
[photo setSingleValue: [content stringByReplacingString: @"\n"
|
||||
withString: @""]
|
||||
atIndex: 0 forKey: @""];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -885,7 +889,7 @@
|
|||
if (value)
|
||||
{
|
||||
if ([elements count] > 0)
|
||||
[[elements objectAtIndex: 0] setValue: 0 to: value];
|
||||
[[elements objectAtIndex: 0] setSingleValue: value forKey: @""];
|
||||
else
|
||||
[newCard addEmail: value
|
||||
types: [NSArray arrayWithObject: @"pref"]];
|
||||
|
@ -894,7 +898,7 @@
|
|||
if (value)
|
||||
{
|
||||
if ([elements count] > 1)
|
||||
[[elements objectAtIndex: 1] setValue: 0 to: value];
|
||||
[[elements objectAtIndex: 1] setSingleValue: value forKey: @""];
|
||||
else
|
||||
[newCard addEmail: value types: nil];
|
||||
}
|
||||
|
@ -902,7 +906,7 @@
|
|||
if (value)
|
||||
{
|
||||
if ([elements count] > 2)
|
||||
[[elements objectAtIndex: 2] setValue: 0 to: value];
|
||||
[[elements objectAtIndex: 2] setSingleValue: value forKey: @""];
|
||||
else
|
||||
[newCard addEmail: value types: nil];
|
||||
}
|
||||
|
@ -942,7 +946,7 @@
|
|||
[element addAttribute: @"type"
|
||||
value: @"pref"];
|
||||
}
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
}
|
||||
|
||||
elements = [newCard childrenWithTag: @"adr"
|
||||
|
@ -960,22 +964,22 @@
|
|||
[element addAttribute: @"type" value: @"pref"];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressPostOfficeBox)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value atIndex: 0 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressStreet)];
|
||||
if (value)
|
||||
[element setValue: 2 to: value];
|
||||
[element setSingleValue: value atIndex: 2 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressCity)];
|
||||
if (value)
|
||||
[element setValue: 3 to: value];
|
||||
[element setSingleValue: value atIndex: 3 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressState)];
|
||||
if (value)
|
||||
[element setValue: 4 to: value];
|
||||
[element setSingleValue: value atIndex: 4 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressPostalCode)];
|
||||
if (value)
|
||||
[element setValue: 5 to: value];
|
||||
[element setSingleValue: value atIndex: 5 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressCountry)];
|
||||
if (value)
|
||||
[element setValue: 6 to: value];
|
||||
[element setSingleValue: value atIndex: 6 forKey: @""];
|
||||
|
||||
//
|
||||
// home postal addresses handling
|
||||
|
@ -1001,7 +1005,7 @@
|
|||
[element addAttribute: @"type"
|
||||
value: @"pref"];
|
||||
}
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
}
|
||||
|
||||
elements = [newCard childrenWithTag: @"adr"
|
||||
|
@ -1020,22 +1024,22 @@
|
|||
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_POST_OFFICE_BOX_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value atIndex: 0 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey( PR_HOME_ADDRESS_STREET_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 2 to: value];
|
||||
[element setSingleValue: value atIndex: 2 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_CITY_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 3 to: value];
|
||||
[element setSingleValue: value atIndex: 3 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_STATE_OR_PROVINCE_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 4 to: value];
|
||||
[element setSingleValue: value atIndex: 4 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_POSTAL_CODE_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 5 to: value];
|
||||
[element setSingleValue: value atIndex: 5 forKey: @""];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_COUNTRY_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 6 to: value];
|
||||
[element setSingleValue: value atIndex: 6 forKey: @""];
|
||||
|
||||
|
||||
//
|
||||
|
@ -1044,27 +1048,27 @@
|
|||
element = [self _elementWithTag: @"tel" ofType: @"work" forCard: newCard];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_OFFICE_TELEPHONE_NUMBER_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
|
||||
element = [self _elementWithTag: @"tel" ofType: @"home" forCard: newCard];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_HOME_TELEPHONE_NUMBER_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
|
||||
element = [self _elementWithTag: @"tel" ofType: @"fax" forCard: newCard];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_BUSINESS_FAX_NUMBER_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
|
||||
element = [self _elementWithTag: @"tel" ofType: @"pager" forCard: newCard];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_PAGER_TELEPHONE_NUMBER_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
|
||||
element = [self _elementWithTag: @"tel" ofType: @"cell" forCard: newCard];
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_MOBILE_TELEPHONE_NUMBER_UNICODE)];
|
||||
if (value)
|
||||
[element setValue: 0 to: value];
|
||||
[element setSingleValue: value forKey: @""];
|
||||
|
||||
|
||||
//
|
||||
|
@ -1092,15 +1096,14 @@
|
|||
if (value)
|
||||
{
|
||||
[[self _elementWithTag: @"url" ofType: @"work" forCard: newCard]
|
||||
setValue: 0 to: value];
|
||||
setSingleValue: value forKey: @""];
|
||||
}
|
||||
|
||||
value = [properties objectForKey: MAPIPropertyKey(PidLidInstantMessagingAddress)];
|
||||
if (value)
|
||||
{
|
||||
[[newCard uniqueChildWithTag: @"x-aim"]
|
||||
setValue: 0
|
||||
to: value];
|
||||
setSingleValue: value forKey: @""];
|
||||
}
|
||||
|
||||
value = [properties objectForKey: MAPIPropertyKey(PR_BIRTHDAY)];
|
||||
|
@ -1117,6 +1120,22 @@
|
|||
fromProperties: [attachment properties]];
|
||||
}
|
||||
|
||||
/* Note */
|
||||
value = [properties objectForKey: MAPIPropertyKey (PR_BODY_UNICODE)];
|
||||
if (!value)
|
||||
{
|
||||
value = [properties objectForKey: MAPIPropertyKey (PR_HTML)];
|
||||
if (value)
|
||||
{
|
||||
value = [[NSString alloc] initWithData: value
|
||||
encoding: NSUTF8StringEncoding];
|
||||
[value autorelease];
|
||||
value = [value htmlToText];
|
||||
}
|
||||
}
|
||||
if (value)
|
||||
[newCard setNote: value];
|
||||
|
||||
//
|
||||
// we save the new/modified card
|
||||
//
|
||||
|
|
|
@ -105,6 +105,9 @@ static Class MAPIStoreContactsMessageK, NGMailAddressK, NSDataK, NSStringK;
|
|||
rc = MAPIRestrictionStateAlwaysFalse;
|
||||
break;
|
||||
|
||||
case PR_SENSITIVITY:
|
||||
rc = MAPIRestrictionStateAlwaysTrue;
|
||||
break;
|
||||
case PidLidAddressBookProviderArrayType:
|
||||
case PidLidAddressBookProviderEmailList:
|
||||
/* FIXME: this is a hack. We should return a real qualifier here */
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#undef DEBUG
|
||||
#include <stdbool.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
#include <util/attr.h>
|
||||
#include <libmapiproxy.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
@ -207,11 +208,17 @@ _prepareContextClass (Class contextClass,
|
|||
andTDBIndexing: (struct tdb_wrap *) indexingTdb
|
||||
{
|
||||
NSString *username;
|
||||
SOGoUser *activeUser;
|
||||
|
||||
if ((self = [self init]))
|
||||
{
|
||||
ASSIGN (contextUrl, newUrl);
|
||||
username = [NSString stringWithUTF8String: newConnInfo->username];
|
||||
activeUser = [SOGoUser userWithLogin: username];
|
||||
if (!activeUser)
|
||||
[self errorWithFormat: @"user '%@' not found in SOGo environment",
|
||||
username];
|
||||
[woContext setActiveUser: activeUser];
|
||||
ASSIGN (mapping, [MAPIStoreMapping mappingForUsername: username
|
||||
withIndexing: indexingTdb]);
|
||||
[mapping increaseUseCount];
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#import "MAPIStoreFAIMessage.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <talloc.h>
|
||||
#include <util/time.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
@implementation MAPIStoreFAIMessage
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#import "MAPIStoreFAIMessageTable.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <talloc.h>
|
||||
#include <util/time.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
static Class MAPIStoreFAIMessageK = Nil;
|
||||
|
|
|
@ -34,9 +34,6 @@
|
|||
|
||||
#import "MAPIStoreFSBaseContext.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
static Class MAPIStoreFSFolderK;
|
||||
|
||||
@implementation MAPIStoreFSBaseContext
|
||||
|
|
|
@ -149,23 +149,6 @@ static Class EOKeyValueQualifierK;
|
|||
return entries;
|
||||
}
|
||||
|
||||
- (id) lookupFolder: (NSString *) childKey
|
||||
{
|
||||
id childObject = nil;
|
||||
SOGoMAPIFSFolder *childFolder;
|
||||
|
||||
[self folderKeys];
|
||||
if ([folderKeys containsObject: childKey])
|
||||
{
|
||||
childFolder = [sogoObject lookupName: childKey inContext: nil
|
||||
acquire: NO];
|
||||
childObject = [MAPIStoreFSFolder mapiStoreObjectWithSOGoObject: childFolder
|
||||
inContainer: self];
|
||||
}
|
||||
|
||||
return childObject;
|
||||
}
|
||||
|
||||
- (NSDate *) lastMessageModificationTime
|
||||
{
|
||||
NSUInteger count, max;
|
||||
|
@ -193,4 +176,64 @@ static Class EOKeyValueQualifierK;
|
|||
return date;
|
||||
}
|
||||
|
||||
- (SOGoFolder *) aclFolder
|
||||
{
|
||||
return propsFolder;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
NSMutableArray *roles;
|
||||
|
||||
roles = [NSMutableArray arrayWithCapacity: 9];
|
||||
if (rights & RightsReadItems)
|
||||
[roles addObject: @"RightsReadItems"];
|
||||
if (rights & RightsCreateItems)
|
||||
[roles addObject: @"RightsCreateItems"];
|
||||
if (rights & RightsEditOwn)
|
||||
[roles addObject: @"RightsEditOwn"];
|
||||
if (rights & RightsDeleteOwn)
|
||||
[roles addObject: @"RightsDeleteOwn"];
|
||||
if (rights & RightsEditAll)
|
||||
[roles addObject: @"RightsEditAll"];
|
||||
if (rights & RightsDeleteAll)
|
||||
[roles addObject: @"RightsDeleteAll"];
|
||||
if (rights & RightsCreateSubfolders)
|
||||
[roles addObject: @"RightsCreateSubfolders"];
|
||||
if (rights & RightsFolderOwner)
|
||||
[roles addObject: @"RightsFolderOwner"];
|
||||
if (rights & RightsFolderContact)
|
||||
[roles addObject: @"RightsFolderContact"];
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
|
||||
if ([roles containsObject: @"RightsReadItems"])
|
||||
rights |= RightsReadItems;
|
||||
if ([roles containsObject: @"RightsCreateItems"])
|
||||
rights |= RightsCreateItems;
|
||||
if ([roles containsObject: @"RightsEditOwn"])
|
||||
rights |= RightsEditOwn;
|
||||
if ([roles containsObject: @"RightsDeleteOwn"])
|
||||
rights |= RightsDeleteOwn;
|
||||
if ([roles containsObject: @"RightsEditAll"])
|
||||
rights |= RightsEditAll;
|
||||
if ([roles containsObject: @"RightsDeleteAll"])
|
||||
rights |= RightsDeleteAll;
|
||||
if ([roles containsObject: @"RightsCreateSubfolders"])
|
||||
rights |= RightsCreateSubfolders;
|
||||
if ([roles containsObject: @"RightsFolderOwner"])
|
||||
rights |= RightsFolderOwner;
|
||||
if ([roles containsObject: @"RightsFolderContact"])
|
||||
rights |= RightsFolderContact;
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
|
||||
[sogoObject appendProperties: properties];
|
||||
[sogoObject save];
|
||||
[self resetProperties];
|
||||
[properties removeAllObjects];
|
||||
}
|
||||
|
||||
- (NSDate *) creationTime
|
||||
|
|
|
@ -40,10 +40,10 @@
|
|||
@class MAPIStoreFolderTable;
|
||||
@class MAPIStoreMessageTable;
|
||||
@class MAPIStorePermissionsTable;
|
||||
@class SOGoFolder;
|
||||
@class SOGoMAPIFSFolder;
|
||||
@class SOGoMAPIFSMessage;
|
||||
|
||||
|
||||
#import "MAPIStoreObject.h"
|
||||
|
||||
@interface MAPIStoreFolder : MAPIStoreObject
|
||||
|
@ -74,6 +74,7 @@
|
|||
|
||||
/* permissions */
|
||||
- (MAPIStorePermissionsTable *) permissionsTable;
|
||||
- (NSArray *) permissionEntries;
|
||||
|
||||
/* message objects and tables */
|
||||
- (id) lookupMessage: (NSString *) messageKey;
|
||||
|
@ -135,6 +136,10 @@
|
|||
tableType: (uint8_t) tableType
|
||||
andHandleId: (uint32_t) handleId;
|
||||
|
||||
- (int) modifyPermissions: (struct PermissionData *) permissions
|
||||
withCount: (uint16_t) pcount
|
||||
andFlags: (int8_t) flags;
|
||||
|
||||
/* helpers */
|
||||
- (uint64_t) idForObjectWithKey: (NSString *) childKey;
|
||||
|
||||
|
@ -152,6 +157,10 @@
|
|||
|
||||
- (NSCalendarDate *) lastMessageModificationTime;
|
||||
|
||||
- (SOGoFolder *) aclFolder;
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights;
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles;
|
||||
|
||||
/* subclass helpers */
|
||||
- (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids
|
||||
andMessageURLs: (NSArray *) oldMessageURLs
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreMessage.h"
|
||||
#import "MAPIStorePermissionsTable.h"
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSDate+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
@ -51,6 +52,7 @@
|
|||
#include <gen_ndr/exchange.h>
|
||||
|
||||
#undef DEBUG
|
||||
#include <util/attr.h>
|
||||
#include <libmapiproxy.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_nameid.h>
|
||||
|
@ -187,6 +189,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
sogoFolder = [sogoObject lookupName: folderKey
|
||||
inContext: woContext
|
||||
acquire: NO];
|
||||
[sogoFolder setContext: woContext];
|
||||
if (sogoFolder && ![sogoFolder isKindOfClass: NSExceptionK])
|
||||
childFolder = [isa mapiStoreObjectWithSOGoObject: sogoFolder
|
||||
inContainer: self];
|
||||
|
@ -699,6 +702,23 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
return rc;
|
||||
}
|
||||
|
||||
- (SOGoFolder *) aclFolder
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) _modifyPermissionEntryForUser: (NSString *) user
|
||||
withRoles: (NSArray *) roles
|
||||
isAddition: (BOOL) isAddition
|
||||
withACLFolder: (SOGoFolder *) aclFolder
|
||||
{
|
||||
if (isAddition)
|
||||
[aclFolder addUserInAcls: user];
|
||||
[aclFolder setRoles: roles forUser: user];
|
||||
}
|
||||
|
||||
- (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids
|
||||
andMessageURLs: (NSArray *) oldMessageURLs
|
||||
andCount: (uint32_t) midCount
|
||||
|
@ -898,33 +918,28 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
return rc;
|
||||
}
|
||||
|
||||
- (int) addPropertiesFromRow: (struct SRow *) aRow
|
||||
- (void) addProperties: (NSDictionary *) newProperties
|
||||
{
|
||||
static enum MAPITAGS bannedProps[] = { PR_MID, PR_FID, PR_PARENT_FID,
|
||||
PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY,
|
||||
PR_CHANGE_KEY, 0x00000000 };
|
||||
enum MAPITAGS *currentProp;
|
||||
int rc;
|
||||
|
||||
rc = [super addPropertiesFromRow: aRow];
|
||||
NSMutableDictionary *propsCopy;
|
||||
|
||||
/* TODO: this should no longer be required once mapistore v2 API is in
|
||||
place, when we can then do this from -dealloc below */
|
||||
if ([properties count] > 0)
|
||||
{
|
||||
currentProp = bannedProps;
|
||||
while (*currentProp)
|
||||
{
|
||||
[properties removeObjectForKey: MAPIPropertyKey (*currentProp)];
|
||||
currentProp++;
|
||||
}
|
||||
|
||||
[propsMessage appendProperties: properties];
|
||||
[propsMessage save];
|
||||
[self resetProperties];
|
||||
propsCopy = [newProperties mutableCopy];
|
||||
currentProp = bannedProps;
|
||||
while (*currentProp)
|
||||
{
|
||||
[propsCopy removeObjectForKey: MAPIPropertyKey (*currentProp)];
|
||||
currentProp++;
|
||||
}
|
||||
|
||||
return rc;
|
||||
[propsMessage appendProperties: propsCopy];
|
||||
[propsMessage save];
|
||||
[propsCopy release];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
|
@ -1186,7 +1201,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
value = [[propsMessage properties]
|
||||
objectForKey: MAPIPropertyKey (propTag)];
|
||||
if (value)
|
||||
rc = [value getMAPIValue: data forTag: propTag inMemCtx: memCtx];
|
||||
rc = [value getValue: data forTag: propTag inMemCtx: memCtx];
|
||||
else
|
||||
rc = [super getProperty: data withTag: propTag inMemCtx: memCtx];
|
||||
|
||||
|
@ -1251,6 +1266,196 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
return [MAPIStorePermissionsTable tableForContainer: self];
|
||||
}
|
||||
|
||||
- (NSArray *) permissionEntries
|
||||
{
|
||||
NSMutableArray *permissionEntries;
|
||||
MAPIStorePermissionEntry *entry;
|
||||
NSArray *aclUsers;
|
||||
uint64_t memberId, regularMemberId = 1;
|
||||
NSUInteger count, max;
|
||||
NSString *username, *defaultUserId;
|
||||
SOGoFolder *aclFolder;
|
||||
|
||||
aclFolder = [self aclFolder];
|
||||
|
||||
defaultUserId = [aclFolder defaultUserID];
|
||||
aclUsers = [aclFolder aclUsers];
|
||||
max = [aclUsers count];
|
||||
permissionEntries = [NSMutableArray arrayWithCapacity: max];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
username = [aclUsers objectAtIndex: count];
|
||||
if (![username hasPrefix: @"@"])
|
||||
{
|
||||
if ([username isEqualToString: defaultUserId])
|
||||
memberId = 0;
|
||||
else if ([username isEqualToString: @"anonymous"])
|
||||
memberId = ULLONG_MAX;
|
||||
else
|
||||
{
|
||||
memberId = regularMemberId;
|
||||
regularMemberId++;
|
||||
}
|
||||
entry = [MAPIStorePermissionEntry entryWithUserId: username
|
||||
andMemberId: memberId
|
||||
forFolder: self];
|
||||
[permissionEntries addObject: entry];
|
||||
}
|
||||
}
|
||||
|
||||
return permissionEntries;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (NSString *) _usernameFromEntryId: (struct SBinary_short *) bin
|
||||
{
|
||||
struct Binary_r bin32;
|
||||
struct AddressBookEntryId *entryId;
|
||||
NSString *username;
|
||||
struct ldb_context *samCtx;
|
||||
|
||||
bin32.cb = bin->cb;
|
||||
bin32.lpb = bin->lpb;
|
||||
|
||||
entryId = get_AddressBookEntryId (NULL, &bin32);
|
||||
if (entryId)
|
||||
{
|
||||
samCtx = [[self context] connectionInfo]->sam_ctx;
|
||||
username = MAPIStoreSamDBUserAttribute (samCtx, @"legacyExchangeDN",
|
||||
[NSString stringWithUTF8String: entryId->X500DN],
|
||||
@"sAMAccountName");
|
||||
}
|
||||
else
|
||||
username = nil;
|
||||
talloc_free (entryId);
|
||||
|
||||
return username;
|
||||
}
|
||||
|
||||
- (NSString *) _usernameFromMemberId: (uint64_t) memberId
|
||||
inEntries: (NSArray *) entries
|
||||
{
|
||||
NSString *username = nil;
|
||||
NSUInteger count, max;
|
||||
MAPIStorePermissionEntry *entry;
|
||||
|
||||
max = [entries count];
|
||||
for (count = 0; !username && count < max; count++)
|
||||
{
|
||||
entry = [entries objectAtIndex: count];
|
||||
if ([entry memberId] == memberId)
|
||||
username = [entry userId];
|
||||
}
|
||||
|
||||
return username;
|
||||
}
|
||||
|
||||
- (void) _emptyACL
|
||||
{
|
||||
NSUInteger count, max;
|
||||
NSArray *users;
|
||||
SOGoFolder *aclFolder;
|
||||
|
||||
aclFolder = [self aclFolder];
|
||||
|
||||
users = [aclFolder aclUsers];
|
||||
max = [users count];
|
||||
for (count = 0; count < max; count++)
|
||||
[aclFolder removeUserFromAcls: [users objectAtIndex: count]];
|
||||
}
|
||||
|
||||
- (int) modifyPermissions: (struct PermissionData *) permissions
|
||||
withCount: (uint16_t) pcount
|
||||
andFlags: (int8_t) flags
|
||||
{
|
||||
NSUInteger count, propCount;
|
||||
struct PermissionData *currentPermission;
|
||||
struct mapi_SPropValue *mapiValue;
|
||||
NSString *permissionUser;
|
||||
NSArray *entries;
|
||||
NSArray *permissionRoles;
|
||||
BOOL reset, isAdd;
|
||||
SOGoFolder *aclFolder;
|
||||
|
||||
aclFolder = [self aclFolder];
|
||||
|
||||
reset = ((flags & ModifyPerms_ReplaceRows) != 0);
|
||||
if (reset)
|
||||
[self _emptyACL];
|
||||
|
||||
entries = [self permissionEntries];
|
||||
|
||||
for (count = 0; count < pcount; count++)
|
||||
{
|
||||
currentPermission = permissions + count;
|
||||
|
||||
permissionUser = nil;
|
||||
permissionRoles = nil;
|
||||
|
||||
isAdd = (currentPermission->PermissionDataFlags == ROW_ADD);
|
||||
for (propCount = 0;
|
||||
propCount < currentPermission->lpProps.cValues;
|
||||
propCount++)
|
||||
{
|
||||
mapiValue = currentPermission->lpProps.lpProps + propCount;
|
||||
switch (mapiValue->ulPropTag)
|
||||
{
|
||||
case PR_ENTRYID:
|
||||
permissionUser
|
||||
= [self _usernameFromEntryId: &mapiValue->value.bin];
|
||||
break;
|
||||
case PR_MEMBER_ID:
|
||||
permissionUser = [self _usernameFromMemberId: mapiValue->value.d
|
||||
inEntries: entries];
|
||||
break;
|
||||
case PR_MEMBER_RIGHTS:
|
||||
permissionRoles = [self
|
||||
rolesForExchangeRights: mapiValue->value.l];
|
||||
break;
|
||||
default:
|
||||
if (mapiValue->ulPropTag != PR_MEMBER_NAME)
|
||||
[self warnWithFormat: @"unhandled permission property: %.8x",
|
||||
mapiValue->ulPropTag];
|
||||
}
|
||||
}
|
||||
|
||||
if (reset)
|
||||
{
|
||||
if (isAdd)
|
||||
[self _modifyPermissionEntryForUser: permissionUser
|
||||
withRoles: permissionRoles
|
||||
isAddition: YES
|
||||
withACLFolder: aclFolder];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isAdd || currentPermission->PermissionDataFlags == ROW_MODIFY)
|
||||
[self _modifyPermissionEntryForUser: permissionUser
|
||||
withRoles: permissionRoles
|
||||
isAddition: isAdd
|
||||
withACLFolder: aclFolder];
|
||||
else if (currentPermission->PermissionDataFlags == ROW_REMOVE)
|
||||
[aclFolder removeUserFromAcls: permissionUser];
|
||||
else
|
||||
[self errorWithFormat: @"unhandled permission action flag: %d",
|
||||
currentPermission->PermissionDataFlags];
|
||||
}
|
||||
}
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (uint64_t) objectId
|
||||
{
|
||||
uint64_t objectId;
|
||||
|
|
|
@ -133,6 +133,11 @@
|
|||
return value;
|
||||
}
|
||||
|
||||
- (SOGoFolder *) aclFolder
|
||||
{
|
||||
return (SOGoFolder *) sogoObject;
|
||||
}
|
||||
|
||||
/* synchronisation */
|
||||
|
||||
/* Tree
|
||||
|
|
|
@ -43,11 +43,11 @@
|
|||
#import <Mailer/SOGoTrashFolder.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
|
||||
#import "MAPIApplication.h"
|
||||
#import "MAPIStoreAppointmentWrapper.h"
|
||||
#import "MAPIStoreContext.h"
|
||||
// #import "MAPIStoreDraftsMessage.h"
|
||||
#import "MAPIStoreFAIMessage.h"
|
||||
#import "MAPIStoreMailMessageTable.h"
|
||||
#import "MAPIStoreMapping.h"
|
||||
|
@ -64,6 +64,7 @@
|
|||
static Class SOGoMailFolderK;
|
||||
|
||||
#undef DEBUG
|
||||
#include <util/attr.h>
|
||||
#include <libmapi/libmapi.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
@ -350,23 +351,6 @@ static Class SOGoMailFolderK;
|
|||
return subfolderKeys;
|
||||
}
|
||||
|
||||
- (id) lookupFolder: (NSString *) childKey
|
||||
{
|
||||
id childObject = nil;
|
||||
SOGoMailFolder *childFolder;
|
||||
|
||||
[self folderKeys];
|
||||
if ([folderKeys containsObject: childKey])
|
||||
{
|
||||
childFolder = [sogoObject lookupName: childKey inContext: nil
|
||||
acquire: NO];
|
||||
childObject = [MAPIStoreMailFolder mapiStoreObjectWithSOGoObject: childFolder
|
||||
inContainer: self];
|
||||
}
|
||||
|
||||
return childObject;
|
||||
}
|
||||
|
||||
- (NSDate *) creationTime
|
||||
{
|
||||
return [NSCalendarDate dateWithTimeIntervalSince1970: 0x4dbb2dbe]; /* oc_version_time */
|
||||
|
@ -390,6 +374,11 @@ static Class SOGoMailFolderK;
|
|||
return value;
|
||||
}
|
||||
|
||||
- (SOGoFolder *) aclFolder
|
||||
{
|
||||
return (SOGoFolder *) sogoObject;
|
||||
}
|
||||
|
||||
/* synchronisation */
|
||||
|
||||
/* Tree:
|
||||
|
@ -1007,6 +996,65 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
|||
return newMessage;
|
||||
}
|
||||
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
NSMutableArray *roles;
|
||||
|
||||
roles = [NSMutableArray arrayWithCapacity: 6];
|
||||
if (rights & RoleOwner)
|
||||
[roles addObject: SOGoMailRole_Administrator];
|
||||
if (rights & RightsCreateItems)
|
||||
{
|
||||
[roles addObject: SOGoRole_ObjectCreator];
|
||||
[roles addObject: SOGoMailRole_Writer];
|
||||
[roles addObject: SOGoMailRole_Poster];
|
||||
}
|
||||
if (rights & RightsDeleteAll)
|
||||
{
|
||||
[roles addObject: SOGoRole_ObjectEraser];
|
||||
[roles addObject: SOGoRole_FolderEraser];
|
||||
[roles addObject: SOGoMailRole_Expunger];
|
||||
}
|
||||
if (rights & RightsEditAll)
|
||||
[roles addObject: SOGoRole_ObjectEditor];
|
||||
if (rights & RightsReadItems)
|
||||
[roles addObject: SOGoRole_ObjectViewer];
|
||||
if (rights & RightsCreateSubfolders)
|
||||
[roles addObject: SOGoRole_FolderCreator];
|
||||
if (rights & RightsCreateSubfolders)
|
||||
[roles addObject: SOGoRole_FolderCreator];
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
|
||||
if ([roles containsObject: SOGoMailRole_Administrator])
|
||||
rights |= (RoleOwner ^ RightsAll);
|
||||
if ([roles containsObject: SOGoRole_ObjectCreator])
|
||||
rights |= RightsCreateItems;
|
||||
if ([roles containsObject: SOGoRole_ObjectEraser]
|
||||
&& [roles containsObject: SOGoRole_FolderEraser])
|
||||
rights |= RightsDeleteAll;
|
||||
|
||||
if ([roles containsObject: SOGoRole_ObjectEditor])
|
||||
rights |= RightsEditAll;
|
||||
if ([roles containsObject: SOGoRole_ObjectViewer])
|
||||
rights |= RightsReadItems;
|
||||
if ([roles containsObject: SOGoRole_FolderCreator])
|
||||
rights |= RightsCreateSubfolders;
|
||||
if ([roles containsObject: SOGoRole_FolderCreator])
|
||||
rights |= RightsCreateSubfolders;
|
||||
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MAPIStoreInboxFolder : MAPIStoreMailFolder
|
||||
|
@ -1103,26 +1151,28 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
|||
|
||||
- (id) lookupFolder: (NSString *) childKey
|
||||
{
|
||||
id childObject = nil;
|
||||
MAPIStoreMailFolder *childFolder = nil;
|
||||
SOGoMailAccount *account;
|
||||
SOGoMailFolder *childFolder;
|
||||
SOGoMailFolder *sogoFolder;
|
||||
WOContext *woContext;
|
||||
|
||||
if (usesAltNameSpace)
|
||||
{
|
||||
[self folderKeys];
|
||||
if ([folderKeys containsObject: childKey])
|
||||
if ([[self folderKeys] containsObject: childKey])
|
||||
{
|
||||
woContext = [[self context] woContext];
|
||||
account = [(SOGoMailFolder *) sogoObject mailAccountFolder];
|
||||
childFolder = [account lookupName: childKey inContext: nil
|
||||
acquire: NO];
|
||||
childObject = [MAPIStoreMailFolder mapiStoreObjectWithSOGoObject: childFolder
|
||||
inContainer: self];
|
||||
sogoFolder = [account lookupName: childKey inContext: woContext
|
||||
acquire: NO];
|
||||
[sogoFolder setContext: woContext];
|
||||
childFolder = [MAPIStoreMailFolder mapiStoreObjectWithSOGoObject: sogoFolder
|
||||
inContainer: self];
|
||||
}
|
||||
}
|
||||
else
|
||||
childObject = [super lookupFolder: childKey];
|
||||
childFolder = [super lookupFolder: childKey];
|
||||
|
||||
return childObject;
|
||||
return childFolder;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#import "MAPIStoreMailAttachment.h"
|
||||
#import "MAPIStoreMailFolder.h"
|
||||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
||||
#import "MAPIStoreMailMessage.h"
|
||||
|
@ -263,6 +264,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
iCalCalendar *calendar;
|
||||
iCalEvent *event;
|
||||
NSString *stringValue, *senderEmail;
|
||||
MAPIStoreContext *context;
|
||||
|
||||
if (!appointmentWrapper)
|
||||
{
|
||||
|
@ -280,11 +282,13 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
senderEmail = [[from objectAtIndex: 0] email];
|
||||
else
|
||||
senderEmail = nil;
|
||||
context = [self context];
|
||||
appointmentWrapper = [MAPIStoreAppointmentWrapper
|
||||
wrapperWithICalEvent: event
|
||||
andUser: [[self context] activeUser]
|
||||
andUser: [context activeUser]
|
||||
andSenderEmail: senderEmail
|
||||
inTimeZone: [self ownerTimeZone]];
|
||||
inTimeZone: [self ownerTimeZone]
|
||||
withConnectionInfo: [context connectionInfo]];
|
||||
[appointmentWrapper retain];
|
||||
}
|
||||
}
|
||||
|
@ -721,6 +725,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
NSDictionary *contactInfos;
|
||||
NGMailAddress *ngAddress;
|
||||
NSData *entryId;
|
||||
struct ldb_context *samCtx;
|
||||
int rc;
|
||||
|
||||
if (fullMail)
|
||||
|
@ -743,7 +748,8 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
if (contactInfos)
|
||||
{
|
||||
username = [contactInfos objectForKey: @"c_uid"];
|
||||
entryId = MAPIStoreInternalEntryId (username);
|
||||
samCtx = [[self context] connectionInfo]->sam_ctx;
|
||||
entryId = MAPIStoreInternalEntryId (samCtx, username);
|
||||
}
|
||||
else
|
||||
entryId = MAPIStoreExternalEntryId (cn, email);
|
||||
|
@ -1349,9 +1355,11 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
NSData *entryId;
|
||||
NSDictionary *contactInfos;
|
||||
SOGoUserManager *mgr;
|
||||
struct ldb_context *samCtx;
|
||||
struct mapistore_message *msgData;
|
||||
struct mapistore_message_recipient *recipient;
|
||||
|
||||
samCtx = [[self context] connectionInfo]->sam_ctx;
|
||||
[super getMessageData: &msgData inMemCtx: memCtx];
|
||||
|
||||
if (!headerSetup)
|
||||
|
@ -1397,7 +1405,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
{
|
||||
username = [contactInfos objectForKey: @"c_uid"];
|
||||
recipient->username = [username asUnicodeInMemCtx: msgData];
|
||||
entryId = MAPIStoreInternalEntryId (username);
|
||||
entryId = MAPIStoreInternalEntryId (samCtx, username);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#import "MAPIStoreMailFolder.h"
|
||||
#import "MAPIStoreMIME.h"
|
||||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
|
@ -249,10 +250,13 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
|
|||
NSData *entryId;
|
||||
NSDictionary *allRecipients, *dict, *contactInfos;
|
||||
SOGoUserManager *mgr;
|
||||
struct ldb_context *samCtx;
|
||||
struct mapistore_message *msgData;
|
||||
struct mapistore_message_recipient *recipient;
|
||||
enum ulRecipClass type;
|
||||
|
||||
samCtx = [[self context] connectionInfo]->sam_ctx;
|
||||
|
||||
[super getMessageData: &msgData inMemCtx: memCtx];
|
||||
|
||||
allRecipients = [[sogoObject properties] objectForKey: @"recipients"];
|
||||
|
@ -295,7 +299,7 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
|
|||
{
|
||||
username = [contactInfos objectForKey: @"c_uid"];
|
||||
recipient->username = [username asUnicodeInMemCtx: msgData];
|
||||
entryId = MAPIStoreInternalEntryId (username);
|
||||
entryId = MAPIStoreInternalEntryId (samCtx, username);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -759,7 +763,7 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
|||
messageData = cleanedMessage;
|
||||
}
|
||||
|
||||
[messageData writeToFile: @"/tmp/mimegen.eml" atomically: NO];
|
||||
// [messageData writeToFile: @"/tmp/mimegen.eml" atomically: NO];
|
||||
|
||||
return messageData;
|
||||
}
|
||||
|
@ -812,7 +816,7 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
|||
mapping = [[self context] mapping];
|
||||
[mapping unregisterURLWithID: [self objectId]];
|
||||
[self setIsNew: NO];
|
||||
[self resetProperties];
|
||||
[properties removeAllObjects];
|
||||
[[self container] cleanupCaches];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
|
|
@ -37,9 +37,6 @@
|
|||
|
||||
#import "MAPIStoreObject.h"
|
||||
|
||||
extern NSData *MAPIStoreInternalEntryId (NSString *username);
|
||||
extern NSData *MAPIStoreExternalEntryId (NSString *cn, NSString *email);
|
||||
|
||||
@interface MAPIStoreMessage : MAPIStoreObject
|
||||
{
|
||||
NSArray *attachmentKeys;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSBundle.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
@ -35,6 +36,7 @@
|
|||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreFolder.h"
|
||||
#import "MAPIStorePropertySelectors.h"
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
|
@ -42,6 +44,8 @@
|
|||
|
||||
#import "MAPIStoreMessage.h"
|
||||
|
||||
#include <unrtf.h>
|
||||
|
||||
#undef DEBUG
|
||||
#include <stdbool.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
@ -49,102 +53,64 @@
|
|||
#include <mapistore/mapistore_errors.h>
|
||||
#include <mapistore/mapistore_nameid.h>
|
||||
|
||||
NSData *
|
||||
MAPIStoreInternalEntryId (NSString *username)
|
||||
static NSString *resourcesDir = nil;
|
||||
|
||||
/* rtf conversion via unrtf */
|
||||
static int
|
||||
unrtf_data_output (void *data, const char *str, size_t str_len)
|
||||
{
|
||||
NSMutableData *entryId;
|
||||
static uint8_t providerUid[] = { 0xdc, 0xa7, 0x40, 0xc8,
|
||||
0xc0, 0x42, 0x10, 0x1a,
|
||||
0xb4, 0xb9, 0x08, 0x00,
|
||||
0x2b, 0x2f, 0xe1, 0x82 };
|
||||
NSString *x500dn;
|
||||
NSMutableData *rtfData = data;
|
||||
|
||||
/* structure:
|
||||
flags: 32
|
||||
provideruid: 32 * 4
|
||||
version: 32
|
||||
type: 32
|
||||
X500DN: variable */
|
||||
[rtfData appendBytes: str length: str_len];
|
||||
|
||||
entryId = [NSMutableData dataWithCapacity: 256];
|
||||
[entryId appendUInt32: 0]; // flags
|
||||
[entryId appendBytes: providerUid length: 16]; // provideruid
|
||||
[entryId appendUInt32: 1]; // version
|
||||
[entryId appendUInt32: 0]; // type (local mail user)
|
||||
|
||||
/* X500DN */
|
||||
/* FIXME: the DN will likely work on DEMO installations for now but we
|
||||
really should get the dn prefix from the server */
|
||||
x500dn = [NSString stringWithFormat: @"/O=FIRST ORGANIZATION"
|
||||
@"/OU=FIRST ADMINISTRATIVE GROUP"
|
||||
@"/CN=RECIPIENTS/CN=%@", username];
|
||||
[entryId appendData: [x500dn dataUsingEncoding: NSISOLatin1StringEncoding]];
|
||||
[entryId appendUInt8: 0];
|
||||
|
||||
return entryId;
|
||||
return str_len;
|
||||
}
|
||||
|
||||
NSData *
|
||||
MAPIStoreExternalEntryId (NSString *cn, NSString *email)
|
||||
static NSData *
|
||||
uncompressRTF (NSData *compressedRTF)
|
||||
{
|
||||
NSMutableData *entryId;
|
||||
static uint8_t providerUid[] = { 0x81, 0x2b, 0x1f, 0xa4,
|
||||
0xbe, 0xa3, 0x10, 0x19,
|
||||
0x9d, 0x6e, 0x00, 0xdd,
|
||||
0x01, 0x0f, 0x54, 0x02 };
|
||||
uint8_t flags21, flags22;
|
||||
NSData *rtfData = nil;
|
||||
DATA_BLOB *rtf;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
/* structure:
|
||||
flags: 32
|
||||
provideruid: 32 * 4
|
||||
version: 16
|
||||
{
|
||||
PaD: 1
|
||||
MAE: 2
|
||||
Format: 4
|
||||
M: 1
|
||||
U: 1
|
||||
R: 2
|
||||
L: 1
|
||||
Pad: 4
|
||||
}
|
||||
DisplayName: variable
|
||||
AddressType: variable
|
||||
EmailAddress: variable */
|
||||
mem_ctx = talloc_zero (NULL, TALLOC_CTX);
|
||||
rtf = talloc_zero (mem_ctx, DATA_BLOB);
|
||||
|
||||
entryId = [NSMutableData dataWithCapacity: 256];
|
||||
[entryId appendUInt32: 0]; // flags
|
||||
[entryId appendBytes: providerUid length: 16]; // provideruid
|
||||
[entryId appendUInt16: 0]; // version
|
||||
if (uncompress_rtf (mem_ctx,
|
||||
(uint8_t *) [compressedRTF bytes], [compressedRTF length],
|
||||
rtf)
|
||||
== MAPI_E_SUCCESS)
|
||||
rtfData = [NSData dataWithBytes: rtf->data length: rtf->length];
|
||||
|
||||
flags21 = 0; /* PaD, MAE, R, Pad = 0 */
|
||||
flags21 |= 0x16; /* Format: text and HTML */
|
||||
flags21 |= 0x01; /* M: mime format */
|
||||
talloc_free (mem_ctx);
|
||||
|
||||
flags22 = 0x90; /* U: unicode, L: no lookup */
|
||||
[entryId appendUInt8: flags21];
|
||||
[entryId appendUInt8: flags22];
|
||||
return rtfData;
|
||||
}
|
||||
|
||||
/* DisplayName */
|
||||
if (!cn)
|
||||
cn = @"";
|
||||
[entryId
|
||||
appendData: [cn dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
|
||||
[entryId appendUInt16: 0];
|
||||
static NSData *
|
||||
rtf2html (NSData *compressedRTF)
|
||||
{
|
||||
NSData *rtf;
|
||||
NSMutableData *html = nil;
|
||||
int rc;
|
||||
struct unRTFOptions unrtfOptions;
|
||||
|
||||
/* AddressType */
|
||||
[entryId
|
||||
appendData: [@"SMTP" dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
|
||||
[entryId appendUInt16: 0];
|
||||
rtf = uncompressRTF (compressedRTF);
|
||||
if (rtf)
|
||||
{
|
||||
html = [NSMutableData data];
|
||||
memset (&unrtfOptions, 0, sizeof (struct unRTFOptions));
|
||||
unrtf_set_output_device (&unrtfOptions, unrtf_data_output, html);
|
||||
unrtfOptions.config_directory = [resourcesDir UTF8String];
|
||||
unrtfOptions.output_format = "html";
|
||||
unrtfOptions.nopict_mode = YES;
|
||||
rc = unrtf_convert_from_string (&unrtfOptions,
|
||||
[rtf bytes], [rtf length]);
|
||||
if (!rc)
|
||||
html = nil;
|
||||
}
|
||||
|
||||
/* EMailAddress */
|
||||
if (!email)
|
||||
email = @"";
|
||||
[entryId
|
||||
appendData: [email dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
|
||||
[entryId appendUInt16: 0];
|
||||
|
||||
return entryId;
|
||||
return html;
|
||||
}
|
||||
|
||||
@interface SOGoObject (MAPIStoreProtocol)
|
||||
|
@ -156,6 +122,15 @@ MAPIStoreExternalEntryId (NSString *cn, NSString *email)
|
|||
|
||||
@implementation MAPIStoreMessage
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (!resourcesDir)
|
||||
{
|
||||
resourcesDir = [[NSBundle bundleForClass: self] resourcePath];
|
||||
[resourcesDir retain];
|
||||
}
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
|
@ -304,6 +279,38 @@ MAPIStoreExternalEntryId (NSString *cn, NSString *email)
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (void) addProperties: (NSDictionary *) newNewProperties
|
||||
{
|
||||
NSData *htmlData, *rtfData;
|
||||
static NSNumber *htmlKey = nil, *rtfKey = nil;
|
||||
|
||||
[super addProperties: newNewProperties];
|
||||
|
||||
if (!htmlKey)
|
||||
{
|
||||
htmlKey = MAPIPropertyKey (PR_HTML);
|
||||
[htmlKey retain];
|
||||
}
|
||||
|
||||
if (!rtfKey)
|
||||
{
|
||||
rtfKey = MAPIPropertyKey (PR_RTF_COMPRESSED);
|
||||
[rtfKey retain];
|
||||
}
|
||||
|
||||
if (![properties objectForKey: htmlKey])
|
||||
{
|
||||
rtfData = [properties objectForKey: rtfKey];
|
||||
if (rtfData)
|
||||
{
|
||||
htmlData = rtf2html (rtfData);
|
||||
[properties setObject: htmlData forKey: htmlKey];
|
||||
[properties removeObjectForKey: rtfKey];
|
||||
[properties removeObjectForKey: MAPIPropertyKey (PR_RTF_IN_SYNC)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (MAPIStoreAttachment *) createAttachment
|
||||
{
|
||||
MAPIStoreAttachment *newAttachment;
|
||||
|
@ -460,7 +467,7 @@ MAPIStoreExternalEntryId (NSString *cn, NSString *email)
|
|||
[[containerTables objectAtIndex: count]
|
||||
notifyChangesForChild: self];
|
||||
[self setIsNew: NO];
|
||||
[self resetProperties];
|
||||
[properties removeAllObjects];
|
||||
[container cleanupCaches];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -744,7 +751,7 @@ MAPIStoreExternalEntryId (NSString *cn, NSString *email)
|
|||
|
||||
- (int) setReadFlag: (uint8_t) flag
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
// [self subclassResponsibility: _cmd];
|
||||
|
||||
return MAPISTORE_ERROR;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,6 @@
|
|||
|
||||
- (void) addProperties: (NSDictionary *) newProperties;
|
||||
- (NSDictionary *) properties;
|
||||
- (void) resetProperties;
|
||||
|
||||
/* ops */
|
||||
- (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
|
||||
|
|
|
@ -235,11 +235,6 @@ static Class NSExceptionK, MAPIStoreFolderK;
|
|||
return properties;
|
||||
}
|
||||
|
||||
- (void) resetProperties
|
||||
{
|
||||
[properties removeAllObjects];
|
||||
}
|
||||
|
||||
- (int) getProperty: (void **) data
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
|
@ -252,7 +247,7 @@ static Class NSExceptionK, MAPIStoreFolderK;
|
|||
|
||||
value = [properties objectForKey: MAPIPropertyKey (propTag)];
|
||||
if (value)
|
||||
rc = [value getMAPIValue: data forTag: propTag inMemCtx: memCtx];
|
||||
rc = [value getValue: data forTag: propTag inMemCtx: memCtx];
|
||||
else
|
||||
{
|
||||
propValue = (propTag & 0xffff0000) >> 16;
|
||||
|
@ -451,14 +446,18 @@ static Class NSExceptionK, MAPIStoreFolderK;
|
|||
{
|
||||
struct SPropValue *cValue;
|
||||
NSUInteger counter;
|
||||
NSMutableDictionary *newProperties;
|
||||
|
||||
newProperties = [NSMutableDictionary dictionaryWithCapacity: aRow->cValues];
|
||||
for (counter = 0; counter < aRow->cValues; counter++)
|
||||
{
|
||||
cValue = aRow->lpProps + counter;
|
||||
[properties setObject: NSObjectFromSPropValue (cValue)
|
||||
forKey: MAPIPropertyKey (cValue->ulPropTag)];
|
||||
[newProperties setObject: NSObjectFromSPropValue (cValue)
|
||||
forKey: MAPIPropertyKey (cValue->ulPropTag)];
|
||||
}
|
||||
|
||||
[self addProperties: newProperties];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,31 @@
|
|||
|
||||
#import "MAPIStoreTable.h"
|
||||
|
||||
struct ldb_context;
|
||||
|
||||
@interface MAPIStorePermissionEntry : MAPIStoreObject
|
||||
{
|
||||
NSString *userId;
|
||||
uint64_t memberId;
|
||||
}
|
||||
|
||||
+ (id) entryWithUserId: (NSString *) newUserId
|
||||
andMemberId: (uint64_t) newMemberId
|
||||
forFolder: (MAPIStoreFolder *) newFolder;
|
||||
- (id) initWithUserId: (NSString *) newUserId
|
||||
andMemberId: (uint64_t) newMemberId
|
||||
forFolder: (MAPIStoreFolder *) newFolder;
|
||||
|
||||
- (NSString *) userId;
|
||||
- (uint64_t) memberId;
|
||||
|
||||
@end
|
||||
|
||||
@interface MAPIStorePermissionsTable : MAPIStoreTable
|
||||
{
|
||||
NSMutableDictionary *entries;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif /* MAPISTOREPERMISSIONSTABLE_H */
|
||||
|
|
|
@ -21,44 +21,48 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import "MAPIStoreObject.h"
|
||||
#import <SOGo/SOGoObject.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreFolder.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
||||
#import "MAPIStorePermissionsTable.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
@interface MAPIStorePermissionEntry : MAPIStoreObject
|
||||
{
|
||||
NSString *userId;
|
||||
}
|
||||
|
||||
+ (id) entryWithUserId: (NSString *) newUserId;
|
||||
- (id) initWithUserId: (NSString *) newUserId;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MAPIStorePermissionEntry
|
||||
|
||||
+ (id) entryWithUserId: (NSString *) newUserId
|
||||
andMemberId: (uint64_t) newMemberId
|
||||
forFolder: (MAPIStoreFolder *) newFolder
|
||||
{
|
||||
MAPIStorePermissionEntry *newEntry;
|
||||
|
||||
newEntry = [[self alloc] initWithUserId: newUserId];
|
||||
newEntry = [[self alloc] initWithUserId: newUserId andMemberId: newMemberId
|
||||
forFolder: newFolder];
|
||||
[newEntry autorelease];
|
||||
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
- (id) initWithUserId: (NSString *) newUserId
|
||||
andMemberId: (uint64_t) newMemberId
|
||||
forFolder: (MAPIStoreFolder *) newFolder
|
||||
{
|
||||
if ((self = [self init]))
|
||||
if ((self = [self initWithSOGoObject: nil inContainer: newFolder]))
|
||||
{
|
||||
ASSIGN (userId, newUserId);
|
||||
memberId = newMemberId;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -70,15 +74,20 @@
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString *) userId
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
|
||||
- (uint64_t) memberId
|
||||
{
|
||||
return memberId;
|
||||
}
|
||||
|
||||
- (int) getPrMemberId: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
uint64_t value = 0;
|
||||
|
||||
if ([userId isEqualToString: @"anonymous"])
|
||||
value = ULLONG_MAX;
|
||||
|
||||
*data = MAPILongLongValue (memCtx, value);
|
||||
*data = MAPILongLongValue (memCtx, memberId);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -86,7 +95,17 @@
|
|||
- (int) getPrEntryid: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = [[NSData data] asBinaryInMemCtx: memCtx];
|
||||
NSData *entryId;
|
||||
struct mapistore_connection_info *connInfo;
|
||||
|
||||
if (memberId == 0 || memberId == ULLONG_MAX)
|
||||
entryId = [NSData data];
|
||||
else
|
||||
{
|
||||
connInfo = [[container context] connectionInfo];
|
||||
entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, userId);
|
||||
}
|
||||
*data = [entryId asBinaryInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -94,7 +113,16 @@
|
|||
- (int) getPrMemberName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = [userId asUnicodeInMemCtx: memCtx];
|
||||
NSString *displayName;
|
||||
|
||||
if (memberId == 0)
|
||||
displayName = @"";
|
||||
else if (memberId == ULLONG_MAX)
|
||||
displayName = @"Anonymous";
|
||||
else
|
||||
displayName = [[SOGoUser userWithLogin: userId] cn];
|
||||
|
||||
*data = [displayName asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -102,7 +130,13 @@
|
|||
- (int) getPrMemberRights: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPILongValue (memCtx, 0);
|
||||
uint32_t rights;
|
||||
NSArray *roles;
|
||||
|
||||
roles = [[(MAPIStoreFolder *) container aclFolder] aclsForUser: userId];
|
||||
rights = [(MAPIStoreFolder *) container exchangeRightsForRoles: roles];
|
||||
|
||||
*data = MAPILongValue (memCtx, rights);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -111,9 +145,37 @@
|
|||
|
||||
@implementation MAPIStorePermissionsTable
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[entries release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) _fetchEntries
|
||||
{
|
||||
NSArray *permEntries;
|
||||
NSUInteger count, max;
|
||||
MAPIStorePermissionEntry *entry;
|
||||
|
||||
entries = [NSMutableDictionary new];
|
||||
permEntries = [(MAPIStoreFolder *) container permissionEntries];
|
||||
max = [permEntries count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
entry = [permEntries objectAtIndex: count];
|
||||
[entries setObject: entry forKey: [entry userId]];
|
||||
}
|
||||
|
||||
childKeys = [entries allKeys];
|
||||
[childKeys retain];
|
||||
}
|
||||
|
||||
- (NSArray *) childKeys
|
||||
{
|
||||
return [NSArray arrayWithObjects: @"default", @"anonymous", nil];
|
||||
if (!entries)
|
||||
[self _fetchEntries];
|
||||
|
||||
return childKeys;
|
||||
}
|
||||
|
||||
- (NSArray *) restrictedChildKeys
|
||||
|
@ -123,7 +185,10 @@
|
|||
|
||||
- (id) lookupChild: (NSString *) childKey
|
||||
{
|
||||
return [MAPIStorePermissionEntry entryWithUserId: childKey];
|
||||
if (!entries)
|
||||
[self _fetchEntries];
|
||||
|
||||
return [entries objectForKey: childKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
#import <NGCards/iCalCalendar.h>
|
||||
#import <NGCards/iCalRecurrenceRule.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <gen_ndr/property.h>
|
||||
|
||||
@class NSCalendarDate;
|
||||
@class iCalRepeatableEntityObject;
|
||||
@class iCalRecurrenceRule;
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
#import "NSDate+MAPIStore.h"
|
||||
#import "MAPIStoreRecurrenceUtils.h"
|
||||
|
||||
#include <talloc.h>
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/property.h>
|
||||
|
||||
@implementation iCalCalendar (MAPIStoreRecurrence)
|
||||
|
||||
- (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity
|
||||
|
@ -92,7 +96,7 @@
|
|||
[rule setFrequency: iCalRecurrenceFrequenceYearly];
|
||||
[rule setRepeatInterval: rp->Period / 12];
|
||||
month = [NSString stringWithFormat: @"%d", [startDate monthOfYear]];
|
||||
[rule setNamedValue: @"bymonth" to: month];
|
||||
[rule setSingleValue: month forKey: @"bymonth"];
|
||||
}
|
||||
else
|
||||
[self errorWithFormat:
|
||||
|
@ -112,7 +116,7 @@
|
|||
else
|
||||
monthDay = [NSString stringWithFormat: @"%d",
|
||||
rp->PatternTypeSpecific.MonthRecurrencePattern.N];
|
||||
[rule setNamedValue: @"bymonthday" to: monthDay];
|
||||
[rule setSingleValue: monthDay forKey: @"bymonthday"];
|
||||
}
|
||||
else if ((rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern
|
||||
== 0x3e) /* Nth week day */
|
||||
|
@ -135,8 +139,9 @@
|
|||
else
|
||||
bySetPos = rp->PatternTypeSpecific.MonthRecurrencePattern.N;
|
||||
|
||||
[rule setNamedValue: @"bysetpos"
|
||||
to: [NSString stringWithFormat: @"%d", bySetPos]];
|
||||
[rule
|
||||
setSingleValue: [NSString stringWithFormat: @"%d", bySetPos]
|
||||
forKey: @"bysetpos"];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -163,9 +168,10 @@
|
|||
|| (rp->PatternType & 4) == 4)
|
||||
{
|
||||
/* MonthEnd, HjMonth and HjMonthEnd */
|
||||
[rule setNamedValue: @"bymonthday"
|
||||
to: [NSString stringWithFormat: @"%d",
|
||||
rp->PatternTypeSpecific.Day]];
|
||||
[rule
|
||||
setSingleValue: [NSString stringWithFormat: @"%d",
|
||||
rp->PatternTypeSpecific.Day]
|
||||
forKey: @"bymonthday"];
|
||||
}
|
||||
else
|
||||
[self errorWithFormat: @"invalid value for PatternType: %.4x",
|
||||
|
@ -305,6 +311,14 @@
|
|||
rp->FirstDateTime = [moduloDate asMinutesSince1601];
|
||||
|
||||
byMonthDay = [[self byMonthDay] objectAtIndex: 0];
|
||||
if (!byMonthDay && (freq == iCalRecurrenceFrequenceYearly))
|
||||
{
|
||||
byMonthDay = [NSString stringWithFormat: @"%d", [startDate dayOfMonth]];
|
||||
[self warnWithFormat: @"no month day specified in yearly"
|
||||
@" recurrence: we deduce it from the start date: %@",
|
||||
byMonthDay];
|
||||
}
|
||||
|
||||
if (byMonthDay)
|
||||
{
|
||||
if ([byMonthDay intValue] < 0)
|
||||
|
@ -325,15 +339,18 @@
|
|||
{
|
||||
rp->PatternType = PatternType_MonthNth;
|
||||
byDayMask = [self byDayMask];
|
||||
days = [byDayMask weekDayOccurrences];
|
||||
mask = 0;
|
||||
for (count = 0; count < 7; count++)
|
||||
if (days[0][count])
|
||||
mask |= 1 << count;
|
||||
days = [byDayMask weekDayOccurrences];
|
||||
if (days)
|
||||
{
|
||||
for (count = 0; count < 7; count++)
|
||||
if (days[0][count])
|
||||
mask |= 1 << count;
|
||||
}
|
||||
if (mask)
|
||||
{
|
||||
rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern = mask;
|
||||
bySetPos = [self namedValue: @"bysetpos"];
|
||||
bySetPos = [self flattenedValuesForKey: @"bysetpos"];
|
||||
if ([bySetPos length])
|
||||
rp->PatternTypeSpecific.MonthRecurrencePattern.N
|
||||
= ([bySetPos hasPrefix: @"-"]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreSOGo.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010, 2011 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -100,6 +100,7 @@ sogo_backend_init (void)
|
|||
[[MAPIApplicationK new] activateApplication];
|
||||
|
||||
[[SOGoCache sharedCache] disableRequestsCache];
|
||||
[[SOGoCache sharedCache] disableLocalCache];
|
||||
|
||||
[pool release];
|
||||
|
||||
|
@ -554,6 +555,36 @@ sogo_folder_open_table(void *folder_object, TALLOC_CTX *mem_ctx,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
sogo_folder_modify_permissions(void *folder_object, uint8_t flags,
|
||||
uint16_t pcount,
|
||||
struct PermissionData *permissions)
|
||||
{
|
||||
struct MAPIStoreTallocWrapper *wrapper;
|
||||
NSAutoreleasePool *pool;
|
||||
MAPIStoreFolder *folder;
|
||||
int rc;
|
||||
|
||||
DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__));
|
||||
|
||||
if (folder_object)
|
||||
{
|
||||
wrapper = folder_object;
|
||||
folder = wrapper->MAPIStoreSOGoObject;
|
||||
pool = [NSAutoreleasePool new];
|
||||
rc = [folder modifyPermissions: permissions
|
||||
withCount: pcount
|
||||
andFlags: flags];
|
||||
[pool release];
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = sogo_backend_unexpected_error();
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
sogo_message_get_message_data(void *message_object,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
|
@ -1189,6 +1220,7 @@ int mapistore_init_backend(void)
|
|||
backend.folder.get_deleted_fmids = sogo_folder_get_deleted_fmids;
|
||||
backend.folder.get_child_count = sogo_folder_get_child_count;
|
||||
backend.folder.open_table = sogo_folder_open_table;
|
||||
backend.folder.modify_permissions = sogo_folder_modify_permissions;
|
||||
backend.message.create_attachment = sogo_message_create_attachment;
|
||||
backend.message.get_attachment_table = sogo_message_get_attachment_table;
|
||||
backend.message.open_attachment = sogo_message_open_attachment;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/* MAPIStoreSamDBUtils.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, 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 MAPISTORESAMDBUTILS_H
|
||||
#define MAPISTORESAMDBUTILS_H
|
||||
|
||||
@class NSString;
|
||||
|
||||
struct ldb_context;
|
||||
|
||||
NSString *MAPIStoreSamDBUserAttribute (struct ldb_context *samCtx,
|
||||
NSString *userKey,
|
||||
NSString *value,
|
||||
NSString *attributeName);
|
||||
NSData *MAPIStoreInternalEntryId (struct ldb_context *, NSString *username);
|
||||
NSData *MAPIStoreExternalEntryId (NSString *cn, NSString *email);
|
||||
|
||||
#endif /* MAPISTORESAMDBUTILS_H */
|
|
@ -0,0 +1,165 @@
|
|||
/* MAPIStoreSamDBUtils.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, 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 <Foundation/NSData.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#include <talloc.h>
|
||||
#include <ldb.h>
|
||||
|
||||
#import "NSData+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
|
||||
NSString *
|
||||
MAPIStoreSamDBUserAttribute (struct ldb_context *samCtx,
|
||||
NSString *userKey,
|
||||
NSString *value,
|
||||
NSString *attributeName)
|
||||
{
|
||||
NSString *resultValue = nil;
|
||||
const char *attrs[] = { "", NULL };
|
||||
NSString *searchFormat;
|
||||
const char *result;
|
||||
struct ldb_result *res = NULL;
|
||||
TALLOC_CTX *memCtx;
|
||||
int ret;
|
||||
|
||||
memCtx = talloc_zero(NULL, TALLOC_CTX);
|
||||
|
||||
attrs[0] = [attributeName UTF8String];
|
||||
searchFormat
|
||||
= [NSString stringWithFormat: @"(&(objectClass=user)(%@=%%s))", userKey];
|
||||
ret = ldb_search (samCtx, memCtx, &res, ldb_get_default_basedn(samCtx),
|
||||
LDB_SCOPE_SUBTREE, attrs,
|
||||
[searchFormat UTF8String],
|
||||
[value UTF8String]);
|
||||
if (ret == LDB_SUCCESS && res->count == 1)
|
||||
{
|
||||
result = ldb_msg_find_attr_as_string (res->msgs[0], attrs[0], NULL);
|
||||
if (result)
|
||||
resultValue = [NSString stringWithUTF8String: result];
|
||||
}
|
||||
|
||||
talloc_free (memCtx);
|
||||
|
||||
return resultValue;
|
||||
}
|
||||
|
||||
NSData *
|
||||
MAPIStoreInternalEntryId (struct ldb_context *samCtx, NSString *username)
|
||||
{
|
||||
static const uint8_t const providerUid[] = { 0xdc, 0xa7, 0x40, 0xc8,
|
||||
0xc0, 0x42, 0x10, 0x1a,
|
||||
0xb4, 0xb9, 0x08, 0x00,
|
||||
0x2b, 0x2f, 0xe1, 0x82 };
|
||||
NSMutableData *entryId;
|
||||
NSData *legacyDNData;
|
||||
NSString *legacyDN;
|
||||
|
||||
/* structure:
|
||||
flags: 32
|
||||
provideruid: 32 * 4
|
||||
version: 32
|
||||
type: 32
|
||||
X500DN: variable */
|
||||
|
||||
legacyDN = MAPIStoreSamDBUserAttribute (samCtx, @"sAMAccountName", username,
|
||||
@"legacyExchangeDN");
|
||||
if (legacyDN)
|
||||
{
|
||||
entryId = [NSMutableData dataWithCapacity: 256];
|
||||
[entryId appendUInt32: 0]; // flags
|
||||
[entryId appendBytes: providerUid length: 16]; // provideruid
|
||||
[entryId appendUInt32: 1]; // version
|
||||
[entryId appendUInt32: 0]; // type (local mail user)
|
||||
legacyDNData = [legacyDN dataUsingEncoding: NSASCIIStringEncoding];
|
||||
[entryId appendData: legacyDNData]; // x500dn
|
||||
[entryId appendUInt8: 0]; // end of string
|
||||
}
|
||||
else
|
||||
entryId = nil;
|
||||
|
||||
return entryId;
|
||||
}
|
||||
|
||||
NSData *
|
||||
MAPIStoreExternalEntryId (NSString *cn, NSString *email)
|
||||
{
|
||||
NSMutableData *entryId;
|
||||
static uint8_t providerUid[] = { 0x81, 0x2b, 0x1f, 0xa4,
|
||||
0xbe, 0xa3, 0x10, 0x19,
|
||||
0x9d, 0x6e, 0x00, 0xdd,
|
||||
0x01, 0x0f, 0x54, 0x02 };
|
||||
uint8_t flags21, flags22;
|
||||
|
||||
/* structure:
|
||||
flags: 32
|
||||
provideruid: 32 * 4
|
||||
version: 16
|
||||
{
|
||||
PaD: 1
|
||||
MAE: 2
|
||||
Format: 4
|
||||
M: 1
|
||||
U: 1
|
||||
R: 2
|
||||
L: 1
|
||||
Pad: 4
|
||||
}
|
||||
DisplayName: variable
|
||||
AddressType: variable
|
||||
EmailAddress: variable */
|
||||
|
||||
entryId = [NSMutableData dataWithCapacity: 256];
|
||||
[entryId appendUInt32: 0]; // flags
|
||||
[entryId appendBytes: providerUid length: 16]; // provideruid
|
||||
[entryId appendUInt16: 0]; // version
|
||||
|
||||
flags21 = 0; /* PaD, MAE, R, Pad = 0 */
|
||||
flags21 |= 0x16; /* Format: text and HTML */
|
||||
flags21 |= 0x01; /* M: mime format */
|
||||
|
||||
flags22 = 0x90; /* U: unicode, L: no lookup */
|
||||
[entryId appendUInt8: flags21];
|
||||
[entryId appendUInt8: flags22];
|
||||
|
||||
/* DisplayName */
|
||||
if (!cn)
|
||||
cn = @"";
|
||||
[entryId
|
||||
appendData: [cn dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
|
||||
[entryId appendUInt16: 0];
|
||||
|
||||
/* AddressType */
|
||||
[entryId
|
||||
appendData: [@"SMTP" dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
|
||||
[entryId appendUInt16: 0];
|
||||
|
||||
/* EMailAddress */
|
||||
if (!email)
|
||||
email = @"";
|
||||
[entryId
|
||||
appendData: [email dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
|
||||
[entryId appendUInt16: 0];
|
||||
|
||||
return entryId;
|
||||
}
|
|
@ -25,6 +25,7 @@
|
|||
#import <Foundation/NSURL.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
#import <Appointments/SOGoTaskObject.h>
|
||||
|
@ -36,6 +37,9 @@
|
|||
|
||||
#import "MAPIStoreTasksFolder.h"
|
||||
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
||||
@implementation MAPIStoreTasksFolder
|
||||
|
||||
- (id) initWithURL: (NSURL *) newURL
|
||||
|
@ -106,4 +110,51 @@
|
|||
return newMessage;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
NSMutableArray *roles;
|
||||
|
||||
roles = [NSMutableArray arrayWithCapacity: 6];
|
||||
if (rights & RightsCreateItems)
|
||||
[roles addObject: SOGoRole_ObjectCreator];
|
||||
if (rights & RightsDeleteAll)
|
||||
[roles addObject: SOGoRole_ObjectEraser];
|
||||
if (rights & RightsEditAll)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicModifier];
|
||||
[roles addObject: SOGoCalendarRole_PrivateModifier];
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialModifier];
|
||||
}
|
||||
else if (rights & RightsReadItems)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicViewer];
|
||||
[roles addObject: SOGoCalendarRole_PrivateViewer];
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialViewer];
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
|
||||
if ([roles containsObject: SOGoRole_ObjectCreator])
|
||||
rights |= RightsCreateItems;
|
||||
if ([roles containsObject: SOGoRole_ObjectEraser])
|
||||
rights |= RightsDeleteAll;
|
||||
if ([roles containsObject: SOGoCalendarRole_PublicModifier]
|
||||
&& [roles containsObject: SOGoCalendarRole_PrivateModifier]
|
||||
&& [roles containsObject: SOGoCalendarRole_ConfidentialModifier])
|
||||
rights |= RightsReadItems | RightsEditAll;
|
||||
else if ([roles containsObject: SOGoCalendarRole_PublicViewer]
|
||||
&& [roles containsObject: SOGoCalendarRole_PrivateViewer]
|
||||
&& [roles containsObject: SOGoCalendarRole_ConfidentialViewer])
|
||||
rights |= RightsReadItems;
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#import <Foundation/NSValue.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <talloc.h>
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
||||
@class NSData;
|
||||
|
@ -38,7 +40,7 @@ double *MAPIDoubleValue (void *memCtx, double value);
|
|||
|
||||
id NSObjectFromSPropValue (const struct SPropValue *);
|
||||
id NSObjectFromMAPISPropValue (const struct mapi_SPropValue *);
|
||||
id NSObjectFromValuePointer (enum MAPITAGS, void *);
|
||||
id NSObjectFromValuePointer (enum MAPITAGS, const void *);
|
||||
|
||||
static inline NSNumber *
|
||||
MAPIPropertyKey (enum MAPITAGS propTag)
|
||||
|
|
|
@ -20,24 +20,22 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
#include <talloc.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
#include <libmapi/libmapi.h>
|
||||
#include <libmapiproxy.h>
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSNull.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import "NSArray+MAPIStore.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSDate+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
uint8_t *
|
||||
MAPIBoolValue (void *memCtx, BOOL value)
|
||||
{
|
||||
|
@ -126,6 +124,22 @@ NSObjectFromMAPISPropValue (const struct mapi_SPropValue *value)
|
|||
result = [NSData dataWithGUID: &value->value.lpguid];
|
||||
break;
|
||||
|
||||
case PT_MV_LONG:
|
||||
result = [NSArray arrayFromMAPIMVLong: &value->value.MVl];
|
||||
break;
|
||||
case PT_MV_STRING8:
|
||||
result = [NSArray arrayFromMAPIMVString: &value->value.MVszA];
|
||||
break;
|
||||
case PT_MV_UNICODE:
|
||||
result = [NSArray arrayFromMAPIMVUnicode: &value->value.MVszW];
|
||||
break;
|
||||
case PT_MV_CLSID:
|
||||
result = [NSArray arrayFromMAPIMVGuid: &value->value.MVguid];
|
||||
break;
|
||||
case PT_MV_BINARY:
|
||||
result = [NSArray arrayFromMAPIMVBinary: &value->value.MVbin];
|
||||
break;
|
||||
|
||||
default:
|
||||
// #define PT_UNSPECIFIED 0x0
|
||||
// #define PT_I2 0x2
|
||||
|
@ -138,8 +152,9 @@ NSObjectFromMAPISPropValue (const struct mapi_SPropValue *value)
|
|||
// #define PT_SRESTRICT 0xFD
|
||||
// #define PT_ACTIONS 0xFE
|
||||
result = [NSNull null];
|
||||
abort();
|
||||
NSLog (@"%s: object type not handled: %d (0x%.4x)",
|
||||
__PRETTY_FUNCTION__, valueType, valueType);
|
||||
__PRETTY_FUNCTION__, valueType, valueType);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -192,6 +207,30 @@ NSObjectFromSPropValue (const struct SPropValue *value)
|
|||
case PT_CLSID:
|
||||
result = [NSData dataWithFlatUID: value->value.lpguid];
|
||||
break;
|
||||
case PT_MV_SHORT:
|
||||
result = [NSArray arrayFromMVShort: &value->value.MVi];
|
||||
break;
|
||||
case PT_MV_LONG:
|
||||
result = [NSArray arrayFromMVLong: &value->value.MVl];
|
||||
break;
|
||||
case PT_MV_I8:
|
||||
result = [NSArray arrayFromMVI8: &value->value.MVi8];
|
||||
break;
|
||||
case PT_MV_STRING8:
|
||||
result = [NSArray arrayFromMVString: &value->value.MVszA];
|
||||
break;
|
||||
case PT_MV_UNICODE:
|
||||
result = [NSArray arrayFromMVUnicode: &value->value.MVszW];
|
||||
break;
|
||||
case PT_MV_CLSID:
|
||||
result = [NSArray arrayFromMVGuid: &value->value.MVguid];
|
||||
break;
|
||||
case PT_MV_BINARY:
|
||||
result = [NSArray arrayFromMVBinary: &value->value.MVbin];
|
||||
break;
|
||||
case PT_MV_SYSTIME:
|
||||
result = [NSArray arrayFromMVFileTime: &value->value.MVft];
|
||||
break;
|
||||
|
||||
default:
|
||||
// #define PT_UNSPECIFIED 0x0
|
||||
|
@ -205,72 +244,24 @@ NSObjectFromSPropValue (const struct SPropValue *value)
|
|||
// #define PT_SRESTRICT 0xFD
|
||||
// #define PT_ACTIONS 0xFE
|
||||
result = [NSNull null];
|
||||
abort();
|
||||
NSLog (@"%s: object type not handled: %d (0x%.4x)",
|
||||
__PRETTY_FUNCTION__, valueType, valueType);
|
||||
__PRETTY_FUNCTION__, valueType, valueType);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
id
|
||||
NSObjectFromValuePointer (enum MAPITAGS propTag, void *data)
|
||||
NSObjectFromValuePointer (enum MAPITAGS propTag, const void *data)
|
||||
{
|
||||
struct SPropValue sPropValue;
|
||||
id result;
|
||||
|
||||
switch (propTag & 0xffff)
|
||||
{
|
||||
case PT_NULL:
|
||||
result = [NSNull null];
|
||||
break;
|
||||
case PT_SHORT:
|
||||
result = [NSNumber numberWithShort: *(int16_t *) data];
|
||||
break;
|
||||
case PT_LONG:
|
||||
result = [NSNumber numberWithLong: *(int32_t *) data];
|
||||
break;
|
||||
case PT_I8:
|
||||
result = [NSNumber numberWithUnsignedLongLong: *(uint64_t *) data];
|
||||
break;
|
||||
case PT_BOOLEAN:
|
||||
result = [NSNumber numberWithBool: ((*(uint8_t *) data) ? YES : NO)];
|
||||
break;
|
||||
case PT_DOUBLE:
|
||||
result = [NSNumber numberWithDouble: *(double *) data];
|
||||
break;
|
||||
case PT_UNICODE:
|
||||
result = [NSString stringWithUTF8String: data];
|
||||
break;
|
||||
case PT_STRING8:
|
||||
result = [NSString stringWithUTF8String: data];
|
||||
break;
|
||||
case PT_SYSTIME:
|
||||
result = [NSCalendarDate dateFromFileTime: data];
|
||||
break;
|
||||
case PT_BINARY:
|
||||
case PT_SVREID:
|
||||
// lpProps->value.bin = *((const struct Binary_r *)data);
|
||||
|
||||
result = [NSData dataWithBinary: (const struct Binary_r *) data];
|
||||
break;
|
||||
// case PT_CLSID:
|
||||
// result = [NSData dataWithFlatUID: value->value.lpguid];
|
||||
// break;
|
||||
|
||||
default:
|
||||
// #define PT_UNSPECIFIED 0x0
|
||||
// #define PT_I2 0x2
|
||||
// #define PT_CURRENCY 0x6
|
||||
// #define PT_APPTIME 0x7
|
||||
// #define PT_ERROR 0xa
|
||||
// #define PT_OBJECT 0xd
|
||||
// #define PT_I8 0x14
|
||||
// #define PT_SVREID 0xFB
|
||||
// #define PT_SRESTRICT 0xFD
|
||||
// #define PT_ACTIONS 0xFE
|
||||
result = [NSNull null];
|
||||
NSLog (@"%s: object type not handled: %d (0x%.8x)", __PRETTY_FUNCTION__,
|
||||
propTag, propTag);
|
||||
}
|
||||
if (set_SPropValue_proptag(&sPropValue, propTag, data))
|
||||
result = NSObjectFromSPropValue (&sPropValue);
|
||||
else
|
||||
result = nil;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -80,25 +80,10 @@ Class NSNumberK;
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (int) addPropertiesFromRow: (struct SRow *) aRow
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = [super addPropertiesFromRow: aRow];
|
||||
if (rc == MAPISTORE_SUCCESS)
|
||||
{
|
||||
[sogoObject appendProperties: properties];
|
||||
[properties removeAllObjects];
|
||||
ASSIGN (lastModificationTime, [NSDate date]);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (void) addProperties: (NSDictionary *) newProperties
|
||||
{
|
||||
[super addProperties: newProperties];
|
||||
[sogoObject appendProperties: newProperties];
|
||||
[sogoObject appendProperties: properties];
|
||||
[properties removeAllObjects];
|
||||
ASSIGN (lastModificationTime, [NSDate date]);
|
||||
}
|
||||
|
@ -129,7 +114,7 @@ Class NSNumberK;
|
|||
|
||||
value = [[sogoObject properties] objectForKey: MAPIPropertyKey (propTag)];
|
||||
if (value)
|
||||
rc = [value getMAPIValue: data forTag: propTag inMemCtx: memCtx];
|
||||
rc = [value getValue: data forTag: propTag inMemCtx: memCtx];
|
||||
else
|
||||
rc = [super getProperty: data withTag: propTag inMemCtx: memCtx];
|
||||
|
||||
|
|
|
@ -27,8 +27,24 @@
|
|||
|
||||
@interface NSArray (MAPIStoreFolders)
|
||||
|
||||
- (struct WStringArray_r *) asArrayOfUnicodeStringsInCtx: (void *) memCtx;
|
||||
// - (struct mapi_SPLSTRArrayW *) asArrayOfUnicodeStringsInCtx: (void *) memCtx;
|
||||
/* mapi structs */
|
||||
+ (id) arrayFromMAPIMVLong: (const struct mapi_MV_LONG_STRUCT *) mvLong;
|
||||
+ (id) arrayFromMAPIMVUnicode: (const struct mapi_SPLSTRArrayW *) mvUnicode;
|
||||
+ (id) arrayFromMAPIMVString: (const struct mapi_SLPSTRArray *) mvString;
|
||||
+ (id) arrayFromMAPIMVBinary: (const struct mapi_SBinaryArray *) mvBinary;
|
||||
+ (id) arrayFromMAPIMVGuid: (const struct mapi_SGuidArray *) mvGuid;
|
||||
|
||||
+ (id) arrayFromMVShort: (const struct ShortArray_r *) mvShort;
|
||||
+ (id) arrayFromMVLong: (const struct LongArray_r *) mvLong;
|
||||
- (struct LongArray_r *) asMVLongInMemCtx: (void *) memCtx;
|
||||
+ (id) arrayFromMVI8: (const struct I8Array_r *) mvI8;
|
||||
+ (id) arrayFromMVString: (const struct StringArray_r *) mvString;
|
||||
+ (id) arrayFromMVUnicode: (const struct WStringArray_r *) mvUnicode;
|
||||
- (struct WStringArray_r *) asMVUnicodeInMemCtx: (void *) memCtx;
|
||||
+ (id) arrayFromMVBinary: (const struct BinaryArray_r *) mvBinary;
|
||||
- (struct BinaryArray_r *) asMVBinaryInMemCtx: (void *) memCtx;
|
||||
+ (id) arrayFromMVGuid: (const struct FlatUIDArray_r *) mvGuid;
|
||||
+ (id) arrayFromMVFileTime: (const struct DateTimeArray_r *) mvGuid;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -22,26 +22,195 @@
|
|||
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import "NSDate+MAPIStore.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
||||
#import "NSArray+MAPIStore.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <talloc.h>
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
@implementation NSArray (MAPIStoreFolders)
|
||||
|
||||
- (struct WStringArray_r *) asArrayOfUnicodeStringsInCtx: (void *) memCtx
|
||||
+ (id) arrayFromMAPIMVLong: (struct mapi_MV_LONG_STRUCT *) mvLong
|
||||
{
|
||||
NSUInteger count;
|
||||
NSNumber *subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvLong->cValues];
|
||||
for (count = 0; count < mvLong->cValues; count++)
|
||||
{
|
||||
subObject = [NSNumber numberWithLong: mvLong->lpl[count]];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMAPIMVUnicode: (struct mapi_SPLSTRArrayW *) mvUnicode
|
||||
{
|
||||
NSUInteger count;
|
||||
NSString *subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvUnicode->cValues];
|
||||
for (count = 0; count < mvUnicode->cValues; count++)
|
||||
{
|
||||
subObject
|
||||
= [NSString stringWithUTF8String: mvUnicode->strings[count].lppszW];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMAPIMVString: (struct mapi_SLPSTRArray *) mvString
|
||||
{
|
||||
NSUInteger count;
|
||||
id subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvString->cValues];
|
||||
for (count = 0; count < mvString->cValues; count++)
|
||||
{
|
||||
subObject = [NSString stringWithUTF8String: mvString->strings[count].lppszA];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMAPIMVBinary: (struct mapi_SBinaryArray *) mvBinary
|
||||
{
|
||||
NSUInteger count;
|
||||
id subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvBinary->cValues];
|
||||
for (count = 0; count < mvBinary->cValues; count++)
|
||||
{
|
||||
subObject = [NSData dataWithShortBinary: mvBinary->bin + count];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMAPIMVGuid: (struct mapi_SGuidArray *) mvGuid
|
||||
{
|
||||
NSUInteger count;
|
||||
id subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvGuid->cValues];
|
||||
for (count = 0; count < mvGuid->cValues; count++)
|
||||
{
|
||||
subObject = [NSData dataWithGUID: mvGuid->lpguid + count];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMVShort: (const struct ShortArray_r *) mvShort
|
||||
{
|
||||
NSUInteger count;
|
||||
NSNumber *subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvShort->cValues];
|
||||
for (count = 0; count < mvShort->cValues; count++)
|
||||
{
|
||||
subObject = [NSNumber numberWithShort: mvShort->lpi[count]];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMVLong: (const struct LongArray_r *) mvLong
|
||||
{
|
||||
NSUInteger count;
|
||||
NSNumber *subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvLong->cValues];
|
||||
for (count = 0; count < mvLong->cValues; count++)
|
||||
{
|
||||
subObject = [NSNumber numberWithLong: mvLong->lpl[count]];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
- (struct LongArray_r *) asMVLongInMemCtx: (void *) memCtx
|
||||
{
|
||||
struct LongArray_r *list;
|
||||
NSNumber *number;
|
||||
NSInteger count, max;
|
||||
|
||||
max = [self count];
|
||||
|
||||
list = talloc_zero (memCtx, struct LongArray_r);
|
||||
list->cValues = max;
|
||||
list->lpl = talloc_array (list, uint32_t, max);
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
number = [self objectAtIndex: count];
|
||||
list->lpl[count] = [number longValue];
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMVI8: (const struct I8Array_r *) mvI8
|
||||
{
|
||||
NSUInteger count;
|
||||
NSNumber *subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvI8->cValues];
|
||||
for (count = 0; count < mvI8->cValues; count++)
|
||||
{
|
||||
subObject = [NSNumber numberWithLongLong: mvI8->lpi8[count]];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMVUnicode: (const struct WStringArray_r *) mvUnicode
|
||||
{
|
||||
NSUInteger count;
|
||||
NSString *subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvUnicode->cValues];
|
||||
for (count = 0; count < mvUnicode->cValues; count++)
|
||||
{
|
||||
subObject = [NSString stringWithUTF8String: mvUnicode->lppszW[count]];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
- (struct WStringArray_r *) asMVUnicodeInMemCtx: (void *) memCtx
|
||||
{
|
||||
struct WStringArray_r *list;
|
||||
NSInteger count, max;
|
||||
|
||||
max = [self count];
|
||||
|
||||
list = talloc_zero(memCtx, struct WStringArray_r);
|
||||
list = talloc_zero (memCtx, struct WStringArray_r);
|
||||
list->cValues = max;
|
||||
list->lppszW = talloc_array(list, const char *, max);
|
||||
list->lppszW = talloc_array (list, const char *, max);
|
||||
|
||||
for (count = 0; count < max; count++)
|
||||
list->lppszW[count] = [[self objectAtIndex: count] asUnicodeInMemCtx: list->lppszW];
|
||||
|
@ -49,4 +218,90 @@
|
|||
return list;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMVString: (const struct StringArray_r *) mvString
|
||||
{
|
||||
NSUInteger count;
|
||||
id subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvString->cValues];
|
||||
for (count = 0; count < mvString->cValues; count++)
|
||||
{
|
||||
subObject = [NSString stringWithUTF8String: mvString->lppszA[count]];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMVBinary: (const struct BinaryArray_r *) mvBinary
|
||||
{
|
||||
NSUInteger count;
|
||||
id subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvBinary->cValues];
|
||||
for (count = 0; count < mvBinary->cValues; count++)
|
||||
{
|
||||
subObject = [NSData dataWithBinary: mvBinary->lpbin + count];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
- (struct BinaryArray_r *) asMVBinaryInMemCtx: (void *) memCtx
|
||||
{
|
||||
struct BinaryArray_r *list;
|
||||
NSData *data;
|
||||
NSInteger count, max;
|
||||
|
||||
max = [self count];
|
||||
|
||||
list = talloc_zero (memCtx,struct BinaryArray_r);
|
||||
list->cValues = max;
|
||||
list->lpbin = talloc_array (list, struct Binary_r, max);
|
||||
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
data = [self objectAtIndex: count];
|
||||
list->lpbin[count].cb = [data length];
|
||||
list->lpbin[count].lpb = talloc_memdup (list->lpbin, [data bytes], list->lpbin[count].cb);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMVGuid: (const struct FlatUIDArray_r *) mvGuid
|
||||
{
|
||||
NSUInteger count;
|
||||
id subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvGuid->cValues];
|
||||
for (count = 0; count < mvGuid->cValues; count++)
|
||||
{
|
||||
subObject = [NSData dataWithFlatUID: mvGuid->lpguid[count]];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
+ (id) arrayFromMVFileTime: (const struct DateTimeArray_r *) mvFileTime
|
||||
{
|
||||
NSUInteger count;
|
||||
id subObject;
|
||||
NSMutableArray *mvResult;
|
||||
|
||||
mvResult = [NSMutableArray arrayWithCapacity: mvFileTime->cValues];
|
||||
for (count = 0; count < mvFileTime->cValues; count++)
|
||||
{
|
||||
subObject = [NSDate dateFromFileTime: mvFileTime->lpft + count];
|
||||
[mvResult addObject: subObject];
|
||||
}
|
||||
|
||||
return mvResult;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
#undef DEBUG
|
||||
#include <stdbool.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
#include <talloc.h>
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
||||
@implementation NSData (MAPIStoreDataTypes)
|
||||
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
#import "NSDate+MAPIStore.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <talloc.h>
|
||||
#include <util/time.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
static NSCalendarDate *refDate = nil;
|
||||
|
||||
|
|
|
@ -40,9 +40,9 @@ struct MAPIStoreTallocWrapper
|
|||
|
||||
@interface NSObject (MAPIStoreDataTypes)
|
||||
|
||||
- (int) getMAPIValue: (void **) data
|
||||
forTag: (enum MAPITAGS) propTag
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getValue: (void **) data
|
||||
forTag: (enum MAPITAGS) propTag
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
|
||||
/* getter helpers */
|
||||
- (int) getEmptyString: (void **) data inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSArray+MAPIStore.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSDate+MAPIStore.h"
|
||||
#import "NSValue+MAPIStore.h"
|
||||
|
@ -68,9 +69,9 @@ static int MAPIStoreTallocWrapperDestroy (void *data)
|
|||
|
||||
@implementation NSObject (MAPIStoreDataTypes)
|
||||
|
||||
- (int) getMAPIValue: (void **) data
|
||||
forTag: (enum MAPITAGS) propTag
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
- (int) getValue: (void **) data
|
||||
forTag: (enum MAPITAGS) propTag
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
uint16_t valueType;
|
||||
int rc = MAPISTORE_SUCCESS;
|
||||
|
@ -110,10 +111,20 @@ static int MAPIStoreTallocWrapperDestroy (void *data)
|
|||
case PT_CLSID:
|
||||
*data = [(NSData *) self asGUIDInMemCtx: memCtx];
|
||||
break;
|
||||
case PT_MV_LONG:
|
||||
*data = [(NSArray *) self asMVLongInMemCtx: memCtx];
|
||||
break;
|
||||
case PT_MV_UNICODE:
|
||||
*data = [(NSArray *) self asMVUnicodeInMemCtx: memCtx];
|
||||
break;
|
||||
case PT_MV_BINARY:
|
||||
*data = [(NSArray *) self asMVBinaryInMemCtx: memCtx];
|
||||
break;
|
||||
|
||||
default:
|
||||
[self errorWithFormat: @"object type not handled: %d (0x%.4x)",
|
||||
valueType, valueType];
|
||||
abort();
|
||||
*data = NULL;
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#import "NSString+MAPIStore.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <talloc.h>
|
||||
#include <util/time.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
@implementation NSString (MAPIStoreDataTypes)
|
||||
|
|
|
@ -21,13 +21,17 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSFileManager.h>
|
||||
#import <Foundation/NSPropertyList.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
|
||||
#import "EOQualifier+MAPI.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
|
@ -35,6 +39,8 @@
|
|||
#import "SOGoMAPIFSFolder.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <talloc.h>
|
||||
#include <util/time.h>
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
#include <libmapiproxy.h>
|
||||
|
@ -198,11 +204,14 @@ static NSString *privateDir = nil;
|
|||
for (count = 0; count < max; count++)
|
||||
{
|
||||
file = [contents objectAtIndex: count];
|
||||
fullName = [directory stringByAppendingPathComponent: file];
|
||||
if ([fm fileExistsAtPath: fullName
|
||||
isDirectory: &isDir]
|
||||
&& dirs == isDir)
|
||||
[files addObject: file];
|
||||
if (![file isEqualToString: @"permissions.plist"])
|
||||
{
|
||||
fullName = [directory stringByAppendingPathComponent: file];
|
||||
if ([fm fileExistsAtPath: fullName
|
||||
isDirectory: &isDir]
|
||||
&& dirs == isDir)
|
||||
[files addObject: file];
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
|
@ -303,4 +312,108 @@ static NSString *privateDir = nil;
|
|||
return [self _fileAttributeForKey: NSFileModificationDate];
|
||||
}
|
||||
|
||||
/* acl */
|
||||
- (NSString *) defaultUserID
|
||||
{
|
||||
return @"default";
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *) _aclEntries
|
||||
{
|
||||
NSMutableDictionary *aclEntries;
|
||||
NSData *content;
|
||||
NSString *error, *filename;
|
||||
NSPropertyListFormat format;
|
||||
|
||||
filename = [directory stringByAppendingPathComponent: @"permissions.plist"];
|
||||
content = [NSData dataWithContentsOfFile: filename];
|
||||
if (content)
|
||||
aclEntries = [NSPropertyListSerialization propertyListFromData: content
|
||||
mutabilityOption: NSPropertyListMutableContainers
|
||||
format: &format
|
||||
errorDescription: &error];
|
||||
else
|
||||
aclEntries = nil;
|
||||
if (!aclEntries)
|
||||
{
|
||||
aclEntries = [NSMutableDictionary dictionary];
|
||||
[aclEntries setObject: [NSMutableArray array] forKey: @"users"];
|
||||
[aclEntries setObject: [NSMutableDictionary dictionary]
|
||||
forKey: @"entries"];
|
||||
}
|
||||
|
||||
return aclEntries;
|
||||
}
|
||||
|
||||
- (void) _saveAcl: (NSDictionary *) acl
|
||||
{
|
||||
NSString *filename;
|
||||
NSData *content;
|
||||
|
||||
filename = [directory stringByAppendingPathComponent: @"permissions.plist"];
|
||||
[self ensureDirectory];
|
||||
|
||||
if (acl)
|
||||
content = [NSPropertyListSerialization
|
||||
dataFromPropertyList: acl
|
||||
format: NSPropertyListBinaryFormat_v1_0
|
||||
errorDescription: NULL];
|
||||
else
|
||||
content = [NSData data];
|
||||
if (![content writeToFile: filename atomically: NO])
|
||||
[NSException raise: @"MAPIStoreIOException"
|
||||
format: @"could not save acl"];
|
||||
}
|
||||
|
||||
- (void) addUserInAcls: (NSString *) user
|
||||
{
|
||||
NSMutableDictionary *acl;
|
||||
NSMutableArray *users;
|
||||
|
||||
acl = [self _aclEntries];
|
||||
users = [acl objectForKey: @"users"];
|
||||
[users addObjectUniquely: user];
|
||||
[self _saveAcl: acl];
|
||||
}
|
||||
|
||||
- (void) removeAclsForUsers: (NSArray *) oldUsers
|
||||
{
|
||||
NSDictionary *acl;
|
||||
NSMutableDictionary *entries;
|
||||
NSMutableArray *users;
|
||||
|
||||
acl = [self _aclEntries];
|
||||
entries = [acl objectForKey: @"entries"];
|
||||
[entries removeObjectsForKeys: oldUsers];
|
||||
users = [acl objectForKey: @"users"];
|
||||
[users removeObjectsInArray: oldUsers];
|
||||
[self _saveAcl: acl];
|
||||
}
|
||||
|
||||
- (NSArray *) aclUsers
|
||||
{
|
||||
return [[self _aclEntries] objectForKey: @"users"];
|
||||
}
|
||||
|
||||
- (NSArray *) aclsForUser: (NSString *) uid
|
||||
{
|
||||
NSDictionary *entries;
|
||||
|
||||
entries = [[self _aclEntries] objectForKey: @"entries"];
|
||||
|
||||
return [entries objectForKey: uid];
|
||||
}
|
||||
|
||||
- (void) setRoles: (NSArray *) roles
|
||||
forUser: (NSString *) uid
|
||||
{
|
||||
NSMutableDictionary *acl;
|
||||
NSMutableDictionary *entries;
|
||||
|
||||
acl = [self _aclEntries];
|
||||
entries = [acl objectForKey: @"entries"];
|
||||
[entries setObject: roles forKey: uid];
|
||||
[self _saveAcl: acl];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -81,6 +81,8 @@ h_template = """/* %(filename)s (auto-generated) - this file is part of SOGo
|
|||
#import <Foundation/NSObjCRuntime.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <talloc.h>
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
||||
extern const NSUInteger MAPIStorePropertyGettersCount;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -0,0 +1,75 @@
|
|||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <ctype.h> header file. */
|
||||
#define HAVE_CTYPE_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#define HAVE_STDIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "unrtf"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "bug-unrtf@gnu.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "unrtf"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "unrtf 0.21.2"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "unrtf"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "0.21.2"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "0.21.2"
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* #undef malloc */
|
|
@ -54,6 +54,7 @@
|
|||
+ (SOGoCache *) sharedCache;
|
||||
|
||||
- (void) disableRequestsCache;
|
||||
- (void) disableLocalCache;
|
||||
|
||||
- (void) killCache;
|
||||
|
||||
|
|
|
@ -154,6 +154,12 @@ static memcached_st *handle = NULL;
|
|||
requestsCacheEnabled = NO;
|
||||
}
|
||||
|
||||
- (void) disableLocalCache
|
||||
{
|
||||
[localCache release];
|
||||
localCache = nil;
|
||||
}
|
||||
|
||||
- (void) killCache
|
||||
{
|
||||
[cache removeAllObjects];
|
||||
|
|
|
@ -282,4 +282,4 @@
|
|||
"Password change is not supported." = "Changement de mot de passe non-supporté.";
|
||||
"Unhandled HTTP error code: %{0}" = "Code HTTP non-géré: %{0}";
|
||||
"New password:" = "Nova senha:";
|
||||
"Confirmation:" = "Confirmação:";
|
||||
"Confirmation:" = "Confirmação:";
|
||||
|
|
|
@ -282,4 +282,4 @@
|
|||
"Password change is not supported." = "Changement de mot de passe non-supporté.";
|
||||
"Unhandled HTTP error code: %{0}" = "Code HTTP non-géré: %{0}";
|
||||
"New password:" = "Új jelszó:";
|
||||
"Confirmation:" = "Megerősítés:";
|
||||
"Confirmation:" = "Megerősítés:";
|
||||
|
|
|
@ -282,4 +282,4 @@
|
|||
"Password change is not supported." = "Changement de mot de passe non-supporté.";
|
||||
"Unhandled HTTP error code: %{0}" = "Code HTTP non-géré: %{0}";
|
||||
"New password:" = "Nytt passord:";
|
||||
"Confirmation:" = "Bekreft:";
|
||||
"Confirmation:" = "Bekreft:";
|
||||
|
|
|
@ -284,4 +284,4 @@ Servernamn:";
|
|||
"Password change is not supported." = "Changement de mot de passe non-supporté.";
|
||||
"Unhandled HTTP error code: %{0}" = "Code HTTP non-géré: %{0}";
|
||||
"New password:" = "Nytt lösenord:";
|
||||
"Confirmation:" = "Bekräfta:";
|
||||
"Confirmation:" = "Bekräfta:";
|
||||
|
|
|
@ -282,4 +282,4 @@
|
|||
"Password change is not supported." = "Changement de mot de passe non-supporté.";
|
||||
"Unhandled HTTP error code: %{0}" = "Code HTTP non-géré: %{0}";
|
||||
"New password:" = "New password:";
|
||||
"Confirmation:" = "Confirmation:";
|
||||
"Confirmation:" = "Confirmation:";
|
||||
|
|
Loading…
Reference in New Issue