propagate from branch 'ca.inverse.sogo.1_3_18' (head 749811709acadced020a19e4ce7c00f07ac86e77)
to branch 'ca.inverse.sogo' (head b142d5d1ddfd110920b6b9d0c4efbba96c4ccedd) Monotone-Parent: 749811709acadced020a19e4ce7c00f07ac86e77 Monotone-Parent: b142d5d1ddfd110920b6b9d0c4efbba96c4ccedd Monotone-Revision: cebb37d367ee5534f83da28bfdd4300b276e285d Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-08-29T12:56:04 Monotone-Branch: ca.inverse.sogomaint-2.0.2
commit
c13f9364ff
452
ChangeLog
452
ChangeLog
|
@ -1,3 +1,8 @@
|
|||
2012-08-28 Jean Raby <jraby@inverse.ca>
|
||||
|
||||
* Scripts/openchange_cleanup.py:
|
||||
New script to clean an openchange user profile
|
||||
|
||||
2012-08-27 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/SOGoAptMailInvitation.m,
|
||||
|
@ -31,6 +36,229 @@
|
|||
* UI/MailPartViewers/UIxMailPartHTMLViewer.m (-_sanitizeContent):
|
||||
fix invalid void tags to insure proper HTML decoding. Fixes #1581.
|
||||
|
||||
2012-08-23 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* SoObjects/Mailer/SOGoMailFolder.m - added safety
|
||||
checks around the ACL code so we don't crash if
|
||||
we can't read the ACLs.
|
||||
|
||||
2012-08-21 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreFolder.m (-getPidTagAccessLevel)
|
||||
(-getPidTagRights, -getPidTagAccessControlListData): fixed
|
||||
methods.
|
||||
|
||||
* OpenChange/MAPIStoreMessage.m
|
||||
(-getPidTagDeleteAfterSubmit:inMemCtx:): moved from
|
||||
MAPIStoreMailMessage.
|
||||
|
||||
* OpenChange/MAPIStoreContactsMessage.m
|
||||
(-getPidTagAlternateRecipientAllowed:inMemCtx:)
|
||||
(-getPidTagMessageFlags:inMemCtx:)
|
||||
(-getPidTagDeleteAfterSubmit:inMemCtx:): new getters.
|
||||
|
||||
* OpenChange/MAPIStoreGCSFolder.m
|
||||
(-setChangeKey:forMessageWithKey:): removed useless method.
|
||||
(-updateVersionsForMessageWithKey:withChangeKey:): set the change
|
||||
key provided by the client as member of the predecessor
|
||||
changelist, but never as the actual change key for the object.
|
||||
This hopefully fixes the issue where Outlook deletes objects that
|
||||
have a different change list than what they expect.
|
||||
|
||||
2012-08-17 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreCalendarMessage.m
|
||||
(-getPidTagMessageClass:inMemCtx:): return
|
||||
"IPM.Schedule.Meeting.Request" when the owner user is an attendee.
|
||||
|
||||
* OpenChange/MAPIStoreAppointmentWrapper.m
|
||||
(-getPidLidAppointmentNotAllowPropose:inMemCtx): new getter that
|
||||
always return "YES", in order to disallow counter proposals.
|
||||
|
||||
* OpenChange/MAPIStoreContext.m (-getPath:ofFMID:inMemCtx:):
|
||||
properly escape urls containing non-ascii chars.
|
||||
(-getRootFoldeR:withFID:): idem.
|
||||
|
||||
2012-08-16 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreCalendarMessage.m
|
||||
(-getMessageData:inMemCtx:): when a "recipients" records is
|
||||
available in the properties, we must return that list instead of
|
||||
the list of attendees since it will be the most recent one.
|
||||
(_fixupAppointmentObjectWithUID::): when an appointment had been
|
||||
deleted, we first attempt to resurrect it from the database before
|
||||
reinstantiating it, which allows the event synchronisation to
|
||||
happen properly in [SOGoAppointmentObject
|
||||
updateContentWithCalendar:fromRequest:].
|
||||
|
||||
* OpenChange/MAPIStoreMapping.m (_updateFolderWithURL:withURL:):
|
||||
we retain and release "oldURL" to avoid releasing it when it
|
||||
is replaced in the list of urls to modify.
|
||||
|
||||
* OpenChange/MAPIStoreAppointmentWrapper.m
|
||||
(-getPidTagInternetCodepage:inMemCtx:): new getter for a property
|
||||
that is sometimes requested.
|
||||
(-getPidTagBody:inMemCtx:): we return an empty string when no
|
||||
"description"/"comment" is actually present.
|
||||
|
||||
2012-08-15 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreMailFolder.m (-addProperties:): make use of
|
||||
the new methods below when a mail folder has been renamed, as this
|
||||
operation affects the url of mail objects.
|
||||
|
||||
* OpenChange/SOGoMAPIDBObject.m (-setNameInContainer): update the
|
||||
object record in the database to reflect the change of folder
|
||||
name.
|
||||
|
||||
* OpenChange/MAPIStoreMailContext.m (-updateURLWithFolderName):
|
||||
change the folder name used in the context url to use the new
|
||||
folder name after a rename operation, so that further invocations
|
||||
of -url will return the right url.
|
||||
|
||||
* OpenChange/MAPIStoreMailFolder.m
|
||||
(-moveCopyToFolder:withNewName:isMove:isRecursive:): implemented
|
||||
IMAP-based copy operation, for speed.
|
||||
(-addProperties): restored the ability to rename IMAP folders by
|
||||
properly updating the fid/url mapping with our new methods.
|
||||
|
||||
2012-08-14 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreFolder.m (-moveToFolder:withNewName:):
|
||||
renamed to "moveCopyToFolder:withNewName:isMove:isRecursive:",
|
||||
with the ability to specify whether the operation is a move or
|
||||
copy operation and whether it is recursive or not (for copy).
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m (sogo_folder_move_folder): if
|
||||
"target_folder_object", we do not attempt to access the
|
||||
corresponding instance member.
|
||||
|
||||
* OpenChange/MAPIStoreMailFolder.m (-
|
||||
moveCopyMessagesWithMIDs:andCount:fromFolder:withMIDs:andChangeKeys:wantCopy:):
|
||||
do not attempt to access targetChangeKeys when NULL, to avoid a
|
||||
SEGFAULT.
|
||||
|
||||
2012-08-14 Jean Raby <jraby@inverse.ca>
|
||||
|
||||
* OpenChange/GNUmakefile: use version_info[{0,1}] instead of
|
||||
version_info.{major,minor} when checking for legacy version
|
||||
of python since these named attributes where added in python2.7
|
||||
|
||||
2012-08-13 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m (sogo_properties_get_uri): removed
|
||||
useless backend method.
|
||||
|
||||
* OpenChange/MAPIStoreFolder.m (-createFolder:withRow:andFID:):
|
||||
append a "/" to the new folder url when registering with the
|
||||
url/id mapper.
|
||||
|
||||
* OpenChange/MAPIStoreDBFolder.m (-moveToFolder:withNewName:):
|
||||
implemented method.
|
||||
|
||||
* OpenChange/MAPIStoreMailFolder.m (-moveToFolder:withNewName:):
|
||||
invoke changePathTo: on the dbFolder.
|
||||
|
||||
* OpenChange/SOGoMAPIDBFolder.m (-changePathTo:): overriden method
|
||||
in order to update children records too.
|
||||
|
||||
* OpenChange/SOGoMAPIDBObject.m (-performBatchSQLQueries:) new
|
||||
method to perform void queries under a transaction.
|
||||
(-changePathTo:) new method that updates the references for the
|
||||
object record in the dbfs table.
|
||||
|
||||
* SoObjects/SOGo/NSString+Utilities.m
|
||||
(-stringByReplacingPrefix:withPrefix:): new self-explicit method.
|
||||
|
||||
* OpenChange/SOGoMAPIDBFolder.m
|
||||
(-childKeysOfType:includeDeleted:matchingQualifier:andSortOrderings:):
|
||||
records now have a c_parent_path column in order to avoid fetch
|
||||
the children of children due to the nature of our "LIKE" clause.
|
||||
|
||||
* OpenChange/SOGoMAPIDBObject.m (-save): records now have a
|
||||
c_parent_path.
|
||||
|
||||
* OpenChange/MAPIStoreMailFolder.m (-supportsSubFolders):
|
||||
overriden method to return YES.
|
||||
|
||||
2012-08-12 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreMailFolder.m (-moveToFolder:withName:): if
|
||||
the new name is not provided (unlikely), the computed new name
|
||||
must not have the "folder" prefix.
|
||||
We now also make use of -[MAPIStoreMapping updateID:withURL:] to
|
||||
change the references in the mapping database.
|
||||
|
||||
* OpenChange/MAPIStoreFolder.m (-objectId): folder keys always end
|
||||
with a "/" by convention.
|
||||
|
||||
* OpenChange/MAPIStoreMapping.m (-updateID:withURL:): new method
|
||||
that perform a change of url on container and leaf entries.
|
||||
|
||||
2012-08-10 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m (sogo_properties_get_uri): new
|
||||
backend method.
|
||||
|
||||
2012-08-10 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* Changed OpenChange/SOGoMAPIDBObject.m so we use
|
||||
GNUstep's binary encoding - which is an order or
|
||||
magnitude faster at encoding data than any other formats.
|
||||
|
||||
2012-08-10 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m (sogo_folder_move_folder)
|
||||
(sogo_folder_copy_folder): the object on which the backend method
|
||||
is invoked is now the folder being moved rather than its parent.
|
||||
|
||||
2012-08-09 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreMailFolder.m
|
||||
(-moveFolderWithFID:fromFolder:withNewName:): first implementation
|
||||
for IMAP folders.
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m (sogo_folder_move_folder)
|
||||
(sogo_folder_copy_folder): new backend methods.
|
||||
(sogo_folder_move_folder): do not instantiate an NSString from a
|
||||
NULL "new_folder_name" parameter.
|
||||
|
||||
2012-08-08 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreCalendarMessage.m (-save): generate a
|
||||
"nameInContainer" for the new object iif it is not set yet. If
|
||||
set, we generate a new UID from it instead.
|
||||
|
||||
* OpenChange/MAPIStoreMessage.m (-saveMessage): make sure that the
|
||||
PidTagChangeKey and PidTagChangeNumber props are no longer set in
|
||||
the properties dict after the save occurred.
|
||||
|
||||
* OpenChange/MAPIApplication.m (-shouldSetupSignalHandlers):
|
||||
overriden method by returning "NO".
|
||||
|
||||
2012-08-07 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/SOGoAptMailNotification.m (-setupValues):
|
||||
test whether each value is non-nil before adding it to the
|
||||
dictionary.
|
||||
|
||||
* OpenChange/MAPIStoreMailVolatileMessage.m (-save): restored
|
||||
registration of message url when saved.
|
||||
|
||||
2012-08-06 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreRecurrenceUtils.m (-[iCalRecurrenceRule
|
||||
fillRecurrencePattern:withEvent:inTimeZone:inMemCtx:]): fixed a
|
||||
crash occurring when the exception has no recurrence-id and
|
||||
ignore the specific occurrence.
|
||||
|
||||
* OpenChange/MAPIStoreMailVolatileMessage.m (MakeMessageBody):
|
||||
take "attachmentParts" parameter, deduced from the ivar with the
|
||||
corresponding name.
|
||||
|
||||
* OpenChange/MAPIStoreSOGoObject.m (-objectId): force generation
|
||||
of objectId by parent, whether it is a folder or not.
|
||||
|
||||
2012-08-07 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* UI/Contacts/UIxListEditor.m (-setReferencesValue:): check for
|
||||
|
@ -38,10 +266,16 @@
|
|||
|
||||
2012-08-03 Jean Raby <jraby@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/LDAPSource.m (-changePasswordForLogin):
|
||||
if userPasswordAlgorithm was not set or was set to "none",
|
||||
use the plaintext password directly instead of using '{none}plaintext'
|
||||
which isn't valid.
|
||||
* SoObjects/SOGo/LDAPSource.m (changePasswordForLogin):
|
||||
if userPasswordAlgorithm was not set or was set to "none",
|
||||
use the plaintext password directly instead of using '{none}plaintext'
|
||||
which isn't valid.
|
||||
|
||||
2012-08-02 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreUserContext.m (-_readUserPassword:)
|
||||
We now read per-user passwords instead of relying on
|
||||
a global file.
|
||||
|
||||
2012-07-31 Jean Raby <jraby@inverse.ca>
|
||||
|
||||
|
@ -54,6 +288,22 @@
|
|||
(-sieveScriptWithRequirements:): filters must not be conditional
|
||||
to each other.
|
||||
|
||||
2012-07-26 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/iCalTimeZone+MAPIStore.[hm]: new category module.
|
||||
(-asTimeZoneStructInMemCtx:): new method that returns a struct
|
||||
TimeZoneStruct as a binary blob from an iCalTimeZone object.
|
||||
|
||||
* OpenChange/MAPIStoreAppointmentWrapper.m
|
||||
(-getPidLidTimeZoneStruct:inMemCtx:): new property getter that
|
||||
returns the equivalent of the iCalTimeZone of the current event.
|
||||
|
||||
2012-07-25 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreDBFolder.m (-createFolder:withFID:andKey:):
|
||||
invoke "reloadIfNeeded" on the created folder object in order to
|
||||
initialize it.
|
||||
|
||||
2012-07-25 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* SoObjects/Mailer/SOGoMailFolder.m
|
||||
|
@ -71,6 +321,15 @@
|
|||
* UI/WebServerResources/MailerUI.js (initMailer): define default
|
||||
columns widths when not set.
|
||||
|
||||
2012-07-24 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreUserContext.m
|
||||
(-initWithUsername:andTDBIndexing:): attempt to read the user
|
||||
password from a property list.
|
||||
|
||||
* OpenChange/samba-get-config.py: new utility taking a samba
|
||||
configuration variable and prints the value on stdout
|
||||
|
||||
2012-07-24 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* UI/WebServerResources/UIxPreferences.js (savePreferences):
|
||||
|
@ -89,8 +348,113 @@
|
|||
(_shouldDisplayAsAttachment:): refactored to consider
|
||||
the "bodyId" parameter only for non text/* parts.
|
||||
|
||||
2012-07-20 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* UI/WebServerResources/MailerUI.js (onEmailTo): append the email
|
||||
address from the href attribute if it doesn't appear in the link content.
|
||||
|
||||
* UI/MailPartViewers/UIxMailPartHTMLViewer.m
|
||||
(-startElement:namespace:rawName:attributes:): don't skip "mailto:"
|
||||
href.
|
||||
|
||||
* SoObjects/Appointments/SOGoAptMailReceipt.m (aptSummary-): new
|
||||
method that returns a properly formatted string of the event title
|
||||
with respect to the current operation (creation/deletion/update).
|
||||
|
||||
2012-07-20 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/NSObject+MAPIStore.m (-getSMTPAddrType:inMemCtx:):
|
||||
new helper getter.
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m
|
||||
(sogo_message_attachment_create_embedded_message): new backend method.
|
||||
|
||||
* OpenChange/NSObject+MAPIStore.m
|
||||
(+fillAvailableProperties:withExclusions:): new method that fills
|
||||
an existing array of properties with properties existing in
|
||||
another class, as long as they are not listed in the array of
|
||||
exclusions.
|
||||
|
||||
* OpenChange/MAPIStoreObject.m (-init): assigned a mutable array
|
||||
to "proxies"
|
||||
(-canGetProperty:): test the proxies for the availability of
|
||||
properties so that -getAvailableProperties:inMemCtx: can return an
|
||||
accurate result.
|
||||
|
||||
* OpenChange/MAPIStoreMessage.m (-getPidTagSubject:inMemCtx:): now
|
||||
compute the return value based on PidTagNormalizedSubject and
|
||||
PidTagSubjectPrefix as PidTagSubject is never actually set from
|
||||
the client.
|
||||
|
||||
2012-07-19 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreObject.m (-nameInContainer): moved method
|
||||
from MAPIStoreSOGoObject and made mandatory for subclasses.
|
||||
(-url): new methed moved from MAPIStoreSOGoObject.
|
||||
|
||||
* OpenChange/MAPIStoreAppointmentWrapper.m: now a subclass of
|
||||
MAPIStoreObjectProxy.
|
||||
|
||||
* OpenChange/MAPIStoreCalendarMessage.m
|
||||
(-initWithSOGoObject:inContainer:): we now register our
|
||||
appointment wrapper as a proxy.
|
||||
|
||||
* OpenChange/MAPIStoreObject.m (-addProxy:): new method that keeps
|
||||
proxy objects in the new "proxies" ivar.
|
||||
(-getProperty:withTag:inMemCtx:): added code that pass the request
|
||||
to the available object proxies, when the property getters have
|
||||
not been found in the local class.
|
||||
|
||||
* OpenChange/MAPIStoreObjectProxy.[hm]: new class module that
|
||||
provide a facility for providing property getters in the name of
|
||||
another class, working around the fact that Objective-C does not
|
||||
provide multiple-inheritance.
|
||||
|
||||
* OpenChange/NSObject+MAPIStore.m
|
||||
(+getAvailableProperties:inMemCtx:)
|
||||
(-getAvailableProperties:inMemCtx:, canGetProperty:): methods
|
||||
moved from MAPIStoreObject.m
|
||||
|
||||
2012-07-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreCalendarFolder.m (-createMessage): attach a
|
||||
WOContext to the newEntry in order to enable page templates
|
||||
resolution when notifications are sent.
|
||||
|
||||
* OpenChange/MAPIApplication.m (-init): a WEResourceManager is
|
||||
setup for the application so that page templates can be properly
|
||||
be initialized.
|
||||
|
||||
* OpenChange/MAPIStoreDBMessage.m (-objectVersion): shift the
|
||||
version number by 16 bits, instead of doing it in -save.
|
||||
(-save): don t swap the bytes of the version number as it would
|
||||
return a wrong change number and a wrong change key for DB objects.
|
||||
|
||||
2012-07-20 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/NSObject+MAPIStore.m (-getSMTPAddrType:inMemCtx:):
|
||||
new helper getter.
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m
|
||||
(sogo_message_attachment_create_embedded_message): new backend method.
|
||||
|
||||
* OpenChange/NSObject+MAPIStore.m
|
||||
(+fillAvailableProperties:withExclusions:): new method that fills
|
||||
an existing array of properties with properties existing in
|
||||
another class, as long as they are not listed in the array of
|
||||
exclusions.
|
||||
|
||||
* OpenChange/MAPIStoreObject.m (-init): assigned a mutable array
|
||||
to "proxies"
|
||||
(-canGetProperty:): test the proxies for the availability of
|
||||
properties so that -getAvailableProperties:inMemCtx: can return an
|
||||
accurate result.
|
||||
|
||||
* OpenChange/MAPIStoreMessage.m (-getPidTagSubject:inMemCtx:): now
|
||||
compute the return value based on PidTagNormalizedSubject and
|
||||
PidTagSubjectPrefix as PidTagSubject is never actually set from
|
||||
the client.
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
(_appendCycleException:firstInstanceCalendarDateRange:fromRow:forRange:withTimeZone:toArray:):
|
||||
return immediately if the occurrence does not have a valid
|
||||
|
@ -109,6 +473,50 @@
|
|||
method that returns a properly formatted string of the event title
|
||||
with respect to the current operation (creation/deletion/update).
|
||||
|
||||
2012-07-19 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreObject.m (-nameInContainer): moved method
|
||||
from MAPIStoreSOGoObject and made mandatory for subclasses.
|
||||
(-url): new methed moved from MAPIStoreSOGoObject.
|
||||
|
||||
* OpenChange/MAPIStoreAppointmentWrapper.m: now a subclass of
|
||||
MAPIStoreObjectProxy.
|
||||
|
||||
* OpenChange/MAPIStoreCalendarMessage.m
|
||||
(-initWithSOGoObject:inContainer:): we now register our
|
||||
appointment wrapper as a proxy.
|
||||
|
||||
* OpenChange/MAPIStoreObject.m (-addProxy:): new method that keeps
|
||||
proxy objects in the new "proxies" ivar.
|
||||
(-getProperty:withTag:inMemCtx:): added code that pass the request
|
||||
to the available object proxies, when the property getters have
|
||||
not been found in the local class.
|
||||
|
||||
* OpenChange/MAPIStoreObjectProxy.[hm]: new class module that
|
||||
provide a facility for providing property getters in the name of
|
||||
another class, working around the fact that Objective-C does not
|
||||
provide multiple-inheritance.
|
||||
|
||||
* OpenChange/NSObject+MAPIStore.m
|
||||
(+getAvailableProperties:inMemCtx:)
|
||||
(-getAvailableProperties:inMemCtx:, canGetProperty:): methods
|
||||
moved from MAPIStoreObject.m
|
||||
|
||||
2012-07-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreCalendarFolder.m (-createMessage): attach a
|
||||
WOContext to the newEntry in order to enable page templates
|
||||
resolution when notifications are sent.
|
||||
|
||||
* OpenChange/MAPIApplication.m (-init): a WEResourceManager is
|
||||
setup for the application so that page templates can be properly
|
||||
be initialized.
|
||||
|
||||
* OpenChange/MAPIStoreDBMessage.m (-objectVersion): shift the
|
||||
version number by 16 bits, instead of doing it in -save.
|
||||
(-save): don t swap the bytes of the version number as it would
|
||||
return a wrong change number and a wrong change key for DB objects.
|
||||
|
||||
2012-07-18 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
|
@ -286,6 +694,25 @@
|
|||
Show all addresses returned from secondaryEmails.
|
||||
This still need some css tweaks.
|
||||
|
||||
2012-07-01 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreRecurrenceUtils.m
|
||||
(-setupRecurrenceWithMasterEntity:fromRecurrencePattern:): add
|
||||
exception dates to master entity based on the
|
||||
"DeletedInstanceDates" member of the struct.
|
||||
(-fillRecurrencePattern:withEvent:inTimeZone:inMemCtx:): new name
|
||||
for fillRecurrencePattern:withStartDate:andEndDate:, add exception
|
||||
dates to struct.
|
||||
|
||||
* OpenChange/NSDate+MAPIStore.m (NSDateCompare): new comparison
|
||||
function for sorting array of NSDate instances.
|
||||
|
||||
2012-06-30 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/NSObject+MAPIStore.h: renamed
|
||||
MAPIStoreTallocWrapper.MAPIStoreSOGoObject to .instance, to avoid
|
||||
confusion in certain versions of GCC with our new class type.
|
||||
|
||||
2012-06-29 Jean Raby <jraby@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/WORequest+SOGo.[mh]
|
||||
|
@ -296,6 +723,23 @@
|
|||
Let sogo append system sources if the request comes from an android
|
||||
client even if its user agent matches the IPhoneAddressBook
|
||||
|
||||
2012-06-29 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m
|
||||
(sogo_message_attachment_open_embedded_message): added the "mode"
|
||||
parameter.
|
||||
|
||||
* OpenChange/SOGoMAPIDBObject.m: new class module that replaced
|
||||
SOGoMAPIFSMessage.
|
||||
|
||||
* OpenChange/SOGoMAPIDBFolder.m: new class module that replaced
|
||||
SOGoMAPIFSFolder.
|
||||
|
||||
2012-06-28 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/SOGoObject.m (-initWithName:inContainer:): make
|
||||
sure that "_name" is neither nil nor empty.
|
||||
|
||||
2012-06-27 Jean Raby <jraby@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
|
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
|
@ -201,6 +201,7 @@ static BOOL debugLeaks;
|
|||
fileSuffix = [channelURL scheme];
|
||||
tc = [cm acquireOpenChannelForURL: channelURL];
|
||||
|
||||
/* FIXME: make use of [EOChannelAdaptor describeTableNames] instead */
|
||||
tableName = [url lastPathComponent];
|
||||
if ([tc evaluateExpressionX:
|
||||
[NSString stringWithFormat: @"SELECT count(*) FROM %@",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* EOBitmaskQualifier.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* EOBitmaskQualifier.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* EOQualifier+MAPI.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -25,11 +25,11 @@
|
|||
|
||||
#import <EOControl/EOQualifier.h>
|
||||
|
||||
@class SOGoMAPIVolatileMessage;
|
||||
@class SOGoMAPIDBObject;
|
||||
|
||||
@interface EOQualifier (MAPIStoreRestrictions)
|
||||
|
||||
- (BOOL) evaluateMAPIVolatileMessage: (SOGoMAPIVolatileMessage *) message;
|
||||
- (BOOL) evaluateSOGoMAPIDBObject: (SOGoMAPIDBObject *) object;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* EOQualifier+MAPI.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -28,28 +28,28 @@
|
|||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import "SOGoMAPIVolatileMessage.h"
|
||||
#import "EOBitmaskQualifier.h"
|
||||
#import "SOGoMAPIDBObject.h"
|
||||
|
||||
#import "EOQualifier+MAPI.h"
|
||||
#import "EOBitmaskQualifier.h"
|
||||
|
||||
@implementation EOQualifier (MAPIStoreRestrictions)
|
||||
|
||||
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties
|
||||
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) evaluateMAPIVolatileMessage: (SOGoMAPIVolatileMessage *) message
|
||||
- (BOOL) evaluateSOGoMAPIDBObject: (SOGoMAPIDBObject *) object
|
||||
{
|
||||
NSDictionary *properties;
|
||||
BOOL rc;
|
||||
|
||||
[self logWithFormat: @"evaluating message '%@'", message];
|
||||
[self logWithFormat: @"evaluating object '%@'", object];
|
||||
|
||||
properties = [message properties];
|
||||
rc = [self _evaluateMAPIVolatileMessageProperties: properties];
|
||||
properties = [object properties];
|
||||
rc = [self _evaluateSOGoMAPIDBObject: properties];
|
||||
|
||||
[self logWithFormat: @" evaluation result: %d", rc];
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
|||
|
||||
@implementation EOAndQualifier (MAPIStoreRestrictionsPrivate)
|
||||
|
||||
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties
|
||||
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
|
||||
{
|
||||
NSUInteger i;
|
||||
BOOL rc;
|
||||
|
@ -69,7 +69,7 @@
|
|||
|
||||
for (i = 0; rc && i < count; i++)
|
||||
rc = [[qualifiers objectAtIndex: i]
|
||||
_evaluateMAPIVolatileMessageProperties: properties];
|
||||
_evaluateSOGoMAPIDBObject: properties];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@
|
|||
|
||||
@implementation EOOrQualifier (MAPIStoreRestrictionsPrivate)
|
||||
|
||||
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties
|
||||
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
|
||||
{
|
||||
NSUInteger i;
|
||||
BOOL rc;
|
||||
|
@ -87,7 +87,7 @@
|
|||
|
||||
for (i = 0; !rc && i < count; i++)
|
||||
rc = [[qualifiers objectAtIndex: i]
|
||||
_evaluateMAPIVolatileMessageProperties: properties];
|
||||
_evaluateSOGoMAPIDBObject: properties];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -96,9 +96,9 @@
|
|||
|
||||
@implementation EONotQualifier (MAPIStoreRestrictionsPrivate)
|
||||
|
||||
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties
|
||||
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
|
||||
{
|
||||
return ![qualifier _evaluateMAPIVolatileMessageProperties: properties];
|
||||
return ![qualifier _evaluateSOGoMAPIDBObject: properties];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -107,7 +107,7 @@
|
|||
|
||||
typedef BOOL (*EOComparator) (id, SEL, id);
|
||||
|
||||
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties
|
||||
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
|
||||
{
|
||||
id finalKey;
|
||||
id propValue;
|
||||
|
@ -136,7 +136,7 @@ typedef BOOL (*EOComparator) (id, SEL, id);
|
|||
|
||||
@implementation EOBitmaskQualifier (MAPIStoreRestrictionsPrivate)
|
||||
|
||||
- (BOOL) _evaluateMAPIVolatileMessageProperties: (NSDictionary *) properties
|
||||
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
|
||||
{
|
||||
NSNumber *propTag;
|
||||
id propValue;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* GCSSpecialQueries+OpenChange.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2012 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 GCSSPECIALQUERIES_OPENCHANGE_H
|
||||
#define GCSSPECIALQUERIES_OPENCHANGE_H
|
||||
|
||||
#import <GDLContentStore/GCSSpecialQueries.h>
|
||||
|
||||
@interface GCSSpecialQueries (OpenChangeHelpers)
|
||||
|
||||
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* GCSSPECIALQUERIES_OPENCHANGE_H */
|
|
@ -0,0 +1,107 @@
|
|||
/* GCSSpecialQueries+OpenChange.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2012 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 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import "GCSSpecialQueries+OpenChange.h"
|
||||
|
||||
@interface GCSPostgreSQLSpecialQueries (OpenChangeHelpers)
|
||||
@end
|
||||
|
||||
@interface GCSMySQLSpecialQueries (OpenChangeHelpers)
|
||||
@end
|
||||
|
||||
@interface GCSOracleSpecialQueries (OpenChangeHelpers)
|
||||
@end
|
||||
|
||||
@implementation GCSSpecialQueries (OpenChangeHelpers)
|
||||
|
||||
/* FIXME: c_parent_path should be indexed */
|
||||
|
||||
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GCSPostgreSQLSpecialQueries (OpenChangeHelpers)
|
||||
|
||||
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
|
||||
{
|
||||
static NSString *sqlFolderFormat
|
||||
= (@"CREATE TABLE %@ ("
|
||||
@" c_path VARCHAR(255) PRIMARY KEY,"
|
||||
@" c_parent_path VARCHAR(255),"
|
||||
@" c_type SMALLINT NOT NULL,"
|
||||
@" c_creationdate INT4 NOT NULL,"
|
||||
@" c_lastmodified INT4 NOT NULL,"
|
||||
@" c_version INT4 NOT NULL DEFAULT 0,"
|
||||
@" c_deleted SMALLINT NOT NULL DEFAULT 0,"
|
||||
@" c_content TEXT)");
|
||||
|
||||
return [NSString stringWithFormat: sqlFolderFormat, tableName];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GCSMySQLSpecialQueries (OpenChangeHelpers)
|
||||
|
||||
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
|
||||
{
|
||||
static NSString *sqlFolderFormat
|
||||
= (@"CREATE TABLE %@ ("
|
||||
@" c_path VARCHAR(255) PRIMARY KEY,"
|
||||
@" c_parent_path VARCHAR(255),"
|
||||
@" c_type TINYINT NOT NULL,"
|
||||
@" c_creationdate INT NOT NULL,"
|
||||
@" c_lastmodified INT NOT NULL,"
|
||||
@" c_version INT NOT NULL DEFAULT 0,"
|
||||
@" c_deleted TINYINT NOT NULL DEFAULT 0,"
|
||||
@" c_content TEXT)");
|
||||
|
||||
return [NSString stringWithFormat: sqlFolderFormat, tableName];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GCSOracleSpecialQueries (OpenChangeHelpers)
|
||||
|
||||
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
|
||||
{
|
||||
static NSString *sqlFolderFormat
|
||||
= (@"CREATE TABLE %@ ("
|
||||
@" c_path VARCHAR2(255) PRIMARY KEY,"
|
||||
@" c_parent_path VARCHAR2(255),"
|
||||
@" c_type SMALLINT NOT NULL,"
|
||||
@" c_creationdate INT4 NOT NULL,"
|
||||
@" c_lastmodified INT4 NOT NULL,"
|
||||
@" c_version INT4 NOT NULL DEFAULT 0,"
|
||||
@" c_deleted SMALLINT NOT NULL DEFAULT 0,"
|
||||
@" c_content CLOB)");
|
||||
|
||||
return [NSString stringWithFormat: sqlFolderFormat, tableName];
|
||||
}
|
||||
|
||||
@end
|
|
@ -26,6 +26,17 @@ BUNDLE_INSTALL_DIR = $(SOGO_LIBDIR)
|
|||
|
||||
UNRTF_DIR = unrtf-$(UNRTF_VERSION)
|
||||
|
||||
PYTHON = /usr/bin/python
|
||||
PYTHON_IS_GOOD = $(shell $(PYTHON) -c 'from sys import version_info; a=version_info; print a[0] == 2 and a[1] >= 6')
|
||||
ifeq (${PYTHON_IS_GOOD},False)
|
||||
PYTHON = /usr/bin/python2.6
|
||||
endif
|
||||
|
||||
all::
|
||||
@echo " Python executable: ${PYTHON}"
|
||||
|
||||
SAMBA_PRIVATE_DIR = $(shell $(PYTHON) ./samba-get-config.py "private dir")
|
||||
|
||||
$(SOGOBACKEND)_SUBPROJECTS += $(UNRTF_DIR)/src
|
||||
|
||||
$(SOGOBACKEND)_PRINCIPAL_CLASS = MAPIApplication
|
||||
|
@ -41,9 +52,11 @@ $(SOGOBACKEND)_OBJC_FILES += \
|
|||
MAPIStoreSamDBUtils.m \
|
||||
MAPIStoreUserContext.m \
|
||||
\
|
||||
SOGoMAPIVolatileMessage.m \
|
||||
SOGoMAPIFSFolder.m \
|
||||
SOGoMAPIFSMessage.m \
|
||||
SOGoMAPIObject.m \
|
||||
\
|
||||
SOGoMAPIDBObject.m \
|
||||
SOGoMAPIDBMessage.m \
|
||||
SOGoMAPIDBFolder.m \
|
||||
\
|
||||
MAPIStoreAppointmentWrapper.m \
|
||||
MAPIStoreAttachment.m \
|
||||
|
@ -53,18 +66,18 @@ $(SOGOBACKEND)_OBJC_FILES += \
|
|||
MAPIStoreFolder.m \
|
||||
MAPIStoreMessage.m \
|
||||
MAPIStoreObject.m \
|
||||
MAPIStoreObjectProxy.m \
|
||||
MAPIStoreSOGoObject.m \
|
||||
MAPIStoreTable.m \
|
||||
MAPIStoreMessageTable.m \
|
||||
MAPIStoreFolderTable.m \
|
||||
MAPIStorePermissionsTable.m \
|
||||
\
|
||||
MAPIStoreVolatileMessage.m \
|
||||
\
|
||||
MAPIStoreFSBaseContext.m \
|
||||
MAPIStoreFSFolder.m \
|
||||
MAPIStoreFSFolderTable.m \
|
||||
MAPIStoreFSMessage.m \
|
||||
MAPIStoreFSMessageTable.m \
|
||||
MAPIStoreDBBaseContext.m \
|
||||
MAPIStoreDBFolder.m \
|
||||
MAPIStoreDBFolderTable.m \
|
||||
MAPIStoreDBMessage.m \
|
||||
MAPIStoreDBMessageTable.m \
|
||||
\
|
||||
MAPIStoreFAIMessage.m \
|
||||
MAPIStoreFAIMessageTable.m \
|
||||
|
@ -78,6 +91,7 @@ $(SOGOBACKEND)_OBJC_FILES += \
|
|||
MAPIStoreCalendarContext.m \
|
||||
MAPIStoreCalendarFolder.m \
|
||||
MAPIStoreCalendarMessage.m \
|
||||
MAPIStoreCalendarEmbeddedMessage.m \
|
||||
MAPIStoreCalendarMessageTable.m \
|
||||
MAPIStoreRecurrenceUtils.m \
|
||||
\
|
||||
|
@ -112,8 +126,14 @@ $(SOGOBACKEND)_OBJC_FILES += \
|
|||
NSString+MAPIStore.m \
|
||||
NSValue+MAPIStore.m \
|
||||
\
|
||||
EOBitmaskQualifier.m \
|
||||
iCalEvent+MAPIStore.m \
|
||||
iCalTimeZone+MAPIStore.m \
|
||||
\
|
||||
GCSSpecialQueries+OpenChange.m\
|
||||
\
|
||||
EOQualifier+MAPI.m \
|
||||
\
|
||||
EOBitmaskQualifier.m
|
||||
|
||||
|
||||
$(SOGOBACKEND)_RESOURCE_FILES += \
|
||||
|
@ -145,7 +165,18 @@ PLREADER_TOOL = plreader
|
|||
$(PLREADER_TOOL)_OBJC_FILES += \
|
||||
plreader.m \
|
||||
|
||||
TEST_TOOL_NAME += $(PLREADER_TOOL)
|
||||
DBMSGREADER_TOOL = dbmsgreader
|
||||
$(DBMSGREADER_TOOL)_OBJC_FILES += \
|
||||
dbmsgreader.m
|
||||
|
||||
$(DBMSGREADER_TOOL)_LIB_DIRS += \
|
||||
-L../SoObjects/SOGo/SOGo.framework/ -lSOGo \
|
||||
-L../OGoContentStore/obj/ -lOGoContentStore \
|
||||
-L../SOPE/GDLContentStore/obj/ -lGDLContentStore \
|
||||
-L../SOPE/NGCards/obj/ -lNGCards \
|
||||
-lNGObjWeb
|
||||
|
||||
TEST_TOOL_NAME += $(PLREADER_TOOL) $(DBMSGREADER_TOOL)
|
||||
|
||||
### cflags and libs
|
||||
LIBMAPI_CFLAGS = $(shell pkg-config libmapi --cflags)
|
||||
|
@ -160,7 +191,7 @@ SAMBA_LIB_DIR = $(shell pkg-config libmapistore --variable=libdir)
|
|||
LIBMAPI_LIBS = $(shell pkg-config libmapi --libs)
|
||||
|
||||
LIBMAPISTORE_CFLAGS = $(shell pkg-config libmapistore --cflags) -DSAMBA_PREFIX="\"$(shell pkg-config libmapistore --variable=prefix)\""
|
||||
LIBMAPISTORE_LIBS = $(shell pkg-config libmapistore --libs) -lmapiproxy
|
||||
LIBMAPISTORE_LIBS = $(shell pkg-config libmapistore --libs) -lmapiproxy -lWEExtensions
|
||||
|
||||
$(MAPISTORESOGO)_INSTALL_DIR = $(DESTDIR)/$(SAMBA_LIB_DIR)/mapistore_backends
|
||||
$(MAPISTORESOGO)_LIB_DIRS += \
|
||||
|
@ -176,6 +207,7 @@ $(SOGOBACKEND)_LIB_DIRS += \
|
|||
|
||||
ADDITIONAL_INCLUDE_DIRS += \
|
||||
-Werror -Wall \
|
||||
-DSAMBA_PRIVATE_DIR=@"\"$(SAMBA_PRIVATE_DIR)\"" \
|
||||
$(LIBMAPI_CFLAGS) \
|
||||
$(LIBMAPISTORE_CFLAGS) \
|
||||
-I$(UNRTF_DIR)/src \
|
||||
|
|
|
@ -2,4 +2,4 @@ all:: MAPIStorePropertySelectors.m MAPIStorePropertySelectors.h
|
|||
|
||||
MAPIStorePropertySelectors.m MAPIStorePropertySelectors.h: gen-property-selectors.py code-MAPIStorePropertySelectors.m code-MAPIStorePropertySelectors.h
|
||||
@echo " Auto-generating MAPIStorePropertySelectors.[hm]..."
|
||||
@./gen-property-selectors.py -o MAPIStorePropertySelectors $(LIBMAPISTORE_CFLAGS)
|
||||
@$(PYTHON) ./gen-property-selectors.py -o MAPIStorePropertySelectors $(LIBMAPISTORE_CFLAGS)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIApplication.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
#import <Foundation/NSTimeZone.h>
|
||||
#import <WEExtensions/WEResourceManager.h>
|
||||
|
||||
#import <SOGo/SOGoProductLoader.h>
|
||||
#import <SOGo/SOGoSystemDefaults.h>
|
||||
|
@ -46,12 +47,18 @@ MAPIApplication *MAPIApp = nil;
|
|||
{
|
||||
if (!MAPIApp)
|
||||
{
|
||||
WEResourceManager *rm;
|
||||
|
||||
// TODO publish
|
||||
[iCalEntityObject initializeSOGoExtensions];
|
||||
|
||||
MAPIApp = [super init];
|
||||
[MAPIApp retain];
|
||||
|
||||
rm = [[WEResourceManager alloc] init];
|
||||
[self setResourceManager:rm];
|
||||
[rm release];
|
||||
|
||||
utcTZ = [NSTimeZone timeZoneWithName: @"UTC"];
|
||||
[utcTZ retain];
|
||||
}
|
||||
|
@ -59,6 +66,11 @@ MAPIApplication *MAPIApp = nil;
|
|||
return MAPIApp;
|
||||
}
|
||||
|
||||
- (BOOL) shouldSetupSignalHandlers
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) setUserContext: (MAPIStoreUserContext *) newContext
|
||||
{
|
||||
/* user contexts must not be retained here ad their holder (mapistore)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreActiveTables.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreActiveTables.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreAppointmentWrapper.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -23,10 +23,11 @@
|
|||
#ifndef MAPISTORECALENDARWRAPPER_H
|
||||
#define MAPISTORECALENDARWRAPPER_H
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
#import <Appointments/iCalEntityObject+SOGo.h>
|
||||
|
||||
#import "MAPIStoreObjectProxy.h"
|
||||
|
||||
@class NSTimeZone;
|
||||
|
||||
@class iCalAlarm;
|
||||
|
@ -35,10 +36,11 @@
|
|||
|
||||
@class SOGoUser;
|
||||
|
||||
@interface MAPIStoreAppointmentWrapper : NSObject
|
||||
@interface MAPIStoreAppointmentWrapper : MAPIStoreObjectProxy
|
||||
{
|
||||
struct mapistore_connection_info *connInfo;
|
||||
iCalCalendar *calendar;
|
||||
iCalEvent *firstEvent;
|
||||
iCalEvent *event;
|
||||
NSTimeZone *timeZone;
|
||||
SOGoUser *user;
|
||||
|
@ -120,8 +122,8 @@
|
|||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPidLidIndentedBusyStatus: (void **) data // TODO
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPidTagSubject: (void **) data // SUMMARY
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPidTagNormalizedSubject: (void **) data // SUMMARY
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPidLidLocation: (void **) data // LOCATION
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) getPidLidPrivate: (void **) data // private (bool), should depend on CLASS and permissions
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreAppointmentWrapper.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -20,24 +20,28 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <talloc.h>
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSCharacterSet.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSTimeZone.h>
|
||||
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGCards/iCalAlarm.h>
|
||||
#import <NGCards/iCalDateTime.h>
|
||||
#import <NGCards/iCalEvent.h>
|
||||
#import <NGCards/iCalEventChanges.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
#import <NGCards/iCalRecurrenceRule.h>
|
||||
#import <NGCards/iCalTimeZone.h>
|
||||
#import <NGCards/iCalTrigger.h>
|
||||
#import <NGCards/NSString+NGCards.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserManager.h>
|
||||
|
||||
#import "iCalTimeZone+MAPIStore.h"
|
||||
#import "MAPIStoreRecurrenceUtils.h"
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
@ -49,7 +53,6 @@
|
|||
#import "MAPIStoreAppointmentWrapper.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <talloc.h>
|
||||
#include <stdbool.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
#include <gen_ndr/property.h>
|
||||
|
@ -181,11 +184,15 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
inTimeZone: (NSTimeZone *) newTimeZone
|
||||
withConnectionInfo: (struct mapistore_connection_info *) newConnInfo
|
||||
{
|
||||
NSArray *events;
|
||||
|
||||
if ((self = [self init]))
|
||||
{
|
||||
connInfo = newConnInfo;
|
||||
ASSIGN (event, newEvent);
|
||||
ASSIGN (calendar, [event parent]);
|
||||
ASSIGN (calendar, [newEvent parent]);
|
||||
event = newEvent;
|
||||
events = [calendar events];
|
||||
firstEvent = [events objectAtIndex: 0];
|
||||
ASSIGN (timeZone, newTimeZone);
|
||||
ASSIGN (user, newUser);
|
||||
ASSIGN (senderEmail, newSenderEmail);
|
||||
|
@ -198,7 +205,6 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
- (void) dealloc
|
||||
{
|
||||
[calendar release];
|
||||
[event release];
|
||||
[timeZone release];
|
||||
[user release];
|
||||
[senderEmail release];
|
||||
|
@ -435,7 +441,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
|
||||
- (int) getPidTagIconIndex: (void **) data // TODO
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
uint32_t longValue;
|
||||
|
||||
|
@ -580,7 +586,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
|
||||
- (int) getPidTagMessageClass: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
const char *className;
|
||||
|
||||
|
@ -626,35 +632,20 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidAppointmentMessageClass: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = talloc_strdup (memCtx, "IPM.Appointment");
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidFInvited: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getYes: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagStartDate: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
if ([event isRecurrent])
|
||||
dateValue = [event firstRecurrenceStartDate];
|
||||
else
|
||||
dateValue = [event startDate];
|
||||
if ([event isAllDay])
|
||||
{
|
||||
offset = -[timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
}
|
||||
[dateValue setTimeZone: utcTZ];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidAppointmentSequence: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -718,17 +709,255 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidAppointmentNotAllowPropose: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getYes: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidLidAppointmentStartWhole: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidTagStartDate: data inMemCtx: memCtx];
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
// if ([event isRecurrent])
|
||||
// dateValue = [event firstRecurrenceStartDate];
|
||||
// else
|
||||
dateValue = [event startDate];
|
||||
if ([event isAllDay])
|
||||
{
|
||||
offset = -[timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
}
|
||||
[dateValue setTimeZone: utcTZ];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagStartDate: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
/* "The PidTagStartDate property ([MS-OXPROPS] section 2.1077) SHOULD be
|
||||
set, and when set, it MUST be equal to the value of the
|
||||
PidLidAppointmentStartWhole property (section 2.2.1.5).". Not true for
|
||||
exceptions, where it is the normal start date for the day of the
|
||||
exception. */
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
dateValue = [event recurrenceId];
|
||||
if (!dateValue)
|
||||
dateValue = [event startDate];
|
||||
[dateValue setTimeZone: timeZone];
|
||||
if ([event isAllDay])
|
||||
{
|
||||
offset = -[timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
}
|
||||
[dateValue setTimeZone: utcTZ];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidCommonStart: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidLidAppointmentStartWhole: data inMemCtx: memCtx];
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
dateValue = [firstEvent startDate];
|
||||
if ([firstEvent isAllDay])
|
||||
{
|
||||
offset = -[timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
}
|
||||
[dateValue setTimeZone: utcTZ];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidClipStart: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
NSCalendarDate *dateValue;
|
||||
|
||||
if ([event isRecurrent])
|
||||
{
|
||||
dateValue = [[event startDate] hour: 0 minute: 0 second: 0];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else if ([event recurrenceId] != nil)
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
else
|
||||
rc = [self getPidLidAppointmentStartWhole: data inMemCtx: memCtx];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPidTagExceptionStartTime: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) localMemCtx
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
if ([event recurrenceId] != nil)
|
||||
{
|
||||
dateValue = [event startDate];
|
||||
[dateValue setTimeZone: timeZone];
|
||||
if (![event isAllDay])
|
||||
{
|
||||
offset = [timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
}
|
||||
*data = [dateValue asFileTimeInMemCtx: localMemCtx];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPidLidAppointmentEndWhole: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
// if ([event isRecurrent])
|
||||
// dateValue = [event firstRecurrenceStartDate];
|
||||
// else
|
||||
dateValue = [event startDate];
|
||||
offset = [event durationAsTimeInterval];
|
||||
if ([event isAllDay])
|
||||
offset -= [timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagEndDate: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
dateValue = [event recurrenceId];
|
||||
if (!dateValue)
|
||||
dateValue = [event startDate];
|
||||
[dateValue setTimeZone: timeZone];
|
||||
offset = [firstEvent durationAsTimeInterval];
|
||||
if ([firstEvent isAllDay])
|
||||
offset -= [timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidCommonEnd: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
// if ([event isRecurrent])
|
||||
// dateValue = [event firstRecurrenceStartDate];
|
||||
// else
|
||||
dateValue = [firstEvent startDate];
|
||||
offset = [firstEvent durationAsTimeInterval];
|
||||
if ([event isAllDay])
|
||||
offset -= [timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidClipEnd: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
iCalRecurrenceRule *rrule;
|
||||
|
||||
if ([event isRecurrent])
|
||||
{
|
||||
rrule = [[event recurrenceRules] objectAtIndex: 0];
|
||||
dateValue = [rrule untilDate];
|
||||
if (dateValue)
|
||||
{
|
||||
if ([event isAllDay])
|
||||
offset = -[timeZone secondsFromGMTForDate: dateValue];
|
||||
else
|
||||
offset = 0;
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
}
|
||||
else
|
||||
dateValue = [NSCalendarDate dateWithYear: 4500 month: 8 day: 31
|
||||
hour: 23 minute: 59 second: 59
|
||||
timeZone: utcTZ];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else if ([event recurrenceId] != nil)
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
else
|
||||
rc = [self getPidLidAppointmentEndWhole: data inMemCtx: memCtx];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPidTagExceptionEndTime: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) localMemCtx
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
if ([event recurrenceId] != nil)
|
||||
{
|
||||
dateValue = [event startDate];
|
||||
[dateValue setTimeZone: timeZone];
|
||||
offset = [event durationAsTimeInterval];
|
||||
if (![event isAllDay])
|
||||
offset += [timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
*data = [dateValue asFileTimeInMemCtx: localMemCtx];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) _getEntryIdFromCN: (NSString *) cn
|
||||
|
@ -827,7 +1056,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
|
||||
/* sender (organizer) */
|
||||
- (int) getPidTagSenderEmailAddress: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self _getEmailAddress: data
|
||||
forICalPerson: [event organizer]
|
||||
|
@ -835,7 +1064,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
|
||||
- (int) getPidTagSenderAddressType: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self _getAddrType: data
|
||||
forICalPerson: [event organizer]
|
||||
|
@ -843,7 +1072,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
|
||||
- (int) getPidTagSenderName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self _getName: data
|
||||
forICalPerson: [event organizer]
|
||||
|
@ -851,16 +1080,41 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
|
||||
- (int) getPidTagSenderEntryId: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self _getEntryId: data
|
||||
forICalPerson: [event organizer]
|
||||
inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
/* sender representing */
|
||||
- (int) getPidTagSentRepresentingEmailAddress: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidTagSenderEmailAddress: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagSentRepresentingAddressType: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getSMTPAddrType: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagSentRepresentingName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidTagSenderName: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagSentRepresentingEntryId: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidTagSenderEntryId: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
/* attendee */
|
||||
- (int) getPidTagReceivedByEmailAddress: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self _getEmailAddress: data
|
||||
forICalPerson: [event userAsAttendee: user]
|
||||
|
@ -868,7 +1122,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
|
||||
- (int) getPidTagReceivedByAddressType: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self _getAddrType: data
|
||||
forICalPerson: [event userAsAttendee: user]
|
||||
|
@ -876,7 +1130,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
|
||||
- (int) getPidTagReceivedByName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self _getName: data
|
||||
forICalPerson: [event userAsAttendee: user]
|
||||
|
@ -884,7 +1138,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
|
||||
- (int) getPidTagReceivedByEntryId: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self _getEntryId: data
|
||||
forICalPerson: [event userAsAttendee: user]
|
||||
|
@ -892,40 +1146,6 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
/* /attendee */
|
||||
|
||||
- (int) getPidTagEndDate: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
if ([event isRecurrent])
|
||||
dateValue = [event firstRecurrenceStartDate];
|
||||
else
|
||||
dateValue = [event startDate];
|
||||
offset = [event durationAsTimeInterval];
|
||||
if ([event isAllDay])
|
||||
offset -= [timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
[dateValue setTimeZone: utcTZ];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidAppointmentEndWhole: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidTagEndDate: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidLidCommonEnd: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidLidAppointmentEndWhole: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidLidAppointmentDuration: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -966,8 +1186,8 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
return [self getPidLidBusyStatus: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagSubject: (void **) data // SUMMARY
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
- (int) getPidTagNormalizedSubject: (void **) data // SUMMARY
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = [[event summary] asUnicodeInMemCtx: memCtx];
|
||||
|
||||
|
@ -995,7 +1215,8 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
return [self getPidLidLocation: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidLidServerProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
|
||||
- (int) getPidLidServerProcessed: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
/* TODO: we need to check whether the event has been processed internally by
|
||||
SOGo or if it was received only by mail. We only assume the SOGo case
|
||||
|
@ -1003,7 +1224,8 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
return [self getYes: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidLidServerProcessingActions: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
|
||||
- (int) getPidLidServerProcessingActions: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPILongValue (memCtx,
|
||||
0x00000010 /* cpsCreatedOnPrincipal */
|
||||
|
@ -1020,14 +1242,14 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
|
||||
- (int) getPidTagSensitivity: (void **) data // not implemented, depends on CLASS
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
// normal = 0, personal?? = 1, private = 2, confidential = 3
|
||||
return [self getLongZero: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagImportance: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
uint32_t v;
|
||||
if ([[event priority] isEqualToString: @"9"])
|
||||
|
@ -1043,7 +1265,7 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
}
|
||||
|
||||
- (int) getPidTagBody: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
int rc = MAPISTORE_SUCCESS;
|
||||
NSString *stringValue;
|
||||
|
@ -1053,15 +1275,23 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
if ([stringValue length] > 0)
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
*data = [@"" asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPidLidIsRecurring: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
- (int) getPidTagInternetCodepage: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPIBoolValue (memCtx, [event isRecurrent]);
|
||||
/* ref:
|
||||
http://msdn.microsoft.com/en-us/library/dd317756%28v=vs.85%29.aspx
|
||||
|
||||
minimal list that should be handled:
|
||||
us-ascii: 20127
|
||||
iso-8859-1: 28591
|
||||
iso-8859-15: 28605
|
||||
utf-8: 65001 */
|
||||
*data = MAPILongValue(memCtx, 65001);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -1074,37 +1304,144 @@ static NSCharacterSet *hexCharacterSet = nil;
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
||||
NSCalendarDate *startDate, NSTimeInterval duration,
|
||||
NSCalendarDate * endDate, iCalRecurrenceRule *rule)
|
||||
- (int) getPidLidIsRecurring: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
uint32_t startMinutes;
|
||||
*data = MAPIBoolValue (memCtx,
|
||||
[event isRecurrent]
|
||||
|| ([event recurrenceId] != nil));
|
||||
|
||||
[rule fillRecurrencePattern: &arp->RecurrencePattern
|
||||
withStartDate: startDate andEndDate: endDate];
|
||||
arp->ReaderVersion2 = 0x00003006;
|
||||
arp->WriterVersion2 = 0x00003009;
|
||||
|
||||
startMinutes = ([startDate hourOfDay] * 60 + [startDate minuteOfHour]);
|
||||
arp->StartTimeOffset = startMinutes;
|
||||
arp->EndTimeOffset = startMinutes + (uint32_t) (duration / 60);
|
||||
|
||||
arp->ExceptionCount = 0;
|
||||
arp->ReservedBlock1Size = 0;
|
||||
|
||||
/* Currently ignored in property.idl:
|
||||
arp->ReservedBlock2Size = 0; */
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (struct SBinary_short *) _computeAppointmentRecurInMemCtx: (TALLOC_CTX *) memCtx
|
||||
- (int) getPidLidIsException: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPIBoolValue (memCtx, [event recurrenceId] != nil);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidFExceptionalBody: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getNo: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidLidExceptionReplaceTime: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
dateValue = [event recurrenceId];
|
||||
if (dateValue)
|
||||
{
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
|
||||
if ([event isAllDay])
|
||||
{
|
||||
offset = -[timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
}
|
||||
[dateValue setTimeZone: utcTZ];
|
||||
*data = [dateValue asFileTimeInMemCtx: memCtx];
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (void) _fillExceptionInfo: (struct ExceptionInfo *) exceptionInfo
|
||||
andExtendedException: (struct ExtendedException *) extendedException
|
||||
withException: (iCalEvent *) exceptionEvent
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
iCalEventChanges *changes;
|
||||
NSArray *changedProperties;
|
||||
NSCalendarDate *dateValue;
|
||||
NSInteger offset;
|
||||
|
||||
changes = [iCalEventChanges changesFromEvent: event toEvent: exceptionEvent];
|
||||
|
||||
memset (exceptionInfo, 0, sizeof (struct ExceptionInfo));
|
||||
memset (extendedException, 0, sizeof (struct ExtendedException));
|
||||
extendedException->ChangeHighlight.Size = sizeof (uint32_t);
|
||||
|
||||
dateValue = [exceptionEvent startDate];
|
||||
offset = [timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
exceptionInfo->StartDateTime = [dateValue asMinutesSince1601];
|
||||
extendedException->ChangeHighlight.Value = BIT_CH_START;
|
||||
extendedException->StartDateTime = exceptionInfo->StartDateTime;
|
||||
|
||||
dateValue = [exceptionEvent endDate];
|
||||
offset = [timeZone secondsFromGMTForDate: dateValue];
|
||||
dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
exceptionInfo->EndDateTime = [dateValue asMinutesSince1601];
|
||||
extendedException->ChangeHighlight.Value |= BIT_CH_END;
|
||||
extendedException->EndDateTime = exceptionInfo->EndDateTime;
|
||||
|
||||
dateValue = [[exceptionEvent recurrenceId]
|
||||
dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
exceptionInfo->OriginalStartDate = [dateValue asMinutesSince1601];
|
||||
extendedException->OriginalStartDate = exceptionInfo->OriginalStartDate;
|
||||
|
||||
changedProperties = [changes updatedProperties];
|
||||
if ([changedProperties containsObject: @"summary"])
|
||||
{
|
||||
extendedException->ChangeHighlight.Value |= BIT_CH_SUBJECT;
|
||||
extendedException->Subject
|
||||
= [[exceptionEvent summary] asUnicodeInMemCtx: memCtx];
|
||||
|
||||
exceptionInfo->OverrideFlags |= ARO_SUBJECT;
|
||||
exceptionInfo->Subject.subjectMsg.msg
|
||||
= (uint8_t *) extendedException->Subject;
|
||||
/* FIXME: this will fail with non ascii chars */
|
||||
exceptionInfo->Subject.subjectMsg.msgLength2 = [[exceptionEvent summary] length];
|
||||
exceptionInfo->Subject.subjectMsg.msgLength = exceptionInfo->Subject.subjectMsg.msgLength2 + 1;
|
||||
}
|
||||
if ([changedProperties containsObject: @"location"])
|
||||
{
|
||||
extendedException->ChangeHighlight.Value |= BIT_CH_LOCATION;
|
||||
extendedException->Location
|
||||
= [[exceptionEvent location] asUnicodeInMemCtx: memCtx];
|
||||
exceptionInfo->OverrideFlags |= ARO_LOCATION;
|
||||
exceptionInfo->Location.locationMsg.msg
|
||||
= (uint8_t *) extendedException->Location;
|
||||
/* FIXME: this will fail with non ascii chars */
|
||||
exceptionInfo->Location.locationMsg.msgLength2 = [[exceptionEvent location] length];
|
||||
exceptionInfo->Location.locationMsg.msgLength = exceptionInfo->Location.locationMsg.msgLength2 + 1;
|
||||
}
|
||||
if ([event isAllDay] != [exceptionEvent isAllDay])
|
||||
{
|
||||
exceptionInfo->OverrideFlags |= ARO_SUBTYPE;
|
||||
exceptionInfo->SubType.sType = [exceptionEvent isAllDay];
|
||||
}
|
||||
}
|
||||
|
||||
// - (struct SBinary_short *) _computeAppointmentRecurInMemCtx: (TALLOC_CTX *) memCtx
|
||||
- (struct Binary_r *) _computeAppointmentRecurInMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
struct AppointmentRecurrencePattern *arp;
|
||||
struct Binary_r *bin;
|
||||
struct SBinary_short *sBin;
|
||||
// struct SBinary_short *sBin;
|
||||
NSCalendarDate *firstStartDate;
|
||||
iCalRecurrenceRule *rule;
|
||||
NSUInteger startMinutes;
|
||||
NSArray *events, *exceptions;
|
||||
iCalEvent *exceptionEvent;
|
||||
NSUInteger count, max;
|
||||
|
||||
rule = [[event recurrenceRules] objectAtIndex: 0];
|
||||
|
||||
|
@ -1113,15 +1450,47 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
|||
{
|
||||
[firstStartDate setTimeZone: timeZone];
|
||||
|
||||
arp = talloc_zero (memCtx, struct AppointmentRecurrencePattern);
|
||||
_fillAppointmentRecurrencePattern (arp, firstStartDate,
|
||||
[event durationAsTimeInterval],
|
||||
[event lastPossibleRecurrenceStartDate],
|
||||
rule);
|
||||
sBin = talloc_zero (memCtx, struct SBinary_short);
|
||||
bin = set_AppointmentRecurrencePattern (sBin, arp);
|
||||
sBin->cb = bin->cb;
|
||||
sBin->lpb = bin->lpb;
|
||||
arp = talloc_zero (NULL, struct AppointmentRecurrencePattern);
|
||||
[rule fillRecurrencePattern: &arp->RecurrencePattern
|
||||
withEvent: event
|
||||
inTimeZone: timeZone
|
||||
inMemCtx: arp];
|
||||
arp->ReaderVersion2 = 0x00003006;
|
||||
arp->WriterVersion2 = 0x00003008; /* 0x3008 for compatibility with
|
||||
ol2003 */
|
||||
|
||||
startMinutes = ([firstStartDate hourOfDay] * 60
|
||||
+ [firstStartDate minuteOfHour]);
|
||||
arp->StartTimeOffset = startMinutes;
|
||||
arp->EndTimeOffset = (startMinutes
|
||||
+ (NSUInteger) ([event durationAsTimeInterval]
|
||||
/ 60));
|
||||
|
||||
events = [[event parent] events];
|
||||
exceptions
|
||||
= [events subarrayWithRange: NSMakeRange (1, [events count] - 1)];
|
||||
max = [exceptions count];
|
||||
arp->ExceptionCount = max;
|
||||
arp->ExceptionInfo = talloc_array (memCtx, struct ExceptionInfo, max);
|
||||
arp->ExtendedException = talloc_array (memCtx, struct ExtendedException, max);
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
exceptionEvent = [exceptions objectAtIndex: count];
|
||||
[self _fillExceptionInfo: arp->ExceptionInfo + count
|
||||
andExtendedException: arp->ExtendedException + count
|
||||
withException: exceptionEvent
|
||||
inMemCtx: arp];
|
||||
}
|
||||
arp->ReservedBlock1Size = 0;
|
||||
arp->ReservedBlock2Size = 0;
|
||||
|
||||
/* Currently ignored in property.idl: arp->ReservedBlock2Size = 0; */
|
||||
|
||||
/* convert struct to blob */
|
||||
// sBin = talloc_zero (memCtx, struct SBinary_short);
|
||||
bin = set_AppointmentRecurrencePattern (memCtx, arp);
|
||||
// sBin->cb = bin->cb;
|
||||
// sBin->lpb = bin->lpb;
|
||||
talloc_free (arp);
|
||||
|
||||
// DEBUG(5, ("To client:\n"));
|
||||
|
@ -1130,12 +1499,100 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
|||
else
|
||||
{
|
||||
[self errorWithFormat: @"no first occurrence found in rule: %@", rule];
|
||||
sBin = NULL;
|
||||
// bin = NULL;
|
||||
bin = NULL;
|
||||
}
|
||||
|
||||
return sBin;
|
||||
return bin;
|
||||
}
|
||||
|
||||
/* exception 12345 + 123456 (exchange):
|
||||
81ad0102 (PT_BINARY):
|
||||
named prop
|
||||
guid: {00062002-0000-0000-c000-000000000046}
|
||||
dispid: 0x00008216
|
||||
(163 bytes)
|
||||
04 30 04 30 0a 20 00 00 | \x04 0 \x04 0 \x0a \x00 \x00
|
||||
00 00 00 00 00 00 a0 05 | \x00 \x00 \x00 \x00 \x00 \x00 \xa0 \x05
|
||||
00 00 00 00 00 00 23 20 | \x00 \x00 \x00 \x00 \x00 \x00 #
|
||||
00 00 0a 00 00 00 00 00 | \x00 \x00 \x0a \x00 \x00 \x00 \x00 \x00
|
||||
00 00 01 00 00 00 a0 c6 | \x00 \x00 \x01 \x00 \x00 \x00 \xa0 \xc6
|
||||
e6 0c 01 00 00 00 a0 c6 | \xe6 \x0c \x01 \x00 \x00 \x00 \xa0 \xc6
|
||||
e6 0c 00 c1 e6 0c df 80 | \xe6 \x0c \x00 \xc1 \xe6 \x0c \xdf \x80
|
||||
e9 5a 06 30 00 00 08 30 | \xe9 Z \x06 0 \x00 \x00 \x08 0
|
||||
00 00 66 03 00 00 84 03 | \x00 \x00 f \x03 \x00 \x00 \x84 \x03
|
||||
00 00 01 00 e8 c9 e6 0c | \x00 \x00 \x01 \x00 \xe8 \xc9 \xe6 \x0c
|
||||
f6 ca e6 0c 06 ca e6 0c | \xf6 \xca \xe6 \x0c \x06 \xca \xe6 \x0c
|
||||
11 00 06 00 05 00 31 32 | \x11 \x00 \x06 \x00 \x05 \x00 1 2
|
||||
33 34 35 07 00 06 00 31 | 3 4 5 \x07 \x00 \x06 \x00 1
|
||||
32 33 34 35 36 00 00 00 | 2 3 4 5 6 \x00 \x00 \x00
|
||||
00 00 00 00 00 e8 c9 e6 | \x00 \x00 \x00 \x00 \x00 \xe8 \xc9 \xe6
|
||||
0c f6 ca e6 0c 06 ca e6 | \x0c \xf6 \xca \xe6 \x0c \x06 \xca \xe6
|
||||
0c 05 00 31 00 32 00 33 | \x0c \x05 \x00 1 \x00 2 \x00 3
|
||||
00 34 00 35 00 06 00 31 | \x00 4 \x00 5 \x00 \x06 \x00 1
|
||||
00 32 00 33 00 34 00 35 | \x00 2 \x00 3 \x00 4 \x00 5
|
||||
00 36 00 00 00 00 00 00 | \x00 6 \x00 \x00 \x00 \x00 \x00 \x00
|
||||
00 00 00 | \x00 \x00 \x00
|
||||
|
||||
openchange:
|
||||
918b0102 (PT_BINARY):
|
||||
named prop
|
||||
guid: {00062002-0000-0000-c000-000000000046}
|
||||
dispid: 0x00008216
|
||||
(167 bytes)
|
||||
|
||||
|
||||
recurrence pattern
|
||||
readerversion: 04 30
|
||||
writerversion: 04 30
|
||||
recurfrequency: 0a 20 (daily)
|
||||
patterntype: 00 00
|
||||
calendartype: 00 00
|
||||
firstdatetime: 00 00 00 00
|
||||
period: a0 05 00 00 (1440 minutes)
|
||||
slidingflag: 00 00 00 00
|
||||
patterntypespecific: (0 bytes)
|
||||
endtype: 23 20 00 00
|
||||
occurrencecount: *00->0a 00 00 00 (meaningless since no enddate)
|
||||
firstdow: 00 00 00 00
|
||||
deletedicount: 01 00 00 00
|
||||
deletedinstancedates: (1)
|
||||
a0 c6 e6 0c
|
||||
modifiedicount: 01 00 00 00
|
||||
modifiedinstancedates: (1)
|
||||
a0 c6 e6 0c
|
||||
startdate: 00 c1 e6 0c
|
||||
enddate: df 80 e9 5a
|
||||
ReaderVersion2: 06 30 00 00
|
||||
WriterVersion2: 08 30 00 00
|
||||
StartTimeOffset: 66 03 00 00
|
||||
EndTimeOffset: 84 03 00 00
|
||||
ExceptionCount: 01 00
|
||||
ExceptionInfos: (1)
|
||||
StartDateTime: *e7->e8 *ca->c9 e6 0c
|
||||
EndDateTime: *e6->f6 *cb->ca e6 0c
|
||||
OriginalStartDate: *a0->06 *c6->ca e6 0c
|
||||
OverrideFlags: 11 00
|
||||
SubjectLength2: 06 00
|
||||
SubjectLength: 05 00
|
||||
Subject: 31 32 33 34 35
|
||||
LocationLength2: 07 00
|
||||
LocationLength: 06 00
|
||||
Location: 31 32 33 34 35 36
|
||||
ReservedBlock1Size: 00 00 00 00
|
||||
ExtendedException: (1)
|
||||
ReservedBlockEE1Size: 00 00 00 00
|
||||
StartDateTime: *e7->e8 *ca->c9 e6 0c
|
||||
EndDateTime: *e6->f6 *cb->ca e6 0c
|
||||
OriginalStartDate: *a0->06 *c6->ca e6 0c
|
||||
WideCharSubjectLength *06->05
|
||||
WideCharSubject: 00 31 00 32 00 33 00 34 00 35 00 [2bytes sup: 00 00]
|
||||
LocationLength: *07->06
|
||||
Location 00 31 00 32 00 33 00 34 00 35 00 36 00 00
|
||||
ReservedBlockEE2Size: 00 00 00 00
|
||||
ReservedBlockEE2Size: 00 00 00 00
|
||||
*/
|
||||
|
||||
- (int) getPidLidAppointmentRecur: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -1515,4 +1972,41 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
|
|||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidLidTimeZoneDescription: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
NSString *tzid;
|
||||
|
||||
tzid = [(iCalDateTime *) [event firstChildWithTag: @"dtstart"]
|
||||
value: 0 ofAttribute: @"tzid"];
|
||||
if ([tzid length] > 0)
|
||||
{
|
||||
*data = [tzid asUnicodeInMemCtx: memCtx];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPidLidTimeZoneStruct: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
iCalTimeZone *icalTZ;
|
||||
|
||||
icalTZ = [(iCalDateTime *) [event firstChildWithTag: @"dtstart"] timeZone];
|
||||
if (icalTZ)
|
||||
{
|
||||
*data = [icalTZ asTimeZoneStructInMemCtx: memCtx];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreAttachment.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -40,10 +40,16 @@
|
|||
withMID: (uint64_t *) mid
|
||||
withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (int) createEmbeddedMessage: (MAPIStoreEmbeddedMessage **) messagePtr
|
||||
withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
|
||||
/* helpers */
|
||||
- (NSData *) mimeAttachTag;
|
||||
|
||||
/* move & copy operations */
|
||||
- (void) copyToAttachment: (MAPIStoreAttachment *) newAttachment;
|
||||
|
||||
/* subclasses */
|
||||
- (MAPIStoreEmbeddedMessage *) openEmbeddedMessage;
|
||||
- (MAPIStoreEmbeddedMessage *) createEmbeddedMessage;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreAttachment.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -28,6 +28,7 @@
|
|||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreMessage.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <stdbool.h>
|
||||
|
@ -90,6 +91,12 @@
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagAccessLevel: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getLongZero: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) openEmbeddedMessage: (MAPIStoreEmbeddedMessage **) messagePtr
|
||||
withMID: (uint64_t *) mid
|
||||
withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr
|
||||
|
@ -103,20 +110,34 @@
|
|||
|
||||
mapping = [self mapping];
|
||||
|
||||
// if (attMessage)
|
||||
attMessage = [self openEmbeddedMessage];
|
||||
if (attMessage)
|
||||
{
|
||||
*mid = [mapping idFromURL: [attMessage url]];
|
||||
[mapping registerURL: [attMessage url]
|
||||
withID: *mid];
|
||||
*messagePtr = attMessage;
|
||||
*mapistoreMsgPtr = mapistoreMsg;
|
||||
}
|
||||
|
||||
return (attMessage ? MAPISTORE_SUCCESS : MAPISTORE_ERROR);
|
||||
}
|
||||
|
||||
- (int) createEmbeddedMessage: (MAPIStoreEmbeddedMessage **) messagePtr
|
||||
withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
MAPIStoreEmbeddedMessage *attMessage;
|
||||
struct mapistore_message *mapistoreMsg;
|
||||
|
||||
mapistoreMsg = talloc_zero (memCtx, struct mapistore_message);
|
||||
attMessage = [self createEmbeddedMessage];
|
||||
if (attMessage)
|
||||
{
|
||||
*messagePtr = attMessage;
|
||||
*mapistoreMsgPtr = mapistoreMsg;
|
||||
}
|
||||
// else if (flags == MAPI_CREATE)
|
||||
// {
|
||||
// attMessage = [self createEmbeddedMessage];
|
||||
// if (attMessage)
|
||||
// [mapping registerURL: [attMessage url]
|
||||
// withID: *mid];
|
||||
// }
|
||||
|
||||
return (attMessage ? MAPISTORE_SUCCESS : MAPISTORE_ERROR);
|
||||
}
|
||||
|
@ -137,6 +158,30 @@
|
|||
return ULLONG_MAX;
|
||||
}
|
||||
|
||||
- (void) copyToAttachment: (MAPIStoreAttachment *) newAttachment
|
||||
{
|
||||
void *attachMethod;
|
||||
enum mapistore_error error;
|
||||
MAPIStoreEmbeddedMessage *embeddedMessage, *newEmbeddedMessage;
|
||||
|
||||
[self copyPropertiesToObject: newAttachment];
|
||||
|
||||
attachMethod = NULL;
|
||||
error = [self getProperty: &attachMethod
|
||||
withTag: PidTagAttachMethod
|
||||
inMemCtx: NULL];
|
||||
if (error == MAPISTORE_SUCCESS && attachMethod)
|
||||
{
|
||||
if (*(uint32_t *) attachMethod == afEmbeddedMessage)
|
||||
{
|
||||
embeddedMessage = [self openEmbeddedMessage];
|
||||
newEmbeddedMessage = [newAttachment createEmbeddedMessage];
|
||||
[embeddedMessage copyToMessage: newEmbeddedMessage];
|
||||
}
|
||||
talloc_free (attachMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/* subclasses */
|
||||
- (MAPIStoreEmbeddedMessage *) openEmbeddedMessage
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreAttachmentTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreAttachmentTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/* MAPIStoreAuthenticator.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreAuthenticator.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreCalendarAttachment.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -25,7 +25,15 @@
|
|||
|
||||
#import "MAPIStoreAttachment.h"
|
||||
|
||||
@interface MAPIStoreCalendarAttachment : MAPIStoreAttachment
|
||||
@class iCalEvent;
|
||||
|
||||
@interface MAPIStoreCalendarAttachment : MAPIStoreAttachment
|
||||
{
|
||||
iCalEvent *event;
|
||||
}
|
||||
|
||||
- (void) setEvent: (iCalEvent *) newEvent;
|
||||
- (iCalEvent *) event;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreCalendarAttachment.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -20,9 +20,22 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSTimeZone.h>
|
||||
|
||||
#import "MAPIStoreEmbeddedMessage.h"
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import "iCalEvent+MAPIStore.h"
|
||||
#import "MAPIStoreCalendarEmbeddedMessage.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "MAPIStoreUserContext.h"
|
||||
#import "NSDate+MAPIStore.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreCalendarAttachment.h"
|
||||
|
||||
|
@ -34,12 +47,42 @@
|
|||
|
||||
@implementation MAPIStoreCalendarAttachment
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
event = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[event release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setEvent: (iCalEvent *) newEvent
|
||||
{
|
||||
ASSIGN (event, newEvent);
|
||||
}
|
||||
|
||||
- (iCalEvent *) event
|
||||
{
|
||||
return event;
|
||||
}
|
||||
|
||||
- (NSString *) nameInContainer
|
||||
{
|
||||
return [[event uniqueChildWithTag: @"recurrence-id"]
|
||||
flattenedValuesForKey: @""];
|
||||
}
|
||||
|
||||
- (int) getPidTagAttachmentHidden: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) localMemCtx
|
||||
{
|
||||
*data = MAPIBoolValue (localMemCtx, YES);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
return [self getYes: data inMemCtx: localMemCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagAttachmentFlags: (void **) data
|
||||
|
@ -50,34 +93,69 @@
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagAttachmentLinkId: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) localMemCtx
|
||||
{
|
||||
return [self getLongZero: data inMemCtx: localMemCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagAttachFlags: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) localMemCtx
|
||||
{
|
||||
return [self getLongZero: data inMemCtx: localMemCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagAttachMethod: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) localMemCtx
|
||||
{
|
||||
*data = MAPILongValue (localMemCtx, 0x00000005); /* afEmbeddedMessage */
|
||||
*data = MAPILongValue (localMemCtx, afEmbeddedMessage);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
// case PidTagExceptionStartTime:
|
||||
// case PidTagExceptionEndTime:
|
||||
- (int) getPidTagAttachEncoding: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) localMemCtx
|
||||
{
|
||||
*data = [[NSData data] asBinaryInMemCtx: localMemCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagDisplayName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) localMemCtx
|
||||
{
|
||||
*data = "Untitled";
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagAttachmentContactPhoto: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getNo: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
// case PidTagExceptionReplaceTime:
|
||||
|
||||
/* subclasses */
|
||||
- (MAPIStoreEmbeddedMessage *) openEmbeddedMessage
|
||||
- (MAPIStoreCalendarEmbeddedMessage *) openEmbeddedMessage
|
||||
{
|
||||
MAPIStoreEmbeddedMessage *msg;
|
||||
MAPIStoreCalendarEmbeddedMessage *msg;
|
||||
|
||||
if (isNew)
|
||||
msg = nil;
|
||||
else
|
||||
msg = nil;
|
||||
msg = [MAPIStoreCalendarEmbeddedMessage
|
||||
mapiStoreObjectInContainer: self];
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
- (MAPIStoreEmbeddedMessage *) createEmbeddedMessage
|
||||
- (MAPIStoreCalendarEmbeddedMessage *) createEmbeddedMessage
|
||||
{
|
||||
return [MAPIStoreEmbeddedMessage embeddedMessageWithAttachment: self];
|
||||
MAPIStoreCalendarEmbeddedMessage *msg;
|
||||
|
||||
msg = [self openEmbeddedMessage];
|
||||
[msg setIsNew: YES];
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreCalendarContext.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreCalendarContext.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* MAPIStoreCalendarEmbeddedMessage.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2012 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 MAPISTORECALENDAREMBEDDEDMESSAGE_H
|
||||
#define MAPISTORECALENDAREMBEDDEDMESSAGE_H
|
||||
|
||||
#import "MAPIStoreEmbeddedMessage.h"
|
||||
|
||||
@class MAPIStoreAppointmentWrapper;
|
||||
|
||||
@interface MAPIStoreCalendarEmbeddedMessage : MAPIStoreEmbeddedMessage
|
||||
|
||||
@end
|
||||
|
||||
#endif /* MAPISTORECALENDAREMBEDDEDMESSAGE_H */
|
|
@ -0,0 +1,208 @@
|
|||
/* MAPIStoreCalendarEmbeddedMessage.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
#include <talloc.h>
|
||||
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import "iCalEvent+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreAppointmentWrapper.h"
|
||||
#import "MAPIStoreCalendarAttachment.h"
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreUserContext.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreCalendarEmbeddedMessage.h"
|
||||
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
@implementation MAPIStoreCalendarEmbeddedMessage
|
||||
|
||||
- (id) initInContainer: (id) newContainer
|
||||
{
|
||||
MAPIStoreContext *context;
|
||||
MAPIStoreUserContext *userContext;
|
||||
MAPIStoreAppointmentWrapper *appointmentWrapper;
|
||||
|
||||
if ((self = [super initInContainer: newContainer]))
|
||||
{
|
||||
context = [self context];
|
||||
userContext = [self userContext];
|
||||
appointmentWrapper
|
||||
= [MAPIStoreAppointmentWrapper
|
||||
wrapperWithICalEvent: [newContainer event]
|
||||
andUser: [userContext sogoUser]
|
||||
andSenderEmail: nil
|
||||
inTimeZone: [userContext timeZone]
|
||||
withConnectionInfo: [context connectionInfo]];
|
||||
[self addProxy: appointmentWrapper];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDate *) creationTime
|
||||
{
|
||||
return [[container event] created];
|
||||
}
|
||||
|
||||
- (NSDate *) lastModificationTime
|
||||
{
|
||||
return [[container event] lastModified];
|
||||
}
|
||||
|
||||
- (void) getMessageData: (struct mapistore_message **) dataPtr
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
struct mapistore_message *msgData;
|
||||
|
||||
[super getMessageData: &msgData inMemCtx: memCtx];
|
||||
|
||||
/* HACK: we know the first (and only) proxy is our appointment wrapper
|
||||
instance, but this might not always be true */
|
||||
[[proxies objectAtIndex: 0] fillMessageData: msgData
|
||||
inMemCtx: memCtx];
|
||||
*dataPtr = msgData;
|
||||
}
|
||||
|
||||
- (int) getPidTagMessageClass: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = talloc_strdup (memCtx, "IPM.OLE.CLASS.{00061055-0000-0000-C000-000000000046}");
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagMessageFlags: (void **) data // TODO
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPILongValue (memCtx, MSGFLAG_UNMODIFIED);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getYes: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagResponseRequested: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getYes: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
/* discarded properties */
|
||||
|
||||
- (int) getPidLidAppointmentLastSequence: (void **)
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidLidMeetingWorkspaceUrl: (void **)
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidLidContacts: (void **)
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagSensitivity: (void **)
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidLidPrivate: (void **)
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidNameKeywords: (void **)
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (void) save
|
||||
{
|
||||
// (gdb) po embeddedMessage->properties
|
||||
// 2442592320 = "2012-07-11 22:30:00 +0000";
|
||||
// 2448359488 = "2012-07-11 22:30:00 +0000";
|
||||
// 2442723392 = "2012-07-11 22:30:00 +0000";
|
||||
// 2442068032 = "2012-07-11 22:30:00 +0000";
|
||||
// 2441740352 = "2012-07-11 23:00:00 +0000";
|
||||
// 131083 = 1; 2442330115 = 2;
|
||||
// 235339779 = 9;
|
||||
// 6291520 = "2012-07-11 16:00:00 +0000";
|
||||
// 2442526784 = "2012-07-11 23:00:00 +0000";
|
||||
// 2818059 = 0;
|
||||
// 1703967 = "IPM.OLE.CLASS.{00061055-0000-0000-C000-000000000046}";
|
||||
// 3538947 = 0;
|
||||
// 1071513603 = 28591; 805830720 = "2012-07-10 16:42:00 +0000";
|
||||
// 2485977346 = <02013000 02001500 45006100 73007400
|
||||
// 65007200 6e002000 53007400 61006e00 64006100 72006400 20005400 69006d00
|
||||
// 65000200 02013e00 0000d607 00000000 00000000 00000000 00002c01 00000000
|
||||
// 0000c4ff ffff0000 0a000000 05000200 00000000 00000000 04000000 01000200
|
||||
// 00000000 00000201 3e000200 d7070000 00000000 00000000 00000000 2c010000
|
||||
// 00000000 c4ffffff 00000b00 00000100 02000000 00000000 00000300 00000200
|
||||
// 02000000 00000000>; 2454257728 = "2012-07-11 16:00:00 +0000"; 2442985475 =
|
||||
// 118330; 1507331 = 1; 805765184 = "2012-07-09 18:32:00 +0000"; 2442657856 =
|
||||
// "2012-07-11 23:00:00 +0000"; 2443051039 = "11.0"; 236912651 = 1; 2485911810 =
|
||||
// <02013000 02001500 45006100 73007400 65007200 6e002000 53007400 61006e00
|
||||
// 64006100 72006400 20005400 69006d00 65000200 02013e00 0000d607 00000000
|
||||
// 00000000 00000000 00002c01 00000000 0000c4ff ffff0000 0a000000 05000200
|
||||
// 00000000 00000000 04000000 01000200 00000000 00000201 3e000200 d7070000
|
||||
// 00000000 00000000 00000000 2c010000 00000000 c4ffffff 00000b00 00000100
|
||||
// 02000000 00000000 00000300 00000200 02000000 00000000>; 2441543683 = 30;
|
||||
// 2442068032 = "2012-07-11 22:30:00 +0000";
|
||||
// 1073348639 = "OpenChange User";
|
||||
// 806027522 = <2d64f6f5 89a59243 992d29d1 49173b3a>; 6357056 = "2012-07-11
|
||||
// 16:30:00 +0000";
|
||||
// */
|
||||
|
||||
// // 0x92490040 = 2454257728
|
||||
|
||||
// }
|
||||
|
||||
SOGoUser *activeUser;
|
||||
|
||||
activeUser = [[self context] activeUser];
|
||||
|
||||
[[container event] updateFromMAPIProperties: properties
|
||||
inUserContext: [self userContext]
|
||||
withActiveUser: activeUser];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreCalendarFolder.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreCalendarFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -35,6 +35,7 @@
|
|||
#import "MAPIStoreCalendarContext.h"
|
||||
#import "MAPIStoreCalendarMessage.h"
|
||||
#import "MAPIStoreCalendarMessageTable.h"
|
||||
#import "MAPIStoreUserContext.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreCalendarFolder.h"
|
||||
|
@ -67,6 +68,8 @@
|
|||
newEntry = [SOGoAppointmentObject objectWithName: name
|
||||
inContainer: sogoObject];
|
||||
[newEntry setIsNew: YES];
|
||||
/* the WOContext is required here for resolving notification pages */
|
||||
[newEntry setContext: [[self userContext] woContext]];
|
||||
newMessage = [MAPIStoreCalendarMessage mapiStoreObjectWithSOGoObject: newEntry
|
||||
inContainer: self];
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreCalendarMessage.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -25,11 +25,14 @@
|
|||
|
||||
#import "MAPIStoreGCSMessage.h"
|
||||
|
||||
@class iCalCalendar;
|
||||
@class iCalEvent;
|
||||
@class MAPIStoreAppointmentWrapper;
|
||||
|
||||
@interface MAPIStoreCalendarMessage : MAPIStoreGCSMessage
|
||||
{
|
||||
MAPIStoreAppointmentWrapper *appointmentWrapper;
|
||||
iCalCalendar *calendar;
|
||||
iCalEvent *masterEvent;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreCalendarMessageTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreCalendarMessageTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContactsAttachment.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContactsAttachment.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContactsContext.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContactsContext.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContactsFolder.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContactsFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContactsMessage.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContactsMessage.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
@ -35,6 +35,7 @@
|
|||
#import <Mailer/NSString+Mail.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
|
||||
#import "MAPIStoreAttachment.h"
|
||||
#import "MAPIStoreContactsAttachment.h"
|
||||
#import "MAPIStoreContactsFolder.h"
|
||||
#import "MAPIStorePropertySelectors.h"
|
||||
|
@ -109,6 +110,28 @@
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagAlternateRecipientAllowed: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
|
||||
{
|
||||
return [self getYes: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagMessageFlags: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPILongValue (memCtx, MSGFLAG_READ);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagDeleteAfterSubmit: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
|
||||
{
|
||||
return [self getNo: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagMessageClass: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -179,8 +202,8 @@
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagSubject: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
- (int) getPidTagNormalizedSubject: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidTagDisplayName: data inMemCtx: memCtx];
|
||||
}
|
||||
|
@ -188,13 +211,34 @@
|
|||
- (int) getPidLidFileUnder: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidTagDisplayName: data inMemCtx: memCtx];
|
||||
NSString *surName, *givenName, *middleName;
|
||||
NSMutableString *fileUnder;
|
||||
CardElement *n;
|
||||
|
||||
n = [[sogoObject vCard] n];
|
||||
surName = [n flattenedValueAtIndex: 0
|
||||
forKey: @""];
|
||||
fileUnder = [surName mutableCopy];
|
||||
[fileUnder autorelease];
|
||||
[fileUnder appendString: @","];
|
||||
givenName = [n flattenedValueAtIndex: 1
|
||||
forKey: @""];
|
||||
if ([givenName length] > 0)
|
||||
[fileUnder appendFormat: @" %@", givenName];
|
||||
middleName = [n flattenedValueAtIndex: 2
|
||||
forKey: @""];
|
||||
if ([middleName length] > 0)
|
||||
[fileUnder appendFormat: @" %@", middleName];
|
||||
|
||||
*data = [fileUnder asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidLidFileUnderId: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPILongValue (memCtx, 0xffffffff);
|
||||
*data = MAPILongValue (memCtx, 0x00008017); /* what ol2003 sets */
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -208,7 +252,7 @@
|
|||
vCard = [sogoObject vCard];
|
||||
fn = [vCard fn];
|
||||
email = [vCard preferredEMail];
|
||||
*data = [[NSString stringWithFormat: @"%@ <%@>", fn, email]
|
||||
*data = [[NSString stringWithFormat: @"%@ (%@)", fn, email]
|
||||
asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
|
@ -217,7 +261,8 @@
|
|||
- (int) getPidLidEmail1OriginalDisplayName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidLidEmail1DisplayName: data inMemCtx: memCtx];
|
||||
return [self getPidLidEmail1EmailAddress: data
|
||||
inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidLidEmail1EmailAddress: (void **) data
|
||||
|
@ -767,8 +812,7 @@
|
|||
|| [encoding isEqualToString: @"BASE64"])
|
||||
{
|
||||
attachment = [MAPIStoreContactsAttachment
|
||||
mapiStoreObjectWithSOGoObject: nil
|
||||
inContainer: self];
|
||||
mapiStoreObjectInContainer: self];
|
||||
[attachment setAID: 0];
|
||||
[attachment setPhoto: photo];
|
||||
[attachmentParts setObject: attachment forKey: @"photo"];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContactsMessageTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContactsMessageTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -74,10 +74,12 @@ static Class MAPIStoreContactsMessageK, NGMailAddressK, NSDataK, NSStringK;
|
|||
forKey: MAPIPropertyKey (PidLidEmail2EmailAddress)];
|
||||
[knownProperties setObject: @"c_mail"
|
||||
forKey: MAPIPropertyKey (PidLidEmail3EmailAddress)];
|
||||
[knownProperties setObject: @"c_cn"
|
||||
forKey: MAPIPropertyKey (PR_DISPLAY_NAME_UNICODE)];
|
||||
[knownProperties setObject: @"c_cn"
|
||||
forKey: MAPIPropertyKey (PidLidFileUnder)];
|
||||
[knownProperties setObject: @"c_cn"
|
||||
forKey: MAPIPropertyKey (PidTagDisplayName)];
|
||||
[knownProperties setObject: @"c_cn"
|
||||
forKey: MAPIPropertyKey (PidTagSubject)];
|
||||
}
|
||||
|
||||
return [knownProperties objectForKey: MAPIPropertyKey (property)];
|
||||
|
@ -213,7 +215,11 @@ static Class MAPIStoreContactsMessageK, NGMailAddressK, NSDataK, NSStringK;
|
|||
[knownProperties setObject: @"c_cn"
|
||||
forKey: MAPIPropertyKey (PidLidFileUnder)];
|
||||
[knownProperties setObject: @"c_cn"
|
||||
forKey: MAPIPropertyKey (PR_DISPLAY_NAME_UNICODE)];
|
||||
forKey: MAPIPropertyKey (PidTagDisplayName)];
|
||||
[knownProperties setObject: @"c_cn"
|
||||
forKey: MAPIPropertyKey (PidTagSubject)];
|
||||
[knownProperties setObject: @"c_cn"
|
||||
forKey: MAPIPropertyKey (PidTagNormalizedSubject)];
|
||||
}
|
||||
|
||||
return [knownProperties objectForKey: MAPIPropertyKey (property)];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContext.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreContext.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -28,11 +28,9 @@
|
|||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import <SOGo/SOGoFolder.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
|
||||
#import "SOGoMAPIFSFolder.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
|
||||
#import "MAPIStoreAttachment.h"
|
||||
// #import "MAPIStoreAttachmentTable.h"
|
||||
#import "MAPIStoreFallbackContext.h"
|
||||
|
@ -294,9 +292,11 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
|
|||
[MAPIStoreUserContext userContextWithUsername: username
|
||||
andTDBIndexing: indexingTdb]);
|
||||
|
||||
#if 0
|
||||
mapistore_mgmt_backend_register_user (newConnInfo,
|
||||
"SOGo",
|
||||
[username UTF8String]);
|
||||
#endif
|
||||
|
||||
connInfo = newConnInfo;
|
||||
username = [NSString stringWithUTF8String: newConnInfo->username];
|
||||
|
@ -315,9 +315,12 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
#if 0
|
||||
mapistore_mgmt_backend_unregister_user ([self connectionInfo], "SOGo",
|
||||
[[userContext username]
|
||||
UTF8String]);
|
||||
#endif
|
||||
|
||||
[contextUrl release];
|
||||
[userContext release];
|
||||
[containersBag release];
|
||||
|
@ -363,7 +366,8 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
|
|||
NSString *objectURL, *url;
|
||||
// TDB_DATA key, dbuf;
|
||||
|
||||
url = [contextUrl absoluteString];
|
||||
url = [[contextUrl absoluteString]
|
||||
stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
|
||||
objectURL = [[userContext mapping] urlFromID: fmid];
|
||||
if (objectURL)
|
||||
{
|
||||
|
@ -414,39 +418,46 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
|
|||
MAPIStoreFolder *baseFolder;
|
||||
SOGoFolder *currentFolder;
|
||||
WOContext *woContext;
|
||||
NSString *path;
|
||||
NSString *path, *urlString;
|
||||
NSArray *pathComponents;
|
||||
NSUInteger count, max;
|
||||
|
||||
mapping = [userContext mapping];
|
||||
if (![mapping urlFromID: newFid])
|
||||
[mapping registerURL: [contextUrl absoluteString]
|
||||
withID: newFid];
|
||||
|
||||
{
|
||||
urlString = [[contextUrl absoluteString]
|
||||
stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
|
||||
[mapping registerURL: urlString
|
||||
withID: newFid];
|
||||
}
|
||||
[userContext activateWithUser: activeUser];
|
||||
woContext = [userContext woContext];
|
||||
|
||||
[self ensureContextFolder];
|
||||
currentFolder = [self rootSOGoFolder];
|
||||
[containersBag addObject: currentFolder];
|
||||
path = [contextUrl path];
|
||||
if ([path hasPrefix: @"/"])
|
||||
path = [path substringFromIndex: 1];
|
||||
if ([path hasSuffix: @"/"])
|
||||
path = [path substringToIndex: [path length] - 1];
|
||||
pathComponents = [path componentsSeparatedByString: @"/"];
|
||||
max = [pathComponents count];
|
||||
for (count = 0; currentFolder && count < max; count++)
|
||||
if ([path length] > 0)
|
||||
{
|
||||
[woContext setClientObject: currentFolder];
|
||||
currentFolder
|
||||
= [currentFolder lookupName: [pathComponents objectAtIndex: count]
|
||||
inContext: woContext
|
||||
pathComponents = [path componentsSeparatedByString: @"/"];
|
||||
max = [pathComponents count];
|
||||
for (count = 0; currentFolder && count < max; count++)
|
||||
{
|
||||
[woContext setClientObject: currentFolder];
|
||||
currentFolder = [currentFolder
|
||||
lookupName: [pathComponents objectAtIndex: count]
|
||||
inContext: woContext
|
||||
acquire: NO];
|
||||
if ([currentFolder isKindOfClass: SOGoObjectK]) /* class common to all
|
||||
SOGo folder types */
|
||||
[containersBag addObject: currentFolder];
|
||||
else
|
||||
currentFolder = nil;
|
||||
if ([currentFolder isKindOfClass: SOGoObjectK]) /* class common to all
|
||||
SOGo folder types */
|
||||
[containersBag addObject: currentFolder];
|
||||
else
|
||||
currentFolder = nil;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentFolder)
|
||||
|
@ -455,7 +466,6 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri)
|
|||
mapiStoreObjectWithSOGoObject: currentFolder
|
||||
inContainer: nil];
|
||||
[baseFolder setContext: self];
|
||||
|
||||
*folderPtr = baseFolder;
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFSBaseContext.h - this file is part of SOGo
|
||||
/* MAPIStoreDBBaseContext.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -20,13 +20,13 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef MAPISTOREFSBASECONTEXT_H
|
||||
#define MAPISTOREFSBASECONTEXT_H
|
||||
#ifndef MAPISTOREDBBASECONTEXT_H
|
||||
#define MAPISTOREDBBASECONTEXT_H
|
||||
|
||||
#import "MAPIStoreContext.h"
|
||||
|
||||
@interface MAPIStoreFSBaseContext : MAPIStoreContext
|
||||
@interface MAPIStoreDBBaseContext : MAPIStoreContext
|
||||
|
||||
@end
|
||||
|
||||
#endif /* MAPISTOREFSBASECONTEXT_H */
|
||||
#endif /* MAPISTOREDBBASECONTEXT_H */
|
|
@ -0,0 +1,116 @@
|
|||
/* MAPIStoreDBBaseContext.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2012 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 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* A generic parent class for all context that will store their data on the
|
||||
disk in the form of a plist. */
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import "MAPIStoreDBFolder.h"
|
||||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreUserContext.h"
|
||||
#import "SOGoMAPIDBFolder.h"
|
||||
|
||||
#import "MAPIStoreDBBaseContext.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
static Class MAPIStoreDBFolderK;
|
||||
|
||||
@implementation MAPIStoreDBBaseContext
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
MAPIStoreDBFolderK = [MAPIStoreDBFolder class];
|
||||
}
|
||||
|
||||
+ (NSString *) MAPIModuleName
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (Class) MAPIStoreFolderClass
|
||||
{
|
||||
return MAPIStoreDBFolderK;
|
||||
}
|
||||
|
||||
- (void) ensureContextFolder
|
||||
{
|
||||
SOGoMAPIDBFolder *currentFolder;
|
||||
NSArray *parts;
|
||||
NSMutableArray *folders;
|
||||
NSString *folderName;
|
||||
NSUInteger count, max;
|
||||
|
||||
parts = [[contextUrl path] componentsSeparatedByString: @"/"];
|
||||
max = [parts count];
|
||||
folders = [NSMutableArray arrayWithCapacity: max];
|
||||
|
||||
/* build the folder chain */
|
||||
currentFolder = [self rootSOGoFolder];
|
||||
[folders addObject: currentFolder];
|
||||
for (count = 1; count < max; count++)
|
||||
{
|
||||
folderName = [parts objectAtIndex: count];
|
||||
if ([folderName length] > 0)
|
||||
{
|
||||
currentFolder = [SOGoMAPIDBFolder objectWithName: folderName
|
||||
inContainer: currentFolder];
|
||||
[folders addObject: currentFolder];
|
||||
}
|
||||
}
|
||||
|
||||
/* ensure each folder in the chain actually exists, so that it becomes
|
||||
"listable" in further operations */
|
||||
max = [folders count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentFolder = [folders objectAtIndex: count];
|
||||
[currentFolder reloadIfNeeded];
|
||||
if ([currentFolder isNew])
|
||||
[currentFolder save];
|
||||
}
|
||||
}
|
||||
|
||||
- (id) rootSOGoFolder
|
||||
{
|
||||
SOGoMAPIDBFolder *folder;
|
||||
|
||||
[userContext ensureFolderTableExists];
|
||||
|
||||
folder = [SOGoMAPIDBFolder objectWithName: [isa MAPIModuleName]
|
||||
inContainer: nil];
|
||||
[folder setTableUrl: [userContext folderTableURL]];
|
||||
// [folder reloadIfNeeded];
|
||||
|
||||
/* we don't need to set the "path prefix" of the folder since the module
|
||||
name is used as the label for the top folder */
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFSFolder.h - this file is part of SOGo
|
||||
/* MAPIStoreDBFolder.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -20,14 +20,14 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef MAPISTOREFSFOLDER_H
|
||||
#define MAPISTOREFSFOLDER_H
|
||||
#ifndef MAPISTOREDBFOLDER_H
|
||||
#define MAPISTOREDBFOLDER_H
|
||||
|
||||
#import "MAPIStoreFolder.h"
|
||||
|
||||
@interface MAPIStoreFSFolder : MAPIStoreFolder
|
||||
@interface MAPIStoreDBFolder : MAPIStoreFolder
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#endif /* MAPISTOREFSFOLDER_H */
|
||||
#endif /* MAPISTOREDBFOLDER_H */
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFSFolder.m - this file is part of SOGo
|
||||
/* MAPIStoreDBFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -24,28 +24,32 @@
|
|||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <SOGo/SOGoFolder.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import "EOQualifier+MAPI.h"
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreFSFolderTable.h"
|
||||
#import "MAPIStoreFSMessage.h"
|
||||
#import "MAPIStoreFSMessageTable.h"
|
||||
#import "MAPIStoreDBFolderTable.h"
|
||||
#import "MAPIStoreDBMessage.h"
|
||||
#import "MAPIStoreDBMessageTable.h"
|
||||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "MAPIStoreUserContext.h"
|
||||
#import "SOGoMAPIFSFolder.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
#import "SOGoMAPIDBFolder.h"
|
||||
#import "SOGoMAPIDBMessage.h"
|
||||
|
||||
#import "MAPIStoreFSFolder.h"
|
||||
#import "MAPIStoreDBFolder.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
static Class EOKeyValueQualifierK;
|
||||
static Class EOKeyValueQualifierK, SOGoMAPIDBFolderK, MAPIStoreDBFolderK;
|
||||
|
||||
static NSString *MAPIStoreRightReadItems = @"RightsReadItems";
|
||||
static NSString *MAPIStoreRightCreateItems = @"RightsCreateItems";
|
||||
|
@ -57,54 +61,127 @@ static NSString *MAPIStoreRightCreateSubfolders = @"RightsCreateSubfolders";
|
|||
static NSString *MAPIStoreRightFolderOwner = @"RightsFolderOwner";
|
||||
static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
|
||||
|
||||
@implementation MAPIStoreFSFolder
|
||||
@implementation MAPIStoreDBFolder
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
EOKeyValueQualifierK = [EOKeyValueQualifier class];
|
||||
SOGoMAPIDBFolderK = [SOGoMAPIDBFolder class];
|
||||
MAPIStoreDBFolderK = [MAPIStoreDBFolder class];
|
||||
}
|
||||
|
||||
- (void) setupAuxiliaryObjects
|
||||
{
|
||||
[super setupAuxiliaryObjects];
|
||||
ASSIGN (sogoObject, dbFolder);
|
||||
}
|
||||
|
||||
- (MAPIStoreMessageTable *) messageTable
|
||||
{
|
||||
return [MAPIStoreFSMessageTable tableForContainer: self];
|
||||
return [MAPIStoreDBMessageTable tableForContainer: self];
|
||||
}
|
||||
|
||||
- (MAPIStoreFolderTable *) folderTable
|
||||
{
|
||||
return [MAPIStoreFSFolderTable tableForContainer: self];
|
||||
return [MAPIStoreDBFolderTable tableForContainer: self];
|
||||
}
|
||||
|
||||
- (enum mapistore_error) createFolder: (struct SRow *) aRow
|
||||
withFID: (uint64_t) newFID
|
||||
andKey: (NSString **) newKeyP
|
||||
{
|
||||
NSString *newKey, *urlString;
|
||||
NSURL *childURL;
|
||||
SOGoMAPIFSFolder *childFolder;
|
||||
enum mapistore_error rc;
|
||||
NSString *folderName, *nameInContainer;
|
||||
SOGoMAPIDBFolder *newFolder;
|
||||
struct SPropValue *value;
|
||||
|
||||
newKey = [NSString stringWithFormat: @"0x%.16"PRIx64, (unsigned long long) newFID];
|
||||
value = get_SPropValue_SRow (aRow, PidTagDisplayName);
|
||||
if (value)
|
||||
folderName = [NSString stringWithUTF8String: value->value.lpszW];
|
||||
else
|
||||
{
|
||||
value = get_SPropValue_SRow (aRow, PidTagDisplayName_string8);
|
||||
if (value)
|
||||
folderName = [NSString stringWithUTF8String: value->value.lpszA];
|
||||
else
|
||||
folderName = nil;
|
||||
}
|
||||
|
||||
urlString = [NSString stringWithFormat: @"%@/%@", [self url], newKey];
|
||||
childURL = [NSURL URLWithString: [urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
|
||||
childFolder = [SOGoMAPIFSFolder folderWithURL: childURL
|
||||
andTableType: MAPISTORE_MESSAGE_TABLE];
|
||||
[childFolder ensureDirectory];
|
||||
*newKeyP = newKey;
|
||||
if (folderName)
|
||||
{
|
||||
nameInContainer = [NSString stringWithFormat: @"0x%.16"PRIx64,
|
||||
(unsigned long long) newFID];
|
||||
newFolder = [SOGoMAPIDBFolderK objectWithName: nameInContainer
|
||||
inContainer: sogoObject];
|
||||
[newFolder reloadIfNeeded];
|
||||
[[newFolder properties] setObject: folderName
|
||||
forKey: MAPIPropertyKey (PidTagDisplayName)];
|
||||
[newFolder save];
|
||||
*newKeyP = nameInContainer;
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_INVALID_PARAMETER;
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (enum mapistore_error) moveCopyToFolder: (MAPIStoreFolder *) targetFolder
|
||||
withNewName: (NSString *) newFolderName
|
||||
isMove: (BOOL) isMove
|
||||
isRecursive: (BOOL) isRecursive
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
NSString *path, *pathComponent, *targetPath, *newPath;
|
||||
NSString *newURL;
|
||||
MAPIStoreMapping *mapping;
|
||||
NSRange slashRange;
|
||||
|
||||
if (isMove && [targetFolder isKindOfClass: MAPIStoreDBFolderK])
|
||||
{
|
||||
path = [sogoObject path];
|
||||
slashRange = [path rangeOfString: @"/" options: NSBackwardsSearch];
|
||||
if (slashRange.location == NSNotFound)
|
||||
[NSException raise: @"MAPIStoreIOException"
|
||||
format: @"db folder path must start with a '/'"];
|
||||
else
|
||||
pathComponent = [path substringFromIndex: slashRange.location + 1];
|
||||
targetPath = [[targetFolder sogoObject] path];
|
||||
newPath = [NSString stringWithFormat: @"%@/%@",
|
||||
targetPath, pathComponent];
|
||||
[dbFolder changePathTo: newPath];
|
||||
|
||||
mapping = [self mapping];
|
||||
newURL = [NSString stringWithFormat: @"%@%@/",
|
||||
[targetFolder url], pathComponent];
|
||||
[mapping updateID: [self objectId]
|
||||
withURL: newURL];
|
||||
|
||||
[targetFolder cleanupCaches];
|
||||
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
rc = [super moveCopyToFolder: targetFolder withNewName: newFolderName
|
||||
isMove: isMove
|
||||
isRecursive: isRecursive];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (MAPIStoreMessage *) createMessage
|
||||
{
|
||||
MAPIStoreMessage *newMessage;
|
||||
SOGoMAPIFSMessage *fsObject;
|
||||
SOGoMAPIDBMessage *fsObject;
|
||||
NSString *newKey;
|
||||
|
||||
newKey = [NSString stringWithFormat: @"%@.plist",
|
||||
[SOGoObject globallyUniqueObjectId]];
|
||||
fsObject = [SOGoMAPIFSMessage objectWithName: newKey
|
||||
fsObject = [SOGoMAPIDBMessage objectWithName: newKey
|
||||
inContainer: sogoObject];
|
||||
newMessage = [MAPIStoreFSMessage mapiStoreObjectWithSOGoObject: fsObject
|
||||
[fsObject setObjectType: MAPIDBObjectTypeMessage];
|
||||
[fsObject reloadIfNeeded];
|
||||
newMessage = [MAPIStoreDBMessage mapiStoreObjectWithSOGoObject: fsObject
|
||||
inContainer: self];
|
||||
|
||||
return newMessage;
|
||||
|
@ -119,9 +196,10 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
|
|||
ownerUser = [[self userContext] sogoUser];
|
||||
if ([[context activeUser] isEqual: ownerUser]
|
||||
|| [self subscriberCanReadMessages])
|
||||
keys = [(SOGoMAPIFSFolder *) sogoObject
|
||||
toOneRelationshipKeysMatchingQualifier: qualifier
|
||||
andSortOrderings: sortOrderings];
|
||||
keys = [(SOGoMAPIDBFolder *) sogoObject childKeysOfType: MAPIDBObjectTypeMessage
|
||||
includeDeleted: NO
|
||||
matchingQualifier: qualifier
|
||||
andSortOrderings: sortOrderings];
|
||||
else
|
||||
keys = [NSArray array];
|
||||
|
||||
|
@ -131,39 +209,26 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
|
|||
- (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier
|
||||
andSortOrderings: (NSArray *) sortOrderings
|
||||
{
|
||||
NSArray *entries;
|
||||
NSMutableArray *filteredEntries;
|
||||
NSUInteger count, max;
|
||||
MAPIStoreFSFolder *subfolder;
|
||||
SOGoMAPIFSMessage *propertiesMessage;
|
||||
NSString *subfolderKey;
|
||||
|
||||
entries = [(SOGoMAPIFSFolder *) sogoObject toManyRelationshipKeys];
|
||||
if (qualifier)
|
||||
{
|
||||
max = [entries count];
|
||||
filteredEntries = [NSMutableArray arrayWithCapacity: max];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
subfolderKey = [entries objectAtIndex: count];
|
||||
subfolder = [self lookupFolder: subfolderKey];
|
||||
propertiesMessage = [subfolder propertiesMessage];
|
||||
if ([qualifier evaluateMAPIVolatileMessage: propertiesMessage])
|
||||
[filteredEntries addObject: subfolderKey];
|
||||
}
|
||||
entries = filteredEntries;
|
||||
}
|
||||
if (sortOrderings)
|
||||
[self errorWithFormat: @"sort orderings are not used for folders"];
|
||||
|
||||
return entries;
|
||||
return [dbFolder childKeysOfType: MAPIDBObjectTypeFolder
|
||||
includeDeleted: NO
|
||||
matchingQualifier: qualifier
|
||||
andSortOrderings: sortOrderings];
|
||||
}
|
||||
|
||||
/* TODO: now that we are DB-based, this method can easily be implemented
|
||||
|
||||
- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum
|
||||
andCN: (NSNumber **) cnNbrs
|
||||
inTableType: (enum mapistore_table_type) tableType
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
- (NSDate *) lastMessageModificationTime
|
||||
{
|
||||
NSUInteger count, max;
|
||||
NSDate *date, *fileDate;
|
||||
MAPIStoreFSMessage *msg;
|
||||
MAPIStoreDBMessage *msg;
|
||||
NSArray *messageKeys;
|
||||
|
||||
messageKeys = [self messageKeys];
|
||||
|
@ -189,7 +254,7 @@ static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact";
|
|||
|
||||
- (SOGoFolder *) aclFolder
|
||||
{
|
||||
return propsFolder;
|
||||
return sogoObject;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFSFolderTable.h - this file is part of SOGo
|
||||
/* MAPIStoreDBFolderTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -20,12 +20,12 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef MAPISTOREFSFOLDERTABLE_H
|
||||
#define MAPISTOREFSFOLDERTABLE_H
|
||||
#ifndef MAPISTOREDBFOLDERTABLE_H
|
||||
#define MAPISTOREDBFOLDERTABLE_H
|
||||
|
||||
#import "MAPIStoreFolderTable.h"
|
||||
|
||||
@interface MAPIStoreFSFolderTable : MAPIStoreFolderTable
|
||||
@interface MAPIStoreDBFolderTable : MAPIStoreFolderTable
|
||||
@end
|
||||
|
||||
#endif /* MAPISTOREFSFOLDERTABLE_H */
|
||||
#endif /* MAPISTOREDBFOLDERTABLE_H */
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFSFolderTable.m - this file is part of SOGo
|
||||
/* MAPIStoreDBFolderTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -24,9 +24,9 @@
|
|||
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
||||
#import "MAPIStoreFSFolderTable.h"
|
||||
#import "MAPIStoreDBFolderTable.h"
|
||||
|
||||
@implementation MAPIStoreFSFolderTable
|
||||
@implementation MAPIStoreDBFolderTable
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFSMessage.h - this file is part of SOGo
|
||||
/* MAPIStoreDBMessage.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -20,12 +20,12 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef MAPISTOREFSMESSAGE_H
|
||||
#define MAPISTOREFSMESSAGE_H
|
||||
#ifndef MAPISTOREDBMESSAGE_H
|
||||
#define MAPISTOREDBMESSAGE_H
|
||||
|
||||
#import "MAPIStoreVolatileMessage.h"
|
||||
#import "MAPIStoreMessage.h"
|
||||
|
||||
@interface MAPIStoreFSMessage : MAPIStoreVolatileMessage
|
||||
@interface MAPIStoreDBMessage : MAPIStoreMessage
|
||||
@end
|
||||
|
||||
#endif /* MAPISTOREFSMESSAGE_H */
|
||||
#endif /* MAPISTOREDBMESSAGE_H */
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFSMessage.m - this file is part of SOGo
|
||||
/* MAPIStoreDBMessage.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -21,24 +21,25 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStorePropertySelectors.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
#import "SOGoMAPIDBMessage.h"
|
||||
|
||||
#import "MAPIStoreFSFolder.h"
|
||||
#import "MAPIStoreFSMessage.h"
|
||||
#import "MAPIStoreDBFolder.h"
|
||||
#import "MAPIStoreDBMessage.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
@implementation MAPIStoreFSMessage
|
||||
@implementation MAPIStoreDBMessage
|
||||
|
||||
+ (int) getAvailableProperties: (struct SPropTagArray **) propertiesP
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
|
@ -60,13 +61,79 @@
|
|||
/* FIXME (hack): append a few undocumented properties that can be added to
|
||||
FAI messages */
|
||||
for (count = 0; count < 8; count++)
|
||||
properties->aulPropTag[MAPIStoreSupportedPropertiesCount+count] = faiProperties[count];
|
||||
properties->aulPropTag[MAPIStoreSupportedPropertiesCount+count]
|
||||
= faiProperties[count];
|
||||
|
||||
*propertiesP = properties;
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (id) initWithSOGoObject: (id) newSOGoObject
|
||||
inContainer: (MAPIStoreObject *) newContainer
|
||||
{
|
||||
if ((self = [super initWithSOGoObject: newSOGoObject
|
||||
inContainer: newContainer]))
|
||||
{
|
||||
[properties release];
|
||||
properties = [newSOGoObject properties];
|
||||
[properties retain];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (uint64_t) objectVersion
|
||||
{
|
||||
NSNumber *versionNbr;
|
||||
uint64_t objectVersion;
|
||||
|
||||
[(SOGoMAPIDBMessage *) sogoObject reloadIfNeeded];
|
||||
versionNbr = [properties objectForKey: @"version"];
|
||||
if (versionNbr)
|
||||
objectVersion = [versionNbr unsignedLongLongValue] >> 16;
|
||||
else
|
||||
objectVersion = ULLONG_MAX;
|
||||
|
||||
return objectVersion;
|
||||
}
|
||||
|
||||
- (int) getProperties: (struct mapistore_property_data *) data
|
||||
withTags: (enum MAPITAGS *) tags
|
||||
andCount: (uint16_t) columnCount
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
[sogoObject reloadIfNeeded];
|
||||
|
||||
return [super getProperties: data
|
||||
withTags: tags
|
||||
andCount: columnCount
|
||||
inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getProperty: (void **) data
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
id value;
|
||||
int rc;
|
||||
|
||||
value = [properties objectForKey: MAPIPropertyKey (propTag)];
|
||||
if (value)
|
||||
rc = [value getValue: data forTag: propTag inMemCtx: memCtx];
|
||||
else
|
||||
rc = [super getProperty: data withTag: propTag inMemCtx: memCtx];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (void) addProperties: (NSDictionary *) newNewProperties
|
||||
{
|
||||
[sogoObject reloadIfNeeded];
|
||||
|
||||
[super addProperties: newNewProperties];
|
||||
}
|
||||
|
||||
- (void) save
|
||||
{
|
||||
uint64_t newVersion;
|
||||
|
@ -74,15 +141,13 @@
|
|||
if ([attachmentKeys count] > 0)
|
||||
[properties setObject: attachmentParts forKey: @"attachments"];
|
||||
|
||||
newVersion = exchange_globcnt ([[self context] getNewChangeNumber] >> 16);
|
||||
newVersion = [[self context] getNewChangeNumber];
|
||||
[properties setObject: [NSNumber numberWithUnsignedLongLong: newVersion]
|
||||
forKey: @"version"];
|
||||
forKey: @"version"];
|
||||
|
||||
[self logWithFormat: @"%d props in dict", [properties count]];
|
||||
|
||||
[sogoObject appendProperties: properties];
|
||||
[sogoObject save];
|
||||
[properties removeAllObjects];
|
||||
}
|
||||
|
||||
- (BOOL) _messageIsFreeBusy
|
||||
|
@ -91,7 +156,7 @@
|
|||
|
||||
/* This is a HACK until we figure out how to determine a message position in
|
||||
the mailbox hierarchy.... (missing: folderid and role) */
|
||||
msgClass = [[sogoObject properties]
|
||||
msgClass = [properties
|
||||
objectForKey: MAPIPropertyKey (PR_MESSAGE_CLASS_UNICODE)];
|
||||
|
||||
return [msgClass isEqualToString: @"IPM.Microsoft.ScheduleData.FreeBusy"];
|
||||
|
@ -115,12 +180,12 @@
|
|||
|
||||
- (NSDate *) creationTime
|
||||
{
|
||||
return [sogoObject creationTime];
|
||||
return [sogoObject creationDate];
|
||||
}
|
||||
|
||||
- (NSDate *) lastModificationTime
|
||||
{
|
||||
return [sogoObject lastModificationTime];
|
||||
return [sogoObject lastModified];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFSMessageTable.h - this file is part of SOGo
|
||||
/* MAPIStoreDBMessageTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -20,12 +20,12 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef MAPISTOREFSMESSAGETABLE_H
|
||||
#define MAPISTOREFSMESSAGETABLE_H
|
||||
#ifndef MAPISTOREDBMESSAGETABLE_H
|
||||
#define MAPISTOREDBMESSAGETABLE_H
|
||||
|
||||
#import "MAPIStoreMessageTable.h"
|
||||
|
||||
@interface MAPIStoreFSMessageTable : MAPIStoreMessageTable
|
||||
@interface MAPIStoreDBMessageTable : MAPIStoreMessageTable
|
||||
@end
|
||||
|
||||
#endif /* MAPISTOREFSMESSAGETABLE_H */
|
||||
#endif /* MAPISTOREDBMESSAGETABLE_H */
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFSMessageTable.m - this file is part of SOGo
|
||||
/* MAPIStoreDBMessageTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -25,25 +25,25 @@
|
|||
#import <EOControl/EOQualifier.h>
|
||||
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "MAPIStoreFSMessage.h"
|
||||
#import "MAPIStoreDBMessage.h"
|
||||
|
||||
#import "MAPIStoreFSMessageTable.h"
|
||||
#import "MAPIStoreDBMessageTable.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
static Class MAPIStoreFSMessageK = Nil;
|
||||
static Class MAPIStoreDBMessageK = Nil;
|
||||
|
||||
@implementation MAPIStoreFSMessageTable
|
||||
@implementation MAPIStoreDBMessageTable
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
MAPIStoreFSMessageK = [MAPIStoreFSMessage class];
|
||||
MAPIStoreDBMessageK = [MAPIStoreDBMessage class];
|
||||
}
|
||||
|
||||
+ (Class) childObjectClass
|
||||
{
|
||||
return MAPIStoreFSMessageK;
|
||||
return MAPIStoreDBMessageK;
|
||||
}
|
||||
|
||||
- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreEmbeddedMessage.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -26,13 +26,6 @@
|
|||
#import "MAPIStoreMessage.h"
|
||||
|
||||
@interface MAPIStoreEmbeddedMessage : MAPIStoreMessage
|
||||
{
|
||||
id attachment;
|
||||
}
|
||||
|
||||
+ (id) embeddedMessageWithAttachment: (id) newAttachment;
|
||||
|
||||
- (id) initWithAttachment: (id) newAttachment;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreEmbeddedMessage.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -23,9 +23,13 @@
|
|||
#import <Foundation/NSString.h>
|
||||
|
||||
#import "MAPIStoreAttachment.h"
|
||||
#import "MAPIStoreFolder.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreEmbeddedMessage.h"
|
||||
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
static Class MAPIStoreAttachmentK;
|
||||
|
||||
@implementation MAPIStoreEmbeddedMessage
|
||||
|
@ -35,30 +39,116 @@ static Class MAPIStoreAttachmentK;
|
|||
MAPIStoreAttachmentK = [MAPIStoreAttachment class];
|
||||
}
|
||||
|
||||
+ (id) embeddedMessageWithAttachment: (id) newAttachment
|
||||
- (uint64_t) objectId
|
||||
{
|
||||
MAPIStoreEmbeddedMessage *newMessage;
|
||||
NSString *objectKey;
|
||||
MAPIStoreMessage *grandParent;
|
||||
|
||||
newMessage = [[self alloc] initWithAttachment: newAttachment];
|
||||
[newMessage autorelease];
|
||||
grandParent = (MAPIStoreMessage *) [container container];
|
||||
|
||||
return newMessage;
|
||||
/* FIXME: this is a hack */
|
||||
objectKey = [NSString stringWithFormat: @"%@/%@/as-message",
|
||||
[grandParent nameInContainer],
|
||||
[container nameInContainer],
|
||||
[self nameInContainer]];
|
||||
|
||||
return [(MAPIStoreFolder *) [grandParent container]
|
||||
idForObjectWithKey: objectKey];
|
||||
}
|
||||
|
||||
- (id) initWithAttachment: (id) newAttachment
|
||||
- (int) getPidTagAccessLevel: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
if ((self = [self init]))
|
||||
{
|
||||
if ([newAttachment isKindOfClass: MAPIStoreAttachmentK])
|
||||
ASSIGN (container, newAttachment);
|
||||
}
|
||||
|
||||
return self;
|
||||
return [self getLongZero: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
/* disabled properties */
|
||||
- (int) getPidTagFolderId: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagChangeKey: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagSourceKey: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagParentSourceKey: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagChangeNumber: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagInstID: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagInstanceNum: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagRowType: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagDepth: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagIconIndex: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagGenerateExchangeViews: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagOriginalMessageClass: (void **) dataa
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* common methods */
|
||||
- (NSString *) nameInContainer
|
||||
{
|
||||
return @"as-message";
|
||||
}
|
||||
|
||||
- (uint64_t) objectVersion
|
||||
{
|
||||
return ULLONG_MAX;
|
||||
}
|
||||
|
||||
- (void) save
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFAIMessage.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -23,9 +23,9 @@
|
|||
#ifndef MAPISTOREFAIMESSAGE_H
|
||||
#define MAPISTOREFAIMESSAGE_H
|
||||
|
||||
#import "MAPIStoreFSMessage.h"
|
||||
#import "MAPIStoreDBMessage.h"
|
||||
|
||||
@interface MAPIStoreFAIMessage : MAPIStoreFSMessage
|
||||
@interface MAPIStoreFAIMessage : MAPIStoreDBMessage
|
||||
@end
|
||||
|
||||
#endif /* MAPISTOREFAIMESSAGE_H */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFAIMessage.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFAIMessageTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -23,9 +23,9 @@
|
|||
#ifndef MAPISTOREFAIMESSAGETABLE_H
|
||||
#define MAPISTOREFAIMESSAGETABLE_H
|
||||
|
||||
#import "MAPIStoreFSMessageTable.h"
|
||||
#import "MAPIStoreDBMessageTable.h"
|
||||
|
||||
@interface MAPIStoreFAIMessageTable : MAPIStoreFSMessageTable
|
||||
@interface MAPIStoreFAIMessageTable : MAPIStoreDBMessageTable
|
||||
@end
|
||||
|
||||
#endif /* MAPISTOREFAIMESSAGETABLE_H */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFAIMessageTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
/* MAPIStoreFSBaseContext.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 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 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* A generic parent class for all context that will store their data on the
|
||||
disk in the form of a plist. */
|
||||
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import "MAPIStoreFSFolder.h"
|
||||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreUserContext.h"
|
||||
#import "SOGoMAPIFSFolder.h"
|
||||
|
||||
#import "MAPIStoreFSBaseContext.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
|
||||
static Class MAPIStoreFSFolderK;
|
||||
|
||||
@implementation MAPIStoreFSBaseContext
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
MAPIStoreFSFolderK = [MAPIStoreFSFolder class];
|
||||
}
|
||||
|
||||
+ (NSString *) MAPIModuleName
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (Class) MAPIStoreFolderClass
|
||||
{
|
||||
return MAPIStoreFSFolderK;
|
||||
}
|
||||
|
||||
- (void) ensureContextFolder
|
||||
{
|
||||
SOGoMAPIFSFolder *contextFolder;
|
||||
|
||||
contextFolder = [SOGoMAPIFSFolder folderWithURL: contextUrl
|
||||
andTableType: MAPISTORE_MESSAGE_TABLE];
|
||||
[contextFolder ensureDirectory];
|
||||
}
|
||||
|
||||
- (id) rootSOGoFolder
|
||||
{
|
||||
NSString *urlString;
|
||||
|
||||
urlString = [NSString stringWithFormat: @"sogo://%@@%@/",
|
||||
[userContext username], [isa MAPIModuleName]];
|
||||
return [SOGoMAPIFSFolder folderWithURL: [NSURL URLWithString: urlString]
|
||||
andTableType: MAPISTORE_MESSAGE_TABLE];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFallbackContext.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -23,9 +23,9 @@
|
|||
#ifndef MAPISTOREFALLBACKCONTEXT_H
|
||||
#define MAPISTOREFALLBACKCONTEXT_H
|
||||
|
||||
#import "MAPIStoreFSBaseContext.h"
|
||||
#import "MAPIStoreDBBaseContext.h"
|
||||
|
||||
@interface MAPIStoreFallbackContext : MAPIStoreFSBaseContext
|
||||
@interface MAPIStoreFallbackContext : MAPIStoreDBBaseContext
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFallbackContext.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc.
|
||||
* Copyright (C) 2011-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
#import "MAPIStoreUserContext.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
#import "SOGoMAPIFSFolder.h"
|
||||
#import "SOGoMAPIDBFolder.h"
|
||||
|
||||
#import "MAPIStoreFallbackContext.h"
|
||||
|
||||
|
@ -51,10 +51,11 @@
|
|||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
struct mapistore_contexts_list *firstContext = NULL, *context;
|
||||
SOGoMAPIFSFolder *root;
|
||||
SOGoMAPIDBFolder *root;
|
||||
NSArray *names;
|
||||
NSUInteger count, max;
|
||||
NSString *baseURL, *url, *name;
|
||||
MAPIStoreUserContext *userContext;
|
||||
|
||||
baseURL = [NSString stringWithFormat: @"sogo://%@@fallback/", userName];
|
||||
|
||||
|
@ -67,11 +68,15 @@
|
|||
|
||||
DLIST_ADD_END (firstContext, context, void);
|
||||
|
||||
|
||||
/* Maybe emsmdbp_provisioning should be fixed in order to only take the uri
|
||||
returned above to avoid deleting its entries... */
|
||||
root = [SOGoMAPIFSFolder folderWithURL: [NSURL URLWithString: baseURL]
|
||||
andTableType: MAPISTORE_MESSAGE_TABLE];
|
||||
root = [SOGoMAPIDBFolder objectWithName: [self MAPIModuleName]
|
||||
inContainer: nil];
|
||||
[root setOwner: userName];
|
||||
userContext = [MAPIStoreUserContext userContextWithUsername: userName
|
||||
andTDBIndexing: indexingTdb];
|
||||
[userContext ensureFolderTableExists];
|
||||
[root setTableUrl: [userContext folderTableURL]];
|
||||
names = [root toManyRelationshipKeys];
|
||||
max = [names count];
|
||||
for (count = 0; count < max; count++)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFolder.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -38,29 +38,34 @@
|
|||
@class MAPIStoreMessageTable;
|
||||
@class MAPIStorePermissionsTable;
|
||||
@class SOGoFolder;
|
||||
@class SOGoMAPIFSFolder;
|
||||
@class SOGoMAPIFSMessage;
|
||||
@class SOGoMAPIDBFolder;
|
||||
@class SOGoMAPIDBMessage;
|
||||
|
||||
#import "MAPIStoreObject.h"
|
||||
#import "MAPIStoreSOGoObject.h"
|
||||
|
||||
@interface MAPIStoreFolder : MAPIStoreObject
|
||||
@interface MAPIStoreFolder : MAPIStoreSOGoObject
|
||||
{
|
||||
MAPIStoreContext *context;
|
||||
// NSArray *messageKeys;
|
||||
// NSArray *faiMessageKeys;
|
||||
// NSArray *folderKeys;
|
||||
|
||||
SOGoMAPIFSFolder *faiFolder;
|
||||
SOGoMAPIFSFolder *propsFolder;
|
||||
SOGoMAPIFSMessage *propsMessage;
|
||||
SOGoMAPIDBFolder *dbFolder;
|
||||
// SOGoMAPIDBFolder *faiFolder;
|
||||
// SOGoMAPIDBFolder *propsFolder;
|
||||
// SOGoMAPIDBMessage *propsMessage;
|
||||
}
|
||||
|
||||
- (void) setContext: (MAPIStoreContext *) newContext;
|
||||
|
||||
- (void) setupAuxiliaryObjects;
|
||||
|
||||
- (SOGoMAPIDBFolder *) dbFolder;
|
||||
|
||||
- (NSArray *) activeMessageTables;
|
||||
- (NSArray *) activeFAIMessageTables;
|
||||
|
||||
- (SOGoMAPIFSMessage *) propertiesMessage;
|
||||
// - (SOGoMAPIDBMessage *) propertiesMessage;
|
||||
|
||||
- (id) lookupMessageByURL: (NSString *) messageURL;
|
||||
- (id) lookupFolderByURL: (NSString *) folderURL;
|
||||
|
@ -118,6 +123,11 @@
|
|||
andChangeKeys: (struct Binary_r **) targetChangeKeys
|
||||
wantCopy: (uint8_t) want_copy;
|
||||
|
||||
- (enum mapistore_error) moveCopyToFolder: (MAPIStoreFolder *) targetFolder
|
||||
withNewName: (NSString *) newFolderName
|
||||
isMove: (BOOL) isMove
|
||||
isRecursive: (BOOL) isRecursive;
|
||||
|
||||
- (int) getDeletedFMIDs: (struct I8Array_r **) fmidsPtr
|
||||
andCN: (uint64_t *) cnPtr
|
||||
fromChangeNumber: (uint64_t) changeNum
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -23,7 +23,9 @@
|
|||
/* TODO: main key arrays must be initialized */
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSAutoreleasePool.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
@ -45,11 +47,12 @@
|
|||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "MAPIStoreUserContext.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSDate+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
#import "SOGoMAPIFSFolder.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
#import "SOGoMAPIDBFolder.h"
|
||||
#import "SOGoMAPIDBMessage.h"
|
||||
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
||||
|
@ -79,33 +82,69 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
// messageKeys = nil;
|
||||
// faiMessageKeys = nil;
|
||||
// folderKeys = nil;
|
||||
faiFolder = nil;
|
||||
dbFolder = nil;
|
||||
context = nil;
|
||||
|
||||
propsFolder = nil;
|
||||
propsMessage = nil;
|
||||
// propsFolder = nil;
|
||||
// propsMessage = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) _setupAuxiliaryObjects
|
||||
- (void) setupAuxiliaryObjects
|
||||
{
|
||||
NSURL *propsURL;
|
||||
NSString *urlString;
|
||||
NSURL *folderURL;
|
||||
NSMutableString *pathPrefix;
|
||||
NSString *path, *escapedURL, *folderName;
|
||||
NSArray *parts;
|
||||
NSUInteger lastPartIdx;
|
||||
MAPIStoreUserContext *userContext;
|
||||
|
||||
escapedURL = [[self url]
|
||||
stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
|
||||
folderURL = [NSURL URLWithString: escapedURL];
|
||||
path = [folderURL path];
|
||||
path = [path substringFromIndex: 1];
|
||||
if ([path length] > 0)
|
||||
{
|
||||
parts = [path componentsSeparatedByString: @"/"];
|
||||
lastPartIdx = [parts count] - 1;
|
||||
if ([path hasSuffix: @"/"])
|
||||
lastPartIdx--;
|
||||
folderName = [parts objectAtIndex: lastPartIdx];
|
||||
}
|
||||
else
|
||||
folderName = [folderURL host];
|
||||
|
||||
userContext = [self userContext];
|
||||
[userContext ensureFolderTableExists];
|
||||
|
||||
ASSIGN (dbFolder,
|
||||
[SOGoMAPIDBFolder objectWithName: folderName
|
||||
inContainer: [container dbFolder]]);
|
||||
[dbFolder setTableUrl: [userContext folderTableURL]];
|
||||
if (!container && [path length] > 0)
|
||||
{
|
||||
pathPrefix = [NSMutableString stringWithCapacity: 64];
|
||||
[pathPrefix appendFormat: @"/%@", [folderURL host]];
|
||||
parts = [parts subarrayWithRange: NSMakeRange (0, lastPartIdx)];
|
||||
if ([parts count] > 0)
|
||||
[pathPrefix appendFormat: @"/%@", [parts componentsJoinedByString: @"/"]];
|
||||
[dbFolder setPathPrefix: pathPrefix];
|
||||
}
|
||||
[dbFolder reloadIfNeeded];
|
||||
|
||||
/* propsMessage and self share the same properties dictionary */
|
||||
// ASSIGN (propsMessage,
|
||||
// [SOGoMAPIDBMessage objectWithName: @"properties.plist"
|
||||
// inContainer: dbFolder]);
|
||||
// [propsMessage setObjectType: MAPIDBObjectTypeInternal];
|
||||
// [propsMessage reloadIfNeeded];
|
||||
[properties release];
|
||||
properties = [dbFolder properties];
|
||||
[properties retain];
|
||||
|
||||
urlString = [[self url] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
|
||||
propsURL = [NSURL URLWithString: urlString];
|
||||
[self logWithFormat: @"_setupAuxiliaryObjects: %@", propsURL];
|
||||
ASSIGN (faiFolder,
|
||||
[SOGoMAPIFSFolder folderWithURL: propsURL
|
||||
andTableType: MAPISTORE_FAI_TABLE]);
|
||||
ASSIGN (propsFolder,
|
||||
[SOGoMAPIFSFolder folderWithURL: propsURL
|
||||
andTableType: MAPISTORE_FOLDER_TABLE]);
|
||||
ASSIGN (propsMessage,
|
||||
[SOGoMAPIFSMessage objectWithName: @"properties.plist"
|
||||
inContainer: propsFolder]);
|
||||
[self setupVersionsMessage];
|
||||
}
|
||||
|
||||
|
@ -119,7 +158,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
inContainer: newContainer])
|
||||
&& newContainer)
|
||||
{
|
||||
[self _setupAuxiliaryObjects];
|
||||
[self setupAuxiliaryObjects];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -129,13 +168,13 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
{
|
||||
ASSIGN (context, newContext);
|
||||
if (newContext)
|
||||
[self _setupAuxiliaryObjects];
|
||||
[self setupAuxiliaryObjects];
|
||||
}
|
||||
|
||||
- (MAPIStoreContext *) context
|
||||
{
|
||||
if (!context)
|
||||
[self setContext: [container context]];
|
||||
[self setContext: (MAPIStoreContext *) [container context]];
|
||||
|
||||
return context;
|
||||
}
|
||||
|
@ -145,29 +184,31 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
// [messageKeys release];
|
||||
// [faiMessageKeys release];
|
||||
// [folderKeys release];
|
||||
[propsMessage release];
|
||||
[propsFolder release];
|
||||
[faiFolder release];
|
||||
// [propsMessage release];
|
||||
[dbFolder release];
|
||||
[context release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (SOGoMAPIDBFolder *) dbFolder
|
||||
{
|
||||
return dbFolder;
|
||||
}
|
||||
|
||||
/* backend interface */
|
||||
|
||||
- (SOGoMAPIFSMessage *) propertiesMessage
|
||||
{
|
||||
return propsMessage;
|
||||
}
|
||||
// - (SOGoMAPIDBMessage *) propertiesMessage
|
||||
// {
|
||||
// return propsMessage;
|
||||
// }
|
||||
|
||||
- (uint64_t) objectVersion
|
||||
{
|
||||
NSNumber *value;
|
||||
NSDictionary *props;
|
||||
uint64_t cn;
|
||||
|
||||
props = [propsMessage properties];
|
||||
value = [props objectForKey: MAPIPropertyKey (PidTagChangeNumber)];
|
||||
value = [properties objectForKey: MAPIPropertyKey (PidTagChangeNumber)];
|
||||
if (value)
|
||||
cn = [value unsignedLongLongValue];
|
||||
else
|
||||
|
@ -175,10 +216,10 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
[self logWithFormat: @"no value for PidTagChangeNumber, adding one now"];
|
||||
cn = [[self context] getNewChangeNumber];
|
||||
value = [NSNumber numberWithUnsignedLongLong: cn];
|
||||
props = [NSDictionary dictionaryWithObject: value
|
||||
forKey: MAPIPropertyKey (PidTagChangeNumber)];
|
||||
[propsMessage appendProperties: props];
|
||||
[propsMessage save];
|
||||
|
||||
[properties setObject: value
|
||||
forKey: MAPIPropertyKey (PidTagChangeNumber)];
|
||||
[dbFolder save];
|
||||
}
|
||||
|
||||
return cn >> 16;
|
||||
|
@ -186,21 +227,24 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
|
||||
- (id) lookupFolder: (NSString *) folderKey
|
||||
{
|
||||
MAPIStoreFolder *childFolder = nil;
|
||||
MAPIStoreFolder *childFolder;
|
||||
SOGoFolder *sogoFolder;
|
||||
WOContext *woContext;
|
||||
|
||||
if ([[self folderKeys] containsObject: folderKey])
|
||||
{
|
||||
woContext = [[self userContext] woContext];
|
||||
sogoFolder = [sogoObject lookupName: folderKey
|
||||
inContext: woContext
|
||||
sogoFolder = [sogoObject lookupName: folderKey inContext: woContext
|
||||
acquire: NO];
|
||||
[sogoFolder setContext: woContext];
|
||||
if (sogoFolder && ![sogoFolder isKindOfClass: NSExceptionK])
|
||||
childFolder = [isa mapiStoreObjectWithSOGoObject: sogoFolder
|
||||
inContainer: self];
|
||||
{
|
||||
[sogoFolder setContext: woContext];
|
||||
childFolder = [isa mapiStoreObjectWithSOGoObject: sogoFolder
|
||||
inContainer: self];
|
||||
}
|
||||
}
|
||||
else
|
||||
childFolder = nil;
|
||||
|
||||
return childFolder;
|
||||
}
|
||||
|
@ -264,9 +308,9 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
{
|
||||
if ([[self faiMessageKeys] containsObject: messageKey])
|
||||
{
|
||||
msgObject = [faiFolder lookupName: messageKey
|
||||
inContext: nil
|
||||
acquire: NO];
|
||||
msgObject = [dbFolder lookupName: messageKey
|
||||
inContext: nil
|
||||
acquire: NO];
|
||||
childMessage
|
||||
= [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: msgObject
|
||||
inContainer: self];
|
||||
|
@ -360,7 +404,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
baseURL = [self url];
|
||||
if (![baseURL hasSuffix: @"/"])
|
||||
baseURL = [NSString stringWithFormat: @"%@/", baseURL];
|
||||
childURL = [NSString stringWithFormat: @"%@%@",
|
||||
childURL = [NSString stringWithFormat: @"%@%@/",
|
||||
baseURL, folderKey];
|
||||
[mapping registerURL: childURL withID: fid];
|
||||
childFolder = [self lookupFolder: folderKey];
|
||||
|
@ -383,9 +427,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
|
||||
- (int) deleteFolder
|
||||
{
|
||||
[propsMessage delete];
|
||||
[propsFolder delete];
|
||||
[faiFolder delete];
|
||||
// [propsMessage delete];
|
||||
[dbFolder delete];
|
||||
|
||||
[self cleanupCaches];
|
||||
|
||||
|
@ -615,13 +658,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
int rc;
|
||||
MAPIStoreMessage *sourceMsg, *destMsg;
|
||||
TALLOC_CTX *memCtx;
|
||||
struct SPropTagArray *availableProps;
|
||||
bool *exclusions;
|
||||
NSUInteger count;
|
||||
enum MAPITAGS propTag;
|
||||
struct SRow *aRow;
|
||||
int error;
|
||||
void *data;
|
||||
struct SRow aRow;
|
||||
struct SPropValue property;
|
||||
|
||||
memCtx = talloc_zero (NULL, TALLOC_CTX);
|
||||
rc = [sourceFolder openMessage: &sourceMsg
|
||||
|
@ -631,56 +669,23 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
if (rc != MAPISTORE_SUCCESS)
|
||||
goto end;
|
||||
|
||||
rc = [sourceMsg getAvailableProperties: &availableProps
|
||||
inMemCtx: memCtx];
|
||||
if (rc != MAPISTORE_SUCCESS)
|
||||
goto end;
|
||||
|
||||
exclusions = talloc_array(NULL, bool, 65536);
|
||||
exclusions[PR_ROW_TYPE >> 16] = true;
|
||||
exclusions[PR_INSTANCE_KEY >> 16] = true;
|
||||
exclusions[PR_INSTANCE_NUM >> 16] = true;
|
||||
exclusions[PR_INST_ID >> 16] = true;
|
||||
exclusions[PR_FID >> 16] = true;
|
||||
exclusions[PR_MID >> 16] = true;
|
||||
exclusions[PR_SOURCE_KEY >> 16] = true;
|
||||
exclusions[PR_PARENT_SOURCE_KEY >> 16] = true;
|
||||
exclusions[PR_PARENT_FID >> 16] = true;
|
||||
exclusions[PR_CHANGE_KEY >> 16] = true;
|
||||
exclusions[PR_PREDECESSOR_CHANGE_LIST >> 16] = true;
|
||||
|
||||
aRow = talloc_zero (memCtx, struct SRow);
|
||||
aRow->lpProps = talloc_array (aRow, struct SPropValue, 65535);
|
||||
|
||||
for (count = 0; count < availableProps->cValues; count++)
|
||||
{
|
||||
propTag = availableProps->aulPropTag[count];
|
||||
if (!exclusions[propTag >> 16])
|
||||
{
|
||||
error = [sourceMsg getProperty: &data
|
||||
withTag: propTag
|
||||
inMemCtx: aRow];
|
||||
if (error == MAPISTORE_SUCCESS && data)
|
||||
{
|
||||
set_SPropValue_proptag(&aRow->lpProps[aRow->cValues], propTag, data);
|
||||
aRow->cValues++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targetChangeKey)
|
||||
{
|
||||
set_SPropValue_proptag(&aRow->lpProps[aRow->cValues], PR_CHANGE_KEY, targetChangeKey);
|
||||
aRow->cValues++;
|
||||
}
|
||||
|
||||
rc = [self createMessage: &destMsg withMID: targetMid
|
||||
isAssociated: [sourceMsg isKindOfClass: MAPIStoreFAIMessageK]];
|
||||
if (rc != MAPISTORE_SUCCESS)
|
||||
goto end;
|
||||
rc = [destMsg addPropertiesFromRow: aRow];
|
||||
if (rc != MAPISTORE_SUCCESS)
|
||||
goto end;
|
||||
|
||||
[sourceMsg copyToMessage: destMsg];
|
||||
|
||||
if (targetChangeKey)
|
||||
{
|
||||
property.ulPropTag = PidTagChangeKey;
|
||||
property.value.bin = *targetChangeKey;
|
||||
aRow.cValues = 1;
|
||||
aRow.lpProps = &property;
|
||||
rc = [destMsg addPropertiesFromRow: &aRow];
|
||||
if (rc != MAPISTORE_SUCCESS)
|
||||
goto end;
|
||||
}
|
||||
[destMsg save];
|
||||
if (!wantCopy)
|
||||
rc = [sourceFolder deleteMessageWithMID: srcMid andFlags: 0];
|
||||
|
@ -757,6 +762,122 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
return rc;
|
||||
}
|
||||
|
||||
- (enum mapistore_error) moveCopyToFolder: (MAPIStoreFolder *) targetFolder
|
||||
withNewName: (NSString *) newFolderName
|
||||
isMove: (BOOL) isMove
|
||||
isRecursive: (BOOL) isRecursive
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
NSAutoreleasePool *pool;
|
||||
struct SRow folderRow;
|
||||
struct SPropValue nameProperty;
|
||||
MAPIStoreFolder *subFolder, *newFolder;
|
||||
NSArray *children;
|
||||
MAPIStoreMapping *mapping;
|
||||
MAPIStoreMessage *message, *targetMessage;
|
||||
NSUInteger count, max;
|
||||
NSString *childKey;
|
||||
uint64_t fmid;
|
||||
|
||||
/* TODO: one possible issue with this algorithm is that moved messages will
|
||||
lack a version number and will all be assigned a new one, even though
|
||||
they have not changed. This also means that they will be transferred
|
||||
again to the client during a sync operation. */
|
||||
|
||||
if ([targetFolder supportsSubFolders])
|
||||
{
|
||||
mapping = [self mapping];
|
||||
|
||||
if (!newFolderName)
|
||||
newFolderName = [sogoObject displayName];
|
||||
nameProperty.ulPropTag = PidTagDisplayName;
|
||||
nameProperty.value.lpszW = [newFolderName UTF8String];
|
||||
folderRow.lpProps = &nameProperty;
|
||||
folderRow.cValues = 1;
|
||||
rc = [targetFolder createFolder: &folderRow
|
||||
withFID: [self objectId]
|
||||
andKey: &childKey];
|
||||
if (rc == MAPISTORE_SUCCESS)
|
||||
{
|
||||
newFolder = [targetFolder lookupFolder: childKey];
|
||||
[self copyPropertiesToObject: newFolder];
|
||||
|
||||
pool = [NSAutoreleasePool new];
|
||||
children = [self messageKeys];
|
||||
max = [children count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
childKey = [children objectAtIndex: count];
|
||||
message = [self lookupMessage: childKey];
|
||||
targetMessage = [newFolder createMessage: NO];
|
||||
[targetMessage setIsNew: YES];
|
||||
[message copyToMessage: targetMessage];
|
||||
if (isMove)
|
||||
{
|
||||
fmid = [mapping idFromURL: [message url]];
|
||||
[self deleteMessageWithMID: fmid andFlags: 0];
|
||||
[mapping registerURL: [targetMessage url]
|
||||
withID: fmid];
|
||||
}
|
||||
[targetMessage save];
|
||||
}
|
||||
[pool release];
|
||||
|
||||
pool = [NSAutoreleasePool new];
|
||||
children = [self faiMessageKeys];
|
||||
max = [children count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
childKey = [children objectAtIndex: count];
|
||||
message = [self lookupFAIMessage: childKey];
|
||||
targetMessage = [newFolder createMessage: YES];
|
||||
[targetMessage setIsNew: YES];
|
||||
[message copyToMessage: targetMessage];
|
||||
if (isMove)
|
||||
{
|
||||
fmid = [mapping idFromURL: [message url]];
|
||||
[self deleteMessageWithMID: fmid andFlags: 0];
|
||||
[mapping registerURL: [targetMessage url]
|
||||
withID: fmid];
|
||||
}
|
||||
[targetMessage save];
|
||||
}
|
||||
[pool release];
|
||||
|
||||
if (isRecursive)
|
||||
{
|
||||
pool = [NSAutoreleasePool new];
|
||||
children = [self folderKeys];
|
||||
max = [children count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
childKey = [children objectAtIndex: count];
|
||||
subFolder = [self lookupFolder: childKey];
|
||||
[subFolder moveCopyToFolder: newFolder withNewName: nil
|
||||
isMove: isMove
|
||||
isRecursive: isRecursive];
|
||||
}
|
||||
[pool release];
|
||||
}
|
||||
|
||||
if (isMove)
|
||||
{
|
||||
fmid = [mapping idFromURL: [self url]];
|
||||
[mapping unregisterURLWithID: fmid];
|
||||
[self deleteFolder];
|
||||
[mapping registerURL: [newFolder url]
|
||||
withID: fmid];
|
||||
}
|
||||
[targetFolder cleanupCaches];
|
||||
}
|
||||
[self cleanupCaches];
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERR_DENIED;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (SOGoFolder *) aclFolder
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
@ -1004,7 +1125,11 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
/* TODO: this should no longer be required once mapistore v2 API is in
|
||||
place, when we can then do this from -dealloc below */
|
||||
|
||||
[dbFolder reloadIfNeeded];
|
||||
|
||||
propsCopy = [newProperties mutableCopy];
|
||||
[propsCopy autorelease];
|
||||
|
||||
currentProp = bannedProps;
|
||||
while (*currentProp)
|
||||
{
|
||||
|
@ -1012,9 +1137,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
currentProp++;
|
||||
}
|
||||
|
||||
[propsMessage appendProperties: propsCopy];
|
||||
[propsMessage save];
|
||||
[propsCopy release];
|
||||
[properties addEntriesFromDictionary: propsCopy];
|
||||
[dbFolder save];
|
||||
}
|
||||
|
||||
- (NSArray *) messageKeys
|
||||
|
@ -1039,9 +1163,10 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
- (NSArray *) faiMessageKeysMatchingQualifier: (EOQualifier *) qualifier
|
||||
andSortOrderings: (NSArray *) sortOrderings
|
||||
{
|
||||
return [faiFolder
|
||||
toOneRelationshipKeysMatchingQualifier: qualifier
|
||||
andSortOrderings: sortOrderings];
|
||||
return [dbFolder childKeysOfType: MAPIDBObjectTypeFAI
|
||||
includeDeleted: NO
|
||||
matchingQualifier: qualifier
|
||||
andSortOrderings: sortOrderings];
|
||||
}
|
||||
|
||||
- (NSArray *) faiMessageKeys
|
||||
|
@ -1192,7 +1317,51 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
- (int) getPidTagAccessLevel: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPILongValue (memCtx, 0x01);
|
||||
SOGoUser *ownerUser;
|
||||
BOOL userIsOwner;
|
||||
|
||||
ownerUser = [[self userContext] sogoUser];
|
||||
|
||||
userIsOwner = [[context activeUser] isEqual: ownerUser];
|
||||
|
||||
*data = MAPILongValue (memCtx, (userIsOwner) ? 0x01 : 0x00);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagRights: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
SOGoUser *ownerUser;
|
||||
BOOL userIsOwner;
|
||||
|
||||
ownerUser = [[self userContext] sogoUser];
|
||||
|
||||
userIsOwner = [[context activeUser] isEqual: ownerUser];
|
||||
if (userIsOwner || [self subscriberCanReadMessages])
|
||||
rights |= RightsReadItems;
|
||||
if (userIsOwner || [self subscriberCanCreateMessages])
|
||||
rights |= RightsCreateItems;
|
||||
if (userIsOwner || [self subscriberCanModifyMessages])
|
||||
rights |= RightsEditOwn | RightsEditAll;
|
||||
if (userIsOwner || [self subscriberCanDeleteMessages])
|
||||
rights |= RightsDeleteOwn | RightsDeleteAll;
|
||||
if ((userIsOwner || [self subscriberCanCreateSubFolders])
|
||||
&& [self supportsSubFolders])
|
||||
rights |= RightsCreateSubfolders;
|
||||
if (userIsOwner)
|
||||
rights |= RightsFolderOwner | RightsFolderContact;
|
||||
|
||||
*data = MAPILongValue (memCtx, rights);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagAccessControlListData: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = [[NSData data] asBinaryInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -1287,6 +1456,19 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getProperties: (struct mapistore_property_data *) data
|
||||
withTags: (enum MAPITAGS *) tags
|
||||
andCount: (uint16_t) columnCount
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
[dbFolder reloadIfNeeded];
|
||||
|
||||
return [super getProperties: data
|
||||
withTags: tags
|
||||
andCount: columnCount
|
||||
inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getProperty: (void **) data
|
||||
withTag: (enum MAPITAGS) propTag
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
|
@ -1294,8 +1476,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
int rc;
|
||||
id value;
|
||||
|
||||
value = [[propsMessage properties]
|
||||
objectForKey: MAPIPropertyKey (propTag)];
|
||||
value = [properties objectForKey: MAPIPropertyKey (propTag)];
|
||||
if (value)
|
||||
rc = [value getValue: data forTag: propTag inMemCtx: memCtx];
|
||||
else
|
||||
|
@ -1307,13 +1488,15 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
- (MAPIStoreMessage *) _createAssociatedMessage
|
||||
{
|
||||
MAPIStoreMessage *newMessage;
|
||||
SOGoMAPIFSMessage *fsObject;
|
||||
SOGoMAPIDBMessage *dbObject;
|
||||
NSString *newKey;
|
||||
|
||||
newKey = [NSString stringWithFormat: @"%@.plist",
|
||||
[SOGoObject globallyUniqueObjectId]];
|
||||
fsObject = [SOGoMAPIFSMessage objectWithName: newKey inContainer: faiFolder];
|
||||
newMessage = [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: fsObject
|
||||
dbObject = [SOGoMAPIDBMessage objectWithName: newKey inContainer: dbFolder];
|
||||
[dbObject setObjectType: MAPIDBObjectTypeFAI];
|
||||
[dbObject setIsNew: YES];
|
||||
newMessage = [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: dbObject
|
||||
inContainer: self];
|
||||
|
||||
return newMessage;
|
||||
|
@ -1328,9 +1511,15 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
newMessage = [self _createAssociatedMessage];
|
||||
else
|
||||
newMessage = [self createMessage];
|
||||
[newMessage setIsNew: YES];
|
||||
/* FIXME: this is ugly as the specifics of message creation should all be
|
||||
delegated to subclasses */
|
||||
if ([newMessage respondsToSelector: @selector (setIsNew:)])
|
||||
[newMessage setIsNew: YES];
|
||||
woContext = [[self userContext] woContext];
|
||||
[[newMessage sogoObject] setContext: woContext];
|
||||
/* FIXME: this is ugly too as the specifics of message creation should all
|
||||
be delegated to subclasses */
|
||||
if ([newMessage respondsToSelector: @selector (sogoObject:)])
|
||||
[[newMessage sogoObject] setContext: woContext];
|
||||
|
||||
return newMessage;
|
||||
}
|
||||
|
@ -1354,7 +1543,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
url = [NSString stringWithFormat: @"%@/", [super url]];
|
||||
else
|
||||
{
|
||||
url = [[context url] absoluteString];
|
||||
url = [[[context url] absoluteString]
|
||||
stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
|
||||
if (![url hasSuffix: @"/"])
|
||||
url = [NSString stringWithFormat: @"%@/", url];
|
||||
}
|
||||
|
@ -1581,9 +1771,14 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
- (uint64_t) objectId
|
||||
{
|
||||
uint64_t objectId;
|
||||
NSString *folderKey;
|
||||
|
||||
if (container)
|
||||
objectId = [super objectId];
|
||||
{
|
||||
folderKey = [NSString stringWithFormat: @"%@/",
|
||||
[sogoObject nameInContainer]];
|
||||
objectId = [container idForObjectWithKey: folderKey];
|
||||
}
|
||||
else
|
||||
objectId = [self idForObjectWithKey: nil];
|
||||
|
||||
|
@ -1598,12 +1793,12 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
|
||||
- (NSDate *) creationTime
|
||||
{
|
||||
return [propsMessage creationTime];
|
||||
return [dbFolder creationDate];
|
||||
}
|
||||
|
||||
- (NSDate *) lastModificationTime
|
||||
{
|
||||
return [propsMessage lastModificationTime];
|
||||
return [dbFolder lastModified];
|
||||
}
|
||||
|
||||
/* subclasses */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFolderTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreFolderTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreGCSBaseContext.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreGCSBaseContext.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreGCSFolder.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -34,7 +34,7 @@
|
|||
|
||||
@interface MAPIStoreGCSFolder : MAPIStoreFolder
|
||||
{
|
||||
SOGoMAPIFSMessage *versionsMessage;
|
||||
SOGoMAPIDBMessage *versionsMessage;
|
||||
NSArray *activeUserRoles;
|
||||
EOQualifier *componentQualifier;
|
||||
}
|
||||
|
@ -45,11 +45,8 @@
|
|||
withChangeKey: (NSData *) newChangeKey;
|
||||
- (NSNumber *) lastModifiedFromMessageChangeNumber: (NSNumber *) changeNum;
|
||||
- (NSNumber *) changeNumberForMessageWithKey: (NSString *) messageKey;
|
||||
|
||||
- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey;
|
||||
- (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey;
|
||||
- (void) setChangeKey: (NSData *) changeKey
|
||||
forMessageWithKey: (NSString *) messageKey;
|
||||
|
||||
- (NSArray *) activeUserRoles;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreGCSFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -40,7 +40,7 @@
|
|||
#import "NSData+MAPIStore.h"
|
||||
#import "NSDate+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
#import "SOGoMAPIDBMessage.h"
|
||||
|
||||
#import "MAPIStoreGCSFolder.h"
|
||||
|
||||
|
@ -71,8 +71,9 @@ static Class NSNumberK;
|
|||
- (void) setupVersionsMessage
|
||||
{
|
||||
ASSIGN (versionsMessage,
|
||||
[SOGoMAPIFSMessage objectWithName: @"versions.plist"
|
||||
inContainer: propsFolder]);
|
||||
[SOGoMAPIDBMessage objectWithName: @"versions.plist"
|
||||
inContainer: dbFolder]);
|
||||
[versionsMessage setObjectType: MAPIDBObjectTypeInternal];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
|
@ -260,6 +261,7 @@ static Class NSNumberK;
|
|||
|
||||
- (void) _setChangeKey: (NSData *) changeKey
|
||||
forMessageEntry: (NSMutableDictionary *) messageEntry
|
||||
inChangeListOnly: (BOOL) inChangeListOnly
|
||||
{
|
||||
struct XID *xid;
|
||||
NSString *guid;
|
||||
|
@ -272,12 +274,15 @@ static Class NSNumberK;
|
|||
globCnt = [NSData dataWithBytes: xid->Data length: xid->Size];
|
||||
talloc_free (xid);
|
||||
|
||||
/* 1. set change key association */
|
||||
changeKeyDict = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
guid, @"GUID",
|
||||
globCnt, @"LocalId",
|
||||
nil];
|
||||
[messageEntry setObject: changeKeyDict forKey: @"ChangeKey"];
|
||||
if (!inChangeListOnly)
|
||||
{
|
||||
/* 1. set change key association */
|
||||
changeKeyDict = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
guid, @"GUID",
|
||||
globCnt, @"LocalId",
|
||||
nil];
|
||||
[messageEntry setObject: changeKeyDict forKey: @"ChangeKey"];
|
||||
}
|
||||
|
||||
/* 2. append/update predecessor change list */
|
||||
changeList = [messageEntry objectForKey: @"PredecessorChangeList"];
|
||||
|
@ -285,7 +290,7 @@ static Class NSNumberK;
|
|||
{
|
||||
changeList = [NSMutableDictionary new];
|
||||
[messageEntry setObject: changeList
|
||||
forKey: @"PredecessorChangeList"];
|
||||
forKey: @"PredecessorChangeList"];
|
||||
[changeList release];
|
||||
}
|
||||
[changeList setObject: globCnt forKey: guid];
|
||||
|
@ -349,6 +354,7 @@ static Class NSNumberK;
|
|||
[sortOrdering retain];
|
||||
}
|
||||
|
||||
[versionsMessage reloadIfNeeded];
|
||||
currentProperties = [versionsMessage properties];
|
||||
|
||||
lastModificationDate = [currentProperties objectForKey: @"SyncLastModificationDate"];
|
||||
|
@ -430,7 +436,8 @@ static Class NSNumberK;
|
|||
[messageEntry setObject: changeNumber forKey: @"version"];
|
||||
|
||||
changeKey = [self getReplicaKeyFromGlobCnt: newChangeNum >> 16];
|
||||
[self _setChangeKey: changeKey forMessageEntry: messageEntry];
|
||||
[self _setChangeKey: changeKey forMessageEntry: messageEntry
|
||||
inChangeListOnly: NO];
|
||||
|
||||
[mapping setObject: cLastModified forKey: changeNumber];
|
||||
|
||||
|
@ -451,7 +458,6 @@ static Class NSNumberK;
|
|||
forKey: @"SyncLastSynchronisationDate"];
|
||||
[currentProperties setObject: lastModificationDate
|
||||
forKey: @"SyncLastModificationDate"];
|
||||
[versionsMessage appendProperties: currentProperties];
|
||||
[versionsMessage save];
|
||||
}
|
||||
}
|
||||
|
@ -462,10 +468,21 @@ static Class NSNumberK;
|
|||
- (void) updateVersionsForMessageWithKey: (NSString *) messageKey
|
||||
withChangeKey: (NSData *) newChangeKey
|
||||
{
|
||||
[self synchroniseCache];
|
||||
NSMutableDictionary *messages, *messageEntry;
|
||||
|
||||
[self synchroniseCache];
|
||||
if (newChangeKey)
|
||||
[self setChangeKey: newChangeKey forMessageWithKey: messageKey];
|
||||
{
|
||||
messages = [[versionsMessage properties] objectForKey: @"Messages"];
|
||||
messageEntry = [messages objectForKey: messageKey];
|
||||
if (!messageEntry)
|
||||
[NSException raise: @"MAPIStoreIOException"
|
||||
format: @"no version record found for message '%@'",
|
||||
messageKey];
|
||||
[self _setChangeKey: newChangeKey forMessageEntry: messageEntry
|
||||
inChangeListOnly: YES];
|
||||
[versionsMessage save];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSNumber *) lastModifiedFromMessageChangeNumber: (NSNumber *) changeNum
|
||||
|
@ -491,26 +508,6 @@ static Class NSNumberK;
|
|||
return changeNumber;
|
||||
}
|
||||
|
||||
- (void) setChangeKey: (NSData *) changeKey
|
||||
forMessageWithKey: (NSString *) messageKey
|
||||
{
|
||||
NSMutableDictionary *messages;
|
||||
NSMutableDictionary *messageEntry;
|
||||
|
||||
messages = [[versionsMessage properties] objectForKey: @"Messages"];
|
||||
messageEntry = [messages objectForKey: messageKey];
|
||||
if (!messageEntry)
|
||||
{
|
||||
[self synchroniseCache];
|
||||
messageEntry = [messages objectForKey: messageKey];
|
||||
if (!messageEntry)
|
||||
abort ();
|
||||
}
|
||||
[self _setChangeKey: changeKey forMessageEntry: messageEntry];
|
||||
|
||||
[versionsMessage save];
|
||||
}
|
||||
|
||||
- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey
|
||||
{
|
||||
NSDictionary *messages, *changeKeyDict;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreGCSMessage.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreGCSMessage.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreGCSMessageTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreGCSMessageTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMIME.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMIME.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailAttachment.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -30,9 +30,11 @@
|
|||
@interface MAPIStoreMailAttachment : MAPIStoreAttachment
|
||||
{
|
||||
NSDictionary *bodyInfo;
|
||||
SOGoMailBodyPart *bodyPart;
|
||||
}
|
||||
|
||||
- (void) setBodyInfo: (NSDictionary *) newBodyInfo;
|
||||
- (void) setBodyPart: (SOGoMailBodyPart *) newBodyPart;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailAttachment.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -52,6 +52,7 @@
|
|||
if ((self = [super init]))
|
||||
{
|
||||
bodyInfo = nil;
|
||||
bodyPart = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -60,6 +61,7 @@
|
|||
- (void) dealloc
|
||||
{
|
||||
[bodyInfo release];
|
||||
[bodyPart release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -68,6 +70,11 @@
|
|||
ASSIGN (bodyInfo, newBodyInfo);
|
||||
}
|
||||
|
||||
- (void) setBodyPart: (SOGoMailBodyPart *) newBodyPart
|
||||
{
|
||||
ASSIGN (bodyPart, newBodyPart);
|
||||
}
|
||||
|
||||
- (int) getPidTagAttachMethod: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -187,7 +194,7 @@
|
|||
- (int) getPidTagAttachDataBinary: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = [[sogoObject fetchBLOBWithPeek: YES] asBinaryInMemCtx: memCtx];
|
||||
*data = [[bodyPart fetchBLOBWithPeek: YES] asBinaryInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailContext.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -26,6 +26,9 @@
|
|||
#import "MAPIStoreContext.h"
|
||||
|
||||
@interface MAPIStoreMailContext : MAPIStoreContext
|
||||
|
||||
- (void) updateURLWithFolderName: (NSString *) newFolderName;
|
||||
|
||||
@end
|
||||
|
||||
@interface MAPIStoreOutboxContext : MAPIStoreMailContext
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailContext.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -23,7 +23,8 @@
|
|||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import <Foundation/NSURL.h>
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
#import <Mailer/SOGoMailAccount.h>
|
||||
#import <Mailer/SOGoMailFolder.h>
|
||||
|
||||
|
@ -203,6 +204,34 @@ MakeDisplayFolderName (NSString *folderName)
|
|||
return [[userContext rootFolders] objectForKey: @"mail"];
|
||||
}
|
||||
|
||||
- (void) updateURLWithFolderName: (NSString *) newFolderName
|
||||
{
|
||||
NSString *urlString, *escapedName;
|
||||
NSMutableArray *pathComponents;
|
||||
BOOL hasSlash;
|
||||
NSUInteger max, folderNameIdx;
|
||||
NSURL *newURL;
|
||||
|
||||
/* we do not need to unescape the url here as it will be reassembled later
|
||||
in the method */
|
||||
urlString = [contextUrl absoluteString];
|
||||
hasSlash = [urlString hasSuffix: @"/"];
|
||||
pathComponents = [[urlString componentsSeparatedByString: @"/"]
|
||||
mutableCopy];
|
||||
[pathComponents autorelease];
|
||||
max = [pathComponents count];
|
||||
if (hasSlash)
|
||||
folderNameIdx = max - 2;
|
||||
else
|
||||
folderNameIdx = max - 1;
|
||||
escapedName = [newFolderName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
|
||||
[pathComponents replaceObjectAtIndex: folderNameIdx
|
||||
withObject: escapedName];
|
||||
urlString = [pathComponents componentsJoinedByString: @"/"];
|
||||
newURL = [NSURL URLWithString: urlString];
|
||||
ASSIGN (contextUrl, newURL);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MAPIStoreOutboxContext
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailFolder.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -36,7 +36,7 @@
|
|||
|
||||
@interface MAPIStoreMailFolder : MAPIStoreFolder
|
||||
{
|
||||
SOGoMAPIFSMessage *versionsMessage;
|
||||
SOGoMAPIDBMessage *versionsMessage;
|
||||
}
|
||||
|
||||
- (BOOL) ensureFolderExists;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailFolder.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -49,19 +49,20 @@
|
|||
#import "MAPIStoreAppointmentWrapper.h"
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreFAIMessage.h"
|
||||
#import "MAPIStoreMailContext.h"
|
||||
#import "MAPIStoreMailMessageTable.h"
|
||||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
#import "SOGoMAPIDBMessage.h"
|
||||
#import "SOGoMAPIDBFolder.h"
|
||||
|
||||
#import "SOGoMAPIVolatileMessage.h"
|
||||
#import "MAPIStoreMailVolatileMessage.h"
|
||||
|
||||
#import "MAPIStoreMailFolder.h"
|
||||
|
||||
static Class SOGoMailFolderK, MAPIStoreOutboxFolderK;
|
||||
static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK;
|
||||
|
||||
#undef DEBUG
|
||||
#include <util/attr.h>
|
||||
|
@ -74,6 +75,7 @@ static Class SOGoMailFolderK, MAPIStoreOutboxFolderK;
|
|||
+ (void) initialize
|
||||
{
|
||||
SOGoMailFolderK = [SOGoMailFolder class];
|
||||
MAPIStoreMailFolderK = [MAPIStoreMailFolder class];
|
||||
MAPIStoreOutboxFolderK = [MAPIStoreOutboxFolder class];
|
||||
[MAPIStoreAppointmentWrapper class];
|
||||
}
|
||||
|
@ -97,8 +99,9 @@ static Class SOGoMailFolderK, MAPIStoreOutboxFolderK;
|
|||
- (void) setupVersionsMessage
|
||||
{
|
||||
ASSIGN (versionsMessage,
|
||||
[SOGoMAPIFSMessage objectWithName: @"versions.plist"
|
||||
inContainer: propsFolder]);
|
||||
[SOGoMAPIDBMessage objectWithName: @"versions.plist"
|
||||
inContainer: dbFolder]);
|
||||
[versionsMessage setObjectType: MAPIDBObjectTypeInternal];
|
||||
}
|
||||
|
||||
- (BOOL) ensureFolderExists
|
||||
|
@ -108,9 +111,10 @@ static Class SOGoMailFolderK, MAPIStoreOutboxFolderK;
|
|||
|
||||
- (void) addProperties: (NSDictionary *) newProperties
|
||||
{
|
||||
NSString *newDisplayName;
|
||||
NSString *newDisplayName, *newNameInContainer;
|
||||
NSMutableDictionary *propsCopy;
|
||||
NSNumber *key;
|
||||
uint64_t fid;
|
||||
|
||||
key = MAPIPropertyKey (PR_DISPLAY_NAME_UNICODE);
|
||||
newDisplayName = [newProperties objectForKey: key];
|
||||
|
@ -119,7 +123,16 @@ static Class SOGoMailFolderK, MAPIStoreOutboxFolderK;
|
|||
&& ![[(SOGoMailFolder *) sogoObject displayName]
|
||||
isEqualToString: newDisplayName])
|
||||
{
|
||||
fid = [self objectId];
|
||||
[(SOGoMailFolder *) sogoObject renameTo: newDisplayName];
|
||||
newNameInContainer = [sogoObject nameInContainer];
|
||||
if (!container)
|
||||
[(MAPIStoreMailContext *) context
|
||||
updateURLWithFolderName: newNameInContainer];
|
||||
[[self mapping] updateID: fid withURL: [self url]];
|
||||
[dbFolder setNameInContainer: newNameInContainer];
|
||||
[self cleanupCaches];
|
||||
|
||||
propsCopy = [newProperties mutableCopy];
|
||||
[propsCopy removeObjectForKey: key];
|
||||
[propsCopy autorelease];
|
||||
|
@ -202,7 +215,7 @@ static Class SOGoMailFolderK, MAPIStoreOutboxFolderK;
|
|||
}
|
||||
|
||||
- (int) getPidTagContentUnreadCount: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
EOQualifier *searchQualifier;
|
||||
uint32_t longValue;
|
||||
|
@ -393,6 +406,11 @@ static Class SOGoMailFolderK, MAPIStoreOutboxFolderK;
|
|||
return permissionEntries;
|
||||
}
|
||||
|
||||
- (BOOL) supportsSubFolders
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* synchronisation */
|
||||
|
||||
/* Tree:
|
||||
|
@ -489,10 +507,8 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
now = [NSCalendarDate date];
|
||||
[now setTimeZone: utcTZ];
|
||||
|
||||
currentProperties = [[versionsMessage properties] mutableCopy];
|
||||
if (!currentProperties)
|
||||
currentProperties = [NSMutableDictionary new];
|
||||
[currentProperties autorelease];
|
||||
[versionsMessage reloadIfNeeded];
|
||||
currentProperties = [versionsMessage properties];
|
||||
messages = [currentProperties objectForKey: @"Messages"];
|
||||
if (!messages)
|
||||
{
|
||||
|
@ -613,7 +629,6 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
ti = [NSNumber numberWithDouble: [now timeIntervalSince1970]];
|
||||
[currentProperties setObject: ti
|
||||
forKey: @"SyncLastSynchronisationDate"];
|
||||
[versionsMessage appendProperties: currentProperties];
|
||||
[versionsMessage save];
|
||||
}
|
||||
|
||||
|
@ -978,14 +993,17 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
|||
}
|
||||
|
||||
/* Update the change keys */
|
||||
[self synchroniseCache];
|
||||
for (count = 0; count < midCount; count++)
|
||||
if (targetChangeKeys)
|
||||
{
|
||||
changeKey = [NSData dataWithBinary: targetChangeKeys[count]];
|
||||
messageKey = [NSString stringWithFormat: @"%@.eml",
|
||||
[destUIDs objectAtIndex: count]];
|
||||
[self setChangeKey: changeKey
|
||||
forMessageWithKey: messageKey];
|
||||
[self synchroniseCache];
|
||||
for (count = 0; count < midCount; count++)
|
||||
{
|
||||
changeKey = [NSData dataWithBinary: targetChangeKeys[count]];
|
||||
messageKey = [NSString stringWithFormat: @"%@.eml",
|
||||
[destUIDs objectAtIndex: count]];
|
||||
[self setChangeKey: changeKey
|
||||
forMessageWithKey: messageKey];
|
||||
}
|
||||
}
|
||||
|
||||
[self postNotificationsForMoveCopyMessagesWithMIDs: srcMids
|
||||
|
@ -1002,21 +1020,133 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (MAPIStoreMessage *) createMessage
|
||||
- (enum mapistore_error) moveCopyToFolder: (MAPIStoreFolder *) targetFolder
|
||||
withNewName: (NSString *) newFolderName
|
||||
isMove: (BOOL) isMove
|
||||
isRecursive: (BOOL) isRecursive
|
||||
{
|
||||
MAPIStoreMailVolatileMessage *newMessage;
|
||||
SOGoMAPIVolatileMessage *newObject;
|
||||
enum mapistore_error rc;
|
||||
NSURL *folderURL, *newFolderURL;
|
||||
struct SRow folderRow;
|
||||
struct SPropValue nameProperty;
|
||||
MAPIStoreMailFolder *newFolder;
|
||||
SOGoMailFolder *targetSOGoFolder;
|
||||
NSMutableArray *uids;
|
||||
NSArray *childKeys;
|
||||
NSUInteger count, max;
|
||||
NGImap4Connection *connection;
|
||||
NGImap4Client *client;
|
||||
NSString *newURL, *parentDBFolderPath, *childKey, *folderIMAPName, *newFolderIMAPName;
|
||||
NSException *error;
|
||||
MAPIStoreMapping *mapping;
|
||||
NSDictionary *result;
|
||||
|
||||
newObject = [SOGoMAPIVolatileMessage
|
||||
objectWithName: [SOGoObject globallyUniqueObjectId]
|
||||
inContainer: sogoObject];
|
||||
newMessage
|
||||
= [MAPIStoreMailVolatileMessage mapiStoreObjectWithSOGoObject: newObject
|
||||
inContainer: self];
|
||||
|
||||
return newMessage;
|
||||
if ([targetFolder isKindOfClass: MAPIStoreMailFolderK])
|
||||
{
|
||||
folderURL = [sogoObject imap4URL];
|
||||
if (!newFolderName)
|
||||
newFolderName = [sogoObject displayName];
|
||||
targetSOGoFolder = [targetFolder sogoObject];
|
||||
if (isMove)
|
||||
{
|
||||
newFolderURL = [NSURL
|
||||
URLWithString: [newFolderName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]
|
||||
relativeToURL: [targetSOGoFolder imap4URL]];
|
||||
error = [[sogoObject imap4Connection]
|
||||
moveMailboxAtURL: folderURL
|
||||
toURL: newFolderURL];
|
||||
if (error)
|
||||
rc = MAPISTORE_ERR_DENIED;
|
||||
else
|
||||
{
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
mapping = [self mapping];
|
||||
newURL = [NSString stringWithFormat: @"%@folder%@/",
|
||||
[targetFolder url], newFolderName];
|
||||
[mapping updateID: [self objectId] withURL: newURL];
|
||||
parentDBFolderPath = [[targetFolder dbFolder] path];
|
||||
if (!parentDBFolderPath)
|
||||
parentDBFolderPath = @"";
|
||||
[dbFolder changePathTo: [NSString stringWithFormat:
|
||||
@"%@/folder%@",
|
||||
parentDBFolderPath,
|
||||
newFolderName]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nameProperty.ulPropTag = PidTagDisplayName;
|
||||
nameProperty.value.lpszW = [newFolderName UTF8String];
|
||||
folderRow.lpProps = &nameProperty;
|
||||
folderRow.cValues = 1;
|
||||
rc = [targetFolder createFolder: &folderRow
|
||||
withFID: -1
|
||||
andKey: &childKey];
|
||||
if (rc == MAPISTORE_SUCCESS)
|
||||
{
|
||||
newFolder = [targetFolder lookupFolder: childKey];
|
||||
|
||||
connection = [sogoObject imap4Connection];
|
||||
folderIMAPName = [connection
|
||||
imap4FolderNameForURL: [sogoObject imap4URL]];
|
||||
newFolderIMAPName = [connection
|
||||
imap4FolderNameForURL: [[newFolder sogoObject] imap4URL]];
|
||||
client = [connection client];
|
||||
[client select: folderIMAPName];
|
||||
|
||||
childKeys = [self messageKeys];
|
||||
max = [childKeys count];
|
||||
uids = [NSMutableArray arrayWithCapacity: max];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
childKey = [childKeys objectAtIndex: count];
|
||||
[uids addObject: [self messageUIDFromMessageKey: childKey]];
|
||||
}
|
||||
|
||||
result = [client copyUids: uids
|
||||
toFolder: newFolderIMAPName];
|
||||
if ([[result objectForKey: @"result"] boolValue])
|
||||
{
|
||||
if (isRecursive)
|
||||
{
|
||||
childKeys = [self folderKeys];
|
||||
max = [childKeys count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
childKey = [childKeys objectAtIndex: count];
|
||||
[[self lookupFolder: childKey]
|
||||
moveCopyToFolder: newFolder
|
||||
withNewName: nil
|
||||
isMove: NO
|
||||
isRecursive: YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rc = MAPISTORE_ERROR;
|
||||
}
|
||||
}
|
||||
[targetFolder cleanupCaches];
|
||||
}
|
||||
else
|
||||
rc = [super moveCopyToFolder: targetFolder withNewName: newFolderName
|
||||
isMove: isMove
|
||||
isRecursive: isRecursive];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (MAPIStoreMessage *) createMessage
|
||||
{
|
||||
SOGoMAPIObject *childObject;
|
||||
|
||||
childObject = [SOGoMAPIObject objectWithName: [SOGoMAPIObject
|
||||
globallyUniqueObjectId]
|
||||
inContainer: sogoObject];
|
||||
return [MAPIStoreMailVolatileMessage
|
||||
mapiStoreObjectWithSOGoObject: childObject
|
||||
inContainer: self];
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
|
@ -1043,8 +1173,6 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
|||
[roles addObject: SOGoRole_ObjectViewer];
|
||||
if (rights & RightsCreateSubfolders)
|
||||
[roles addObject: SOGoRole_FolderCreator];
|
||||
if (rights & RightsCreateSubfolders)
|
||||
[roles addObject: SOGoRole_FolderCreator];
|
||||
|
||||
// [self logWithFormat: @"roles for rights %.8x = (%@)", rights, roles];
|
||||
|
||||
|
@ -1069,8 +1197,6 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
|||
rights |= RightsReadItems;
|
||||
if ([roles containsObject: SOGoRole_FolderCreator])
|
||||
rights |= RightsCreateSubfolders;
|
||||
if ([roles containsObject: SOGoRole_FolderCreator])
|
||||
rights |= RightsCreateSubfolders;
|
||||
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailMessage.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailMessage.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
@ -373,7 +373,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
if (uid)
|
||||
{
|
||||
changeNumber = [(MAPIStoreMailFolder *) container
|
||||
changeNumberForMessageUID: uid];
|
||||
changeNumberForMessageUID: uid];
|
||||
if (!changeNumber)
|
||||
{
|
||||
[self warnWithFormat: @"attempting to get change number"
|
||||
|
@ -448,19 +448,6 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagSubject: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSString *stringValue;
|
||||
|
||||
stringValue = [self subject];
|
||||
if (!stringValue)
|
||||
stringValue = @"";
|
||||
*data = [stringValue asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagSubjectPrefix: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -1013,12 +1000,6 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
return [self getNo: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagDeleteAfterSubmit: (void **) data // TODO
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getNo: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidLidGlobalObjectId: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -1529,8 +1510,8 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
|
|||
if (currentPart)
|
||||
{
|
||||
attachment = [MAPIStoreMailAttachment
|
||||
mapiStoreObjectWithSOGoObject: currentPart
|
||||
inContainer: self];
|
||||
mapiStoreObjectInContainer: self];
|
||||
[attachment setBodyPart: currentPart];
|
||||
[attachment setBodyInfo: [attachmentParts objectForKey: childKey]];
|
||||
[attachment setAID: [[self attachmentKeys] indexOfObject: childKey]];
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailMessageTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailMessageTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -332,7 +332,7 @@ static Class MAPIStoreMailMessageK, NSDataK, NSStringK;
|
|||
if (!fetchedCoreInfos)
|
||||
{
|
||||
fetchedCoreInfos = YES;
|
||||
[(SOGoMailFolder *) [container sogoObject]
|
||||
[(SOGoMailFolder *) [(MAPIStoreMailFolder *) container sogoObject]
|
||||
prefetchCoreInfosForMessageKeys: [self restrictedChildKeys]];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailVolatileMessage.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -23,9 +23,9 @@
|
|||
#ifndef MAPISTOREMAILVOLATILEMESSAGE_H
|
||||
#define MAPISTOREMAILVOLATILEMESSAGE_H
|
||||
|
||||
#import "MAPIStoreVolatileMessage.h"
|
||||
#import "MAPIStoreMessage.h"
|
||||
|
||||
@interface MAPIStoreMailVolatileMessage : MAPIStoreVolatileMessage
|
||||
@interface MAPIStoreMailVolatileMessage : MAPIStoreMessage
|
||||
|
||||
- (int) submitWithFlags: (enum SubmitFlags) flags;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMailVolatileMessage.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -51,6 +51,7 @@
|
|||
#import <Mailer/NSString+Mail.h>
|
||||
|
||||
#import "MAPIStoreAttachment.h"
|
||||
#import "MAPIStoreAttachmentTable.h"
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreMailFolder.h"
|
||||
#import "MAPIStoreMIME.h"
|
||||
|
@ -60,7 +61,7 @@
|
|||
#import "NSData+MAPIStore.h"
|
||||
#import "NSObject+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
#import "SOGoMAPIVolatileMessage.h"
|
||||
#import "SOGoMAPIObject.h"
|
||||
|
||||
#import "MAPIStoreMailVolatileMessage.h"
|
||||
|
||||
|
@ -68,6 +69,8 @@
|
|||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
static Class NSNumberK = Nil;
|
||||
|
||||
static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
|
||||
|
||||
//
|
||||
|
@ -242,6 +245,85 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
|
|||
|
||||
@implementation MAPIStoreMailVolatileMessage
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
NSNumberK = [NSNumber class];
|
||||
}
|
||||
|
||||
- (id) initWithSOGoObject: (id) newSOGoObject
|
||||
inContainer: (MAPIStoreObject *) newContainer
|
||||
{
|
||||
if ((self = [super initWithSOGoObject: newSOGoObject
|
||||
inContainer: newContainer]))
|
||||
{
|
||||
ASSIGN (properties, [sogoObject properties]);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) addProperties: (NSDictionary *) newProperties
|
||||
{
|
||||
[super addProperties: newProperties];
|
||||
[sogoObject adjustLastModified];
|
||||
}
|
||||
|
||||
- (BOOL) canGetProperty: (enum MAPITAGS) propTag
|
||||
{
|
||||
return ([super canGetProperty: propTag]
|
||||
|| [properties objectForKey: MAPIPropertyKey (propTag)] != nil);
|
||||
}
|
||||
|
||||
- (uint64_t) objectVersion
|
||||
{
|
||||
NSNumber *version;
|
||||
|
||||
version = [properties objectForKey: @"version"];
|
||||
|
||||
return (version
|
||||
? exchange_globcnt ([version unsignedLongLongValue])
|
||||
: ULLONG_MAX);
|
||||
}
|
||||
|
||||
- (int) getPidTagMessageClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = [@"IPM.Note" asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (int) getPidTagChangeKey: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
NSData *changeKey;
|
||||
int rc;
|
||||
|
||||
changeKey = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
|
||||
if (changeKey)
|
||||
{
|
||||
*data = [changeKey asBinaryInMemCtx: memCtx];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
rc = [super getPidTagChangeKey: data inMemCtx: memCtx];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (NSDate *) creationTime
|
||||
{
|
||||
return [sogoObject creationDate];
|
||||
}
|
||||
|
||||
- (NSDate *) lastModificationTime
|
||||
{
|
||||
return [sogoObject lastModified];
|
||||
}
|
||||
|
||||
- (id) lookupAttachment: (NSString *) childKey
|
||||
{
|
||||
return [attachmentParts objectForKey: childKey];
|
||||
}
|
||||
|
||||
- (void) getMessageData: (struct mapistore_message **) dataPtr
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -258,9 +340,11 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
|
|||
|
||||
samCtx = [[self context] connectionInfo]->sam_ctx;
|
||||
|
||||
[super getMessageData: &msgData inMemCtx: memCtx];
|
||||
// [super getMessageData: &msgData inMemCtx: memCtx];
|
||||
|
||||
allRecipients = [[sogoObject properties] objectForKey: @"recipients"];
|
||||
msgData = talloc_zero (memCtx, struct mapistore_message);
|
||||
|
||||
allRecipients = [properties objectForKey: @"recipients"];
|
||||
msgData->columns = set_SPropTagArray (msgData, 9,
|
||||
PR_OBJECT_TYPE,
|
||||
PR_DISPLAY_TYPE,
|
||||
|
@ -660,9 +744,11 @@ MakeTextPartBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
|||
return textBody;
|
||||
}
|
||||
|
||||
// static id
|
||||
// MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
||||
// NSString **contentType)
|
||||
static id
|
||||
MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
||||
NSString **contentType)
|
||||
MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, NSString **contentType)
|
||||
{
|
||||
id messageBody, textBody;
|
||||
NSString *textContentType;
|
||||
|
@ -707,22 +793,19 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
|||
|
||||
- (NGMimeMessage *) _generateMessage
|
||||
{
|
||||
NSDictionary *mailProperties;
|
||||
NSString *contentType;
|
||||
NGMimeMessage *message;
|
||||
NGMutableHashMap *headers;
|
||||
id messageBody;
|
||||
|
||||
mailProperties = [sogoObject properties];
|
||||
|
||||
headers = [[NGMutableHashMap alloc] initWithCapacity: 16];
|
||||
FillMessageHeadersFromProperties (headers, mailProperties,
|
||||
FillMessageHeadersFromProperties (headers, properties,
|
||||
[[self context] connectionInfo]);
|
||||
message = [[NGMimeMessage alloc] initWithHeader: headers];
|
||||
[message autorelease];
|
||||
[headers release];
|
||||
|
||||
messageBody = MakeMessageBody (mailProperties, attachmentParts, &contentType);
|
||||
messageBody = MakeMessageBody (properties, attachmentParts, &contentType);
|
||||
if (messageBody)
|
||||
{
|
||||
[headers setObject: contentType forKey: @"content-type"];
|
||||
|
@ -775,7 +858,7 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
|||
|
||||
- (int) submitWithFlags: (enum SubmitFlags) flags
|
||||
{
|
||||
NSDictionary *mailProperties, *recipients;
|
||||
NSDictionary *recipients;
|
||||
NSData *messageData;
|
||||
NSMutableArray *recipientEmails;
|
||||
NSArray *list;
|
||||
|
@ -785,19 +868,17 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
|||
// SOGoMailFolder *sentFolder;
|
||||
SOGoDomainDefaults *dd;
|
||||
NSException *error;
|
||||
MAPIStoreMapping *mapping;
|
||||
// MAPIStoreMapping *mapping;
|
||||
|
||||
mailProperties = [sogoObject properties];
|
||||
msgClass = [mailProperties objectForKey: MAPIPropertyKey (PidTagMessageClass)];
|
||||
msgClass = [properties objectForKey: MAPIPropertyKey (PidTagMessageClass)];
|
||||
if ([msgClass isEqualToString: @"IPM.Note"]) /* we skip invitation replies */
|
||||
{
|
||||
/* send mail */
|
||||
|
||||
messageData = [self _generateMailDataWithBcc: NO];
|
||||
|
||||
mailProperties = [sogoObject properties];
|
||||
recipientEmails = [NSMutableArray arrayWithCapacity: 32];
|
||||
recipients = [mailProperties objectForKey: @"recipients"];
|
||||
recipients = [properties objectForKey: @"recipients"];
|
||||
for (count = 0; count < 3; count++)
|
||||
{
|
||||
recId = recTypes[count];
|
||||
|
@ -819,11 +900,11 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
|||
if (error)
|
||||
[self logWithFormat: @"an error occurred: '%@'", error];
|
||||
|
||||
mapping = [self mapping];
|
||||
[mapping unregisterURLWithID: [self objectId]];
|
||||
[self setIsNew: NO];
|
||||
[properties removeAllObjects];
|
||||
[[self container] cleanupCaches];
|
||||
// mapping = [self mapping];
|
||||
// [mapping unregisterURLWithID: [self objectId]];
|
||||
// [self setIsNew: NO];
|
||||
// [properties removeAllObjects];
|
||||
[(MAPIStoreMailFolder *) [self container] cleanupCaches];
|
||||
}
|
||||
else
|
||||
[self logWithFormat: @"skipping submit of message with class '%@'",
|
||||
|
@ -834,7 +915,7 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
|||
|
||||
- (void) save
|
||||
{
|
||||
NSString *folderName, *flag, *newIdString;
|
||||
NSString *folderName, *flag, *newIdString, *messageKey;
|
||||
NSData *changeKey, *messageData;
|
||||
NGImap4Connection *connection;
|
||||
NGImap4Client *client;
|
||||
|
@ -858,23 +939,27 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts,
|
|||
responseResult = [[result objectForKey: @"RawResponse"]
|
||||
objectForKey: @"ResponseResult"];
|
||||
flag = [responseResult objectForKey: @"flag"];
|
||||
|
||||
newIdString = [[flag componentsSeparatedByString: @" "]
|
||||
objectAtIndex: 2];
|
||||
mid = [self objectId];
|
||||
mapping = [self mapping];
|
||||
mid = [self objectId];
|
||||
[mapping unregisterURLWithID: mid];
|
||||
[sogoObject setNameInContainer: [NSString stringWithFormat: @"%@.eml", newIdString]];
|
||||
[mapping registerURL: [self url] withID: mid];
|
||||
}
|
||||
// [sogoObject setNameInContainer: ];
|
||||
|
||||
/* synchronise the cache and update the change key with the one provided by
|
||||
the client */
|
||||
[(MAPIStoreMailFolder *) container synchroniseCache];
|
||||
changeKey = [[sogoObject properties]
|
||||
objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
|
||||
if (changeKey)
|
||||
[(MAPIStoreMailFolder *) container
|
||||
setChangeKey: changeKey forMessageWithKey: [self nameInContainer]];
|
||||
messageKey = [NSString stringWithFormat: @"%@.eml", newIdString];
|
||||
[sogoObject setNameInContainer: messageKey];
|
||||
[mapping registerURL: [self url] withID: mid];
|
||||
|
||||
/* synchronise the cache and update the change key with the one provided
|
||||
by the client */
|
||||
[(MAPIStoreMailFolder *) container synchroniseCache];
|
||||
changeKey = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)];
|
||||
if (changeKey)
|
||||
[(MAPIStoreMailFolder *) container
|
||||
setChangeKey: changeKey
|
||||
forMessageWithKey: messageKey];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMapping.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -54,6 +54,8 @@
|
|||
- (BOOL) registerURL: (NSString *) urlString
|
||||
withID: (uint64_t) idNbr;
|
||||
- (void) unregisterURLWithID: (uint64_t) idNbr;
|
||||
- (void) updateID: (uint64_t) idNbr
|
||||
withURL: (NSString *) urlString;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMapping.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -30,6 +30,8 @@
|
|||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
||||
#import "MAPIStoreMapping.h"
|
||||
|
@ -204,6 +206,91 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
|
|||
return idNbr;
|
||||
}
|
||||
|
||||
- (void) _updateFolderWithURL: (NSString *) oldURL
|
||||
withURL: (NSString *) urlString
|
||||
{
|
||||
NSArray *allKeys;
|
||||
NSUInteger count, max;
|
||||
NSString *currentKey, *newKey;
|
||||
NSNumber *idKey;
|
||||
TDB_DATA key, dbuf;
|
||||
|
||||
[oldURL retain];
|
||||
|
||||
allKeys = [reverseMapping allKeys];
|
||||
max = [allKeys count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentKey = [allKeys objectAtIndex: count];
|
||||
if ([currentKey hasPrefix: oldURL])
|
||||
{
|
||||
newKey = [currentKey stringByReplacingPrefix: oldURL
|
||||
withPrefix: urlString];
|
||||
|
||||
idKey = [reverseMapping objectForKey: currentKey];
|
||||
[mapping setObject: newKey forKey: idKey];
|
||||
[reverseMapping setObject: idKey forKey: newKey];
|
||||
[reverseMapping removeObjectForKey: currentKey];
|
||||
|
||||
/* update the record in the indexing database */
|
||||
key.dptr = (unsigned char *) talloc_asprintf (NULL, "0x%.16"PRIx64,
|
||||
(uint64_t) [idKey unsignedLongLongValue]);
|
||||
key.dsize = strlen ((const char *) key.dptr);
|
||||
|
||||
dbuf.dptr = (unsigned char *) talloc_strdup (NULL,
|
||||
[newKey UTF8String]);
|
||||
dbuf.dsize = strlen ((const char *) dbuf.dptr);
|
||||
tdb_store (indexing->tdb, key, dbuf, TDB_MODIFY);
|
||||
talloc_free (key.dptr);
|
||||
talloc_free (dbuf.dptr);
|
||||
}
|
||||
}
|
||||
|
||||
[oldURL release];
|
||||
}
|
||||
|
||||
- (void) updateID: (uint64_t) idNbr
|
||||
withURL: (NSString *) urlString
|
||||
{
|
||||
NSString *oldURL;
|
||||
NSNumber *idKey;
|
||||
TDB_DATA key, dbuf;
|
||||
|
||||
idKey = [NSNumber numberWithUnsignedLongLong: idNbr];
|
||||
oldURL = [mapping objectForKey: idKey];
|
||||
if (oldURL)
|
||||
{
|
||||
if ([oldURL hasSuffix: @"/"]) /* is container ? */
|
||||
{
|
||||
if (![urlString hasSuffix: @"/"])
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"a container url must have an ending '/'"];
|
||||
tdb_transaction_start (indexing->tdb);
|
||||
[self _updateFolderWithURL: oldURL withURL: urlString];
|
||||
tdb_transaction_commit (indexing->tdb);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([urlString hasSuffix: @"/"])
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"a leaf url must not have an ending '/'"];
|
||||
[mapping setObject: urlString forKey: idKey];
|
||||
[reverseMapping setObject: idKey forKey: urlString];
|
||||
[reverseMapping removeObjectForKey: oldURL];
|
||||
|
||||
/* update the record in the indexing database */
|
||||
key.dptr = (unsigned char *) talloc_asprintf(NULL, "0x%.16"PRIx64, idNbr);
|
||||
key.dsize = strlen((const char *) key.dptr);
|
||||
|
||||
dbuf.dptr = (unsigned char *) talloc_strdup (NULL, [urlString UTF8String]);
|
||||
dbuf.dsize = strlen((const char *) dbuf.dptr);
|
||||
tdb_store (indexing->tdb, key, dbuf, TDB_MODIFY);
|
||||
talloc_free (key.dptr);
|
||||
talloc_free (dbuf.dptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) registerURL: (NSString *) urlString
|
||||
withID: (uint64_t) idNbr
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMessage.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -35,9 +35,9 @@
|
|||
@class MAPIStoreAttachmentTable;
|
||||
@class MAPIStoreFolder;
|
||||
|
||||
#import "MAPIStoreObject.h"
|
||||
#import "MAPIStoreSOGoObject.h"
|
||||
|
||||
@interface MAPIStoreMessage : MAPIStoreObject
|
||||
@interface MAPIStoreMessage : MAPIStoreSOGoObject
|
||||
{
|
||||
NSArray *attachmentKeys;
|
||||
NSMutableDictionary *attachmentParts;
|
||||
|
@ -66,13 +66,13 @@
|
|||
- (int) setReadFlag: (uint8_t) flag;
|
||||
- (enum mapistore_error) saveMessage;
|
||||
|
||||
/* helper getters */
|
||||
- (int) getSMTPAddrType: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (NSArray *) activeContainerMessageTables;
|
||||
|
||||
- (NSArray *) activeUserRoles;
|
||||
|
||||
/* move & copy internal ops */
|
||||
- (void) copyToMessage: (MAPIStoreMessage *) newMessage;
|
||||
|
||||
/* subclasses */
|
||||
- (void) save;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMessage.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2011 Inverse inc
|
||||
* Copyright (C) 2011-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -36,6 +36,7 @@
|
|||
#import "MAPIStoreAttachmentTable.h"
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreFolder.h"
|
||||
#import "MAPIStoreMessageTable.h"
|
||||
#import "MAPIStorePropertySelectors.h"
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
@ -55,6 +56,7 @@
|
|||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
static NSString *resourcesDir = nil;
|
||||
static Class MAPIStoreFolderK = nil;
|
||||
|
||||
/* rtf conversion via unrtf */
|
||||
static int
|
||||
|
@ -116,7 +118,6 @@ rtf2html (NSData *compressedRTF)
|
|||
|
||||
@interface SOGoObject (MAPIStoreProtocol)
|
||||
|
||||
- (NSString *) davEntityTag;
|
||||
- (NSString *) davContentLength;
|
||||
|
||||
@end
|
||||
|
@ -130,6 +131,7 @@ rtf2html (NSData *compressedRTF)
|
|||
resourcesDir = [[NSBundle bundleForClass: self] resourcePath];
|
||||
[resourcesDir retain];
|
||||
}
|
||||
MAPIStoreFolderK = [MAPIStoreFolder class];
|
||||
}
|
||||
|
||||
- (id) init
|
||||
|
@ -304,6 +306,7 @@ rtf2html (NSData *compressedRTF)
|
|||
NSData *htmlData, *rtfData;
|
||||
static NSNumber *htmlKey = nil, *rtfKey = nil;
|
||||
|
||||
/* we intercept any RTF content and convert it to HTML */
|
||||
[super addProperties: newNewProperties];
|
||||
|
||||
if (!htmlKey)
|
||||
|
@ -339,10 +342,8 @@ rtf2html (NSData *compressedRTF)
|
|||
|
||||
newAid = [[self attachmentKeys] count];
|
||||
|
||||
newAttachment = [MAPIStoreAttachment
|
||||
mapiStoreObjectWithSOGoObject: nil
|
||||
inContainer: self];
|
||||
[newAttachment setIsNew: YES];
|
||||
newAttachment = [MAPIStoreAttachment mapiStoreObjectInContainer: self];
|
||||
// [newAttachment setIsNew: YES];
|
||||
[newAttachment setAID: newAid];
|
||||
newKey = [NSString stringWithFormat: @"%ul", newAid];
|
||||
[attachmentParts setObject: newAttachment
|
||||
|
@ -424,6 +425,41 @@ rtf2html (NSData *compressedRTF)
|
|||
andType: MAPISTORE_MESSAGE_TABLE];
|
||||
}
|
||||
|
||||
- (void) copyToMessage: (MAPIStoreMessage *) newMessage
|
||||
|
||||
{
|
||||
TALLOC_CTX *memCtx;
|
||||
struct mapistore_message *messageData;
|
||||
NSArray *keys;
|
||||
NSUInteger count, max;
|
||||
NSString *key;
|
||||
MAPIStoreAttachment *attachment, *newAttachment;
|
||||
|
||||
memCtx = talloc_zero (NULL, TALLOC_CTX);
|
||||
|
||||
/* message headers and recipients */
|
||||
[self getMessageData: &messageData inMemCtx: memCtx];
|
||||
[newMessage modifyRecipientsWithRecipients: messageData->recipients
|
||||
andCount: messageData->recipients_count
|
||||
andColumns: messageData->columns];
|
||||
|
||||
/* properties */
|
||||
[self copyPropertiesToObject: newMessage];
|
||||
|
||||
/* attachments */
|
||||
keys = [self attachmentKeys];
|
||||
max = [keys count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
key = [keys objectAtIndex: count];
|
||||
attachment = [self lookupAttachment: key];
|
||||
newAttachment = [newMessage createAttachment];
|
||||
[attachment copyToAttachment: newAttachment];
|
||||
}
|
||||
|
||||
talloc_free (memCtx);
|
||||
}
|
||||
|
||||
- (enum mapistore_error) saveMessage
|
||||
{
|
||||
enum mapistore_error rc;
|
||||
|
@ -443,62 +479,73 @@ rtf2html (NSData *compressedRTF)
|
|||
|| (!isNew && [self subscriberCanModifyMessage])))
|
||||
{
|
||||
/* notifications */
|
||||
folderId = [(MAPIStoreFolder *) container objectId];
|
||||
mstoreCtx = [[self context] connectionInfo]->mstore_ctx;
|
||||
|
||||
/* folder modified */
|
||||
notif_parameters
|
||||
= talloc_zero(NULL, struct mapistore_object_notification_parameters);
|
||||
notif_parameters->object_id = folderId;
|
||||
if (isNew)
|
||||
if ([container isKindOfClass: MAPIStoreFolderK])
|
||||
{
|
||||
notif_parameters->tag_count = 3;
|
||||
notif_parameters->tags = talloc_array (notif_parameters,
|
||||
enum MAPITAGS, 3);
|
||||
notif_parameters->tags[0] = PR_CONTENT_COUNT;
|
||||
notif_parameters->tags[1] = PR_MESSAGE_SIZE;
|
||||
notif_parameters->tags[2] = PR_NORMAL_MESSAGE_SIZE;
|
||||
notif_parameters->new_message_count = true;
|
||||
notif_parameters->message_count
|
||||
= [[(MAPIStoreFolder *) container messageKeys] count] + 1;
|
||||
}
|
||||
mapistore_push_notification (mstoreCtx,
|
||||
MAPISTORE_FOLDER, MAPISTORE_OBJECT_MODIFIED,
|
||||
notif_parameters);
|
||||
talloc_free (notif_parameters);
|
||||
folderId = [(MAPIStoreFolder *) container objectId];
|
||||
mstoreCtx = [[self context] connectionInfo]->mstore_ctx;
|
||||
|
||||
/* message created */
|
||||
if (isNew)
|
||||
{
|
||||
/* folder modified */
|
||||
notif_parameters
|
||||
= talloc_zero(NULL,
|
||||
struct mapistore_object_notification_parameters);
|
||||
notif_parameters->object_id = [self objectId];
|
||||
notif_parameters->folder_id = folderId;
|
||||
|
||||
notif_parameters->tag_count = 0xffff;
|
||||
= talloc_zero(NULL, struct mapistore_object_notification_parameters);
|
||||
notif_parameters->object_id = folderId;
|
||||
if (isNew)
|
||||
{
|
||||
notif_parameters->tag_count = 3;
|
||||
notif_parameters->tags = talloc_array (notif_parameters,
|
||||
enum MAPITAGS, 3);
|
||||
notif_parameters->tags[0] = PR_CONTENT_COUNT;
|
||||
notif_parameters->tags[1] = PR_MESSAGE_SIZE;
|
||||
notif_parameters->tags[2] = PR_NORMAL_MESSAGE_SIZE;
|
||||
notif_parameters->new_message_count = true;
|
||||
notif_parameters->message_count
|
||||
= [[(MAPIStoreFolder *) container messageKeys] count] + 1;
|
||||
}
|
||||
mapistore_push_notification (mstoreCtx,
|
||||
MAPISTORE_MESSAGE, MAPISTORE_OBJECT_CREATED,
|
||||
MAPISTORE_FOLDER,
|
||||
MAPISTORE_OBJECT_MODIFIED,
|
||||
notif_parameters);
|
||||
talloc_free (notif_parameters);
|
||||
}
|
||||
|
||||
/* we ensure the table caches are loaded so that old and new state
|
||||
can be compared */
|
||||
containerTables = [self activeContainerMessageTables];
|
||||
max = [containerTables count];
|
||||
for (count = 0; count < max; count++)
|
||||
[[containerTables objectAtIndex: count] restrictedChildKeys];
|
||||
/* message created */
|
||||
if (isNew)
|
||||
{
|
||||
notif_parameters
|
||||
= talloc_zero(NULL,
|
||||
struct mapistore_object_notification_parameters);
|
||||
notif_parameters->object_id = [self objectId];
|
||||
notif_parameters->folder_id = folderId;
|
||||
|
||||
notif_parameters->tag_count = 0xffff;
|
||||
mapistore_push_notification (mstoreCtx,
|
||||
MAPISTORE_MESSAGE, MAPISTORE_OBJECT_CREATED,
|
||||
notif_parameters);
|
||||
talloc_free (notif_parameters);
|
||||
}
|
||||
|
||||
/* we ensure the table caches are loaded so that old and new state
|
||||
can be compared */
|
||||
containerTables = [self activeContainerMessageTables];
|
||||
max = [containerTables count];
|
||||
for (count = 0; count < max; count++)
|
||||
[[containerTables objectAtIndex: count] restrictedChildKeys];
|
||||
}
|
||||
|
||||
[self save];
|
||||
/* We make sure that any change-related properties are removes from the
|
||||
properties dictionary, to make sure that related methods will be
|
||||
invoked the next time they are requested. */
|
||||
[properties removeObjectForKey: MAPIPropertyKey (PidTagChangeKey)];
|
||||
[properties removeObjectForKey: MAPIPropertyKey (PidTagChangeNumber)];
|
||||
|
||||
/* table modified */
|
||||
for (count = 0; count < max; count++)
|
||||
[[containerTables objectAtIndex: count]
|
||||
notifyChangesForChild: self];
|
||||
if ([container isKindOfClass: MAPIStoreFolderK])
|
||||
{
|
||||
/* table modified */
|
||||
for (count = 0; count < max; count++)
|
||||
[[containerTables objectAtIndex: count]
|
||||
notifyChangesForChild: self];
|
||||
[container cleanupCaches];
|
||||
}
|
||||
[self setIsNew: NO];
|
||||
[properties removeAllObjects];
|
||||
[container cleanupCaches];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
else
|
||||
|
@ -507,14 +554,6 @@ rtf2html (NSData *compressedRTF)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* helper getters */
|
||||
- (int) getSMTPAddrType: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = [@"SMTP" asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
/* getters */
|
||||
- (int) getPidTagInstID: (void **) data // TODO: DOUBT
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
|
@ -615,7 +654,8 @@ rtf2html (NSData *compressedRTF)
|
|||
- (int) getPidLidCurrentVersion: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPILongValue (memCtx, 115608); // Outlook 11.5608
|
||||
// *data = MAPILongValue (memCtx, 115608); // Outlook 11.5608
|
||||
*data = MAPILongValue (memCtx, 0x1ce3a); // Outlook 11.8330
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -655,9 +695,19 @@ rtf2html (NSData *compressedRTF)
|
|||
- (int) getPidTagMid: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPILongLongValue (memCtx, [self objectId]);
|
||||
int rc;
|
||||
uint64_t obId;
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
obId = [self objectId];
|
||||
if (obId == ULLONG_MAX)
|
||||
rc = MAPISTORE_ERR_NOT_FOUND;
|
||||
else
|
||||
{
|
||||
*data = MAPILongLongValue (memCtx, obId);
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPidTagMessageLocaleId: (void **) data
|
||||
|
@ -708,21 +758,35 @@ rtf2html (NSData *compressedRTF)
|
|||
- (int) getPidTagSubject: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
int rc;
|
||||
TALLOC_CTX *localMemCtx;
|
||||
char *prefix, *normalizedSubject;
|
||||
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
localMemCtx = talloc_zero (NULL, TALLOC_CTX);
|
||||
if ([self getProperty: (void **) &prefix
|
||||
withTag: PidTagSubjectPrefix
|
||||
inMemCtx: localMemCtx]
|
||||
!= MAPISTORE_SUCCESS)
|
||||
prefix = "";
|
||||
rc = [self getProperty: (void **) &normalizedSubject
|
||||
withTag: PidTagNormalizedSubject
|
||||
inMemCtx: localMemCtx];
|
||||
if (rc == MAPISTORE_SUCCESS)
|
||||
*data = talloc_asprintf (memCtx, "%s%s", prefix, normalizedSubject);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (int) getPidTagNormalizedSubject: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidTagSubject: data inMemCtx: memCtx];
|
||||
return MAPISTORE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
- (int) getPidTagOriginalSubject: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidTagNormalizedSubject: data inMemCtx: memCtx];
|
||||
return [self getPidTagSubject: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagConversationTopic: (void **) data
|
||||
|
@ -737,6 +801,12 @@ rtf2html (NSData *compressedRTF)
|
|||
return [self getEmptyString: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagDeleteAfterSubmit: (void **) data // TODO
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getNo: data inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagDisplayTo: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
|
@ -792,7 +862,7 @@ rtf2html (NSData *compressedRTF)
|
|||
- (int) getPidTagOriginalMessageClass: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
return [self getPidTagMessageClass: data inMemCtx: memCtx];
|
||||
return [self getProperty: data withTag: PidTagMessageClass inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
- (int) getPidTagHasAttachments: (void **) data
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMessageTable.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -28,6 +28,7 @@
|
|||
@interface MAPIStoreMessageTable : MAPIStoreTable
|
||||
|
||||
- (void) setSortOrder: (const struct SSortOrderSet *) set;
|
||||
- (void) notifyChangesForChild: (MAPIStoreMessage *) child;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreMessageTable.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc
|
||||
* Copyright (C) 2010-2012 Inverse inc
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -27,7 +27,9 @@
|
|||
#import <SOGo/SOGoFolder.h>
|
||||
#import <SOGo/SOGoObject.h>
|
||||
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreFolder.h"
|
||||
#import "MAPIStoreMessage.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
@ -83,4 +85,60 @@
|
|||
return [(MAPIStoreFolder *) container lookupMessage: childKey];
|
||||
}
|
||||
|
||||
- (void) notifyChangesForChild: (MAPIStoreMessage *) child
|
||||
{
|
||||
NSUInteger currentChildRow, newChildRow;
|
||||
NSArray *list;
|
||||
NSString *childName;
|
||||
struct mapistore_table_notification_parameters notif_parameters;
|
||||
struct mapistore_context *mstoreCtx;
|
||||
|
||||
mstoreCtx = [[(MAPIStoreFolder *) container context]
|
||||
connectionInfo]->mstore_ctx;
|
||||
|
||||
notif_parameters.table_type = tableType;
|
||||
notif_parameters.handle = handleId;
|
||||
notif_parameters.folder_id = [(MAPIStoreFolder *) container objectId];
|
||||
notif_parameters.object_id = [child objectId];
|
||||
notif_parameters.instance_id = 0; /* TODO: always 0 ? */
|
||||
|
||||
childName = [child nameInContainer];
|
||||
list = [self restrictedChildKeys];
|
||||
currentChildRow = [list indexOfObject: childName];
|
||||
notif_parameters.row_id = currentChildRow;
|
||||
|
||||
[self cleanupCaches];
|
||||
list = [self restrictedChildKeys];
|
||||
newChildRow = [list indexOfObject: childName];
|
||||
|
||||
if (currentChildRow == NSNotFound)
|
||||
{
|
||||
if (newChildRow != NSNotFound)
|
||||
{
|
||||
notif_parameters.row_id = newChildRow;
|
||||
mapistore_push_notification (mstoreCtx,
|
||||
MAPISTORE_TABLE,
|
||||
MAPISTORE_OBJECT_CREATED,
|
||||
¬if_parameters);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (newChildRow == NSNotFound)
|
||||
mapistore_push_notification (mstoreCtx,
|
||||
MAPISTORE_TABLE,
|
||||
MAPISTORE_OBJECT_DELETED,
|
||||
¬if_parameters);
|
||||
else
|
||||
{
|
||||
/* the fact that the row order has changed has no impact here */
|
||||
notif_parameters.row_id = newChildRow;
|
||||
mapistore_push_notification (mstoreCtx,
|
||||
MAPISTORE_TABLE,
|
||||
MAPISTORE_OBJECT_MODIFIED,
|
||||
¬if_parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreNotesContext.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010-2012 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -23,9 +23,9 @@
|
|||
#ifndef MAPISTORENOTESCONTEXT_H
|
||||
#define MAPISTORENOTESCONTEXT_H
|
||||
|
||||
#import "MAPIStoreFSBaseContext.h"
|
||||
#import "MAPIStoreDBBaseContext.h"
|
||||
|
||||
@interface MAPIStoreNotesContext : MAPIStoreFSBaseContext
|
||||
@interface MAPIStoreNotesContext : MAPIStoreDBBaseContext
|
||||
|
||||
@end
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue