diff --git a/OpenChange/COPYING b/OpenChange/COPYING deleted file mode 100644 index 94a9ed024..000000000 --- a/OpenChange/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/OpenChange/Codepages.h b/OpenChange/Codepages.h deleted file mode 100644 index 60d8223d8..000000000 --- a/OpenChange/Codepages.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Codepages.h - this file is part of SOGo - * - * Copyright (C) 2014 Jesús García Sáez - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#import -#import -#import - - -@interface Codepages - -+ (NSDictionary *) getCodepagesTable; -+ (NSDictionary *) getReverseCodepagesTable; - -+ (NSNumber *) getCodepageFromName: (NSString *) name; -+ (NSString *) getNameFromCodepage: (NSNumber *) codepage; - -@end diff --git a/OpenChange/Codepages.m b/OpenChange/Codepages.m deleted file mode 100644 index 8776ffe22..000000000 --- a/OpenChange/Codepages.m +++ /dev/null @@ -1,214 +0,0 @@ -/* Codepages.m - this file is part of SOGo - * - * Copyright (C) 2014 Jesús García Sáez - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#import "Codepages.h" -#import - -@implementation Codepages - -+ (NSDictionary *) getCodepagesTable -{ - static NSDictionary *table = nil; - - if (table == nil) - { - /* http://msdn.microsoft.com/en-us/library/dd317756%28v=vs.85%29.aspx */ - table = [[NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt: 37], @"ibm037", - [NSNumber numberWithInt: 437], @"ibm437", - [NSNumber numberWithInt: 500], @"ibm500", - [NSNumber numberWithInt: 708], @"asmo-708", - [NSNumber numberWithInt: 720], @"dos-720", - [NSNumber numberWithInt: 737], @"ibm737", - [NSNumber numberWithInt: 775], @"ibm775", - [NSNumber numberWithInt: 850], @"ibm850", - [NSNumber numberWithInt: 852], @"ibm852", - [NSNumber numberWithInt: 855], @"ibm855", - [NSNumber numberWithInt: 857], @"ibm857", - [NSNumber numberWithInt: 858], @"ibm00858", - [NSNumber numberWithInt: 860], @"ibm860", - [NSNumber numberWithInt: 861], @"ibm861", - [NSNumber numberWithInt: 862], @"dos-862", - [NSNumber numberWithInt: 863], @"ibm863", - [NSNumber numberWithInt: 864], @"ibm864", - [NSNumber numberWithInt: 865], @"ibm865", - [NSNumber numberWithInt: 866], @"cp866", - [NSNumber numberWithInt: 869], @"ibm869", - [NSNumber numberWithInt: 870], @"ibm870", - [NSNumber numberWithInt: 874], @"windows-874", - [NSNumber numberWithInt: 875], @"cp875", - [NSNumber numberWithInt: 932], @"shift_jis", - [NSNumber numberWithInt: 936], @"gb2312", - [NSNumber numberWithInt: 949], @"ks_c_5601-1987", - [NSNumber numberWithInt: 950], @"big5", - [NSNumber numberWithInt: 1026], @"ibm1026", - [NSNumber numberWithInt: 1047], @"ibm01047", - [NSNumber numberWithInt: 1140], @"ibm01140", - [NSNumber numberWithInt: 1141], @"ibm01141", - [NSNumber numberWithInt: 1142], @"ibm01142", - [NSNumber numberWithInt: 1143], @"ibm01143", - [NSNumber numberWithInt: 1144], @"ibm01144", - [NSNumber numberWithInt: 1145], @"ibm01145", - [NSNumber numberWithInt: 1146], @"ibm01146", - [NSNumber numberWithInt: 1147], @"ibm01147", - [NSNumber numberWithInt: 1148], @"ibm01148", - [NSNumber numberWithInt: 1149], @"ibm01149", - [NSNumber numberWithInt: 1200], @"utf-16", - [NSNumber numberWithInt: 1201], @"unicodefffe", - [NSNumber numberWithInt: 1250], @"windows-1250", - [NSNumber numberWithInt: 1251], @"windows-1251", - [NSNumber numberWithInt: 1252], @"windows-1252", - [NSNumber numberWithInt: 1253], @"windows-1253", - [NSNumber numberWithInt: 1254], @"windows-1254", - [NSNumber numberWithInt: 1255], @"windows-1255", - [NSNumber numberWithInt: 1256], @"windows-1256", - [NSNumber numberWithInt: 1257], @"windows-1257", - [NSNumber numberWithInt: 1258], @"windows-1258", - [NSNumber numberWithInt: 1361], @"johab", - [NSNumber numberWithInt: 10000], @"macintosh", - [NSNumber numberWithInt: 10001], @"x-mac-japanese", - [NSNumber numberWithInt: 10002], @"x-mac-chinesetrad", - [NSNumber numberWithInt: 10003], @"x-mac-korean", - [NSNumber numberWithInt: 10004], @"x-mac-arabic", - [NSNumber numberWithInt: 10005], @"x-mac-hebrew", - [NSNumber numberWithInt: 10006], @"x-mac-greek", - [NSNumber numberWithInt: 10007], @"x-mac-cyrillic", - [NSNumber numberWithInt: 10008], @"x-mac-chinesesimp", - [NSNumber numberWithInt: 10010], @"x-mac-romanian", - [NSNumber numberWithInt: 10017], @"x-mac-ukrainian", - [NSNumber numberWithInt: 10021], @"x-mac-thai", - [NSNumber numberWithInt: 10029], @"x-mac-ce", - [NSNumber numberWithInt: 10079], @"x-mac-icelandic", - [NSNumber numberWithInt: 10081], @"x-mac-turkish", - [NSNumber numberWithInt: 10082], @"x-mac-croatian", - [NSNumber numberWithInt: 12000], @"utf-32", - [NSNumber numberWithInt: 12001], @"utf-32be", - [NSNumber numberWithInt: 20000], @"x-chinese-cns", - [NSNumber numberWithInt: 20001], @"x-cp20001", - [NSNumber numberWithInt: 20002], @"x-chinese-eten", - [NSNumber numberWithInt: 20003], @"x-cp20003", - [NSNumber numberWithInt: 20004], @"x-cp20004", - [NSNumber numberWithInt: 20005], @"x-cp20005", - [NSNumber numberWithInt: 20105], @"x-ia5", - [NSNumber numberWithInt: 20106], @"x-ia5-german", - [NSNumber numberWithInt: 20107], @"x-ia5-swedish", - [NSNumber numberWithInt: 20108], @"x-ia5-norwegian", - [NSNumber numberWithInt: 20127], @"us-ascii", - [NSNumber numberWithInt: 20261], @"x-cp20261", - [NSNumber numberWithInt: 20269], @"x-cp20269", - [NSNumber numberWithInt: 20273], @"ibm273", - [NSNumber numberWithInt: 20277], @"ibm277", - [NSNumber numberWithInt: 20278], @"ibm278", - [NSNumber numberWithInt: 20280], @"ibm280", - [NSNumber numberWithInt: 20284], @"ibm284", - [NSNumber numberWithInt: 20285], @"ibm285", - [NSNumber numberWithInt: 20290], @"ibm290", - [NSNumber numberWithInt: 20297], @"ibm297", - [NSNumber numberWithInt: 20420], @"ibm420", - [NSNumber numberWithInt: 20423], @"ibm423", - [NSNumber numberWithInt: 20424], @"ibm424", - [NSNumber numberWithInt: 20833], @"x-ebcdic-koreanextended", - [NSNumber numberWithInt: 20838], @"ibm-thai", - [NSNumber numberWithInt: 20866], @"koi8-r", - [NSNumber numberWithInt: 20871], @"ibm871", - [NSNumber numberWithInt: 20880], @"ibm880", - [NSNumber numberWithInt: 20905], @"ibm905", - [NSNumber numberWithInt: 20924], @"ibm00924", - [NSNumber numberWithInt: 20932], @"euc-jp", - [NSNumber numberWithInt: 20936], @"x-cp20936", - [NSNumber numberWithInt: 20949], @"x-cp20949", - [NSNumber numberWithInt: 21025], @"cp1025", - [NSNumber numberWithInt: 21866], @"koi8-u", - [NSNumber numberWithInt: 28591], @"iso-8859-1", - [NSNumber numberWithInt: 28592], @"iso-8859-2", - [NSNumber numberWithInt: 28593], @"iso-8859-3", - [NSNumber numberWithInt: 28594], @"iso-8859-4", - [NSNumber numberWithInt: 28595], @"iso-8859-5", - [NSNumber numberWithInt: 28596], @"iso-8859-6", - [NSNumber numberWithInt: 28597], @"iso-8859-7", - [NSNumber numberWithInt: 28598], @"iso-8859-8", - [NSNumber numberWithInt: 28599], @"iso-8859-9", - [NSNumber numberWithInt: 28603], @"iso-8859-13", - [NSNumber numberWithInt: 28605], @"iso-8859-15", - [NSNumber numberWithInt: 29001], @"x-europa", - [NSNumber numberWithInt: 38598], @"iso-8859-8-i", - [NSNumber numberWithInt: 50220], @"iso-2022-jp", - [NSNumber numberWithInt: 50221], @"csiso2022jp", - [NSNumber numberWithInt: 50222], @"iso-2022-jp", - [NSNumber numberWithInt: 50225], @"iso-2022-kr", - [NSNumber numberWithInt: 50227], @"x-cp50227", - [NSNumber numberWithInt: 51932], @"euc-jp", - [NSNumber numberWithInt: 51936], @"euc-cn", - [NSNumber numberWithInt: 51949], @"euc-kr", - [NSNumber numberWithInt: 52936], @"hz-gb-2312", - [NSNumber numberWithInt: 54936], @"gb18030", - [NSNumber numberWithInt: 57002], @"x-iscii-de", - [NSNumber numberWithInt: 57003], @"x-iscii-be", - [NSNumber numberWithInt: 57004], @"x-iscii-ta", - [NSNumber numberWithInt: 57005], @"x-iscii-te", - [NSNumber numberWithInt: 57006], @"x-iscii-as", - [NSNumber numberWithInt: 57007], @"x-iscii-or", - [NSNumber numberWithInt: 57008], @"x-iscii-ka", - [NSNumber numberWithInt: 57009], @"x-iscii-ma", - [NSNumber numberWithInt: 57010], @"x-iscii-gu", - [NSNumber numberWithInt: 57011], @"x-iscii-pa", - [NSNumber numberWithInt: 65000], @"utf-7", - [NSNumber numberWithInt: 65001], @"utf-8", - nil] retain]; - } - return table; -} - -+ (NSDictionary *) getReverseCodepagesTable -{ - static NSDictionary *table = nil; - - if (table == nil) - { - NSDictionary *codepages_table; - NSEnumerator *enumerator; - NSMutableArray *codepages, *names; - id key; - // Build reverse table: (NSNumber) codepage -> (NSString) encoding name - codepages_table = [self getCodepagesTable]; - codepages = [NSMutableArray arrayWithCapacity: [codepages_table count]]; - names = [NSMutableArray arrayWithCapacity: [codepages_table count]]; - enumerator = [codepages_table keyEnumerator]; - while ((key = [enumerator nextObject])) - { - [names addObject: key]; - [codepages addObject: [codepages_table objectForKey: key]]; - } - table = [[NSDictionary dictionaryWithObjects: names forKeys: codepages] retain]; - } - return table; -} - -+ (NSNumber *) getCodepageFromName: (NSString *) name -{ - return [[self getCodepagesTable] objectForKey: [name lowercaseString]]; -} - -+ (NSString *) getNameFromCodepage: (NSNumber *) codepage -{ - return [[self getReverseCodepagesTable] objectForKey: codepage]; -} - -@end diff --git a/OpenChange/GNUmakefile b/OpenChange/GNUmakefile deleted file mode 100644 index 739fbd95b..000000000 --- a/OpenChange/GNUmakefile +++ /dev/null @@ -1,200 +0,0 @@ - -# GNUstep makefile - -include ../config.make -include $(GNUSTEP_MAKEFILES)/common.make -include ../Version - -BACKEND_VERSION = 1.0.0 - -### bootstrap library -MAPISTORESOGO = MAPIStoreSOGo -LIBRARY_NAME = $(MAPISTORESOGO) - -$(MAPISTORESOGO)_VERSION = $(BACKEND_VERSION) - -$(MAPISTORESOGO)_OBJC_FILES += \ - MAPIStoreSOGo.m - -### backend bundle -SOGOBACKEND = SOGoBackend -BUNDLE_NAME = $(SOGOBACKEND) -BUNDLE_EXTENSION = .MAPIStore -BUNDLE_INSTALL_DIR = $(SOGO_LIBDIR) - -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' || echo /var/lib/samba/private) - -$(SOGOBACKEND)_PRINCIPAL_CLASS = MAPIApplication - -$(SOGOBACKEND)_OBJC_FILES += \ - MAPIApplication.m \ - MAPIStoreActiveTables.m \ - MAPIStoreAuthenticator.m \ - MAPIStoreMapping.m \ - MAPIStoreMIME.m \ - MAPIStoreTypes.m \ - MAPIStorePropertySelectors.m \ - MAPIStoreSamDBUtils.m \ - MAPIStoreUserContext.m \ - \ - SOGoMAPIDBMessage.m \ - SOGoCacheGCSObject+MAPIStore.m \ - \ - MAPIStoreAppointmentWrapper.m \ - MAPIStoreAttachment.m \ - MAPIStoreAttachmentTable.m \ - MAPIStoreContext.m \ - MAPIStoreEmbeddedMessage.m \ - MAPIStoreFolder.m \ - MAPIStoreMessage.m \ - MAPIStoreObject.m \ - MAPIStoreObjectProxy.m \ - MAPIStoreSOGoObject.m \ - MAPIStoreTable.m \ - MAPIStoreMessageTable.m \ - MAPIStoreFolderTable.m \ - MAPIStorePermissionsTable.m \ - \ - MAPIStoreDBBaseContext.m \ - MAPIStoreDBFolder.m \ - MAPIStoreDBFolderTable.m \ - MAPIStoreDBMessage.m \ - MAPIStoreDBMessageTable.m \ - \ - MAPIStoreFAIMessage.m \ - MAPIStoreFAIMessageTable.m \ - \ - MAPIStoreGCSBaseContext.m \ - MAPIStoreGCSFolder.m \ - MAPIStoreGCSMessage.m \ - MAPIStoreGCSMessageTable.m \ - \ - MAPIStoreCalTaskFolder.m \ - MAPIStoreCalTaskMessage.m \ - \ - MAPIStoreCalendarAttachment.m \ - MAPIStoreCalendarContext.m \ - MAPIStoreCalendarFolder.m \ - MAPIStoreCalendarMessage.m \ - MAPIStoreCalendarEmbeddedMessage.m \ - MAPIStoreCalendarMessageTable.m \ - MAPIStoreRecurrenceUtils.m \ - \ - MAPIStoreContactsAttachment.m \ - MAPIStoreContactsContext.m \ - MAPIStoreContactsFolder.m \ - MAPIStoreContactsMessage.m \ - MAPIStoreContactsMessageTable.m \ - \ - MAPIStoreTasksContext.m \ - MAPIStoreTasksFolder.m \ - MAPIStoreTasksMessage.m \ - MAPIStoreTasksMessageTable.m \ - \ - MAPIStoreMailAttachment.m \ - MAPIStoreMailContext.m \ - MAPIStoreMailFolder.m \ - MAPIStoreMailFolderTable.m \ - MAPIStoreMailMessage.m \ - MAPIStoreMailVolatileMessage.m \ - MAPIStoreMailMessageTable.m \ - \ - MAPIStoreNotesContext.m \ - MAPIStoreNotesFolder.m \ - MAPIStoreNotesMessage.m \ - \ - MAPIStoreFallbackContext.m \ - \ - MAPIStoreSharingMessage.m \ - \ - NSArray+MAPIStore.m \ - NSData+MAPIStore.m \ - NSDate+MAPIStore.m \ - NSObject+MAPIStore.m \ - NSString+MAPIStore.m \ - NSValue+MAPIStore.m \ - \ - iCalEvent+MAPIStore.m \ - iCalTimeZone+MAPIStore.m \ - \ - RTFHandler.m \ - \ - Codepages.m - - -$(SOGOBACKEND)_RESOURCE_FILES += \ - product.plist - -### pl reader -PLREADER_TOOL = plreader -$(PLREADER_TOOL)_OBJC_FILES += \ - plreader.m \ - -DBMSGREADER_TOOL = dbmsgreader -$(DBMSGREADER_TOOL)_OBJC_FILES += \ - dbmsgreader.m \ - NSObject+PropertyList.m - -$(DBMSGREADER_TOOL)_LIB_DIRS += \ - -L../SoObjects/SOGo/SOGo.framework/sogo -lSOGo \ - -L../SOPE/GDLContentStore/obj/ -lGDLContentStore \ - -L../SOPE/NGCards/obj/ -lNGCards \ - -lNGObjWeb \ - $(LIBMAPI_LIBS) - -TEST_TOOL_NAME += $(PLREADER_TOOL) $(DBMSGREADER_TOOL) - -### cflags and libs -LIBMAPI_CFLAGS = $(shell pkg-config libmapi --cflags) - -ifeq ($(LIBMAPI_CFLAGS),) -all install:: - @echo "Cannot build the OpenChange SOGo backend (empty CFLAGS for libmapistore)" -else - -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 -lWEExtensions - -$(MAPISTORESOGO)_INSTALL_DIR = $(DESTDIR)/$(SAMBA_LIB_DIR)/mapistore_backends -$(MAPISTORESOGO)_LIB_DIRS += \ - -L../SoObjects/SOGo/SOGo.framework/sogo/ -lSOGo -lgnustep-base -lobjc -lNGObjWeb \ - $(LIBMAPI_LIBS) \ - $(LIBMAPISTORE_LIBS) - -$(SOGOBACKEND)_LIB_DIRS += \ - -L../SoObjects/SOGo/SOGo.framework/sogo/ -lSOGo \ - $(LIBMAPI_LIBS) \ - $(LIBMAPISTORE_LIBS) - -ADDITIONAL_INCLUDE_DIRS += \ - -Wall \ - -DSAMBA_PRIVATE_DIR=@"\"$(SAMBA_PRIVATE_DIR)\"" \ - $(LIBMAPI_CFLAGS) \ - $(LIBMAPISTORE_CFLAGS) \ - -I../SoObjects -I../SOPE \ - -DBACKEND_BUNDLE_NAME="@\"$(BUNDLE_NAME)$(BUNDLE_EXTENSION)\"" \ - -DSOGO_BUNDLES_DIR="@\"$(BUNDLE_INSTALL_DIR)\"" - -ADDITIONAL_LDFLAGS += -Wl,--rpath,$(SOGO_SYSLIBDIR)/sogo - --include GNUmakefile.preamble -include $(GNUSTEP_MAKEFILES)/bundle.make -include $(GNUSTEP_MAKEFILES)/library.make -include $(GNUSTEP_MAKEFILES)/test-tool.make -include $(GNUSTEP_MAKEFILES)/aggregate.make --include GNUmakefile.postamble - -endif diff --git a/OpenChange/GNUmakefile.preamble b/OpenChange/GNUmakefile.preamble deleted file mode 100644 index 7dba896b6..000000000 --- a/OpenChange/GNUmakefile.preamble +++ /dev/null @@ -1,8 +0,0 @@ -all:: MAPIStorePropertySelectors.m MAPIStorePropertySelectors.h - -MAPIStorePropertySelectors.m MAPIStorePropertySelectors.h: gen-property-selectors.py code-MAPIStorePropertySelectors.m code-MAPIStorePropertySelectors.h - @echo " Auto-generating MAPIStorePropertySelectors.[hm]..." - @$(PYTHON) ./gen-property-selectors.py -o MAPIStorePropertySelectors $(LIBMAPISTORE_CFLAGS) - -distclean clean:: - -rm -f MAPIStorePropertySelectors.m MAPIStorePropertySelectors.h diff --git a/OpenChange/MAPIApplication.h b/OpenChange/MAPIApplication.h deleted file mode 100644 index 44fdaa15a..000000000 --- a/OpenChange/MAPIApplication.h +++ /dev/null @@ -1,44 +0,0 @@ -/* MAPIApplication.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPIAPPLICATION_H -#define MAPIAPPLICATION_H - -#import - -@class MAPIStoreUserContext; - -@interface MAPIApplication : SoApplication -{ - MAPIStoreUserContext *userContext; -} - -- (id) authenticatorInContext: (id) context; -- (MAPIStoreUserContext *) userContext; -- (void) setUserContext: (MAPIStoreUserContext *) newContext; -- (void) cleanup; - -@end - -extern MAPIApplication *MAPIApp; - -#endif /* MAPIAPPLICATION_H */ diff --git a/OpenChange/MAPIApplication.m b/OpenChange/MAPIApplication.m deleted file mode 100644 index 818ec1199..000000000 --- a/OpenChange/MAPIApplication.m +++ /dev/null @@ -1,101 +0,0 @@ -/* MAPIApplication.m - this file is part of SOGo - * - * Copyright (C) 2010 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import - -#import -#import - -#import - -#import "MAPIStoreUserContext.h" -#import "MAPIStoreTypes.h" - -#import "MAPIApplication.h" - -MAPIApplication *MAPIApp = nil; - -@implementation MAPIApplication - -+ (BOOL) isCachingEnabled; -{ - return NO; -} - -- (NSString *) name -{ - return @"SOGo"; -} - -- (id) init -{ - 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]; - } - - return MAPIApp; -} - -- (BOOL) shouldSetupSignalHandlers -{ - return NO; -} - -- (MAPIStoreUserContext *) userContext -{ - return userContext; -} - -- (void) setUserContext: (MAPIStoreUserContext *) newContext -{ - /* user contexts must not be retained here ad their holder (mapistore) - contexts must be active when any operation occurs. */ - userContext = newContext; -} - -- (id) authenticatorInContext: (id) context -{ - return [userContext authenticator]; -} - -- (void) cleanup -{ - [userContext deactivate]; -} - -@end diff --git a/OpenChange/MAPIStoreActiveTables.h b/OpenChange/MAPIStoreActiveTables.h deleted file mode 100644 index 8459bd9c1..000000000 --- a/OpenChange/MAPIStoreActiveTables.h +++ /dev/null @@ -1,47 +0,0 @@ -/* MAPIStoreActiveTables.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREACTIVETABLES_H -#define MAPISTOREACTIVETABLES_H - -#import - -@class NSMutableArray; - -@class MAPIStoreTable; - -@interface MAPIStoreActiveTables : NSObject -{ - NSMutableArray *records; -} - -+ (id) activeTables; - -- (void) registerTable: (MAPIStoreTable *) table; -- (void) unregisterTable: (MAPIStoreTable *) table; - -- (NSArray *) activeTablesForFMID: (uint64_t) fmid - andType: (uint8_t) tableType; - -@end - -#endif /* MAPISTOREACTIVETABLES_H */ diff --git a/OpenChange/MAPIStoreActiveTables.m b/OpenChange/MAPIStoreActiveTables.m deleted file mode 100644 index a9cb0c254..000000000 --- a/OpenChange/MAPIStoreActiveTables.m +++ /dev/null @@ -1,198 +0,0 @@ -/* MAPIStoreActiveTables.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -/* MAPIStoreActiveTables provides an interface to keep accounting of all - instances of a given table, independently from its store and context. - Primary useful for notifications across different connections. */ - -#import -#import - -#import "MAPIStoreFolder.h" -#import "MAPIStoreTable.h" - -#import "MAPIStoreActiveTables.h" - -@interface MAPIStoreActiveTableRecord : NSObject -{ - uint64_t folderId; - uint8_t tableType; - MAPIStoreTable *table; -} - -+ (id) recordForTable: (MAPIStoreTable *) newTable; -- (id) initWithTable: (MAPIStoreTable *) newTable; - -- (MAPIStoreTable *) table; - -- (BOOL) exactlyMatchesTable: (MAPIStoreTable *) otherTable; -- (BOOL) matchesFMID: (uint64_t) otherFMid - andTableType: (uint8_t) otherTableType; -- (BOOL) matchesTable: (MAPIStoreTable *) otherTable; - -@end - -@implementation MAPIStoreActiveTableRecord : NSObject - -+ (id) recordForTable: (MAPIStoreTable *) newTable -{ - MAPIStoreActiveTableRecord *record; - - record = [[self alloc] initWithTable: newTable]; - [record autorelease]; - - return record; -} - -- (id) init -{ - if ((self = [super init])) - { - folderId = 0; - tableType = 0; - table = nil; - } - - return self; -} - -- (id) initWithTable: (MAPIStoreTable *) newTable -{ - if ((self = [self init])) - { - table = newTable; - folderId = [[table container] objectId]; - tableType = [table tableType]; - } - - return self; -} - -- (MAPIStoreTable *) table -{ - return table; -} - -- (BOOL) exactlyMatchesTable: (MAPIStoreTable *) otherTable -{ - return (table == otherTable); -} - -- (BOOL) matchesFMID: (uint64_t) otherFMid - andTableType: (uint8_t) otherTableType -{ - return (tableType == otherTableType - && folderId == otherFMid); -} - -- (BOOL) matchesTable: (MAPIStoreTable *) otherTable -{ - uint64_t otherFMid; - BOOL rc; - - rc = [self exactlyMatchesTable: otherTable]; - if (!rc) - { - otherFMid = [[otherTable container] objectId]; - rc = [self matchesFMID: otherFMid andTableType: [otherTable tableType]]; - } - - return rc; -} - -@end - -@implementation MAPIStoreActiveTables - -+ (id) activeTables -{ - static MAPIStoreActiveTables *activeTables = nil; - - if (!activeTables) - activeTables = [self new]; - - return activeTables; -} - -- (id) init -{ - if ((self = [super init])) - { - records = [NSMutableArray new]; - } - - return self; -} - -- (void) dealloc -{ - [records release]; - [super dealloc]; -} - -- (void) registerTable: (MAPIStoreTable *) table -{ - MAPIStoreActiveTableRecord *newRecord; - - newRecord = [MAPIStoreActiveTableRecord recordForTable: table]; - [records addObject: newRecord]; -} - -- (void) unregisterTable: (MAPIStoreTable *) table -{ - MAPIStoreActiveTableRecord *currentRecord; - NSUInteger count, max; - BOOL done = NO; - - max = [records count]; - for (count = 0; !done && count < max; count++) - { - currentRecord = [records objectAtIndex: count]; - if ([currentRecord exactlyMatchesTable: table]) - { - [records removeObject: currentRecord]; - done = YES; - } - } -} - -- (NSArray *) activeTablesForFMID: (uint64_t) fmid - andType: (uint8_t) tableType -{ - NSUInteger count, max; - NSMutableArray *tables; - MAPIStoreActiveTableRecord *currentRecord; - - tables = [NSMutableArray arrayWithCapacity: 5]; - - max = [records count]; - for (count = 0; count < max; count++) - { - currentRecord = [records objectAtIndex: count]; - if ([currentRecord matchesFMID: fmid andTableType: tableType]) - [tables addObject: [currentRecord table]]; - } - - return tables; -} - -@end diff --git a/OpenChange/MAPIStoreAppointmentWrapper.h b/OpenChange/MAPIStoreAppointmentWrapper.h deleted file mode 100644 index 5ed4c83ff..000000000 --- a/OpenChange/MAPIStoreAppointmentWrapper.h +++ /dev/null @@ -1,177 +0,0 @@ -/* MAPIStoreAppointmentWrapper.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORECALENDARWRAPPER_H -#define MAPISTORECALENDARWRAPPER_H - -#import -#import -#import - -#import "MAPIStoreObjectProxy.h" - -@class NSTimeZone; - -@class iCalAlarm; -@class iCalCalendar; -@class iCalEvent; - -@class SOGoUser; - -@interface MAPIStoreAppointmentWrapper : MAPIStoreObjectProxy -{ - struct mapistore_connection_info *connInfo; - iCalCalendar *calendar; - iCalEvent *firstEvent; - iCalEvent *event; - iCalTimeZone *timeZone; - SOGoUser *user; - NSString *senderEmail; - NSData *globalObjectId; - NSData *cleanGlobalObjectId; - BOOL alarmSet; - iCalAlarm *alarm; - BOOL itipSetup; - NSString *method; - iCalPersonPartStat partstat; -} - -+ (id) wrapperWithICalEvent: (iCalEvent *) newEvent - andUser: (SOGoUser *) newUser - andSenderEmail: (NSString *) newSenderEmail - withConnectionInfo: (struct mapistore_connection_info *) newConnInfo; -- (id) initWithICalEvent: (iCalEvent *) newEvent - andUser: (SOGoUser *) newUser - andSenderEmail: (NSString *) newSenderEmail - withConnectionInfo: (struct mapistore_connection_info *) newConnInfo; - -/* getters */ -- (void) fillMessageData: (struct mapistore_message *) dataPtr - inMemCtx: (TALLOC_CTX *) memCtx; - -- (NSString *) creator; -- (NSString *) owner; -- (NSUInteger) sensitivity; - -- (enum mapistore_error) getPidTagSenderEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagSenderAddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagSenderName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagSenderEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; - -- (enum mapistore_error) getPidTagReceivedByAddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagReceivedByEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagReceivedByName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagReceivedByEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; - -- (enum mapistore_error) getPidTagIconIndex: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagOwnerAppointmentId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidMeetingType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagStartDate: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidAppointmentSequence: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidAppointmentStateFlags: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidResponseStatus: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; - -- (enum mapistore_error) getPidLidAppointmentStartWhole: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidCommonStart: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagEndDate: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidAppointmentEndWhole: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidCommonEnd: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidAppointmentDuration: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidAppointmentSubType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidBusyStatus: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidIndentedBusyStatus: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagNormalizedSubject: (void **) data // SUMMARY - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidLocation: (void **) data // LOCATION - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidPrivate: (void **) data // private (bool), should depend on CLASS and permissions - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagSensitivity: (void **) data // not implemented, depends on CLASS - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagImportance: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagBody: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidIsRecurring: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidRecurring: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidAppointmentRecur: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidGlobalObjectId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidCleanGlobalObjectId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidServerProcessed: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidServerProcessingActions: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidAppointmentReplyTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; - -/* reminders */ -- (enum mapistore_error) getPidLidReminderSet: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidReminderDelta: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidReminderTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidReminderSignalTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidReminderOverride: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidReminderType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidReminderPlaySound: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidReminderFileParameter: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; - -@end - -#endif /* MAPISTORECALENDARWRAPPER_H */ diff --git a/OpenChange/MAPIStoreAppointmentWrapper.m b/OpenChange/MAPIStoreAppointmentWrapper.m deleted file mode 100644 index 1881a16a5..000000000 --- a/OpenChange/MAPIStoreAppointmentWrapper.m +++ /dev/null @@ -1,2115 +0,0 @@ -/* MAPIStoreAppointmentWrapper.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -#include - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "iCalTimeZone+MAPIStore.h" -#import "MAPIStoreRecurrenceUtils.h" -#import "MAPIStoreSamDBUtils.h" -#import "MAPIStoreTypes.h" -#import "NSArray+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSDate+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreAppointmentWrapper.h" - -#undef DEBUG -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static NSCharacterSet *hexCharacterSet = nil; - -@implementation MAPIStoreAppointmentWrapper - -+ (void) initialize -{ - if (!hexCharacterSet) - { - hexCharacterSet = [NSCharacterSet characterSetWithCharactersInString: @"1234567890abcdefABCDEF"]; - [hexCharacterSet retain]; - } -} - -+ (id) wrapperWithICalEvent: (iCalEvent *) newEvent - andUser: (SOGoUser *) newUser - andSenderEmail: (NSString *) newSenderEmail - withConnectionInfo: (struct mapistore_connection_info *) newConnInfo -{ - MAPIStoreAppointmentWrapper *wrapper; - - wrapper = [[self alloc] initWithICalEvent: newEvent - andUser: newUser - andSenderEmail: newSenderEmail - withConnectionInfo: newConnInfo]; - [wrapper autorelease]; - - return wrapper; -} - -- (id) init -{ - if ((self = [super init])) - { - connInfo = NULL; - calendar = nil; - event = nil; - timeZone = nil; - senderEmail = nil; - globalObjectId = nil; - cleanGlobalObjectId = nil; - user = nil; - alarmSet = NO; - itipSetup = NO; - alarm = nil; - method = nil; - } - - return self; -} - -- (void) _setupITIPContextFromAttendees -{ - iCalPerson *attendee = nil; - NSArray *attendees; - - attendee = [event userAsAttendee: user]; - if (attendee) - method = @"REQUEST"; - else if ([event userIsOrganizer: user]) - { - if (senderEmail) - attendee = [event findAttendeeWithEmail: senderEmail]; - if (!attendee) - { - attendees = [event attendees]; - if ([attendees count] == 1) - attendee = [attendees objectAtIndex: 0]; - } - if (attendee) - { - method = @"REPLY"; - partstat = [attendee participationStatus]; - } - else - { - [self logWithFormat: @"no attendee matching sender found"]; - method = nil; - } - } - else - method = nil; - - [method retain]; -} - -- (void) _setupITIPContext -{ - NSArray *attendees; - NSUInteger max; - - /* Here we attempt to determine the type of message from the ITIP method - contained in the event. It it fails, we attempt to determine this by - checking the identity of the organizer and of the attendees. */ - itipSetup = YES; - method = [[event parent] method]; - if ([method length] > 0) - { - method = [method uppercaseString]; - [method retain]; - if ([method isEqualToString: @"REPLY"]) - { - attendees = [event attendees]; - max = [attendees count]; - if (max == 1) - partstat = [[attendees objectAtIndex: 0] participationStatus]; - else if (max > 1) - [self _setupITIPContextFromAttendees]; - } - } - else - [self _setupITIPContextFromAttendees]; -} - -- (id) initWithICalEvent: (iCalEvent *) newEvent - andUser: (SOGoUser *) newUser - andSenderEmail: (NSString *) newSenderEmail - withConnectionInfo: (struct mapistore_connection_info *) newConnInfo -{ - NSArray *events; - iCalTimeZone *tz; - - if ((self = [self init])) - { - connInfo = newConnInfo; - ASSIGN (calendar, [newEvent parent]); - event = newEvent; - events = [calendar events]; - firstEvent = [events objectAtIndex: 0]; - ASSIGN (user, newUser); - ASSIGN (senderEmail, newSenderEmail); - /* If newEvent comes from the client, we set its time zone in - updateFromMAPIProperties. If it is not present, we use the - time zone of the user */ - tz = (iCalTimeZone *) [calendar firstChildWithTag: @"vtimezone"]; - if (!tz) - { - tz = [iCalTimeZone timeZoneForName: [[[user userDefaults] timeZone] name]]; - if (!tz) - [self logWithFormat: @"no time zone could be set"]; - } - ASSIGN (timeZone, tz); - - [self _setupITIPContext]; - } - - return self; -} - -- (void) dealloc -{ - [calendar release]; - [timeZone release]; - [user release]; - [senderEmail release]; - [globalObjectId release]; - [cleanGlobalObjectId release]; - [alarm release]; - [method release]; - [super dealloc]; -} - -- (void) fillMessageData: (struct mapistore_message *) msgData - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *username, *cn, *email; - NSData *entryId; - NSArray *attendees; - iCalPerson *person; - iCalPersonPartStat partStat; - uint32_t partStatValue; - SOGoUserManager *mgr; - NSDictionary *contactInfos; - struct mapistore_message_recipient *recipient; - int count, max, p; - - msgData->columns = set_SPropTagArray (msgData, 9, - PR_OBJECT_TYPE, - PR_DISPLAY_TYPE, - PR_7BIT_DISPLAY_NAME_UNICODE, - PR_SMTP_ADDRESS_UNICODE, - PR_SEND_INTERNET_ENCODING, - PR_RECIPIENT_DISPLAY_NAME_UNICODE, - PR_RECIPIENT_FLAGS, - PR_RECIPIENT_ENTRYID, - PR_RECIPIENT_TRACKSTATUS); -// , -// PR_RECORD_KEY); - - attendees = [event attendees]; - max = [attendees count]; - - if (max > 0) - { - mgr = [SOGoUserManager sharedUserManager]; - msgData->recipients_count = max + 1; - msgData->recipients = talloc_array (msgData, struct mapistore_message_recipient, max + 1); - for (count = 0; count < max; count++) - { - recipient = msgData->recipients + count; - - person = [attendees objectAtIndex: count]; - cn = [person cn]; - email = [person rfc822Email]; - if ([cn length] == 0) - cn = email; - contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - - if (contactInfos) - { - username = [contactInfos objectForKey: @"sAMAccountName"]; - recipient->username = [username asUnicodeInMemCtx: msgData]; - entryId = MAPIStoreInternalEntryId (connInfo, username); - } - else - { - recipient->username = NULL; - entryId = MAPIStoreExternalEntryId (cn, email); - } - recipient->type = [[person role] isEqualToString: @"OPT-PARTICIPANT"] ? MAPI_CC : MAPI_TO; - - /* properties */ - p = 0; - recipient->data = talloc_array (msgData, void *, msgData->columns->cValues); - memset (recipient->data, 0, msgData->columns->cValues * sizeof (void *)); - - // PR_OBJECT_TYPE = MAPI_MAILUSER (see MAPI_OBJTYPE) - recipient->data[p] = MAPILongValue (msgData, MAPI_MAILUSER); - p++; - - // PR_DISPLAY_TYPE = DT_MAILUSER (see MS-NSPI) - recipient->data[p] = MAPILongValue (msgData, 0); - p++; - - // PR_7BIT_DISPLAY_NAME_UNICODE - recipient->data[p] = [cn asUnicodeInMemCtx: msgData]; - p++; - - // PR_SMTP_ADDRESS_UNICODE - recipient->data[p] = [email asUnicodeInMemCtx: msgData]; - p++; - - // PR_SEND_INTERNET_ENCODING = 0x00060000 (plain text, see OXCMAIL) - recipient->data[p] = MAPILongValue (msgData, 0x00060000); - p++; - - // PR_RECIPIENT_DISPLAY_NAME_UNICODE - recipient->data[p] = [cn asUnicodeInMemCtx: msgData]; - p++; - - // PR_RECIPIENT_FLAGS - recipient->data[p] = MAPILongValue (msgData, 1); - p++; - - // PR_RECIPIENT_ENTRYID - recipient->data[p] = [entryId asBinaryInMemCtx: msgData]; - p++; - - // PR_RECIPIENT_TRACKSTATUS - /* - respNone 0x00000000 - No response is required for this object. This is the case for Appointment objects and Meeting Response objects. - respOrganized 0x00000001 - This Meeting object belongs to the organizer. - respTentative 0x00000002 - This value on the attendee's Meeting object indicates that the - attendee has tentatively accepted the Meeting Request object. - respAccepted 0x00000003 - This value on the attendee's Meeting object indicates that the - attendee has accepted the Meeting Request object. - respDeclined 0x00000004 - This value on the attendee's Meeting object indicates that the attendee has declined the Meeting Request - object. - respNotResponded 0x00000005 - This value on the attendee's Meeting object indicates that the attendee has - not yet responded. This value is on the Meet - */ - partStat = [person participationStatus]; - switch (partStat) - { - case iCalPersonPartStatAccepted: - partStatValue = 3; - break; - case iCalPersonPartStatDeclined: - partStatValue = 4; - break; - case iCalPersonPartStatTentative: - partStatValue = 2; - break; - default: - partStatValue = 5; - } - recipient->data[p] = MAPILongValue (msgData, partStatValue); - p++; - - // // PR_RECORD_KEY - // recipient->data[p] = [entryId asBinaryInMemCtx: msgData]; - // p++; - } - - /* On with the organizer: */ - { - recipient = msgData->recipients + max; - - person = [event organizer]; - cn = [person cn]; - email = [person rfc822Email]; - contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - - if (contactInfos) - { - username = [contactInfos objectForKey: @"sAMAccountName"]; - recipient->username = [username asUnicodeInMemCtx: msgData]; - entryId = MAPIStoreInternalEntryId (connInfo, username); - } - else - { - recipient->username = NULL; - entryId = MAPIStoreExternalEntryId (cn, email); - } - recipient->type = MAPI_TO; - - p = 0; - recipient->data = talloc_array (msgData, void *, msgData->columns->cValues); - memset (recipient->data, 0, msgData->columns->cValues * sizeof (void *)); - - // PR_OBJECT_TYPE = MAPI_MAILUSER (see MAPI_OBJTYPE) - recipient->data[p] = MAPILongValue (msgData, MAPI_MAILUSER); - p++; - - // PR_DISPLAY_TYPE = DT_MAILUSER (see MS-NSPI) - recipient->data[p] = MAPILongValue (msgData, 0); - p++; - - // PR_7BIT_DISPLAY_NAME_UNICODE - recipient->data[p] = [cn asUnicodeInMemCtx: msgData]; - p++; - - // PR_SMTP_ADDRESS_UNICODE - recipient->data[p] = [email asUnicodeInMemCtx: msgData]; - p++; - - // PR_SEND_INTERNET_ENCODING = 0x00060000 (plain text, see OXCMAIL) - recipient->data[p] = MAPILongValue (msgData, 0x00060000); - p++; - - // PR_RECIPIENT_DISPLAY_NAME_UNICODE - recipient->data[p] = [cn asUnicodeInMemCtx: msgData]; - p++; - - // PR_RECIPIENT_FLAGS - recipient->data[p] = MAPILongValue (msgData, 3); - p++; - - // PR_RECIPIENT_ENTRYID = NULL - recipient->data[p] = [entryId asBinaryInMemCtx: msgData]; - p++; - - // PR_RECIPIENT_TRACKSTATUS - /* - respNone 0x00000000 - No response is required for this object. This is the case for Appointment objects and Meeting Response objects. - respOrganized 0x00000001 - This Meeting object belongs to the organizer. - respTentative 0x00000002 - This value on the attendee's Meeting object indicates that the - attendee has tentatively accepted the Meeting Request object. - respAccepted 0x00000003 - This value on the attendee's Meeting object indicates that the - attendee has accepted the Meeting Request object. - respDeclined 0x00000004 - This value on the attendee's Meeting object indicates that the attendee has declined the Meeting Request - object. - respNotResponded 0x00000005 - This value on the attendee's Meeting object indicates that the attendee has - not yet responded. This value is on the Meet - */ - recipient->data[p] = MAPILongValue (msgData, 1); - p++; - - // // PR_RECORD_KEY - // recipient->data[p] = [entryId asBinaryInMemCtx: msgData]; - // p++; - } - } -} - -- (enum mapistore_error) getPidTagIconIndex: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t longValue; - - /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx: - Single instance appointment: 0x00000400 - Recurring appointment: 0x00000401 - Single instance meeting: 0x00000402 - Recurring meeting: 0x00000403 - Meeting request: 0x00000404 - Accept: 0x00000405 - Decline: 0x00000406 - Tentativly: 0x00000407 - Cancellation: 0x00000408 - Informational update: 0x00000409 */ - - // if ([headerMethod isEqualToString: @"REQUEST"]) - // longValue = 0x0404; - // else - // longValue = 0x0400; - - if (!itipSetup) - [self _setupITIPContext]; - - longValue = 0x0400; - - if (method) - { - if ([method isEqualToString: @"REQUEST"]) - longValue |= 0x0004; - else if ([method isEqualToString: @"REPLY"]) - { - longValue |= 0x0004; - switch (partstat) - { - case iCalPersonPartStatAccepted: - longValue |= 0x0001; - break; - case iCalPersonPartStatDeclined: - longValue |= 0x0002; - break; - case iCalPersonPartStatTentative: - longValue |= 0x0003; - break; - default: - longValue = 0x0400; - [self logWithFormat: @"unhandled part stat"]; - } - } - else if ([method isEqualToString: @"CANCEL"]) - longValue |= 0x0008; - } - else - { - if ([event isRecurrent]) - longValue |= 0x0001; - if ([[event attendees] count] > 0) - longValue |= 0x0002; - } - - *data = MAPILongValue (memCtx, longValue); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagOwnerAppointmentId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - const char *utf8UID; - union { - uint32_t longValue; - char charValue[4]; - } value; - NSUInteger max, length; - - if ([[event attendees] count] > 0) - { - utf8UID = [[event uid] UTF8String]; - length = strlen (utf8UID); - max = 2; - if (length < max) - max = length; - memcpy (value.charValue, utf8UID, max); - memcpy (value.charValue + 2, utf8UID + length - 2, max); - - *data = MAPILongValue (memCtx, value.longValue); - - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidMeetingType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* TODO - See 2.2.6.5 PidLidMeetingType (OXOCAL) */ - *data = MAPILongValue (memCtx, 0x00000001); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidOwnerCriticalChange: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - NSCalendarDate *lastModified; - - if ([[event attendees] count] > 0) - { - lastModified = [event lastModified]; - if (lastModified) - { - *data = [lastModified asFileTimeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - } - - return rc; -} - -- (enum mapistore_error) getPidLidAttendeeCriticalChange: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - NSCalendarDate *lastModified; - - if ([[event attendees] count] > 0) - { - lastModified = [event lastModified]; - if (lastModified) - { - *data = [lastModified asFileTimeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - } - - return rc; -} - -- (enum mapistore_error) getPidTagMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - const char *className; - - if (!itipSetup) - [self _setupITIPContext]; - - if (method) - { - if ([method isEqualToString: @"REQUEST"]) - className = "IPM.Schedule.Meeting.Request"; - else if ([method isEqualToString: @"REPLY"]) - { - switch (partstat) - { - case iCalPersonPartStatAccepted: - className = "IPM.Schedule.Meeting.Resp.Pos"; - break; - case iCalPersonPartStatDeclined: - className = "IPM.Schedule.Meeting.Resp.Neg"; - break; - case iCalPersonPartStatTentative: - className = "IPM.Schedule.Meeting.Resp.Tent"; - break; - default: - className = "IPM.Appointment"; - [self logWithFormat: @"unhandled part stat"]; - } - } - else if ([method isEqualToString: @"COUNTER"]) - className = "IPM.Schedule.Meeting.Resp.Tent"; - else if ([method isEqualToString: @"CANCEL"]) - className = "IPM.Schedule.Meeting.Cancelled"; - else - { - className = "IPM.Appointment"; - [self logWithFormat: @"unhandled method: %@", method]; - } - } - else - className = "IPM.Appointment"; - *data = talloc_strdup(memCtx, className); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidAppointmentMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = talloc_strdup (memCtx, "IPM.Appointment"); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidFInvited: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidAppointmentSequence: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, [[event sequence] unsignedIntValue]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidAppointmentStateFlags: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t flags = 0x00; - - if ([[event attendees] count] > 0) - { - flags |= 0x01; /* asfMeeting */ - if ([event userAsAttendee: user]) - flags |= 0x02; /* asfReceived */ - /* TODO: asfCancelled */ - } - - *data = MAPILongValue (memCtx, flags); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidResponseStatus: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t status = 0x00; - iCalPerson *person; - - if ([[event attendees] count] > 0) - { - if ([event userIsOrganizer: user]) - status = 1; - else - { - person = [event userAsAttendee: user]; - if (person) - { - switch ([person participationStatus]) - { - case iCalPersonPartStatTentative: - status = 2; - break; - case iCalPersonPartStatAccepted: - status = 3; - break; - case iCalPersonPartStatDeclined: - status = 4; - break; - default: - status = 5; - } - } - } - } - - *data = MAPILongValue (memCtx, status); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidAppointmentNotAllowPropose: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidAppointmentStartWhole: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSCalendarDate *dateValue; - - // if ([event isRecurrent]) - // dateValue = [event firstRecurrenceStartDate]; - // else - dateValue = [event startDate]; - if ([event isAllDay]) - dateValue = [timeZone shiftedCalendarDateForDate: dateValue]; - *data = [dateValue asFileTimeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) 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; - - dateValue = [event recurrenceId]; - if (!dateValue) - dateValue = [event startDate]; - if ([event isAllDay]) - dateValue = [timeZone shiftedCalendarDateForDate: dateValue]; - *data = [dateValue asFileTimeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidCommonStart: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSCalendarDate *dateValue; - - dateValue = [firstEvent startDate]; - if ([firstEvent isAllDay]) - dateValue = [timeZone shiftedCalendarDateForDate: dateValue]; - *data = [dateValue asFileTimeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidClipStart: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSCalendarDate *dateValue, *start; - - if ([event isRecurrent]) - { - /* [MS-OXOCAL] For a recurring series, this property specifies - midnight in the user's machine time zone, on the date of the - first instance, then is persisted in UTC. */ - start = [event startDate]; - dateValue = [NSCalendarDate dateWithYear: [start yearOfCommonEra] - month: [start monthOfYear] - day: [start dayOfMonth] - hour: 0 minute: 0 second: 0 - timeZone: utcTZ]; - dateValue = [timeZone shiftedCalendarDateForDate: dateValue]; - *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; -} - -- (enum mapistore_error) 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 periodForDate: dateValue] secondsOffsetFromGMT]; - dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: offset]; - *data = [dateValue asFileTimeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagEndDate: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSCalendarDate *dateValue; - NSInteger offset; - - dateValue = [event recurrenceId]; - if (!dateValue) - dateValue = [event startDate]; - offset = [firstEvent durationAsTimeInterval]; - if ([firstEvent isAllDay]) - offset -= [[timeZone periodForDate: dateValue] secondsOffsetFromGMT]; - dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: offset]; - *data = [dateValue asFileTimeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) 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 periodForDate: dateValue] secondsOffsetFromGMT]; - dateValue = [dateValue dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: offset]; - *data = [dateValue asFileTimeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidClipEnd: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSCalendarDate *dateValue; - iCalRecurrenceRule *rrule; - - if ([event isRecurrent]) - { - rrule = [[event recurrenceRules] objectAtIndex: 0]; - dateValue = [rrule untilDate]; - if (dateValue && [event isAllDay]) - dateValue = [timeZone shiftedCalendarDateForDate: dateValue]; - else - dateValue = [NSCalendarDate dateWithYear: 4500 month: 8 day: 31 - hour: 23 minute: 59 second: 00 - 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; -} - -- (enum mapistore_error) _getEntryIdFromCN: (NSString *) cn - andEmail: (NSString *) email - inData: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *username; - SOGoUserManager *mgr; - NSDictionary *contactInfos; - NSData *entryId; - - mgr = [SOGoUserManager sharedUserManager]; - contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - if (contactInfos) - { - username = [contactInfos objectForKey: @"sAMAccountName"]; - entryId = MAPIStoreInternalEntryId (connInfo, username); - } - else - entryId = MAPIStoreExternalEntryId (cn, email); - - *data = [entryId asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) _getEmailAddress: (void **) data - forICalPerson: (iCalPerson *) person - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSString *email; - - email = [person rfc822Email]; - if ([email length] > 0) - { - *data = [email asUnicodeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) _getAddrType: (void **) data - forICalPerson: (iCalPerson *) person - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"SMTP" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) _getName: (void **) data - forICalPerson: (iCalPerson *) person - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSString *cn; - - cn = [person cn]; - if ([cn length] > 0) - { - *data = [cn asUnicodeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) _getEntryId: (void **) data - forICalPerson: (iCalPerson *) person - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - NSString *email, *cn; - - if (person) - { - email = [person rfc822Email]; - if ([email length] > 0) - { - cn = [person cn]; - rc = [self _getEntryIdFromCN: cn andEmail: email - inData: data - inMemCtx: memCtx]; - } - } - - return rc; -} - -/* sender (organizer) */ -- (enum mapistore_error) getPidTagSenderEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getEmailAddress: data - forICalPerson: [event organizer] - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSenderAddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getAddrType: data - forICalPerson: [event organizer] - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSenderName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getName: data - forICalPerson: [event organizer] - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSenderEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getEntryId: data - forICalPerson: [event organizer] - inMemCtx: memCtx]; -} - -/* creator (only if created from Outlook/SOGo or organizer as fallback */ -- (NSString *) creator -{ - iCalPerson *person; - NSDictionary *contactInfos; - NSString *creator = nil, *email; - SOGoUserManager *mgr; - - creator = [[event uniqueChildWithTag: @"x-sogo-component-created-by"] - flattenedValuesForKey: @""]; - if ([creator length] == 0) - { - person = [event organizer]; - if (person) - { - email = [person rfc822Email]; - if ([email length] > 0) - { - mgr = [SOGoUserManager sharedUserManager]; - contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - if (contactInfos) - creator = [contactInfos objectForKey: @"sAMAccountName"]; - } - } - } - return creator; -} - -/* owner is the organizer of the event, if none, try with the creator - who has saved only from Outlook or SOGo */ -- (NSString *) owner -{ - iCalPerson *person; - NSDictionary *contactInfos; - NSString *email, *owner = nil; - SOGoUserManager *mgr; - - person = [event organizer]; - if (person) - { - email = [person rfc822Email]; - if ([email length] > 0) - { - mgr = [SOGoUserManager sharedUserManager]; - contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - if (contactInfos) - owner = [contactInfos objectForKey: @"sAMAccountName"]; - } - } - - if (!owner) - owner = [[event uniqueChildWithTag: @"x-sogo-component-created-by"] - flattenedValuesForKey: @""]; - - return owner; -} - -- (NSUInteger) sensitivity -{ - NSString *accessClass = nil; - NSUInteger v; - - accessClass = [event accessClass]; - if (accessClass) - { - if ([accessClass isEqualToString: @"X-PERSONAL"]) - v = 0x1; - else if ([accessClass isEqualToString: @"PRIVATE"]) - v = 0x2; - else if ([accessClass isEqualToString: @"CONFIDENTIAL"]) - v = 0x3; - else - v = 0x0; /* PUBLIC */ - } - else - v = 0x0; /* PUBLIC */ - - return v; -} - -/* sender representing */ -- (enum mapistore_error) getPidTagSentRepresentingEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagSenderEmailAddress: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSentRepresentingAddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSentRepresentingName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagSenderName: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSentRepresentingEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagSenderEntryId: data inMemCtx: memCtx]; -} - -/* attendee */ -- (enum mapistore_error) getPidTagReceivedByEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getEmailAddress: data - forICalPerson: [event userAsAttendee: user] - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedByAddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getAddrType: data - forICalPerson: [event userAsAttendee: user] - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedByName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getName: data - forICalPerson: [event userAsAttendee: user] - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedByEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getEntryId: data - forICalPerson: [event userAsAttendee: user] - inMemCtx: memCtx]; -} -/* /attendee */ - -- (enum mapistore_error) getPidLidAppointmentDuration: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSTimeInterval timeValue; - - timeValue = [[event endDate] timeIntervalSinceDate: [event startDate]]; - *data = MAPILongValue (memCtx, (uint32_t) (timeValue / 60)); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidAppointmentSubType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPIBoolValue (memCtx, [event isAllDay]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidBusyStatus: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint8_t value; - - value = 0x2; // olBusy - - if (![event isOpaque]) - value = 0x0; // olFree - - *data = MAPILongValue (memCtx, value); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidIndentedBusyStatus: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidBusyStatus: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagNormalizedSubject: (void **) data // SUMMARY - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[event summary] asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidLocation: (void **) data // LOCATION - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSString *location; - - location = [event location]; - if (location) - *data = [location asUnicodeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidWhere: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidLocation: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) 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 - here. */ - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidServerProcessingActions: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, - 0x00000010 /* cpsCreatedOnPrincipal */ - | 0x00000080 /* cpsUpdatedCalItem */ - | 0x00000100 /* cpsCopiedOldProperties */); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidPrivate: (void **) data // private (bool), should depend on CLASS and permissions - inMemCtx: (TALLOC_CTX *) memCtx -{ - if ([event symbolicAccessClass] == iCalAccessPublic) - return [self getNo: data inMemCtx: memCtx]; - - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSensitivity: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* See [MS-OXCICAL] Section 2.1.3.11.20.4 */ - uint32_t v; - - v = (uint32_t) [self sensitivity]; - *data = MAPILongValue (memCtx, v); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagImportance: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t v; - if ([[event priority] isEqualToString: @"9"]) - v = 0x0; - else if ([[event priority] isEqualToString: @"1"]) - v = 0x2; - else - v = 0x1; - - *data = MAPILongValue (memCtx, v); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidNameKeywords: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* See [MS-OXCICAL] Section 2.1.3.1.1.20.3 */ - NSArray *categories; - - categories = [event categories]; - if (categories) - { - *data = [categories asMVUnicodeInMemCtx: memCtx]; - return MAPISTORE_SUCCESS; - } - else - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagBody: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSRange range; - NSString *stringValue; - NSString *trimingString = @"\r\n\n"; - - /* FIXME: there is a confusion in NGCards around "comment" and "description" */ - stringValue = [event comment]; - if ([stringValue length] > 0 - && ![stringValue isEqualToString: @"\r\n"] - && ![stringValue isEqualToString: @"\n"]) - { - /* Avoiding those trail weird characters at event description */ - range = [stringValue rangeOfString: trimingString - options: NSBackwardsSearch]; - if (range.location != NSNotFound) - { - stringValue = [stringValue substringToIndex: (NSMaxRange(range) -1)]; - } - - rc = MAPISTORE_SUCCESS; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidTagInternetCodepage: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* 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; -} - -- (enum mapistore_error) getPidLidRecurring: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPIBoolValue (memCtx, [event isRecurrent]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidIsRecurring: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPIBoolValue (memCtx, - [event isRecurrent] - || ([event recurrenceId] != nil)); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidIsException: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPIBoolValue (memCtx, [event recurrenceId] != nil); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidExceptionReplaceTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSCalendarDate *dateValue; - - dateValue = [event recurrenceId]; - if (dateValue) - { - rc = MAPISTORE_SUCCESS; - - if ([event isAllDay]) - dateValue = [timeZone shiftedCalendarDateForDate: dateValue]; - *data = [dateValue asFileTimeInMemCtx: memCtx]; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidRecurrencePattern: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"No description" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (void) _fillExceptionInfo: (struct ExceptionInfo *) exceptionInfo - andExtendedException: (struct ExtendedException *) extendedException - withException: (iCalEvent *) exceptionEvent - inMemCtx: (TALLOC_CTX *) memCtx -{ - iCalEventChanges *changes; - NSArray *changedProperties; - NSCalendarDate *dateValue; - - 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 = [timeZone computedDateForDate: [exceptionEvent startDate]]; - exceptionInfo->StartDateTime = [dateValue asMinutesSince1601]; - extendedException->ChangeHighlight.Value = BIT_CH_START; - extendedException->StartDateTime = exceptionInfo->StartDateTime; - - dateValue = [timeZone computedDateForDate: [exceptionEvent endDate]]; - exceptionInfo->EndDateTime = [dateValue asMinutesSince1601]; - extendedException->ChangeHighlight.Value |= BIT_CH_END; - extendedException->EndDateTime = exceptionInfo->EndDateTime; - - dateValue = [timeZone computedDateForDate: [exceptionEvent recurrenceId]]; - 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; - NSCalendarDate *firstStartDate; - iCalRecurrenceRule *rule; - NSUInteger startMinutes; - NSArray *events, *exceptions; - iCalEvent *exceptionEvent; - NSUInteger count, max; - - rule = [[event recurrenceRules] objectAtIndex: 0]; - - firstStartDate = [event firstRecurrenceStartDate]; - if (firstStartDate) - { - arp = talloc_zero (NULL, struct AppointmentRecurrencePattern); - [rule fillRecurrencePattern: &arp->RecurrencePattern - withEvent: event - inMemCtx: arp]; - arp->ReaderVersion2 = 0x00003006; - arp->WriterVersion2 = 0x00003008; /* 0x3008 for compatibility with - ol2003 */ - - /* All day events' dates are specified in floating time - ([MS-OXCICAL] 2.1.3.1.1.20.10). The StartTimeOffset and EndTimeOffset - fields are relative to midnight of those days ([MS-OXOCAL] 2.2.1.44.5), - so no time zone adjustment is needed */ - if (![event isAllDay]) - firstStartDate = [timeZone computedDateForDate: firstStartDate]; - 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")); - // NDR_PRINT_DEBUG (AppointmentRecurrencePattern, arp); - } - else - { - [self errorWithFormat: @"no first occurrence found in rule: %@", rule]; - // bin = NULL; - bin = NULL; - } - - 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 -*/ - -- (enum mapistore_error) getPidLidAppointmentRecur: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - - if ([event isRecurrent]) - *data = [self _computeAppointmentRecurInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidRecurrenceType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - iCalRecurrenceFrequency freq; - iCalRecurrenceRule *rrule; - enum RecurrenceType rectype; - - if ([event isRecurrent]) - { - rrule = [[event recurrenceRules] objectAtIndex: 0]; - freq = [rrule frequency]; - if (freq == iCalRecurrenceFrequenceDaily) - rectype = rectypeDaily; - else if (freq == iCalRecurrenceFrequenceWeekly) - rectype = rectypeWeekly; - else if (freq == iCalRecurrenceFrequenceMonthly) - rectype = rectypeMonthly; - else if (freq == iCalRecurrenceFrequenceYearly) - rectype = rectypeYearly; - else - rectype = rectypeNone; /* or "unsupported" */ - - *data = MAPILongValue (memCtx, rectype); - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -// - (enum mapistore_error) getPidLidGlobalObjectId: (void **) data -// inMemCtx: (TALLOC_CTX *) memCtx -// { -// static char byteArrayId[] = {0x04, 0x00, 0x00, 0x00, 0x82, 0x00, 0xE0, -// 0x00, 0x74, 0xC5, 0xB7, 0x10, 0x1A, 0x82, -// 0xE0, 0x08}; -// static char X[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -// NSMutableData *nsData; -// NSData *uidData; -// NSCalendarDate *creationTime; -// struct FILETIME *creationFileTime; -// uint32_t uidDataLength; - -// nsData = [NSMutableData dataWithCapacity: 256]; -// [nsData appendBytes: byteArrayId length: 16]; - -// /* FIXME TODO */ -// [nsData appendBytes: X length: 4]; -// /* /FIXME */ - -// creationTime = [event created]; -// if (!creationTime) -// { -// [self logWithFormat: @"" __location__ ": event has no 'CREATED' tag -> inventing one"]; -// creationTime = [event lastModified]; -// if (!creationTime) -// creationTime = [NSCalendarDate date]; -// } -// creationFileTime = [creationTime asFileTimeInMemCtx: NULL]; -// [nsData appendBytes: &creationFileTime->dwLowDateTime length: 4]; -// [nsData appendBytes: &creationFileTime->dwHighDateTime length: 4]; -// talloc_free (creationFileTime); - -// uidData = [[event uid] dataUsingEncoding: NSUTF8StringEncoding]; -// uidDataLength = [uidData length]; -// [nsData appendBytes: &uidDataLength length: 4]; -// [nsData appendData: uidData]; -// *data = [nsData asBinaryInMemCtx: memCtx]; - -// return MAPISTORE_SUCCESS; -// } - -- (void) _setInstanceDate: (struct GlobalObjectId *) newGlobalId - fromDate: (NSCalendarDate *) instanceDate; -{ - uint16_t year; - NSCalendarDate *dateValue; - - if (instanceDate) - { - dateValue = [timeZone computedDateForDate: instanceDate]; - year = [dateValue yearOfCommonEra]; - newGlobalId->YH = year >> 8; - newGlobalId->YL = year & 0xff; - newGlobalId->Month = [dateValue monthOfYear]; - newGlobalId->D = [dateValue dayOfMonth]; - } -} - -/* note: returns a retained object */ -- (NSData *) _objectIdAsNSData: (const struct GlobalObjectId *) newGlobalId -{ - NSData *nsData; - TALLOC_CTX *localMemCtx; - struct ndr_push *ndr; - - localMemCtx = talloc_zero (NULL, TALLOC_CTX); - ndr = ndr_push_init_ctx (localMemCtx); - ndr_push_GlobalObjectId (ndr, NDR_SCALARS, newGlobalId); - nsData = [[NSData alloc] initWithBytes: ndr->data - length: ndr->offset]; - talloc_free (localMemCtx); - - return nsData; -} - -- (void) _computeGlobalObjectIds -{ - static NSString *prefix = @"040000008200e00074c5b7101a82e008"; - static uint8_t dataPrefix[] = { 0x76, 0x43, 0x61, 0x6c, 0x2d, 0x55, 0x69, - 0x64, 0x01, 0x00, 0x00, 0x00 }; - NSString *uid; - const char *uidAsUTF8; - NSUInteger uidLength; - NSData *encodedGlobalIdData; - struct Binary_r *encodedGlobalIdBinary; - struct GlobalObjectId *encodedGlobalId; - struct GlobalObjectId newGlobalId; - uint16_t year; - NSData *binPrefix; - TALLOC_CTX *localMemCtx; - - localMemCtx = talloc_zero (NULL, TALLOC_CTX); - - memset (&newGlobalId, 0, sizeof (struct GlobalObjectId)); - - uid = [event uid]; - uidLength = [uid length]; - if (uidLength >= 82 && (uidLength % 2) == 0 && [uid hasPrefix: prefix] - && [[uid stringByTrimmingCharactersInSet: hexCharacterSet] length] == 0) - { - encodedGlobalIdData = [uid convertHexStringToBytes]; - if (encodedGlobalIdData) - { - encodedGlobalIdBinary - = [encodedGlobalIdData asBinaryInMemCtx: localMemCtx]; - encodedGlobalId = get_GlobalObjectId (localMemCtx, - encodedGlobalIdBinary); - if (encodedGlobalId) - { - memcpy (newGlobalId.ByteArrayID, - encodedGlobalId->ByteArrayID, - 16); - year = ((uint16_t) encodedGlobalId->YH << 8) | encodedGlobalId->YL; - if (year >= 1601 && year <= 4500 - && encodedGlobalId->Month > 0 && encodedGlobalId->Month < 13 - && encodedGlobalId->D > 0 && encodedGlobalId->D < 31) - { - newGlobalId.YH = encodedGlobalId->YH; - newGlobalId.YL = encodedGlobalId->YL; - newGlobalId.Month = encodedGlobalId->Month; - newGlobalId.D = encodedGlobalId->D; - } - else - [self _setInstanceDate: &newGlobalId - fromDate: [event recurrenceId]]; - newGlobalId.CreationTime = encodedGlobalId->CreationTime; - memcpy (newGlobalId.X, encodedGlobalId->X, 8); - newGlobalId.Size = encodedGlobalId->Size; - newGlobalId.Data = encodedGlobalId->Data; - } - else - abort (); - } - else - abort (); - } - else - { - binPrefix = [prefix convertHexStringToBytes]; - [binPrefix getBytes: &newGlobalId.ByteArrayID]; - [self _setInstanceDate: &newGlobalId - fromDate: [event recurrenceId]]; - uidAsUTF8 = [uid UTF8String]; - newGlobalId.Size = 0x0c + strlen (uidAsUTF8); - newGlobalId.Data = talloc_array (localMemCtx, uint8_t, - newGlobalId.Size); - memcpy (newGlobalId.Data, dataPrefix, 0x0c); - memcpy (newGlobalId.Data + 0x0c, uidAsUTF8, newGlobalId.Size - 0x0c); - } - - globalObjectId = [self _objectIdAsNSData: &newGlobalId]; - - newGlobalId.YH = 0; - newGlobalId.YL = 0; - newGlobalId.Month = 0; - newGlobalId.D = 0; - cleanGlobalObjectId = [self _objectIdAsNSData: &newGlobalId]; - - talloc_free (localMemCtx); -} - -- (enum mapistore_error) getPidLidGlobalObjectId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - - if (!globalObjectId) - [self _computeGlobalObjectIds]; - - if (globalObjectId) - *data = [globalObjectId asBinaryInMemCtx: memCtx]; - else - abort (); - - return rc; -} - -- (enum mapistore_error) getPidLidCleanGlobalObjectId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - - if (!cleanGlobalObjectId) - [self _computeGlobalObjectIds]; - - if (cleanGlobalObjectId) - *data = [cleanGlobalObjectId asBinaryInMemCtx: memCtx]; - else - abort (); - - return rc; -} - -- (enum mapistore_error) getPidLidAppointmentReplyTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* We always return LAST-MODIFIED, which is a hack, but one that works - because: the user is either (NOT recipient OR (is recipient AND its - status is N/A), where this value should not be taken into account by the - client OR the user is recipient and its status is defined, where this - value is thus correct because the recipient status is the only property - that can be changed. */ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - NSCalendarDate *lastModified; - - lastModified = [event lastModified]; - if (lastModified) - { - *data = [lastModified asFileTimeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - - return rc; -} - -/* reminders */ -- (void) _setupAlarm -{ - NSArray *alarms; - NSUInteger count, max; - iCalAlarm *currentAlarm; - NSString *action, *webstatus; - - alarms = [event alarms]; - max = [alarms count]; - for (count = 0; !alarm && count < max; count++) - { - currentAlarm = [alarms objectAtIndex: count]; - - // Only handle 'display' alarms - action = [currentAlarm action]; - if ([action caseInsensitiveCompare: @"display"] != NSOrderedSame) - continue; - - // Ignore alarms already triggered - webstatus = [[currentAlarm trigger] value: 0 ofAttribute: @"x-webstatus"]; - if ([webstatus caseInsensitiveCompare: @"triggered"] == NSOrderedSame) - continue; - - ASSIGN (alarm, currentAlarm); - } - - alarmSet = YES; -} - -- (enum mapistore_error) getPidLidReminderSet: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!alarmSet) - [self _setupAlarm]; - - *data = MAPIBoolValue (memCtx, (alarm != nil)); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidReminderTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!alarmSet) - [self _setupAlarm]; - - return (alarm - ? [self getPidTagStartDate: data inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidReminderDelta: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - iCalTrigger *trigger; - NSCalendarDate *startDate, *relationDate, *alarmDate; - NSTimeInterval interval; - NSString *relation; - - if (!alarmSet) - [self _setupAlarm]; - - if (alarm) - { - trigger = [alarm trigger]; - if ([[trigger valueType] caseInsensitiveCompare: @"DURATION"] == NSOrderedSame) - { - startDate = [event startDate]; - relation = [[trigger relationType] lowercaseString]; - interval = [[trigger flattenedValuesForKey: @""] - durationAsTimeInterval]; - if ([relation isEqualToString: @"end"]) - relationDate = [event endDate]; - else - relationDate = startDate; - - // Compute the next alarm date with respect to the reference date - if (relationDate) - { - alarmDate = [relationDate addTimeInterval: interval]; - interval = [startDate timeIntervalSinceDate: alarmDate]; - *data = MAPILongValue (memCtx, (int) (interval / 60)); - rc = MAPISTORE_SUCCESS; - } - } - } - - return rc; -} - -- (enum mapistore_error) getPidLidReminderSignalTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSCalendarDate *alarmDate; - - if (!alarmSet) - [self _setupAlarm]; - - if (alarm) - { - alarmDate = [alarm nextAlarmDate]; - *data = [alarmDate asFileTimeInMemCtx: memCtx]; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidReminderOverride: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - - if (!alarmSet) - [self _setupAlarm]; - - if (alarm) - *data = MAPIBoolValue (memCtx, YES); - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidReminderPlaySound: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - - if (!alarmSet) - [self _setupAlarm]; - - if (alarm) - *data = MAPIBoolValue (memCtx, YES); - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidReminderFileParameter: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - // if (!alarmSet) - // [self _setupAlarm]; - - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidLidReminderType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidLidTimeZoneDescription: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSString *tzid; - - tzid = [timeZone tzId]; - if ([tzid length] > 0) - { - *data = [tzid asUnicodeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidTimeZoneStruct: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - - *data = [timeZone asTimeZoneStructInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - - return rc; -} - -- (enum mapistore_error) getPidLidAppointmentTimeZoneDefinitionStartDisplay: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - - /* [MS-OXOCAL] 3.1.5.5.1: This property is used in floating (all-day) events, - specified in floating time, to convert the start date from UTC to the user's - time zone */ - if ([event isAllDay] || [event isRecurrent]) - { - /* [MS-OXOCAL] 2.2.1.42: This property can only have the E flag set in the - TimeZoneDefinition struct */ - *data = [timeZone asZoneTimeDefinitionWithFlags: TZRULE_FLAG_EFFECTIVE_TZREG - inMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidAppointmentTimeZoneDefinitionEndDisplay: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidAppointmentTimeZoneDefinitionStartDisplay: data - inMemCtx: memCtx]; -} - -@end diff --git a/OpenChange/MAPIStoreAttachment.h b/OpenChange/MAPIStoreAttachment.h deleted file mode 100644 index 24ba32c43..000000000 --- a/OpenChange/MAPIStoreAttachment.h +++ /dev/null @@ -1,59 +0,0 @@ -/* MAPIStoreAttachment.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREATTACHMENT_H -#define MAPISTOREATTACHMENT_H - -#import "MAPIStoreObject.h" - -@class NSData; -@class MAPIStoreEmbeddedMessage; - -@interface MAPIStoreAttachment : MAPIStoreObject -{ - uint32_t aid; -} - -- (void) setAID: (uint32_t) newAID; -- (uint32_t) AID; - -- (enum mapistore_error) openEmbeddedMessage: (MAPIStoreEmbeddedMessage **) messagePtr - withMID: (uint64_t *) mid - withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) createEmbeddedMessage: (MAPIStoreEmbeddedMessage **) messagePtr - withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr - inMemCtx: (TALLOC_CTX *) memCtx; - -/* helpers */ -- (NSData *) mimeAttachTag; - -/* move & copy operations */ -- (void) copyToAttachment: (MAPIStoreAttachment *) newAttachment inMemCtx: (TALLOC_CTX *) memCtx; - -/* subclasses */ -- (MAPIStoreEmbeddedMessage *) openEmbeddedMessage; -- (MAPIStoreEmbeddedMessage *) createEmbeddedMessage; - -@end - -#endif /* MAPISTOREATTACHMENT_H */ diff --git a/OpenChange/MAPIStoreAttachment.m b/OpenChange/MAPIStoreAttachment.m deleted file mode 100644 index 754436d7e..000000000 --- a/OpenChange/MAPIStoreAttachment.m +++ /dev/null @@ -1,194 +0,0 @@ -/* MAPIStoreAttachment.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import "MAPIStoreAttachment.h" -#import "MAPIStoreEmbeddedMessage.h" -#import "MAPIStoreContext.h" -#import "MAPIStoreMapping.h" -#import "MAPIStoreMessage.h" -#import "MAPIStoreTypes.h" -#import "NSObject+MAPIStore.h" - -#undef DEBUG -#include -#include -#include -#include - -@implementation MAPIStoreAttachment - -- (void) setAID: (uint32_t) newAID -{ - aid = newAID; -} - -- (uint32_t) AID -{ - return aid; -} - -- (NSString *) nameInContainer -{ - return [NSString stringWithFormat: @"%d", aid]; -} - -- (NSData *) mimeAttachTag -{ - static NSData *mimeAttachTag = nil; - char tagBytes[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x14, 0x03, 0x0a, 0x04}; - - if (!mimeAttachTag) - { - mimeAttachTag = [NSData dataWithBytes: tagBytes length: 9]; - [mimeAttachTag retain]; - } - - return mimeAttachTag; -} - -- (enum mapistore_error) getPidTagMid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongLongValue (memCtx, [container objectId]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, aid); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagRenderingPosition: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0xffffffff); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAccessLevel: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) openEmbeddedMessage: (MAPIStoreEmbeddedMessage **) messagePtr - withMID: (uint64_t *) mid - withMAPIStoreMsg: (struct mapistore_message **) mapistoreMsgPtr - inMemCtx: (TALLOC_CTX *) memCtx -{ - MAPIStoreEmbeddedMessage *attMessage; - struct mapistore_message *mapistoreMsg; - - mapistoreMsg = talloc_zero (memCtx, struct mapistore_message); - - attMessage = [self openEmbeddedMessage]; - if (attMessage) - { - *mid = [attMessage objectId]; - *messagePtr = attMessage; - *mapistoreMsgPtr = mapistoreMsg; - } - - return (attMessage ? MAPISTORE_SUCCESS : MAPISTORE_ERROR); -} - -- (enum mapistore_error) 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; - } - - return (attMessage ? MAPISTORE_SUCCESS : MAPISTORE_ERROR); -} - -- (NSDate *) creationTime -{ - return [container creationTime]; -} - -- (NSDate *) lastModificationTime -{ - return [container lastModificationTime]; -} - -- (uint64_t) objectVersion -{ - /* attachments have no version number */ - return ULLONG_MAX; -} - -- (void) copyToAttachment: (MAPIStoreAttachment *) newAttachment inMemCtx: (TALLOC_CTX *) memCtx -{ - void *attachMethod; - enum mapistore_error error; - MAPIStoreEmbeddedMessage *embeddedMessage, *newEmbeddedMessage; - - [self copyPropertiesToObject: newAttachment inMemCtx: memCtx]; - - 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 inMemCtx: memCtx]; - } - talloc_free (attachMethod); - } -} - -/* subclasses */ -- (MAPIStoreEmbeddedMessage *) openEmbeddedMessage -{ - // [self subclassResponsibility: _cmd]; - - return nil; -} - -- (MAPIStoreEmbeddedMessage *) createEmbeddedMessage -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -@end diff --git a/OpenChange/MAPIStoreAttachmentTable.h b/OpenChange/MAPIStoreAttachmentTable.h deleted file mode 100644 index d066a7b8c..000000000 --- a/OpenChange/MAPIStoreAttachmentTable.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreAttachmentTable.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREATTACHMENTTABLE_H -#define MAPISTOREATTACHMENTTABLE_H - -#import "MAPIStoreTable.h" - -@interface MAPIStoreAttachmentTable : MAPIStoreTable -@end - -#endif /* MAPISTOREATTACHMENTTABLE_H */ diff --git a/OpenChange/MAPIStoreAttachmentTable.m b/OpenChange/MAPIStoreAttachmentTable.m deleted file mode 100644 index 61c82dd1b..000000000 --- a/OpenChange/MAPIStoreAttachmentTable.m +++ /dev/null @@ -1,73 +0,0 @@ -/* MAPIStoreAttachmentTable.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import "MAPIStoreMessage.h" - -#import "MAPIStoreAttachmentTable.h" - -@implementation MAPIStoreAttachmentTable - -- (NSArray *) childKeys -{ - if (!childKeys) - { - childKeys = [(MAPIStoreMessage *) - container attachmentKeysMatchingQualifier: nil - andSortOrderings: sortOrderings]; - [childKeys retain]; - } - - return childKeys; -} - -- (NSArray *) restrictedChildKeys -{ - NSArray *keys; - - if (!restrictedChildKeys) - { - if (restrictionState != MAPIRestrictionStateAlwaysTrue) - { - if (restrictionState == MAPIRestrictionStateNeedsEval) - keys = [(MAPIStoreMessage *) - container attachmentKeysMatchingQualifier: restriction - andSortOrderings: sortOrderings]; - else - keys = [NSArray array]; - } - else - keys = [self childKeys]; - - ASSIGN (restrictedChildKeys, keys); - } - - return restrictedChildKeys; -} - -- (id) lookupChild: (NSString *) childKey -{ - return [(MAPIStoreMessage *) container lookupAttachment: childKey]; -} - -@end diff --git a/OpenChange/MAPIStoreAuthenticator.h b/OpenChange/MAPIStoreAuthenticator.h deleted file mode 100644 index ce88a60be..000000000 --- a/OpenChange/MAPIStoreAuthenticator.h +++ /dev/null @@ -1,54 +0,0 @@ - -/* MAPIStoreAuthenticator.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREAUTHENTICATOR_H -#define MAPISTOREAUTHENTICATOR_H - -#import - -@class NSString; -@class NSURL; - -@class WOContext; - -@interface MAPIStoreAuthenticator : NSObject -{ - NSString *username; - NSString *password; -} - -- (void) setUsername: (NSString *) newUsername; -- (NSString *) username; - -- (void) setPassword: (NSString *) newPassword; - -- (NSString *) imapPasswordInContext: (WOContext *) context - forURL: (NSURL *) server - forceRenew: (BOOL) renew; - -- (NSString *) passwordInContext: (WOContext *) context; - - -@end - -#endif /* MAPISTOREAUTHENTICATOR_H */ diff --git a/OpenChange/MAPIStoreAuthenticator.m b/OpenChange/MAPIStoreAuthenticator.m deleted file mode 100644 index 41e4ed081..000000000 --- a/OpenChange/MAPIStoreAuthenticator.m +++ /dev/null @@ -1,79 +0,0 @@ -/* MAPIStoreAuthenticator.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import - -#import -#import - -#import "MAPIStoreAuthenticator.h" - -@implementation MAPIStoreAuthenticator - -- (void) dealloc -{ - [username release]; - [password release]; - [super dealloc]; -} - -- (void) setUsername: (NSString *) newUsername -{ - ASSIGN (username, newUsername); -} - -- (NSString *) username -{ - return username; -} - -- (void) setPassword: (NSString *) newPassword -{ - ASSIGN (password, newPassword); -} - -- (SOGoUser *) userInContext: (WOContext *)_ctx -{ - return [SOGoUser userWithLogin: username - roles: [NSArray arrayWithObject: SoRole_Authenticated]]; -} - -- (NSString *) imapPasswordInContext: (WOContext *) context - forURL: (NSURL *) server - forceRenew: (BOOL) renew -{ - NSString *imapPassword; - - if (renew) - imapPassword = nil; - else - imapPassword = password; - - return imapPassword; -} - -- (NSString *) passwordInContext: (WOContext *) context -{ - return password; -} -@end diff --git a/OpenChange/MAPIStoreCalTaskFolder.h b/OpenChange/MAPIStoreCalTaskFolder.h deleted file mode 100644 index 92b75e463..000000000 --- a/OpenChange/MAPIStoreCalTaskFolder.h +++ /dev/null @@ -1,35 +0,0 @@ -/* MAPIStoreCalTaskFolder.h - this file is part of SOGo - * - * Copyright (C) 2016 Enrique J. Hernandez - * - * Author: Enrique J. Hernandez - * - * 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 MAPISTORECALTASKFOLDER_H -#define MAPISTORECALTASKFOLDER_H - -#import "MAPIStoreGCSFolder.h" - -/* This class is intended to share code between Calendar and Tasks as - of nowadays share the table */ - -@interface MAPIStoreCalTaskFolder : MAPIStoreGCSFolder - -@end - -#endif /* MAPISTORECALTASKFOLDER_H */ diff --git a/OpenChange/MAPIStoreCalTaskFolder.m b/OpenChange/MAPIStoreCalTaskFolder.m deleted file mode 100644 index 8876c77e5..000000000 --- a/OpenChange/MAPIStoreCalTaskFolder.m +++ /dev/null @@ -1,101 +0,0 @@ -/* MAPIStoreCalTaskFolder.m - this file is part of SOGo - * - * Copyright (C) 2016 Enrique J. Hernandez - * - * Author: Enrique J. Hernandez - * - * 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 -#import -#import -#import - -#import - -#import "MAPIStoreCalTaskFolder.h" - -@implementation MAPIStoreCalTaskFolder - -- (NSArray *) expandRoles: (NSArray *) roles -{ - static NSDictionary *rolesMap = nil; - NSArray *subRoles; - NSMutableSet *expandedRoles; - NSString *role, *subRole; - NSUInteger i, max, j; - - if (!rolesMap) - { - /* Build the map of array permissions */ - rolesMap = [[NSDictionary alloc] initWithObjects: [NSArray arrayWithObjects: - [NSArray arrayWithObjects: SOGoCalendarRole_PublicDAndTViewer, - SOGoCalendarRole_PublicViewer, - SOGoCalendarRole_PublicResponder, - SOGoCalendarRole_PublicModifier, nil], - [NSArray arrayWithObjects: SOGoCalendarRole_ConfidentialDAndTViewer, - SOGoCalendarRole_ConfidentialViewer, - SOGoCalendarRole_ConfidentialResponder, - SOGoCalendarRole_ConfidentialModifier, nil], - [NSArray arrayWithObjects: SOGoCalendarRole_PrivateDAndTViewer, - SOGoCalendarRole_PrivateViewer, - SOGoCalendarRole_PrivateResponder, - SOGoCalendarRole_PrivateModifier, nil], - [NSArray arrayWithObjects: SOGoCalendarRole_ComponentDAndTViewer, - SOGoCalendarRole_ComponentViewer, - SOGoCalendarRole_ComponentResponder, - SOGoCalendarRole_ComponentModifier, nil], - nil] - forKeys: [NSArray arrayWithObjects: @"Public", @"Confidential", @"Private", - @"Component", nil]]; - } - - max = [roles count]; - expandedRoles = [NSMutableSet set]; - for (i = 0; i < max; i++) - { - role = [roles objectAtIndex: i]; - subRoles = nil; - if ([role hasPrefix: @"Public"]) - subRoles = [rolesMap objectForKey: @"Public"]; - else if ([role hasPrefix: @"Confidential"]) - subRoles = [rolesMap objectForKey: @"Confidential"]; - else if ([role hasPrefix: @"Private"]) - subRoles = [rolesMap objectForKey: @"Private"]; - else if ([role hasPrefix: @"Component"]) - subRoles = [rolesMap objectForKey: @"Component"]; - - if (subRoles) - { - for (j = 0; j < [subRoles count]; j++) - { - subRole = [subRoles objectAtIndex: j]; - [expandedRoles addObject: subRole]; - - if ([subRole isEqualToString: role]) - break; - } - } - else - { - [expandedRoles addObject: role]; - } - } - - return [expandedRoles allObjects]; -} - -@end diff --git a/OpenChange/MAPIStoreCalTaskMessage.h b/OpenChange/MAPIStoreCalTaskMessage.h deleted file mode 100644 index 8e284b414..000000000 --- a/OpenChange/MAPIStoreCalTaskMessage.h +++ /dev/null @@ -1,40 +0,0 @@ -/* MAPIStoreCalTaskMessage.h - this file is part of SOGo - * - * Copyright (C) 2016 Enrique J. Hernandez - * - * Author: Enrique J. Hernandez - * - * 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 MAPISTORECALTASKMESSAGE_H -#define MAPISTORECALTASKMESSAGE_H - -#import "MAPIStoreGCSMessage.h" - -/* This class is intended to share common logic for Calendar and Tasks - as of today they are stored in the same table. This is relevant for - permissions */ -@interface MAPIStoreCalTaskMessage : MAPIStoreGCSMessage -{ -} - -/* Get the sensitivity (access class) from a message */ -- (NSUInteger) sensitivity; - -@end - -#endif /* MAPISTORECALTASKMESSAGE_H */ diff --git a/OpenChange/MAPIStoreCalTaskMessage.m b/OpenChange/MAPIStoreCalTaskMessage.m deleted file mode 100644 index b88e9c2ef..000000000 --- a/OpenChange/MAPIStoreCalTaskMessage.m +++ /dev/null @@ -1,107 +0,0 @@ -/* MAPIStoreCalTaskMessage.h - this file is part of SOGo - * - * Copyright (C) 2016 Enrique J. Hernandez - * - * Author: Enrique J. Hernandez - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#import -#import - -#import - -#import - -#import "MAPIStoreFolder.h" -#import "MAPIStoreCalTaskMessage.h" - -@implementation MAPIStoreCalTaskMessage - -/* It must be implemented by subclasses */ -- (NSUInteger) sensitivity -{ - [self subclassResponsibility: _cmd]; - - return 0; -} - -- (NSArray *) expandRoles: (NSArray *) roles -{ - return [container expandRoles: roles]; -} - -- (BOOL) subscriberCanModifyMessage -{ - BOOL rc; - NSArray *roles; - - roles = [self activeUserRoles]; - - if (isNew) - rc = [roles containsObject: SOGoRole_ObjectCreator]; - else - rc = ([roles containsObject: SOGoCalendarRole_ComponentModifier] - || [roles containsObject: SOGoCalendarRole_ComponentResponder]); - - /* Check if the message is owned and it has permission to edit it */ - if (!rc && [roles containsObject: MAPIStoreRightEditOwn]) - { - NSString *currentUser; - - currentUser = [[container context] activeUser]; - rc = [currentUser isEqual: [self ownerUser]]; - } - - if (!rc) - { - NSUInteger sensitivity; - - /* Get sensitivity of the message to check if the user can - modify the message */ - sensitivity = [self sensitivity]; - /* FIXME: Use OpenChange constant names */ - switch (sensitivity) - { - case 0: /* PUBLIC */ - rc = [roles containsObject: SOGoCalendarRole_PublicModifier] - || [roles containsObject: SOGoCalendarRole_PublicResponder]; - break; - case 1: /* PERSONAL */ - case 2: /* PRIVATE */ - rc = [roles containsObject: SOGoCalendarRole_PrivateModifier] - || [roles containsObject: SOGoCalendarRole_PrivateResponder]; - break; - case 3: /* CONFIDENTIAL */ - rc = [roles containsObject: SOGoCalendarRole_ConfidentialModifier] - || [roles containsObject: SOGoCalendarRole_ConfidentialResponder]; - } - } - return rc; -} - -- (BOOL) subscriberCanReadMessage -{ - NSArray *roles; - - roles = [self activeUserRoles]; - - return ([roles containsObject: SOGoCalendarRole_ComponentViewer] - || [roles containsObject: SOGoCalendarRole_ComponentDAndTViewer] - || [self subscriberCanModifyMessage]); -} - -@end diff --git a/OpenChange/MAPIStoreCalendarAttachment.h b/OpenChange/MAPIStoreCalendarAttachment.h deleted file mode 100644 index b0a35d6b2..000000000 --- a/OpenChange/MAPIStoreCalendarAttachment.h +++ /dev/null @@ -1,43 +0,0 @@ -/* MAPIStoreCalendarAttachment.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORECALENDARATTACHMENT_H -#define MAPISTORECALENDARATTACHMENT_H - -#import "MAPIStoreAttachment.h" - -@class NSTimeZone; - -@class iCalEvent; - -@interface MAPIStoreCalendarAttachment : MAPIStoreAttachment -{ - iCalEvent *event; - NSTimeZone *timeZone; -} - -- (void) setEvent: (iCalEvent *) newEvent; -- (iCalEvent *) event; - -@end - -#endif /* MAPISTORECALENDARATTACHMENT_H */ diff --git a/OpenChange/MAPIStoreCalendarAttachment.m b/OpenChange/MAPIStoreCalendarAttachment.m deleted file mode 100644 index b2044b602..000000000 --- a/OpenChange/MAPIStoreCalendarAttachment.m +++ /dev/null @@ -1,255 +0,0 @@ -/* MAPIStoreCalendarAttachment.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import - -#import -#import - -#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" - -#undef DEBUG -#include -#include -#include -#include - -@implementation MAPIStoreCalendarAttachment - -- (id) init -{ - if ((self = [super init])) - { - event = nil; - timeZone = nil; - } - - return self; -} - -- (id) initInContainer: (MAPIStoreObject *) newContainer -{ - MAPIStoreUserContext *userContext; - - if ((self = [super initInContainer: newContainer])) - { - userContext = [newContainer userContext]; - ASSIGN (timeZone, [userContext timeZone]); - } - - return self; -} - -- (void) dealloc -{ - [event release]; - [timeZone release]; - [super dealloc]; -} - -- (void) setEvent: (iCalEvent *) newEvent -{ - ASSIGN (event, newEvent); -} - -- (iCalEvent *) event -{ - return event; -} - -- (NSString *) nameInContainer -{ - return [[event uniqueChildWithTag: @"recurrence-id"] - flattenedValuesForKey: @""]; -} - -- (enum mapistore_error) getPidTagAttachmentHidden: (void **) data - inMemCtx: (TALLOC_CTX *) localMemCtx -{ - return [self getYes: data inMemCtx: localMemCtx]; -} - -- (enum mapistore_error) getPidTagAttachmentFlags: (void **) data - inMemCtx: (TALLOC_CTX *) localMemCtx -{ - *data = MAPILongValue (localMemCtx, 0x00000002); /* afException */ - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachmentLinkId: (void **) data - inMemCtx: (TALLOC_CTX *) localMemCtx -{ - return [self getLongZero: data inMemCtx: localMemCtx]; -} - -- (enum mapistore_error) getPidTagAttachFlags: (void **) data - inMemCtx: (TALLOC_CTX *) localMemCtx -{ - return [self getLongZero: data inMemCtx: localMemCtx]; -} - -- (enum mapistore_error) getPidTagAttachMethod: (void **) data - inMemCtx: (TALLOC_CTX *) localMemCtx -{ - *data = MAPILongValue (localMemCtx, afEmbeddedMessage); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachEncoding: (void **) data - inMemCtx: (TALLOC_CTX *) localMemCtx -{ - *data = [[NSData data] asBinaryInMemCtx: localMemCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) localMemCtx -{ - *data = [@"Untitled" asUnicodeInMemCtx: localMemCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachmentContactPhoto: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagExceptionReplaceTime: (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; -} - -- (enum mapistore_error) 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; -} - -- (enum mapistore_error) 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; -} - -/* subclasses */ -- (MAPIStoreCalendarEmbeddedMessage *) openEmbeddedMessage -{ - MAPIStoreCalendarEmbeddedMessage *msg; - - msg = [MAPIStoreCalendarEmbeddedMessage - mapiStoreObjectInContainer: self]; - - return msg; -} - -- (MAPIStoreCalendarEmbeddedMessage *) createEmbeddedMessage -{ - MAPIStoreCalendarEmbeddedMessage *msg; - - msg = [self openEmbeddedMessage]; - [msg setIsNew: YES]; - - return msg; -} - -@end diff --git a/OpenChange/MAPIStoreCalendarContext.h b/OpenChange/MAPIStoreCalendarContext.h deleted file mode 100644 index e6f804805..000000000 --- a/OpenChange/MAPIStoreCalendarContext.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreCalendarContext.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTORECALENDARCONTEXT_H -#define MAPISTORECALENDARCONTEXT_H - -#import "MAPIStoreGCSBaseContext.h" - -@interface MAPIStoreCalendarContext : MAPIStoreGCSBaseContext - -@end - -#endif /* MAPISTORECALENDARCONTEXT_H */ diff --git a/OpenChange/MAPIStoreCalendarContext.m b/OpenChange/MAPIStoreCalendarContext.m deleted file mode 100644 index 035741afb..000000000 --- a/OpenChange/MAPIStoreCalendarContext.m +++ /dev/null @@ -1,64 +0,0 @@ -/* MAPIStoreCalendarContext.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import - -#import "MAPIStoreMapping.h" -#import "MAPIStoreCalendarFolder.h" -#import "MAPIStoreUserContext.h" - -#import "MAPIStoreCalendarContext.h" - -#undef DEBUG -#include - -static Class MAPIStoreCalendarFolderK; - -@implementation MAPIStoreCalendarContext - -+ (void) initialize -{ - MAPIStoreCalendarFolderK = [MAPIStoreCalendarFolder class]; -} - -+ (NSString *) MAPIModuleName -{ - return @"calendar"; -} - -+ (enum mapistore_context_role) MAPIContextRole -{ - return MAPISTORE_CALENDAR_ROLE; -} - -- (Class) MAPIStoreFolderClass -{ - return MAPIStoreCalendarFolderK; -} - -+ (NSString *) folderNameSuffix -{ - return @"c"; -} - -@end diff --git a/OpenChange/MAPIStoreCalendarEmbeddedMessage.h b/OpenChange/MAPIStoreCalendarEmbeddedMessage.h deleted file mode 100644 index 3e27c575c..000000000 --- a/OpenChange/MAPIStoreCalendarEmbeddedMessage.h +++ /dev/null @@ -1,34 +0,0 @@ -/* MAPIStoreCalendarEmbeddedMessage.h - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 */ diff --git a/OpenChange/MAPIStoreCalendarEmbeddedMessage.m b/OpenChange/MAPIStoreCalendarEmbeddedMessage.m deleted file mode 100644 index 02a776949..000000000 --- a/OpenChange/MAPIStoreCalendarEmbeddedMessage.m +++ /dev/null @@ -1,215 +0,0 @@ -/* MAPIStoreCalendarEmbeddedMessage.m - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import -#import - -#import - -#import -#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 - -@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 - 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; -} - -- (enum mapistore_error) getPidTagMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = talloc_strdup (memCtx, "IPM.OLE.CLASS.{00061055-0000-0000-C000-000000000046}"); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMessageFlags: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, MSGFLAG_UNMODIFIED); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagResponseRequested: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -/* discarded properties */ - -- (enum mapistore_error) getPidLidAppointmentLastSequence: (void **) - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidLidMeetingWorkspaceUrl: (void **) - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidLidContacts: (void **) - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagSensitivity: (void **) - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidLidPrivate: (void **) - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidNameKeywords: (void **) - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidLidFExceptionalBody: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (void) save: (TALLOC_CTX *) memCtx -{ -// (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 - isNew: NO - inMemCtx: memCtx]; -} - -@end diff --git a/OpenChange/MAPIStoreCalendarFolder.h b/OpenChange/MAPIStoreCalendarFolder.h deleted file mode 100644 index 9b3a4cf5c..000000000 --- a/OpenChange/MAPIStoreCalendarFolder.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreCalendarFolder.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORECALENDARFOLDER_H -#define MAPISTORECALENDARFOLDER_H - -#import "MAPIStoreCalTaskFolder.h" - -@interface MAPIStoreCalendarFolder : MAPIStoreCalTaskFolder - -@end - -#endif /* MAPISTORECALENDARFOLDER_H */ diff --git a/OpenChange/MAPIStoreCalendarFolder.m b/OpenChange/MAPIStoreCalendarFolder.m deleted file mode 100644 index ed949e638..000000000 --- a/OpenChange/MAPIStoreCalendarFolder.m +++ /dev/null @@ -1,226 +0,0 @@ -/* MAPIStoreCalendarFolder.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIApplication.h" -#import "MAPIStoreCalendarContext.h" -#import "MAPIStoreCalendarMessage.h" -#import "MAPIStoreCalendarMessageTable.h" -#import "MAPIStoreUserContext.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreCalendarFolder.h" - -#include -#include -#include - -@implementation MAPIStoreCalendarFolder - -- (MAPIStoreMessageTable *) messageTable -{ - [self synchroniseCache]; - return [MAPIStoreCalendarMessageTable tableForContainer: self]; -} - -- (NSString *) component -{ - return @"vevent"; -} - -- (MAPIStoreMessage *) createMessage -{ - MAPIStoreMessage *newMessage; - SOGoAppointmentObject *newEntry; - NSString *name; - - [[self userContext] activate]; - - name = [NSString stringWithFormat: @"%@.ics", - [SOGoObject globallyUniqueObjectId]]; - newEntry = [SOGoAppointmentObject objectWithName: name - inContainer: sogoObject]; - [newEntry setIsNew: YES]; - newMessage = [MAPIStoreCalendarMessage mapiStoreObjectWithSOGoObject: newEntry - inContainer: self]; - return newMessage; -} - -- (NSArray *) rolesForExchangeRights: (uint32_t) rights -{ - /* Limitations - - Following rights are not supported by SOGo specifically: - - - CreateSubfolders: No calendar subfolders - - FolderVisible: It is inferred by other rights when extracting - */ - NSMutableArray *roles; - - roles = [NSMutableArray arrayWithCapacity: 6]; - if (rights & RightsCreateItems) - [roles addObject: SOGoRole_ObjectCreator]; - if (rights & RightsDeleteAll) - [roles addObject: SOGoRole_ObjectEraser]; - if (rights & RightsDeleteOwn) - [roles addObject: MAPIStoreRightDeleteOwn]; - - if (rights & RightsEditAll) - { - [roles addObject: SOGoCalendarRole_PublicModifier]; - [roles addObject: SOGoCalendarRole_PrivateModifier]; - [roles addObject: SOGoCalendarRole_ConfidentialModifier]; - } - if (rights & RightsEditOwn) - [roles addObject: MAPIStoreRightEditOwn]; - - if (rights & RightsReadItems) - { - [roles addObject: SOGoCalendarRole_PublicViewer]; - [roles addObject: SOGoCalendarRole_PrivateViewer]; - [roles addObject: SOGoCalendarRole_ConfidentialViewer]; - } - if (rights & RightsFreeBusySimple) - [roles addObject: SOGoCalendarRole_PublicDAndTViewer]; - - if (rights & RightsFreeBusyDetailed) - [roles addObject: SOGoCalendarRole_ConfidentialDAndTViewer]; - - if (rights & RightsFolderOwner) - [roles addObject: MAPIStoreRightFolderOwner]; - - if (rights & RightsFolderContact) - [roles addObject: MAPIStoreRightFolderContact]; - - // [self logWithFormat: @"roles for rights %.8x = (%@)", rights, roles]; - - return roles; -} - -- (uint32_t) exchangeRightsForRoles: (NSArray *) roles -{ - uint32_t rights = 0; - - if ([roles containsObject: SOGoRole_ObjectCreator]) - rights |= RightsCreateItems; - if ([roles containsObject: SOGoRole_ObjectEraser]) - rights |= RightsDeleteAll | RightsDeleteOwn; - if ([roles containsObject: SOGoCalendarRole_PublicModifier] - && [roles containsObject: SOGoCalendarRole_PrivateModifier] - && [roles containsObject: SOGoCalendarRole_ConfidentialModifier]) - rights |= RightsReadItems | RightsEditAll | RightsEditOwn | RightsFreeBusySimple | RightsFreeBusyDetailed; - else if ([roles containsObject: SOGoCalendarRole_PublicViewer] - && [roles containsObject: SOGoCalendarRole_PrivateViewer] - && [roles containsObject: SOGoCalendarRole_ConfidentialViewer]) - rights |= RightsReadItems; - - if ([roles containsObject: MAPIStoreRightEditOwn]) - rights |= RightsEditOwn; - if ([roles containsObject: MAPIStoreRightDeleteOwn]) - rights |= RightsDeleteOwn; - - if ([roles containsObject: SOGoCalendarRole_PublicDAndTViewer]) - rights |= RightsFreeBusySimple; - - if ([roles containsObject: SOGoCalendarRole_ConfidentialDAndTViewer]) - rights |= RightsFreeBusySimple | RightsFreeBusyDetailed; - - if ((rights & RightsReadItems) != 0 || (rights & RightsCreateItems) != 0 || (rights & RightsDeleteAll) != 0) - rights |= RoleNone; /* actually "folder visible" */ - - if ([roles containsObject: MAPIStoreRightFolderOwner]) - rights |= RightsFolderOwner | RoleNone; - - if ([roles containsObject: MAPIStoreRightFolderContact]) - rights |= RightsFolderContact; - - // [self logWithFormat: @"rights for roles (%@) = %.8x", roles, rights]; - - return rights; -} - -- (BOOL) subscriberCanReadMessages -{ - static NSArray *viewerRoles = nil; - - if (!viewerRoles) - viewerRoles = [[NSArray alloc] initWithObjects: - SOGoCalendarRole_PublicViewer, - SOGoCalendarRole_PublicDAndTViewer, - SOGoCalendarRole_PrivateViewer, - SOGoCalendarRole_PrivateDAndTViewer, - SOGoCalendarRole_ConfidentialViewer, - SOGoCalendarRole_ConfidentialDAndTViewer, - nil]; - - return ([[self activeUserRoles] firstObjectCommonWithArray: viewerRoles] - != nil); -} - -- (BOOL) subscriberCanModifyMessages -{ - static NSArray *modifierRoles = nil; - - if (!modifierRoles) - modifierRoles = [[NSArray alloc] initWithObjects: - SOGoCalendarRole_PublicModifier, - SOGoCalendarRole_PrivateModifier, - SOGoCalendarRole_ConfidentialModifier, - nil]; - - return ([[self activeUserRoles] firstObjectCommonWithArray: modifierRoles] - != nil); -} - -- (EOQualifier *) aclQualifier -{ - return [EOQualifier qualifierWithQualifierFormat: - [(SOGoAppointmentFolder *) sogoObject aclSQLListingFilter]]; -} - -- (enum mapistore_error) getPidTagContainerClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPF.Appointment" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagDefaultPostMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPM.Appointment" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -@end diff --git a/OpenChange/MAPIStoreCalendarMessage.h b/OpenChange/MAPIStoreCalendarMessage.h deleted file mode 100644 index 99e286073..000000000 --- a/OpenChange/MAPIStoreCalendarMessage.h +++ /dev/null @@ -1,40 +0,0 @@ -/* MAPIStoreCalendarMessage.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORECALENDARMESSAGE_H -#define MAPISTORECALENDARMESSAGE_H - -#import "MAPIStoreCalTaskMessage.h" - -@class iCalCalendar; -@class iCalEvent; -@class MAPIStoreAppointmentWrapper; - -@interface MAPIStoreCalendarMessage : MAPIStoreCalTaskMessage -{ - iCalCalendar *calendar; - iCalEvent *masterEvent; -} - -@end - -#endif /* MAPISTORECALENDARMESSAGE_H */ diff --git a/OpenChange/MAPIStoreCalendarMessage.m b/OpenChange/MAPIStoreCalendarMessage.m deleted file mode 100644 index 5ec92d07f..000000000 --- a/OpenChange/MAPIStoreCalendarMessage.m +++ /dev/null @@ -1,669 +0,0 @@ -/* MAPIStoreCalendarMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -/* TODO: - - merge common code with tasks - - take the tz definitions from Outlook */ - -#include -#include - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "iCalEvent+MAPIStore.h" -#import "MAPIStoreAppointmentWrapper.h" -#import "MAPIStoreCalendarAttachment.h" -#import "MAPIStoreCalendarFolder.h" -#import "MAPIStoreContext.h" -#import "MAPIStoreMapping.h" -#import "MAPIStoreRecurrenceUtils.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSDate+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" -#import "NSValue+MAPIStore.h" - -#import "MAPIStoreCalendarMessage.h" - -#undef DEBUG -#include -#include -#include -#include -#include -#include -#include - -// extern void ndr_print_AppointmentRecurrencePattern(struct ndr_print *ndr, const char *name, const struct AppointmentRecurrencePattern *r); - -static Class NSArrayK, MAPIStoreAppointmentWrapperK; - -@implementation SOGoAppointmentObject (MAPIStoreExtension) - -- (Class) mapistoreMessageClass -{ - return [MAPIStoreCalendarMessage class]; -} - -@end - -@implementation MAPIStoreCalendarMessage - -+ (void) initialize -{ - NSArrayK = [NSArray class]; - MAPIStoreAppointmentWrapperK = [MAPIStoreAppointmentWrapper class]; -} - -+ (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP - inMemCtx: (TALLOC_CTX *) memCtx -{ - BOOL listedProperties[65536]; - NSUInteger count; - uint16_t propId; - - memset (listedProperties, NO, 65536 * sizeof (BOOL)); - [super getAvailableProperties: propertiesP inMemCtx: memCtx]; - for (count = 0; count < (*propertiesP)->cValues; count++) - { - propId = ((*propertiesP)->aulPropTag[count] >> 16) & 0xffff; - listedProperties[propId] = YES; - } - [MAPIStoreAppointmentWrapper fillAvailableProperties: *propertiesP - withExclusions: listedProperties]; - - return MAPISTORE_SUCCESS; -} - -- (id) init -{ - if ((self = [super init])) - { - calendar = nil; - masterEvent = nil; - } - - return self; -} - -- (void) _setupAttachmentParts -{ - NSUInteger count, max; - NSArray *events; - NSString *newKey; - MAPIStoreCalendarAttachment *attachment; - NSUInteger aid; - iCalEvent *event; - - events = [calendar events]; - max = [events count]; - for (count = 1; count < max; count++) - { - attachment = [MAPIStoreCalendarAttachment - mapiStoreObjectInContainer: self]; - /* we now that there are no attachments yet, so we can assume that the - right AID is 0 from the start */ - aid = count - 1; - [attachment setAID: aid]; - event = [events objectAtIndex: count]; - [attachment setEvent: event]; - newKey = [[event uniqueChildWithTag: @"recurrence-id"] - flattenedValuesForKey: @""]; - [attachmentParts setObject: attachment forKey: newKey]; - } -} - -- (id) initWithSOGoObject: (id) newSOGoObject - inContainer: (MAPIStoreObject *) newFolder -{ - MAPIStoreContext *context; - MAPIStoreUserContext *userContext; - iCalCalendar *origCalendar; - MAPIStoreAppointmentWrapper *appointmentWrapper; - - if ((self = [super initWithSOGoObject: newSOGoObject - inContainer: newFolder])) - { - if ([newSOGoObject isNew]) - { - ASSIGN (calendar, [iCalCalendar groupWithTag: @"vcalendar"]); - [calendar setVersion: @"2.0"]; - [calendar setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"]; - masterEvent = [iCalEvent groupWithTag: @"vevent"]; - [calendar addChild: masterEvent]; - [masterEvent setCreated: [NSCalendarDate date]]; - } - else - { - origCalendar = [sogoObject calendar: YES secure: YES]; - if (!origCalendar) - { - [self errorWithFormat: @"Incorrect calendar event %@. Empty message is created", - [self url]]; - return self; - } - calendar = [origCalendar mutableCopy]; - masterEvent = [[calendar events] objectAtIndex: 0]; - [self _setupAttachmentParts]; - } - context = [self context]; - userContext = [self userContext]; - appointmentWrapper - = [MAPIStoreAppointmentWrapper wrapperWithICalEvent: masterEvent - andUser: [userContext sogoUser] - andSenderEmail: nil - withConnectionInfo: [context connectionInfo]]; - [self addProxy: appointmentWrapper]; - } - - return self; -} - -- (void) dealloc -{ - //NSLog(@"MAPIStoreCalendarMessage: -dealloc (%p)", self); - [calendar release]; - [super dealloc]; -} - -- (MAPIStoreAppointmentWrapper *) _appointmentWrapper -{ - NSUInteger i, max; - id proxy; - max = [proxies count]; - for (i = 0; i < max; i++) { - proxy = [proxies objectAtIndex: i]; - if ([proxy isKindOfClass: MAPIStoreAppointmentWrapperK]) - { - return proxy; - } - } - return nil; -} - - -/* getters */ -- (enum mapistore_error) getPidTagMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - SOGoUser *owner; - - owner = [[self userContext] sogoUser]; - if ([masterEvent userAsAttendee: owner]) - *data = talloc_strdup (memCtx, "IPM.Schedule.Meeting.Request"); - else - *data = talloc_strdup (memCtx, "IPM.Appointment"); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidSideEffects: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, - seOpenToDelete | seOpenToCopy | seOpenToMove - | seCoerceToInbox | seOpenForCtxMenu); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -- (void) getMessageData: (struct mapistore_message **) dataPtr - inMemCtx: (TALLOC_CTX *) memCtx -{ - static NSString *recTypes[] = {@"orig", @"to", @"cc", @"bcc"}; - static NSInteger recTypesValue[] = {MAPI_ORIG, MAPI_TO, MAPI_CC, MAPI_BCC}; - struct mapistore_message *msgData; - NSDictionary *recipients, *contactInfos; - NSString *email; - NSArray *attendees; - NSDictionary *attendee; - SOGoUserManager *mgr; - struct mapistore_message_recipient *recipient; - NSUInteger nRecType, maxRecTypes, count, max, propCount; - NSObject *currentValue; - - [super getMessageData: &msgData inMemCtx: memCtx]; - - /* The presence of the "recipients" meta-property means that our most recent - list of recipients has not been saved yet and that we must return that - one instead of the one stored in the event. */ - recipients = [properties objectForKey: @"recipients"]; - if (recipients) - { - mgr = [SOGoUserManager sharedUserManager]; - - /* TODO: this code might need to be moved into MAPIStoreMessage */ - msgData->columns = set_SPropTagArray (msgData, 9, - PR_OBJECT_TYPE, - PR_DISPLAY_TYPE, - PR_7BIT_DISPLAY_NAME_UNICODE, - PR_SMTP_ADDRESS_UNICODE, - PR_SEND_INTERNET_ENCODING, - PR_RECIPIENT_DISPLAY_NAME_UNICODE, - PR_RECIPIENT_FLAGS, - PR_RECIPIENT_ENTRYID, - PR_RECIPIENT_TRACKSTATUS); - - maxRecTypes = sizeof(recTypes) / sizeof(recTypes[0]); - for (nRecType = 0; nRecType < maxRecTypes; nRecType++) - { - attendees = [recipients objectForKey: recTypes[nRecType]]; - max = [attendees count]; - if (max > 0) - { - msgData->recipients_count += max; - msgData->recipients = talloc_realloc(msgData, - msgData->recipients, struct - mapistore_message_recipient, msgData->recipients_count); - recipient = msgData->recipients; - for (count = 0; count < max; count++) - { - attendee = [attendees objectAtIndex: count]; - recipient->type = recTypesValue[nRecType]; - email = [attendee objectForKey: @"email"]; - if (email) - { - contactInfos - = [mgr contactInfosForUserWithUIDorEmail: email]; - recipient->username = [[contactInfos - objectForKey: @"c_uid"] - asUnicodeInMemCtx: msgData]; - } - else - recipient->username = NULL; - - recipient->data = talloc_array(msgData, void *, - msgData->columns->cValues); - for (propCount = 0; - propCount < msgData->columns->cValues; - propCount++) - { - currentValue = [attendee objectForKey: MAPIPropertyKey (msgData->columns->aulPropTag[propCount])]; - [currentValue getValue: recipient->data + propCount - forTag: msgData->columns->aulPropTag[propCount] - inMemCtx: msgData]; - } - recipient++; - } - } - } - } - else - { - [[self _appointmentWrapper] fillMessageData: msgData - inMemCtx: memCtx]; - } - - *dataPtr = msgData; -} - -- (enum mapistore_error) getPidTagResponseRequested: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -/* This three methods: getPidTagNormalizedSubject, - getPidTagSensitivity and getPidTagImportance are implemented in - MAPIStoreMessage base class, then the proxy method is not reached - (see MAPIStoreObject). -*/ -- (enum mapistore_error) getPidTagNormalizedSubject: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - MAPIStoreAppointmentWrapper *appointmentWrapper; - - appointmentWrapper = [self _appointmentWrapper]; - if (appointmentWrapper) - return [appointmentWrapper getPidTagNormalizedSubject: data inMemCtx: memCtx]; - - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagSensitivity: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - MAPIStoreAppointmentWrapper *appointmentWrapper; - - appointmentWrapper = [self _appointmentWrapper]; - if (appointmentWrapper) - return [appointmentWrapper getPidTagSensitivity: data inMemCtx: memCtx]; - - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagImportance: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - MAPIStoreAppointmentWrapper *appointmentWrapper; - - appointmentWrapper = [self _appointmentWrapper]; - if (appointmentWrapper) - return [appointmentWrapper getPidTagImportance: data inMemCtx: memCtx]; - - *data = MAPILongValue (memCtx, 1); - - return MAPISTORE_SUCCESS; -} - - -- (NSString *) _uidFromGlobalObjectId: (TALLOC_CTX *) memCtx -{ - NSData *objectId; - NSString *uid = nil; - char *bytesDup, *uidStart; - NSUInteger length; - - /* NOTE: we only handle the generic case at the moment, see - MAPIStoreAppointmentWrapper */ - objectId = [properties - objectForKey: MAPIPropertyKey (PidLidGlobalObjectId)]; - if (objectId) - { - length = [objectId length]; - bytesDup = talloc_array (memCtx, char, length + 1); - memcpy (bytesDup, [objectId bytes], length); - bytesDup[length] = 0; - uidStart = bytesDup + length - 1; - while (uidStart != bytesDup && *(uidStart - 1)) - uidStart--; - if (uidStart > bytesDup && *uidStart) - uid = [NSString stringWithUTF8String: uidStart]; - talloc_free (bytesDup); - } - - return uid; -} - -- (SOGoAppointmentObject *) _resurrectRecord: (NSString *) cname - fromFolder: (SOGoAppointmentFolder *) folder -{ - NSArray *records; - EOQualifier *qualifier; - EOFetchSpecification *fs; - GCSFolder *ocsFolder; - SOGoAppointmentObject *newObject; - NSMutableDictionary *newRecord; - static NSArray *childRecordFields = nil; - - if (!childRecordFields) - { - childRecordFields = [NSArray arrayWithObjects: @"c_name", - @"c_creationdate", @"c_lastmodified", - @"c_content", nil]; - [childRecordFields retain]; - } - - ocsFolder = [folder ocsFolder]; - - qualifier - = [EOQualifier qualifierWithQualifierFormat: - [NSString stringWithFormat: @"c_name='%@'", cname]]; - fs = [EOFetchSpecification fetchSpecificationWithEntityName: [ocsFolder folderName] - qualifier: qualifier - sortOrderings: nil]; - records = [ocsFolder fetchFields: childRecordFields - fetchSpecification: fs - ignoreDeleted: NO]; - if ([records isKindOfClass: NSArrayK] && [records count]) - { - newRecord = [[records objectAtIndex: 0] mutableCopy]; - [newRecord setObject: [NSNumber numberWithInt: 0] - forKey: @"c_version"]; - newObject = [SOGoAppointmentObject objectWithRecord: newRecord - inContainer: folder]; - [newRecord autorelease]; - [newObject setIsNew: NO]; - } - else - newObject = nil; - - - return newObject; -} - -- (void) _fixupAppointmentObjectWithUID: (NSString *) uid -{ - NSString *cname, *url; - MAPIStoreMapping *mapping; - uint64_t objectId; - WOContext *woContext; - SOGoAppointmentFolder *folder; - SOGoAppointmentObject *newObject; - - cname = [[container sogoObject] resourceNameForEventUID: uid]; - if (cname) - isNew = NO; - else - cname = [NSString stringWithFormat: @"%@.ics", uid]; - - mapping = [self mapping]; - - url = [NSString stringWithFormat: @"%@%@", [container url], cname]; - folder = [sogoObject container]; - - /* reinstantiate the old sogo object and attach it to self */ - [[self userContext] activate]; - woContext = [[self userContext] woContext]; - if (isNew) - { - /* event could have been deleted, let's try to resurrect it */ - newObject = [self _resurrectRecord: cname fromFolder: folder]; - if (!newObject) - { - newObject = [SOGoAppointmentObject objectWithName: cname - inContainer: folder]; - [newObject setIsNew: YES]; - } - } - else - { - /* dissociate the object url from the old object's id */ - objectId = [mapping idFromURL: url]; - [mapping unregisterURLWithID: objectId]; - newObject = [folder lookupName: cname - inContext: woContext - acquire: NO]; - } - - /* dissociate the object url associated with this object, as we want to - discard it */ - objectId = [self objectId]; - [mapping unregisterURLWithID: objectId]; - - /* associate the new object url with this object id */ - [mapping registerURL: url withID: objectId]; - - [newObject setContext: woContext]; - ASSIGN (sogoObject, newObject); -} - -- (NSUInteger) sensitivity -{ - return [[self _appointmentWrapper] sensitivity]; -} - -- (NSString *) creator -{ - return [[self _appointmentWrapper] creator]; -} - -- (NSString *) owner -{ - return [[self _appointmentWrapper] owner]; -} - -- (void) _updateAttachedEvents -{ - NSArray *allAttachments; - NSUInteger count, max; - NSString *uid, *summary; - iCalEvent *event; - MAPIStoreCalendarAttachment *attachment; - - /* ensure that all exception events have the same UID as the master */ - uid = [masterEvent uid]; - summary = [masterEvent summary]; - - allAttachments = [attachmentParts allValues]; - max = [allAttachments count]; - for (count = 0; count < max; count++) - { - attachment = [allAttachments objectAtIndex: count]; - event = [attachment event]; - if ([[event summary] length] == 0) - [event setSummary: summary]; - [event setUid: uid]; - } -} - -- (void) save: (TALLOC_CTX *) memCtx -{ - // iCalCalendar *vCalendar; - // NSCalendarDate *now; - NSString *uid, *nameInContainer; - // iCalEvent *newEvent; - // iCalPerson *userPerson; - SOGoUser *activeUser; - NSRange rangeOfDot; - - if (isNew) - { - uid = [self _uidFromGlobalObjectId: memCtx]; - if (uid) - { - /* Hack required because of what's explained in oxocal 3.1.4.7.1: - basically, Outlook creates a copy of the event and then removes - the old instance. We perform a trickery to avoid performing those - operations in the backend, in a way that enables us to recover - the initial instance and act solely on it. */ - [self _fixupAppointmentObjectWithUID: uid]; - } - else - { - /* We create a UID from the nameInContainer, or the reverse if the - latter is already set... */ - nameInContainer = [sogoObject nameInContainer]; - if (nameInContainer) - { - rangeOfDot = [nameInContainer rangeOfString: @"." - options: NSBackwardsSearch]; - if (rangeOfDot.location == NSNotFound) - uid = nameInContainer; - else - uid = [nameInContainer substringToIndex: rangeOfDot.location]; - } - else - { - uid = [SOGoObject globallyUniqueObjectId]; - nameInContainer = [NSString stringWithFormat: @"%@.ics", uid]; - [sogoObject setNameInContainer: nameInContainer]; - } - } - [masterEvent setUid: uid]; - } - - // [self logWithFormat: @"-save, event props:"]; - // MAPIStoreDumpMessageProperties (newProperties); - - // now = [NSCalendarDate date]; - - activeUser = [[self context] activeUser]; - [masterEvent updateFromMAPIProperties: properties - inUserContext: [self userContext] - withActiveUser: activeUser - isNew: isNew - inMemCtx: memCtx]; - [self _updateAttachedEvents]; - [[self userContext] activate]; - [sogoObject updateContentWithCalendar: calendar - fromRequest: nil]; - [self updateVersions]; -} - -- (id) lookupAttachment: (NSString *) childKey -{ - return [attachmentParts objectForKey: childKey]; -} - -- (MAPIStoreAttachment *) createAttachment -{ - MAPIStoreCalendarAttachment *newAttachment; - uint32_t newAid; - NSString *newKey; - iCalEvent *newEvent; - - newAid = [[self attachmentKeys] count]; - - newAttachment = [MAPIStoreCalendarAttachment - mapiStoreObjectInContainer: self]; - [newAttachment setAID: newAid]; - newEvent = [iCalEvent groupWithTag: @"vevent"]; - [newAttachment setEvent: newEvent]; - [calendar addToEvents: newEvent]; - - newKey = [NSString stringWithFormat: @"%ul", newAid]; - [attachmentParts setObject: newAttachment - forKey: newKey]; - [attachmentKeys release]; - attachmentKeys = nil; - - return newAttachment; -} - -- (enum mapistore_error) setReadFlag: (uint8_t) flag -{ - return MAPISTORE_SUCCESS; -} - -@end diff --git a/OpenChange/MAPIStoreCalendarMessageTable.h b/OpenChange/MAPIStoreCalendarMessageTable.h deleted file mode 100644 index eeccbc455..000000000 --- a/OpenChange/MAPIStoreCalendarMessageTable.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreCalendarMessageTable.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTORECALENDARMESSAGETABLE_H -#define MAPISTORECALENDARMESSAGETABLE_H - -#import "MAPIStoreGCSMessageTable.h" - -@interface MAPIStoreCalendarMessageTable : MAPIStoreGCSMessageTable - -@end - -#endif /* MAPISTORECALENDARMESSAGETABLE_H */ diff --git a/OpenChange/MAPIStoreCalendarMessageTable.m b/OpenChange/MAPIStoreCalendarMessageTable.m deleted file mode 100644 index bbf05274f..000000000 --- a/OpenChange/MAPIStoreCalendarMessageTable.m +++ /dev/null @@ -1,193 +0,0 @@ -/* MAPIStoreCalendarMessageTable.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import - -#import - -#import - -#import "MAPIStoreCalendarMessage.h" -#import "MAPIStoreTypes.h" -#import "NSDate+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreCalendarMessageTable.h" - -#include - -static Class MAPIStoreCalendarMessageK = Nil; - -@implementation MAPIStoreCalendarMessageTable - -+ (void) initialize -{ - MAPIStoreCalendarMessageK = [MAPIStoreCalendarMessage class]; -} - -+ (Class) childObjectClass -{ - return MAPIStoreCalendarMessageK; -} - -- (EOQualifier *) _orgMailNotNullQualifier -{ - static EOQualifier *orgMailQualifier = nil; - EOQualifier *notNullQualifier, *nullQualifier, *notEmptyQualifier, *emptyQualifier; - - if (!orgMailQualifier) - { - nullQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_orgmail" - operatorSelector: EOQualifierOperatorEqual - value: [NSNull null]]; - notNullQualifier = [[EONotQualifier alloc] - initWithQualifier: nullQualifier]; - emptyQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_orgmail" - operatorSelector: EOQualifierOperatorEqual - value: @""]; - notEmptyQualifier = [[EONotQualifier alloc] - initWithQualifier: emptyQualifier]; - orgMailQualifier = [[EOAndQualifier alloc] - initWithQualifiers: notNullQualifier, - notEmptyQualifier, nil]; - [nullQualifier release]; - [notNullQualifier release]; - [emptyQualifier release]; - [notEmptyQualifier release]; - } - - return orgMailQualifier; -} - -- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState rc; - id value; - NSMutableString *likeString; - NSString *likePartString; - EOAndQualifier *andQualifier, *stringQualifier; - union { - uint32_t longValue; - char charValue[4]; - } apptIdValue; - - value = NSObjectFromMAPISPropValue (&res->lpProp); - switch ((uint32_t) res->ulPropTag) - { - case PR_MESSAGE_CLASS_UNICODE: - if ([value isEqualToString: @"IPM.Appointment"]) - rc = MAPIRestrictionStateAlwaysTrue; - else - rc = MAPIRestrictionStateAlwaysFalse; - break; - case PR_OWNER_APPT_ID: - // c_orgmail != NULL && c_orgmail != '' && c_uid like 'ab%89'; - apptIdValue.longValue = [value unsignedLongValue]; - likeString = [NSMutableString string]; - likePartString = [[NSString alloc] - initWithBytes: apptIdValue.charValue - length: 2 - encoding: NSISOLatin1StringEncoding]; - [likeString appendString: likePartString]; - [likePartString release]; - [likeString appendString: @"%%"]; - likePartString = [[NSString alloc] - initWithBytes: apptIdValue.charValue + 2 - length: 2 - encoding: NSISOLatin1StringEncoding]; - [likeString appendString: likePartString]; - [likePartString release]; - stringQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_uid" - operatorSelector: EOQualifierOperatorLike - value: likeString]; - andQualifier = [[EOAndQualifier alloc] - initWithQualifiers: [self _orgMailNotNullQualifier], - stringQualifier, nil]; - [andQualifier autorelease]; - [stringQualifier release]; - *qualifier = andQualifier; - rc = MAPIRestrictionStateNeedsEval; - break; - case PidLidBusyStatus: - rc = MAPIRestrictionStateAlwaysTrue; // should be based on c_isopaque - break; - default: - rc = [super evaluatePropertyRestriction: res intoQualifier: qualifier]; - } - - return rc; -} - -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property -{ - static NSMutableDictionary *knownProperties = nil; - - if (!knownProperties) - { - knownProperties = [NSMutableDictionary new]; - [knownProperties setObject: @"c_startdate" - forKey: MAPIPropertyKey (PidLidAppointmentStartWhole)]; - [knownProperties setObject: @"c_enddate" - forKey: MAPIPropertyKey (PidLidAppointmentEndWhole)]; - [knownProperties setObject: @"c_iscycle" - forKey: MAPIPropertyKey (PidLidRecurring)]; - } - - return [knownProperties objectForKey: MAPIPropertyKey (property)]; -} - -/* sorting */ - -- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property -{ - static NSMutableDictionary *knownProperties = nil; - - if (!knownProperties) - { - knownProperties = [NSMutableDictionary new]; - [knownProperties setObject: @"c_startdate" - forKey: MAPIPropertyKey (PidLidAppointmentStartWhole)]; - [knownProperties setObject: @"c_enddate" - forKey: MAPIPropertyKey (PidLidAppointmentEndWhole)]; - [knownProperties setObject: @"c_iscycle" - forKey: MAPIPropertyKey (PidLidRecurring)]; - [knownProperties setObject: @"c_isallday" - forKey: MAPIPropertyKey (PidLidAppointmentSubType)]; - [knownProperties setObject: @"c_creationdate" - forKey: MAPIPropertyKey (PR_CREATION_TIME)]; - [knownProperties setObject: @"c_uid" - forKey: MAPIPropertyKey (PR_OWNER_APPT_ID)]; - /* Use by oxcfxics to sort the latest first */ - [knownProperties setObject: @"c_lastmodified" - forKey: MAPIPropertyKey (PidTagMessageDeliveryTime)]; - } - - return [knownProperties objectForKey: MAPIPropertyKey (property)]; -} - -@end diff --git a/OpenChange/MAPIStoreContactsAttachment.h b/OpenChange/MAPIStoreContactsAttachment.h deleted file mode 100644 index c4a368849..000000000 --- a/OpenChange/MAPIStoreContactsAttachment.h +++ /dev/null @@ -1,41 +0,0 @@ -/* MAPIStoreContactsAttachment.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTORECONTACTSATTACHMENT_H -#define MAPISTORECONTACTSATTACHMENT_H - -#import "MAPIStoreAttachment.h" - -@class NSData; -@class NGVCardPhoto; - -@interface MAPIStoreContactsAttachment : MAPIStoreAttachment -{ - NGVCardPhoto *photo; - NSData *photoData; -} - -- (void) setPhoto: (NGVCardPhoto *) newPhoto; - -@end - -#endif /* MAPISTORECONTACTSATTACHMENT_H */ diff --git a/OpenChange/MAPIStoreContactsAttachment.m b/OpenChange/MAPIStoreContactsAttachment.m deleted file mode 100644 index 6b0d73133..000000000 --- a/OpenChange/MAPIStoreContactsAttachment.m +++ /dev/null @@ -1,197 +0,0 @@ -/* MAPIStoreContactsAttachment.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import - -#import "MAPIStoreTypes.h" -#import "NSData+MAPIStore.h" -#import "NSDate+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreContactsAttachment.h" - -#include - -/* TODO: handle URL pictures via PidTagAttachMethod = ref ? */ - -@implementation MAPIStoreContactsAttachment - -- (id) init -{ - if ((self = [super init])) - { - photo = nil; - photoData = nil; - } - - return self; -} - -- (void) dealloc -{ - [photo release]; - [photoData release]; - [super dealloc]; -} - -- (void) setPhoto: (NGVCardPhoto *) newPhoto -{ - ASSIGN (photo, newPhoto); -} - -- (NSString *) fileExtension -{ - NSString *type, *extension; - - type = [photo type]; - if ([type isEqualToString: @"JPEG"] - || [type isEqualToString: @"JPG"]) - extension = @".jpg"; - else if ([type isEqualToString: @"PNG"]) - extension = @".png"; - else if ([type isEqualToString: @"BMP"]) - extension = @".bmp"; - else if ([type isEqualToString: @"GIF"]) - extension = @".gif"; - else - extension = nil; - - return extension; -} - -- (NSDate *) creationTime -{ - return [container creationTime]; -} - -- (NSDate *) lastModificationTime -{ - return [container lastModificationTime]; -} - -- (enum mapistore_error) getPidTagAttachEncoding: (void **) data inMemCtx: (TALLOC_CTX *) memCtx; -{ - *data = [[NSData data] asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachFlags: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagAttachmentFlags: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagAttachmentHidden: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagAttachmentLinkId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagAttachMethod: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0x00000001); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachmentContactPhoto: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagAttachDataBinary: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!photoData) - ASSIGN (photoData, - [[photo flattenedValuesForKey: @""] dataByDecodingBase64]); - - *data = [photoData asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachSize: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!photoData) - ASSIGN (photoData, - [[photo flattenedValuesForKey: @""] dataByDecodingBase64]); - - *data = MAPILongValue (memCtx, [photoData length]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachExtension: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[self fileExtension] asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachLongFilename: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *filename; - - filename = [NSString stringWithFormat: @"ContactPhoto%@", - [self fileExtension]]; - - *data = [filename asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachFilename: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagAttachLongFilename: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagAttachLongFilename: data inMemCtx: memCtx]; -} - -@end diff --git a/OpenChange/MAPIStoreContactsContext.h b/OpenChange/MAPIStoreContactsContext.h deleted file mode 100644 index 68120215e..000000000 --- a/OpenChange/MAPIStoreContactsContext.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreContactsContext.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTORECONTACTSCONTEXT_H -#define MAPISTORECONTACTSCONTEXT_H - -#import "MAPIStoreGCSBaseContext.h" - -@interface MAPIStoreContactsContext : MAPIStoreGCSBaseContext - -@end - -#endif /* MAPISTORECONTACTSCONTEXT_H */ diff --git a/OpenChange/MAPIStoreContactsContext.m b/OpenChange/MAPIStoreContactsContext.m deleted file mode 100644 index bfef33e27..000000000 --- a/OpenChange/MAPIStoreContactsContext.m +++ /dev/null @@ -1,59 +0,0 @@ -/* MAPIStoreContactsContext.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import - -#import "MAPIStoreContactsFolder.h" -#import "MAPIStoreUserContext.h" - -#import "MAPIStoreContactsContext.h" - -#undef DEBUG -#include - -static Class MAPIStoreContactsFolderK; - -@implementation MAPIStoreContactsContext - -+ (void) initialize -{ - MAPIStoreContactsFolderK = [MAPIStoreContactsFolder class]; -} - -+ (NSString *) MAPIModuleName -{ - return @"contacts"; -} - -+ (enum mapistore_context_role) MAPIContextRole -{ - return MAPISTORE_CONTACTS_ROLE; -} - -- (Class) MAPIStoreFolderClass -{ - return MAPIStoreContactsFolderK; -} - -@end diff --git a/OpenChange/MAPIStoreContactsFolder.h b/OpenChange/MAPIStoreContactsFolder.h deleted file mode 100644 index 2bade99f7..000000000 --- a/OpenChange/MAPIStoreContactsFolder.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreContactsFolder.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORECONTACTSFOLDER_H -#define MAPISTORECONTACTSFOLDER_H - -#import "MAPIStoreGCSFolder.h" - -@interface MAPIStoreContactsFolder : MAPIStoreGCSFolder - -@end - -#endif /* MAPISTORECONTACTSFOLDER_H */ diff --git a/OpenChange/MAPIStoreContactsFolder.m b/OpenChange/MAPIStoreContactsFolder.m deleted file mode 100644 index d55c34a25..000000000 --- a/OpenChange/MAPIStoreContactsFolder.m +++ /dev/null @@ -1,157 +0,0 @@ -/* MAPIStoreContactsFolder.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import - -#import "MAPIApplication.h" -#import "MAPIStoreUserContext.h" -#import "MAPIStoreContactsContext.h" -#import "MAPIStoreContactsMessage.h" -#import "MAPIStoreContactsMessageTable.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreContactsFolder.h" - -#include -#include -#include - -@implementation MAPIStoreContactsFolder - -- (MAPIStoreMessageTable *) messageTable -{ - [self synchroniseCache]; - return [MAPIStoreContactsMessageTable tableForContainer: self]; -} - -- (NSString *) component -{ - return @"vcard"; -} - -- (MAPIStoreMessage *) createMessage -{ - MAPIStoreMessage *newMessage; - SOGoContactGCSEntry *newEntry; - NSString *name; - - [[self userContext] activate]; - - name = [NSString stringWithFormat: @"%@.vcf", - [SOGoObject globallyUniqueObjectId]]; - newEntry = [SOGoContactGCSEntry objectWithName: name - inContainer: sogoObject]; - [newEntry setIsNew: YES]; - newMessage = [MAPIStoreContactsMessage mapiStoreObjectWithSOGoObject: newEntry - inContainer: self]; - - return newMessage; -} - -- (NSArray *) rolesForExchangeRights: (uint32_t) rights -{ - /* Limitations - - Following rights are not supported by SOGo specifically: - - - CreateSubfolders: No contacts subfolders - - FolderVisible: It is inferred by other rights when extracting - */ - NSMutableArray *roles; - - roles = [NSMutableArray arrayWithCapacity: 8]; - if (rights & RightsCreateItems) - [roles addObject: SOGoRole_ObjectCreator]; - if (rights & RightsDeleteAll) - [roles addObject: SOGoRole_ObjectEraser]; - if (rights & RightsDeleteOwn) - [roles addObject: MAPIStoreRightDeleteOwn]; - if (rights & RightsEditAll) - [roles addObject: SOGoRole_ObjectEditor]; - if (rights & RightsEditOwn) - [roles addObject: MAPIStoreRightEditOwn]; - if (rights & RightsReadItems) - [roles addObject: SOGoRole_ObjectViewer]; - - if (rights & RightsFolderOwner) - [roles addObject: MAPIStoreRightFolderOwner]; - if (rights & RightsFolderContact) - [roles addObject: MAPIStoreRightFolderContact]; - - return roles; -} - -- (uint32_t) exchangeRightsForRoles: (NSArray *) roles -{ - uint32_t rights = 0; - - if ([roles containsObject: SOGoRole_ObjectCreator]) - rights |= RightsCreateItems; - - if ([roles containsObject: SOGoRole_ObjectEraser]) - rights |= RightsDeleteAll | RightsDeleteOwn; - else if ([roles containsObject: MAPIStoreRightDeleteOwn]) - rights |= RightsDeleteOwn; - - if ([roles containsObject: SOGoRole_ObjectEditor]) - rights |= RightsEditAll | RightsEditOwn; - else if ([roles containsObject: MAPIStoreRightEditOwn]) - rights |= RightsEditOwn; - - if ([roles containsObject: SOGoRole_ObjectViewer]) - rights |= RightsReadItems; - if (rights != 0) - rights |= RoleNone; /* actually "folder visible" */ - - if ([roles containsObject: MAPIStoreRightFolderOwner]) - rights |= RightsFolderOwner | RoleNone; - - if ([roles containsObject: MAPIStoreRightFolderContact]) - rights |= RightsFolderContact; - - return rights; -} - -- (BOOL) subscriberCanModifyMessages -{ - return [[self activeUserRoles] containsObject: SOGoRole_ObjectEditor]; -} - -- (BOOL) subscriberCanReadMessages -{ - return [[self activeUserRoles] containsObject: SOGoRole_ObjectViewer]; -} - -- (enum mapistore_error) getPidTagDefaultPostMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPM.Contact" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -@end diff --git a/OpenChange/MAPIStoreContactsMessage.h b/OpenChange/MAPIStoreContactsMessage.h deleted file mode 100644 index 48d5bafb0..000000000 --- a/OpenChange/MAPIStoreContactsMessage.h +++ /dev/null @@ -1,35 +0,0 @@ -/* MAPIStoreContactsMessage.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORECONTACTSMESSAGE_H -#define MAPISTORECONTACTSMESSAGE_H - -#import "MAPIStoreGCSMessage.h" - -@interface MAPIStoreContactsMessage : MAPIStoreGCSMessage -{ - BOOL fetchedAttachments; -} - -@end - -#endif /* MAPISTORECONTACTSMESSAGE_H */ diff --git a/OpenChange/MAPIStoreContactsMessage.m b/OpenChange/MAPIStoreContactsMessage.m deleted file mode 100644 index 344f31c39..000000000 --- a/OpenChange/MAPIStoreContactsMessage.m +++ /dev/null @@ -1,1619 +0,0 @@ -/* MAPIStoreContactsMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * Ludovic Marcotte - * - * 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 -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreAttachment.h" -#import "MAPIStoreContactsAttachment.h" -#import "MAPIStoreContactsFolder.h" -#import "MAPIStoreContext.h" -#import "MAPIStorePropertySelectors.h" -#import "MAPIStoreSamDBUtils.h" -#import "MAPIStoreTypes.h" -#import "NSArray+MAPIStore.h" -#import "NSDate+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreContactsMessage.h" - -#undef DEBUG -#include -#include -#include -#include -#include - -@implementation SOGoContactGCSEntry (MAPIStoreExtension) - -- (Class) mapistoreMessageClass -{ - return [MAPIStoreContactsMessage class]; -} - -@end - -@implementation MAPIStoreContactsMessage - -- (id) init -{ - if ((self = [super init])) - { - fetchedAttachments = NO; - } - - return self; -} - -// TODO: this should be combined with the version found -// in UIxContactEditor.m -- (CardElement *) _elementWithTag: (NSString *) tag - ofType: (NSString *) type - forCard: (NGVCard *) card -{ - NSArray *elements; - CardElement *element; - - elements = [card childrenWithTag: tag - andAttribute: @"type" havingValue: type]; - if ([elements count] > 0) - element = [elements objectAtIndex: 0]; - else - { - element = [CardElement new]; - [element autorelease]; - [element setTag: tag]; - [element addType: type]; - [card addChild: element]; - } - - return element; -} - -- (enum mapistore_error) getPidTagIconIndex: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */ - *data = MAPILongValue (memCtx, 0x00000200); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAlternateRecipientAllowed: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx - -{ - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagMessageFlags: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, MSGFLAG_READ); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagDeleteAfterSubmit: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx - -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = talloc_strdup (memCtx, "IPM.Contact"); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagSendInternetEncoding: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0x00065001); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagNormalizedSubject: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagDisplayName: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidFileUnder: (void **) data - inMemCtx: (TALLOC_CTX *) 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; -} - -- (enum mapistore_error) getPidLidFileUnderId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0x00008017); /* what ol2003 sets */ - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAccount: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidEmail1EmailAddress: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagContactEmailAddresses: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[sogoObject vCard] preferredEMail]; - if (!stringValue) - stringValue = @""; - *data = [[NSArray arrayWithObject: stringValue] - asMVUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagEmsAbTargetAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[sogoObject vCard] preferredEMail]; - *data = [[NSString stringWithFormat: @"SMTP:%@", stringValue] - asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagSearchKey: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[sogoObject vCard] preferredEMail]; - *data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding] - asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMailPermission: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagBody: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSString *stringValue; - - stringValue = [[sogoObject vCard] note]; - if ([stringValue length] > 0) - *data = [stringValue asUnicodeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidTagSensitivity: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -// --------------------------------------------------------- -// Contact Name Properties [MS-OXOCNTC 2.2.1.1] -// --------------------------------------------------------- - -- (enum mapistore_error) getPidTagNickname: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[sogoObject vCard] nickname]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagGeneration: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] - flattenedValueAtIndex: 4 - forKey: @""]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagSurname: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] - flattenedValueAtIndex: 0 - forKey: @""]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMiddleName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] - flattenedValueAtIndex: 2 - forKey: @""]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagGivenName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] - flattenedValueAtIndex: 1 - forKey: @""]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagDisplayNamePrefix: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] firstChildWithTag: @"n"] - flattenedValueAtIndex: 3 - forKey: @""]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -// ------------------------------------------------------- -// Electronic Address Properties [MS-OXOCNTC 2.2.1.2] -// ------------------------------------------------------- - -enum { // [MS-OXOCNTC] 2.2.1.2.11 - AddressBookProviderEmailValueEmail1 = 0, - AddressBookProviderEmailValueEmail2, - AddressBookProviderEmailValueEmail3, - AddressBookProviderEmailValueBusinessFax, - AddressBookProviderEmailValueHomeFax, - AddressBookProviderEmailValuePrimaryFax -}; - -/* - Fetch Email1, Email2 and Email3 values from the vcard. - Returns nil if not found -*/ -- (NSString *) _fetchEmailAddress: (NSUInteger) position -{ - NSMutableArray *emails; - NSString *email, *stringValue = nil; - NGVCard *card; - NSUInteger count, max; - - card = [sogoObject vCard]; - - if (position == 1) - // Predefined email - return [card preferredEMail]; - - emails = [NSMutableArray array]; - [emails addObjectsFromArray: [card childrenWithTag: @"email"]]; - [emails removeObjectsInArray: [card childrenWithTag: @"email" - andAttribute: @"type" - havingValue: @"pref"]]; - max = [emails count]; - for (count = 0; !stringValue && count < max; count++) - { - email = [[emails objectAtIndex: count] flattenedValuesForKey: @""]; - - if ([email caseInsensitiveCompare: [card preferredEMail]] != NSOrderedSame) - { - position--; - if (position == 1) - stringValue = email; - } - } - - return stringValue; -} - -/* - Store on *data the given email (position) - It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist -*/ -- (enum mapistore_error) _getPidLidEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx - atPosition: (NSUInteger) position -{ - NSString *email; - - email = [self _fetchEmailAddress: position]; - if (!email) return MAPISTORE_ERR_NOT_FOUND; - - *data = [email asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidEmail1EmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailAddress: data inMemCtx: memCtx atPosition: 1]; -} - -- (enum mapistore_error) getPidLidEmail2EmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailAddress: data inMemCtx: memCtx atPosition: 2]; -} - -- (enum mapistore_error) getPidLidEmail3EmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailAddress: data inMemCtx: memCtx atPosition: 3]; -} - -- (enum mapistore_error) getPidLidEmail1OriginalDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidEmail1EmailAddress: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidEmail2OriginalDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidEmail2EmailAddress: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidEmail3OriginalDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidEmail3EmailAddress: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidEmail1AddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (![self _fetchEmailAddress: 1]) return MAPISTORE_ERR_NOT_FOUND; - - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidEmail2AddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (![self _fetchEmailAddress: 2]) return MAPISTORE_ERR_NOT_FOUND; - - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidEmail3AddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (![self _fetchEmailAddress: 3]) return MAPISTORE_ERR_NOT_FOUND; - - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - -/* - Store on *data a string with the display name for the given email (position) - It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist -*/ -- (enum mapistore_error) _getPidLidEmailDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx - atPosition: (NSUInteger) position -{ - NGVCard *vCard; - NSString *fn, *email; - - email = [self _fetchEmailAddress: position]; - if (!email) return MAPISTORE_ERR_NOT_FOUND; - - vCard = [sogoObject vCard]; - fn = [vCard fn]; - - *data = [[NSString stringWithFormat: @"%@ (%@)", fn, email] - asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidEmail1DisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 1]; -} - -- (enum mapistore_error) getPidLidEmail2DisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 2]; -} - -- (enum mapistore_error) getPidLidEmail3DisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailDisplayName: data inMemCtx: memCtx atPosition: 3]; -} - -/* - Return an entry id (either one-off or addressbook entry) for the given email - It can return nil if the email doesn't exist -*/ -- (NSData *) _buildEntryIdForEmail: (NSUInteger) position -{ - NSString *email, *username; - NSData *data; - SOGoUserManager *mgr; - NSDictionary *contactInfos; - - email = [self _fetchEmailAddress: position]; - if (!email) return nil; - - // Try to figure out if this email is from local domain - mgr = [SOGoUserManager sharedUserManager]; - contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - if (contactInfos) - { - username = [contactInfos objectForKey: @"sAMAccountName"]; - data = MAPIStoreInternalEntryId ([[self context] connectionInfo], username); - } - else - data = MAPIStoreExternalEntryId ([[sogoObject vCard] fn], email); - - return data; -} -/* - Store on *data an entryId for the given email (position) - It can return MAPISTORE_ERR_NOT_FOUND if the email doesn't exist -*/ -- (enum mapistore_error) _getPidLidEmailOriginalEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx - atPosition: (NSUInteger) position -{ - NSData *value; - - value = [self _buildEntryIdForEmail: position]; - if (!value) return MAPISTORE_ERR_NOT_FOUND; - - *data = [value asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidEmail1OriginalEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailOriginalEntryId: data - inMemCtx: memCtx - atPosition: 1]; -} - -- (enum mapistore_error) getPidLidEmail2OriginalEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailOriginalEntryId: data - inMemCtx: memCtx - atPosition: 2]; -} - -- (enum mapistore_error) getPidLidEmail3OriginalEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getPidLidEmailOriginalEntryId: data - inMemCtx: memCtx - atPosition: 3]; -} - -- (enum mapistore_error) _getElement: (NSString *) elementTag - ofType: (NSString *) aType - excluding: (NSString *) aTypeToExclude - atPos: (NSUInteger) pos - inData: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSArray *elements; - CardElement *ce; - NSUInteger count, max; - NGVCard *vCard; - NSString *stringValue; - - stringValue = nil; - - vCard = [sogoObject vCard]; - elements = [[vCard childrenWithTag: elementTag] - cardElementsWithAttribute: @"type" - havingValue: aType]; - max = [elements count]; - for (count = 0; !stringValue && count < max; count++) - { - ce = [elements objectAtIndex: count]; - if (!aTypeToExclude - || ![ce hasAttribute: @"type" havingValue: aTypeToExclude]) - stringValue = [ce flattenedValueAtIndex: pos forKey: @""]; - } - - if (!stringValue) - return MAPISTORE_ERR_NOT_FOUND; - - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagBusinessFaxNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"fax" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -/* - [MS-OXOCNTC] 2.2.1.2.11 - https://msdn.microsoft.com/en-us/library/ee158427%28v=exchg.80%29.aspx -*/ -- (NSArray *) _buildAddressBookProviderEmailList -{ - NSMutableArray *list = [[NSMutableArray alloc] init]; - NSArray *elements; - - // Is there a fax number? - elements = [[[sogoObject vCard] childrenWithTag: @"tel"] - cardElementsWithAttribute: @"type" - havingValue: @"fax"]; - if ([elements count] > 0) - [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueBusinessFax]]; - - // How many different email addresses? - if ([self _fetchEmailAddress: 1]) - [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail1]]; - else - return list; - if ([self _fetchEmailAddress: 2]) - [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail2]]; - else - return list; - if ([self _fetchEmailAddress: 3]) - [list addObject: [NSNumber numberWithInteger: AddressBookProviderEmailValueEmail3]]; - - return list; -} - -- (enum mapistore_error) getPidLidAddressBookProviderArrayType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - // [MS-OXOCNTC] 2.2.1.2.12 - // https://msdn.microsoft.com/en-us/library/ee218011%28v=exchg.80%29.aspx - uint32_t value = 0; - NSArray *emailList = [self _buildAddressBookProviderEmailList]; - - if ([emailList count] > 0) - { - for (NSNumber *maskValue in emailList) - value |= 1 << [maskValue intValue]; - - *data = MAPILongValue (memCtx, value); - - return MAPISTORE_SUCCESS; - } - else - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidLidAddressBookProviderEmailList: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSArray *emailList = [self _buildAddressBookProviderEmailList]; - - if ([emailList count] > 0) - { - *data = [emailList asMVLongInMemCtx: memCtx]; - return MAPISTORE_SUCCESS; - } - else - return MAPISTORE_ERR_NOT_FOUND; -} - -// --------------------------------------------------------- -// Physical Address Properties [MS-OXOCNTC 2.2.1.3] -// --------------------------------------------------------- - -// Home Address - -- (enum mapistore_error) getPidTagHomeAddressStreet: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"home" excluding: nil - atPos: 2 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagHomeAddressCity: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"home" excluding: nil - atPos: 3 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagHomeAddressStateOrProvince: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"home" excluding: nil - atPos: 4 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagHomeAddressPostalCode: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"home" excluding: nil - atPos: 5 inData: data inMemCtx: memCtx]; -} -- (enum mapistore_error) getPidTagHomeAddressCountry: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"home" excluding: nil - atPos: 6 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagHomeAddressPostOfficeBox: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"home" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidHomeAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"label" ofType: @"home" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -// Work Address - -- (enum mapistore_error) getPidLidWorkAddressStreet: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"work" excluding: nil - atPos: 2 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidWorkAddressCity: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"work" excluding: nil - atPos: 3 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidWorkAddressState: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"work" excluding: nil - atPos: 4 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidWorkAddressPostalCode: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"work" excluding: nil - atPos: 5 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidWorkAddressCountry: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"work" excluding: nil - atPos: 6 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidWorkAddressPostOfficeBox: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"work" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidWorkAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"label" ofType: @"work" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -// Mailing Address - -- (enum mapistore_error) getPidTagStreetAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 2 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagLocality: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 3 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagStateOrProvince: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 4 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagPostalCode: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 5 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagCountry: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 6 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagPostOfficeBox: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"adr" ofType: @"pref" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagPostalAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"label" ofType: @"pref" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidPostalAddressId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSArray *elements; - CardElement *element; - uint32_t longValue = 0; - NGVCard *vCard; - - vCard = [sogoObject vCard]; - elements = [[vCard childrenWithTag: @"adr"] - cardElementsWithAttribute: @"type" - havingValue: @"pref"]; - if ([elements count] > 0) - { - element = [elements objectAtIndex: 0]; - if ([element hasAttribute: @"type" - havingValue: @"home"]) - longValue = 1; // The Home Address is the mailing address. - else if ([element hasAttribute: @"type" - havingValue: @"work"]) - longValue = 2; // The Work Address is the mailing address. - } - *data = MAPILongValue (memCtx, longValue); - - return MAPISTORE_SUCCESS; -} - -// ------------------------------------------------------- -// Telephone Properties [MS-OXOCNTC 2.2.1.4] -// ------------------------------------------------------- - -- (enum mapistore_error) getPidTagPagerTelephoneNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"pager" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagBusinessTelephoneNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"work" excluding: @"fax" - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagHomeTelephoneNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"home" excluding: @"fax" - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagPrimaryTelephoneNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"pref" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagMobileTelephoneNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"tel" ofType: @"cell" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -// --------------------------------------------------------- -// Event Properties [MS-OXOCNTC 2.2.1.5] -// --------------------------------------------------------- - -- (enum mapistore_error) getPidTagBirthday: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSCalendarDate *dateValue; - NSString *stringValue; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - stringValue = [[sogoObject vCard] bday]; - if ([stringValue length] != 0) - { - dateValue = [NSCalendarDate dateWithString: stringValue - calendarFormat: @"%Y-%m-%d"]; - //dateValue = [dateValue addYear: 0 month: 0 day: 1 hour: 0 minute: 0 second: 0]; - *data = [dateValue asFileTimeInMemCtx: memCtx]; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidTagWeddingAnniversary: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSCalendarDate *dateValue; - NSString *stringValue; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-anniversary"] - flattenedValuesForKey: @""]; - if ([stringValue length] != 0) - { - dateValue = [NSCalendarDate dateWithString: stringValue - calendarFormat: @"%Y-%m-%d"]; - *data = [dateValue asFileTimeInMemCtx: memCtx]; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -// --------------------------------------------------------- -// Professional Properties [MS-OXOCNTC 2.2.1.6] -// --------------------------------------------------------- - -- (enum mapistore_error) getPidTagTitle: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[sogoObject vCard] title]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagCompanyName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - CardElement *org; - - org = [[sogoObject vCard] org]; - *data = [[org flattenedValueAtIndex: 0 forKey: @""] - asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagDepartmentName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - CardElement *org; - - org = [[sogoObject vCard] org]; - *data = [[org flattenedValueAtIndex: 1 forKey: @""] - asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagOfficeLocation: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-office"] - flattenedValuesForKey: @""]; - if ([stringValue length] != 0) - *data = [stringValue asUnicodeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidTagManagerName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-manager"] - flattenedValuesForKey: @""]; - if ([stringValue length] != 0) - *data = [stringValue asUnicodeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidTagAssistant: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-assistant"] - flattenedValuesForKey: @""]; - if ([stringValue length] != 0) - *data = [stringValue asUnicodeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidTagProfession: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - stringValue = [[sogoObject vCard] role]; - if (stringValue) - *data = [stringValue asUnicodeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -// --------------------------------------------------------- -// Contact Photo Properties [MS-OXOCNTC 2.2.1.8] -// --------------------------------------------------------- - -- (void) _fetchAttachmentParts -{ - NGVCardPhoto *photo; - MAPIStoreContactsAttachment *attachment; - NSString *encoding; - - photo = (NGVCardPhoto *) [[sogoObject vCard] firstChildWithTag: @"photo"]; - if (photo) - { - encoding = [[photo value: 0 ofAttribute: @"encoding"] uppercaseString]; - if ([encoding isEqualToString: @"B"] - || [encoding isEqualToString: @"BASE64"]) - { - attachment = [MAPIStoreContactsAttachment - mapiStoreObjectInContainer: self]; - [attachment setAID: 0]; - [attachment setPhoto: photo]; - [attachmentParts setObject: attachment forKey: @"photo"]; - } - } - - fetchedAttachments = YES; -} - -- (enum mapistore_error) getPidLidHasPicture: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!fetchedAttachments) - [self _fetchAttachmentParts]; - - *data = MAPIBoolValue (memCtx, ([attachmentParts count] > 0)); - - return MAPISTORE_SUCCESS; -} - -- (NSArray *) attachmentKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - if (!fetchedAttachments) - [self _fetchAttachmentParts]; - - return [super attachmentKeysMatchingQualifier: qualifier - andSortOrderings: sortOrderings]; -} - -- (id) lookupAttachment: (NSString *) childKey -{ - if (!fetchedAttachments) - [self _fetchAttachmentParts]; - - return [attachmentParts objectForKey: childKey]; -} - -- (void) _updatePhotoInVCard: (NGVCard *) card - fromProperties: (NSDictionary *) attachmentProps -{ - NSString *photoExt, *photoType, *content; - CardElement *photo; - - if ([[attachmentProps - objectForKey: MAPIPropertyKey (PR_ATTACHMENT_CONTACTPHOTO)] - boolValue]) - { - photoExt = [[attachmentProps - objectForKey: MAPIPropertyKey (PR_ATTACH_EXTENSION_UNICODE)] - uppercaseString]; - if ([photoExt isEqualToString: @".JPG"]) - photoType = @"JPEG"; - else if ([photoExt isEqualToString: @".PNG"]) - photoType = @"PNG"; - else if ([photoExt isEqualToString: @".BMP"]) - photoType = @"BMP"; - else if ([photoExt isEqualToString: @".GIF"]) - photoType = @"GIF"; - else - photoType = nil; - - content = [[attachmentProps - objectForKey: MAPIPropertyKey (PR_ATTACH_DATA_BIN)] - stringByEncodingBase64]; - if (photoType && content) - { - photo = [card uniqueChildWithTag: @"photo"]; - [photo setValue: 0 ofAttribute: @"type" - to: photoType]; - [photo setValue: 0 ofAttribute: @"encoding" - to: @"b"]; - [photo setSingleValue: [content stringByReplacingString: @"\n" - withString: @""] - atIndex: 0 forKey: @""]; - } - } -} - -// --------------------------------------------------------- -// Other Properties [MS-OXOCNTC 2.2.1.10] -// --------------------------------------------------------- - -- (enum mapistore_error) getPidTagSpouseName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-ms-spouse"] - flattenedValuesForKey: @""]; - if ([stringValue length] != 0) - *data = [stringValue asUnicodeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidInstantMessagingAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"x-aim"] - flattenedValuesForKey: @""]; - if (!stringValue) - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidFreeBusyLocation: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - stringValue = [[[sogoObject vCard] uniqueChildWithTag: @"fburl"] - flattenedValuesForKey: @""]; - if ([stringValue length] != 0) - *data = [stringValue asUnicodeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidTagPersonalHomePage: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"url" ofType: @"home" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagBusinessHomePage: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getElement: @"url" ofType: @"work" excluding: nil - atPos: 0 inData: data inMemCtx: memCtx]; -} - -// --------------------------------------------------------- -// Permissions -// --------------------------------------------------------- - -- (NSString *) creator -{ - return [[[sogoObject vCard] uniqueChildWithTag: @"x-openchange-creator"] - flattenedValuesForKey: @""]; -} - -- (NSString *) owner -{ - return [self creator]; -} - -- (BOOL) subscriberCanReadMessage -{ - return [[self activeUserRoles] containsObject: SOGoRole_ObjectViewer]; -} - -// --------------------------------------------------------- -// Save -// --------------------------------------------------------- -- (void) saveDistList:(TALLOC_CTX *) memCtx -{ - [self warnWithFormat: @"IPM.DistList messages are ignored"]; -} - -- (void) saveContact:(TALLOC_CTX *) memCtx -{ - NSArray *elements, *units; - CardElement *element; - NGVCard *newCard; - MAPIStoreAttachment *attachment; - int postalAddressId; - id value; - - [self logWithFormat: @"setMAPIProperties: %@", properties]; - - newCard = [sogoObject vCard]; - [newCard setTag: @"vcard"]; - [newCard setVersion: @"3.0"]; - [newCard setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"]; - [newCard setProfile: @"vCard"]; - - // Decomposed fullname - [newCard setNWithFamily: [properties objectForKey: MAPIPropertyKey(PR_SURNAME_UNICODE)] - given: [properties objectForKey: MAPIPropertyKey(PR_GIVEN_NAME_UNICODE)] - additional: [properties objectForKey: MAPIPropertyKey(PR_MIDDLE_NAME_UNICODE)] - prefixes: [properties objectForKey: MAPIPropertyKey(PR_DISPLAY_NAME_PREFIX_UNICODE)] - suffixes: [properties objectForKey: MAPIPropertyKey(PR_GENERATION_UNICODE)]]; - - // - // display name - // - value = [properties objectForKey: MAPIPropertyKey(PR_DISPLAY_NAME_UNICODE)]; - if (value) - [newCard setFn: value]; - - // - // email addresses handling - // - elements = [newCard childrenWithTag: @"email"]; - value = [properties objectForKey: MAPIPropertyKey(PidLidEmail1EmailAddress)]; - if (value) - { - if ([elements count] > 0) - [[elements objectAtIndex: 0] setSingleValue: value forKey: @""]; - else - [newCard addEmail: value - types: [NSArray arrayWithObject: @"pref"]]; - } - value = [properties objectForKey: MAPIPropertyKey (PidLidEmail2EmailAddress)]; - if (value) - { - if ([elements count] > 1) - [[elements objectAtIndex: 1] setSingleValue: value forKey: @""]; - else - [newCard addEmail: value types: nil]; - } - value = [properties objectForKey: MAPIPropertyKey (PidLidEmail3EmailAddress)]; - if (value) - { - if ([elements count] > 2) - [[elements objectAtIndex: 2] setSingleValue: value forKey: @""]; - else - [newCard addEmail: value types: nil]; - } - - // - // work postal addresses handling - // - // Possible values for PidLidPostalAddressId are: - // - // 0x00000000 - No address is selected as the Mailing Address. - // 0x00000001 - The Home Address is the Mailing Address. - // 0x00000002 - The Work Address is the Mailing Address - // 0x00000003 - The Other Address is the Mailing Address. - // - // - postalAddressId = [[properties objectForKey: MAPIPropertyKey (PidLidPostalAddressId)] - intValue]; - - value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddress)]; - if ([value length]) - { - elements = [newCard childrenWithTag: @"label" - andAttribute: @"type" - havingValue: @"work"]; - if ([elements count] > 0) - element = [elements objectAtIndex: 0]; - else - { - element = [CardElement elementWithTag: @"label"]; - [element addAttribute: @"type" value: @"work"]; - [newCard addChild: element]; - } - if (postalAddressId == 2) - { - [element removeValue: @"pref" - fromAttribute: @"type"]; - [element addAttribute: @"type" - value: @"pref"]; - } - [element setSingleValue: value forKey: @""]; - } - - elements = [newCard childrenWithTag: @"adr" - andAttribute: @"type" - havingValue: @"work"]; - if ([elements count] > 0) - element = [elements objectAtIndex: 0]; - else - { - element = [CardElement elementWithTag: @"adr"]; - [element addAttribute: @"type" value: @"work"]; - [newCard addChild: element]; - } - if (postalAddressId == 2) - [element addAttribute: @"type" value: @"pref"]; - value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressPostOfficeBox)]; - if (value) - [element setSingleValue: value atIndex: 0 forKey: @""]; - value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressStreet)]; - if (value) - [element setSingleValue: value atIndex: 2 forKey: @""]; - value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressCity)]; - if (value) - [element setSingleValue: value atIndex: 3 forKey: @""]; - value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressState)]; - if (value) - [element setSingleValue: value atIndex: 4 forKey: @""]; - value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressPostalCode)]; - if (value) - [element setSingleValue: value atIndex: 5 forKey: @""]; - value = [properties objectForKey: MAPIPropertyKey(PidLidWorkAddressCountry)]; - if (value) - [element setSingleValue: value atIndex: 6 forKey: @""]; - - // - // home postal addresses handling - // - value = [properties objectForKey: MAPIPropertyKey(PidLidHomeAddress)]; - if ([value length]) - { - elements = [newCard childrenWithTag: @"label" - andAttribute: @"type" - havingValue: @"home"]; - if ([elements count] > 0) - element = [elements objectAtIndex: 0]; - else - { - element = [CardElement elementWithTag: @"label"]; - [element addAttribute: @"type" value: @"home"]; - [newCard addChild: element]; - } - if (postalAddressId == 1) - { - [element removeValue: @"pref" - fromAttribute: @"type"]; - [element addAttribute: @"type" - value: @"pref"]; - } - [element setSingleValue: value forKey: @""]; - } - - elements = [newCard childrenWithTag: @"adr" - andAttribute: @"type" - havingValue: @"home"]; - if ([elements count] > 0) - element = [elements objectAtIndex: 0]; - else - { - element = [CardElement elementWithTag: @"adr"]; - [element addAttribute: @"type" value: @"home"]; - [newCard addChild: element]; - } - if (postalAddressId == 1) - [element addAttribute: @"type" value: @"pref"]; - - value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_POST_OFFICE_BOX_UNICODE)]; - if (value) - [element setSingleValue: value atIndex: 0 forKey: @""]; - value = [properties objectForKey: MAPIPropertyKey( PR_HOME_ADDRESS_STREET_UNICODE)]; - if (value) - [element setSingleValue: value atIndex: 2 forKey: @""]; - value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_CITY_UNICODE)]; - if (value) - [element setSingleValue: value atIndex: 3 forKey: @""]; - value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_STATE_OR_PROVINCE_UNICODE)]; - if (value) - [element setSingleValue: value atIndex: 4 forKey: @""]; - value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_POSTAL_CODE_UNICODE)]; - if (value) - [element setSingleValue: value atIndex: 5 forKey: @""]; - value = [properties objectForKey: MAPIPropertyKey(PR_HOME_ADDRESS_COUNTRY_UNICODE)]; - if (value) - [element setSingleValue: value atIndex: 6 forKey: @""]; - - - // - // telephone numbers: work, home, fax, pager and mobile - // - element = [self _elementWithTag: @"tel" ofType: @"work" forCard: newCard]; - value = [properties objectForKey: MAPIPropertyKey(PR_OFFICE_TELEPHONE_NUMBER_UNICODE)]; - if (value) - [element setSingleValue: value forKey: @""]; - - element = [self _elementWithTag: @"tel" ofType: @"home" forCard: newCard]; - value = [properties objectForKey: MAPIPropertyKey(PR_HOME_TELEPHONE_NUMBER_UNICODE)]; - if (value) - [element setSingleValue: value forKey: @""]; - - element = [self _elementWithTag: @"tel" ofType: @"fax" forCard: newCard]; - value = [properties objectForKey: MAPIPropertyKey(PR_BUSINESS_FAX_NUMBER_UNICODE)]; - if (value) - [element setSingleValue: value forKey: @""]; - - element = [self _elementWithTag: @"tel" ofType: @"pager" forCard: newCard]; - value = [properties objectForKey: MAPIPropertyKey(PR_PAGER_TELEPHONE_NUMBER_UNICODE)]; - if (value) - [element setSingleValue: value forKey: @""]; - - element = [self _elementWithTag: @"tel" ofType: @"cell" forCard: newCard]; - value = [properties objectForKey: MAPIPropertyKey(PR_MOBILE_TELEPHONE_NUMBER_UNICODE)]; - if (value) - [element setSingleValue: value forKey: @""]; - - - // - // job title, profession, nickname, company name, deparment, work url, im address/screen name and birthday - // - value = [properties objectForKey: MAPIPropertyKey(PR_TITLE_UNICODE)]; - if (value) - [newCard setTitle: value]; - - value = [properties objectForKey: MAPIPropertyKey(PR_PROFESSION_UNICODE)]; - if (value) - { - [newCard setRole: value]; - } - - value = [properties objectForKey: MAPIPropertyKey(PR_NICKNAME_UNICODE)]; - if (value) - [newCard setNickname: value]; - - value = [properties objectForKey: MAPIPropertyKey(PR_DEPARTMENT_NAME_UNICODE)]; - if (value) - units = [NSArray arrayWithObject: value]; - else - units = nil; - - value = [properties objectForKey: MAPIPropertyKey(PR_COMPANY_NAME_UNICODE)]; - if (value) - [newCard setOrg: value units: units]; - - value = [properties objectForKey: MAPIPropertyKey(PR_BUSINESS_HOME_PAGE_UNICODE)]; - if (value) - { - [[self _elementWithTag: @"url" ofType: @"work" forCard: newCard] - setSingleValue: value forKey: @""]; - } - - value = [properties objectForKey: MAPIPropertyKey(PidLidInstantMessagingAddress)]; - if (value) - { - [[newCard uniqueChildWithTag: @"x-aim"] - setSingleValue: value forKey: @""]; - } - - value = [properties objectForKey: MAPIPropertyKey(PR_BIRTHDAY)]; - if (value) - { - [newCard setBday: [value descriptionWithCalendarFormat: @"%Y-%m-%d"]]; - } - - // - // wedding anniversary, spouse's name, manager's name, assistant's name, office location, freebusy location - // - value = [properties objectForKey: MAPIPropertyKey(PidTagWeddingAnniversary)]; - if (value) - { - [[newCard uniqueChildWithTag: @"x-ms-anniversary"] - setSingleValue: [value descriptionWithCalendarFormat: @"%Y-%m-%d"] - forKey: @""]; - } - - value = [properties objectForKey: MAPIPropertyKey(PR_SPOUSE_NAME_UNICODE)]; - if (value) - { - [[newCard uniqueChildWithTag: @"x-ms-spouse"] - setSingleValue: value forKey: @""]; - } - - value = [properties objectForKey: MAPIPropertyKey(PR_MANAGER_NAME_UNICODE)]; - if (value) - { - [[newCard uniqueChildWithTag: @"x-ms-manager"] - setSingleValue: value forKey: @""]; - } - - value = [properties objectForKey: MAPIPropertyKey(PR_ASSISTANT_UNICODE)]; - if (value) - { - [[newCard uniqueChildWithTag: @"x-ms-assistant"] - setSingleValue: value forKey: @""]; - } - - value = [properties objectForKey: MAPIPropertyKey(PR_OFFICE_LOCATION_UNICODE)]; - if (value) - { - [[newCard uniqueChildWithTag: @"x-ms-office"] - setSingleValue: value forKey: @""]; - } - - value = [properties objectForKey: MAPIPropertyKey(PidLidFreeBusyLocation)]; - if (value) - { - [[newCard uniqueChildWithTag: @"fburl"] - setSingleValue: value forKey: @""]; - } - - /* photo */ - if ([attachmentParts count] > 0) - { - attachment = [[attachmentParts allValues] objectAtIndex: 0]; - [self _updatePhotoInVCard: newCard - fromProperties: [attachment properties]]; - } - - /* Note */ - value = [properties objectForKey: MAPIPropertyKey (PR_BODY_UNICODE)]; - if (!value) - { - value = [properties objectForKey: MAPIPropertyKey (PR_HTML)]; - if (value) - { - value = [[NSString alloc] initWithData: value - encoding: NSUTF8StringEncoding]; - [value autorelease]; - value = [value htmlToText]; - } - } - if (value) - [newCard setNote: value]; - - /* Store the creator name for sharing purposes */ - if (isNew) - { - value = [[[self context] activeUser] login]; - [[newCard uniqueChildWithTag: @"x-openchange-creator"] - setSingleValue: value forKey: @""]; - } - - // - // we save the new/modified card - // - [sogoObject saveComponent: newCard]; - - [self updateVersions]; -} - -- (void) save:(TALLOC_CTX *) memCtx -{ - NSString *messageClass = [properties objectForKey: MAPIPropertyKey(PR_MESSAGE_CLASS_UNICODE)]; - if ([messageClass isEqualToString: @"IPM.DistList"]) - [self saveDistList: memCtx]; - else - [self saveContact: memCtx]; -} - -@end diff --git a/OpenChange/MAPIStoreContactsMessageTable.h b/OpenChange/MAPIStoreContactsMessageTable.h deleted file mode 100644 index 0563f9b2e..000000000 --- a/OpenChange/MAPIStoreContactsMessageTable.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreContactsMessageTable.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTORECONTACTSMESSAGETABLE_H -#define MAPISTORECONTACTSMESSAGETABLE_H - -#import "MAPIStoreGCSMessageTable.h" - -@interface MAPIStoreContactsMessageTable : MAPIStoreGCSMessageTable -@end - -#endif /* MAPISTORECONTACTSMESSAGETABLE_H */ diff --git a/OpenChange/MAPIStoreContactsMessageTable.m b/OpenChange/MAPIStoreContactsMessageTable.m deleted file mode 100644 index b88158a26..000000000 --- a/OpenChange/MAPIStoreContactsMessageTable.m +++ /dev/null @@ -1,231 +0,0 @@ -/* MAPIStoreContactsMessageTable.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import - -#import -#import -#import -#import -#import - -#import - -#import "MAPIStoreContactsMessage.h" -#import "MAPIStoreTypes.h" -#import "NSDate+MAPIStore.h" -#import "NSArray+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreContactsMessageTable.h" - -#include - -static Class MAPIStoreContactsMessageK, NGMailAddressK, NSDataK, NSStringK; - -@implementation MAPIStoreContactsMessageTable - -+ (void) initialize -{ - MAPIStoreContactsMessageK = [MAPIStoreContactsMessage class]; - NSDataK = [NSData class]; - NSStringK = [NSString class]; - NGMailAddressK = [NGMailAddress class]; -} - -+ (Class) childObjectClass -{ - return MAPIStoreContactsMessageK; -} - -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property -{ - static NSMutableDictionary *knownProperties = nil; - - if (!knownProperties) - { - knownProperties = [NSMutableDictionary new]; - [knownProperties setObject: @"c_mail" - forKey: MAPIPropertyKey (PidLidEmail1EmailAddress)]; - [knownProperties setObject: @"c_mail" - forKey: MAPIPropertyKey (PidLidEmail2EmailAddress)]; - [knownProperties setObject: @"c_mail" - forKey: MAPIPropertyKey (PidLidEmail3EmailAddress)]; - [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)]; -} - -/* restrictions */ - -- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState rc; - EOAndQualifier *andQualifier; - EOKeyValueQualifier *fullNameQualifier, *emailQualifier; - NSString *fullName, *email; - SEL operator; - id value, ngAddress; - - value = NSObjectFromMAPISPropValue (&res->lpProp); - switch ((uint32_t) res->ulPropTag) - { - case PR_MESSAGE_CLASS_UNICODE: - if ([value isEqualToString: @"IPM.Contact"]) - rc = MAPIRestrictionStateAlwaysTrue; - else - rc = MAPIRestrictionStateAlwaysFalse; - break; - - case PR_SENSITIVITY: - rc = MAPIRestrictionStateAlwaysTrue; - break; - case PidLidAddressBookProviderArrayType: - case PidLidAddressBookProviderEmailList: - /* FIXME: this is a hack. We should return a real qualifier here */ - rc = MAPIRestrictionStateAlwaysTrue; - break; - - case PidLidEmail1OriginalDisplayName: - case PidLidEmail2OriginalDisplayName: - case PidLidEmail3OriginalDisplayName: - rc = MAPIRestrictionStateAlwaysFalse; - value = NSObjectFromMAPISPropValue (&res->lpProp); - if (value && [value isKindOfClass: NSStringK]) - { - rc = MAPIRestrictionStateNeedsEval; - ngAddress = [[NGMailAddressParser mailAddressParserWithString: value] - parse]; - if ([ngAddress isKindOfClass: NGMailAddressK]) - { - operator = [self operatorFromRestrictionOperator: res->relop]; - fullName = [ngAddress displayName]; - email = [ngAddress address]; - emailQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_mail" - operatorSelector: operator - value: email]; - if ([fullName length] > 0) - { - fullNameQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_cn" - operatorSelector: operator - value: fullName]; - andQualifier = [[EOAndQualifier alloc] - initWithQualifiers: - emailQualifier, fullNameQualifier, nil]; - [fullNameQualifier release]; - [emailQualifier release]; - *qualifier = andQualifier; - } - else - *qualifier = emailQualifier; - [*qualifier autorelease]; - } - } - break; - case PidLidEmail1AddressType: - case PidLidEmail2AddressType: - case PidLidEmail3AddressType: - if ([value isEqualToString: @"SMTP"]) - rc = MAPIRestrictionStateAlwaysTrue; - else - rc = MAPIRestrictionStateAlwaysFalse; - break; - - default: - rc = [super evaluatePropertyRestriction: res intoQualifier: qualifier]; - } - - return rc; -} - -- (MAPIRestrictionState) evaluateContentRestriction: (struct mapi_SContentRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState rc; - id value; - - value = NSObjectFromMAPISPropValue (&res->lpProp); - if ([value isKindOfClass: NSDataK]) - { - value = [[NSString alloc] initWithData: value - encoding: NSUTF8StringEncoding]; - [value autorelease]; - } - else if (![value isKindOfClass: NSStringK]) - [NSException raise: @"MAPIStoreTypeConversionException" - format: @"unhandled content restriction for class '%@'", - NSStringFromClass ([value class])]; - - switch (res->ulPropTag) - { - case PR_MESSAGE_CLASS_UNICODE: /* FIXME: should make use of c_component here */ - if ([value isEqualToString: @"IPM.Contact"]) - rc = MAPIRestrictionStateAlwaysTrue; - else - rc = MAPIRestrictionStateAlwaysFalse; - break; - default: - rc = [super evaluateContentRestriction: res intoQualifier: qualifier]; - } - - return rc; -} - -/* sorting */ - -- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property -{ - static NSMutableDictionary *knownProperties = nil; - - if (!knownProperties) - { - knownProperties = [NSMutableDictionary new]; - [knownProperties setObject: @"c_cn" - forKey: MAPIPropertyKey (PidLidFileUnder)]; - [knownProperties setObject: @"c_cn" - forKey: MAPIPropertyKey (PidTagDisplayName)]; - [knownProperties setObject: @"c_cn" - forKey: MAPIPropertyKey (PidTagSubject)]; - [knownProperties setObject: @"c_cn" - forKey: MAPIPropertyKey (PidTagNormalizedSubject)]; - /* Use by oxcfxics to sort the latest first */ - [knownProperties setObject: @"c_lastmodified" - forKey: MAPIPropertyKey (PidTagMessageDeliveryTime)]; - } - - return [knownProperties objectForKey: MAPIPropertyKey (property)]; -} - -@end diff --git a/OpenChange/MAPIStoreContext.h b/OpenChange/MAPIStoreContext.h deleted file mode 100644 index 4bde9d79a..000000000 --- a/OpenChange/MAPIStoreContext.h +++ /dev/null @@ -1,125 +0,0 @@ -/* MAPIStoreContext.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTORECONTEXT_H -#define MAPISTORECONTEXT_H - -#include - -#import - -@class NSArray; -@class NSFileHandle; -@class NSMutableArray; -@class NSMutableDictionary; -@class NSString; -@class NSURL; - -@class EOQualifier; - -@class WOContext; - -@class SOGoFolder; -@class SOGoMAPIFSFolder; -@class SOGoObject; -@class SOGoUser; - -@class MAPIStoreAuthenticator; -@class MAPIStoreAttachment; -@class MAPIStoreAttachmentTable; -@class MAPIStoreFolder; -@class MAPIStoreMessage; -@class MAPIStoreTable; -@class MAPIStoreUserContext; - -@interface MAPIStoreContext : NSObject -{ - struct mapistore_connection_info *connInfo; - NSMutableArray *containersBag; - SOGoUser *activeUser; /* the user accessing the resource */ - MAPIStoreUserContext *userContext; /* the owner or the resource */ - NSURL *contextUrl; -} - -+ (struct mapistore_contexts_list *) listAllContextsForUser: (NSString *) userName - withIndexing: (struct indexing_context *) indexing - inMemCtx: (TALLOC_CTX *) memCtx; -+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName - withIndexing: (struct indexing_context *) indexing - inMemCtx: (TALLOC_CTX *) memCtx; -+ (enum mapistore_error) createRootFolder: (NSString **) mapistoreUriP - withFID: (uint64_t ) fid - andName: (NSString *) folderName - forUser: (NSString *) username - withRole: (enum mapistore_context_role) role; - -+ (enum mapistore_error) openContext: (MAPIStoreContext **) contextPtr - withURI: (const char *) newUri - connectionInfo: (struct mapistore_connection_info *) newConnInfo - andTDBIndexing: (struct indexing_context *) indexing; - -- (id) initFromURL: (NSURL *) newUri - withConnectionInfo: (struct mapistore_connection_info *) newConnInfo - andTDBIndexing: (struct indexing_context *) indexing; - -- (NSURL *) url; -- (struct mapistore_connection_info *) connectionInfo; - -- (MAPIStoreUserContext *) userContext; - -- (SOGoUser *) activeUser; - -// - (id) lookupObject: (NSString *) objectURLString; - -/* backend methods */ -- (enum mapistore_error) getPath: (char **) path - ofFMID: (uint64_t) fmid - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getRootFolder: (MAPIStoreFolder **) folderPtr - withFID: (uint64_t) fmid; - -/* util methods */ -- (NSString *) extractChildNameFromURL: (NSString *) childURL - andFolderURLAt: (NSString **) folderURL; - -- (uint64_t) idForObjectWithKey: (NSString *) key - inFolderURL: (NSString *) folderURL; -- (NSArray *) getNewFMIDs: (uint64_t) max; -- (uint64_t) getNewChangeNumber; -- (NSArray *) getNewChangeNumbers: (uint64_t) max; - -/* subclass methods */ -+ (NSString *) MAPIModuleName; -+ (enum mapistore_context_role) MAPIContextRole; -+ (NSString *) - createRootSecondaryFolderWithFID: (uint64_t) fid - andName: (NSString *) folderName - forUser: (NSString *) userName; -- (Class) MAPIStoreFolderClass; - -/* the top-most parent of the context folder: SOGoMailAccount, - SOGoCalendarFolders, ... */ -- (id) rootSOGoFolder; - -@end - -#endif /* MAPISTORECONTEXT_H */ diff --git a/OpenChange/MAPIStoreContext.m b/OpenChange/MAPIStoreContext.m deleted file mode 100644 index 32a01e147..000000000 --- a/OpenChange/MAPIStoreContext.m +++ /dev/null @@ -1,644 +0,0 @@ -/* MAPIStoreContext.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import - -#import -#import -#import - -#import -#import - -#import "MAPIStoreAttachment.h" -#import "MAPIStoreFallbackContext.h" -#import "MAPIStoreFolder.h" -#import "MAPIStoreFolderTable.h" -#import "MAPIStoreMapping.h" -#import "MAPIStoreMessage.h" -#import "MAPIStoreMessageTable.h" -#import "MAPIStoreFAIMessage.h" -#import "MAPIStoreFAIMessageTable.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSArray+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreContext.h" - -#undef DEBUG -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* TODO: homogenize method names and order of parameters */ - -@implementation MAPIStoreContext : NSObject - -/* sogo://username:password@{contacts,calendar,tasks,journal,notes,mail}/dossier/id */ - -static Class NSExceptionK, MAPIStoreFallbackContextK, SOGoObjectK; - -static NSMutableDictionary *contextClassMapping; - -+ (void) initialize -{ - NSArray *classes; - Class currentClass; - NSUInteger count, max; - NSString *moduleName; - - NSExceptionK = [NSException class]; - SOGoObjectK = [SOGoObject class]; - - contextClassMapping = [NSMutableDictionary new]; - classes = GSObjCAllSubclassesOfClass (self); - max = [classes count]; - for (count = 0; count < max; count++) - { - currentClass = [classes objectAtIndex: count]; - moduleName = [currentClass MAPIModuleName]; - if (moduleName) - { - [contextClassMapping setObject: currentClass - forKey: moduleName]; - NSLog (@" registered class '%@' as handler of '%@' contexts", - NSStringFromClass (currentClass), moduleName); - } - } - - MAPIStoreFallbackContextK = [MAPIStoreFallbackContext class]; -} - -+ (struct mapistore_contexts_list *) listAllContextsForUser: (NSString *) userName - withIndexing: (struct indexing_context *) indexing - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct mapistore_contexts_list *list, *current; - NSArray *classes; - Class currentClass; - NSUInteger count, max; - - list = NULL; - - // User context is activated on initialization - [MAPIStoreUserContext userContextWithUsername: userName - andTDBIndexing: indexing]; - - classes = GSObjCAllSubclassesOfClass (self); - max = [classes count]; - for (count = 0; count < max; count++) - { - currentClass = [classes objectAtIndex: count]; - current = [currentClass listContextsForUser: userName - withIndexing: indexing - inMemCtx: memCtx]; - if (current) - DLIST_CONCATENATE(list, current, void); - } - - return list; -} - -+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName - withIndexing: (struct indexing_context *) indexing - inMemCtx: (TALLOC_CTX *) memCtx -{ - return NULL; -} - -static Class -MAPIStoreLookupContextClassByRole (Class self, enum mapistore_context_role role) -{ - static NSMutableDictionary *classMapping = nil; - Class currentClass; - enum mapistore_context_role classRole; - NSNumber *roleNbr; - NSArray *classes; - NSUInteger count, max; - - if (!classMapping) - { - classMapping = [NSMutableDictionary new]; - classes = GSObjCAllSubclassesOfClass (self); - max = [classes count]; - for (count = 0; count < max; count++) - { - currentClass = [classes objectAtIndex: count]; - classRole = [currentClass MAPIContextRole]; - if (classRole != -1) - { - roleNbr = [NSNumber numberWithUnsignedInt: classRole]; - [classMapping setObject: currentClass - forKey: roleNbr]; - } - } - } - - roleNbr = [NSNumber numberWithUnsignedInt: role]; - - return [classMapping objectForKey: roleNbr]; -} - -+ (enum mapistore_error) createRootFolder: (NSString **) mapistoreUriP - withFID: (uint64_t) fid - andName: (NSString *) folderName - forUser: (NSString *) userName - withRole: (enum mapistore_context_role) role -{ - Class contextClass; - NSString *mapistoreURI; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - contextClass = MAPIStoreLookupContextClassByRole (self, role); - if (!contextClass) - contextClass = MAPIStoreFallbackContextK; - - mapistoreURI = [contextClass createRootSecondaryFolderWithFID: fid - andName: folderName - forUser: userName]; - if (!mapistoreURI && contextClass != MAPIStoreFallbackContextK) - mapistoreURI = [MAPIStoreFallbackContextK createRootSecondaryFolderWithFID: fid - andName: folderName - forUser: userName]; - if (mapistoreURI) - *mapistoreUriP = mapistoreURI; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -static inline NSURL *CompleteURLFromMapistoreURI (const char *uri) -{ - NSString *urlString; - NSURL *completeURL; - - urlString = [NSString stringWithFormat: @"sogo://%@", - [NSString stringWithUTF8String: uri]]; - if (![urlString hasSuffix: @"/"]) - urlString = [urlString stringByAppendingString: @"/"]; - completeURL = [NSURL URLWithString: urlString]; - - return completeURL; -} - -+ (enum mapistore_error) openContext: (MAPIStoreContext **) contextPtr - withURI: (const char *) newUri - connectionInfo: (struct mapistore_connection_info *) newConnInfo - andTDBIndexing: (struct indexing_context *) indexing -{ - MAPIStoreContext *context; - Class contextClass; - NSString *module; - NSURL *baseURL; - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - - context = nil; - - baseURL = CompleteURLFromMapistoreURI (newUri); - if (baseURL) - { - module = [baseURL host]; - if (module) - { - contextClass = [contextClassMapping objectForKey: module]; - if (contextClass) - { - context = [[contextClass alloc] initFromURL: baseURL - withConnectionInfo: newConnInfo - andTDBIndexing: indexing]; - if (context) - { - [context autorelease]; - rc = MAPISTORE_SUCCESS; - *contextPtr = context; - } - } - else - NSLog (@"ERROR: unrecognized module name '%@'", module); - } - } - else - NSLog (@"ERROR: url could not be parsed"); - - return rc; -} - -- (id) init -{ - if ((self = [super init])) - { - activeUser = nil; - userContext = nil; - contextUrl = nil; - containersBag = [NSMutableArray new]; - } - - return self; -} - -- (id) initFromURL: (NSURL *) newUrl - withConnectionInfo: (struct mapistore_connection_info *) newConnInfo - andTDBIndexing: (struct indexing_context *) indexing -{ - NSString *username; - - if (newConnInfo == NULL) - { - return nil; - } - - if ((self = [self init])) - { - ASSIGN (contextUrl, newUrl); - - username = [newUrl user]; - if ([username length] == 0) - { - [self errorWithFormat: - @"attempt to instantiate a context with an empty owner"]; - [self release]; - return nil; - } - - ASSIGN (userContext, - [MAPIStoreUserContext userContextWithUsername: username - andTDBIndexing: indexing]); - connInfo = newConnInfo; - username = [NSString stringWithUTF8String: newConnInfo->username]; - ASSIGN (activeUser, [SOGoUser userWithLogin: username]); - if (!activeUser) - { - [self errorWithFormat: @"user '%@' not found in SOGo environment", - username]; - [self release]; - return nil; - } - } - - return self; -} - -- (void) dealloc -{ - [contextUrl release]; - [userContext release]; - [containersBag release]; - - [super dealloc]; -} - -- (MAPIStoreUserContext *) userContext -{ - return userContext; -} - -- (NSURL *) url -{ - return contextUrl; -} - -- (struct mapistore_connection_info *) connectionInfo -{ - return connInfo; -} - -- (SOGoUser *) activeUser -{ - return activeUser; -} - -- (enum mapistore_error) getPath: (char **) path - ofFMID: (uint64_t) fmid - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSString *objectURL, *url; - - url = [contextUrl absoluteString]; - // FIXME transform percent escapes but not for user part of the url - //[xxxx stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; - objectURL = [[userContext mapping] urlFromID: fmid]; - if (objectURL) - { - if ([objectURL hasPrefix: url]) - { - *path = [[objectURL substringFromIndex: 7] asUnicodeInMemCtx: memCtx]; - [self logWithFormat: @"found path '%s' for fmid 0x%.16"PRIx64"", *path, fmid]; - rc = MAPISTORE_SUCCESS; - } - else - { - [self logWithFormat: @"context (%@, %@) does not contain " - @"found fmid: 0x%.16"PRIx64"", objectURL, url, fmid]; - *path = NULL; - rc = MAPISTORE_SUCCESS; - } - } - else - { - [self errorWithFormat: @"%s: you should *never* get here", __PRETTY_FUNCTION__]; - *path = NULL; - rc = MAPISTORE_SUCCESS; - } - - return rc; -} - -- (void) ensureContextFolder -{ -} - -- (enum mapistore_error) getRootFolder: (MAPIStoreFolder **) folderPtr - withFID: (uint64_t) newFid -{ - enum mapistore_error rc; - MAPIStoreFolder *baseFolder; - SOGoFolder *currentFolder; - WOContext *woContext; - NSString *path; - NSArray *pathComponents; - NSUInteger count, max; - - [userContext activate]; - woContext = [userContext woContext]; - - [self ensureContextFolder]; - currentFolder = [self rootSOGoFolder]; - [containersBag addObject: currentFolder]; - - /* HACK: - -[NSURL path] returns unescaped strings in theory. In pratice, sometimes - it does, sometimes not. Therefore we use the result of our own - implementation of -[NSString - stringByReplacingPercentEscapeUsingEncoding:], which returns nil if the - original string contains non-ascii chars, from which we can determine - whether the path was unescaped or not. */ - path = [[contextUrl path] - stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; - if (!path) - path = [contextUrl path]; - - if ([path hasPrefix: @"/"]) - path = [path substringFromIndex: 1]; - if ([path hasSuffix: @"/"]) - path = [path substringToIndex: [path length] - 1]; - if ([path length] > 0) - { - 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) - { - baseFolder = [[self MAPIStoreFolderClass] - mapiStoreObjectWithSOGoObject: currentFolder - inContainer: nil]; - [baseFolder setContext: self]; - - if ([[userContext sogoUser] isEqual: activeUser] - || [baseFolder subscriberCanReadMessages]) - { - *folderPtr = baseFolder; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_DENIED; - - } - else if ([[userContext sogoUser] isEqual: activeUser]) - rc = MAPISTORE_ERR_NOT_FOUND; - else - rc = MAPISTORE_ERR_DENIED; - - return rc; -} - -/* utils */ - -- (NSString *) extractChildNameFromURL: (NSString *) objectURL - andFolderURLAt: (NSString **) folderURL; -{ - NSString *childKey; - NSRange lastSlash; - NSUInteger slashPtr; - - if ([objectURL hasSuffix: @"/"]) - objectURL = [objectURL substringToIndex: [objectURL length] - 2]; - lastSlash = [objectURL rangeOfString: @"/" - options: NSBackwardsSearch]; - if (lastSlash.location != NSNotFound) - { - slashPtr = NSMaxRange (lastSlash); - childKey = [objectURL substringFromIndex: slashPtr]; - if ([childKey length] == 0) - childKey = nil; - if (folderURL) - *folderURL = [objectURL substringToIndex: slashPtr]; - } - else - childKey = nil; - - return childKey; -} - -- (uint64_t) idForObjectWithKey: (NSString *) key - inFolderURL: (NSString *) folderURL -{ - NSString *childURL; - MAPIStoreMapping *mapping; - uint64_t mappingId; - enum mapistore_error ret; - - if (key) - childURL = [NSString stringWithFormat: @"%@%@", folderURL, - [key stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; - else - childURL = folderURL; - mapping = [userContext mapping]; - mappingId = [mapping idFromURL: childURL]; - if (mappingId == NSNotFound) - { - const char *owner; - - [self logWithFormat: @"No id exist yet for '%@', requesting one", childURL]; - owner = [[userContext username] UTF8String]; - ret = mapistore_indexing_get_new_folderID_as_user (connInfo->mstore_ctx, owner, &mappingId); - if (ret == MAPISTORE_SUCCESS) - [mapping registerURL: childURL withID: mappingId]; - else - [self errorWithFormat: @"Error trying to get new folder id (%d): %s", - ret, mapistore_errstr (ret)]; - } - - return mappingId; -} - -/* Get new change number from openchange db interface using - resource's owner user */ -- (uint64_t) getNewChangeNumber -{ - const char *owner; - enum MAPISTATUS retval; - uint64_t newVersionNumber; - - owner = [[userContext username] UTF8String]; - retval = openchangedb_get_new_changeNumber (connInfo->oc_ctx, owner, &newVersionNumber); - if (retval != MAPI_E_SUCCESS) - [NSException raise: @"MAPIStoreIOException" - format: @"Impossible to get new change number for %s: %s", owner, - mapi_get_errstr (retval)]; - - return newVersionNumber; -} - -/* Get new change numbers from openchange db interface using - resource's owner user */ -- (NSArray *) getNewChangeNumbers: (uint64_t) max -{ - const char *owner; - enum MAPISTATUS retval; - TALLOC_CTX *memCtx; - NSMutableArray *newChangeNumbers; - uint64_t count; - struct UI8Array_r *numbers; - NSString *newNumber; - - memCtx = talloc_new (NULL); - if (!memCtx) - [NSException raise: @"MAPIStoreIOException" - format: @"Not enough memory to allocate change numbers"]; - - newChangeNumbers = [NSMutableArray arrayWithCapacity: max]; - owner = [[userContext username] UTF8String]; - - retval = openchangedb_get_new_changeNumbers (connInfo->oc_ctx, memCtx, owner, max, &numbers); - if (retval != MAPI_E_SUCCESS || numbers->cValues != max) - { - talloc_free (memCtx); - [NSException raise: @"MAPIStoreIOException" - format: @"Failing to get %d new change numbers: %s", max, - mapi_get_errstr (retval)]; - } - - for (count = 0; count < max; count++) - { - newNumber = [NSString stringWithUnsignedLongLong: numbers->lpui8[count]]; - [newChangeNumbers addObject: newNumber]; - } - - talloc_free (memCtx); - - return newChangeNumbers; -} - -/* Get new fmids from mapistore_indexing interface using resource's - owner user */ -- (NSArray *) getNewFMIDs: (uint64_t) max -{ - const char *owner; - enum mapistore_error ret; - NSMutableArray *newFMIDs; - NSString *newNumber; - uint64_t count, newFID; - - newFMIDs = [NSMutableArray arrayWithCapacity: max]; - /* Get the resource's owner name */ - owner = [[userContext username] UTF8String]; - - for (count = 0; count < max; count++) - { - ret = mapistore_indexing_get_new_folderID_as_user (connInfo->mstore_ctx, owner, &newFID); - if (ret != MAPISTORE_SUCCESS) - [NSException raise: @"MAPIStoreIOException" - format: @"Impossible to get new fmid for %s", owner]; - - newNumber = [NSString stringWithUnsignedLongLong: newFID]; - [newFMIDs addObject: newNumber]; - } - - return newFMIDs; -} - -/* subclasses */ - -+ (NSString *) MAPIModuleName -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -+ (enum mapistore_context_role) MAPIContextRole -{ - return -1; -} - -+ (NSString *) - createRootSecondaryFolderWithFID: (uint64_t) fid - andName: (NSString *) folderName - forUser: (NSString *) userName -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (Class) MAPIStoreFolderClass -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (id) rootSOGoFolder -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -@end diff --git a/OpenChange/MAPIStoreDBBaseContext.h b/OpenChange/MAPIStoreDBBaseContext.h deleted file mode 100644 index 62f5bd489..000000000 --- a/OpenChange/MAPIStoreDBBaseContext.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreDBBaseContext.h - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREDBBASECONTEXT_H -#define MAPISTOREDBBASECONTEXT_H - -#import "MAPIStoreContext.h" - -@interface MAPIStoreDBBaseContext : MAPIStoreContext - -@end - -#endif /* MAPISTOREDBBASECONTEXT_H */ diff --git a/OpenChange/MAPIStoreDBBaseContext.m b/OpenChange/MAPIStoreDBBaseContext.m deleted file mode 100644 index 22a15bc85..000000000 --- a/OpenChange/MAPIStoreDBBaseContext.m +++ /dev/null @@ -1,114 +0,0 @@ -/* MAPIStoreDBBaseContext.m - this file is part of SOGo - * - * Copyright (C) 2012-2014 Inverse inc. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 -#import -#import - -#import - -#import "MAPIStoreDBFolder.h" -#import "MAPIStoreMapping.h" -#import "MAPIStoreUserContext.h" -#import - -#import "MAPIStoreDBBaseContext.h" - -#undef DEBUG -#include - -static Class MAPIStoreDBFolderK; - -@implementation MAPIStoreDBBaseContext - -+ (void) initialize -{ - MAPIStoreDBFolderK = [MAPIStoreDBFolder class]; -} - -+ (NSString *) MAPIModuleName -{ - return nil; -} - -- (Class) MAPIStoreFolderClass -{ - return MAPIStoreDBFolderK; -} - -- (void) ensureContextFolder -{ - SOGoCacheGCSFolder *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 = [SOGoCacheGCSFolder 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 -{ - SOGoCacheGCSFolder *folder; - - [userContext ensureFolderTableExists]; - - folder = [SOGoCacheGCSFolder 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 diff --git a/OpenChange/MAPIStoreDBFolder.h b/OpenChange/MAPIStoreDBFolder.h deleted file mode 100644 index 1da4d1bd9..000000000 --- a/OpenChange/MAPIStoreDBFolder.h +++ /dev/null @@ -1,43 +0,0 @@ -/* MAPIStoreDBFolder.h - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREDBFOLDER_H -#define MAPISTOREDBFOLDER_H - -#import "MAPIStoreFolder.h" - -extern NSString *MAPIStoreRightReadItems; -extern NSString *MAPIStoreRightCreateItems; -extern NSString *MAPIStoreRightEditOwn; -extern NSString *MAPIStoreRightEditAll; -extern NSString *MAPIStoreRightDeleteOwn; -extern NSString *MAPIStoreRightDeleteAll; -extern NSString *MAPIStoreRightCreateSubfolders; -extern NSString *MAPIStoreRightFolderOwner; -extern NSString *MAPIStoreRightFolderContact; - -@interface MAPIStoreDBFolder : MAPIStoreFolder - -@end - - -#endif /* MAPISTOREDBFOLDER_H */ diff --git a/OpenChange/MAPIStoreDBFolder.m b/OpenChange/MAPIStoreDBFolder.m deleted file mode 100644 index 4fc954112..000000000 --- a/OpenChange/MAPIStoreDBFolder.m +++ /dev/null @@ -1,382 +0,0 @@ -/* MAPIStoreDBFolder.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -#include - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import "MAPIStoreContext.h" -#import "MAPIStoreDBFolderTable.h" -#import "MAPIStoreDBMessage.h" -#import "MAPIStoreDBMessageTable.h" -#import "MAPIStoreMapping.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import -#import "SOGoMAPIDBMessage.h" - -#import "MAPIStoreDBFolder.h" - -#undef DEBUG -#include -#include - -static Class EOKeyValueQualifierK, SOGoCacheGCSFolderK, MAPIStoreDBFolderK; - -@implementation MAPIStoreDBFolder - -+ (void) initialize -{ - EOKeyValueQualifierK = [EOKeyValueQualifier class]; - SOGoCacheGCSFolderK = [SOGoCacheGCSFolder class]; - MAPIStoreDBFolderK = [MAPIStoreDBFolder class]; -} - -- (void) setupAuxiliaryObjects -{ - [super setupAuxiliaryObjects]; - ASSIGN (sogoObject, dbFolder); -} - -- (MAPIStoreMessageTable *) messageTable -{ - return [MAPIStoreDBMessageTable tableForContainer: self]; -} - -- (MAPIStoreFolderTable *) folderTable -{ - return [MAPIStoreDBFolderTable tableForContainer: self]; -} - -- (enum mapistore_error) createFolder: (struct SRow *) aRow - withFID: (uint64_t) newFID - andKey: (NSString **) newKeyP -{ - enum mapistore_error rc; - NSString *folderName, *nameInContainer; - SOGoCacheGCSFolder *newFolder; - struct SPropValue *value; - - 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: (const char *) value->value.lpszA]; - else - folderName = nil; - } - - if (folderName) - { - nameInContainer = [NSString stringWithFormat: @"0x%.16"PRIx64, - (unsigned long long) newFID]; - newFolder = [SOGoCacheGCSFolderK 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 rc; -} - -- (enum mapistore_error) moveCopyToFolder: (MAPIStoreFolder *) targetFolder - withNewName: (NSString *) newFolderName - isMove: (BOOL) isMove - isRecursive: (BOOL) isRecursive - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSString *path, *pathComponent, *targetPath, *newPath; - NSString *newURL; - MAPIStoreMapping *mapping; - NSRange slashRange; - - pathComponent = nil; - - if (isMove && ([targetFolder isKindOfClass: MAPIStoreDBFolderK] || !targetFolder)) - { - 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]; - - if (targetFolder) - { - targetPath = [[targetFolder sogoObject] path]; - newPath = [NSString stringWithFormat: @"%@/%@", - targetPath, pathComponent]; - [dbFolder changePathTo: newPath - intoNewContainer: [targetFolder dbFolder]]; - } - else - [dbFolder changePathTo: [NSString stringWithFormat: @"/fallback/%@", pathComponent] - intoNewContainer: nil]; - - mapping = [self mapping]; - - if (targetFolder) - newURL = [NSString stringWithFormat: @"%@%@/", - [targetFolder url], pathComponent]; - else - newURL = [NSString stringWithFormat: @"sogo://%@@fallback/%@/", - [[self userContext] username], pathComponent]; - - [mapping updateID: [self objectId] - withURL: newURL]; - - [targetFolder cleanupCaches]; - - rc = MAPISTORE_SUCCESS; - } - else - rc = [super moveCopyToFolder: targetFolder withNewName: newFolderName - isMove: isMove - isRecursive: isRecursive - inMemCtx: memCtx]; - - return rc; -} - -- (MAPIStoreMessage *) createMessage -{ - MAPIStoreMessage *newMessage; - SOGoMAPIDBMessage *fsObject; - NSString *newKey; - - [[self userContext] activate]; - - newKey = [NSString stringWithFormat: @"%@.plist", - [SOGoObject globallyUniqueObjectId]]; - fsObject = [SOGoMAPIDBMessage objectWithName: newKey - inContainer: sogoObject]; - [fsObject setObjectType: MAPIMessageCacheObject]; - [fsObject reloadIfNeeded]; - newMessage = [MAPIStoreDBMessage mapiStoreObjectWithSOGoObject: fsObject - inContainer: self]; - - return newMessage; -} - -- (NSArray *) messageKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - NSArray *keys; - SOGoUser *ownerUser; - - ownerUser = [[self userContext] sogoUser]; - if ([[context activeUser] isEqual: ownerUser] - || [self subscriberCanReadMessages]) - { - [[self userContext] activate]; - keys = [(SOGoCacheGCSFolder *) sogoObject childKeysOfType: MAPIMessageCacheObject - includeDeleted: NO - matchingQualifier: qualifier - andSortOrderings: sortOrderings]; - } - else - keys = [NSArray array]; - - return keys; -} - -- (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - [[self userContext] activate]; - return [dbFolder childKeysOfType: MAPIFolderCacheObject - 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; - MAPIStoreDBMessage *msg; - NSArray *messageKeys; - - messageKeys = [self messageKeys]; - - date = [NSCalendarDate date]; - //[self logWithFormat: @"current date: %@", date]; - - max = [messageKeys count]; - for (count = 0; count < max; count++) - { - msg = [self lookupMessage: [messageKeys objectAtIndex: count]]; - fileDate = [msg lastModificationTime]; - if ([date laterDate: fileDate] == fileDate) - { - //[self logWithFormat: @"current date: %@", date]; - - date = fileDate; - } - } - - return date; -} - -- (SOGoFolder *) aclFolder -{ - return sogoObject; -} - -- (NSArray *) rolesForExchangeRights: (uint32_t) rights -{ - NSMutableArray *roles; - - roles = [NSMutableArray arrayWithCapacity: 9]; - if (rights & RightsReadItems) - [roles addObject: MAPIStoreRightReadItems]; - if (rights & RightsCreateItems) - [roles addObject: MAPIStoreRightCreateItems]; - if (rights & RightsEditOwn) - [roles addObject: MAPIStoreRightEditOwn]; - if (rights & RightsDeleteOwn) - [roles addObject: MAPIStoreRightDeleteOwn]; - if (rights & RightsEditAll) - [roles addObject: MAPIStoreRightEditAll]; - if (rights & RightsDeleteAll) - [roles addObject: MAPIStoreRightDeleteAll]; - if (rights & RightsCreateSubfolders) - [roles addObject: MAPIStoreRightCreateSubfolders]; - if (rights & RightsFolderOwner) - [roles addObject: MAPIStoreRightFolderOwner]; - if (rights & RightsFolderContact) - [roles addObject: MAPIStoreRightFolderContact]; - - return roles; -} - -- (uint32_t) exchangeRightsForRoles: (NSArray *) roles -{ - uint32_t rights = 0; - - if ([roles containsObject: MAPIStoreRightReadItems]) - rights |= RightsReadItems; - if ([roles containsObject: MAPIStoreRightCreateItems]) - rights |= RightsCreateItems; - if ([roles containsObject: MAPIStoreRightEditOwn]) - rights |= RightsEditOwn; - if ([roles containsObject: MAPIStoreRightDeleteOwn]) - rights |= RightsDeleteOwn; - if ([roles containsObject: MAPIStoreRightEditAll]) - rights |= RightsEditAll | RightsEditOwn; - if ([roles containsObject: MAPIStoreRightDeleteAll]) - rights |= RightsDeleteAll | RightsDeleteOwn; - if ([roles containsObject: MAPIStoreRightCreateSubfolders]) - rights |= RightsCreateSubfolders; - if ([roles containsObject: MAPIStoreRightFolderOwner]) - rights |= RightsFolderOwner; - if ([roles containsObject: MAPIStoreRightFolderContact]) - rights |= RightsFolderContact; - if (rights != 0) - rights |= RoleNone; /* actually "folder visible" */ - - return rights; -} - -- (BOOL) _testRoleForActiveUser: (const NSString *) role -{ - SOGoUser *activeUser; - NSArray *roles; - - activeUser = [[self context] activeUser]; - - roles = [[self aclFolder] aclsForUser: [activeUser login]]; - - return [roles containsObject: role]; -} - -- (BOOL) subscriberCanCreateMessages -{ - return [self _testRoleForActiveUser: MAPIStoreRightCreateItems]; -} - -- (BOOL) subscriberCanModifyMessages -{ - return [self _testRoleForActiveUser: MAPIStoreRightEditAll]; -} - -- (BOOL) subscriberCanReadMessages -{ - NSString *displayName; - - /* when this folder is the "Freebusy Data" folder, we need to allow - subscribed to read an open contained messages in order to enable them to - find the "LocalFreebusy" message */ - [sogoObject reloadIfNeeded]; - - displayName = [[sogoObject properties] - objectForKey: MAPIPropertyKey (PidTagDisplayName)]; - - return ([displayName isEqualToString: @"Freebusy Data"] - || [self _testRoleForActiveUser: MAPIStoreRightReadItems]); -} - -- (BOOL) subscriberCanDeleteMessages -{ - return [self _testRoleForActiveUser: MAPIStoreRightDeleteAll]; -} - -- (BOOL) subscriberCanCreateSubFolders -{ - return [self _testRoleForActiveUser: MAPIStoreRightCreateSubfolders]; -} - -- (BOOL) supportsSubFolders -{ - return YES; -} - -@end diff --git a/OpenChange/MAPIStoreDBFolderTable.h b/OpenChange/MAPIStoreDBFolderTable.h deleted file mode 100644 index afc3018e2..000000000 --- a/OpenChange/MAPIStoreDBFolderTable.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreDBFolderTable.h - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREDBFOLDERTABLE_H -#define MAPISTOREDBFOLDERTABLE_H - -#import "MAPIStoreFolderTable.h" - -@interface MAPIStoreDBFolderTable : MAPIStoreFolderTable -@end - -#endif /* MAPISTOREDBFOLDERTABLE_H */ diff --git a/OpenChange/MAPIStoreDBFolderTable.m b/OpenChange/MAPIStoreDBFolderTable.m deleted file mode 100644 index 01a40b7f0..000000000 --- a/OpenChange/MAPIStoreDBFolderTable.m +++ /dev/null @@ -1,36 +0,0 @@ -/* MAPIStoreDBFolderTable.m - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import "MAPIStoreTypes.h" - -#import "MAPIStoreDBFolderTable.h" - -@implementation MAPIStoreDBFolderTable - -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property -{ - return [NSString stringWithFormat: @"%@", MAPIPropertyKey (property)]; -} - -@end diff --git a/OpenChange/MAPIStoreDBMessage.h b/OpenChange/MAPIStoreDBMessage.h deleted file mode 100644 index 532f53a8e..000000000 --- a/OpenChange/MAPIStoreDBMessage.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreDBMessage.h - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREDBMESSAGE_H -#define MAPISTOREDBMESSAGE_H - -#import "MAPIStoreMessage.h" - -@interface MAPIStoreDBMessage : MAPIStoreMessage -@end - -#endif /* MAPISTOREDBMESSAGE_H */ diff --git a/OpenChange/MAPIStoreDBMessage.m b/OpenChange/MAPIStoreDBMessage.m deleted file mode 100644 index ca2b772d0..000000000 --- a/OpenChange/MAPIStoreDBMessage.m +++ /dev/null @@ -1,495 +0,0 @@ -/* MAPIStoreDBMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreContext.h" -#import "MAPIStorePropertySelectors.h" -#import "SOGoMAPIDBMessage.h" - -#import "MAPIStoreDBFolder.h" -#import "MAPIStoreDBMessage.h" -#import "MAPIStoreTypes.h" -#import "NSData+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#undef DEBUG -#include -#include - -@implementation MAPIStoreDBMessage - -+ (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct SPropTagArray *properties; - NSUInteger count; - - enum MAPITAGS faiProperties[] = { - 0x68330048, /* PR_VIEW_CLSID */ - 0x68350102, /* PR_VIEW_STATE */ - 0x683c0102, - 0x683d0040, - 0x683e0102, - 0x683f0102, /* PR_VIEW_VIEWTYPE_KEY */ - 0x68410003, - 0x68420102, - 0x68450102, - 0x68460003, - 0x7006001F, /* PR_VD_NAME_W */ - 0x70030003, /* PR_VD_FLAGS */ - 0x70070003 /* PR_VD_VERSION */ - }; - - size_t faiSize = sizeof(faiProperties) / sizeof(enum MAPITAGS); - - properties = talloc_zero (memCtx, struct SPropTagArray); - properties->cValues = MAPIStoreSupportedPropertiesCount + faiSize; - properties->aulPropTag = talloc_array (properties, enum MAPITAGS, - MAPIStoreSupportedPropertiesCount + faiSize); - - for (count = 0; count < MAPIStoreSupportedPropertiesCount; count++) - properties->aulPropTag[count] = MAPIStoreSupportedProperties[count]; - - /* FIXME (hack): append a few undocumented properties that can be added to - FAI messages */ - for (count = 0; count < faiSize; count++) - properties->aulPropTag[MAPIStoreSupportedPropertiesCount+count] - = faiProperties[count]; - - *propertiesP = properties; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [[self class] getAvailableProperties: propertiesP - inMemCtx: memCtx]; -} - -- (id) initWithSOGoObject: (id) newSOGoObject - inContainer: (MAPIStoreObject *) newContainer -{ - if ((self = [super initWithSOGoObject: newSOGoObject - inContainer: newContainer])) - { - [properties release]; - properties = [newSOGoObject properties]; - [properties retain]; - } - - return self; -} - -- (NSString *) description -{ - id key, value; - NSEnumerator *propEnumerator; - NSMutableString *description; - - description = [NSMutableString stringWithFormat: @"%@ %@. Properties: {", NSStringFromClass ([self class]), - [self url]]; - - propEnumerator = [properties keyEnumerator]; - while ((key = [propEnumerator nextObject])) - { - uint32_t proptag = 0; - if ([key isKindOfClass: [NSString class]] && [(NSString *)key intValue] > 0) - proptag = [(NSString *)key intValue]; - else if ([key isKindOfClass: [NSNumber class]]) - proptag = [key unsignedLongValue]; - - if (proptag > 0) - { - const char *propTagName = get_proptag_name ([key unsignedLongValue]); - NSString *propName; - - if (propTagName) - propName = [NSString stringWithCString: propTagName - encoding: NSUTF8StringEncoding]; - else - propName = [NSString stringWithFormat: @"0x%.4x", [key unsignedLongValue]]; - - [description appendFormat: @"'%@': ", propName]; - } - else - [description appendFormat: @"'%@': ", key]; - - value = [properties objectForKey: key]; - [description appendFormat: @"%@ (%@), ", value, NSStringFromClass ([value class])]; - } - - [description appendString: @"}\n"]; - - return description; -} - -- (uint64_t) objectVersion -{ - /* Return the global counter from CN structure. - See [MS-OXCFXICS] Section 2.2.2.1 */ - NSNumber *versionNbr, *cn; - uint64_t objectVersion; - - [(SOGoMAPIDBMessage *) sogoObject reloadIfNeeded]; - versionNbr = [properties objectForKey: @"version_number"]; - if (versionNbr) - objectVersion = exchange_globcnt ([versionNbr unsignedLongLongValue]); - else - { - /* Old version which stored the CN structure not useful for searching */ - cn = [properties objectForKey: @"version"]; - if (cn) - objectVersion = (([cn unsignedLongLongValue] >> 16) - & 0x0000ffffffffffffLL); - else - objectVersion = ULLONG_MAX; - } - - return objectVersion; -} - -- (void) _updatePredecessorChangeList -{ - BOOL updated; - enum mapistore_error rc; - NSData *currentChangeList, *changeKey; - NSMutableArray *changeKeys; - NSMutableData *newChangeList; - NSUInteger count, len; - struct SizedXid *changes; - struct SPropValue property; - struct SRow aRow; - struct XID *currentChangeKey; - TALLOC_CTX *localMemCtx; - uint32_t nChanges; - - localMemCtx = talloc_new (NULL); - if (!localMemCtx) - { - [self errorWithFormat: @"No more memory"]; - return; - } - - changeKey = [self getReplicaKeyFromGlobCnt: [self objectVersion]]; - - currentChangeList = [properties objectForKey: MAPIPropertyKey (PidTagPredecessorChangeList)]; - if (!currentChangeList) - { - /* Create a new PredecessorChangeList */ - len = [changeKey length]; - newChangeList = [NSMutableData dataWithCapacity: len + 1]; - [newChangeList appendUInt8: len]; - [newChangeList appendData: changeKey]; - } - else - { - /* Update current predecessor change list with new change key */ - changes = [currentChangeList asSizedXidArrayInMemCtx: localMemCtx - with: &nChanges]; - - updated = NO; - currentChangeKey = [changeKey asXIDInMemCtx: localMemCtx]; - for (count = 0; count < nChanges && !updated; count++) - { - if (GUID_equal(&changes[count].XID.NameSpaceGuid, ¤tChangeKey->NameSpaceGuid)) - { - NSData *globCnt, *oldGlobCnt; - oldGlobCnt = [NSData dataWithBytes: changes[count].XID.LocalId.data length: changes[count].XID.LocalId.length]; - globCnt = [NSData dataWithBytes: currentChangeKey->LocalId.data length: currentChangeKey->LocalId.length]; - if ([globCnt compare: oldGlobCnt] == NSOrderedDescending) - { - if ([globCnt length] != [oldGlobCnt length]) - { - [self errorWithFormat: @"Cannot compare globcnt with different length: %@ and %@", globCnt, oldGlobCnt]; - abort(); - } - memcpy (changes[count].XID.LocalId.data, currentChangeKey->LocalId.data, currentChangeKey->LocalId.length); - updated = YES; - } - } - } - - /* Serialise it */ - changeKeys = [NSMutableArray array]; - - if (!updated) - [changeKeys addObject: changeKey]; - - for (count = 0; count < nChanges; count++) - { - changeKey = [NSData dataWithXID: &changes[count].XID]; - [changeKeys addObject: changeKey]; - } - - [changeKeys sortUsingFunction: MAPIChangeKeyGUIDCompare context: localMemCtx]; - - newChangeList = [NSMutableData data]; - len = [changeKeys count]; - for (count = 0; count < len; count++) - { - changeKey = [changeKeys objectAtIndex: count]; - [newChangeList appendUInt8: [changeKey length]]; - [newChangeList appendData: changeKey]; - } - } - - if ([newChangeList length] > 0) - { - property.ulPropTag = PidTagPredecessorChangeList; - property.value.bin = *[newChangeList asBinaryInMemCtx: localMemCtx]; - aRow.cValues = 1; - aRow.lpProps = &property; - rc = [self addPropertiesFromRow: &aRow]; - if (rc != MAPISTORE_SUCCESS) - [self errorWithFormat: @"Impossible to add a new predecessor change list: %d", rc]; - } - - talloc_free (localMemCtx); -} - -// -// FIXME: how this can happen? -// -// We might get there if for some reasons, all classes weren't able -// to tell us the message class. -// -- (enum mapistore_error) getPidTagMessageClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPM.Note" asUnicodeInMemCtx: memCtx]; - - [self logWithFormat: @"METHOD '%s' - unable to determine message class. Falling back to IPM.Note", __FUNCTION__]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) 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]; -} - -- (enum mapistore_error) getProperty: (void **) data - withTag: (enum MAPITAGS) propTag - inMemCtx: (TALLOC_CTX *) memCtx -{ - id value; - enum mapistore_error 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: (TALLOC_CTX *) memCtx -{ - uint64_t newVersion; - - if ([attachmentKeys count] > 0) - [properties setObject: attachmentParts forKey: @"attachments"]; - - newVersion = [[self context] getNewChangeNumber]; - newVersion = exchange_globcnt ((newVersion >> 16) & 0x0000ffffffffffffLL); - - [properties setObject: [NSNumber numberWithUnsignedLongLong: newVersion] - forKey: @"version_number"]; - - /* Remove old version */ - [properties removeObjectForKey: @"version"]; - - /* Update PredecessorChangeList accordingly */ - [self _updatePredecessorChangeList]; - - if (isNew) - { - NSString *lastModifierName; - - lastModifierName = (NSString *)[properties objectForKey: MAPIPropertyKey (PidTagLastModifierName)]; - if ([lastModifierName length] > 0) - [properties setObject: lastModifierName - forKey: MAPIPropertyKey (PidTagCreatorName)]; - } - - // [self logWithFormat: @"Saving %@", [self description]]; - // [self logWithFormat: @"%d props in dict", [properties count]]; - - [sogoObject save]; -} - -- (BOOL) _messageIsFreeBusy -{ - NSString *msgClass; - - /* This is a HACK until we figure out how to determine a message position in - the mailbox hierarchy.... (missing: folderid and role) */ - msgClass = [properties - objectForKey: MAPIPropertyKey (PR_MESSAGE_CLASS_UNICODE)]; - - return [msgClass isEqualToString: @"IPM.Microsoft.ScheduleData.FreeBusy"]; -} - -//----------------------------- -// Permissions -//----------------------------- - -- (BOOL) subscriberCanReadMessage -{ - return [(MAPIStoreFolder *) container subscriberCanReadMessages]; -} - -- (SOGoUser *) _ownerUser -{ - NSString *ownerName; - SOGoUser *ownerUser = nil; - - ownerName = [properties objectForKey: MAPIPropertyKey (PidTagCreatorName)]; - if ([ownerName length] > 0) - ownerUser = [SOGoUser userWithLogin: ownerName]; - - return ownerUser; -} - -- (NSArray *) activeUserRoles -{ - /* Override because of this exception: NSInvalidArgumentException, - reason: [SOGoMAPIDBMessage-aclsForUser:] should be overridden by - subclass */ - if (!activeUserRoles) - { - SOGoUser *activeUser; - - activeUser = [[self context] activeUser]; - activeUserRoles = [[container aclFolder] aclsForUser: [activeUser login]]; - [activeUserRoles retain]; - } - - return activeUserRoles; -} - -- (BOOL) subscriberCanModifyMessage -{ - BOOL rc; - NSArray *roles; - - roles = [self activeUserRoles]; - - if (isNew) - rc = [(MAPIStoreFolder *) container subscriberCanCreateMessages]; - else - rc = [roles containsObject: MAPIStoreRightEditAll]; - - /* Check if the message is owned and it has permission to edit it */ - if (!rc && [roles containsObject: MAPIStoreRightEditOwn]) - rc = [[[container context] activeUser] isEqual: [self _ownerUser]]; - - return rc; -} - -- (BOOL) subscriberCanDeleteMessage -{ - BOOL rc; - NSArray *roles; - - roles = [self activeUserRoles]; - - rc = [roles containsObject: MAPIStoreRightDeleteAll]; - - /* Check if the message is owned and it has permission to delete it */ - if (!rc && [roles containsObject: MAPIStoreRightDeleteOwn]) - rc = [[[container context] activeUser] isEqual: [self _ownerUser]]; - - return rc; -} - -- (NSDate *) creationTime -{ - return [sogoObject creationDate]; -} - -- (NSDate *) lastModificationTime -{ - return [sogoObject lastModified]; -} - -- (enum mapistore_error) setReadFlag: (uint8_t) flag -{ - /* Modify PidTagMessageFlags from SetMessageReadFlag and - SyncImportReadStateChanges ROPs */ - NSNumber *flags; - uint32_t newFlag; - - flags = [properties objectForKey: MAPIPropertyKey (PR_MESSAGE_FLAGS)]; - if (flags) - { - newFlag = [flags unsignedLongValue]; - if (flag & SUPPRESS_RECEIPT) - newFlag |= MSGFLAG_READ; - if (flag & CLEAR_RN_PENDING) - newFlag &= ~MSGFLAG_RN_PENDING; - if (flag & CLEAR_READ_FLAG) - newFlag &= ~MSGFLAG_READ; - if (flag & CLEAR_NRN_PENDING) - newFlag &= ~MSGFLAG_NRN_PENDING; - } - else - { - newFlag = MSGFLAG_READ; - if (flag & CLEAR_READ_FLAG) - newFlag = 0x0; - } - [properties setObject: [NSNumber numberWithUnsignedLong: newFlag] - forKey: MAPIPropertyKey (PR_MESSAGE_FLAGS)]; - - return MAPISTORE_SUCCESS; -} - -@end diff --git a/OpenChange/MAPIStoreDBMessageTable.h b/OpenChange/MAPIStoreDBMessageTable.h deleted file mode 100644 index 4b9f66480..000000000 --- a/OpenChange/MAPIStoreDBMessageTable.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreDBMessageTable.h - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREDBMESSAGETABLE_H -#define MAPISTOREDBMESSAGETABLE_H - -#import "MAPIStoreMessageTable.h" - -@interface MAPIStoreDBMessageTable : MAPIStoreMessageTable -@end - -#endif /* MAPISTOREDBMESSAGETABLE_H */ diff --git a/OpenChange/MAPIStoreDBMessageTable.m b/OpenChange/MAPIStoreDBMessageTable.m deleted file mode 100644 index a8c68abd1..000000000 --- a/OpenChange/MAPIStoreDBMessageTable.m +++ /dev/null @@ -1,133 +0,0 @@ -/* MAPIStoreDBMessageTable.m - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import - -#import "MAPIStoreTypes.h" -#import "MAPIStoreDBMessage.h" - -#import "MAPIStoreDBMessageTable.h" - -#undef DEBUG -#include - -static Class MAPIStoreDBMessageK = Nil; - -@implementation MAPIStoreDBMessageTable - -+ (void) initialize -{ - MAPIStoreDBMessageK = [MAPIStoreDBMessage class]; -} - -+ (Class) childObjectClass -{ - return MAPIStoreDBMessageK; -} - -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property -{ - return [NSString stringWithFormat: @"%@", MAPIPropertyKey (property)]; -} - -- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState rc; - id value; - NSNumber *version; - uint64_t cVersion; - - if ((uint32_t) res->ulPropTag == PidTagChangeNumber) - { - SEL operator; - - value = NSObjectFromMAPISPropValue (&res->lpProp); - cVersion = exchange_globcnt (([value unsignedLongLongValue] >> 16) - & 0x0000ffffffffffffLL); - version = [NSNumber numberWithUnsignedLongLong: cVersion]; - operator = [self operatorFromRestrictionOperator: res->relop]; - *qualifier = [[EOKeyValueQualifier alloc] initWithKey: @"version_number" - operatorSelector: operator - value: version]; - [*qualifier autorelease]; - rc = MAPIRestrictionStateNeedsEval; - } - else if ((uint32_t) res->ulPropTag == PR_SUBJECT_UNICODE) - { - EOQualifier *subjectQualifier, *nSubjectQualifier, *subjectPQualifier; - EOQualifier *orQualifier, *andQualifier; - struct mapi_SPropertyRestriction subRes; - char *colPtr, *prefix; - - [super evaluatePropertyRestriction: res - intoQualifier: &subjectQualifier]; - - subRes.relop = res->relop; - subRes.ulPropTag = PR_NORMALIZED_SUBJECT_UNICODE; - subRes.lpProp.ulPropTag = PR_NORMALIZED_SUBJECT_UNICODE; - - colPtr = strstr (res->lpProp.value.lpszW, ":"); - if (colPtr) - subRes.lpProp.value.lpszW = colPtr + 1; - else - subRes.lpProp.value.lpszW = res->lpProp.value.lpszW; - - [self evaluatePropertyRestriction: &subRes - intoQualifier: &nSubjectQualifier]; - if (colPtr) - { - prefix = strndup (res->lpProp.value.lpszW, (colPtr - res->lpProp.value.lpszW)); - - subRes.relop = RELOP_EQ; - subRes.ulPropTag = PR_SUBJECT_PREFIX_UNICODE; - subRes.lpProp.ulPropTag = PR_SUBJECT_PREFIX_UNICODE; - subRes.lpProp.value.lpszW = prefix; - [self evaluatePropertyRestriction: &subRes - intoQualifier: &subjectPQualifier]; - free (prefix); - - andQualifier = [[EOOrQualifier alloc] - initWithQualifiers: - subjectPQualifier, nSubjectQualifier, nil]; - orQualifier = [[EOOrQualifier alloc] - initWithQualifiers: - subjectQualifier, andQualifier, nil]; - [andQualifier release]; - } - else - orQualifier = [[EOOrQualifier alloc] - initWithQualifiers: - subjectQualifier, nSubjectQualifier, nil]; - [orQualifier autorelease]; - *qualifier = orQualifier; - rc = MAPIRestrictionStateNeedsEval; - } - else - rc = [super evaluatePropertyRestriction: res intoQualifier: qualifier]; - - return rc; -} - -@end diff --git a/OpenChange/MAPIStoreEmbeddedMessage.h b/OpenChange/MAPIStoreEmbeddedMessage.h deleted file mode 100644 index 4ef65f261..000000000 --- a/OpenChange/MAPIStoreEmbeddedMessage.h +++ /dev/null @@ -1,33 +0,0 @@ -/* MAPIStoreEmbeddedMessage.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREEMBEDDEDMESSAGE_H -#define MAPISTOREEMBEDDEDMESSAGE_H - -#import "MAPIStoreMessage.h" - -@interface MAPIStoreEmbeddedMessage : MAPIStoreMessage - -@end - - -#endif /* MAPISTOREEMBEDDEDMESSAGE_H */ diff --git a/OpenChange/MAPIStoreEmbeddedMessage.m b/OpenChange/MAPIStoreEmbeddedMessage.m deleted file mode 100644 index ff5f8b825..000000000 --- a/OpenChange/MAPIStoreEmbeddedMessage.m +++ /dev/null @@ -1,154 +0,0 @@ -/* MAPIStoreEmbeddedMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import "MAPIStoreAttachment.h" -#import "MAPIStoreFolder.h" -#import "NSObject+MAPIStore.h" - -#import "MAPIStoreEmbeddedMessage.h" - -#include - -static Class MAPIStoreAttachmentK; - -@implementation MAPIStoreEmbeddedMessage - -+ (void) initialize -{ - MAPIStoreAttachmentK = [MAPIStoreAttachment class]; -} - -- (uint64_t) objectId -{ - NSString *objectKey; - MAPIStoreMessage *grandParent; - - grandParent = (MAPIStoreMessage *) [container container]; - - /* FIXME: this is a hack */ - objectKey = [NSString stringWithFormat: @"%@/%@/as-message", - [grandParent nameInContainer], - [container nameInContainer], - [self nameInContainer]]; - - return [(MAPIStoreFolder *) [grandParent container] - idForObjectWithKey: objectKey]; -} - -- (enum mapistore_error) getPidTagAccessLevel: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -/* disabled properties */ -- (enum mapistore_error) getPidTagFolderId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagChangeKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagSourceKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagParentSourceKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagChangeNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagInstID: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagInstanceNum: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagRowType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagDepth: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagIconIndex: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagGenerateExchangeViews: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) 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: (TALLOC_CTX *) memCtx -{ - [self subclassResponsibility: _cmd]; -} - -@end diff --git a/OpenChange/MAPIStoreFAIMessage.h b/OpenChange/MAPIStoreFAIMessage.h deleted file mode 100644 index 509bd37be..000000000 --- a/OpenChange/MAPIStoreFAIMessage.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreFAIMessage.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREFAIMESSAGE_H -#define MAPISTOREFAIMESSAGE_H - -#import "MAPIStoreDBMessage.h" - -@interface MAPIStoreFAIMessage : MAPIStoreDBMessage -@end - -#endif /* MAPISTOREFAIMESSAGE_H */ diff --git a/OpenChange/MAPIStoreFAIMessage.m b/OpenChange/MAPIStoreFAIMessage.m deleted file mode 100644 index 1c0f1b9a0..000000000 --- a/OpenChange/MAPIStoreFAIMessage.m +++ /dev/null @@ -1,81 +0,0 @@ -/* MAPIStoreFAIMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import "MAPIStoreActiveTables.h" -#import "MAPIStoreContext.h" -#import "MAPIStoreFolder.h" -#import "MAPIStoreUserContext.h" -#import "NSObject+MAPIStore.h" - -#import "MAPIStoreFAIMessage.h" - -#undef DEBUG -#include -#include -#include -#include -#include - -@implementation MAPIStoreFAIMessage - -- (NSArray *) activeContainerMessageTables -{ - return [[MAPIStoreActiveTables activeTables] - activeTablesForFMID: [container objectId] - andType: MAPISTORE_FAI_TABLE]; -} - -- (enum mapistore_error) getPidTagAssociated: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) saveMessage: (TALLOC_CTX *) memCtx; -{ - enum mapistore_error rc; - MAPIStoreContext *context; - SOGoUser *ownerUser; - - context = [self context]; - ownerUser = [[self userContext] sogoUser]; - if ([[context activeUser] isEqual: ownerUser]) - rc = [super saveMessage: memCtx]; - else - rc = MAPISTORE_ERR_DENIED; - - return rc; -} - -- (BOOL) subscriberCanReadMessage -{ - return [(MAPIStoreFolder *)container subscriberCanReadMessages]; -} - -- (BOOL) subscriberCanModifyMessage -{ - return NO; -} - -@end diff --git a/OpenChange/MAPIStoreFAIMessageTable.h b/OpenChange/MAPIStoreFAIMessageTable.h deleted file mode 100644 index c12f20f99..000000000 --- a/OpenChange/MAPIStoreFAIMessageTable.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreFAIMessageTable.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREFAIMESSAGETABLE_H -#define MAPISTOREFAIMESSAGETABLE_H - -#import "MAPIStoreDBMessageTable.h" - -@interface MAPIStoreFAIMessageTable : MAPIStoreDBMessageTable -@end - -#endif /* MAPISTOREFAIMESSAGETABLE_H */ diff --git a/OpenChange/MAPIStoreFAIMessageTable.m b/OpenChange/MAPIStoreFAIMessageTable.m deleted file mode 100644 index 531299868..000000000 --- a/OpenChange/MAPIStoreFAIMessageTable.m +++ /dev/null @@ -1,101 +0,0 @@ -/* MAPIStoreFAIMessageTable.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import "MAPIStoreFAIMessage.h" -#import "MAPIStoreFolder.h" - -#import "MAPIStoreFAIMessageTable.h" - -#undef DEBUG -#include -#include -#include - -static Class MAPIStoreFAIMessageK = Nil; - -@implementation MAPIStoreFAIMessageTable - -+ (void) initialize -{ - MAPIStoreFAIMessageK = [MAPIStoreFAIMessage class]; -} - -+ (Class) childObjectClass -{ - return MAPIStoreFAIMessageK; -} - -- (id) init -{ - if ((self = [super init])) - { - tableType = MAPISTORE_FAI_TABLE; - } - - return self; -} - -- (NSArray *) childKeys -{ - if (!childKeys) - { - childKeys = [(MAPIStoreFolder *) - container faiMessageKeysMatchingQualifier: nil - andSortOrderings: sortOrderings]; - [childKeys retain]; - } - - return childKeys; -} - -- (NSArray *) restrictedChildKeys -{ - NSArray *keys; - - if (!restrictedChildKeys) - { - if (restrictionState != MAPIRestrictionStateAlwaysTrue) - { - if (restrictionState == MAPIRestrictionStateNeedsEval) - keys = [(MAPIStoreFolder *) - container faiMessageKeysMatchingQualifier: restriction - andSortOrderings: sortOrderings]; - else - keys = [NSArray array]; - } - else - keys = [self childKeys]; - - ASSIGN (restrictedChildKeys, keys); - } - - return restrictedChildKeys; -} - -- (id) lookupChild: (NSString *) childKey -{ - return [(MAPIStoreFolder *) container lookupFAIMessage: childKey]; -} - -@end diff --git a/OpenChange/MAPIStoreFallbackContext.h b/OpenChange/MAPIStoreFallbackContext.h deleted file mode 100644 index a6a2707ab..000000000 --- a/OpenChange/MAPIStoreFallbackContext.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreFallbackContext.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREFALLBACKCONTEXT_H -#define MAPISTOREFALLBACKCONTEXT_H - -#import "MAPIStoreDBBaseContext.h" - -@interface MAPIStoreFallbackContext : MAPIStoreDBBaseContext - -@end - -#endif /* MAPISTOREFALLBACKCONTEXT_H */ diff --git a/OpenChange/MAPIStoreFallbackContext.m b/OpenChange/MAPIStoreFallbackContext.m deleted file mode 100644 index 1555226d5..000000000 --- a/OpenChange/MAPIStoreFallbackContext.m +++ /dev/null @@ -1,112 +0,0 @@ -/* MAPIStoreFallbackContext.m - this file is part of SOGo - * - * Copyright (C) 2011-2014 Inverse inc. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 -#import -#import - -#import "MAPIStoreUserContext.h" -#import "NSString+MAPIStore.h" -#import - -#import "MAPIStoreFallbackContext.h" - -#undef DEBUG -#include -#include -#include - -@implementation MAPIStoreFallbackContext - -+ (NSString *) MAPIModuleName -{ - return @"fallback"; -} - -+ (enum mapistore_context_role) MAPIContextRole -{ - return MAPISTORE_MAIL_ROLE; -} - -+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName - withIndexing: (struct indexing_context *) indexing - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct mapistore_contexts_list *firstContext = NULL, *context; - SOGoCacheGCSFolder *root; - NSArray *names; - NSUInteger count, max; - NSString *baseURL, *url, *name; - MAPIStoreUserContext *userContext; - - baseURL = [NSString stringWithFormat: @"sogo://%@@fallback/", - [userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"]]; - - - context = talloc_zero (memCtx, struct mapistore_contexts_list); - context->url = [baseURL asUnicodeInMemCtx: context]; - context->name = "Fallback"; - context->main_folder = true; - context->role = MAPISTORE_FALLBACK_ROLE; - context->tag = "tag"; - - 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 = [SOGoCacheGCSFolder objectWithName: [self MAPIModuleName] - inContainer: nil]; - [root setOwner: userName]; - userContext = [MAPIStoreUserContext userContextWithUsername: userName - andTDBIndexing: indexing]; - [userContext ensureFolderTableExists]; - [root setTableUrl: [userContext folderTableURL]]; - names = [root toManyRelationshipKeys]; - max = [names count]; - for (count = 0; count < max; count++) - { - name = [names objectAtIndex: count]; - url = [NSString stringWithFormat: @"%@%@/", baseURL, name]; - context = talloc_zero (memCtx, struct mapistore_contexts_list); - context->url = [url asUnicodeInMemCtx: context]; - context->name = [name asUnicodeInMemCtx: context]; - context->main_folder = false; - context->role = MAPISTORE_FALLBACK_ROLE; - context->tag = "tag"; - DLIST_ADD_END (firstContext, context, void); - } - - return firstContext; -} - -+ (NSString *) - createRootSecondaryFolderWithFID: (uint64_t) fid - andName: (NSString *) folderName - forUser: (NSString *) userName -{ - return [NSString stringWithFormat: @"sogo://%@@fallback/0x%.16"PRIx64"/", - [userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"], - (unsigned long long) fid]; - -} - -@end diff --git a/OpenChange/MAPIStoreFolder.h b/OpenChange/MAPIStoreFolder.h deleted file mode 100644 index 46e13d235..000000000 --- a/OpenChange/MAPIStoreFolder.h +++ /dev/null @@ -1,209 +0,0 @@ -/* MAPIStoreFolder.h - this file is part of SOGo - * - * Copyright (C) 2011-2014 Inverse inc - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 MAPISTOREFOLDER_H -#define MAPISTOREFOLDER_H - -#import -#import - -@class NSArray; -@class NSMutableArray; -@class NSNumber; - -@class EOQualifier; - -@class MAPIStoreContext; -@class MAPIStoreMessage; -@class MAPIStoreFAIMessageTable; -@class MAPIStoreFolderTable; -@class MAPIStoreMessageTable; -@class MAPIStorePermissionsTable; -@class SOGoFolder; -@class SOGoCacheGCSFolder; -@class SOGoMAPIDBMessage; - -#import "MAPIStoreSOGoObject.h" - -/* MAPI Permissions - - This set has only sogo-openchange library scope - */ -extern NSString *MAPIStoreRightReadItems; -extern NSString *MAPIStoreRightCreateItems; -extern NSString *MAPIStoreRightEditOwn; -extern NSString *MAPIStoreRightEditAll; -extern NSString *MAPIStoreRightDeleteOwn; -extern NSString *MAPIStoreRightDeleteAll; -extern NSString *MAPIStoreRightCreateSubfolders; -extern NSString *MAPIStoreRightFolderOwner; -extern NSString *MAPIStoreRightFolderContact; - -@interface MAPIStoreFolder : MAPIStoreSOGoObject -{ - MAPIStoreContext *context; - // NSArray *messageKeys; - // NSArray *faiMessageKeys; - // NSArray *folderKeys; - - SOGoCacheGCSFolder *dbFolder; - // SOGoMAPIDBFolder *faiFolder; - // SOGoMAPIDBFolder *propsFolder; - // SOGoMAPIDBMessage *propsMessage; -} - -- (void) setContext: (MAPIStoreContext *) newContext; - -- (void) setupAuxiliaryObjects; - -- (SOGoCacheGCSFolder *) dbFolder; - -- (NSArray *) activeMessageTables; -- (NSArray *) activeFAIMessageTables; - -// - (SOGoMAPIDBMessage *) propertiesMessage; - -- (NSString *) childKeyFromURL: (NSString *) childURL; - -- (id) lookupMessageByURL: (NSString *) messageURL; -- (id) lookupFolderByURL: (NSString *) folderURL; - -/* permissions */ -- (MAPIStorePermissionsTable *) permissionsTable; -- (NSArray *) permissionEntries; - -- (NSArray *) expandRoles: (NSArray *) roles; - -/* message objects and tables */ -- (id) lookupMessage: (NSString *) messageKey; -- (NSArray *) messageKeys; - -/* FAI message objects and tables */ -- (id) lookupFAIMessage: (NSString *) messageKey; -- (MAPIStoreFAIMessageTable *) faiMessageTable; -- (NSArray *) faiMessageKeys; -- (NSArray *) faiMessageKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings; - -/* folder objects and tables */ -- (id) lookupFolder: (NSString *) folderKey; -- (MAPIStoreFolderTable *) folderTable; -- (NSArray *) folderKeys; -- (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings; - -- (MAPIStoreMessage *) createMessage: (BOOL) isAssociated; - -/* backend interface */ - -- (enum mapistore_error) openFolder: (MAPIStoreFolder **) childFolderPtr - withFID: (uint64_t) fid; -- (enum mapistore_error) createFolder: (MAPIStoreFolder **) childFolderPtr - withRow: (struct SRow *) aRow - andFID: (uint64_t) fid; -- (enum mapistore_error) deleteFolder; -- (enum mapistore_error) getChildCount: (uint32_t *) rowCount - ofTableType: (enum mapistore_table_type) tableType; - -- (enum mapistore_error) createMessage: (MAPIStoreMessage **) messagePtr - withMID: (uint64_t) mid - isAssociated: (BOOL) isAssociated; - -- (enum mapistore_error) openMessage: (MAPIStoreMessage **) messagePtr - withMID: (uint64_t) mid - forWriting: (BOOL) readWrite - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) deleteMessageWithMID: (uint64_t) mid - andFlags: (uint8_t) flags; - -- (enum mapistore_error) moveCopyMessagesWithMIDs: (uint64_t *) srcMids - andCount: (uint32_t) count - fromFolder: (MAPIStoreFolder *) sourceFolder - withMIDs: (uint64_t *) targetMids - andChangeKeys: (struct Binary_r **) targetChangeKeys - andPredecessorChangeLists: (struct Binary_r **) targetPredecessorChangeLists - wantCopy: (uint8_t) want_copy - inMemCtx: (TALLOC_CTX *) memCtx; - -- (enum mapistore_error) moveCopyToFolder: (MAPIStoreFolder *) targetFolder - withNewName: (NSString *) newFolderName - isMove: (BOOL) isMove - isRecursive: (BOOL) isRecursive - inMemCtx: (TALLOC_CTX *) memCtx; - -- (enum mapistore_error) getDeletedFMIDs: (struct UI8Array_r **) fmidsPtr - andCN: (uint64_t *) cnPtr - fromChangeNumber: (uint64_t) changeNum - inTableType: (enum mapistore_table_type) tableType - inMemCtx: (TALLOC_CTX *) mem_ctx; - -- (enum mapistore_error) getTable: (MAPIStoreTable **) tablePtr - andRowCount: (uint32_t *) count - tableType: (enum mapistore_table_type) tableType - andHandleId: (uint32_t) handleId; - -- (enum mapistore_error) modifyPermissions: (struct PermissionData *) permissions - withCount: (uint16_t) pcount - andFlags: (int8_t) flags; -- (enum mapistore_error) preloadMessageBodiesWithMIDs: (const struct UI8Array_r *) mids - ofTableType: (enum mapistore_table_type) tableType; - - -/* helpers */ -- (uint64_t) idForObjectWithKey: (NSString *) childKey; -- (MAPIStoreFolder *) rootContainer; - -/* subclasses */ -- (MAPIStoreMessage *) createMessage; -- (MAPIStoreMessageTable *) messageTable; -- (NSArray *) messageKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings; -- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum - andCN: (NSNumber **) cnNbr - inTableType: (enum mapistore_table_type) tableType; - -- (enum mapistore_error) createFolder: (struct SRow *) aRow - withFID: (uint64_t) newFID - andKey: (NSString **) newKeyP; - -- (NSCalendarDate *) lastMessageModificationTime; - -- (SOGoFolder *) aclFolder; -- (NSArray *) rolesForExchangeRights: (uint32_t) rights; -- (uint32_t) exchangeRightsForRoles: (NSArray *) roles; - -- (BOOL) subscriberCanCreateMessages; -- (BOOL) subscriberCanModifyMessages; -- (BOOL) subscriberCanReadMessages; -- (BOOL) subscriberCanDeleteMessages; -- (BOOL) subscriberCanCreateSubFolders; - -- (BOOL) supportsSubFolders; /* capability */ - -- (enum mapistore_error) preloadMessageBodiesWithKeys: (NSArray *) keys - ofTableType: (enum mapistore_table_type) tableType; - -/* subclass helpers */ -- (void) setupVersionsMessage; -- (void) ensureIDsForChildKeys: (NSArray *) keys; - -@end - -#endif /* MAPISTOREFOLDER_H */ diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m deleted file mode 100644 index 43efcaff9..000000000 --- a/OpenChange/MAPIStoreFolder.m +++ /dev/null @@ -1,1897 +0,0 @@ -/* MAPIStoreFolder.m - this file is part of SOGo - * - * Copyright (C) 2011-2014 Inverse inc - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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. - */ - -/* TODO: main key arrays must be initialized */ - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreActiveTables.h" -#import "MAPIStoreContext.h" -#import "MAPIStoreFAIMessage.h" -#import "MAPIStoreFAIMessageTable.h" -#import "MAPIStoreFolder.h" -#import "MAPIStoreFolderTable.h" -#import "MAPIStoreMapping.h" -#import "MAPIStoreMessage.h" -#import "MAPIStorePermissionsTable.h" -#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 -#import "SOGoMAPIDBMessage.h" -#import "SOGoCacheGCSObject+MAPIStore.h" -#import - -#include - -#undef DEBUG -#include -#include -#include -#include - -Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMessageTableK, MAPIStoreFolderTableK; - -/* MAPI permissions */ -NSString *MAPIStoreRightReadItems = @"RightsReadItems"; -NSString *MAPIStoreRightCreateItems = @"RightsCreateItems"; -NSString *MAPIStoreRightEditOwn = @"RightsEditOwn"; -NSString *MAPIStoreRightEditAll = @"RightsEditAll"; -NSString *MAPIStoreRightDeleteOwn = @"RightsDeleteOwn"; -NSString *MAPIStoreRightDeleteAll = @"RightsDeleteAll"; -NSString *MAPIStoreRightCreateSubfolders = @"RightsCreateSubfolders"; -NSString *MAPIStoreRightFolderOwner = @"RightsFolderOwner"; -NSString *MAPIStoreRightFolderContact = @"RightsFolderContact"; - -@implementation MAPIStoreFolder - -+ (void) initialize -{ - NSExceptionK = [NSException class]; - MAPIStoreFAIMessageK = [MAPIStoreFAIMessage class]; - MAPIStoreMessageTableK = [MAPIStoreMessageTable class]; - MAPIStoreFAIMessageTableK = [MAPIStoreFAIMessageTable class]; - MAPIStoreFolderTableK = [MAPIStoreFolderTable class]; -} - -- (id) init -{ - if ((self = [super init])) - { - // messageKeys = nil; - // faiMessageKeys = nil; - // folderKeys = nil; - dbFolder = nil; - context = nil; - - // propsFolder = nil; - // propsMessage = nil; - } - - return self; -} - -- (void) setupAuxiliaryObjects -{ - NSURL *folderURL; - NSMutableString *pathPrefix; - NSString *path, *folderName; - NSArray *parts; - NSUInteger lastPartIdx; - MAPIStoreUserContext *userContext; - - parts = 0; - lastPartIdx = 0; - folderURL = [NSURL URLWithString: [self url]]; - /* note: -[NSURL path] returns an unescaped representation */ - 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 activate]; - [userContext ensureFolderTableExists]; - - ASSIGN (dbFolder, - [SOGoCacheGCSFolder 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: MAPIInternalCacheObject]; - // [propsMessage reloadIfNeeded]; - [properties release]; - properties = [dbFolder properties]; - [properties retain]; - - [self setupVersionsMessage]; -} - -- (id) initWithSOGoObject: (id) newSOGoObject - inContainer: (MAPIStoreObject *) newContainer -{ - /* The instantiation of auxiliary folders is postponed when newContainer is - nil since there is no way to deduce the parent url. When setContext: is - invoked, it becomes possible again. */ - if ((self = [super initWithSOGoObject: newSOGoObject - inContainer: newContainer]) - && newContainer) - { - [self setupAuxiliaryObjects]; - } - - return self; -} - -- (void) setContext: (MAPIStoreContext *) newContext -{ - ASSIGN (context, newContext); - if (newContext) - [self setupAuxiliaryObjects]; -} - -- (MAPIStoreContext *) context -{ - if (!context) - [self setContext: (MAPIStoreContext *) [container context]]; - - return context; -} - -- (void) dealloc -{ - //[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__]; - - // [messageKeys release]; - // [faiMessageKeys release]; - // [folderKeys release]; - // [propsMessage release]; - [dbFolder release]; - [context release]; - - [super dealloc]; -} - -- (SOGoCacheGCSFolder *) dbFolder -{ - return dbFolder; -} - -/* backend interface */ - -// - (SOGoMAPIDBMessage *) propertiesMessage -// { -// return propsMessage; -// } - -- (uint64_t) objectVersion -{ - NSNumber *value; - uint64_t cn; - - value = [properties objectForKey: MAPIPropertyKey (PidTagChangeNumber)]; - if (value) - cn = [value unsignedLongLongValue]; - else - { - [self logWithFormat: @"no value for PidTagChangeNumber, adding one now"]; - cn = [[self context] getNewChangeNumber]; - value = [NSNumber numberWithUnsignedLongLong: cn]; - - [properties setObject: value - forKey: MAPIPropertyKey (PidTagChangeNumber)]; - [dbFolder save]; - } - - return cn >> 16; -} - -- (id) lookupFolder: (NSString *) folderKey -{ - MAPIStoreFolder *childFolder = nil; - SOGoFolder *sogoFolder; - - if ([[self folderKeys] containsObject: folderKey]) - { - [[self userContext] activate]; - sogoFolder = [sogoObject lookupName: folderKey - inContext: nil - acquire: NO]; - if (sogoFolder && ![sogoFolder isKindOfClass: NSExceptionK]) - childFolder = [isa mapiStoreObjectWithSOGoObject: sogoFolder - inContainer: self]; - } - - return childFolder; -} - -- (id) lookupFolderByURL: (NSString *) childURL -{ - MAPIStoreObject *foundObject; - NSString *key, *slashLessURL; - - if ([childURL hasSuffix: @"/"]) - slashLessURL = [childURL substringToIndex: [childURL length] - 1]; - else - slashLessURL = childURL; - key = [self childKeyFromURL: slashLessURL]; - if (key) - foundObject = [self lookupFolder: key]; - else - foundObject = nil; - - return foundObject; -} - -- (id) lookupMessage: (NSString *) messageKey -{ - MAPIStoreObject *childMessage = nil; - Class messageClass; - SOGoObject *msgObject; - - if (messageKey) - { - [[self userContext] activate]; - msgObject = [sogoObject lookupName: messageKey - inContext: nil - acquire: NO]; - /* If the lookup in the indexing table works, but the IMAP does - not have the message, then the message does not exist in this - folder */ - if (msgObject && [msgObject isKindOfClass: [SOGoMailObject class]] - && ! [(SOGoMailObject *)msgObject doesMailExist]) - return nil; - if (msgObject && ![msgObject isKindOfClass: NSExceptionK]) - { - [msgObject setContext: [[self userContext] woContext]]; - messageClass = [msgObject mapistoreMessageClass]; - childMessage - = [messageClass mapiStoreObjectWithSOGoObject: msgObject - inContainer: self]; - } - } - - return childMessage; -} - -- (id) lookupFAIMessage: (NSString *) messageKey -{ - MAPIStoreObject *childMessage = nil; - SOGoObject *msgObject; - - if (messageKey) - { - [[self userContext] activate]; - if ([[self faiMessageKeys] containsObject: messageKey]) - { - msgObject = [dbFolder lookupName: messageKey - inContext: nil - acquire: NO]; - childMessage - = [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: msgObject - inContainer: self]; - } - } - - return childMessage; -} - -- (NSString *) childKeyFromURL: (NSString *) childURL -{ - NSString *baseURL, *subURL, *key = nil; - NSArray *parts; - NSUInteger partsCount; - - baseURL = [self url]; - if (![baseURL hasSuffix: @"/"]) - baseURL = [NSString stringWithFormat: @"%@/", baseURL]; - if ([childURL hasPrefix: baseURL]) - { - subURL = [childURL substringFromIndex: [baseURL length]]; - if ([subURL length] > 0) - { - parts = [subURL componentsSeparatedByString: @"/"]; - partsCount = [parts count]; - if (partsCount == 1) - { - key = [[parts objectAtIndex: 0] - stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; - } - } - } - - return key; -} - -- (id) lookupMessageByURL: (NSString *) childURL -{ - MAPIStoreObject *foundObject; - NSString *key; - - key = [self childKeyFromURL: childURL]; - if (key) - { - foundObject = [self lookupFAIMessage: key]; - if (!foundObject) - foundObject = [self lookupMessage: key]; - } - else - foundObject = nil; - - return foundObject; -} - -- (enum mapistore_error) openFolder: (MAPIStoreFolder **) childFolderPtr - withFID: (uint64_t) fid -{ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - MAPIStoreFolder *childFolder; - MAPIStoreMapping *mapping; - NSString *childURL; - - //[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__]; - - mapping = [self mapping]; - childURL = [mapping urlFromID: fid]; - if (childURL) - { - childFolder = [self lookupFolderByURL: childURL]; - if (childFolder) - { - *childFolderPtr = childFolder; - rc = MAPISTORE_SUCCESS; - } - } - - return rc; -} - -- (enum mapistore_error) createFolder: (MAPIStoreFolder **) childFolderPtr - withRow: (struct SRow *) aRow - andFID: (uint64_t) fid -{ - BOOL mapped; - enum mapistore_error rc = MAPISTORE_SUCCESS; - MAPIStoreMapping *mapping; - NSString *baseURL, *childURL, *folderKey; - MAPIStoreFolder *childFolder; - SOGoUser *ownerUser; - - //[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__]; - - ownerUser = [[self userContext] sogoUser]; - if ([[context activeUser] isEqual: ownerUser] - || [self subscriberCanCreateSubFolders]) - { - mapping = [self mapping]; - childURL = [mapping urlFromID: fid]; - if (childURL) - rc = MAPISTORE_ERR_EXIST; - else - { - rc = [self createFolder: aRow withFID: fid andKey: &folderKey]; - if (rc == MAPISTORE_SUCCESS) - { - [self cleanupCaches]; - baseURL = [self url]; - if (![baseURL hasSuffix: @"/"]) - baseURL = [NSString stringWithFormat: @"%@/", baseURL]; - childURL = [NSString stringWithFormat: @"%@%@/", - baseURL, - [folderKey stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; - - mapped = [mapping registerURL: childURL withID: fid]; - if (!mapped) - /* Enforce the creation if the backend does know the fid */ - [mapping updateURL: childURL withID: fid]; - - childFolder = [self lookupFolder: folderKey]; - if (childFolder) - { - [childFolder addPropertiesFromRow: aRow]; - *childFolderPtr = childFolder; - } - else - [NSException raise: @"MAPIStoreIOException" - format: @"unable to fetch created folder"]; - } - } - } - else - rc = MAPISTORE_ERR_DENIED; - - return rc; -} - -- (enum mapistore_error) deleteFolder -{ - // TODO: raise exception in case underlying delete fails? - // [propsMessage delete]; - [dbFolder delete]; - - [self cleanupCaches]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getChildCount: (uint32_t *) rowCount - ofTableType: (enum mapistore_table_type) tableType -{ - NSArray *keys; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - //[self logWithFormat: @"METHOD '%s' (%d) -- tableType: %d", - //__FUNCTION__, __LINE__, tableType]; - - if (tableType == MAPISTORE_MESSAGE_TABLE) - keys = [self messageKeys]; - else if (tableType == MAPISTORE_FOLDER_TABLE) - keys = [self folderKeys]; - else if (tableType == MAPISTORE_FAI_TABLE) - keys = [self faiMessageKeys]; - else - { - keys = nil; - rc = MAPISTORE_ERR_NOT_FOUND; - } - *rowCount = [keys count]; - - return rc; -} - -- (enum mapistore_error) openMessage: (MAPIStoreMessage **) messagePtr - withMID: (uint64_t) mid - forWriting: (BOOL) readWrite - inMemCtx: (TALLOC_CTX *) memCtx; -{ - NSString *messageURL; - MAPIStoreMapping *mapping; - MAPIStoreMessage *message; - SOGoUser *ownerUser; - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - - mapping = [self mapping]; - messageURL = [mapping urlFromID: mid]; - if (messageURL) - { - message = [self lookupMessageByURL: messageURL]; - if (message) - { - ownerUser = [[self userContext] sogoUser]; - if ([[context activeUser] isEqual: ownerUser] - || (readWrite && [message subscriberCanModifyMessage]) - || (!readWrite && [message subscriberCanReadMessage])) - { - *messagePtr = message; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_DENIED; - } - else - { - /* Unregistering from indexing table as the backend says the - object was not found */ - [mapping unregisterURLWithID: mid]; - } - } - - return rc; -} - -- (enum mapistore_error) createMessage: (MAPIStoreMessage **) messagePtr - withMID: (uint64_t) mid - isAssociated: (BOOL) isAssociated -{ - enum mapistore_error rc; - MAPIStoreMessage *message; - NSString *baseURL, *childURL; - MAPIStoreMapping *mapping; - SOGoUser *ownerUser; - - //[self logWithFormat: @"METHOD '%s' -- mid: 0x%.16llx associated: %d", - // __FUNCTION__, mid, isAssociated]; - - context = [self context]; - ownerUser = [[self userContext] sogoUser]; - [[self userContext] activate]; - - if ([[context activeUser] isEqual: ownerUser] - || (!isAssociated && [self subscriberCanCreateMessages])) - { - mapping = [self mapping]; - if ([mapping urlFromID: mid]) - rc = MAPISTORE_ERR_EXIST; - else - { - message = [self createMessage: isAssociated]; - if (message) - { - baseURL = [self url]; - if (![baseURL hasSuffix: @"/"]) - baseURL = [NSString stringWithFormat: @"%@/", baseURL]; - childURL = [NSString stringWithFormat: @"%@%@", - baseURL, [message nameInContainer]]; - [mapping registerURL: childURL withID: mid]; - *messagePtr = message; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERROR; - } - } - else - rc = MAPISTORE_ERR_DENIED; - - return rc; -} - -- (enum mapistore_error) deleteMessageWithMID: (uint64_t) mid - andFlags: (uint8_t) flags -{ - NSString *childURL; - MAPIStoreMapping *mapping; - MAPIStoreMessage *message; - NSArray *activeTables; - NSUInteger count, max; - id msgObject; - SOGoUser *ownerUser; - enum mapistore_error rc; - - /* flags that control the behaviour of the operation - (MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE) */ - [self logWithFormat: @"-deleteMessageWithMID: mid: 0x%.16llx flags: %d", mid, flags]; - - mapping = [self mapping]; - childURL = [mapping urlFromID: mid]; - if (childURL) - { - message = [self lookupMessageByURL: childURL]; - if (message) - { - ownerUser = [[self userContext] sogoUser]; - - if ([[context activeUser] isEqual: ownerUser] - || (![message isKindOfClass: MAPIStoreFAIMessageK] - && ([self subscriberCanDeleteMessages] || [message subscriberCanDeleteMessage]))) - { - /* we ensure the table caches are loaded so that old and new state - can be compared */ - activeTables = ([message isKindOfClass: MAPIStoreFAIMessageK] - ? [self activeFAIMessageTables] - : [self activeMessageTables]); - max = [activeTables count]; - for (count = 0; count < max; count++) - [[activeTables objectAtIndex: count] restrictedChildKeys]; - - msgObject = [message sogoObject]; - if (([msgObject respondsToSelector: @selector (prepareDelete)] - && [msgObject prepareDelete]) - || [msgObject delete]) - { - rc = MAPISTORE_ERROR; - [self logWithFormat: @"ERROR deleting object at URL: %@", childURL]; - } - else - { - [self logWithFormat: @"successfully deleted object at URL: %@", childURL]; - /* Ensure we are respecting flags parameter */ - [mapping unregisterURLWithID: mid andFlags: flags]; - [self cleanupCaches]; - rc = MAPISTORE_SUCCESS; - } - } - else - rc = MAPISTORE_ERR_DENIED; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -// private method -- (enum mapistore_error) _moveCopyMessageWithMID: (uint64_t) srcMid - fromFolder: (MAPIStoreFolder *) sourceFolder - withMID: (uint64_t) targetMid - andChangeKey: (struct Binary_r *) targetChangeKey - andPredecessorChangeList: (struct Binary_r *) targetPredecessorChangeList - wantCopy: (uint8_t) wantCopy - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - MAPIStoreMessage *sourceMsg, *destMsg; - //TALLOC_CTX *memCtx; - struct SRow aRow; - struct SPropValue property; - uint8_t deleteFlags; - - [self logWithFormat: @"-moveCopyMessageWithMID: 0x%.16llx .. withMID: 0x%.16llx .. wantCopy: %d", srcMid, targetMid, wantCopy]; - - //memCtx = talloc_zero (NULL, TALLOC_CTX); - rc = [sourceFolder openMessage: &sourceMsg - withMID: srcMid - forWriting: NO - inMemCtx: memCtx]; - if (rc != MAPISTORE_SUCCESS) - goto end; - - rc = [self createMessage: &destMsg withMID: targetMid - isAssociated: [sourceMsg isKindOfClass: MAPIStoreFAIMessageK]]; - if (rc != MAPISTORE_SUCCESS) - goto end; - - [sourceMsg copyToMessage: destMsg inMemCtx: memCtx]; - - if (targetPredecessorChangeList) - { - property.ulPropTag = PidTagPredecessorChangeList; - property.value.bin = *targetPredecessorChangeList; - aRow.cValues = 1; - aRow.lpProps = &property; - rc = [destMsg addPropertiesFromRow: &aRow]; - if (rc != MAPISTORE_SUCCESS) - { - [self errorWithFormat: @"Cannot add PredecessorChangeList on move"]; - goto end; - } - } - [destMsg save: memCtx]; - if (!wantCopy) - /* We want to keep mid for restoring/shared data to work if mids are different. */ - deleteFlags = (srcMid == targetMid) ? MAPISTORE_PERMANENT_DELETE : MAPISTORE_SOFT_DELETE; - rc = [sourceFolder deleteMessageWithMID: srcMid andFlags: deleteFlags]; - - end: - //talloc_free (memCtx); - - return rc; -} - -- (enum mapistore_error) moveCopyMessagesWithMIDs: (uint64_t *) srcMids - andCount: (uint32_t) midCount - fromFolder: (MAPIStoreFolder *) sourceFolder - withMIDs: (uint64_t *) targetMids - andChangeKeys: (struct Binary_r **) targetChangeKeys - andPredecessorChangeLists: (struct Binary_r **) targetPredecessorChangeLists - wantCopy: (uint8_t) wantCopy - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSUInteger count; - NSMutableArray *oldMessageURLs; - NSString *oldMessageURL; - MAPIStoreMapping *mapping; - SOGoUser *ownerUser; - struct Binary_r *targetChangeKey, *targetPredecessorChangeList; - //TALLOC_CTX *memCtx; - - //memCtx = talloc_zero (NULL, TALLOC_CTX); - - ownerUser = [[self userContext] sogoUser]; - - if (wantCopy || [[context activeUser] isEqual: ownerUser]) - { - if ([sourceFolder isKindOfClass: isa] - || [self isKindOfClass: [sourceFolder class]]) - [self logWithFormat: @"%s: this class could probably implement" - @" a specialized/optimized version", __FUNCTION__]; - oldMessageURLs = [NSMutableArray arrayWithCapacity: midCount]; - mapping = [self mapping]; - for (count = 0; rc == MAPISTORE_SUCCESS && count < midCount; count++) - { - oldMessageURL = [mapping urlFromID: srcMids[count]]; - if (oldMessageURL) - { - [oldMessageURLs addObject: oldMessageURL]; - if (targetChangeKeys && targetPredecessorChangeList) - { - targetChangeKey = targetChangeKeys[count]; - targetPredecessorChangeList = targetPredecessorChangeLists[count]; - } - else - { - targetChangeKey = NULL; - targetPredecessorChangeList = NULL; - } - rc = [self _moveCopyMessageWithMID: srcMids[count] - fromFolder: sourceFolder - withMID: targetMids[count] - andChangeKey: targetChangeKey - andPredecessorChangeList: targetPredecessorChangeList - wantCopy: wantCopy - inMemCtx: memCtx]; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - } - - /* Notifications */ - if (rc == MAPISTORE_SUCCESS) - { - // We cleanup cache of our source and destination folders - [self cleanupCaches]; - [sourceFolder cleanupCaches]; - } - } - else - rc = MAPISTORE_ERR_DENIED; - - //talloc_free (memCtx); - - return rc; -} - -- (enum mapistore_error) moveCopyToFolder: (MAPIStoreFolder *) targetFolder - withNewName: (NSString *) newFolderName - isMove: (BOOL) isMove - isRecursive: (BOOL) isRecursive - inMemCtx: (TALLOC_CTX *) memCtx - -{ - 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; - //TALLOC_CTX *memCtx; - - //memCtx = talloc_zero (NULL, TALLOC_CTX); - - /* 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 inMemCtx: memCtx]; - - 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 inMemCtx: memCtx]; - if (isMove) - { - fmid = [mapping idFromURL: [message url]]; - [self deleteMessageWithMID: fmid andFlags: MAPISTORE_PERMANENT_DELETE]; - [mapping registerURL: [targetMessage url] - withID: fmid]; - } - [targetMessage save: memCtx]; - } - [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 inMemCtx: memCtx]; - if (isMove) - { - fmid = [mapping idFromURL: [message url]]; - [self deleteMessageWithMID: fmid andFlags: MAPISTORE_PERMANENT_DELETE]; - [mapping registerURL: [targetMessage url] - withID: fmid]; - } - [targetMessage save: memCtx]; - } - [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 - inMemCtx: memCtx]; - - } - [pool release]; - } - - if (isMove) - [self deleteFolder]; - - [targetFolder cleanupCaches]; - } - [self cleanupCaches]; - - /* We perform the mapping operations at the - end as objectId is required to be available - until the caches are cleaned up */ - if (isMove && rc == MAPISTORE_SUCCESS) - { - fmid = [mapping idFromURL: [self url]]; - [mapping unregisterURLWithID: fmid]; - [mapping registerURL: [newFolder url] - withID: fmid]; - } - - } - else - rc = MAPISTORE_ERR_DENIED; - - //talloc_free (memCtx); - - return rc; -} - -- (SOGoFolder *) aclFolder -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (NSArray *) expandRoles: (NSArray *) roles -{ - return roles; -} - -- (void) _modifyPermissionEntryForUser: (NSString *) user - withRoles: (NSArray *) roles - isAddition: (BOOL) isAddition - withACLFolder: (SOGoFolder *) aclFolder -{ - if (user) - { - if (isAddition) - [aclFolder addUserInAcls: user]; - [aclFolder setRoles: roles forUser: user]; - } - else - [self logWithFormat: @"user is nil, keeping intended entry intact"]; -} - -- (void) setupVersionsMessage -{ -} - -- (void) ensureIDsForChildKeys: (NSArray *) keys -{ - NSMutableArray *missingURLs; - MAPIStoreMapping *mapping; - NSUInteger count, max; - NSString *baseURL, *URL, *key; - NSArray *newIDs; - uint64_t idNbr; - bool softDeleted; - - baseURL = [self url]; - - mapping = [self mapping]; - max = [keys count]; - missingURLs = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - key = [keys objectAtIndex: count]; - URL = [NSString stringWithFormat: @"%@%@", baseURL, key]; - idNbr = [mapping idFromURL: URL isSoftDeleted: &softDeleted]; - if (idNbr == NSNotFound && !softDeleted) - [missingURLs addObject: URL]; - } - - max = [missingURLs count]; - newIDs = [[self context] getNewFMIDs: max]; - [mapping registerURLs: missingURLs - withIDs: newIDs]; -} - -- (enum mapistore_error) getDeletedFMIDs: (struct UI8Array_r **) fmidsPtr - andCN: (uint64_t *) cnPtr - fromChangeNumber: (uint64_t) changeNum - inTableType: (enum mapistore_table_type) tableType - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSString *baseURL, *format, *url; - NSArray *keys; - NSNumber *cnNbr; - NSUInteger count, max; - MAPIStoreMapping *mapping; - struct UI8Array_r *fmids; - uint64_t fmid; - bool softDeleted; - - keys = [self getDeletedKeysFromChangeNumber: changeNum andCN: &cnNbr - inTableType: tableType]; - if (keys) - { - mapping = [self mapping]; - - max = [keys count]; - - fmids = talloc_zero (memCtx, struct UI8Array_r); - fmids->cValues = 0; - fmids->lpui8 = talloc_array (fmids, uint64_t, max); - *fmidsPtr = fmids; - if (max > 0) - *cnPtr = [cnNbr unsignedLongLongValue]; - - baseURL = [self url]; - if ([baseURL hasSuffix: @"/"]) - format = @"%@%@"; - else - format = @"%@/%@"; - - for (count = 0; count < max; count++) - { - url = [NSString stringWithFormat: format, - baseURL, [keys objectAtIndex: count]]; - fmid = [mapping idFromURL: url isSoftDeleted: &softDeleted]; - if (fmid != NSNotFound) /* if no fmid is returned, then the object - "never existed" in the OpenChange - databases. Soft-deleted messages are returned back */ - { - fmids->lpui8[fmids->cValues] = fmid; - fmids->cValues++; - } - } - - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getTable: (MAPIStoreTable **) tablePtr - andRowCount: (uint32_t *) countPtr - tableType: (enum mapistore_table_type) tableType - andHandleId: (uint32_t) handleId -{ - BOOL access; - enum mapistore_error rc = MAPISTORE_SUCCESS; - MAPIStoreTable *table; - SOGoUser *activeUser, *ownerUser; - - if (tableType == MAPISTORE_MESSAGE_TABLE) - table = [self messageTable]; - else if (tableType == MAPISTORE_FAI_TABLE) - table = [self faiMessageTable]; - else if (tableType == MAPISTORE_FOLDER_TABLE) - table = [self folderTable]; - else if (tableType == MAPISTORE_PERMISSIONS_TABLE) - { - ownerUser = [[self userContext] sogoUser]; - activeUser = [context activeUser]; - access = [activeUser isEqual: ownerUser]; - if (!access) - { - NSArray *roles; - - roles = [[self aclFolder] aclsForUser: [activeUser login]]; - roles = [self expandRoles: roles]; // Not required here - /* Check FolderVisible right to return the table */ - access = ([self exchangeRightsForRoles: roles] & RoleNone) != 0; - } - - if (access) - table = [self permissionsTable]; - else - rc = MAPISTORE_ERR_DENIED; - } - else - { - table = nil; - [NSException raise: @"MAPIStoreIOException" - format: @"unsupported table type: %d", tableType]; - } - - if (rc == MAPISTORE_SUCCESS) - { - if (table) - { - [table setHandleId: handleId]; - *tablePtr = table; - *countPtr = [[table childKeys] count]; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - } - - return rc; -} - -- (void) addProperties: (NSDictionary *) newProperties -{ - static enum MAPITAGS bannedProps[] = { PR_MID, PR_FID, PR_PARENT_FID, - PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY, - PR_CHANGE_KEY, PidTagChangeNumber, 0x00000000 }; - enum MAPITAGS *currentProp; - NSMutableDictionary *propsCopy; - uint64_t cn; - - /* 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) - { - [propsCopy removeObjectForKey: MAPIPropertyKey (*currentProp)]; - currentProp++; - } - - [properties addEntriesFromDictionary: propsCopy]; - - /* Update change number after setting the properties */ - cn = [[self context] getNewChangeNumber]; - [properties setObject: [NSNumber numberWithUnsignedLongLong: cn] - forKey: MAPIPropertyKey (PidTagChangeNumber)]; - - [dbFolder save]; -} - -- (NSArray *) messageKeys -{ - return [self messageKeysMatchingQualifier: nil - andSortOrderings: nil]; - // if (!messageKeys) - // { - // messageKeys = [self messageKeysMatchingQualifier: nil - // andSortOrderings: nil]; - // [messageKeys retain]; - // } - - // return messageKeys; -} - -- (MAPIStoreFAIMessageTable *) faiMessageTable -{ - return [MAPIStoreFAIMessageTable tableForContainer: self]; -} - -- (NSArray *) faiMessageKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - [[self userContext] activate]; - return [dbFolder childKeysOfType: MAPIFAICacheObject - includeDeleted: NO - matchingQualifier: qualifier - andSortOrderings: sortOrderings]; -} - -- (NSArray *) faiMessageKeys -{ - return [self faiMessageKeysMatchingQualifier: nil - andSortOrderings: nil]; - // if (!faiMessageKeys) - // { - // faiMessageKeys = [self faiMessageKeysMatchingQualifier: nil - // andSortOrderings: nil]; - // [faiMessageKeys retain]; - // } - - // return faiMessageKeys; -} - -- (MAPIStoreFolderTable *) folderTable -{ - return [MAPIStoreFolderTable tableForContainer: self]; -} - -- (NSArray *) folderKeys -{ - return [self folderKeysMatchingQualifier: nil - andSortOrderings: nil]; - // if (!folderKeys) - // { - // folderKeys = [self folderKeysMatchingQualifier: nil - // andSortOrderings: nil]; - // [folderKeys retain]; - // } - - // return folderKeys; -} - -- (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - if (qualifier) - [self errorWithFormat: @"qualifier is not used for folders"]; - if (sortOrderings) - [self errorWithFormat: @"sort orderings are not used for folders"]; - - return [sogoObject toManyRelationshipKeys]; -} - -- (NSArray *) activeMessageTables -{ - return [[MAPIStoreActiveTables activeTables] - activeTablesForFMID: [self objectId] - andType: MAPISTORE_MESSAGE_TABLE]; -} - -- (NSArray *) activeFAIMessageTables -{ - return [[MAPIStoreActiveTables activeTables] - activeTablesForFMID: [self objectId] - andType: MAPISTORE_FAI_TABLE]; -} - -- (void) _cleanupTableCaches: (enum mapistore_table_type) tableType -{ - NSArray *tables; - NSUInteger count, max; - - tables = [[MAPIStoreActiveTables activeTables] - activeTablesForFMID: [self objectId] - andType: tableType]; - max = [tables count]; - for (count = 0; count < max; count++) - [[tables objectAtIndex: count] cleanupCaches]; -} - -- (void) cleanupCaches -{ - [self _cleanupTableCaches: MAPISTORE_MESSAGE_TABLE]; - [self _cleanupTableCaches: MAPISTORE_FAI_TABLE]; - [self _cleanupTableCaches: MAPISTORE_FOLDER_TABLE]; - // [faiMessageKeys release]; - // faiMessageKeys = nil; - // [messageKeys release]; - // messageKeys = nil; - // [folderKeys release]; - // folderKeys = nil; -} - -- (enum mapistore_error) getPidTagParentFolderId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongLongValue (memCtx, [container objectId]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagFolderId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongLongValue (memCtx, [self objectId]); - - return MAPISTORE_SUCCESS; -} - -/* - Possible values are: - - 0x00000001 Modify - 0x00000002 Read - 0x00000004 Delete - 0x00000008 Create Hierarchy Table - 0x00000010 Create Contents Table - 0x00000020 Create Associated Contents Table -*/ -- (enum mapistore_error) getPidTagAccess: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t access = 0; - SOGoUser *ownerUser; - BOOL userIsOwner; - - ownerUser = [[self userContext] sogoUser]; - - userIsOwner = [[context activeUser] isEqual: ownerUser]; - if (userIsOwner || [self subscriberCanModifyMessages]) - access |= 0x01; - if (userIsOwner || [self subscriberCanReadMessages]) - access |= 0x02; - if (userIsOwner || [self subscriberCanDeleteMessages]) - access |= 0x04; - if ((userIsOwner || [self subscriberCanCreateSubFolders]) - && [self supportsSubFolders]) - access |= 0x08; - if (userIsOwner || [self subscriberCanCreateMessages]) - access |= 0x10; - if (userIsOwner) - access |= 0x20; - - *data = MAPILongValue (memCtx, access); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagRights: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t rights = 0; - SOGoUser *activeUser, *ownerUser; - - ownerUser = [[self userContext] sogoUser]; - activeUser = [context activeUser]; - - if ([activeUser isEqual: ownerUser]) - { - rights = RightsReadItems | RightsCreateItems | RightsEditOwn | RightsEditAll - | RightsDeleteOwn | RightsDeleteAll | RightsFolderOwner | RightsFolderContact | RoleNone; - if ([self supportsSubFolders]) - rights |= RightsCreateSubfolders; - } - else - { - NSArray *roles; - - roles = [[self aclFolder] aclsForUser: [activeUser login]]; - roles = [self expandRoles: roles]; - rights = [self exchangeRightsForRoles: roles]; - /* FreeBusySimple and FreeBusyDetailed does not apply here - [MS-OXCFOLD] Section 2.2.2.2.2.8 */ - rights &= ~RightsFreeBusySimple & ~RightsFreeBusyDetailed; - } - - *data = MAPILongValue (memCtx, rights); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAccessControlListData: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[NSData data] asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttributeHidden: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagAttributeSystem: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagAttributeReadOnly: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSubfolders: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPIBoolValue (memCtx, [self supportsSubFolders] && [[self folderKeys] count] > 0); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagFolderChildCount: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, [[self folderKeys] count]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagContentCount: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, [[self messageKeys] count]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagContentUnreadCount: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAssociatedContentCount: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, [[self faiMessageKeys] count]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagDeletedCountTotal: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* TODO */ - *data = MAPILongValue (memCtx, 0); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagLocalCommitTimeMax: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSDate *date; - - date = [self lastMessageModificationTime]; - if (date) - *data = [date asFileTimeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidTagDefaultPostMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPM.Note" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) 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]; -} - -- (enum mapistore_error) getProperty: (void **) data - withTag: (enum MAPITAGS) propTag - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - id value; - - 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; -} - -- (MAPIStoreMessage *) _createAssociatedMessage -{ - MAPIStoreMessage *newMessage; - SOGoMAPIDBMessage *dbObject; - NSString *newKey; - - newKey = [NSString stringWithFormat: @"%@.plist", - [SOGoObject globallyUniqueObjectId]]; - dbObject = [SOGoMAPIDBMessage objectWithName: newKey inContainer: dbFolder]; - [dbObject setObjectType: MAPIFAICacheObject]; - [dbObject setIsNew: YES]; - newMessage = [MAPIStoreFAIMessageK mapiStoreObjectWithSOGoObject: dbObject - inContainer: self]; - - return newMessage; -} - -- (MAPIStoreMessage *) createMessage: (BOOL) isAssociated -{ - MAPIStoreMessage *newMessage; - WOContext *woContext; - - [[self userContext] activate]; - - if (isAssociated) - newMessage = [self _createAssociatedMessage]; - else - newMessage = [self createMessage]; - /* 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]; - /* 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; -} - -- (enum mapistore_error) createFolder: (struct SRow *) aRow - withFID: (uint64_t) newFID - andKey: (NSString **) newKeyP -{ - [self errorWithFormat: @"new folders cannot be created in this context"]; - - return MAPISTORE_ERR_DENIED; -} - -/* helpers */ - -- (NSString *) url -{ - NSString *url; - - if (container) - url = [NSString stringWithFormat: @"%@/", [super url]]; - else - { - url = [[context url] absoluteString]; - if (![url hasSuffix: @"/"]) - url = [NSString stringWithFormat: @"%@/", url]; - } - - return url; -} - -- (MAPIStorePermissionsTable *) permissionsTable -{ - return [MAPIStorePermissionsTable tableForContainer: self]; -} - -- (NSArray *) permissionEntries -{ - NSMutableArray *permissionEntries; - MAPIStorePermissionEntry *entry; - NSArray *aclUsers; - uint64_t memberId, regularMemberId = 1; - NSUInteger count, max; - NSString *username, *defaultUserId; - SOGoFolder *aclFolder; - - aclFolder = [self aclFolder]; - - defaultUserId = [aclFolder defaultUserID]; - aclUsers = [aclFolder aclUsers]; - max = [aclUsers count]; - permissionEntries = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - username = [aclUsers objectAtIndex: count]; - if (![username hasPrefix: @"@"]) - { - if ([username isEqualToString: defaultUserId]) - memberId = 0; - else if ([username isEqualToString: @"anonymous"]) - memberId = ULLONG_MAX; - else - { - memberId = regularMemberId; - regularMemberId++; - } - entry = [MAPIStorePermissionEntry entryWithUserId: username - andMemberId: memberId - forFolder: self]; - [permissionEntries addObject: entry]; - } - } - - return permissionEntries; -} - -- (NSArray *) rolesForExchangeRights: (uint32_t) rights -{ - [self subclassResponsibility: _cmd]; - return nil; -} - -- (uint32_t) exchangeRightsForRoles: (NSArray *) roles -{ - [self subclassResponsibility: _cmd]; - return 0; -} - -- (NSString *) _usernameFromEntryId: (struct SBinary_short *) bin -{ - struct Binary_r bin32; - struct AddressBookEntryId *entryId; - NSString *username; - - if (bin && bin->cb) - { - bin32.cb = bin->cb; - bin32.lpb = bin->lpb; - - entryId = get_AddressBookEntryId (NULL, &bin32); - if (entryId) - { - username = MAPIStoreSamDBUserAttribute ([[self context] connectionInfo], - @"legacyExchangeDN", - [NSString stringWithUTF8String: entryId->X500DN], - @"sAMAccountName"); - } - else - username = nil; - talloc_free (entryId); - } - else - username = nil; - - return username; -} - -- (NSString *) _usernameFromMemberId: (uint64_t) memberId - inEntries: (NSArray *) entries -{ - NSString *username = nil; - NSUInteger count, max; - MAPIStorePermissionEntry *entry; - - if (memberId == 0) - username = [[self aclFolder] defaultUserID]; - else if (memberId == ULLONG_MAX) - username = @"anonymous"; - else - { - max = [entries count]; - for (count = 0; !username && count < max; count++) - { - entry = [entries objectAtIndex: count]; - if ([entry memberId] == memberId) - username = [entry userId]; - } - } - - return username; -} - -- (void) _emptyACL -{ - NSUInteger count, max; - NSArray *users; - SOGoFolder *aclFolder; - - aclFolder = [self aclFolder]; - - users = [[aclFolder aclUsers] copy]; - max = [users count]; - for (count = 0; count < max; count++) - [aclFolder removeUserFromAcls: [users objectAtIndex: count]]; - - [users release]; -} - -- (enum mapistore_error) modifyPermissions: (struct PermissionData *) permissions - withCount: (uint16_t) pcount - andFlags: (int8_t) flags -{ - NSUInteger count, propCount; - struct PermissionData *currentPermission; - struct mapi_SPropValue *mapiValue; - NSString *permissionUser; - NSArray *entries; - NSArray *permissionRoles; - BOOL reset, isAdd = NO, isDelete = NO, isModify = NO; - SOGoFolder *aclFolder; - SOGoUser *activeUser, *ownerUser; - - /* Check if we have permissions to modify the permissions. - See [MS-OXCPERM] Section 3.2.5.2 for details */ - ownerUser = [[self userContext] sogoUser]; - activeUser = [context activeUser]; - if (![activeUser isEqual: ownerUser]) - { - /* Check if we have FolderOwner right */ - NSArray *roles; - - roles = [[self aclFolder] aclsForUser: [activeUser login]]; - roles = [self expandRoles: roles]; // Not required - if (([self exchangeRightsForRoles: roles] & RightsFolderOwner) == 0) - return MAPISTORE_ERR_DENIED; - } - - aclFolder = [self aclFolder]; - - reset = ((flags & ModifyPerms_ReplaceRows) != 0); - if (reset) - [self _emptyACL]; - - entries = [self permissionEntries]; - - for (count = 0; count < pcount; count++) - { - currentPermission = permissions + count; - - permissionUser = nil; - permissionRoles = nil; - - if (currentPermission->PermissionDataFlags == ROW_ADD) - isAdd = YES; - else if (currentPermission->PermissionDataFlags == ROW_MODIFY) - isModify = YES; - else - isDelete = YES; - - for (propCount = 0; - propCount < currentPermission->lpProps.cValues; - propCount++) - { - mapiValue = currentPermission->lpProps.lpProps + propCount; - switch (mapiValue->ulPropTag) - { - case PR_ENTRYID: - if (isAdd) - permissionUser - = [self _usernameFromEntryId: &mapiValue->value.bin]; - break; - case PR_MEMBER_ID: - if (isModify || isDelete) - permissionUser = [self _usernameFromMemberId: mapiValue->value.d - inEntries: entries]; - break; - case PR_MEMBER_RIGHTS: - if (isAdd || isModify) - permissionRoles - = [self rolesForExchangeRights: mapiValue->value.l]; - break; - default: - if (mapiValue->ulPropTag != PR_MEMBER_NAME) - [self warnWithFormat: @"unhandled permission property: %.8x", - mapiValue->ulPropTag]; - } - } - - if (reset) - { - if (isAdd) - [self _modifyPermissionEntryForUser: permissionUser - withRoles: permissionRoles - isAddition: YES - withACLFolder: aclFolder]; - } - else - { - if (isAdd || currentPermission->PermissionDataFlags == ROW_MODIFY) - [self _modifyPermissionEntryForUser: permissionUser - withRoles: permissionRoles - isAddition: isAdd - withACLFolder: aclFolder]; - else if (currentPermission->PermissionDataFlags == ROW_REMOVE) - [aclFolder removeUserFromAcls: permissionUser]; - else - [self errorWithFormat: @"unhandled permission action flag: %d", - currentPermission->PermissionDataFlags]; - } - } - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) preloadMessageBodiesWithMIDs: (const struct UI8Array_r *) mids - ofTableType: (enum mapistore_table_type) tableType -{ - uint32_t count; - NSMutableArray *messageKeys; - MAPIStoreMapping *mapping; - NSString *messageURL, *messageKey; - - messageKeys = [NSMutableArray arrayWithCapacity: mids->cValues]; - - mapping = [self mapping]; - for (count = 0; count < mids->cValues; count++) - { - messageURL = [mapping urlFromID: mids->lpui8[count]]; - if (messageURL) - { - messageKey = [self childKeyFromURL: messageURL]; - if (messageKey) - [messageKeys addObject: messageKey]; - } - } - - return [self preloadMessageBodiesWithKeys: messageKeys - ofTableType: tableType]; -} - -- (enum mapistore_error) preloadMessageBodiesWithKeys: (NSArray *) keys - ofTableType: (enum mapistore_table_type) tableType -{ - return MAPISTORE_SUCCESS; -} - -- (uint64_t) objectId -{ - uint64_t objectId; - NSString *folderKey; - - if (container) - { - folderKey = [NSString stringWithFormat: @"%@/", - [sogoObject nameInContainer]]; - objectId = [container idForObjectWithKey: folderKey]; - } - else - objectId = [self idForObjectWithKey: nil]; - - return objectId; -} - -- (uint64_t) idForObjectWithKey: (NSString *) childKey -{ - return [[self context] idForObjectWithKey: childKey - inFolderURL: [self url]]; -} - -- (MAPIStoreFolder *) rootContainer -{ - /* Return the oldest ancestor, which does not have - container. If there is not container, it returns itself. - */ - if (container) - return [container rootContainer]; - else - return self; -} - -- (NSDate *) creationTime -{ - return [dbFolder creationDate]; -} - -- (NSDate *) lastModificationTime -{ - return [dbFolder lastModified]; -} - -/* subclasses */ - -- (MAPIStoreMessageTable *) messageTable -{ - return nil; -} - -- (NSArray *) messageKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum - andCN: (NSNumber **) cnNbrs - inTableType: (enum mapistore_table_type) tableType -{ - return nil; -} - -- (MAPIStoreMessage *) createMessage -{ - [self logWithFormat: @"ignored method: %s", __PRETTY_FUNCTION__]; - return nil; -} - -- (NSCalendarDate *) lastMessageModificationTime -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (BOOL) subscriberCanCreateMessages -{ - return NO; -} - -- (BOOL) subscriberCanModifyMessages -{ - return NO; -} - -- (BOOL) subscriberCanReadMessages -{ - return NO; -} - -- (BOOL) subscriberCanDeleteMessages -{ - return NO; -} - -- (BOOL) subscriberCanCreateSubFolders -{ - return NO; -} - -- (BOOL) supportsSubFolders -{ - return NO; -} - -@end diff --git a/OpenChange/MAPIStoreFolderTable.h b/OpenChange/MAPIStoreFolderTable.h deleted file mode 100644 index b584c6084..000000000 --- a/OpenChange/MAPIStoreFolderTable.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreFolderTable.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREFOLDERTABLE_H -#define MAPISTOREFOLDERTABLE_H - -#import "MAPIStoreTable.h" - -@interface MAPIStoreFolderTable : MAPIStoreTable -@end - -#endif /* MAPISTOREFOLDERTABLE_H */ diff --git a/OpenChange/MAPIStoreFolderTable.m b/OpenChange/MAPIStoreFolderTable.m deleted file mode 100644 index d76c9890e..000000000 --- a/OpenChange/MAPIStoreFolderTable.m +++ /dev/null @@ -1,118 +0,0 @@ -/* MAPIStoreFolderTable.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import - -#import "MAPIStoreFolder.h" -#import "MAPIStoreTypes.h" - -#import "MAPIStoreFolderTable.h" - -#undef DEBUG -#include -#include -#include - -@implementation MAPIStoreFolderTable - -- (id) init -{ - if ((self = [super init])) - { - tableType = MAPISTORE_FOLDER_TABLE; - } - - return self; -} - -- (NSArray *) childKeys -{ - if (!childKeys) - { - childKeys = [(MAPIStoreFolder *) - container folderKeysMatchingQualifier: nil - andSortOrderings: sortOrderings]; - [childKeys retain]; - } - - return childKeys; -} - -- (NSArray *) restrictedChildKeys -{ - NSArray *keys; - - /* FIXME: restrictions are ignored on folder tables */ - - if (!restrictedChildKeys) - { - if (restrictionState != MAPIRestrictionStateAlwaysTrue) - { - if (restrictionState == MAPIRestrictionStateNeedsEval) - keys = [(MAPIStoreFolder *) - container folderKeysMatchingQualifier: restriction - andSortOrderings: sortOrderings]; - else - keys = [NSArray array]; - } - else - keys = [self childKeys]; - - ASSIGN (restrictedChildKeys, keys); - } - - return restrictedChildKeys; -} - -- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState rc; - - switch ((uint32_t) res->ulPropTag) - { - /* HACK: we cheat here as we current have no mechanism for searching - folders based on PR_CHANGE_NUM, which is used by the oxcfxics - mechanism... */ - case PidTagChangeNumber: - rc = MAPIRestrictionStateAlwaysTrue; - break; - default: - rc = [super evaluatePropertyRestriction: res intoQualifier: qualifier]; - } - - return rc; -} - -- (id) lookupChild: (NSString *) childKey -{ - return [(MAPIStoreFolder *) container lookupFolder: childKey]; -} - -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property -{ - return nil; -} - -@end diff --git a/OpenChange/MAPIStoreGCSBaseContext.h b/OpenChange/MAPIStoreGCSBaseContext.h deleted file mode 100644 index 8d9e57f5d..000000000 --- a/OpenChange/MAPIStoreGCSBaseContext.h +++ /dev/null @@ -1,37 +0,0 @@ -/* MAPIStoreGCSBaseContext.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREGCSBASECONTEXT_H -#define MAPISTOREGCSBASECONTEXT_H - -#import "MAPIStoreContext.h" - -@class EOQualifier; - -@interface MAPIStoreGCSBaseContext : MAPIStoreContext - -+ (NSString *) folderNameSuffix; -+ (NSString *) getFolderDisplayName: (NSString *) sogoDisplayName; - -@end - -#endif /* MAPISTOREGCSBASECONTEXT_H */ diff --git a/OpenChange/MAPIStoreGCSBaseContext.m b/OpenChange/MAPIStoreGCSBaseContext.m deleted file mode 100644 index e0f06482d..000000000 --- a/OpenChange/MAPIStoreGCSBaseContext.m +++ /dev/null @@ -1,145 +0,0 @@ -/* MAPIStoreGCSBaseContext.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import - -#import -#import - -#import "MAPIApplication.h" -#import "MAPIStoreUserContext.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreGCSBaseContext.h" - -#undef DEBUG -#include -#include - -@implementation MAPIStoreGCSBaseContext - -+ (NSString *) MAPIModuleName -{ - return nil; -} - -+ (NSString *) folderNameSuffix -{ - return @""; -} - -+ (NSString *) getFolderDisplayName: (NSString *) sogoDisplayName -{ - NSString *suffix, *displayName; - - suffix = [self folderNameSuffix]; - if ([suffix length] > 0 && ![sogoDisplayName hasSuffix: suffix]) - displayName = [NSString stringWithFormat: @"%@ (%@)", - sogoDisplayName, suffix]; - else - displayName = sogoDisplayName; - - return displayName; -} - -+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName - withIndexing: (struct indexing_context *) indexing - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct mapistore_contexts_list *firstContext = NULL, *context; - NSString *moduleName, *baseUrl, *url, *nameInContainer, *displayName; - NSArray *subfolders; - MAPIStoreUserContext *userContext; - SOGoParentFolder *parentFolder; - NSUInteger count, max; - SOGoGCSFolder *currentFolder; - - moduleName = [self MAPIModuleName]; - if (moduleName) - { - userContext = [MAPIStoreUserContext userContextWithUsername: userName - andTDBIndexing: indexing]; - parentFolder = [[userContext rootFolders] objectForKey: moduleName]; - baseUrl = [NSString stringWithFormat: @"sogo://%@@%@/", - [userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"], - moduleName]; - - subfolders = [parentFolder subFolders]; - max = [subfolders count]; - for (count = 0; count < max; count++) - { - currentFolder = [subfolders objectAtIndex: count]; - if ([[currentFolder ownerInContext: nil] isEqualToString: userName]) - { - context = talloc_zero (memCtx, struct mapistore_contexts_list); - nameInContainer = [currentFolder nameInContainer]; - url = [NSString stringWithFormat: @"%@%@", baseUrl, nameInContainer]; - context->url = [url asUnicodeInMemCtx: context]; - displayName = [self getFolderDisplayName: [currentFolder displayName]]; - context->name = [displayName asUnicodeInMemCtx: context]; - context->main_folder = [nameInContainer isEqualToString: @"personal"]; - context->role = [self MAPIContextRole]; - context->tag = "tag"; - DLIST_ADD_END (firstContext, context, void); - } - } - } - - return firstContext; -} - -+ (NSString *) - createRootSecondaryFolderWithFID: (uint64_t) fid - andName: (NSString *) folderName - forUser: (NSString *) userName -{ - NSString *mapistoreURI, *nameInContainer, *moduleName; - MAPIStoreUserContext *userContext; - SOGoParentFolder *parentFolder; - - userContext = [MAPIStoreUserContext userContextWithUsername: userName - andTDBIndexing: NULL]; - moduleName = [self MAPIModuleName]; - parentFolder = [[userContext rootFolders] objectForKey: moduleName]; - nameInContainer = nil; - - if (![parentFolder newFolderWithName: folderName - nameInContainer: &nameInContainer]) - mapistoreURI = [NSString stringWithFormat: @"sogo://%@@%@/%@/", - [userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"], - moduleName, nameInContainer]; - else - mapistoreURI = nil; - - return mapistoreURI; -} - -- (id) rootSOGoFolder -{ - return [[userContext rootFolders] objectForKey: [isa MAPIModuleName]]; -} - -@end diff --git a/OpenChange/MAPIStoreGCSFolder.h b/OpenChange/MAPIStoreGCSFolder.h deleted file mode 100644 index de2b9692b..000000000 --- a/OpenChange/MAPIStoreGCSFolder.h +++ /dev/null @@ -1,64 +0,0 @@ -/* MAPIStoreGCSFolder.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREGCSFOLDER_H -#define MAPISTOREGCSFOLDER_H - -#import "MAPIStoreFolder.h" - -@class NSArray; -@class NSCalendarDate; -@class NSData; -@class NSMutableDictionary; -@class NSNumber; -@class NSString; - -@interface MAPIStoreGCSFolder : MAPIStoreFolder -{ - SOGoMAPIDBMessage *versionsMessage; - NSArray *activeUserRoles; - EOQualifier *componentQualifier; -} - -/* synchronisation */ -- (BOOL) synchroniseCache; -- (BOOL) synchroniseCacheFor: (NSString *) nameInContainer; -- (void) updateVersionsForMessageWithKey: (NSString *) messageKey - withChangeKey: (NSData *) oldChangeKey - andPredecessorChangeList: (NSData *) pcl; -- (NSNumber *) lastModifiedFromMessageChangeNumber: (NSString *) changeNumber; -- (NSString *) changeNumberForMessageWithKey: (NSString *) messageKey; -- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey; -- (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey; - -- (NSArray *) activeUserRoles; - -- (EOQualifier *) componentQualifier; -- (EOQualifier *) contentComponentQualifier; - -/* subclasses */ -- (EOQualifier *) aclQualifier; -- (NSString *) component; - -@end - -#endif /* MAPISTOREGCSFOLDER_H */ diff --git a/OpenChange/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m deleted file mode 100644 index 9b269df35..000000000 --- a/OpenChange/MAPIStoreGCSFolder.m +++ /dev/null @@ -1,893 +0,0 @@ -/* MAPIStoreGCSFolder.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreGCSBaseContext.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSData+MAPIStore.h" -#import "NSDate+MAPIStore.h" -#import "NSString+MAPIStore.h" -#import "SOGoMAPIDBMessage.h" - -#import "MAPIStoreGCSFolder.h" - -#undef DEBUG -#include -#include - -static Class NSNumberK; - -@implementation MAPIStoreGCSFolder - -+ (void) initialize -{ - NSNumberK = [NSNumber class]; -} - -- (id) initWithSOGoObject: (id) newSOGoObject - inContainer: (MAPIStoreObject *) newContainer -{ - if ((self = [super initWithSOGoObject: newSOGoObject inContainer: newContainer])) - { - activeUserRoles = nil; - } - - return self; -} - -- (void) setupVersionsMessage -{ - ASSIGN (versionsMessage, - [SOGoMAPIDBMessage objectWithName: @"versions.plist" - inContainer: dbFolder]); - [versionsMessage setObjectType: MAPIInternalCacheObject]; - [versionsMessage reloadIfNeeded]; -} - -- (void) dealloc -{ - [versionsMessage release]; - [activeUserRoles release]; - [componentQualifier release]; - [super dealloc]; -} - -- (enum mapistore_error) deleteFolder -{ - enum mapistore_error rc; - NSException *error; - NSString *name; - - name = [self nameInContainer]; - if ([name isEqualToString: @"personal"]) - rc = MAPISTORE_ERR_DENIED; - else - { - [[sogoObject container] removeSubFolder: name]; - error = [(SOGoGCSFolder *) sogoObject delete]; - if (error) - rc = MAPISTORE_ERROR; - else - { - if (![versionsMessage delete]) - rc = MAPISTORE_SUCCESS; - else - rc = MAPISTORE_ERROR; - } - } - - return (rc == MAPISTORE_SUCCESS) ? [super deleteFolder] : rc; -} - -- (void) setDisplayName: (NSString *) newDisplayName -{ - NSString *suffix, *fullSuffix; - Class cClass; - - cClass = [(MAPIStoreGCSBaseContext *) [self context] class]; - - /* if a suffix exists, we strip it from the final name */ - suffix = [cClass folderNameSuffix]; - if ([suffix length] > 0) - { - fullSuffix = [NSString stringWithFormat: @"(%@)", suffix]; - if ([newDisplayName hasSuffix: fullSuffix]) - { - newDisplayName = [newDisplayName substringToIndex: - [newDisplayName length] - - [fullSuffix length]]; - newDisplayName = [newDisplayName stringByTrimmingSpaces]; - } - } - - if (![[sogoObject displayName] isEqualToString: newDisplayName]) - [sogoObject renameTo: newDisplayName]; -} - -- (enum mapistore_error) getPidTagDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *displayName; - Class cClass; - - cClass = [(MAPIStoreGCSBaseContext *) [self context] class]; - displayName = [cClass getFolderDisplayName: [sogoObject displayName]]; - *data = [displayName asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (void) addProperties: (NSDictionary *) newProperties -{ - NSString *newDisplayName; - NSMutableDictionary *propsCopy; - NSNumber *key; - - key = MAPIPropertyKey (PR_DISPLAY_NAME_UNICODE); - newDisplayName = [newProperties objectForKey: key]; - if (newDisplayName) - { - [self setDisplayName: newDisplayName]; - propsCopy = [newProperties mutableCopy]; - [propsCopy removeObjectForKey: key]; - [propsCopy autorelease]; - newProperties = propsCopy; - } - - [super addProperties: newProperties]; -} - -- (NSArray *) messageKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - static NSArray *fields = nil; - SOGoUser *ownerUser; - NSArray *records; - NSMutableArray *qualifierArray; - EOQualifier *fetchQualifier, *aclQualifier; - GCSFolder *ocsFolder; - EOFetchSpecification *fs; - NSArray *keys; - - if (!fields) - fields = [[NSArray alloc] - initWithObjects: @"c_name", @"c_version", nil]; - - qualifierArray = [NSMutableArray new]; - ownerUser = [[self userContext] sogoUser]; - if (![[context activeUser] isEqual: ownerUser]) - { - aclQualifier = [self aclQualifier]; - if (aclQualifier) - [qualifierArray addObject: aclQualifier]; - } - [qualifierArray addObject: [self componentQualifier]]; - if (qualifier) - [qualifierArray addObject: qualifier]; - - fetchQualifier = [[EOAndQualifier alloc] - initWithQualifierArray: qualifierArray]; - - ocsFolder = [sogoObject ocsFolder]; - fs = [EOFetchSpecification - fetchSpecificationWithEntityName: [ocsFolder folderName] - qualifier: fetchQualifier - sortOrderings: sortOrderings]; - [fetchQualifier release]; - [qualifierArray release]; - records = [ocsFolder fetchFields: fields fetchSpecification: fs]; - keys = [records objectsForKey: @"c_name" - notFoundMarker: nil]; - - return keys; -} - -- (NSDate *) lastMessageModificationTime -{ - NSDate *value; - NSNumber *ti; - - [self synchroniseCache]; - - ti = [[versionsMessage properties] - objectForKey: @"SyncLastModificationDate"]; - if (ti) - value = [NSDate dateWithTimeIntervalSince1970: [ti doubleValue]]; - else - value = nil; - - return value; -} - -- (SOGoFolder *) aclFolder -{ - return (SOGoFolder *) sogoObject; -} - -/* synchronisation */ - -/* Tree -{ - SyncLastModseq = x; - SyncLastSynchronisationDate = x; ** not updated until something changed - Messages = { - MessageKey = { - Version = x; - Modseq = x; - Deleted = b; - ChangeKey = d; - PredecessorChangeList = { guid1 = globcnt1, guid2 ... }; - }; - ... - }; - VersionMapping = { - Version = last-modified; - ... - } -} - */ -- (void) _setChangeKey: (NSData *) changeKey - forMessageEntry: (NSMutableDictionary *) messageEntry -{ - struct XID *xid; - NSString *guid; - NSData *globCnt; - NSDictionary *changeKeyDict; - NSMutableDictionary *changeList; - - xid = [changeKey asXIDInMemCtx: NULL]; - guid = [NSString stringWithGUID: &xid->NameSpaceGuid]; - globCnt = [NSData dataWithBytes: xid->LocalId.data length: xid->LocalId.length]; - talloc_free (xid); - - /* 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"]; - if (!changeList) - { - changeList = [NSMutableDictionary new]; - [messageEntry setObject: changeList - forKey: @"PredecessorChangeList"]; - [changeList release]; - } - [changeList setObject: globCnt forKey: guid]; -} - -- (void) _updatePredecessorChangeList: (NSData *) predecessorChangeList - forMessageEntry: (NSMutableDictionary *) messageEntry - withOldChangeKey: (NSData *) oldChangeKey -{ - NSData *globCnt, *oldGlobCnt; - NSDictionary *changeKeyDict; - NSString *guid; - NSMutableDictionary *changeList; - struct SizedXid *sizedXIDList; - struct XID xid, *givenChangeKey; - TALLOC_CTX *localMemCtx; - uint32_t i, length; - - localMemCtx = talloc_new (NULL); - if (!localMemCtx) - { - [self errorWithFormat: @"No more memory"]; - return; - } - - if (predecessorChangeList) - { - sizedXIDList = [predecessorChangeList asSizedXidArrayInMemCtx: localMemCtx with: &length]; - - changeList = [messageEntry objectForKey: @"PredecessorChangeList"]; - if (!changeList) - { - changeList = [NSMutableDictionary new]; - [messageEntry setObject: changeList - forKey: @"PredecessorChangeList"]; - [changeList release]; - } - - if (sizedXIDList) { - for (i = 0; i < length; i++) - { - xid = sizedXIDList[i].XID; - guid = [NSString stringWithGUID: &xid.NameSpaceGuid]; - globCnt = [NSData dataWithBytes: xid.LocalId.data length: xid.LocalId.length]; - oldGlobCnt = [changeList objectForKey: guid]; - if (!oldGlobCnt || ([globCnt compare: oldGlobCnt] == NSOrderedDescending)) - [changeList setObject: globCnt forKey: guid]; - } - } - } - - if (oldChangeKey) - { - givenChangeKey = [oldChangeKey asXIDInMemCtx: localMemCtx]; - if (givenChangeKey) { - guid = [NSString stringWithGUID: &givenChangeKey->NameSpaceGuid]; - globCnt = [NSData dataWithBytes: givenChangeKey->LocalId.data length: givenChangeKey->LocalId.length]; - - changeKeyDict = [messageEntry objectForKey: @"ChangeKey"]; - if (!changeKeyDict || - ([guid isEqualToString: [changeKeyDict objectForKey: @"GUID"]] - && ([globCnt compare: [changeKeyDict objectForKey: @"LocalId"]] == NSOrderedDescending))) - { - /* The given change key is greater than current one stored in - metadata or it does not exist */ - [messageEntry setObject: [NSDictionary dictionaryWithObjectsAndKeys: guid, @"GUID", - globCnt, @"LocalId", - nil] - forKey: @"ChangeKey"]; - } - } - } - - talloc_free (localMemCtx); -} - -- (EOQualifier *) componentQualifier -{ - if (!componentQualifier) - componentQualifier - = [[EOKeyValueQualifier alloc] initWithKey: @"c_component" - operatorSelector: EOQualifierOperatorEqual - value: [self component]]; - - return componentQualifier; -} - -- (EOQualifier *) contentComponentQualifier -{ - EOQualifier *contentComponentQualifier; - NSString *likeString; - - likeString = [NSString stringWithFormat: @"%%BEGIN:%@%%", - [[self component] uppercaseString]]; - contentComponentQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_content" - operatorSelector: EOQualifierOperatorLike - value: likeString]; - [contentComponentQualifier autorelease]; - - return contentComponentQualifier; -} - -- (BOOL) synchroniseCache -{ - BOOL rc = YES; - uint64_t newChangeNum; - NSData *changeKey; - NSString *cName, *changeNumber; - NSNumber *ti, *lastModificationDate, *cVersion, *cLastModified, *cDeleted; - EOFetchSpecification *fs; - EOQualifier *searchQualifier, *fetchQualifier; - NSUInteger count, max; - NSArray *fetchResults, *changeNumbers; - NSMutableArray *keys, *modifiedEntries; - NSDictionary *result; - NSMutableDictionary *currentProperties, *messages, *mapping, *messageEntry; - NSCalendarDate *now; - GCSFolder *ocsFolder; - static NSArray *fields = nil; - static EOSortOrdering *sortOrdering = nil; - - /* NOTE: we are using NSString instance for "changeNumber" because - NSNumber proved to give very bad performances when used as NSDictionary - keys with GNUstep 1.22.1. The bug seems to be solved with 1.24 but many - distros still ship an older version. */ - - if (!fields) - fields = [[NSArray alloc] - initWithObjects: @"c_name", @"c_version", @"c_lastmodified", - @"c_deleted", nil]; - - if (!sortOrdering) - { - sortOrdering = [EOSortOrdering sortOrderingWithKey: @"c_lastmodified" - selector: EOCompareAscending]; - [sortOrdering retain]; - } - - [versionsMessage reloadIfNeeded]; - currentProperties = [versionsMessage properties]; - - lastModificationDate = [currentProperties objectForKey: @"SyncLastModificationDate"]; - if (lastModificationDate) - { - searchQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_lastmodified" - operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo - value: lastModificationDate]; - fetchQualifier = [[EOAndQualifier alloc] - initWithQualifiers: searchQualifier, - [self contentComponentQualifier], - nil]; - [fetchQualifier autorelease]; - [searchQualifier release]; - } - else - fetchQualifier = [self componentQualifier]; - - ocsFolder = [sogoObject ocsFolder]; - fs = [EOFetchSpecification - fetchSpecificationWithEntityName: [ocsFolder folderName] - qualifier: fetchQualifier - sortOrderings: [NSArray arrayWithObject: sortOrdering]]; - fetchResults = [ocsFolder fetchFields: fields - fetchSpecification: fs - ignoreDeleted: NO]; - max = [fetchResults count]; - if (max > 0) - { - messages = [currentProperties objectForKey: @"Messages"]; - if (!messages) - { - messages = [NSMutableDictionary new]; - [currentProperties setObject: messages forKey: @"Messages"]; - [messages release]; - } - mapping = [currentProperties objectForKey: @"VersionMapping"]; - if (!mapping) - { - mapping = [NSMutableDictionary new]; - [currentProperties setObject: mapping forKey: @"VersionMapping"]; - [mapping release]; - } - - keys = [NSMutableArray arrayWithCapacity: max]; - modifiedEntries = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - result = [fetchResults objectAtIndex: count]; - cName = [result objectForKey: @"c_name"]; - [keys addObject: cName]; - cDeleted = [result objectForKey: @"c_deleted"]; - if ([cDeleted isKindOfClass: NSNumberK] && [cDeleted intValue]) - cVersion = [NSNumber numberWithInt: -1]; - else - cVersion = [result objectForKey: @"c_version"]; - cLastModified = [result objectForKey: @"c_lastmodified"]; - - messageEntry = [messages objectForKey: cName]; - if (!messageEntry) - { - messageEntry = [NSMutableDictionary new]; - [messages setObject: messageEntry forKey: cName]; - [messageEntry release]; - } - - if (![[messageEntry objectForKey: @"c_version"] - isEqual: cVersion]) - { - [sogoObject removeChildRecordWithName: cName]; - - [modifiedEntries addObject: messageEntry]; - - [messageEntry setObject: cLastModified forKey: @"c_lastmodified"]; - [messageEntry setObject: cVersion forKey: @"c_version"]; - - if (!lastModificationDate - || ([lastModificationDate compare: cLastModified] - == NSOrderedAscending)) - lastModificationDate = cLastModified; - } - } - - /* make sure all returned objects have a corresponding mid */ - [self ensureIDsForChildKeys: keys]; - - max = [modifiedEntries count]; - if (max > 0) - { - changeNumbers = [[self context] getNewChangeNumbers: max]; - for (count = 0; count < max; count++) - { - messageEntry = [modifiedEntries objectAtIndex: count]; - - changeNumber = [changeNumbers objectAtIndex: count]; - cLastModified = [messageEntry objectForKey: @"c_lastmodified"]; - [mapping setObject: cLastModified forKey: changeNumber]; - [messageEntry setObject: changeNumber forKey: @"version"]; - - newChangeNum = [changeNumber unsignedLongLongValue]; - - // A GLOBCNT structure is a 6-byte global namespace counter, - // we strip the first 2 bytes. The first two bytes is the ReplicaId - changeKey = [self getReplicaKeyFromGlobCnt: newChangeNum >> 16]; - [self _setChangeKey: changeKey forMessageEntry: messageEntry]; - } - - now = [NSCalendarDate date]; - ti = [NSNumber numberWithDouble: [now timeIntervalSince1970]]; - [currentProperties setObject: ti - forKey: @"SyncLastSynchronisationDate"]; - [currentProperties setObject: lastModificationDate - forKey: @"SyncLastModificationDate"]; - [versionsMessage save]; - } - } - - return rc; -} - -- (BOOL) synchroniseCacheFor: (NSString *) nameInContainer -{ - /* Try to synchronise old messages in versions.plist cache using an - specific c_name. It returns a boolean indicating if the - synchronisation was carried out succesfully. - - It should be used as last resort, keeping synchroniseCache as the - main sync entry point. */ - - uint64_t changeNumber; - NSString *changeNumberStr; - NSData *changeKey; - NSNumber *cLastModified, *cDeleted, *cVersion; - EOFetchSpecification *fs; - EOQualifier *searchQualifier, *fetchQualifier; - NSArray *fetchResults; - NSDictionary *result; - NSMutableDictionary *currentProperties, *messages, *mapping, *messageEntry; - GCSFolder *ocsFolder; - static NSArray *fields; - - [versionsMessage reloadIfNeeded]; - currentProperties = [versionsMessage properties]; - - messages = [currentProperties objectForKey: @"Messages"]; - if (!messages) - { - messages = [NSMutableDictionary new]; - [currentProperties setObject: messages forKey: @"Messages"]; - [messages release]; - } - - messageEntry = [messages objectForKey: nameInContainer]; - if (!messageEntry) - { - /* Fetch the message by its name */ - if (!fields) - fields = [[NSArray alloc] - initWithObjects: @"c_name", @"c_version", @"c_lastmodified", - @"c_deleted", nil]; - - searchQualifier = [[EOKeyValueQualifier alloc] initWithKey: @"c_name" - operatorSelector: EOQualifierOperatorEqual - value: nameInContainer]; - fetchQualifier = [[EOAndQualifier alloc] - initWithQualifiers: searchQualifier, - [self contentComponentQualifier], - nil]; - [fetchQualifier autorelease]; - [searchQualifier release]; - - ocsFolder = [sogoObject ocsFolder]; - fs = [EOFetchSpecification - fetchSpecificationWithEntityName: [ocsFolder folderName] - qualifier: fetchQualifier - sortOrderings: nil]; - fetchResults = [ocsFolder fetchFields: fields - fetchSpecification: fs - ignoreDeleted: NO]; - - if ([fetchResults count] == 1) - { - result = [fetchResults objectAtIndex: 0]; - cLastModified = [result objectForKey: @"c_lastmodified"]; - cDeleted = [result objectForKey: @"c_deleted"]; - if ([cDeleted isKindOfClass: NSNumberK] && [cDeleted intValue]) - cVersion = [NSNumber numberWithInt: -1]; - else - cVersion = [result objectForKey: @"c_version"]; - - changeNumber = [[self context] getNewChangeNumber]; - changeNumberStr = [NSString stringWithUnsignedLongLong: changeNumber]; - - /* Create new message entry in Messages dict */ - messageEntry = [NSMutableDictionary new]; - [messages setObject: messageEntry forKey: nameInContainer]; - [messageEntry release]; - - /* Store cLastModified, cVersion and the change number */ - [messageEntry setObject: cLastModified forKey: @"c_lastmodified"]; - [messageEntry setObject: cVersion forKey: @"c_version"]; - [messageEntry setObject: changeNumberStr forKey: @"version"]; - - /* Store the change key */ - changeKey = [self getReplicaKeyFromGlobCnt: changeNumber >> 16]; - [self _setChangeKey: changeKey forMessageEntry: messageEntry]; - - /* Store the changeNumber -> cLastModified mapping */ - mapping = [currentProperties objectForKey: @"VersionMapping"]; - if (!mapping) - { - mapping = [NSMutableDictionary new]; - [currentProperties setObject: mapping forKey: @"VersionMapping"]; - [mapping release]; - } - [mapping setObject: cLastModified forKey: changeNumberStr]; - - /* Save the message */ - [versionsMessage save]; - return YES; - } - else - return NO; - } - - /* If message entry exists, then synchroniseCache did its job */ - return YES; -} - -- (void) updateVersionsForMessageWithKey: (NSString *) messageKey - withChangeKey: (NSData *) oldChangeKey - andPredecessorChangeList: (NSData *) pcl -{ - NSMutableDictionary *messages, *messageEntry; - - [self synchroniseCache]; - if (oldChangeKey || pcl) - { - messages = [[versionsMessage properties] objectForKey: @"Messages"]; - messageEntry = [messages objectForKey: messageKey]; - if (!messageEntry) - [NSException raise: @"MAPIStoreIOException" - format: @"no version record found for message '%@'", - messageKey]; - [self _updatePredecessorChangeList: pcl forMessageEntry: messageEntry - withOldChangeKey: oldChangeKey]; - [versionsMessage save]; - } -} - -- (NSNumber *) lastModifiedFromMessageChangeNumber: (NSString *) changeNumber -{ - NSDictionary *mapping; - NSNumber *lastModified; - - mapping = [[versionsMessage properties] objectForKey: @"VersionMapping"]; - lastModified = [mapping objectForKey: changeNumber]; - - return lastModified; -} - -- (NSString *) changeNumberForMessageWithKey: (NSString *) messageKey -{ - NSDictionary *messages; - NSString *changeNumber; - - messages = [[versionsMessage properties] objectForKey: @"Messages"]; - changeNumber = [[messages objectForKey: messageKey] - objectForKey: @"version"]; - - return changeNumber; -} - -- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey -{ - NSDictionary *messages, *changeKeyDict; - NSString *guid; - NSData *globCnt, *changeKey = nil; - - messages = [[versionsMessage properties] objectForKey: @"Messages"]; - changeKeyDict = [[messages objectForKey: messageKey] - objectForKey: @"ChangeKey"]; - if (changeKeyDict) - { - guid = [changeKeyDict objectForKey: @"GUID"]; - globCnt = [changeKeyDict objectForKey: @"LocalId"]; - changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; - } - - return changeKey; -} - -- (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey -{ - NSMutableData *list = nil; - NSDictionary *messages, *changeListDict; - NSArray *keys; - NSMutableArray *changeKeys; - NSUInteger count, max; - NSData *changeKey; - NSString *guid; - NSData *globCnt; - - messages = [[versionsMessage properties] objectForKey: @"Messages"]; - changeListDict = [[messages objectForKey: messageKey] - objectForKey: @"PredecessorChangeList"]; - if (changeListDict) - { - keys = [changeListDict allKeys]; - max = [keys count]; - - changeKeys = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - guid = [keys objectAtIndex: count]; - globCnt = [changeListDict objectForKey: guid]; - changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; - [changeKeys addObject: changeKey]; - } - [changeKeys sortUsingFunction: MAPIChangeKeyGUIDCompare - context: nil]; - - list = [NSMutableData data]; - for (count = 0; count < max; count++) - { - changeKey = [changeKeys objectAtIndex: count]; - [list appendUInt8: [changeKey length]]; - [list appendData: changeKey]; - } - } - - return list; -} - -- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum - andCN: (NSNumber **) cnNbr - inTableType: (uint8_t) tableType -{ - NSArray *deletedKeys, *deletedCNames, *records; - NSNumber *lastModified; - NSString *cName, *changeNumber; - NSDictionary *versionProperties, *messageEntry; - NSMutableDictionary *messages; - uint64_t maxChangeNum = changeNum, currentChangeNum; - EOAndQualifier *fetchQualifier; - EOKeyValueQualifier *cDeletedQualifier, *cLastModifiedQualifier; - EOFetchSpecification *fs; - GCSFolder *ocsFolder; - NSUInteger count, max; - - if (tableType == MAPISTORE_MESSAGE_TABLE) - { - deletedKeys = [NSMutableArray array]; - - changeNumber = [NSString stringWithUnsignedLongLong: changeNum]; - lastModified = [self lastModifiedFromMessageChangeNumber: changeNumber]; - if (lastModified) - { - versionProperties = [versionsMessage properties]; - messages = [versionProperties objectForKey: @"Messages"]; - - ocsFolder = [sogoObject ocsFolder]; - cLastModifiedQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_lastmodified" - operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo - value: lastModified]; - cDeletedQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_deleted" - operatorSelector: EOQualifierOperatorEqual - value: [NSNumber numberWithInt: 1]]; - fetchQualifier = [[EOAndQualifier alloc] initWithQualifiers: - cLastModifiedQualifier, - cDeletedQualifier, - nil]; - [fetchQualifier autorelease]; - [cLastModifiedQualifier release]; - [cDeletedQualifier release]; - - fs = [EOFetchSpecification - fetchSpecificationWithEntityName: [ocsFolder folderName] - qualifier: fetchQualifier - sortOrderings: nil]; - records = [ocsFolder - fetchFields: [NSArray arrayWithObject: @"c_name"] - fetchSpecification: fs - ignoreDeleted: NO]; - deletedCNames = [records objectsForKey: @"c_name" notFoundMarker: nil]; - max = [deletedCNames count]; - for (count = 0; count < max; count++) - { - cName = [deletedCNames objectAtIndex: count]; - [sogoObject removeChildRecordWithName: cName]; - messageEntry = [messages objectForKey: cName]; - if (messageEntry) - { - currentChangeNum - = [[messageEntry objectForKey: @"version"] - unsignedLongLongValue]; - if (MAPICNCompare (changeNum, currentChangeNum, NULL) - == NSOrderedAscending) - { - [(NSMutableArray *) deletedKeys addObject: cName]; - if (MAPICNCompare (maxChangeNum, currentChangeNum, NULL) - == NSOrderedAscending) - maxChangeNum = currentChangeNum; - } - } - } - if (maxChangeNum != changeNum) - *cnNbr = [NSNumber numberWithUnsignedLongLong: maxChangeNum]; - } - } - else - deletedKeys = [super getDeletedKeysFromChangeNumber: changeNum - andCN: cnNbr - inTableType: tableType]; - - return deletedKeys; -} - -- (NSArray *) activeUserRoles -{ - SOGoUser *activeUser; - WOContext *woContext; - - if (!activeUserRoles) - { - activeUser = [[self context] activeUser]; - woContext = [[self userContext] woContext]; - activeUserRoles = [activeUser rolesForObject: sogoObject - inContext: woContext]; - activeUserRoles = [self expandRoles: activeUserRoles]; - [activeUserRoles retain]; - } - - return activeUserRoles; -} - -- (BOOL) subscriberCanCreateMessages -{ - return [[self activeUserRoles] containsObject: SOGoRole_ObjectCreator]; -} - -- (BOOL) subscriberCanDeleteMessages -{ - return [[self activeUserRoles] containsObject: SOGoRole_ObjectEraser]; -} - -/* subclasses */ - -- (EOQualifier *) aclQualifier -{ - return nil; -} - -- (NSString *) component -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -@end diff --git a/OpenChange/MAPIStoreGCSMessage.h b/OpenChange/MAPIStoreGCSMessage.h deleted file mode 100644 index 2cfd480d0..000000000 --- a/OpenChange/MAPIStoreGCSMessage.h +++ /dev/null @@ -1,44 +0,0 @@ -/* MAPIStoreGCSMessage.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREGCSMESSAGE_H -#define MAPISTOREGCSMESSAGE_H - -#import - -#import "MAPIStoreMessage.h" - -@interface MAPIStoreGCSMessage : MAPIStoreMessage -{ -} - -/* subclass helpers */ - -/* Return the message original creator */ -- (NSString *) creator; -- (NSString *) owner; -- (SOGoUser *) ownerUser; -- (void) updateVersions; - -@end - -#endif /* MAPISTOREGCSMESSAGE_H */ diff --git a/OpenChange/MAPIStoreGCSMessage.m b/OpenChange/MAPIStoreGCSMessage.m deleted file mode 100644 index e1792fbdf..000000000 --- a/OpenChange/MAPIStoreGCSMessage.m +++ /dev/null @@ -1,264 +0,0 @@ -/* MAPIStoreGCSMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreContext.h" -#import "MAPIStoreGCSFolder.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSData+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreGCSMessage.h" - -#undef DEBUG -#include -#include - -@implementation MAPIStoreGCSMessage - -- (NSDate *) creationTime -{ - return [sogoObject creationDate]; -} - -- (NSDate *) lastModificationTime -{ - return [sogoObject lastModified]; -} - -- (enum mapistore_error) getPidTagCreatorName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSString *creator; - - creator = [self creator]; - if (creator) - { - *data = [creator asUnicodeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidTagChangeKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSData *changeKey; - MAPIStoreGCSFolder *parentFolder; - NSString *nameInContainer; - - if (isNew) - rc = MAPISTORE_ERR_NOT_FOUND; - else - { - parentFolder = (MAPIStoreGCSFolder *)[self container]; - nameInContainer = [self nameInContainer]; - changeKey = [parentFolder changeKeyForMessageWithKey: nameInContainer]; - if (!changeKey) - { - [parentFolder synchroniseCache]; - changeKey = [parentFolder changeKeyForMessageWithKey: nameInContainer]; - } - if (changeKey) - *data = [changeKey asBinaryInMemCtx: memCtx]; - else - { - [self warnWithFormat: @"No change key for %@ in folder %@", - nameInContainer, - [parentFolder url] - ]; - rc = MAPISTORE_ERR_NOT_FOUND; - } - } - - return rc; -} - -- (enum mapistore_error) getPidTagPredecessorChangeList: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSData *changeList; - MAPIStoreGCSFolder *parentFolder; - - if (isNew) - rc = MAPISTORE_ERR_NOT_FOUND; - else - { - parentFolder = (MAPIStoreGCSFolder *)[self container]; - changeList = [parentFolder - predecessorChangeListForMessageWithKey: [self nameInContainer]]; - if (!changeList) - { - [parentFolder synchroniseCache]; - changeList = [parentFolder - predecessorChangeListForMessageWithKey: [self nameInContainer]]; - } - if (!changeList) - abort (); - *data = [changeList asBinaryInMemCtx: memCtx]; - } - - return rc; -} - -- (uint64_t) objectVersion -{ - uint64_t version = ULLONG_MAX; - NSString *changeNumber; - BOOL synced; - - if (!isNew) - { - changeNumber = [(MAPIStoreGCSFolder *) container - changeNumberForMessageWithKey: [self nameInContainer]]; - if (!changeNumber) - { - [self warnWithFormat: @"attempting to get change number" - @" by synchronising folder..."]; - synced = [(MAPIStoreGCSFolder *) container synchroniseCache]; - if (synced) - { - changeNumber = [(MAPIStoreGCSFolder *) container - changeNumberForMessageWithKey: [self nameInContainer]]; - } - if (!changeNumber) - { - [self warnWithFormat: @"attempting to get change number" - @" by synchronising this specific message..."]; - synced = [(MAPIStoreGCSFolder *) container - synchroniseCacheFor: [self nameInContainer]]; - if (synced) - { - changeNumber = [(MAPIStoreGCSFolder *) container - changeNumberForMessageWithKey: [self nameInContainer]]; - } - if (!changeNumber) - { - [self errorWithFormat: @"still nothing. We crash!"]; - abort(); - } - } - } - version = [changeNumber unsignedLongLongValue] >> 16; - } - - return version; -} - -- (void) updateVersions -{ - /* Update ChangeKey and PredecessorChangeList on message's save */ - NSData *newChangeKey, *predecessorChangeList; - - newChangeKey = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)]; - predecessorChangeList = [properties objectForKey: MAPIPropertyKey (PR_PREDECESSOR_CHANGE_LIST)]; - - [(MAPIStoreGCSFolder *) container - updateVersionsForMessageWithKey: [self nameInContainer] - withChangeKey: newChangeKey - andPredecessorChangeList: predecessorChangeList]; -} - -//---------------------- -// Sharing -//---------------------- - -- (NSString *) creator -{ - return [self owner]; -} - -- (NSString *) owner -{ - return [sogoObject ownerInContext: nil]; -} - -- (SOGoUser *) ownerUser -{ - NSString *ownerName; - SOGoUser *owner = nil; - - ownerName = [self owner]; - if ([ownerName length] != 0) - owner = [SOGoUser userWithLogin: ownerName]; - - return owner; -} - -- (BOOL) subscriberCanModifyMessage -{ - BOOL rc; - NSArray *roles; - - roles = [self activeUserRoles]; - - if (isNew) - rc = [roles containsObject: SOGoRole_ObjectCreator]; - else - rc = [roles containsObject: SOGoRole_ObjectEditor]; - - /* Check if the message is owned and it has permission to edit it */ - if (!rc && [roles containsObject: MAPIStoreRightEditOwn]) - rc = [[[container context] activeUser] isEqual: [self ownerUser]]; - - return rc; -} - -- (BOOL) subscriberCanDeleteMessage -{ - BOOL rc; - NSArray *roles; - - roles = [self activeUserRoles]; - rc = [roles containsObject: SOGoRole_ObjectEraser]; - - /* Check if the message is owned and it has permission to delete it */ - if (!rc && [roles containsObject: MAPIStoreRightDeleteOwn]) - { - NSString *currentUser; - - currentUser = [[container context] activeUser]; - rc = [currentUser isEqual: [self ownerUser]]; - } - - return rc; -} - -@end diff --git a/OpenChange/MAPIStoreGCSMessageTable.h b/OpenChange/MAPIStoreGCSMessageTable.h deleted file mode 100644 index 72190c221..000000000 --- a/OpenChange/MAPIStoreGCSMessageTable.h +++ /dev/null @@ -1,36 +0,0 @@ -/* MAPIStoreGCSMessageTable.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREGCSMESSAGETABLE_H -#define MAPISTOREGCSMESSAGETABLE_H - -#import "MAPIStoreMessageTable.h" - -@class EOQualifier; - -@interface MAPIStoreGCSMessageTable : MAPIStoreMessageTable - -- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property; - -@end - -#endif /* MAPISTOREGCSMESSAGETABLE_H */ diff --git a/OpenChange/MAPIStoreGCSMessageTable.m b/OpenChange/MAPIStoreGCSMessageTable.m deleted file mode 100644 index 0dac1fff9..000000000 --- a/OpenChange/MAPIStoreGCSMessageTable.m +++ /dev/null @@ -1,260 +0,0 @@ -/* MAPIStoreGCSMessageTable.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import - -#import -#import - -#import -#import -#import -#import - -#import -#import - -#import "MAPIStoreTypes.h" -#import "MAPIStoreGCSFolder.h" -#import "MAPIStoreGCSMessageTable.h" - -#undef DEBUG -#include - -@implementation MAPIStoreGCSMessageTable - -- (void) cleanupCaches -{ - [(MAPIStoreGCSFolder *) container synchroniseCache]; - [super cleanupCaches]; -} - -- (struct mapi_SPropertyRestriction *) _fixedDatePropertyRestriction: (struct mapi_SPropertyRestriction *) res - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct mapi_SPropertyRestriction *translatedRes; - NSCalendarDate *dateValue; - int32_t longDate; - - translatedRes = talloc (memCtx, struct mapi_SPropertyRestriction); - translatedRes->ulPropTag = (res->ulPropTag & 0xffff0000) | PT_LONG; - translatedRes->relop = res->relop; - dateValue = NSObjectFromMAPISPropValue (&res->lpProp); - longDate = (int32_t) [dateValue timeIntervalSince1970]; - translatedRes->lpProp.ulPropTag = translatedRes->ulPropTag; - translatedRes->lpProp.value.l = longDate; - - return translatedRes; -} - -- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - static SEL operators[] = { EOQualifierOperatorLessThan, - EOQualifierOperatorLessThanOrEqualTo, - EOQualifierOperatorGreaterThan, - EOQualifierOperatorGreaterThanOrEqualTo, - EOQualifierOperatorEqual, - EOQualifierOperatorNotEqual, - EOQualifierOperatorContains }; - SEL operator; - id value; - NSString *property; - NSNumber *lastModified; - MAPIRestrictionState rc; - TALLOC_CTX *memCtx = NULL; - - if (res->ulPropTag == PidTagChangeNumber) - { - NSString *changeNumber; - - value = NSObjectFromMAPISPropValue (&res->lpProp); - changeNumber = [NSString stringWithUnsignedLongLong: [(NSNumber *)value unsignedLongLongValue]]; - lastModified = [(MAPIStoreGCSFolder *) - container lastModifiedFromMessageChangeNumber: changeNumber]; - //[self logWithFormat: @"change number from oxcfxics: %.16lx", [value unsignedLongLongValue]]; - //[self logWithFormat: @" c_lastmodified: %@", lastModified]; - if (lastModified) - { - SEL operator; - - operator = [self operatorFromRestrictionOperator: res->relop]; - *qualifier = [[EOKeyValueQualifier alloc] initWithKey: @"c_lastmodified" - operatorSelector: operator - value: lastModified]; - [*qualifier autorelease]; - rc = MAPIRestrictionStateNeedsEval; - } - else - { - [self logWithFormat: @"No last modified found for: 0x%.16"PRIx64". Then no restriction applied", - [value unsignedLongLongValue]]; - rc = MAPIRestrictionStateAlwaysTrue; - } - } - else - { - property = [self backendIdentifierForProperty: res->ulPropTag]; - if (property) - { - if (res->relop < 7) - operator = operators[res->relop]; - else - { - operator = NULL; - [NSException raise: @"MAPIStoreRestrictionException" - format: @"unhandled operator type number %d", res->relop]; - } - - if ((res->ulPropTag & 0xffff) == PT_SYSTIME) - { - memCtx = talloc_zero (NULL, TALLOC_CTX); - res = [self _fixedDatePropertyRestriction: res - inMemCtx: memCtx]; - } - - value = NSObjectFromMAPISPropValue (&res->lpProp); - if ((res->ulPropTag & 0xffff) == PT_UNICODE) - { - property = [NSString stringWithFormat: @"UPPER(%@)", property]; - value = [value uppercaseString]; - } - - *qualifier = [[EOKeyValueQualifier alloc] initWithKey: property - operatorSelector: operator - value: value]; - [*qualifier autorelease]; - if (memCtx) - talloc_free (memCtx); - - rc = MAPIRestrictionStateNeedsEval; - } - else - { - [self warnUnhandledProperty: res->ulPropTag - inFunction: __FUNCTION__]; - rc = MAPIRestrictionStateAlwaysFalse; - } - } - - return rc; -} - -/* sorting */ - -- (EOSortOrdering *) _sortOrderingFromSortOrder: (struct SSortOrder *) sortOrder -{ - EOSortOrdering *newSortOrdering = nil; - NSString *sortIdentifier; - SEL orderSelector = NULL; - const char *propName; - - sortIdentifier = [self sortIdentifierForProperty: sortOrder->ulPropTag]; - if (sortIdentifier) - { - if ((sortOrder->ulPropTag & 0xffff) == PT_UNICODE - || (sortOrder->ulPropTag & 0xffff) == PT_STRING8) - { - if (sortOrder->ulOrder == TABLE_SORT_ASCEND) - orderSelector = EOCompareCaseInsensitiveAscending; - else if (sortOrder->ulOrder == TABLE_SORT_DESCEND) - orderSelector = EOCompareCaseInsensitiveDescending; - else if (sortOrder->ulOrder == TABLE_SORT_MAXIMUM_CATEGORY) - { - orderSelector = EOCompareCaseInsensitiveAscending; - [self errorWithFormat: - @"TABLE_SORT_MAXIMUM_CATEGORY is not handled"]; - } - } - else - { - if (sortOrder->ulOrder == TABLE_SORT_ASCEND) - orderSelector = EOCompareAscending; - else if (sortOrder->ulOrder == TABLE_SORT_DESCEND) - orderSelector = EOCompareDescending; - else if (sortOrder->ulOrder == TABLE_SORT_MAXIMUM_CATEGORY) - { - orderSelector = EOCompareAscending; - [self errorWithFormat: - @"TABLE_SORT_MAXIMUM_CATEGORY is not handled"]; - } - } - if (orderSelector) - newSortOrdering = [EOSortOrdering sortOrderingWithKey: sortIdentifier - selector: orderSelector]; - } - else - { - propName = get_proptag_name (sortOrder->ulPropTag); - if (!propName) - propName = ""; - [self errorWithFormat: - @"sort unhandled for property: %s (0x%.8x)", - propName, sortOrder->ulPropTag]; - } - - return newSortOrdering; -} - -- (void) setSortOrder: (const struct SSortOrderSet *) set -{ - NSMutableArray *newSortOrderings; - EOSortOrdering *sortOrdering; - uint16_t count; - - if (set) - { - newSortOrderings = [NSMutableArray arrayWithCapacity: set->cSorts]; - - /* TODO: */ - if (set->cCategories > 0) - [self errorWithFormat: @"we don't handle sort categories yet"]; - - for (count = 0; count < set->cSorts; count++) - { - sortOrdering = [self _sortOrderingFromSortOrder: set->aSort + count]; - if (sortOrdering) - [newSortOrderings addObject: sortOrdering]; - } - } - else - newSortOrderings = nil; - - ASSIGN (sortOrderings, newSortOrderings); - [self cleanupCaches]; - - [self logWithFormat: @"new sort orderings: %@", sortOrderings]; -} - -/* subclasses */ -- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -@end diff --git a/OpenChange/MAPIStoreMIME.h b/OpenChange/MAPIStoreMIME.h deleted file mode 100644 index eb2d2a6b2..000000000 --- a/OpenChange/MAPIStoreMIME.h +++ /dev/null @@ -1,37 +0,0 @@ -/* MAPIStoreMIME.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREMIME_H -#define MAPISTOREMIME_H - -@interface MAPIStoreMIME : NSObject -{ - NSMutableDictionary *mimeDict; -} - -+ (id) sharedMAPIStoreMIME; - -- (NSString *) mimeTypeForExtension: (NSString *) extension; - -@end - -#endif /* MAPISTOREMIME_H */ diff --git a/OpenChange/MAPIStoreMIME.m b/OpenChange/MAPIStoreMIME.m deleted file mode 100644 index 712cc88bc..000000000 --- a/OpenChange/MAPIStoreMIME.m +++ /dev/null @@ -1,154 +0,0 @@ -/* MAPIStoreMIME.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import - -#import "MAPIStoreMIME.h" - -/* Seems common to all distros ? */ -#define MAPIStoreMIMEFile @"/etc/mime.types" - -@implementation MAPIStoreMIME - -+ (id) sharedMAPIStoreMIME -{ - static MAPIStoreMIME *sharedInstance = nil; - - if (!sharedInstance) - sharedInstance = [self new]; - - return sharedInstance; -} - -- (void) _parseLine: (const char *) line - withLength: (NSUInteger) length -{ - NSUInteger count = 0, lastWord = 0; - NSString *mimeType = nil, *word; - NSData *wordData; - BOOL comment = NO; - - while (count < length && !comment) - { - while (count < length - && (line[count] == ' ' || line[count] == '\t')) - count++; - lastWord = count; - while (count < length - && line[count] != ' ' && line[count] != '\t' - && !comment) - { - if (line[count] == '#') - comment = YES; - else - count++; - } - if (count > lastWord) - { - wordData = [NSData dataWithBytes: line + lastWord - length: count - lastWord]; - word = [[NSString alloc] initWithData: wordData - encoding: NSASCIIStringEncoding]; - if (word) - { - if (mimeType) - { - [mimeDict setObject: mimeType forKey: word]; - [word release]; - } - else - mimeType = word; - } - } - } - - [mimeType release]; -} - -- (void) _parseContent: (NSData *) content -{ - const char *data; - NSUInteger lineStart = 0, bytesRead = 0, max; - - data = [content bytes]; - max = [content length]; - bytesRead = 0; - lineStart = 0; - - while (bytesRead < max) - { - if (data[bytesRead] == '\n') - { - [self _parseLine: data + lineStart withLength: bytesRead - lineStart]; - lineStart = bytesRead + 1; - } - else if (data[bytesRead] == '\r') - { - [self _parseLine: data + lineStart withLength: bytesRead - lineStart]; - if (bytesRead < (max - 1) && data[bytesRead] == '\n') - lineStart = bytesRead + 2; - else - lineStart = bytesRead + 1; - } - bytesRead++; - } - - if (bytesRead > (lineStart + 1)) - [self _parseLine: data + lineStart withLength: bytesRead - lineStart]; -} - -- (void) _readMIMEFile -{ - NSFileHandle *inH; - NSData *content; - - inH = [NSFileHandle fileHandleForReadingAtPath: MAPIStoreMIMEFile]; - content = [inH readDataToEndOfFile]; - [self _parseContent: content]; -} - -- (id) init -{ - if ((self = [super init])) - { - mimeDict = [NSMutableDictionary new]; - [self _readMIMEFile]; - } - - return self; -} - -- (void) dealloc -{ - [mimeDict release]; - [super dealloc]; -} - -- (NSString *) mimeTypeForExtension: (NSString *) extension -{ - return [mimeDict objectForKey: [extension lowercaseString]]; -} - -@end diff --git a/OpenChange/MAPIStoreMailAttachment.h b/OpenChange/MAPIStoreMailAttachment.h deleted file mode 100644 index b04b197ab..000000000 --- a/OpenChange/MAPIStoreMailAttachment.h +++ /dev/null @@ -1,41 +0,0 @@ -/* MAPIStoreMailAttachment.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREMAILATTACHMENT_H -#define MAPISTOREMAILATTACHMENT_H - -#import "MAPIStoreAttachment.h" - -@class NSDictionary; - -@interface MAPIStoreMailAttachment : MAPIStoreAttachment -{ - NSDictionary *bodyInfo; - SOGoMailBodyPart *bodyPart; -} - -- (void) setBodyInfo: (NSDictionary *) newBodyInfo; -- (void) setBodyPart: (SOGoMailBodyPart *) newBodyPart; - -@end - -#endif /* MAPISTOREMAILATTACHMENT_H */ diff --git a/OpenChange/MAPIStoreMailAttachment.m b/OpenChange/MAPIStoreMailAttachment.m deleted file mode 100644 index 17520202b..000000000 --- a/OpenChange/MAPIStoreMailAttachment.m +++ /dev/null @@ -1,204 +0,0 @@ -/* MAPIStoreMailAttachment.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreTypes.h" -#import "MAPIStoreMailMessage.h" -#import "NSData+MAPIStore.h" -#import "NSDate+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreMailAttachment.h" - -#undef DEBUG -#include -#include -#include -#include - -@implementation MAPIStoreMailAttachment - -- (id) init -{ - if ((self = [super init])) - { - bodyInfo = nil; - bodyPart = nil; - } - - return self; -} - -- (void) dealloc -{ - [bodyInfo release]; - [bodyPart release]; - [super dealloc]; -} - -- (void) setBodyInfo: (NSDictionary *) newBodyInfo -{ - ASSIGN (bodyInfo, newBodyInfo); -} - -- (void) setBodyPart: (SOGoMailBodyPart *) newBodyPart -{ - ASSIGN (bodyPart, newBodyPart); -} - -- (enum mapistore_error) getPidTagAttachMethod: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0x00000001); // afByValue - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachTag: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[self mimeAttachTag] asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachSize: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t longValue; - - longValue = [[bodyInfo objectForKey: @"size"] longValue]; - *data = MAPILongValue (memCtx, longValue); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagRecordKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - static char recordBytes[] = {0xd9, 0xd8, 0x11, 0xa3, 0xe2, 0x90, 0x18, 0x41, - 0x9e, 0x04, 0x58, 0x46, 0x9d, 0x6d, 0x1b, - 0x68}; - - *data = [[NSData dataWithBytes: recordBytes length: 16] - asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (NSString *) _fileName -{ - return [bodyInfo filename]; -} - -- (enum mapistore_error) getPidTagAttachLongFilename: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[self _fileName] asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachFilename: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *fileName, *baseName, *ext; - - fileName = [self _fileName]; - baseName = [fileName stringByDeletingPathExtension]; - if ([baseName length] > 8) - baseName = [baseName substringToIndex: 8]; - - ext = [fileName pathExtension]; - if ([ext length] > 3) - ext = [ext substringToIndex: 3]; - fileName = [NSString stringWithFormat: @"%@.%@", baseName, ext]; - - *data = [fileName asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *fileName; - - fileName = [self _fileName]; - if ([fileName isEqualToString: @"sharing_metadata.xml"]) - /* Required to disallow user from seeing the attachment by default */ - *data = [@"sharing_metadata.xml" asUnicodeInMemCtx: memCtx]; - else - *data = [[bodyInfo objectForKey: @"description"] - asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachContentId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[bodyInfo objectForKey: @"bodyId"] - asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachMimeTag: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *mimeTag, *fileName; - - fileName = [self _fileName]; - if ([fileName isEqualToString: @"sharing_metadata.xml"]) - /* Required by [MS-OXWSMSHR] Section 3.1.1 */ - mimeTag = [NSString stringWithFormat: @"application/x-sharing-metadata-xml"]; - else - mimeTag = [NSString stringWithFormat: @"%@/%@", - [bodyInfo objectForKey: @"type"], - [bodyInfo objectForKey: @"subtype"]]; - - *data = [[mimeTag lowercaseString] asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAttachDataBinary: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[bodyPart fetchBLOBWithPeek: YES] asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -@end diff --git a/OpenChange/MAPIStoreMailContext.h b/OpenChange/MAPIStoreMailContext.h deleted file mode 100644 index 9e8371714..000000000 --- a/OpenChange/MAPIStoreMailContext.h +++ /dev/null @@ -1,37 +0,0 @@ -/* MAPIStoreMailContext.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREMAILCONTEXT_H -#define MAPISTOREMAILCONTEXT_H - -#import "MAPIStoreContext.h" - -@interface MAPIStoreMailContext : MAPIStoreContext - -- (void) updateURLWithFolderName: (NSString *) newFolderName; - -@end - -@interface MAPIStoreOutboxContext : MAPIStoreMailContext -@end - -#endif /* MAPISTOREMAILCONTEXT_H */ diff --git a/OpenChange/MAPIStoreMailContext.m b/OpenChange/MAPIStoreMailContext.m deleted file mode 100644 index c1f39565f..000000000 --- a/OpenChange/MAPIStoreMailContext.m +++ /dev/null @@ -1,312 +0,0 @@ -/* MAPIStoreMailContext.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreMailFolder.h" -#import "MAPIStoreUserContext.h" -#import "NSString+MAPIStore.h" - -#import -#import "MAPIApplication.h" -#import "MAPIStoreMailContext.h" - -#include -#undef DEBUG -#include - -static Class MAPIStoreMailFolderK, MAPIStoreOutboxFolderK; - -@implementation MAPIStoreMailContext - -+ (void) initialize -{ - MAPIStoreMailFolderK = [MAPIStoreMailFolder class]; - MAPIStoreOutboxFolderK = [MAPIStoreOutboxFolder class]; -} - -+ (NSString *) MAPIModuleName -{ - return @"mail"; -} - -+ (enum mapistore_context_role) MAPIContextRole -{ - return MAPISTORE_MAIL_ROLE; -} - -static inline NSString * -MakeDisplayFolderName (NSString *folderName) -{ - NSArray *parts; - NSString *lastFolder; - NSUInteger max; - - parts = [folderName componentsSeparatedByString: @"/"]; - max = [parts count]; - if (max > 1) - { - lastFolder = [parts objectAtIndex: max - 1]; - if ([lastFolder length] == 0) - lastFolder = [parts objectAtIndex: max - 2]; - } - else - lastFolder = folderName; - - return [[lastFolder substringFromIndex: 6] fromCSSIdentifier]; -} - -+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName - withIndexing: (struct indexing_context *) indexing - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct mapistore_contexts_list *firstContext = NULL, *context; - NSString *urlBase, *stringData, *currentName, *realName, *inboxName, *draftsName, *sentName, *trashName; - NSArray *unprefixedFolders; - NSMutableArray *secondaryFolders; - enum mapistore_context_role role[] = {MAPISTORE_MAIL_ROLE, - MAPISTORE_DRAFTS_ROLE, - MAPISTORE_SENTITEMS_ROLE}; - NSString *folderName[3]; - NSUInteger count, max; - SOGoMailAccount *accountFolder; - MAPIStoreUserContext *userContext; - WOContext *woContext; - - userContext = [MAPIStoreUserContext userContextWithUsername: userName - andTDBIndexing: indexing]; - accountFolder = [[userContext rootFolders] objectForKey: @"mail"]; - woContext = [userContext woContext]; - - inboxName = @"folderINBOX"; - folderName[0] = inboxName; - - unprefixedFolders = [[accountFolder draftsFolderNameInContext: woContext] - componentsSeparatedByString: @"/"]; - draftsName = [NSString stringWithFormat: @"folder%@", - [unprefixedFolders componentsJoinedByString: @"/folder"]]; - folderName[1] = draftsName; - - unprefixedFolders = [[accountFolder sentFolderNameInContext: woContext] - componentsSeparatedByString: @"/"]; - sentName = [NSString stringWithFormat: @"folder%@", - [unprefixedFolders componentsJoinedByString: @"/folder"]]; - folderName[2] = sentName; - - /* Note: trash is not used as a mail folder, since "Deleted Items" makes use of - the fallback context */ - unprefixedFolders = [[accountFolder trashFolderNameInContext: woContext] - componentsSeparatedByString: @"/"]; - trashName = [NSString stringWithFormat: @"folder%@", - [unprefixedFolders componentsJoinedByString: @"/folder"]]; - - urlBase = [NSString stringWithFormat: @"sogo://%@:%@@mail/", - [userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"], - [userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"]]; - for (count = 0; count < 3; count++) - { - context = talloc_zero (memCtx, struct mapistore_contexts_list); - stringData = [NSString stringWithFormat: @"%@%@", urlBase, - [folderName[count] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; - context->url = [stringData asUnicodeInMemCtx: context]; - /* remove "folder" prefix */ - stringData = MakeDisplayFolderName (folderName[count]); - context->name = [stringData asUnicodeInMemCtx: context]; - context->main_folder = true; - context->role = role[count]; - context->tag = "tag"; - DLIST_ADD_END (firstContext, context, void); - } - - /* FIXME: Flush any cache before retrieving the hierarchy */ - [accountFolder flushMailCaches]; - - secondaryFolders = [[accountFolder toManyRelationshipKeysWithNamespaces: NO] - mutableCopy]; - [secondaryFolders autorelease]; - [secondaryFolders removeObject: inboxName]; - [secondaryFolders removeObject: draftsName]; - [secondaryFolders removeObject: sentName]; - [secondaryFolders removeObject: trashName]; - max = [secondaryFolders count]; - for (count = 0; count < max; count++) - { - context = talloc_zero (memCtx, struct mapistore_contexts_list); - // secondaryFolders has the names (1) Imap4Encoded ,(2) asCSSIdentifier and (3) "folder"-prefixed - // e.g.: folderProbl&AOg-mes_SP_de_SP_synchronisation - currentName = [secondaryFolders objectAtIndex: count]; - // To get the real name we have to revert that (applying the decode functions - // in reverse order) - // e.g.: Problèmes de synchronisation - realName = [[[currentName substringFromIndex: 6] - fromCSSIdentifier] - stringByDecodingImap4FolderName]; - // And finally to represent that as URI we have to (1) asCSSIdentifier, - // (2) Imap4Encode (3) AddPercentEscapes and (4) add the "folder" prefix - // e.g.: folderProbl&AOg-mes_SP_de_SP_synchronisation - // In the example there are no percent escapes added because is already ok - stringData = [[[realName asCSSIdentifier] - stringByEncodingImap4FolderName] - stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; - stringData = [NSString stringWithFormat: @"folder%@", stringData]; - context->url = [[NSString stringWithFormat: @"%@%@", urlBase, stringData] asUnicodeInMemCtx: context]; - context->name = [realName asUnicodeInMemCtx: context]; - context->main_folder = false; - context->role = MAPISTORE_MAIL_ROLE; - context->tag = "tag"; - DLIST_ADD_END (firstContext, context, void); - } - - return firstContext; -} - -+ (NSString *) - createRootSecondaryFolderWithFID: (uint64_t) fid - andName: (NSString *) newFolderName - forUser: (NSString *) userName -{ - NSString *mapistoreURI, *folderName; - MAPIStoreUserContext *userContext; - SOGoMailAccount *accountFolder; - SOGoMailFolder *newFolder; - - userContext = [MAPIStoreUserContext userContextWithUsername: userName - andTDBIndexing: NULL]; - accountFolder = [[userContext rootFolders] objectForKey: @"mail"]; - folderName = [NSString stringWithFormat: @"folder%@", - [[newFolderName stringByEncodingImap4FolderName] asCSSIdentifier]]; - newFolder = [SOGoMailFolder objectWithName: folderName - inContainer: accountFolder]; - if ([newFolder create]) - mapistoreURI = [NSString stringWithFormat: @"sogo://%@:%@@mail/%@/", - [userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"], - [userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"], - [folderName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; - else - mapistoreURI = nil; - - return mapistoreURI; -} - -- (Class) MAPIStoreFolderClass -{ - return MAPIStoreMailFolderK; -} - -- (id) rootSOGoFolder -{ - 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 - -+ (NSString *) MAPIModuleName -{ - return @"outbox"; -} - -+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName - withIndexing: (struct indexing_context *) indexing - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct mapistore_contexts_list *context; - NSString *url, *folderName; - NSArray *unprefixedFolders; - SOGoMailAccount *accountFolder; - MAPIStoreUserContext *userContext; - WOContext *woContext; - - userContext = [MAPIStoreUserContext userContextWithUsername: userName - andTDBIndexing: indexing]; - accountFolder = [[userContext rootFolders] objectForKey: @"mail"]; - woContext = [userContext woContext]; - - unprefixedFolders = [[accountFolder draftsFolderNameInContext: woContext] - componentsSeparatedByString: @"/"]; - folderName = [NSString stringWithFormat: @"folder%@", - [unprefixedFolders componentsJoinedByString: @"/folder"]]; - url = [NSString stringWithFormat: @"sogo://%@:%@@outbox/%@", - [userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"], - [userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"], - folderName]; - - context = talloc_zero (memCtx, struct mapistore_contexts_list); - context->url = [url asUnicodeInMemCtx: context]; - /* TODO: use a localized version of this display name */ - context->name = [@"Outbox" asUnicodeInMemCtx: context]; - context->main_folder = true; - context->role = MAPISTORE_OUTBOX_ROLE; - context->tag = "tag"; - context->prev = context; - - return context; -} - -- (Class) MAPIStoreFolderClass -{ - return MAPIStoreOutboxFolderK; -} - -@end diff --git a/OpenChange/MAPIStoreMailFolder.h b/OpenChange/MAPIStoreMailFolder.h deleted file mode 100644 index 717868efb..000000000 --- a/OpenChange/MAPIStoreMailFolder.h +++ /dev/null @@ -1,72 +0,0 @@ -/* MAPIStoreMailFolder.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREMAILFOLDER_H -#define MAPISTOREMAILFOLDER_H - -#import "MAPIStoreFolder.h" - -@class NSNumber; - -@class WOContext; - -@class SOGoMailAccount; -@class SOGoMailFolder; - -@class MAPIStoreMailMessageTable; - -@interface MAPIStoreMailFolder : MAPIStoreFolder -{ - SOGoMAPIDBMessage *versionsMessage; - NSMutableDictionary *bodyData; -} - -- (BOOL) ensureFolderExists; - -/* synchronisation & versioning */ -- (BOOL) synchroniseCache; -- (void) synchronizeUpdatedFolder: (NSNumber *) lastModseq - withMapping: (NSMutableDictionary *) mapping; -- (BOOL) synchroniseCacheForUID: (NSString *) messageUID; -- (NSNumber *) modseqFromMessageChangeNumber: (NSString *) changeNum; -- (NSString *) messageUIDFromMessageKey: (NSString *) messageKey; -- (NSString *) changeNumberForMessageUID: (NSString *) messageUid; -- (void) setChangeKey: (NSData *) changeKey - forMessageWithKey: (NSString *) messageKey; -- (BOOL) updatePredecessorChangeListWith: (NSData *) changeKey - forMessageWithKey: (NSString *) messageKey; -- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey; -- (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey; - -/* Extra properties from mail messages that already hit the server */ -- (void) setExtraProperties: (NSDictionary *) props - forMessage: (NSString *) messageKey; -- (NSDictionary *) extraPropertiesForMessage: (NSString *) messageKey; - -@end - -/* MAPIStoreOutboxFolder is a special subclass of MAPIStoreMailFolder where - the displayname is always "Outbox" and can not be changed. */ -@interface MAPIStoreOutboxFolder : MAPIStoreMailFolder -@end - -#endif /* MAPISTOREMAILFOLDER_H */ diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m deleted file mode 100644 index ee2ff7d61..000000000 --- a/OpenChange/MAPIStoreMailFolder.m +++ /dev/null @@ -1,1777 +0,0 @@ -/* MAPIStoreMailFolder.m - this file is part of SOGo - * - * Copyright (C) 2011-2013 Inverse inc - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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. - */ - -#include - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIApplication.h" -#import "MAPIStoreAppointmentWrapper.h" -#import "MAPIStoreContext.h" -#import "MAPIStoreFAIMessage.h" -#import "MAPIStoreMailContext.h" -#import "MAPIStoreMailMessage.h" -#import "MAPIStoreMailFolderTable.h" -#import "MAPIStoreMailMessageTable.h" -#import "MAPIStoreMapping.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSData+MAPIStore.h" -#import "NSString+MAPIStore.h" -#import "SOGoMAPIDBMessage.h" -#import - -#import "MAPIStoreMailVolatileMessage.h" - -#import "MAPIStoreMailFolder.h" - -static Class SOGoMailFolderK, MAPIStoreMailFolderK, MAPIStoreOutboxFolderK; - -#include - -#undef DEBUG -#include -#include -#include -#include -#include -#include - -@implementation MAPIStoreMailFolder - -+ (void) initialize -{ - SOGoMailFolderK = [SOGoMailFolder class]; - MAPIStoreMailFolderK = [MAPIStoreMailFolder class]; - MAPIStoreOutboxFolderK = [MAPIStoreOutboxFolder class]; - [MAPIStoreAppointmentWrapper class]; -} - -- (id) init -{ - if ((self = [super init])) - { - versionsMessage = nil; - bodyData = [NSMutableDictionary new]; - } - - return self; -} - -- (void) dealloc -{ - [versionsMessage release]; - [bodyData release]; - [super dealloc]; -} - -- (void) setupVersionsMessage -{ - ASSIGN (versionsMessage, - [SOGoMAPIDBMessage objectWithName: @"versions.plist" - inContainer: dbFolder]); - [versionsMessage setObjectType: MAPIInternalCacheObject]; - [versionsMessage reloadIfNeeded]; -} - -- (BOOL) ensureFolderExists -{ - return [(SOGoMailFolder *) sogoObject exists] || [sogoObject create]; -} - -- (void) addProperties: (NSDictionary *) newProperties -{ - NSString *newDisplayName, *newNameInContainer; - NSMutableDictionary *propsCopy; - NSNumber *key; - uint64_t fid; - - key = MAPIPropertyKey (PR_DISPLAY_NAME_UNICODE); - newDisplayName = [newProperties objectForKey: key]; - if (newDisplayName - && ![self isKindOfClass: 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]; - newProperties = propsCopy; - } - - [super addProperties: newProperties]; -} - -- (MAPIStoreMessageTable *) messageTable -{ - [self synchroniseCache]; - return [MAPIStoreMailMessageTable tableForContainer: self]; -} - -- (MAPIStoreFolderTable *) folderTable -{ - return [MAPIStoreMailFolderTable tableForContainer: self]; -} - -- (enum mapistore_error) createFolder: (struct SRow *) aRow - withFID: (uint64_t) newFID - andKey: (NSString **) newKeyP -{ - enum mapistore_error rc; - NSString *folderName, *nameInContainer; - SOGoMailFolder *newFolder; - int i; - - nameInContainer = nil; - rc = MAPISTORE_ERROR; - - folderName = nil; - for (i = 0; !folderName && i < aRow->cValues; i++) - { - if (aRow->lpProps[i].ulPropTag == PR_DISPLAY_NAME_UNICODE) - folderName = [NSString stringWithUTF8String: aRow->lpProps[i].value.lpszW]; - else if (aRow->lpProps[i].ulPropTag == PR_DISPLAY_NAME) - folderName = [NSString stringWithUTF8String: (const char *) aRow->lpProps[i].value.lpszA]; - } - - if (folderName) - { - nameInContainer = [NSString stringWithFormat: @"folder%@", - [[folderName stringByEncodingImap4FolderName] asCSSIdentifier]]; - - [[self userContext] activate]; - - newFolder = [SOGoMailFolderK objectWithName: nameInContainer - inContainer: sogoObject]; - if ([newFolder create]) - { - *newKeyP = nameInContainer; - rc = MAPISTORE_SUCCESS; - } - else if ([newFolder exists]) - rc = MAPISTORE_ERR_EXIST; - else - rc = MAPISTORE_ERR_DENIED; - } - - return rc; -} - -- (enum mapistore_error) deleteFolder -{ - enum mapistore_error rc; - NSException *error; - NSString *name; - - name = [self nameInContainer]; - if ([name isEqualToString: @"folderINBOX"]) - rc = MAPISTORE_ERR_DENIED; - else - { - error = [(SOGoMailFolder *) sogoObject delete]; - if (error) - rc = MAPISTORE_ERROR; - else - { - if (![versionsMessage delete]) - rc = MAPISTORE_SUCCESS; - else - rc = MAPISTORE_ERROR; - } - } - - return (rc == MAPISTORE_SUCCESS) ? [super deleteFolder] : rc; -} - -- (enum mapistore_error) getPidTagContentUnreadCount: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - EOQualifier *searchQualifier; - uint32_t longValue; - - searchQualifier - = [EOQualifier qualifierWithQualifierFormat: @"flags = %@", @"unseen"]; - longValue = [[sogoObject fetchUIDsMatchingQualifier: searchQualifier - sortOrdering: nil] - count]; - *data = MAPILongValue (memCtx, longValue); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagContainerClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPF.Note" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (EOQualifier *) simplifyQualifier: (EOQualifier *) qualifier -{ - /* Hack: Reduce the number of MODSEQ constraints to a single one as - we assume the difference among MODSEQs will be small enough to - return a small number of UIDs. - - This is the only case we do simplify: - MODSEQ >= x | MODSEQ >= y | MODSEQ >= z => MODSEQ >= min(x,y,z) - */ - if (qualifier && [qualifier isKindOfClass: [EOOrQualifier class]]) - { - EOQualifier *simplifiedQualifier; - NSArray *quals; - NSNumber *minModseq; - NSUInteger i, count; - - quals = [(EOOrQualifier *)qualifier qualifiers]; - count = [quals count]; - if (count < 2) - return qualifier; - - minModseq = [NSNumber numberWithUnsignedLongLong: ULLONG_MAX]; - - for (i = 0; i < count; i++) - { - EOQualifier *subQualifier; - - subQualifier = [quals objectAtIndex: i]; - if ([subQualifier isKindOfClass: [EOAndQualifier class]] - && [[(EOAndQualifier *)subQualifier qualifiers] count] == 1) - subQualifier = [[(EOAndQualifier *)subQualifier qualifiers] objectAtIndex: 0]; - - if ([subQualifier isKindOfClass: [EOKeyValueQualifier class]] - && [[(EOKeyValueQualifier *)subQualifier key] isEqualToString: @"MODSEQ"]) - { - NSNumber *value; - - value = (NSNumber *)[(EOKeyValueQualifier *)subQualifier value]; - if ([minModseq compare: value] == NSOrderedDescending - && [value unsignedLongLongValue] > 0) - minModseq = (NSNumber *)[(EOKeyValueQualifier *)subQualifier value]; - - } - else - return qualifier; - } - - if ([minModseq unsignedLongLongValue] > 0 && [minModseq unsignedLongLongValue] < ULLONG_MAX) - { - simplifiedQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"MODSEQ" - operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo - value: minModseq]; - [simplifiedQualifier autorelease]; - return simplifiedQualifier; - } - } - - return qualifier; -} - -- (EOQualifier *) nonDeletedQualifier -{ - static EOQualifier *nonDeletedQualifier = nil; - EOQualifier *deletedQualifier; - - if (!nonDeletedQualifier) - { - deletedQualifier - = [[EOKeyValueQualifier alloc] - initWithKey: @"FLAGS" - operatorSelector: EOQualifierOperatorContains - value: [NSArray arrayWithObject: @"Deleted"]]; - nonDeletedQualifier = [[EONotQualifier alloc] - initWithQualifier: deletedQualifier]; - [deletedQualifier release]; - } - - return nonDeletedQualifier; -} - -- (NSArray *) messageKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - NSArray *uidKeys; - EOQualifier *fetchQualifier, *simplifiedQualifier; - - if ([self ensureFolderExists]) - { - if (!sortOrderings) - sortOrderings = [NSArray arrayWithObject: @"ARRIVAL"]; - - if (qualifier) - { - simplifiedQualifier = [self simplifyQualifier: qualifier]; - fetchQualifier - = [[EOAndQualifier alloc] initWithQualifiers: - [self nonDeletedQualifier], simplifiedQualifier, - nil]; - [fetchQualifier autorelease]; - } - else - fetchQualifier = [self nonDeletedQualifier]; - - uidKeys = [[sogoObject fetchUIDsMatchingQualifier: fetchQualifier - sortOrdering: sortOrderings] - stringsWithFormat: @"%@.eml"]; - } - else - uidKeys = nil; - - return uidKeys; -} - -- (NSMutableString *) _imapFolderNameRepresentation: (NSString *) subfolderName -{ - NSMutableString *representation; - NSString *nameInContainer, *strippedName; - - nameInContainer = [self nameInContainer]; - if (container) - representation = [(MAPIStoreMailFolder *) container - _imapFolderNameRepresentation: nameInContainer]; - else - { - if (![nameInContainer hasPrefix: @"folder"]) - abort (); - strippedName = [nameInContainer substringFromIndex: 6]; - representation = [NSMutableString stringWithString: strippedName]; - } - - if (![subfolderName hasPrefix: @"folder"]) - abort (); - strippedName = [[subfolderName substringFromIndex: 6] stringByDecodingImap4FolderName]; - [representation appendFormat: @"/%@", strippedName]; - - return representation; -} - -- (void) _cleanupSubfolderKeys: (NSMutableArray *) subfolderKeys -{ - SOGoMailAccount *account; - NSString *draftsFolderName, *sentFolderName, *trashFolderName; - NSString *subfolderKey, *cmpString; - NSUInteger count, max; - NSMutableArray *keysToRemove; - - account = [(SOGoMailFolder *) sogoObject mailAccountFolder]; - draftsFolderName = [account draftsFolderNameInContext: nil]; - sentFolderName = [account sentFolderNameInContext: nil]; - trashFolderName = [account trashFolderNameInContext: nil]; - - max = [subfolderKeys count]; - keysToRemove = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - subfolderKey = [subfolderKeys objectAtIndex: count]; - cmpString = [self _imapFolderNameRepresentation: subfolderKey]; - if ([cmpString isEqualToString: draftsFolderName] - || [cmpString isEqualToString: sentFolderName] - || [cmpString isEqualToString: trashFolderName]) - [keysToRemove addObject: subfolderKey]; - } - - [subfolderKeys removeObjectsInArray: keysToRemove]; -} - -- (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - NSArray *filteredSubfolderKeys; - NSMutableArray *subfolderKeys; - NSMutableArray *subfolderKeysQualifying; - NSString *subfolderKey; - NSUInteger count, max; - - if ([self ensureFolderExists]) - { - /* Only folder name can be used as qualifier key */ - if (qualifier) - [self warnWithFormat: @"qualifier is only used for folders with name"]; - if (sortOrderings) - [self errorWithFormat: @"sort orderings are not used for folders"]; - - /* FIXME: Flush any cache before retrieving the hierarchy, this - slows things down but it is safer */ - if (!qualifier) - [sogoObject flushMailCaches]; - - subfolderKeys = [[sogoObject toManyRelationshipKeys] mutableCopy]; - [subfolderKeys autorelease]; - - [self _cleanupSubfolderKeys: subfolderKeys]; - - if (qualifier) - { - subfolderKeysQualifying = [NSMutableArray array]; - max = [subfolderKeys count]; - for (count = 0; count < max; count++) { - subfolderKey = [subfolderKeys objectAtIndex: count]; - /* Remove "folder" prefix */ - subfolderKey = [subfolderKey substringFromIndex: 6]; - subfolderKey = [[subfolderKey fromCSSIdentifier] stringByDecodingImap4FolderName]; - [subfolderKeysQualifying addObject: [NSDictionary dictionaryWithObject: subfolderKey - forKey: @"name"]]; - } - filteredSubfolderKeys = [subfolderKeysQualifying filteredArrayUsingQualifier: qualifier]; - - max = [filteredSubfolderKeys count]; - subfolderKeys = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - subfolderKey = [[filteredSubfolderKeys objectAtIndex: count] valueForKey: @"name"]; - subfolderKey = [NSString stringWithFormat: @"folder%@", [[subfolderKey stringByEncodingImap4FolderName] asCSSIdentifier]]; - [subfolderKeys addObject: subfolderKey]; - } - - } - } - else - subfolderKeys = nil; - - return subfolderKeys; -} - -- (NSDate *) creationTime -{ - return [NSCalendarDate dateWithTimeIntervalSince1970: 0x4dbb2dbe]; /* oc_version_time */ -} - -- (NSDate *) lastMessageModificationTime -{ - NSNumber *ti; - NSDate *value = nil; - - [self synchroniseCache]; - ti = [[versionsMessage properties] - objectForKey: @"SyncLastSynchronisationDate"]; - if (ti) - value = [NSDate dateWithTimeIntervalSince1970: [ti doubleValue]]; - else - value = [NSDate date]; - - //[self logWithFormat: @"lastMessageModificationTime: %@", value]; - - return value; -} - -- (SOGoFolder *) aclFolder -{ - return (SOGoFolder *) sogoObject; -} - -- (NSArray *) permissionEntries -{ - NSArray *permissionEntries; - - if ([self ensureFolderExists]) - permissionEntries = [super permissionEntries]; - else - permissionEntries = nil; - - return permissionEntries; -} - -- (BOOL) supportsSubFolders -{ - BOOL supportsSubFolders; - MAPIStoreUserContext *userContext; - - if ([[self nameInContainer] isEqualToString: @"folderINBOX"]) - { - userContext = [self userContext]; - supportsSubFolders = ![userContext inboxHasNoInferiors]; - } - else - supportsSubFolders = YES; - - return supportsSubFolders; -} - -/* synchronisation */ - -/* Tree: -{ - SyncLastModseq = x; - SyncLastSynchronisationDate = x; ** not updated until something changed - Messages = { - MessageKey = { - Version = x; - Modseq = x; - Deleted = b; - }; - ... - }; - VersionMapping = { - Version = MessageKey; - ... - } -} -*/ - -static NSComparisonResult -_compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) -{ - static NSNumber *zeroNumber = nil; - NSNumber *modseq1, *modseq2; - - if (!zeroNumber) - { - zeroNumber = [NSNumber numberWithUnsignedLongLong: 0]; - [zeroNumber retain]; - } - - modseq1 = [entry1 objectForKey: @"modseq"]; - if (!modseq1) - modseq1 = zeroNumber; - modseq2 = [entry2 objectForKey: @"modseq"]; - if (!modseq2) - modseq2 = zeroNumber; - - return [modseq1 compare: modseq2]; -} - -- (void) _updatePredecessorChangeListWith: (NSData *) predecessorChangeList - forMessageEntry: (NSMutableDictionary *) messageEntry -{ - NSData *globCnt, *oldGlobCnt; - NSMutableDictionary *changeList; - NSString *guid; - struct SizedXid *sizedXIDList; - struct XID xid; - uint32_t i, length; - - sizedXIDList = [predecessorChangeList asSizedXidArrayInMemCtx: NULL with: &length]; - - changeList = [messageEntry objectForKey: @"PredecessorChangeList"]; - if (!changeList) - { - changeList = [NSMutableDictionary new]; - [messageEntry setObject: changeList - forKey: @"PredecessorChangeList"]; - [changeList release]; - } - - if (sizedXIDList) { - for (i = 0; i < length; i++) - { - xid = sizedXIDList[i].XID; - guid = [NSString stringWithGUID: &xid.NameSpaceGuid]; - globCnt = [NSData dataWithBytes: xid.LocalId.data length: xid.LocalId.length]; - oldGlobCnt = [changeList objectForKey: guid]; - if (!oldGlobCnt || ([globCnt compare: oldGlobCnt] == NSOrderedDescending)) - [changeList setObject: globCnt forKey: guid]; - } - - talloc_free (sizedXIDList); - } - - [versionsMessage save]; -} - -- (void) _setChangeKey: (NSData *) changeKey - forMessageEntry: (NSMutableDictionary *) messageEntry -{ - struct XID *xid; - NSString *guid; - NSData *globCnt; - NSDictionary *changeKeyDict; - NSMutableDictionary *changeList; - - xid = [changeKey asXIDInMemCtx: NULL]; - guid = [NSString stringWithGUID: &xid->NameSpaceGuid]; - globCnt = [NSData dataWithBytes: xid->LocalId.data length: xid->LocalId.length]; - talloc_free (xid); - - /* 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"]; - if (!changeList) - { - changeList = [NSMutableDictionary new]; - [messageEntry setObject: changeList - forKey: @"PredecessorChangeList"]; - [changeList release]; - } - [changeList setObject: globCnt forKey: guid]; -} - -- (BOOL) synchroniseCache -{ - BOOL rc = YES; - uint64_t newChangeNum; - NSNumber *ti, *modseq, *lastModseq, *nextModseq; - NSString *changeNumber, *uid, *messageKey; - uint64_t lastModseqNbr; - EOQualifier *searchQualifier; - NSArray *uids, *changeNumbers; - NSUInteger count, max, nFetched; - NSArray *fetchResults; - NSDictionary *result; - NSData *changeKey; - NSMutableArray *messageKeys; - NSMutableDictionary *currentProperties, *messages, *mapping, *messageEntry; - NSCalendarDate *now; - BOOL foundChange = NO; - - /* NOTE: we are using NSString instance for "uid" and "changeNumber" because - NSNumber proved to give very bad performances when used as NSDictionary - keys with GNUstep 1.22.1. The bug seems to be solved with 1.24 but many - distros still ship an older version. */ - now = [NSCalendarDate date]; - [now setTimeZone: utcTZ]; - - [versionsMessage reloadIfNeeded]; - currentProperties = [versionsMessage properties]; - messages = [currentProperties objectForKey: @"Messages"]; - if (!messages) - { - messages = [NSMutableDictionary new]; - [currentProperties setObject: messages forKey: @"Messages"]; - [messages release]; - } - mapping = [currentProperties objectForKey: @"VersionMapping"]; - if (!mapping) - { - mapping = [NSMutableDictionary new]; - [currentProperties setObject: mapping forKey: @"VersionMapping"]; - [mapping release]; - } - - lastModseq = [currentProperties objectForKey: @"SyncLastModseq"]; - if (lastModseq) - { - lastModseqNbr = [lastModseq unsignedLongLongValue]; - nextModseq = [NSNumber numberWithUnsignedLongLong: lastModseqNbr + 1]; - searchQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"modseq" - operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo - value: nextModseq]; - - [searchQualifier autorelease]; - } - else - { - lastModseqNbr = 0; - searchQualifier = [self nonDeletedQualifier]; - } - - /* 1. we fetch modified or added uids */ - uids = [sogoObject fetchUIDsMatchingQualifier: searchQualifier - sortOrdering: nil]; - max = [uids count]; - if (max > 0) - { - messageKeys = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - messageKey = [NSString stringWithFormat: @"%@.eml", - [uids objectAtIndex: count]]; - [messageKeys addObject: messageKey]; - } - [self ensureIDsForChildKeys: messageKeys]; - - changeNumbers = [[self context] getNewChangeNumbers: max]; - - fetchResults - = [(NSDictionary *) [sogoObject fetchUIDs: uids - parts: [NSArray arrayWithObjects: @"modseq", @"flags", nil]] - objectForKey: @"fetch"]; - - /* NOTE: we sort items manually because Cyrus does not properly sort - entries with a MODSEQ of 0 */ - fetchResults - = [fetchResults sortedArrayUsingFunction: _compareFetchResultsByMODSEQ - context: NULL]; - - nFetched = [fetchResults count]; - if (nFetched != max) { - [self errorWithFormat: @"Error fetching UIDs. Asked: %d Received: %d." - @"Check the IMAP conversation for details", max, nFetched]; - return NO; - } - - for (count = 0; count < max; count++) - { - result = [fetchResults objectAtIndex: count]; - uid = [[result objectForKey: @"uid"] stringValue]; - modseq = [result objectForKey: @"modseq"]; - newChangeNum = [[changeNumbers objectAtIndex: count] - unsignedLongLongValue]; - changeNumber = [NSString stringWithUnsignedLongLong: newChangeNum]; - - messageEntry = [NSMutableDictionary new]; - [messages setObject: messageEntry forKey: uid]; - [messageEntry release]; - - [messageEntry setObject: modseq forKey: @"modseq"]; - [messageEntry setObject: changeNumber forKey: @"version"]; - - //[self logWithFormat: @"added message entry for uid %@, modseq %@," - // @" version %@", uid, modseq, changeNumber]; - - changeKey = [self getReplicaKeyFromGlobCnt: newChangeNum >> 16]; - [self _setChangeKey: changeKey forMessageEntry: messageEntry]; - - [mapping setObject: modseq forKey: changeNumber]; - - if (!lastModseq - || ([lastModseq compare: modseq] == NSOrderedAscending)) - lastModseq = modseq; - - if ([[result objectForKey: @"flags"] containsObject: @"deleted"]) - [currentProperties setObject: changeNumber - forKey: @"SyncLastDeleteChangeNumber"]; - } - - [currentProperties setObject: lastModseq forKey: @"SyncLastModseq"]; - foundChange = YES; - } - - /* 2. we synchronise expunged UIDs */ - fetchResults = [(SOGoMailFolder *) sogoObject - fetchUIDsOfVanishedItems: lastModseqNbr]; - - max = [fetchResults count]; - - changeNumber = nil; - for (count = 0; count < max; count++) - { - uid = [[fetchResults objectAtIndex: count] stringValue]; - if ([messages objectForKey: uid]) - { - if (!changeNumber) - { - newChangeNum = [[self context] getNewChangeNumber]; - changeNumber = [NSString stringWithUnsignedLongLong: newChangeNum]; - } - [messages removeObjectForKey: uid]; - [self logWithFormat: @"Removed message entry for UID %@", uid]; - } - else - { - [self logWithFormat:@"Message entry not found for UID %@", uid]; - } - } - if (changeNumber) - { - [currentProperties setObject: changeNumber - forKey: @"SyncLastDeleteChangeNumber"]; - [mapping setObject: lastModseq forKey: changeNumber]; - foundChange = YES; - } - - if (foundChange) - { - [self synchronizeUpdatedFolder: lastModseq - withMapping: mapping]; - - ti = [NSNumber numberWithDouble: [now timeIntervalSince1970]]; - [currentProperties setObject: ti - forKey: @"SyncLastSynchronisationDate"]; - [versionsMessage save]; - } - - - return rc; -} - -- (void) synchronizeUpdatedFolder: (NSNumber *) lastModseq - withMapping: (NSMutableDictionary *) mapping -{ - /* This method should be called whenever something has changed on the folder. - Then we will perform two actions: - 1 - Update the PidTagChangeNumber property of the root container. - 2 - Store relationship PidTagChangenumber with lastModseq value on the - mapping given as parameter for this folder */ - uint64_t *current_cn; - struct SRow row; - struct SPropValue prop; - uint64_t fid; - const char *username; - struct openchangedb_context *oc_ctx; - enum MAPISTATUS retval; - TALLOC_CTX *local_mem_ctx = NULL; - - row.cValues = 1; - prop.ulPropTag = PidTagChangeNumber; - prop.value.d = 0; // It doesn't matter, it will be autogenerated - row.lpProps = ∝ - - /* We are doing a "touch" operation to update change number of the root container. - We get the root container as it has the properties in the OpenChange DB */ - username = [[self context] connectionInfo]->username; - oc_ctx = [[self context] connectionInfo]->oc_ctx; - fid = [[self rootContainer] objectId]; - retval = openchangedb_set_folder_properties(oc_ctx, username, fid, &row); - if (retval != MAPI_E_SUCCESS) - { - [self errorWithFormat:@"%s: Error setting change number on %"PRIu64, - __PRETTY_FUNCTION__, fid]; - return; - } - - local_mem_ctx = talloc_named(NULL, 0, __PRETTY_FUNCTION__); - if (local_mem_ctx == NULL) - { - [self errorWithFormat:@"%s: Error with talloc_named, out of memory?", - __PRETTY_FUNCTION__]; - return; - } - retval = openchangedb_get_folder_property(local_mem_ctx, oc_ctx, username, - PidTagChangeNumber, fid, - (void **) ¤t_cn); - if (retval != MAPI_E_SUCCESS) - { - [self errorWithFormat:@"%s: Error getting change number on %"PRIu64, - __PRETTY_FUNCTION__, fid]; - talloc_free(local_mem_ctx); - return; - } - - [mapping setObject: lastModseq - forKey: [NSString stringWithUnsignedLongLong: *current_cn]]; - talloc_free(local_mem_ctx); -} - -- (BOOL) synchroniseCacheForUID: (NSString *) messageUID -{ - /* Try to synchronise old UIDs in versions.plist cache using an - specific UID. It returns a boolean indicating if the - synchronisation were done. - - It should be used as last resort, keeping synchroniseCache to main - sync entry point. - */ - NSMutableDictionary *currentProperties, *messages, *messageEntry, *mapping; - NSArray *fetchResults; - uint64_t changeNumber; - NSDictionary *result; - NSNumber *modseq; - NSString *changeNumberStr; - NSData *changeKey; - - [versionsMessage reloadIfNeeded]; - currentProperties = [versionsMessage properties]; - messages = [currentProperties objectForKey: @"Messages"]; - messageEntry = [messages objectForKey: messageUID]; - if (!messageEntry) - { - fetchResults = [(NSDictionary *) [sogoObject fetchUIDs: [NSArray arrayWithObject: messageUID] - parts: [NSArray arrayWithObjects: @"modseq", @"flags", nil]] - objectForKey: @"fetch"]; - if ([fetchResults count] == 1) - { - result = [fetchResults objectAtIndex: 0]; - modseq = [result objectForKey: @"modseq"]; - changeNumber = [[self context] getNewChangeNumber]; - changeNumberStr = [NSString stringWithUnsignedLongLong: changeNumber]; - - /* Create new message entry in Messages dict */ - messageEntry = [NSMutableDictionary new]; - [messages setObject: messageEntry forKey: messageUID]; - [messageEntry release]; - - /* Store the modseq and change number */ - [messageEntry setObject: modseq forKey: @"modseq"]; - [messageEntry setObject: changeNumberStr forKey: @"version"]; - - /* Store the change key */ - changeKey = [self getReplicaKeyFromGlobCnt: changeNumber >> 16]; - [self _setChangeKey: changeKey forMessageEntry: messageEntry]; - - /* Store the changeNumber -> modseq mapping */ - mapping = [currentProperties objectForKey: @"VersionMapping"]; - [mapping setObject: modseq forKey: changeNumberStr]; - - /* Store the last deleted change number if it is soft-deleted */ - if ([[result objectForKey: @"flags"] containsObject: @"deleted"]) - [currentProperties setObject: changeNumberStr - forKey: @"SyncLastDeleteChangeNumber"]; - - /* Save the message */ - [versionsMessage save]; - return YES; - } - else - { - return NO; - } - } - /* If message entry exists, then synchroniseCache did its job */ - return YES; -} - - -- (NSNumber *) modseqFromMessageChangeNumber: (NSString *) changeNum -{ - NSDictionary *mapping; - NSNumber *modseq; - NSEnumerator *enumerator; - id key; - uint64_t found, target, current, replica_id, current_cn; - NSString *closestChangeNum; - - mapping = [[versionsMessage properties] objectForKey: @"VersionMapping"]; - modseq = [mapping objectForKey: changeNum]; - if (modseq) return modseq; - - // Not found from stored change numbers for this folder. - // Get the closest modseq for the change number given. - // O(n) cost but will be unusual behaviour. - target = exchange_globcnt([changeNum unsignedLongLongValue] >> 16); - replica_id = [changeNum unsignedLongLongValue] & 0xFFFF; - found = 0; - enumerator = [mapping keyEnumerator]; - while ((key = [enumerator nextObject])) - { - current_cn = [(NSString *)key unsignedLongLongValue]; - if ((current_cn & 0xFFFF) != replica_id) - continue; - current = exchange_globcnt(current_cn >> 16); - if (current < target && current > found) - found = current; - } - - if (found) - { - closestChangeNum = [NSString stringWithUnsignedLongLong: - (exchange_globcnt(found) << 16 | replica_id)]; - modseq = [mapping objectForKey: closestChangeNum]; - } - - return modseq; -} - -- (NSString *) messageUIDFromMessageKey: (NSString *) messageKey -{ - NSString *messageUid; - NSRange dotRange; - - dotRange = [messageKey rangeOfString: @".eml"]; - if (dotRange.location != NSNotFound) - messageUid = [messageKey substringToIndex: dotRange.location]; - else - { - messageUid = nil; - [self errorWithFormat:@"%s: Unexpected messageKey value [%@]", - __PRETTY_FUNCTION__, messageKey]; - } - - return messageUid; -} - -- (NSString *) changeNumberForMessageUID: (NSString *) messageUid -{ - NSDictionary *messages; - NSString *changeNumber; - - messages = [[versionsMessage properties] objectForKey: @"Messages"]; - changeNumber = [[messages objectForKey: messageUid] - objectForKey: @"version"]; - - return changeNumber; -} - -- (NSMutableDictionary *) _messageEntryFromMessageKey: (NSString *) messageKey -{ - NSMutableDictionary *messages, *messageEntry; - NSString *messageUid; - BOOL synced; - - messageUid = [self messageUIDFromMessageKey: messageKey]; - messages = [[versionsMessage properties] objectForKey: @"Messages"]; - messageEntry = [messages objectForKey: messageUid]; - if (!messageEntry) - { - [self warnWithFormat: @"attempting to synchronise to get the message entry for " - @"this message %@", messageKey]; - synced = [self synchroniseCacheForUID: messageUid]; - if (synced) - messageEntry = [[[versionsMessage properties] objectForKey: @"Messages"] objectForKey: messageUid]; - if (!messageEntry) - { - [self errorWithFormat: @"still nothing. We crash!"]; - abort (); - } - } - - return messageEntry; -} - -- (void) setChangeKey: (NSData *) changeKey - forMessageWithKey: (NSString *) messageKey -{ - [self _setChangeKey: changeKey - forMessageEntry: [self _messageEntryFromMessageKey: messageKey]]; - - [versionsMessage save]; -} - -- (BOOL) updatePredecessorChangeListWith: (NSData *) changeKey - forMessageWithKey: (NSString *) messageKey -{ - /* Update predecessor change list property given the change key. It - returns if the change key has been added to the list or not */ - BOOL added = NO; - NSData *globCnt, *oldGlobCnt; - NSDictionary *messageEntry; - NSMutableDictionary *changeList; - NSString *guid; - struct XID *xid; - - xid = [changeKey asXIDInMemCtx: NULL]; - guid = [NSString stringWithGUID: &xid->NameSpaceGuid]; - globCnt = [NSData dataWithBytes: xid->LocalId.data length: xid->LocalId.length]; - talloc_free (xid); - - messageEntry = [self _messageEntryFromMessageKey: messageKey]; - if (messageEntry) - { - changeList = [messageEntry objectForKey: @"PredecessorChangeList"]; - if (changeList) - { - oldGlobCnt = [changeList objectForKey: guid]; - if (!oldGlobCnt || ([globCnt compare: oldGlobCnt] == NSOrderedDescending)) - { - [changeList setObject: globCnt forKey: guid]; - [versionsMessage save]; - added = YES; - } - } - else - [self errorWithFormat: @"Missing predecessor change list to update"]; - } - - return added; -} - -- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey -{ - NSDictionary *messages, *changeKeyDict; - NSString *guid, *messageUid; - NSData *globCnt, *changeKey = nil; - - messageUid = [self messageUIDFromMessageKey: messageKey]; - messages = [[versionsMessage properties] objectForKey: @"Messages"]; - changeKeyDict = [[messages objectForKey: messageUid] - objectForKey: @"ChangeKey"]; - if (changeKeyDict) - { - guid = [changeKeyDict objectForKey: @"GUID"]; - globCnt = [changeKeyDict objectForKey: @"LocalId"]; - changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; - } - - return changeKey; -} - -- (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey -{ - NSMutableData *list = nil; - NSDictionary *messages, *changeListDict; - NSArray *keys; - NSMutableArray *changeKeys; - NSUInteger count, max; - NSData *changeKey; - NSString *guid, *messageUid; - NSData *globCnt; - - messageUid = [self messageUIDFromMessageKey: messageKey]; - messages = [[versionsMessage properties] objectForKey: @"Messages"]; - changeListDict = [[messages objectForKey: messageUid] - objectForKey: @"PredecessorChangeList"]; - if (changeListDict) - { - keys = [changeListDict allKeys]; - max = [keys count]; - - changeKeys = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - guid = [keys objectAtIndex: count]; - globCnt = [changeListDict objectForKey: guid]; - changeKey = [NSData dataWithChangeKeyGUID: guid andCnt: globCnt]; - [changeKeys addObject: changeKey]; - } - [changeKeys sortUsingFunction: MAPIChangeKeyGUIDCompare - context: nil]; - - list = [NSMutableData data]; - for (count = 0; count < max; count++) - { - changeKey = [changeKeys objectAtIndex: count]; - [list appendUInt8: [changeKey length]]; - [list appendData: changeKey]; - } - } - - return list; -} - -/* Management for extra properties once they already hit the IMAP server */ -- (void) setExtraProperties: (NSDictionary *) props - forMessage: (NSString *) messageKey -{ - NSMutableDictionary *extraProps, *currentProperties; - NSString *messageUid; - - messageUid = [self messageUIDFromMessageKey: messageKey]; - currentProperties = [versionsMessage properties]; - extraProps = [currentProperties objectForKey: @"ExtraMessagesProperties"]; - if (!extraProps) - { - extraProps = [NSMutableDictionary new]; - [currentProperties setObject: extraProps forKey: @"ExtraMessagesProperties"]; - [extraProps release]; - } - - [extraProps setObject: props - forKey: messageUid]; - [versionsMessage save]; -} - -- (NSDictionary *) extraPropertiesForMessage: (NSString *) messageKey -{ - NSString *messageUid; - - messageUid = [self messageUIDFromMessageKey: messageKey]; - return [[[versionsMessage properties] objectForKey: @"ExtraMessagesProperties"] - objectForKey: messageUid]; -} - -- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum - andCN: (NSNumber **) cnNbr - inTableType: (uint8_t) tableType -{ - NSArray *deletedKeys, *deletedUIDs; - NSString *changeNumber; - uint64_t modseq; - NSDictionary *versionProperties; - EOQualifier *deletedQualifier, *kvQualifier, *searchQualifier; - - if (tableType == MAPISTORE_MESSAGE_TABLE) - { - changeNumber = [NSString stringWithFormat: @"0x%.16llx", changeNum]; - modseq = [[self modseqFromMessageChangeNumber: changeNumber] - unsignedLongLongValue]; - if (modseq > 0) - { - /* Hard deleted items */ - deletedUIDs = [(SOGoMailFolder *) sogoObject - fetchUIDsOfVanishedItems: modseq]; - - /* Soft deleted items */ - kvQualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"modseq" - operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo - value: [NSNumber numberWithUnsignedLongLong: modseq]]; - deletedQualifier - = [[EOKeyValueQualifier alloc] - initWithKey: @"FLAGS" - operatorSelector: EOQualifierOperatorContains - value: [NSArray arrayWithObject: @"Deleted"]]; - - searchQualifier = [[EOAndQualifier alloc] - initWithQualifiers: - kvQualifier, deletedQualifier, nil]; - - deletedUIDs = [deletedUIDs arrayByAddingObjectsFromArray: - [sogoObject fetchUIDsMatchingQualifier: searchQualifier - sortOrdering: nil]]; - - [deletedQualifier release]; - [kvQualifier release]; - [searchQualifier release]; - - deletedKeys = [deletedUIDs stringsWithFormat: @"%@.eml"]; - if ([deletedUIDs count] > 0) - { - versionProperties = [versionsMessage properties]; - changeNumber = [versionProperties - objectForKey: @"SyncLastDeleteChangeNumber"]; - *cnNbr = [NSNumber numberWithUnsignedLongLong: - [changeNumber unsignedLongLongValue]]; - [versionsMessage save]; - } - } - else - deletedKeys = [NSArray array]; - } - else - deletedKeys = [super getDeletedKeysFromChangeNumber: changeNum - andCN: cnNbr - inTableType: tableType]; - - return deletedKeys; -} - -static void -_appendIMAPRange (NSMutableArray *UIDs, uint32_t low, uint32_t high) -{ - uint32_t count; - - for (count = low; count < high + 1; count++) - [UIDs addObject: [NSNumber numberWithUnsignedLong: count]]; -} - -static NSUInteger -_parseUID (const unichar *uniString, uint32_t *newUidP) -{ - NSUInteger count = 0; - uint32_t newUid = 0; - - while (uniString[count] >= '0' && uniString[count] <= '9') - { - newUid = newUid * 10 + (uniString[count] - 48); - count++; - } - *newUidP = newUid; - - return count; -} - -static NSUInteger -_parseIMAPRange (const unichar *uniString, NSArray **UIDsP) -{ - NSMutableArray *UIDs; - NSUInteger count = 0; - uint32_t currentUid, rangeMin; - BOOL done = NO, inRange = NO; - - rangeMin = 0; - currentUid = 0; - UIDs = [NSMutableArray array]; - while (!done) - { - count += _parseUID (uniString + count, ¤tUid); - switch (uniString[count]) - { - case ':': - inRange = YES; - rangeMin = currentUid; - break; - case ' ': - case 0: - done = YES; - case ',': - if (inRange) - { - _appendIMAPRange (UIDs, rangeMin, currentUid); - inRange = NO; - } - else - [UIDs addObject: [NSNumber numberWithUnsignedLong: currentUid]]; - break; - default: - abort (); - } - count++; - } - *UIDsP = UIDs; - - return count; -} - -static void -_parseCOPYUID (NSString *line, NSArray **destUIDsP) -{ - unichar *uniString; - NSUInteger count = 0, max; - // char state = 'i'; /* i = init, v = validity, s = source range, d = dest range */ - - /* sample: 1 OK [COPYUID 1311899334 1:3 11:13] Completed */ - - max = [line length]; - uniString = NSZoneMalloc (NULL, sizeof (unichar) * (max + 1)); - [line getCharacters: uniString]; - uniString[max] = 0; - - while (count < max && uniString[count] != ' ') - count++; - count++; - while (count < max && uniString[count] != ' ') - count++; - count++; - while (count < max && uniString[count] != ' ') - count++; - count++; - if (count < max) - count += _parseIMAPRange (uniString + count, destUIDsP); - - NSZoneFree (NULL, uniString); -} - -// -// Move (or eventually copy) the mails identified by -// "srcMids" from the source folder into this folder. -// -- (enum mapistore_error) moveCopyMessagesWithMIDs: (uint64_t *) srcMids - andCount: (uint32_t) midCount - fromFolder: (MAPIStoreFolder *) sourceFolder - withMIDs: (uint64_t *) targetMids - andChangeKeys: (struct Binary_r **) targetChangeKeys - andPredecessorChangeLists: (struct Binary_r **) targetPredecessorChangeLists - wantCopy: (uint8_t) wantCopy - inMemCtx: (TALLOC_CTX *) memCtx -{ - NGImap4Connection *connection; - NGImap4Client *client; - NSString *sourceFolderName, *targetFolderName, *messageURL, *messageKey, - *uid, *v; - NSMutableArray *uids, *oldMessageURLs; - NSArray *destUIDs; - MAPIStoreMapping *mapping; - NSDictionary *result; - NSUInteger count; - NSArray *a; - NSData *changeList; - - if (![sourceFolder isKindOfClass: [MAPIStoreMailFolder class]]) - return [super moveCopyMessagesWithMIDs: srcMids andCount: midCount - fromFolder: sourceFolder withMIDs: targetMids - andChangeKeys: targetChangeKeys - andPredecessorChangeLists: targetPredecessorChangeLists - wantCopy: wantCopy - inMemCtx: memCtx]; - - /* Conversion of mids to IMAP uids */ - mapping = [self mapping]; - uids = [NSMutableArray arrayWithCapacity: midCount]; - oldMessageURLs = [NSMutableArray arrayWithCapacity: midCount]; - for (count = 0; count < midCount; count++) - { - messageURL = [mapping urlFromID: srcMids[count]]; - if (messageURL) - { - uid = [self messageUIDFromMessageKey: [messageURL lastPathComponent]]; - [uids addObject: uid]; - - [oldMessageURLs addObject: messageURL]; - } - else - return MAPISTORE_ERROR; - } - - /* IMAP COPY */ - connection = [sogoObject imap4Connection]; - sourceFolderName = [connection - imap4FolderNameForURL: [[sourceFolder sogoObject] imap4URL]]; - targetFolderName = [connection - imap4FolderNameForURL: [sogoObject imap4URL]]; - - client = [connection client]; - [client select: sourceFolderName]; - result = [client copyUids: uids toFolder: targetFolderName]; - if (![[result objectForKey: @"result"] boolValue]) - return MAPISTORE_ERROR; - - /* "Move" treatment: Store \Deleted and unregister urls as soft-deleted */ - if (!wantCopy) - { - [client storeFlags: [NSArray arrayWithObject: @"Deleted"] forUIDs: uids - addOrRemove: YES]; - for (count = 0; count < midCount; count++) - { - /* Using soft-deleted to make deleted fmids to return the - srcMids. - See [MAPIStoreFolder getDeletedFMIDs:andCN:fromChangeNumber:inTableType:inMemCtx] - for details */ - [mapping unregisterURLWithID: srcMids[count] - andFlags: MAPISTORE_SOFT_DELETE]; - } - } - - /* Registration of target messages */ - // - // We use the UIDPLUS IMAP extension here in order to speedup UID retrieval - // If supported by the server, we'll get something like: COPYUID 1315425789 1 8 - // - // Sometimes COPYUID isn't returned at all by Cyrus or in case the server doesn't - // support the UIDPLUS IMAP extension, we fallback to a simple UID search. - // - v = [[[result objectForKey: @"RawResponse"] objectForKey: @"ResponseResult"] objectForKey: @"flag"]; - if (v) - { - destUIDs = nil; - _parseCOPYUID (v, &destUIDs); - } - else - { - /* FIXME: this may fail if new messages are appended to the folder - between the COPY and SORT operations */ - [client select: targetFolderName]; - a = [[client sort: @"ARRIVAL" qualifier: nil encoding: @"UTF-8"] - objectForKey: @"sort"]; - destUIDs = [[a sortedArrayUsingSelector: @selector (compare:)] - subarrayWithRange: NSMakeRange ([a count] - midCount, midCount)]; - } - for (count = 0; count < midCount; count++) - { - messageURL = [NSString stringWithFormat: @"%@%@.eml", - [self url], - [destUIDs objectAtIndex: count]]; - [mapping registerURL: messageURL withID: targetMids[count]]; - } - - /* Update the change keys */ - if (targetChangeKeys) - { - [self synchroniseCache]; - for (count = 0; count < midCount; count++) - { - changeList = [NSData dataWithBinary: targetPredecessorChangeLists[count]]; - messageKey = [NSString stringWithFormat: @"%@.eml", - [destUIDs objectAtIndex: count]]; - [self _updatePredecessorChangeListWith: changeList - forMessageEntry: [self _messageEntryFromMessageKey: messageKey]]; - } - } - - // We cleanup cache of our source and destination folders - [self cleanupCaches]; - [sourceFolder cleanupCaches]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) moveCopyToFolder: (MAPIStoreFolder *) targetFolder - withNewName: (NSString *) newFolderName - isMove: (BOOL) isMove - isRecursive: (BOOL) isRecursive - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSURL *folderURL, *newFolderURL; - struct SRow folderRow; - struct SPropValue nameProperty; - MAPIStoreMailFolder *newFolder; - SOGoMailAccount *accountFolder; - SOGoMailFolder *targetSOGoFolder; - NSMutableArray *uids; - NSArray *childKeys; - NSUInteger count, max; - NGImap4Connection *connection; - NGImap4Client *client; - NSString *newURL, *parentDBFolderPath, *childKey, *folderIMAPName, - *urlNamePart, *newFolderIMAPName, *newFolderDBName; - NSException *error; - MAPIStoreMapping *mapping; - NSDictionary *result; - - if ([targetFolder isKindOfClass: MAPIStoreMailFolderK] || (!targetFolder && isMove)) - { - folderURL = [sogoObject imap4URL]; - if (!newFolderName) - newFolderName = [sogoObject displayName]; - targetSOGoFolder = [targetFolder sogoObject]; - if (isMove) - { - newFolderDBName = [[newFolderName stringByEncodingImap4FolderName] asCSSIdentifier]; - if (targetSOGoFolder) - { - /* Mimetise [SOGoMailFolderK imap4URLString] */ - urlNamePart = [[newFolderName stringByEncodingImap4FolderName] stringByEscapingURL]; - newFolderURL = [NSURL URLWithString: urlNamePart - relativeToURL: [targetSOGoFolder imap4URL]]; - } - else - { - /* Mimetise what createRootSecondaryFolderWithFID does */ - accountFolder = [[[self userContext] rootFolders] objectForKey: @"mail"]; - targetSOGoFolder = [SOGoMailFolder objectWithName: [NSString stringWithFormat: @"folder%@", - newFolderDBName] - inContainer: accountFolder]; - newFolderURL = [targetSOGoFolder imap4URL]; - } - error = [[sogoObject imap4Connection] - moveMailboxAtURL: folderURL - toURL: newFolderURL]; - if (error) - rc = MAPISTORE_ERR_DENIED; - else - { - rc = MAPISTORE_SUCCESS; - mapping = [self mapping]; - if (targetFolder) - newURL = [NSString stringWithFormat: @"%@folder%@/", - [targetFolder url], newFolderDBName]; - else - newURL = [NSString stringWithFormat: @"sogo://%@:%@@mail/folder%@/", - [[self userContext] username], [[self userContext] username], - newFolderDBName]; - [mapping updateID: [self objectId] withURL: newURL]; - if (targetFolder) - { - parentDBFolderPath = [[targetFolder dbFolder] path]; - if (!parentDBFolderPath) - parentDBFolderPath = @""; - [dbFolder changePathTo: [NSString stringWithFormat: - @"%@/folder%@", - parentDBFolderPath, - newFolderDBName] - intoNewContainer: [targetFolder dbFolder]]; - } - else - [dbFolder changePathTo: [NSString stringWithFormat: - @"/mail/folder%@", newFolderDBName] - intoNewContainer: nil]; - } - } - 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 - inMemCtx: memCtx]; - } - } - } - else - rc = MAPISTORE_ERROR; - } - } - [targetFolder cleanupCaches]; - } - else - rc = [super moveCopyToFolder: targetFolder withNewName: newFolderName - isMove: isMove - isRecursive: isRecursive - inMemCtx: memCtx]; - - return rc; -} - -- (MAPIStoreMessage *) createMessage -{ - SOGoCacheObject *childObject; - - [[[self context] userContext] activate]; - - childObject = [SOGoCacheObject objectWithName: [SOGoCacheObject globallyUniqueObjectId] - inContainer: sogoObject]; - return [MAPIStoreMailVolatileMessage - mapiStoreObjectWithSOGoObject: childObject - inContainer: self]; -} - -- (id) lookupMessage: (NSString *) messageKey -{ - MAPIStoreMailMessage *message; - NSArray *rawBodyData; - - message = [super lookupMessage: messageKey]; - if (message) - { - rawBodyData = [bodyData objectForKey: messageKey]; - if (rawBodyData) - [message setBodyContentFromRawData: rawBodyData]; - } - - return message; -} - -- (NSArray *) rolesForExchangeRights: (uint32_t) rights -{ - NSMutableArray *roles; - - roles = [NSMutableArray arrayWithCapacity: 6]; - if (rights & RoleOwner) - [roles addObject: SOGoMailRole_Administrator]; - if (rights & RightsCreateItems) - { - [roles addObject: SOGoRole_ObjectCreator]; - [roles addObject: SOGoMailRole_Writer]; - [roles addObject: SOGoMailRole_Poster]; - } - if (rights & RightsDeleteAll) - { - [roles addObject: SOGoRole_ObjectEraser]; - [roles addObject: SOGoRole_FolderEraser]; - [roles addObject: SOGoMailRole_Expunger]; - } - if (rights & RightsEditAll) - [roles addObject: SOGoRole_ObjectEditor]; - if (rights & RightsReadItems) - [roles addObject: SOGoRole_ObjectViewer]; - if (rights & RightsCreateSubfolders) - [roles addObject: SOGoRole_FolderCreator]; - - // [self logWithFormat: @"roles for rights %.8x = (%@)", rights, roles]; - - return roles; -} - -- (uint32_t) exchangeRightsForRoles: (NSArray *) roles -{ - uint32_t rights = 0; - - if ([roles containsObject: SOGoMailRole_Administrator]) - rights |= (RoleOwner ^ RightsAll); - if ([roles containsObject: SOGoRole_ObjectCreator]) - rights |= RightsCreateItems; - if ([roles containsObject: SOGoRole_ObjectEraser] - && [roles containsObject: SOGoRole_FolderEraser]) - rights |= RightsDeleteAll | RightsDeleteOwn; - - if ([roles containsObject: SOGoRole_ObjectEditor]) - rights |= RightsEditAll | RightsEditOwn; - if ([roles containsObject: SOGoRole_ObjectViewer]) - rights |= RightsReadItems; - if ([roles containsObject: SOGoRole_FolderCreator]) - rights |= RightsCreateSubfolders; - - if (rights != 0) - rights |= RoleNone; /* actually "folder visible" */ - - // [self logWithFormat: @"rights for roles (%@) = %.8x", roles, rights]; - - return rights; -} - -- (enum mapistore_error) preloadMessageBodiesWithKeys: (NSArray *) keys - ofTableType: (enum mapistore_table_type) tableType -{ - NSEnumerator *enumerator; - NSUInteger max; - NSString *messageKey; - MAPIStoreMailMessage *message; - NSArray* bodyContent; - - if (tableType != MAPISTORE_MESSAGE_TABLE) - return MAPISTORE_SUCCESS; - - [bodyData removeAllObjects]; - - max = [keys count]; - if (max == 0) - return MAPISTORE_SUCCESS; - - enumerator = [keys objectEnumerator]; - while ((messageKey = [enumerator nextObject])) - { - message = [self lookupMessage: messageKey]; - if (message) - { - bodyContent = [message getBodyContent]; - if (bodyContent) - { - [bodyData setObject: bodyContent forKey: messageKey]; - } - } - } - - return MAPISTORE_SUCCESS; -} - -@end - -@implementation MAPIStoreOutboxFolder - -- (enum mapistore_error) getPidTagDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"Outbox" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -@end diff --git a/OpenChange/MAPIStoreMailFolderTable.h b/OpenChange/MAPIStoreMailFolderTable.h deleted file mode 100644 index 5ec2c4a5b..000000000 --- a/OpenChange/MAPIStoreMailFolderTable.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreMailFolderTable.h - this file is part of SOGo - * - * Copyright (C) 2015 Enrique J. Hernández - * - * Author: Enrique J. Hernández - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREMAILFOLDERTABLE_H -#define MAPISTOREMAILFOLDERTABLE_H - -#import "MAPIStoreFolderTable.h" - -@interface MAPIStoreMailFolderTable : MAPIStoreFolderTable -@end - -#endif /* MAPISTOREMAILFOLDERTABLE_H */ diff --git a/OpenChange/MAPIStoreMailFolderTable.m b/OpenChange/MAPIStoreMailFolderTable.m deleted file mode 100644 index 542e1dc8f..000000000 --- a/OpenChange/MAPIStoreMailFolderTable.m +++ /dev/null @@ -1,42 +0,0 @@ -/* MAPIStoreMailFolderTable.m - this file is part of SOGo - * - * Copyright (C) 2015 Enrique J. Hernández - * - * 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 - -#import "MAPIStoreMailFolderTable.h" -#import "MAPIStoreTypes.h" - -@implementation MAPIStoreMailFolderTable - -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property -{ - switch(property) - { - case PR_DISPLAY_NAME: - case PR_DISPLAY_NAME_UNICODE: - return @"name"; - default: - return nil; - } -} - - -@end - diff --git a/OpenChange/MAPIStoreMailMessage.h b/OpenChange/MAPIStoreMailMessage.h deleted file mode 100644 index 580be0a6e..000000000 --- a/OpenChange/MAPIStoreMailMessage.h +++ /dev/null @@ -1,88 +0,0 @@ -/* MAPIStoreMailMessage.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREMAILMESSAGE_H -#define MAPISTOREMAILMESSAGE_H - -#import "MAPIStoreMessage.h" - -@class NSString; -@class NSArray; -@class NSMutableArray; -@class NSMutableDictionary; - -@class MAPIStoreAppointmentWrapper; -@class MAPIStoreMailFolder; - -@interface MAPIStoreMailMessage : MAPIStoreMessage -{ - BOOL headerSetup; - BOOL mailIsEvent; - BOOL mailIsMeetingRequest; - BOOL mailIsSharingObject; - - NSMutableArray *bodyContentKeys; - NSMutableDictionary *bodyPartsEncodings; - NSMutableDictionary *bodyPartsCharsets; - NSMutableDictionary *bodyPartsMimeTypes; - NSMutableDictionary *bodyPartsMixed; - - NSString *headerCharset; - NSString *headerMimeType; - BOOL bodySetup; - NSArray *bodyContent; - BOOL fetchedAttachments; - - MAPIStoreAppointmentWrapper *appointmentWrapper; -} - -- (NSString *) subject; - -- (enum mapistore_error) getPidTagIconIndex: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagFlagStatus: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; - -- (enum mapistore_error) getPidTagMessageFlags: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagFollowupIcon: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagImportance: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagReceivedByEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagSenderEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagDisplayTo: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagDisplayCc: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagDisplayBcc: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; - -/* batch-mode helpers */ -- (void) setBodyContentFromRawData: (NSArray *) rawContent; -- (NSArray *) getBodyContent; - -@end - -#endif /* MAPISTOREMAILMESSAGE_H */ diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m deleted file mode 100644 index 6c20a6b04..000000000 --- a/OpenChange/MAPIStoreMailMessage.m +++ /dev/null @@ -1,2019 +0,0 @@ -/* MAPIStoreMailMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * Ludovic Marcotte - * - * 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 -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "Codepages.h" -#import "NSData+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" -#import "MAPIStoreAppointmentWrapper.h" -#import "MAPIStoreContext.h" -#import "MAPIStoreFolder.h" -#import "MAPIStoreMailAttachment.h" -#import "MAPIStoreMailFolder.h" -#import "MAPIStoreMapping.h" -#import "MAPIStoreSamDBUtils.h" -#import "MAPIStoreSharingMessage.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" - -#import "MAPIStoreMailMessage.h" - -#undef DEBUG -#include -#include -#include -#include - -#define BODY_CONTENT_TEXT 0 -#define BODY_CONTENT_HTML 1 - -@class iCalCalendar, iCalEvent; - -static Class NSExceptionK, MAPIStoreSharingMessageK; -static NSArray *acceptedMimeTypes; - -@interface NSString (MAPIStoreMIME) - -- (NSString *) _strippedBodyKey; - -@end - -@implementation NSString (MAPIStoreMIME) - -- (NSString *) _strippedBodyKey -{ - NSRange bodyRange; - NSString *strippedKey; - - bodyRange = [self rangeOfString: @"body.peek["]; - if (bodyRange.length > 0) - { - strippedKey = [self substringFromIndex: NSMaxRange (bodyRange)]; - strippedKey = [strippedKey substringToIndex: [strippedKey length] - 1]; - } - else - strippedKey = nil; - - return strippedKey; -} - -@end - -@implementation SOGoMailObject (MAPIStoreExtension) - -- (Class) mapistoreMessageClass -{ - return [MAPIStoreMailMessage class]; -} - -@end - -@implementation MAPIStoreMailMessage - -+ (void) initialize -{ - NSExceptionK = [NSException class]; - MAPIStoreSharingMessageK = [MAPIStoreSharingMessage class]; - acceptedMimeTypes = [[NSArray alloc] initWithObjects: @"text/calendar", - @"application/ics", - @"text/html", - @"text/plain", - nil]; -} - -- (id) init -{ - if ((self = [super init])) - { - bodyContentKeys = nil; - bodyPartsEncodings = nil; - bodyPartsCharsets = nil; - bodyPartsMimeTypes = nil; - bodyPartsMixed = nil; - - headerSetup = NO; - bodySetup = NO; - bodyContent = nil; - - mailIsEvent = NO; - mailIsMeetingRequest = NO; - mailIsSharingObject = NO; - headerCharset = nil; - headerMimeType = nil; - - appointmentWrapper = nil; - } - - return self; -} - -- (void) dealloc -{ - [bodyContentKeys release]; - [bodyPartsEncodings release]; - [bodyPartsCharsets release]; - [bodyPartsMimeTypes release]; - [bodyPartsMixed release]; - - [bodyContent release]; - - [headerMimeType release]; - [headerCharset release]; - [appointmentWrapper release]; - [super dealloc]; -} - -- (NSString *) subject -{ - return [sogoObject decodedSubject]; -} - -- (NSDate *) creationTime -{ - return [sogoObject date]; -} - -- (NSDate *) lastModificationTime -{ - return [sogoObject date]; -} - -- (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP - inMemCtx: (TALLOC_CTX *) memCtx -{ - BOOL listedProperties[65536]; - NSUInteger count; - uint16_t propId; - - if (mailIsSharingObject) - { - memset (listedProperties, NO, 65536 * sizeof (BOOL)); - [super getAvailableProperties: propertiesP inMemCtx: memCtx]; - for (count = 0; count < (*propertiesP)->cValues; count++) - { - propId = ((*propertiesP)->aulPropTag[count] >> 16) & 0xffff; - listedProperties[propId] = YES; - } - [MAPIStoreSharingMessage fillAvailableProperties: *propertiesP - withExclusions: listedProperties]; - return MAPISTORE_SUCCESS; - } - else - return [super getAvailableProperties: propertiesP inMemCtx: memCtx]; -} - -static NSComparisonResult -_compareBodyKeysByPriority (id entry1, id entry2, void *data) -{ - NSComparisonResult result; - NSArray *keys; - NSString *data1, *data2; - NSUInteger count1, count2; - - keys = data; - - data1 = [entry1 objectForKey: @"mimeType"]; - count1 = [keys indexOfObject: data1]; - data2 = [entry2 objectForKey: @"mimeType"]; - count2 = [keys indexOfObject: data2]; - - if (count1 == count2) - { - data1 = [entry1 objectForKey: @"key"]; - count1 = [data1 countOccurrencesOfString: @"."]; - data2 = [entry2 objectForKey: @"key"]; - count2 = [data2 countOccurrencesOfString: @"."]; - if (count1 == count2) - { - data1 = [data1 _strippedBodyKey]; - count1 = [data1 intValue]; - data2 = [data2 _strippedBodyKey]; - count2 = [data2 intValue]; - if (count1 == count2) - result = NSOrderedSame; - else if (count1 < count2) - result = NSOrderedAscending; - else - result = NSOrderedDescending; - } - else if (count1 < count2) - result = NSOrderedAscending; - else - result = NSOrderedDescending; - } - else if (count1 < count2) - result = NSOrderedAscending; - else - result = NSOrderedDescending; - - return result; -} - -- (void) _fetchHeaderData -{ - MAPIStoreSharingMessage *sharingMessage; - NSMutableArray *keys; - NSUInteger keysCount; - NSDictionary *partHeaderData, *parameters; - NSString *sharingHeader; - - keys = [NSMutableArray array]; - [sogoObject addRequiredKeysOfStructure: [sogoObject bodyStructure] - path: @"" - toArray: keys - acceptedTypes: acceptedMimeTypes - withPeek: YES]; - [keys sortUsingFunction: _compareBodyKeysByPriority context: acceptedMimeTypes]; - keysCount = [keys count]; - if (keysCount > 0) - { - NSUInteger i; - BOOL hasHtml = NO; - BOOL hasText = NO; - - bodyContentKeys = [[NSMutableArray alloc] initWithCapacity: keysCount]; - bodyPartsEncodings = [[NSMutableDictionary alloc] initWithCapacity: keysCount]; - bodyPartsCharsets = [[NSMutableDictionary alloc] initWithCapacity: keysCount]; - bodyPartsMimeTypes = [[NSMutableDictionary alloc] initWithCapacity: keysCount]; - bodyPartsMixed = [[NSMutableDictionary alloc] initWithCapacity: keysCount]; - - for (i = 0; i < keysCount; i++) - { - NSDictionary *bodyStructureKey; - NSString *key; - NSString *mimeType; - BOOL mixedPart; - NSString *strippedKey; - NSString *encoding; - NSString *charset; - NSDictionary *partParameters; - NSString *multipart; - - bodyStructureKey = [keys objectAtIndex: i]; - key = [bodyStructureKey objectForKey: @"key"]; - if (key == nil) - continue; - - [bodyContentKeys addObject: key]; - - strippedKey = [key _strippedBodyKey]; - partHeaderData = [sogoObject lookupInfoForBodyPart: strippedKey]; - - partParameters = [partHeaderData objectForKey: @"parameterList"]; - encoding = [partHeaderData objectForKey: @"encoding"]; - charset = [partParameters objectForKey: @"charset"]; - mimeType = [bodyStructureKey objectForKey: @"mimeType"]; - - /* multipart/mixed is the default type. - multipart/alternative is the only other type of multipart supported now. - */ - multipart = [bodyStructureKey objectForKey: @"multipart"]; - if ([multipart isEqualToString: @""]) - { - mixedPart = NO; - } - else - { - mixedPart = !([multipart isEqualToString: @"multipart/alternative"] || - [multipart isEqualToString: @"multipart/related"]); - } - - if (encoding) - [bodyPartsEncodings setObject: encoding forKey: key]; - if (charset) - [bodyPartsCharsets setObject: charset forKey: key]; - if (mimeType) - { - [bodyPartsMimeTypes setObject: mimeType forKey: key]; - if ([mimeType isEqualToString: @"text/plain"]) - hasText = YES; - else if ([mimeType isEqualToString: @"text/html"]) - hasHtml = YES; - } - [bodyPartsMixed setObject: [NSNumber numberWithBool: mixedPart] forKey: key]; - - if (i == 0) - { - ASSIGN (headerMimeType, mimeType); - parameters = partParameters; - } - - if (charset) - { - if (headerCharset == nil) - { - ASSIGN (headerCharset, charset); - } - else if (![headerCharset isEqualToString: charset]) - { - /* Because we have different charsets we will encode all in UTF-8 */ - ASSIGN (headerCharset, @"utf-8"); - } - } - - } - - if (!hasHtml || !hasText) - { - NSArray *bodyPartsMixedKeys = [bodyPartsMixed allKeys]; - for (i = 0; i < [keys count]; i++) - { - NSString *key = [bodyPartsMixedKeys objectAtIndex: i]; - [bodyPartsMixed setObject: [NSNumber numberWithBool: NO] forKey: key]; - } - } - - - if ([headerMimeType isEqualToString: @"text/calendar"] - || [headerMimeType isEqualToString: @"application/ics"]) - { - mailIsEvent = YES; - if ([[parameters objectForKey: @"method"] isEqualToString: @"REQUEST"]) - mailIsMeetingRequest = YES; - } - else - { - sharingHeader = [[sogoObject mailHeaders] objectForKey: @"x-ms-sharing-localtype"]; - if (sharingHeader) - { - mailIsSharingObject = YES; - /* It is difficult to subclass this in folder class, that's why - a sharing object is a proxy in a mail message */ - sharingMessage = [[MAPIStoreSharingMessage alloc] - initWithMailHeaders: [sogoObject mailHeaders] - andConnectionInfo: [[self context] connectionInfo] - fromMessage: self]; - [self addProxy: sharingMessage]; - [sharingMessage release]; - } - } - } - - headerSetup = YES; -} - -- (void) _fetchBodyData -{ - if (!headerSetup) - [self _fetchHeaderData]; - - if (!bodyContent && bodyContentKeys) - { - id result; - NSString *key; - NSEnumerator *enumerator; - NSMutableData *htmlContent; - NSMutableData *textContent; - NSStringEncoding headerEncoding; - - result = [sogoObject fetchParts: bodyContentKeys]; - result = [[result valueForKey: @"RawResponse"] objectForKey: @"fetch"]; - - htmlContent = [[NSMutableData alloc] initWithCapacity: 0]; - textContent = [[NSMutableData alloc] initWithCapacity: 0]; - - headerEncoding = [NSString stringEncodingForEncodingNamed: headerCharset]; - - enumerator = [bodyContentKeys objectEnumerator]; - while ((key = [enumerator nextObject])) - { - NSString *noPeekKey = [key stringByReplacingOccurrencesOfString: @"body.peek" - withString: @"body"]; - - NSData *content = [[result objectForKey: noPeekKey] objectForKey: @"data"]; - if (content == nil) - continue; - NSString *mimeType = [bodyPartsMimeTypes objectForKey: key]; - if (mimeType == nil) - continue; - NSString *contentEncoding = [bodyPartsEncodings objectForKey: key]; - if (contentEncoding == nil) - contentEncoding = @"7-bit"; - - /* We should provide a case for each of the types in acceptedMimeTypes */ - if (!mailIsEvent) - { - NSString *charset; - NSStringEncoding charsetEncoding; - NSString *stringValue; - BOOL html; - BOOL mixed = [[bodyPartsMixed objectForKey: key] boolValue]; - if ([mimeType isEqualToString: @"text/html"]) - { - html = YES; - } - else if ([mimeType isEqualToString: @"text/plain"]) - { - html = NO; - } - else - { - [self warnWithFormat: @"Unsupported MIME type for non-event body part: %@.", - mimeType]; - continue; - } - - content = [content bodyDataFromEncoding: contentEncoding]; - charset = [bodyPartsCharsets objectForKey: key]; - - stringValue = nil; - if (charset) - { - charsetEncoding = [NSString stringEncodingForEncodingNamed: charset]; - if ((charsetEncoding == headerEncoding) || !headerEncoding) - { - if (html) - [htmlContent appendData: content]; - else - [textContent appendData: content]; - } - else - { - stringValue = [content bodyStringFromCharset: charset]; - if (html) - [htmlContent appendData: [stringValue dataUsingEncoding: headerEncoding]]; - else - [textContent appendData: [stringValue dataUsingEncoding: headerEncoding]]; - } - - if (mixed) - { - // We must add it also to the other mail representation - if (html) - { - // TODO: html conversion to text - if (stringValue && headerEncoding) - [textContent appendData: [stringValue dataUsingEncoding: headerEncoding]]; - else - [textContent appendData: content]; - } - else - { - if (headerEncoding) - { - if (stringValue == nil) - stringValue = [content bodyStringFromCharset: charset]; - - stringValue = [stringValue stringByReplacingOccurrencesOfString: @"\n" - withString: @"
"]; - [htmlContent appendData: [stringValue dataUsingEncoding: headerEncoding]]; - } - else - { - [htmlContent appendData: content]; - } - } - } - } - else - { - /* Without charset we cannot mangle the text, so we add as it stands */ - if (html || mixed) - [htmlContent appendData: content]; - if (!html || mixed) - [textContent appendData: content]; - } - - } - else if ([mimeType isEqualToString: @"text/calendar"] || - [mimeType isEqualToString: @"application/ics"]) - { - content = [content bodyDataFromEncoding: contentEncoding]; - [textContent appendData: content]; - } - else - { - [self warnWithFormat: @"Unsupported combination for event body part. MIME type: %@", - mimeType]; - } - } - - NSArray *newBodyContent = [[NSArray alloc] initWithObjects: textContent, htmlContent, nil]; - ASSIGN (bodyContent, newBodyContent); - } - - bodySetup = YES; -} - -- (NSArray*) getBodyContent -{ - if (!bodySetup) - [self _fetchBodyData]; - return bodyContent; -} - -- (MAPIStoreAppointmentWrapper *) _appointmentWrapper -{ - NSData *textContent; - NSArray *events, *from; - iCalCalendar *calendar; - iCalEvent *event; - NSString *stringValue, *senderEmail; - MAPIStoreContext *context; - - if (!appointmentWrapper) - { - if (!bodySetup) - [self _fetchBodyData]; - - textContent = [bodyContent objectAtIndex: BODY_CONTENT_TEXT]; - stringValue = [textContent bodyStringFromCharset: headerCharset]; - calendar = [iCalCalendar parseSingleFromSource: stringValue]; - events = [calendar events]; - if ([events count] > 0) - { - event = [events objectAtIndex: 0]; - from = [sogoObject fromEnvelopeAddresses]; - if ([from count] > 0) - senderEmail = [[from objectAtIndex: 0] email]; - else - senderEmail = nil; - context = [self context]; - appointmentWrapper = [MAPIStoreAppointmentWrapper - wrapperWithICalEvent: event - andUser: [context activeUser] - andSenderEmail: senderEmail - withConnectionInfo: [context connectionInfo]]; - [appointmentWrapper retain]; - } - } - - return appointmentWrapper; -} - -- (enum mapistore_error) getPidTagChangeKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSData *changeKey; - MAPIStoreMailFolder *parentFolder; - NSString *nameInContainer; - - if (isNew) - rc = MAPISTORE_ERR_NOT_FOUND; - else - { - parentFolder = (MAPIStoreMailFolder *)[self container]; - nameInContainer = [self nameInContainer]; - changeKey = [parentFolder changeKeyForMessageWithKey: nameInContainer]; - if (!changeKey) - { - [self warnWithFormat: @"attempting to get change key" - @" by synchronising folder..."]; - [(MAPIStoreMailFolder *) container synchroniseCache]; - [parentFolder synchroniseCache]; - changeKey = [parentFolder changeKeyForMessageWithKey: nameInContainer]; - if (changeKey) - [self logWithFormat: @"got one"]; - else - { - [self errorWithFormat: @"still nothing. We crash!"]; - abort (); - } - } - *data = [changeKey asBinaryInMemCtx: memCtx]; - } - - return rc; -} - -- (enum mapistore_error) getPidTagPredecessorChangeList: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSData *changeList; - - if (isNew) - rc = MAPISTORE_ERR_NOT_FOUND; - else - { - changeList = [(MAPIStoreMailFolder *)[self container] - predecessorChangeListForMessageWithKey: [self nameInContainer]]; - if (!changeList) - { - [self warnWithFormat: @"attempting to get predecessor change list" - @" by synchronising folder..."]; - [(MAPIStoreMailFolder *) container synchroniseCache]; - changeList = [(MAPIStoreMailFolder *)[self container] - predecessorChangeListForMessageWithKey: [self nameInContainer]]; - if (changeList) - [self logWithFormat: @"got one"]; - else - { - [self errorWithFormat: @"still nothing. We crash!"]; - abort (); - } - } - *data = [changeList asBinaryInMemCtx: memCtx]; - } - - return rc; -} - -- (uint64_t) objectVersion -{ - uint64_t version = ULLONG_MAX; - NSString *uid, *changeNumber; - BOOL synced; - - uid = [(MAPIStoreMailFolder *) - container messageUIDFromMessageKey: [self nameInContainer]]; - if (uid) - { - changeNumber = [(MAPIStoreMailFolder *) container - changeNumberForMessageUID: uid]; - if (!changeNumber) - { - [self warnWithFormat: @"attempting to get change number" - @" by synchronising folder..."]; - [(MAPIStoreMailFolder *) container synchroniseCache]; - changeNumber = [(MAPIStoreMailFolder *) container - changeNumberForMessageUID: uid]; - if (changeNumber) - [self logWithFormat: @"got one"]; - else - { - [self warnWithFormat: @"attempting to get change number" - @" by synchronising this specific message..."]; - synced = [(MAPIStoreMailFolder *) container synchroniseCacheForUID: uid]; - if (synced) - { - changeNumber = [(MAPIStoreMailFolder *) container - changeNumberForMessageUID: uid]; - } - else - { - [self errorWithFormat: @"still nothing. We crash!"]; - abort(); - } - } - } - version = [changeNumber unsignedLongLongValue] >> 16; - } - else - abort(); - - return version; -} - -- (enum mapistore_error) getPidTagIconIndex: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t longValue; - - if (!headerSetup) - [self _fetchHeaderData]; - - if (mailIsEvent) - [[self _appointmentWrapper] getPidTagIconIndex: data inMemCtx: memCtx]; - else - { - /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */ - if ([sogoObject isNewMail]) - longValue = 0xffffffff; - else if ([sogoObject replied]) - longValue = 0x105; - else if ([sogoObject forwarded]) - longValue = 0x106; - else if ([sogoObject read]) - longValue = 0x100; - else - longValue = 0x101; - *data = MAPILongValue (memCtx, longValue); - } - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidResponseStatus: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidImapDeleted: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t longValue; - - if ([sogoObject deleted]) - longValue = 1; - else - longValue = 0; - *data = MAPILongValue (memCtx, longValue); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagSubjectPrefix: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *subject; - NSUInteger colIdx; - NSString *stringValue; - - /* As specified in [MS-OXCMAIL] 2.2.3.2.6.1, if there are three - or less characters followed by a colon at the beginning of - the subject, we can assume that's the subject prefix */ - subject = [self subject]; - colIdx = [subject rangeOfString: @":"].location; - if (colIdx != NSNotFound && colIdx < 4) - stringValue = [NSString stringWithFormat: @"%@: ", - [subject substringToIndex: colIdx]]; - else - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagNormalizedSubject: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue, *subject; - NSUInteger quoteStartIdx, quoteEndIdx, colIdx; - NSRange quoteRange; - - if (!headerSetup) - [self _fetchHeaderData]; - - subject = [self subject]; - if (mailIsMeetingRequest) - { - - /* SOGo "spices up" the invitation/update mail's subject, but - the client uses it to name the attendee's event, so we keep - only what's inside the quotes */ - quoteStartIdx = [subject rangeOfString: @"\""].location; - quoteEndIdx = [subject rangeOfString: @"\"" - options: NSBackwardsSearch].location; - if (quoteStartIdx != NSNotFound - && quoteEndIdx != NSNotFound - && quoteStartIdx != quoteEndIdx) - { - quoteRange = NSMakeRange(quoteStartIdx + 1, quoteEndIdx - quoteStartIdx - 1); - stringValue = [subject substringWithRange: quoteRange]; - } - else stringValue = subject; - } - else - { - - /* As specified in [MS-OXCMAIL] 2.2.3.2.6.1, if there are three - or less characters followed by a colon at the beginning of - the subject, we can assume that's the subject prefix */ - colIdx = [subject rangeOfString: @":"].location; - if (colIdx != NSNotFound && colIdx < 4) - stringValue = [[subject substringFromIndex: colIdx + 1] - stringByTrimmingLeadSpaces]; - else - stringValue = subject; - } - if (!stringValue) - stringValue = @""; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidFInvited: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - if (mailIsEvent) - [[self _appointmentWrapper] getPidTagMessageClass: data - inMemCtx: memCtx]; - else if (mailIsSharingObject) - *data = talloc_strdup (memCtx, "IPM.Sharing"); - else - *data = talloc_strdup (memCtx, "IPM.Note"); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagReplyRequested: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsMeetingRequest - ? [self getYes: data inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidTagResponseRequested: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagReplyRequested: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagLatestDeliveryTime: (void **) data // DOUBT - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagCreationTime: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagOriginalSubmitTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagCreationTime: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagClientSubmitTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagCreationTime: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagMessageDeliveryTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagCreationTime: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagMessageFlags: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSDictionary *coreInfos; - NSArray *flags; - unsigned int v = 0; - - coreInfos = [sogoObject fetchCoreInfos]; - flags = [coreInfos objectForKey: @"flags"]; - - // if ([container isKindOfClass: MAPIStoreSentItemsFolderK] - // || [container isKindOfClass: MAPIStoreDraftsFolderK]) - // v |= MSGFLAG_FROMME; - if ([flags containsObject: @"seen"]) - v |= MSGFLAG_READ; - if ([[self attachmentKeys] - count] > 0) - v |= MSGFLAG_HASATTACH; - - *data = MAPILongValue (memCtx, v); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagFlagStatus: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSDictionary *coreInfos; - NSArray *flags; - unsigned int v; - - coreInfos = [sogoObject fetchCoreInfos]; - - flags = [coreInfos objectForKey: @"flags"]; - if ([flags containsObject: @"flagged"]) - v = 2; - else - v = 0; - - *data = MAPILongValue (memCtx, v); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagFollowupIcon: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSDictionary *coreInfos; - NSArray *flags; - unsigned int v; - - coreInfos = [sogoObject fetchCoreInfos]; - - flags = [coreInfos objectForKey: @"flags"]; - if ([flags containsObject: @"flagged"]) - v = 6; - else - v = 0; - - *data = MAPILongValue (memCtx, v); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagSensitivity: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagOriginalSensitivity: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagSensitivity: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSentRepresentingAddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedRepresentingAddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedByAddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSenderAddressType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getSMTPAddrType: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) _getEmailAddressFromEmail: (NSString *) fullMail - inData: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NGMailAddress *ngAddress; - NSString *email; - - if (!fullMail) - fullMail = @""; - - ngAddress = [[NGMailAddressParser mailAddressParserWithString: fullMail] - parse]; - if ([ngAddress isKindOfClass: [NGMailAddress class]]) - email = [ngAddress address]; - else - email = @""; - - *data = [email asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) _getCNFromEmail: (NSString *) fullMail - inData: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NGMailAddress *ngAddress; - NSString *cn; - - if (!fullMail) - fullMail = @""; - - ngAddress = [[NGMailAddressParser mailAddressParserWithString: fullMail] - parse]; - if ([ngAddress isKindOfClass: [NGMailAddress class]]) - { - cn = [ngAddress displayName]; - - // If we don't have a displayName, we use the email address instead. This - // avoid bug #2119 - where Outlook won't display anything in the "From" field, - // nor in the recipient field if we reply to the email. - if (![cn length]) - cn = [ngAddress address]; - } - else - cn = @""; - - *data = [cn asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) _getEntryIdFromEmail: (NSString *) fullMail - inData: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *username, *cn, *email; - SOGoUserManager *mgr; - NSDictionary *contactInfos; - NGMailAddress *ngAddress; - NSData *entryId; - enum mapistore_error rc; - - if (fullMail) - { - ngAddress = [[NGMailAddressParser mailAddressParserWithString: fullMail] - parse]; - if ([ngAddress isKindOfClass: [NGMailAddress class]]) - { - email = [ngAddress address]; - cn = [ngAddress displayName]; - } - else - { - email = fullMail; - cn = @""; - } - - mgr = [SOGoUserManager sharedUserManager]; - contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - if (contactInfos) - { - username = [contactInfos objectForKey: @"sAMAccountName"]; - entryId = MAPIStoreInternalEntryId([[self context] connectionInfo], username); - } - else - entryId = MAPIStoreExternalEntryId (cn, email); - - *data = [entryId asBinaryInMemCtx: memCtx]; - - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidTagSenderEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getEmailAddressFromEmail: [sogoObject from] - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSenderName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getCNFromEmail: [sogoObject from] - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSenderEntryId: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getEntryIdFromEmail: [sogoObject from] - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagOriginalAuthorName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagSenderEmailAddress: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSentRepresentingEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagSenderEmailAddress: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSentRepresentingName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagSenderName: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSentRepresentingEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagSenderEntryId: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedByEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getEmailAddressFromEmail: [sogoObject to] - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedByName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getCNFromEmail: [sogoObject to] - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedByEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getEntryIdFromEmail: [sogoObject to] - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedRepresentingName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagReceivedByName: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedRepresentingEmailAddress: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagReceivedByEmailAddress: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagReceivedRepresentingEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagReceivedByEntryId: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagDisplayTo: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[sogoObject to] asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagOriginalDisplayTo: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagDisplayTo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagDisplayCc: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [sogoObject cc]; - if (!stringValue) - stringValue = @""; - - *data = [stringValue asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagOriginalDisplayCc: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagDisplayCc: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagDisplayBcc: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getEmptyString: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagOriginalDisplayBcc: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagDisplayBcc: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidNameContentType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"message/rfc822" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagImportance: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t v; - NSString *s; - - s = [[sogoObject mailHeaders] objectForKey: @"x-priority"]; - v = 0x1; - - if ([s hasPrefix: @"1"]) v = 0x2; - else if ([s hasPrefix: @"2"]) v = 0x2; - else if ([s hasPrefix: @"4"]) v = 0x0; - else if ([s hasPrefix: @"5"]) v = 0x0; - - *data = MAPILongValue (memCtx, v); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagInternetCodepage: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSNumber *codepage; - - codepage = [Codepages getCodepageFromName: headerCharset]; - if (!codepage) - { - [self warnWithFormat: @"Couldn't find codepage from `%@`. " - @"Using UTF-8 by default", headerCharset]; - codepage = [Codepages getCodepageFromName: @"utf-8"]; - } - - *data = MAPILongValue(memCtx, [codepage intValue]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagBody: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSData *textContent; - enum mapistore_error rc; - - if (!bodySetup) - [self _fetchBodyData]; - - if (!bodyContent) - { - *data = NULL; - return MAPISTORE_ERR_NOT_FOUND; - } - - if (mailIsEvent) - { - rc = [[self _appointmentWrapper] getPidTagBody: data - inMemCtx: memCtx]; - } - else - { - textContent = [bodyContent objectAtIndex: BODY_CONTENT_TEXT]; - if ([textContent length]) - { - NSString *stringValue = [textContent bodyStringFromCharset: headerCharset]; - *data = [stringValue asUnicodeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - else - { - *data = NULL; - rc = MAPISTORE_ERR_NOT_FOUND; - } - } - - return rc; -} - -- (enum mapistore_error) getPidTagHtml: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSData *htmlContent; - enum mapistore_error rc; - - if (!bodySetup) - [self _fetchBodyData]; - - if (!bodyContent || mailIsEvent) - { - *data = NULL; - return MAPISTORE_ERR_NOT_FOUND; - } - - htmlContent = [bodyContent objectAtIndex: BODY_CONTENT_HTML] ; - - if ([htmlContent length]) - { - *data = [htmlContent asBinaryInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - else - { - *data = NULL; - rc = MAPISTORE_ERR_NOT_FOUND; - } - - return rc; -} - -- (enum mapistore_error) getPidTagRtfCompressed: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = NULL; - - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagRtfInSync: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagInternetMessageId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[sogoObject messageId] asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagReadReceiptRequested: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidGlobalObjectId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidGlobalObjectId: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidCleanGlobalObjectId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidCleanGlobalObjectId: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidServerProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidServerProcessed: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidServerProcessingActions: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidServerProcessingActions: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidTagProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - - if (!headerSetup) - [self _fetchHeaderData]; - - if (mailIsEvent) - rc = [self getYes: data inMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -// - (enum mapistore_error) getPidLidServerProcessed: (void **) data -// inMemCtx: (TALLOC_CTX *) memCtx -// { -// if (!headerSetup) -// [self _fetchHeaderData]; - -// return (mailIsEvent -// ? [[self _appointmentWrapper] getPidLidServerProcessed: data -// inMemCtx: memCtx] -// : MAPISTORE_ERR_NOT_FOUND); -// } - -- (enum mapistore_error) getPidLidPrivate: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidPrivate: data - inMemCtx: memCtx] - : [self getNo: data inMemCtx: memCtx]); -} - -- (enum mapistore_error) getPidTagMessageEditorFormat: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t format; - - if (!headerSetup) - [self _fetchHeaderData]; - - if ([headerMimeType isEqualToString: @"text/plain"]) - format = EDITOR_FORMAT_PLAINTEXT; - else if ([headerMimeType isEqualToString: @"text/html"]) - format = EDITOR_FORMAT_HTML; - else - format = 0; /* EDITOR_FORMAT_DONTKNOW */ - - *data = MAPILongValue (memCtx, format); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidReminderSet: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidUseTnef: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidRemoteStatus: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidAgingDontAgeMe: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -/* event getters */ -- (enum mapistore_error) getPidTagStartDate: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidTagStartDate: data inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidAppointmentMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - - if (!headerSetup) - [self _fetchHeaderData]; - - if (mailIsEvent) - *data = talloc_strdup (memCtx, "IPM.Appointment"); - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidAppointmentStartWhole: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidAppointmentStartWhole: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidCommonStart: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidCommonStart: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidTagEndDate: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidTagEndDate: data inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidAppointmentEndWhole: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidAppointmentEndWhole: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidCommonEnd: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidCommonEnd: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidAppointmentDuration: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidAppointmentDuration: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidAppointmentSubType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidAppointmentSubType: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidBusyStatus: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidBusyStatus: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidLocation: (void **) data // LOCATION - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidLocation: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidIsRecurring: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidIsRecurring: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidRecurring: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidRecurring: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidAppointmentRecur: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidAppointmentRecur: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidTagOwnerAppointmentId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidTagOwnerAppointmentId: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidLidMeetingType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!headerSetup) - [self _fetchHeaderData]; - - return (mailIsEvent - ? [[self _appointmentWrapper] getPidLidMeetingType: data - inMemCtx: memCtx] - : MAPISTORE_ERR_NOT_FOUND); -} - -- (enum mapistore_error) getPidTagTransportMessageHeaders: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSDictionary *mailHeaders; - NSEnumerator *keyEnumerator; - NSMutableArray *headers; - NGMimeMessageGenerator *g; - NSString *headerKey, *fullHeader, *headerGenerated; - id headerValue; - NSData *headerData; - - /* Let's encode each mail header and put them on 'headers' array */ - mailHeaders = [sogoObject mailHeaders]; - headers = [NSMutableArray arrayWithCapacity: [mailHeaders count]]; - - g = [[NGMimeMessageGenerator alloc] init]; - keyEnumerator = [mailHeaders keyEnumerator]; - while ((headerKey = [keyEnumerator nextObject])) - { - headerValue = [mailHeaders objectForKey: headerKey]; - - headerData = [g generateDataForHeaderField: headerKey value: headerValue]; - headerGenerated = [[NSString alloc] initWithData: headerData encoding:NSUTF8StringEncoding]; - fullHeader = [NSString stringWithFormat:@"%@: %@", headerKey, headerGenerated]; - [headerGenerated release]; - - [headers addObject: fullHeader]; - } - [g release]; - - *data = [[headers componentsJoinedByString:@"\n"] asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (void) getMessageData: (struct mapistore_message **) dataPtr - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSArray *addresses; - NSString *addressMethods[] = { @"fromEnvelopeAddresses", - @"toEnvelopeAddresses", - @"ccEnvelopeAddresses", - @"bccEnvelopeAddresses" }; - enum ulRecipClass addressTypes[] = { MAPI_ORIG, MAPI_TO, - MAPI_CC, MAPI_BCC }; - NSUInteger arrayCount, count, recipientStart, max, p; - NGImap4EnvelopeAddress *currentAddress; - NSString *username, *cn, *email; - NSData *entryId; - NSDictionary *contactInfos; - SOGoUserManager *mgr; - struct mapistore_message *msgData; - struct mapistore_message_recipient *recipient; - - [super getMessageData: &msgData inMemCtx: memCtx]; - - if (!headerSetup) - [self _fetchHeaderData]; - - if (mailIsEvent) - [[self _appointmentWrapper] fillMessageData: msgData - inMemCtx: memCtx]; - else - { - mgr = [SOGoUserManager sharedUserManager]; - - /* Retrieve recipients from the message */ - - msgData->columns = set_SPropTagArray (msgData, 9, - PR_OBJECT_TYPE, - PR_DISPLAY_TYPE, - PR_7BIT_DISPLAY_NAME_UNICODE, - PR_SMTP_ADDRESS_UNICODE, - PR_SEND_INTERNET_ENCODING, - PR_RECIPIENT_DISPLAY_NAME_UNICODE, - PR_RECIPIENT_FLAGS, - PR_RECIPIENT_ENTRYID, - PR_RECIPIENT_TRACKSTATUS); - - msgData->recipients_count = 0; - msgData->recipients = NULL; - - recipientStart = 0; - - for (arrayCount = 0; arrayCount < 4; arrayCount++) - { - addresses = [sogoObject performSelector: NSSelectorFromString (addressMethods[arrayCount])]; - max = [addresses count]; - if (max > 0) - { - msgData->recipients_count += max; - msgData->recipients = talloc_realloc (msgData, msgData->recipients, struct mapistore_message_recipient, msgData->recipients_count); - - for (count = 0; count < max; count++) - { - recipient = msgData->recipients + recipientStart; - currentAddress = [addresses objectAtIndex: count]; - cn = [currentAddress personalName]; - email = [currentAddress baseEMail]; - if ([cn length] == 0) - cn = email; - contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - - if (contactInfos) - { - username = [contactInfos objectForKey: @"sAMAccountName"]; - recipient->username = [username asUnicodeInMemCtx: msgData]; - entryId = MAPIStoreInternalEntryId ([[self context] connectionInfo], username); - } - else - { - recipient->username = NULL; - entryId = MAPIStoreExternalEntryId (cn, email); - } - recipient->type = addressTypes[arrayCount]; - - /* properties */ - p = 0; - recipient->data = talloc_array (msgData, void *, msgData->columns->cValues); - memset (recipient->data, 0, msgData->columns->cValues * sizeof (void *)); - - // PR_OBJECT_TYPE = MAPI_MAILUSER (see MAPI_OBJTYPE) - recipient->data[p] = MAPILongValue (msgData, MAPI_MAILUSER); - p++; - - // PR_DISPLAY_TYPE = DT_MAILUSER (see MS-NSPI) - recipient->data[p] = MAPILongValue (msgData, 0); - p++; - - // PR_7BIT_DISPLAY_NAME_UNICODE - recipient->data[p] = [cn asUnicodeInMemCtx: msgData]; - p++; - - // PR_SMTP_ADDRESS_UNICODE - recipient->data[p] = [email asUnicodeInMemCtx: msgData]; - p++; - - // PR_SEND_INTERNET_ENCODING = 0x00060000 (plain text, see OXCMAIL) - recipient->data[p] = MAPILongValue (msgData, 0x00060000); - p++; - - // PR_RECIPIENT_DISPLAY_NAME_UNICODE - recipient->data[p] = [cn asUnicodeInMemCtx: msgData]; - p++; - - // PR_RECIPIENT_FLAGS - recipient->data[p] = MAPILongValue (msgData, 0x01); - p++; - - // PR_RECIPIENT_ENTRYID - recipient->data[p] = [entryId asBinaryInMemCtx: msgData]; - p++; - - // PR_RECIPIENT_TRACKSTATUS - recipient->data[p] = MAPILongValue (msgData, 0x00); - p++; - - recipientStart++; - } - } - } - } - *dataPtr = msgData; -} - -- (void) _fetchAttachmentPartsInBodyInfo: (NSDictionary *) bodyInfo - withPrefix: (NSString *) keyPrefix -{ - NSArray *parts; - NSUInteger count, max; - - if ([[bodyInfo filename] length] > 0) - { - if ([keyPrefix length] == 0) - keyPrefix = @"0"; - [attachmentParts setObject: bodyInfo - forKey: keyPrefix]; - } - else - { - if ([keyPrefix length] > 0) - keyPrefix = [NSString stringWithFormat: @"%@/", keyPrefix]; - parts = [bodyInfo objectForKey: @"parts"]; - max = [parts count]; - for (count = 0; count < max; count++) - [self _fetchAttachmentPartsInBodyInfo: [parts objectAtIndex: count] - withPrefix: [NSString stringWithFormat: @"%@%d", - keyPrefix, count + 1]]; - } -} - -- (NSArray *) attachmentKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - [self _fetchAttachmentPartsInBodyInfo: [sogoObject bodyStructure] - withPrefix: @""]; - - return [super attachmentKeysMatchingQualifier: qualifier - andSortOrderings: sortOrderings]; -} - -- (id) lookupAttachment: (NSString *) childKey -{ - MAPIStoreMailAttachment *attachment; - SOGoMailBodyPart *currentPart; - NSArray *keyParts; - NSUInteger count, max; - - attachment = nil; - - keyParts = [childKey componentsSeparatedByString: @"/"]; - max = [keyParts count]; - if (max > 0) - { - [[self userContext] activate]; - - currentPart = [sogoObject lookupName: [keyParts objectAtIndex: 0] - inContext: nil - acquire: NO]; - if ([currentPart isKindOfClass: NSExceptionK]) - currentPart = nil; - - for (count = 1; currentPart && count < max; count++) - { - [parentContainersBag addObject: currentPart]; - currentPart = [currentPart lookupName: [keyParts objectAtIndex: count] - inContext: nil - acquire: NO]; - if ([currentPart isKindOfClass: NSExceptionK]) - currentPart = nil; - } - - if (currentPart) - { - attachment = [MAPIStoreMailAttachment - mapiStoreObjectInContainer: self]; - [attachment setBodyPart: currentPart]; - [attachment setBodyInfo: [attachmentParts objectForKey: childKey]]; - [attachment setAID: [[self attachmentKeys] indexOfObject: childKey]]; - } - } - - return attachment; -} - -- (enum mapistore_error) setReadFlag: (uint8_t) flag -{ - /* TODO: notifications should probably be emitted from here */ - if (flag & CLEAR_READ_FLAG) - [properties setObject: [NSNumber numberWithBool: NO] forKey: @"read_flag_set"]; - else - [properties setObject: [NSNumber numberWithBool: YES] forKey: @"read_flag_set"]; - - return MAPISTORE_SUCCESS; -} - -- (void) setBodyContentFromRawData: (NSArray *) rawContent -{ - if (!headerSetup) - [self _fetchHeaderData]; - - ASSIGN (bodyContent, rawContent); - bodySetup = YES; -} - -- (MAPIStoreSharingMessage *) _sharingObject -{ - /* Get the sharing object if available */ - NSUInteger i, max; - id proxy; - - max = [proxies count]; - for (i = 0; i < max; i++) { - proxy = [proxies objectAtIndex: i]; - if ([proxy isKindOfClass: MAPIStoreSharingMessageK]) - return proxy; - } - return nil; -} - -- (void) save: (TALLOC_CTX *) memCtx -{ - BOOL modified = NO; - BOOL seen, storedSeenFlag; - NSNumber *value; - NSString *imapFlag = @"\\Seen"; - - value = [properties objectForKey: MAPIPropertyKey (PR_FLAG_STATUS)]; - if (value) - { - /* We don't handle the concept of "Follow Up" */ - if ([value intValue] == 2) - [sogoObject addFlags: @"\\Flagged"]; - else /* 0: unflagged, 1: follow up complete */ - [sogoObject removeFlags: @"\\Flagged"]; - - modified = YES; - } - - /* Manage seen flag on save */ - value = [properties objectForKey: @"read_flag_set"]; - if (value) - { - seen = [value boolValue]; - storedSeenFlag = [[[sogoObject fetchCoreInfos] objectForKey: @"flags"] containsObject: @"seen"]; - /* We modify the flags anyway to generate a new change number */ - if (seen) - { - if (storedSeenFlag) - [sogoObject removeFlags: imapFlag]; - [sogoObject addFlags: imapFlag]; - } - else - { - if (!storedSeenFlag) - [sogoObject addFlags: imapFlag]; - [sogoObject removeFlags: imapFlag]; - } - modified = YES; - } - - if (modified) - [(MAPIStoreMailFolder *)[self container] synchroniseCache]; - - if (mailIsSharingObject) - [[self _sharingObject] saveWithMessage: self - andSOGoObject: sogoObject]; - -} - -@end diff --git a/OpenChange/MAPIStoreMailMessageTable.h b/OpenChange/MAPIStoreMailMessageTable.h deleted file mode 100644 index 8efa43c16..000000000 --- a/OpenChange/MAPIStoreMailMessageTable.h +++ /dev/null @@ -1,35 +0,0 @@ -/* MAPIStoreMailMessageTable.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREMAILMESSAGETABLE_H -#define MAPISTOREMAILMESSAGETABLE_H - -#import "MAPIStoreMessageTable.h" - -@interface MAPIStoreMailMessageTable : MAPIStoreMessageTable -{ - BOOL fetchedCoreInfos; -} - -@end - -#endif /* MAPISTOREMAILMESSAGETABLE_H */ diff --git a/OpenChange/MAPIStoreMailMessageTable.m b/OpenChange/MAPIStoreMailMessageTable.m deleted file mode 100644 index 2375ca39b..000000000 --- a/OpenChange/MAPIStoreMailMessageTable.m +++ /dev/null @@ -1,359 +0,0 @@ -/* MAPIStoreMailMessageTable.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import - -#import -#import -#import - -#import "MAPIStoreContext.h" -#import "MAPIStoreMailFolder.h" -#import "MAPIStoreMailMessage.h" -#import "MAPIStoreTypes.h" -#import "NSData+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreMailMessageTable.h" - -#undef DEBUG -#include -#include - -@implementation MAPIStoreMailMessageTable - -static Class MAPIStoreMailMessageK, NSDataK, NSStringK; - -+ (void) initialize -{ - MAPIStoreMailMessageK = [MAPIStoreMailMessage class]; - NSDataK = [NSData class]; - NSStringK = [NSString class]; -} - -+ (Class) childObjectClass -{ - return MAPIStoreMailMessageK; -} - -- (id) init -{ - if ((self = [super init])) - { - ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]); - fetchedCoreInfos = NO; - } - - return self; -} - -- (void) cleanupCaches -{ - [(MAPIStoreMailFolder *) container synchroniseCache]; - fetchedCoreInfos = NO; - [super cleanupCaches]; -} - -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property -{ - static NSMutableDictionary *knownProperties = nil; - - if (!knownProperties) - { - knownProperties = [NSMutableDictionary new]; - [knownProperties setObject: @"DATE" - forKey: MAPIPropertyKey (PR_CLIENT_SUBMIT_TIME)]; - [knownProperties setObject: @"DATE" - forKey: MAPIPropertyKey (PR_MESSAGE_DELIVERY_TIME)]; - [knownProperties setObject: @"MESSAGE-ID" - forKey: MAPIPropertyKey (PR_INTERNET_MESSAGE_ID_UNICODE)]; - } - - return [knownProperties objectForKey: MAPIPropertyKey (property)]; -} - -/* restrictions */ - -- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState rc; - id value; - NSNumber *modseq; - - value = NSObjectFromMAPISPropValue (&res->lpProp); - switch ((uint32_t) res->ulPropTag) - { - case PR_MESSAGE_CLASS_UNICODE: - if ([value isEqualToString: @"IPM.Note"]) - rc = MAPIRestrictionStateAlwaysTrue; - else - rc = MAPIRestrictionStateAlwaysFalse; - break; - - case PidLidAppointmentStartWhole: - case PidLidAppointmentEndWhole: - case PidLidRecurring: - //[self logWithFormat: @"apt restriction on mail folder?"]; - rc = MAPIRestrictionStateAlwaysFalse; - break; - - case PidLidAutoProcessState: - if ([value intValue] == 0) - rc = MAPIRestrictionStateAlwaysTrue; - else - rc = MAPIRestrictionStateAlwaysFalse; - break; - - case PR_SEARCH_KEY: - rc = MAPIRestrictionStateAlwaysFalse; - break; - - case 0x0fff00fb: /* PR_ENTRY_ID in PtyServerId form */ - case 0x0ff600fb: - /* resProperty: struct mapi_SPropertyRestriction - relop : 0x04 (4) - ulPropTag : UNKNOWN_ENUM_VALUE (0xFF600FB) - lpProp: struct mapi_SPropValue - ulPropTag : UNKNOWN_ENUM_VALUE (0xFF600FB) - value : union mapi_SPropValue_CTR(case 251) - bin : SBinary_short cb=21 -[0000] 01 01 00 1A 00 00 00 00 00 9C 83 E8 0F 00 00 00 ........ ........ -[0010] 00 00 00 00 00 ..... */ - rc = MAPIRestrictionStateAlwaysFalse; - break; - - case PidTagConversationKey: - rc = MAPIRestrictionStateAlwaysFalse; - break; - - case PidTagChangeNumber: - { - value = [NSString stringWithFormat: @"0x%.16llx", [value unsignedLongLongValue]]; - modseq = [(MAPIStoreMailFolder *) - container modseqFromMessageChangeNumber: value]; - //[self logWithFormat: @"change number from oxcfxics: %.16lx", [value unsignedLongLongValue]]; - //[self logWithFormat: @" modseq: %.16lx", [modseq unsignedLongLongValue]]; - if (modseq) - { - if (res->relop == RELOP_GT) - modseq = [NSNumber numberWithUnsignedLongLong: - [modseq unsignedLongLongValue] + 1]; - - } - else - modseq = [NSNumber numberWithUnsignedLongLong: 0]; - - if (res->relop == RELOP_GT || res->relop == RELOP_GE) - { - *qualifier = [[EOKeyValueQualifier alloc] initWithKey: @"MODSEQ" - operatorSelector: EOQualifierOperatorGreaterThanOrEqualTo - value: modseq]; - [*qualifier autorelease]; - rc = MAPIRestrictionStateNeedsEval; - } - else - { - /* Ignore other operations as IMAP only support MODSEQ >= X */ - [self warnWithFormat: @"Ignoring '%@' as only supported operators are > and >=", - NSStringFromSelector ([self operatorFromRestrictionOperator: res->relop])]; - rc = MAPIRestrictionStateAlwaysTrue; - } - } - break; - - default: - rc = [super evaluatePropertyRestriction: res intoQualifier: qualifier]; - } - - return rc; -} - -- (MAPIRestrictionState) evaluateContentRestriction: (struct mapi_SContentRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState rc; - id value; - - value = NSObjectFromMAPISPropValue (&res->lpProp); - if ([value isKindOfClass: NSDataK]) - { - value = [[NSString alloc] initWithData: value - encoding: NSUTF8StringEncoding]; - [value autorelease]; - } - else if (![value isKindOfClass: NSStringK]) - [NSException raise: @"MAPIStoreTypeConversionException" - format: @"unhandled content restriction for class '%@'", - NSStringFromClass ([value class])]; - - switch (res->ulPropTag) - { - case PR_MESSAGE_CLASS_UNICODE: - if ([value isEqualToString: @"IPM.Note"]) - rc = MAPIRestrictionStateAlwaysTrue; - else - rc = MAPIRestrictionStateAlwaysFalse; - break; - case PidTagConversationKey: - rc = MAPIRestrictionStateAlwaysFalse; - break; - default: - rc = [super evaluateContentRestriction: res intoQualifier: qualifier]; - } - - return rc; -} - -- (MAPIRestrictionState) evaluateExistRestriction: (struct mapi_SExistRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState rc; - - switch (res->ulPropTag) - { - case PR_MESSAGE_CLASS_UNICODE: - rc = MAPIRestrictionStateAlwaysFalse; - break; - case PR_MESSAGE_DELIVERY_TIME: - rc = MAPIRestrictionStateAlwaysTrue; - break; - case PR_CLIENT_SUBMIT_TIME: - rc = MAPIRestrictionStateAlwaysTrue; - break; - case PR_PROCESSED: - rc = MAPIRestrictionStateAlwaysFalse; - break; - default: - rc = [super evaluateExistRestriction: res intoQualifier: qualifier]; - } - - return rc; -} - -/* sorting */ - -- (NSString *) _sortIdentifierForProperty: (enum MAPITAGS) property -{ - static NSMutableDictionary *knownProperties = nil; - - if (!knownProperties) - { - knownProperties = [NSMutableDictionary new]; - /* ARRIVAL, CC */ - [knownProperties setObject: @"DATE" - forKey: MAPIPropertyKey (PR_CLIENT_SUBMIT_TIME)]; - [knownProperties setObject: @"DATE" - forKey: MAPIPropertyKey (PR_MESSAGE_DELIVERY_TIME)]; - [knownProperties setObject: @"FROM" - forKey: MAPIPropertyKey (PR_SENT_REPRESENTING_NAME_UNICODE)]; - [knownProperties setObject: @"SIZE" - forKey: MAPIPropertyKey (PR_MESSAGE_SIZE)]; - [knownProperties setObject: @"SIZE" - forKey: MAPIPropertyKey (PidLidRemoteTransferSize)]; - [knownProperties setObject: @"SUBJECT" - forKey: MAPIPropertyKey (PR_NORMALIZED_SUBJECT_UNICODE)]; - [knownProperties setObject: @"TO" - forKey: MAPIPropertyKey (PR_DISPLAY_TO_UNICODE)]; - } - - return [knownProperties objectForKey: MAPIPropertyKey (property)]; -} - -- (void) setSortOrder: (const struct SSortOrderSet *) set -{ - NSMutableArray *newSortOrderings; - NSMutableString *newSortOrdering; - struct SSortOrder *sortOrder; - NSString *sortIdentifier; - const char *propName; - uint16_t count; - - if (set) - { - /* TODO: */ - if (set->cCategories > 0) - [self errorWithFormat: @"we don't handle sort categories yet"]; - - newSortOrderings = [NSMutableArray array]; - - for (count = 0; count < set->cSorts; count++) - { - sortOrder = set->aSort + count; - sortIdentifier - = [self _sortIdentifierForProperty: sortOrder->ulPropTag]; - if (sortIdentifier) - { - newSortOrdering = [NSMutableString string]; - if (sortOrder->ulOrder == TABLE_SORT_DESCEND) - [newSortOrdering appendString: @" REVERSE"]; - else if (sortOrder->ulOrder == TABLE_SORT_MAXIMUM_CATEGORY) - [self errorWithFormat: @"TABLE_SORT_MAXIMUM_CATEGORY is not handled"]; - [newSortOrdering appendFormat: @" %@", sortIdentifier]; - [newSortOrderings addObject: [newSortOrdering substringFromIndex: 1]]; - } - else - { - propName = get_proptag_name (sortOrder->ulPropTag); - if (!propName) - propName = ""; - [self errorWithFormat: - @"sort unhandled for property: %s (0x%.8x)", - propName, sortOrder->ulPropTag]; - } - } - if ([newSortOrderings count] > 0) - ASSIGN (sortOrderings, newSortOrderings); - else - ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]); - //[self logWithFormat: @"new sort orderings: '%@'", sortOrderings]; - } - else - ASSIGN (sortOrderings, [NSArray arrayWithObject: @"ARRIVAL"]); - - [self cleanupCaches]; -} - -- (enum mapistore_error) getRow: (struct mapistore_property_data **) dataP - withRowID: (uint32_t) rowId - andQueryType: (enum mapistore_query_type) queryType - inMemCtx: (TALLOC_CTX *) memCtx -{ - if (!fetchedCoreInfos) - { - fetchedCoreInfos = YES; - [(SOGoMailFolder *) [(MAPIStoreMailFolder *) container sogoObject] - prefetchCoreInfosForMessageKeys: [self restrictedChildKeys]]; - } - - return [super getRow: dataP withRowID: rowId - andQueryType: queryType inMemCtx: memCtx]; -} - -@end diff --git a/OpenChange/MAPIStoreMailVolatileMessage.h b/OpenChange/MAPIStoreMailVolatileMessage.h deleted file mode 100644 index 417faeff6..000000000 --- a/OpenChange/MAPIStoreMailVolatileMessage.h +++ /dev/null @@ -1,34 +0,0 @@ -/* MAPIStoreMailVolatileMessage.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREMAILVOLATILEMESSAGE_H -#define MAPISTOREMAILVOLATILEMESSAGE_H - -#import "MAPIStoreMessage.h" - -@interface MAPIStoreMailVolatileMessage : MAPIStoreMessage - -- (enum mapistore_error) submitWithFlags: (enum SubmitFlags) flags; - -@end - -#endif /* MAPISTOREMAILVOLATILEMESSAGE_H */ diff --git a/OpenChange/MAPIStoreMailVolatileMessage.m b/OpenChange/MAPIStoreMailVolatileMessage.m deleted file mode 100644 index 36c3179e7..000000000 --- a/OpenChange/MAPIStoreMailVolatileMessage.m +++ /dev/null @@ -1,1190 +0,0 @@ -/* MAPIStoreMailVolatileMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -/* TODO: - - calendar invitations - - merge some code in a common module with SOGoDraftObject -*/ - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "Codepages.h" -#import "MAPIStoreAttachment.h" -#import "MAPIStoreAttachmentTable.h" -#import "MAPIStoreContext.h" -#import "MAPIStoreMailFolder.h" -#import "MAPIStoreMIME.h" -#import "MAPIStoreMapping.h" -#import "MAPIStoreSamDBUtils.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSData+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreMailVolatileMessage.h" - -#undef DEBUG -#include -#include -#include - -static Class NSNumberK = Nil; - -static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" }; - -// -// Useful extension that comes from Pantomime which is also -// released under the LGPL. We should eventually merge -// this with the same category found in SOPE's NGSmtpClient.m -// or simply drop sope-mime in favor of Pantomime -// -@interface NSMutableData (DataCleanupExtension) - -- (NSRange) rangeOfCString: (const char *) theCString; -- (NSRange) rangeOfCString: (const char *) theCString - options: (unsigned int) theOptions - range: (NSRange) theRange; -@end - -@implementation NSMutableData (DataCleanupExtension) - -- (NSRange) rangeOfCString: (const char *) theCString -{ - return [self rangeOfCString: theCString - options: 0 - range: NSMakeRange(0,[self length])]; -} - --(NSRange) rangeOfCString: (const char *) theCString - options: (unsigned int) theOptions - range: (NSRange) theRange -{ - const char *b, *bytes; - int i, len, slen; - - if (!theCString) - { - return NSMakeRange(NSNotFound,0); - } - - bytes = [self bytes]; - len = [self length]; - slen = strlen(theCString); - - b = bytes; - - if (len > theRange.location + theRange.length) - { - len = theRange.location + theRange.length; - } - - if (theOptions == NSCaseInsensitiveSearch) - { - i = theRange.location; - b += i; - - for (; i <= len-slen; i++, b++) - { - if (!strncasecmp(theCString,b,slen)) - { - return NSMakeRange(i,slen); - } - } - } - else - { - i = theRange.location; - b += i; - - for (; i <= len-slen; i++, b++) - { - if (!memcmp(theCString,b,slen)) - { - return NSMakeRange(i,slen); - } - } - } - - return NSMakeRange(NSNotFound,0); -} - -@end - -@interface MAPIStoreAttachment (MAPIStoreMIME) - -- (BOOL) hasContentId; -- (NGMimeBodyPart *) asMIMEBodyPart; - -@end - -@implementation MAPIStoreAttachment (MAPIStoreMIME) - -- (BOOL) hasContentId -{ - NSString *contentId = [properties - objectForKey: MAPIPropertyKey (PR_ATTACH_CONTENT_ID_UNICODE)]; - return contentId && [contentId length] > 0; -} - -- (NGMimeBodyPart *) asMIMEBodyPart -{ - NGMimeBodyPart *bodyPart = nil; - NSString *filename, *mimeType, *baseDisposition, *contentType, - *contentDisposition, *contentId; - NSData *content; - struct mapistore_connection_info *connInfo; - SOGoDomainDefaults *dd; - SOGoUser *activeUser; - NGMutableHashMap *map; - - content = [properties objectForKey: MAPIPropertyKey (PR_ATTACH_DATA_BIN)]; - if (content) - { - filename - = [properties - objectForKey: MAPIPropertyKey (PR_ATTACH_LONG_FILENAME_UNICODE)]; - if (![filename length]) - filename - = [properties - objectForKey: MAPIPropertyKey (PR_ATTACH_FILENAME_UNICODE)]; - - mimeType = [properties - objectForKey: MAPIPropertyKey (PR_ATTACH_MIME_TAG_UNICODE)]; - if (!mimeType && [filename length]) - mimeType = [[MAPIStoreMIME sharedMAPIStoreMIME] - mimeTypeForExtension: [filename pathExtension]]; - if (!mimeType) - mimeType = @"application/octet-stream"; - - if ([mimeType hasPrefix: @"text/"]) - { - connInfo = [[self context] connectionInfo]; - activeUser = [SOGoUser userWithLogin: [NSString stringWithUTF8String: connInfo->username]]; - dd = [activeUser domainDefaults]; - baseDisposition = ([dd mailAttachTextDocumentsInline] - ? @"inline" : @"attachment"); - } - else if ([mimeType hasPrefix: @"image/"] || [mimeType hasPrefix: @"message"]) - baseDisposition = @"inline"; - else - baseDisposition = @"attachment"; - - if ([filename length] > 0) - { - contentType = [NSString stringWithFormat: @"%@; name=\"%@\"", - mimeType, filename]; - contentDisposition = [NSString stringWithFormat: @"%@; filename=\"%@\"", - baseDisposition, filename]; - } - else - { - contentType = mimeType; - contentDisposition = baseDisposition; - } - - map = [[NGMutableHashMap alloc] initWithCapacity: 16]; - [map addObject: contentType forKey: @"content-type"]; - [map addObject: contentDisposition forKey: @"content-disposition"]; - contentId = [properties - objectForKey: MAPIPropertyKey (PR_ATTACH_CONTENT_ID_UNICODE)]; - if (contentId && [contentId length] > 0) - [map setObject: [NSString stringWithFormat: @"<%@>", contentId] - forKey: @"content-id"]; - bodyPart = [NGMimeBodyPart bodyPartWithHeader: map]; - [bodyPart setBody: content]; - [map release]; - } - else - [self errorWithFormat: @"no content for attachment"]; - - return bodyPart; -} - -@end - -@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 - ? [version unsignedLongLongValue] - : ULLONG_MAX); -} - -- (enum mapistore_error) getPidTagMessageClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPM.Note" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagChangeKey: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - NSData *changeKey; - enum mapistore_error 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 -{ - NSArray *recipients; - NSUInteger count, max, recipientsMax, p, current; - NSString *username, *cn, *email; - NSData *entryId; - NSDictionary *allRecipients, *dict, *contactInfos; - SOGoUserManager *mgr; - struct mapistore_message *msgData; - struct mapistore_message_recipient *recipient; - enum ulRecipClass type; - - // [super getMessageData: &msgData inMemCtx: memCtx]; - - msgData = talloc_zero (memCtx, struct mapistore_message); - - allRecipients = [properties objectForKey: @"recipients"]; - msgData->columns = set_SPropTagArray (msgData, 9, - PR_OBJECT_TYPE, - PR_DISPLAY_TYPE, - PR_7BIT_DISPLAY_NAME_UNICODE, - PR_SMTP_ADDRESS_UNICODE, - PR_SEND_INTERNET_ENCODING, - PR_RECIPIENT_DISPLAY_NAME_UNICODE, - PR_RECIPIENT_FLAGS, - PR_RECIPIENT_ENTRYID, - PR_RECIPIENT_TRACKSTATUS); - - /* Retrieve recipients from the message */ - max = ([[allRecipients objectForKey: @"orig"] count] - + [[allRecipients objectForKey: @"to"] count] - + [[allRecipients objectForKey: @"cc"] count] - + [[allRecipients objectForKey: @"bcc"] count]); - - mgr = [SOGoUserManager sharedUserManager]; - msgData->recipients_count = max; - msgData->recipients = talloc_array (msgData, struct mapistore_message_recipient, max); - current = 0; - for (type = MAPI_ORIG; type <= MAPI_BCC; type++) - { - recipients = [allRecipients objectForKey: recTypes[type]]; - recipientsMax = [recipients count]; - for (count = 0; count < recipientsMax; count++) - { - recipient = msgData->recipients + current; - recipient->type = type; - - dict = [recipients objectAtIndex: count]; - cn = [dict objectForKey: @"fullName"]; - email = [dict objectForKey: @"email"]; - - contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - if (contactInfos) - { - username = [contactInfos objectForKey: @"sAMAccountName"]; - recipient->username = [username asUnicodeInMemCtx: msgData]; - entryId = MAPIStoreInternalEntryId ([[self context] connectionInfo], username); - } - else - { - recipient->username = NULL; - entryId = MAPIStoreExternalEntryId (cn, email); - } - - /* properties */ - p = 0; - recipient->data = talloc_array (msgData, void *, msgData->columns->cValues); - memset (recipient->data, 0, msgData->columns->cValues * sizeof (void *)); - - // PR_OBJECT_TYPE = MAPI_MAILUSER (see MAPI_OBJTYPE) - recipient->data[p] = MAPILongValue (msgData, MAPI_MAILUSER); - p++; - - // PR_DISPLAY_TYPE = DT_MAILUSER (see MS-NSPI) - recipient->data[p] = MAPILongValue (msgData, 0); - p++; - - // PR_7BIT_DISPLAY_NAME_UNICODE - recipient->data[p] = [cn asUnicodeInMemCtx: msgData]; - p++; - - // PR_SMTP_ADDRESS_UNICODE - recipient->data[p] = [email asUnicodeInMemCtx: msgData]; - p++; - - // PR_SEND_INTERNET_ENCODING = 0x00060000 (plain text, see OXCMAIL) - recipient->data[p] = MAPILongValue (msgData, 0x00060000); - p++; - - // PR_RECIPIENT_DISPLAY_NAME_UNICODE - recipient->data[p] = [cn asUnicodeInMemCtx: msgData]; - p++; - - // PR_RECIPIENT_FLAGS - recipient->data[p] = MAPILongValue (msgData, 0x01); - p++; - - // PR_RECIPIENT_ENTRYID - recipient->data[p] = [entryId asBinaryInMemCtx: msgData]; - p++; - - // PR_RECIPIENT_TRACKSTATUS - recipient->data[p] = MAPILongValue (msgData, 0x00); - p++; - - current++; - } - } - *dataPtr = msgData; -} - -static inline NSString * -MakeRecipientString (NSDictionary *recipient) -{ - NSString *fullName, *email, *fullEmail; - - fullName = [recipient objectForKey: @"fullName"]; - email = [recipient objectForKey: @"email"]; - if ([email length] > 0) - { - if ([fullName length] > 0) - fullEmail = [NSString stringWithFormat: @"%@ <%@>", fullName, email]; - else - fullEmail = email; - } - else - { - NSLog (@"recipient not generated from record: %@", recipient); - fullEmail = nil; - } - - return fullEmail; -} - -static inline NSArray * -MakeRecipientsList (NSArray *recipients) -{ - NSMutableArray *list; - NSUInteger count, max; - NSString *recipient; - - max = [recipients count]; - list = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - recipient = MakeRecipientString ([recipients objectAtIndex: count]); - if (recipient) - [list addObject: recipient]; - } - - return list; -} - -static NSString * -QuoteSpecials (NSString *address) -{ - NSString *result, *part, *s2; - int i, len; - - // We want to correctly send mails to recipients such as : - // foo.bar - // foo (bar) - // bar, foo - if ([address indexOf: '('] >= 0 || [address indexOf: ')'] >= 0 - || [address indexOf: '<'] >= 0 || [address indexOf: '>'] >= 0 - || [address indexOf: '@'] >= 0 || [address indexOf: ','] >= 0 - || [address indexOf: ';'] >= 0 || [address indexOf: ':'] >= 0 - || [address indexOf: '\\'] >= 0 || [address indexOf: '"'] >= 0 - || [address indexOf: '.'] >= 0 - || [address indexOf: '['] >= 0 || [address indexOf: ']'] >= 0) - { - // We search for the first instance of < from the end - // and we quote what was before if we need to - len = [address length]; - i = -1; - while (len--) - if ([address characterAtIndex: len] == '<') - { - i = len; - break; - } - - if (i > 0) - { - part = [address substringToIndex: i - 1]; - s2 = [[part stringByReplacingString: @"\\" withString: @"\\\\"] - stringByReplacingString: @"\"" withString: @"\\\""]; - result = [NSString stringWithFormat: @"\"%@\" %@", s2, [address substringFromIndex: i]]; - } - else - { - s2 = [[address stringByReplacingString: @"\\" withString: @"\\\\"] - stringByReplacingString: @"\"" withString: @"\\\""]; - result = [NSString stringWithFormat: @"\"%@\"", s2]; - } - } - else - result = address; - - return result; -} - -static inline void -FillMessageHeadersFromSharingProperties (NGMutableHashMap *headers, NSDictionary *mailProperties) -{ - /* Store the *important* properties related with a sharing object as - MIME eXtension headers. See [MS-OXSHARE] Section 2.2 for details - about the properties */ - - id value; - NSNumber *sharingFlavourNum = nil; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingCapabilities)]; - if (value) - [headers setObject: value - forKey: @"X-MS-Sharing-Capabilities"]; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingFlavor)]; - if (value) - sharingFlavourNum = (NSNumber *)value; - else - { - value = [mailProperties objectForKey: MAPIPropertyKey (PidNameXSharingFlavor)]; - if (value) - { - /* Transform the hex string to unsigned int */ - NSScanner *scanner; - unsigned int sharingFlavour; - scanner = [NSScanner scannerWithString:value]; - if ([scanner scanHexInt:&sharingFlavour]) - sharingFlavourNum =[NSNumber numberWithUnsignedInt: sharingFlavour]; - } - } - if (sharingFlavourNum) - { - if ([sharingFlavourNum unsignedIntegerValue] == 0x5100) - { - /* 0x5100 sharing flavour is not in standard but it seems to - be a denial of request + invitation message so we store - deny sharing flavour */ - sharingFlavourNum = [NSNumber numberWithUnsignedInt: SHARING_DENY_REQUEST]; - } - [headers setObject: sharingFlavourNum - forKey: @"X-MS-Sharing-Flavor"]; - } - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingInitiatorEntryId)]; - if (value) - [headers setObject: [[value stringByEncodingBase64] stringByReplacingOccurrencesOfString: @"\n" - withString: @""] - forKey: @"X-MS-Sharing-InitiatorEntryId"]; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingInitiatorName)]; - if (value) - [headers setObject: value - forKey: @"X-MS-Sharing-InitiatorName"]; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingInitiatorSmtp)]; - if (value) - [headers setObject: value - forKey: @"X-MS-Sharing-InitiatorSmtp"]; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingLocalType)]; - if (value) - [headers setObject: value - forKey: @"X-MS-Sharing-LocalType"]; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingProviderName)]; - if (value) - [headers setObject: value - forKey: @"X-MS-Sharing-ProviderName"]; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingRemoteName)]; - if (value) - [headers setObject: value - forKey: @"X-MS-Sharing-RemoteName"]; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingRemoteStoreUid)]; - if (value) - [headers setObject: value - forKey: @"X-MS-Sharing-RemoteStoreUid"]; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingRemoteUid)]; - if (value) - [headers setObject: value - forKey: @"X-MS-Sharing-RemoteUid"]; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingResponseTime)]; - if (value) - [headers setObject: value - forKey: @"X-MS-Sharing-ResponseTime"]; - - value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingResponseType)]; - if (value) - [headers setObject: value - forKey: @"X-MS-Sharing-ResponseType"]; - -} - -static inline void -FillMessageHeadersFromProperties (NGMutableHashMap *headers, - NSDictionary *mailProperties, BOOL withBcc, - struct mapistore_connection_info *connInfo) -{ - BOOL fromResolved = NO; - NSData *senderEntryId; - NSMutableString *subject; - NSString *from, *recId, *messageId, *subjectData, *recipientsStr, *msgClass; - NSArray *list; - NSCalendarDate *date; - NSDictionary *recipients; - enum ulRecipClass type, bccLimit; - SOGoUser *activeUser; - NSNumber *priority; - - activeUser - = [SOGoUser - userWithLogin: [NSString stringWithUTF8String: connInfo->username]]; - - from = [NSString stringWithFormat: @"%@ <%@>", - [activeUser cn], [[activeUser allEmails] objectAtIndex: 0]]; - [headers setObject: QuoteSpecials (from) forKey: @"from"]; - - /* save the recipients */ - recipients = [mailProperties objectForKey: @"recipients"]; - if (recipients) - { - if (withBcc) - bccLimit = MAPI_BCC; - else - bccLimit = MAPI_CC; - - for (type = MAPI_TO; type <= bccLimit; type++) - { - recId = recTypes[type]; - list = MakeRecipientsList ([recipients objectForKey: recId]); - [headers setObjects: list forKey: recId]; - } - - list = MakeRecipientsList ([recipients objectForKey: @"orig"]); - if ([list count]) - { - [headers setObjects: list forKey: @"from"]; - fromResolved = YES; - } - } - - if (!fromResolved) - { - TALLOC_CTX *local_mem_ctx; - local_mem_ctx = talloc_new(NULL); - if (!local_mem_ctx) - { - NSLog (@"%s: Out of memory", __PRETTY_FUNCTION__); - return; - } - - NSLog (@"Message without an orig from, try to guess it from PidTagSenderEntryId"); - senderEntryId = [mailProperties objectForKey: MAPIPropertyKey (PR_SENDER_ENTRYID)]; - if (senderEntryId) - { - struct Binary_r bin32; - struct AddressBookEntryId *addrBookEntryId; - NSString *username; - NSMutableDictionary *fromRecipient; - - fromRecipient = [NSMutableDictionary dictionaryWithCapacity: 2]; - - bin32.cb = [senderEntryId length]; - bin32.lpb = (uint8_t *) [senderEntryId bytes]; - addrBookEntryId = get_AddressBookEntryId (local_mem_ctx, &bin32); - if (addrBookEntryId && [[NSString stringWithGUID: &addrBookEntryId->ProviderUID] - hasSuffix: @"08002b2fe182"]) - { - /* TODO: better way to distinguish local and other ones */ - username = MAPIStoreSamDBUserAttribute (connInfo, @"legacyExchangeDN", - [NSString stringWithUTF8String: addrBookEntryId->X500DN], @"sAMAccountName"); - if (username) - { - SOGoUser *fromUser; - - fromUser = [SOGoUser userWithLogin: [username lowercaseString]]; - [fromRecipient setObject: [fromUser cn] forKey: @"fullName"]; - [fromRecipient setObject: [[fromUser allEmails] objectAtIndex: 0] - forKey: @"email"]; - } - else - [fromRecipient setObject: [NSString stringWithUTF8String: addrBookEntryId->X500DN] - forKey: @"email"]; - - } - else - { - /* Try with One-Off EntryId */ - struct OneOffEntryId *oneOffEntryId; - - oneOffEntryId = get_OneOffEntryId (local_mem_ctx, &bin32); - if (oneOffEntryId && [[NSString stringWithGUID: &oneOffEntryId->ProviderUID] - hasSuffix: @"00dd010f5402"]) - { - [fromRecipient setObject: [NSString stringWithUTF8String: oneOffEntryId->DisplayName.lpszW] - forKey: @"fullName"]; - [fromRecipient setObject: [NSString stringWithUTF8String: oneOffEntryId->EmailAddress.lpszW] - forKey: @"email"]; - } - } - - if ([[fromRecipient allKeys] count] > 0) - { - list = MakeRecipientsList ([NSArray arrayWithObjects: fromRecipient, nil]); - if ([list count]) - [headers setObjects: list forKey: @"from"]; - } - - } - /* Free entryId */ - talloc_free(local_mem_ctx); - } - - if (!recipients) - { - NSLog (@"Message without recipients." - @"Guessing recipients from PidTagOriginalDisplayTo and PidTagOriginalCc"); - recipientsStr = [mailProperties objectForKey: MAPIPropertyKey (PidTagOriginalDisplayTo)]; - if (recipientsStr) - { - list = [recipientsStr componentsSeparatedByString:@", "]; - if ([list count]) - [headers setObjects: list forKey: @"to"]; - } - - recipientsStr = [mailProperties objectForKey: MAPIPropertyKey (PidTagOriginalDisplayCc)]; - if (recipientsStr) - { - list = [recipientsStr componentsSeparatedByString:@", "]; - if ([list count]) - [headers setObjects: list forKey: @"cc"]; - } - } - - subject = [NSMutableString stringWithCapacity: 128]; - subjectData = [mailProperties objectForKey: MAPIPropertyKey (PR_SUBJECT_PREFIX_UNICODE)]; - if (subjectData) - [subject appendString: subjectData]; - subjectData = [mailProperties objectForKey: MAPIPropertyKey (PR_NORMALIZED_SUBJECT_UNICODE)]; - if (subjectData) - [subject appendString: subjectData]; - if ([subject length] == 0) - { - subjectData = [mailProperties objectForKey: MAPIPropertyKey (PR_SUBJECT_UNICODE)]; - if (subjectData) - [subject appendString: subjectData]; - } - [headers setObject: [subject asQPSubjectString: @"utf-8"] forKey: @"subject"]; - - messageId = [mailProperties objectForKey: MAPIPropertyKey (PR_INTERNET_MESSAGE_ID_UNICODE)]; - if ([messageId length]) - [headers setObject: messageId forKey: @"message-id"]; - - date = [mailProperties objectForKey: MAPIPropertyKey (PR_CLIENT_SUBMIT_TIME)]; - if (date) - { - [headers addObject: [date rfc822DateString] forKey: @"date"]; - } - [headers addObject: @"1.0" forKey: @"MIME-Version"]; - - priority = [mailProperties objectForKey: MAPIPropertyKey (PidTagImportance)]; - - if ([priority intValue] == 2) - { - [headers addObject: @"1 (Highest)" forKey: @"X-Priority"]; - } - else if ([priority intValue] == 1) - { - [headers removeAllObjectsForKey: @"X-Priority"]; - } - else - { - [headers addObject: @"5 (Lowest)" forKey: @"X-Priority"]; - } - - msgClass = [mailProperties objectForKey: MAPIPropertyKey (PidTagMessageClass)]; - if ([msgClass isEqualToString: @"IPM.Sharing"]) - { - FillMessageHeadersFromSharingProperties (headers, mailProperties); - } - -} - -static NSArray * -MakeAttachmentParts (NSDictionary *attachmentParts, BOOL withContentId) -{ - NSMutableArray *attachmentMimeParts; - NSArray *keys; - MAPIStoreAttachment *attachment; - NSUInteger count, max; - NGMimeBodyPart *mimePart; - - keys = [attachmentParts allKeys]; - max = [keys count]; - attachmentMimeParts = [NSMutableArray arrayWithCapacity: max]; - for (count = 0; count < max; count++) - { - attachment = [attachmentParts - objectForKey: [keys objectAtIndex: count]]; - if ([attachment hasContentId] == withContentId) - { - mimePart = [attachment asMIMEBodyPart]; - if (mimePart) - [attachmentMimeParts addObject: mimePart]; - } - } - - return attachmentMimeParts; -} - -static inline id -MakeTextPlainBody (NSDictionary *mailProperties, NSString **contentType) -{ - id textPlainBody; - - textPlainBody = [[mailProperties - objectForKey: MAPIPropertyKey (PR_BODY_UNICODE)] - dataUsingEncoding: NSUTF8StringEncoding]; - *contentType = @"text/plain; charset=utf-8"; - - return textPlainBody; -} - -static inline id -MakeTextHtmlBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, - NSString **contentType) -{ - id textHtmlBody; - NSData *htmlBody; - NSString *charset, *htmlContentType; - NSArray *parts; - NSNumber *codePage; - NGMimeBodyPart *htmlBodyPart; - NGMutableHashMap *headers; - NSUInteger count, max; - - htmlBody = [mailProperties objectForKey: MAPIPropertyKey (PR_HTML)]; - if (htmlBody) - { - /* charset */ - codePage = [mailProperties objectForKey: MAPIPropertyKey (PR_INTERNET_CPID)]; - charset = [Codepages getNameFromCodepage: codePage]; - if (!charset) - charset = @"utf-8"; - htmlContentType = [NSString stringWithFormat: @"text/html; charset=%@", - charset]; - - parts = MakeAttachmentParts (attachmentParts, YES); - max = [parts count]; - if (max > 0) - { - textHtmlBody = [NGMimeMultipartBody new]; - [textHtmlBody autorelease]; - - headers = [[NGMutableHashMap alloc] initWithCapacity: 1]; - [headers setObject: htmlContentType forKey: @"content-type"]; - htmlBodyPart = [NGMimeBodyPart bodyPartWithHeader: headers]; - [htmlBodyPart setBody: htmlBody]; - [headers release]; - [textHtmlBody addBodyPart: htmlBodyPart]; - - for (count = 0; count < max; count++) - [textHtmlBody addBodyPart: [parts objectAtIndex: count]]; - - *contentType = @"multipart/related"; - } - else - { - textHtmlBody = htmlBody; - *contentType = htmlContentType; - } - } - else - textHtmlBody = nil; - - return textHtmlBody; -} - -static inline id -MakeTextPartBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, - NSString **contentType) -{ - id textBody, textPlainBody, textHtmlBody; - NSString *textPlainContentType, *textHtmlContentType; - NGMutableHashMap *headers; - NGMimeBodyPart *bodyPart; - - textPlainBody = MakeTextPlainBody (mailProperties, &textPlainContentType); - textHtmlBody = MakeTextHtmlBody (mailProperties, attachmentParts, &textHtmlContentType); - if (textPlainBody) - { - if (textHtmlBody) - { - textBody = [NGMimeMultipartBody new]; - [textBody autorelease]; - - headers = [[NGMutableHashMap alloc] initWithCapacity: 1]; - [headers setObject: textHtmlContentType forKey: @"content-type"]; - bodyPart = [NGMimeBodyPart bodyPartWithHeader: headers]; - [bodyPart setBody: textHtmlBody]; - [headers release]; - [textBody addBodyPart: bodyPart]; - - headers = [[NGMutableHashMap alloc] initWithCapacity: 1]; - [headers setObject: textPlainContentType forKey: @"content-type"]; - bodyPart = [NGMimeBodyPart bodyPartWithHeader: headers]; - [bodyPart setBody: textPlainBody]; - [headers release]; - [textBody addBodyPart: bodyPart]; - - *contentType = @"multipart/alternative"; - } - else - { - textBody = textPlainBody; - *contentType = textPlainContentType; - } - } - else - { - textBody = textHtmlBody; - *contentType = textHtmlContentType; - } - - return textBody; -} - -// static id -// MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, -// NSString **contentType) -static id -MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, NSString **contentType) -{ - id messageBody, textBody; - NSString *textContentType; - NSArray *parts; - NGMimeBodyPart *textBodyPart; - NGMutableHashMap *headers; - NSUInteger count, max; - - textBody = MakeTextPartBody (mailProperties, attachmentParts, - &textContentType); - - parts = MakeAttachmentParts (attachmentParts, NO); - max = [parts count]; - if (max > 0) - { - messageBody = [NGMimeMultipartBody new]; - [messageBody autorelease]; - - if (textBody) - { - headers = [[NGMutableHashMap alloc] initWithCapacity: 1]; - [headers setObject: textContentType forKey: @"content-type"]; - textBodyPart = [NGMimeBodyPart bodyPartWithHeader: headers]; - [textBodyPart setBody: textBody]; - [headers release]; - [messageBody addBodyPart: textBodyPart]; - } - - for (count = 0; count < max; count++) - [messageBody addBodyPart: [parts objectAtIndex: count]]; - - *contentType = @"multipart/mixed"; - } - else - { - messageBody = textBody; - *contentType = textContentType; - } - - return messageBody; -} - -- (NGMimeMessage *) _generateMessageWithBcc: (BOOL) withBcc -{ - NSString *contentType; - NGMimeMessage *message; - NGMutableHashMap *headers; - id messageBody; - - headers = [[NGMutableHashMap alloc] initWithCapacity: 16]; - FillMessageHeadersFromProperties (headers, properties, withBcc, - [[self context] connectionInfo]); - message = [[NGMimeMessage alloc] initWithHeader: headers]; - [message autorelease]; - [headers release]; - - messageBody = MakeMessageBody (properties, attachmentParts, &contentType); - if (messageBody) - { - [message setHeader: contentType forKey: @"content-type"]; - [message setBody: messageBody]; - } - - return message; -} - -- (NSData *) _generateMailDataWithBcc: (BOOL) withBcc -{ - NGMimeMessage *message; - NGMimeMessageGenerator *generator; - NSData *messageData; - - /* mime message generation */ - generator = [NGMimeMessageGenerator new]; - message = [self _generateMessageWithBcc: withBcc]; - messageData = [generator generateMimeFromPart: message]; - [generator release]; - - // [messageData writeToFile: @"/tmp/mimegen.eml" atomically: NO]; - - return messageData; -} - -- (enum mapistore_error) submitWithFlags: (enum SubmitFlags) flags -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSDictionary *recipients; - NSData *messageData; - NSMutableArray *recipientEmails; - NSArray *list; - NSString *recId, *from, *msgClass; - enum ulRecipClass type; - SOGoUser *activeUser; - SOGoDomainDefaults *dd; - NSException *error; - WOContext *woContext; - id authenticator; - - msgClass = [properties objectForKey: MAPIPropertyKey (PidTagMessageClass)]; - if ([msgClass isEqualToString: @"IPM.Note"] || [msgClass isEqualToString: @"IPM.Sharing"]) /* we skip invitation replies */ - { - /* send mail */ - - messageData = [self _generateMailDataWithBcc: NO]; - - recipientEmails = [NSMutableArray arrayWithCapacity: 32]; - recipients = [properties objectForKey: @"recipients"]; - for (type = MAPI_ORIG; type <= MAPI_BCC; type++) - { - recId = recTypes[type]; - list = [recipients objectForKey: recId]; - [recipientEmails - addObjectsFromArray: [list objectsForKey: @"email" - notFoundMarker: nil]]; - } - - activeUser = [[self context] activeUser]; - - [self logWithFormat: @"recipients: %@", recipientEmails]; - dd = [activeUser domainDefaults]; - from = [[activeUser allEmails] objectAtIndex: 0]; - - [[self userContext] activate]; - woContext = [[self userContext] woContext]; - authenticator = [sogoObject authenticatorInContext: woContext]; - error = [[SOGoMailer mailerWithDomainDefaults: dd] - sendMailData: messageData - toRecipients: recipientEmails - sender: from - withAuthenticator: authenticator - inContext: woContext]; - if (error) - { - [self errorWithFormat: @"an error occurred: '%@'", error]; - rc = MAPISTORE_ERR_MSG_SEND; - } - - // 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 '%@'", - msgClass]; - - return rc; -} - -- (void) save: (TALLOC_CTX *) memCtx -{ - BOOL updatedMetadata; - NSString *folderName, *flag, *newIdString, *messageKey, *changeNumber; - NSData *changeKey, *messageData; - NGImap4Connection *connection; - NGImap4Client *client; - SOGoMailFolder *containerFolder; - NSDictionary *result, *responseResult; - MAPIStoreMapping *mapping; - uint64_t mid; - - messageData = [self _generateMailDataWithBcc: YES]; - - /* appending to imap folder */ - containerFolder = [container sogoObject]; - connection = [containerFolder imap4Connection]; - client = [connection client]; - folderName = [connection imap4FolderNameForURL: [containerFolder imap4URL]]; - result = [client append: messageData toFolder: folderName - withFlags: [NSArray arrayWithObjects: @"seen", nil]]; - if ([[result objectForKey: @"result"] boolValue]) - { - /* we reregister the new message URL with the id mapper */ - responseResult = [[result objectForKey: @"RawResponse"] - objectForKey: @"ResponseResult"]; - flag = [responseResult objectForKey: @"flag"]; - - newIdString = [[flag componentsSeparatedByString: @" "] - objectAtIndex: 2]; - mapping = [self mapping]; - mid = [self objectId]; - [mapping unregisterURLWithID: mid]; - // [sogoObject setNameInContainer: ]; - - messageKey = [NSString stringWithFormat: @"%@.eml", newIdString]; - [sogoObject setNameInContainer: messageKey]; - [mapping registerURL: [self url] withID: mid]; - - /* synchronise the cache and update the predecessor change list - with the change key provided by the client. Before doing - this, lets issue a unselect/select combo because of timing - issues with Dovecot in obtaining the latest modseq. - Sometimes, Dovecot doesn't return the newly appended UID if - we do a "UID SORT (DATE) UTF-8 (MODSEQ XYZ) (NOT DELETED)" - command (where XYZ is the HIGHESTMODSEQ+1) immediately after - IMAP APPEND */ - [client unselect]; - [client select: folderName]; - - [(MAPIStoreMailFolder *) container synchroniseCache]; - changeKey = [properties objectForKey: MAPIPropertyKey (PR_CHANGE_KEY)]; - if (changeKey) - { - updatedMetadata = [(MAPIStoreMailFolder *) container updatePredecessorChangeListWith: changeKey - forMessageWithKey: messageKey]; - if (!updatedMetadata) - [self warnWithFormat: @"Predecessor change list not updated with client data"]; - } - - /* Update version property (PR_CHANGE_KEY indeed) as it is - requested once it is saved */ - changeNumber = [(MAPIStoreMailFolder *) container changeNumberForMessageUID: newIdString]; - if (changeNumber) - [properties setObject: [NSNumber numberWithUnsignedLongLong: [changeNumber unsignedLongLongValue] >> 16] - forKey: @"version"]; - } -} - -@end diff --git a/OpenChange/MAPIStoreMapping.h b/OpenChange/MAPIStoreMapping.h deleted file mode 100644 index 55c2e944a..000000000 --- a/OpenChange/MAPIStoreMapping.h +++ /dev/null @@ -1,68 +0,0 @@ -/* MAPIStoreMapping.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREMAPPING_H -#define MAPISTOREMAPPING_H - -#import - -@class NSMutableDictionary; -@class NSString; - -@interface MAPIStoreMapping : NSObject -{ - void *memCtx; - NSString *username; - struct indexing_context *indexing; - NSUInteger useCount; -} - -+ (id) mappingForUsername: (NSString *) username - withIndexing: (struct indexing_context *) indexing; - -- (id) initForUsername: (NSString *) username - withIndexing: (struct indexing_context *) indexing; - - -- (void) increaseUseCount; -- (void) decreaseUseCount; - -- (NSString *) urlFromID: (uint64_t) idKey; - -- (uint64_t) idFromURL: (NSString *) url; -- (uint64_t) idFromURL: (NSString *) url - isSoftDeleted: (bool *) softDeleted; -- (BOOL) registerURL: (NSString *) urlString - withID: (uint64_t) idNbr; -- (void) registerURLs: (NSArray *) urlString - withIDs: (NSArray *) idNbrs; -- (void) unregisterURLWithID: (uint64_t) idNbr; -- (void) unregisterURLWithID: (uint64_t) idNbr - andFlags: (uint8_t) flags; -- (void) updateID: (uint64_t) idNbr - withURL: (NSString *) urlString; -- (BOOL) updateURL: (NSString *) urlString - withID: (uint64_t) idNbr; - -@end - -#endif /* MAPISTOREMAPPING_H */ diff --git a/OpenChange/MAPIStoreMapping.m b/OpenChange/MAPIStoreMapping.m deleted file mode 100644 index 2e2c9a66d..000000000 --- a/OpenChange/MAPIStoreMapping.m +++ /dev/null @@ -1,327 +0,0 @@ -/* MAPIStoreMapping.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -#include - -#import -#import -#import -#import -#import - -#import -#import - -#import - -#undef DEBUG -#include -#include - -#import "MAPIStoreTypes.h" - -#import "MAPIStoreMapping.h" - -#include - -static NSMutableDictionary *mappingRegistry = nil; - -@implementation MAPIStoreMapping - -+ (void) initialize -{ - mappingRegistry = [NSMutableDictionary new]; -} - -static inline id -MAPIStoreMappingKeyFromId (uint64_t idNbr) -{ - return [NSString stringWithUnsignedLongLong: idNbr]; -} - - -+ (id) mappingForUsername: (NSString *) username - withIndexing: (struct indexing_context *) indexing -{ - id mapping; - - mapping = [mappingRegistry objectForKey: username]; - if (!mapping) - { - mapping = [[self alloc] initForUsername: username - withIndexing: indexing]; - [mapping autorelease]; - } - - return mapping; -} - -- (id) init -{ - if ((self = [super init])) - { - memCtx = talloc_zero (NULL, TALLOC_CTX); - indexing = NULL; - useCount = 0; - } - - return self; -} - -- (void) increaseUseCount -{ - if (useCount == 0) - { - [mappingRegistry setObject: self forKey: username]; - [self logWithFormat: @"mapping registered (%@)", username]; - } - useCount++; -} - -- (void) decreaseUseCount -{ - useCount--; - if (useCount == 0) - { - [mappingRegistry removeObjectForKey: username]; - [self logWithFormat: @"mapping deregistered (%@)", username]; - } -} - -- (id) initForUsername: (NSString *) newUsername - withIndexing: (struct indexing_context *) newIndexing -{ - if ((self = [self init])) - { - ASSIGN (username, newUsername); - indexing = newIndexing; - /* Workaround so all indexing context are valid and won't be freed. */ - // TODO refactor indexing interface - talloc_reference(memCtx, indexing); - } - - return self; -} - -- (void) dealloc -{ - [username release]; - talloc_free (memCtx); - [super dealloc]; -} - -- (NSString *) urlFromID: (uint64_t) idNbr -{ - char* url = NULL; - enum mapistore_error ret; - bool soft_delete = false; - - ret = indexing->get_uri(indexing, [username UTF8String], - memCtx, idNbr, &url, &soft_delete); - if (ret != MAPISTORE_SUCCESS) - return NULL; - NSString *res = [[[NSString alloc] initWithUTF8String:url] autorelease]; - talloc_free(url); - - return res; -} - -- (uint64_t) idFromURL: (NSString *) url -{ - enum mapistore_error ret; - uint64_t idNbr; - bool softDeleted; - - ret = indexing->get_fmid(indexing, [username UTF8String], [url UTF8String], - false, &idNbr, &softDeleted); - - if (ret == MAPISTORE_SUCCESS && !softDeleted) - return idNbr; - else - return NSNotFound; -} - -- (uint64_t) idFromURL: (NSString *) url - isSoftDeleted: (bool *) softDeleted -{ - enum mapistore_error ret; - uint64_t idNbr; - - ret = indexing->get_fmid(indexing, [username UTF8String], [url UTF8String], - false, &idNbr, softDeleted); - - if (ret != MAPISTORE_SUCCESS) - return NSNotFound; - - return idNbr; -} - -- (void) _updateFolderWithURL: (NSString *) oldURL - withURL: (NSString *) urlString -{ - const char *searchURL; - uint64_t idNbr; - bool softDeleted; - NSString *current; - NSString *newURL; - - if ([oldURL isEqualToString: urlString]) return; - - searchURL = [[oldURL stringByAppendingString:@"*"] UTF8String]; - - while (indexing->get_fmid(indexing, [username UTF8String], - searchURL,true, &idNbr, &softDeleted) == MAPISTORE_SUCCESS) - { - // Ignore deleted - if (softDeleted) continue; - - current = [self urlFromID:idNbr]; - newURL = [current stringByReplacingPrefix: oldURL withPrefix: urlString]; - indexing->update_fmid(indexing, [username UTF8String], idNbr, [newURL UTF8String]); - } -} - -- (void) updateID: (uint64_t) idNbr - withURL: (NSString *) urlString -{ - NSString *oldURL; - - oldURL = [self urlFromID: idNbr]; - if (oldURL) - { - if ([oldURL hasSuffix: @"/"]) /* is container ? */ - { - if (![urlString hasSuffix: @"/"]) - [NSException raise: NSInvalidArgumentException - format: @"a container url must have an ending '/'"]; - [self _updateFolderWithURL: oldURL withURL: urlString]; - } - else - { - if ([urlString hasSuffix: @"/"]) - [NSException raise: NSInvalidArgumentException - format: @"a leaf url must not have an ending '/'"]; - - indexing->update_fmid(indexing, [username UTF8String], - idNbr, [urlString UTF8String]); - } - } -} - -- (BOOL) updateURL: (NSString *) urlString - withID: (uint64_t) idNbr -{ - BOOL rc = NO; - uint64_t oldIDNbr; - - oldIDNbr = [self idFromURL: urlString]; - if (oldIDNbr) - { - [self logWithFormat: @"Updating URL: %@ with id %.16"PRIx64" from old id %.16"PRIx64, - urlString, idNbr, oldIDNbr]; - [self unregisterURLWithID: oldIDNbr]; - [self registerURL: urlString - withID: idNbr]; - rc = YES; - } - - return rc; -} - -- (BOOL) registerURL: (NSString *) urlString - withID: (uint64_t) idNbr -{ - NSString *oldURL; - uint64_t oldIdNbr; - bool softDeleted; - - oldURL = [self urlFromID: idNbr]; - if (oldURL != NULL) - { - [self errorWithFormat: - @"url with idNbr already registered: (oldUrl='%@', newUrl='%@', id=0x%.16"PRIx64")", - oldURL, urlString, idNbr]; - return NO; - } - - oldIdNbr = [self idFromURL: urlString isSoftDeleted: &softDeleted]; - if (oldIdNbr != NSNotFound) - { - if (softDeleted) - [self logWithFormat: @"Attempt to register a soft-deleted %@", urlString]; - else - [self errorWithFormat: - @"attempt to double register an entry with idNbr ('%@', %lld," - @" 0x%.16"PRIx64", oldid=0x%.16"PRIx64")", - urlString, idNbr, idNbr, oldIdNbr]; - return NO; - } - else - { - // [self logWithFormat: @"registered url '%@' with id %lld (0x%.16"PRIx64")", - // urlString, idNbr, idNbr]; - - /* Add the record given its fid and mapistore_uri */ - indexing->add_fmid(indexing, [username UTF8String], - idNbr, [urlString UTF8String]); - } - - return YES; -} - -- (void) registerURLs: (NSArray *) urlStrings - withIDs: (NSArray *) idNbrs -{ - uint64_t count, max, newID; - - max = [urlStrings count]; - if (max == [idNbrs count]) - { - for (count = 0; count < max; count++) - { - newID = [[idNbrs objectAtIndex: count] - unsignedLongLongValue]; - [self registerURL: [urlStrings objectAtIndex: count] - withID: newID]; - } - } - else - [NSException raise: NSInvalidArgumentException - format: @"number of urls (%d) and ids (%d) do not match", max, [idNbrs count]]; -} - -- (void) unregisterURLWithID: (uint64_t) idNbr -{ - indexing->del_fmid(indexing, [username UTF8String], - idNbr, MAPISTORE_PERMANENT_DELETE); -} - -- (void) unregisterURLWithID: (uint64_t) idNbr - andFlags: (uint8_t) flags -{ - indexing->del_fmid(indexing, [username UTF8String], - idNbr, - (flags == MAPISTORE_SOFT_DELETE) ? MAPISTORE_SOFT_DELETE : MAPISTORE_PERMANENT_DELETE); -} - - -@end diff --git a/OpenChange/MAPIStoreMessage.h b/OpenChange/MAPIStoreMessage.h deleted file mode 100644 index b7441a74c..000000000 --- a/OpenChange/MAPIStoreMessage.h +++ /dev/null @@ -1,90 +0,0 @@ -/* MAPIStoreMessage.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREMESSAGE_H -#define MAPISTOREMESSAGE_H - -#import - -@class NSArray; -@class NSMutableArray; -@class NSMutableDictionary; - -@class EOQualifier; - -@class MAPIStoreAttachment; -@class MAPIStoreAttachmentTable; -@class MAPIStoreFolder; - -#import "MAPIStoreSOGoObject.h" - -@interface MAPIStoreMessage : MAPIStoreSOGoObject -{ - NSArray *attachmentKeys; - NSMutableDictionary *attachmentParts; - NSMutableArray *activeTables; - NSArray *activeUserRoles; -} - -- (void) getMessageData: (struct mapistore_message **) dataPtr - inMemCtx: (TALLOC_CTX *) memCtx; - -- (enum mapistore_error) modifyRecipientsWithRecipients: (struct mapistore_message_recipient *) recipients - andCount: (NSUInteger) max - andColumns: (struct SPropTagArray *) columns; -- (NSArray *) attachmentKeys; -- (NSArray *) attachmentKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings; -- (id) lookupAttachment: (NSString *) childKey; - -/* backend methods */ -- (enum mapistore_error) createAttachment: (MAPIStoreAttachment **) attachmentPtr - inAID: (uint32_t *) aidPtr; -- (enum mapistore_error) getAttachment: (MAPIStoreAttachment **) attachmentPtr - withAID: (uint32_t) aid; -- (enum mapistore_error) getAttachmentTable: (MAPIStoreAttachmentTable **) tablePtr - andRowCount: (uint32_t *) countPtr; -- (enum mapistore_error) setReadFlag: (uint8_t) flag; -- (enum mapistore_error) saveMessage: (TALLOC_CTX *) memCtx; - -- (NSArray *) activeContainerMessageTables; - -- (NSArray *) activeUserRoles; -- (NSArray *) expandRoles: (NSArray *) roles; - -/* move & copy internal ops */ -- (void) copyToMessage: (MAPIStoreMessage *) newMessage inMemCtx: (TALLOC_CTX *) memCtx; - -/* subclasses */ -- (void) save: (TALLOC_CTX *) memCtx; - -/* attachments (subclasses) */ -- (MAPIStoreAttachment *) createAttachment; -- (MAPIStoreAttachmentTable *) attachmentTable; - -- (BOOL) subscriberCanReadMessage; -- (BOOL) subscriberCanModifyMessage; -- (BOOL) subscriberCanDeleteMessage; - -@end - -#endif /* MAPISTOREMESSAGE_H */ diff --git a/OpenChange/MAPIStoreMessage.m b/OpenChange/MAPIStoreMessage.m deleted file mode 100644 index 3e303e5a3..000000000 --- a/OpenChange/MAPIStoreMessage.m +++ /dev/null @@ -1,1018 +0,0 @@ -/* MAPIStoreMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreActiveTables.h" -#import "MAPIStoreAttachment.h" -#import "MAPIStoreAttachmentTable.h" -#import "MAPIStoreContext.h" -#import "MAPIStoreEmbeddedMessage.h" -#import "MAPIStoreFolder.h" -#import "MAPIStoreMessageTable.h" -#import "MAPIStorePropertySelectors.h" -#import "MAPIStoreSamDBUtils.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSData+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" -#import "RTFHandler.h" - -#import "MAPIStoreMessage.h" - -#undef DEBUG -#include -#include -#include -#include - -static Class MAPIStoreFolderK, MAPIStoreEmbeddedMessageK; - -static NSString *resourcesDir = nil; - -static NSData * -uncompressRTF (NSData *compressedRTF) -{ - NSData *rtfData = nil; - DATA_BLOB *rtf; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_zero (NULL, TALLOC_CTX); - rtf = talloc_zero (mem_ctx, DATA_BLOB); - - if (uncompress_rtf (mem_ctx, - (uint8_t *) [compressedRTF bytes], [compressedRTF length], - rtf) - == MAPI_E_SUCCESS) - rtfData = [NSData dataWithBytes: rtf->data length: rtf->length]; - - talloc_free (mem_ctx); - - return rtfData; -} - -static NSData * -rtf2html (NSData *compressedRTF) -{ - NSData *rtf; - NSMutableData *html = nil; - - rtf = uncompressRTF (compressedRTF); - if (rtf) - { - //html = [NSMutableData data]; - RTFHandler *handler; - - handler = [[RTFHandler alloc] initWithData: rtf]; - AUTORELEASE(handler); - - html = [handler parse]; - } - - return html; -} - -@interface SOGoObject (MAPIStoreProtocol) - -- (NSString *) davContentLength; - -@end - -@implementation MAPIStoreMessage - -+ (void) initialize -{ - if (!resourcesDir) - { - resourcesDir = [[NSBundle bundleForClass: self] resourcePath]; - [resourcesDir retain]; - } - MAPIStoreFolderK = [MAPIStoreFolder class]; - MAPIStoreEmbeddedMessageK = [MAPIStoreEmbeddedMessage class]; -} - -- (id) init -{ - //[self logWithFormat: @"METHOD '%s' (%d) (%d)", __FUNCTION__, __LINE__, self]; - - if ((self = [super init])) - { - attachmentParts = [NSMutableDictionary new]; - activeTables = [NSMutableArray new]; - activeUserRoles = nil; - } - - return self; -} - -- (void) dealloc -{ - //[self logWithFormat: @"METHOD '%s' (%d) (%d)", __FUNCTION__, __LINE__, self]; - [activeUserRoles release]; - [attachmentKeys release]; - [attachmentParts release]; - [activeTables release]; - [super dealloc]; -} - -- (void) getMessageData: (struct mapistore_message **) dataPtr - inMemCtx: (TALLOC_CTX *) memCtx -{ - void *propValue; - struct mapistore_message *msgData; - - // [self logWithFormat: @"INCOMPLETE METHOD '%s' (%d): no recipient handling", - // __FUNCTION__, __LINE__]; - - msgData = talloc_zero (memCtx, struct mapistore_message); - - if ([self getPidTagSubjectPrefix: &propValue - inMemCtx: msgData] == MAPISTORE_SUCCESS - && propValue) - msgData->subject_prefix = propValue; - else - msgData->subject_prefix = ""; - - if ([self getPidTagNormalizedSubject: &propValue - inMemCtx: msgData] == MAPISTORE_SUCCESS - && propValue) - msgData->normalized_subject = propValue; - else - msgData->normalized_subject = ""; - - msgData->columns = talloc_zero(msgData, struct SPropTagArray); - msgData->recipients_count = 0; - *dataPtr = msgData; -} - -- (NSDictionary *) _convertRecipient: (struct mapistore_message_recipient *) recipient - andColumns: (struct SPropTagArray *) columns -{ - NSMutableDictionary *recipientProperties; - enum MAPITAGS prop_tag; - char *displayName = NULL; - char *email = NULL; - enum MAPI_OBJTYPE object_type = 0; - char *smtpAddress = NULL; - SOGoUser *recipientUser; - NSUInteger count; - NSString *recipientEmail = nil; - NSString *recipientFullName = nil; - id value; - - recipientProperties = [NSMutableDictionary dictionaryWithCapacity: columns->cValues + 2]; - - for (count = 0; count < columns->cValues; count++) - { - prop_tag = columns->aulPropTag[count]; - switch(prop_tag) { - case PidTagDisplayName: - displayName = recipient->data[count]; - break; - case PidTagEmailAddress: - email = recipient->data[count]; - break; - case PidTagObjectType: - if (recipient->data[count]) - object_type = *((uint8_t*) recipient->data[count]); - break; - case PidTagSmtpAddress: - smtpAddress = recipient->data[count]; - break; - default: - break; - } - - if (recipient->data[count]) - { - value = NSObjectFromValuePointer (prop_tag, - recipient->data[count]); - if (value) - [recipientProperties setObject: value - forKey: MAPIPropertyKey (prop_tag)]; - } - } - - if (recipient->username) - { - value = [NSString stringWithUTF8String: recipient->username]; - [recipientProperties setObject: value forKey: @"x500dn"]; - } - - if (object_type == MAPI_MAILUSER && recipient->username) - { - /* values from user object have priority over data sent by the client */ - recipientUser = [SOGoUser userWithLogin: [value lowercaseString]]; - if (recipientUser) - { - value = [recipientUser cn]; - if ([value length] > 0) - recipientFullName = value; - - value = [[recipientUser allEmails] objectAtIndex: 0]; - if ([value length] > 0) - recipientEmail = value; - } - } - - /* If we do not have values from the user object we try to get them from the parameters */ - if (!recipientFullName && displayName) - { - value = [NSString stringWithUTF8String: displayName]; - if ([value length] > 0) - recipientFullName = value; - } - - if (!recipientEmail && email) - { - value = [NSString stringWithUTF8String: email]; - if ([value length] > 0) - recipientEmail = value; - } - - if (!recipientEmail && smtpAddress) - { - value = [NSString stringWithUTF8String: smtpAddress]; - if ([value length] > 0) - recipientEmail = value; - } - - /* Now we can set the properties if we have them */ - if (recipientFullName) - [recipientProperties setObject: recipientFullName forKey: @"fullName"]; - - if (recipientEmail) - [recipientProperties setObject: recipientEmail forKey: @"email"]; - - return recipientProperties; -} - -- (enum mapistore_error) modifyRecipientsWithRecipients: (struct mapistore_message_recipient *) newRecipients - andCount: (NSUInteger) max - andColumns: (struct SPropTagArray *) columns; -{ - static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" }; - NSDictionary *recipientProperties; - NSMutableDictionary *recipients; - NSMutableArray *list; - NSString *recType; - struct mapistore_message_recipient *recipient; - NSUInteger count; - - //[self logWithFormat: @"METHOD '%s'", __FUNCTION__]; - - recipients = [NSMutableDictionary new]; - recipientProperties = [NSDictionary dictionaryWithObject: recipients - forKey: @"recipients"]; - [recipients release]; - - for (count = 0; count < max; count++) - { - recipient = newRecipients + count; - - if (recipient->type >= MAPI_ORIG && recipient->type <= MAPI_BCC) - { - recType = recTypes[recipient->type]; - list = [recipients objectForKey: recType]; - if (!list) - { - list = [NSMutableArray new]; - [recipients setObject: list forKey: recType]; - [list release]; - } - [list addObject: - [self _convertRecipient: recipient andColumns: columns]]; - } - } - [self addProperties: recipientProperties]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) addPropertiesFromRow: (struct SRow *) aRow -{ - enum mapistore_error rc; - MAPIStoreContext *context; - SOGoUser *ownerUser; - BOOL userIsOwner; - MAPIStoreMessage *mainMessage; - - context = [self context]; - ownerUser = [[self userContext] sogoUser]; - userIsOwner = [[context activeUser] isEqual: ownerUser]; - if (userIsOwner) - mainMessage = nil; - else if ([self isKindOfClass: MAPIStoreEmbeddedMessageK]) - mainMessage = (MAPIStoreMessage *) [[self container] container]; - else - mainMessage = self; - - if (userIsOwner || [mainMessage subscriberCanModifyMessage]) - rc = [super addPropertiesFromRow: aRow]; - else - rc = MAPISTORE_ERR_DENIED; - - return rc; -} - -- (void) addProperties: (NSDictionary *) newNewProperties -{ - NSData *htmlData, *rtfData; - static NSNumber *htmlKey = nil, *rtfKey = nil; - - /* we intercept any RTF content and convert it to HTML */ - [super addProperties: newNewProperties]; - - if (!htmlKey) - { - htmlKey = MAPIPropertyKey (PR_HTML); - [htmlKey retain]; - } - - if (!rtfKey) - { - rtfKey = MAPIPropertyKey (PR_RTF_COMPRESSED); - [rtfKey retain]; - } - - if (![properties objectForKey: htmlKey]) - { - rtfData = [properties objectForKey: rtfKey]; - if (rtfData) - { - htmlData = rtf2html (rtfData); - [properties setObject: htmlData forKey: htmlKey]; - [properties removeObjectForKey: rtfKey]; - [properties removeObjectForKey: MAPIPropertyKey (PR_RTF_IN_SYNC)]; - } - } -} - -- (MAPIStoreAttachment *) createAttachment -{ - MAPIStoreAttachment *newAttachment; - uint32_t newAid; - NSString *newKey; - - newAid = [[self attachmentKeys] count]; - - newAttachment = [MAPIStoreAttachment mapiStoreObjectInContainer: self]; - // [newAttachment setIsNew: YES]; - [newAttachment setAID: newAid]; - newKey = [NSString stringWithFormat: @"%ul", newAid]; - [attachmentParts setObject: newAttachment - forKey: newKey]; - [attachmentKeys release]; - attachmentKeys = nil; - - return newAttachment; -} - -- (enum mapistore_error) createAttachment: (MAPIStoreAttachment **) attachmentPtr - inAID: (uint32_t *) aidPtr -{ - MAPIStoreAttachment *attachment; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - attachment = [self createAttachment]; - if (attachment) - { - *attachmentPtr = attachment; - *aidPtr = [attachment AID]; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (id) lookupAttachment: (NSString *) childKey -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (enum mapistore_error) getAttachment: (MAPIStoreAttachment **) attachmentPtr - withAID: (uint32_t) aid -{ - MAPIStoreAttachment *attachment; - NSArray *keys; - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - - keys = [self attachmentKeys]; - if (aid < [keys count]) - { - attachment = [self lookupAttachment: [keys objectAtIndex: aid]]; - if (attachment) - { - *attachmentPtr = attachment; - rc = MAPISTORE_SUCCESS; - } - } - - return rc; -} - -- (enum mapistore_error) getAttachmentTable: (MAPIStoreAttachmentTable **) tablePtr - andRowCount: (uint32_t *) countPtr -{ - MAPIStoreAttachmentTable *attTable; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - attTable = [self attachmentTable]; - if (attTable) - { - *tablePtr = attTable; - *countPtr = [[attTable childKeys] count]; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (NSArray *) activeContainerMessageTables -{ - return [[MAPIStoreActiveTables activeTables] - activeTablesForFMID: [container objectId] - andType: MAPISTORE_MESSAGE_TABLE]; -} - -- (void) copyToMessage: (MAPIStoreMessage *) newMessage inMemCtx: (TALLOC_CTX *) memCtx; - -{ - //TALLOC_CTX *memCtx; - struct mapistore_message *messageData; - NSArray *keys; - NSUInteger count, max; - NSString *key; - MAPIStoreAttachment *attachment, *newAttachment; - - //[self logWithFormat: @"METHOD '%s' (%d) (%d)", __FUNCTION__, __LINE__, self]; - - //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 inMemCtx: memCtx]; - - /* 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 inMemCtx: memCtx]; - } - - //talloc_free (memCtx); -} - -- (enum mapistore_error) saveMessage: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - NSArray *containerTables; - NSUInteger count, max; - MAPIStoreContext *context; - SOGoUser *ownerUser; - BOOL userIsOwner; - MAPIStoreMessage *mainMessage; - - //[self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__]; - - containerTables = nil; - max = 0; - context = [self context]; - ownerUser = [[self userContext] sogoUser]; - userIsOwner = [[context activeUser] isEqual: ownerUser]; - if (userIsOwner) - mainMessage = nil; - else if ([self isKindOfClass: MAPIStoreEmbeddedMessageK]) - mainMessage = (MAPIStoreMessage *) [[self container] container]; - else - mainMessage = self; - - if (userIsOwner - || ([self isKindOfClass: MAPIStoreEmbeddedMessageK] - && [mainMessage subscriberCanModifyMessage]) - || (![self isKindOfClass: MAPIStoreEmbeddedMessageK] - && ((isNew - && [(MAPIStoreFolder *) container subscriberCanCreateMessages]) - || (!isNew && [self subscriberCanModifyMessage])))) - { - /* notifications */ - if ([container isKindOfClass: MAPIStoreFolderK]) - { - /* 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]; - } - - /* TODO: Check the save process succeeded */ - [self save: memCtx]; - /* We make sure that any change-related properties are removed 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)]; - [properties removeObjectForKey: MAPIPropertyKey (PidTagPredecessorChangeList)]; - - if ([container isKindOfClass: MAPIStoreFolderK]) - { - /* table modified */ - for (count = 0; count < max; count++) - { - id table; - - table = [containerTables objectAtIndex: count]; - - /* Safety check here as we could have MAPIStorePermissionsTable instances - in our containerTables array. This code might need to be reworked later */ - if ([table respondsToSelector: @selector(notifyChangesForChild:)]) - [table notifyChangesForChild: self]; - } - [container cleanupCaches]; - } - [self setIsNew: NO]; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_DENIED; - - return rc; -} - -/* getters */ -- (enum mapistore_error) getPidTagInstID: (void **) data // TODO: DOUBT - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* we return a unique id based on the key */ - *data = MAPILongLongValue (memCtx, [[sogoObject nameInContainer] hash]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagInstanceNum: (void **) data // TODO: DOUBT - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagRowType: (void **) data // TODO: DOUBT - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, TBL_LEAF_ROW); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagDepth: (void **) data // TODO: DOUBT - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongLongValue (memCtx, 0); - - return MAPISTORE_SUCCESS; -} - -/* - Possible values are: - - 0x00000001 Modify - 0x00000002 Read - 0x00000004 Delete - 0x00000008 Create Hierarchy Table - 0x00000010 Create Contents Table - 0x00000020 Create Associated Contents Table -*/ -- (enum mapistore_error) getPidTagAccess: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t access = 0; - BOOL userIsOwner; - MAPIStoreContext *context; - SOGoUser *ownerUser; - MAPIStoreMessage *mainMessage; - - context = [self context]; - ownerUser = [[self userContext] sogoUser]; - userIsOwner = [[context activeUser] isEqual: ownerUser]; - if (userIsOwner) - mainMessage = nil; - else if ([self isKindOfClass: MAPIStoreEmbeddedMessageK]) - mainMessage = (MAPIStoreMessage *) [[self container] container]; - else - mainMessage = self; - - if (userIsOwner || [mainMessage subscriberCanModifyMessage]) - access |= 0x01; - if (userIsOwner || [mainMessage subscriberCanReadMessage]) - access |= 0x02; - if (userIsOwner - || ([self isKindOfClass: MAPIStoreEmbeddedMessageK] - && [mainMessage subscriberCanModifyMessage]) - || [mainMessage subscriberCanDeleteMessage]) - access |= 0x04; - - *data = MAPILongValue (memCtx, access); - - return MAPISTORE_SUCCESS; -} - -/* - Possible values are: - - 0x00000000 Read-Only - 0x00000001 Modify -*/ -- (enum mapistore_error) getPidTagAccessLevel: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t access = 0; - BOOL userIsOwner; - MAPIStoreContext *context; - SOGoUser *ownerUser; - - context = [self context]; - ownerUser = [[self userContext] sogoUser]; - userIsOwner = [[context activeUser] isEqual: ownerUser]; - if (userIsOwner || [self subscriberCanModifyMessage]) - access = 0x01; - else - access = 0; - *data = MAPILongValue (memCtx, access); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagHasNamedProperties: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSideEffects: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidCurrentVersion: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - // *data = MAPILongValue (memCtx, 115608); // Outlook 11.5608 - *data = MAPILongValue (memCtx, 0x1ce3a); // Outlook 11.8330 - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidCurrentVersionName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"11.0" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidAutoProcessState: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0x00000000); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagFolderId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongLongValue (memCtx, [container objectId]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - uint64_t obId; - - obId = [self objectId]; - if (obId == ULLONG_MAX) - rc = MAPISTORE_ERR_NOT_FOUND; - else - { - *data = MAPILongLongValue (memCtx, obId); - rc = MAPISTORE_SUCCESS; - } - - return rc; -} - -- (enum mapistore_error) getPidTagMessageLocaleId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0x0409); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMessageFlags: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, MSGFLAG_FROMME | MSGFLAG_READ | MSGFLAG_UNMODIFIED); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMessageSize: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* TODO: choose another name in SOGo for that method */ - *data = MAPILongValue (memCtx, [[sogoObject davContentLength] intValue]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagImportance: (void **) data // TODO -> subclass? - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 1); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagPriority: (void **) data // TODO -> subclass? - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSensitivity: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSubject: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - TALLOC_CTX *localMemCtx; - char *prefix, *normalizedSubject; - - localMemCtx = talloc_zero (memCtx, 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); - - talloc_free(localMemCtx); - - return rc; -} - -- (enum mapistore_error) getPidTagNormalizedSubject: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagOriginalSubject: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagSubject: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagConversationTopic: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagNormalizedSubject: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSubjectPrefix: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getEmptyString: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagDeleteAfterSubmit: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagDisplayTo: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getEmptyString: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagDisplayCc: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getEmptyString: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagDisplayBcc: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getEmptyString: data inMemCtx: memCtx]; -} - -// - (enum mapistore_error) getPidTagOriginalDisplayTo: (void **) data -// { -// return [self getPidTagDisplayTo: data]; -// } - -// - (enum mapistore_error) getPidTagOriginalDisplayCc: (void **) data -// { -// return [self getPidTagDisplayCc: data]; -// } - -// - (enum mapistore_error) getPidTagOriginalDisplayBcc: (void **) data -// { -// return [self getPidTagDisplayBcc: data]; -// } - -- (enum mapistore_error) getPidTagLastModifierName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSURL *contextUrl; - - contextUrl = (NSURL *) [[self context] url]; - *data = [[contextUrl user] asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - [self subclassResponsibility: _cmd]; - - return MAPISTORE_ERR_NOT_FOUND; -} - -- (enum mapistore_error) getPidTagOriginalMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getProperty: data withTag: PidTagMessageClass inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagHasAttachments: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPIBoolValue (memCtx, - [[self attachmentKeys] count] > 0); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagAssociated: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx];; -} - -- (enum mapistore_error) setReadFlag: (uint8_t) flag -{ - // [self subclassResponsibility: _cmd]; - - return MAPISTORE_ERROR; -} - -- (void) save: (TALLOC_CTX *) memCtx -{ - [self subclassResponsibility: _cmd]; -} - -- (NSArray *) attachmentKeys -{ - if (!attachmentKeys) - { - attachmentKeys = [self attachmentKeysMatchingQualifier: nil - andSortOrderings: nil]; - [attachmentKeys retain]; - } - - return attachmentKeys; -} - -- (NSArray *) attachmentKeysMatchingQualifier: (EOQualifier *) qualifier - andSortOrderings: (NSArray *) sortOrderings -{ - if (qualifier) - [self errorWithFormat: @"qualifier is not used for attachments"]; - if (sortOrderings) - [self errorWithFormat: @"sort orderings are not used for attachments"]; - - return [attachmentParts allKeys]; -} - -- (MAPIStoreAttachmentTable *) attachmentTable -{ - return [MAPIStoreAttachmentTable tableForContainer: self]; -} - -- (void) addActiveTable: (MAPIStoreTable *) activeTable -{ - [activeTables addObject: activeTable]; -} - -- (void) removeActiveTable: (MAPIStoreTable *) activeTable -{ - [activeTables removeObject: activeTable]; -} - -- (NSArray *) activeUserRoles -{ - MAPIStoreContext *context; - MAPIStoreUserContext *userContext; - - if (!activeUserRoles) - { - context = [self context]; - userContext = [self userContext]; - activeUserRoles = [[context activeUser] - rolesForObject: sogoObject - inContext: [userContext woContext]]; - /* We use in this library the roles as flags, so we expand high - access rights with the lower ones */ - activeUserRoles = [self expandRoles: activeUserRoles]; - [activeUserRoles retain]; - } - - return activeUserRoles; -} - -/* Expand current roles with lower access roles to transform them to - flags */ -- (NSArray *) expandRoles: (NSArray *) roles -{ - return roles; -} - -/* Can the current active user read the message? */ -- (BOOL) subscriberCanReadMessage -{ - return NO; -} - -/* Can the current active user modify the message? */ -- (BOOL) subscriberCanModifyMessage -{ - return NO; -} - -/* Can the current active user delete the message? */ -- (BOOL) subscriberCanDeleteMessage -{ - return NO; -} - -@end diff --git a/OpenChange/MAPIStoreMessageTable.h b/OpenChange/MAPIStoreMessageTable.h deleted file mode 100644 index 9b1473325..000000000 --- a/OpenChange/MAPIStoreMessageTable.h +++ /dev/null @@ -1,35 +0,0 @@ -/* MAPIStoreMessageTable.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREMESSAGETABLE_H -#define MAPISTOREMESSAGETABLE_H - -#import "MAPIStoreTable.h" - -@interface MAPIStoreMessageTable : MAPIStoreTable - -- (void) setSortOrder: (const struct SSortOrderSet *) set; -- (void) notifyChangesForChild: (MAPIStoreMessage *) child; - -@end - -#endif /* MAPISTOREMESSAGETABLE_H */ diff --git a/OpenChange/MAPIStoreMessageTable.m b/OpenChange/MAPIStoreMessageTable.m deleted file mode 100644 index f978a5ea6..000000000 --- a/OpenChange/MAPIStoreMessageTable.m +++ /dev/null @@ -1,93 +0,0 @@ -/* MAPIStoreMessageTable.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import - -#import -#import - -#import "MAPIStoreContext.h" -#import "MAPIStoreFolder.h" -#import "MAPIStoreMessage.h" -#import "MAPIStoreTypes.h" -#import "NSData+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreMessageTable.h" - -@implementation MAPIStoreMessageTable - -- (void) setSortOrder: (const struct SSortOrderSet *) set -{ - [self logWithFormat: @"unimplemented method: %@", NSStringFromSelector (_cmd)]; -} - -- (NSArray *) childKeys -{ - if (!childKeys) - { - childKeys = [(MAPIStoreFolder *) - container messageKeysMatchingQualifier: nil - andSortOrderings: sortOrderings]; - [childKeys retain]; - } - - return childKeys; -} - -- (NSArray *) restrictedChildKeys -{ - NSArray *keys; - - if (!restrictedChildKeys) - { - if (restrictionState != MAPIRestrictionStateAlwaysTrue) - { - if (restrictionState == MAPIRestrictionStateNeedsEval) - keys = [(MAPIStoreFolder *) - container messageKeysMatchingQualifier: restriction - andSortOrderings: sortOrderings]; - else - keys = [NSArray array]; - } - else - keys = [self childKeys]; - - ASSIGN (restrictedChildKeys, keys); - } - - return restrictedChildKeys; -} - -- (id) lookupChild: (NSString *) childKey -{ - return [(MAPIStoreFolder *) container lookupMessage: childKey]; -} - -- (void) notifyChangesForChild: (MAPIStoreMessage *) child -{ - -} - -@end diff --git a/OpenChange/MAPIStoreNotesContext.h b/OpenChange/MAPIStoreNotesContext.h deleted file mode 100644 index 0c2f58261..000000000 --- a/OpenChange/MAPIStoreNotesContext.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreNotesContext.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTORENOTESCONTEXT_H -#define MAPISTORENOTESCONTEXT_H - -#import "MAPIStoreDBBaseContext.h" - -@interface MAPIStoreNotesContext : MAPIStoreDBBaseContext - -@end - -#endif /* MAPISTORENOTESCONTEXT_H */ diff --git a/OpenChange/MAPIStoreNotesContext.m b/OpenChange/MAPIStoreNotesContext.m deleted file mode 100644 index f5b8b1be3..000000000 --- a/OpenChange/MAPIStoreNotesContext.m +++ /dev/null @@ -1,77 +0,0 @@ -/* MAPIStoreNotesContext.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * Copyright (C) 2016 Enrique J. Hernandez - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import "MAPIStoreNotesFolder.h" -#import "MAPIStoreMapping.h" - -#import "MAPIStoreNotesContext.h" - -#undef DEBUG -#include - -static Class MAPIStoreNotesFolderK; - -@implementation MAPIStoreNotesContext - -+ (void) initialize -{ - MAPIStoreNotesFolderK = [MAPIStoreNotesFolder class]; -} - -+ (NSString *) MAPIModuleName -{ - return @"notes"; -} - -+ (enum mapistore_context_role) MAPIContextRole -{ - return MAPISTORE_NOTES_ROLE; -} - -- (Class) MAPIStoreFolderClass -{ - return MAPIStoreNotesFolderK; -} - -+ (struct mapistore_contexts_list *) listContextsForUser: (NSString *) userName - withIndexing: (struct indexing_context *) indexing - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct mapistore_contexts_list *context; - - context = talloc_zero(memCtx, struct mapistore_contexts_list); - context->url = talloc_asprintf (context, "sogo://%s@notes/", - [[userName stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"] UTF8String]); - // context->name = "Notes personnelles"; - context->main_folder = true; - context->role = MAPISTORE_NOTES_ROLE; - context->tag = "tag"; - context->prev = context; - - return context; -} - -@end diff --git a/OpenChange/MAPIStoreNotesFolder.h b/OpenChange/MAPIStoreNotesFolder.h deleted file mode 100644 index 4f049fb4f..000000000 --- a/OpenChange/MAPIStoreNotesFolder.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreNotesFolder.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORENOTESFOLDER_H -#define MAPISTORENOTESFOLDER_H - -#import "MAPIStoreDBFolder.h" - -@interface MAPIStoreNotesFolder : MAPIStoreDBFolder -@end - -#endif /* MAPISTORENOTESFOLDER_H */ diff --git a/OpenChange/MAPIStoreNotesFolder.m b/OpenChange/MAPIStoreNotesFolder.m deleted file mode 100644 index c3c1c4777..000000000 --- a/OpenChange/MAPIStoreNotesFolder.m +++ /dev/null @@ -1,41 +0,0 @@ -/* MAPIStoreNotesFolder.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 "MAPIStoreNotesFolder.h" -#import "MAPIStoreNotesMessage.h" -#import "NSString+MAPIStore.h" - -#include - -#import "MAPIStoreNotesFolder.h" - -@implementation MAPIStoreNotesFolder - -- (enum mapistore_error) getPidTagDefaultPostMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPM.StickyNote" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -@end diff --git a/OpenChange/MAPIStoreNotesMessage.h b/OpenChange/MAPIStoreNotesMessage.h deleted file mode 100644 index 08c1223d0..000000000 --- a/OpenChange/MAPIStoreNotesMessage.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MAPIStoreNotesMessage.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORENOTESMESSAGE_H -#define MAPISTORENOTESMESSAGE_H - -#import "MAPIStoreDBMessage.h" - -@interface MAPIStoreNotesMessage : MAPIStoreDBMessage -@end - -#endif /* MAPISTORENOTESMESSAGE_H */ diff --git a/OpenChange/MAPIStoreNotesMessage.m b/OpenChange/MAPIStoreNotesMessage.m deleted file mode 100644 index f594b6c27..000000000 --- a/OpenChange/MAPIStoreNotesMessage.m +++ /dev/null @@ -1,56 +0,0 @@ -/* MAPIStoreNotesMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import "MAPIStoreTypes.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreNotesMessage.h" - -#include - -@implementation MAPIStoreNotesMessage - -- (enum mapistore_error) getPidTagIconIndex: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */ - // *longValue = 0x00000300 for blue - // *longValue = 0x00000301 for green - // *longValue = 0x00000302 for pink - // *longValue = 0x00000303 for yellow - // *longValue = 0x00000304 for white - *data = MAPILongValue (memCtx, 0x00000303); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMessageClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPM.StickyNote" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -@end diff --git a/OpenChange/MAPIStoreObject.h b/OpenChange/MAPIStoreObject.h deleted file mode 100644 index abf126658..000000000 --- a/OpenChange/MAPIStoreObject.h +++ /dev/null @@ -1,103 +0,0 @@ -/* MAPIStoreObject.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREOBJECT_H -#define MAPISTOREOBJECT_H - -#include - -#import - -@class NSDate; -@class NSData; -@class NSString; -@class NSMutableArray; -@class NSMutableDictionary; - -@class MAPIStoreContext; -@class MAPIStoreMapping; -@class MAPIStoreObjectProxy; -@class MAPIStoreUserContext; -@class MAPIStoreSOGoObject; - -@interface MAPIStoreObject : NSObject -{ - const IMP *classGetters; - - NSMutableArray *parentContainersBag; - NSMutableArray *proxies; - id container; - NSMutableDictionary *properties; -} - -+ (id) mapiStoreObjectInContainer: (MAPIStoreObject *) newContainer; -- (id) initInContainer: (MAPIStoreObject *) newContainer; - -- (void) addProxy: (MAPIStoreObjectProxy *) newProxy; - -- (MAPIStoreObject *) container; - -- (MAPIStoreContext *) context; -- (MAPIStoreUserContext *) userContext; -- (MAPIStoreMapping *) mapping; - -- (NSString *) url; - -/* properties */ - -- (void) addProperties: (NSDictionary *) newProperties; -- (NSMutableDictionary *) properties; - -/* ops */ -- (enum mapistore_error) getProperties: (struct mapistore_property_data *) data - withTags: (enum MAPITAGS *) tags - andCount: (uint16_t) columnCount - inMemCtx: (TALLOC_CTX *) localMemCtx; - -- (enum mapistore_error) addPropertiesFromRow: (struct SRow *) aRow; - -- (enum mapistore_error) getProperty: (void **) data - withTag: (enum MAPITAGS) propTag - inMemCtx: (TALLOC_CTX *) localMemCtx; - -/* helper getters */ -- (NSData *) getReplicaKeyFromGlobCnt: (uint64_t) objectCnt; -- (enum mapistore_error) getReplicaKey: (void **) data - fromGlobCnt: (uint64_t) objectCnt - inMemCtx: (TALLOC_CTX *) memCtx; - -- (enum mapistore_error) getPidTagCreationTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagLastModificationTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; - -/* move and copy operations */ -- (void) copyPropertiesToObject: (MAPIStoreObject *) newObject inMemCtx: (TALLOC_CTX *) memCtx; - -/* subclasses */ -- (NSString *) nameInContainer; -- (NSDate *) creationTime; -- (NSDate *) lastModificationTime; - -@end - -#endif /* MAPISTOREOBJECT_H */ diff --git a/OpenChange/MAPIStoreObject.m b/OpenChange/MAPIStoreObject.m deleted file mode 100644 index c5c8cacb2..000000000 --- a/OpenChange/MAPIStoreObject.m +++ /dev/null @@ -1,395 +0,0 @@ -/* MAPIStoreObject.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreContext.h" -#import "MAPIStoreFolder.h" -#import "MAPIStorePropertySelectors.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSDate+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreObject.h" - -#undef DEBUG -#include -#include -#include -#include -#include - -@implementation MAPIStoreObject - -static Class NSExceptionK, MAPIStoreFolderK; - -+ (void) initialize -{ - NSExceptionK = [NSExceptionK class]; - MAPIStoreFolderK = [MAPIStoreFolder class]; -} - -+ (id) mapiStoreObjectInContainer: (MAPIStoreObject *) newContainer -{ - id newObject; - - newObject = [[self alloc] initInContainer: newContainer]; - [newObject autorelease]; - - return newObject; -} - -- (id) init -{ - if ((self = [super init])) - { - classGetters = (IMP *) MAPIStorePropertyGettersForClass (isa); - parentContainersBag = [NSMutableArray new]; - container = nil; - properties = [NSMutableDictionary new]; - proxies = [NSMutableArray new]; - } - - // [self logWithFormat: @"-init"]; - - return self; -} - -- (id) initInContainer: (MAPIStoreObject *) newContainer -{ - if ((self = [self init])) - { - ASSIGN (container, newContainer); - } - - return self; -} - -- (void) dealloc -{ - // [self logWithFormat: @"-dealloc"]; - [proxies release]; - [properties release]; - [parentContainersBag release]; - [container release]; - [super dealloc]; -} - -- (MAPIStoreObject *) container -{ - return container; -} - -- (MAPIStoreContext *) context -{ - return (MAPIStoreContext *) [container context]; -} - -- (MAPIStoreUserContext *) userContext -{ - return [[self context] userContext]; -} - -- (MAPIStoreMapping *) mapping -{ - return [[self userContext] mapping]; -} - -- (NSString *) url -{ - NSString *containerURL, *urlName, *format; - - containerURL = (NSString *) [container url]; - if ([containerURL hasSuffix: @"/"]) - format = @"%@%@"; - else - format = @"%@/%@"; - - urlName = [[self nameInContainer] - stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; - return [NSString stringWithFormat: format, containerURL, urlName]; -} - -/* helpers */ - -- (void) addProperties: (NSDictionary *) newNewProperties -{ - [properties addEntriesFromDictionary: newNewProperties]; -} - -- (NSMutableDictionary *) properties -{ - return properties; -} - -- (enum mapistore_error) getProperty: (void **) data - withTag: (enum MAPITAGS) propTag - inMemCtx: (TALLOC_CTX *) memCtx -{ - MAPIStorePropertyGetter method = NULL; - uint16_t propValue; - SEL methodSel; - id value; - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - NSUInteger count, max; - - value = [properties objectForKey: MAPIPropertyKey (propTag)]; - if (value) - rc = [value getValue: data forTag: propTag inMemCtx: memCtx]; - else - { - propValue = (propTag & 0xffff0000) >> 16; - methodSel = MAPIStoreSelectorForPropertyGetter (propValue); - method = (MAPIStorePropertyGetter) classGetters[propValue]; - if (method) - rc = method (self, methodSel, data, memCtx); - } - - if (rc == MAPISTORE_ERR_NOT_FOUND) - { - max = [proxies count]; - for (count = 0; rc == MAPISTORE_ERR_NOT_FOUND && count < max; count++) - rc = [[proxies objectAtIndex: count] - getProperty: data - withTag: propTag - inMemCtx: memCtx]; - } - - return rc; -} - -- (enum mapistore_error) getPidTagCreationTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[self creationTime] asFileTimeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagLastModificationTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[self lastModificationTime] asFileTimeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (BOOL) canGetProperty: (enum MAPITAGS) propTag -{ - uint16_t propValue; - BOOL canGetProperty; - NSUInteger count, max; - - propValue = (propTag >> 16) & 0xffff; - - canGetProperty = (classGetters[propValue] - || [properties objectForKey: MAPIPropertyKey (propTag)]); - max = [proxies count]; - for (count = 0; !canGetProperty && count < max; count++) - canGetProperty = [[proxies objectAtIndex: count] canGetProperty: propTag]; - - return canGetProperty; -} - -- (enum mapistore_error) getProperties: (struct mapistore_property_data *) data - withTags: (enum MAPITAGS *) tags - andCount: (uint16_t) columnCount - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint16_t count; - - for (count = 0; count < columnCount; count++) - data[count].error = [self getProperty: &data[count].data - withTag: tags[count] - inMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (void) addProxy: (MAPIStoreObjectProxy *) newProxy -{ - [proxies addObject: newProxy]; -} - -- (enum mapistore_error) addPropertiesFromRow: (struct SRow *) aRow -{ - struct SPropValue *cValue; - NSUInteger counter; - NSMutableDictionary *newProperties; - id value; - - newProperties = [NSMutableDictionary dictionaryWithCapacity: aRow->cValues]; - for (counter = 0; counter < aRow->cValues; counter++) - { - cValue = aRow->lpProps + counter; - value = NSObjectFromSPropValue (cValue); - if (value == nil) - continue; - - switch (cValue->ulPropTag & 0xffff) - { - case PT_STRING8: - case PT_MV_STRING8: - [self warnWithFormat: - @"attempting to set string property as PR_STRING8: %.8x", - cValue->ulPropTag]; - break; - } - [newProperties setObject: value - forKey: MAPIPropertyKey (cValue->ulPropTag)]; - } - - [self addProperties: newProperties]; - - return MAPISTORE_SUCCESS; -} - -// -// The GlobCnt is 6 bytes long. -// -- (NSData *) getReplicaKeyFromGlobCnt: (uint64_t) objectCnt -{ - struct mapistore_connection_info *connInfo; - NSMutableData *replicaKey; - char buffer[6]; - NSUInteger count; - - connInfo = [[self context] connectionInfo]; - - for (count = 0; count < 6; count++) - { - buffer[count] = objectCnt & 0xff; - objectCnt >>= 8; - } - - replicaKey = [NSMutableData dataWithCapacity: 22]; - [replicaKey appendBytes: &connInfo->replica_guid - length: sizeof (struct GUID)]; - [replicaKey appendBytes: buffer length: 6]; - - return replicaKey; -} - -- (enum mapistore_error) getReplicaKey: (void **) data - fromGlobCnt: (uint64_t) objectCnt - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[self getReplicaKeyFromGlobCnt: objectCnt] asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -/* move and copy operations */ -- (void) copyPropertiesToObject: (MAPIStoreObject *) newObject inMemCtx: (TALLOC_CTX *) memCtx -{ - //TALLOC_CTX *memCtx; - struct SPropTagArray *availableProps; - struct SRow row; - enum MAPITAGS propTag; - bool *exclusions; - NSUInteger count; - enum mapistore_error error; - void *data; - - //memCtx = talloc_zero (NULL, TALLOC_CTX); - - [self getAvailableProperties: &availableProps inMemCtx: memCtx]; - - /* We exclude identity and versioning properties to facilitate copy - operations. If they need to be set (move operations), the caller will need - to take care of them. */ - exclusions = talloc_array (memCtx, bool, 65536); - exclusions[(PidTagRowType >> 16) & 0xffff] = true; - exclusions[(PidTagInstanceKey >> 16) & 0xffff] = true; - exclusions[(PidTagInstanceNum >> 16) & 0xffff] = true; - exclusions[(PidTagInstID >> 16) & 0xffff] = true; - exclusions[(PidTagAttachNumber >> 16) & 0xffff] = true; - exclusions[(PidTagFolderId >> 16) & 0xffff] = true; - exclusions[(PidTagMid >> 16) & 0xffff] = true; - exclusions[(PidTagSourceKey >> 16) & 0xffff] = true; - exclusions[(PidTagParentSourceKey >> 16) & 0xffff] = true; - exclusions[(PidTagParentFolderId >> 16) & 0xffff] = true; - exclusions[(PidTagChangeKey >> 16) & 0xffff] = true; - exclusions[(PidTagChangeNumber >> 16) & 0xffff] = true; - exclusions[(PidTagPredecessorChangeList >> 16) & 0xffff] = true; - - row.cValues = 0; - row.lpProps = talloc_array (memCtx, struct SPropValue, 65535); - - for (count = 0; count < availableProps->cValues; count++) - { - propTag = availableProps->aulPropTag[count]; - if (!exclusions[(propTag >> 16) & 0xffff]) - { - error = [self getProperty: &data withTag: propTag inMemCtx: memCtx]; - if (error == MAPISTORE_SUCCESS && data) - { - set_SPropValue_proptag (row.lpProps + row.cValues, propTag, - data); - row.cValues++; - } - } - } - [newObject addPropertiesFromRow: &row]; - - //talloc_free (memCtx); -} - -/* subclasses */ -- (NSString *) nameInContainer -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (NSDate *) creationTime -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (NSDate *) lastModificationTime -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -/* logging */ -- (NSString *) loggingPrefix -{ - return [NSString stringWithFormat:@"<%@:%p:%@>", - NSStringFromClass (isa), self, [self nameInContainer]]; -} - -@end diff --git a/OpenChange/MAPIStoreObjectProxy.h b/OpenChange/MAPIStoreObjectProxy.h deleted file mode 100644 index 6e9aee13e..000000000 --- a/OpenChange/MAPIStoreObjectProxy.h +++ /dev/null @@ -1,41 +0,0 @@ -/* MAPIStoreObjectProxy.h - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREOBJECTPROXY_H -#define MAPISTOREOBJECTPROXY_H - -#include - -#import - -@interface MAPIStoreObjectProxy : NSObject -{ - const IMP *classGetters; -} - -- (enum mapistore_error) getProperty: (void **) data - withTag: (enum MAPITAGS) propTag - inMemCtx: (TALLOC_CTX *) localMemCtx; - -@end - -#endif /* MAPISTOREOBJECTPROXY_H */ diff --git a/OpenChange/MAPIStoreObjectProxy.m b/OpenChange/MAPIStoreObjectProxy.m deleted file mode 100644 index 1fc6157e6..000000000 --- a/OpenChange/MAPIStoreObjectProxy.m +++ /dev/null @@ -1,67 +0,0 @@ -/* MAPIStoreObjectProxy.m - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#import "MAPIStorePropertySelectors.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreObjectProxy.h" - -#undef DEBUG -#include -#include -#include -#include -#include - -@implementation MAPIStoreObjectProxy - -- (id) init -{ - if ((self = [super init])) - { - classGetters = (IMP *) MAPIStorePropertyGettersForClass (isa); - } - - return self; -} - -- (enum mapistore_error) getProperty: (void **) data - withTag: (enum MAPITAGS) propTag - inMemCtx: (TALLOC_CTX *) memCtx -{ - MAPIStorePropertyGetter method; - uint16_t propValue; - SEL methodSel; - enum mapistore_error rc; - - propValue = (propTag & 0xffff0000) >> 16; - methodSel = MAPIStoreSelectorForPropertyGetter (propValue); - method = (MAPIStorePropertyGetter) classGetters[propValue]; - if (method) - rc = method (self, methodSel, data, memCtx); - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -@end diff --git a/OpenChange/MAPIStorePermissionsTable.h b/OpenChange/MAPIStorePermissionsTable.h deleted file mode 100644 index 3f951f50c..000000000 --- a/OpenChange/MAPIStorePermissionsTable.h +++ /dev/null @@ -1,55 +0,0 @@ -/* MAPIStorePermissionsTable.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTOREPERMISSIONSTABLE_H -#define MAPISTOREPERMISSIONSTABLE_H - -#import "MAPIStoreTable.h" - -struct ldb_context; - -@interface MAPIStorePermissionEntry : MAPIStoreObject -{ - NSString *userId; - uint64_t memberId; -} - -+ (id) entryWithUserId: (NSString *) newUserId - andMemberId: (uint64_t) newMemberId - forFolder: (MAPIStoreFolder *) newFolder; -- (id) initWithUserId: (NSString *) newUserId - andMemberId: (uint64_t) newMemberId - forFolder: (MAPIStoreFolder *) newFolder; - -- (NSString *) userId; -- (uint64_t) memberId; - -@end - -@interface MAPIStorePermissionsTable : MAPIStoreTable -{ - NSMutableDictionary *entries; -} - -@end - -#endif /* MAPISTOREPERMISSIONSTABLE_H */ diff --git a/OpenChange/MAPIStorePermissionsTable.m b/OpenChange/MAPIStorePermissionsTable.m deleted file mode 100644 index 3bd2f84b7..000000000 --- a/OpenChange/MAPIStorePermissionsTable.m +++ /dev/null @@ -1,195 +0,0 @@ -/* MAPIStorePermissionsTable.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import - -#import "MAPIStoreContext.h" -#import "MAPIStoreFolder.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreSamDBUtils.h" -#import "NSData+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStorePermissionsTable.h" - -#undef DEBUG -#include -#include - -@implementation MAPIStorePermissionEntry - -+ (id) entryWithUserId: (NSString *) newUserId - andMemberId: (uint64_t) newMemberId - forFolder: (MAPIStoreFolder *) newFolder -{ - MAPIStorePermissionEntry *newEntry; - - newEntry = [[self alloc] initWithUserId: newUserId andMemberId: newMemberId - forFolder: newFolder]; - [newEntry autorelease]; - - return newEntry; -} - -- (id) initWithUserId: (NSString *) newUserId - andMemberId: (uint64_t) newMemberId - forFolder: (MAPIStoreFolder *) newFolder -{ - if ((self = [self initInContainer: newFolder])) - { - ASSIGN (userId, newUserId); - memberId = newMemberId; - } - - return self; -} - -- (void) dealloc -{ - [userId release]; - [super dealloc]; -} - -- (NSString *) userId -{ - return userId; -} - -- (uint64_t) memberId -{ - return memberId; -} - -- (enum mapistore_error) getPidTagMemberId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongLongValue (memCtx, memberId); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSData *entryId; - struct mapistore_connection_info *connInfo; - - if (memberId == 0 || memberId == ULLONG_MAX) - entryId = [NSData data]; - else - { - connInfo = [(MAPIStoreContext *) [container context] connectionInfo]; - entryId = MAPIStoreInternalEntryId (connInfo, userId); - } - *data = [entryId asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMemberName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *displayName; - - if (memberId == 0) - displayName = @""; - else if (memberId == ULLONG_MAX) - displayName = @"Anonymous"; - else - displayName = [[SOGoUser userWithLogin: userId] cn]; - - *data = [displayName asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMemberRights: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t rights; - NSArray *roles; - - roles = [[(MAPIStoreFolder *) container aclFolder] aclsForUser: userId]; - roles = [(MAPIStoreFolder *) container expandRoles: roles]; - rights = [(MAPIStoreFolder *) container exchangeRightsForRoles: roles]; - - *data = MAPILongValue (memCtx, rights); - - return MAPISTORE_SUCCESS; -} - -@end - -@implementation MAPIStorePermissionsTable - -- (void) dealloc -{ - [entries release]; - [super dealloc]; -} - -- (void) _fetchEntries -{ - NSArray *permEntries; - NSUInteger count, max; - MAPIStorePermissionEntry *entry; - - entries = [NSMutableDictionary new]; - permEntries = [(MAPIStoreFolder *) container permissionEntries]; - max = [permEntries count]; - for (count = 0; count < max; count++) - { - entry = [permEntries objectAtIndex: count]; - [entries setObject: entry forKey: [entry userId]]; - } - - childKeys = [entries allKeys]; - [childKeys retain]; -} - -- (NSArray *) childKeys -{ - if (!entries) - [self _fetchEntries]; - - return childKeys; -} - -- (NSArray *) restrictedChildKeys -{ - return [self childKeys]; -} - -- (id) lookupChild: (NSString *) childKey -{ - if (!entries) - [self _fetchEntries]; - - return [entries objectForKey: childKey]; -} - -@end diff --git a/OpenChange/MAPIStoreRecurrenceUtils.h b/OpenChange/MAPIStoreRecurrenceUtils.h deleted file mode 100644 index dbb2f0c19..000000000 --- a/OpenChange/MAPIStoreRecurrenceUtils.h +++ /dev/null @@ -1,58 +0,0 @@ -/* MAPIStoreRecurrenceUtils.h - this file is part of $PROJECT_NAME_HERE$ - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORERECURRENCEUTILS_H -#define MAPISTORERECURRENCEUTILS_H - -#include - -#import -#import -#import - -@class iCalEvent; -@class iCalRepeatableEntityObject; -@class iCalRecurrenceRule; - -#define SOGoMinutesPerHour 60 -#define SOGoHoursPerDay 24 -#define SOGoMinutesPerDay (SOGoMinutesPerHour * SOGoHoursPerDay) - -@interface iCalCalendar (MAPIStoreRecurrence) - -- (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity - fromRecurrencePattern: (struct RecurrencePattern *) rp - withExceptions: (struct ExceptionInfo *) exInfos - andExceptionCount: (uint16_t) exInfoCount - inTimeZone: (iCalTimeZone *) tz; - -@end - -@interface iCalRecurrenceRule (MAPIStoreRecurrence) - -- (void) fillRecurrencePattern: (struct RecurrencePattern *) rp - withEvent: (iCalEvent *) event - inMemCtx: (TALLOC_CTX *) memCtx; - -@end - -#endif /* MAPISTORERECURRENCEUTILS_H */ diff --git a/OpenChange/MAPIStoreRecurrenceUtils.m b/OpenChange/MAPIStoreRecurrenceUtils.m deleted file mode 100644 index 90052474a..000000000 --- a/OpenChange/MAPIStoreRecurrenceUtils.m +++ /dev/null @@ -1,483 +0,0 @@ -/* MAPIStoreRecurrenceUtils.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import - -#import -#import - -#import -#import -#import -#import -#import -#import -#import - -#import "NSDate+MAPIStore.h" -#import "MAPIStoreRecurrenceUtils.h" -#import "MAPIStoreTypes.h" - -#include -#include -#include -#include - -@implementation iCalCalendar (MAPIStoreRecurrence) - -- (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity - fromRecurrencePattern: (struct RecurrencePattern *) rp - withExceptions: (struct ExceptionInfo *) exInfos - andExceptionCount: (uint16_t) exInfoCount - inTimeZone: (iCalTimeZone *) tz - -{ - NSCalendarDate *startDate, *olEndDate, *untilDate, *exDate; - NSString *monthDay, *month; - NSMutableSet *exceptionDates; - NSArray *realExDates; - iCalRecurrenceRule *rule; - iCalByDayMask *byDayMask; - iCalWeekOccurrence weekOccurrence; - iCalWeekOccurrences dayMaskDays; - NSUInteger count, max; - NSInteger bySetPos, tzOffset; - unsigned char maskValue; - - [entity removeAllRecurrenceRules]; - [entity removeAllExceptionRules]; - [entity removeAllExceptionDates]; - - rule = [iCalRecurrenceRule elementWithTag: @"rrule"]; - [entity addToRecurrenceRules: rule]; - - startDate = [entity startDate]; - // DEBUG(5, ("From client:\n")); - // NDR_PRINT_DEBUG(AppointmentRecurrencePattern, pattern); - - memset (&dayMaskDays, 0, sizeof (iCalWeekOccurrences)); - if (rp->PatternType == PatternType_Day) - { - [rule setFrequency: iCalRecurrenceFrequenceDaily]; - [rule setRepeatInterval: rp->Period / SOGoMinutesPerDay]; - } - else if (rp->PatternType == PatternType_Week) - { - [rule setFrequency: iCalRecurrenceFrequenceWeekly]; - [rule setRepeatInterval: rp->Period]; - /* MAPI values for days are the same as in NGCards */ - for (count = 0; count < 7; count++) - { - maskValue = 1 << count; - if ((rp->PatternTypeSpecific.WeekRecurrencePattern & maskValue)) - dayMaskDays[count] = iCalWeekOccurrenceAll; - } - byDayMask = [iCalByDayMask byDayMaskWithDays: dayMaskDays]; - [rule setByDayMask: byDayMask]; - } - else - { - if (rp->RecurFrequency - == RecurFrequency_Monthly) - { - [rule setFrequency: iCalRecurrenceFrequenceMonthly]; - [rule setRepeatInterval: rp->Period]; - } - else if (rp->RecurFrequency - == RecurFrequency_Yearly) - { - [rule setFrequency: iCalRecurrenceFrequenceYearly]; - [rule setRepeatInterval: rp->Period / 12]; - month = [NSString stringWithFormat: @"%d", [startDate monthOfYear]]; - [rule setSingleValue: month forKey: @"bymonth"]; - } - else - [self errorWithFormat: - @"unhandled frequency case for Month pattern type: %d", - rp->RecurFrequency]; - - if ((rp->PatternType & 3) == 3) - { - /* HjMonthNth and MonthNth */ - if (rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern - == 0x7f) - { - /* firsts or last day of month */ - if (rp->PatternTypeSpecific.MonthRecurrencePattern.N - == RecurrenceN_Last) - monthDay = @"-1"; - else - monthDay = [NSString stringWithFormat: @"%d", - rp->PatternTypeSpecific.MonthRecurrencePattern.N]; - [rule setSingleValue: monthDay forKey: @"bymonthday"]; - } - else if ((rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern - == 0x3e) /* Nth week day */ - || (rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern - == 0x41)) /* Nth week-end day */ - { - for (count = 0; count < 7; count++) - { - maskValue = 1 << count; - if ((rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern - & maskValue)) - dayMaskDays[count] = iCalWeekOccurrenceAll; - } - byDayMask = [iCalByDayMask byDayMaskWithDays: dayMaskDays]; - [rule setByDayMask: byDayMask]; - - if (rp->PatternTypeSpecific.MonthRecurrencePattern.N - == RecurrenceN_Last) - bySetPos = -1; - else - bySetPos = rp->PatternTypeSpecific.MonthRecurrencePattern.N; - - [rule - setSingleValue: [NSString stringWithFormat: @"%d", bySetPos] - forKey: @"bysetpos"]; - } - else - { - if (rp->PatternTypeSpecific.MonthRecurrencePattern.N - < RecurrenceN_Last) - weekOccurrence = (1 - << (rp->PatternTypeSpecific.MonthRecurrencePattern.N - - 1)); - else - weekOccurrence = iCalWeekOccurrenceLast; - - for (count = 0; count < 7; count++) - { - maskValue = 1 << count; - if ((rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern - & maskValue)) - dayMaskDays[count] = weekOccurrence; - } - byDayMask = [iCalByDayMask byDayMaskWithDays: dayMaskDays]; - [rule setByDayMask: byDayMask]; - } - } - else if ((rp->PatternType & 2) == 2 - || (rp->PatternType & 4) == 4) - { - /* MonthEnd, HjMonth and HjMonthEnd */ - [rule - setSingleValue: [NSString stringWithFormat: @"%d", - rp->PatternTypeSpecific.Day] - forKey: @"bymonthday"]; - } - else - [self errorWithFormat: @"invalid value for PatternType: %.4x", - rp->PatternType]; - } - - switch (rp->EndType) - { - case END_NEVER_END: - case NEVER_END: - break; - case END_AFTER_N_OCCURRENCES: - [rule setRepeatCount: rp->OccurrenceCount]; - break; - case END_AFTER_DATE: - olEndDate = [NSCalendarDate dateFromMinutesSince1601: rp->EndDate]; - untilDate = [NSCalendarDate dateWithYear: [olEndDate yearOfCommonEra] - month: [olEndDate monthOfYear] - day: [olEndDate dayOfMonth] - hour: [startDate hourOfDay] - minute: [startDate minuteOfHour] - second: [startDate secondOfMinute] - timeZone: [startDate timeZone]]; - [rule setUntilDate: untilDate]; - break; - default: - [self errorWithFormat: @"invalid value for EndType: %.4x", - rp->EndType]; - } - - /* exception dates: - - take all deleted instances - - remove all modified instances available in ExceptionInfo from the above set - - add remaining instances, in chronological order - */ - - /* Heuristic to avoid these loops */ - if (rp->DeletedInstanceCount != rp->ModifiedInstanceCount) { - exceptionDates = [NSMutableSet set]; - for (count = 0; count < rp->DeletedInstanceCount; count++) - { - exDate - = [NSDate dateFromMinutesSince1601: rp->DeletedInstanceDates[count]]; - exDate = [exDate hour: [startDate hourOfDay] - minute: [startDate minuteOfHour] - second: [startDate secondOfMinute]]; - [exceptionDates addObject: exDate]; - } - /* Read the exceptions to remove the instances that are modified and not deleted */ - if (exInfos && exInfoCount > 0) - { - for (count = 0; count < exInfoCount; count++) - { - /* The OriginalStartDate is in local time */ - exDate = [NSDate dateFromMinutesSince1601: exInfos[count].OriginalStartDate]; - tzOffset = -[[tz periodForDate: exDate] secondsOffsetFromGMT]; - exDate = [exDate dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: tzOffset]; - [exceptionDates removeObject: exDate]; - } - } - - realExDates = [[exceptionDates allObjects] - sortedArrayUsingSelector: @selector (compare:)]; - max = [realExDates count]; - for (count = 0; count < max; count++) - [entity addToExceptionDates: [realExDates objectAtIndex: count]]; - } -} - -@end - -@implementation iCalRecurrenceRule (MAPIStoreRecurrence) - -- (void) fillRecurrencePattern: (struct RecurrencePattern *) rp - withEvent: (iCalEvent *) event - inMemCtx: (TALLOC_CTX *) memCtx -{ - iCalRecurrenceFrequency freq; - iCalByDayMask *byDayMask; - NSString *byMonthDay, *bySetPos; - NSCalendarDate *startDate, *endDate, *untilDate, *beginOfWeek, *minimumDate, - *moduloDate, *midnight; - iCalWeekOccurrences *days; - NSInteger dayOfWeek, repeatInterval, repeatCount, count, firstOccurrence, - max; - uint32_t nbrMonths, mask; - NSArray *events; - NSMutableArray *deletedDates, *modifiedDates; - - startDate = [event firstRecurrenceStartDate]; - endDate = [event lastPossibleRecurrenceStartDate]; - - rp->ReaderVersion = 0x3004; - rp->WriterVersion = 0x3004; - - rp->StartDate = [[startDate beginOfDay] asMinutesSince1601]; - - untilDate = [self untilDate]; - if (untilDate) - { - rp->EndDate = [untilDate asMinutesSince1601]; - rp->EndType = END_AFTER_DATE; - } - else - { - repeatCount = [self repeatCount]; - if (repeatCount > 0) - { - rp->EndDate = [endDate asMinutesSince1601]; - rp->OccurrenceCount = repeatCount; - rp->EndType = END_AFTER_N_OCCURRENCES; - } - else - { - rp->EndDate = 0x5ae980df; - rp->OccurrenceCount = 0xa; - rp->EndType = END_NEVER_END; - } - } - - freq = [self frequency]; - repeatInterval = [self repeatInterval]; - if (freq == iCalRecurrenceFrequenceDaily) - { - rp->RecurFrequency = RecurFrequency_Daily; - rp->PatternType = PatternType_Day; - rp->Period = repeatInterval * SOGoMinutesPerDay; - rp->FirstDateTime = rp->StartDate % rp->Period; - } - else if (freq == iCalRecurrenceFrequenceWeekly) - { - rp->RecurFrequency = RecurFrequency_Weekly; - rp->PatternType = PatternType_Week; - rp->Period = repeatInterval; - - dayOfWeek = [startDate dayOfWeek]; - - mask = 0; - byDayMask = [self byDayMask]; - if (byDayMask) - { - for (count = 0; count < 7; count++) - if ([byDayMask occursOnDay: count]) - mask |= 1 << count; - } - else - { - /* Set the recurrence pattern using start date */ - mask |= 1 << dayOfWeek; - } - rp->PatternTypeSpecific.WeekRecurrencePattern = mask; - - /* FirstDateTime */ - if (dayOfWeek) - beginOfWeek = [startDate dateByAddingYears: 0 months: 0 - days: -dayOfWeek - hours: 0 minutes: 0 - seconds: 0]; - else - beginOfWeek = startDate; - rp->FirstDateTime = ([[beginOfWeek beginOfDay] asMinutesSince1601] - % (repeatInterval * 10080)); - } - else - { - if (freq == iCalRecurrenceFrequenceMonthly) - { - rp->RecurFrequency = RecurFrequency_Monthly; - rp->Period = repeatInterval; - } - else if (freq == iCalRecurrenceFrequenceYearly) - { - rp->RecurFrequency = RecurFrequency_Yearly; - rp->Period = 12; - if (repeatInterval != 1) - [self errorWithFormat: - @"yearly interval '%d' cannot be converted", - repeatInterval]; - } - else - [self errorWithFormat: @"frequency '%d' cannot be converted", freq]; - - /* FirstDateTime */ - midnight = [[startDate firstDayOfMonth] beginOfDay]; - minimumDate = [NSCalendarDate dateFromMinutesSince1601: 0]; - nbrMonths = (([midnight yearOfCommonEra] - - [minimumDate yearOfCommonEra]) * 12 - + [midnight monthOfYear] - 1); - moduloDate = [minimumDate dateByAddingYears: 0 - months: (nbrMonths % rp->Period) - days: 0 hours: 0 minutes: 0 - seconds: 0]; - rp->FirstDateTime = [moduloDate asMinutesSince1601]; - - byMonthDay = [[self byMonthDay] objectAtIndex: 0]; - if (!byMonthDay && (freq == iCalRecurrenceFrequenceYearly)) - { - byMonthDay = [NSString stringWithFormat: @"%d", [startDate dayOfMonth]]; - [self warnWithFormat: @"no month day specified in yearly" - @" recurrence: we deduce it from the start date: %@", - byMonthDay]; - } - - if (byMonthDay) - { - if ([byMonthDay intValue] < 0) - { - /* This means we cannot handle values of BYMONTHDAY that are < - -7. */ - rp->PatternType = PatternType_MonthNth; - rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern = 0x7f; - rp->PatternTypeSpecific.MonthRecurrencePattern.N = RecurrenceN_Last; - } - else - { - rp->PatternType = PatternType_Month; - rp->PatternTypeSpecific.Day = [byMonthDay intValue]; - } - } - else - { - rp->PatternType = PatternType_MonthNth; - byDayMask = [self byDayMask]; - mask = 0; - days = [byDayMask weekDayOccurrences]; - if (days) - { - for (count = 0; count < 7; count++) - if (days[0][count]) - mask |= 1 << count; - } - if (mask) - { - rp->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern = mask; - bySetPos = [self flattenedValuesForKey: @"bysetpos"]; - if ([bySetPos length]) - rp->PatternTypeSpecific.MonthRecurrencePattern.N - = ([bySetPos hasPrefix: @"-"] - ? RecurrenceN_Last : [bySetPos intValue]); - else - { - firstOccurrence = [byDayMask firstOccurrence]; - if (firstOccurrence) - rp->PatternTypeSpecific.MonthRecurrencePattern.N - = ((firstOccurrence > -1) - ? firstOccurrence : RecurrenceN_Last); - } - } - else - [self errorWithFormat: @"rule for an event that never occurs"]; - } - } - - events = [[event parent] events]; - max = [events count]; - modifiedDates = [NSMutableArray arrayWithCapacity: max]; - for (count = 1; count < max; count++) - { - startDate = [[events objectAtIndex: count] recurrenceId]; - if (startDate) - [modifiedDates addObject: startDate]; - else - [self errorWithFormat: @"missing recurrence-id for event %d", count]; - } - max = [modifiedDates count]; - rp->ModifiedInstanceCount = max; - rp->ModifiedInstanceDates = talloc_array (memCtx, uint32_t, max); - for (count = 0; count < max; count++) - { - startDate = [[modifiedDates objectAtIndex: count] - hour: 0 minute: 0 second: 0]; - *(rp->ModifiedInstanceDates + count) = [startDate asMinutesSince1601]; - } - - deletedDates = [modifiedDates mutableCopy]; - [deletedDates autorelease]; - [deletedDates - addObjectsFromArray: [event exceptionDatesWithTimeZone: utcTZ]]; - [deletedDates sortUsingFunction: NSDateCompare context: NULL]; - - max = [deletedDates count]; - rp->DeletedInstanceCount = max; - rp->DeletedInstanceDates = talloc_array (memCtx, uint32_t, max); - for (count = 0; count < max; count++) - { - startDate = [[deletedDates objectAtIndex: count] - hour: 0 minute: 0 second: 0]; - *(rp->DeletedInstanceDates + count) = [startDate asMinutesSince1601]; - } -} - -@end diff --git a/OpenChange/MAPIStoreSOGo.m b/OpenChange/MAPIStoreSOGo.m deleted file mode 100644 index 604482ee7..000000000 --- a/OpenChange/MAPIStoreSOGo.m +++ /dev/null @@ -1,1751 +0,0 @@ -/* MAPIStoreSOGo.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -/* OpenChange SOGo storage backend */ - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIApplication.h" -#import "MAPIStoreAttachment.h" -#import "MAPIStoreAttachmentTable.h" -#import "MAPIStoreContext.h" -#import "MAPIStoreEmbeddedMessage.h" -#import "MAPIStoreFolder.h" -#import "MAPIStoreMessage.h" -#import "MAPIStoreMailVolatileMessage.h" -#import "MAPIStoreObject.h" -#import "MAPIStoreTable.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#include -#include -#include -#include - -static Class MAPIStoreContextK = Nil; -static BOOL leakDebugging = NO; -static BOOL initialization_done = NO; - -#define NS_CURRENT_THREAD_REGISTER() \ - BOOL __nsrct_thread_registered = GSRegisterCurrentThread(); \ - if (!initialization_done) { \ - OC_DEBUG(5, "[SOGo] You should call sogo_backend_init() first. Current thread: %p, pid: %d\n", \ - GSCurrentThread(), getpid()); \ - } \ - OC_DEBUG(5, "[SOGo] --->"); - -#define NS_CURRENT_THREAD_TRY_UNREGISTER(rc) \ - if (__nsrct_thread_registered) { \ - GSUnregisterCurrentThread(); \ - } \ - OC_DEBUG(6, "[SOGo] <--- [%s]", mapistore_errstr (rc)); - -#define TRYCATCH_START @try { -#define TRYCATCH_END(pool) \ - } @catch (NSException * e) { \ - enum mapistore_error ret = sogo_backend_handle_objc_exception(e, __PRETTY_FUNCTION__, __LINE__); \ - mapiapp_cleanup(); \ - [pool release]; \ - NS_CURRENT_THREAD_TRY_UNREGISTER(ret); \ - return ret; \ - } \ - mapiapp_cleanup(); - - -static enum mapistore_error -sogo_backend_unexpected_error() -{ - NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); - abort(); - return MAPISTORE_SUCCESS; -} - -static enum mapistore_error -sogo_backend_handle_objc_exception(NSException *e, const char *fn_name, const int line_no) -{ - NSString *callStackSymbols = nil; - if ([e respondsToSelector:@selector(callStackSymbols)]) - { - callStackSymbols = [[e callStackSymbols] componentsJoinedByString:@"\n\t"]; - } - NSLog(@"[SOGo: %s:%d] - EXCEPTION: %@, reason: %@, backtrace: \n\t%@\n", - fn_name, line_no, [e name], [e reason], callStackSymbols); - - // Another point of view on the stack trace - { - void *frames[128]; - int i, len = backtrace(frames, 128); - char **symbols = backtrace_symbols(frames, len); - NSLog(@"Backtrace using execinfo.h:\n"); - for (i = 0; i < len; ++i) - NSLog(@"\t%s", symbols[i]); - free(symbols); - } - - if ([[e name] isEqual:@"NotImplementedException"]) - { - return MAPISTORE_ERR_NOT_IMPLEMENTED; - } - return MAPISTORE_ERROR; -} - -static void -sogo_backend_atexit (void) -{ - NSAutoreleasePool *pool; - - GSRegisterCurrentThread (); - pool = [NSAutoreleasePool new]; - //NSLog (@"allocated classes:\n%s", GSDebugAllocationList (YES)); - [pool release]; - GSUnregisterCurrentThread (); -} - - -/** - \details Initialize sogo mapistore backend - - \return MAPISTORE_SUCCESS on success -*/ -static enum mapistore_error -sogo_backend_init (void) -{ - NSAutoreleasePool *pool; - SOGoProductLoader *loader; - Class MAPIApplicationK; - NSUserDefaults *ud; - SoProductRegistry *registry; - char *argv[] = { SAMBA_PREFIX "/sbin/samba", NULL }; - NSString *debugLevel; - uint8_t parentLogLevel; - - GSRegisterCurrentThread(); - - if (initialization_done) { - OC_DEBUG(5, "[SOGo] SOGo backend already initialized.\n"); - return MAPISTORE_SUCCESS; - } - - pool = [NSAutoreleasePool new]; - - /* Here we work around a bug in GNUstep which decodes XML user - defaults using the system encoding rather than honouring - the encoding specified in the file. */ - putenv ("GNUSTEP_STRING_ENCODING=NSUTF8StringEncoding"); - //putenv ("NSZombieEnabled=YES"); - - [NSProcessInfo initializeWithArguments: argv - count: 1 - environment: environ]; - - [SOGoSystemDefaults sharedSystemDefaults]; - - /* We force the plugin to base its configuration on the SOGo tree. */ - ud = [NSUserDefaults standardUserDefaults]; - - /* Ensure imap4Connection calls raise Exception if - IMAP connection is not established. See NGImap4Connection.m */ - [ud setBool: YES forKey: @"SoIMAP4ExceptionsEnabled"]; - - if (!leakDebugging && [ud boolForKey: @"SOGoDebugLeaks"]) - { - NSLog (@" leak debugging on"); - GSDebugAllocationActive (YES); - atexit (sogo_backend_atexit); - leakDebugging = YES; - } - - /* Set debug level according to samba */ - parentLogLevel = DEBUGLEVEL_CLASS[DBGC_ALL]; // FIXME: samba logger specific code - if (parentLogLevel >= 4) - debugLevel = @"DEBUG"; - else if (parentLogLevel >= 3) - debugLevel = @"INFO"; - else if (parentLogLevel >= 2) - debugLevel = @"WARN"; - else if (parentLogLevel >= 1) - debugLevel = @"ERROR"; - else - debugLevel = @"FATAL"; - OC_DEBUG(3, "[SOGo] Setting log level to %s", [debugLevel UTF8String]); - [ud setObject: debugLevel forKey: @"NGLogDefaultLogLevel"]; - [ud synchronize]; - - registry = [SoProductRegistry sharedProductRegistry]; - [registry scanForProductsInDirectory: SOGO_BUNDLES_DIR]; - - loader = [SOGoProductLoader productLoader]; - [loader loadProducts: [NSArray arrayWithObject: BACKEND_BUNDLE_NAME]]; - - MAPIApplicationK = NSClassFromString (@"MAPIApplication"); - if (MAPIApplicationK) - [[MAPIApplicationK new] activateApplication]; - - [[SOGoCache sharedCache] disableRequestsCache]; - [[SOGoCache sharedCache] disableLocalCache]; - - MAPIStoreContextK = NSClassFromString (@"MAPIStoreContext"); - - [pool release]; - - OC_DEBUG(5, "[SOGo] backend init SUCCESS. Current thread: %p, pid: %d\n", GSCurrentThread(), getpid()); - initialization_done = YES; - - return MAPISTORE_SUCCESS; -} - -/** - \details Cleanup operation to execute after an action has been performed - so there won't be any conflicts with future calls. - In practice this will deactivate the current user context set on MAPIApp - (which is the current WOApplication), this means two things: (1) set nil - as current user context on MAPIApp and (2) remove woContext from current - thread dictionary (this is used on WOContext.m). -*/ -static void mapiapp_cleanup(void) -{ - Class MAPIApplicationK; - MAPIApplicationK = NSClassFromString (@"MAPIApplication"); - if (MAPIApplicationK) - [[MAPIApplicationK application] cleanup]; -} - -/** - \details Create a connection context to the sogo backend - - \param mem_ctx pointer to the memory context - \param conn_info pointer to the connection information available for this context - (database connection, connected user, replica server info) - \param indexing pointer to the indexing database connection - \param uri pointer to the sogo path - \param private_data pointer to the private backend context - - \note the developer must free allocated private_data -*/ - -static enum mapistore_error -sogo_backend_create_context(TALLOC_CTX *mem_ctx, - struct mapistore_connection_info *conn_info, - struct indexing_context *indexing, - const char *uri, void **context_object) -{ - NSAutoreleasePool *pool; - MAPIStoreContext *context; - enum mapistore_error rc; - - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - if (MAPIStoreContextK) - { - TRYCATCH_START - rc = [MAPIStoreContextK openContext: &context - withURI: uri - connectionInfo: conn_info - andTDBIndexing: indexing]; - if (rc == MAPISTORE_SUCCESS) - *context_object = [context tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - } - else - rc = MAPISTORE_ERROR; - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - - return rc; -} - -static enum mapistore_error -sogo_backend_create_root_folder (const char *username, - enum mapistore_context_role role, - uint64_t fid, const char *name, - // struct indexing_context *indexing, - TALLOC_CTX *mem_ctx, char **mapistore_urip) -{ - NSAutoreleasePool *pool; - NSString *userName, *folderName; - NSString *mapistoreUri; - enum mapistore_error rc; - - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - if (MAPIStoreContextK) - { - TRYCATCH_START - userName = [NSString stringWithUTF8String: username]; - folderName = [NSString stringWithUTF8String: name]; - rc = [MAPIStoreContextK createRootFolder: &mapistoreUri - withFID: fid - andName: folderName - forUser: userName - withRole: role]; - if (rc == MAPISTORE_SUCCESS) - *mapistore_urip = [mapistoreUri asUnicodeInMemCtx: mem_ctx]; - TRYCATCH_END(pool) - } - else - rc = MAPISTORE_ERROR; - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - - return rc; -} - -static enum mapistore_error -sogo_backend_list_contexts(const char *username, struct indexing_context *indexing, - TALLOC_CTX *mem_ctx, - struct mapistore_contexts_list **contexts_listp) -{ - NSAutoreleasePool *pool; - NSString *userName; - enum mapistore_error rc; - - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - if (MAPIStoreContextK) - { - TRYCATCH_START - userName = [NSString stringWithUTF8String: username]; - *contexts_listp = [MAPIStoreContextK listAllContextsForUser: userName - withIndexing: indexing - inMemCtx: mem_ctx]; - rc = MAPISTORE_SUCCESS; - TRYCATCH_END(pool) - } - else - rc = MAPISTORE_ERROR; - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - - return rc; -} - -// andFID: fid -// uint64_t fid, -// void **private_data) - -/** - \details return the mapistore path associated to a given message or - folder ID - - \param private_data pointer to the current sogo context - \param fmid the folder/message ID to lookup - \param type whether it is a folder or message - \param path pointer on pointer to the path to return - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error -*/ -static enum mapistore_error -sogo_context_get_path(void *backend_object, TALLOC_CTX *mem_ctx, - uint64_t fmid, char **path) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreContext *context; - enum mapistore_error rc; - - if (backend_object) - { - wrapper = backend_object; - context = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [context getPath: path ofFMID: fmid inMemCtx: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_context_get_root_folder(void *backend_object, TALLOC_CTX *mem_ctx, - uint64_t fid, void **folder_object) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreContext *context; - MAPIStoreFolder *folder; - enum mapistore_error rc; - - if (backend_object) - { - wrapper = backend_object; - context = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [context getRootFolder: &folder withFID: fid]; - if (rc == MAPISTORE_SUCCESS) - *folder_object = [folder tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -/** - \details Open a folder from the sogo backend - - \param private_data pointer to the current sogo context - \param parent_fid the parent folder identifier - \param fid the identifier of the colder to open - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR -*/ -static enum mapistore_error -sogo_folder_open_folder(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t fid, void **childfolder_object) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder, *childFolder; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder openFolder: &childFolder withFID: fid]; - if (rc == MAPISTORE_SUCCESS) - *childfolder_object = [childFolder tallocWrapper: mem_ctx]; - // [context tearDownRequest]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -/** - \details Create a folder in the sogo backend - - \param private_data pointer to the current sogo context - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR -*/ -static enum mapistore_error -sogo_folder_create_folder(void *folder_object, TALLOC_CTX *mem_ctx, - uint64_t fid, struct SRow *aRow, - void **childfolder_object) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder, *childFolder; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder createFolder: &childFolder withRow: aRow andFID: fid]; - if (rc == MAPISTORE_SUCCESS) - *childfolder_object = [childFolder tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -/** - \details Delete a folder from the sogo backend - - \param private_data pointer to the current sogo context - \param parent_fid the FID for the parent of the folder to delete - \param fid the FID for the folder to delete - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR -*/ -static enum mapistore_error -sogo_folder_delete(void *folder_object) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder deleteFolder]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_get_child_count(void *folder_object, enum mapistore_table_type table_type, uint32_t *child_count) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder getChildCount: child_count ofTableType: table_type]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_open_message(void *folder_object, - TALLOC_CTX *mem_ctx, - uint64_t mid, bool write_access, - void **message_object) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder; - MAPIStoreMessage *message; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder openMessage: &message - withMID: mid - forWriting: write_access - inMemCtx: mem_ctx]; - if (rc == MAPISTORE_SUCCESS) - *message_object = [message tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_create_message(void *folder_object, - TALLOC_CTX *mem_ctx, - uint64_t mid, - uint8_t associated, - void **message_object) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder; - MAPIStoreMessage *message; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder createMessage: &message - withMID: mid - isAssociated: associated]; - if (rc == MAPISTORE_SUCCESS) - *message_object = [message tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_delete_message(void *folder_object, uint64_t mid, uint8_t flags) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder deleteMessageWithMID: mid andFlags: flags]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_move_copy_messages(void *folder_object, - void *source_folder_object, - TALLOC_CTX *mem_ctx, - uint32_t mid_count, - uint64_t *src_mids, uint64_t *t_mids, - struct Binary_r **target_change_keys, - struct Binary_r **target_predecessor_change_lists, - uint8_t want_copy) -{ - MAPIStoreFolder *sourceFolder, *targetFolder; - NSAutoreleasePool *pool; - struct MAPIStoreTallocWrapper *wrapper; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - targetFolder = wrapper->instance; - - wrapper = source_folder_object; - sourceFolder = wrapper->instance; - - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [targetFolder moveCopyMessagesWithMIDs: src_mids - andCount: mid_count - fromFolder: sourceFolder - withMIDs: t_mids - andChangeKeys: target_change_keys - andPredecessorChangeLists: target_predecessor_change_lists - wantCopy: want_copy - inMemCtx: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_move_folder(void *folder_object, void *target_folder_object, - TALLOC_CTX *mem_ctx, const char *new_folder_name) -{ - NSAutoreleasePool *pool; - MAPIStoreFolder *moveFolder, *targetFolder; - NSString *newFolderName; - struct MAPIStoreTallocWrapper *wrapper; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - moveFolder = wrapper->instance; - - wrapper = target_folder_object; - if (wrapper) - targetFolder = wrapper->instance; - else - targetFolder = nil; - - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - if (new_folder_name) - newFolderName = [NSString stringWithUTF8String: new_folder_name]; - else - newFolderName = nil; - - TRYCATCH_START - rc = [moveFolder moveCopyToFolder: targetFolder - withNewName: newFolderName - isMove: YES - isRecursive: YES - inMemCtx: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_copy_folder(void *folder_object, void *target_folder_object, TALLOC_CTX *mem_ctx, - bool recursive, const char *new_folder_name) -{ - NSAutoreleasePool *pool; - MAPIStoreFolder *copyFolder, *targetFolder; - NSString *newFolderName; - struct MAPIStoreTallocWrapper *wrapper; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - copyFolder = wrapper->instance; - - wrapper = target_folder_object; - targetFolder = wrapper->instance; - - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - newFolderName = [NSString stringWithUTF8String: new_folder_name]; - - TRYCATCH_START - rc = [copyFolder moveCopyToFolder: targetFolder - withNewName: newFolderName - isMove: NO - isRecursive: recursive - inMemCtx: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_get_deleted_fmids(void *folder_object, TALLOC_CTX *mem_ctx, - enum mapistore_table_type table_type, uint64_t change_num, - struct UI8Array_r **fmidsp, uint64_t *cnp) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder getDeletedFMIDs: fmidsp - andCN: cnp - fromChangeNumber: change_num - inTableType: table_type - inMemCtx: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_open_table(void *folder_object, TALLOC_CTX *mem_ctx, - enum mapistore_table_type table_type, uint32_t handle_id, - void **table_object, uint32_t *row_count) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder; - MAPIStoreTable *table; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder getTable: &table - andRowCount: row_count - tableType: table_type - andHandleId: handle_id]; - if (rc == MAPISTORE_SUCCESS) - *table_object = [table tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_modify_permissions(void *folder_object, uint8_t flags, - uint16_t pcount, - struct PermissionData *permissions) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder modifyPermissions: permissions - withCount: pcount - andFlags: flags]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_folder_preload_message_bodies(void *folder_object, enum mapistore_table_type table_type, const struct UI8Array_r *mids) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreFolder *folder; - enum mapistore_error rc; - - if (folder_object) - { - wrapper = folder_object; - folder = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [folder preloadMessageBodiesWithMIDs: mids - ofTableType: table_type]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_message_get_message_data(void *message_object, - TALLOC_CTX *mem_ctx, - struct mapistore_message **msg_dataP) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreMessage *message; - enum mapistore_error rc; - - if (message_object) - { - wrapper = message_object; - message = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - [message getMessageData: msg_dataP - inMemCtx: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - rc = MAPISTORE_SUCCESS; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_message_create_attachment (void *message_object, TALLOC_CTX *mem_ctx, void **attachment_object, uint32_t *aidp) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreMessage *message; - MAPIStoreAttachment *attachment; - enum mapistore_error rc; - - if (message_object) - { - wrapper = message_object; - message = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [message createAttachment: &attachment inAID: aidp]; - if (rc == MAPISTORE_SUCCESS) - *attachment_object = [attachment tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_message_open_attachment (void *message_object, TALLOC_CTX *mem_ctx, - uint32_t aid, void **attachment_object) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreMessage *message; - MAPIStoreAttachment *attachment; - enum mapistore_error rc; - - if (message_object) - { - wrapper = message_object; - message = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [message getAttachment: &attachment withAID: aid]; - if (rc == MAPISTORE_SUCCESS) - *attachment_object = [attachment tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_message_get_attachment_table (void *message_object, TALLOC_CTX *mem_ctx, void **table_object, uint32_t *row_count) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreMessage *message; - MAPIStoreAttachmentTable *table; - enum mapistore_error rc; - - if (message_object) - { - wrapper = message_object; - message = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [message getAttachmentTable: &table - andRowCount: row_count]; - if (rc == MAPISTORE_SUCCESS) - *table_object = [table tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_message_modify_recipients (void *message_object, - struct SPropTagArray *columns, - uint16_t count, - struct mapistore_message_recipient *recipients) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreMessage *message; - enum mapistore_error rc; - - if (message_object) - { - wrapper = message_object; - message = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [message modifyRecipientsWithRecipients: recipients - andCount: count - andColumns: columns]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_message_set_read_flag (void *message_object, uint8_t flag) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreMessage *message; - enum mapistore_error rc; - - if (message_object) - { - wrapper = message_object; - message = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [message setReadFlag: flag]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_message_save (void *message_object, TALLOC_CTX *mem_ctx) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreMessage *message; - enum mapistore_error rc; - - if (message_object) - { - wrapper = message_object; - message = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [message saveMessage: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_message_submit (void *message_object, enum SubmitFlags flags) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreMailVolatileMessage *message; - enum mapistore_error rc; - - if (message_object) - { - wrapper = message_object; - message = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [message submitWithFlags: flags]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_message_attachment_open_embedded_message (void *attachment_object, - TALLOC_CTX *mem_ctx, - void **message_object, - uint64_t *midP, - struct mapistore_message **msg) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreAttachment *attachment; - MAPIStoreEmbeddedMessage *message; - enum mapistore_error rc; - - if (attachment_object) - { - wrapper = attachment_object; - attachment = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [attachment openEmbeddedMessage: &message - withMID: midP - withMAPIStoreMsg: msg - inMemCtx: mem_ctx]; - if (rc == MAPISTORE_SUCCESS) - *message_object = [message tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_message_attachment_create_embedded_message (void *attachment_object, - TALLOC_CTX *mem_ctx, - void **message_object, - struct mapistore_message **msg) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreAttachment *attachment; - MAPIStoreEmbeddedMessage *message; - enum mapistore_error rc; - - if (attachment_object) - { - wrapper = attachment_object; - attachment = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [attachment createEmbeddedMessage: &message - withMAPIStoreMsg: msg - inMemCtx: mem_ctx]; - if (rc == MAPISTORE_SUCCESS) - *message_object = [message tallocWrapper: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error sogo_table_get_available_properties(void *table_object, - TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesP) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreTable *table; - enum mapistore_error rc; - - if (table_object) - { - wrapper = table_object; - table = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [table getAvailableProperties: propertiesP inMemCtx: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_table_set_columns (void *table_object, uint16_t count, enum MAPITAGS *properties) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreTable *table; - enum mapistore_error rc; - - if (table_object) - { - wrapper = table_object; - table = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [table setColumns: properties - withCount: count]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_table_set_restrictions (void *table_object, struct mapi_SRestriction *restrictions, uint8_t *table_status) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreTable *table; - enum mapistore_error rc; - - if (table_object) - { - wrapper = table_object; - table = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - [table setRestrictions: restrictions]; - //[table cleanupCaches]; - rc = MAPISTORE_SUCCESS; - *table_status = TBLSTAT_COMPLETE; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_table_set_sort_order (void *table_object, struct SSortOrderSet *sort_order, uint8_t *table_status) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreTable *table; - enum mapistore_error rc; - - if (table_object) - { - wrapper = table_object; - table = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - [table setSortOrder: sort_order]; - [table cleanupCaches]; - rc = MAPISTORE_SUCCESS; - *table_status = TBLSTAT_COMPLETE; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_table_get_row (void *table_object, TALLOC_CTX *mem_ctx, - enum mapistore_query_type query_type, uint32_t row_id, - struct mapistore_property_data **data) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreTable *table; - enum mapistore_error rc; - - if (table_object) - { - wrapper = table_object; - table = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [table getRow: data withRowID: row_id andQueryType: query_type - inMemCtx: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_table_get_row_count (void *table_object, - enum mapistore_query_type query_type, - uint32_t *row_countp) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreTable *table; - enum mapistore_error rc; - - if (table_object) - { - wrapper = table_object; - table = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [table getRowCount: row_countp - withQueryType: query_type]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_table_handle_destructor (void *table_object, uint32_t handle_id) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreTable *table; - enum mapistore_error rc; - - if (table_object) - { - wrapper = table_object; - table = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - [table destroyHandle: handle_id]; - TRYCATCH_END(pool) - - [pool release]; - rc = MAPISTORE_SUCCESS; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error sogo_properties_get_available_properties(void *object, - TALLOC_CTX *mem_ctx, - struct SPropTagArray **propertiesP) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreObject *propObject; - enum mapistore_error rc; - - if (object) - { - wrapper = object; - propObject = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [propObject getAvailableProperties: propertiesP inMemCtx: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_properties_get_properties (void *object, - TALLOC_CTX *mem_ctx, - uint16_t count, enum MAPITAGS *properties, - struct mapistore_property_data *data) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreObject *propObject; - enum mapistore_error rc; - - if (object) - { - wrapper = object; - propObject = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [propObject getProperties: data withTags: properties - andCount: count - inMemCtx: mem_ctx]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_properties_set_properties (void *object, struct SRow *aRow) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - MAPIStoreObject *propObject; - enum mapistore_error rc; - - if (object) - { - wrapper = object; - propObject = wrapper->instance; - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - rc = [propObject addPropertiesFromRow: aRow]; - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(rc); - } - else - { - rc = sogo_backend_unexpected_error(); - } - - return rc; -} - -static enum mapistore_error -sogo_manager_generate_uri (TALLOC_CTX *mem_ctx, - const char *user, - const char *folder, - const char *message, - const char *rootURI, - char **uri) -{ - NSAutoreleasePool *pool; - NSString *partialURLString, *username, *directory; - - if (uri == NULL) return MAPISTORE_ERR_INVALID_PARAMETER; - - /* This fixes a crash occurring during the instantiation of the - NSAutoreleasePool below. */ - NS_CURRENT_THREAD_REGISTER(); - pool = [NSAutoreleasePool new]; - - TRYCATCH_START - // printf("rootURI = %s\n", rootURI); - if (rootURI) - partialURLString = [NSString stringWithUTF8String: rootURI]; - else - { - /* sogo uri are of type: sogo://[username]:[password]@[folder type]/folder/id */ - username = [NSString stringWithUTF8String: (user ? user : "*")]; - /* Do proper directory lookup here */ - directory = [NSString stringWithUTF8String: (folder ? folder : "*")]; - partialURLString = [NSString stringWithFormat: @"sogo://%@:*@%@", - [username stringByReplacingOccurrencesOfString: @"@" - withString: @"%40"], - directory]; - } - if (![partialURLString hasSuffix: @"/"]) - partialURLString = [partialURLString stringByAppendingString: @"/"]; - - if (message) - partialURLString = [partialURLString stringByAppendingFormat: @"%s.eml", message]; - - // printf("uri = %s\n", [partialURLString UTF8String]); - *uri = talloc_strdup (mem_ctx, [partialURLString UTF8String]); - TRYCATCH_END(pool) - - [pool release]; - NS_CURRENT_THREAD_TRY_UNREGISTER(MAPISTORE_SUCCESS); - - return MAPISTORE_SUCCESS; -} - -/** - \details Entry point for mapistore SOGO backend - - \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error -*/ -enum mapistore_error mapistore_init_backend(void) -{ - struct mapistore_backend backend; - enum mapistore_error ret; - static BOOL registered = NO; - - if (registered) - ret = MAPISTORE_SUCCESS; - else - { - registered = YES; - - backend.backend.name = "SOGo"; - backend.backend.description = "mapistore SOGo backend"; - backend.backend.namespace = "sogo://"; - backend.backend.init = sogo_backend_init; - backend.backend.create_context = sogo_backend_create_context; - backend.backend.create_root_folder = sogo_backend_create_root_folder; - backend.backend.list_contexts = sogo_backend_list_contexts; - backend.context.get_path = sogo_context_get_path; - backend.context.get_root_folder = sogo_context_get_root_folder; - backend.folder.open_folder = sogo_folder_open_folder; - backend.folder.create_folder = sogo_folder_create_folder; - backend.folder.delete = sogo_folder_delete; - backend.folder.open_message = sogo_folder_open_message; - backend.folder.create_message = sogo_folder_create_message; - backend.folder.delete_message = sogo_folder_delete_message; - backend.folder.move_copy_messages = sogo_folder_move_copy_messages; - backend.folder.move_folder = sogo_folder_move_folder; - backend.folder.copy_folder = sogo_folder_copy_folder; - backend.folder.get_deleted_fmids = sogo_folder_get_deleted_fmids; - backend.folder.get_child_count = sogo_folder_get_child_count; - backend.folder.open_table = sogo_folder_open_table; - backend.folder.modify_permissions = sogo_folder_modify_permissions; - backend.folder.preload_message_bodies = sogo_folder_preload_message_bodies; - backend.message.create_attachment = sogo_message_create_attachment; - backend.message.get_attachment_table = sogo_message_get_attachment_table; - backend.message.open_attachment = sogo_message_open_attachment; - backend.message.open_embedded_message = sogo_message_attachment_open_embedded_message; - backend.message.create_embedded_message = sogo_message_attachment_create_embedded_message; - backend.message.get_message_data = sogo_message_get_message_data; - backend.message.modify_recipients = sogo_message_modify_recipients; - backend.message.set_read_flag = sogo_message_set_read_flag; - backend.message.save = sogo_message_save; - backend.message.submit = sogo_message_submit; - backend.table.get_available_properties = sogo_table_get_available_properties; - backend.table.set_restrictions = sogo_table_set_restrictions; - backend.table.set_sort_order = sogo_table_set_sort_order; - backend.table.set_columns = sogo_table_set_columns; - backend.table.get_row = sogo_table_get_row; - backend.table.get_row_count = sogo_table_get_row_count; - backend.table.handle_destructor = sogo_table_handle_destructor; - backend.properties.get_available_properties = sogo_properties_get_available_properties; - backend.properties.get_properties = sogo_properties_get_properties; - backend.properties.set_properties = sogo_properties_set_properties; - backend.manager.generate_uri = sogo_manager_generate_uri; - - /* Register ourselves with the MAPISTORE subsystem */ - ret = mapistore_backend_register (&backend); - if (ret != MAPISTORE_SUCCESS) - OC_DEBUG(0, "[SOGo] Failed to register the '%s' mapistore backend!\n", backend.backend.name); - } - - return ret; -} diff --git a/OpenChange/MAPIStoreSOGoObject.h b/OpenChange/MAPIStoreSOGoObject.h deleted file mode 100644 index dc9748371..000000000 --- a/OpenChange/MAPIStoreSOGoObject.h +++ /dev/null @@ -1,86 +0,0 @@ -/* MAPIStoreObject.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORESOGOOBJECT_H -#define MAPISTORESOGOOBJECT_H - -#include - -#import "MAPIStoreObject.h" - -@class NSDate; -@class NSData; -@class NSString; -@class NSMutableArray; -@class NSMutableDictionary; - -@class EOQualifier; - -@class MAPIStoreContext; -@class MAPIStoreFolder; -@class MAPIStoreMapping; -@class MAPIStoreTable; -@class MAPIStoreUserContext; - -@interface MAPIStoreSOGoObject : MAPIStoreObject -{ - id sogoObject; - BOOL isNew; -} - -+ (id) mapiStoreObjectWithSOGoObject: (id) newSOGoObject - inContainer: (MAPIStoreObject *) newContainer; - -- (id) initWithSOGoObject: (id) newSOGoObject - inContainer: (MAPIStoreObject *) newFolder; - -- (void) setIsNew: (BOOL) newIsNew; -- (BOOL) isNew; - -- (id) sogoObject; - -- (MAPIStoreObject *) container; - -- (void) cleanupCaches; - -- (uint64_t) objectId; - -/* implemented getters */ -- (enum mapistore_error) getPidTagDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagSearchKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagGenerateExchangeViews: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagParentSourceKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagSourceKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTagChangeKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; - -/* subclasses */ -- (uint64_t) objectVersion; - -@end - -#endif /* MAPISTORESOGOOBJECT_H */ diff --git a/OpenChange/MAPIStoreSOGoObject.m b/OpenChange/MAPIStoreSOGoObject.m deleted file mode 100644 index 497ee5116..000000000 --- a/OpenChange/MAPIStoreSOGoObject.m +++ /dev/null @@ -1,232 +0,0 @@ -/* MAPIStoreObject.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreContext.h" -#import "MAPIStoreFolder.h" -#import "MAPIStorePropertySelectors.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSDate+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreSOGoObject.h" - -#undef DEBUG -#include -#include -#include -#include -#include - -@implementation MAPIStoreSOGoObject - -static Class MAPIStoreFolderK; - -+ (void) initialize -{ - MAPIStoreFolderK = [MAPIStoreFolder class]; -} - -+ (id) mapiStoreObjectWithSOGoObject: (id) newSOGoObject - inContainer: (MAPIStoreObject *) newContainer -{ - id newObject; - - newObject = [[self alloc] initWithSOGoObject: newSOGoObject - inContainer: newContainer]; - [newObject autorelease]; - - return newObject; -} - -- (id) init -{ - if ((self = [super init])) - { - sogoObject = nil; - isNew = NO; - } - - // [self logWithFormat: @"-init"]; - - return self; -} - -- (id) initWithSOGoObject: (id) newSOGoObject - inContainer: (MAPIStoreObject *) newContainer -{ - if ((self = [self initInContainer: newContainer])) - { - ASSIGN (sogoObject, newSOGoObject); - } - - return self; -} - -- (void) dealloc -{ - // [self logWithFormat: @"-dealloc"]; - [sogoObject release]; - [super dealloc]; -} - -- (void) setIsNew: (BOOL) newIsNew -{ - isNew = newIsNew; -} - -- (BOOL) isNew -{ - return isNew; -} - -- (id) sogoObject -{ - return sogoObject; -} - -- (MAPIStoreObject *) container -{ - return container; -} - -- (NSString *) nameInContainer -{ - return [sogoObject nameInContainer]; -} - -- (void) cleanupCaches -{ -} - -/* helpers */ -- (uint64_t) objectId -{ - return [container idForObjectWithKey: [sogoObject nameInContainer]]; -} - -/* getters */ -- (enum mapistore_error) getPidTagDisplayName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [[sogoObject displayName] asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagSearchKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *stringValue; - - stringValue = [sogoObject nameInContainer]; - *data = [[stringValue dataUsingEncoding: NSASCIIStringEncoding] - asBinaryInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagGenerateExchangeViews: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagParentSourceKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getReplicaKey: data fromGlobCnt: [container objectId] >> 16 - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSourceKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getReplicaKey: data fromGlobCnt: [self objectId] >> 16 - inMemCtx: memCtx]; -} - -/* helper getters */ -- (enum mapistore_error) getPidTagChangeKey: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - uint64_t obVersion; - - obVersion = [self objectVersion]; - if (obVersion == ULLONG_MAX) - rc = MAPISTORE_ERR_NOT_FOUND; - else - rc = [self getReplicaKey: data fromGlobCnt: obVersion - inMemCtx: memCtx]; - - return rc; -} - -- (enum mapistore_error) getPidTagChangeNumber: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc; - struct mapistore_connection_info *connInfo; - uint64_t obVersion; - - obVersion = [self objectVersion]; - if (obVersion == ULLONG_MAX) - rc = MAPISTORE_ERR_NOT_FOUND; - else - { - connInfo = [[self context] connectionInfo]; - *data = MAPILongLongValue (memCtx, ((obVersion << 16) - | connInfo->repl_id)); - rc = MAPISTORE_SUCCESS; - } - - return rc; -} - -/* subclasses */ -- (uint64_t) objectVersion -{ - [self subclassResponsibility: _cmd]; - - return ULLONG_MAX; -} - -/* logging */ -- (NSString *) loggingPrefix -{ - return [NSString stringWithFormat:@"<%@:%p:%@>", - NSStringFromClass (isa), self, [self nameInContainer]]; -} - -@end diff --git a/OpenChange/MAPIStoreSamDBUtils.h b/OpenChange/MAPIStoreSamDBUtils.h deleted file mode 100644 index 84825332b..000000000 --- a/OpenChange/MAPIStoreSamDBUtils.h +++ /dev/null @@ -1,37 +0,0 @@ -/* MAPIStoreSamDBUtils.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTORESAMDBUTILS_H -#define MAPISTORESAMDBUTILS_H - -@class NSString; - -#include - -NSString *MAPIStoreSamDBUserAttribute (struct mapistore_connection_info *connInfo, - NSString *userKey, - NSString *value, - NSString *attributeName); -NSData *MAPIStoreInternalEntryId (struct mapistore_connection_info *connInfo, NSString *username); -NSData *MAPIStoreExternalEntryId (NSString *cn, NSString *email); - -#endif /* MAPISTORESAMDBUTILS_H */ diff --git a/OpenChange/MAPIStoreSamDBUtils.m b/OpenChange/MAPIStoreSamDBUtils.m deleted file mode 100644 index f26d173c2..000000000 --- a/OpenChange/MAPIStoreSamDBUtils.m +++ /dev/null @@ -1,183 +0,0 @@ -/* MAPIStoreSamDBUtils.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#import -#import -#include -#include -#include -#include - -#import "NSData+MAPIStore.h" - -#import "MAPIStoreSamDBUtils.h" - - - - -NSString * -MAPIStoreSamDBUserAttribute (struct mapistore_connection_info *connInfo, - NSString *userKey, - NSString *value, - NSString *attributeName) -{ - NSString *resultValue = nil; - const char *attrs[] = { "", NULL }; - NSString *searchFormat; - const char *result; - struct ldb_result *res = NULL; - TALLOC_CTX *memCtx; - int ret; - - memCtx = talloc_zero(NULL, TALLOC_CTX); - - attrs[0] = [attributeName UTF8String]; - searchFormat - = [NSString stringWithFormat: @"(&(objectClass=user)(%@=%%s))", userKey]; -#if SAMBA_VERSION_MAJOR <= 4 && SAMBA_VERSION_MINOR < 3 - ret = ldb_search (connInfo->sam_ctx, memCtx, &res, - ldb_get_default_basedn(connInfo->sam_ctx), - LDB_SCOPE_SUBTREE, attrs, - [searchFormat UTF8String], - [value UTF8String]); -#else - ret = safe_ldb_search (&connInfo->sam_ctx, memCtx, &res, - ldb_get_default_basedn(connInfo->sam_ctx), - LDB_SCOPE_SUBTREE, attrs, - [searchFormat UTF8String], - [value UTF8String]); -#endif - - if (ret == LDB_SUCCESS && res->count == 1) - { - result = ldb_msg_find_attr_as_string (res->msgs[0], attrs[0], NULL); - if (result) - resultValue = [NSString stringWithUTF8String: result]; - } - - talloc_free (memCtx); - - return resultValue; -} - -NSData * -MAPIStoreInternalEntryId (struct mapistore_connection_info *connInfo, NSString *username) -{ - static const uint8_t const providerUid[] = { 0xdc, 0xa7, 0x40, 0xc8, - 0xc0, 0x42, 0x10, 0x1a, - 0xb4, 0xb9, 0x08, 0x00, - 0x2b, 0x2f, 0xe1, 0x82 }; - NSMutableData *entryId; - NSData *legacyDNData; - NSString *legacyDN; - - /* structure: - flags: 32 - provideruid: 32 * 4 - version: 32 - type: 32 - X500DN: variable */ - - legacyDN = MAPIStoreSamDBUserAttribute (connInfo, @"sAMAccountName", username, - @"legacyExchangeDN"); - if (legacyDN) - { - entryId = [NSMutableData dataWithCapacity: 256]; - [entryId appendUInt32: 0]; // flags - [entryId appendBytes: providerUid length: 16]; // provideruid - [entryId appendUInt32: 1]; // version - [entryId appendUInt32: 0]; // type (local mail user) - legacyDNData = [legacyDN dataUsingEncoding: NSASCIIStringEncoding]; - [entryId appendData: legacyDNData]; // x500dn - [entryId appendUInt8: 0]; // end of string - } - else - { - NSLog (@"Error trying to generate EntryId for `%@`", username); - entryId = nil; - } - - return entryId; -} - -NSData * -MAPIStoreExternalEntryId (NSString *cn, NSString *email) -{ - NSMutableData *entryId; - static uint8_t providerUid[] = { 0x81, 0x2b, 0x1f, 0xa4, - 0xbe, 0xa3, 0x10, 0x19, - 0x9d, 0x6e, 0x00, 0xdd, - 0x01, 0x0f, 0x54, 0x02 }; - uint8_t flags21, flags22; - - /* structure: - flags: 32 - provideruid: 32 * 4 - version: 16 - { - PaD: 1 - MAE: 2 - Format: 4 - M: 1 - U: 1 - R: 2 - L: 1 - Pad: 4 - } - DisplayName: variable - AddressType: variable - EmailAddress: variable */ - - entryId = [NSMutableData dataWithCapacity: 256]; - [entryId appendUInt32: 0]; // flags - [entryId appendBytes: providerUid length: 16]; // provideruid - [entryId appendUInt16: 0]; // version - - flags21 = 0; /* PaD, MAE, R, Pad = 0 */ - flags21 |= 0x16; /* Format: text and HTML */ - flags21 |= 0x01; /* M: mime format */ - - flags22 = 0x90; /* U: unicode, L: no lookup */ - [entryId appendUInt8: flags21]; - [entryId appendUInt8: flags22]; - - /* DisplayName */ - if (!cn) - cn = @""; - [entryId - appendData: [cn dataUsingEncoding: NSUTF16LittleEndianStringEncoding]]; - [entryId appendUInt16: 0]; - - /* AddressType */ - [entryId - appendData: [@"SMTP" dataUsingEncoding: NSUTF16LittleEndianStringEncoding]]; - [entryId appendUInt16: 0]; - - /* EMailAddress */ - if (!email) - email = @""; - [entryId - appendData: [email dataUsingEncoding: NSUTF16LittleEndianStringEncoding]]; - [entryId appendUInt16: 0]; - - return entryId; -} diff --git a/OpenChange/MAPIStoreSharingMessage.h b/OpenChange/MAPIStoreSharingMessage.h deleted file mode 100644 index 101a64d6d..000000000 --- a/OpenChange/MAPIStoreSharingMessage.h +++ /dev/null @@ -1,101 +0,0 @@ -/* MAPIStoreSharingMessage.h - this file is part of SOGo-OpenChange - * - * Copyright (C) 2015-2016 Enrique J. Hernández - * - * Author: Enrique J. Hernández - * - * 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 MAPISTORESHARINGMESSAGE_H -#define MAPISTORESHARINGMESSAGE_H - -#import "MAPIStoreMailMessage.h" -#import "MAPIStoreObjectProxy.h" - -#define SHARING_SPECIAL_FOLDER 0x40290 - -@interface MAPIStoreSharingMessage : MAPIStoreObjectProxy -{ - struct mapistore_connection_info *connInfo; - NSMutableDictionary *properties; -} - -- (id) initWithMailHeaders: (NSDictionary *) mailHeaders - andConnectionInfo: (struct mapistore_connection_info *) newConnInfo - fromMessage: (MAPIStoreMailMessage *) msg; - -/* getters */ -- (enum mapistore_error) getPidLidSharingCapabilities: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidNameXSharingCapabilities: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingConfigurationUrl: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidNameXSharingConfigUrl: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingFlavor: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidNameXSharingFlavor: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingInitiatorEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingInitiatorName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingInitiatorSmtp: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingLocalType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidNameXSharingLocalType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingProviderGuid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidNameXSharingProviderGuid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingProviderName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidNameXSharingProviderName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingProviderUrl: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidNameXSharingProviderUrl: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingRemoteName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidNameXSharingRemoteName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingRemoteStoreUid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidNameXSharingRemoteStoreUid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingRemoteType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidTypeXSharingRemoteType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingResponseTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidLidSharingResponseType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getPidNameContentClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx; - -/* Save */ -- (void) saveWithMessage: (MAPIStoreMailMessage *) msg - andSOGoObject: (SOGoMailObject *) sogoObject; - -@end - -#endif /* MAPISTORECALENDARWRAPPER_H */ diff --git a/OpenChange/MAPIStoreSharingMessage.m b/OpenChange/MAPIStoreSharingMessage.m deleted file mode 100644 index 27ecbd47b..000000000 --- a/OpenChange/MAPIStoreSharingMessage.m +++ /dev/null @@ -1,463 +0,0 @@ -/* MAPIStoreSharingMessage.m - this file is part of SOGo-OpenChange - * - * Copyright (C) 2015-2016 Enrique J. Hernández - * - * Author: Enrique J. Hernández - * - * 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 - -#import -#import -#import - -#import -#import - -#import "NSData+MAPIStore.h" -#import "NSDate+MAPIStore.h" -#import "NSString+MAPIStore.h" -#import "NSValue+MAPIStore.h" - -#import "MAPIStoreMailFolder.h" -#import "MAPIStoreSharingMessage.h" -#import "MAPIStoreTypes.h" - -#include -#include -#include - -@implementation MAPIStoreSharingMessage - -- (id) init -{ - if ((self = [super init])) - { - connInfo = NULL; - properties = nil; - } - - return self; -} - -- (id) initWithMailHeaders: (NSDictionary *) mailHeaders - andConnectionInfo: (struct mapistore_connection_info *) newConnInfo - fromMessage: (MAPIStoreMailMessage *) msg -{ - NSEnumerator *enumerator; - NSString *key; - - if ((self = [self init])) - { - connInfo = newConnInfo; - enumerator = [mailHeaders keyEnumerator]; - properties = [NSMutableDictionary new]; - while ((key = [enumerator nextObject])) - { - if ([key hasPrefix: @"x-ms-sharing-"]) - [properties setObject: [mailHeaders objectForKey: key] - forKey: key]; - } - - /* Set request properties from container folder */ - NSDictionary *requestProps = [(MAPIStoreMailFolder *)[msg container] - extraPropertiesForMessage: [msg nameInContainer]]; - if (requestProps) - [properties addEntriesFromDictionary: requestProps]; - } - - return self; -} - -- (void) dealloc -{ - [properties release]; - [super dealloc]; -} - -- (enum mapistore_error) _getStringProperty: (NSString *) propertyName - inData: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - id value; - - value = [properties objectForKey: propertyName]; - if (value) - { - *data = [value asUnicodeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - - return rc; - -} - -- (enum mapistore_error) getPidLidSharingCapabilities: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - id value; - - value = [properties objectForKey: @"x-ms-sharing-capabilities"]; - if (value) - { - *data = MAPILongValue (memCtx, [value intValue]); - rc = MAPISTORE_SUCCESS; - } - - return rc; -} - -- (enum mapistore_error) getPidNameXSharingCapabilities: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - id value; - - value = [properties objectForKey: @"x-ms-sharing-capabilities"]; - if (value) - { - *data = [[NSString stringWithFormat:@"%X", [value intValue]] - asUnicodeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - - return rc; -} - -- (enum mapistore_error) getPidLidSharingConfigurationUrl: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - - *data = [@"" asUnicodeInMemCtx: memCtx]; - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidNameXSharingConfigUrl: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidSharingConfigurationUrl: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSharingFlavor: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* See [MS-OXSHARE] Section 2.2.2.5 for details */ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - id value, auxValue; - - value = [properties objectForKey: @"x-ms-sharing-flavor"]; - if (value) - { - *data = MAPILongValue (memCtx, [value intValue]); - rc = MAPISTORE_SUCCESS; - } - else - { - /* Guess its value required by old clients based on other properties */ - value = [properties objectForKey: @"x-ms-sharing-capabilities"]; - if (value) - { - if ([value intValue] == SHARING_SPECIAL_FOLDER) - { - value = [properties objectForKey: @"x-ms-sharing-responsetime"]; - auxValue = [properties objectForKey: @"x-ms-sharing-remoteuid"]; - if (value) /* A sharing request */ - { - if (auxValue) - *data = MAPILongValue (memCtx, SHARING_INVITATION_REQUEST_FOLDER); - else - *data = MAPILongValue (memCtx, SHARING_REQUEST_SPECIAL_FOLDER); - } - else - { - if (auxValue) /* It SHOULD be an invitation or response */ - *data = MAPILongValue (memCtx, SHARING_INVITATION_SPECIAL_FOLDER); - else /* No remote info, then denial */ - *data = MAPILongValue (memCtx, SHARING_DENY_REQUEST); - } - } - else - { - *data = MAPILongValue (memCtx, SHARING_INVITATION_FOLDER); - } - rc = MAPISTORE_SUCCESS; - } - } - - return rc; -} - -- (enum mapistore_error) getPidNameXSharingFlavor: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - id value; - - value = [properties objectForKey: @"x-ms-sharing-flavor"]; - if (value) - { - *data = [[NSString stringWithFormat:@"%X", [value intValue]] - asUnicodeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - - return rc; -} - -- (enum mapistore_error) getPidLidSharingInitiatorEntryId: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - id value; - NSData *entryId; - - value = [properties objectForKey: @"x-ms-sharing-initiatorentryid"]; - if (value) - { - entryId = [value dataByDecodingBase64]; - if (entryId) - { - *data = [entryId asBinaryInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - } - - return rc; -} - -- (enum mapistore_error) getPidLidSharingInitiatorName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getStringProperty: @"x-ms-sharing-initiatorname" - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSharingInitiatorSmtp: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getStringProperty: @"x-ms-sharing-initiatorsmtp" - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSharingLocalType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getStringProperty: @"x-ms-sharing-localtype" - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidNameXSharingLocalType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidSharingLocalType: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSharingProviderGuid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - const unsigned char providerGuidBytes[] = {0xAE, 0xF0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}; - NSData *providerGuid = [NSData dataWithBytes: providerGuidBytes length: 16]; - *data = [providerGuid asBinaryInMemCtx: memCtx]; - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidNameXSharingProviderGuid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"AEF0060000000000C000000000000046" asUnicodeInMemCtx: memCtx]; - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidSharingProviderName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - - return [self _getStringProperty: @"x-ms-sharing-providername" - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidNameXSharingProviderName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidSharingProviderName: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSharingProviderUrl: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getStringProperty: @"x-ms-sharing-providerurl" - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidNameXSharingProviderUrl: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidSharingProviderUrl: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSharingRemoteName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getStringProperty: @"x-ms-sharing-remotename" - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidNameXSharingRemoteName: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidSharingRemoteName: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSharingRemoteStoreUid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getStringProperty: @"x-ms-sharing-remotestoreuid" - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidNameXSharingRemoteStoreUid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidSharingRemoteStoreUid: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSharingRemoteType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getStringProperty: @"x-ms-sharing-remotetype" - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTypeXSharingRemoteType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidSharingRemoteType: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSharingRemoteUid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self _getStringProperty: @"x-ms-sharing-remoteuid" - inData: data - inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidUidXSharingRemoteUid: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidLidSharingRemoteUid: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidSharingResponseTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - id value; - - value = [properties objectForKey: MAPIPropertyKey (PidLidSharingResponseTime)]; - if (!value) - { - value = [properties objectForKey: @"x-ms-sharing-responsetime"]; - if (value) - { - /* Here the value is a GSCBufferString */ - NSString * responseTime = [NSString stringWithUTF8String: [value UTF8String]]; - value = [NSDate dateWithString: responseTime]; - } - } - - if (value) - { - *data = [value asFileTimeInMemCtx: memCtx]; - rc = MAPISTORE_SUCCESS; - } - - return rc; -} - -- (enum mapistore_error) getPidLidSharingResponseType: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - - enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - id value; - - value = [properties objectForKey: MAPIPropertyKey (PidLidSharingResponseType)]; - if (!value) - value = [properties objectForKey: @"x-ms-sharing-responsetype"]; - - if (value) - { - *data = MAPILongValue (memCtx, [value intValue]); - rc = MAPISTORE_SUCCESS; - } - - return rc; -} - -- (enum mapistore_error) getPidNameContentClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = talloc_strdup (memCtx, "Sharing"); - return MAPISTORE_SUCCESS; -} - -- (void) saveWithMessage: (MAPIStoreMailMessage *) msg - andSOGoObject: (SOGoMailObject *) sogoObject -{ - /* Store PidLidSharingResponseType and PidLidSharingResponseTime if - required in versions message from the container as I don't see - other straightforward place to put that information */ - id response; - NSDictionary *propsToStore; - - response = [[msg properties] objectForKey: MAPIPropertyKey (PidLidSharingResponseType)]; - if (response) - { - /* FIXME: Is there any better way to increase the modseq? */ - [sogoObject addFlags: @"\\Draft"]; - [sogoObject removeFlags: @"\\Draft"]; - - /* Store this modification in container folder along the property values */ - propsToStore = [NSDictionary dictionaryWithObjects: - [NSArray arrayWithObjects: response, - [[msg properties] objectForKey: MAPIPropertyKey (PidLidSharingResponseTime)], - nil] - forKeys: - [NSArray arrayWithObjects: MAPIPropertyKey (PidLidSharingResponseType), - MAPIPropertyKey (PidLidSharingResponseTime), nil]]; - - [(MAPIStoreMailFolder *)[msg container] setExtraProperties: propsToStore - forMessage: [msg nameInContainer]]; - } -} - -@end diff --git a/OpenChange/MAPIStoreTable.h b/OpenChange/MAPIStoreTable.h deleted file mode 100644 index 63e39dc79..000000000 --- a/OpenChange/MAPIStoreTable.h +++ /dev/null @@ -1,129 +0,0 @@ -/* MAPIStoreTable.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORETABLE_H -#define MAPISTORETABLE_H - -#include - -#import "NSObject+MAPIStore.h" - -#undef DEBUG -#include - -#define SENSITIVITY_NONE 0 -#define SENSITIVITY_PERSONAL 1 -#define SENSITIVITY_PRIVATE 2 -#define SENSITIVITY_COMPANY_CONFIDENTIAL 3 - -typedef enum { - MAPIRestrictionStateAlwaysFalse = NO, - MAPIRestrictionStateAlwaysTrue = YES, - MAPIRestrictionStateNeedsEval, /* needs passing of qualifier to underlying - database */ -} MAPIRestrictionState; - -@class NSArray; -@class NSMutableArray; -@class NSString; -@class EOQualifier; - -@class MAPIStoreObject; - -@interface MAPIStoreTable : NSObject -{ - MAPIStoreObject *container; - - uint32_t handleId; /* hack for identifying tables during notifications */ - - NSArray *childKeys; - NSArray *restrictedChildKeys; - - EOQualifier *restriction; /* should probably be a dictionary too */ - MAPIRestrictionState restrictionState; - NSMutableArray *sortOrderings; - - uint32_t currentRow; - MAPIStoreObject *currentChild; - - enum mapistore_table_type tableType; /* mapistore */ - - /* proof of concept */ - uint16_t columnsCount; - enum MAPITAGS *columns; -} - -+ (id) tableForContainer: (MAPIStoreObject *) newContainer; -+ (Class) childObjectClass; - -- (id) initForContainer: (MAPIStoreObject *) newContainer; - -- (id) container; -- (enum mapistore_table_type) tableType; - -- (void) setHandleId: (uint32_t) newHandleId; -- (void) destroyHandle: (uint32_t) handleId; - -- (id) childAtRowID: (uint32_t) rowId - forQueryType: (enum mapistore_query_type) queryType; - -- (void) cleanupCaches; - -- (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP - inMemCtx: (TALLOC_CTX *) localMemCtx; -- (void) setRestrictions: (const struct mapi_SRestriction *) res; -- (enum mapistore_error) setColumns: (enum MAPITAGS *) newColumns - withCount: (uint16_t) newColumCount; -- (enum mapistore_error) getRow: (struct mapistore_property_data **) dataP - withRowID: (uint32_t) rowId - andQueryType: (enum mapistore_query_type) queryType - inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getRowCount: (uint32_t *) countP - withQueryType: (enum mapistore_query_type) queryType; - -/* helpers */ - -- (SEL) operatorFromRestrictionOperator: (uint32_t) resOp; -- (void) warnUnhandledProperty: (enum MAPITAGS) property - inFunction: (const char *) function; - -/* subclasses */ -- (NSArray *) childKeys; -- (NSArray *) restrictedChildKeys; - -- (id) lookupChild: (NSString *) childKey; - -- (void) setSortOrder: (const struct SSortOrderSet *) set; - -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property; -- (MAPIRestrictionState) evaluateContentRestriction: (const struct mapi_SContentRestriction *) res - intoQualifier: (EOQualifier **) qualifier; -- (MAPIRestrictionState) evaluatePropertyRestriction: (const struct mapi_SPropertyRestriction *) res - intoQualifier: (EOQualifier **) qualifier; -- (MAPIRestrictionState) evaluateBitmaskRestriction: (const struct mapi_SBitmaskRestriction *) res - intoQualifier: (EOQualifier **) qualifier; -- (MAPIRestrictionState) evaluateExistRestriction: (const struct mapi_SExistRestriction *) res - intoQualifier: (EOQualifier **) qualifier; - -@end - -#endif /* MAPISTORETABLE_H */ diff --git a/OpenChange/MAPIStoreTable.m b/OpenChange/MAPIStoreTable.m deleted file mode 100644 index 5bcba670e..000000000 --- a/OpenChange/MAPIStoreTable.m +++ /dev/null @@ -1,889 +0,0 @@ -/* MAPIStoreTable.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import -#import - -#import -#import "MAPIStoreActiveTables.h" -#import "MAPIStoreObject.h" -#import "MAPIStoreTypes.h" -#import "NSData+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreContext.h" -#import "MAPIStoreObject.h" - -#import "MAPIStoreTable.h" - -#undef DEBUG -#include -#include -#include - -@interface MAPIStoreTable (Private) - -- (MAPIRestrictionState) evaluateRestriction: (const struct mapi_SRestriction *) res - intoQualifier: (EOQualifier **) qualifier; -@end - -static Class NSDataK, NSStringK; - -// static NSString * -// MAPIStringForRestrictionState (MAPIRestrictionState state) -// { -// NSString *stateStr; - -// if (state == MAPIRestrictionStateAlwaysTrue) -// stateStr = @"always true"; -// else if (state == MAPIRestrictionStateAlwaysFalse) -// stateStr = @"always false"; -// else -// stateStr = @"needs eval"; - -// return stateStr; -// } - -// static NSString * -// MAPIStringForRestriction (const struct mapi_SRestriction *resPtr); - -// static NSString * -// _MAPIIndentString(int indent) -// { -// NSString *spaces; -// char *buffer; - -// if (indent > 0) -// { -// buffer = malloc (indent + 1); -// memset (buffer, 32, indent); -// *(buffer+indent) = 0; -// spaces = [NSString stringWithFormat: @"%s", buffer]; -// free (buffer); -// } -// else -// spaces = @""; - -// return spaces; -// } - -// static NSString * -// MAPIStringForAndRestriction (const struct mapi_SAndRestriction *resAnd) -// { -// NSMutableArray *restrictions; -// uint16_t count; - -// restrictions = [NSMutableArray arrayWithCapacity: 8]; -// for (count = 0; count < resAnd->cRes; count++) -// [restrictions addObject: MAPIStringForRestriction ((struct mapi_SRestriction *) resAnd->res + count)]; - -// return [NSString stringWithFormat: @"(%@)", [restrictions componentsJoinedByString: @" && "]]; -// } - -// static NSString * -// MAPIStringForOrRestriction (const struct mapi_SOrRestriction *resOr) -// { -// NSMutableArray *restrictions; -// uint16_t count; - -// restrictions = [NSMutableArray arrayWithCapacity: 8]; -// for (count = 0; count < resOr->cRes; count++) -// [restrictions addObject: MAPIStringForRestriction ((struct mapi_SRestriction *) resOr->res + count)]; - -// return [NSString stringWithFormat: @"(%@)", [restrictions componentsJoinedByString: @" || "]]; -// } - -// static NSString * -// MAPIStringForNotRestriction (const struct mapi_SNotRestriction *resNot) -// { -// return [NSString stringWithFormat: @"!(%@)", -// MAPIStringForRestriction ((struct mapi_SRestriction *) &resNot->res)]; -// } - -// static NSString * -// MAPIStringForContentRestriction (const struct mapi_SContentRestriction *resContent) -// { -// NSString *eqMatch, *caseMatch; -// id value; -// const char *propName; - -// switch (resContent->fuzzy & 0xf) -// { -// case 0: eqMatch = @"eq"; break; -// case 1: eqMatch = @"substring"; break; -// case 2: eqMatch = @"prefix"; break; -// default: eqMatch = @"[unknown]"; -// } - -// switch (((resContent->fuzzy) >> 16) & 0xf) -// { -// case 0: caseMatch = @"fl"; break; -// case 1: caseMatch = @"nc"; break; -// case 2: caseMatch = @"ns"; break; -// case 4: caseMatch = @"lo"; break; -// default: caseMatch = @"[unknown]"; -// } - -// propName = get_proptag_name (resContent->ulPropTag); -// if (!propName) -// propName = ""; - -// value = NSObjectFromMAPISPropValue (&resContent->lpProp); - -// return [NSString stringWithFormat: @"%s(0x%.8x) %@,%@ %@", -// propName, resContent->ulPropTag, eqMatch, caseMatch, value]; -// } - -// static NSString * -// MAPIStringForExistRestriction (const struct mapi_SExistRestriction *resExist) -// { -// const char *propName; - -// propName = get_proptag_name (resExist->ulPropTag); -// if (!propName) -// propName = ""; - -// return [NSString stringWithFormat: @"%s(0x%.8x) IS NOT NULL", propName, resExist->ulPropTag]; -// } - -// static NSString * -// MAPIStringForPropertyRestriction (const struct mapi_SPropertyRestriction *resProperty) -// { -// static NSString *operators[] = { @"<", @"<=", @">", @">=", @"==", @"!=", -// @"=~" }; -// NSString *operator; -// id value; -// const char *propName; - -// propName = get_proptag_name (resProperty->ulPropTag); -// if (!propName) -// propName = ""; - -// if (resProperty->relop >= 0 && resProperty->relop < 7) -// operator = operators[resProperty->relop]; -// else -// operator = [NSString stringWithFormat: @"", resProperty->relop]; -// value = NSObjectFromMAPISPropValue (&resProperty->lpProp); - -// return [NSString stringWithFormat: @"%s(0x%.8x) %@ %@", -// propName, resProperty->ulPropTag, operator, value]; -// } - -// static NSString * -// MAPIStringForBitmaskRestriction (const struct mapi_SBitmaskRestriction *resBitmask) -// { -// NSString *format; -// const char *propName; - -// propName = get_proptag_name (resBitmask->ulPropTag); -// if (!propName) -// propName = ""; - -// if (resBitmask->relMBR == 0) -// format = @"((%s(0x%.8x) & 0x%.8x) == 0)"; -// else -// format = @"((%s(0x%.8x) & 0x%.8x) != 0)"; - -// return [NSString stringWithFormat: format, -// propName, resBitmask->ulPropTag, resBitmask->ulMask]; -// } - -// static NSString * -// MAPIStringForRestriction (const struct mapi_SRestriction *resPtr) -// { -// NSString *restrictionStr; - -// if (resPtr) -// { -// switch (resPtr->rt) -// { -// // RES_CONTENT=(int)(0x3), -// // RES_BITMASK=(int)(0x6), -// // RES_EXIST=(int)(0x8), - -// case 0: restrictionStr = MAPIStringForAndRestriction(&resPtr->res.resAnd); break; -// case 1: restrictionStr = MAPIStringForOrRestriction(&resPtr->res.resOr); break; -// case 2: restrictionStr = MAPIStringForNotRestriction(&resPtr->res.resNot); break; -// case 3: restrictionStr = MAPIStringForContentRestriction(&resPtr->res.resContent); break; -// case 4: restrictionStr = MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break; -// case 6: restrictionStr = MAPIStringForBitmaskRestriction(&resPtr->res.resBitmask); break; -// case 8: restrictionStr = MAPIStringForExistRestriction(&resPtr->res.resExist); break; -// // case 5: MAPIStringForComparePropsRestriction(&resPtr->res.resCompareProps); break; -// // case 7: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break; -// // case 9: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break; -// // case 10: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break; -// default: -// restrictionStr -// = [NSString stringWithFormat: @"[unhandled restriction type: %d]", -// resPtr->rt]; -// } -// } -// else -// restrictionStr = @"[unrestricted]"; - -// return restrictionStr; -// } - -@implementation MAPIStoreTable - -+ (void) initialize -{ - NSDataK = [NSData class]; - NSStringK = [NSString class]; -} - -+ (id) tableForContainer: (MAPIStoreObject *) newContainer -{ - MAPIStoreTable *newTable; - - newTable = [[self alloc] initForContainer: newContainer]; - [newTable autorelease]; - - return newTable; -} - -+ (Class) childObjectClass -{ - [self subclassResponsibility: _cmd]; - - return Nil; -} - -- (id) init -{ - if ((self = [super init])) - { - // [self logWithFormat: @"-init"]; - tableType = MAPISTORE_MESSAGE_TABLE; - handleId = -1; - - container = nil; - - childKeys = nil; - restrictedChildKeys = nil; - - currentRow = (uint32_t) -1; - currentChild = nil; - - restriction = nil; - restrictionState = MAPIRestrictionStateAlwaysTrue; - sortOrderings = nil; - - columns = NULL; - columnsCount = 0; - } - - return self; -} - -- (id) initForContainer: (MAPIStoreObject *) newContainer -{ - if ((self = [self init])) - { - container = newContainer; - } - - return self; -} - -// - (id) retain -// { -// [self logWithFormat: @"-retain"]; -// return [super retain]; -// } - -// - (void) release -// { -// [self logWithFormat: @"-release"]; -// [super release]; -// } - -- (void) dealloc -{ - // [self logWithFormat: @"-dealloc"]; - if (columns) - NSZoneFree (NULL, columns); - [currentChild release]; - [childKeys release]; - [restrictedChildKeys release]; - [sortOrderings release]; - [restriction release]; - [super dealloc]; -} - -- (id) container -{ - return container; -} - -- (enum mapistore_table_type) tableType -{ - return tableType; -} - -- (void) setHandleId: (uint32_t) newHandleId -{ - handleId = newHandleId; - if (newHandleId) - [[MAPIStoreActiveTables activeTables] registerTable: self]; -} - -- (void) destroyHandle: (uint32_t) tableHandleId -{ - if (tableHandleId && (handleId == tableHandleId)) - [[MAPIStoreActiveTables activeTables] unregisterTable: self]; -} - -- (void) cleanupCaches -{ - [restrictedChildKeys release]; - restrictedChildKeys = nil; - [childKeys release]; - childKeys = nil; - [currentChild release]; - currentChild = nil; - currentRow = (uint32_t) -1; -} - -- (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [[isa childObjectClass] getAvailableProperties: propertiesP - inMemCtx: memCtx]; -} - -- (void) setRestrictions: (const struct mapi_SRestriction *) res -{ - //EOQualifier *oldRestriction; - - // [self logWithFormat: @"set restriction to (table type: %d): %@", - // type, MAPIStringForRestriction (res)]; - - //oldRestriction = restriction; - [restriction autorelease]; - if (res) - restrictionState = [self evaluateRestriction: res - intoQualifier: &restriction]; - else - restrictionState = MAPIRestrictionStateAlwaysTrue; - - if (restrictionState == MAPIRestrictionStateNeedsEval) - [restriction retain]; - else - restriction = nil; - - // FIXME: we should not flush the caches if the restrictions matches - [self cleanupCaches]; - - //if (restriction) - // [self logWithFormat: @"restriction set to EOQualifier: %@", -// restriction]; - // else if (oldRestriction) - // [self logWithFormat: @"restriction unset (was %@)", oldRestriction]; -} - -- (MAPIRestrictionState) evaluateNotRestriction: (struct mapi_SNotRestriction *) res - intoQualifier: (EOQualifier **) qualifierPtr -{ - MAPIRestrictionState state, subState; - EONotQualifier *qualifier; - EOQualifier *subQualifier; - - subState = [self evaluateRestriction: (struct mapi_SRestriction *)&res->res - intoQualifier: &subQualifier]; - if (subState == MAPIRestrictionStateAlwaysTrue) - state = MAPIRestrictionStateAlwaysFalse; - else if (subState == MAPIRestrictionStateAlwaysFalse) - state = MAPIRestrictionStateAlwaysTrue; - else - { - state = MAPIRestrictionStateNeedsEval; - qualifier = [[EONotQualifier alloc] initWithQualifier: subQualifier]; - [qualifier autorelease]; - *qualifierPtr = qualifier; - } - - return state; -} - -- (MAPIRestrictionState) evaluateAndRestriction: (struct mapi_SAndRestriction *) res - intoQualifier: (EOQualifier **) qualifierPtr -{ - MAPIRestrictionState state, subState; - EOAndQualifier *qualifier; - EOQualifier *subQualifier; - NSMutableArray *subQualifiers; - uint16_t count; - - state = MAPIRestrictionStateNeedsEval; - - subQualifiers = [NSMutableArray arrayWithCapacity: 8]; - for (count = 0; - state == MAPIRestrictionStateNeedsEval && count < res->cRes; - count++) - { - subState = [self evaluateRestriction: (struct mapi_SRestriction *) res->res + count - intoQualifier: &subQualifier]; - if (subState == MAPIRestrictionStateNeedsEval) - [subQualifiers addObject: subQualifier]; - else if (subState == MAPIRestrictionStateAlwaysFalse) - state = MAPIRestrictionStateAlwaysFalse; - } - - if (state == MAPIRestrictionStateNeedsEval) - { - if ([subQualifiers count] == 0) - state = MAPIRestrictionStateAlwaysTrue; - else - { - qualifier = [[EOAndQualifier alloc] - initWithQualifierArray: subQualifiers]; - [qualifier autorelease]; - *qualifierPtr = qualifier; - } - } - - return state; -} - -- (MAPIRestrictionState) evaluateOrRestriction: (struct mapi_SOrRestriction *) res - intoQualifier: (EOQualifier **) qualifierPtr -{ - MAPIRestrictionState state, subState; - EOOrQualifier *qualifier; - EOQualifier *subQualifier; - NSMutableArray *subQualifiers; - uint16_t count, falseCount; - - state = MAPIRestrictionStateNeedsEval; - - falseCount = 0; - subQualifiers = [NSMutableArray arrayWithCapacity: 8]; - for (count = 0; - state == MAPIRestrictionStateNeedsEval && count < res->cRes; - count++) - { - subState = [self evaluateRestriction: (struct mapi_SRestriction *) res->res + count - intoQualifier: &subQualifier]; - if (subState == MAPIRestrictionStateNeedsEval) - [subQualifiers addObject: subQualifier]; - else if (subState == MAPIRestrictionStateAlwaysTrue) - state = MAPIRestrictionStateAlwaysTrue; - else - falseCount++; - } - - if (falseCount == res->cRes) - state = MAPIRestrictionStateAlwaysFalse; - else if ([subQualifiers count] == 0) - state = MAPIRestrictionStateAlwaysTrue; - - if (state == MAPIRestrictionStateNeedsEval) - { - qualifier = [[EOOrQualifier alloc] - initWithQualifierArray: subQualifiers]; - [qualifier autorelease]; - *qualifierPtr = qualifier; - } - - return state; -} - -- (void) warnUnhandledProperty: (enum MAPITAGS) property - inFunction: (const char *) function -{ - const char *propName; - - propName = get_proptag_name (property); - if (!propName) - propName = ""; - [self warnWithFormat: - @"property %s (%.8x) has no matching field name (%@) in '%s'", - propName, property, self, function]; -} - -- (MAPIRestrictionState) evaluateContentRestriction: (struct mapi_SContentRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - NSString *property; - // SEL operator; - id value; - MAPIRestrictionState rc; - - property = [self backendIdentifierForProperty: res->ulPropTag]; - if (property) - { - value = NSObjectFromMAPISPropValue (&res->lpProp); - if ([value isKindOfClass: NSDataK]) - { - value = [[NSString alloc] initWithData: value - encoding: NSUTF8StringEncoding]; - [value autorelease]; - } - else if (![value isKindOfClass: NSStringK]) - [NSException raise: @"MAPIStoreTypeConversionException" - format: @"unhandled content restriction for class '%@'", - NSStringFromClass ([value class])]; - - // switch (res->fuzzy & 0xf) - // { - // case 0: - // operator = EOQualifierOperatorEqual; - // break; - // case 1: - // operator = EOQualifierOperatorLike; - // value = [NSString stringWithFormat: @"%%%@%%", value]; - // break; - // case 2: - // operator = EOQualifierOperatorEqual; - // value = [NSString stringWithFormat: @"%@%%", value]; - // break; - // default: [NSException raise: @"MAPIStoreInvalidOperatorException" - // format: @"fuzzy operator value '%.4x' is invalid", - // res->fuzzy]; - // } - - *qualifier = [[EOKeyValueQualifier alloc] initWithKey: property - operatorSelector: EOQualifierOperatorCaseInsensitiveLike - value: value]; - [*qualifier autorelease]; - - [self logWithFormat: @"%s: resulting qualifier: %@", - __PRETTY_FUNCTION__, *qualifier]; - - rc = MAPIRestrictionStateNeedsEval; - } - else - { - [self warnUnhandledProperty: res->ulPropTag - inFunction: __FUNCTION__]; - - rc = MAPIRestrictionStateAlwaysFalse; - } - - return rc; -} - -- (SEL) operatorFromRestrictionOperator: (uint32_t) resOp -{ - static SEL operators[] = { EOQualifierOperatorLessThan, - EOQualifierOperatorLessThanOrEqualTo, - EOQualifierOperatorGreaterThan, - EOQualifierOperatorGreaterThanOrEqualTo, - EOQualifierOperatorEqual, - EOQualifierOperatorNotEqual, - EOQualifierOperatorContains }; - SEL operator; - - if (resOp < 7) - operator = operators[resOp]; - else - { - operator = NULL; - [NSException raise: @"MAPIStoreRestrictionException" - format: @"unhandled operator type number %d", resOp]; - } - - return operator; -} - -- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - SEL operator; - id value; - NSString *property; - MAPIRestrictionState rc; - - property = [self backendIdentifierForProperty: res->ulPropTag]; - if (property) - { - operator = [self operatorFromRestrictionOperator: res->relop]; - value = NSObjectFromMAPISPropValue (&res->lpProp); - *qualifier = [[EOKeyValueQualifier alloc] initWithKey: property - operatorSelector: operator - value: value]; - [*qualifier autorelease]; - - rc = MAPIRestrictionStateNeedsEval; - } - else - { - [self warnUnhandledProperty: res->ulPropTag - inFunction: __FUNCTION__]; - rc = MAPIRestrictionStateAlwaysFalse; - } - - return rc; -} - -- (MAPIRestrictionState) evaluateBitmaskRestriction: (struct mapi_SBitmaskRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - NSString *property; - MAPIRestrictionState rc; - - property = [self backendIdentifierForProperty: res->ulPropTag]; - if (property) - { - *qualifier = [[EOBitmaskQualifier alloc] initWithKey: property - mask: res->ulMask - isZero: (res->relMBR == BMR_EQZ)]; - [*qualifier autorelease]; - - rc = MAPIRestrictionStateNeedsEval; - } - else - { - [self warnUnhandledProperty: res->ulPropTag - inFunction: __FUNCTION__]; - rc = MAPIRestrictionStateAlwaysFalse; - } - - return rc; -} - -- (MAPIRestrictionState) evaluateExistRestriction: (struct mapi_SExistRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - NSString *property; - MAPIRestrictionState rc; - - property = [self backendIdentifierForProperty: res->ulPropTag]; - if (property) - { - *qualifier = [[EOKeyValueQualifier alloc] initWithKey: property - operatorSelector: EOQualifierOperatorNotEqual - value: nil]; - [*qualifier autorelease]; - - rc = MAPIRestrictionStateNeedsEval; - } - else - { - [self warnUnhandledProperty: res->ulPropTag - inFunction: __FUNCTION__]; - rc = MAPIRestrictionStateAlwaysFalse; - } - - return rc; -} - -- (MAPIRestrictionState) evaluateRestriction: (struct mapi_SRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState state; - - switch (res->rt) - { - /* basic operators */ - case RES_AND: state = [self evaluateAndRestriction: &res->res.resAnd - intoQualifier: qualifier]; - break; - case RES_OR: state = [self evaluateOrRestriction: &res->res.resOr - intoQualifier: qualifier]; - break; - case RES_NOT: state = [self evaluateNotRestriction: &res->res.resNot - intoQualifier: qualifier]; - break; - - /* content restrictions */ - case RES_CONTENT: state = [self evaluateContentRestriction: &res->res.resContent - intoQualifier: qualifier]; - break; - case RES_PROPERTY: state = [self evaluatePropertyRestriction: &res->res.resProperty - intoQualifier: qualifier]; - break; - case RES_BITMASK: state = [self evaluateBitmaskRestriction: &res->res.resBitmask - intoQualifier: qualifier]; - break; - - case RES_SIZE: state = MAPIRestrictionStateAlwaysTrue; /* let's cheat a little */ - break; - case RES_EXIST: state = [self evaluateExistRestriction: &res->res.resExist - intoQualifier: qualifier]; - break; - - case RES_COMMENT: - if (res->res.resComment.RestrictionPresent) - state = [self evaluateRestriction: (struct mapi_SRestriction *) res->res.resComment.Restriction.res - intoQualifier: qualifier]; - else - state = MAPIRestrictionStateAlwaysTrue; - break; - - // case 5: MAPIStringForComparePropsRestriction(&resPtr->res.resCompareProps); break; - // case 7: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break; - // case 9: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break; - // case 10: MAPIStringForPropertyRestriction(&resPtr->res.resProperty); break; - default: - [NSException raise: @"MAPIStoreRestrictionException" - format: @"unhandled restriction type: %.2x", res->rt]; - state = MAPIRestrictionStateAlwaysTrue; - } - - // [self logRestriction: res withState: state]; - - return state; -} - -/* proof of concept */ -- (enum mapistore_error) setColumns: (enum MAPITAGS *) newColumns - withCount: (uint16_t) newColumnsCount -{ - NSUInteger count; - - if (columns) - NSZoneFree (NULL, columns); - columns = NSZoneMalloc (NULL, newColumnsCount * sizeof (enum MAPITAGS)); - for (count = 0; count < newColumnsCount; count++) - columns[count] = newColumns[count]; - columnsCount = newColumnsCount; - - return MAPISTORE_SUCCESS; -} - -- (id) childAtRowID: (uint32_t) rowId - forQueryType: (enum mapistore_query_type) queryType -{ - id child; - NSArray *children, *restrictedChildren; - NSString *childKey; - - if (rowId == currentRow) - child = currentChild; - else - { - [currentChild release]; - child = nil; - - if (queryType == MAPISTORE_PREFILTERED_QUERY) - { - children = [self restrictedChildKeys]; - restrictedChildren = nil; - } - else - { - children = [self childKeys]; - restrictedChildren = [self restrictedChildKeys]; - } - - if ([children count] > rowId) - { - childKey = [children objectAtIndex: rowId]; - - if (queryType == MAPISTORE_PREFILTERED_QUERY - || [restrictedChildren containsObject: childKey]) - child = [self lookupChild: childKey]; - } - - currentChild = child; - [currentChild retain]; - - if (child) - currentRow = rowId; - else - currentRow = (uint32_t) -1; - } - - return child; -} - -- (NSArray *) childKeys -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (NSArray *) restrictedChildKeys -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (id) lookupChild: (NSString *) childKey -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (enum mapistore_error) getRow: (struct mapistore_property_data **) dataP - withRowID: (uint32_t) rowId - andQueryType: (enum mapistore_query_type) queryType - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSUInteger count; - MAPIStoreObject *child; - struct mapistore_property_data *rowData; - enum mapistore_error rc; - - child = [self childAtRowID: rowId forQueryType: queryType]; - if (child) - { - rowData = talloc_array(memCtx, struct mapistore_property_data, columnsCount); - for (count = 0; count < columnsCount; count++) - rowData[count].error = [child getProperty: &rowData[count].data - withTag: columns[count] - inMemCtx: memCtx]; - *dataP = rowData; - rc = MAPISTORE_SUCCESS; - } - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getRowCount: (uint32_t *) countP - withQueryType: (enum mapistore_query_type) queryType -{ - NSArray *children; - - if (queryType == MAPISTORE_PREFILTERED_QUERY) - children = [self restrictedChildKeys]; - else - children = [self childKeys]; - - *countP = [children count]; - - return MAPISTORE_SUCCESS; -} - -/* subclasses */ -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - -- (void) setSortOrder: (const struct SSortOrderSet *) set -{ - [self subclassResponsibility: _cmd]; -} - -@end diff --git a/OpenChange/MAPIStoreTasksContext.h b/OpenChange/MAPIStoreTasksContext.h deleted file mode 100644 index 70d416130..000000000 --- a/OpenChange/MAPIStoreTasksContext.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreTasksContext.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTORETASKSCONTEXT_H -#define MAPISTORETASKSCONTEXT_H - -#import "MAPIStoreGCSBaseContext.h" - -@interface MAPIStoreTasksContext : MAPIStoreGCSBaseContext - -@end - -#endif /* MAPISTORETASKSCONTEXT_H */ diff --git a/OpenChange/MAPIStoreTasksContext.m b/OpenChange/MAPIStoreTasksContext.m deleted file mode 100644 index 096ca3711..000000000 --- a/OpenChange/MAPIStoreTasksContext.m +++ /dev/null @@ -1,63 +0,0 @@ -/* MAPIStoreTasksContext.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 -#import - -#import "MAPIStoreTasksFolder.h" -#import "MAPIStoreUserContext.h" - -#import "MAPIStoreTasksContext.h" - -#undef DEBUG -#include - -static Class MAPIStoreTasksFolderK; - -@implementation MAPIStoreTasksContext - -+ (void) initialize -{ - MAPIStoreTasksFolderK = [MAPIStoreTasksFolder class]; -} - -+ (NSString *) MAPIModuleName -{ - return @"tasks"; -} - -+ (enum mapistore_context_role) MAPIContextRole -{ - return MAPISTORE_TASKS_ROLE; -} - -- (Class) MAPIStoreFolderClass -{ - return MAPIStoreTasksFolderK; -} - -+ (NSString *) folderNameSuffix -{ - return @"t"; -} - -@end diff --git a/OpenChange/MAPIStoreTasksFolder.h b/OpenChange/MAPIStoreTasksFolder.h deleted file mode 100644 index 3d16a44ae..000000000 --- a/OpenChange/MAPIStoreTasksFolder.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreTasksFolder.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORETASKSFOLDER_H -#define MAPISTORETASKSFOLDER_H - -#import "MAPIStoreCalTaskFolder.h" - -@interface MAPIStoreTasksFolder : MAPIStoreCalTaskFolder - -@end - -#endif /* MAPISTORETASKSFOLDER_H */ diff --git a/OpenChange/MAPIStoreTasksFolder.m b/OpenChange/MAPIStoreTasksFolder.m deleted file mode 100644 index 4b198d2d1..000000000 --- a/OpenChange/MAPIStoreTasksFolder.m +++ /dev/null @@ -1,201 +0,0 @@ -/* MAPIStoreTasksFolder.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIApplication.h" -#import "MAPIStoreUserContext.h" -#import "MAPIStoreTasksContext.h" -#import "MAPIStoreTasksMessage.h" -#import "MAPIStoreTasksMessageTable.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreTasksFolder.h" - -#include -#include -#include - -@implementation MAPIStoreTasksFolder - -- (MAPIStoreMessageTable *) messageTable -{ - [self synchroniseCache]; - return [MAPIStoreTasksMessageTable tableForContainer: self]; -} - -- (NSString *) component -{ - return @"vtodo"; -} - -- (MAPIStoreMessage *) createMessage -{ - MAPIStoreMessage *newMessage; - SOGoTaskObject *newEntry; - NSString *name; - - [[[self context] userContext] activate]; - name = [NSString stringWithFormat: @"%@.ics", - [SOGoObject globallyUniqueObjectId]]; - newEntry = [SOGoTaskObject objectWithName: name - inContainer: sogoObject]; - [newEntry setIsNew: YES]; - newMessage = [MAPIStoreTasksMessage mapiStoreObjectWithSOGoObject: newEntry - inContainer: self]; - - - return newMessage; -} - -// -------------------------------------------- -// Permissions and sharing -// -------------------------------------------- - -- (NSArray *) rolesForExchangeRights: (uint32_t) rights -{ - NSMutableArray *roles; - - roles = [NSMutableArray arrayWithCapacity: 6]; - if (rights & RightsCreateItems) - [roles addObject: SOGoRole_ObjectCreator]; - - if (rights & RightsDeleteAll) - [roles addObject: SOGoRole_ObjectEraser]; - if (rights & RightsDeleteOwn) - [roles addObject: MAPIStoreRightDeleteOwn]; - - if (rights & RightsEditAll) - { - [roles addObject: SOGoCalendarRole_PublicModifier]; - [roles addObject: SOGoCalendarRole_PrivateModifier]; - [roles addObject: SOGoCalendarRole_ConfidentialModifier]; - } - if (rights & RightsEditOwn) - [roles addObject: MAPIStoreRightEditOwn]; - - if (rights & RightsReadItems) - { - [roles addObject: SOGoCalendarRole_PublicViewer]; - [roles addObject: SOGoCalendarRole_PrivateViewer]; - [roles addObject: SOGoCalendarRole_ConfidentialViewer]; - } - - if (rights & RightsFolderOwner) - [roles addObject: MAPIStoreRightFolderOwner]; - - if (rights & RightsFolderContact) - [roles addObject: MAPIStoreRightFolderContact]; - - return roles; -} - -- (uint32_t) exchangeRightsForRoles: (NSArray *) roles -{ - uint32_t rights = 0; - - if ([roles containsObject: SOGoRole_ObjectCreator]) - rights |= RightsCreateItems; - if ([roles containsObject: SOGoRole_ObjectEraser]) - rights |= RightsDeleteAll | RightsDeleteOwn; - if ([roles containsObject: SOGoCalendarRole_PublicModifier] - && [roles containsObject: SOGoCalendarRole_PrivateModifier] - && [roles containsObject: SOGoCalendarRole_ConfidentialModifier]) - rights |= RightsReadItems | RightsEditAll | RightsEditOwn; - else if ([roles containsObject: SOGoCalendarRole_PublicViewer] - && [roles containsObject: SOGoCalendarRole_PrivateViewer] - && [roles containsObject: SOGoCalendarRole_ConfidentialViewer]) - rights |= RightsReadItems; - - if ([roles containsObject: MAPIStoreRightEditOwn]) - rights |= RightsEditOwn; - if ([roles containsObject: MAPIStoreRightDeleteOwn]) - rights |= RightsDeleteOwn; - - if (rights != 0) - rights |= RoleNone; /* actually "folder visible" */ - - if ([roles containsObject: MAPIStoreRightFolderOwner]) - rights |= RightsFolderOwner | RoleNone; - - if ([roles containsObject: MAPIStoreRightFolderContact]) - rights |= RightsFolderContact; - - return rights; -} - -- (BOOL) subscriberCanModifyMessages -{ - static NSArray *modifierRoles = nil; - - if (!modifierRoles) - modifierRoles = [[NSArray alloc] initWithObjects: - SOGoCalendarRole_PublicModifier, - SOGoCalendarRole_PrivateModifier, - SOGoCalendarRole_ConfidentialModifier, - nil]; - - return ([[self activeUserRoles] firstObjectCommonWithArray: modifierRoles] - != nil); -} - -- (BOOL) subscriberCanReadMessages -{ - static NSArray *viewerRoles = nil; - - if (!viewerRoles) - viewerRoles = [[NSArray alloc] initWithObjects: - SOGoCalendarRole_PublicViewer, - SOGoCalendarRole_PrivateViewer, - SOGoCalendarRole_ConfidentialViewer, - nil]; - - return ([[self activeUserRoles] firstObjectCommonWithArray: viewerRoles] - != nil); -} - -- (EOQualifier *) aclQualifier -{ - return [EOQualifier qualifierWithQualifierFormat: - [(SOGoAppointmentFolder *) sogoObject aclSQLListingFilter]]; -} - -// -------------------------------------------- -// Property getters -// -------------------------------------------- -- (enum mapistore_error) getPidTagDefaultPostMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"IPM.Task" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -@end diff --git a/OpenChange/MAPIStoreTasksMessage.h b/OpenChange/MAPIStoreTasksMessage.h deleted file mode 100644 index 360c516ad..000000000 --- a/OpenChange/MAPIStoreTasksMessage.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreTasksMessage.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORETASKSMESSAGE_H -#define MAPISTORETASKSMESSAGE_H - -#import "MAPIStoreCalTaskMessage.h" - -@interface MAPIStoreTasksMessage : MAPIStoreCalTaskMessage - -@end - -#endif /* MAPISTORETASKSMESSAGE_H */ diff --git a/OpenChange/MAPIStoreTasksMessage.m b/OpenChange/MAPIStoreTasksMessage.m deleted file mode 100644 index 3cd3f1bfd..000000000 --- a/OpenChange/MAPIStoreTasksMessage.m +++ /dev/null @@ -1,580 +0,0 @@ -/* MAPIStoreTasksMessage.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * Ludovic Marcotte - * - * 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 -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreContext.h" -#import "MAPIStoreTasksFolder.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSDate+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreTasksMessage.h" - -#undef DEBUG -#include -#include -#include -#include -#include - -@implementation SOGoTaskObject (MAPIStoreExtension) - -- (Class) mapistoreMessageClass -{ - return [MAPIStoreTasksMessage class]; -} - -@end - -@implementation MAPIStoreTasksMessage - -- (enum mapistore_error) getPidTagIconIndex: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - /* see http://msdn.microsoft.com/en-us/library/cc815472.aspx */ - // Unassigned recurring task 0x00000501 - // Assignee's task 0x00000502 - // Assigner's task 0x00000503 - // Task request 0x00000504 - // Task acceptance 0x00000505 - // Task rejection 0x00000506 - *data = MAPILongValue (memCtx, 0x00000500); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagMessageClass: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = talloc_strdup(memCtx, "IPM.Task"); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagNormalizedSubject: (void **) data // SUMMARY - inMemCtx: (TALLOC_CTX *) memCtx -{ - iCalToDo *task; - - task = [sogoObject component: NO secure: YES]; - *data = [[task summary] asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -/* FIXME: Should be combined somehow with the code in MAPIStoreAppointmentWrapper.m */ -- (enum mapistore_error) getPidTagBody: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSString *stringValue; - iCalToDo *task; - - /* FIXME: there is a confusion in NGCards around "comment" and "description" */ - task = [sogoObject component: NO secure: YES]; - stringValue = [task comment]; - if ([stringValue length] > 0) - *data = [stringValue asUnicodeInMemCtx: memCtx]; - else - *data = [@"" asUnicodeInMemCtx: memCtx]; - - return rc; -} - -/* FIXME: Should be combined somehow with the code in MAPIStoreAppointmentWrapper.m */ -- (enum mapistore_error) getPidLidPrivate: (void **) data // private (bool), should depend on CLASS and permissions - inMemCtx: (TALLOC_CTX *) memCtx -{ - iCalToDo *task; - - task = [sogoObject component: NO secure: YES]; - - if ([task isPublic]) - return [self getNo: data inMemCtx: memCtx]; - - return [self getYes: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagSensitivity: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t v; - - v = (uint32_t) [self sensitivity]; - - *data = MAPILongValue (memCtx, v); - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidTagImportance: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint32_t v; - iCalToDo *task; - - task = [sogoObject component: NO secure: YES]; - if ([[task priority] isEqualToString: @"9"]) - v = 0x0; - else if ([[task priority] isEqualToString: @"1"]) - v = 0x2; - else - v = 0x1; - - *data = MAPILongValue (memCtx, v); - - return MAPISTORE_SUCCESS; -} - -//------------------------------------ -// Specific task related properties -//------------------------------------ -- (enum mapistore_error) getPidLidTaskComplete: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - iCalToDo *task; - - task = [sogoObject component: NO secure: YES]; - *data = MAPIBoolValue (memCtx, - [[task status] isEqualToString: @"COMPLETED"]); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidPercentComplete: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - double doubleValue; - iCalToDo *task; - - task = [sogoObject component: NO secure: YES]; - - doubleValue = ((double) [[task percentComplete] intValue] / 100); - *data = MAPIDoubleValue (memCtx, doubleValue); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidTaskDateCompleted: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSCalendarDate *dateValue; - iCalToDo *task; - - task = [sogoObject component: NO secure: YES]; - - dateValue = [task completed]; - if (dateValue) - *data = [dateValue asFileTimeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidTaskState: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0x1); // not assigned - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidTaskMode: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidTaskFRecurring: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidTaskAccepted: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidTaskActualEffort: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidTaskEstimatedEffort: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidTagHasAttachments: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidTaskDueDate: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSCalendarDate *dateValue; - iCalToDo *task; - - task = [sogoObject component: NO secure: YES]; - dateValue = [task due]; - if (dateValue) - *data = [dateValue asFileTimeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - -- (enum mapistore_error) getPidLidTaskStartDate: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - enum mapistore_error rc = MAPISTORE_SUCCESS; - NSCalendarDate *dateValue; - iCalToDo *task; - - task = [sogoObject component: NO secure: YES]; - dateValue = [task startDate]; - if (dateValue) - *data = [dateValue asFileTimeInMemCtx: memCtx]; - else - rc = MAPISTORE_ERR_NOT_FOUND; - - return rc; -} - - -- (enum mapistore_error) getPidTagMessageDeliveryTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagLastModificationTime: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getClientSubmitTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagLastModificationTime: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getLocalCommitTime: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getPidTagLastModificationTime: data inMemCtx: memCtx]; -} - -- (enum mapistore_error) getPidLidTaskStatus: (void **) data // status - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *status; - uint32_t longValue; - iCalToDo *task; - - task = [sogoObject component: NO secure: YES]; - status = [task status]; - if (![status length] - || [status isEqualToString: @"NEEDS-ACTION"]) - longValue = 0; - else if ([status isEqualToString: @"IN-PROCESS"]) - longValue = 1; - else if ([status isEqualToString: @"COMPLETED"]) - longValue = 2; - else - longValue = 0xff; - *data = MAPILongValue (memCtx, longValue); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidTaskOwner: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSString *owner; - - /* FIXME: This is wrong when setting task's request */ - owner = [sogoObject ownerInContext: nil]; - - *data = [owner asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getPidLidTaskOwnership: (void **) data - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getLongZero: data inMemCtx: memCtx]; -} - -// ---------------------------------- -// Sharing -// ---------------------------------- -- (NSUInteger) sensitivity -{ - iCalToDo *task; - NSUInteger v; - - task = [sogoObject component: NO secure: YES]; - /* FIXME: Use OpenChange constants names */ - switch ([task symbolicAccessClass]) - { - case iCalAccessPrivate: - v = 0x2; - break; - case iCalAccessConfidential: - v = 0x3; - break; - default: - v = 0x0; - break; - } - return v; -} - -- (NSString *) creator -{ - iCalToDo *task; - - task = [sogoObject component: NO secure: YES]; - return [[task uniqueChildWithTag: @"x-sogo-component-created-by"] - flattenedValuesForKey: @""]; -} - -- (NSString *) owner -{ - /* This is not true but to allow a user edit its own tasks is required. - FIXME: When PidLidTaskOwner getter is properly implemented for Task Requests */ - return [self creator]; -} - -- (void) save:(TALLOC_CTX *) memCtx -{ - iCalCalendar *vCalendar; - iCalToDo *vToDo; - id value; - iCalDateTime *date; - iCalTimeZone *tz; - NSString *status, *priority, *tzName; - NSCalendarDate *now; - NSInteger tzOffset; - NSTimeZone *userTZ; - double doubleValue; - - vToDo = [sogoObject component: YES secure: NO]; - vCalendar = [vToDo parent]; - [vCalendar setProdID: @"-//Inverse inc.//OpenChange+SOGo//EN"]; - - userTZ = [[self userContext] timeZone]; - tzName = [userTZ name]; - tz = [iCalTimeZone timeZoneForName: tzName]; - [vCalendar addTimeZone: tz]; - - // summary - value = [properties - objectForKey: MAPIPropertyKey (PR_NORMALIZED_SUBJECT_UNICODE)]; - if (value) - [vToDo setSummary: value]; - - // comment - value = [properties - objectForKey: MAPIPropertyKey (PR_BODY_UNICODE)]; - if (!value) - { - value = [properties objectForKey: MAPIPropertyKey (PR_HTML)]; - if (value) - { - value = [[NSString alloc] initWithData: value - encoding: NSUTF8StringEncoding]; - [value autorelease]; - value = [value htmlToText]; - } - } - if (value) - { - if ([value length] == 0 || [value isEqualToString: @"\\n"]) - value = nil; - [vToDo setComment: value]; - } - - // location - value = [properties objectForKey: MAPIPropertyKey (PidLidLocation)]; - if (value) - [vToDo setLocation: value]; - - // created - value = [properties objectForKey: MAPIPropertyKey (PR_CREATION_TIME)]; - if (value) - [vToDo setCreated: value]; - - // last-modified + dtstamp - value = [properties objectForKey: MAPIPropertyKey (PR_LAST_MODIFICATION_TIME)]; - if (value) - { - [vToDo setLastModified: value]; - [vToDo setTimeStampAsDate: value]; - } - - // start - value = [properties objectForKey: MAPIPropertyKey (PidLidTaskStartDate)]; - if (value) - { - date = (iCalDateTime *) [vToDo uniqueChildWithTag: @"dtstart"]; - [date setTimeZone: tz]; - /* The property is set to user's local time zone. - See: [MS-OXOTASK] 2.2.2.2.4 - TODO: Ignore when the PT_SYSTIME is 0x5AE980E0*/ - tzOffset = [userTZ secondsFromGMTForDate: value]; - value = [value dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: -tzOffset]; - [date setDateTime: value]; - } - - // due - value = [properties objectForKey: MAPIPropertyKey (PidLidTaskDueDate)]; - if (value) - { - date = (iCalDateTime *) [vToDo uniqueChildWithTag: @"due"]; - [date setTimeZone: tz]; - /* The property is set to user's local time zone. - See: [MS-OXOTASK] 2.2.2.2.5 - TODO: Ignore when the PT_SYSTIME is 0x5AE980E0*/ - tzOffset = [userTZ secondsFromGMTForDate: value]; - value = [value dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: -tzOffset]; - [date setDateTime: value]; - } - - // completed - value = [properties objectForKey: MAPIPropertyKey (PidLidTaskDateCompleted)]; - if (value) - { - date = (iCalDateTime *) [vToDo uniqueChildWithTag: @"completed"]; - /* The property is set to midnight in local time zone converted to UTC: - See: [MS-OXOTASK] 2.2.2.2.9 */ - tzOffset = [userTZ secondsFromGMTForDate: value]; - value = [value dateByAddingYears: 0 months: 0 days: 0 - hours: 0 minutes: 0 - seconds: -tzOffset]; - [date setDate: value]; - } - - // status - value = [properties objectForKey: MAPIPropertyKey (PidLidTaskStatus)]; - if (value) - { - switch ([value intValue]) - { - case 1: status = @"IN-PROCESS"; break; - case 2: status = @"COMPLETED"; break; - default: status = @"NEEDS-ACTION"; - } - [vToDo setStatus: status]; - } - - // priority - value = [properties objectForKey: MAPIPropertyKey (PR_IMPORTANCE)]; - if (value) - { - switch ([value intValue]) - { - case 0: // IMPORTANCE_LOW - priority = @"9"; - break; - case 2: // IMPORTANCE_HIGH - priority = @"1"; - break; - default: // IMPORTANCE_NORMAL - priority = @"5"; - } - [vToDo setPriority: priority]; - } - - // percent complete - // NOTE: this does not seem to work on Outlook 2003. PidLidPercentComplete's value - // is always set to 0, no matter what value is set in Outlook - value = [properties objectForKey: MAPIPropertyKey (PidLidPercentComplete)]; - if (value) - { - doubleValue = [value doubleValue]; - [vToDo setPercentComplete: - [NSString stringWithFormat: @"%d", (int) (doubleValue * 100)]]; - } - - /* privacy */ - /* FIXME: this should be combined with the code found in iCalEvent+MAPIStore.m */ - value = [properties objectForKey: MAPIPropertyKey(PidLidPrivate)]; - - if (value) - { - if ([value boolValue]) - [vToDo setAccessClass: @"PRIVATE"]; - else - [vToDo setAccessClass: @"PUBLIC"]; - } - - /* Creation */ - now = [NSCalendarDate date]; - if ([sogoObject isNew]) - { - [vToDo setCreated: now]; - /* Creator is used for sharing purposes */ - value = [properties objectForKey: MAPIPropertyKey (PidTagLastModifierName)]; - if (value) - [[vToDo uniqueChildWithTag: @"x-sogo-component-created-by"] setSingleValue: value - forKey: @""]; - } - [vToDo setTimeStampAsDate: now]; - - [sogoObject saveCalendar: vCalendar]; - - [self updateVersions]; -} - -@end diff --git a/OpenChange/MAPIStoreTasksMessageTable.h b/OpenChange/MAPIStoreTasksMessageTable.h deleted file mode 100644 index 4be570027..000000000 --- a/OpenChange/MAPIStoreTasksMessageTable.h +++ /dev/null @@ -1,32 +0,0 @@ -/* MAPIStoreTasksMessageTable.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTORETASKSMESSAGETABLE_H -#define MAPISTORETASKSMESSAGETABLE_H - -#import "MAPIStoreGCSMessageTable.h" - -@interface MAPIStoreTasksMessageTable : MAPIStoreGCSMessageTable - -@end - -#endif /* MAPISTORETASKSMESSAGETABLE_H */ diff --git a/OpenChange/MAPIStoreTasksMessageTable.m b/OpenChange/MAPIStoreTasksMessageTable.m deleted file mode 100644 index b0f39341c..000000000 --- a/OpenChange/MAPIStoreTasksMessageTable.m +++ /dev/null @@ -1,168 +0,0 @@ -/* MAPIStoreTasksMessageTable.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import - -#import - -#import - -#import "MAPIStoreTasksMessage.h" -#import "MAPIStoreTypes.h" -#import "NSData+MAPIStore.h" -#import "NSDate+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "MAPIStoreTasksMessageTable.h" - -#include - -static Class MAPIStoreTasksMessageK = Nil; - -@implementation MAPIStoreTasksMessageTable - -+ (void) initialize -{ - MAPIStoreTasksMessageK = [MAPIStoreTasksMessage class]; -} - -+ (Class) childObjectClass -{ - return MAPIStoreTasksMessageK; -} - -- (NSString *) backendIdentifierForProperty: (enum MAPITAGS) property -{ - static NSMutableDictionary *knownProperties = nil; - - if (!knownProperties) - { - knownProperties = [NSMutableDictionary new]; - [knownProperties setObject: @"c_enddate" - forKey: MAPIPropertyKey (PidLidTaskDueDate)]; - } - - return [knownProperties objectForKey: MAPIPropertyKey (property)]; -} - -/* restrictions */ - -- (MAPIRestrictionState) evaluatePropertyRestriction: (struct mapi_SPropertyRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState rc; - id value; - - value = NSObjectFromMAPISPropValue (&res->lpProp); - switch ((uint32_t) res->ulPropTag) - { - case PR_MESSAGE_CLASS_UNICODE: - if ([value isKindOfClass: [NSString class]] - && [value isEqualToString: @"IPM.Task"]) - rc = MAPIRestrictionStateAlwaysTrue; - else - rc = MAPIRestrictionStateAlwaysFalse; - break; - case PR_SENSITIVITY: - rc = MAPIRestrictionStateAlwaysTrue; - break; - case PR_RULE_PROVIDER_UNICODE: // TODO: what's this? - rc = MAPIRestrictionStateAlwaysTrue; - break; - case PidLidTaskOwnership: - rc = MAPIRestrictionStateAlwaysTrue; - break; - case PidLidTaskStatus: - rc = MAPIRestrictionStateAlwaysTrue; - break; - - case PidLidTaskComplete: - *qualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_status" - operatorSelector: EOQualifierOperatorEqual - value: [NSNumber numberWithInt: 1]]; - [*qualifier autorelease]; - rc = MAPIRestrictionStateNeedsEval; - break; - - case PidLidTaskDateCompleted: - rc = MAPIRestrictionStateAlwaysTrue; - break; - - default: - rc = [super evaluatePropertyRestriction: res intoQualifier: qualifier]; - } - - return rc; -} - -- (MAPIRestrictionState) evaluateExistRestriction: (struct mapi_SExistRestriction *) res - intoQualifier: (EOQualifier **) qualifier -{ - MAPIRestrictionState rc; - - switch ((uint32_t) res->ulPropTag) - { - case PidLidTaskDateCompleted: - /* since we don't store the completion date in the quick table, we only - checks whether the task has been completed */ - *qualifier = [[EOKeyValueQualifier alloc] - initWithKey: @"c_status" - operatorSelector: EOQualifierOperatorEqual - value: [NSNumber numberWithInt: 1]]; - [*qualifier autorelease]; - rc = MAPIRestrictionStateNeedsEval; - break; - - default: - rc = [super evaluateExistRestriction: res intoQualifier: qualifier]; - } - - return rc; -} - -/* sorting */ - -- (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property -{ - static NSMutableDictionary *knownProperties = nil; - - if (!knownProperties) - { - knownProperties = [NSMutableDictionary new]; - [knownProperties setObject: @"c_title" - forKey: MAPIPropertyKey (PR_NORMALIZED_SUBJECT_UNICODE)]; - [knownProperties setObject: @"c_enddate" - forKey: MAPIPropertyKey (PidLidTaskDueDate)]; - [knownProperties setObject: @"c_creationdate" - forKey: MAPIPropertyKey (PidLidTaskOrdinal)]; - /* Use by oxcfxics to sort the latest first */ - [knownProperties setObject: @"c_lastmodified" - forKey: MAPIPropertyKey (PidTagMessageDeliveryTime)]; - } - - return [knownProperties objectForKey: MAPIPropertyKey (property)]; -} - -@end diff --git a/OpenChange/MAPIStoreTypes.h b/OpenChange/MAPIStoreTypes.h deleted file mode 100644 index b12cab6a1..000000000 --- a/OpenChange/MAPIStoreTypes.h +++ /dev/null @@ -1,65 +0,0 @@ -/* MAPIStoreTypes.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MAPISTORETYPES_H -#define MAPISTORETYPES_H - -#import - -#include -#include -#include -#include - -@class NSData; -@class NSDictionary; -@class NSTimeZone; - -extern NSTimeZone *utcTZ; - -uint8_t *MAPIBoolValue (void *memCtx, BOOL value); -uint32_t *MAPILongValue (void *memCtx, uint32_t value); -uint64_t *MAPILongLongValue (void *memCtx, uint64_t value); -double *MAPIDoubleValue (void *memCtx, double value); - -id NSObjectFromSPropValue (const struct SPropValue *); -id NSObjectFromMAPISPropValue (const struct mapi_SPropValue *); -id NSObjectFromValuePointer (enum MAPITAGS, const void *); - -NSComparisonResult MAPICNCompare (uint64_t cn1, uint64_t cn2, void *); -NSComparisonResult MAPIChangeKeyGUIDCompare (id ck1, id ck2, void *); - -static inline NSNumber * -MAPIPropertyKey (enum MAPITAGS propTag) -{ -#if (GS_SIZEOF_LONG == 4) - return [NSString stringWithFormat: @"%ul", propTag]; -#elif (GS_SIZEOF_INT == 4) - return [NSString stringWithFormat: @"%u", propTag]; -#else -#error No suitable type for 4 bytes integers -#endif -} - -void MAPIStoreDumpMessageProperties (NSDictionary *properties); - -#endif /* MAPISTORETYPES_H */ diff --git a/OpenChange/MAPIStoreTypes.m b/OpenChange/MAPIStoreTypes.m deleted file mode 100644 index eb3b499b3..000000000 --- a/OpenChange/MAPIStoreTypes.m +++ /dev/null @@ -1,369 +0,0 @@ -/* MAPIStoreTypes.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import - -#import "NSArray+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSDate+MAPIStore.h" - -#import "MAPIStoreTypes.h" - -#undef DEBUG -#include -#include - -NSTimeZone *utcTZ; - -uint8_t * -MAPIBoolValue (void *memCtx, BOOL value) -{ - uint8_t *boolValue; - - boolValue = talloc_zero (memCtx, uint8_t); - *boolValue = value; - - return boolValue; -} - -uint32_t * -MAPILongValue (void *memCtx, uint32_t value) -{ - uint32_t *longValue; - - longValue = talloc_zero (memCtx, uint32_t); - *longValue = value; - - return longValue; -} - -uint64_t * -MAPILongLongValue (void *memCtx, uint64_t value) -{ - uint64_t *llongValue; - - llongValue = talloc_zero (memCtx, uint64_t); - *llongValue = value; - - return llongValue; -} - -double * -MAPIDoubleValue (void *memCtx, double value) -{ - double *doubleValue; - - doubleValue = talloc_zero (memCtx, double); - *doubleValue = value; - - return doubleValue; -} - -id -NSObjectFromMAPISPropValue (const struct mapi_SPropValue *value) -{ - short int valueType; - id result; - - valueType = (value->ulPropTag & 0xffff); - switch (valueType) - { - case PT_NULL: - result = [NSNull null]; - break; - case PT_SHORT: - result = [NSNumber numberWithUnsignedShort: value->value.i]; - break; - case PT_LONG: - case PT_ERROR: - result = [NSNumber numberWithUnsignedLong: value->value.l]; - break; - case PT_I8: - result = [NSNumber numberWithUnsignedLongLong: value->value.d]; - break; - case PT_BOOLEAN: - result = [NSNumber numberWithBool: (value->value.b ? YES : NO)]; - break; - case PT_DOUBLE: - result = [NSNumber numberWithDouble: value->value.dbl]; - break; - case PT_UNICODE: - result = [NSString stringWithUTF8String: value->value.lpszW]; - break; - case PT_STRING8: - result = [NSString stringWithUTF8String: value->value.lpszA]; - break; - case PT_SYSTIME: - result = [NSCalendarDate dateFromFileTime: &(value->value.ft)]; - [result setTimeZone: utcTZ]; - break; - case PT_BINARY: - case PT_SVREID: - result = [NSData dataWithShortBinary: &value->value.bin]; - break; - case PT_CLSID: - result = [NSData dataWithGUID: &value->value.lpguid]; - break; - - case PT_MV_LONG: - result = [NSArray arrayFromMAPIMVLong: &value->value.MVl]; - break; - case PT_MV_STRING8: - result = [NSArray arrayFromMAPIMVString: &value->value.MVszA]; - break; - case PT_MV_UNICODE: - result = [NSArray arrayFromMAPIMVUnicode: &value->value.MVszW]; - break; - case PT_MV_CLSID: - result = [NSArray arrayFromMAPIMVGuid: &value->value.MVguid]; - break; - case PT_MV_BINARY: - result = [NSArray arrayFromMAPIMVBinary: &value->value.MVbin]; - break; - - default: -// #define PT_UNSPECIFIED 0x0 -// #define PT_I2 0x2 -// #define PT_CURRENCY 0x6 -// #define PT_APPTIME 0x7 -// #define PT_ERROR 0xa -// #define PT_OBJECT 0xd -// #define PT_I8 0x14 -// #define PT_SRESTRICT 0xFD -// #define PT_ACTIONS 0xFE - result = nil; - NSLog (@"%s: object type not handled: %d (0x%.4x)", - __PRETTY_FUNCTION__, valueType, valueType); - } - - return result; -} - -id -NSObjectFromSPropValue (const struct SPropValue *value) -{ - short int valueType; - id result; - - valueType = (value->ulPropTag & 0xffff); - switch (valueType) - { - case PT_NULL: - result = [NSNull null]; - break; - case PT_SHORT: - result = [NSNumber numberWithShort: value->value.i]; - break; - case PT_LONG: - case PT_ERROR: - result = [NSNumber numberWithLong: value->value.l]; - break; - case PT_I8: - result = [NSNumber numberWithUnsignedLongLong: value->value.d]; - break; - case PT_BOOLEAN: - result = [NSNumber numberWithBool: (value->value.b ? YES : NO)]; - break; - case PT_DOUBLE: - result = [NSNumber numberWithDouble: value->value.dbl]; - break; - case PT_UNICODE: - result = (value->value.lpszW - ? [NSString stringWithUTF8String: value->value.lpszW] - : (id) @""); - break; - case PT_STRING8: - result = (value->value.lpszA - ? [NSString stringWithUTF8String: (const char *) value->value.lpszA] - : (id) @""); - break; - case PT_SYSTIME: - result = [NSCalendarDate dateFromFileTime: &(value->value.ft)]; - break; - case PT_BINARY: - case PT_SVREID: - // lpProps->value.bin = *((const struct Binary_r *)data); - - result - = [NSData dataWithBinary: - (const struct Binary_r *) &(value->value.bin)]; - break; - case PT_CLSID: - result = [NSData dataWithFlatUID: value->value.lpguid]; - break; - case PT_MV_SHORT: - result = [NSArray arrayFromMVShort: &value->value.MVi]; - break; - case PT_MV_LONG: - result = [NSArray arrayFromMVLong: &value->value.MVl]; - break; - case PT_MV_I8: - result = [NSArray arrayFromMVUI8: &value->value.MVui8]; - break; - case PT_MV_STRING8: - result = [NSArray arrayFromMVString: &value->value.MVszA]; - break; - case PT_MV_UNICODE: - result = [NSArray arrayFromMVUnicode: &value->value.MVszW]; - break; - case PT_MV_CLSID: - result = [NSArray arrayFromMVGuid: &value->value.MVguid]; - break; - case PT_MV_BINARY: - result = [NSArray arrayFromMVBinary: &value->value.MVbin]; - break; - case PT_MV_SYSTIME: - result = [NSArray arrayFromMVFileTime: &value->value.MVft]; - break; - - default: -// #define PT_UNSPECIFIED 0x0 -// #define PT_I2 0x2 -// #define PT_CURRENCY 0x6 -// #define PT_APPTIME 0x7 -// #define PT_ERROR 0xa -// #define PT_OBJECT 0xd -// #define PT_I8 0x14 -// #define PT_SRESTRICT 0xFD -// #define PT_ACTIONS 0xFE - result = nil; - NSLog (@"%s: object type not handled: %d (0x%.4x)", - __PRETTY_FUNCTION__, valueType, valueType); - } - - return result; -} - -id -NSObjectFromValuePointer (enum MAPITAGS propTag, const void *data) -{ - struct SPropValue sPropValue; - id result; - - if (set_SPropValue_proptag(&sPropValue, propTag, data)) - result = NSObjectFromSPropValue (&sPropValue); - else - result = nil; - - return result; -} - -static uint64_t -_reverseCN (uint64_t cn) -{ - return ((cn & UINT64_C (0x00000000000000ff)) << 56 - | (cn & UINT64_C (0x000000000000ff00)) << 40 - | (cn & UINT64_C (0x0000000000ff0000)) << 24 - | (cn & UINT64_C (0x00000000ff000000)) << 8 - | (cn & UINT64_C (0x000000ff00000000)) >> 8 - | (cn & UINT64_C (0x0000ff0000000000)) >> 24 - | (cn & UINT64_C (0x00ff000000000000)) >> 40 - | (cn & UINT64_C (0xff00000000000000)) >> 56); -} - -NSComparisonResult -MAPICNCompare (uint64_t cn1, uint64_t cn2, void *unused) -{ - NSComparisonResult result; - - if (cn1 == cn2) - result = NSOrderedSame; - else if (_reverseCN (cn1) < _reverseCN (cn2)) - result = NSOrderedAscending; - else - result = NSOrderedDescending; - - return result; -} - -NSComparisonResult -MAPIChangeKeyGUIDCompare (id ck1, id ck2, void *unused) -{ - NSUInteger count; - const unsigned char *ptr1, *ptr2; - NSComparisonResult result = NSOrderedSame; - - if ([ck1 length] < 16) - { - NSLog (@"ck1 has a length < 16"); - abort (); - } - if ([ck2 length] < 16) - { - NSLog (@"ck2 has a length < 16"); - abort (); - } - - ptr1 = [ck1 bytes]; - ptr2 = [ck2 bytes]; - for (count = 0; result == NSOrderedSame && count < 16; count++) - { - if (*ptr1 < *ptr2) - result = NSOrderedAscending; - else if (*ptr1 > *ptr2) - result = NSOrderedDescending; - else - { - ptr1++; - ptr2++; - } - } - - return result; -} - -void -MAPIStoreDumpMessageProperties (NSDictionary *properties) -{ - NSNumber *key; - NSArray *allKeys; - NSUInteger count, max; - NSUInteger keyAsInt; - id value; - - allKeys = [properties allKeys]; - max = [allKeys count]; - - NSLog (@"message properties (%d):", max); - - value = [properties objectForKey: @"recipients"]; - if (value) - NSLog (@" recipients: %@", value); - - for (count = 0; count < max; count++) - { - key = [allKeys objectAtIndex: count]; - if ([key isKindOfClass: [NSNumber class]]) - { - keyAsInt = [key intValue]; - value = [properties objectForKey: key]; - NSLog (@" 0x%.4x: %@ (%@)", - keyAsInt, value, - NSStringFromClass ([value class])); - } - } -} diff --git a/OpenChange/MAPIStoreUserContext.h b/OpenChange/MAPIStoreUserContext.h deleted file mode 100644 index b8defd0cd..000000000 --- a/OpenChange/MAPIStoreUserContext.h +++ /dev/null @@ -1,96 +0,0 @@ -/* MAPIStoreUserContext.h - this file is part of $PROJECT_NAME_HERE$ - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 MAPISTOREUSERCONTEXT_H -#define MAPISTOREUSERCONTEXT_H - -#import - -@class NSMutableDictionary; -@class NSString; -@class NSTimeZone; -@class NSURL; - -@class WOContext; - -@class SOGoAppointmentFolders; -@class SOGoContactFolders; -@class SOGoMailAccount; -@class SOGoUser; -@class SOGoUserFolder; - -@class MAPIStoreAuthenticator; -@class MAPIStoreMapping; - -@interface MAPIStoreUserContext : NSObject -{ - NSString *username; - SOGoUser *sogoUser; - NSTimeZone *timeZone; - - SOGoUserFolder *userFolder; - NSMutableArray *containersBag; - NSMutableDictionary *rootFolders; - - MAPIStoreMapping *mapping; - - BOOL userDbTableExists; - NSURL *folderTableURL; - - WOContext *woContext; - MAPIStoreAuthenticator *authenticator; - - BOOL inboxHasNoInferiors; -} - -+ (id) userContextWithUsername: (NSString *) username - andTDBIndexing: (struct indexing_context *) indexing; - -- (id) initWithUsername: (NSString *) newUsername - andTDBIndexing: (struct indexing_context *) indexing; - -- (NSString *) username; -- (SOGoUser *) sogoUser; - -- (NSTimeZone *) timeZone; - -- (SOGoUserFolder *) userFolder; - -- (NSDictionary *) rootFolders; - -- (BOOL) inboxHasNoInferiors; - -- (NSURL *) folderTableURL; -- (MAPIStoreMapping *) mapping; - -- (void) ensureFolderTableExists; - -/* SOGo hacky magic */ -- (void) activateWithUser: (SOGoUser *) activeUser; -- (void) activate; -- (void) deactivate; -- (MAPIStoreAuthenticator *) authenticator; -- (WOContext *) woContext; - -@end - -#endif /* MAPISTOREUSERCONTEXT_H */ diff --git a/OpenChange/MAPIStoreUserContext.m b/OpenChange/MAPIStoreUserContext.m deleted file mode 100644 index de3dfadf1..000000000 --- a/OpenChange/MAPIStoreUserContext.m +++ /dev/null @@ -1,412 +0,0 @@ -/* MAPIStoreUserContext.m - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import - -#import -#import - -#import - -#import -#import -#import -#import -#import -#import -#import -#import - -#import -#import "MAPIApplication.h" -#import "MAPIStoreAuthenticator.h" -#import "MAPIStoreMapping.h" - -#import "MAPIStoreUserContext.h" - -static NSMapTable *contextsTable = nil; - -@implementation MAPIStoreUserContext - -+ (void) initialize -{ - contextsTable = [NSMapTable mapTableWithStrongToWeakObjects]; - [contextsTable retain]; -} - -+ (id) userContextWithUsername: (NSString *) username - andTDBIndexing: (struct indexing_context *) indexing; -{ - id userContext; - - userContext = [contextsTable objectForKey: username]; - if (!userContext) - { - userContext = [[self alloc] initWithUsername: username - andTDBIndexing: indexing]; - [userContext autorelease]; - [contextsTable setObject: userContext forKey: username]; - } - else - [userContext activate]; - - return userContext; -} - -- (id) init -{ - if ((self = [super init])) - { - username = nil; - sogoUser = nil; - - userFolder = nil; - containersBag = [NSMutableArray new]; - rootFolders = nil; - - mapping = nil; - - userDbTableExists = NO; - folderTableURL = nil; - - authenticator = nil; - woContext = [WOContext contextWithRequest: nil]; - [woContext retain]; - } - - return self; -} - -- (NSString *) _readPasswordFile: (NSString *) path -{ - NSString *password; - NSData *content; - - password = nil; - content = [NSData dataWithContentsOfFile: path]; - - if (content) - { - password = [[NSString alloc] initWithData: content - encoding: NSUTF8StringEncoding]; - [password autorelease]; - password = [password stringByTrimmingCharactersInSet: - [NSCharacterSet characterSetWithCharactersInString: @"\r\n"]]; - } - - return password; -} - -- (NSString *) _readUserPassword: (NSString *) newUsername -{ - NSString *password, *path; - - path = [NSString stringWithFormat: SAMBA_PRIVATE_DIR - @"/mapistore/%@/password", newUsername]; - - password = [self _readPasswordFile: path]; - if (password == nil) - { - // Try to get master password - path = [NSString stringWithFormat: SAMBA_PRIVATE_DIR @"/mapistore/master.password"]; - password = [self _readPasswordFile: path]; - } - - return password; -} - -- (id) initWithUsername: (NSString *) newUsername - andTDBIndexing: (struct indexing_context *) indexing -{ - NSString *userPassword; - - if ((self = [self init])) - { - /* "username" will be retained by table */ - username = newUsername; - if (indexing) - ASSIGN (mapping, [MAPIStoreMapping mappingForUsername: username - withIndexing: indexing]); - - authenticator = [MAPIStoreAuthenticator new]; - [authenticator setUsername: username]; - /* TODO: very hackish (IMAP access) */ - userPassword = [self _readUserPassword: newUsername]; - if ([userPassword length] == 0) - userPassword = username; - [authenticator setPassword: userPassword]; - // Activate the profile on initialization - [self activate]; - } - - return self; -} - -- (void) dealloc -{ - [userFolder release]; - [containersBag release]; - [rootFolders release]; - - [woContext release]; - [authenticator release]; - [mapping release]; - - [folderTableURL release]; - - [sogoUser release]; - - [contextsTable removeObjectForKey: username]; - - [super dealloc]; -} - -- (NSString *) username -{ - return username; -} - -- (SOGoUser *) sogoUser -{ - if (!sogoUser) - ASSIGN (sogoUser, [SOGoUser userWithLogin: username]); - - return sogoUser; -} - -- (NSTimeZone *) timeZone -{ - if (!timeZone) - { - SOGoUser *user; - - user = [self sogoUser]; - timeZone = [[user userDefaults] timeZone]; - [timeZone retain]; - } - - return timeZone; -} - -- (SOGoUserFolder *) userFolder -{ - if (!userFolder) - { - userFolder = [SOGoUserFolder objectWithName: username - inContainer: nil]; - [userFolder retain]; - } - - return userFolder; -} - -- (NSDictionary *) rootFolders -{ - SOGoMailAccounts *accountsFolder; - id currentFolder; - NGImap4Connection *connection; - NSDictionary *hierarchy; - NSArray *flags; - - if (!rootFolders) - { - rootFolders = [NSMutableDictionary new]; - [self activate]; - [self userFolder]; // force lazy initialization - [woContext setClientObject: userFolder]; - - /* Calendar */ - currentFolder = [userFolder lookupName: @"Calendar" - inContext: woContext - acquire: NO]; - [rootFolders setObject: currentFolder - forKey: @"calendar"]; - [rootFolders setObject: currentFolder - forKey: @"tasks"]; - - /* Contacts */ - currentFolder = [userFolder lookupName: @"Contacts" - inContext: woContext - acquire: NO]; - [rootFolders setObject: currentFolder - forKey: @"contacts"]; - - /* Mail */ - accountsFolder = [userFolder lookupName: @"Mail" - inContext: woContext - acquire: NO]; - [containersBag addObject: accountsFolder]; - [woContext setClientObject: accountsFolder]; - - currentFolder = [accountsFolder lookupName: @"0" - inContext: woContext - acquire: NO]; - [rootFolders setObject: currentFolder - forKey: @"mail"]; - connection = [currentFolder imap4Connection]; - [connection enableExtensions: [NSArray arrayWithObject: @"QRESYNC"]]; - - /* ensure the folder cache is filled */ - [currentFolder toManyRelationshipKeysWithNamespaces: YES]; - hierarchy = [connection cachedHierarchyResultsForURL: [currentFolder imap4URL]]; - flags = [[hierarchy objectForKey: @"list"] objectForKey: @"/INBOX"]; - inboxHasNoInferiors = [flags containsObject: @"noinferiors"]; - } - - return rootFolders; -} - -- (BOOL) inboxHasNoInferiors -{ - [self rootFolders]; - - return inboxHasNoInferiors; -} - -- (MAPIStoreMapping *) mapping -{ - return mapping; -} - - -/* OpenChange db table */ - -- (NSURL *) folderTableURL -{ - NSString *urlString, *ocFSTableName; - NSMutableArray *parts; - SOGoUser *user; - - if (!folderTableURL) - { - user = [self sogoUser]; - urlString = [[user domainDefaults] folderInfoURL]; - parts = [[urlString componentsSeparatedByString: @"/"] - mutableCopy]; - [parts autorelease]; - if ([parts count] == 5) - { - /* If "OCSFolderInfoURL" is properly configured, we must have 5 - parts in this url. We strip the '-' character in case we have - this in the domain part - like foo@bar-zot.com */ - ocFSTableName = [NSString stringWithFormat: @"sogo_cache_folder_%@", - [[[user login] asCSSIdentifier] - stringByReplacingOccurrencesOfString: @"-" - withString: @"_"]]; - [parts replaceObjectAtIndex: 4 withObject: ocFSTableName]; - folderTableURL - = [NSURL URLWithString: [parts componentsJoinedByString: @"/"]]; - [folderTableURL retain]; - } - else - [NSException raise: @"MAPIStoreIOException" - format: @"'OCSFolderInfoURL' is not set"]; - } - - return folderTableURL; -} - -- (void) ensureFolderTableExists -{ - GCSChannelManager *cm; - EOAdaptorChannel *channel; - NSString *tableName, *query; - GCSSpecialQueries *queries; - - [self folderTableURL]; - - cm = [GCSChannelManager defaultChannelManager]; - channel = [cm acquireOpenChannelForURL: folderTableURL]; - - /* FIXME: make use of [EOChannelAdaptor describeTableNames] instead */ - tableName = [[folderTableURL path] lastPathComponent]; - if ([channel evaluateExpressionX: - [NSString stringWithFormat: @"SELECT count(*) FROM %@", - tableName]]) - { - queries = [channel specialQueries]; - query = [queries createSOGoCacheGCSFolderTableWithName: tableName]; - if ([channel evaluateExpressionX: query]) - [NSException raise: @"MAPIStoreIOException" - format: @"could not create special table '%@'", tableName]; - } - else - [channel cancelFetch]; - - - [cm releaseChannel: channel]; -} - -/* SOGo context objects */ -- (WOContext *) woContext -{ - return woContext; -} - -- (MAPIStoreAuthenticator *) authenticator -{ - return authenticator; -} - -- (void) activate -{ - [self activateWithUser: [self sogoUser]]; -} - -- (void) activateWithUser: (SOGoUser *) activeUser; -{ - NSMutableDictionary *info; - - [MAPIApp setUserContext: self]; - [woContext setActiveUser: activeUser]; - info = [[NSThread currentThread] threadDictionary]; - [info setObject: woContext forKey: @"WOContext"]; -} - -- (void) deactivate -{ - NSMutableDictionary *info; - - if (self == [MAPIApp userContext]) - [MAPIApp setUserContext: nil]; - else - [self errorWithFormat: @"Error: Tried to deactivate an user context " - @"not enabled (%@ vs %@)", - [self username], [[MAPIApp userContext] username]]; - - info = [[NSThread currentThread] threadDictionary]; - if (woContext == [info objectForKey: @"WOContext"]) - [info removeObjectForKey: @"WOContext"]; - else - [self errorWithFormat: @"Error: Tried to deactivate a WOContext " - @"not enabled (%@ vs %@)", - woContext, [info objectForKey: @"WOContext"]]; -} - -@end diff --git a/OpenChange/NSArray+MAPIStore.h b/OpenChange/NSArray+MAPIStore.h deleted file mode 100644 index a61bc4bc3..000000000 --- a/OpenChange/NSArray+MAPIStore.h +++ /dev/null @@ -1,51 +0,0 @@ -/* NSArray+MAPIStore.h - this file is part of SOGo - * - * Copyright (C) 2010 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef NSARRAY_MAPISTORE_H -#define NSARRAY_MAPISTORE_H - -#import - -@interface NSArray (MAPIStoreFolders) - -/* mapi structs */ -+ (id) arrayFromMAPIMVLong: (const struct mapi_MV_LONG_STRUCT *) mvLong; -+ (id) arrayFromMAPIMVUnicode: (const struct mapi_SLPSTRArrayW *) mvUnicode; -+ (id) arrayFromMAPIMVString: (const struct mapi_SLPSTRArray *) mvString; -+ (id) arrayFromMAPIMVBinary: (const struct mapi_SBinaryArray *) mvBinary; -+ (id) arrayFromMAPIMVGuid: (const struct mapi_SGuidArray *) mvGuid; - -+ (id) arrayFromMVShort: (const struct ShortArray_r *) mvShort; -+ (id) arrayFromMVLong: (const struct LongArray_r *) mvLong; -- (struct LongArray_r *) asMVLongInMemCtx: (void *) memCtx; -+ (id) arrayFromMVUI8: (const struct UI8Array_r *) mvI8; -+ (id) arrayFromMVString: (const struct StringArray_r *) mvString; -+ (id) arrayFromMVUnicode: (const struct StringArrayW_r *) mvUnicode; -- (struct StringArrayW_r *) asMVUnicodeInMemCtx: (void *) memCtx; -+ (id) arrayFromMVBinary: (const struct BinaryArray_r *) mvBinary; -- (struct BinaryArray_r *) asMVBinaryInMemCtx: (void *) memCtx; -+ (id) arrayFromMVGuid: (const struct FlatUIDArray_r *) mvGuid; -+ (id) arrayFromMVFileTime: (const struct DateTimeArray_r *) mvGuid; - -@end - -#endif /* NSARRAY+MAPISTORE_H */ diff --git a/OpenChange/NSArray+MAPIStore.m b/OpenChange/NSArray+MAPIStore.m deleted file mode 100644 index be54e9259..000000000 --- a/OpenChange/NSArray+MAPIStore.m +++ /dev/null @@ -1,308 +0,0 @@ -/* NSArray+MAPIStore.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import "NSDate+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "NSArray+MAPIStore.h" - -#undef DEBUG -#include -#include -#include -#include -#include - -@implementation NSArray (MAPIStoreFolders) - -+ (id) arrayFromMAPIMVLong: (struct mapi_MV_LONG_STRUCT *) mvLong -{ - NSUInteger count; - NSNumber *subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvLong->cValues]; - for (count = 0; count < mvLong->cValues; count++) - { - subObject = [NSNumber numberWithLong: mvLong->lpl[count]]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -+ (id) arrayFromMAPIMVUnicode: (struct mapi_SLPSTRArrayW *) mvUnicode -{ - NSUInteger count; - NSString *subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvUnicode->cValues]; - for (count = 0; count < mvUnicode->cValues; count++) - { - subObject - = [NSString stringWithUTF8String: mvUnicode->strings[count].lppszW]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -+ (id) arrayFromMAPIMVString: (struct mapi_SLPSTRArray *) mvString -{ - NSUInteger count; - id subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvString->cValues]; - for (count = 0; count < mvString->cValues; count++) - { - subObject = [NSString stringWithUTF8String: mvString->strings[count].lppszA]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -+ (id) arrayFromMAPIMVBinary: (struct mapi_SBinaryArray *) mvBinary -{ - NSUInteger count; - id subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvBinary->cValues]; - for (count = 0; count < mvBinary->cValues; count++) - { - subObject = [NSData dataWithShortBinary: mvBinary->bin + count]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -+ (id) arrayFromMAPIMVGuid: (struct mapi_SGuidArray *) mvGuid -{ - NSUInteger count; - id subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvGuid->cValues]; - for (count = 0; count < mvGuid->cValues; count++) - { - subObject = [NSData dataWithGUID: mvGuid->lpguid + count]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -+ (id) arrayFromMVShort: (const struct ShortArray_r *) mvShort -{ - NSUInteger count; - NSNumber *subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvShort->cValues]; - for (count = 0; count < mvShort->cValues; count++) - { - subObject = [NSNumber numberWithShort: mvShort->lpi[count]]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -+ (id) arrayFromMVLong: (const struct LongArray_r *) mvLong -{ - NSUInteger count; - NSNumber *subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvLong->cValues]; - for (count = 0; count < mvLong->cValues; count++) - { - subObject = [NSNumber numberWithLong: mvLong->lpl[count]]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -- (struct LongArray_r *) asMVLongInMemCtx: (void *) memCtx -{ - struct LongArray_r *list; - NSNumber *number; - NSInteger count, max; - - max = [self count]; - - list = talloc_zero (memCtx, struct LongArray_r); - list->cValues = max; - list->lpl = talloc_array (list, uint32_t, max); - for (count = 0; count < max; count++) - { - number = [self objectAtIndex: count]; - list->lpl[count] = [number longValue]; - } - - return list; -} - -+ (id) arrayFromMVUI8: (const struct UI8Array_r *) mvUI8 -{ - NSUInteger count; - NSNumber *subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvUI8->cValues]; - for (count = 0; count < mvUI8->cValues; count++) - { - subObject = [NSNumber numberWithLongLong: mvUI8->lpui8[count]]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -+ (id) arrayFromMVUnicode: (const struct StringArrayW_r *) mvUnicode -{ - NSUInteger count; - NSString *subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvUnicode->cValues]; - for (count = 0; count < mvUnicode->cValues; count++) - { - subObject = [NSString stringWithUTF8String: mvUnicode->lppszW[count]]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -- (struct StringArrayW_r *) asMVUnicodeInMemCtx: (void *) memCtx -{ - struct StringArrayW_r *list; - NSInteger count, max; - - max = [self count]; - - list = talloc_zero (memCtx, struct StringArrayW_r); - list->cValues = max; - list->lppszW = talloc_array (list, const char *, max); - - for (count = 0; count < max; count++) - list->lppszW[count] = [[self objectAtIndex: count] asUnicodeInMemCtx: list->lppszW]; - - return list; -} - -+ (id) arrayFromMVString: (const struct StringArray_r *) mvString -{ - NSUInteger count; - id subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvString->cValues]; - for (count = 0; count < mvString->cValues; count++) - { - subObject = [NSString stringWithUTF8String: (const char *) mvString->lppszA[count]]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -+ (id) arrayFromMVBinary: (const struct BinaryArray_r *) mvBinary -{ - NSUInteger count; - id subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvBinary->cValues]; - for (count = 0; count < mvBinary->cValues; count++) - { - subObject = [NSData dataWithBinary: mvBinary->lpbin + count]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -- (struct BinaryArray_r *) asMVBinaryInMemCtx: (void *) memCtx -{ - struct BinaryArray_r *list; - NSData *data; - NSInteger count, max; - - max = [self count]; - - list = talloc_zero (memCtx,struct BinaryArray_r); - list->cValues = max; - list->lpbin = talloc_array (list, struct Binary_r, max); - - for (count = 0; count < max; count++) - { - data = [self objectAtIndex: count]; - list->lpbin[count].cb = [data length]; - list->lpbin[count].lpb = talloc_memdup (list->lpbin, [data bytes], list->lpbin[count].cb); - } - - return list; -} - -+ (id) arrayFromMVGuid: (const struct FlatUIDArray_r *) mvGuid -{ - NSUInteger count; - id subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvGuid->cValues]; - for (count = 0; count < mvGuid->cValues; count++) - { - subObject = [NSData dataWithFlatUID: mvGuid->lpguid[count]]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -+ (id) arrayFromMVFileTime: (const struct DateTimeArray_r *) mvFileTime -{ - NSUInteger count; - id subObject; - NSMutableArray *mvResult; - - mvResult = [NSMutableArray arrayWithCapacity: mvFileTime->cValues]; - for (count = 0; count < mvFileTime->cValues; count++) - { - subObject = [NSDate dateFromFileTime: mvFileTime->lpft + count]; - [mvResult addObject: subObject]; - } - - return mvResult; -} - -@end diff --git a/OpenChange/NSData+MAPIStore.h b/OpenChange/NSData+MAPIStore.h deleted file mode 100644 index 13daa8aef..000000000 --- a/OpenChange/NSData+MAPIStore.h +++ /dev/null @@ -1,62 +0,0 @@ -/* NSData+MAPIStore.h - this file is part of SOGo - * - * Copyright (C) 2010 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef NSDATA_MAPISTORE_H -#define NSDATA_MAPISTORE_H - -#import - -@interface NSData (MAPIStoreDataTypes) - -+ (id) dataWithBinary: (const struct Binary_r *) binData; -- (struct Binary_r *) asBinaryInMemCtx: (void *) memCtx; - -+ (id) dataWithShortBinary: (const struct SBinary_short *) binData; -- (struct SBinary_short *) asShortBinaryInMemCtx: (void *) memCtx; - -+ (id) dataWithFlatUID: (const struct FlatUID_r *) flatUID; -- (struct FlatUID_r *) asFlatUIDInMemCtx: (void *) memCtx; - -+ (id) dataWithGUID: (const struct GUID *) guid; -- (struct GUID *) asGUIDInMemCtx: (void *) memCtx; - -+ (id) dataWithXID: (const struct XID *) xid; -- (struct XID *) asXIDInMemCtx: (void *) memCtx; -- (struct SizedXid *) asSizedXidArrayInMemCtx: (void *) memCtx - with: (uint32_t *) length; - -+ (id) dataWithChangeKeyGUID: (NSString *) guidString - andCnt: (NSData *) globCnt; - -- (void) hexDumpWithLineSize: (NSUInteger) lineSize; - -@end - -@interface NSMutableData (MAPIStoreDataTypes) - -- (void) appendUInt8: (uint8_t) value; -- (void) appendUInt16: (uint16_t) value; -- (void) appendUInt32: (uint32_t) value; - -@end - -#endif /* NSDATA_MAPISTORE_H */ diff --git a/OpenChange/NSData+MAPIStore.m b/OpenChange/NSData+MAPIStore.m deleted file mode 100644 index 5a2afeb1d..000000000 --- a/OpenChange/NSData+MAPIStore.m +++ /dev/null @@ -1,291 +0,0 @@ -/* NSData+MAPIStore.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import "MAPIStoreTypes.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "NSData+MAPIStore.h" - -#undef DEBUG -#include -#include -#include -#include -#include - -@implementation NSData (MAPIStoreDataTypes) - -+ (id) dataWithBinary: (const struct Binary_r *) binData -{ - return [NSData dataWithBytes: binData->lpb length: binData->cb]; -} - -- (struct Binary_r *) asBinaryInMemCtx: (void *) memCtx -{ - struct Binary_r *binary; - - binary = talloc_zero (memCtx, struct Binary_r); - binary->cb = [self length]; - binary->lpb = (uint8_t *) [self bytes]; - [self tallocWrapper: binary]; - - return binary; -} - -+ (id) dataWithShortBinary: (const struct SBinary_short *) binData -{ - return [NSData dataWithBytes: binData->lpb length: binData->cb]; -} - -- (struct SBinary_short *) asShortBinaryInMemCtx: (void *) memCtx -{ - struct SBinary_short *binary; - - binary = talloc_zero (memCtx, struct SBinary_short); - binary->cb = [self length]; - binary->lpb = (uint8_t *) [self bytes]; - [self tallocWrapper: binary]; - - return binary; -} - -+ (id) dataWithFlatUID: (const struct FlatUID_r *) flatUID -{ - return [NSData dataWithBytes: flatUID->ab length: 16]; -} - -- (struct FlatUID_r *) asFlatUIDInMemCtx: (void *) memCtx -{ - struct FlatUID_r *flatUID; - - flatUID = talloc_zero (memCtx, struct FlatUID_r); - [self getBytes: flatUID->ab]; - - return flatUID; -} - -static void _fillFlatUIDWithGUID (struct FlatUID_r *flatUID, const struct GUID *guid) -{ - flatUID->ab[0] = (guid->time_low & 0xFF); - flatUID->ab[1] = ((guid->time_low >> 8) & 0xFF); - flatUID->ab[2] = ((guid->time_low >> 16) & 0xFF); - flatUID->ab[3] = ((guid->time_low >> 24) & 0xFF); - flatUID->ab[4] = (guid->time_mid & 0xFF); - flatUID->ab[5] = ((guid->time_mid >> 8) & 0xFF); - flatUID->ab[6] = (guid->time_hi_and_version & 0xFF); - flatUID->ab[7] = ((guid->time_hi_and_version >> 8) & 0xFF); - memcpy (flatUID->ab + 8, guid->clock_seq, sizeof (uint8_t) * 2); - memcpy (flatUID->ab + 10, guid->node, sizeof (uint8_t) * 6); -} - -+ (id) dataWithGUID: (const struct GUID *) guid -{ - struct FlatUID_r flatUID; - - _fillFlatUIDWithGUID (&flatUID, guid); - - return [self dataWithFlatUID: &flatUID]; -} - -- (void) _extractGUID: (struct GUID *) guid -{ - uint8_t *bytes; - - bytes = (uint8_t *) [self bytes]; - - guid->time_low = (bytes[3] << 24 | bytes[2] << 16 - | bytes[1] << 8 | bytes[0]); - guid->time_mid = (bytes[5] << 8 | bytes[4]); - guid->time_hi_and_version = (bytes[7] << 8 | bytes[6]); - memcpy (guid->clock_seq, bytes + 8, sizeof (uint8_t) * 2); - memcpy (guid->node, bytes + 10, sizeof (uint8_t) * 6); -} - -- (struct GUID *) asGUIDInMemCtx: (void *) memCtx -{ - struct GUID *guid; - - guid = talloc_zero (memCtx, struct GUID); - [self _extractGUID: guid]; - - return guid; -} - -+ (id) dataWithXID: (const struct XID *) xid -{ - NSMutableData *xidData; - struct FlatUID_r flatUID; - - _fillFlatUIDWithGUID (&flatUID, &xid->NameSpaceGuid); - - xidData = [NSMutableData dataWithCapacity: 16 + xid->LocalId.length]; - [xidData appendBytes: flatUID.ab length: 16]; - [xidData appendBytes: xid->LocalId.data length: xid->LocalId.length]; - - return xidData; -} - -- (struct XID *) asXIDInMemCtx: (void *) memCtx -{ - struct XID *xid; - uint8_t *bytes; - NSUInteger max; - - max = [self length]; - if (max > 16) - { - xid = talloc_zero (memCtx, struct XID); - - [self _extractGUID: &xid->NameSpaceGuid]; - - xid->LocalId.length = max - 16; - - bytes = (uint8_t *) [self bytes]; - xid->LocalId.data = talloc_memdup (xid, (bytes+16), xid->LocalId.length); - } - else - { - xid = NULL; - abort (); - } - - return xid; -} - -- (struct SizedXid *) asSizedXidArrayInMemCtx: (void *) memCtx - with: (uint32_t *) length -{ - struct Binary_r bin; - struct SizedXid *sizedXIDArray; - - bin.cb = [self length]; - bin.lpb = (uint8_t *)[self bytes]; - - sizedXIDArray = get_SizedXidArray(memCtx, &bin, length); - if (!sizedXIDArray) - { - NSLog (@"Impossible to parse SizedXID array"); - return NULL; - } - - return sizedXIDArray; -} - -- (NSComparisonResult) compare: (NSData *) otherGlobCnt -{ - uint64_t globCnt = 0, oGlobCnt = 0; - - if ([self length] > 0) - globCnt = *(uint64_t *) [self bytes]; - - if ([otherGlobCnt length] > 0) - oGlobCnt = *(uint64_t *) [otherGlobCnt bytes]; - - return MAPICNCompare (globCnt, oGlobCnt, NULL); -} - -+ (id) dataWithChangeKeyGUID: (NSString *) guidString - andCnt: (NSData *) globCnt; -{ - NSMutableData *changeKey; - struct GUID guid; - - changeKey = [NSMutableData dataWithCapacity: 16 + [globCnt length]]; - - [guidString extractGUID: &guid]; - [changeKey appendData: [NSData dataWithGUID: &guid]]; - [changeKey appendData: globCnt]; - - return changeKey; -} - -- (void) hexDumpWithLineSize: (NSUInteger) lineSize -{ - const char *bytes; - NSUInteger lineCount, count, max, charCount, charMax; - NSMutableString *line; - - bytes = [self bytes]; - max = [self length]; - - lineCount = 0; - for (count = 0; count < max; count++) - { - line = [NSMutableString stringWithFormat: @"%d: ", lineCount]; - if (lineSize) - { - if ((max - count) > lineSize) - charMax = lineSize; - else - charMax = max - count; - } - else - charMax = max; - for (charCount = 0; charCount < charMax; charCount++) - [line appendFormat: @" %.2x", *(bytes + count + charCount)]; - [self logWithFormat: @" %@", line]; - count += charMax; - lineCount++; - } -} - -@end - -@implementation NSMutableData (MAPIStoreDataTypes) - -- (void) appendUInt8: (uint8_t) value -{ - [self appendBytes: (char *) &value length: 1]; -} - -- (void) appendUInt16: (uint16_t) value -{ - NSUInteger count; - char bytes[2]; - - for (count = 0; count < 2; count++) - { - bytes[count] = value & 0xff; - value >>= 8; - } - - [self appendBytes: bytes length: 2]; -} - -- (void) appendUInt32: (uint32_t) value -{ - NSUInteger count; - char bytes[4]; - - for (count = 0; count < 4; count++) - { - bytes[count] = value & 0xff; - value >>= 8; - } - - [self appendBytes: bytes length: 4]; -} - -@end diff --git a/OpenChange/NSDate+MAPIStore.h b/OpenChange/NSDate+MAPIStore.h deleted file mode 100644 index d61df7b11..000000000 --- a/OpenChange/NSDate+MAPIStore.h +++ /dev/null @@ -1,46 +0,0 @@ -/* NSDate+MAPIStore.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef NSCALENDARDATE_MAPISTORE_H -#define NSCALENDARDATE_MAPISTORE_H - -#import - -@class NSCalendarDate; - -@interface NSDate (MAPIStoreDataTypes) - -+ (NSCalendarDate *) dateFromMinutesSince1601: (uint32_t) minutes; -- (uint32_t) asMinutesSince1601; - -+ (id) dateFromFileTime: (const struct FILETIME *) timeValue; -- (struct FILETIME *) asFileTimeInMemCtx: (void *) memCtx; - -- (BOOL) isNever; /* occurs on 4500-12-31 */ - -+ (NSCalendarDate *) dateFromSystemTime: (struct SYSTEMTIME) date - andRuleYear: (uint16_t) rYear; -@end - -NSComparisonResult NSDateCompare (id date1, id date2, void *); - -#endif /* NSCALENDARDATE+MAPISTORE_H */ diff --git a/OpenChange/NSDate+MAPIStore.m b/OpenChange/NSDate+MAPIStore.m deleted file mode 100644 index b8f09dcc6..000000000 --- a/OpenChange/NSDate+MAPIStore.m +++ /dev/null @@ -1,209 +0,0 @@ -/* NSDate+MAPIStore.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import - -#import "MAPIStoreTypes.h" -#import "NSDate+MAPIStore.h" - -#undef DEBUG -#include -#include -#include -#include - -static NSCalendarDate *refDate = nil; - -@interface NSDate (MAPIStorePossibleMethods) - -- (NSTimeZone *) timeZone; - -@end - -@implementation NSDate (MAPIStoreDataTypes) - -static void -_setupRefDate () -{ - refDate = [[NSCalendarDate alloc] - initWithYear: 1601 month: 1 day: 1 - hour: 0 minute: 0 second: 0 - timeZone: utcTZ]; -} - -+ (NSCalendarDate *) dateFromMinutesSince1601: (uint32_t) minutes -{ - NSCalendarDate *result; - - if (!refDate) - _setupRefDate (); - - result = [refDate dateByAddingYears: 0 months: 0 days: 0 hours: 0 - minutes: minutes seconds: 0]; - - return result; -} - -- (uint32_t) asMinutesSince1601 -{ - uint32_t minutes; - NSInteger offset; - - if (!refDate) - _setupRefDate (); - - if ([self respondsToSelector: @selector (timeZone)]) - offset = [[self timeZone] secondsFromGMT]; - else - offset = 0; - minutes = (uint32_t) (([self timeIntervalSinceDate: refDate] + offset) / 60); - - return minutes; -} - -+ (id) dateFromFileTime: (const struct FILETIME *) timeValue -{ - NSCalendarDate *result; - uint64_t interval; - - if (!refDate) - _setupRefDate (); - - interval = ((uint64_t) timeValue->dwHighDateTime << 32 - | timeValue->dwLowDateTime); - result = [[NSCalendarDate alloc] - initWithTimeInterval: (NSTimeInterval) interval / 10000000 - sinceDate: refDate]; - [result autorelease]; - - return result; -} - -- (struct FILETIME *) asFileTimeInMemCtx: (void *) memCtx -{ - struct FILETIME *timeValue; - uint64_t interval; - - if (!refDate) - _setupRefDate (); - - interval = (((uint64_t) [self timeIntervalSinceDate: refDate]) * 10000000); - timeValue = talloc_zero (memCtx, struct FILETIME); - timeValue->dwLowDateTime = (uint32_t) (interval & 0xffffffff); - timeValue->dwHighDateTime = (uint32_t) ((interval >> 32) & 0xffffffff); - - return timeValue; -} - -- (BOOL) isNever /* occurs on 4500-12-31 */ -{ - NSCalendarDate *calDate; - - if ([self isKindOfClass: [NSCalendarDate class]]) - calDate = (NSCalendarDate *) self; - else - calDate = [NSCalendarDate dateWithTimeIntervalSince1970: - [self timeIntervalSince1970]]; - - return [calDate yearOfCommonEra] == 4500; -} - -+ (NSCalendarDate *) dateFromSystemTime: (struct SYSTEMTIME) date - andRuleYear: (uint16_t) rYear -{ - NSCalendarDate *result; - NSInteger daysToDate; - NSUInteger firstDayOfWeek, year; - - /* ([MS-OXOCAL] 2.2.1.41.1) When we're provided an absolute date (i.e., it - happens once), the SYSTEMTIME structure is enough to fill the date. - When we're parsing a SYSTEMTIME field from a time zone rule, however, a - relative date can be provided for the peroidicity of its periods. In this - scenario, the wYear field is empty and we have to use the wYear field in - the parent rule */ - if (date.wYear != 0) - year = date.wYear; - else - year = rYear; - - /* The wDay field indicates the occurrence of the wDayOfWeek within the month. - The 5th occurrence means the last one, even if it is the 4th. */ - if (date.wDay < 5) - { - result = [[NSCalendarDate alloc] initWithYear: year month: date.wMonth day: 1 - hour: date.wHour minute: date.wMinute second: date.wSecond - timeZone: utcTZ]; - [result autorelease]; - - firstDayOfWeek = [result dayOfWeek]; - - daysToDate = 7 * (date.wDay - 1) + date.wDayOfWeek - firstDayOfWeek; - if (date.wDayOfWeek < firstDayOfWeek) - daysToDate += 7; - - result = [result dateByAddingYears: 0 months: 0 days: daysToDate - hours: 0 minutes: 0 - seconds: 0]; - } - else - { - result = [[NSCalendarDate alloc] initWithYear: year month: date.wMonth + 1 day: 1 - hour: date.wHour minute: date.wMinute second: date.wSecond - timeZone: utcTZ]; - [result autorelease]; - - firstDayOfWeek = [result dayOfWeek]; - - daysToDate = date.wDayOfWeek - firstDayOfWeek; - if (date.wDayOfWeek >= firstDayOfWeek) - daysToDate -= 7; - - result = [result dateByAddingYears: 0 months: 0 days: daysToDate - hours: 0 minutes: 0 - seconds: 0]; - } - - return result; -} - -@end - -NSComparisonResult -NSDateCompare (id date1, id date2, void *ctx) -{ - NSTimeInterval secs1, secs2; - NSComparisonResult result; - - secs1 = [date1 timeIntervalSince1970]; - secs2 = [date2 timeIntervalSince1970]; - if (secs1 == secs2) - result = NSOrderedSame; - else if (secs1 < secs2) - result = NSOrderedAscending; - else - result = NSOrderedDescending; - - return result; -} - diff --git a/OpenChange/NSObject+MAPIStore.h b/OpenChange/NSObject+MAPIStore.h deleted file mode 100644 index 52c276c00..000000000 --- a/OpenChange/NSObject+MAPIStore.h +++ /dev/null @@ -1,76 +0,0 @@ -/* NSObject+MAPIStore.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 NSOBJECT_MAPISTORE_H -#define NSOBJECT_MAPISTORE_H - -#import - -#include -#include - -struct MAPIStoreTallocWrapper -{ - id instance; -}; - -@interface NSObject (MAPIStoreTallocHelpers) - -- (struct MAPIStoreTallocWrapper *) tallocWrapper: (TALLOC_CTX *) tallocCtx; - -@end - -@interface NSObject (MAPIStoreDataTypes) - -- (enum mapistore_error) getValue: (void **) data - forTag: (enum MAPITAGS) propTag - inMemCtx: (TALLOC_CTX *) memCtx; - -/* getter helpers */ -- (enum mapistore_error) getEmptyString: (void **) data inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getLongZero: (void **) data inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getYes: (void **) data inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getNo: (void **) data inMemCtx: (TALLOC_CTX *) memCtx; -- (enum mapistore_error) getSMTPAddrType: (void **) data inMemCtx: (TALLOC_CTX *) memCtx; - -@end - -@interface NSObject (MAPIStoreExtension) - -- (Class) mapistoreMessageClass; - -@end - -@interface NSObject (MAPIStoreProperties) - -+ (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP - inMemCtx: (TALLOC_CTX *) memCtx; -+ (void) fillAvailableProperties: (struct SPropTagArray *) properties - withExclusions: (BOOL *) exclusions; - -- (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP - inMemCtx: (TALLOC_CTX *) memCtx; -- (BOOL) canGetProperty: (enum MAPITAGS) propTag; - -@end - -#endif /* NSOBJECT_MAPISTORE_H */ diff --git a/OpenChange/NSObject+MAPIStore.m b/OpenChange/NSObject+MAPIStore.m deleted file mode 100644 index 9962806c4..000000000 --- a/OpenChange/NSObject+MAPIStore.m +++ /dev/null @@ -1,270 +0,0 @@ -/* NSObject+MAPIStore.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import - -#import "MAPIStorePropertySelectors.h" -#import "MAPIStoreTypes.h" -#import "NSArray+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSDate+MAPIStore.h" -#import "NSValue+MAPIStore.h" -#import "NSString+MAPIStore.h" - -#import "NSObject+MAPIStore.h" - -#undef DEBUG -#include -#include - -@implementation NSObject (MAPIStoreTallocHelpers) - -static int -MAPIStoreTallocWrapperDestroy (void *data) -{ - struct MAPIStoreTallocWrapper *wrapper; - NSAutoreleasePool *pool; - -// GSRegisterCurrentThread (); - pool = [NSAutoreleasePool new]; - wrapper = data; - //NSLog (@"destroying wrapped object (wrapper: %p; object: %p (%@))...\n", wrapper, wrapper->instance, NSStringFromClass([wrapper->instance class])); - [wrapper->instance release]; - [pool release]; -// GSUnregisterCurrentThread (); - - return 0; -} - -- (struct MAPIStoreTallocWrapper *) tallocWrapper: (TALLOC_CTX *) tallocCtx -{ - struct MAPIStoreTallocWrapper *wrapper; - - wrapper = talloc_zero (tallocCtx, struct MAPIStoreTallocWrapper); - talloc_set_destructor ((void *) wrapper, MAPIStoreTallocWrapperDestroy); - wrapper->instance = self; - [self retain]; - //NSLog (@"returning wrapper: %p; object: %p (%@)", wrapper, self, NSStringFromClass([self class])); - return wrapper; -} - -@end - -@implementation NSObject (MAPIStoreDataTypes) - -- (enum mapistore_error) getValue: (void **) data - forTag: (enum MAPITAGS) propTag - inMemCtx: (TALLOC_CTX *) memCtx -{ - uint16_t valueType; - enum mapistore_error rc = MAPISTORE_SUCCESS; - - // [self logWithFormat: @"property %.8x found", propTag]; - valueType = (propTag & 0xffff); - switch (valueType) - { - case PT_NULL: - *data = NULL; - break; - case PT_SHORT: - *data = [(NSNumber *) self asShortInMemCtx: memCtx]; - break; - case PT_LONG: - *data = [(NSNumber *) self asLongInMemCtx: memCtx]; - break; - case PT_I8: - *data = [(NSNumber *) self asI8InMemCtx: memCtx]; - break; - case PT_BOOLEAN: - *data = [(NSNumber *) self asBooleanInMemCtx: memCtx]; - break; - case PT_DOUBLE: - *data = [(NSNumber *) self asDoubleInMemCtx: memCtx]; - break; - case PT_UNICODE: - case PT_STRING8: - *data = [(NSString *) self asUnicodeInMemCtx: memCtx]; - break; - case PT_SYSTIME: - *data = [(NSCalendarDate * ) self asFileTimeInMemCtx: memCtx]; - break; - case PT_BINARY: - case PT_SVREID: - *data = [(NSData *) self asBinaryInMemCtx: memCtx]; - break; - case PT_CLSID: - *data = [(NSData *) self asGUIDInMemCtx: memCtx]; - break; - case PT_MV_LONG: - *data = [(NSArray *) self asMVLongInMemCtx: memCtx]; - break; - case PT_MV_UNICODE: - *data = [(NSArray *) self asMVUnicodeInMemCtx: memCtx]; - break; - case PT_MV_BINARY: - *data = [(NSArray *) self asMVBinaryInMemCtx: memCtx]; - break; - - default: - [self errorWithFormat: @"object type not handled: %d (0x%.4x)", - valueType, valueType]; - abort(); - *data = NULL; - rc = MAPISTORE_ERR_NOT_FOUND; - } - - return rc; -} - -/* helper getters */ -- (enum mapistore_error) getEmptyString: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getLongZero: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPILongValue (memCtx, 0); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getYes: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPIBoolValue (memCtx, YES); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getNo: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = MAPIBoolValue (memCtx, NO); - - return MAPISTORE_SUCCESS; -} - -- (enum mapistore_error) getSMTPAddrType: (void **) data inMemCtx: (TALLOC_CTX *) memCtx -{ - *data = [@"SMTP" asUnicodeInMemCtx: memCtx]; - - return MAPISTORE_SUCCESS; -} - -@end - -@implementation NSObject (MAPIStoreProperties) - -+ (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct SPropTagArray *properties; - const MAPIStorePropertyGetter *classGetters; - NSUInteger count; - enum MAPITAGS propTag; - uint16_t propId; - - properties = talloc_zero (memCtx, struct SPropTagArray); - properties->aulPropTag = talloc_array (properties, enum MAPITAGS, - MAPIStoreSupportedPropertiesCount); - classGetters = MAPIStorePropertyGettersForClass (self); - for (count = 0; count < MAPIStoreSupportedPropertiesCount; count++) - { - propTag = MAPIStoreSupportedProperties[count]; - propId = (propTag >> 16) & 0xffff; - if (classGetters[propId]) - { - properties->aulPropTag[properties->cValues] = propTag; - properties->cValues++; - } - } - - *propertiesP = properties; - - return MAPISTORE_SUCCESS; -} - -+ (void) fillAvailableProperties: (struct SPropTagArray *) properties - withExclusions: (BOOL *) exclusions -{ - TALLOC_CTX *localMemCtx; - struct SPropTagArray *subProperties; - uint16_t propId; - NSUInteger count; - - localMemCtx = talloc_zero (NULL, TALLOC_CTX); - [self getAvailableProperties: &subProperties inMemCtx: localMemCtx]; - for (count = 0; count < subProperties->cValues; count++) - { - propId = (subProperties->aulPropTag[count] >> 16) & 0xffff; - if (!exclusions[propId]) - { - properties->aulPropTag[properties->cValues] - = subProperties->aulPropTag[count]; - properties->cValues++; - exclusions[propId] = YES; - } - } - talloc_free (localMemCtx); -} - -- (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP - inMemCtx: (TALLOC_CTX *) memCtx -{ - NSUInteger count; - struct SPropTagArray *availableProps; - enum MAPITAGS propTag; - - availableProps = talloc_zero (memCtx, struct SPropTagArray); - availableProps->aulPropTag = talloc_array (availableProps, enum MAPITAGS, - MAPIStoreSupportedPropertiesCount); - for (count = 0; count < MAPIStoreSupportedPropertiesCount; count++) - { - propTag = MAPIStoreSupportedProperties[count]; - if ([self canGetProperty: propTag]) - { - availableProps->aulPropTag[availableProps->cValues] = propTag; - availableProps->cValues++; - } - } - - *propertiesP = availableProps; - - return MAPISTORE_SUCCESS; -} - -- (BOOL) canGetProperty: (enum MAPITAGS) propTag -{ - uint16_t propId; - const IMP *classGetters; - - classGetters = (IMP *) MAPIStorePropertyGettersForClass (isa); - propId = (propTag >> 16) & 0xffff; - - return (classGetters[propId] != NULL); -} - -@end diff --git a/OpenChange/NSObject+PropertyList.h b/OpenChange/NSObject+PropertyList.h deleted file mode 100644 index 34ea28ea8..000000000 --- a/OpenChange/NSObject+PropertyList.h +++ /dev/null @@ -1,64 +0,0 @@ -/* dbmsgdump.m - this file is part of SOGo - * - * Copyright (C) 2014 Kamen Mazdrashki - * - * Based on implementation done by Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * A format-agnostic dump extensions for: - * NSArray - * NSObject - * NSDictionary - */ - -#ifndef NSOBJECT_PROPERTYLIST_H -#define NSOBJECT_PROPERTYLIST_H - -#import -#import -#import - - -@interface NSObject (plext) - -- (void) displayWithIndentation: (NSInteger) anInt; - -@end - - -@interface NSDictionary (plext) - -- (void) displayKey: (NSString *) key - withIndentation: (NSInteger) anInt; - -- (void) displayWithIndentation: (NSInteger) anInt; - -@end - - -@interface NSArray (plext) - -- (void) displayCount: (NSUInteger) count - withIndentation: (NSInteger) anInt; - -- (void) displayWithIndentation: (NSInteger) anInt; - -@end - -#endif /* NSOBJECT_PROPERTYLIST_H */ diff --git a/OpenChange/NSObject+PropertyList.m b/OpenChange/NSObject+PropertyList.m deleted file mode 100644 index 164ac5054..000000000 --- a/OpenChange/NSObject+PropertyList.m +++ /dev/null @@ -1,137 +0,0 @@ -/* dbmsgdump.m - this file is part of SOGo - * - * Copyright (C) 2011-2014 Inverse inc - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* A format-agnostic property list dumper. - Usage: dbmsgdump [filename] */ - -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import -#import "NSObject+PropertyList.h" - -const char *indentationStep = " "; - - -@implementation NSObject (plext) - -- (void) _outputIndentation: (NSInteger) anInt -{ - NSInteger i; - - for (i = 0; i < anInt; i++) - printf ("%s", indentationStep); -} - -- (void) displayWithIndentation: (NSInteger) anInt -{ - printf ("(%s) %s", - [NSStringFromClass (isa) UTF8String], - [[self description] UTF8String]); -} - -@end - -@implementation NSDictionary (plext) - -- (void) displayKey: (NSString *) key - withIndentation: (NSInteger) anInt -{ - [self _outputIndentation: anInt]; - - printf ("%s ", [[key description] UTF8String]); - if ([key isKindOfClass: [NSValue class]]) - printf ("(%s: 0x%.8x) ", [(NSValue *) key objCType], [key intValue]); - - printf ("= "); -} - -- (void) displayWithIndentation: (NSInteger) anInt -{ - NSUInteger i, max; - NSArray *keys; - NSInteger subIndent; - NSString *key; - - keys = [self allKeys]; - max = [keys count]; - - printf ("{ (%ld) items\n", (long) max); - - subIndent = anInt + 1; - - for (i = 0; i < max; i++) - { - key = [keys objectAtIndex: i]; - [self displayKey: key withIndentation: subIndent]; - [[self objectForKey: key] displayWithIndentation: subIndent]; - if (i < (max - 1)) - printf (","); - printf ("\n"); - } - - [self _outputIndentation: anInt]; - printf ("}"); -} - -@end - -@implementation NSArray (plext) - -- (void) displayCount: (NSUInteger) count - withIndentation: (NSInteger) anInt -{ - [self _outputIndentation: anInt]; - printf ("%lu = ", (unsigned long) count); -} - -- (void) displayWithIndentation: (NSInteger) anInt -{ - NSUInteger i, max; - NSInteger subIndent; - - max = [self count]; - - printf ("[ (%ld) items\n", (long) max); - - subIndent = anInt + 1; - - for (i = 0; i < max; i++) - { - [self displayCount: i withIndentation: subIndent]; - [[self objectAtIndex: i] displayWithIndentation: subIndent]; - if (i < (max - 1)) - printf (","); - printf ("\n"); - } - - [self _outputIndentation: anInt]; - printf ("]"); -} - -@end - diff --git a/OpenChange/NSString+MAPIStore.h b/OpenChange/NSString+MAPIStore.h deleted file mode 100644 index e5006c2ae..000000000 --- a/OpenChange/NSString+MAPIStore.h +++ /dev/null @@ -1,41 +0,0 @@ -/* NSString+MAPIStore.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef NSSTRING_MAPISTORE_H -#define NSSTRING_MAPISTORE_H - -#import - -@interface NSString (MAPIStoreDataTypes) - -+ (id) stringWithGUID: (const struct GUID *) guid; -- (void) extractGUID: (struct GUID *) guid; - -- (char *) asUnicodeInMemCtx: (void *) memCtx; - -- (NSData *) convertHexStringToBytes; - -- (NSString *) stringByReplacingPercentEscapesUsingEncoding: (NSStringEncoding) encoding; - -@end - -#endif /* NSSTRING+MAPISTORE_H */ diff --git a/OpenChange/NSString+MAPIStore.m b/OpenChange/NSString+MAPIStore.m deleted file mode 100644 index 83ca8d6e6..000000000 --- a/OpenChange/NSString+MAPIStore.m +++ /dev/null @@ -1,201 +0,0 @@ -/* NSString+MAPIStore.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -#include -#include - -#import - -#import "NSString+MAPIStore.h" - -#undef DEBUG -#include -#include -#include - -@implementation NSString (MAPIStoreDataTypes) - -+ (id) stringWithGUID: (const struct GUID *) guid -{ - char *guidString; - NSString *newString; - - guidString = GUID_string (NULL, guid); - newString = [self stringWithUTF8String: guidString]; - talloc_free (guidString); - - return newString; -} - -- (void) extractGUID: (struct GUID *) guid -{ - GUID_from_string ([self UTF8String], guid); -} - -- (char *) asUnicodeInMemCtx: (void *) memCtx -{ - char *unicode; - NSData *encoded; - - if ([self length] > 0) - { - encoded = [self dataUsingEncoding: NSUTF8StringEncoding]; - unicode = talloc_strndup (memCtx, [encoded bytes], [encoded length]); - } - else - unicode = talloc_memdup (memCtx, "", 1); - - return unicode; -} - -- (char) _decodeHexByte: (char) byteChar -{ - char newByte; - - if (byteChar >= 48 && byteChar <= 57) - newByte = (uint8_t) byteChar - 48; - else if (byteChar >= 65 && byteChar <= 70) - newByte = (uint8_t) byteChar - 55; - else if (byteChar >= 97 && byteChar <= 102) - newByte = (uint8_t) byteChar - 87; - else - newByte = -1; - - return newByte; -} - -- (BOOL) _decodeHexByte: (uint8_t *) byte - atPos: (NSUInteger) pos -{ - BOOL error = NO; - char newByte; - unichar byteChar; - - byteChar = [self characterAtIndex: pos]; - if (byteChar < 256) - { - newByte = [self _decodeHexByte: (char) byteChar]; - if (newByte == -1) - error = YES; - else - *byte = newByte; - } - else - error = YES; - - return error; -} - -- (BOOL) _decodeHexPair: (uint8_t *) byte - atPos: (NSUInteger) pos -{ - BOOL error; - uint8_t lowValue, highValue; - - error = [self _decodeHexByte: &highValue atPos: pos]; - if (!error) - { - error = [self _decodeHexByte: &lowValue atPos: pos + 1]; - if (!error) - *byte = highValue << 4 | lowValue; - } - - return error; -} - -- (NSData *) convertHexStringToBytes -{ - NSUInteger count, strLen, bytesLen; - uint8_t *bytes, *currentByte; - NSData *decoded = nil; - BOOL error = NO; - - strLen = [self length]; - if ((strLen % 2) == 0) - { - bytesLen = strLen / 2; - bytes = NSZoneCalloc (NULL, bytesLen, sizeof (uint8_t)); - currentByte = bytes; - for (count = 0; !error && count < strLen; count += 2) - { - error = [self _decodeHexPair: currentByte atPos: count]; - currentByte++; - } - if (error) - NSZoneFree (NULL, bytes); - else - decoded = [NSData dataWithBytesNoCopy: bytes - length: bytesLen - freeWhenDone: YES]; - } - - return decoded; -} - -- (NSString *) stringByReplacingPercentEscapesUsingEncoding: (NSStringEncoding) encoding -{ - NSString *newString; - NSData *data; - NSUInteger count, length, newCount; - const char *bytes; - char *newBytes; - char newByte0, newByte1; - - data = [self dataUsingEncoding: NSASCIIStringEncoding]; - if (data) - { - length = [data length]; - bytes = [data bytes]; - newBytes = NSZoneMalloc (NULL, sizeof (char) * length); - newCount = 0; - for (count = 0; count < length; count++) - { - if (bytes[count] == '%') - { - newByte0 = [self _decodeHexByte: bytes[count+1]]; - newByte1 = [self _decodeHexByte: bytes[count+2]]; - if ((newByte0 != -1) && (newByte1 != -1)) - { - newBytes[newCount] = (((newByte0 << 4) & 0xf0) - | (newByte1 & 0x0f)); - count += 2; - } - else - newBytes[newCount] = bytes[count]; - } - else - newBytes[newCount] = bytes[count]; - newCount++; - } - - data = [NSData dataWithBytesNoCopy: newBytes length: newCount freeWhenDone: YES]; - newString = [[NSString alloc] - initWithData: data encoding: encoding]; - [newString autorelease]; - } - else - newString = nil; - - return newString; -} - -@end diff --git a/OpenChange/NSValue+MAPIStore.h b/OpenChange/NSValue+MAPIStore.h deleted file mode 100644 index da0b2aa41..000000000 --- a/OpenChange/NSValue+MAPIStore.h +++ /dev/null @@ -1,38 +0,0 @@ -/* NSValue+MAPIStore.h - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef NSVALUE_MAPISTORE_H -#define NSVALUE_MAPISTORE_H - -#import - -@interface NSNumber (MAPIStoreDataTypes) - -- (uint8_t *) asBooleanInMemCtx: (void *) memCtx; -- (uint16_t *) asShortInMemCtx: (void *) memCtx; -- (uint32_t *) asLongInMemCtx: (void *) memCtx; -- (uint64_t *) asI8InMemCtx: (void *) memCtx; -- (double *) asDoubleInMemCtx: (void *) memCtx; - -@end - -#endif /* NSVALUE_MAPISTORE_H */ diff --git a/OpenChange/NSValue+MAPIStore.m b/OpenChange/NSValue+MAPIStore.m deleted file mode 100644 index a3301ce00..000000000 --- a/OpenChange/NSValue+MAPIStore.m +++ /dev/null @@ -1,79 +0,0 @@ -/* NSValue+MAPIStore.m - this file is part of SOGo - * - * Copyright (C) 2010-2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -#include - -#import "NSValue+MAPIStore.h" - -@implementation NSNumber (MAPIStoreDataTypes) - -- (uint8_t *) asBooleanInMemCtx: (void *) memCtx -{ - uint8_t *value; - - value = talloc (memCtx, uint8_t); - *value = ([self boolValue] ? 1 : 0); - - return value; -} - -- (uint16_t *) asShortInMemCtx: (void *) memCtx -{ - uint16_t *value; - - value = talloc (memCtx, uint16_t); - *value = [self shortValue]; - - return value; -} - -- (uint32_t *) asLongInMemCtx: (void *) memCtx -{ - uint32_t *value; - - value = talloc (memCtx, uint32_t); - *value = [self longValue]; - - return value; -} - -- (uint64_t *) asI8InMemCtx: (void *) memCtx -{ - uint64_t *value; - - value = talloc (memCtx, uint64_t); - *value = [self unsignedLongLongValue]; - - return value; -} - -- (double *) asDoubleInMemCtx: (void *) memCtx -{ - double *value; - - value = talloc (memCtx, double); - *value = [self doubleValue]; - - return value; -} - -@end diff --git a/OpenChange/RTFHandler.h b/OpenChange/RTFHandler.h deleted file mode 100644 index ec776a8d3..000000000 --- a/OpenChange/RTFHandler.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - Copyright (C) 2005-2012 Inverse inc. - - This file is part of SOGo. - - SOGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - SOGo 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#include -#include -#include -#include -#include - -// -// -// -@class RTFFontTable; - -@interface RTFHandler : NSObject -{ - NSMapTable *_charsets; - NSMutableData *_html; - NSData *_data; - - const char *_bytes; - int _current_pos; - int _len; -} - -- (id) initWithData: (NSData *) theData; -- (NSMutableData *) parse; - -- (RTFFontTable *) parseFontTable; -- (void) mangleInternalStateWithBytesPtr: (const char*) newBytes - andCurrentPos: (int) newCurrentPos; - -@end - -// -// -// -@interface RTFStack: NSObject -{ - NSMutableArray *a; -} -- (void) push: (id) theObject; -- (id) pop; -@end - -// -// -// -@interface RTFFormattingOptions : NSObject -{ -@public - BOOL bold; - BOOL italic; - BOOL underline; - BOOL strikethrough; - int font_index; - int color_index; - int start_pos; - const unsigned short *charset; -} -@end - -// -// -// -@interface RTFFontInfo : NSObject -{ -@public - NSString *family; - unsigned char charset; - NSString *name; - unsigned int pitch; - unsigned int index; -} - -- (NSString *) description; -@end - -// -// \fX - font, index in font table -// -@interface RTFFontTable : NSObject -{ - @public - NSMapTable *fontInfos; -} - -- (void) addFontInfo: (RTFFontInfo *) theFontInfo - atIndex: (unsigned int ) theIndex; -- (RTFFontInfo *) fontInfoAtIndex: (unsigned int ) theIndex; -- (NSString *) description; - -@end - -// -// -// -@interface RTFColorDef : NSObject -{ -@public - unsigned char red; - unsigned char green; - unsigned char blue; -} - -@end - -// -// {\colortbl\red0\green0\blue0;\red128\green0\blue0;\red255\green0\blue0;} -// -// \cfX - color/foreground - index -// \cbX - color/background - index -// -// -@interface RTFColorTable : NSObject -{ - @public - NSMutableArray *colorDefs; -} - -- (void) addColorDef: (RTFColorDef *) theColorDef; - -@end diff --git a/OpenChange/RTFHandler.m b/OpenChange/RTFHandler.m deleted file mode 100644 index c89f4c677..000000000 --- a/OpenChange/RTFHandler.m +++ /dev/null @@ -1,1481 +0,0 @@ -/* - Copyright (C) 2005-2013 Inverse inc. - - This file is part of SOGo. - - SOGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - SOGo 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#include "RTFHandler.h" -#include -#include - -// -// Useful macros -// -#define ADVANCE self->_bytes++; self->_current_pos++; -#define ADVANCE_N(N) self->_bytes += (N); self->_current_pos += (N); -#define REWIND self->_bytes--; self->_current_pos--; - -#define DEFAULT_CHARSET 1 -#define FONTNAME_LEN_MAX 100 - -// -// Charset definitions. See http://msdn.microsoft.com/en-us/goglobal/bb964654 for all details. -// -const unsigned short ansicpg1250[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - 0x20ac, 0x0000, 0x201a, 0x0000, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179, - 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a, - 0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, - 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c, - 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, - 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, - 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, - 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 }; - -const unsigned short ansicpg1251[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, - 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, - 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, - 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, - 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, - 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, - 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, - 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f }; - -const unsigned short ansicpg1252[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000, - 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178, - 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, - 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, - 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, - 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, - 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, - 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff }; - -const unsigned short ansicpg1253[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000, 0x203a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x00a0, 0x0385, 0x0386, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x0000, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x2015, - 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x00b5, 0x00b6, 0x00b7, 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, - 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, - 0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, - 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, - 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000 }; - -const unsigned short ansicpg1254[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x0000, 0x0178, - 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, - 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, - 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, - 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, - 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, - 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff }; - -const unsigned short ansicpg1255[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0000, 0x203a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20aa, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, - 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, - 0x05b0, 0x05b1, 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, 0x05b8, 0x05b9, 0x0000, 0x05bb, 0x05bc, 0x05bd, 0x05be, 0x05bf, - 0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05f0, 0x05f1, 0x05f2, 0x05f3, 0x05f4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, - 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000 }; - -const unsigned short ansicpg1256[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - 0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, - 0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba, - 0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, - 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f, - 0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, - 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643, - 0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef, - 0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2 }; - -const unsigned short ansicpg1257[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - 0x20ac, 0x0000, 0x201a, 0x0000, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00a8, 0x02c7, 0x00b8, - 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000, 0x203a, 0x0000, 0x00af, 0x02db, 0x0000, - 0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x0000, 0x00a6, 0x00a7, 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, - 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, - 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, - 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, - 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, - 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x02d9 }; - -const unsigned short ansicpg1258[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0000, 0x203a, 0x0153, 0x0000, 0x0000, 0x0178, - 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, - 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, - 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0300, 0x00cd, 0x00ce, 0x00cf, - 0x0110, 0x00d1, 0x0309, 0x00d3, 0x00d4, 0x01a0, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x01af, 0x0303, 0x00df, - 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0301, 0x00ed, 0x00ee, 0x00ef, - 0x0111, 0x00f1, 0x0323, 0x00f3, 0x00f4, 0x01a1, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x01b0, 0x20ab, 0x00ff }; - -const unsigned short ansicpg874[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - 0x20ac, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, - 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, - 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, - 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f, - 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f, - 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000 }; - -// -// -// -@implementation RTFStack - -- (id) init -{ - if ((self = [super init])) - { - a = [[NSMutableArray alloc] init]; - } - return self; -} - -- (void) dealloc -{ - [a release]; - [super dealloc]; -} - -- (void) push: (id) theObject -{ - [a addObject: theObject]; -} - -- (id) pop -{ - id o = nil; - - if ([a count]) - { - o = [[[a lastObject] retain] autorelease]; - [a removeLastObject]; - } - - return o; -} - -- (id) top -{ - id o = nil; - - if ([a count]) - { - o = [[[a lastObject] retain] autorelease]; - } - - return o; -} - -@end - -// -// -// -@implementation RTFFormattingOptions -@end - -// -// -// -@implementation RTFFontInfo - -- (id) init -{ - if ((self = [super init])) - { - - } - - charset = DEFAULT_CHARSET; - return self; -} - -- (void) dealloc -{ - [family release]; - [name release]; - [super dealloc]; -} - -- (NSString *) description -{ - NSString *description; - description = [NSString stringWithFormat: - @"%u name=%@ family=%@ charset=%u pitch=%u", - index, name, family, charset, pitch - ]; - return description; -} - -@end - -// -// -// -@implementation RTFFontTable - -- (id) init -{ - if ((self = [super init])) - { - fontInfos = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 128); - } - return self; -} - -- (void) dealloc -{ - NSFreeMapTable(fontInfos); - [super dealloc]; -} - -- (void) addFontInfo: (RTFFontInfo *) theFontInfo - atIndex: (unsigned int) theIndex -{ - NSNumber *key; - - key = [NSNumber numberWithInt: theIndex]; - NSMapInsert(fontInfos, key, (void*) theFontInfo); -} - -- (RTFFontInfo *) fontInfoAtIndex: (unsigned int) theIndex -{ - NSNumber *key; - - key = [NSNumber numberWithInt: theIndex]; - return NSMapGet(fontInfos, key); -} - -- (NSString *) description -{ - NSMutableString *description; - NSEnumerator *enumerator; - RTFFontInfo *fontInfo; - - description = [NSMutableString stringWithFormat: @"Number of fonts: %u\n", [fontInfos count]]; - - enumerator = [fontInfos objectEnumerator]; - while ((fontInfo = [enumerator nextObject])) - { - [description appendString: [fontInfo description]]; - [description appendString: @"\n"]; - } - - return description; -} - -@end - -// -// -// -@implementation RTFColorDef - -@end - -// -// -// -@implementation RTFColorTable - -- (id) init -{ - if ((self = [super init])) - { - colorDefs = [[NSMutableArray alloc] init]; - } - return self; -} - -- (void) dealloc -{ - [colorDefs release]; - [super dealloc]; -} - -- (void) addColorDef: (RTFColorDef *) theColorDef -{ - [colorDefs addObject: theColorDef]; -} - -- (RTFColorDef *) colorDefAtIndex: (unsigned int) theIndex -{ - return [colorDefs objectAtIndex: theIndex]; -} - -@end - -// -// -// -@implementation RTFHandler - -static NSMapTable *_charsets = nil; -static NSMapTable *_cws = nil; -typedef enum { - CW_UNKNOWN = 0, - CW_ANSICPG, - CW_B, - CW_CF, - CW_COLORTBL, - CW_F, - CW_FONTTBL, - CW_I, - CW_PAR, - CW_PICT, - CW_SOFTLINE, - CW_STRIKE, - CW_STYLESHEET, - CW_TAB, - CW_U, - CW_UL, - CW_ULNONE -} commandWordId; - -static NSMapTable *_fontCws = nil; -typedef enum { - FONTCW_UNKNOWN = 0, - FONTCW_F, - FONTCW_FBIDI, - FONTCW_FCHARSET, - FONTCW_FDECOR, - FONTCW_FMODERN, - FONTCW_FNIL, - FONTCW_FPRQ, - FONTCW_FROMAN, - FONTCW_FSCRIPT, - FONTCW_FSWISS, - FONTCW_FTECH -} fontCommandWordId; - -static void _init_charsets_table() -{ - _charsets = NSCreateMapTable(NSObjectMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 23); - // 238 — Eastern European - cpg1250 - NSMapInsert(_charsets, @"ansicpg1250", ansicpg1250); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 238], ansicpg1250); - // 204 — Russian - cpg1251 - NSMapInsert(_charsets, @"ansicpg1251", ansicpg1251); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 204], ansicpg1251); - // 0 - Latin 1 - cpg1252 - also know as ANSI - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 0], ansicpg1252); - NSMapInsert(_charsets, @"ansicpg1252", ansicpg1252); - // 161 - Greek cpg1253 - NSMapInsert(_charsets, @"ansicpg1253", ansicpg1253); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 161], ansicpg1253); - // 162 — Turkish - cpg1254 - NSMapInsert(_charsets, @"ansicpg1254", ansicpg1254); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 162], ansicpg1254); - // 177 — Hebrew Traditional - cpg1255 - // also 181 - Hebrew user - NSMapInsert(_charsets, @"ansicpg1255", ansicpg1255); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 177], ansicpg1255); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 181], ansicpg1255); - // 178 — Arabic - cpg1256 - // also 179 - Arabic traditional - // also 180 - Arabic User - NSMapInsert(_charsets, @"ansicpg1256", ansicpg1256); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 178], ansicpg1256); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 179], ansicpg1256); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 180], ansicpg1256); - // 186 — Baltic - pg 1257 - NSMapInsert(_charsets, @"ansicpg1257", ansicpg1257); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 186], ansicpg1257); - // 163 — Vietnamese - pg1259 - NSMapInsert(_charsets, @"ansicpg1258", ansicpg1258); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 163], ansicpg1258); - // 222 — Thai - cpg874 - NSMapInsert(_charsets, @"ansicpg874", ansicpg874); - NSMapInsert(_charsets, [NSNumber numberWithUnsignedChar: 222], ansicpg874); - - // TODO: check differences between traditional/user/no-qualified for Arabic and Hebrew - // TODO: missing codepage for the following codes: - // 2 — Symbol - // 3 — Invalid - // 77 — Mac - // 128 — Shift Jis - // 129 — Hangul - // 130 — Johab - // 134 — GB2312 - // 136 — Big5 - // 254 — PC 437 - // 255 — OEM -} - -static void _init_cws_table() -{ - _cws = NSCreateMapTable(NSObjectMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 16); - NSMapInsert(_cws, @"ansicpg", (void *) CW_ANSICPG); - NSMapInsert(_cws, @"b", (void *) CW_B); - NSMapInsert(_cws, @"cf", (void *) CW_CF); - NSMapInsert(_cws, @"colortbl", (void *) CW_COLORTBL); - NSMapInsert(_cws, @"f", (void *) CW_F); - NSMapInsert(_cws, @"fonttbl", (void *) CW_FONTTBL); - NSMapInsert(_cws, @"i", (void *) CW_I); - NSMapInsert(_cws, @"par", (void *) CW_PAR); - NSMapInsert(_cws, @"pict", (void *) CW_PICT); - NSMapInsert(_cws, @"softline", (void *) CW_SOFTLINE); - NSMapInsert(_cws, @"strike", (void *) CW_STRIKE); - NSMapInsert(_cws, @"stylesheet", (void *) CW_STYLESHEET); - NSMapInsert(_cws, @"tab", (void *) CW_TAB); - NSMapInsert(_cws, @"u", (void *) CW_U); - NSMapInsert(_cws, @"ul", (void *) CW_UL); - NSMapInsert(_cws, @"ulnone", (void *) CW_ULNONE); -} - -static void _init_fontCws_table() -{ - _fontCws = NSCreateMapTable(NSObjectMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 23); - NSMapInsert(_fontCws, @"f", (void *) FONTCW_F); - NSMapInsert(_fontCws, @"fbidi", (void *) FONTCW_FBIDI); - NSMapInsert(_fontCws, @"fcharset", (void *) FONTCW_FCHARSET); - NSMapInsert(_fontCws, @"fdecor", (void *) FONTCW_FDECOR); - NSMapInsert(_fontCws, @"fmodern", (void *) FONTCW_FMODERN); - NSMapInsert(_fontCws, @"fnil", (void *) FONTCW_FNIL); - NSMapInsert(_fontCws, @"fprq", (void *) FONTCW_FPRQ); - NSMapInsert(_fontCws, @"froman", (void *) FONTCW_FROMAN); - NSMapInsert(_fontCws, @"fscript", (void *) FONTCW_FSCRIPT); - NSMapInsert(_fontCws, @"fswiss", (void *) FONTCW_FSWISS); - NSMapInsert(_fontCws, @"ftech", (void *) FONTCW_FTECH); -} - -- (id) initWithData: (NSData *) theData -{ - if ((self = [super init])) - { - ASSIGN(_data, theData); - _bytes = (char *)[_data bytes]; - _len = [_data length]; - _current_pos = 0; - if (_charsets == nil) - _init_charsets_table(); - if (_cws == nil) - _init_cws_table(); - if (_fontCws == nil) - _init_fontCws_table(); - } - - return self; -} - -- (void) dealloc -{ - NSFreeMapTable(_charsets); - [_data release]; - [super dealloc]; -} - -/* - Returns pointer to the control word and in len pointer its length including numeric argument -*/ -- (const char *) parseControlWord: (unsigned int *) len -{ - const char *start, *end; - - start = ADVANCE; - - /* - A control word is defined by: - - \ - */ - while (isalpha(*_bytes)) - { - ADVANCE; - } - - /* - The can be one of the following: - - - A space. This serves only to delimit a control word and is - ignored in subsequent processing. - - - A numeric digit or an ASCII minus sign (-), which indicates - that a numeric parameter is associated with the control word. - Only this case requires to include it in the control word. - - - Any character other than a letter or a digit - */ - if (*_bytes == '-' || isdigit(*_bytes)) - { - ADVANCE; - while (isdigit(*_bytes)) // TODO: Allow up to 10 digits - { - ADVANCE; - } - } - /* In this case, the delimiting character terminates the control - word and is not part of the control word. */ - - end = _bytes; - *len = end-start-1; - - return start+1; -} - -- (const char *) parseControlWordAndSetLenIn: (unsigned int *) len - setHasIntArgumentIn: (BOOL *) hasArg - setIntArgumentIn: (int *) arg -{ - const char *start; - const char *end = NULL; - const char *startArg = NULL; - const char *endArg = NULL; - - ADVANCE; - start = _bytes; - - /* - A control word is defined by: - - \ - */ - while (isalpha(*_bytes)) - { - end = _bytes; - ADVANCE; - } - - if (end == NULL) - { - return NULL; - } - - /* - The can be one of the following: - - - A space. This serves only to delimit a control word and is - ignored in subsequent processing. - - - A numeric digit or an ASCII minus sign (-), which indicates - that a numeric parameter is associated with the control word. - Only this case requires to include it in the control word. - - - Any character other than a letter or a digit - */ - - if (*_bytes == '-' || isdigit(*_bytes)) - { - startArg = _bytes; - endArg = _bytes; - ADVANCE; - while (isdigit(*_bytes)) - { - endArg = _bytes; - ADVANCE; - } - } - - *hasArg = NO; - *arg = 0; - if (startArg) - { - NSString *s; - unsigned int argLength = endArg - startArg + 1; - // the next guard is to protect against a single '-' - if (argLength > 1 || (*startArg != '-')) - { - s = [[NSString alloc] initWithBytesNoCopy: (void *) startArg - length: argLength - encoding: NSASCIIStringEncoding - freeWhenDone: NO]; - [s autorelease]; - *hasArg = YES; - *arg = [s intValue]; // Warning: it does not detect conversion errors - } - } - - - /* In other cases, the delimiting character terminates the control - word and is not part of the control word. */ - *len = end - start + 1; - return start; -} - -// -// {\colortbl\red0\green0\blue0;\red128\green0\blue0;\red255\green0\blue0;} -// -- (RTFColorTable *) parseColorTable -{ - RTFColorTable *colorTable; - RTFColorDef *colorDef; - - colorTable = [[[RTFColorTable alloc] init] autorelease]; - colorDef = [[[RTFColorDef alloc] init] autorelease]; - - while (*_bytes != '}') - { - if (*_bytes == ';') - { - [colorTable addColorDef: colorDef]; - colorDef = [[[RTFColorDef alloc] init] autorelease]; - ADVANCE; - } - else if (*_bytes == '\\') - { - const char *cw; - unsigned int len; - NSString *s; - - cw = [self parseControlWord: &len]; - - // Skip our control word - //if (strncmp(start+1, "colortbl", len) == 0) - // continue; - - s = [[NSString alloc] initWithBytesNoCopy: (void *)cw - length: len - encoding: NSASCIIStringEncoding - freeWhenDone: NO]; - [s autorelease]; - - if ([s hasPrefix: @"red"]) - { - colorDef->red = [[s substringFromIndex: 3] intValue]; - } - else if ([s hasPrefix: @"green"]) - { - colorDef->green = [[s substringFromIndex: 4] intValue]; - } - else - { - colorDef->blue = [[s substringFromIndex: 4] intValue]; - } - } - else - { - ADVANCE; - } - - } - - return colorTable; -} - -// -// Possible formats: -// -// {\fonttbl\f0\fswiss Helvetica;} -// {\fonttbl{\f0\froman\fcharset0\fprq2 Arial;}{\f1\fswiss\fprq2\fcharset0 Arial;}} -// -// FIXME: Complex ones not handled right now: -// -// {\fonttbl{\f2\fnil\fcharset256\fprq2{\*\panose 00020703090202050204}Courier New;}{... -// {\fonttbl{\f31\fnil\fcharset0\fprq0 Times New Roman Monotype{\*\falt Times New Roman};}{... -// -// We receive the full string. -// -- (RTFFontTable *) parseFontTable -{ - RTFFontTable *fontTable; - RTFFontInfo *fontInfo; - - unsigned int level; - - fontTable = [[[RTFFontTable alloc] init] autorelease]; - fontInfo = nil; - level = 0; - - do - { - if (*_bytes == '{') - { - if (fontTable && level == 1) - { - fontInfo = [[[RTFFontInfo alloc] init] autorelease]; - } - ADVANCE; - level++; - } - else if (*_bytes == '}') - { - if (fontTable && level == 2) //&& ![NSAllMapTableValues(fontTable->fontInfos) containsObject: fontInfo]) - { - [fontTable addFontInfo: fontInfo atIndex: fontInfo->index]; - } - ADVANCE; - level--; - } - else if (*_bytes == '\\') - { - const char *cw; - unsigned int len; - BOOL hasArg; - int arg; - NSString *cwKey; - fontCommandWordId cwId; - - cw = [self parseControlWordAndSetLenIn: &len - setHasIntArgumentIn: &hasArg - setIntArgumentIn: &arg]; - if (level != 2) - continue; - else if (cw == NULL) - continue; - - cwKey= [[NSString alloc] initWithBytesNoCopy: (void *)cw - length: len - encoding: NSASCIIStringEncoding - freeWhenDone: NO]; - [cwKey autorelease]; - - cwId = (fontCommandWordId) NSMapGet(_fontCws, cwKey); - switch (cwId) - { - case FONTCW_F: - if (hasArg) - fontInfo->index = arg; - break; - case FONTCW_FBIDI: - fontInfo->family = @"bidi"; - break; - case FONTCW_FCHARSET: - if (hasArg) - fontInfo->charset = arg; - break; - case FONTCW_FDECOR: - fontInfo->family = @"decor"; - break; - case FONTCW_FMODERN: - fontInfo->family = @"modern"; - break; - case FONTCW_FNIL: - fontInfo->family = @"nil"; - break; - case FONTCW_FPRQ: - if (hasArg) - fontInfo->pitch = arg; - break; - case FONTCW_FROMAN: - fontInfo->family = @"roman"; - break; - case FONTCW_FSCRIPT: - fontInfo->family = @"script"; - break; - case FONTCW_FSWISS: - fontInfo->family = @"swiss"; - break; - case FONTCW_FTECH: - fontInfo->family = @"tech"; - break; - case FONTCW_UNKNOWN: - default: - // do nothing - break; - } - } - else // no char - { - if (level == 2 && isalnum(*_bytes)) - { - // we assume this is the fontname - unsigned int fontnameLen; - const char *delim = strpbrk(_bytes, ";{}\\"); - if (delim == NULL) - { - // no delimiter found, we skip to next characters - ADVANCE; - continue; - } - fontnameLen = delim - _bytes; - // only valid if the delimiter is a correct ';' - if (*delim == ';') - { - // there is no explicit limit length but we took 100 - // as protection - if (delim && fontnameLen <= FONTNAME_LEN_MAX) - { - fontInfo->name = [[NSString alloc] initWithBytesNoCopy: (char *) _bytes - length: fontnameLen - encoding: NSASCIIStringEncoding - freeWhenDone: NO]; - ADVANCE_N(fontnameLen); - } - } - else { - // advance just before the special character - ADVANCE_N(fontnameLen - 1); - } - } - ADVANCE; - } - - } while (level > 0); - - return fontTable; -} - -// -// -// -- (void) parseStyleSheet -{ - unsigned int count; - - count = 0; - - do - { - if (*_bytes == '{') - { - count++; - } - else if (*_bytes == '}') - { - count--; - } - ADVANCE; - - } while (count != 0); -} - -- (void) parseIgnoringEverything -{ - unsigned int count = 1; - // Ignore everything. But we cannot parse it blindly because it could have - // binary data with '}' and '{' bytes, so disasters can happen and they will - do - { - if (*_bytes == '\\') - { - unsigned int binary_size, len = 0, cw_len; - const char *cw = [self parseControlWord: &len]; - cw_len = strlen("bin"); - if (strncmp(cw, "bin", cw_len) == 0 && len > cw_len) - { - NSString *s; - s = [[NSString alloc] initWithBytesNoCopy: (void *) cw + cw_len - length: len - cw_len - encoding: NSASCIIStringEncoding - freeWhenDone: NO]; - [s autorelease]; - binary_size = [s intValue]; - ADVANCE_N(binary_size); - } - } - - if (*_bytes == '{') count++; - if (*_bytes == '}') count--; - ADVANCE; - } - while (count > 0); -} - -// -// -// -- (void) parsePicture -{ - [self parseIgnoringEverything]; -} - - -// todo: This keyword is only valid in the RTF header section right after the \ansi, \mac, \pc or \pca keyword. -inline static void parseAnsicpg (BOOL hasArg, int arg, const unsigned short **out_default_char) -{ - NSString *key; - const unsigned short *res; - - if (!hasArg) - return; - key = [NSString stringWithFormat: @"anscicpg%i", arg]; - res = NSMapGet(_charsets, key); - if (res) - *out_default_char = res; -} - -inline static void parseB(RTFHandler *self, BOOL hasArg, int arg, RTFFormattingOptions *formattingOptions) -{ - if (!formattingOptions) - return; - if (hasArg && arg == 0) - { - [self->_html appendBytes: "" length: 4]; - formattingOptions->bold = NO; - } - else - { - [self->_html appendBytes: "" length: 3]; - formattingOptions->bold = YES; - } -} - -inline static void parseCf(RTFHandler *self, BOOL hasArg, int arg, RTFFormattingOptions *formattingOptions, RTFColorTable *colorTable) -{ - RTFColorDef *colorDef; - char *v; - - if (!hasArg) - return; - if (!formattingOptions) - return; - - colorDef = [colorTable colorDefAtIndex: arg]; - if (!colorDef) - return; - - if (formattingOptions->color_index >= 0) - { - [self->_html appendBytes: "" length: 7]; - } - - formattingOptions->color_index = arg; - - v = calloc(23, sizeof(char)); - sprintf(v, "", colorDef->red, colorDef->green, colorDef->blue); - [self->_html appendBytes: v length: strlen(v)]; - free(v); -} - - -inline static void parseColorTableWrapper(RTFHandler *self, RTFColorTable **colorTable) -{ - *colorTable = [self parseColorTable]; -} - -inline static void parseF(RTFHandler *self, BOOL hasArg, int arg, RTFFormattingOptions *formattingOptions, RTFFontTable *fontTable) -{ - RTFFontInfo *fontInfo; - - if (!hasArg) - return; - if (!formattingOptions) - return; - - if (formattingOptions->font_index >= 0 && arg != formattingOptions->font_index) - { - [self->_html appendBytes: "" length: 7]; - } - - formattingOptions->font_index = arg; - - fontInfo = [fontTable fontInfoAtIndex: arg]; - char *v = NULL; - if (fontInfo && fontInfo->name) - { - if ([fontInfo->name length] < 128) - { - int tag_size = 15 + [fontInfo->name length]; - v = calloc(tag_size, sizeof(char)); - snprintf(v, tag_size, "", [fontInfo->name UTF8String]); - } - else - { - NSLog(@"RTFHandler: Font %u has %d chars length, parse error? " - "Ignored", arg, [fontInfo->name length]); - v = calloc(7, sizeof(char)); - sprintf(v, ""); - } - } - else - { - // RTF badformed? We don't know about that font (arg index not found). - // Anyhow, we still open the html tag because in the future - // we will close it (e.g. when new font is used). - v = calloc(7, sizeof(char)); - sprintf(v, ""); - } - - if (fontInfo && fontInfo->charset) - { - if (fontInfo->charset == DEFAULT_CHARSET) - /* charset 1 is default charset */ - formattingOptions->charset = NULL; - else { - NSNumber *key = [NSNumber numberWithUnsignedChar: fontInfo->charset]; - formattingOptions->charset = NSMapGet(_charsets, key); - } - } - - [self->_html appendBytes: v length: strlen(v)]; - free(v); -} - -inline static void parseFontTableWrapper(RTFHandler *self, const char * cw, RTFFontTable **fontTable) -{ - // We rewind our buffer so we start at the beginning of {\fonttbl... - self->_bytes = cw-2; - self->_current_pos -= 9; // Length: {\fonttbl - *fontTable = [self parseFontTable]; - - // We go back 1 byte in order to end our section properly ('}' character) - REWIND; -} - -inline static void parseI(RTFHandler *self, BOOL hasArg, int arg, RTFFormattingOptions *formattingOptions) -{ - if (!formattingOptions) - return; - if (hasArg && arg == 0) - { - [self->_html appendBytes: "" length: 4]; - formattingOptions->italic = NO; - } - else - { - [self->_html appendBytes: "" length: 3]; - formattingOptions->italic = YES; - } -} - -inline static void parsePar(RTFHandler *self) -{ - [self->_html appendBytes: "
" length: 4]; -} - -inline static void parsePictureWrapper(RTFHandler *self, const char * cw) -{ - self->_bytes = cw-2; - self->_current_pos -= 6; // Length: {\pict - [self parsePicture]; - REWIND; -} - -// same implementation that /par -inline static void parseSoftline(RTFHandler *self) -{ - [self->_html appendBytes: "
" length: 4]; -} - -inline static void parseStrike(RTFHandler *self, BOOL hasArg, int arg, RTFFormattingOptions *formattingOptions) -{ - if (!formattingOptions) - return; - if (hasArg && arg == 0) - { - [self->_html appendBytes: "" length: 9]; - formattingOptions->strikethrough = NO; - } - else - { - [self->_html appendBytes: "" length: 8]; - formattingOptions->strikethrough = YES; - } -} - -inline static void parseStyleSheetWrapper(RTFHandler *self, const char * cw) -{ - self->_bytes = cw-2; - self->_current_pos -= 12; // Length: {\stylesheet - [self parseStyleSheet]; - REWIND; -} - -inline static void parseTab(RTFHandler *self) -{ - [self->_html appendBytes: "  " length: 12]; -} - -inline static void parseU(RTFHandler *self, BOOL hasArg, int arg) -{ - unichar uch; - NSString *s; - NSData *d; - - if (!hasArg) - return; - if (arg < 0) - // a negative value means a value greater than 32767 - arg = 32767 - arg; - - uch = (unichar) arg; - s = [NSString stringWithCharacters: &uch length: 1]; - d = [s dataUsingEncoding: NSUTF8StringEncoding]; - [self->_html appendData: d]; -} - -inline static void parseUl(RTFHandler *self, BOOL hasArg, int arg, RTFFormattingOptions *formattingOptions) -{ - if (!formattingOptions) - return; - if (hasArg && arg ==0) - { - [self->_html appendBytes: "" length: 4]; - formattingOptions->underline = NO; - } - else - { - [self->_html appendBytes: "" length: 3]; - formattingOptions->underline = YES; - } -} - - -- (NSMutableData *) parse -{ - RTFFormattingOptions *formattingOptions; - RTFColorTable *colorTable; - RTFFontTable *fontTable; - RTFStack *stack; - - const unsigned short *defaultCharset; - - // convenience variables for parsing - unsigned char c; - NSData *d; - NSString *s; - - stack = [[RTFStack alloc] init]; - fontTable = nil; - colorTable = nil; - defaultCharset = ansicpg1252; - formattingOptions = nil; - - _html = [[[NSMutableData alloc] init] autorelease]; - [_html appendBytes: "" length: 34]; - - - // Check if we got RTF data - // this does not allow \s\n before '}' neither newline before control command - if (_len > 4 && strncmp((const char*)_bytes, "{\\rtf", 4) != 0) - return nil; - - while (_current_pos < _len) - { - c = *_bytes; - - // RTF control code - if (c == '\\') - { - unsigned int len; - const char *cw; - BOOL hasArg; - int arg; - NSString *cwKey; - commandWordId cwId; - char nextByte = *(_bytes+1); - - if (nextByte == '\'') - { - // A hexadecimal value, based on the specified character set (may be used to identify 8-bit values). - const char *b1, *b2; - short index; - short tmp; - - const unsigned short * active_charset; - if (formattingOptions && formattingOptions->charset) - active_charset = formattingOptions->charset; - else - active_charset = defaultCharset; - - - ADVANCE; - ADVANCE; - - b1 = ADVANCE; - b2 = ADVANCE; - - tmp = (isdigit(*b1) ? *b1 - 48 : toupper(*b1) - 55); - if (tmp < 0 || tmp > 16) - { - // Incorrect first hexadecimal character. Skipping. - continue; - } - index = tmp*16; - - tmp = (isdigit(*b2) ? *b2 - 48 : toupper(*b2) - 55); - if (tmp < 0 || tmp > 16) - { - // Incorrect second hexadecimal character. Skipping. - continue; - } - index += tmp; - - s = [NSString stringWithCharacters: &(active_charset[index]) length: 1]; - d = [s dataUsingEncoding: NSUTF8StringEncoding]; - [_html appendData: d]; - continue; - } - else if (nextByte == '*') - { - [self parseIgnoringEverything]; - continue; - } - else if (!isalpha(nextByte)) - { - // escape + character - ADVANCE_N(2); - // check for special escapes for the no-implemented features - // for control of word breaking - if (nextByte == '~') - // no breaking space - nextByte = ' '; - else if (nextByte == '-') - // optional hyphen; we skip it - continue; - else if (nextByte == '_') - // no breaking hyphen, treat it as a normal hyphen - nextByte = '-'; - - [_html appendBytes: &nextByte length: 1]; - continue; - } - - - cw = [self parseControlWordAndSetLenIn: &len - setHasIntArgumentIn: &hasArg - setIntArgumentIn: &arg]; - if (cw == NULL) - continue; - - cwKey= [[NSString alloc] initWithBytesNoCopy: (void *)cw - length: len - encoding: NSASCIIStringEncoding - freeWhenDone: NO]; - [cwKey autorelease]; - - cwId = (commandWordId) NSMapGet(_cws, cwKey); - switch (cwId) - { - case CW_ANSICPG: - parseAnsicpg(hasArg, arg, &defaultCharset); - break; - case CW_B: - parseB(self, hasArg, arg, formattingOptions); - break; - case CW_CF: - parseCf(self, hasArg, arg, formattingOptions, colorTable); - break; - case CW_COLORTBL: - parseColorTableWrapper(self, &colorTable); - break; - case CW_F: - parseF(self, hasArg, arg, formattingOptions, fontTable); - break; - case CW_FONTTBL: - parseFontTableWrapper(self, cw, &fontTable); - break; - case CW_I: - parseI(self, hasArg, arg, formattingOptions); - break; - case CW_PAR: - parsePar(self); - break; - case CW_PICT: - parsePictureWrapper(self, cw); - break; - case CW_SOFTLINE: - parseSoftline(self); - break; - case CW_STRIKE: - parseStrike(self, hasArg, arg, formattingOptions); - break; - case CW_STYLESHEET: - parseStyleSheetWrapper(self, cw); - break; - case CW_TAB: - parseTab(self); - break; - case CW_U: - parseU(self, hasArg, arg); - break; - case CW_UL: - parseUl(self, hasArg, arg, formattingOptions); - break; - case CW_ULNONE: - parseUl(self, YES, 0, formattingOptions); - break; - case CW_UNKNOWN: - default: - // do nothing - break; - } - - // If a space delimits the control word, the space does not appear in the document. - // Any characters following the delimiter, including spaces, will appear in the document. (except newline!) - if (*_bytes == ' ') - { - ADVANCE; - } - } - else if (c == '{') - { - formattingOptions = [[[RTFFormattingOptions alloc] init] autorelease]; - - formattingOptions->bold = NO; - formattingOptions->italic = NO; - formattingOptions->strikethrough = NO; - formattingOptions->underline = NO; - formattingOptions->font_index = -1; - formattingOptions->color_index = -1; - formattingOptions->start_pos = [_html length]; - formattingOptions->charset = defaultCharset; - [stack push: formattingOptions]; - ADVANCE; - } - else if (c == '}') - { - formattingOptions = [stack pop]; - - if (formattingOptions) - { - // Handle {\b bold} vs. \b bold \b0 - if (formattingOptions->bold) - { - [_html appendBytes: "
" length: 4]; - } - - if (formattingOptions->italic) - { - [_html appendBytes: "" length: 4]; - } - - if (formattingOptions->strikethrough) - { - [_html appendBytes: "" length: 9]; - } - - if (formattingOptions->underline) - { - [_html appendBytes: "" length: 4]; - } - - if (formattingOptions->font_index >= 0) - { - [_html appendBytes: "" length: 7]; - } - - if (formattingOptions->color_index >= 0) - { - [_html appendBytes: "" length: 7]; - } - } - - formattingOptions = [stack top]; - ADVANCE; - } - else - { - c = *_bytes; - // We avoid appending NULL bytes or endlines - if (c && (c != '\n') && (c != '\r')) - { - const unsigned short * active_charset; - if (formattingOptions && formattingOptions->charset) - active_charset = formattingOptions->charset; - else - active_charset = defaultCharset; - - s = [NSString stringWithCharacters: &(active_charset[c]) length: 1]; - d = [s dataUsingEncoding: NSUTF8StringEncoding]; - [_html appendData: d]; - } - ADVANCE; - } - } - - [_html appendBytes: "" length: 14]; - - [stack release]; - return _html; -} - -/* This method is for ease of testing and should not be used in normal operations */ -- (void) mangleInternalStateWithBytesPtr: (const char*) newBytes - andCurrentPos: (int) newCurrentPos -{ - _bytes = newBytes; - _current_pos = newCurrentPos; -} - -@end diff --git a/OpenChange/SOGoCacheGCSObject+MAPIStore.h b/OpenChange/SOGoCacheGCSObject+MAPIStore.h deleted file mode 100644 index da8452e3d..000000000 --- a/OpenChange/SOGoCacheGCSObject+MAPIStore.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SOGoCacheGCSObject+MAPIStore.h - this file is part of SOGo - * - * Copyright (C) 2014 Inverse inc. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef SOGOCACHEGCSOBJECTMAPISTORE -#define SOGOCACHEGCSOBJECTMAPISTORE - -#include - -@interface SOGoCacheGCSObject (MAPIStore) - -- (Class) mapistoreMessageClass; - -@end - -#endif // SOGOCACHEGCSOBJECTMAPISTORE diff --git a/OpenChange/SOGoCacheGCSObject+MAPIStore.m b/OpenChange/SOGoCacheGCSObject+MAPIStore.m deleted file mode 100644 index 679bee089..000000000 --- a/OpenChange/SOGoCacheGCSObject+MAPIStore.m +++ /dev/null @@ -1,68 +0,0 @@ -/* SOGoCacheGCSObject+MAPIStore.m - this file is part of SOGo - * - * Copyright (C) 2014 Inverse inc. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 -#import -#import - -#include "MAPIStoreTypes.h" - -#include "SOGoCacheGCSObject+MAPIStore.h" - -@implementation SOGoCacheGCSObject (MAPIStore) - -- (Class) mapistoreMessageClass -{ - NSString *className, *mapiMsgClass; - - switch (objectType) - { - case MAPIMessageCacheObject: - mapiMsgClass = [properties - objectForKey: MAPIPropertyKey (PidTagMessageClass)]; - if (mapiMsgClass) - { - if ([mapiMsgClass isEqualToString: @"IPM.StickyNote"]) - className = @"MAPIStoreNotesMessage"; - else - className = @"MAPIStoreDBMessage"; - //[self logWithFormat: @"PidTagMessageClass = '%@', returning '%@'", - // mapiMsgClass, className]; - } - else - { - //[self warnWithFormat: @"PidTagMessageClass is not set, falling back" - // @" to 'MAPIStoreDBMessage'"]; - className = @"MAPIStoreDBMessage"; - } - break; - case MAPIFAICacheObject: - className = @"MAPIStoreFAIMessage"; - break; - default: - [NSException raise: @"MAPIStoreIOException" - format: @"message class should not be queried for objects" - @" of type '%d'", objectType]; - } - - return NSClassFromString (className); -} - -@end diff --git a/OpenChange/SOGoMAPIDBMessage.h b/OpenChange/SOGoMAPIDBMessage.h deleted file mode 100644 index 4211988f6..000000000 --- a/OpenChange/SOGoMAPIDBMessage.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SOGoMAPIDBMessage.h - this file is part of SOGo - * - * Copyright (C) 2012-2014 Inverse inc. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef SOGOMAPIDBMESSAGE_H -#define SOGOMAPIDBMESSAGE_H - -#import - -@class NSDate; -@class NSString; - -@interface SOGoMAPIDBMessage : SOGoCacheGCSObject -@end - -#endif /* SOGOMAPIDBMESSAGE_H */ diff --git a/OpenChange/SOGoMAPIDBMessage.m b/OpenChange/SOGoMAPIDBMessage.m deleted file mode 100644 index 343b90334..000000000 --- a/OpenChange/SOGoMAPIDBMessage.m +++ /dev/null @@ -1,61 +0,0 @@ -/* SOGoMAPIDBMessage.m - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc. - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import - -#import - -#import - -#import "SOGoMAPIDBMessage.h" - -@implementation SOGoMAPIDBMessage - -- (Class) mapistoreMessageClass -{ - // NSArray *dirMembers; - NSString *className; - - [NSException raise: @"whereisthisusedexception" - format: @"this exception should be triggered only for tracing"]; - // /* FIXME: this method is a bit dirty */ - // dirMembers = [[container directory] componentsSeparatedByString: @"/"]; - // if ([dirMembers containsObject: @"fai"]) /* should not occur as FAI message - // are instantiated directly in - // MAPIStoreFolder */ - // className = @"MAPIStoreFAIMessage"; - // else if ([dirMembers containsObject: @"notes"]) - // className = @"MAPIStoreNotesMessage"; - // else - // className = @"MAPIStoreDBMessage"; - - className = @"nimportequoi"; - return NSClassFromString (className); -} - -@end diff --git a/OpenChange/classes.txt b/OpenChange/classes.txt deleted file mode 100644 index 37f8287b0..000000000 --- a/OpenChange/classes.txt +++ /dev/null @@ -1,26 +0,0 @@ -class hierarchy (*: end points) - -MAPIStoreContext - MAPIStoreGCSBaseContext - * MAPIStoreCalendarContext - * MAPIStoreContactsContext - * MAPIStoreTasksContext - * MAPIStoreMailContext - * MAPIStoreOutboxContext - * MAPIStoreSpoolerContext - MAPIStoreFileSystemBaseContext - * MAPIStoreCommonViewsContext - * MAPIStoreDeferredActionsContext - * MAPIStoreDraftsContext - * MAPIStoreJournalContext - * MAPIStoreNotesContext - * MAPIStoreRemindersContext - * MAPIStoreSearchContext - * MAPIStoreSentItemsContext - * MAPIStoreShortcutsContext - - (undecided:) - DeletedItems (trash IMAP folder?) - Freebusy (needs info) - Schedule (needs info + purpose?) - Views (needs info + purpose) diff --git a/OpenChange/code-MAPIStorePropertySelectors.h b/OpenChange/code-MAPIStorePropertySelectors.h deleted file mode 100644 index cf2148e0d..000000000 --- a/OpenChange/code-MAPIStorePropertySelectors.h +++ /dev/null @@ -1,27 +0,0 @@ -/* code-MAPIStorePropertySelectors.h - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -typedef enum mapistore_error (*MAPIStorePropertyGetter) (id inst, SEL _cmd, - void **data, TALLOC_CTX *memCtx); - -const MAPIStorePropertyGetter *MAPIStorePropertyGettersForClass (Class klass); -SEL MAPIStoreSelectorForPropertyGetter (uint16_t propertyId); diff --git a/OpenChange/code-MAPIStorePropertySelectors.m b/OpenChange/code-MAPIStorePropertySelectors.m deleted file mode 100644 index 86ac76f20..000000000 --- a/OpenChange/code-MAPIStorePropertySelectors.m +++ /dev/null @@ -1,73 +0,0 @@ -/* code-MAPIStorePropertySelectors.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import - -#undef DEBUG -#include - -const MAPIStorePropertyGetter * -MAPIStorePropertyGettersForClass (Class klass) -{ - static NSMapTable *classesTable = nil; - MAPIStorePropertyGetter *getters; - MAPIStorePropertyGetter getter; - uint16_t count, idx; - SEL currentSel; - - if (!classesTable) - classesTable = NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks, - NSNonOwnedPointerMapValueCallBacks, - 0); - - getters = NSMapGet (classesTable, klass); - if (!getters) - { - getters = NSZoneCalloc (NULL, 65536, sizeof (MAPIStorePropertyGetter)); - NSMapInsert (classesTable, klass, getters); - for (count = 0; count < 65535; count++) - { - idx = MAPIStorePropertyGettersIdx[count]; - if (idx != 0xffff && !getters[count]) - { - currentSel = MAPIStorePropertyGetterSelectors[idx]; - if ([klass instancesRespondToSelector: currentSel]) - { - getter = (MAPIStorePropertyGetter) - [klass instanceMethodForSelector: currentSel]; - if (getter) - getters[count] = getter; - } - } - } - } - - return getters; -} - -SEL MAPIStoreSelectorForPropertyGetter (uint16_t propertyId) -{ - return ((MAPIStorePropertyGettersIdx[propertyId] != 0xffff) - ? MAPIStorePropertyGetterSelectors[MAPIStorePropertyGettersIdx[propertyId]] - : NULL); -} diff --git a/OpenChange/dbmsgreader.m b/OpenChange/dbmsgreader.m deleted file mode 100644 index 5ad74b82b..000000000 --- a/OpenChange/dbmsgreader.m +++ /dev/null @@ -1,160 +0,0 @@ -/* dbmsgreader.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * 2015 Enrique J. Hernandez - * - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* A format-agnostic property list readerer. - Usage: dbmsgreader [username] [filename] */ - -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import - -#import "MAPIStoreUserContext.h" -#import - -#import -#import "NSObject+PropertyList.h" - - -Class MAPIStoreUserContextK, SOGoCacheGCSObjectK, NSStringK; - -static void -DumpBSONData(NSData *data) -{ - id key, value; - NSEnumerator *dictEnum; - NSDictionary *dvalue; - NSMutableString *outStr; - NSUInteger max; - - dvalue = [data BSONValue]; - max = [dvalue count]; - dictEnum = [dvalue keyEnumerator]; - NSStringK = [NSString class]; - outStr = [NSMutableString stringWithFormat: @"{ %d items\n", max]; - while ((key = [dictEnum nextObject])) - { - uint32_t proptag = 0; - if ([key isKindOfClass: NSStringK] && [(NSString *)key intValue] > 0) - proptag = [(NSString *)key intValue]; - - if (proptag > 0) - { - const char *propTagName = get_proptag_name (proptag); - NSString *propName; - - if (propTagName) - propName = [NSString stringWithCString: propTagName - encoding: NSUTF8StringEncoding]; - else - propName = [NSString stringWithFormat: @"0x%.4x", [key unsignedLongValue]]; - - [outStr appendFormat: @" %@ = ", propName]; - } - else - [outStr appendFormat: @" %@ = ", key]; - - value = [dvalue objectForKey: key]; - [outStr appendFormat: @"(%@) %@,\n", NSStringFromClass ([value class]), value]; - } - [outStr appendFormat: @"}\n"]; - printf ("%s\n", [outStr UTF8String]); -} - -static void -DbDumpObject (NSString *username, NSString *path) -{ - id ctx; - NSData *content; - id dbobject; - NSDictionary *record; - - ctx = [MAPIStoreUserContextK userContextWithUsername: username - andTDBIndexing: NULL]; - dbobject = [SOGoCacheGCSObjectK new]; - [dbobject setTableUrl: [ctx folderTableURL]]; - record = [dbobject lookupRecord: path newerThanVersion: -1]; - if (record) - { - printf("record found: %p\n", record); - content = [[record objectForKey: @"c_content"] dataByDecodingBase64]; - DumpBSONData (content); - } - else - NSLog (@"record not found"); - - [dbobject release]; -} - -int main (int argc, char *argv[], char *envp[]) -{ - NSAutoreleasePool *pool; - SOGoProductLoader *loader; - NSUserDefaults *ud; - SoProductRegistry *registry; - NSArray *arguments; - - /* Here we work around a bug in GNUstep which decodes XML user - defaults using the system encoding rather than honouring - the encoding specified in the file. */ - putenv ("GNUSTEP_STRING_ENCODING=NSUTF8StringEncoding"); - - pool = [NSAutoreleasePool new]; - - [SOGoSystemDefaults sharedSystemDefaults]; - - /* We force the plugin to base its configuration on the SOGo tree. */ - ud = [NSUserDefaults standardUserDefaults]; - [ud registerDefaults: [ud persistentDomainForName: @"sogod"]]; - - [NSProcessInfo initializeWithArguments: argv - count: argc - environment: envp]; - - registry = [SoProductRegistry sharedProductRegistry]; - [registry scanForProductsInDirectory: SOGO_BUNDLES_DIR]; - - loader = [SOGoProductLoader productLoader]; - [loader loadProducts: [NSArray arrayWithObject: BACKEND_BUNDLE_NAME]]; - - MAPIStoreUserContextK = NSClassFromString (@"MAPIStoreUserContext"); - SOGoCacheGCSObjectK = NSClassFromString (@"SOGoCacheGCSObject"); - - arguments = [[NSProcessInfo processInfo] arguments]; - if ([arguments count] > 2) { - DbDumpObject ([arguments objectAtIndex: 1], - [arguments objectAtIndex: 2]); - } else if ([arguments count] > 1) { - DumpBSONData([[arguments objectAtIndex:1] dataByDecodingBase64]); - } - - [pool release]; - - return 0; -} diff --git a/OpenChange/gen-charset-table.py b/OpenChange/gen-charset-table.py deleted file mode 100755 index 1bcc1aa17..000000000 --- a/OpenChange/gen-charset-table.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/python - -import getopt -import os -import re -import string -import sys - -h_template = """unsigned short %(charsetName)s[%(len)d] = { %(values)s };""" -CHAR_UNDEF = "0x0000" -MAP_LEN = 256 -itemsPerLine = 16 - -def usage(): - usageMsg = """ -Usage: %s -f inputFile -""" % (os.path.basename(sys.argv[0])) - sys.stderr.write(usageMsg) - -def parseCharsetFile(file = None): - if file is None: - return None - - charmap = [CHAR_UNDEF] * MAP_LEN - - # Sample line: - # FD = U+200E : LEFT-TO-RIGHT MARK - for line in file.xreadlines(): - m = re.search("(\w{2}) = U\+(\w{4}) :", line) - if not m: - sys.stderr.write("Skipping weird line: %s" % line) - continue - - ind = int(m.group(1), base=16) - unicodeValue = str(m.group(2)).lower() - - charmap[ind] = "0x%s" % (unicodeValue) - - return charmap - - -def formatCharacterMap(charmap = None): - if not charmap: - return None - - value = "" - for i in xrange(0,MAP_LEN-1): - char = charmap[i] - if i % itemsPerLine == 0: - value += "\n " - value += "%s, " % (char) - i += 1 - value += charmap[MAP_LEN-1] - - return value - -if __name__ == '__main__': - inputFile = None - - try: - opts, args = getopt.getopt(sys.argv[1:], "f:") - except getopt.GetoptError, err: - sys.stderr.write(str(err)) - usage() - sys.exit(2) - - for o, a in opts: - if o == "-f": - inputFile = a - else: - assert False, "unhandled option" - - if not inputFile: - usage() - sys.exit(1) - - - f = open(inputFile, "r", 1) - - charsetMap = parseCharsetFile(f) - charsetValues = formatCharacterMap(charsetMap) - print h_template % {"len": len(charsetMap), - "charsetName": os.path.basename(inputFile), - "values": charsetValues} diff --git a/OpenChange/gen-property-selectors.py b/OpenChange/gen-property-selectors.py deleted file mode 100755 index d0431784b..000000000 --- a/OpenChange/gen-property-selectors.py +++ /dev/null @@ -1,266 +0,0 @@ -#!/usr/bin/python - -include_dirs = [ "/usr/include" ] - -output = "-" - -import os -import sys - -m_template = """/* %(filename)s (auto-generated) */ - -#include -#include - -#import "%(h_filename)s" - -const NSUInteger MAPIStorePropertyGettersCount = %(nbr_getters)d; -const NSUInteger MAPIStoreLastPropertyIdx = %(last_property)d; -const NSUInteger MAPIStoreSupportedPropertiesCount = %(nbr_supported_properties)d; - -const enum MAPITAGS MAPIStoreSupportedProperties[] = { -%(supported_properties)s -}; - -static const uint16_t MAPIStorePropertyGettersIdx[] = { -%(getters_idx)s -}; - -static const SEL MAPIStorePropertyGetterSelectors[] = { -%(getters)s -}; - -#include "code-%(filename)s" -""" - -h_template = """/* %(filename)s (auto-generated) */ - -#ifndef %(h_exclusion)s -#define %(h_exclusion)s 1 - -#import - -#include -#include -#include -#include - -extern const NSUInteger MAPIStorePropertyGettersCount; -extern const NSUInteger MAPIStoreLastPropertyIdx; - -extern const NSUInteger MAPIStoreSupportedPropertiesCount; -extern const enum MAPITAGS MAPIStoreSupportedProperties[]; - -#import "MAPIStoreObject.h" - -@interface MAPIStoreObject (MAPIStorePropertySelectors) - -%(prototypes)s - -@end - -#include "code-%(filename)s" - -#endif /* %(h_exclusion)s */ -""" - -# hack: some properties have multiple and incompatible types. Sometimes those -# props are not related at all... -bannedProps = set(["PidTagBodyHtml", "PidTagFavAutosubfolders", - "PidTagAttachDataObj", "PidTagAclTable", "PidTagAclData", - "PidTagRulesTable", "PidTagRulesData", - "PidTagDisableWinsock", - "PidTagHierarchyServer", "PidTagOfflineAddrbookEntryid", - "PidTagShorttermEntryidFromObject", - "PidTagNormalMessageSizeExtended", - "PidTagAssocMessageSizeExtended", - "PidTagMessageSizeExtended", - "PidTagOabContainerGuid", - "PidTagOfflineAddressBookMessageClass", "PidTagScriptData", - "PidTagOfflineAddressBookTruncatedProperties", - "PidTagOfflineAddressBookContainerGuid", - "PidTagOfflineAddressBookDistinguishedName", - "PidTagOfflineAddressBookShaHash", - "PidTagSenderTelephoneNumber", - "PidTagGatewayNeedsToRefresh", - "PidTagWlinkType", "PidTagWlinkFlags", - "PidTagWlinkGroupClsid", "PidTagWlinkGroupName", - "PidTagWlinkGroupHeaderID", - "PidTagScheduleInfoDelegatorWantsCopy", - "PidTagWlinkOrdinal", - "PidTagWlinkSection", "PidTagWlinkCalendarColor", - "PidTagWlinkAddressBookEID", "PidTagWlinkFolderType", - "PidTagScheduleInfoDelegateNames", - "PidTagScheduleInfoDelegateEntryIds", - "PidTagBusiness2TelephoneNumbers", - "PidTagHome2TelephoneNumbers", - "PidTagAttachDataObject", - "PidTagShorttermEntryIdFromObject", - ]) - -def ParseExchangeH(names, lines): - state = 0 - maxlines = len(lines) - x = 0 - while x < maxlines and state != 3: - stripped = lines[x].strip() - if state == 0: - if stripped == "enum MAPITAGS": - state = 1 - elif state == 1: - if stripped == "{": - state = 2 - elif state == 2: - if stripped == "}": - state = 3 - else: - ParseExchangeHDefinition(names, stripped) - x = x + 1 - -def ParseExchangeHDefinition(names, line): - stripped = line.strip() - eqIdx = stripped.find("=") - if eqIdx == -1: - raise Exception, "line does not contain a '='" - - propName = stripped[0:eqIdx] - if not propName.endswith("_Error") and not propName.endswith("_string8") \ - and propName not in bannedProps: - intIdx = stripped.find("(int", eqIdx) - valueIdx = stripped.find("0x", intIdx + 1) - endIdx = stripped.find(")", valueIdx) - value = int(stripped[valueIdx:endIdx], 16) - if value < 0x80000000: - names[propName] = value - -def ParseMapistoreNameIDH(names, lines): - for line in lines: - stripped = line.strip() - if stripped.startswith("#define Pid"): - ParseMapistoreNameIDHDefinition(names, stripped) - -def ParseMapistoreNameIDHDefinition(names, line): - stripped = line.strip() - pidIdx = stripped.find("Pid") - if pidIdx == -1: - raise Exception, "line does not contain a 'Pid'" - valueIdx = stripped.find("0x") - propName = stripped[pidIdx:valueIdx].strip() - if not propName.startswith("PidLidUnknown") and propName not in bannedProps: - value = int(stripped[valueIdx:], 16) - names[propName] = value - -def FindHFile(filename): - found = None - - for dirname in include_dirs: - full_filename = "%s/%s" % (dirname, filename) - if os.path.exists(full_filename): - found = full_filename - - if found is None: - raise Exception, "'%s' not found in include dirs" % filename - - return found - -def ProcessHeaders(names, hdict): - for filename in hdict: - header_filename = FindHFile(filename) - header_file = open(header_filename, "r") - lines = header_file.readlines() - header_file.close() - hdict[filename](names, lines) - -if __name__ == "__main__": - arg_count = len(sys.argv) - x = 0 - while x < arg_count: - arg = sys.argv[x] - argname = None - if arg.startswith("-"): - argname = arg[1] - if len(arg) == 2: - argvalue = sys.argv[x + 1] - x = x + 1 - else: - argvalue = arg[2:] - x = x + 1 - - if argname == "o": - output = argvalue - elif argname == "I": - include_dirs.append(argvalue) - - names = {} - ProcessHeaders(names, - {"gen_ndr/exchange.h": ParseExchangeH, - "mapistore/mapistore_nameid.h": ParseMapistoreNameIDH}) - - getters = [] - getters_idx = [] - # setters = [] - # preferred_types = [] - prototypes = [] - - for x in xrange(0x10000): - getters_idx.append(" 0xffff") - # setters.append(" NULL") - - prop_types = {} - # sanitization: only take unicode version of text properties - for name, prop_tag in names.iteritems(): - prop_id = prop_tag >> 16 - prop_type = prop_tag & 0xffff - if not prop_id in prop_types: - prop_types[prop_id] = [] - prop_types[prop_id].append(prop_type) - if (prop_type & 0xfff) == 0x001e: - prop_tag = (prop_tag & 0xfffff000) | 0x001f - names[name] = prop_tag - - #sanitization: report multiple types for the same keynames - for prop_id, xtypes in prop_types.iteritems(): - cnt = len(xtypes) - if cnt > 1: - print "%d types available for prop id 0x%.4x: %s" % (cnt, prop_id, ", ".join(["%.4x" % x for x in xtypes])) - - supported_properties = [] - current_getter_idx = 0 - highest_prop_idx = 0 - for name, prop_tag in names.iteritems(): - supported_properties.append(" 0x%.8x" % prop_tag); - prop_idx = (prop_tag & 0xffff0000) >> 16 - getters_idx[prop_idx] = " 0x%.4x" % current_getter_idx - if prop_idx > highest_prop_idx: - highest_prop_idx = prop_idx - getters.append(" @selector (get%s:inMemCtx:)" % name) - # preferred_types.append(" 0x%.4x" % (prop_tag & 0xffff)) - prototypes.append("- (enum mapistore_error) get%s: (void **) data inMemCtx: (TALLOC_CTX *) memCtx;" % name) - current_getter_idx = current_getter_idx + 1 - # setters[prop_idx] = " @selector (set%s:)" % name - # prototypes.append("- (int) set%s: (void **) data;" % name) - # prototypes.append("") - - filename = "%s.m" % output - h_filename = "%s.h" % output - outf = open(filename, "wb+") - outf.write(m_template % {"getters_idx": ",\n".join(getters_idx), - "getters": ",\n".join(getters), - "nbr_getters": len(getters), - "last_property": highest_prop_idx, - "nbr_supported_properties": len(supported_properties), - "supported_properties": ",\n".join(supported_properties), - "filename": filename, - "h_filename": h_filename}) - outf.close() - - outf = open(h_filename, "wb+") - exclusion = "" - for x in h_filename.upper(): - if ord(x) < 65 or ord(x) > 90: - x = "_" - exclusion = exclusion + x - outf.write(h_template % {"prototypes": "\n".join(prototypes), - "h_exclusion": exclusion, - "filename": h_filename }) - outf.close() diff --git a/OpenChange/iCalEvent+MAPIStore.h b/OpenChange/iCalEvent+MAPIStore.h deleted file mode 100644 index 8d73923e1..000000000 --- a/OpenChange/iCalEvent+MAPIStore.h +++ /dev/null @@ -1,44 +0,0 @@ -/* iCalEvent+MAPIStore.h - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 ICALEVENT_MAPISTORE_H -#define ICALEVENT_MAPISTORE_H - -#include - -#import - -@class MAPIStoreUserContext; -@class NSDictionary; -@class NSString; -@class SOGoUser; - -@interface iCalEvent (MAPIStoreProperties) - -- (void) updateFromMAPIProperties: (NSDictionary *) properties - inUserContext: (MAPIStoreUserContext *) userContext - withActiveUser: (SOGoUser *) activeUser - isNew: (BOOL) isNew - inMemCtx: (TALLOC_CTX *) memCtx; -@end - -#endif /* ICALEVENT_MAPISTORE_H */ diff --git a/OpenChange/iCalEvent+MAPIStore.m b/OpenChange/iCalEvent+MAPIStore.m deleted file mode 100644 index 1bf0d261a..000000000 --- a/OpenChange/iCalEvent+MAPIStore.m +++ /dev/null @@ -1,587 +0,0 @@ -/* iCalEvent+MAPIStore.m - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "MAPIStoreAppointmentWrapper.h" -#import "MAPIStoreCalendarAttachment.h" -#import "MAPIStoreCalendarFolder.h" -#import "MAPIStoreContext.h" -#import "MAPIStoreMapping.h" -#import "MAPIStoreRecurrenceUtils.h" -#import "MAPIStoreTypes.h" -#import "MAPIStoreUserContext.h" -#import "NSDate+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSObject+MAPIStore.h" -#import "NSString+MAPIStore.h" -#import "NSValue+MAPIStore.h" - -#import "MAPIStoreCalendarMessage.h" - -#undef DEBUG -#include -#include -#include -#include -#include -#include -#include - -#import "iCalEvent+MAPIStore.h" -#import "iCalTimeZone+MAPIStore.h" - -@implementation iCalEvent (MAPIStoreProperties) - -- (void) _setupEventRecurrence: (NSData *) mapiRecurrenceData - inTimeZone: (iCalTimeZone *) tz - inMemCtx: (TALLOC_CTX *) memCtx -{ - struct Binary_r *blob; - struct AppointmentRecurrencePattern *pattern; - - blob = [mapiRecurrenceData asBinaryInMemCtx: memCtx]; - pattern = get_AppointmentRecurrencePattern (memCtx, blob); - - if (pattern == NULL) { - [self logWithFormat: @"Error parsing recurrence pattern. No changes in event recurrence will be done"]; - return; - } - - [(iCalCalendar *) parent setupRecurrenceWithMasterEntity: self - fromRecurrencePattern: &pattern->RecurrencePattern - withExceptions: pattern->ExceptionInfo - andExceptionCount: pattern->ExceptionCount - inTimeZone: tz - ]; - //talloc_free (blob); -} - -- (void) _setupEventAlarmFromProperties: (NSDictionary *) properties -{ - NSArray *alarms; - iCalAlarm *currentAlarm, *alarm = nil; - iCalTrigger *trigger; - NSNumber *delta; - NSString *action; - NSUInteger count, max; - - /* find and remove first display alarm */ - alarms = [self alarms]; - max = [alarms count]; - for (count = 0; !alarm && count < max; count++) - { - currentAlarm = [alarms objectAtIndex: count]; - action = [[currentAlarm action] lowercaseString]; - if (!action || [action isEqualToString: @"display"]) - alarm = currentAlarm; - } - - if (alarm) - [self removeChild: alarm]; - - if ([[properties objectForKey: MAPIPropertyKey (PidLidReminderSet)] - boolValue]) - { - delta - = [properties objectForKey: MAPIPropertyKey (PidLidReminderDelta)]; - if (delta) - { - alarm = [iCalAlarm new]; - [alarm setAction: @"DISPLAY"]; - trigger = [iCalTrigger elementWithTag: @"trigger"]; - [trigger setValueType: @"DURATION"]; - [trigger - setSingleValue: [NSString stringWithFormat: @"-PT%@M", delta] - forKey: @""]; - [alarm setTrigger: trigger]; - [self addToAlarms: alarm]; - [alarm release]; - } - } -} - -- (int) _updateFromAttendeeMAPIProperties: (NSArray *) recipients - withRole: (NSString *) role - outParam: (BOOL *) organizerIsSet -{ - NSDictionary *dict; - NSString *attEmail; - iCalPerson *person; - iCalPersonPartStat newPartStat; - NSNumber *flags, *trackStatus; - int i, effective; - - effective = 0; - for (i = 0; i < [recipients count]; i++) - { - dict = [recipients objectAtIndex: i]; - person = [iCalPerson new]; - [person setCn: [dict objectForKey: @"fullName"]]; - attEmail = [dict objectForKey: @"email"]; - [person setEmail: attEmail]; - - flags = [dict objectForKey: MAPIPropertyKey (PR_RECIPIENT_FLAGS)]; - if (!flags) - { - [self logWithFormat: - @"no recipient flags specified: skipping recipient"]; - continue; - } - - if (([flags unsignedIntValue] & 0x0002)) /* recipOrganizer */ - { - [self setOrganizer: person]; - *organizerIsSet = YES; - [self logWithFormat: @"organizer set via recipient flags"]; - } - else - { - BOOL isOrganizer = NO; - - // /* Work-around: it happens that Outlook still passes the - // organizer as a recipient, maybe because of a feature - // documented in a pre-mesozoic PDF still buried in a - // cavern... In that case we remove it, and we keep the - // number of effective recipients in "effective". If the - // total is 0, we remove the "ORGANIZER" too. */ - // if ([attEmail isEqualToString: orgEmail]) - // { - // [self logWithFormat: - // @"avoiding setting organizer as recipient"]; - // continue; - // } - - trackStatus = [dict objectForKey: MAPIPropertyKey (PidTagRecipientTrackStatus)]; - if (trackStatus) - { - /* FIXME: we should provide a data converter between OL - partstats and SOGo */ - switch ([trackStatus unsignedIntValue]) - { - case 0x01: /* respOrganized */ - isOrganizer = YES; - break; - case 0x02: /* respTentative */ - newPartStat = iCalPersonPartStatTentative; - break; - case 0x03: /* respAccepted */ - newPartStat = iCalPersonPartStatAccepted; - break; - case 0x04: /* respDeclined */ - newPartStat = iCalPersonPartStatDeclined; - break; - default: - newPartStat = iCalPersonPartStatNeedsAction; - } - - if (isOrganizer) - { - [self setOrganizer: person]; - *organizerIsSet = YES; - [self logWithFormat: @"organizer set via track status"]; - } - else - { - [person setParticipationStatus: newPartStat]; - [person setRsvp: @"TRUE"]; - [person setRole: role]; - [self addToAttendees: person]; - effective++; - } - } - else - [self errorWithFormat: @"skipped recipient due" - @" to missing track status"]; - } - - [person release]; - } - - return effective; -} - - -- (void) updateFromMAPIProperties: (NSDictionary *) properties - inUserContext: (MAPIStoreUserContext *) userContext - withActiveUser: (SOGoUser *) activeUser - isNew: (BOOL) isNew - inMemCtx: (TALLOC_CTX *) memCtx -{ - BOOL isAllDay; - iCalDateTime *start, *end; - iCalTimeZone *tz; - NSString *priority, *class = nil, *tzDescription = nil; - NSUInteger responseStatus = 0; - SOGoUser *ownerUser; - id value; - - // value = [properties objectForKey: MAPIPropertyKey (PidTagMessageClass)]; - // if (value) - // isException = [value isEqualToString: @"IPM.OLE.CLASS.{00061055-0000-0000-C000-000000000046}"]; - // else - // isException = NO; - - /* privacy */ - value = [properties objectForKey: MAPIPropertyKey(PidLidPrivate)]; - - if (value) - { - if ([value boolValue]) - [self setAccessClass: @"PRIVATE"]; - else - [self setAccessClass: @"PUBLIC"]; - } - - /* Time zone = PidLidAppointmentTimeZoneDefinitionRecur - or PidLidAppointmentTimeZoneDefinition[Start|End]Display */ - value = [properties objectForKey: MAPIPropertyKey (PidLidAppointmentTimeZoneDefinitionStartDisplay)]; - if (!value) - { - value = [properties objectForKey: MAPIPropertyKey (PidLidAppointmentTimeZoneDefinitionEndDisplay)]; - if (!value) - { - /* If PidLidtimeZoneStruct, TZID SHOULD come from PidLidTimeZoneDescription, - if PidLidAppointmentTimeZoneDefinition[Start|End]Display it MUST be derived from KeyName - (MS-OXCICAL] 2.1.3.1.1.19.1) */ - value = [properties objectForKey: MAPIPropertyKey (PidLidAppointmentTimeZoneDefinitionRecur)]; - tzDescription = [properties objectForKey: MAPIPropertyKey (PidLidTimeZoneDescription)]; - } - } - if (value) - { - tz = [[iCalTimeZone alloc] iCalTimeZoneFromDefinition: value - withDescription: tzDescription - inMemCtx: memCtx]; - } - else - /* The client is more likely to have the webmail's time zone than any other */ - tz = [iCalTimeZone timeZoneForName: [[userContext timeZone] name]]; - [(iCalCalendar *) parent addTimeZone: tz]; - - /* CREATED */ - value = [properties objectForKey: MAPIPropertyKey (PidTagCreationTime)]; - if (value) - [self setCreated: value]; - - // LAST-MODIFIED = PidTagLastModificationTime - value = [properties objectForKey: MAPIPropertyKey (PidTagLastModificationTime)]; - if (value) - [self setLastModified: value]; - - /* DTSTAMP = PidLidOwnerCriticalChange or PidLidAttendeeCriticalChange */ - value = [properties objectForKey: MAPIPropertyKey (PidLidOwnerCriticalChange)]; - if (value) - [self setTimeStampAsDate: value]; - - /* SUMMARY */ - value = [properties objectForKey: MAPIPropertyKey (PidTagNormalizedSubject)]; - if (value) - [self setSummary: value]; - - // Location - value = [properties objectForKey: MAPIPropertyKey (PidLidLocation)]; - if (value) - [self setLocation: value]; - - isAllDay = [self isAllDay]; - value = [properties - objectForKey: MAPIPropertyKey (PidLidAppointmentSubType)]; - if (value) - isAllDay = [value boolValue]; - - // recurrence-id - value - = [properties objectForKey: MAPIPropertyKey (PidLidExceptionReplaceTime)]; - if (value) - [self setRecurrenceId: value]; - - // start - value = [properties objectForKey: MAPIPropertyKey (PidLidAppointmentStartWhole)]; - if (!value) - value = [properties objectForKey: MAPIPropertyKey (PR_START_DATE)]; - if (value) - { - start = (iCalDateTime *) [self uniqueChildWithTag: @"dtstart"]; - [start setTimeZone: tz]; - if (isAllDay) - { - /* All-day events are set in floating time ([MS-OXCICAL] 2.1.3.1.1.20.8) */ - [start setDate: value]; - [start setTimeZone: nil]; - } - else - [start setDateTime: value]; - } - - /* end */ - value = [properties objectForKey: MAPIPropertyKey (PidLidAppointmentEndWhole)]; - if (!value) - value = [properties objectForKey: MAPIPropertyKey (PR_END_DATE)]; - if (value) - { - end = (iCalDateTime *) [self uniqueChildWithTag: @"dtend"]; - [end setTimeZone: tz]; - if (isAllDay) - { - /* All-day events are set in floating time ([MS-OXCICAL] 2.1.3.1.1.20.8) */ - [end setDate: value]; - [end setTimeZone: nil]; - } - else - [end setDateTime: value]; - } - - /* priority */ - value = [properties objectForKey: MAPIPropertyKey(PR_IMPORTANCE)]; - if (value) - { - switch ([value intValue]) - { - case 0: // IMPORTANCE_LOW - priority = @"9"; - break; - case 2: // IMPORTANCE_HIGH - priority = @"1"; - break; - default: // IMPORTANCE_NORMAL - priority = @"5"; - } - } - else - priority = @"0"; // None - [self setPriority: priority]; - - /* class */ - /* See [MS-OXCICAL] Section 2.1.3.11.20.4 */ - value = [properties objectForKey: MAPIPropertyKey(PR_SENSITIVITY)]; - if (value) - { - switch ([value intValue]) - { - case 1: - class = @"X-PERSONAL"; - break; - case 2: - class = @"PRIVATE"; - break; - case 3: - class = @"CONFIDENTIAL"; - break; - default: /* 0 as well */ - class = @"PUBLIC"; - } - } - - if (class) - [self setAccessClass: class]; - - /* Categories */ - /* See [MS-OXCICAL] Section 2.1.3.1.1.20.3 */ - value = [properties objectForKey: MAPIPropertyKey (PidNameKeywords)]; - if (value) - [self setCategories: value]; - - /* show time as free/busy/tentative/out of office. Possible values are: - 0x00000000 - olFree - 0x00000001 - olTentative - 0x00000002 - olBusy - 0x00000003 - olOutOfOffice */ - value = [properties objectForKey: MAPIPropertyKey(PidLidBusyStatus)]; - if (value) - { - switch ([value intValue]) - { - case 0: - [self setTransparency: @"TRANSPARENT"]; - break; - case 1: - case 2: - case 3: - default: - [self setTransparency: @"OPAQUE"]; - } - } - - /* Comment */ - value = [properties objectForKey: MAPIPropertyKey (PR_BODY_UNICODE)]; - if (!value) - { - value = [properties objectForKey: MAPIPropertyKey (PR_HTML)]; - if (value) - { - value = [[NSString alloc] initWithData: value - encoding: NSUTF8StringEncoding]; - [value autorelease]; - value = [value htmlToText]; - } - } - if (value) - { - if ([value length] == 0 || [value isEqualToString: @"\\n"]) - value = nil; - [self setComment: value]; - } - - /* recurrence */ - value = [properties - objectForKey: MAPIPropertyKey (PidLidAppointmentRecur)]; - if (value) - [self _setupEventRecurrence: value inTimeZone: tz inMemCtx: memCtx]; - - /* alarm */ - [self _setupEventAlarmFromProperties: properties]; - - // Organizer - value = [properties objectForKey: @"recipients"]; - if (value) - { - NSDictionary *dict; - NSString *orgEmail, *sentBy; - iCalPerson *person; - iCalPersonPartStat newPartStat; - int effective; - BOOL organizerIsSet = NO; - - [self setOrganizer: nil]; - [self removeAllAttendees]; - - /* In [MS-OXOCAL] Section 2.2.4.10.7 says the recipient type is 0x01 as Required - and 0x02 as Optional and other documents such [MS-OXCMSG] 2.2.3.1.2 indicates - that MAPI_TO is 0x01 and MAPI_CC is 0x02, that's why in SOGo is in 'to' and 'cc' - respectively. */ - effective = [self _updateFromAttendeeMAPIProperties: [value objectForKey: @"to"] - withRole: @"REQ-PARTICIPANT" - outParam: &organizerIsSet]; - effective += [self _updateFromAttendeeMAPIProperties: [value objectForKey: @"cc"] - withRole: @"OPT-PARTICIPANT" - outParam: &organizerIsSet]; - - if (effective == 0) /* See work-around inside _updateFromAttendeeMAPIProperties */ - [self setOrganizer: nil]; - else - { - // SEQUENCE = PidLidAppointmentSequence - value = [properties objectForKey: MAPIPropertyKey (PidLidAppointmentSequence)]; - if (value) - [self setSequence: value]; - - ownerUser = [userContext sogoUser]; - if (organizerIsSet) - { - /* We must reset the participation status to the value - obtained from PidLidResponseStatus as the value in - PidTagRecipientTrackStatus is not correct. Note (hack): - the method used here requires that the user directory - from LDAP and Samba matches perfectly. This can be solved - more appropriately by making use of the sender - properties... */ - person = [self userAsAttendee: ownerUser]; - if (person) - { - value - = [properties objectForKey: MAPIPropertyKey (PidLidResponseStatus)]; - if (value) - responseStatus = [value unsignedLongValue]; - - /* FIXME: we should provide a data converter between OL partstats and - SOGo */ - switch (responseStatus) - { - case 0x02: /* respTentative */ - newPartStat = iCalPersonPartStatTentative; - break; - case 0x03: /* respAccepted */ - newPartStat = iCalPersonPartStatAccepted; - break; - case 0x04: /* respDeclined */ - newPartStat = iCalPersonPartStatDeclined; - break; - default: - newPartStat = iCalPersonPartStatNeedsAction; - } - [person setParticipationStatus: newPartStat]; - - value = [properties objectForKey: MAPIPropertyKey (PidLidAttendeeCriticalChange)]; - if (value && ![value isNever]) - [self setTimeStampAsDate: value]; - } - } - else - { - [self errorWithFormat: @"organizer was not set although a" - @" recipient list was specified"]; - /* We must set the organizer preliminarily here because, unlike what - the doc states, Outlook does not always pass the real organizer - in the recipients list. */ - dict = [ownerUser primaryIdentity]; - person = [iCalPerson new]; - [person setCn: [dict objectForKey: @"fullName"]]; - orgEmail = [dict objectForKey: @"email"]; - [person setEmail: orgEmail]; - - if (![activeUser isEqual: ownerUser]) - { - dict = [activeUser primaryIdentity]; - sentBy = [NSString stringWithFormat: @"mailto:%@", - [dict objectForKey: @"email"]]; - [person setSentBy: sentBy]; - } - [self setOrganizer: person]; - [person release]; - } - } - } - // Creator (with sharing purposes) - if (isNew) - { - value = [properties objectForKey: MAPIPropertyKey (PidTagLastModifierName)]; - if (value) - [[self uniqueChildWithTag: @"x-sogo-component-created-by"] setSingleValue: value - forKey: @""]; - } -} - -@end diff --git a/OpenChange/iCalTimeZone+MAPIStore.h b/OpenChange/iCalTimeZone+MAPIStore.h deleted file mode 100644 index 25817392a..000000000 --- a/OpenChange/iCalTimeZone+MAPIStore.h +++ /dev/null @@ -1,42 +0,0 @@ -/* iCalTimeZone+MAPIStore.h - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef ICALTIMEZONE_MAPISTORE_H -#define ICALTIMEZONE_MAPISTORE_H - -#import - -@interface iCalTimeZone (MAPIStoreProperties) - -- (struct Binary_r *) asTimeZoneStructInMemCtx: (TALLOC_CTX *) memCtx; -- (struct Binary_r *) asZoneTimeDefinitionWithFlags: (enum TZRuleFlag) flags - inMemCtx: (TALLOC_CTX *) memCtx; -- (iCalTimeZone *) iCalTimeZoneFromDefinition: (NSData *) value - withDescription: (NSString *) description - inMemCtx: (TALLOC_CTX *) memCtx; -- (NSCalendarDate *) shiftedCalendarDateForDate: (NSCalendarDate *) date; - - -@end - - -#endif /* ICALTIMEZONE_MAPISTORE_H */ diff --git a/OpenChange/iCalTimeZone+MAPIStore.m b/OpenChange/iCalTimeZone+MAPIStore.m deleted file mode 100644 index 7cf380fdf..000000000 --- a/OpenChange/iCalTimeZone+MAPIStore.m +++ /dev/null @@ -1,377 +0,0 @@ -/* iCalTimeZone+MAPIStore.m - this file is part of SOGo - * - * Copyright (C) 2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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 -#import -#import -#import -#import -#import -#import -#import - -#import "NSString+MAPIStore.h" -#import "NSData+MAPIStore.h" -#import "NSDate+MAPIStore.h" - -#include -#include -#include -#undef DEBUG -#include - -#import "iCalTimeZone+MAPIStore.h" -#import "MAPIStoreTypes.h" - -@interface iCalTimeZonePeriod (MAPIStorePropertiesPrivate) - -- (void) _fillTZDate: (struct SYSTEMTIME *) tzData; - -@end - -@implementation iCalTimeZonePeriod (MAPIStorePropertiesPrivate) - -- (void) _fillTZDate: (struct SYSTEMTIME *) tzData -{ - iCalRecurrenceRule *rrule; - NSArray *byMonth; - iCalByDayMask *mask; - NSCalendarDate *dateValue; - int16_t wDay; - - rrule = [self recurrenceRule]; - byMonth = [rrule byMonth]; - if ([byMonth count] > 0) - { - tzData->wMonth = [[byMonth objectAtIndex: 0] intValue]; - mask = [rrule byDayMask]; - tzData->wDayOfWeek = [mask firstDay]; - wDay = [mask firstOccurrence]; - if (wDay < 0) - /* [MS-OXOCAL] the wDay field is set to indicate the - occurrence of the day of the week within the month (1 to - 5, where 5 indicates the final occurrence during the - month if that day of the week does not occur 5 times). */ - wDay += 6; - tzData->wDay = (uint16_t) wDay; - - dateValue = [self startDate]; - tzData->wHour = [dateValue hourOfDay]; - tzData->wMinute = [dateValue minuteOfHour]; - tzData->wSecond = [dateValue secondOfMinute]; - } -} - -@end - -@implementation iCalTimeZone (MAPIStoreProperties) - -- (iCalTimeZonePeriod *) _mostRecentPeriodWithName: (NSString *) periodName -{ - NSArray *periods; - iCalTimeZonePeriod *period; - NSUInteger max; - - periods = [self childrenWithTag: periodName]; - max = [periods count]; - if (max > 0) - { - periods = [periods sortedArrayUsingSelector: @selector (compare:)]; - period = (iCalTimeZonePeriod *) [periods objectAtIndex: (max - 1)]; - } - else - period = nil; - - return period; -} - -- (struct Binary_r *) asTimeZoneStructInMemCtx: (TALLOC_CTX *) memCtx -{ - iCalTimeZonePeriod *period; - struct TimeZoneStruct tz; - int32_t lBias, dlBias; - - memset (&tz, 0, sizeof (struct TimeZoneStruct)); - period = [self _mostRecentPeriodWithName: @"STANDARD"]; - lBias = -[period secondsOffsetFromGMT] / 60; - tz.lBias = lBias; - [period _fillTZDate: &tz.stStandardDate]; - period = [self _mostRecentPeriodWithName: @"DAYLIGHT"]; - if (!period) - tz.stStandardDate.wMonth = 0; - dlBias = -([period secondsOffsetFromGMT] / 60) - lBias; - tz.lDaylightBias = dlBias; - [period _fillTZDate: &tz.stDaylightDate]; - tz.wStandardYear = tz.stStandardDate.wYear; - tz.wDaylightYear = tz.stDaylightDate.wYear; - - return set_TimeZoneStruct (memCtx, &tz); -} - -- (struct Binary_r *) asZoneTimeDefinitionWithFlags: (enum TZRuleFlag) flags - inMemCtx: (TALLOC_CTX *) memCtx -{ - iCalTimeZonePeriod *period; - struct TimeZoneDefinition definition; - struct TZRule rule; - NSString *tzId; - int lBias, dlBias; - - memset (&definition, 0, sizeof (struct TimeZoneDefinition)); - - definition.major = 0x02; - definition.minor = 0x01; - definition.reserved = 0x0002; - - tzId = [self tzId]; - definition.keyName = [tzId asUnicodeInMemCtx: memCtx]; - definition.cbHeader = 6 + [tzId length] * 2; - - definition.cRules = 1; - definition.TZRules = &rule; - - memset (&rule, 0, sizeof (struct TZRule)); - rule.major = 0x02; - rule.minor = 0x01; - rule.reserved = 0x003e; - rule.flags = flags; - - period = [self _mostRecentPeriodWithName: @"STANDARD"]; - rule.wYear = [[period startDate] yearOfCommonEra]; - lBias = -[period secondsOffsetFromGMT] / 60; - rule.lBias = lBias; - [period _fillTZDate: &rule.stStandardDate]; - period = [self _mostRecentPeriodWithName: @"DAYLIGHT"]; - if (!period) - rule.stStandardDate.wMonth = 0; - dlBias = -([period secondsOffsetFromGMT] / 60) - lBias; - rule.lDaylightBias = dlBias; - [period _fillTZDate: &rule.stDaylightDate]; - - - return set_TimeZoneDefinition (memCtx, &definition); -} - -- (NSString *) _offsetStringFromOffset: (NSInteger) offset -{ - NSInteger offsetHours, offsetMins; - NSString *offsetSign; - - /* The offset format is, eg, "+0200" for 2 hours 0 minutes ahead */ - if (offset < 0) - offsetSign = @"-"; - else - offsetSign = @"+"; - offsetHours = abs (offset) / 60; - offsetMins = abs (offset) % 60; - - return [NSString stringWithFormat: @"%@%d%d%d%d", - offsetSign, offsetHours / 10, offsetHours % 10, - offsetMins / 10, offsetMins % 10]; - -} - -- (NSString *) _rRuleStringFromSystemTime: (struct SYSTEMTIME) date -{ - NSString *result, *byDay; - - /* The conversion tables between the SYSTEMTIME fields and the RRULE ones - can be found at [MS-OXCICAL] 2.1.3.2.1 */ - if (date.wDay == 5) - byDay = @"-1"; - else - byDay = [NSString stringWithFormat: @"%d", date.wDay]; - - switch (date.wDayOfWeek) - { - case iCalWeekDaySunday: - byDay = [byDay stringByAppendingString: @"SU"]; - break; - case iCalWeekDayMonday: - byDay = [byDay stringByAppendingString: @"MO"]; - break; - case iCalWeekDayTuesday: - byDay = [byDay stringByAppendingString: @"TU"]; - break; - case iCalWeekDayWednesday: - byDay = [byDay stringByAppendingString: @"WE"]; - break; - case iCalWeekDayThursday: - byDay = [byDay stringByAppendingString: @"TH"]; - break; - case iCalWeekDayFriday: - byDay = [byDay stringByAppendingString: @"FR"]; - break; - case iCalWeekDaySaturday: - byDay = [byDay stringByAppendingString: @"SA"]; - break; - } - - result = [NSString stringWithFormat: @"FREQ=YEARLY;BYDAY=%@;BYMONTH=%d", byDay, date.wMonth]; - - return result; -} - -- (iCalTimeZone *) iCalTimeZoneFromDefinition: (NSData *) value - withDescription: (NSString *) description - inMemCtx: (TALLOC_CTX *) memCtx -{ - BOOL daylightDefined = NO, ruleFound = NO; - iCalDateTime *daylightStart, *standardStart; - iCalRecurrenceRule *daylightRRule, *standardRRule; - iCalTimeZone *tz = nil; - iCalTimeZonePeriod *daylight, *standard; - NSCalendarDate *dlStartValue, *stStartValue; - NSString *strOffsetFrom, *strOffsetTo, *tzID; - char *keyName; - struct Binary_r *binValue; - struct SYSTEMTIME initDate; - struct TimeZoneDefinition *definition; - struct TZRule rule; - uint16_t count; - - binValue = [value asBinaryInMemCtx: memCtx]; - definition = get_TimeZoneDefinition (memCtx, binValue); - - if (!definition) - return nil; - - if (!definition->cRules) - goto end; - - for (count = 0; count < definition->cRules; count++) - { - /* ([MS-OXCICAL] 2.1.3.1.1.19) The TZRule with the - TZRULE_FLAG_EFFECTIVE_TZREG bit set in the TZRule flags field - is the one that MUST be exported */ - if (definition->TZRules[count].flags & TZRULE_FLAG_EFFECTIVE_TZREG) - { - rule = definition->TZRules[count]; - ruleFound = YES; - break; - } - } - - if (!ruleFound) - goto end; - - if (!description) - { - /* The cbHeader field contains the size, in bytes of the Reserved (2b), - cchKeyName (2b) keyName (variable Unicode string) and cRules (2b) - ([MS-OXOCAL] 2.2.1.41). The keyName field is a non-NULL-terminated - char array. */ - keyName = talloc_strndup (memCtx, definition->keyName, (definition->cbHeader - 6) / 2); - tzID = [NSString stringWithCString: keyName - encoding: [NSString defaultCStringEncoding]]; - talloc_free (keyName); - } - else - tzID = [NSString stringWithString: description]; - - tz = [iCalTimeZone groupWithTag: @"vtimezone"]; - [tz addChild: [CardElement simpleElementWithTag: @"tzid" - value: tzID]]; - - if (rule.stStandardDate.wMonth != 0) - daylightDefined = YES; - - /* STANDARD TIME ([MS-OXCICAL] 2.1.3.1.1.19.2) */ - standard = [iCalTimeZonePeriod groupWithTag: @"standard"]; - - /* TZOFFSETFROM = -1 * (PidLidTimeZoneStruct.lBias + PidLidTimeZoneStruct.lDaylightBias) */ - strOffsetFrom = [self _offsetStringFromOffset: -1 * (rule.lBias + rule.lDaylightBias)]; - [standard addChild: [CardElement simpleElementWithTag: @"tzoffsetfrom" - value: strOffsetFrom]]; - - /* TZOFFSETTO = -1 * (PidLidTimeZoneStruct.lBias + PidLidTimeZoneStruct.lStandardBias) */ - strOffsetTo = [self _offsetStringFromOffset: -1 * (rule.lBias + rule.lStandardBias)]; - [standard addChild: [CardElement simpleElementWithTag: @"tzoffsetto" - value: strOffsetTo]]; - - /* DTSTART & RRULE are derived from the stStandardDate and wYear properties */ - standardStart = [iCalDateTime elementWithTag: @"dtstart"]; - - initDate = rule.stStandardDate; - stStartValue = [NSCalendarDate dateFromSystemTime: initDate - andRuleYear: rule.wYear]; - - [standardStart setDateTime: stStartValue]; - [standard addChild: standardStart]; - - if (daylightDefined) - { - standardRRule = [[iCalRecurrenceRule alloc] initWithString: [self _rRuleStringFromSystemTime: initDate]]; - [standard addChild: standardRRule]; - - /* DAYLIGHT SAVING TIME ([MS-OXCICAL] 2.1.3.1.1.19.3) */ - daylight = [iCalTimeZonePeriod groupWithTag: @"daylight"]; - /* TZOFFSETFROM = -1 * (PidLidTimeZoneStruct.lBias + PidLidTimeZoneStruct.lStandardBias) */ - [daylight addChild: [CardElement simpleElementWithTag: @"tzoffsetfrom" - value: strOffsetTo]]; - /* TZOFFSETTO = -1 * (PidLidTimeZoneStruct.lBias + PidLidTimeZoneStruct.lDaylightBias) */ - [daylight addChild: [CardElement simpleElementWithTag: @"tzoffsetto" - value: strOffsetFrom]]; - - /* DTSTART & RRULE are derived from the stDaylightDate and wYear properties */ - daylightStart = [iCalDateTime elementWithTag: @"dtstart"]; - initDate = rule.stDaylightDate; - dlStartValue = [NSCalendarDate dateFromSystemTime: initDate - andRuleYear: rule.wYear]; - - [daylightStart setDateTime: dlStartValue]; - [daylight addChild: daylightStart]; - - daylightRRule = [[iCalRecurrenceRule alloc] initWithString: [self _rRuleStringFromSystemTime: initDate]]; - [daylight addChild: daylightRRule]; - [tz addChild: daylight]; - } - [tz addChild: standard]; - -end: - - talloc_free (definition); - return tz; -} - -/** - * Adjust a date in this vTimeZone to its representation in UTC - * Example: Timezone is +0001, the date is 2015-12-15 00:00:00 +0000 - * it returns 2015-12-14 23:00:00 +0000 - * @param date the date to adjust to the timezone. - * @return a new GMT date adjusted with the offset of the timezone. - */ -- (NSCalendarDate *) shiftedCalendarDateForDate: (NSCalendarDate *) date -{ - NSCalendarDate *tmpDate; - - tmpDate = [date copy]; - [tmpDate autorelease]; - - [tmpDate setTimeZone: utcTZ]; - - return [tmpDate addYear: 0 month: 0 day: 0 - hour: 0 minute: 0 - second: -[[self periodForDate: tmpDate] secondsOffsetFromGMT]]; -} - -@end diff --git a/OpenChange/plreader.m b/OpenChange/plreader.m deleted file mode 100644 index 69d0cd099..000000000 --- a/OpenChange/plreader.m +++ /dev/null @@ -1,99 +0,0 @@ -/* plreader.m - this file is part of SOGo - * - * Copyright (C) 2011-2012 Inverse inc - * - * Author: Wolfgang Sourdeau - * - * 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. - */ - -/* A format-agnostic property list dumper. - Usage: plreader [filename] */ - -#import -#import -#import - -#import "NSObject+PropertyList.m" - -static void -OCDumpPListData (NSData *content) -{ - //NSDictionary *d; - //NSPropertyListFormat format; - //NSString *error = nil; - //const char *formatName; - - //d = [NSPropertyListSerialization propertyListFromData: content - // mutabilityOption: NSPropertyListImmutable - // format: &format - // errorDescription: &error]; - //d = [content BSONValue]; - - // if (d) - // { - // switch (format) - // { - // case NSPropertyListOpenStepFormat: - // formatName = "OpenStep"; - // break; - // case NSPropertyListXMLFormat_v1_0: - // formatName = "XML"; - // break; - // case NSPropertyListBinaryFormat_v1_0: - // formatName = "Binary"; - // break; - // case NSPropertyListGNUstepFormat: - // formatName = "GNUstep"; - // break; - // case NSPropertyListGNUstepBinaryFormat: - // formatName = "GNUstep binary"; - // break; - // default: formatName = "unknown"; - // } - - // printf ("File format is: %s\n", formatName); - // [d displayWithIndentation: 0]; - // printf ("\n"); - // } - // else - // printf ("an error occurred: %s\n", [error UTF8String]); -} - -static void -PLReaderDumpPListFile (NSString *filename) -{ - NSData *content; - - content = [NSData dataWithContentsOfFile: filename]; - OCDumpPListData (content); -} - -int main() -{ - NSAutoreleasePool *p; - NSProcessInfo *pi; - NSArray *arguments; - - p = [NSAutoreleasePool new]; - pi = [NSProcessInfo processInfo]; - arguments = [pi arguments]; - if ([arguments count] > 1) - PLReaderDumpPListFile ([arguments objectAtIndex: 1]); - [p release]; - - return 0; -} diff --git a/OpenChange/product.plist b/OpenChange/product.plist deleted file mode 100644 index 87075ccfb..000000000 --- a/OpenChange/product.plist +++ /dev/null @@ -1,3 +0,0 @@ -{ - requires = ( MAIN, Appointments, Contacts, Mailer ); -} diff --git a/OpenChange/samba-get-config.py b/OpenChange/samba-get-config.py deleted file mode 100755 index 06311d996..000000000 --- a/OpenChange/samba-get-config.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python - -import sys -import samba.param - -a = samba.param.LoadParm() -a.set('debug level', '0') -a.load_default() -print a.get(sys.argv[1]) diff --git a/packaging/debian/rules b/packaging/debian/rules index d93cf46ac..b0c6ca662 100755 --- a/packaging/debian/rules +++ b/packaging/debian/rules @@ -6,9 +6,7 @@ export DH_VERBOSE=1 DESTDIR=$(CURDIR)/debian/tmp DIST_CODENAME=$(shell lsb_release -cs) -#ifeq ($(DIST_CODENAME), squeeze) SAML2_CONFIG=--enable-saml2 -#endif include /etc/GNUstep/GNUstep.conf include /usr/share/GNUstep/Makefiles/common.make @@ -24,9 +22,6 @@ build-arch: build-arch-stamp build-arch-stamp: config.make # Add here commands to compile the arch part of the package. $(MAKE) - if pkg-config --atleast-version=1.0 libmapi; \ - then (cd OpenChange; $(MAKE)); \ - fi (cd ActiveSync && $(MAKE)) touch $@ @@ -39,14 +34,9 @@ clean: -find Tests -name "*.pyc" -exec rm -f {} \; if [ -f config.make ]; \ then \ - if pkg-config --atleast-version=1.0 libmapi; \ - then \ - (cd OpenChange; make clean); \ - fi; \ (cd ActiveSync; $(MAKE) clean); \ make clean; \ fi - -rm -f OpenChange/MAPIStorePropertySelectors.* -rm -f config.make dh_clean diff --git a/packaging/rhel/sogo.spec b/packaging/rhel/sogo.spec index e28207e95..0ae20352e 100644 --- a/packaging/rhel/sogo.spec +++ b/packaging/rhel/sogo.spec @@ -1,17 +1,4 @@ -# We disable OpenChange builds on el5 since it's prehistoric -%define enable_openchange 0 -%{?el5:%define enable_openchange 0} -%{?el6:%define enable_openchange 0} -%{?el7:%define enable_openchange 0} - -%ifarch %ix86 -%define enable_openchange 0 -%endif - %{!?sogo_major_version: %global sogo_major_version %(/bin/echo %{sogo_version} | /bin/cut -f 1 -d .)} -%if %enable_openchange -%global oc_build_depends samba4 openchange -%endif %{!?python_sys_pyver: %global python_sys_pyver %(/usr/bin/python -c "import sys; print sys.hexversion")} @@ -138,29 +125,11 @@ AutoReqProv: off %description -n sope%{sope_major_version}%{sope_minor_version}-cards-devel SOPE versit parsing library for iCal and VCard formats -%if %enable_openchange -%package openchange-backend -Summary: SOGo backend for OpenChange -Group: Productivity/Groupware -AutoReqProv: off - -%description openchange-backend -SOGo backend for OpenChange -%endif - ######################################## %prep rm -fr ${RPM_BUILD_ROOT} %setup -q -n SOGo-%{sogo_version} - -# small tweak to the python script for RHEL5 -# if hex(sys.hexversion) < 0x02060000 -#%if %{python_sys_pyver} < 33947648 -# sed -i 's!/usr/bin/env python!/usr/bin/env python2.6!' Scripts/openchange_user_cleanup -#%endif - - # ****************************** build ******************************** %build . /usr/lib64/GNUstep/Makefiles/GNUstep.sh @@ -177,13 +146,6 @@ esac make CC="$cc" LDFLAGS="$ldflags" messages=yes -# OpenChange -%if %enable_openchange -(cd OpenChange; \ - LD_LIBRARY_PATH=../SOPE/NGCards/obj:../SOPE/GDLContentStore/obj \ - make GNUSTEP_INSTALLATION_DOMAIN=SYSTEM ) -%endif - # ****************************** install ****************************** %install QA_SKIP_BUILD_ROOT=1 @@ -216,7 +178,6 @@ install -d ${RPM_BUILD_ROOT}/var/run/sogo install -d ${RPM_BUILD_ROOT}/var/spool/sogo install -d -m 750 -o %sogo_user -g %sogo_user ${RPM_BUILD_ROOT}/etc/sogo install -m 640 -o %sogo_user -g %sogo_user Scripts/sogo.conf ${RPM_BUILD_ROOT}/etc/sogo/ -#install -m 755 Scripts/openchange_user_cleanup ${RPM_BUILD_ROOT}/%{_sbindir} cat Apache/SOGo.conf | sed -e "s@/lib/@/%{_lib}/@g" > ${RPM_BUILD_ROOT}/etc/httpd/conf.d/SOGo.conf install -m 600 Scripts/sogo.cron ${RPM_BUILD_ROOT}/etc/cron.d/sogo cp Scripts/tmpwatch ${RPM_BUILD_ROOT}/etc/cron.daily/sogo-tmpwatch @@ -230,16 +191,6 @@ chmod 644 ${RPM_BUILD_ROOT}/etc/tmpfiles.d/sogo.conf cp Scripts/sogo-default ${RPM_BUILD_ROOT}/etc/sysconfig/sogo rm -rf ${RPM_BUILD_ROOT}%{_bindir}/test_quick_extract -# OpenChange -%if %enable_openchange -(cd OpenChange; \ - LD_LIBRARY_PATH=${RPM_BUILD_ROOT}%{_libdir} \ - make DESTDIR=${RPM_BUILD_ROOT} \ - GNUSTEP_INSTALLATION_DOMAIN=SYSTEM \ - CC="$cc" LDFLAGS="$ldflags" \ - install) -%endif - # ActiveSync (cd ActiveSync; \ LD_LIBRARY_PATH=${RPM_BUILD_ROOT}%{_libdir} \ @@ -265,7 +216,6 @@ rm -fr ${RPM_BUILD_ROOT} %dir %attr(0700, %sogo_user, %sogo_user) %{_var}/spool/sogo %dir %attr(0750, root, %sogo_user) %{_sysconfdir}/sogo %{_sbindir}/sogod -#%{_sbindir}/openchange_user_cleanup %{_libdir}/sogo/libSOGo.so* %{_libdir}/sogo/libSOGoUI.so* %{_libdir}/GNUstep/SOGo/AdministrationUI.SOGo @@ -339,13 +289,6 @@ rm -fr ${RPM_BUILD_ROOT} %{_includedir}/NGCards %{_libdir}/sogo/libNGCards.so* -%if %enable_openchange -%files openchange-backend -%defattr(-,root,root,-) -%{_libdir}/GNUstep/SOGo/*.MAPIStore -%{_libdir}/mapistore_backends/* -%endif - # **************************** pkgscripts ***************************** %pre if ! getent group %sogo_user >& /dev/null; then