pax_global_header00006660000000000000000000000064145653760420014526gustar00rootroot0000000000000052 comment=58190f628c58d80a95743dab287ac4d7fbc34079 libmrss-0.19.4/000077500000000000000000000000001456537604200132745ustar00rootroot00000000000000libmrss-0.19.4/.gitignore000066400000000000000000000004171456537604200152660ustar00rootroot00000000000000*.o *.lo Makefile Makefile.in .deps .libs aclocal.m4 autom4te.cache/ compile config.guess config.h config.h.in config.log config.status config.sub configure depcomp doxy.conf install-sh libtool ltmain.sh m4/ missing mrss.pc src/libmrss.la src/mrss.h stamp-h1 test-driver libmrss-0.19.4/AUTHORS000066400000000000000000000004671456537604200143530ustar00rootroot00000000000000Andrea Marchesini Thanks to: Robert Sandilands Bernhard Walle Matthieu Weber Holger Freyther Roelof Naude Vanilla I. Shu Andreas Krennmair libmrss-0.19.4/COPYING000066400000000000000000000575061456537604200143440ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, 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 this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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 Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS libmrss-0.19.4/ChangeLog000066400000000000000000000037771456537604200150640ustar00rootroot000000000000002024-02-21 libmrss 0.19.4 Fix a memory leak 2021-08-02 libmrss 0.19.3 Dacav's patches to fix crashes, indentation, tests, and much more. 2008-08-21 libmrss 0.19.2 Gregor Herrmann's patch about signals and curl 2008-02-26 libmrss 0.19.1 OpenEmbedded Project's patch applied (transfer buffer) Andreas Krennmair's patch applied (ATOM string) 2008-01-25 libmrss 0.19.0 atom type for the string tags (title, datatypes,..) 2007-07-08 libmrss 0.18.0 a new release with a new version number 2007-06-10 libmrss 0.17.4 curl code with an error 2007-06-09 libmrss 0.17.3 locale check jerome's patch about INCLUDE and srcdir Holger Freyther's patch about atom writting CURLcode error, mrss_curl_strerror and mrss_parse_url_with_options_and_error function 2007-05-02 libmrss 0.17.2 patch about tm_mon - 1 patch 27: mrss_get_last_modified_with_options ignores proxy settings patch 26: mrss_free does not check for NULL mrss_t pointer 2007-04-02 libmrss 0.17.1 2 memory leaks fixed locale about the datatime in atom feed Holger Freyther's patches 2007-02-10 libmrss 0.17 other_tags and attributes atom supported 2006-12-29 libmrss 0.16 libnxml 0.16 updated 2006-11-22 libmrss 0.15 libnxml 0.15 with cacert support php updated 2006-10-28 libmrss 0.14 libnxml 0.14 updated 2006-09-11 libmrss 0.13 options struct for timeout, proxy and certficate. removed mrss_set/get_timeout. 2006-06-12 libmrss 0.12 mrss.pc updated 2006-03-21 libmrss 0.11 copyright updates enclouse with only argoments support for podcast 2006-03-07 libmrss 0.10 some memory leaks 2006-02-27 libmrss 0.9 mrss_write_url php bug fixes 2006-02-06 libmrss 0.8 encoding in mrss_t 2005-01-20 libmrss 0.7 mrss_get_last_modified a new test (time.c) doxygen mainpage 2005-01-14 libmrss 0.6 bug fixes in the write function 2006-01-04 libmrss 0.5 GPL -> LGPL 2005-12-15 libmrss 0.4 mrss_set_timeout mrss_get_timeout 2005-11-01 libmrss 0.3 libxml2 -> libnxml rss 1.0 2005-07-27 libmrss 0.2 phpsupport doxygen libmrss-0.19.4/Makefile.am000066400000000000000000000002241456537604200153260ustar00rootroot00000000000000SUBDIRS = src test doc phpmrss EXTRA_DIST = mrss.pc mrss.pc.in doxy.conf doxy.conf.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = mrss.pc libmrss-0.19.4/README000066400000000000000000000001621456537604200141530ustar00rootroot00000000000000mRSS is a C library for parsing, writing and creating RSS files or streams. Read the test/*.c files as examples. libmrss-0.19.4/autogen.sh000077500000000000000000000001331456537604200152720ustar00rootroot00000000000000#!/bin/sh set -e aclocal libtoolize autoheader autoconf automake --add-missing --foreign libmrss-0.19.4/configure.ac000066400000000000000000000043431456537604200155660ustar00rootroot00000000000000m4_define([libmrss_major_version], [0]) m4_define([libmrss_minor_version], [19]) m4_define([libmrss_macro_version], [4]) m4_define([libmrss_version], [libmrss_major_version.libmrss_minor_version.libmrss_macro_version]) m4_define([libmrss_version_info], [libmrss_minor_version:libmrss_macro_version:libmrss_minor_version]) AC_INIT([libmrss], [libmrss_version]) AC_CONFIG_SRCDIR([src/mrss_generic.c]) AC_CONFIG_MACRO_DIRS([m4]) AM_INIT_AUTOMAKE AM_SANITY_CHECK AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE AC_PROG_CC AC_GNU_SOURCE AC_ISC_POSIX AC_PROG_LIBTOOL AC_PROG_INSTALL AM_PROG_CC_STDC AC_HEADER_STDC AC_HEADER_DIRENT LT_INIT AC_CHECK_HEADER(curl/curl.h,, AC_MSG_ERROR(libcurl is required to compile libmrss)) AC_CHECK_LIB(curl,curl_version,, AC_MSG_ERROR(libcurl is required to compile libmrss)) PKG_CHECK_MODULES(NXML, nxml >= 0.18 , nxml=yes, nxml=no) if test "$nxml" = no; then AC_MSG_ERROR(libnXML is required to compile libmrss!) fi # LOCALE CHECKS... AC_MSG_CHECKING(for locale enviroment) AH_TEMPLATE([USE_LOCALE], [Define to 1 if we can use locale]) AH_TEMPLATE([USE_X_LOCALE], [Define to 1 if this is a macosx or xlocale compatible OS]) AH_TEMPLATE([USE_GENERIC_LOCALE], [Define to 1 if this is a generic OS with locale support]) AC_TRY_COMPILE([ #include ], [newlocale (LC_ALL_MASK, "C", NULL)], x_locale=yes, x_locale=no) if test "$x_locale" = "yes"; then AC_DEFINE(USE_X_LOCALE) AC_DEFINE(USE_LOCALE) use_locale=yes fi AC_TRY_COMPILE([ #include ], [newlocale (LC_ALL_MASK, "C", NULL)], generic_locale=yes, generic_locale=no) if test "$generic_locale" = "yes"; then AC_DEFINE(USE_GENERIC_LOCALE) AC_DEFINE(USE_LOCALE) use_locale=yes fi if test "$use_locale" = "yes"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi LDFLAGS="$LDFLAGS $NXML_LIBS" CFLAGS="$CFLAGS $NXML_CFLAGS -Wall" AC_SUBST(LIBMRSS_VERSION, [libmrss_version]) AC_SUBST(LIBMRSS_VERSION_INFO, [libmrss_version_info]) AC_SUBST(LIBMRSS_MAJOR_VERSION, [libmrss_major_version]) AC_SUBST(LIBMRSS_MINOR_VERSION, [libmrss_minor_version]) AC_SUBST(LIBMRSS_MICRO_VERSION, [libmrss_macro_version]) AC_OUTPUT([ Makefile src/mrss.h src/Makefile test/Makefile doc/Makefile phpmrss/Makefile mrss.pc doxy.conf ]) libmrss-0.19.4/doc/000077500000000000000000000000001456537604200140415ustar00rootroot00000000000000libmrss-0.19.4/doc/Makefile.am000066400000000000000000000000271456537604200160740ustar00rootroot00000000000000EXTRA_DIST = main.doxy libmrss-0.19.4/doc/main.doxy000066400000000000000000000064721456537604200157030ustar00rootroot00000000000000/*!\mainpage mRss Library * * \section Author * Andrea Marchesini - Web Site: * https://github.com/bakulf/libmrss * * \section Description * * mRss is a C library for parsing, writing and creating RSS/ATOM files or * streams. This library can be also used not only in C or C++, but also * in PHP with the PHP extension. * * This library supports: * - RSS 0.91 - http://my.netscape.com/publish/formats/rss-spec-0.91.html * - RSS 0.92 - http://backend.userland.com/rss092 * - RSS 1.0 - http://web.resource.org/rss/1.0/ * - RSS 2.0 - http://www.rssboard.org/rss-specification * - ATOM 0.3 - http://www.mnot.net/drafts/draft-nottingham-atom-format-02.html * - ATOM 1.0 - http://tools.ietf.org/html/rfc4287 * * \section License * * mRss is a FreeSoftware project released under * LGPL 2.0. * * \section Required * * - nXML is a C * library for parsing, writing and creating XML 1.0 and 1.1 files or streams. * It supports utf-8, utf-16be and utf-16le, ucs-4 (1234, 4321, 2143, 2312). * - libcurl is a free and easy-to-use * client-side URL transfer library, supporting FTP, FTPS, HTTP, HTTPS, SCP, * SFTP, TFTP, TELNET, DICT, FILE and LDAP. libcurl supports SSL certificates, * HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, * cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, * Kerberos4), file transfer resume, http proxy tunneling and more! * * For the PHP extension: * - php http://www.php.net/ * * \section Download * * - libmrss https://github.com/bakulf/libmrss * * \section install1 Installation from source * * \code * tar xvfz libmrss-.tar.gz * cd libmrss- * ./configure --prefix=/usr * make * make install * \endcode * * If you want the PHP extension: * * \code * cd phpmrss * ./phpmrss_install.sh * \endcode * * \section install2 Installation from CVS * Run the following commands in a directory that you have write access to * (such as your home dirctory): * * \code * cvs -d:pserver:anonymous@ippolita.net:/home/cvs login * \endcode * (Just hit enter for the password) * \code * cvs -z3 -d:pserver:anonymous@ippolita.net:/home/cvs co libmrss * \endcode * * Once you have checked the source of libmrss, run the following commands: * * \code * cd libmrss * ./autogen.sh * ./configure --prefix=/usr * make * make install * \endcode * * When there are changes to libmrss's code, you will want to update you local * copy. Run from the directory libmrss: * * \code * cvs update -dP * ./autogen.sh * ./configure --prefix=/usr * make * make install * \endcode * * \section Support * * Support for mRss is available to all via email: baku@ippolita.net * * \section support1 Commercial Support * Commercial users of mRss are strongly encouraged to purchase a commercial * support contract, please contact me for a quotation. I will always * prioritise support requests from those with support contracts. * * \section Donations * Users not purchasing commercial support are encouraged (but not obliged) to * make a donation. By donating you are supporting the principle of open * source software and you will help ensure continued development of mRss. */ libmrss-0.19.4/doxy.conf.in000066400000000000000000000202721456537604200155360ustar00rootroot00000000000000# Doxyfile 0.1 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = @PACKAGE@ PROJECT_NUMBER = @VERSION@ OUTPUT_DIRECTORY = doc CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = NO STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = YES INHERIT_DOCS = NO DISTRIBUTE_GROUP_DOC = NO SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = NO EXTRACT_LOCAL_METHODS = NO HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = YES FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = src/ \ doc/ FILE_PATTERNS = mrss.h \ main.doxy RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXAMPLE_PATH = EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES INLINE_SOURCES = YES STRIP_CODE_COMMENTS = NO REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = NO HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES CLASS_GRAPH = NO COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = YES INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = YES GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = /usr/bin/dot DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 MAX_DOT_GRAPH_HEIGHT = 1024 MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO libmrss-0.19.4/mrss.pc.in000066400000000000000000000003751456537604200152160ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=@includedir@ Name: libmrss Description: library C for creating, parsing and writing feed rss Version: @VERSION@ Requires: nxml Libs: -L${libdir} -lmrss Cflags: -I${includedir} libmrss-0.19.4/phpmrss/000077500000000000000000000000001456537604200147705ustar00rootroot00000000000000libmrss-0.19.4/phpmrss/Makefile.am000066400000000000000000000000751456537604200170260ustar00rootroot00000000000000EXTRA_DIST = config.m4 README php.c phpmrss_install.sh *.php libmrss-0.19.4/phpmrss/README000066400000000000000000000001161456537604200156460ustar00rootroot00000000000000Install: phpize ./configure make make install Or: ./phpmrss_install.sh libmrss-0.19.4/phpmrss/all.php000066400000000000000000000003441456537604200162520ustar00rootroot00000000000000 libmrss-0.19.4/phpmrss/config.m4000066400000000000000000000022531456537604200165010ustar00rootroot00000000000000PHP_ARG_WITH(mrss, for MRSS support, [ --with-mrss=DIR Include MRSS support where DIR is MRSS install prefix. If DIR is not set, the bundled MRSS library will be used.]) PHP_ARG_ENABLE(mrss, Support for mrss, [ --enable-mrss Enable mrss support]) if test "$PHP_MRSS" = "yes"; then for i in $with_mrss /usr/local /usr; do if test -f $i/lib/libmrss.$SHLIB_SUFFIX_NAME -o -f $i/lib/libmrss.a; then MRSS_DIR=$i fi done if test -z "$MRSS_DIR"; then AC_MSG_ERROR("Please reinstall mrss distribution. libmrss.(a|so) not found.) fi if test -f $MRSS_DIR/include/mrss.h; then MRSS_INC_DIR=$MRSS_DIR/include fi if test -z "$MRSS_INC_DIR"; then AC_MSG_ERROR("Please reinstall mrss distribution. mrss.h not found.) fi PHP_CHECK_LIBRARY(mrss, mrss_parse_url, [ AC_DEFINE(HAVE_MRSS, 1, [ ]) ],[ AC_MSG_ERROR([LiBOX library required.]) ], [ -L$MRSS_DIR/lib ] ) PHP_ADD_INCLUDE($MRSS_INC_DIR) PHP_ADD_LIBRARY_WITH_PATH(mrss, $MRSS_DIR/lib, MRSS_SHARED_LIBADD) PHP_NEW_EXTENSION(mrss, php.c, $ext_shared) PHP_SUBST(MRSS_SHARED_LIBADD) fi libmrss-0.19.4/phpmrss/php.c000066400000000000000000000410271456537604200157270ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include #define PHP_MRSS_VERSION "0.2" #define PHP_MRSS_EXTNAME "mrss" PHP_FUNCTION(mrss_parse_url); PHP_FUNCTION(mrss_parse_url_with_options); PHP_FUNCTION(mrss_parse_file); PHP_FUNCTION(mrss_parse_buffer); PHP_FUNCTION(mrss_write_file); PHP_FUNCTION(mrss_write_buffer); PHP_FUNCTION(mrss_free); PHP_FUNCTION(mrss_error); PHP_FUNCTION(mrss_strerror); PHP_FUNCTION(mrss_get); PHP_FUNCTION(mrss_get_last_modified); PHP_FUNCTION(mrss_get_last_modified_with_options); PHP_FUNCTION(mrss_options_new); PHP_FUNCTION(mrss_options_free); zend_module_entry mrss_module_entry; PHP_MINIT_FUNCTION(mrss) { REGISTER_LONG_CONSTANT("MRSS_OK", MRSS_OK, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MRSS_ERR_POSIX", MRSS_ERR_POSIX, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MRSS_ERR_PARSER", MRSS_ERR_PARSER, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MRSS_ERR_VERSION", MRSS_ERR_VERSION, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MRSS_ERR_DATA", MRSS_ERR_DATA, CONST_CS | CONST_PERSISTENT); return SUCCESS; } static function_entry mrss_functions[] = { PHP_FE (mrss_parse_url, NULL) PHP_FE (mrss_parse_url_with_options, NULL) PHP_FE (mrss_parse_file, NULL) PHP_FE (mrss_parse_buffer, NULL) PHP_FE (mrss_write_file, NULL) PHP_FE (mrss_write_buffer, NULL) PHP_FE (mrss_free, NULL) PHP_FE (mrss_error, NULL) PHP_FE (mrss_strerror, NULL) PHP_FE (mrss_get, NULL) PHP_FE (mrss_get_last_modified, NULL) PHP_FE (mrss_get_last_modified_with_options, NULL) PHP_FE (mrss_options_new, NULL) PHP_FE (mrss_options_free, NULL) {NULL, NULL, NULL} }; zend_module_entry mrss_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif PHP_MRSS_EXTNAME, mrss_functions, PHP_MINIT(mrss), NULL, NULL, NULL, NULL, #if ZEND_MODULE_API_NO >= 20010901 PHP_MRSS_VERSION, #endif STANDARD_MODULE_PROPERTIES }; ZEND_GET_MODULE (mrss); struct phpmrss_data { char magic_code[5]; mrss_t *mrss; mrss_error_t error; }; PHP_FUNCTION (mrss_parse_url) { char *url; int url_len; struct phpmrss_data *data; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &url,&url_len) == FAILURE) return; data=(struct phpmrss_data *)malloc(sizeof(struct phpmrss_data)); memset(data, 0, sizeof(struct phpmrss_data)); strcpy(data->magic_code, PHP_MRSS_EXTNAME); if((data->error=mrss_parse_url(url, &data->mrss))!=MRSS_OK) data->mrss=NULL; RETURN_LONG((long)data); } PHP_FUNCTION (mrss_parse_url_with_options) { char *url; int url_len; struct phpmrss_data *data; mrss_options_t *options; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &url,&url_len, &options) == FAILURE) return; data=(struct phpmrss_data *)malloc(sizeof(struct phpmrss_data)); memset(data, 0, sizeof(struct phpmrss_data)); strcpy(data->magic_code, PHP_MRSS_EXTNAME); if((data->error=mrss_parse_url_with_options(url, &data->mrss, options))!=MRSS_OK) data->mrss=NULL; RETURN_LONG((long)data); } PHP_FUNCTION (mrss_parse_file) { char *file; int file_len; struct phpmrss_data *data; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file,&file_len) == FAILURE) return; data=(struct phpmrss_data *)malloc(sizeof(struct phpmrss_data)); memset(data, 0, sizeof(struct phpmrss_data)); strcpy(data->magic_code, PHP_MRSS_EXTNAME); if((data->error=mrss_parse_file(file, &data->mrss))!=MRSS_OK) data->mrss=NULL; RETURN_LONG((long)data); } PHP_FUNCTION (mrss_parse_buffer) { char *buffer; int buffer_len; struct phpmrss_data *data; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buffer,&buffer_len) == FAILURE) return; data=(struct phpmrss_data *)malloc(sizeof(struct phpmrss_data)); memset(data, 0, sizeof(struct phpmrss_data)); strcpy(data->magic_code, PHP_MRSS_EXTNAME); if((data->error=mrss_parse_buffer(buffer, buffer_len, &data->mrss))!=MRSS_OK) data->mrss=NULL; RETURN_LONG((long)data); } PHP_FUNCTION (mrss_write_file) { char *file; int file_len; struct phpmrss_data *data; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &data, &file,&file_len) == FAILURE) return; if(!data || data->magic_code[0]!='m' || data->magic_code[1]!='r' || data->magic_code[2]!='s' || data->magic_code[3]!='s' || data->magic_code[4]!='\0') { php_error(E_ERROR, "The data object must be a MRSS element!"); return; } if(!data->mrss) { php_error(E_ERROR, "The data object must be a MRSS element not empty!"); return; } data->error=mrss_write_file(data->mrss, file); RETURN_BOOL(0); } PHP_FUNCTION (mrss_write_buffer) { struct phpmrss_data *data; char *buffer=NULL; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &data) == FAILURE) return; if(!data || data->magic_code[0]!='m' || data->magic_code[1]!='r' || data->magic_code[2]!='s' || data->magic_code[3]!='s' || data->magic_code[4]!='\0') { php_error(E_ERROR, "The data object must be a MRSS element!"); return; } if(!data->mrss) { php_error(E_ERROR, "The data object must be a MRSS element not empty!"); return; } data->error=mrss_write_buffer(data->mrss, &buffer); if(data->error!=MRSS_OK) { RETURN_EMPTY_STRING(); } else { RETURN_STRING(buffer, 1); } } PHP_FUNCTION (mrss_free) { struct phpmrss_data *data; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &data) == FAILURE) return; if(!data || data->magic_code[0]!='m' || data->magic_code[1]!='r' || data->magic_code[2]!='s' || data->magic_code[3]!='s' || data->magic_code[4]!='\0') { php_error(E_ERROR, "The data object must be a MRSS element!"); return; } mrss_free(data->mrss); free(data); RETURN_NULL(); } PHP_FUNCTION (mrss_error) { struct phpmrss_data *data; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &data) == FAILURE) return; if(!data || data->magic_code[0]!='m' || data->magic_code[1]!='r' || data->magic_code[2]!='s' || data->magic_code[3]!='s' || data->magic_code[4]!='\0') { php_error(E_ERROR, "The data object must be a MRSS element!"); return; } RETURN_LONG(data->error); } PHP_FUNCTION (mrss_strerror) { struct phpmrss_data *data; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &data) == FAILURE) return; if(!data || data->magic_code[0]!='m' || data->magic_code[1]!='r' || data->magic_code[2]!='s' || data->magic_code[3]!='s' || data->magic_code[4]!='\0') { php_error(E_ERROR, "The data object must be a MRSS element!"); return; } RETURN_STRING(mrss_strerror(data->error), 1); } PHP_FUNCTION (mrss_get) { struct phpmrss_data *data; zval *hour, *day, *category, *item, *category_zval, *item_zval; mrss_hour_t *h; mrss_day_t *d; mrss_category_t *c; mrss_item_t *ip; int i, j; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &data) == FAILURE) return; if(!data || data->magic_code[0]!='m' || data->magic_code[1]!='r' || data->magic_code[2]!='s' || data->magic_code[3]!='s' || data->magic_code[4]!='\0') { php_error(E_ERROR, "The data object must be a MRSS element!"); return; } if(!data->mrss) { php_error(E_ERROR, "The data object must be a MRSS element not empty!"); return; } if (array_init(return_value) == FAILURE) { FREE_ZVAL(return_value); return; } #define INSERT_STRING( x , y , z ) add_assoc_string (x, y, z ? z : "", 1) INSERT_STRING(return_value, "file", data->mrss->file); add_assoc_long(return_value, "size", data->mrss->size); INSERT_STRING(return_value, "encoding", data->mrss->encoding); add_assoc_long(return_value, "version", data->mrss->version); INSERT_STRING(return_value, "title", data->mrss->title); INSERT_STRING(return_value, "title_type", data->mrss->title_type); INSERT_STRING(return_value, "description", data->mrss->description); INSERT_STRING(return_value, "description_type", data->mrss->description_type); INSERT_STRING(return_value, "link", data->mrss->link); INSERT_STRING(return_value, "id", data->mrss->id); INSERT_STRING(return_value, "language", data->mrss->language); INSERT_STRING(return_value, "rating", data->mrss->rating); INSERT_STRING(return_value, "copyright", data->mrss->copyright); INSERT_STRING(return_value, "copyright_type", data->mrss->copyright_type); INSERT_STRING(return_value, "pubDate", data->mrss->pubDate); INSERT_STRING(return_value, "lastBuildDate", data->mrss->lastBuildDate); INSERT_STRING(return_value, "docs", data->mrss->docs); INSERT_STRING(return_value, "managingeditor", data->mrss->managingeditor); INSERT_STRING(return_value, "managingeditor_email", data->mrss->managingeditor_email); INSERT_STRING(return_value, "managingeditor_uri", data->mrss->managingeditor_uri); INSERT_STRING(return_value, "webMaster", data->mrss->webMaster); add_assoc_long(return_value, "ttl", data->mrss->ttl); INSERT_STRING(return_value, "about", data->mrss->about); INSERT_STRING(return_value, "contributor", data->mrss->contributor); INSERT_STRING(return_value, "contributor_email", data->mrss->contributor_email); INSERT_STRING(return_value, "contributor_uri", data->mrss->contributor_uri); INSERT_STRING(return_value, "generator", data->mrss->generator); INSERT_STRING(return_value, "generator_uri", data->mrss->generator_uri); INSERT_STRING(return_value, "generator_version", data->mrss->generator_version); INSERT_STRING(return_value, "image_title", data->mrss->image_title); INSERT_STRING(return_value, "image_url", data->mrss->image_url); INSERT_STRING(return_value, "image_link", data->mrss->image_link); add_assoc_long(return_value, "image_width", data->mrss->image_width); add_assoc_long(return_value, "image_height", data->mrss->image_height); INSERT_STRING(return_value, "image_description", data->mrss->image_description); INSERT_STRING(return_value, "textinput_title", data->mrss->textinput_title); INSERT_STRING(return_value, "textinput_description", data->mrss->textinput_description); INSERT_STRING(return_value, "textinput_name", data->mrss->textinput_name); INSERT_STRING(return_value, "textinput_link", data->mrss->textinput_link); INSERT_STRING(return_value, "cloud", data->mrss->cloud); INSERT_STRING(return_value, "cloud_domain", data->mrss->cloud_domain); add_assoc_long(return_value, "cloud_port", data->mrss->cloud_port); INSERT_STRING(return_value, "cloud_path", data->mrss->cloud_path); INSERT_STRING(return_value, "cloud_registerProcedure", data->mrss->cloud_registerProcedure); INSERT_STRING(return_value, "cloud_protocol", data->mrss->cloud_protocol); MAKE_STD_ZVAL(hour); if (array_init(hour) == FAILURE) { FREE_ZVAL(hour); return; } h=data->mrss->skipHours; i=0; while(h) { add_index_string(hour, i++, h->hour ? h->hour : "", 1); h=h->next; } add_assoc_zval(return_value,"skipHours", hour); MAKE_STD_ZVAL(day); if (array_init(day) == FAILURE) { FREE_ZVAL(day); return; } d=data->mrss->skipDays; i=0; while(d) { add_index_string(day, i++, d->day ? d->day : "", 1); d=d->next; } add_assoc_zval(return_value,"skipDays", day); MAKE_STD_ZVAL(category); if (array_init(category) == FAILURE) { FREE_ZVAL(category); return; } c=data->mrss->category; i=0; while(c) { MAKE_STD_ZVAL(category_zval); if (array_init(category_zval) == FAILURE) { FREE_ZVAL(category_zval); return; } INSERT_STRING(category_zval, "category", c->category); INSERT_STRING(category_zval, "domain", c->domain); INSERT_STRING(category_zval, "label", c->label); add_index_zval(category, i++, category_zval); c=c->next; } add_assoc_zval(return_value,"category", category); MAKE_STD_ZVAL(item); if (array_init(item) == FAILURE) { FREE_ZVAL(item); return; } ip=data->mrss->item; i=0; while(ip) { MAKE_STD_ZVAL(item_zval); if (array_init(item_zval) == FAILURE) { FREE_ZVAL(item_zval); return; } INSERT_STRING(item_zval, "title", ip->title); INSERT_STRING(item_zval, "title_type", ip->title_type); INSERT_STRING(item_zval, "link", ip->link); INSERT_STRING(item_zval, "description", ip->description); INSERT_STRING(item_zval, "description_type", ip->description_type); INSERT_STRING(item_zval, "copyright", ip->copyright); INSERT_STRING(item_zval, "copyright_type", ip->copyright_type); INSERT_STRING(item_zval, "author", ip->author); INSERT_STRING(item_zval, "author_email", ip->author_email); INSERT_STRING(item_zval, "author_uri", ip->author_uri); INSERT_STRING(item_zval, "contributor", ip->contributor); INSERT_STRING(item_zval, "contributor_email", ip->contributor_email); INSERT_STRING(item_zval, "contributor_uri", ip->contributor_uri); INSERT_STRING(item_zval, "comments", ip->comments); INSERT_STRING(item_zval, "pubDate", ip->pubDate); INSERT_STRING(item_zval, "guid", ip->guid); add_assoc_long(item_zval, "guid_isPermaLink", ip->guid_isPermaLink); INSERT_STRING(item_zval, "source", ip->source); INSERT_STRING(item_zval, "source_url", ip->source_url); INSERT_STRING(item_zval, "enclosure", ip->enclosure); INSERT_STRING(item_zval, "enclosure_url", ip->enclosure_url); add_assoc_long(item_zval, "enclosure_length", ip->enclosure_length); INSERT_STRING(item_zval, "enclosure_type", ip->enclosure_type); MAKE_STD_ZVAL(category); if (array_init(category) == FAILURE) { FREE_ZVAL(category); return; } c=data->mrss->category; j=0; while(c) { MAKE_STD_ZVAL(category_zval); if (array_init(category_zval) == FAILURE) { FREE_ZVAL(category_zval); return; } INSERT_STRING(category_zval, "category", c->category); INSERT_STRING(category_zval, "domain", c->domain); INSERT_STRING(category_zval, "label", c->label); add_index_zval(category, j++, category_zval); c=c->next; } add_assoc_zval(item_zval,"category", category); add_index_zval(item, i++, item_zval); ip=ip->next; } add_assoc_zval(return_value,"item", item); } PHP_FUNCTION (mrss_get_last_modified) { char *url; int url_len; time_t t; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &url,&url_len) == FAILURE) return; if(mrss_get_last_modified(url, &t)!=MRSS_OK) { RETURN_LONG(0); } else { RETURN_LONG((long)t); } } PHP_FUNCTION (mrss_get_last_modified_with_options) { char *url; int url_len; time_t t; mrss_options_t *options; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &url,&url_len, &options) == FAILURE) return; if(mrss_get_last_modified_with_options(url, &t, options)!=MRSS_OK) { RETURN_LONG(0); } else { RETURN_LONG((long)t); } } PHP_FUNCTION (mrss_options_new) { mrss_options_t *options; char *proxy, *certfile, *password, *authentication, *proxy_authentication, *user_agent, *cacert; int proxy_len, certfile_len, password_len, verifypeer, authentication_len, timeout, proxy_authentication_len, user_agent_len, cacert_len; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lssssslss", &timeout, &proxy, &proxy_len, &proxy_authentication, &proxy_authentication_len, &certfile, &certfile_len, &password, &password_len, &cacert, &cacert_len, &verifypeer, &authentication, &authentication_len, user_agent, user_agent_len) == FAILURE) return; options=mrss_options_new(timeout, proxy, proxy_authentication, certfile, password, cacert, verifypeer, authentication, user_agent); RETURN_LONG((long) options); } PHP_FUNCTION (mrss_options_free) { mrss_options_t *options; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &options) == FAILURE) return; if(options) mrss_options_free(options); RETURN_NULL(); } libmrss-0.19.4/phpmrss/phpmrss_install.sh000077500000000000000000000013031456537604200205460ustar00rootroot00000000000000#!/bin/bash function check { if ! test $1 = "0"; then echo " error." exit fi } echo -n "Creating a work directory... " rm -rf /tmp/phpmrss > /dev/null check $? mkdir /tmp/phpmrss > /dev/null check $? cp -r * /tmp/phpmrss > /dev/null check $? cd /tmp/phpmrss > /dev/null check $? echo " done." echo -n "Checking data with phpize... " phpize > /dev/null check $? echo " done." echo -n "Configuring... " ./configure > /dev/null check $? echo " done." echo -n "Compiling... " make > /dev/null check $? echo " done." echo -n "Installing... " make install > /dev/null check $? echo " done." echo -n "Removing work directory... " rm -rf /tmp/phpmrss > /dev/null check $? echo " done." # bye :) libmrss-0.19.4/src/000077500000000000000000000000001456537604200140635ustar00rootroot00000000000000libmrss-0.19.4/src/Makefile.am000066400000000000000000000005171456537604200161220ustar00rootroot00000000000000lib_LTLIBRARIES = libmrss.la libmrss_la_SOURCES = \ mrss_free.c \ mrss_parser.c \ mrss_write.c \ mrss_download.c \ mrss_edit.c \ mrss_generic.c \ mrss_options.c \ mrss_search.c libmrss_la_LDFLAGS = -version-info @LIBMRSS_VERSION_INFO@ EXTRA_DIST = mrss.h.in mrss.h mrss_internal.h incdir = $(includedir) inc_DATA = mrss.h libmrss-0.19.4/src/mrss.h.in000066400000000000000000000674351456537604200156440ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __M_RSS_H__ #define __M_RSS_H__ #include #include #define LIBMRSS_VERSION_STRING "@VERSION@" #define LIBMRSS_MAJOR_VERSION @LIBMRSS_MAJOR_VERSION@ #define LIBMRSS_MINOR_VERSION @LIBMRSS_MINOR_VERSION@ #define LIBMRSS_MICRO_VERSION @LIBMRSS_MICRO_VERSION@ #ifdef __cplusplus extern "C" { #endif typedef struct mrss_t mrss_t; typedef struct mrss_options_t mrss_options_t; typedef struct mrss_item_t mrss_item_t; typedef struct mrss_category_t mrss_category_t; typedef struct mrss_hour_t mrss_hour_t; typedef struct mrss_day_t mrss_day_t; typedef struct mrss_tag_t mrss_tag_t; typedef struct mrss_attribute_t mrss_attribute_t; typedef void * mrss_generic_t; /** This enum describes the error type of libmrss */ typedef enum { MRSS_OK = 0, /**< No error */ MRSS_ERR_POSIX, /**< For the correct error, use errno */ MRSS_ERR_PARSER, /**< Parser error */ MRSS_ERR_DOWNLOAD, /**< Download error */ MRSS_ERR_VERSION, /**< The RSS has a no compatible VERSION */ MRSS_ERR_DATA /**< The parameters are incorrect */ } mrss_error_t; typedef enum { MRSS_VERSION_0_91, /**< 0.91 RSS version */ MRSS_VERSION_0_92, /**< 0.92 RSS version */ MRSS_VERSION_1_0, /**< 1.0 RSS version */ MRSS_VERSION_2_0, /**< 2.0 RSS version */ MRSS_VERSION_ATOM_0_3, /**< 0.3 Atom version */ MRSS_VERSION_ATOM_1_0 /**< 1.0 Atom version */ } mrss_version_t; /** Flag list for mrss_set and mrss_get functions */ typedef enum { /* Generic */ /** Set the ersion to a mrss_t element - the value is a mrss_version_t enum */ MRSS_FLAG_VERSION = 1, /** Set the title to a mrss_t element - the value is a string */ MRSS_FLAG_TITLE, /** Set the title type to a mrss_t element - the value is a string (ex: text, html, ...)*/ MRSS_FLAG_TITLE_TYPE, /** Set the description to a mrss_t element - the value is a string */ MRSS_FLAG_DESCRIPTION, /** Set the description type to a mrss_t element - the value is a string */ MRSS_FLAG_DESCRIPTION_TYPE, /** Set the link to a mrss_t element - the value is a string */ MRSS_FLAG_LINK, /** Set the id to a mrss_t element - the value is a string */ MRSS_FLAG_ID, /** Set the language to a mrss_t element - the value is a string */ MRSS_FLAG_LANGUAGE, /** Set the rating to a mrss_t element - the value is a string */ MRSS_FLAG_RATING, /** Set the copyright to a mrss_t element - the value is a string */ MRSS_FLAG_COPYRIGHT, /** Set the copyright type to a mrss_t element - the value is a string */ MRSS_FLAG_COPYRIGHT_TYPE, /** Set the pubDate to a mrss_t element - the value is a string */ MRSS_FLAG_PUBDATE, /** Set the lastBuildDate to a mrss_t element - the value is a string */ MRSS_FLAG_LASTBUILDDATE, /** Set the docs to a mrss_t element - the value is a string */ MRSS_FLAG_DOCS, /** Set the managingeditor to a mrss_t element - the value is a string */ MRSS_FLAG_MANAGINGEDITOR, /** Set the managingeditor's email to a mrss_t element - the value is a string */ MRSS_FLAG_MANAGINGEDITOR_EMAIL, /** Set the managingeditor's uri to a mrss_t element - the value is a string */ MRSS_FLAG_MANAGINGEDITOR_URI, /** Set the webMaster to a mrss_t element - the value is a string */ MRSS_FLAG_WEBMASTER, /** Set the generator to a mrss_t element - the value is a string */ MRSS_FLAG_TTL, /** Set the about to a mrss_t element - the value is a string */ MRSS_FLAG_ABOUT, /* Contributor */ /** Set the contributor to a mrss_t element - the value is a string */ MRSS_FLAG_CONTRIBUTOR, /** Set the contributor's email to a mrss_t element - the value is a string */ MRSS_FLAG_CONTRIBUTOR_EMAIL, /** Set the contributor's uri to a mrss_t element - the value is a string */ MRSS_FLAG_CONTRIBUTOR_URI, /* Generator */ /** Set the generator to a mrss_t element - the value is a string */ MRSS_FLAG_GENERATOR, /** Set the generator's email to a mrss_t element - the value is a string */ MRSS_FLAG_GENERATOR_URI, /** Set the generator's uri to a mrss_t element - the value is a string */ MRSS_FLAG_GENERATOR_VERSION, /* Image */ /** Set the image_title to a mrss_t element - the value is a string */ MRSS_FLAG_IMAGE_TITLE, /** Set the image_url to a mrss_t element - the value is a string */ MRSS_FLAG_IMAGE_URL, /** Set the image_logo to a mrss_t element - the value is a string */ MRSS_FLAG_IMAGE_LOGO, /** Set the image_link to a mrss_t element - the value is a string */ MRSS_FLAG_IMAGE_LINK, /** Set the image_width to a mrss_t element - the value is a integer */ MRSS_FLAG_IMAGE_WIDTH, /** Set the image_height to a mrss_t element - the value is a integer */ MRSS_FLAG_IMAGE_HEIGHT, /** Set the image_description to a mrss_t element - the value is a string */ MRSS_FLAG_IMAGE_DESCRIPTION, /* TextInput */ /** Set the textinput_title to a mrss_t element - the value is a string */ MRSS_FLAG_TEXTINPUT_TITLE, /** Set the textinput_description to a mrss_t element - the value is a string */ MRSS_FLAG_TEXTINPUT_DESCRIPTION, /** Set the textinput_name to a mrss_t element - the value is a string */ MRSS_FLAG_TEXTINPUT_NAME, /** Set the textinput_link to a mrss_t element - the value is a string */ MRSS_FLAG_TEXTINPUT_LINK, /* Cloud */ /** Set the cloud to a mrss_t element - the value is a string */ MRSS_FLAG_CLOUD, /** Set the cloud_domain to a mrss_t element - the value is a string */ MRSS_FLAG_CLOUD_DOMAIN, /** Set the cloud_port to a mrss_t element - the value is a string */ MRSS_FLAG_CLOUD_PORT, /** Set the cloud_path to a mrss_t element - the value is a integer */ MRSS_FLAG_CLOUD_PATH, /** Set the cloud_registerProcedure to a mrss_t element - * the value is a string */ MRSS_FLAG_CLOUD_REGISTERPROCEDURE, /** Set the cloud_protocol to a mrss_t element - the value is a string */ MRSS_FLAG_CLOUD_PROTOCOL, /* SkipHours */ /** Set the hour to a mrss_hour_t element - the value is a string */ MRSS_FLAG_HOUR, /* SkipDays */ /** Set the day to a mrss_day_t element - the value is a string */ MRSS_FLAG_DAY, /* Category or Item/Category */ /** Set the category to a mrss_category_t element - the value is a string */ MRSS_FLAG_CATEGORY, /** Set the domain to a mrss_category_t element - the value is a string */ MRSS_FLAG_CATEGORY_DOMAIN, /** Set the label to a mrss_category_t element - the value is a string */ MRSS_FLAG_CATEGORY_LABEL, /* Item */ /** Set the title to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_TITLE, /** Set the title type to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_TITLE_TYPE, /** Set the link to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_LINK, /** Set the description to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_DESCRIPTION, /** Set the description type to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_DESCRIPTION_TYPE, /** Set the copyright to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_COPYRIGHT, /** Set the copyright type to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_COPYRIGHT_TYPE, /** Set the author to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_AUTHOR, /** Set the author's uri to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_AUTHOR_URI, /** Set the author's email to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_AUTHOR_EMAIL, /** Set the contributor to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_CONTRIBUTOR, /** Set the contributor's uri to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_CONTRIBUTOR_URI, /** Set the contributor's email to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_CONTRIBUTOR_EMAIL, /** Set the comments to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_COMMENTS, /** Set the pubDate to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_PUBDATE, /** Set the guid to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_GUID, /** Set the guid_isPermaLink to a mrss_item_t element - * the value is a integer */ MRSS_FLAG_ITEM_GUID_ISPERMALINK, /** Set the source to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_SOURCE, /** Set the source_url to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_SOURCE_URL, /** Set the enclosure to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_ENCLOSURE, /** Set the enclosure_url to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_ENCLOSURE_URL, /** Set the enclosure_length to a mrss_item_t element - * the value is a integer */ MRSS_FLAG_ITEM_ENCLOSURE_LENGTH, /** Set the enclosure_type to a mrss_item_t element - the value is a string */ MRSS_FLAG_ITEM_ENCLOSURE_TYPE, /* Item */ /** Set the name to a mrss_tag_t element - the value is a string */ MRSS_FLAG_TAG_NAME, /** Set the value to a mrss_tag_t element - the value is a string */ MRSS_FLAG_TAG_VALUE, /** Set the namespace to a mrss_tag_t element - the value is a string */ MRSS_FLAG_TAG_NS, /** Set the name to a mrss_attribute_t element - the value is a string */ MRSS_FLAG_ATTRIBUTE_NAME, /** Set the value to a mrss_attribute_t element - the value is a string */ MRSS_FLAG_ATTRIBUTE_VALUE, /** Set the namespace to a mrss_attribute_t element - the value is a string */ MRSS_FLAG_ATTRIBUTE_NS, /** Set the terminetor flag */ MRSS_FLAG_END = 0 } mrss_flag_t; /** Enum for the casting of the libmrss data struct */ typedef enum { /** The data struct is a mrss_t */ MRSS_ELEMENT_CHANNEL, /** The data struct is a mrss_item_t */ MRSS_ELEMENT_ITEM, /** The data struct is a mrss_hour_t */ MRSS_ELEMENT_SKIPHOURS, /** The data struct is a mrss_day_t */ MRSS_ELEMENT_SKIPDAYS, /** The data struct is a mrss_category_t */ MRSS_ELEMENT_CATEGORY, /** The data struct is a mrss_tag_t */ MRSS_ELEMENT_TAG, /** The data struct is a mrss_attribute_t */ MRSS_ELEMENT_ATTRIBUTE } mrss_element_t; /** Data struct for any items of RSS. It contains a pointer to the list * of categories. * * \brief * Struct data for item elements */ struct mrss_item_t { /** For internal use only: */ mrss_element_t element; int allocated; /* Data: */ /* 0.91 0.92 1.0 2.0 ATOM */ char *title; /* R O O O R */ char *title_type; /* - - - - O */ char *link; /* R O O O O */ char *description; /* R O - O O */ char *description_type; /* - - - - 0 */ char *copyright; /* - - - - O */ char *copyright_type; /* - - - - O */ char *author; /* - - - O O */ char *author_uri; /* - - - - O */ char *author_email; /* - - - - O */ char *contributor; /* - - - - O */ char *contributor_uri; /* - - - - O */ char *contributor_email; /* - - - - O */ char *comments; /* - - - O - */ char *pubDate; /* - - - O O */ char *guid; /* - - - O O */ int guid_isPermaLink; /* - - - O - */ char *source; /* - O - O - */ char *source_url; /* - R - R - */ char *enclosure; /* - O - O - */ char *enclosure_url; /* - R - R - */ int enclosure_length; /* - R - R - */ char *enclosure_type; /* - R - R - */ mrss_category_t *category; /* - O - O O */ mrss_tag_t *other_tags; mrss_item_t *next; }; /** Data struct for skipHours elements. * * \brief * Struct data for skipHours elements */ struct mrss_hour_t { /** For internal use only: */ mrss_element_t element; int allocated; /* Data: */ /* 0.91 0.92 1.0 2.0 ATOM */ char *hour; /* R R - R - */ mrss_hour_t *next; }; /** Data struct for skipDays elements. * * \brief * Struct data for skipDays elements */ struct mrss_day_t { /** For internal use only: */ mrss_element_t element; int allocated; /* Data: */ /* 0.91 0.92 1.0 2.0 ATOM */ char *day; /* R R - R - */ mrss_day_t *next; }; /** Data struct for category elements * * \brief * Struct data for category elements */ struct mrss_category_t { /** For internal use only: */ mrss_element_t element; int allocated; /* Data: */ /* 0.91 0.92 1.0 2.0 ATOM */ char *category; /* - R - R R */ char *domain; /* - O - O O */ char *label; /* - - - - O */ mrss_category_t *next; }; /** Principal data struct. It contains pointers to any other structures. * * \brief * Principal data struct. It contains pointers to any other structures */ struct mrss_t { /** For internal use only: */ mrss_element_t element; int allocated; int curl_error; /* Data: */ char *file; size_t size; char *encoding; mrss_version_t version; /* 0.91 0.92 1.0 2.0 ATOM */ char *title; /* R R R R R */ char *title_type; /* - - - - O */ char *description; /* R R R R R */ char *description_type; /* - - - - O */ char *link; /* R R R R O */ char *id; /* - - - - O */ char *language; /* R O - O O */ char *rating; /* O O - O - */ char *copyright; /* O O - O O */ char *copyright_type; /* - - - - O */ char *pubDate; /* O O - O - */ char *lastBuildDate; /* O O - O O */ char *docs; /* O O - O - */ char *managingeditor; /* O O - O O */ char *managingeditor_email; /* O O - O O */ char *managingeditor_uri; /* O O - O O */ char *webMaster; /* O O - O - */ int ttl; /* - - - O - */ char *about; /* - - R - - */ /* Contributor */ /* - - - - O */ char *contributor; /* - - - - R */ char *contributor_email; /* - - - - O */ char *contributor_uri; /* - - - - O */ /* Generator */ char *generator; /* - - - O O */ char *generator_uri; /* - - - - O */ char *generator_version; /* - - - - O */ /* Tag Image: */ /* O O O O - */ char *image_title; /* R R R R - */ char *image_url; /* R R R R O */ char *image_logo; /* - - - - O */ char *image_link; /* R R R R - */ unsigned int image_width; /* O O - O - */ unsigned int image_height; /* O O - O - */ char *image_description; /* O O - O - */ /* TextInput: */ /* O O O O - */ char *textinput_title; /* R R R R - */ char *textinput_description; /* R R R R - */ char *textinput_name; /* R R R R - */ char *textinput_link; /* R R R R - */ /* Cloud */ char *cloud; /* - O - O - */ char *cloud_domain; /* - R - R - */ int cloud_port; /* - R - R - */ char *cloud_path; /* - R - R - */ char *cloud_registerProcedure;/* - R - R - */ char *cloud_protocol; /* - R - R - */ mrss_hour_t *skipHours; /* O O - O - */ mrss_day_t *skipDays; /* O O - O - */ mrss_category_t *category; /* - O - O O */ mrss_item_t *item; /* R R R R R */ mrss_tag_t *other_tags; #ifdef USE_LOCALE void *c_locale; #endif }; /** Data struct for any other tag out of the RSS namespace. * * \brief * Struct data for external tags */ struct mrss_tag_t { /** For internal use only: */ mrss_element_t element; int allocated; /*name of the tag */ char *name; /* value */ char *value; /* namespace */ char *ns; /* list of attributes: */ mrss_attribute_t *attributes; /* Sub tags: */ mrss_tag_t *children; /* the next tag: */ mrss_tag_t *next; }; /** Data struct for the attributes of the tag * * \brief * Struct data for external attribute */ struct mrss_attribute_t { /** For internal use only: */ mrss_element_t element; int allocated; /* name of the tag */ char *name; /* value */ char *value; /* namespace */ char *ns; /* The next attribute: */ mrss_attribute_t *next; }; /** Options data struct. It contains some user preferences. * * \brief * Options data struct. It contains some user preferences. */ struct mrss_options_t { int timeout; char *proxy; char *proxy_authentication; char *certfile; char *cacert; char *password; int verifypeer; char *authentication; char *user_agent; }; /** PARSE FUNCTIONS *********************************************************/ /** * Parses a url and creates the data struct of the feed RSS url. * This function downloads your request if this is http or ftp. * \param url The url to be parsed * \param mrss the pointer to your data struct * \return the error code */ mrss_error_t mrss_parse_url (char * url, mrss_t ** mrss); /** * Like the previous function but with a options struct. * \param url The url to be parsed * \param mrss the pointer to your data struct * \param options a pointer to a options data struct * \return the error code */ mrss_error_t mrss_parse_url_with_options (char * url, mrss_t ** mrss, mrss_options_t * options); /** * Like the previous function but with CURLcode error * \param url The url to be parsed * \param mrss the pointer to your data struct * \param options a pointer to a options data struct. It can be NULL * \param curlcode the error code from libcurl * \return the error code */ mrss_error_t mrss_parse_url_with_options_and_error (char * url, mrss_t ** mrss, mrss_options_t * options, CURLcode * curlcode); /** * Like the previous function but you take ownership of the downloaded buffer * in case of success * \param url The url to be parsed * \param mrss the pointer to your data struct * \param options a pointer to a options data struct * \param curlcode the error code from libcurl * \param feed_content a pointer to the buffer with the document. This is not NULL terminated * \param feed_size the size of the buffer above * \return the error code */ mrss_error_t mrss_parse_url_with_options_error_and_transfer_buffer (char * url, mrss_t ** mrss, mrss_options_t * options, CURLcode * curlcode, char ** feed_content, int * feed_size); /** * Parses a file and creates the data struct of the feed RSS url * \param file The file to be parsed * \param mrss the pointer to your data struct * \return the error code */ mrss_error_t mrss_parse_file (char * file, mrss_t ** mrss); /** * Parses a buffer and creates the data struct of the feed RSS url * \param buffer Pointer to the xml memory stream to be parsed * \param size_buffer The size of the array of char * \param mrss the pointer to your data struct * \return the error code */ mrss_error_t mrss_parse_buffer (char * buffer, size_t size_buffer, mrss_t ** mrss); /** WRITE FUNCTIONS *********************************************************/ /** * Writes a RSS struct data in a local file * \param mrss the rss struct data * \param file the local file * \return the error code */ mrss_error_t mrss_write_file (mrss_t * mrss, char * file); /** * Write a RSS struct data in a buffer. * * \code * char *buffer; * buffer=NULL; //<--- This is important!! * mrss_write_buffer (mrss, &buffer); * \endcode * * The buffer must be NULL. * \param mrss the rss struct data * \param buffer the buffer * \return the error code */ mrss_error_t mrss_write_buffer (mrss_t * mrss, char ** buffer); /** FREE FUNCTION ***********************************************************/ /** * This function frees any type of data struct of libmrss. If the element * is alloced by libmrss, it will be freed, else this function frees * only the internal data. * * \code * mrss_t *t=....; * mrss_item_t *item=...; * * mrss_free(t); * mrss_free(item); * \endcode * * \param element the data struct * \return the error code */ mrss_error_t mrss_free (mrss_generic_t element); /** GENERIC FUNCTION ********************************************************/ /** * This function returns a static string with the description of error code * \param err the error code that you need as string * \return a string. Don't free this string! */ char * mrss_strerror (mrss_error_t err); /** * This function returns a static string with the description of curl code * \param err the error code that you need as string * \return a string. Don't free this string! */ char * mrss_curl_strerror (CURLcode err); /** * This function returns the mrss_element_t of a mrss data struct. * \param element it is the element that you want check * \param ret it is a pointer to a mrss_element_t. It will be sets. * \return the error code */ mrss_error_t mrss_element (mrss_generic_t element, mrss_element_t *ret); /** * This function returns the number of seconds sinze Jennuary 1st 1970 in the * UTC time zone, for the url that the urlstring parameter specifies. * * \param urlstring the url * \param lastmodified is a pointer to a time_t struct. The return value can * be 0 if the HEAD request does not return a Last-Modified value. * \return the error code */ mrss_error_t mrss_get_last_modified (char * urlstring, time_t * lastmodified); /** * Like the previous function but with a options struct. * * \param urlstring the url * \param lastmodified is a pointer to a time_t struct. The return value can * be 0 if the HEAD request does not return a Last-Modified value. * \param options a pointer to a options struct * \return the error code */ mrss_error_t mrss_get_last_modified_with_options (char * urlstring, time_t * lastmodified, mrss_options_t * options); /** * Like the previous function but with a CURLcode pointer. * * \param urlstring the url * \param lastmodified is a pointer to a time_t struct. The return value can * be 0 if the HEAD request does not return a Last-Modified value. * \param options a pointer to a options struct * \param curl_code it will contain the error code of libcurl * \return the error code */ mrss_error_t mrss_get_last_modified_with_options_and_error (char * urlstring, time_t * lastmodified, mrss_options_t * options, CURLcode * curl_code); /** EDIT FUNCTIONS **********************************************************/ /** If you want create a new feed RSS from scratch, you need use * this function as the first. * * \code * mrss_t *d; * mrss_error_t err; * char *string; * int integer; * * d=NULL; // ->this is important! If d!=NULL, mrss_new doesn't alloc memory. * mrss_new(&d); * * err=mrss_set (d, * MRSS_FLAG_VERSION, MRSS_VERSION_0_92, * MRSS_FLAG_TITLE, "the title!", * MRSS_FLAG_TTL, 12, * MRSS_FLAG_END); * * if(err!=MRSS_OK) printf("%s\n",mrss_strerror(err)); * * err=mrss_get (d, * MRSS_FLAG_TITLE, &string, * MRSS_FLAG_TTL, &integer, * MRSS_FLAG_END); * * if(err!=MRSS_OK) printf("%s\n",mrss_strerror(err)); * printf("The title is: '%s'\n", string); * printf("The ttl is: '%d'\n", integer); * free(string); * \endcode * * \param mrss is the pointer to the new data struct * \return the error code */ mrss_error_t mrss_new (mrss_t ** mrss); /** * For insert/replace/remove a flags use this function as this example: * \code * mrss_set(mrss, MRSS_FLAG_TITLE, "hello world", MRSS_FLAG_END); * mrss_set(item, MRSS_FLAG_DESCRIPTION, NULL, MRSS_FLAG_END); * \endcode * * \param element it is the mrss data that you want changes the the next * list of elements. The list is composted by KEY - VALUES and as last * element MRSS_FLAG_END. The variable of value depends from key. * \see mrss_flag_t * \return the error code */ mrss_error_t mrss_set (mrss_generic_t element, ...); /** * This function returns the request arguments. The syntax is the same of * mrss_set but the values of the list are pointer to data element (int *, * char **). If the key needs a char **, the value will be allocated. * \code * mrss_get(category, MRSS_FLAG_CATEGORY_DOMAIN, &string, MRSS_FLAG_END); * if(string) free(string); * \endcode * \param element it is any type of mrss data struct. * \return the error code */ mrss_error_t mrss_get (mrss_generic_t element, ...); /** * This function adds an element to another element. For example you can * add a item to a channel, or a category to a item, and so on. Look this * example: * \code * mrss_item_t *item = NULL; * mrss_hour_t *hour = NULL; * mrss_day_t day; // If the element is no null, the function * mrss_category_t category, // does not alloc it * * mrss_new_subdata(mrss, MRSS_ELEMENT_ITEM, &item); * mrss_new_subdata(mrss, MRSS_ELEMENT_SKIPHOURS, &hour); * mrss_new_subdata(mrss, MRSS_ELEMENT_SKIPDAYS, &day); * mrss_new_subdata(item, MRSS_ELEMENT_ITEM_CATEGORY, &category); * \endcode * \param element it is the parent element * \param subelement it is the type of the child (MRSS_ELEMENT_ITEM, * MRSS_ELEMENT_CATEGORY, ...) * \param subdata it is the pointer to the new struct. If the pointer * of *subdata exists, it will no alloced, else yes. * \return the error code * \see mrss_element_t */ mrss_error_t mrss_new_subdata (mrss_generic_t element, mrss_element_t subelement, mrss_generic_t subdata); /** * This function removes a subdata element. As first argoment you must specify * the parent, and second argoment the child. * \code * mrss_remove_subdata(mrss, item); * \endcode * \param element it is the parent * \param subdata the child that you want remove. Remember: * mrss_remove_subdata does not free the memory. So you can remove a item * and reinsert it after. * \return the error code */ mrss_error_t mrss_remove_subdata (mrss_generic_t element, mrss_generic_t subdata); /* TAGS FUNCTIONS **********************************************************/ /** * This function search a tag in a mrss_t, a mrss_item_t or a mrss_tag_t from * name and a namespace. * \param element it is the parent node (mrss_t or mrss_item_t) * \param name the name of the element * \param ns the namespace. It can be null if the tag has a null namespace * \param tag the return pointer * \return the error code */ mrss_error_t mrss_search_tag (mrss_generic_t element, char * name, char * ns, mrss_tag_t ** tag); /** * This function search an attribute from a mrss_tag_t, a name and a namespace * \param element it is the mrss_tag_t * \param name the name of the element * \param ns the namespace. It can be null if the tag has a null namespace * \param attribute the return pointer * \return the error code */ mrss_error_t mrss_search_attribute (mrss_generic_t element, char * name, char * ns, mrss_attribute_t ** attribute); /* OPTIONS FUNCTIONS *******************************************************/ /** * This function creates a options struct. * * \param timeout timeout for the download procedure * \param proxy a proxy server. can be NULL * \param proxy_authentication a proxy authentication (user:pwd). can be NULL * \param certfile a certificate for ssl autentication connection * \param password the password of certfile * \param cacert CA certificate to verify peer against. can be NULL * \param verifypeer active/deactive the peer check * \param authentication an authentication login (user:pwd). can be NULL * \param user_agent a user_agent. can be NULL * \return a pointer to a new allocated mrss_options_t struct */ mrss_options_t * mrss_options_new (int timeout, char *proxy, char *proxy_authentication, char *certfile, char *password, char *cacert, int verifypeer, char *authentication, char *user_agent); /** * This function destroys a options struct. * \param options a pointer to a options struct */ void mrss_options_free (mrss_options_t *options); #ifdef __cplusplus } #endif #endif /* EOF */ libmrss-0.19.4/src/mrss_download.c000066400000000000000000000027371456537604200171130ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #else #error Use configure; make; make install #endif #include "mrss.h" #include "mrss_internal.h" char *__mrss_download_file(nxml_t *nxml, char *fl, size_t *size, mrss_error_t *error, CURLcode *code) { char *buffer; if (code) *code = CURLE_OK; switch (nxml_download_file(nxml, fl, &buffer, size)) { case NXML_OK: return buffer; case NXML_ERR_DOWNLOAD: if (code) *code = nxml_curl_error(nxml, NXML_ERR_DOWNLOAD); *error = MRSS_ERR_DOWNLOAD; return NULL; default: *error = MRSS_ERR_POSIX; return NULL; } } /* EOF */ libmrss-0.19.4/src/mrss_edit.c000066400000000000000000001062171456537604200162270ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #else #error Use configure; make; make install #endif #include "mrss.h" #include "mrss_internal.h" static mrss_error_t __mrss_set_channel(mrss_t *, va_list); static mrss_error_t __mrss_set_item(mrss_item_t *, va_list); static mrss_error_t __mrss_set_hour(mrss_hour_t *, va_list); static mrss_error_t __mrss_set_day(mrss_day_t *, va_list); static mrss_error_t __mrss_set_category(mrss_category_t *, va_list); static mrss_error_t __mrss_set_tag(mrss_tag_t *, va_list); static mrss_error_t __mrss_set_attribute(mrss_attribute_t *, va_list); static mrss_error_t __mrss_get_channel(mrss_t *, va_list); static mrss_error_t __mrss_get_item(mrss_item_t *, va_list); static mrss_error_t __mrss_get_hour(mrss_hour_t *, va_list); static mrss_error_t __mrss_get_day(mrss_day_t *, va_list); static mrss_error_t __mrss_get_category(mrss_category_t *, va_list); static mrss_error_t __mrss_get_tag(mrss_tag_t *, va_list); static mrss_error_t __mrss_get_attribute(mrss_attribute_t *, va_list); static mrss_error_t __mrss_new_subdata_channel(mrss_t *, mrss_element_t, mrss_generic_t); static mrss_error_t __mrss_new_subdata_item(mrss_item_t *, mrss_element_t, mrss_generic_t); static mrss_error_t __mrss_new_subdata_tag(mrss_tag_t *, mrss_element_t, mrss_generic_t); static mrss_error_t __mrss_remove_subdata_channel(mrss_t *, mrss_generic_t); static mrss_error_t __mrss_remove_subdata_item(mrss_item_t *, mrss_generic_t); static mrss_error_t __mrss_remove_subdata_tag(mrss_tag_t *, mrss_generic_t); #define __MRSS_SET_STRING(x) \ if (x) \ free(x); \ if (value && !(x = strdup(value))) \ return MRSS_ERR_POSIX; \ else if (!value) \ x = NULL; #define __MRSS_SET_INTEGER(x) x = (int)value; #define __MRSS_GET_STRING(x) \ string = (char **)value; \ if (!x) \ *string = NULL; \ else if (!(*string = strdup(x))) \ return MRSS_ERR_POSIX; #define __MRSS_GET_INTEGER(x) \ integer = (int *)value; \ *integer = x; mrss_error_t mrss_new(mrss_t **data) { int allocated; if (!data) return MRSS_ERR_DATA; if (!*data) { if (!(*data = (mrss_t *)malloc(sizeof(mrss_t)))) return MRSS_ERR_POSIX; allocated = 1; } else allocated = 0; memset(*data, 0, sizeof(mrss_t)); (*data)->element = MRSS_ELEMENT_CHANNEL; (*data)->allocated = allocated; return MRSS_OK; } mrss_error_t mrss_set(mrss_generic_t data, ...) { va_list va; mrss_error_t err; mrss_t *tmp; if (!data) return MRSS_ERR_DATA; va_start(va, data); tmp = (mrss_t *)data; switch (tmp->element) { case MRSS_ELEMENT_CHANNEL: err = __mrss_set_channel((mrss_t *)data, va); break; case MRSS_ELEMENT_ITEM: err = __mrss_set_item((mrss_item_t *)data, va); break; case MRSS_ELEMENT_SKIPHOURS: err = __mrss_set_hour((mrss_hour_t *)data, va); break; case MRSS_ELEMENT_SKIPDAYS: err = __mrss_set_day((mrss_day_t *)data, va); break; case MRSS_ELEMENT_CATEGORY: err = __mrss_set_category((mrss_category_t *)data, va); break; case MRSS_ELEMENT_TAG: err = __mrss_set_tag((mrss_tag_t *)data, va); break; case MRSS_ELEMENT_ATTRIBUTE: err = __mrss_set_attribute((mrss_attribute_t *)data, va); break; default: err = MRSS_ERR_DATA; break; } va_end(va); return err; } static mrss_error_t __mrss_set_channel(mrss_t *data, va_list va) { mrss_flag_t flag; void *value; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_VERSION: if ((mrss_version_t)value != MRSS_VERSION_0_91 && (mrss_version_t)value != MRSS_VERSION_0_92 && (mrss_version_t)value != MRSS_VERSION_2_0) return MRSS_ERR_DATA; data->version = (mrss_version_t)value; break; case MRSS_FLAG_TITLE: __MRSS_SET_STRING(data->title); break; case MRSS_FLAG_TITLE_TYPE: __MRSS_SET_STRING(data->title_type); break; case MRSS_FLAG_DESCRIPTION: __MRSS_SET_STRING(data->description); break; case MRSS_FLAG_DESCRIPTION_TYPE: __MRSS_SET_STRING(data->description_type); break; case MRSS_FLAG_LINK: __MRSS_SET_STRING(data->link); break; case MRSS_FLAG_ID: __MRSS_SET_STRING(data->id); break; case MRSS_FLAG_LANGUAGE: __MRSS_SET_STRING(data->language); break; case MRSS_FLAG_RATING: __MRSS_SET_STRING(data->rating); break; case MRSS_FLAG_COPYRIGHT: __MRSS_SET_STRING(data->copyright); break; case MRSS_FLAG_COPYRIGHT_TYPE: __MRSS_SET_STRING(data->copyright_type); break; case MRSS_FLAG_PUBDATE: __MRSS_SET_STRING(data->pubDate); break; case MRSS_FLAG_LASTBUILDDATE: __MRSS_SET_STRING(data->lastBuildDate); break; case MRSS_FLAG_DOCS: __MRSS_SET_STRING(data->docs); break; case MRSS_FLAG_MANAGINGEDITOR: __MRSS_SET_STRING(data->managingeditor); break; case MRSS_FLAG_MANAGINGEDITOR_EMAIL: __MRSS_SET_STRING(data->managingeditor_email); break; case MRSS_FLAG_MANAGINGEDITOR_URI: __MRSS_SET_STRING(data->managingeditor_uri); break; case MRSS_FLAG_WEBMASTER: __MRSS_SET_STRING(data->webMaster); break; case MRSS_FLAG_TTL: __MRSS_SET_INTEGER(data->ttl); break; case MRSS_FLAG_ABOUT: __MRSS_SET_STRING(data->about); break; case MRSS_FLAG_CONTRIBUTOR: __MRSS_SET_STRING(data->contributor); break; case MRSS_FLAG_CONTRIBUTOR_EMAIL: __MRSS_SET_STRING(data->contributor_email); break; case MRSS_FLAG_CONTRIBUTOR_URI: __MRSS_SET_STRING(data->contributor_uri); break; case MRSS_FLAG_GENERATOR: __MRSS_SET_STRING(data->generator); break; case MRSS_FLAG_GENERATOR_URI: __MRSS_SET_STRING(data->generator_uri); break; case MRSS_FLAG_GENERATOR_VERSION: __MRSS_SET_STRING(data->generator_version); break; case MRSS_FLAG_IMAGE_TITLE: __MRSS_SET_STRING(data->image_title); break; case MRSS_FLAG_IMAGE_URL: __MRSS_SET_STRING(data->image_url); break; case MRSS_FLAG_IMAGE_LOGO: __MRSS_SET_STRING(data->image_logo); break; case MRSS_FLAG_IMAGE_LINK: __MRSS_SET_STRING(data->image_link); break; case MRSS_FLAG_IMAGE_WIDTH: __MRSS_SET_INTEGER(data->image_width); break; case MRSS_FLAG_IMAGE_HEIGHT: __MRSS_SET_INTEGER(data->image_height); break; case MRSS_FLAG_IMAGE_DESCRIPTION: __MRSS_SET_STRING(data->image_description); break; case MRSS_FLAG_TEXTINPUT_TITLE: __MRSS_SET_STRING(data->textinput_title); break; case MRSS_FLAG_TEXTINPUT_DESCRIPTION: __MRSS_SET_STRING(data->textinput_description); break; case MRSS_FLAG_TEXTINPUT_NAME: __MRSS_SET_STRING(data->textinput_name); break; case MRSS_FLAG_TEXTINPUT_LINK: __MRSS_SET_STRING(data->textinput_link); break; case MRSS_FLAG_CLOUD: __MRSS_SET_STRING(data->cloud); break; case MRSS_FLAG_CLOUD_DOMAIN: __MRSS_SET_STRING(data->cloud_domain); break; case MRSS_FLAG_CLOUD_PORT: __MRSS_SET_INTEGER(data->cloud_port); break; case MRSS_FLAG_CLOUD_PATH: __MRSS_SET_STRING(data->cloud_path); break; case MRSS_FLAG_CLOUD_REGISTERPROCEDURE: __MRSS_SET_STRING(data->cloud_registerProcedure); break; case MRSS_FLAG_CLOUD_PROTOCOL: __MRSS_SET_STRING(data->cloud_protocol); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_set_hour(mrss_hour_t *data, va_list va) { mrss_flag_t flag; void *value; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_HOUR: __MRSS_SET_STRING(data->hour); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_set_day(mrss_day_t *data, va_list va) { mrss_flag_t flag; void *value; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_DAY: __MRSS_SET_STRING(data->day); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_set_category(mrss_category_t *data, va_list va) { mrss_flag_t flag; void *value; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_CATEGORY: __MRSS_SET_STRING(data->category); break; case MRSS_FLAG_CATEGORY_DOMAIN: __MRSS_SET_STRING(data->domain); break; case MRSS_FLAG_CATEGORY_LABEL: __MRSS_SET_STRING(data->label); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_set_tag(mrss_tag_t *data, va_list va) { mrss_flag_t flag; void *value; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_TAG_NAME: __MRSS_SET_STRING(data->name); break; case MRSS_FLAG_TAG_VALUE: __MRSS_SET_STRING(data->value); break; case MRSS_FLAG_TAG_NS: __MRSS_SET_STRING(data->ns); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_set_attribute(mrss_attribute_t *data, va_list va) { mrss_flag_t flag; void *value; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_ATTRIBUTE_NAME: __MRSS_SET_STRING(data->name); break; case MRSS_FLAG_ATTRIBUTE_VALUE: __MRSS_SET_STRING(data->value); break; case MRSS_FLAG_ATTRIBUTE_NS: __MRSS_SET_STRING(data->ns); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_set_item(mrss_item_t *data, va_list va) { mrss_flag_t flag; void *value; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_ITEM_TITLE: __MRSS_SET_STRING(data->title); break; case MRSS_FLAG_ITEM_TITLE_TYPE: __MRSS_SET_STRING(data->title_type); break; case MRSS_FLAG_ITEM_LINK: __MRSS_SET_STRING(data->link); break; case MRSS_FLAG_ITEM_DESCRIPTION: __MRSS_SET_STRING(data->description); break; case MRSS_FLAG_ITEM_DESCRIPTION_TYPE: __MRSS_SET_STRING(data->description_type); break; case MRSS_FLAG_ITEM_COPYRIGHT: __MRSS_SET_STRING(data->copyright); break; case MRSS_FLAG_ITEM_COPYRIGHT_TYPE: __MRSS_SET_STRING(data->copyright_type); break; case MRSS_FLAG_ITEM_AUTHOR: __MRSS_SET_STRING(data->author); break; case MRSS_FLAG_ITEM_AUTHOR_EMAIL: __MRSS_SET_STRING(data->author_email); break; case MRSS_FLAG_ITEM_AUTHOR_URI: __MRSS_SET_STRING(data->author_uri); break; case MRSS_FLAG_ITEM_CONTRIBUTOR: __MRSS_SET_STRING(data->contributor); break; case MRSS_FLAG_ITEM_CONTRIBUTOR_EMAIL: __MRSS_SET_STRING(data->contributor_email); break; case MRSS_FLAG_ITEM_CONTRIBUTOR_URI: __MRSS_SET_STRING(data->contributor_uri); break; case MRSS_FLAG_ITEM_COMMENTS: __MRSS_SET_STRING(data->comments); break; case MRSS_FLAG_ITEM_PUBDATE: __MRSS_SET_STRING(data->pubDate); break; case MRSS_FLAG_ITEM_GUID: __MRSS_SET_STRING(data->guid); break; case MRSS_FLAG_ITEM_GUID_ISPERMALINK: __MRSS_SET_INTEGER(data->guid_isPermaLink); break; case MRSS_FLAG_ITEM_SOURCE: __MRSS_SET_STRING(data->source); break; case MRSS_FLAG_ITEM_SOURCE_URL: __MRSS_SET_STRING(data->source_url); break; case MRSS_FLAG_ITEM_ENCLOSURE: __MRSS_SET_STRING(data->enclosure); break; case MRSS_FLAG_ITEM_ENCLOSURE_URL: __MRSS_SET_STRING(data->enclosure_url); break; case MRSS_FLAG_ITEM_ENCLOSURE_LENGTH: __MRSS_SET_INTEGER(data->enclosure_length); break; case MRSS_FLAG_ITEM_ENCLOSURE_TYPE: __MRSS_SET_STRING(data->enclosure_type); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } mrss_error_t mrss_get(mrss_generic_t data, ...) { va_list va; mrss_error_t err; mrss_t *tmp; if (!data) return MRSS_ERR_DATA; va_start(va, data); tmp = (mrss_t *)data; switch (tmp->element) { case MRSS_ELEMENT_CHANNEL: err = __mrss_get_channel((mrss_t *)data, va); break; case MRSS_ELEMENT_ITEM: err = __mrss_get_item((mrss_item_t *)data, va); break; case MRSS_ELEMENT_SKIPHOURS: err = __mrss_get_hour((mrss_hour_t *)data, va); break; case MRSS_ELEMENT_SKIPDAYS: err = __mrss_get_day((mrss_day_t *)data, va); break; case MRSS_ELEMENT_CATEGORY: err = __mrss_get_category((mrss_category_t *)data, va); break; case MRSS_ELEMENT_TAG: err = __mrss_get_tag((mrss_tag_t *)data, va); break; case MRSS_ELEMENT_ATTRIBUTE: err = __mrss_get_attribute((mrss_attribute_t *)data, va); break; default: err = MRSS_ERR_DATA; break; } va_end(va); return err; } static mrss_error_t __mrss_get_channel(mrss_t *data, va_list va) { mrss_flag_t flag; void *value; int *integer; mrss_version_t *version; char **string; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_VERSION: version = value; *version = data->version; break; case MRSS_FLAG_TITLE: __MRSS_GET_STRING(data->title); break; case MRSS_FLAG_TITLE_TYPE: __MRSS_GET_STRING(data->title_type); break; case MRSS_FLAG_DESCRIPTION: __MRSS_GET_STRING(data->description); break; case MRSS_FLAG_DESCRIPTION_TYPE: __MRSS_GET_STRING(data->description_type); break; case MRSS_FLAG_LINK: __MRSS_GET_STRING(data->link); break; case MRSS_FLAG_ID: __MRSS_GET_STRING(data->id); break; case MRSS_FLAG_LANGUAGE: __MRSS_GET_STRING(data->language); break; case MRSS_FLAG_RATING: __MRSS_GET_STRING(data->rating); break; case MRSS_FLAG_COPYRIGHT: __MRSS_GET_STRING(data->copyright); break; case MRSS_FLAG_COPYRIGHT_TYPE: __MRSS_GET_STRING(data->copyright_type); break; case MRSS_FLAG_PUBDATE: __MRSS_GET_STRING(data->pubDate); break; case MRSS_FLAG_LASTBUILDDATE: __MRSS_GET_STRING(data->lastBuildDate); break; case MRSS_FLAG_DOCS: __MRSS_GET_STRING(data->docs); break; case MRSS_FLAG_MANAGINGEDITOR: __MRSS_GET_STRING(data->managingeditor); break; case MRSS_FLAG_MANAGINGEDITOR_EMAIL: __MRSS_GET_STRING(data->managingeditor_email); break; case MRSS_FLAG_MANAGINGEDITOR_URI: __MRSS_GET_STRING(data->managingeditor_uri); break; case MRSS_FLAG_WEBMASTER: __MRSS_GET_STRING(data->webMaster); break; case MRSS_FLAG_TTL: __MRSS_GET_INTEGER(data->ttl); break; case MRSS_FLAG_ABOUT: __MRSS_GET_STRING(data->about); break; case MRSS_FLAG_CONTRIBUTOR: __MRSS_GET_STRING(data->contributor); break; case MRSS_FLAG_CONTRIBUTOR_EMAIL: __MRSS_GET_STRING(data->contributor_email); break; case MRSS_FLAG_CONTRIBUTOR_URI: __MRSS_GET_STRING(data->contributor_uri); break; case MRSS_FLAG_GENERATOR: __MRSS_GET_STRING(data->generator); break; case MRSS_FLAG_GENERATOR_URI: __MRSS_GET_STRING(data->generator_uri); break; case MRSS_FLAG_GENERATOR_VERSION: __MRSS_GET_STRING(data->generator_version); break; case MRSS_FLAG_IMAGE_TITLE: __MRSS_GET_STRING(data->image_title); break; case MRSS_FLAG_IMAGE_URL: __MRSS_GET_STRING(data->image_url); break; case MRSS_FLAG_IMAGE_LOGO: __MRSS_GET_STRING(data->image_logo); break; case MRSS_FLAG_IMAGE_LINK: __MRSS_GET_STRING(data->image_link); break; case MRSS_FLAG_IMAGE_WIDTH: __MRSS_GET_INTEGER(data->image_width); break; case MRSS_FLAG_IMAGE_HEIGHT: __MRSS_GET_INTEGER(data->image_height); break; case MRSS_FLAG_IMAGE_DESCRIPTION: __MRSS_GET_STRING(data->image_description); break; case MRSS_FLAG_TEXTINPUT_TITLE: __MRSS_GET_STRING(data->textinput_title); break; case MRSS_FLAG_TEXTINPUT_DESCRIPTION: __MRSS_GET_STRING(data->textinput_description); break; case MRSS_FLAG_TEXTINPUT_NAME: __MRSS_GET_STRING(data->textinput_name); break; case MRSS_FLAG_TEXTINPUT_LINK: __MRSS_GET_STRING(data->textinput_link); break; case MRSS_FLAG_CLOUD: __MRSS_GET_STRING(data->cloud); break; case MRSS_FLAG_CLOUD_DOMAIN: __MRSS_GET_STRING(data->cloud_domain); break; case MRSS_FLAG_CLOUD_PORT: __MRSS_GET_INTEGER(data->cloud_port); break; case MRSS_FLAG_CLOUD_PATH: __MRSS_GET_STRING(data->cloud_path); break; case MRSS_FLAG_CLOUD_REGISTERPROCEDURE: __MRSS_GET_STRING(data->cloud_registerProcedure); break; case MRSS_FLAG_CLOUD_PROTOCOL: __MRSS_GET_STRING(data->cloud_protocol); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_get_hour(mrss_hour_t *data, va_list va) { mrss_flag_t flag; void *value; char **string; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_HOUR: __MRSS_GET_STRING(data->hour); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_get_day(mrss_day_t *data, va_list va) { mrss_flag_t flag; void *value; char **string; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_DAY: __MRSS_GET_STRING(data->day); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_get_category(mrss_category_t *data, va_list va) { mrss_flag_t flag; void *value; char **string; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_CATEGORY: __MRSS_GET_STRING(data->category); break; case MRSS_FLAG_CATEGORY_DOMAIN: __MRSS_GET_STRING(data->domain); break; case MRSS_FLAG_CATEGORY_LABEL: __MRSS_GET_STRING(data->label); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_get_tag(mrss_tag_t *data, va_list va) { mrss_flag_t flag; void *value; char **string; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_TAG_NAME: __MRSS_GET_STRING(data->name); break; case MRSS_FLAG_TAG_VALUE: __MRSS_GET_STRING(data->value); break; case MRSS_FLAG_TAG_NS: __MRSS_GET_STRING(data->ns); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_get_attribute(mrss_attribute_t *data, va_list va) { mrss_flag_t flag; void *value; char **string; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_ATTRIBUTE_NAME: __MRSS_GET_STRING(data->name); break; case MRSS_FLAG_ATTRIBUTE_VALUE: __MRSS_GET_STRING(data->value); break; case MRSS_FLAG_ATTRIBUTE_NS: __MRSS_GET_STRING(data->ns); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } static mrss_error_t __mrss_get_item(mrss_item_t *data, va_list va) { mrss_flag_t flag; void *value; char **string; int *integer; while ((flag = va_arg(va, mrss_flag_t))) { value = va_arg(va, void *); switch (flag) { case MRSS_FLAG_ITEM_TITLE: __MRSS_GET_STRING(data->title); break; case MRSS_FLAG_ITEM_TITLE_TYPE: __MRSS_GET_STRING(data->title_type); break; case MRSS_FLAG_ITEM_LINK: __MRSS_GET_STRING(data->link); break; case MRSS_FLAG_ITEM_DESCRIPTION: __MRSS_GET_STRING(data->description); break; case MRSS_FLAG_ITEM_DESCRIPTION_TYPE: __MRSS_GET_STRING(data->description_type); break; case MRSS_FLAG_ITEM_COPYRIGHT: __MRSS_GET_STRING(data->copyright); break; case MRSS_FLAG_ITEM_COPYRIGHT_TYPE: __MRSS_GET_STRING(data->copyright_type); break; case MRSS_FLAG_ITEM_AUTHOR: __MRSS_GET_STRING(data->author); break; case MRSS_FLAG_ITEM_AUTHOR_EMAIL: __MRSS_GET_STRING(data->author_email); break; case MRSS_FLAG_ITEM_AUTHOR_URI: __MRSS_GET_STRING(data->author_uri); break; case MRSS_FLAG_ITEM_CONTRIBUTOR: __MRSS_GET_STRING(data->contributor); break; case MRSS_FLAG_ITEM_CONTRIBUTOR_EMAIL: __MRSS_GET_STRING(data->contributor_email); break; case MRSS_FLAG_ITEM_CONTRIBUTOR_URI: __MRSS_GET_STRING(data->contributor_uri); break; case MRSS_FLAG_ITEM_COMMENTS: __MRSS_GET_STRING(data->comments); break; case MRSS_FLAG_ITEM_PUBDATE: __MRSS_GET_STRING(data->pubDate); break; case MRSS_FLAG_ITEM_GUID: __MRSS_GET_STRING(data->guid); break; case MRSS_FLAG_ITEM_GUID_ISPERMALINK: __MRSS_GET_INTEGER(data->guid_isPermaLink); break; case MRSS_FLAG_ITEM_SOURCE: __MRSS_GET_STRING(data->source); break; case MRSS_FLAG_ITEM_SOURCE_URL: __MRSS_GET_STRING(data->source_url); break; case MRSS_FLAG_ITEM_ENCLOSURE: __MRSS_GET_STRING(data->enclosure); break; case MRSS_FLAG_ITEM_ENCLOSURE_URL: __MRSS_GET_STRING(data->enclosure_url); break; case MRSS_FLAG_ITEM_ENCLOSURE_LENGTH: __MRSS_GET_INTEGER(data->enclosure_length); break; case MRSS_FLAG_ITEM_ENCLOSURE_TYPE: __MRSS_GET_STRING(data->enclosure_type); break; default: return MRSS_ERR_DATA; } } return MRSS_OK; } mrss_error_t mrss_new_subdata(mrss_generic_t data, mrss_element_t element, mrss_generic_t new) { mrss_t *tmp; if (!data || !new) return MRSS_ERR_DATA; tmp = (mrss_t *)data; switch (tmp->element) { case MRSS_ELEMENT_CHANNEL: return __mrss_new_subdata_channel((mrss_t *)data, element, new); case MRSS_ELEMENT_ITEM: return __mrss_new_subdata_item((mrss_item_t *)data, element, new); case MRSS_ELEMENT_TAG: return __mrss_new_subdata_tag((mrss_tag_t *)data, element, new); default: return MRSS_ERR_DATA; } } static mrss_error_t __mrss_new_subdata_channel(mrss_t *mrss, mrss_element_t element, mrss_generic_t data) { mrss_item_t **item; mrss_hour_t **hour; mrss_day_t **day; mrss_category_t **category; mrss_tag_t **tag; int allocated; switch (element) { case MRSS_ELEMENT_ITEM: item = (mrss_item_t **)data; if (!*item) { if (!(*item = (mrss_item_t *)malloc(sizeof(mrss_item_t)))) return MRSS_ERR_POSIX; allocated = 1; } else allocated = 0; memset(*item, 0, sizeof(mrss_item_t)); (*item)->element = MRSS_ELEMENT_ITEM; (*item)->allocated = allocated; (*item)->next = mrss->item; mrss->item = (*item); break; case MRSS_ELEMENT_SKIPHOURS: hour = (mrss_hour_t **)data; if (!*hour) { if (!(*hour = (mrss_hour_t *)malloc(sizeof(mrss_hour_t)))) return MRSS_ERR_POSIX; allocated = 1; } else allocated = 0; memset(*hour, 0, sizeof(mrss_hour_t)); (*hour)->element = MRSS_ELEMENT_SKIPHOURS; (*hour)->allocated = allocated; (*hour)->next = mrss->skipHours; mrss->skipHours = (*hour); break; case MRSS_ELEMENT_SKIPDAYS: day = (mrss_day_t **)data; if (!*day) { if (!(*day = (mrss_day_t *)malloc(sizeof(mrss_day_t)))) return MRSS_ERR_POSIX; allocated = 1; } else allocated = 0; memset(*day, 0, sizeof(mrss_day_t)); (*day)->element = MRSS_ELEMENT_SKIPDAYS; (*day)->allocated = allocated; (*day)->next = mrss->skipDays; mrss->skipDays = (*day); break; case MRSS_ELEMENT_CATEGORY: category = (mrss_category_t **)data; if (!*category) { if (!(*category = (mrss_category_t *)malloc(sizeof(mrss_category_t)))) return MRSS_ERR_POSIX; allocated = 1; } else allocated = 0; memset(*category, 0, sizeof(mrss_category_t)); (*category)->element = MRSS_ELEMENT_CATEGORY; (*category)->allocated = allocated; (*category)->next = mrss->category; mrss->category = (*category); break; case MRSS_ELEMENT_TAG: tag = (mrss_tag_t **)data; if (!*tag) { if (!(*tag = (mrss_tag_t *)malloc(sizeof(mrss_tag_t)))) return MRSS_ERR_POSIX; allocated = 1; } else allocated = 0; memset(*tag, 0, sizeof(mrss_tag_t)); (*tag)->element = MRSS_ELEMENT_TAG; (*tag)->allocated = allocated; (*tag)->next = mrss->other_tags; mrss->other_tags = (*tag); break; default: return MRSS_ERR_DATA; } return MRSS_OK; } static mrss_error_t __mrss_new_subdata_item(mrss_item_t *item, mrss_element_t element, mrss_generic_t data) { mrss_category_t **category; mrss_tag_t **tag; int allocated; switch (element) { case MRSS_ELEMENT_CATEGORY: category = (mrss_category_t **)data; if (!*category) { if (!(*category = (mrss_category_t *)malloc(sizeof(mrss_category_t)))) return MRSS_ERR_POSIX; allocated = 1; } else allocated = 0; memset(*category, 0, sizeof(mrss_category_t)); (*category)->element = MRSS_ELEMENT_CATEGORY; (*category)->allocated = allocated; (*category)->next = item->category; item->category = (*category); break; case MRSS_ELEMENT_TAG: tag = (mrss_tag_t **)data; if (!*tag) { if (!(*tag = (mrss_tag_t *)malloc(sizeof(mrss_tag_t)))) return MRSS_ERR_POSIX; allocated = 1; } else allocated = 0; memset(*tag, 0, sizeof(mrss_tag_t)); (*tag)->element = MRSS_ELEMENT_TAG; (*tag)->allocated = allocated; (*tag)->next = item->other_tags; item->other_tags = (*tag); break; default: return MRSS_ERR_DATA; } return MRSS_OK; } static mrss_error_t __mrss_new_subdata_tag(mrss_tag_t *tag, mrss_element_t element, mrss_generic_t data) { mrss_tag_t **new; mrss_attribute_t **attribute; int allocated; switch (element) { case MRSS_ELEMENT_TAG: new = (mrss_tag_t **)data; if (!*new) { if (!(*new = (mrss_tag_t *)malloc(sizeof(mrss_tag_t)))) return MRSS_ERR_POSIX; allocated = 1; } else allocated = 0; memset(*new, 0, sizeof(mrss_tag_t)); (*new)->element = MRSS_ELEMENT_TAG; (*new)->allocated = allocated; (*new)->next = tag->children; tag->children = (*new); break; case MRSS_ELEMENT_ATTRIBUTE: attribute = (mrss_attribute_t **)data; if (!*attribute) { if (!(*attribute = (mrss_attribute_t *)malloc(sizeof(mrss_attribute_t)))) return MRSS_ERR_POSIX; allocated = 1; } else allocated = 0; memset(*attribute, 0, sizeof(mrss_attribute_t)); (*attribute)->element = MRSS_ELEMENT_ATTRIBUTE; (*attribute)->allocated = allocated; (*attribute)->next = tag->attributes; tag->attributes = (*attribute); break; default: return MRSS_ERR_DATA; } return MRSS_OK; } mrss_error_t mrss_remove_subdata(mrss_generic_t data, mrss_generic_t subdata) { mrss_t *tmp; if (!data || !subdata) return MRSS_ERR_DATA; tmp = (mrss_t *)data; switch (tmp->element) { case MRSS_ELEMENT_CHANNEL: return __mrss_remove_subdata_channel((mrss_t *)data, subdata); case MRSS_ELEMENT_ITEM: return __mrss_remove_subdata_item((mrss_item_t *)data, subdata); case MRSS_ELEMENT_TAG: return __mrss_remove_subdata_tag((mrss_tag_t *)data, subdata); default: return MRSS_ERR_DATA; } } static mrss_error_t __mrss_remove_subdata_channel(mrss_t *data, mrss_generic_t subdata) { mrss_hour_t *hour, *hour_tmp, *hour_old; mrss_day_t *day, *day_tmp, *day_old; mrss_category_t *category, *category_tmp, *category_old; mrss_item_t *item, *item_tmp, *item_old; mrss_tag_t *tag, *tag_tmp, *tag_old; int found = 0; mrss_t *tmp = (mrss_t *)subdata; switch (tmp->element) { case MRSS_ELEMENT_ITEM: item = (mrss_item_t *)subdata; item_tmp = data->item; item_old = NULL; while (item_tmp) { if (item_tmp == item) { found++; if (item_old) item_old->next = item_tmp->next; else data->item = item_tmp->next; break; } item_old = item_tmp; item_tmp = item_tmp->next; } if (!found) return MRSS_ERR_DATA; break; case MRSS_ELEMENT_SKIPHOURS: hour = (mrss_hour_t *)subdata; hour_tmp = data->skipHours; hour_old = NULL; while (hour_tmp) { if (hour_tmp == hour) { found++; if (hour_old) hour_old->next = hour_tmp->next; else data->skipHours = hour_tmp->next; break; } hour_old = hour_tmp; hour_tmp = hour_tmp->next; } if (!found) return MRSS_ERR_DATA; break; case MRSS_ELEMENT_SKIPDAYS: day = (mrss_day_t *)subdata; day_tmp = data->skipDays; day_old = NULL; while (day_tmp) { if (day_tmp == day) { found++; if (day_old) day_old->next = day_tmp->next; else data->skipDays = day_tmp->next; break; } day_old = day_tmp; day_tmp = day_tmp->next; } if (!found) return MRSS_ERR_DATA; break; case MRSS_ELEMENT_CATEGORY: category = (mrss_category_t *)subdata; category_tmp = data->category; category_old = NULL; while (category_tmp) { if (category_tmp == category) { found++; if (category_old) category_old->next = category_tmp->next; else data->category = category_tmp->next; break; } category_old = category_tmp; category_tmp = category_tmp->next; } if (!found) return MRSS_ERR_DATA; break; case MRSS_ELEMENT_TAG: tag = (mrss_tag_t *)subdata; tag_tmp = data->other_tags; tag_old = NULL; while (tag_tmp) { if (tag_tmp == tag) { found++; if (tag_old) tag_old->next = tag_tmp->next; else data->other_tags = tag_tmp->next; break; } tag_old = tag_tmp; tag_tmp = tag_tmp->next; } if (!found) return MRSS_ERR_DATA; break; default: return MRSS_ERR_DATA; } return MRSS_OK; } static mrss_error_t __mrss_remove_subdata_item(mrss_item_t *data, mrss_generic_t subdata) { mrss_category_t *category, *category_tmp, *category_old; mrss_tag_t *tag, *tag_tmp, *tag_old; int found = 0; mrss_t *tmp = (mrss_t *)subdata; switch (tmp->element) { case MRSS_ELEMENT_CATEGORY: category = (mrss_category_t *)subdata; category_tmp = data->category; category_old = NULL; while (category_tmp) { if (category_tmp == category) { found++; if (category_old) category_old->next = category_tmp->next; else data->category = category_tmp->next; break; } category_old = category_tmp; category_tmp = category_tmp->next; } if (!found) return MRSS_ERR_DATA; break; case MRSS_ELEMENT_TAG: tag = (mrss_tag_t *)subdata; tag_tmp = data->other_tags; tag_old = NULL; while (tag_tmp) { if (tag_tmp == tag) { found++; if (tag_old) tag_old->next = tag_tmp->next; else data->other_tags = tag_tmp->next; break; } tag_old = tag_tmp; tag_tmp = tag_tmp->next; } if (!found) return MRSS_ERR_DATA; break; default: return MRSS_ERR_DATA; } return MRSS_OK; } static mrss_error_t __mrss_remove_subdata_tag(mrss_tag_t *data, mrss_generic_t subdata) { mrss_attribute_t *attribute, *attribute_tmp, *attribute_old; mrss_tag_t *tag, *tag_tmp, *tag_old; int found = 0; mrss_t *tmp = (mrss_t *)subdata; switch (tmp->element) { case MRSS_ELEMENT_TAG: tag = (mrss_tag_t *)subdata; tag_tmp = data->children; tag_old = NULL; while (tag_tmp) { if (tag_tmp == tag) { found++; if (tag_old) tag_old->next = tag_tmp->next; else data->children = tag_tmp->next; break; } tag_old = tag_tmp; tag_tmp = tag_tmp->next; } if (!found) return MRSS_ERR_DATA; break; case MRSS_ELEMENT_ATTRIBUTE: attribute = (mrss_attribute_t *)subdata; attribute_tmp = data->attributes; attribute_old = NULL; while (attribute_tmp) { if (attribute_tmp == attribute) { found++; if (attribute_old) attribute_old->next = attribute_tmp->next; else data->attributes = attribute_tmp->next; break; } attribute_old = attribute_tmp; attribute_tmp = attribute_tmp->next; } if (!found) return MRSS_ERR_DATA; break; default: return MRSS_ERR_DATA; } return MRSS_OK; } /* EOF */ libmrss-0.19.4/src/mrss_free.c000066400000000000000000000205751456537604200162250ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #else #error Use configure; make; make install #endif #include "mrss.h" #include "mrss_internal.h" static void __mrss_free_channel(mrss_t *mrss); static void __mrss_free_category(mrss_category_t *category); static void __mrss_free_hour(mrss_hour_t *hour); static void __mrss_free_day(mrss_day_t *day); static void __mrss_free_item(mrss_item_t *item); static void __mrss_free_tag(mrss_tag_t *tag); static void __mrss_free_attribute(mrss_attribute_t *attribute); static void __mrss_free_channel(mrss_t *mrss) { mrss_hour_t *hour; mrss_day_t *day; mrss_category_t *category; mrss_item_t *item; mrss_tag_t *tag; void *old; if (!mrss) return; if (mrss->file) free(mrss->file); if (mrss->encoding) free(mrss->encoding); if (mrss->title) free(mrss->title); if (mrss->title_type) free(mrss->title_type); if (mrss->description) free(mrss->description); if (mrss->description_type) free(mrss->description_type); if (mrss->link) free(mrss->link); if (mrss->id) free(mrss->id); if (mrss->language) free(mrss->language); if (mrss->rating) free(mrss->rating); if (mrss->copyright) free(mrss->copyright); if (mrss->copyright_type) free(mrss->copyright_type); if (mrss->pubDate) free(mrss->pubDate); if (mrss->lastBuildDate) free(mrss->lastBuildDate); if (mrss->docs) free(mrss->docs); if (mrss->managingeditor) free(mrss->managingeditor); if (mrss->managingeditor_email) free(mrss->managingeditor_email); if (mrss->managingeditor_uri) free(mrss->managingeditor_uri); if (mrss->webMaster) free(mrss->webMaster); if (mrss->about) free(mrss->about); if (mrss->contributor) free(mrss->contributor); if (mrss->contributor_email) free(mrss->contributor_email); if (mrss->contributor_uri) free(mrss->contributor_uri); if (mrss->generator) free(mrss->generator); if (mrss->generator_uri) free(mrss->generator_uri); if (mrss->generator_version) free(mrss->generator_version); if (mrss->image_title) free(mrss->image_title); if (mrss->image_url) free(mrss->image_url); if (mrss->image_logo) free(mrss->image_logo); if (mrss->image_link) free(mrss->image_link); if (mrss->image_description) free(mrss->image_description); if (mrss->textinput_title) free(mrss->textinput_title); if (mrss->textinput_description) free(mrss->textinput_description); if (mrss->textinput_name) free(mrss->textinput_name); if (mrss->textinput_link) free(mrss->textinput_link); if (mrss->cloud) free(mrss->cloud); if (mrss->cloud_domain) free(mrss->cloud_domain); if (mrss->cloud_path) free(mrss->cloud_path); if (mrss->cloud_registerProcedure) free(mrss->cloud_registerProcedure); if (mrss->cloud_protocol) free(mrss->cloud_protocol); category = mrss->category; while (category) { old = category; category = category->next; __mrss_free_category((mrss_category_t *)old); } tag = mrss->other_tags; while (tag) { old = tag; tag = tag->next; __mrss_free_tag((mrss_tag_t *)old); } hour = mrss->skipHours; while (hour) { old = hour; hour = hour->next; __mrss_free_hour((mrss_hour_t *)old); } day = mrss->skipDays; while (day) { old = day; day = day->next; __mrss_free_day((mrss_day_t *)old); } item = mrss->item; while (item) { old = item; item = item->next; __mrss_free_item((mrss_item_t *)old); } #ifdef USE_LOCALE if (mrss->c_locale) freelocale(mrss->c_locale); #endif if (mrss->allocated) free(mrss); } static void __mrss_free_tag(mrss_tag_t *tag) { mrss_attribute_t *attribute; mrss_tag_t *child; void *old; if (!tag) return; if (tag->name) free(tag->name); if (tag->value) free(tag->value); if (tag->ns) free(tag->ns); attribute = tag->attributes; while (attribute) { old = attribute; attribute = attribute->next; __mrss_free_attribute((mrss_attribute_t *)old); } child = tag->children; while (child) { old = child; child = child->next; __mrss_free_tag((mrss_tag_t *)old); } if (tag->allocated) free(tag); } static void __mrss_free_attribute(mrss_attribute_t *attribute) { if (!attribute) return; if (attribute->name) free(attribute->name); if (attribute->value) free(attribute->value); if (attribute->ns) free(attribute->ns); if (attribute->allocated) free(attribute); } static void __mrss_free_category(mrss_category_t *category) { if (!category) return; if (category->category) free(category->category); if (category->domain) free(category->domain); if (category->label) free(category->label); if (category->allocated) free(category); } static void __mrss_free_hour(mrss_hour_t *hour) { if (!hour) return; if (hour->hour) free(hour->hour); if (hour->allocated) free(hour); } static void __mrss_free_day(mrss_day_t *day) { if (!day) return; if (day->day) free(day->day); if (day->allocated) free(day); } static void __mrss_free_item(mrss_item_t *item) { mrss_category_t *category; mrss_tag_t *tag; void *old; if (!item) return; if (item->title) free(item->title); if (item->title_type) free(item->title_type); if (item->link) free(item->link); if (item->description) free(item->description); if (item->description_type) free(item->description_type); if (item->copyright) free(item->copyright); if (item->copyright_type) free(item->copyright_type); if (item->author) free(item->author); if (item->author_email) free(item->author_email); if (item->author_uri) free(item->author_uri); if (item->contributor) free(item->contributor); if (item->contributor_email) free(item->contributor_email); if (item->contributor_uri) free(item->contributor_uri); if (item->comments) free(item->comments); if (item->pubDate) free(item->pubDate); if (item->guid) free(item->guid); if (item->source) free(item->source); if (item->source_url) free(item->source_url); if (item->enclosure) free(item->enclosure); if (item->enclosure_url) free(item->enclosure_url); if (item->enclosure_type) free(item->enclosure_type); category = item->category; while (category) { old = category; category = category->next; __mrss_free_category((mrss_category_t *)old); } tag = item->other_tags; while (tag) { old = tag; tag = tag->next; __mrss_free_tag((mrss_tag_t *)old); } if (item->allocated) free(item); } /*************************** EXTERNAL FUNCTION ******************************/ mrss_error_t mrss_free(mrss_generic_t element) { mrss_t *tmp; tmp = (mrss_t *)element; if (!tmp) return MRSS_OK; switch (tmp->element) { case MRSS_ELEMENT_CHANNEL: __mrss_free_channel((mrss_t *)element); break; case MRSS_ELEMENT_ITEM: __mrss_free_item((mrss_item_t *)element); break; case MRSS_ELEMENT_SKIPHOURS: __mrss_free_hour((mrss_hour_t *)element); break; case MRSS_ELEMENT_SKIPDAYS: __mrss_free_day((mrss_day_t *)element); break; case MRSS_ELEMENT_CATEGORY: __mrss_free_category((mrss_category_t *)element); break; case MRSS_ELEMENT_TAG: __mrss_free_tag((mrss_tag_t *)element); break; case MRSS_ELEMENT_ATTRIBUTE: __mrss_free_attribute((mrss_attribute_t *)element); break; default: return MRSS_ERR_DATA; } return MRSS_OK; } /* EOF */ libmrss-0.19.4/src/mrss_generic.c000066400000000000000000000074351456537604200167200ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #else #error Use configure; make; make install #endif #include "mrss.h" #include "mrss_internal.h" char *mrss_strerror(mrss_error_t err) { switch (err) { case MRSS_OK: return "Success"; case MRSS_ERR_PARSER: return "Parser error"; case MRSS_ERR_DOWNLOAD: return "Download error"; case MRSS_ERR_VERSION: return "Version error"; case MRSS_ERR_DATA: return "No correct paramenter in the function"; default: return strerror(errno); } } char *mrss_curl_strerror(CURLcode err) { return (char *)curl_easy_strerror(err); } mrss_error_t mrss_element(mrss_generic_t element, mrss_element_t *ret) { mrss_t *tmp; if (!element || !ret) return MRSS_ERR_DATA; tmp = (mrss_t *)element; *ret = tmp->element; return MRSS_OK; } static size_t __mrss_get_last_modified_header(void *ptr, size_t size, size_t nmemb, time_t *timing) { char *header = (char *)ptr; if (!strncmp("Last-Modified:", header, 14)) *timing = curl_getdate(header + 14, NULL); return size * nmemb; } mrss_error_t mrss_get_last_modified(char *urlstring, time_t *lastmodified) { return mrss_get_last_modified_with_options(urlstring, lastmodified, NULL); } mrss_error_t mrss_get_last_modified_with_options(char *urlstring, time_t *lastmodified, mrss_options_t *options) { CURL *curl; if (!urlstring || !lastmodified) return MRSS_ERR_DATA; *lastmodified = 0; curl_global_init(CURL_GLOBAL_DEFAULT); if (!(curl = curl_easy_init())) return MRSS_ERR_POSIX; curl_easy_setopt(curl, CURLOPT_URL, urlstring); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, __mrss_get_last_modified_header); curl_easy_setopt(curl, CURLOPT_HEADERDATA, lastmodified); curl_easy_setopt(curl, CURLOPT_NOBODY, 1); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); if (options) { if (options->timeout > 0) curl_easy_setopt(curl, CURLOPT_TIMEOUT, options->timeout); else if (options->timeout < 0) curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); if (options->certfile) curl_easy_setopt(curl, CURLOPT_SSLCERT, options->certfile); if (options->password) curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, options->password); if (options->cacert) curl_easy_setopt(curl, CURLOPT_CAINFO, options->cacert); if (options->proxy) { curl_easy_setopt(curl, CURLOPT_PROXY, options->proxy); if (options->proxy_authentication) curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, options->proxy_authentication); } curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, options->verifypeer); } if (curl_easy_perform(curl)) { curl_easy_cleanup(curl); return MRSS_ERR_POSIX; } curl_easy_cleanup(curl); return MRSS_OK; } /* EOF */ libmrss-0.19.4/src/mrss_internal.h000066400000000000000000000024361456537604200171210ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __M_RSS_INTERNAL_H__ #define __M_RSS_INTERNAL_H__ #include #include #include #include #include #include #ifdef USE_LOCALE #ifdef USE_X_LOCALE #include #endif #ifdef USE_GENERIC_LOCALE #include #endif #endif char *__mrss_download_file(nxml_t *, char *, size_t *, mrss_error_t *, CURLcode *code); #endif /* EOF */ libmrss-0.19.4/src/mrss_options.c000066400000000000000000000046571456537604200170020ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #else #error Use configure; make; make install #endif #include "mrss.h" #include "mrss_internal.h" mrss_options_t *mrss_options_new(int timeout, char *proxy, char *proxy_authentication, char *certfile, char *password, char *cacert, int verifypeer, char *authentication, char *user_agent) { mrss_options_t *options; if (!(options = (mrss_options_t *)malloc(sizeof(mrss_options_t)))) return NULL; options->timeout = timeout; options->proxy = proxy ? strdup(proxy) : NULL; options->proxy_authentication = proxy_authentication ? strdup(proxy_authentication) : NULL; options->certfile = certfile ? strdup(certfile) : NULL; options->password = password ? strdup(password) : NULL; options->cacert = cacert ? strdup(cacert) : NULL; options->authentication = authentication ? strdup(authentication) : NULL; options->user_agent = user_agent ? strdup(user_agent) : NULL; options->verifypeer = verifypeer; return options; } void mrss_options_free(mrss_options_t *options) { if (!options) return; if (options->proxy) free(options->proxy); if (options->proxy_authentication) free(options->proxy_authentication); if (options->certfile) free(options->certfile); if (options->password) free(options->password); if (options->cacert) free(options->cacert); if (options->authentication) free(options->authentication); if (options->user_agent) free(options->user_agent); free(options); } /* EOF */ libmrss-0.19.4/src/mrss_parser.c000066400000000000000000000771441456537604200166040ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #else #error Use configure; make; make install #endif #include "mrss.h" #include "mrss_internal.h" static void __mrss_parse_tag_insert(mrss_tag_t **where, mrss_tag_t *what) { if (!*where) *where = what; else { mrss_tag_t *tag = *where; while (tag->next) tag = tag->next; tag->next = what; } } static mrss_tag_t *__mrss_parse_tag(nxml_t *doc, nxml_data_t *cur) { mrss_tag_t *tag; mrss_attribute_t *attribute; nxml_attr_t *nxml_attr; if (!(tag = (mrss_tag_t *)calloc(1, sizeof(mrss_tag_t)))) return NULL; tag->element = MRSS_ELEMENT_TAG; tag->allocated = 1; if (!(tag->name = strdup(cur->value))) { mrss_free(tag); return NULL; } if (cur->ns && cur->ns->ns && !(tag->ns = strdup(cur->ns->ns))) { mrss_free(tag); return NULL; } for (nxml_attr = cur->attributes; nxml_attr; nxml_attr = nxml_attr->next) { if (!(attribute = (mrss_attribute_t *)calloc(1, sizeof(mrss_attribute_t)))) return NULL; attribute->element = MRSS_ELEMENT_ATTRIBUTE; attribute->allocated = 1; if (!(attribute->name = strdup(nxml_attr->name))) { mrss_free(tag); return NULL; } if (!(attribute->value = strdup(nxml_attr->value))) { mrss_free(tag); return NULL; } if (nxml_attr->ns && nxml_attr->ns->ns && !(attribute->ns = strdup(nxml_attr->ns->ns))) { mrss_free(tag); return NULL; } if (!tag->attributes) tag->attributes = attribute; else { mrss_attribute_t *tmp = tag->attributes; while (tmp->next) tmp = tmp->next; tmp->next = attribute; } } for (cur = cur->children; cur; cur = cur->next) { if (cur->type == NXML_TYPE_TEXT) { if (!tag->value && !(tag->value = strdup(cur->value))) { mrss_free(tag); return NULL; } } else if (cur->type == NXML_TYPE_ELEMENT) { mrss_tag_t *child = __mrss_parse_tag(doc, cur); if (child) __mrss_parse_tag_insert(&tag->children, child); } } return tag; } static void __mrss_parser_atom_string(nxml_t *doc, nxml_data_t *cur, char **what, char **type) { char *c; if (!(c = nxmle_find_attribute(cur, "type", NULL)) || !strcmp(c, "text")) { *what = nxmle_get_string(cur, NULL); *type = c; return; } if (!strcmp(c, "html") || !strcmp(c, "xhtml")) { nxml_data_t *ncur; char *total, *c1; nxml_t *new; int size; total = NULL; size = 0; c1 = nxmle_get_string(cur, NULL); if (c1 && *c1) { total = c1; size = strlen(total); } else { free(c1); while ((ncur = cur->children)) { char *buffer = NULL, *p; char *tmp; int len; if (nxml_remove(doc, cur, ncur) != NXML_OK) continue; if (nxml_new(&new) != NXML_OK) { nxml_free_data(ncur); continue; } if (nxml_add(new, NULL, &ncur) != NXML_OK) { nxml_free_data(ncur); nxml_free(new); continue; } if (!(buffer = nxmle_write_buffer(new, NULL))) { nxml_free(new); continue; } nxml_free(new); if (strncmp(buffer, "') p++; if (!*p) { free(buffer); continue; } p++; while (*p && (*p == ' ' || *p == '\t' || *p == '\n')) p++; len = strlen(p); if (!(tmp = realloc(total, size + len + 1))) { free(buffer); if (total) { free(total); total = NULL; } break; } total = tmp; strcpy(total + size, p); size += len; free(buffer); } } *what = total; *type = c; return; } free(c); *what = nxmle_get_string(cur, NULL); } static char *__mrss_atom_prepare_date(mrss_t *data, char *datestr) { struct tm stm; if (!datestr) return NULL; memset(&stm, 0, sizeof(stm)); /* ISO8601 Local TZ timestamp: 2018-04-04T09:27:41CEST */ if (strptime(datestr, "%Y-%m-%dT%T%Z", &stm) != NULL) { char datebuf[256]; #ifdef USE_LOCALE if (!data->c_locale && !(data->c_locale = newlocale(LC_ALL_MASK, "C", NULL))) return NULL; strftime_l(datebuf, sizeof(datebuf), "%a, %d %b %Y %H:%M:%S %z", &stm, data->c_locale); #else strftime(datebuf, sizeof(datebuf), "%a, %d %b %Y %H:%M:%S %z", &stm); #endif return strdup(datebuf); } return NULL; } static void __mrss_parser_atom_category(nxml_data_t *cur, mrss_category_t **category) { char *c; mrss_category_t *cat; if (!(cat = calloc(1, sizeof(mrss_category_t)))) return; if (!(c = nxmle_find_attribute(cur, "term", NULL))) { free(cat); return; } cat->element = MRSS_ELEMENT_CATEGORY; cat->allocated = 1; cat->category = c; if ((c = nxmle_find_attribute(cur, "scheme", NULL))) cat->domain = c; if ((c = nxmle_find_attribute(cur, "label", NULL))) cat->label = c; if (!*category) *category = cat; else { mrss_category_t *tmp; tmp = *category; while (tmp->next) tmp = tmp->next; tmp->next = cat; } } static void __mrss_parser_atom_author(nxml_data_t *cur, char **name, char **email, char **uri) { for (cur = cur->children; cur; cur = cur->next) { if (!*name && !strcmp(cur->value, "name")) *name = nxmle_get_string(cur, NULL); else if (!*email && !strcmp(cur->value, "email")) *email = nxmle_get_string(cur, NULL); else if (!*uri && !strcmp(cur->value, "uri")) *uri = nxmle_get_string(cur, NULL); } } static void __mrss_parser_atom_entry(nxml_t *doc, nxml_data_t *cur, mrss_t *data) { char *c; mrss_item_t *item; if (!(item = malloc(sizeof(mrss_item_t)))) return; memset(item, 0, sizeof(mrss_item_t)); item->element = MRSS_ELEMENT_ITEM; item->allocated = 1; for (cur = cur->children; cur; cur = cur->next) { if (cur->type == NXML_TYPE_ELEMENT) { /* title -> title */ if (!item->title && !strcmp(cur->value, "title")) __mrss_parser_atom_string(doc, cur, &item->title, &item->title_type); /* link href -> link */ else if (!item->link && !strcmp(cur->value, "link") && (c = nxmle_find_attribute(cur, "href", NULL))) item->link = c; /* content -> description */ else if (!item->description && !strcmp(cur->value, "content")) __mrss_parser_atom_string(doc, cur, &item->description, &item->description_type); /* summary -> description */ else if (!item->description && !strcmp(cur->value, "summary")) __mrss_parser_atom_string(doc, cur, &item->description, &item->description_type); /* right -> copyright */ else if (!item->copyright && !strcmp(cur->value, "rights")) __mrss_parser_atom_string(doc, cur, &item->copyright, &item->copyright_type); /* author structure -> author elements */ else if (!strcmp(cur->value, "author")) __mrss_parser_atom_author(cur, &item->author, &item->author_email, &item->author_uri); /* contributor structure -> contributor elements */ else if (!strcmp(cur->value, "contributor")) __mrss_parser_atom_author(cur, &item->contributor, &item->contributor_email, &item->contributor_uri); /* published -> pubDate */ else if (!item->pubDate && !strcmp(cur->value, "published") && data->version == MRSS_VERSION_ATOM_1_0 && (c = nxmle_get_string(cur, NULL))) { item->pubDate = __mrss_atom_prepare_date(data, c); free(c); } else if (!item->pubDate && !strcmp(cur->value, "updated") && data->version == MRSS_VERSION_ATOM_1_0 && (c = nxmle_get_string(cur, NULL))) { item->pubDate = __mrss_atom_prepare_date(data, c); free(c); } /* issued -> pubDate (Atom 0.3) */ else if (!item->pubDate && !strcmp(cur->value, "issued") && (c = nxmle_get_string(cur, NULL))) { item->pubDate = __mrss_atom_prepare_date(data, c); free(c); } /* id -> guid */ else if (!item->guid && !strcmp(cur->value, "id") && (c = nxmle_get_string(cur, NULL))) item->guid = c; /* categories */ else if (!strcmp(cur->value, "category")) __mrss_parser_atom_category(cur, &item->category); else { mrss_tag_t *tag; if ((tag = __mrss_parse_tag(doc, cur))) __mrss_parse_tag_insert(&item->other_tags, tag); } } } if (!data->item) data->item = item; else { mrss_item_t *tmp = data->item; while (tmp->next) tmp = tmp->next; tmp->next = item; } } static void __mrss_parser_rss_image(nxml_t *doc, nxml_data_t *cur, mrss_t *data) { char *c; for (cur = cur->children; cur; cur = cur->next) { if (cur->type == NXML_TYPE_ELEMENT) { /* title */ if (!strcmp(cur->value, "title") && !data->image_title && (c = nxmle_get_string(cur, NULL))) data->image_title = c; /* url */ else if (!strcmp(cur->value, "url") && !data->image_url && (c = nxmle_get_string(cur, NULL))) data->image_url = c; /* link */ else if (!strcmp(cur->value, "link") && !data->image_link && (c = nxmle_get_string(cur, NULL))) data->image_link = c; /* width */ else if (!strcmp(cur->value, "width") && !data->image_width && (c = nxmle_get_string(cur, NULL))) { data->image_width = atoi(c); free(c); } /* height */ else if (!strcmp(cur->value, "height") && !data->image_height && (c = nxmle_get_string(cur, NULL))) { data->image_height = atoi(c); free(c); } /* description */ else if (!strcmp(cur->value, "description") && !data->image_description && (c = nxmle_get_string(cur, NULL))) data->image_description = c; } } } static void __mrss_parser_rss_textinput(nxml_t *doc, nxml_data_t *cur, mrss_t *data) { char *c; for (cur = cur->children; cur; cur = cur->next) { if (cur->type == NXML_TYPE_ELEMENT) { /* title */ if (!strcmp(cur->value, "title") && !data->textinput_title && (c = nxmle_get_string(cur, NULL))) data->textinput_title = c; /* description */ else if (!strcmp(cur->value, "description") && !data->textinput_description && (c = nxmle_get_string(cur, NULL))) data->textinput_description = c; /* name */ else if (!strcmp(cur->value, "name") && !data->textinput_name && (c = nxmle_get_string(cur, NULL))) data->textinput_name = c; /* link */ else if (!strcmp(cur->value, "link") && !data->textinput_link && (c = nxmle_get_string(cur, NULL))) data->textinput_link = c; } } } static void __mrss_parser_rss_skipHours(nxml_t *doc, nxml_data_t *cur, mrss_t *data) { char *c; for (cur = cur->children; cur; cur = cur->next) { if (cur->type == NXML_TYPE_ELEMENT) { if (!strcmp(cur->value, "hour") && (c = nxmle_get_string(cur, NULL))) { mrss_hour_t *hour; if (!(hour = (mrss_hour_t *)calloc(1, sizeof(mrss_hour_t)))) { free(c); return; } hour->element = MRSS_ELEMENT_SKIPHOURS; hour->allocated = 1; hour->hour = c; if (!data->skipHours) data->skipHours = hour; else { mrss_hour_t *tmp; tmp = data->skipHours; while (tmp->next) tmp = tmp->next; tmp->next = hour; } } } } } static void __mrss_parser_rss_skipDays(nxml_t *doc, nxml_data_t *cur, mrss_t *data) { char *c; for (cur = cur->children; cur; cur = cur->next) { if (cur->type == NXML_TYPE_ELEMENT) { if (!strcmp(cur->value, "day") && (c = nxmle_get_string(cur, NULL))) { mrss_day_t *day; if (!(day = (mrss_day_t *)calloc(1, sizeof(mrss_day_t)))) { free(c); return; } day->element = MRSS_ELEMENT_SKIPDAYS; day->allocated = 1; day->day = c; if (!data->skipDays) data->skipDays = day; else { mrss_day_t *tmp; tmp = data->skipDays; while (tmp->next) tmp = tmp->next; tmp->next = day; } } } } } static void __mrss_parser_rss_item(nxml_t *doc, nxml_data_t *cur, mrss_t *data) { char *c; char *attr; mrss_item_t *item; if (!(item = (mrss_item_t *)calloc(1, sizeof(mrss_item_t)))) return; item->element = MRSS_ELEMENT_ITEM; item->allocated = 1; for (cur = cur->children; cur; cur = cur->next) { if (cur->type == NXML_TYPE_ELEMENT) { /* title */ if (!strcmp(cur->value, "title") && !item->title && (c = nxmle_get_string(cur, NULL))) item->title = c; /* link */ else if (!strcmp(cur->value, "link") && !item->link && (c = nxmle_get_string(cur, NULL))) item->link = c; /* description */ else if (!strcmp(cur->value, "description") && !item->description && (c = nxmle_get_string(cur, NULL))) item->description = c; /* source */ else if (!strcmp(cur->value, "source") && !item->source) { item->source = nxmle_get_string(cur, NULL); if ((attr = nxmle_find_attribute(cur, "url", NULL))) item->source_url = attr; } /* enclosure */ else if (!strcmp(cur->value, "enclosure") && !item->enclosure) { item->enclosure = nxmle_get_string(cur, NULL); if ((attr = nxmle_find_attribute(cur, "url", NULL))) item->enclosure_url = attr; if ((attr = nxmle_find_attribute(cur, "length", NULL))) { item->enclosure_length = atoi(attr); free(attr); } if ((attr = nxmle_find_attribute(cur, "type", NULL))) item->enclosure_type = attr; } /* category */ else if (!strcmp(cur->value, "category") && (c = nxmle_get_string(cur, NULL))) { mrss_category_t *category; if (!(category = (mrss_category_t *)calloc(1, sizeof(mrss_category_t)))) { free(c); return; } category->element = MRSS_ELEMENT_CATEGORY; category->allocated = 1; category->category = c; if ((attr = nxmle_find_attribute(cur, "domain", NULL))) category->domain = attr; if (!item->category) item->category = category; else { mrss_category_t *tmp; tmp = item->category; while (tmp->next) tmp = tmp->next; tmp->next = category; } } /* author */ else if (!strcmp(cur->value, "author") && !item->author && (c = nxmle_get_string(cur, NULL))) item->author = c; /* comments */ else if (!strcmp(cur->value, "comments") && !item->comments && (c = nxmle_get_string(cur, NULL))) item->comments = c; /* guid */ else if (!strcmp(cur->value, "guid") && !item->guid && (c = nxmle_get_string(cur, NULL))) { item->guid = c; if ((attr = nxmle_find_attribute(cur, "isPermaLink", NULL))) { if (!strcmp(attr, "false")) item->guid_isPermaLink = 0; else item->guid_isPermaLink = 1; free(attr); } } /* pubDate */ else if (!strcmp(cur->value, "pubDate") && !item->pubDate && (c = nxmle_get_string(cur, NULL))) item->pubDate = c; /* Other tags: */ else { mrss_tag_t *tag; if ((tag = __mrss_parse_tag(doc, cur))) __mrss_parse_tag_insert(&item->other_tags, tag); } } } if (!data->item) data->item = item; else { mrss_item_t *tmp; tmp = data->item; while (tmp->next) tmp = tmp->next; tmp->next = item; } } static mrss_error_t __mrss_parser_atom(nxml_t *doc, nxml_data_t *cur, mrss_t **ret) { mrss_t *data; char *c = NULL; if (!(data = malloc(sizeof(mrss_t)))) return MRSS_ERR_POSIX; memset(data, 0, sizeof(mrss_t)); data->element = MRSS_ELEMENT_CHANNEL; data->allocated = 1; data->version = MRSS_VERSION_ATOM_1_0; if (doc->encoding && !(data->encoding = strdup(doc->encoding))) { mrss_free(data); return MRSS_ERR_POSIX; } if (!data->language && (c = nxmle_find_attribute(cur, "xml:lang", NULL))) data->language = c; if ((c = nxmle_find_attribute(cur, "version", NULL))) { if (!strcmp(c, "0.3")) data->version = MRSS_VERSION_ATOM_0_3; free(c); } for (cur = cur->children; cur; cur = cur->next) { if (cur->type == NXML_TYPE_ELEMENT) { /* title -> title */ if (!data->title && !strcmp(cur->value, "title")) __mrss_parser_atom_string(doc, cur, &data->title, &data->title_type); /* subtitle -> description */ else if (!data->description && data->version == MRSS_VERSION_ATOM_1_0 && !strcmp(cur->value, "subtitle")) __mrss_parser_atom_string(doc, cur, &data->description, &data->description_type); /* tagline -> description (Atom 0.3) */ else if (data->version == MRSS_VERSION_ATOM_0_3 && !data->description && !strcmp(cur->value, "tagline")) __mrss_parser_atom_string(doc, cur, &data->description, &data->description_type); /* link href -> link */ else if (!strcmp(cur->value, "link") && !data->link && (c = nxmle_find_attribute(cur, "href", NULL))) data->link = c; /* id -> id */ else if (!strcmp(cur->value, "id") && !data->id && (c = nxmle_get_string(cur, NULL))) data->id = c; /* rights -> copyright */ else if (!data->copyright && !strcmp(cur->value, "rights")) __mrss_parser_atom_string(doc, cur, &data->copyright, &data->copyright_type); /* updated -> lastBuildDate */ else if (!strcmp(cur->value, "updated") && (c = nxmle_get_string(cur, NULL))) { data->lastBuildDate = __mrss_atom_prepare_date(data, c); free(c); } /* author -> managingeditor */ else if (!strcmp(cur->value, "author")) __mrss_parser_atom_author(cur, &data->managingeditor, &data->managingeditor_email, &data->managingeditor_uri); /* contributor */ else if (!strcmp(cur->value, "contributor")) __mrss_parser_atom_author(cur, &data->contributor, &data->contributor_email, &data->contributor_uri); /* generator -> generator */ else if (!strcmp(cur->value, "generator") && !data->generator && (c = nxmle_get_string(cur, NULL))) { char *attr; data->generator = c; if ((attr = nxmle_find_attribute(cur, "uri", NULL))) data->generator_uri = attr; if ((attr = nxmle_find_attribute(cur, "version", NULL))) data->generator_version = attr; } /* icon -> image_url */ else if (!strcmp(cur->value, "icon") && !data->image_url && (c = nxmle_get_string(cur, NULL))) data->image_url = c; /* logo -> image_logo */ else if (!strcmp(cur->value, "logo") && !data->image_logo && (c = nxmle_get_string(cur, NULL))) data->image_logo = c; /* category */ else if (!strcmp(cur->value, "category")) __mrss_parser_atom_category(cur, &data->category); /* entry -> item */ else if (!strcmp(cur->value, "entry")) __mrss_parser_atom_entry(doc, cur, data); else { mrss_tag_t *tag; if ((tag = __mrss_parse_tag(doc, cur))) __mrss_parse_tag_insert(&data->other_tags, tag); } } } *ret = data; return MRSS_OK; } static mrss_error_t __mrss_parser_rss(mrss_version_t v, nxml_t *doc, nxml_data_t *cur, mrss_t **ret) { mrss_t *data; char *c, *attr; if (!(data = (mrss_t *)calloc(1, sizeof(mrss_t)))) return MRSS_ERR_POSIX; data->element = MRSS_ELEMENT_CHANNEL; data->allocated = 1; data->version = v; if (doc->encoding && !(data->encoding = strdup(doc->encoding))) { mrss_free(data); return MRSS_ERR_POSIX; } if (data->version == MRSS_VERSION_1_0) { nxml_data_t *cur_channel = NULL; while (cur) { if (!strcmp(cur->value, "channel")) cur_channel = cur; else if (!strcmp(cur->value, "image")) __mrss_parser_rss_image(doc, cur, data); else if (!strcmp(cur->value, "textinput")) __mrss_parser_rss_textinput(doc, cur, data); else if (!strcmp(cur->value, "item")) __mrss_parser_rss_item(doc, cur, data); cur = cur->next; } cur = cur_channel; } else { while (cur && strcmp(cur->value, "channel")) cur = cur->next; } if (!cur) { mrss_free(data); return MRSS_ERR_PARSER; } if (data->version == MRSS_VERSION_1_0) { if ((attr = nxmle_find_attribute(cur, "about", NULL))) data->about = attr; } for (cur = cur->children; cur; cur = cur->next) { if (cur->type == NXML_TYPE_ELEMENT) { /* title */ if (!strcmp(cur->value, "title") && !data->title && (c = nxmle_get_string(cur, NULL))) data->title = c; /* description */ else if (!strcmp(cur->value, "description") && !data->description && (c = nxmle_get_string(cur, NULL))) data->description = c; /* link */ else if (!strcmp(cur->value, "link") && !data->link && (c = nxmle_get_string(cur, NULL))) data->link = c; /* language */ else if (!strcmp(cur->value, "language") && !data->language && (c = nxmle_get_string(cur, NULL))) data->language = c; /* rating */ else if (!strcmp(cur->value, "rating") && !data->rating && (c = nxmle_get_string(cur, NULL))) data->rating = c; /* copyright */ else if (!strcmp(cur->value, "copyright") && !data->copyright && (c = nxmle_get_string(cur, NULL))) data->copyright = c; /* pubDate */ else if (!strcmp(cur->value, "pubDate") && !data->pubDate && (c = nxmle_get_string(cur, NULL))) data->pubDate = c; /* lastBuildDate */ else if (!strcmp(cur->value, "lastBuildDate") && !data->lastBuildDate && (c = nxmle_get_string(cur, NULL))) data->lastBuildDate = c; /* docs */ else if (!strcmp(cur->value, "docs") && !data->docs && (c = nxmle_get_string(cur, NULL))) data->docs = c; /* managingeditor */ else if (!strcmp(cur->value, "managingeditor") && !data->managingeditor && (c = nxmle_get_string(cur, NULL))) data->managingeditor = c; /* webMaster */ else if (!strcmp(cur->value, "webMaster") && !data->webMaster && (c = nxmle_get_string(cur, NULL))) data->webMaster = c; /* image */ else if (!strcmp(cur->value, "image")) __mrss_parser_rss_image(doc, cur, data); /* textinput */ else if (!strcmp(cur->value, "textinput")) __mrss_parser_rss_textinput(doc, cur, data); /* skipHours */ else if (!strcmp(cur->value, "skipHours")) __mrss_parser_rss_skipHours(doc, cur, data); /* skipDays */ else if (!strcmp(cur->value, "skipDays")) __mrss_parser_rss_skipDays(doc, cur, data); /* item */ else if (!strcmp(cur->value, "item")) __mrss_parser_rss_item(doc, cur, data); /* category */ else if (!strcmp(cur->value, "category") && (c = nxmle_get_string(cur, NULL))) { mrss_category_t *category; if (!(category = (mrss_category_t *)calloc(1, sizeof(mrss_category_t)))) { mrss_free((mrss_generic_t *)data); free(c); return MRSS_ERR_POSIX; } category->element = MRSS_ELEMENT_CATEGORY; category->allocated = 1; category->category = c; if ((attr = nxmle_find_attribute(cur, "domain", NULL))) category->domain = attr; if (!data->category) data->category = category; else { mrss_category_t *tmp; tmp = data->category; while (tmp->next) tmp = tmp->next; tmp->next = category; } } /* enclosure */ else if (!strcmp(cur->value, "cloud") && !data->cloud) { data->cloud = nxmle_get_string(cur, NULL); if (!data->cloud_domain && (attr = nxmle_find_attribute(cur, "domain", NULL))) data->cloud_domain = attr; if (!data->cloud_port && (attr = nxmle_find_attribute(cur, "port", NULL))) { data->cloud_port = atoi(attr); free(attr); } if (!data->cloud_registerProcedure && (attr = nxmle_find_attribute(cur, "registerProcedure", NULL))) data->cloud_registerProcedure = attr; if (!data->cloud_protocol && (attr = nxmle_find_attribute(cur, "protocol", NULL))) data->cloud_protocol = attr; } /* generator */ else if (!strcmp(cur->value, "generator") && !data->generator && (c = nxmle_get_string(cur, NULL))) data->generator = c; /* ttl */ else if (!strcmp(cur->value, "ttl") && !data->ttl && (c = nxmle_get_string(cur, NULL))) { data->ttl = atoi(c); free(c); } /* Other tags: */ else if (data->version != MRSS_VERSION_1_0 || strcmp(cur->value, "items")) { mrss_tag_t *tag; if ((tag = __mrss_parse_tag(doc, cur))) __mrss_parse_tag_insert(&data->other_tags, tag); } } } *ret = data; return MRSS_OK; } static mrss_error_t __mrss_parser(nxml_t *doc, mrss_t **ret) { mrss_error_t r = MRSS_ERR_VERSION; nxml_data_t *cur; char *c; if (!(cur = nxmle_root_element(doc, NULL))) return MRSS_ERR_PARSER; if (!strcmp(cur->value, "rss")) { if ((c = nxmle_find_attribute(cur, "version", NULL))) { /* 0.91 VERSION */ if (!strcmp(c, "0.91")) r = __mrss_parser_rss(MRSS_VERSION_0_91, doc, cur->children, ret); /* 0.92 VERSION */ else if (!strcmp(c, "0.92")) r = __mrss_parser_rss(MRSS_VERSION_0_92, doc, cur->children, ret); /* 2.0 VERSION */ else if (!strcmp(c, "2.0")) r = __mrss_parser_rss(MRSS_VERSION_2_0, doc, cur->children, ret); else r = MRSS_ERR_VERSION; free(c); } else r = MRSS_ERR_VERSION; } else if (!strcmp(cur->value, "RDF")) r = __mrss_parser_rss(MRSS_VERSION_1_0, doc, cur->children, ret); else if (!strcmp(cur->value, "feed")) r = __mrss_parser_atom(doc, cur, ret); else r = MRSS_ERR_PARSER; return r; } /*************************** EXTERNAL FUNCTION ******************************/ mrss_error_t mrss_parse_url(char *url, mrss_t **ret) { return mrss_parse_url_with_options_error_and_transfer_buffer( url, ret, NULL, NULL, NULL, NULL); } mrss_error_t mrss_parse_url_with_options(char *url, mrss_t **ret, mrss_options_t *options) { return mrss_parse_url_with_options_error_and_transfer_buffer( url, ret, options, NULL, NULL, NULL); } mrss_error_t mrss_parse_url_with_options_and_error(char *url, mrss_t **ret, mrss_options_t *options, CURLcode *code) { return mrss_parse_url_with_options_error_and_transfer_buffer( url, ret, options, code, NULL, NULL); } mrss_error_t mrss_parse_url_with_options_error_and_transfer_buffer( char *url, mrss_t **ret, mrss_options_t *options, CURLcode *code, char **feed_content, int *feed_size) { nxml_t *doc; mrss_error_t err; char *buffer; size_t size; if (feed_content) *feed_content = NULL; if (feed_size) *feed_size = 0; if (!url || !ret) return MRSS_ERR_DATA; if (nxml_new(&doc) != NXML_OK) return MRSS_ERR_POSIX; if (options) { if (options->timeout >= 0) nxml_set_timeout(doc, options->timeout); if (options->proxy) nxml_set_proxy(doc, options->proxy, options->proxy_authentication); if (options->authentication) nxml_set_authentication(doc, options->authentication); if (options->user_agent) nxml_set_user_agent(doc, options->user_agent); nxml_set_certificate(doc, options->certfile, options->password, options->cacert, options->verifypeer); } if (!(buffer = __mrss_download_file(doc, url, &size, &err, code))) return err; if (nxml_parse_buffer(doc, buffer, size) != NXML_OK) { free(buffer); nxml_free(doc); return MRSS_ERR_PARSER; } if (!(err = __mrss_parser(doc, ret))) { if (!((*ret)->file = strdup(url))) { mrss_free(*ret); nxml_free(doc); free(buffer); return MRSS_ERR_POSIX; } (*ret)->size = size; } nxml_free(doc); /* transfer ownership: */ if (!feed_content) free(buffer); else *feed_content = buffer; if (feed_size) *feed_size = size; return err; } mrss_error_t mrss_parse_file(char *file, mrss_t **ret) { nxml_t *doc; mrss_error_t err; struct stat st; if (!file || !ret) return MRSS_ERR_DATA; if (lstat(file, &st)) return MRSS_ERR_POSIX; if (nxml_new(&doc) != NXML_OK) return MRSS_ERR_POSIX; if (nxml_parse_file(doc, file) != NXML_OK) { nxml_free(doc); return MRSS_ERR_PARSER; } if (!(err = __mrss_parser(doc, ret))) { if (!((*ret)->file = strdup(file))) { nxml_free(doc); mrss_free(*ret); return MRSS_ERR_POSIX; } (*ret)->size = st.st_size; } nxml_free(doc); return err; } mrss_error_t mrss_parse_buffer(char *buffer, size_t size, mrss_t **ret) { nxml_t *doc; mrss_error_t err; if (!buffer || !size || !ret) return MRSS_ERR_DATA; if (nxml_new(&doc) != NXML_OK) return MRSS_ERR_POSIX; if (nxml_parse_buffer(doc, buffer, size)) { nxml_free(doc); return MRSS_ERR_PARSER; } if (!(err = __mrss_parser(doc, ret))) (*ret)->size = size; nxml_free(doc); return err; } /* EOF */ libmrss-0.19.4/src/mrss_search.c000066400000000000000000000056021456537604200165430ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #else #error Use configure; make; make install #endif #include "mrss.h" #include "mrss_internal.h" static mrss_error_t __mrss_search_tag_real(mrss_tag_t *tag, char *name, char *ns, mrss_tag_t **ret); mrss_error_t mrss_search_tag(mrss_generic_t data, char *name, char *ns, mrss_tag_t **tag) { mrss_t *tmp; mrss_error_t err; if (!data || !name) return MRSS_ERR_DATA; tmp = (mrss_t *)data; switch (tmp->element) { case MRSS_ELEMENT_CHANNEL: err = __mrss_search_tag_real(((mrss_t *)data)->other_tags, name, ns, tag); break; case MRSS_ELEMENT_ITEM: err = __mrss_search_tag_real(((mrss_item_t *)data)->other_tags, name, ns, tag); break; case MRSS_ELEMENT_TAG: err = __mrss_search_tag_real(((mrss_tag_t *)data)->children, name, ns, tag); break; default: err = MRSS_ERR_DATA; break; } return err; } static mrss_error_t __mrss_search_tag_real(mrss_tag_t *tag, char *name, char *ns, mrss_tag_t **ret) { int i; for (*ret = NULL; tag; tag = tag->next) { i = 0; if (tag->ns) i++; if (ns) i++; if ((!i || (i == 2 && !strcmp(tag->ns, ns))) && !strcmp(name, tag->name)) { *ret = tag; return MRSS_OK; } } return MRSS_OK; } mrss_error_t mrss_search_attribute(mrss_generic_t data, char *name, char *ns, mrss_attribute_t **attribute) { mrss_tag_t *tag; mrss_attribute_t *attr; int i; if (!data || !name) return MRSS_ERR_DATA; tag = (mrss_tag_t *)data; if (tag->element != MRSS_ELEMENT_TAG) return MRSS_ERR_DATA; for (*attribute = NULL, attr = tag->attributes; attr; attr = attr->next) { i = 0; if (attr->ns) i++; if (ns) i++; if ((!i || (i == 2 && !strcmp(attr->ns, ns))) && !strcmp(name, attr->name)) { *attribute = attr; return MRSS_OK; } } return MRSS_OK; } /* EOF */ libmrss-0.19.4/src/mrss_write.c000066400000000000000000000665571456537604200164500ustar00rootroot00000000000000/* mRss - Copyright (C) 2005-2007 baku - Andrea Marchesini * * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #else #error Use configure; make; make install #endif #include "mrss.h" #include "mrss_internal.h" static void __mrss_write_string(void (*func)(void *, char *, ...), void *obj, char *str) { int i; int len; char buf[1024]; int j; #define __NXML_CHECK_BUF \ if (j == sizeof(buf) - 1) { \ buf[j] = 0; \ func(obj, "%s", buf); \ j = 0; \ } if (!str) return; len = strlen(str); for (j = i = 0; i < len; i++) { if (str[i] == '\r') continue; else if (str[i] == '<') { buf[j++] = '&'; __NXML_CHECK_BUF; buf[j++] = 'l'; __NXML_CHECK_BUF; buf[j++] = 't'; __NXML_CHECK_BUF; buf[j++] = ';'; __NXML_CHECK_BUF; } else if (str[i] == '>') { buf[j++] = '&'; __NXML_CHECK_BUF; buf[j++] = 'g'; __NXML_CHECK_BUF; buf[j++] = 't'; __NXML_CHECK_BUF; buf[j++] = ';'; __NXML_CHECK_BUF; } else if (str[i] == '&') { buf[j++] = '&'; __NXML_CHECK_BUF; buf[j++] = 'a'; __NXML_CHECK_BUF; buf[j++] = 'm'; __NXML_CHECK_BUF; buf[j++] = 'p'; __NXML_CHECK_BUF; buf[j++] = ';'; __NXML_CHECK_BUF; } else if (str[i] == '\'') { buf[j++] = '&'; __NXML_CHECK_BUF; buf[j++] = 'a'; __NXML_CHECK_BUF; buf[j++] = 'p'; __NXML_CHECK_BUF; buf[j++] = 'o'; __NXML_CHECK_BUF; buf[j++] = 's'; __NXML_CHECK_BUF; buf[j++] = ';'; __NXML_CHECK_BUF; } else if (str[i] == '\"') { buf[j++] = '&'; __NXML_CHECK_BUF; buf[j++] = 'q'; __NXML_CHECK_BUF; buf[j++] = 'u'; __NXML_CHECK_BUF; buf[j++] = 'o'; __NXML_CHECK_BUF; buf[j++] = 't'; __NXML_CHECK_BUF; buf[j++] = ';'; __NXML_CHECK_BUF; } else { buf[j++] = str[i]; __NXML_CHECK_BUF; } } if (j) { buf[j] = 0; func(obj, "%s", buf); j = 0; } } static void __mrss_write_real_image(mrss_t *mrss, void (*func)(void *, char *, ...), void *obj) { if (mrss->image_title || mrss->image_url || mrss->image_link || mrss->image_width || mrss->image_height || mrss->description) { func(obj, " %s\n", mrss->version == MRSS_VERSION_1_0 ? "" : " "); if (mrss->image_title) { func(obj, " %s", mrss->version == MRSS_VERSION_1_0 ? "" : " "); __mrss_write_string(func, obj, mrss->image_title); func(obj, "\n"); } if (mrss->image_url) { func(obj, " %s", mrss->version == MRSS_VERSION_1_0 ? "" : " "); __mrss_write_string(func, obj, mrss->image_url); func(obj, "\n"); } if (mrss->image_link) { func(obj, " %s", mrss->version == MRSS_VERSION_1_0 ? "" : " "); __mrss_write_string(func, obj, mrss->image_link); func(obj, "\n"); } if (mrss->version != MRSS_VERSION_1_0) { if (mrss->image_width) func(obj, " %d\n", mrss->image_width); if (mrss->image_height) func(obj, " %d\n", mrss->image_height); if (mrss->image_description) { func(obj, " "); __mrss_write_string(func, obj, mrss->image_description); func(obj, "\n"); } } func(obj, " %s\n", mrss->version == MRSS_VERSION_1_0 ? "" : " "); } } static void __mrss_write_real_textinput(mrss_t *mrss, void (*func)(void *, char *, ...), void *obj) { if (mrss->textinput_title || mrss->textinput_description || mrss->textinput_name || mrss->textinput_link) { func(obj, " %s\n", mrss->version == MRSS_VERSION_1_0 ? "" : " "); if (mrss->textinput_title) { func(obj, " %s", mrss->version == MRSS_VERSION_1_0 ? "" : " "); __mrss_write_string(func, obj, mrss->textinput_title); func(obj, "\n"); } if (mrss->textinput_description) { func(obj, " %s", mrss->version == MRSS_VERSION_1_0 ? "" : " "); __mrss_write_string(func, obj, mrss->textinput_description); func(obj, "\n"); } if (mrss->textinput_name) { func(obj, " %s", mrss->version == MRSS_VERSION_1_0 ? "" : " "); __mrss_write_string(func, obj, mrss->textinput_name); func(obj, "\n"); } if (mrss->textinput_link) { func(obj, " %s", mrss->version == MRSS_VERSION_1_0 ? "" : " "); __mrss_write_string(func, obj, mrss->textinput_link); func(obj, "\n"); } func(obj, " \n"); } } static void __mrss_write_real_cloud(mrss_t *mrss, void (*func)(void *, char *, ...), void *obj) { if ((mrss->version == MRSS_VERSION_0_92 || mrss->version == MRSS_VERSION_2_0) && (mrss->cloud || mrss->cloud_domain || mrss->cloud_port || mrss->cloud_path || mrss->cloud_registerProcedure || mrss->cloud_protocol)) { func(obj, " cloud_domain) { func(obj, " domain=\""); __mrss_write_string(func, obj, mrss->cloud_domain); func(obj, "\""); } if (mrss->cloud_port) func(obj, " port=\"%d\"", mrss->cloud_port); if (mrss->cloud_path) { func(obj, " path=\""); __mrss_write_string(func, obj, mrss->cloud_path); func(obj, "\""); } if (mrss->cloud_registerProcedure) { func(obj, " registerProcedure=\""); __mrss_write_string(func, obj, mrss->cloud_registerProcedure); func(obj, "\""); } if (mrss->cloud_protocol) { func(obj, " protocol=\""); __mrss_write_string(func, obj, mrss->cloud_protocol); func(obj, "\""); } if (mrss->cloud) func(obj, ">%s\n", mrss->cloud); else func(obj, " />\n", mrss->cloud); } } static void __mrss_write_real_skipHours(mrss_t *mrss, void (*func)(void *, char *, ...), void *obj) { if (mrss->skipHours && mrss->version != MRSS_VERSION_1_0) { mrss_hour_t *hour; func(obj, " \n"); hour = mrss->skipHours; while (hour) { func(obj, " "); __mrss_write_string(func, obj, hour->hour); func(obj, "\n"); hour = hour->next; } func(obj, " \n"); } } static void __mrss_write_real_skipDays(mrss_t *mrss, void (*func)(void *, char *, ...), void *obj) { if (mrss->skipDays && mrss->version != MRSS_VERSION_1_0) { mrss_day_t *day; func(obj, " \n"); day = mrss->skipDays; while (day) { func(obj, " "); __mrss_write_string(func, obj, day->day); func(obj, "\n"); day = day->next; } func(obj, " \n"); } } static void __mrss_write_real_category(mrss_t *mrss, mrss_category_t *category, void (*func)(void *, char *, ...), void *obj) { if ((mrss->version == MRSS_VERSION_0_92 || mrss->version == MRSS_VERSION_2_0) && mrss->category) { while (category) { func(obj, " domain) { func(obj, " domain=\""); __mrss_write_string(func, obj, category->domain); func(obj, "\""); } func(obj, ">"); __mrss_write_string(func, obj, category->category); func(obj, "\n"); category = category->next; } } } static void __mrss_write_real_tag(mrss_tag_t *tag, void (*func)(void *, char *, ...), void *obj, int index) { mrss_attribute_t *attribute; struct mrss_ns_t { char *ns; struct mrss_ns_t *next; } *namespaces = NULL, *nstmp; int i; while (tag) { if (tag->ns) { if (!(namespaces = calloc(1, sizeof(struct mrss_ns_t)))) return; namespaces->ns = tag->ns; } for (attribute = tag->attributes; attribute; attribute = attribute->next) { if (attribute->ns) { for (nstmp = namespaces; nstmp; nstmp = nstmp->next) if (!strcmp(nstmp->ns, attribute->ns)) break; if (nstmp) continue; if (!(nstmp = calloc(1, sizeof(struct mrss_ns_t)))) return; nstmp->ns = attribute->ns; nstmp->next = namespaces->next; namespaces->next = nstmp; } } for (i = 0; i < index; i++) func(obj, " "); if (tag->ns) func(obj, " name); else func(obj, " <%s", tag->name); for (i = 0, nstmp = namespaces; nstmp; nstmp = nstmp->next) func(obj, " xmlns:ns%d=\"%s\"", i++, nstmp->ns); for (attribute = tag->attributes; attribute; attribute = attribute->next) { if (attribute->ns) { for (i = 0, nstmp = namespaces; nstmp; i++, nstmp = nstmp->next) { if (!strcmp(nstmp->ns, attribute->ns)) { func(obj, " ns%d:%s=\"%s\"", i, attribute->name, attribute->value); break; } } } else func(obj, " %s=\"%s\"", attribute->name, attribute->value); } if (tag->value) { func(obj, ">"); __mrss_write_string(func, obj, tag->value); } if (tag->children) { if (!tag->value) func(obj, ">\n"); func(obj, "\n"); __mrss_write_real_tag(tag->children, func, obj, index + 1); } if (tag->children || tag->value) { if (tag->children) for (i = 0; i < index; i++) func(obj, " "); if (tag->ns) func(obj, "\n", tag->name); else func(obj, "\n", tag->name); } else func(obj, "/>\n"); while (namespaces) { nstmp = namespaces; namespaces = namespaces->next; free(nstmp); } tag = tag->next; } } static void __mrss_write_real_item(mrss_t *mrss, void (*func)(void *, char *, ...), void *obj) { mrss_item_t *item = mrss->item; while (item) { func(obj, " %s\n", mrss->version == MRSS_VERSION_1_0 ? "" : " "); if (item->title) { func(obj, " %s", mrss->version == MRSS_VERSION_1_0 ? "" : " "); __mrss_write_string(func, obj, item->title); func(obj, "\n"); } if (item->link) { func(obj, " %s", mrss->version == MRSS_VERSION_1_0 ? "" : " "); __mrss_write_string(func, obj, item->link); func(obj, "\n"); } if (item->description) { func(obj, " %s", mrss->version == MRSS_VERSION_1_0 ? "" : " "); __mrss_write_string(func, obj, item->description); func(obj, "\n"); } if (mrss->version == MRSS_VERSION_2_0) { if (item->author) { func(obj, " "); __mrss_write_string(func, obj, item->author); func(obj, "\n"); } if (item->comments) { func(obj, " "); __mrss_write_string(func, obj, item->comments); func(obj, "\n"); } if (item->pubDate) { func(obj, " "); __mrss_write_string(func, obj, item->pubDate); func(obj, "\n"); } if (item->guid) { func(obj, " ", item->guid_isPermaLink ? "true" : "false"); __mrss_write_string(func, obj, item->guid); func(obj, "\n"); } } if (mrss->version == MRSS_VERSION_2_0 || mrss->version == MRSS_VERSION_0_92) { if (item->source || item->source_url) { func(obj, " source_url) { func(obj, " url=\""); __mrss_write_string(func, obj, item->source_url); func(obj, "\""); } if (item->source) { func(obj, ">"); __mrss_write_string(func, obj, item->source); func(obj, "\n"); } else func(obj, " />\n"); } } if (item->enclosure || item->enclosure_length || item->enclosure_type) { func(obj, " enclosure_url) { func(obj, " url=\""); __mrss_write_string(func, obj, item->enclosure_url); func(obj, "\""); } if (item->enclosure_length) func(obj, " length=\"%d\"", item->enclosure_length); if (item->enclosure_type) { func(obj, " type=\""); __mrss_write_string(func, obj, item->enclosure_type); func(obj, "\""); } if (item->enclosure) { func(obj, ">"); __mrss_write_string(func, obj, item->enclosure); func(obj, "\n"); } else func(obj, " />\n"); } __mrss_write_real_category(mrss, item->category, func, obj); if (item->other_tags) __mrss_write_real_tag(item->other_tags, func, obj, 1); func(obj, " %s\n", mrss->version == MRSS_VERSION_1_0 ? "" : " "); item = item->next; } } static void __mrss_write_real_atom_category(mrss_category_t *category, void (*func)(void *, char *, ...), void *obj) { while (category) { func(obj, " domain) { func(obj, " scheme=\""); __mrss_write_string(func, obj, category->domain); func(obj, "\""); } if (category->category) { func(obj, " term=\""); __mrss_write_string(func, obj, category->category); func(obj, "\""); } if (category->label) { func(obj, " label=\""); __mrss_write_string(func, obj, category->label); func(obj, "\""); } func(obj, "/>\n"); category = category->next; } } static void __mrss_write_real_atom_entry(mrss_t *mrss, void (*func)(void *, char *, ...), void *obj) { mrss_item_t *item = mrss->item; while (item) { func(obj, " \n"); if (item->title) { func(obj, " title_type) { func(obj, " type=\""); __mrss_write_string(func, obj, item->title_type); func(obj, "\""); } func(obj, ">"); __mrss_write_string(func, obj, item->title); func(obj, "\n"); } if (item->link) { func(obj, " "); __mrss_write_string(func, obj, item->link); func(obj, "\n"); } if (item->description) { func(obj, " description_type) { func(obj, " type=\""); __mrss_write_string(func, obj, item->description_type); func(obj, "\""); } func(obj, ">"); __mrss_write_string(func, obj, item->description); func(obj, "\n"); } if (item->copyright) { func(obj, " "); __mrss_write_string(func, obj, item->copyright); func(obj, "\n"); } if (item->author) { func(obj, " \n"); func(obj, " "); __mrss_write_string(func, obj, item->author); func(obj, "\n"); if (item->author_email) { func(obj, " "); __mrss_write_string(func, obj, item->author_email); func(obj, "\n"); } if (item->author_uri) { func(obj, " "); __mrss_write_string(func, obj, item->author_uri); func(obj, "\n"); } func(obj, " \n"); } if (item->contributor) { func(obj, " \n"); func(obj, " "); __mrss_write_string(func, obj, item->contributor); func(obj, "\n"); if (item->contributor_email) { func(obj, " "); __mrss_write_string(func, obj, item->contributor_email); func(obj, "\n"); } if (item->contributor_uri) { func(obj, " "); __mrss_write_string(func, obj, item->contributor_uri); func(obj, "\n"); } func(obj, " \n"); } /* TODO */ if (mrss->pubDate) { if (mrss->version == MRSS_VERSION_ATOM_1_0) { func(obj, " "); __mrss_write_string(func, obj, item->pubDate); func(obj, "\n"); } else { func(obj, " "); __mrss_write_string(func, obj, item->pubDate); func(obj, "\n"); } } if (item->guid) { func(obj, " "); __mrss_write_string(func, obj, item->guid); func(obj, "\n"); } __mrss_write_real_atom_category(item->category, func, obj); if (item->other_tags) __mrss_write_real_tag(item->other_tags, func, obj, 1); func(obj, " \n"); item = item->next; } } static mrss_error_t __mrss_write_atom(mrss_t *mrss, void (*func)(void *, char *, ...), void *obj) { func(obj, "language) func(obj, " xml:lang=\"%s\"", mrss->language); if (mrss->version == MRSS_VERSION_ATOM_0_3) func(obj, " version=\"0.3\""); func(obj, ">\n"); func(obj, " title_type) { func(obj, " type=\""); __mrss_write_string(func, obj, mrss->title_type); func(obj, "\""); } func(obj, ">"); __mrss_write_string(func, obj, mrss->title); func(obj, "\n"); if (mrss->description) { if (mrss->version == MRSS_VERSION_ATOM_1_0) { func(obj, " description_type) { func(obj, " type=\""); __mrss_write_string(func, obj, mrss->description_type); func(obj, "\""); } func(obj, ">"); __mrss_write_string(func, obj, mrss->description); func(obj, "\n"); } else { func(obj, " description_type) { func(obj, " type=\""); __mrss_write_string(func, obj, mrss->description_type); func(obj, "\""); } func(obj, ">"); __mrss_write_string(func, obj, mrss->description); func(obj, "\n"); } } if (mrss->link) { func(obj, " link); func(obj, "\"/>\n"); } if (mrss->id) { func(obj, " "); __mrss_write_string(func, obj, mrss->id); func(obj, "\n"); } if (mrss->copyright) { func(obj, " copyright_type) { func(obj, " type=\""); __mrss_write_string(func, obj, mrss->copyright_type); func(obj, "\""); } func(obj, ">"); __mrss_write_string(func, obj, mrss->copyright); func(obj, "\n"); } /* TODO */ if (mrss->lastBuildDate) { func(obj, " "); __mrss_write_string(func, obj, mrss->lastBuildDate); func(obj, "\n"); } if (mrss->managingeditor) { func(obj, " \n"); func(obj, " "); __mrss_write_string(func, obj, mrss->managingeditor); func(obj, "\n"); if (mrss->managingeditor_email) { func(obj, " "); __mrss_write_string(func, obj, mrss->managingeditor_email); func(obj, "\n"); } if (mrss->managingeditor_uri) { func(obj, " "); __mrss_write_string(func, obj, mrss->managingeditor_uri); func(obj, "\n"); } func(obj, " \n"); } if (mrss->generator) { func(obj, " generator_uri) { func(obj, " uri=\""); __mrss_write_string(func, obj, mrss->generator_uri); func(obj, "\""); } if (mrss->generator_version) { func(obj, " version=\""); __mrss_write_string(func, obj, mrss->generator_version); func(obj, "\""); } func(obj, ">"); __mrss_write_string(func, obj, mrss->generator); func(obj, "\n"); } if (mrss->image_url) { func(obj, " "); __mrss_write_string(func, obj, mrss->image_url); func(obj, "\n"); } if (mrss->image_logo) { func(obj, " "); __mrss_write_string(func, obj, mrss->image_logo); func(obj, "\n"); } __mrss_write_real_atom_category(mrss->category, func, obj); __mrss_write_real_atom_entry(mrss, func, obj); if (mrss->other_tags) __mrss_write_real_tag(mrss->other_tags, func, obj, 0); func(obj, "\n"); return MRSS_OK; } static mrss_error_t __mrss_write_real(mrss_t *mrss, void (*func)(void *, char *, ...), void *obj) { func(obj, "\n"); if (mrss->version == MRSS_VERSION_1_0) func(obj, "\n"); else if (mrss->version == MRSS_VERSION_ATOM_1_0 || mrss->version == MRSS_VERSION_ATOM_0_3) return __mrss_write_atom(mrss, func, obj); else { func(obj, "version) { case MRSS_VERSION_0_91: func(obj, "0.91"); break; case MRSS_VERSION_0_92: func(obj, "0.92"); break; case MRSS_VERSION_2_0: func(obj, "2.0"); break; default: break; } func(obj, "\">\n"); } if (mrss->version == MRSS_VERSION_1_0 && mrss->about) { func(obj, " about); func(obj, "\">\n"); } else func(obj, " \n"); if (mrss->title) { func(obj, " "); __mrss_write_string(func, obj, mrss->title); func(obj, "\n"); } if (mrss->description) { func(obj, " "); __mrss_write_string(func, obj, mrss->description); func(obj, "\n"); } if (mrss->link) { func(obj, " "); __mrss_write_string(func, obj, mrss->link); func(obj, "\n"); } if (mrss->language && mrss->version != MRSS_VERSION_1_0) { func(obj, " "); __mrss_write_string(func, obj, mrss->language); func(obj, "\n"); } if (mrss->rating && mrss->version != MRSS_VERSION_1_0) { func(obj, " "); __mrss_write_string(func, obj, mrss->rating); func(obj, "\n"); } if (mrss->copyright && mrss->version != MRSS_VERSION_1_0) { func(obj, " "); __mrss_write_string(func, obj, mrss->copyright); func(obj, "\n"); } if (mrss->pubDate && mrss->version != MRSS_VERSION_1_0) { func(obj, " "); __mrss_write_string(func, obj, mrss->pubDate); func(obj, "\n"); } if (mrss->lastBuildDate && mrss->version != MRSS_VERSION_1_0) { func(obj, " "); __mrss_write_string(func, obj, mrss->lastBuildDate); func(obj, "\n"); } if (mrss->docs && mrss->version != MRSS_VERSION_1_0) { func(obj, " "); __mrss_write_string(func, obj, mrss->docs); func(obj, "\n"); } if (mrss->managingeditor && mrss->version != MRSS_VERSION_1_0) { func(obj, " "); __mrss_write_string(func, obj, mrss->managingeditor); func(obj, "\n"); } if (mrss->webMaster && mrss->version != MRSS_VERSION_1_0) { func(obj, " "); __mrss_write_string(func, obj, mrss->webMaster); func(obj, "\n"); } if (mrss->version == MRSS_VERSION_2_0) { if (mrss->generator) { func(obj, " "); __mrss_write_string(func, obj, mrss->generator); func(obj, "\n"); } if (mrss->ttl) func(obj, " %d\n", mrss->ttl); } if (mrss->version == MRSS_VERSION_1_0) { if (mrss->image_url) { func(obj, " image_url); func(obj, "\" />\n"); } if (mrss->textinput_link) { func(obj, " textinput_link); func(obj, "\" />\n"); } if (mrss->item) { mrss_item_t *item = mrss->item; func(obj, " \n" " \n"); while (item) { func(obj, " link); func(obj, "\" />\n"); item = item->next; } func(obj, " \n" " \n"); } func(obj, " \n"); } __mrss_write_real_image(mrss, func, obj); __mrss_write_real_textinput(mrss, func, obj); __mrss_write_real_cloud(mrss, func, obj); __mrss_write_real_skipHours(mrss, func, obj); __mrss_write_real_skipDays(mrss, func, obj); __mrss_write_real_category(mrss, mrss->category, func, obj); if (mrss->other_tags) __mrss_write_real_tag(mrss->other_tags, func, obj, 1); __mrss_write_real_item(mrss, func, obj); if (mrss->version != MRSS_VERSION_1_0) func(obj, " \n" "\n"); else func(obj, "\n"); return MRSS_OK; } static void __mrss_file_write(void *obj, char *str, ...) { va_list va; va_start(va, str); vfprintf((FILE *)obj, str, va); va_end(va); } static void __mrss_buffer_write(void *obj, char *str, ...) { va_list va; char s[4096]; int len; char **buffer = (char **)obj; va_start(va, str); len = vsnprintf(s, sizeof(s), str, va); va_end(va); if (!*buffer) { if (!(*buffer = (char *)malloc(sizeof(char) * (len + 1)))) return; strncpy(*buffer, s, len + 1); } else { if (!(*buffer = (char *)realloc(*buffer, sizeof(char) * (strlen(*buffer) + len + 1)))) return; strncat(*buffer, s, len + 1); } } /*************************** EXTERNAL FUNCTION ******************************/ mrss_error_t mrss_write_file(mrss_t *mrss, char *file) { FILE *fl; mrss_error_t ret; if (!mrss || !file) return MRSS_ERR_DATA; if (!(fl = fopen(file, "wb"))) return MRSS_ERR_POSIX; ret = __mrss_write_real(mrss, __mrss_file_write, fl); fclose(fl); return ret; } mrss_error_t mrss_write_buffer(mrss_t *mrss, char **buffer) { if (!mrss || !buffer) return MRSS_ERR_DATA; return __mrss_write_real(mrss, __mrss_buffer_write, buffer); } /* EOF */ libmrss-0.19.4/test/000077500000000000000000000000001456537604200142535ustar00rootroot00000000000000libmrss-0.19.4/test/.gitignore000066400000000000000000000000511456537604200162370ustar00rootroot00000000000000new parser search time write *.trs *.log libmrss-0.19.4/test/Makefile.am000066400000000000000000000006261456537604200163130ustar00rootroot00000000000000noinst_PROGRAMS = parser time write search check_PROGRAMS = new TESTS = $(check_PROGRAMS) parser_SOURCES = parser.c parser_LDADD = ../src/libmrss.la write_SOURCES = write.c write_LDADD = ../src/libmrss.la new_SOURCES = new.c new_LDADD = ../src/libmrss.la time_SOURCES = time.c time_LDADD = ../src/libmrss.la search_SOURCES = search.c search_LDADD = ../src/libmrss.la AM_CPPFLAGS = -I$(srcdir)/../src libmrss-0.19.4/test/new.c000066400000000000000000000151331456537604200152130ustar00rootroot00000000000000#include #include #include "mrss.h" void check (mrss_error_t ret) { puts (mrss_strerror (ret)); if (ret != MRSS_OK) exit (1); } int main (int argc, char **argv) { mrss_t *data; mrss_error_t ret; char *buffer; int i; data = NULL; fprintf (stdout, "New data... "); ret = mrss_new (&data); check (ret); fprintf (stdout, "Set some values... "); ret = mrss_set (data, MRSS_FLAG_VERSION, MRSS_VERSION_2_0, MRSS_FLAG_TITLE, "a title", MRSS_FLAG_DESCRIPTION, "a description", MRSS_FLAG_LINK, "a link", MRSS_FLAG_LANGUAGE, "it_IT", MRSS_FLAG_RATING, "rating", MRSS_FLAG_COPYRIGHT, "the copyright", MRSS_FLAG_PUBDATE, "today", MRSS_FLAG_LASTBUILDDATE, "yesterday", MRSS_FLAG_DOCS, "http://github.com/bakulf", MRSS_FLAG_MANAGINGEDITOR, "vim", MRSS_FLAG_WEBMASTER, "b", MRSS_FLAG_GENERATOR, "none!", MRSS_FLAG_TTL, 255, MRSS_FLAG_IMAGE_TITLE, "title of the image", MRSS_FLAG_IMAGE_URL, "http://github.com/bakulf/img.png", MRSS_FLAG_IMAGE_LINK, "http://github.com/bakulf/", MRSS_FLAG_IMAGE_WIDTH, 1000, MRSS_FLAG_IMAGE_HEIGHT, 2000, MRSS_FLAG_IMAGE_DESCRIPTION, "no image description", MRSS_FLAG_TEXTINPUT_TITLE, "textinput title", MRSS_FLAG_TEXTINPUT_DESCRIPTION, "textinput description", MRSS_FLAG_TEXTINPUT_NAME, "textinput name", MRSS_FLAG_TEXTINPUT_LINK, "http://github.com/bakulf", MRSS_FLAG_CLOUD, "Cloud!", MRSS_FLAG_CLOUD_DOMAIN, "github.com", MRSS_FLAG_CLOUD_PORT, 8080, MRSS_FLAG_CLOUD_PATH, "/bakulf/libmrss", MRSS_FLAG_CLOUD_REGISTERPROCEDURE, "none", MRSS_FLAG_CLOUD_PROTOCOL, "gopher", MRSS_FLAG_END); check (ret); for (i = 0; i < 10; i++) { mrss_hour_t *hour = NULL; char s[1024]; fprintf (stdout, "New skipHours element... "); ret = mrss_new_subdata (data, MRSS_ELEMENT_SKIPHOURS, &hour); check (ret); snprintf (s, sizeof (s), "Element %d", i); fprintf (stdout, "Set skipHours value... "); ret = mrss_set (hour, MRSS_FLAG_HOUR, s, MRSS_FLAG_END); check (ret); } for (i = 0; i < 10; i++) { mrss_day_t *day = NULL; char s[1024]; fprintf (stdout, "New skipDays element... "); ret = mrss_new_subdata (data, MRSS_ELEMENT_SKIPDAYS, &day); check (ret); snprintf (s, sizeof (s), "Element %d", i); fprintf (stdout, "Set skipDays value... "); ret = mrss_set (day, MRSS_FLAG_DAY, s, MRSS_FLAG_END); check (ret); } for (i = 0; i < 10; i++) { mrss_category_t *category = NULL; char s1[1024]; char s2[1024]; fprintf (stdout, "New category element... "); ret = mrss_new_subdata (data, MRSS_ELEMENT_CATEGORY, &category); check (ret); snprintf (s1, sizeof (s1), "Element %d", i); snprintf (s2, sizeof (s2), "Domain %d", i); fprintf (stdout, "Set category values... "); ret = mrss_set (category, MRSS_FLAG_CATEGORY, s1, MRSS_FLAG_CATEGORY_DOMAIN, s2, MRSS_FLAG_END); check (ret); } for (i = 0; i < 10; i++) { mrss_tag_t *tag = NULL; char s1[1024]; char s2[1024]; char s3[1024]; fprintf (stdout, "New tag element... "); ret = mrss_new_subdata (data, MRSS_ELEMENT_TAG, &tag); check (ret); snprintf (s1, sizeof (s1), "Element %d", i); snprintf (s2, sizeof (s2), "element_%d", i); snprintf (s3, sizeof (s3), "http://www.something.net/"); fprintf (stdout, "Set tag value... "); ret = mrss_set (tag, MRSS_FLAG_TAG_NAME, s2, MRSS_FLAG_TAG_VALUE, s1, MRSS_FLAG_TAG_NS, s3, MRSS_FLAG_END); check (ret); } for (i = 0; i < 10; i++) { mrss_item_t *item = NULL; int j; fprintf (stdout, "New item element... "); ret = mrss_new_subdata (data, MRSS_ELEMENT_ITEM, &item); check (ret); fprintf (stdout, "Set item values... "); ret = mrss_set (item, MRSS_FLAG_ITEM_TITLE, "item title", MRSS_FLAG_ITEM_LINK, "item link", MRSS_FLAG_ITEM_DESCRIPTION, "item description", MRSS_FLAG_ITEM_AUTHOR, "item author", MRSS_FLAG_ITEM_COMMENTS, "item comments", MRSS_FLAG_ITEM_PUBDATE, "item pubdate", MRSS_FLAG_ITEM_GUID, "item guid", MRSS_FLAG_ITEM_GUID_ISPERMALINK, 1 /* 0 is false */ , MRSS_FLAG_ITEM_SOURCE, "item source", MRSS_FLAG_ITEM_SOURCE_URL, "item source url", MRSS_FLAG_ITEM_ENCLOSURE, "item enclosure", MRSS_FLAG_ITEM_ENCLOSURE_URL, "item enclosure url", MRSS_FLAG_ITEM_ENCLOSURE_LENGTH, 1234, MRSS_FLAG_ITEM_ENCLOSURE_TYPE, "item enclosure type", MRSS_FLAG_END); for (j = 0; j < 10; j++) { mrss_category_t *category = NULL; char s1[1024]; char s2[1024]; fprintf (stdout, "New category element... "); ret = mrss_new_subdata (item, MRSS_ELEMENT_CATEGORY, &category); check (ret); snprintf (s1, sizeof (s1), "Element %d", j); snprintf (s2, sizeof (s2), "Domain %d", j); fprintf (stdout, "Set category values... "); ret = mrss_set (category, MRSS_FLAG_CATEGORY, s1, MRSS_FLAG_CATEGORY_DOMAIN, s2, MRSS_FLAG_END); check (ret); } for (i = 0; i < 10; i++) { mrss_tag_t *tag = NULL; char s1[1024]; char s2[1024]; char s3[1024]; int j; fprintf (stdout, "New tag element... "); ret = mrss_new_subdata (item, MRSS_ELEMENT_TAG, &tag); check (ret); snprintf (s1, sizeof (s1), "Element %d", i); snprintf (s2, sizeof (s2), "element_%d", i); snprintf (s3, sizeof (s3), "http://www.something%d.net/", i); fprintf (stdout, "Set tag value... "); ret = mrss_set (tag, MRSS_FLAG_TAG_NAME, s2, MRSS_FLAG_TAG_VALUE, s1, MRSS_FLAG_TAG_NS, s3, MRSS_FLAG_END); check (ret); for (j = 0; j < 10; j++) { mrss_attribute_t *attribute = NULL; char s1[1024]; char s2[1024]; char s3[1024]; fprintf (stdout, "New attribute element... "); ret = mrss_new_subdata (tag, MRSS_ELEMENT_ATTRIBUTE, &attribute); check (ret); snprintf (s1, sizeof (s1), "Element %d", j); snprintf (s2, sizeof (s2), "element_%d", j); snprintf (s3, sizeof (s3), "http://www.something%d.net/", j); fprintf (stdout, "Set attribute value... "); ret = mrss_set (attribute, MRSS_FLAG_ATTRIBUTE_NAME, s2, MRSS_FLAG_ATTRIBUTE_VALUE, s1, MRSS_FLAG_ATTRIBUTE_NS, s3, MRSS_FLAG_END); check (ret); } } check (ret); } buffer = NULL; fprintf (stdout, "Create the RSS in memory... "); ret = mrss_write_buffer (data, &buffer); check (ret); puts (buffer); free (buffer); mrss_free (data); return 0; } libmrss-0.19.4/test/parser.c000066400000000000000000000150321456537604200157140ustar00rootroot00000000000000#include #include #include "mrss.h" static void print_tags (mrss_tag_t * tag, int index); int main (int argc, char **argv) { mrss_t *data; mrss_error_t ret; mrss_hour_t *hour; mrss_day_t *day; mrss_category_t *category; mrss_item_t *item; CURLcode code; if (argc != 2) { fprintf (stderr, "Usage:\n\t%s url_rss\n\nExample:\n\t%s http://ngvision.org/rss|file.rss\n\n", argv[0], argv[0]); return 1; } if (!strncmp (argv[1], "http://", 7) || !strncmp (argv[1], "https://", 8)) ret = mrss_parse_url_with_options_and_error (argv[1], &data, NULL, &code); else ret = mrss_parse_file (argv[1], &data); if (ret) { fprintf (stderr, "MRSS return error: %s\n", ret == MRSS_ERR_DOWNLOAD ? mrss_curl_strerror (code) : mrss_strerror (ret)); return 1; } fprintf (stdout, "\nGeneric:\n"); fprintf (stdout, "\tfile: %s\n", data->file); fprintf (stdout, "\tencoding: %s\n", data->encoding); fprintf (stdout, "\tsize: %d\n", (int) data->size); fprintf (stdout, "\tversion:"); switch (data->version) { case MRSS_VERSION_0_91: fprintf (stdout, " 0.91\n"); break; case MRSS_VERSION_0_92: fprintf (stdout, " 0.92\n"); break; case MRSS_VERSION_1_0: fprintf (stdout, " 1.0\n"); break; case MRSS_VERSION_2_0: fprintf (stdout, " 2.0\n"); break; case MRSS_VERSION_ATOM_1_0: fprintf (stdout, " Atom 1.0\n"); break; case MRSS_VERSION_ATOM_0_3: fprintf (stdout, " Atom 0.3\n"); break; } fprintf (stdout, "\nChannel:\n"); fprintf (stdout, "\ttitle: %s\n", data->title); fprintf (stdout, "\tdescription: %s\n", data->description); fprintf (stdout, "\tlink: %s\n", data->link); fprintf (stdout, "\tlanguage: %s\n", data->language); fprintf (stdout, "\trating: %s\n", data->rating); fprintf (stdout, "\tcopyright: %s\n", data->copyright); fprintf (stdout, "\tpubDate: %s\n", data->pubDate); fprintf (stdout, "\tlastBuildDate: %s\n", data->lastBuildDate); fprintf (stdout, "\tdocs: %s\n", data->docs); fprintf (stdout, "\tmanagingeditor: %s\n", data->managingeditor); fprintf (stdout, "\twebMaster: %s\n", data->webMaster); fprintf (stdout, "\tgenerator: %s\n", data->generator); fprintf (stdout, "\tttl: %d\n", data->ttl); fprintf (stdout, "\tabout: %s\n", data->about); fprintf (stdout, "\nImage:\n"); fprintf (stdout, "\timage_title: %s\n", data->image_title); fprintf (stdout, "\timage_url: %s\n", data->image_url); fprintf (stdout, "\timage_link: %s\n", data->image_link); fprintf (stdout, "\timage_width: %d\n", data->image_width); fprintf (stdout, "\timage_height: %d\n", data->image_height); fprintf (stdout, "\timage_description: %s\n", data->image_description); fprintf (stdout, "\nTextInput:\n"); fprintf (stdout, "\ttextinput_title: %s\n", data->textinput_title); fprintf (stdout, "\ttextinput_description: %s\n", data->textinput_description); fprintf (stdout, "\ttextinput_name: %s\n", data->textinput_name); fprintf (stdout, "\ttextinput_link: %s\n", data->textinput_link); fprintf (stdout, "\nCloud:\n"); fprintf (stdout, "\tcloud: %s\n", data->cloud); fprintf (stdout, "\tcloud_domain: %s\n", data->cloud_domain); fprintf (stdout, "\tcloud_port: %d\n", data->cloud_port); fprintf (stdout, "\tcloud_registerProcedure: %s\n", data->cloud_registerProcedure); fprintf (stdout, "\tcloud_protocol: %s\n", data->cloud_protocol); fprintf (stdout, "\nSkipHours:\n"); hour = data->skipHours; while (hour) { fprintf (stdout, "\t%s\n", hour->hour); hour = hour->next; } fprintf (stdout, "\nSkipDays:\n"); day = data->skipDays; while (day) { fprintf (stdout, "\t%s\n", day->day); day = day->next; } fprintf (stdout, "\nCategory:\n"); category = data->category; while (category) { fprintf (stdout, "\tcategory: %s\n", category->category); fprintf (stdout, "\tcategory_domain: %s\n", category->domain); category = category->next; } if (data->other_tags) print_tags (data->other_tags, 0); fprintf (stdout, "\nItems:\n"); item = data->item; while (item) { fprintf (stdout, "\ttitle: %s\n", item->title); fprintf (stdout, "\tlink: %s\n", item->link); fprintf (stdout, "\tdescription: %s\n", item->description); fprintf (stdout, "\tauthor: %s\n", item->author); fprintf (stdout, "\tcomments: %s\n", item->comments); fprintf (stdout, "\tpubDate: %s\n", item->pubDate); fprintf (stdout, "\tguid: %s\n", item->guid); fprintf (stdout, "\tguid_isPermaLink: %d\n", item->guid_isPermaLink); fprintf (stdout, "\tsource: %s\n", item->source); fprintf (stdout, "\tsource_url: %s\n", item->source_url); fprintf (stdout, "\tenclosure: %s\n", item->enclosure); fprintf (stdout, "\tenclosure_url: %s\n", item->enclosure_url); fprintf (stdout, "\tenclosure_length: %d\n", item->enclosure_length); fprintf (stdout, "\tenclosure_type: %s\n", item->enclosure_type); fprintf (stdout, "\tCategory:\n"); category = item->category; while (category) { fprintf (stdout, "\t\tcategory: %s\n", category->category); fprintf (stdout, "\t\tcategory_domain: %s\n", category->domain); category = category->next; } if (item->other_tags) print_tags (item->other_tags, 1); fprintf (stdout, "\n"); item = item->next; } mrss_free (data); return 0; } static void print_tags (mrss_tag_t * tag, int index) { mrss_attribute_t *attribute; int i; for (i = 0; i < index; i++) fprintf (stdout, "\t"); fprintf (stdout, "Other Tags:\n"); while (tag) { for (i = 0; i < index; i++) fprintf (stdout, "\t"); fprintf (stdout, "\ttag name: %s\n", tag->name); for (i = 0; i < index; i++) fprintf (stdout, "\t"); fprintf (stdout, "\ttag value: %s\n", tag->value); for (i = 0; i < index; i++) fprintf (stdout, "\t"); fprintf (stdout, "\ttag ns: %s\n", tag->ns); if (tag->children) print_tags (tag->children, index + 1); for (attribute = tag->attributes; attribute; attribute = attribute->next) { for (i = 0; i < index; i++) fprintf (stdout, "\t"); fprintf (stdout, "\tattribute name: %s\n", attribute->name); for (i = 0; i < index; i++) fprintf (stdout, "\t"); fprintf (stdout, "\tattribute value: %s\n", attribute->value); for (i = 0; i < index; i++) fprintf (stdout, "\t"); fprintf (stdout, "\tattribute ns: %s\n", attribute->ns); } tag = tag->next; } } libmrss-0.19.4/test/search.c000066400000000000000000000021731456537604200156670ustar00rootroot00000000000000#include #include #include "mrss.h" int main (int argc, char **argv) { mrss_t *data; mrss_error_t ret; mrss_item_t *item; mrss_tag_t *tag; CURLcode code; if (argc != 2) { fprintf (stderr, "Usage:\n\t%s url_rss\n\nExample:\n\t%s http://ngvision.org/rss|file.rss\n\n", argv[0], argv[0]); return 1; } if (!strncmp (argv[1], "http://", 7) || !strncmp (argv[1], "https://", 8)) ret = mrss_parse_url_with_options_and_error (argv[1], &data, NULL, &code); else ret = mrss_parse_file (argv[1], &data); if (ret) { fprintf (stderr, "MRSS return error: %s\n", ret == MRSS_ERR_DOWNLOAD ? mrss_curl_strerror (code) : mrss_strerror (ret)); return 1; } for (item = data->item; item; item = item->next) { fprintf (stdout, "Item -%s-: ", item->link); if (mrss_search_tag (item, "encoded", "http://purl.org/rss/1.0/modules/content/", &tag) != MRSS_OK || !tag) { fprintf (stdout, " no Encoded tag\n"); } else fprintf (stdout, " encoded %s\n", tag->value); } mrss_free (data); return 0; } libmrss-0.19.4/test/time.c000066400000000000000000000013631456537604200153600ustar00rootroot00000000000000#include #include #include #include #include #include "mrss.h" int main (int argc, char **argv) { time_t t; mrss_error_t err; char *buf; struct tm *k; if (argc != 2) { fprintf (stderr, "Usage: %s url\n\n", argv[0]); return 1; } if ((err = mrss_get_last_modified (argv[1], &t)) != MRSS_OK) { fprintf (stderr, "ERROR: %s\n", mrss_strerror (err)); return 1; } if (!(k = localtime (&t))) { fprintf (stderr, "ERROR: %s\n", strerror (errno)); return 1; } if (!(buf = asctime (k))) { fprintf (stderr, "ERROR: %s\n", strerror (errno)); return 1; } fprintf (stdout, "Last Modified: %s\n", buf); return 0; } libmrss-0.19.4/test/write.c000066400000000000000000000014361456537604200155550ustar00rootroot00000000000000#include #include #include "mrss.h" int main (int argc, char **argv) { mrss_t *data; mrss_error_t ret; if (argc != 3) { fprintf (stderr, "Usage:\n\t%s url_rss output\n\nExample:\n\t%s http://ngvision.org/rss file.rss\n\n", argv[0], argv[0]); return 1; } if (!strncmp (argv[1], "http://", 7)) ret = mrss_parse_url (argv[1], &data); else ret = mrss_parse_file (argv[1], &data); if (ret) { fprintf (stderr, "MRSS return error: %s\n", mrss_strerror (ret)); return 1; } data->version = MRSS_VERSION_ATOM_1_0; ret = mrss_write_file (data, argv[2]); if (ret) { fprintf (stderr, "MRSS return error: %s\n", mrss_strerror (ret)); return 1; } mrss_free (data); return 0; }