Move csync to src/csync
authorJocelyn Turcotte <jturcotte@woboq.com>
Mon, 14 Aug 2017 17:19:52 +0000 (19:19 +0200)
committerRoeland Jago Douma <roeland@famdouma.nl>
Thu, 5 Oct 2017 20:01:03 +0000 (22:01 +0200)
124 files changed:
CMakeLists.txt
csync/AUTHORS [deleted file]
csync/CMakeLists.txt [deleted file]
csync/COPYING [deleted file]
csync/ChangeLog [deleted file]
csync/ConfigureChecks.cmake [deleted file]
csync/DefineOptions.cmake [deleted file]
csync/INSTALL [deleted file]
csync/README [deleted file]
csync/config_csync.h.cmake [deleted file]
csync/src/CMakeLists.txt [deleted file]
csync/src/csync.c [deleted file]
csync/src/csync.h [deleted file]
csync/src/csync_exclude.c [deleted file]
csync/src/csync_exclude.h [deleted file]
csync/src/csync_log.c [deleted file]
csync/src/csync_log.h [deleted file]
csync/src/csync_macros.h [deleted file]
csync/src/csync_misc.c [deleted file]
csync/src/csync_misc.h [deleted file]
csync/src/csync_private.h [deleted file]
csync/src/csync_reconcile.c [deleted file]
csync/src/csync_reconcile.h [deleted file]
csync/src/csync_rename.cc [deleted file]
csync/src/csync_rename.h [deleted file]
csync/src/csync_statedb.c [deleted file]
csync/src/csync_statedb.h [deleted file]
csync/src/csync_time.c [deleted file]
csync/src/csync_time.h [deleted file]
csync/src/csync_update.c [deleted file]
csync/src/csync_update.h [deleted file]
csync/src/csync_util.c [deleted file]
csync/src/csync_util.h [deleted file]
csync/src/csync_version.h.in [deleted file]
csync/src/std/CMakeLists.txt [deleted file]
csync/src/std/asprintf.c [deleted file]
csync/src/std/asprintf.h [deleted file]
csync/src/std/c_alloc.c [deleted file]
csync/src/std/c_alloc.h [deleted file]
csync/src/std/c_jhash.h [deleted file]
csync/src/std/c_lib.h [deleted file]
csync/src/std/c_macro.h [deleted file]
csync/src/std/c_path.c [deleted file]
csync/src/std/c_path.h [deleted file]
csync/src/std/c_private.h [deleted file]
csync/src/std/c_rbtree.c [deleted file]
csync/src/std/c_rbtree.h [deleted file]
csync/src/std/c_string.c [deleted file]
csync/src/std/c_string.h [deleted file]
csync/src/std/c_time.c [deleted file]
csync/src/std/c_time.h [deleted file]
csync/src/std/c_utf8.cc [deleted file]
csync/src/vio/csync_vio.c [deleted file]
csync/src/vio/csync_vio.h [deleted file]
csync/src/vio/csync_vio_file_stat.c [deleted file]
csync/src/vio/csync_vio_local.h [deleted file]
csync/src/vio/csync_vio_local_unix.c [deleted file]
csync/src/vio/csync_vio_local_win.c [deleted file]
src/CMakeLists.txt
src/cmd/CMakeLists.txt
src/csync/AUTHORS [new file with mode: 0644]
src/csync/CMakeLists.txt [new file with mode: 0644]
src/csync/COPYING [new file with mode: 0644]
src/csync/ChangeLog [new file with mode: 0644]
src/csync/ConfigureChecks.cmake [new file with mode: 0644]
src/csync/DefineOptions.cmake [new file with mode: 0644]
src/csync/INSTALL [new file with mode: 0644]
src/csync/README [new file with mode: 0644]
src/csync/config_csync.h.cmake [new file with mode: 0644]
src/csync/csync.c [new file with mode: 0644]
src/csync/csync.h [new file with mode: 0644]
src/csync/csync_exclude.c [new file with mode: 0644]
src/csync/csync_exclude.h [new file with mode: 0644]
src/csync/csync_log.c [new file with mode: 0644]
src/csync/csync_log.h [new file with mode: 0644]
src/csync/csync_macros.h [new file with mode: 0644]
src/csync/csync_misc.c [new file with mode: 0644]
src/csync/csync_misc.h [new file with mode: 0644]
src/csync/csync_private.h [new file with mode: 0644]
src/csync/csync_reconcile.c [new file with mode: 0644]
src/csync/csync_reconcile.h [new file with mode: 0644]
src/csync/csync_rename.cc [new file with mode: 0644]
src/csync/csync_rename.h [new file with mode: 0644]
src/csync/csync_statedb.c [new file with mode: 0644]
src/csync/csync_statedb.h [new file with mode: 0644]
src/csync/csync_time.c [new file with mode: 0644]
src/csync/csync_time.h [new file with mode: 0644]
src/csync/csync_update.c [new file with mode: 0644]
src/csync/csync_update.h [new file with mode: 0644]
src/csync/csync_util.c [new file with mode: 0644]
src/csync/csync_util.h [new file with mode: 0644]
src/csync/csync_version.h.in [new file with mode: 0644]
src/csync/std/CMakeLists.txt [new file with mode: 0644]
src/csync/std/asprintf.c [new file with mode: 0644]
src/csync/std/asprintf.h [new file with mode: 0644]
src/csync/std/c_alloc.c [new file with mode: 0644]
src/csync/std/c_alloc.h [new file with mode: 0644]
src/csync/std/c_jhash.h [new file with mode: 0644]
src/csync/std/c_lib.h [new file with mode: 0644]
src/csync/std/c_macro.h [new file with mode: 0644]
src/csync/std/c_path.c [new file with mode: 0644]
src/csync/std/c_path.h [new file with mode: 0644]
src/csync/std/c_private.h [new file with mode: 0644]
src/csync/std/c_rbtree.c [new file with mode: 0644]
src/csync/std/c_rbtree.h [new file with mode: 0644]
src/csync/std/c_string.c [new file with mode: 0644]
src/csync/std/c_string.h [new file with mode: 0644]
src/csync/std/c_time.c [new file with mode: 0644]
src/csync/std/c_time.h [new file with mode: 0644]
src/csync/std/c_utf8.cc [new file with mode: 0644]
src/csync/vio/csync_vio.c [new file with mode: 0644]
src/csync/vio/csync_vio.h [new file with mode: 0644]
src/csync/vio/csync_vio_file_stat.c [new file with mode: 0644]
src/csync/vio/csync_vio_local.h [new file with mode: 0644]
src/csync/vio/csync_vio_local_unix.c [new file with mode: 0644]
src/csync/vio/csync_vio_local_win.c [new file with mode: 0644]
src/gui/CMakeLists.txt
src/libsync/CMakeLists.txt
src/libsync/syncjournaldb.cpp
test/CMakeLists.txt
test/csync/csync_tests/check_csync_exclude.c
test/owncloud_add_test.cmake
test/testexcludedfiles.cpp
test/testsyncjournaldb.cpp

index d4b2a52cae78264498be3f71f8ed70b181294bf6..976f19aecc175cc15357bb7b62f32dcbc0fb0916 100644 (file)
@@ -219,7 +219,6 @@ if(UNIT_TESTING)
     add_subdirectory(test)
 endif(UNIT_TESTING)
 
-add_subdirectory(csync)
 add_subdirectory(src)
 if(NOT BUILD_LIBRARIES_ONLY)
 add_subdirectory(shell_integration)
diff --git a/csync/AUTHORS b/csync/AUTHORS
deleted file mode 100644 (file)
index 5fd81c0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Andreas Schneider <asn@cryptomilk.org>
-Klaas Freitag <freitag@owncloud.com>
-Olivier Goffart <olivier>
diff --git a/csync/CMakeLists.txt b/csync/CMakeLists.txt
deleted file mode 100644 (file)
index 8b36dde..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-# global needed variables
-set(APPLICATION_NAME "ocsync")
-
-set(LIBRARY_VERSION ${MIRALL_VERSION})
-set(LIBRARY_SOVERSION "0")
-
-# add definitions
-include(DefineCMakeDefaults)
-include(DefinePlatformDefaults)
-include(DefineCompilerFlags)
-include(DefineOptions.cmake)
-
-include(DefineInstallationPaths)
-
-# add macros
-include(MacroAddPlugin)
-include(MacroCopyFile)
-
-find_package(SQLite3 3.8.0 REQUIRED)
-
-include(ConfigureChecks.cmake)
-
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-if (MEM_NULL_TESTS)
-  add_definitions(-DCSYNC_MEM_NULL_TESTS)
-endif (MEM_NULL_TESTS)
-
-add_subdirectory(src)
-
-configure_file(config_csync.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config_csync.h)
diff --git a/csync/COPYING b/csync/COPYING
deleted file mode 100644 (file)
index 4362b49..0000000
+++ /dev/null
@@ -1,502 +0,0 @@
-                  GNU LESSER GENERAL PUBLIC LICENSE
-                       Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, 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.
-\f
-  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.
-\f
-                  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.
-\f
-  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.
-\f
-  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.
-\f
-  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.
-\f
-  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.
-\f
-  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.
-\f
-  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
-\f
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    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 Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
diff --git a/csync/ChangeLog b/csync/ChangeLog
deleted file mode 100644 (file)
index a95a075..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-ChangeLog
-==========
-version 0.91.4  (released 2013-12-12, ownCloud Cleint 1.5.0)
- * changelog added, version bumped.
-
-version 0.91.3  (released 2013-12-11, ownCloud Client 1.5.0rc1) 
- * Fix progress bar on win32
- * Fix network rate limiting on win32
- * Do not check for etag during failing requests
- * Start quota timer only after the predecessor returned
- * Remove tmp files in case of certain download problems
- * Some valgrind fixes
- * Theming fix: button behaviour
- * Fix a case where a sync loop could happen.
- * Multi-linguar installer
- * Fix handling of quotes in etags written by older ownClouds
- * Fix errno handling in update phase
- * Make csync compile on FreeBSD
- * Minor cleanups.
-
-version 0.91.2 (released 2013-12-10, ownCloud Client 1.5.0beta3)
- * have translatable error message for indiv. file errors.
- * Use uint64_t for inode on win32 to fix a type glitch.
- * Add test that directories are properly moved.
- * Handle symlinks correctly.
- * No longer recurse into ignored directories in update 
-   phase.
- * Added proper symlink detection for win32 platform.
-
-version 0.91.1 (released 2013-12-03, ownCloud Client 1.5.0beta2)
- * Close database correctly to fix a potential crash (mirall#1229)
- * Handle invalid inodes correctly.
- * Use lstat rather than stat to detect symlinks correctly. 
-   (core#6146)
-
-version 0.91.0 (released 2013-11-28, ownCloud Client 1.5.0beta1)
- * fix ascii to int conversion for large numbers.
- * add support for file ids, needed to detect server side moves.
- * removed unused code, ie. database writing code that went to 
-   mirall.
- * add functions to query the database by fileid.
- * add functions to read fileids from PUT replies.
- * add server side move detection.
- * enhanced test scripts
- * Remove ne_sock_init and ne_sock_exit from owncloud module 
-   (mirall#1115)
- * Renamed 'md5' to 'etag' in code identifiers to avoid confusion.
- * add new state EVAL_RENAME 
- * link the owncloud module directly rather than dl-loading it.
- * add a content type header 'application/octet-stream' to PUTs.
- * remove -gzip from etag header if its there. (mirall#1195)
- * Many minor fixes, refactorings and improvements.
-
-version 0.90.4  (released 2013-10-18, ownCloud Client 1.4.2)
-
-  * Count renamed and deleted files for progress information.
-  * Do not reset csync internal error state in helper funcs 
-    and do not overwrite error messages.
-    That fixes error reporting to the client.
-  * Disable check on inodes on all platforms as inodes are not 
-    reliable.
-  * Fix resuming after user aborting the sync process.
-  * enabled HBF debugging permanently.
-
-version 0.90.1  (released 2013-09-24, ownCloud Client 1.4.1)
-  * no more check on the local inode in updater for win32 (bug #779)
-  * detect if server does not send an etag after an upload 
-    completed.
-  * fix crash in case of network timeout, reported as
-    https://github.comowncloud/client/issues/1010
-  * compile and cmake fixes for win32
-  * fixed behaviour of csync_exclude
-  * documentation and spelling fixes.
-
-version 0.90.0  (released 2013-09-04, ownCloud Client 1.4.0)
-  * Added API to get progress information from csync.
-  * Added c_rename function to csync std.
-  * Fix: Do renames of files before any puts.
-  * Improved database integrity checks.
-  * Improvements of database writing efficiency.
-  * Fix: stat file on win32 even if its opened by application.
-  * httpbf: configurable block size and threshold.
-  * Many fixes found by a Coverity check.
-  * Fix: use correct stat struct on all platforms
-  * Fix: download resuming.
-  * ownCloud module: Bandwith limitation added.
-  * Added ability to remove ignored files automatically.
-  * Fix: Use int64_t and friends
-  * Fix: Removed all compile warnings.
-  * Left excluded files and links in csync's tree to be able to show.
-    them to the user.
-  * Add OC-Total-Length header for better quota handling.
-  * Report inbetween progress
-
-version 0.80.0  (released 2013-06-25)
-  * Big file chunking (e.g. up/download of big files should now be no
-    problem anymore)
-  * Resuming (download of big files will resume)
-  * Fix false conflicts when database is corrupt/missing
-  * Fix false conflicts when file is locked
-  * Put legitimate conflict files only on client side
-  * Fix unreliable sync after push_file failed
-  * Fix rename due to inode cast error
-  * Make chunking work on nginx setups or through nginx proxies
-  * Improve error reporting in csync_update
-  * Clean progress database on csync_commit
-  * Fix issues detected by Coverity
-  * Fix conflict file appearing when a file cannot be stated
-  * Do not shadow server errors by not downloading files that have
-    failed to download in the past
-
-version 0.70.6  (released 2013-04-11)
-  * [Fixes] Try to avoid to upload incomplete files
-  * [Fixes] Increase read timeout to 300 seconds
-  * [Fixes] Handle IGNORE status correctly
-  * [Fixes] Set path and phash for ignored files
-  * [Fixes] Fix some issues discovered by Coverity
-  * [Fixes] Make sure to never allow empty pathes in rmdir
-  * [Fixes] Fix a crash caused by superfluous free() calls
-
-version 0.70.5  (released 2013-04-02)
-  * detect 'wrong' conflict files on client side. 
-  * [Fixes] Give context to module to enable logging (cmd client).
-  * [Fixes] Fix version table contents.
-  * [Fixes] Fix handling of non statable files on Win32.
-  * [Fixes] Fix renames on clientside on read only shares.
-  * [Fixes] Various small fixes and improvements.
-
-version 0.70.4  (released 2013-02-26)
-  * [Win32] Ship with upto-date openssl version to fix SSL problems we saw.
-  * [Fixes] Fix crash during mkdir.
-  * [Fixes] Added workaround for problem that server sometimes does
-            not respond properly to PROPFIND (mirall#285)
-  * [Fixes] Fix handling of deletion of non empty or locked
-            directories.
-  * [Fixes] Fixed some potential memory leaks.
-  * [Fixes] Files with filenames with unix extensions
-           are ignored now.
-
-version 0.70.3  (released 2013-01-24)
-  * [Platform] Fix session cookie extraction (mirall bug #260).
-
-version 0.70.2  (released 2013-01-23)
-  * [Platform] Improved module parameter system.
-  * [Platform] New logging framework. Dropped log4c dependency.
-  * [Platform] New API to provide sync progress information.
-  * [Fixes] More efficiency for the ownCloud plugin through less HTTP requests to
-            the server.
-  * [Fixes] ownCloud plugin: Improved upload performance.
-  * [Fixes] Improved error reporting to mirall.
-  * [Fixes] ownCloud plugin: Improved interpretation of HTTP error codes.
-  * [Fixes] ownCloud plugin: Do not abort on errors with individual files any
-            more.
-  * [Fixes] Lots of other minor fixes.
-  * [MacOSX] Use libneon with proper big file support.
-  * [Win32] Use libneon with openSSL support now.
-
-version 0.70.0 and 0.70.1 were beta versions.
-
-version 0.60.2  (released 2012-11-26)
-  * Migration to cross platform testing system cmocka.
-  * Fixed various minor things incl. potential mem leaks.
-  * Clang fixes.
-  * Moved journal database to sync directory.
-  * Fixed more csync->ocsync renaming issues.
-  * Fixed statedb query below path.
-  * Fixed win32 Daylight Saving Time issues.
-  * Allow static linking with iniparser and sqlite.
-  * Win32: Fix CreateHandle function in local stat.
-  * Win32: More wide char fixes.
-  * Added version table to journal database.
-  * Fixes for HTTP reply computation.
-  * Stricter error checks on PROPFIND results.
-  * Workaround for DST influenced times from previous versions.
-  * Detect looping in mkdirs to fix sharing.
-
-version 0.60.1  (released 2012-10-18)
-  * Fix improper memory cleanup which could
-            cause memory leaks and crashes
-  * Fix memory leak
-  * Allow single quote (') in file names
-  * Remove stray temporary files
-
-version 0.60.0  (released 2012-10-10)
-  * simplification of pac based proxy support. 
-  * syncing algorithm based on ids rather than on timestamps
-  * make it possible to relocate database
-
-version 0.50.11 (third beta version, released 2012-10-05)
-  * Renamed ownCloud version of csync to ocsync for ownCloud.
-  * Migration paths for csync database and config.
-  * Fixed that exclude patterns are also tested on files basenames.
-  * Fixed return type for query function if no database exists.
-  * minor code fixes
-
-version 0.50.10 (second beta version, released 2012-09-20)
-  * Fixed crash by removing a bogus free.
-  * More useful logging.
-  * ownCloud: Maintain the http session by handling the HTTP Cookie.
-
-version 0.50.9 (first beta version, released 2012-08-30)
-  * Fixed strncpy handling (mkdir on windows problem).
-  * extend database with columns uniq id and type.
-  * Use server maintained uniq IDs for update detection instead of 
-    mtimes. 
-  * Maintain uniq IDs in local database
-  * Handle change propagation through the file tree locally and remote.
-  * Added module to build a file tree from the local database (dbtree.c)
-  * Added methods to query IDs from the server and maintain it locally.
-
-version 0.50.8 (released 2012-08-10)
-  * Inode equivalent support for Win32 platforms to support rename
-  * ownCloud supports propagates renames from local to webdav MOVE
-  * ownCloud module works with proxy, settings from mirall.
-  * improved CMake modules (openSSL)
-  * Fixed namespace for lastmodified propset.
-  * Added cmocka based tests for ownCloud module.
-  * Added a config_test.h config_csync.header file.
-  * Fix link handling: Ignore symlinks.
-  * Modules can now report their capabilities to csync core.
-  * A lot of minor fixes and improvements.
-
-version 0.50.7 (released 2012-06-19)
-  * Added ability to log to a callback, ie. let the app 
-    catch the log output
-  * Added push to remote without pushing to temp file first.
-  * Fixed file copy function to use wide character (win32).
-  * Fixed loading of statedb if user has special char (win32).
-
-version 0.50.6 (released 2012-05-18)
-  * Directories with 'strange' characters broke sync. (oC bug #613)
-  * Special characters in Windows did not sync correctly. (oC bug #478)
-  * Make neon redirecting
-  * Switch logging off on Apple to not fill the syslog. (oC bug #622)
-
-version 0.50.5 (released 2012-04-18)
-  * removed argp lib dependency
-  * simplified and fixed CMake files
-  * MacOS porting efforts
-  * more granular error reports, thread save
-
-version 0.50.0 (released 2013-08-01)
-  * Added owncloud module.
-  * Added support for more platforms: FreeBSD, Windows and MacOSX
-  * Added support for more compilers: CLang, MinGW and latest GCC
-  * Added a backup mode to the reconciler.
-  * Added new logging framework (removed log4c dependency).
-  * Added new config parser (removed iniparser dependency).
-  * Added cmocka tests.
-  * Added a way to export file_tree_walk functions.
-  * Added capabilities for modules.
-  * Added possiblity to push information to the modules.
-  * Added iconv support to support various char sets.
-  * Added csync_commit() to rerun on the same context.
-  * Added content checking in conflict case.
-  * Added callbacks for progress information.
-  * Added get() and put() functions for modules.
-  * Improved database: more performance, more integrity checks
-  * Improved error reporting: status codes, custom errnos
-  * Fixed serveral bugs.
-  * Relicensed libcsync to LGPLv2.1+.
-
-version 0.44.0 (released 2010-02-15)
-  * Migrated sftp module to libssh 0.4.
-  * Added more cache entries to the default config.
-  * Added missing requirements.
-  * Fixed build warnings.
-  * Fixed some memory leaks using sftp attributes.
-  * Some code cleanups.
-
-version 0.43.0 (released 2009-05-25)
-  * Added SFTP support with libssh 0.3.
-  * Added possibility to pass userdata to the auth function.
-  * Added a better version function.
-  * Fixed CMake build.
-  * Fixed CMake find modules.
-  * Fixed some flaws in cstd functions.
-  * Documented all public functions.
-
-version 0.42.0 (released 2009-02-10)
-  * Small fix in the userguide.
-
-version 0.42.0 rc3 (released 2009-01-23)
-  libcsync:
-  * Added checks for unix extensions.
-  * Added more documentation to the userguide.
-  * Fixed loading of plugins.
-  * Fixed call for deletion functions.
-  * Normalize the path to <hostname>/<path> for the statedb filename.
-  * More change name of client options to be more descriptive.
-
-version 0.42.0 rc2 (released 2009-01-07)
-  libcsync:
-  * Fixed a bug in the creation of the statedb
-  * Completed userguide
-
-version 0.42.0 rc1 (released 2008-12-04)
-  libcsync:
-  * Reduced calls of syscall functions.
-  * Added own function to create a temporary filename.
-  * Fixed libsmbclient 3.0.x support.
-
-version 0.42.0 beta1 (released 2008-09-10)
-
-  libcsync:
-  * Added a sftp module using libssh
-  * Added user guide (just a start)
-  * Added testcase for update detection
-  * Added a function to parse an uri to cstdlib
-  * Updated the manpage
-  * Fixed some segfaults in cstdlib
-  * Fixed some memory leaks
-
-  csync:
-  * Improved the auth callback
-
-version 0.42.0 alpha4 (released 2008-07-02)
-
-  libcsync:
-  * Added the possibility to run csync completely without a journal
-  * Improved chmod calls during propagation. Most of the time we use the
-    default mode and don't need to call chmod.
-  * Improved the exclude list handling in the file tree walker. This
-    increased the speed of the update detection.
-  * Fixed csync on PPC
-  * Fixed serveral small bugs
-
-  csync:
-  * Added commandline option to run csync completely without a journal
-  * Added a manpage
-
-version 0.42.0 alpha3 (released 2008-06-25)
-
-  libcsync:
-  * Added a tree merger to write a complete journal
-  * Added support to run csync without a journal
-  * Fixed kerberos support in csync_smb module
-  * Fixed closing of files after the copy
-  * Fixed update detection to detect special files (fifo, pipes,
-    char devices, ..)
-  * Fixed O_NOATIME flag on open() if we don't have the permission
-
-  csync:
-  * Add a variable to run csync completely without a journal
-
-version 0.42.0 alpha2 (released 2008-06-16)
-
-  libcsync:
-  * Peformance improvements
-  * Add more directories to the standard exclude file
-  * Bugfixes
-
-version 0.42.0 alpha1 (released 2008-06-02)
-
-  * Initial release
diff --git a/csync/ConfigureChecks.cmake b/csync/ConfigureChecks.cmake
deleted file mode 100644 (file)
index 6d64d5a..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-include(CheckIncludeFile)
-include(CheckSymbolExists)
-include(CheckFunctionExists)
-include(CheckLibraryExists)
-include(CheckTypeSize)
-include(CheckCXXSourceCompiles)
-
-set(PACKAGE ${APPLICATION_NAME})
-set(VERSION ${APPLICATION_VERSION})
-set(DATADIR ${DATA_INSTALL_DIR})
-set(LIBDIR ${LIB_INSTALL_DIR})
-set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
-
-set(BINARYDIR ${CMAKE_CURRENT_BINARY_DIR})
-set(SOURCEDIR ${CMAKE_CURRENT_SOURCE_DIR})
-
-# HEADER FILES
-check_include_file(argp.h HAVE_ARGP_H)
-
-# FUNCTIONS
-if (NOT LINUX)
-    # librt
-    check_library_exists(rt nanosleep "" HAVE_LIBRT)
-
-    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} )
-endif (NOT LINUX)
-
-check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
-if (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
-    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} rt)
-endif (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
-
-check_library_exists(dl dlopen "" HAVE_LIBDL)
-if (HAVE_LIBDL)
-    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} dl)
-endif (HAVE_LIBDL)
-
-check_function_exists(asprintf HAVE_ASPRINTF)
-
-check_function_exists(fnmatch HAVE_FNMATCH)
-if(NOT HAVE_FNMATCH AND WIN32)
-  find_library(SHLWAPI_LIBRARY shlwapi)
-  set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} shlwapi)
-endif()
-
-if(WIN32)
-  set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} psapi kernel32)
-endif()
-
-check_function_exists(timegm HAVE_TIMEGM)
-check_function_exists(strerror_r HAVE_STRERROR_R)
-check_function_exists(utimes HAVE_UTIMES)
-check_function_exists(lstat HAVE_LSTAT)
-check_function_exists(asprintf HAVE_ASPRINTF)
-if (WIN32)
-       check_function_exists(__mingw_asprintf HAVE___MINGW_ASPRINTF)
-endif(WIN32)
-if (UNIX AND HAVE_ASPRINTF)
-  add_definitions(-D_GNU_SOURCE)
-endif (UNIX AND HAVE_ASPRINTF)
-if (WIN32)
-  check_function_exists(__mingw_asprintf HAVE___MINGW_ASPRINTF)
-endif(WIN32)
-
-set(CSYNC_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "csync required system libraries")
diff --git a/csync/DefineOptions.cmake b/csync/DefineOptions.cmake
deleted file mode 100644 (file)
index 485e183..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-option(UNIT_TESTING "Build with unit tests" OFF)
-option(MEM_NULL_TESTS "Enable NULL memory testing" OFF)
diff --git a/csync/INSTALL b/csync/INSTALL
deleted file mode 100644 (file)
index caf65c2..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-# How to build from source
-
-## Requirements
-
-### Common requirements
-
-In order to build csync, you need to install several components:
-
-- A C compiler
-- [CMake](http://www.cmake.org) >= 2.6.0.
-- [check](http://check.sourceforge.net) >= 0.9.5
-- [sqlite3](http://www.sqlite.org) >= 3.4
-- [libneon](http://www.webdav.org/neon/) >= 0.29.0
-
-optional:
-- [libsmbclient](http://www.samba.org) >= 3.5
-- [libssh](http://www.libssh.org) >= 0.5
-
-sqlite3 is a runtime requirement. libsmbclient is needed for
-the smb plugin, libssh for the sftp plugin. libneon is required for the 
-ownCloud plugin.
-
-Note that these version numbers are versions we know work correctly. If you
-build and run csync successfully with an older version, please let us know.
-
-
-## Building
-First, you need to configure the compilation, using CMake. Go inside the
-`build` dir. Create it if it doesn't exist.
-
-GNU/Linux and MacOS X:
-
-    cmake -DCMAKE_BUILD_TYPE=Debug ..
-    make
-
-### CMake standard options
-Here is a list of the most interesting options provided out of the box by CMake.
-
-- CMAKE_BUILD_TYPE: The type of build (can be Debug Release MinSizeRel RelWithDebInfo)
-- CMAKE_INSTALL_PREFIX: The prefix to use when running make install (Default to
-  /usr/local on GNU/Linux and MacOS X)
-- CMAKE_C_COMPILER: The path to the C compiler
-- CMAKE_CXX_COMPILER: The path to the C++ compiler
-
-### CMake options defined for csync
-
-Options are defined in the following files:
-
-- DefineOptions.cmake
-
-They can be changed with the -D option:
-
-`cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_LOG4C=OFF ..`
-
-### Browsing/editing CMake options
-
-In addition to passing options on the command line, you can browse and edit
-CMake options using `cmakesetup` (Windows) or `ccmake` (GNU/Linux and MacOS X).
-
-- Go to the build dir
-- On Windows: run `cmakesetup`
-- On GNU/Linux and MacOS X: run `ccmake ..`
-
-## Installing
-
-Before installing you can run the tests if everything is working:
-
-    make test
-
-If you want to install csync after compilation run:
-
-    make install
-
-## Running
-
-The csync binary can be found in the `build/client` directory.
-
-## About this document
-
-This document is written using [Markdown][] syntax, making it possible to
-provide usable information in both plain text and HTML format. Whenever
-modifying this document please use [Markdown][] syntax.
-
-[markdown]: http://www.daringfireball.net/projects/markdown
diff --git a/csync/README b/csync/README
deleted file mode 100644 (file)
index 2487e24..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-WHAT IS CSYNC?
-==============
-
-csync is a lightweight utility to synchronize files between two directories on
-a system or between multiple systems.
-
-It synchronizes bidirectionally and allows the user to keep two copies of files
-and directories in sync. csync uses widely adopted protocols, such as smb or
-sftp, so that there is no need for a server component. It is a user-level
-program which means you don’t need to be a superuser or administrator.
-
-CONTRIBUTIONS
-=============
-
-If you want to contribute to the development of the software then please join
-the mailing list. Patches are accepted preferably created with git and we are
-always glad to receive feedback or suggestions to the address
-csync-devel@csync.org.
-More information on the various mailing lists can be found at
-http://www.csync.org/communication/.
-
-You can also get the sourcecode straight from the git repository - see
-http://git.csync.org/
-
-DOCUMENTATION
-=============
-
-As a user you can find a userguide which is shipped with this package or is
-available at the website. For developers there is doxygen documentation and
-comments in the source code itself. See
-
-http://www.csync.org/userguide/
-and
-http://www.csync.org/api/
diff --git a/csync/config_csync.h.cmake b/csync/config_csync.h.cmake
deleted file mode 100644 (file)
index f5c9f09..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#cmakedefine PACKAGE "${APPLICATION_NAME}"
-#cmakedefine VERSION "${APPLICATION_VERSION}"
-#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
-#cmakedefine LIBDIR "${LIBDIR}"
-#cmakedefine SYSCONFDIR "${SYSCONFDIR}"
-#cmakedefine BINARYDIR "${BINARYDIR}"
-#cmakedefine SOURCEDIR "${SOURCEDIR}"
-
-#cmakedefine HAVE_CLOCK_GETTIME
-
-#cmakedefine WITH_LOG4C 1
-
-#cmakedefine HAVE_ARGP_H 1
-
-#cmakedefine HAVE_TIMEGM 1
-#cmakedefine HAVE_STRERROR_R 1
-#cmakedefine HAVE_UTIMES 1
-#cmakedefine HAVE_LSTAT 1
-#cmakedefine HAVE_FNMATCH 1
-
-#cmakedefine HAVE___MINGW_ASPRINTF 1
-#cmakedefine HAVE_ASPRINTF 1
-
-#cmakedefine WITH_TESTING 1
diff --git a/csync/src/CMakeLists.txt b/csync/src/CMakeLists.txt
deleted file mode 100644 (file)
index 8bce5f4..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-project(libcsync)
-
-add_subdirectory(std)
-
-# Statically include sqlite
-
-set(CSYNC_PUBLIC_INCLUDE_DIRS
-  ${CMAKE_CURRENT_BINARY_DIR}
-  ${CMAKE_CURRENT_SOURCE_DIR}
-  ${CMAKE_SOURCE_DIR}
-  CACHE INTERNAL "csync public include directories"
-)
-
-set(CSYNC_PRIVATE_INCLUDE_DIRS
-  ${SQLITE3_INCLUDE_DIRS}
-  ${CSTDLIB_PUBLIC_INCLUDE_DIRS}
-  ${CMAKE_BINARY_DIR}
-)
-
-set(CSYNC_LIBRARY
-  ocsync
-  CACHE INTERNAL "ocsync library"
-)
-
-set(CSYNC_LINK_LIBRARIES
-  ${CSTDLIB_LIBRARY}
-  ${CSYNC_REQUIRED_LIBRARIES}
-  ${SQLITE3_LIBRARIES}
-)
-
-# Specific option for builds tied to servers that do not support renaming extensions
-set(NO_RENAME_EXTENSION 0 CACHE BOOL "Do not issue rename if the extension changes")
-if(NO_RENAME_EXTENSION)
-    add_definitions(-DNO_RENAME_EXTENSION)
-endif()
-
-set(csync_SRCS
-  csync.c
-  csync_exclude.c
-  csync_log.c
-  csync_statedb.c
-  csync_time.c
-  csync_util.c
-  csync_misc.c
-
-  csync_update.c
-  csync_reconcile.c
-
-  csync_rename.cc
-
-  vio/csync_vio.c
-  vio/csync_vio_file_stat.c
-)
-
-if (WIN32)
-    list(APPEND csync_SRCS
-        vio/csync_vio_local_win.c
-    )
-else()
-    list(APPEND csync_SRCS
-        vio/csync_vio_local_unix.c
-    )
-endif()
-
-
-configure_file(csync_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h)
-
-set(csync_HDRS
-  ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h
-  csync.h
-  vio/csync_vio.h
-  vio/csync_vio_method.h
-  vio/csync_vio_module.h
-)
-
-# Statically include sqlite
-if (USE_OUR_OWN_SQLITE3)
-    list(APPEND csync_SRCS ${SQLITE3_SOURCE})
-    if (WIN32)
-        # We want to export sqlite symbols from the ocsync DLL without
-        # having to patch both sqlite3.h and the amalgation sqlite3.c,
-        # so do the import/export magic manually through the build system.
-        remove_definitions(-DSQLITE_API=__declspec\(dllimport\))
-        add_definitions(-DSQLITE_API=__declspec\(dllexport\))
-    endif()
-endif()
-
-include_directories(
-  ${CSYNC_PUBLIC_INCLUDE_DIRS}
-  ${CSYNC_PRIVATE_INCLUDE_DIRS}
-)
-
-add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS})
-#add_library(${CSYNC_LIBRARY}_static STATIC ${csync_SRCS})
-
-generate_export_header( ${CSYNC_LIBRARY}
-  BASE_NAME ${CSYNC_LIBRARY}
-  EXPORT_MACRO_NAME OCSYNC_EXPORT
-  EXPORT_FILE_NAME ocsynclib.h
-)
-
-target_link_libraries(${CSYNC_LIBRARY} ${CSYNC_LINK_LIBRARIES})
-#target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES})
-
-set_target_properties(
-  ${CSYNC_LIBRARY}
-    PROPERTIES
-      VERSION
-        ${LIBRARY_VERSION}
-      SOVERSION
-        ${LIBRARY_SOVERSION}
-      RUNTIME_OUTPUT_DIRECTORY
-        ${BIN_OUTPUT_DIRECTORY}
-)
-if(BUILD_OWNCLOUD_OSX_BUNDLE)
-  INSTALL(
-    TARGETS
-      ${CSYNC_LIBRARY}
-    LIBRARY DESTINATION
-       ${LIB_INSTALL_DIR}
-    ARCHIVE DESTINATION
-       ${LIB_INSTALL_DIR}
-    RUNTIME DESTINATION
-       ${BIN_INSTALL_DIR}
-    )
-else()
-  INSTALL(
-  TARGETS
-    ${CSYNC_LIBRARY}
-  LIBRARY DESTINATION
-    ${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
-  ARCHIVE DESTINATION
-    ${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
-  RUNTIME DESTINATION
-    ${BIN_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
-  )
-endif()
-
-
diff --git a/csync/src/csync.c b/csync/src/csync.c
deleted file mode 100644 (file)
index 1f75ac3..0000000
+++ /dev/null
@@ -1,651 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <stdbool.h>
-
-#include "c_lib.h"
-#include "csync_private.h"
-#include "csync_exclude.h"
-#include "csync_statedb.h"
-#include "csync_time.h"
-#include "csync_util.h"
-#include "csync_misc.h"
-#include "std/c_private.h"
-
-#include "csync_update.h"
-#include "csync_reconcile.h"
-
-#include "vio/csync_vio.h"
-
-#include "csync_log.h"
-#include "csync_rename.h"
-#include "c_jhash.h"
-
-static int _key_cmp(const void *key, const void *data) {
-  uint64_t a;
-  csync_file_stat_t *b;
-
-  a = *(uint64_t *) (key);
-  b = (csync_file_stat_t *) data;
-
-  if (a < b->phash) {
-    return -1;
-  } else if (a > b->phash) {
-    return 1;
-  }
-
-  return 0;
-}
-
-static int _data_cmp(const void *key, const void *data) {
-  csync_file_stat_t *a, *b;
-
-  a = (csync_file_stat_t *) key;
-  b = (csync_file_stat_t *) data;
-
-  if (a->phash < b->phash) {
-    return -1;
-  } else if (a->phash > b->phash) {
-    return 1;
-  }
-
-  return 0;
-}
-
-void csync_create(CSYNC **csync, const char *local) {
-  CSYNC *ctx;
-  size_t len = 0;
-
-  ctx = c_malloc(sizeof(CSYNC));
-
-  ctx->status_code = CSYNC_STATUS_OK;
-
-  /* remove trailing slashes */
-  len = strlen(local);
-  while(len > 0 && local[len - 1] == '/') --len;
-
-  ctx->local.uri = c_strndup(local, len);
-
-  ctx->status_code = CSYNC_STATUS_OK;
-
-  ctx->current_fs = NULL;
-
-  ctx->abort = false;
-
-  ctx->ignore_hidden_files = true;
-
-  *csync = ctx;
-}
-
-void csync_init(CSYNC *ctx, const char *db_file) {
-  assert(ctx);
-  /* Do not initialize twice */
-
-  assert(!(ctx->status & CSYNC_STATUS_INIT));
-  ctx->status_code = CSYNC_STATUS_OK;
-
-  ctx->local.type = LOCAL_REPLICA;
-
-  ctx->remote.type = REMOTE_REPLICA;
-
-  SAFE_FREE(ctx->statedb.file);
-  ctx->statedb.file = c_strdup(db_file);
-
-  c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
-  c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);
-
-  ctx->remote.root_perms = 0;
-
-  ctx->status = CSYNC_STATUS_INIT;
-
-  /* initialize random generator */
-  srand(time(NULL));
-}
-
-int csync_update(CSYNC *ctx) {
-  int rc = -1;
-  struct timespec start, finish;
-
-  if (ctx == NULL) {
-    errno = EBADF;
-    return -1;
-  }
-  ctx->status_code = CSYNC_STATUS_OK;
-
-  /* Path of database file is set in csync_init */
-  if (csync_statedb_load(ctx, ctx->statedb.file, &ctx->statedb.db) < 0) {
-      rc = -1;
-      return rc;
-  }
-
-  ctx->status_code = CSYNC_STATUS_OK;
-
-  csync_memstat_check();
-
-  if (!ctx->excludes) {
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "No exclude file loaded or defined!");
-  }
-
-  /* update detection for local replica */
-  csync_gettime(&start);
-  ctx->current = LOCAL_REPLICA;
-  ctx->replica = ctx->local.type;
-
-  rc = csync_ftw(ctx, ctx->local.uri, csync_walker, MAX_DEPTH);
-  if (rc < 0) {
-    if(ctx->status_code == CSYNC_STATUS_OK) {
-        ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_UPDATE_ERROR);
-    }
-    goto out;
-  }
-
-  csync_gettime(&finish);
-
-  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
-            "Update detection for local replica took %.2f seconds walking %zu files.",
-            c_secdiff(finish, start), c_rbtree_size(ctx->local.tree));
-  csync_memstat_check();
-
-  /* update detection for remote replica */
-  csync_gettime(&start);
-  ctx->current = REMOTE_REPLICA;
-  ctx->replica = ctx->remote.type;
-
-  rc = csync_ftw(ctx, "", csync_walker, MAX_DEPTH);
-  if (rc < 0) {
-      if(ctx->status_code == CSYNC_STATUS_OK) {
-          ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_UPDATE_ERROR);
-      }
-      goto out;
-  }
-
-  csync_gettime(&finish);
-
-  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
-            "Update detection for remote replica took %.2f seconds "
-            "walking %zu files.",
-            c_secdiff(finish, start), c_rbtree_size(ctx->remote.tree));
-  csync_memstat_check();
-
-  ctx->status |= CSYNC_STATUS_UPDATE;
-
-  rc = 0;
-
-out:
-  csync_statedb_close(ctx);
-  return rc;
-}
-
-int csync_reconcile(CSYNC *ctx) {
-  int rc = -1;
-  struct timespec start, finish;
-
-  if (ctx == NULL) {
-    errno = EBADF;
-    return -1;
-  }
-  ctx->status_code = CSYNC_STATUS_OK;
-
-  /* Reconciliation for local replica */
-  csync_gettime(&start);
-
-  if (csync_statedb_load(ctx, ctx->statedb.file, &ctx->statedb.db) < 0) {
-    rc = -1;
-    return rc;
-  }
-
-  ctx->current = LOCAL_REPLICA;
-  ctx->replica = ctx->local.type;
-
-  rc = csync_reconcile_updates(ctx);
-
-  csync_gettime(&finish);
-
-  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
-      "Reconciliation for local replica took %.2f seconds visiting %zu files.",
-      c_secdiff(finish, start), c_rbtree_size(ctx->local.tree));
-
-  if (rc < 0) {
-      if (!CSYNC_STATUS_IS_OK(ctx->status_code)) {
-          ctx->status_code = csync_errno_to_status( errno, CSYNC_STATUS_RECONCILE_ERROR );
-      }
-      goto out;
-  }
-
-  /* Reconciliation for remote replica */
-  csync_gettime(&start);
-
-  ctx->current = REMOTE_REPLICA;
-  ctx->replica = ctx->remote.type;
-
-  rc = csync_reconcile_updates(ctx);
-
-  csync_gettime(&finish);
-
-  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
-      "Reconciliation for remote replica took %.2f seconds visiting %zu files.",
-      c_secdiff(finish, start), c_rbtree_size(ctx->remote.tree));
-
-  if (rc < 0) {
-      if (!CSYNC_STATUS_IS_OK(ctx->status_code)) {
-          ctx->status_code = csync_errno_to_status(errno,  CSYNC_STATUS_RECONCILE_ERROR );
-      }
-      goto out;
-  }
-
-  ctx->status |= CSYNC_STATUS_RECONCILE;
-
-  rc = 0;
-
-out:
-  csync_statedb_close(ctx);
-  return 0;
-}
-
-/*
- * local visitor which calls the user visitor with repacked stat info.
- */
-static int _csync_treewalk_visitor(void *obj, void *data) {
-    int rc = 0;
-    csync_file_stat_t *cur         = NULL;
-    CSYNC *ctx                     = NULL;
-    c_rbtree_visit_func *visitor   = NULL;
-    _csync_treewalk_context *twctx = NULL;
-    TREE_WALK_FILE trav;
-    c_rbtree_t *other_tree = NULL;
-    c_rbnode_t *other_node = NULL;
-
-    cur = (csync_file_stat_t *) obj;
-    ctx = (CSYNC *) data;
-
-    if (ctx == NULL) {
-      return -1;
-    }
-
-    /* we need the opposite tree! */
-    switch (ctx->current) {
-    case LOCAL_REPLICA:
-        other_tree = ctx->remote.tree;
-        break;
-    case REMOTE_REPLICA:
-        other_tree = ctx->local.tree;
-        break;
-    default:
-        break;
-    }
-
-    other_node = c_rbtree_find(other_tree, &cur->phash);
-
-    if (!other_node) {
-        /* Check the renamed path as well. */
-        int len;
-        uint64_t h = 0;
-        char *renamed_path = csync_rename_adjust_path(ctx, cur->path);
-
-        if (!c_streq(renamed_path, cur->path)) {
-            len = strlen( renamed_path );
-            h = c_jhash64((uint8_t *) renamed_path, len, 0);
-            other_node = c_rbtree_find(other_tree, &h);
-        }
-        SAFE_FREE(renamed_path);
-    }
-
-    if (!other_node) {
-        /* Check the source path as well. */
-        int len;
-        uint64_t h = 0;
-        char *renamed_path = csync_rename_adjust_path_source(ctx, cur->path);
-
-        if (!c_streq(renamed_path, cur->path)) {
-            len = strlen( renamed_path );
-            h = c_jhash64((uint8_t *) renamed_path, len, 0);
-            other_node = c_rbtree_find(other_tree, &h);
-        }
-        SAFE_FREE(renamed_path);
-    }
-
-    if (obj == NULL || data == NULL) {
-      ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
-      return -1;
-    }
-    ctx->status_code = CSYNC_STATUS_OK;
-
-    twctx = (_csync_treewalk_context*) ctx->callbacks.userdata;
-    if (twctx == NULL) {
-      ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
-      return -1;
-    }
-
-    if (twctx->instruction_filter > 0 &&
-        !(twctx->instruction_filter & cur->instruction) ) {
-        return 0;
-    }
-
-    visitor = (c_rbtree_visit_func*)(twctx->user_visitor);
-    if (visitor != NULL) {
-      trav.path         = cur->path;
-      trav.size         = cur->size;
-      trav.modtime      = cur->modtime;
-      trav.mode         = cur->mode;
-      trav.type         = cur->type;
-      trav.instruction  = cur->instruction;
-      trav.rename_path  = cur->destpath;
-      trav.etag         = cur->etag;
-      trav.file_id      = cur->file_id;
-      trav.remotePerm = cur->remotePerm;
-      trav.directDownloadUrl = cur->directDownloadUrl;
-      trav.directDownloadCookies = cur->directDownloadCookies;
-      trav.inode        = cur->inode;
-
-      trav.error_status = cur->error_status;
-      trav.has_ignored_files = cur->has_ignored_files;
-      trav.checksumHeader = cur->checksumHeader;
-
-      if( other_node ) {
-          csync_file_stat_t *other_stat = (csync_file_stat_t*)other_node->data;
-          trav.other.etag = other_stat->etag;
-          trav.other.file_id = other_stat->file_id;
-          trav.other.instruction = other_stat->instruction;
-          trav.other.modtime = other_stat->modtime;
-          trav.other.size = other_stat->size;
-      } else {
-          trav.other.etag = 0;
-          trav.other.file_id = 0;
-          trav.other.instruction = CSYNC_INSTRUCTION_NONE;
-          trav.other.modtime = 0;
-          trav.other.size = 0;
-      }
-
-      rc = (*visitor)(&trav, twctx->userdata);
-      cur->instruction = trav.instruction;
-      if (trav.etag != cur->etag) { // FIXME It would be nice to have this documented
-          SAFE_FREE(cur->etag);
-          cur->etag = c_strdup(trav.etag);
-      }
-
-      return rc;
-    }
-    ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
-    return -1;
-}
-
-/*
- * treewalk function, called from its wrappers below.
- *
- * it encapsulates the user visitor function, the filter and the userdata
- * into a treewalk_context structure and calls the rb treewalk function,
- * which calls the local _csync_treewalk_visitor in this module.
- * The user visitor is called from there.
- */
-static int _csync_walk_tree(CSYNC *ctx, c_rbtree_t *tree, csync_treewalk_visit_func *visitor, int filter)
-{
-    _csync_treewalk_context tw_ctx;
-    int rc = -1;
-
-    if (ctx == NULL) {
-        errno = EBADF;
-        return rc;
-    }
-
-    if (visitor == NULL || tree == NULL) {
-        ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
-        return rc;
-    }
-    
-    tw_ctx.userdata = ctx->callbacks.userdata;
-    tw_ctx.user_visitor = visitor;
-    tw_ctx.instruction_filter = filter;
-
-    ctx->callbacks.userdata = &tw_ctx;
-
-    rc = c_rbtree_walk(tree, (void*) ctx, _csync_treewalk_visitor);
-    if( rc < 0 ) {
-      if( ctx->status_code == CSYNC_STATUS_OK )
-          ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_TREE_ERROR);
-    }
-    ctx->callbacks.userdata = tw_ctx.userdata;
-
-    return rc;
-}
-
-/*
- * wrapper function for treewalk on the remote tree
- */
-int csync_walk_remote_tree(CSYNC *ctx,  csync_treewalk_visit_func *visitor, int filter)
-{
-    c_rbtree_t *tree = NULL;
-    int rc = -1;
-
-    if(ctx != NULL) {
-        ctx->status_code = CSYNC_STATUS_OK;
-        ctx->current = REMOTE_REPLICA;
-        tree = ctx->remote.tree;
-    }
-
-    /* all error handling in the called function */
-    rc = _csync_walk_tree(ctx, tree, visitor, filter);
-    return rc;
-}
-
-/*
- * wrapper function for treewalk on the local tree
- */
-int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter)
-{
-    c_rbtree_t *tree = NULL;
-    int rc = -1;
-
-    if (ctx != NULL) {
-        ctx->status_code = CSYNC_STATUS_OK;
-        ctx->current = LOCAL_REPLICA;
-        tree = ctx->local.tree;
-    }
-
-    /* all error handling in the called function */
-    rc = _csync_walk_tree(ctx, tree, visitor, filter);
-    return rc;  
-}
-
-static void _tree_destructor(void *data) {
-  csync_file_stat_t *freedata = NULL;
-
-  freedata = (csync_file_stat_t *) data;
-  csync_file_stat_free(freedata);
-}
-
-/* reset all the list to empty.
- * used by csync_commit and csync_destroy */
-static void _csync_clean_ctx(CSYNC *ctx)
-{
-    /* destroy the rbtrees */
-    if (c_rbtree_size(ctx->local.tree) > 0) {
-        c_rbtree_destroy(ctx->local.tree, _tree_destructor);
-    }
-
-    if (c_rbtree_size(ctx->remote.tree) > 0) {
-        c_rbtree_destroy(ctx->remote.tree, _tree_destructor);
-    }
-
-    csync_rename_destroy(ctx);
-
-    /* free memory */
-    c_rbtree_free(ctx->local.tree);
-    c_rbtree_free(ctx->remote.tree);
-
-    SAFE_FREE(ctx->remote.root_perms);
-}
-
-int csync_commit(CSYNC *ctx) {
-  int rc = 0;
-
-  if (ctx == NULL) {
-    return -1;
-  }
-
-  ctx->status_code = CSYNC_STATUS_OK;
-
-  if (ctx->statedb.db != NULL
-      && csync_statedb_close(ctx) < 0) {
-    CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "ERR: closing of statedb failed.");
-    rc = -1;
-  }
-  ctx->statedb.db = NULL;
-
-  _csync_clean_ctx(ctx);
-
-  ctx->remote.read_from_db = 0;
-  ctx->read_remote_from_db = true;
-  ctx->db_is_empty = false;
-
-
-  /* Create new trees */
-  c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
-  c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);
-
-
-  ctx->status = CSYNC_STATUS_INIT;
-  SAFE_FREE(ctx->error_string);
-
-  rc = 0;
-  return rc;
-}
-
-int csync_destroy(CSYNC *ctx) {
-  int rc = 0;
-
-  if (ctx == NULL) {
-    errno = EBADF;
-    return -1;
-  }
-  ctx->status_code = CSYNC_STATUS_OK;
-
-  if (ctx->statedb.db != NULL
-      && csync_statedb_close(ctx) < 0) {
-    CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "ERR: closing of statedb failed.");
-    rc = -1;
-  }
-  ctx->statedb.db = NULL;
-
-  _csync_clean_ctx(ctx);
-
-  SAFE_FREE(ctx->statedb.file);
-  SAFE_FREE(ctx->local.uri);
-  SAFE_FREE(ctx->error_string);
-
-  SAFE_FREE(ctx);
-
-  return rc;
-}
-
-void *csync_get_userdata(CSYNC *ctx) {
-  if (ctx == NULL) {
-    return NULL;
-  }
-  return ctx->callbacks.userdata;
-}
-
-int csync_set_userdata(CSYNC *ctx, void *userdata) {
-  if (ctx == NULL) {
-    return -1;
-  }
-
-  ctx->callbacks.userdata = userdata;
-
-  return 0;
-}
-
-csync_auth_callback csync_get_auth_callback(CSYNC *ctx) {
-  if (ctx == NULL) {
-    return NULL;
-  }
-
-  return ctx->callbacks.auth_function;
-}
-
-int csync_set_status(CSYNC *ctx, int status) {
-  if (ctx == NULL || status < 0) {
-    return -1;
-  }
-
-  ctx->status = status;
-
-  return 0;
-}
-
-CSYNC_STATUS csync_get_status(CSYNC *ctx) {
-  if (ctx == NULL) {
-    return -1;
-  }
-
-  return ctx->status_code;
-}
-
-const char *csync_get_status_string(CSYNC *ctx)
-{
-  return csync_vio_get_status_string(ctx);
-}
-
-void csync_request_abort(CSYNC *ctx)
-{
-  if (ctx != NULL) {
-    ctx->abort = true;
-  }
-}
-
-void csync_resume(CSYNC *ctx)
-{
-  if (ctx != NULL) {
-    ctx->abort = false;
-  }
-}
-
-int  csync_abort_requested(CSYNC *ctx)
-{
-  if (ctx != NULL) {
-    return ctx->abort;
-  } else {
-    return (1 == 0);
-  }
-}
-
-void csync_file_stat_free(csync_file_stat_t *st)
-{
-  if (st) {
-    SAFE_FREE(st->directDownloadUrl);
-    SAFE_FREE(st->directDownloadCookies);
-    SAFE_FREE(st->etag);
-    SAFE_FREE(st->destpath);
-    SAFE_FREE(st->checksumHeader);
-    SAFE_FREE(st);
-  }
-}
diff --git a/csync/src/csync.h b/csync/src/csync.h
deleted file mode 100644 (file)
index daf778c..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file csync.h
- *
- * @brief Application developer interface for csync.
- *
- * @defgroup csyncPublicAPI csync public API
- *
- * @{
- */
-
-#ifndef _CSYNC_H
-#define _CSYNC_H
-
-#include "std/c_private.h"
-#include "ocsynclib.h"
-#include <sys/stat.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <config_csync.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum csync_status_codes_e {
-  CSYNC_STATUS_OK         = 0,
-
-  CSYNC_STATUS_ERROR      = 1024, /* don't use this code,
-                                     */
-  CSYNC_STATUS_UNSUCCESSFUL,       /* Unspecific problem happend */
-  CSYNC_STATUS_NO_LOCK,            /* OBSOLETE  does not happen anymore */
-  CSYNC_STATUS_STATEDB_LOAD_ERROR, /* Statedb can not be loaded. */
-  CSYNC_STATUS_STATEDB_CORRUPTED,  /* Statedb is corrupted */
-  CSYNC_STATUS_NO_MODULE,          /* URL passed to csync does not start with owncloud:// or ownclouds:// */
-  CSYNC_STATUS_TIMESKEW,           /* OBSOLETE */
-  CSYNC_STATUS_FILESYSTEM_UNKNOWN, /* UNUSED */
-  CSYNC_STATUS_TREE_ERROR,         /* csync trees could not be created */
-  CSYNC_STATUS_MEMORY_ERROR,       /* not enough memory problem */
-  CSYNC_STATUS_PARAM_ERROR,        /* parameter is zero where not expected */
-  CSYNC_STATUS_UPDATE_ERROR,       /* general update or discovery error */
-  CSYNC_STATUS_RECONCILE_ERROR,    /* general reconcile error */
-  CSYNC_STATUS_PROPAGATE_ERROR,    /* OBSOLETE */
-  CSYNC_STATUS_REMOTE_ACCESS_ERROR, /* UNUSED */
-  CSYNC_STATUS_REMOTE_CREATE_ERROR, /* UNUSED */
-  CSYNC_STATUS_REMOTE_STAT_ERROR,  /* UNUSED */
-  CSYNC_STATUS_LOCAL_CREATE_ERROR, /* UNUSED */
-  CSYNC_STATUS_LOCAL_STAT_ERROR,   /* UNUSED */
-  CSYNC_STATUS_PROXY_ERROR,        /* UNUSED */
-  CSYNC_STATUS_LOOKUP_ERROR,       /* Neon fails to find proxy. Almost OBSOLETE */
-  CSYNC_STATUS_SERVER_AUTH_ERROR,  /* UNUSED */
-  CSYNC_STATUS_PROXY_AUTH_ERROR,   /* UNUSED */
-  CSYNC_STATUS_CONNECT_ERROR,      /* neon driven connection failed */
-  CSYNC_STATUS_TIMEOUT,            /* UNUSED */
-  CSYNC_STATUS_HTTP_ERROR,         /* UNUSED */
-  CSYNC_STATUS_PERMISSION_DENIED,  /*  */
-  CSYNC_STATUS_NOT_FOUND,
-  CSYNC_STATUS_FILE_EXISTS,
-  CSYNC_STATUS_OUT_OF_SPACE,
-  CSYNC_STATUS_QUOTA_EXCEEDED, /* UNUSED */
-  CSYNC_STATUS_SERVICE_UNAVAILABLE,
-  CSYNC_STATUS_STORAGE_UNAVAILABLE,
-  CSYNC_STATUS_FILE_SIZE_ERROR,
-  CSYNC_STATUS_CONTEXT_LOST,
-  CSYNC_STATUS_MERGE_FILETREE_ERROR,
-  CSYNC_STATUS_CSYNC_STATUS_ERROR,
-  CSYNC_STATUS_OPENDIR_ERROR,
-  CSYNC_STATUS_READDIR_ERROR,
-  CSYNC_STATUS_OPEN_ERROR,
-  CSYNC_STATUS_ABORTED,
-    /* Codes for file individual status: */
-    CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK,
-    CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST,
-    CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS,
-    CSYNC_STATUS_INDIVIDUAL_TRAILING_SPACE,
-    CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME,
-    CYSNC_STATUS_FILE_LOCKED_OR_OPEN,
-    CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN,
-    CSYNC_STATUS_INVALID_CHARACTERS,
-    CSYNC_STATUS_INDIVIDUAL_STAT_FAILED,
-    CSYNC_STATUS_FORBIDDEN,
-    CSYNC_STATUS_INDIVIDUAL_TOO_DEEP,
-    CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE
-};
-
-typedef enum csync_status_codes_e CSYNC_STATUS;
-
-#ifndef likely
-# define likely(x) (x)
-#endif
-#ifndef unlikely
-# define unlikely(x) (x)
-#endif
-
-#define CSYNC_STATUS_IS_OK(x) (likely((x) == CSYNC_STATUS_OK))
-#define CSYNC_STATUS_IS_ERR(x) (unlikely((x) >= CSYNC_STATUS_ERROR))
-#define CSYNC_STATUS_IS_EQUAL(x, y) ((x) == (y))
-
-/**
-  * Instruction enum. In the file traversal structure, it describes
-  * the csync state of a file.
-  */
-enum csync_instructions_e {
-  CSYNC_INSTRUCTION_NONE            = 0x00000000,  /* Nothing to do (UPDATE|RECONCILE) */
-  CSYNC_INSTRUCTION_EVAL            = 0x00000001,  /* There was changed compared to the DB (UPDATE) */
-  CSYNC_INSTRUCTION_REMOVE          = 0x00000002,  /* The file need to be removed (RECONCILE) */
-  CSYNC_INSTRUCTION_RENAME          = 0x00000004,  /* The file need to be renamed (RECONCILE) */
-  CSYNC_INSTRUCTION_EVAL_RENAME     = 0x00000800,  /* The file is new, it is the destination of a rename (UPDATE) */
-  CSYNC_INSTRUCTION_NEW             = 0x00000008,  /* The file is new compared to the db (UPDATE) */
-  CSYNC_INSTRUCTION_CONFLICT        = 0x00000010,  /* The file need to be downloaded because it is a conflict (RECONCILE) */
-  CSYNC_INSTRUCTION_IGNORE          = 0x00000020,  /* The file is ignored (UPDATE|RECONCILE) */
-  CSYNC_INSTRUCTION_SYNC            = 0x00000040,  /* The file need to be pushed to the other remote (RECONCILE) */
-  CSYNC_INSTRUCTION_STAT_ERROR      = 0x00000080,
-  CSYNC_INSTRUCTION_ERROR           = 0x00000100,
-  CSYNC_INSTRUCTION_TYPE_CHANGE     = 0x00000200,  /* Like NEW, but deletes the old entity first (RECONCILE)
-                                                      Used when the type of something changes from directory to file
-                                                      or back. */
-  CSYNC_INSTRUCTION_UPDATE_METADATA = 0x00000400,  /* If the etag has been updated and need to be writen to the db,
-                                                      but without any propagation (UPDATE|RECONCILE) */
-};
-
-enum csync_ftw_type_e {
-    CSYNC_FTW_TYPE_FILE,
-    CSYNC_FTW_TYPE_SLINK,
-    CSYNC_FTW_TYPE_DIR,
-    CSYNC_FTW_TYPE_SKIP
-};
-
-
-#define FILE_ID_BUF_SIZE 36
-
-// currently specified at https://github.com/owncloud/core/issues/8322 are 9 to 10
-#define REMOTE_PERM_BUF_SIZE 15
-
-typedef struct csync_vio_file_stat_s csync_vio_file_stat_t;
-
-enum csync_vio_file_flags_e {
-  CSYNC_VIO_FILE_FLAGS_NONE = 0,
-  CSYNC_VIO_FILE_FLAGS_SYMLINK = 1 << 0,
-  CSYNC_VIO_FILE_FLAGS_HIDDEN = 1 << 1
-};
-
-enum csync_vio_file_type_e {
-  CSYNC_VIO_FILE_TYPE_UNKNOWN,
-  CSYNC_VIO_FILE_TYPE_REGULAR,
-  CSYNC_VIO_FILE_TYPE_DIRECTORY,
-  CSYNC_VIO_FILE_TYPE_FIFO,
-  CSYNC_VIO_FILE_TYPE_SOCKET,
-  CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE,
-  CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE,
-  CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK
-};
-
-enum csync_vio_file_stat_fields_e {
-  CSYNC_VIO_FILE_STAT_FIELDS_NONE = 0,
-  CSYNC_VIO_FILE_STAT_FIELDS_TYPE = 1 << 0,
-  CSYNC_VIO_FILE_STAT_FIELDS_MODE = 1 << 1, // local POSIX mode
-  CSYNC_VIO_FILE_STAT_FIELDS_FLAGS = 1 << 2,
-//  CSYNC_VIO_FILE_STAT_FIELDS_DEVICE = 1 << 3,
-  CSYNC_VIO_FILE_STAT_FIELDS_INODE = 1 << 4,
-//  CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT = 1 << 5,
-  CSYNC_VIO_FILE_STAT_FIELDS_SIZE = 1 << 6,
-//  CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_COUNT = 1 << 7, /* will be removed */
-//  CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_SIZE = 1 << 8,  /* will be removed */
-  CSYNC_VIO_FILE_STAT_FIELDS_ATIME = 1 << 9,
-  CSYNC_VIO_FILE_STAT_FIELDS_MTIME = 1 << 10,
-  CSYNC_VIO_FILE_STAT_FIELDS_CTIME = 1 << 11,
-//  CSYNC_VIO_FILE_STAT_FIELDS_SYMLINK_NAME = 1 << 12,
-//  CSYNC_VIO_FILE_STAT_FIELDS_CHECKSUM = 1 << 13,
-//  CSYNC_VIO_FILE_STAT_FIELDS_ACL = 1 << 14,
-//  CSYNC_VIO_FILE_STAT_FIELDS_UID = 1 << 15,
-//  CSYNC_VIO_FILE_STAT_FIELDS_GID = 1 << 16,
-  CSYNC_VIO_FILE_STAT_FIELDS_ETAG = 1 << 17,
-  CSYNC_VIO_FILE_STAT_FIELDS_FILE_ID = 1 << 18,
-  CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADURL = 1 << 19,
-  CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADCOOKIES = 1 << 20,
-  CSYNC_VIO_FILE_STAT_FIELDS_PERM = 1 << 21 // remote oC perm
-
-};
-
-
-struct csync_vio_file_stat_s {
-  char *name;
-  char *etag; // FIXME: Should this be inlined like file_id and perm?
-  char file_id[FILE_ID_BUF_SIZE+1];
-  char *directDownloadUrl;
-  char *directDownloadCookies;
-  char remotePerm[REMOTE_PERM_BUF_SIZE+1];
-
-  time_t atime;
-  time_t mtime;
-  time_t ctime;
-
-  int64_t size;
-
-  mode_t mode;
-
-  uint64_t inode;
-
-  int fields; // actually enum csync_vio_file_stat_fields_e fields;
-  enum csync_vio_file_type_e type;
-
-  enum csync_vio_file_flags_e flags;
-
-  char *original_name; // only set if locale conversion fails
-
-  // For remote file stats: the highest quality checksum the server provided
-  // in the "SHA1:324315da2143" form.
-  char *checksumHeader;
-};
-
-csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_new(void);
-csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
-
-void OCSYNC_EXPORT csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat);
-
-void OCSYNC_EXPORT csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src );
-
-void OCSYNC_EXPORT csync_vio_set_file_id(char* dst, const char *src );
-
-
-/**
- * CSync File Traversal structure.
- *
- * This structure is passed to the visitor function for every file
- * which is seen.
- *
- */
-
-struct csync_tree_walk_file_s {
-    const char *path;
-    int64_t     size;
-    int64_t     inode;
-    time_t      modtime;
-    mode_t      mode;
-    enum csync_ftw_type_e     type;
-    enum csync_instructions_e instruction;
-
-    /* For directories: Does it have children that were ignored (hidden or ignore pattern) */
-    int         has_ignored_files;
-
-    const char *rename_path;
-    const char *etag;
-    const char *file_id;
-    const char *remotePerm;
-    char *directDownloadUrl;
-    char *directDownloadCookies;
-
-    const char *checksumHeader;
-
-    struct {
-        int64_t     size;
-        time_t      modtime;
-        const char *etag;
-        const char *file_id;
-        enum csync_instructions_e instruction;
-    } other;
-
-    CSYNC_STATUS error_status;
-};
-typedef struct csync_tree_walk_file_s TREE_WALK_FILE;
-
-/**
- * csync handle
- */
-typedef struct csync_s CSYNC;
-
-typedef int (*csync_auth_callback) (const char *prompt, char *buf, size_t len,
-    int echo, int verify, void *userdata);
-
-typedef void (*csync_log_callback) (int verbosity,
-                                    const char *function,
-                                    const char *buffer);
-
-typedef void (*csync_update_callback) (bool local,
-                                    const char *dirUrl,
-                                    void *userdata);
-
-typedef void csync_vio_handle_t;
-typedef csync_vio_handle_t* (*csync_vio_opendir_hook) (const char *url,
-                                    void *userdata);
-typedef csync_vio_file_stat_t* (*csync_vio_readdir_hook) (csync_vio_handle_t *dhhandle,
-                                                              void *userdata);
-typedef void (*csync_vio_closedir_hook) (csync_vio_handle_t *dhhandle,
-                                                              void *userdata);
-typedef int (*csync_vio_stat_hook) (csync_vio_handle_t *dhhandle,
-                                                              void *userdata);
-
-/* Compute the checksum of the given \a checksumTypeId for \a path. */
-typedef const char *(*csync_checksum_hook)(
-    const char *path, const char *otherChecksumHeader, void *userdata);
-
-/**
- * @brief Allocate a csync context.
- *
- * @param csync  The context variable to allocate.
- */
-void OCSYNC_EXPORT csync_create(CSYNC **csync, const char *local);
-
-/**
- * @brief Initialize the file synchronizer.
- *
- * This function loads the configuration
- *
- * @param ctx  The context to initialize.
- */
-void OCSYNC_EXPORT csync_init(CSYNC *ctx, const char *db_file);
-
-/**
- * @brief Update detection
- *
- * @param ctx  The context to run the update detection on.
- *
- * @return  0 on success, less than 0 if an error occurred.
- */
-int OCSYNC_EXPORT csync_update(CSYNC *ctx);
-
-/**
- * @brief Reconciliation
- *
- * @param ctx  The context to run the reconciliation on.
- *
- * @return  0 on success, less than 0 if an error occurred.
- */
-int OCSYNC_EXPORT csync_reconcile(CSYNC *ctx);
-
-/**
- * @brief Re-initializes the csync context
- *
- * @param ctx  The context to commit.
- *
- * @return  0 on success, less than 0 if an error occurred.
- */
-int OCSYNC_EXPORT csync_commit(CSYNC *ctx);
-
-/**
- * @brief Destroy the csync context
- *
- * frees the memory.
- *
- * @param ctx  The context to destroy.
- *
- * @return  0 on success, less than 0 if an error occurred.
- */
-int OCSYNC_EXPORT csync_destroy(CSYNC *ctx);
-
-/**
- * @brief Get the userdata saved in the context.
- *
- * @param ctx           The csync context.
- *
- * @return              The userdata saved in the context, NULL if an error
- *                      occurred.
- */
-void *csync_get_userdata(CSYNC *ctx);
-
-/**
- * @brief Save userdata to the context which is passed to the auth
- * callback function.
- *
- * @param ctx           The csync context.
- *
- * @param userdata      The userdata to be stored in the context.
- *
- * @return              0 on success, less than 0 if an error occurred.
- */
-int OCSYNC_EXPORT csync_set_userdata(CSYNC *ctx, void *userdata);
-
-/**
- * @brief Get the authentication callback set.
- *
- * @param ctx           The csync context.
- *
- * @return              The authentication callback set or NULL if an error
- *                      occurred.
- */
-csync_auth_callback OCSYNC_EXPORT csync_get_auth_callback(CSYNC *ctx);
-
-/**
- * @brief Set the authentication callback.
- *
- * @param ctx           The csync context.
- *
- * @param cb            The authentication callback.
- *
- * @return              0 on success, less than 0 if an error occurred.
- */
-int OCSYNC_EXPORT csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
-
-/**
- * @brief Set the log level.
- *
- * @param[in]  level  The log verbosity.
- *
- * @return 0 on success, < 0 if an error occurred.
- */
-int OCSYNC_EXPORT csync_set_log_level(int level);
-
-/**
- * @brief Get the log verbosity
- *
- * @return            The log verbosity, -1 on error.
- */
-int OCSYNC_EXPORT csync_get_log_level(void);
-
-/**
- * @brief Get the logging callback set.
- *
- * @return              The logging callback set or NULL if an error
- *                      occurred.
- */
-csync_log_callback OCSYNC_EXPORT csync_get_log_callback(void);
-
-/**
- * @brief Set the logging callback.
- *
- * @param cb            The logging callback.
- *
- * @return              0 on success, less than 0 if an error occurred.
- */
-int OCSYNC_EXPORT csync_set_log_callback(csync_log_callback cb);
-
-/* Used for special modes or debugging */
-CSYNC_STATUS OCSYNC_EXPORT csync_get_status(CSYNC *ctx);
-
-/* Used for special modes or debugging */
-int OCSYNC_EXPORT csync_set_status(CSYNC *ctx, int status);
-
-typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
-
-/**
- * @brief Walk the local file tree and call a visitor function for each file.
- *
- * @param ctx           The csync context.
- * @param visitor       A callback function to handle the file info.
- * @param filter        A filter, built from or'ed csync_instructions_e
- *
- * @return              0 on success, less than 0 if an error occurred.
- */
-int OCSYNC_EXPORT csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
-
-/**
- * @brief Walk the remote file tree and call a visitor function for each file.
- *
- * @param ctx           The csync context.
- * @param visitor       A callback function to handle the file info.
- * @param filter        A filter, built from and'ed csync_instructions_e
- *
- * @return              0 on success, less than 0 if an error occurred.
- */
-int OCSYNC_EXPORT csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
-
-/**
- * @brief Get the csync status string.
- *
- * @param ctx            The csync context.
- *
- * @return               A const pointer to a string with more precise status info.
- */
-const char OCSYNC_EXPORT *csync_get_status_string(CSYNC *ctx);
-
-/**
- * @brief Aborts the current sync run as soon as possible. Can be called from another thread.
- *
- * @param ctx           The csync context.
- */
-void OCSYNC_EXPORT csync_request_abort(CSYNC *ctx);
-
-/**
- * @brief Clears the abort flag. Can be called from another thread.
- *
- * @param ctx           The csync context.
- */
-void OCSYNC_EXPORT csync_resume(CSYNC *ctx);
-
-/**
- * @brief Checks for the abort flag, to be used from the modules.
- *
- * @param ctx           The csync context.
- */
-int  OCSYNC_EXPORT csync_abort_requested(CSYNC *ctx);
-
-char OCSYNC_EXPORT *csync_normalize_etag(const char *);
-time_t OCSYNC_EXPORT oc_httpdate_parse( const char *date );
-
-#ifdef __cplusplus
-}
-#endif
-
-/**
- * }@
- */
-#endif /* _CSYNC_H */
-/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/csync/src/csync_exclude.c b/csync/src/csync_exclude.c
deleted file mode 100644 (file)
index fea6625..0000000
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <stdio.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "c_lib.h"
-#include "c_private.h"
-
-#include "csync_private.h"
-#include "csync_exclude.h"
-#include "csync_misc.h"
-
-#ifdef _WIN32
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-
-#define CSYNC_LOG_CATEGORY_NAME "csync.exclude"
-#include "csync_log.h"
-
-#ifndef WITH_TESTING
-static
-#endif
-int _csync_exclude_add(c_strlist_t **inList, const char *string) {
-    size_t i = 0;
-
-    // We never want duplicates, so check whether the string is already
-    // in the list first.
-    if (*inList) {
-        for (i = 0; i < (*inList)->count; ++i) {
-            char *pattern = (*inList)->vector[i];
-            if (c_streq(pattern, string)) {
-                return 1;
-            }
-        }
-    }
-    return c_strlist_add_grow(inList, string);
-}
-
-/** Expands C-like escape sequences.
- *
- * The returned string is heap-allocated and owned by the caller.
- */
-static const char *csync_exclude_expand_escapes(const char * input)
-{
-    size_t i_len = strlen(input) + 1;
-    char *out = c_malloc(i_len); // out can only be shorter
-
-    size_t i = 0;
-    size_t o = 0;
-    for (; i < i_len; ++i) {
-        if (input[i] == '\\') {
-            // at worst input[i+1] is \0
-            switch (input[i+1]) {
-            case '\'': out[o++] = '\''; break;
-            case '"': out[o++] = '"'; break;
-            case '?': out[o++] = '?'; break;
-            case '\\': out[o++] = '\\'; break;
-            case 'a': out[o++] = '\a'; break;
-            case 'b': out[o++] = '\b'; break;
-            case 'f': out[o++] = '\f'; break;
-            case 'n': out[o++] = '\n'; break;
-            case 'r': out[o++] = '\r'; break;
-            case 't': out[o++] = '\t'; break;
-            case 'v': out[o++] = '\v'; break;
-            default:
-                out[o++] = input[i];
-                out[o++] = input[i+1];
-                break;
-            }
-            ++i;
-        } else {
-            out[o++] = input[i];
-        }
-    }
-    return out;
-}
-
-int csync_exclude_load(const char *fname, c_strlist_t **list) {
-  int fd = -1;
-  int i = 0;
-  int rc = -1;
-  int64_t size;
-  char *buf = NULL;
-  char *entry = NULL;
-  mbchar_t *w_fname;
-
-  if (fname == NULL) {
-      return -1;
-  }
-
-#ifdef _WIN32
-  _fmode = _O_BINARY;
-#endif
-
-  w_fname = c_utf8_path_to_locale(fname);
-  if (w_fname == NULL) {
-      return -1;
-  }
-
-  fd = _topen(w_fname, O_RDONLY);
-  c_free_locale_string(w_fname);
-  if (fd < 0) {
-    return -1;
-  }
-
-  size = lseek(fd, 0, SEEK_END);
-  if (size < 0) {
-    rc = -1;
-    goto out;
-  }
-  lseek(fd, 0, SEEK_SET);
-  if (size == 0) {
-    rc = 0;
-    goto out;
-  }
-  buf = c_malloc(size + 1);
-  if (read(fd, buf, size) != size) {
-    rc = -1;
-    goto out;
-  }
-  buf[size] = '\0';
-
-  /* FIXME: Use fgets and don't add duplicates */
-  entry = buf;
-  for (i = 0; i < size; i++) {
-    if (buf[i] == '\n' || buf[i] == '\r') {
-      if (entry != buf + i) {
-        buf[i] = '\0';
-        if (*entry != '#') {
-          const char *unescaped = csync_exclude_expand_escapes(entry);
-          rc = _csync_exclude_add(list, unescaped);
-          if( rc == 0 ) {
-              CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
-          }
-          SAFE_FREE(unescaped);
-          if (rc < 0) {
-              goto out;
-          }
-        }
-      }
-      entry = buf + i + 1;
-    }
-  }
-
-  rc = 0;
-out:
-  SAFE_FREE(buf);
-  close(fd);
-  return rc;
-}
-
-// See http://support.microsoft.com/kb/74496 and
-// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
-// Additionally, we ignore '$Recycle.Bin', see https://github.com/owncloud/client/issues/2955
-static const char* win_reserved_words[] = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5",
-                                           "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4",
-                                           "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", "CLOCK$", "$Recycle.Bin" };
-
-bool csync_is_windows_reserved_word(const char* filename) {
-
-  size_t win_reserve_words_len = sizeof(win_reserved_words) / sizeof(char*);
-  size_t j;
-
-  for (j = 0; j < win_reserve_words_len; j++) {
-    int len_reserved_word = strlen(win_reserved_words[j]);
-    int len_filename = strlen(filename);
-    if (len_filename == 2 && filename[1] == ':') {
-        if (filename[0] >= 'a' && filename[0] <= 'z') {
-            return true;
-        }
-        if (filename[0] >= 'A' && filename[0] <= 'Z') {
-            return true;
-        }
-    }
-    if (c_strncasecmp(filename, win_reserved_words[j], len_reserved_word) == 0) {
-        if (len_filename == len_reserved_word) {
-            return true;
-        }
-        if ((len_filename > len_reserved_word) && (filename[len_reserved_word] == '.')) {
-            return true;
-        }
-    }
-  }
-  return false;
-}
-
-static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const char *path, int filetype, bool check_leading_dirs) {
-    size_t i = 0;
-    const char *bname = NULL;
-    size_t blen = 0;
-    char *conflict = NULL;
-    int rc = -1;
-    CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED;
-    CSYNC_EXCLUDE_TYPE type  = CSYNC_NOT_EXCLUDED;
-
-    /* split up the path */
-    bname = strrchr(path, '/');
-    if (bname) {
-        bname += 1; // don't include the /
-    } else {
-        bname = path;
-    }
-    blen = strlen(bname);
-
-    rc = csync_fnmatch("._sync_*.db*", bname, 0);
-    if (rc == 0) {
-        match = CSYNC_FILE_SILENTLY_EXCLUDED;
-        goto out;
-    }
-    rc = csync_fnmatch(".sync_*.db*", bname, 0);
-    if (rc == 0) {
-        match = CSYNC_FILE_SILENTLY_EXCLUDED;
-        goto out;
-    }
-    rc = csync_fnmatch(".csync_journal.db*", bname, 0);
-    if (rc == 0) {
-        match = CSYNC_FILE_SILENTLY_EXCLUDED;
-        goto out;
-    }
-
-    // check the strlen and ignore the file if its name is longer than 254 chars.
-    // whenever changing this also check createDownloadTmpFileName
-    if (blen > 254) {
-        match = CSYNC_FILE_EXCLUDE_LONG_FILENAME;
-        goto out;
-    }
-
-#ifdef _WIN32
-    // Windows cannot sync files ending in spaces (#2176). It also cannot
-    // distinguish files ending in '.' from files without an ending,
-    // as '.' is a separator that is not stored internally, so let's
-    // not allow to sync those to avoid file loss/ambiguities (#416)
-    if (blen > 1) {
-        if (bname[blen-1]== ' ') {
-            match = CSYNC_FILE_EXCLUDE_TRAILING_SPACE;
-            goto out;
-        } else if (bname[blen-1]== '.' ) {
-            match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
-            goto out;
-        }
-    }
-
-    if (csync_is_windows_reserved_word(bname)) {
-      match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
-      goto out;
-    }
-
-    // Filter out characters not allowed in a filename on windows
-    const char *p = NULL;
-    for (p = path; *p; p++) {
-        switch (*p) {
-        case '\\':
-        case ':':
-        case '?':
-        case '*':
-        case '"':
-        case '>':
-        case '<':
-        case '|':
-            match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
-            goto out;
-        default:
-            break;
-        }
-    }
-#endif
-
-    /* We create a desktop.ini on Windows for the sidebar icon, make sure we don't sync them. */
-    rc = csync_fnmatch("Desktop.ini", bname, 0);
-    if (rc == 0) {
-        match = CSYNC_FILE_SILENTLY_EXCLUDED;
-        goto out;
-    }
-
-    rc = csync_fnmatch(".owncloudsync.log*", bname, 0);
-    if (rc == 0) {
-        match = CSYNC_FILE_SILENTLY_EXCLUDED;
-        goto out;
-    }
-
-    /* Always ignore conflict files, not only via the exclude list */
-    rc = csync_fnmatch("*_conflict-*", bname, 0);
-    if (rc == 0) {
-        match = CSYNC_FILE_EXCLUDE_CONFLICT;
-        goto out;
-    }
-
-    if (getenv("CSYNC_CONFLICT_FILE_USERNAME")) {
-        rc = asprintf(&conflict, "*_conflict_%s-*", getenv("CSYNC_CONFLICT_FILE_USERNAME"));
-        if (rc < 0) {
-            goto out;
-        }
-        rc = csync_fnmatch(conflict, path, 0);
-        if (rc == 0) {
-            match = CSYNC_FILE_EXCLUDE_CONFLICT;
-            SAFE_FREE(conflict);
-            goto out;
-        }
-        SAFE_FREE(conflict);
-    }
-
-    if( ! excludes ) {
-        goto out;
-    }
-
-    c_strlist_t *path_components = NULL;
-    if (check_leading_dirs) {
-        /* Build a list of path components to check. */
-        path_components = c_strlist_new(32);
-        char *path_split = strdup(path);
-        size_t len = strlen(path_split);
-        for (i = len; ; --i) {
-            // read backwards until a path separator is found
-            if (i != 0 && path_split[i-1] != '/') {
-                continue;
-            }
-
-            // check 'basename', i.e. for "/foo/bar/fi" we'd check 'fi', 'bar', 'foo'
-            if (path_split[i] != 0) {
-                c_strlist_add_grow(&path_components, path_split + i);
-            }
-
-            if (i == 0) {
-                break;
-            }
-
-            // check 'dirname', i.e. for "/foo/bar/fi" we'd check '/foo/bar', '/foo'
-            path_split[i-1] = '\0';
-            c_strlist_add_grow(&path_components, path_split);
-        }
-        SAFE_FREE(path_split);
-    }
-
-    /* Loop over all exclude patterns and evaluate the given path */
-    for (i = 0; match == CSYNC_NOT_EXCLUDED && i < excludes->count; i++) {
-        bool match_dirs_only = false;
-        char *pattern = excludes->vector[i];
-
-        type = CSYNC_FILE_EXCLUDE_LIST;
-        if (!pattern[0]) { /* empty pattern */
-            continue;
-        }
-        /* Excludes starting with ']' means it can be cleanup */
-        if (pattern[0] == ']') {
-            ++pattern;
-            if (filetype == CSYNC_FTW_TYPE_FILE) {
-                type = CSYNC_FILE_EXCLUDE_AND_REMOVE;
-            }
-        }
-        /* Check if the pattern applies to pathes only. */
-        if (pattern[strlen(pattern)-1] == '/') {
-            if (!check_leading_dirs && filetype == CSYNC_FTW_TYPE_FILE) {
-                continue;
-            }
-            match_dirs_only = true;
-            pattern[strlen(pattern)-1] = '\0'; /* Cut off the slash */
-        }
-
-        /* check if the pattern contains a / and if, compare to the whole path */
-        if (strchr(pattern, '/')) {
-            rc = csync_fnmatch(pattern, path, FNM_PATHNAME);
-            if( rc == 0 ) {
-                match = type;
-            }
-            /* if the pattern requires a dir, but path is not, its still not excluded. */
-            if (match_dirs_only && filetype != CSYNC_FTW_TYPE_DIR) {
-                match = CSYNC_NOT_EXCLUDED;
-            }
-        }
-
-        /* if still not excluded, check each component and leading directory of the path */
-        if (match == CSYNC_NOT_EXCLUDED && check_leading_dirs) {
-            size_t j = 0;
-            if (match_dirs_only && filetype == CSYNC_FTW_TYPE_FILE) {
-                j = 1; // skip the first entry, which is bname
-            }
-            for (; j < path_components->count; ++j) {
-                rc = csync_fnmatch(pattern, path_components->vector[j], 0);
-                if (rc == 0) {
-                    match = type;
-                    break;
-                }
-            }
-        } else if (match == CSYNC_NOT_EXCLUDED && !check_leading_dirs) {
-            rc = csync_fnmatch(pattern, bname, 0);
-            if (rc == 0) {
-                match = type;
-            }
-        }
-        if (match_dirs_only) {
-            /* restore the '/' */
-            pattern[strlen(pattern)] = '/';
-        }
-    }
-    c_strlist_destroy(path_components);
-
-  out:
-
-    return match;
-}
-
-CSYNC_EXCLUDE_TYPE csync_excluded_traversal(c_strlist_t *excludes, const char *path, int filetype) {
-  return _csync_excluded_common(excludes, path, filetype, false);
-}
-
-CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype) {
-  return _csync_excluded_common(excludes, path, filetype, true);
-}
-
diff --git a/csync/src/csync_exclude.h b/csync/src/csync_exclude.h
deleted file mode 100644 (file)
index 722d27c..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _CSYNC_EXCLUDE_H
-#define _CSYNC_EXCLUDE_H
-
-#include "ocsynclib.h"
-
-enum csync_exclude_type_e {
-  CSYNC_NOT_EXCLUDED   = 0,
-  CSYNC_FILE_SILENTLY_EXCLUDED,
-  CSYNC_FILE_EXCLUDE_AND_REMOVE,
-  CSYNC_FILE_EXCLUDE_LIST,
-  CSYNC_FILE_EXCLUDE_INVALID_CHAR,
-  CSYNC_FILE_EXCLUDE_TRAILING_SPACE,
-  CSYNC_FILE_EXCLUDE_LONG_FILENAME,
-  CSYNC_FILE_EXCLUDE_HIDDEN,
-  CSYNC_FILE_EXCLUDE_STAT_FAILED,
-  CSYNC_FILE_EXCLUDE_CONFLICT
-};
-typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
-
-#ifdef WITH_TESTING
-int OCSYNC_EXPORT _csync_exclude_add(c_strlist_t **inList, const char *string);
-#endif
-
-/**
- * @brief Load exclude list
- *
- * @param ctx    The context of the synchronizer.
- * @param fname  The filename to load.
- *
- * @return  0 on success, -1 if an error occurred with errno set.
- */
-int OCSYNC_EXPORT csync_exclude_load(const char *fname, c_strlist_t **list);
-
-/**
- * @brief Check if the given path should be excluded in a traversal situation.
- *
- * It does only part of the work that csync_excluded does because it's assumed
- * that all leading directories have been run through csync_excluded_traversal()
- * before. This can be significantly faster.
- *
- * That means for '/foo/bar/file' only ('/foo/bar/file', 'file') is checked
- * against the exclude patterns.
- *
- * @param ctx   The synchronizer context.
- * @param path  The patch to check.
- *
- * @return  2 if excluded and needs cleanup, 1 if excluded, 0 if not.
- */
-CSYNC_EXCLUDE_TYPE csync_excluded_traversal(c_strlist_t *excludes, const char *path, int filetype);
-
-/**
- * @brief csync_excluded_no_ctx
- * @param excludes
- * @param path
- * @param filetype
- * @return
- */
-CSYNC_EXCLUDE_TYPE OCSYNC_EXPORT csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
-#endif /* _CSYNC_EXCLUDE_H */
-
-/**
- * @brief Checks if filename is considered reserved by Windows
- * @param file_name filename
- * @return true if file is reserved, false otherwise
- */
-bool csync_is_windows_reserved_word(const char *file_name);
-
-
-/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/csync/src/csync_log.c b/csync/src/csync_log.c
deleted file mode 100644 (file)
index 4a2e24a..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include "csync_private.h"
-#include "csync_log.h"
-
-CSYNC_THREAD int csync_log_level;
-CSYNC_THREAD csync_log_callback csync_log_cb;
-
-void csync_log(int verbosity,
-               const char *function,
-               const char *format, ...)
-{
-    csync_log_callback log_fn = csync_get_log_callback();
-    if (log_fn && verbosity <= csync_get_log_level()) {
-        char buffer[1024];
-        va_list va;
-        va_start(va, format);
-        vsnprintf(buffer, sizeof(buffer), format, va);
-        va_end(va);
-
-        log_fn(verbosity, function, buffer);
-        return;
-    }
-}
-
-int csync_set_log_level(int level) {
-  if (level < 0) {
-    return -1;
-  }
-
-  csync_log_level = level;
-
-  return 0;
-}
-
-int csync_get_log_level(void) {
-  return csync_log_level;
-}
-
-int csync_set_log_callback(csync_log_callback cb) {
-  if (cb == NULL) {
-    return -1;
-  }
-
-  csync_log_cb = cb;
-
-  return 0;
-}
-
-csync_log_callback csync_get_log_callback(void) {
-  return csync_log_cb;
-}
diff --git a/csync/src/csync_log.h b/csync/src/csync_log.h
deleted file mode 100644 (file)
index 0cd0d01..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file csync_log.h
- *
- * @brief Logging interface of csync
- *
- * @defgroup csyncLogInternals csync logging internals
- * @ingroup csyncInternalAPI
- *
- * @{
- */
-
-#ifndef _CSYNC_LOG_H
-#define _CSYNC_LOG_H
-
-/* GCC have printf type attribute check.  */
-#ifndef PRINTF_ATTRIBUTE
-#ifdef __GNUC__
-#ifdef _WIN32
-#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__gnu_printf__, a, b)))
-#else
-#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
-#endif
-#else
-#define PRINTF_ATTRIBUTE(a,b)
-#endif /* __GNUC__ */
-#endif /* ndef PRINTF_ATTRIBUTE */
-
-enum csync_log_priority_e {
-    CSYNC_LOG_PRIORITY_NOLOG = 0,
-    CSYNC_LOG_PRIORITY_FATAL,
-    CSYNC_LOG_PRIORITY_ALERT,
-    CSYNC_LOG_PRIORITY_CRIT,
-    CSYNC_LOG_PRIORITY_ERROR,
-    CSYNC_LOG_PRIORITY_WARN,
-    CSYNC_LOG_PRIORITY_NOTICE,
-    CSYNC_LOG_PRIORITY_INFO,
-    CSYNC_LOG_PRIORITY_DEBUG,
-    CSYNC_LOG_PRIORITY_TRACE,
-    CSYNC_LOG_PRIORITY_NOTSET,
-    CSYNC_LOG_PRIORITY_UNKNOWN,
-};
-
-#define CSYNC_LOG(priority, ...) \
-  csync_log(priority, __func__, __VA_ARGS__)
-
-void csync_log(int verbosity,
-               const char *function,
-               const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
-
-/**
- * }@
- */
-#endif /* _CSYNC_LOG_H */
-
-/* vim: set ft=c.doxygen ts=4 sw=4 et cindent: */
diff --git a/csync/src/csync_macros.h b/csync/src/csync_macros.h
deleted file mode 100644 (file)
index f128b43..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _CSYNC_MACROS_H
-#define _CSYNC_MACROS_H
-
-#include <stdlib.h>
-#include <string.h>
-
-/* How many elements there are in a static array */
-#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
-
-/* Some special custom errno values to report bugs properly. The BASE value
- * should always be larger than the highest system errno. */
-#define CSYNC_CUSTOM_ERRNO_BASE 10000
-
-#define ERRNO_GENERAL_ERROR          CSYNC_CUSTOM_ERRNO_BASE+2
-#define ERRNO_LOOKUP_ERROR           CSYNC_CUSTOM_ERRNO_BASE+3
-#define ERRNO_USER_UNKNOWN_ON_SERVER CSYNC_CUSTOM_ERRNO_BASE+4
-#define ERRNO_PROXY_AUTH             CSYNC_CUSTOM_ERRNO_BASE+5
-#define ERRNO_CONNECT                CSYNC_CUSTOM_ERRNO_BASE+6
-#define ERRNO_TIMEOUT                CSYNC_CUSTOM_ERRNO_BASE+7
-#define ERRNO_PRECONDITION           CSYNC_CUSTOM_ERRNO_BASE+8
-#define ERRNO_RETRY                  CSYNC_CUSTOM_ERRNO_BASE+9
-#define ERRNO_REDIRECT               CSYNC_CUSTOM_ERRNO_BASE+10
-#define ERRNO_WRONG_CONTENT          CSYNC_CUSTOM_ERRNO_BASE+11
-#define ERRNO_ERROR_STRING           CSYNC_CUSTOM_ERRNO_BASE+13
-#define ERRNO_SERVICE_UNAVAILABLE    CSYNC_CUSTOM_ERRNO_BASE+14
-#define ERRNO_USER_ABORT             CSYNC_CUSTOM_ERRNO_BASE+16
-#define ERRNO_STORAGE_UNAVAILABLE    CSYNC_CUSTOM_ERRNO_BASE+17
-#define ERRNO_FORBIDDEN              CSYNC_CUSTOM_ERRNO_BASE+18
-
-#endif /* _CSYNC_MACROS_H */
-/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/csync/src/csync_misc.c b/csync/src/csync_misc.c
deleted file mode 100644 (file)
index d232361..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <limits.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <errno.h>
-
-#if _WIN32
-# ifndef _WIN32_IE
-#  define _WIN32_IE 0x0501 // SHGetSpecialFolderPath
-# endif
-# include <shlobj.h>
-#else /* _WIN32 */
-# include <pwd.h>
-#endif /* _WIN32 */
-
-#include "c_lib.h"
-#include "csync_misc.h"
-#include "csync_macros.h"
-#include "csync_log.h"
-
-#ifdef HAVE_FNMATCH
-#include <fnmatch.h>
-
-int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags) {
-    return fnmatch(__pattern, __name, __flags);
-}
-
-#else /* HAVE_FNMATCH */
-
-#include <shlwapi.h>
-int csync_fnmatch(const char *pattern, const char *name, int flags) {
-    BOOL match;
-
-    (void) flags;
-
-    match = PathMatchSpecA(name, pattern);
-
-    if(match)
-        return 0;
-    else
-        return 1;
-}
-#endif /* HAVE_FNMATCH */
-
-CSYNC_STATUS csync_errno_to_status(int error, CSYNC_STATUS default_status)
-{
-  CSYNC_STATUS status = CSYNC_STATUS_OK;
-
-  switch (error) {
-  case 0:
-    status = CSYNC_STATUS_OK;
-    break;
-    /* The custom errnos first. */
-  case ERRNO_GENERAL_ERROR:
-    status = CSYNC_STATUS_UNSUCCESSFUL;
-    break;
-  case ERRNO_LOOKUP_ERROR: /* In Neon: Server or proxy hostname lookup failed */
-    status = CSYNC_STATUS_LOOKUP_ERROR;
-    break;
-  case ERRNO_USER_UNKNOWN_ON_SERVER: /* Neon: User authentication on server failed. */
-    status = CSYNC_STATUS_SERVER_AUTH_ERROR;
-    break;
-  case ERRNO_PROXY_AUTH:
-    status = CSYNC_STATUS_PROXY_AUTH_ERROR; /* Neon: User authentication on proxy failed */
-    break;
-  case ERRNO_CONNECT:
-    status = CSYNC_STATUS_CONNECT_ERROR; /* Network: Connection error */
-    break;
-  case ERRNO_TIMEOUT:
-    status = CSYNC_STATUS_TIMEOUT; /* Network: Timeout error */
-    break;
-  case ERRNO_SERVICE_UNAVAILABLE:
-    status = CSYNC_STATUS_SERVICE_UNAVAILABLE;  /* Service temporarily down */
-    break;
-  case ERRNO_STORAGE_UNAVAILABLE:
-    status = CSYNC_STATUS_STORAGE_UNAVAILABLE;  /* Storage temporarily unavailable */
-    break;
-  case EFBIG:
-    status = CSYNC_STATUS_FILE_SIZE_ERROR;          /* File larger than 2MB */
-    break;
-  case ERRNO_PRECONDITION:
-  case ERRNO_RETRY:
-  case ERRNO_REDIRECT:
-  case ERRNO_WRONG_CONTENT:
-    status = CSYNC_STATUS_HTTP_ERROR;
-    break;
-
-  case EPERM:                  /* Operation not permitted */
-  case EACCES:                /* Permission denied */
-    status = CSYNC_STATUS_PERMISSION_DENIED;
-    break;
-  case ENOENT:                 /* No such file or directory */
-    status = CSYNC_STATUS_NOT_FOUND;
-    break;
-  case EAGAIN:                /* Try again */
-    status = CSYNC_STATUS_TIMEOUT;
-    break;
-  case EEXIST:                /* File exists */
-    status = CSYNC_STATUS_FILE_EXISTS;
-    break;
-  case EINVAL:
-    status = CSYNC_STATUS_PARAM_ERROR;
-    break;
-  case ENOSPC:
-    status = CSYNC_STATUS_OUT_OF_SPACE;
-    break;
-
-    /* All the remaining basic errnos: */
-  case EIO:                    /* I/O error */
-  case ESRCH:                  /* No such process */
-  case EINTR:                  /* Interrupted system call */
-  case ENXIO:                  /* No such device or address */
-  case E2BIG:                  /* Argument list too long */
-  case ENOEXEC:                /* Exec format error */
-  case EBADF:                  /* Bad file number */
-  case ECHILD:                /* No child processes */
-  case ENOMEM:                /* Out of memory */
-  case EFAULT:                /* Bad address */
-#ifndef _WIN32
-  case ENOTBLK:               /* Block device required */
-#endif
-  case EBUSY:                 /* Device or resource busy */
-  case EXDEV:                 /* Cross-device link */
-  case ENODEV:                /* No such device */
-  case ENOTDIR:               /* Not a directory */
-  case EISDIR:                /* Is a directory */
-  case ENFILE:                /* File table overflow */
-  case EMFILE:                /* Too many open files */
-  case ENOTTY:                /* Not a typewriter */
-#ifndef _WIN32
-  case ETXTBSY:               /* Text file busy */
-#endif
-  case ESPIPE:                /* Illegal seek */
-  case EROFS:                 /* Read-only file system */
-  case EMLINK:                /* Too many links */
-  case EPIPE:                 /* Broken pipe */
-
-  case ERRNO_ERROR_STRING:
-  default:
-    status = default_status;
-  }
-
-  return status;
-}
-
-/* Remove possible quotes, and also the -gzip at the end
- * Remove "-gzip" at the end (cf. https://github.comowncloud/client/issues/1195)
- * The caller must take ownership of the resulting string.
- */
-char *csync_normalize_etag(const char *etag)
-{
-    int len = 0;
-    char *buf = NULL;
-    if (!etag)
-        return NULL;
-
-    len = strlen(etag);
-    /* strip "XXXX-gzip" */
-    if(len >= 7 && etag[0] == '"' && c_streq(etag + len - 6, "-gzip\"")) {
-        etag++;
-        len -= 7;
-    }
-    /* strip leading -gzip */
-    if(len >= 5 && c_streq(etag + len - 5, "-gzip")) {
-        len -= 5;
-    }
-    /* strip normal quotes */
-    if (etag[0] == '"' && etag[len-1] == '"') {
-        etag++;
-        len -= 2;
-    }
-
-    buf = c_malloc( len+1 );
-    strncpy( buf, etag, len );
-    buf[len] = '\0';
-    return buf;
-}
-
diff --git a/csync/src/csync_misc.h b/csync/src/csync_misc.h
deleted file mode 100644 (file)
index 6b9f984..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _CSYNC_MISC_H
-#define _CSYNC_MISC_H
-
-#include <config_csync.h>
-#include <csync.h>
-
-#ifdef HAVE_FNMATCH
-#include <fnmatch.h>
-#else
-/* Steal this define to make csync_exclude compile. Note that if fnmatch
- * is not defined it's probably Win32 which uses a different implementation
- * than fmmatch anyway, which does not care for flags.
- **/
-#define FNM_PATHNAME    (1 << 0) /* No wildcard can ever match `/'.  */
-#define FNM_CASEFOLD    (1 << 4) /* Compare without regard to case.  */
-#endif
-
-int csync_fnmatch(const char *pattern, const char *name, int flags);
-
-/**
- * @brief csync_errno_to_status - errno to csync status code
- *
- * This function tries to convert the value of the current set errno
- * to a csync status code.
- *
- * @return the corresponding csync error code.
- */
-CSYNC_STATUS csync_errno_to_status(int error, CSYNC_STATUS default_status);
-
-#endif /* _CSYNC_MISC_H */
diff --git a/csync/src/csync_private.h b/csync/src/csync_private.h
deleted file mode 100644 (file)
index 2edc260..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file csync_private.h
- *
- * @brief Private interface of csync
- *
- * @defgroup csyncInternalAPI csync internal API
- *
- * @{
- */
-
-#ifndef _CSYNC_PRIVATE_H
-#define _CSYNC_PRIVATE_H
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <sqlite3.h>
-
-#include "config_csync.h"
-#include "std/c_lib.h"
-#include "std/c_private.h"
-#include "csync.h"
-#include "csync_misc.h"
-
-#include "csync_macros.h"
-
-/**
- * How deep to scan directories.
- */
-#define MAX_DEPTH 100
-
-#define CSYNC_STATUS_INIT 1 << 0
-#define CSYNC_STATUS_UPDATE 1 << 1
-#define CSYNC_STATUS_RECONCILE 1 << 2
-#define CSYNC_STATUS_PROPAGATE 1 << 3
-
-#define CSYNC_STATUS_DONE (CSYNC_STATUS_INIT | \
-                           CSYNC_STATUS_UPDATE | \
-                           CSYNC_STATUS_RECONCILE | \
-                           CSYNC_STATUS_PROPAGATE)
-
-enum csync_replica_e {
-  LOCAL_REPLICA,
-  REMOTE_REPLICA
-};
-
-typedef struct csync_file_stat_s csync_file_stat_t;
-
-/**
- * @brief csync public structure
- */
-struct csync_s {
-  struct {
-      csync_auth_callback auth_function;
-      void *userdata;
-      csync_update_callback update_callback;
-      void *update_callback_userdata;
-
-      /* hooks for checking the white list (uses the update_callback_userdata) */
-      int (*checkSelectiveSyncBlackListHook)(void*, const char*);
-      int (*checkSelectiveSyncNewFolderHook)(void*, const char* /* path */, const char* /* remotePerm */);
-
-
-      csync_vio_opendir_hook remote_opendir_hook;
-      csync_vio_readdir_hook remote_readdir_hook;
-      csync_vio_closedir_hook remote_closedir_hook;
-      void *vio_userdata;
-
-      /* hook for comparing checksums of files during discovery */
-      csync_checksum_hook checksum_hook;
-      void *checksum_userdata;
-
-  } callbacks;
-  c_strlist_t *excludes;
-  
-  struct {
-    char *file;
-    sqlite3 *db;
-    int exists;
-
-    sqlite3_stmt* by_hash_stmt;
-    sqlite3_stmt* by_fileid_stmt;
-    sqlite3_stmt* by_inode_stmt;
-
-    int lastReturnValue;
-  } statedb;
-
-  struct {
-    char *uri;
-    c_rbtree_t *tree;
-    enum csync_replica_e type;
-  } local;
-
-  struct {
-    c_rbtree_t *tree;
-    enum csync_replica_e type;
-    int  read_from_db;
-    const char *root_perms; /* Permission of the root folder. (Since the root folder is not in the db tree, we need to keep a separate entry.) */
-  } remote;
-
-
-  /* replica we are currently walking */
-  enum csync_replica_e current;
-
-  /* replica we want to work on */
-  enum csync_replica_e replica;
-
-  /* Used in the update phase so changes in the sub directories can be notified to
-     parent directories */
-  csync_file_stat_t *current_fs;
-
-  /* csync error code */
-  enum csync_status_codes_e status_code;
-
-  char *error_string;
-
-  int status;
-  volatile int abort;
-  void *rename_info;
-
-  /**
-   * Specify if it is allowed to read the remote tree from the DB (default to enabled)
-   */
-  bool read_remote_from_db;
-
-  /**
-   * If true, the DB is considered empty and all reads are skipped. (default is false)
-   * This is useful during the initial local discovery as it speeds it up significantly.
-   */
-  bool db_is_empty;
-
-  bool ignore_hidden_files;
-};
-
-
-#ifdef _MSC_VER
-#pragma pack(1)
-#endif
-struct csync_file_stat_s {
-  uint64_t phash;   /* u64 */
-  time_t modtime;   /* u64 */
-  int64_t size;       /* u64 */
-  size_t pathlen;   /* u64 */
-  uint64_t inode;   /* u64 */
-  mode_t mode;      /* u32 */
-  unsigned int type                   : 4;
-  unsigned int child_modified         : 1;
-  unsigned int has_ignored_files      : 1; /* specify that a directory, or child directory contains ignored files */
-
-  char *destpath;   /* for renames */
-  const char *etag;
-  char file_id[FILE_ID_BUF_SIZE+1];  /* the ownCloud file id is fixed width in ownCloud. */
-  char *directDownloadUrl;
-  char *directDownloadCookies;
-  char remotePerm[REMOTE_PERM_BUF_SIZE+1];
-
-  // In the local tree, this can hold a checksum and its type if it is
-  //   computed during discovery for some reason.
-  // In the remote tree, this will have the server checksum, if available.
-  // In both cases, the format is "SHA1:baff".
-  const char *checksumHeader;
-
-  CSYNC_STATUS error_status;
-
-  enum csync_instructions_e instruction; /* u32 */
-  char path[1]; /* u8 */
-}
-#if !defined(__SUNPRO_C) && !defined(_MSC_VER)
-__attribute__ ((packed))
-#endif
-#ifdef _MSC_VER
-#pragma pack()
-#endif
-;
-
-OCSYNC_EXPORT void csync_file_stat_free(csync_file_stat_t *st);
-
-/*
- * context for the treewalk function
- */
-struct _csync_treewalk_context_s
-{
-    csync_treewalk_visit_func *user_visitor;
-    int instruction_filter;
-    void *userdata;
-};
-typedef struct _csync_treewalk_context_s _csync_treewalk_context;
-
-void set_errno_from_http_errcode( int err );
-
-/**
- * }@
- */
-#endif /* _CSYNC_PRIVATE_H */
-/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/csync/src/csync_reconcile.c b/csync/src/csync_reconcile.c
deleted file mode 100644 (file)
index 59156e8..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#include <assert.h>
-#include "csync_private.h"
-#include "csync_reconcile.h"
-#include "csync_util.h"
-#include "csync_statedb.h"
-#include "csync_rename.h"
-#include "c_jhash.h"
-
-#define CSYNC_LOG_CATEGORY_NAME "csync.reconciler"
-#include "csync_log.h"
-
-#include "inttypes.h"
-
-/* Check if a file is ignored because one parent is ignored.
- * return the node of the ignored directoy if it's the case, or NULL if it is not ignored */
-static c_rbnode_t *_csync_check_ignored(c_rbtree_t *tree, const char *path, int pathlen) {
-    uint64_t h = 0;
-    c_rbnode_t *node = NULL;
-
-    /* compute the size of the parent directory */
-    int parentlen = pathlen - 1;
-    while (parentlen > 0 && path[parentlen] != '/') {
-        parentlen--;
-    }
-    if (parentlen <= 0) {
-        return NULL;
-    }
-
-    h = c_jhash64((uint8_t *) path, parentlen, 0);
-    node = c_rbtree_find(tree, &h);
-    if (node) {
-        csync_file_stat_t *n = (csync_file_stat_t*)node->data;
-        if (n->instruction == CSYNC_INSTRUCTION_IGNORE) {
-            /* Yes, we are ignored */
-            return node;
-        } else {
-            /* Not ignored */
-            return NULL;
-        }
-    } else {
-        /* Try if the parent itself is ignored */
-        return _csync_check_ignored(tree, path, parentlen);
-    }
-}
-
-/* Returns true if we're reasonably certain that hash equality
- * for the header means content equality.
- *
- * Cryptographic safety is not required - this is mainly
- * intended to rule out checksums like Adler32 that are not intended for
- * hashing and have high likelihood of collision with particular inputs.
- */
-static bool _csync_is_collision_safe_hash(const char *checksum_header)
-{
-    return strncmp(checksum_header, "SHA1:", 5) == 0
-        || strncmp(checksum_header, "MD5:", 4) == 0;
-}
-
-/**
- * The main function in the reconcile pass.
- *
- * It's called for each entry in the local and remote rbtrees by
- * csync_reconcile()
- *
- * Before the reconcile phase the trees already know about changes
- * relative to the sync journal. This function's job is to spot conflicts
- * between local and remote changes and adjust the nodes accordingly.
- *
- * See doc/dev/sync-algorithm.md for an overview.
- *
- *
- * Older detail comment:
- *
- * We merge replicas at the file level. The merged replica contains the
- * superset of files that are on the local machine and server copies of
- * the replica. In the case where the same file is in both the local
- * and server copy, the file that was modified most recently is used.
- * This means that new files are not deleted, and updated versions of
- * existing files are not overwritten.
- *
- * When a file is updated, the merge algorithm compares the destination
- * file with the the source file. If the destination file is newer
- * (timestamp is newer), it is not overwritten. If both files, on the
- * source and the destination, have been changed, the newer file wins.
- */
-static int _csync_merge_algorithm_visitor(void *obj, void *data) {
-    csync_file_stat_t *cur = NULL;
-    csync_file_stat_t *other = NULL;
-    csync_file_stat_t *tmp = NULL;
-    uint64_t h = 0;
-    int len = 0;
-
-    CSYNC *ctx = NULL;
-    c_rbtree_t *tree = NULL;
-    c_rbnode_t *node = NULL;
-
-    cur = (csync_file_stat_t *) obj;
-    ctx = (CSYNC *) data;
-
-    /* we need the opposite tree! */
-    switch (ctx->current) {
-    case LOCAL_REPLICA:
-        tree = ctx->remote.tree;
-        break;
-    case REMOTE_REPLICA:
-        tree = ctx->local.tree;
-        break;
-    default:
-        break;
-    }
-
-    node = c_rbtree_find(tree, &cur->phash);
-
-    if (!node) {
-        /* Check the renamed path as well. */
-        char *renamed_path = csync_rename_adjust_path(ctx, cur->path);
-        if (!c_streq(renamed_path, cur->path)) {
-            len = strlen( renamed_path );
-            h = c_jhash64((uint8_t *) renamed_path, len, 0);
-            node = c_rbtree_find(tree, &h);
-        }
-        SAFE_FREE(renamed_path);
-    }
-    if (!node) {
-        /* Check if it is ignored */
-        node = _csync_check_ignored(tree, cur->path, cur->pathlen);
-        /* If it is ignored, other->instruction will be  IGNORE so this one will also be ignored */
-    }
-
-    /* file only found on current replica */
-    if (node == NULL) {
-        switch(cur->instruction) {
-        /* file has been modified */
-        case CSYNC_INSTRUCTION_EVAL:
-            cur->instruction = CSYNC_INSTRUCTION_NEW;
-            break;
-            /* file has been removed on the opposite replica */
-        case CSYNC_INSTRUCTION_NONE:
-        case CSYNC_INSTRUCTION_UPDATE_METADATA:
-            if (cur->has_ignored_files) {
-                /* Do not remove a directory that has ignored files */
-                break;
-            }
-            if (cur->child_modified) {
-                /* re-create directory that has modified contents */
-                cur->instruction = CSYNC_INSTRUCTION_NEW;
-                break;
-            }
-            cur->instruction = CSYNC_INSTRUCTION_REMOVE;
-            break;
-        case CSYNC_INSTRUCTION_EVAL_RENAME:
-            if(ctx->current == LOCAL_REPLICA ) {
-                /* use the old name to find the "other" node */
-                tmp = csync_statedb_get_stat_by_inode(ctx, cur->inode);
-                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Finding opposite temp through inode %" PRIu64 ": %s",
-                          cur->inode, tmp ? "true":"false");
-            } else if( ctx->current == REMOTE_REPLICA ) {
-                tmp = csync_statedb_get_stat_by_file_id(ctx, cur->file_id);
-                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Finding opposite temp through file ID %s: %s",
-                          cur->file_id, tmp ? "true":"false");
-            } else {
-                CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Unknown replica...");
-            }
-
-            if( tmp ) {
-                len = strlen( tmp->path );
-                if( len > 0 ) {
-                    h = c_jhash64((uint8_t *) tmp->path, len, 0);
-                    /* First, check that the file is NOT in our tree (another file with the same name was added) */
-                    node = c_rbtree_find(ctx->current == REMOTE_REPLICA ? ctx->remote.tree : ctx->local.tree, &h);
-                    if (node) {
-                        CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Origin found in our tree : %s", tmp->path);
-                    } else {
-                        /* Find the temporar file in the other tree. */
-                        node = c_rbtree_find(tree, &h);
-                        CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "PHash of temporary opposite (%s): %" PRIu64 " %s",
-                                tmp->path , h, node ? "found": "not found" );
-                        if (node) {
-                            other = (csync_file_stat_t*)node->data;
-                        } else {
-                            /* the renamed file could not be found in the opposite tree. That is because it
-                            * is not longer existing there, maybe because it was renamed or deleted.
-                            * The journal is cleaned up later after propagation.
-                            */
-                        }
-                    }
-                }
-
-                if(!other) {
-                    cur->instruction = CSYNC_INSTRUCTION_NEW;
-                } else if (other->instruction == CSYNC_INSTRUCTION_NONE
-                           || other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
-                           || cur->type == CSYNC_FTW_TYPE_DIR) {
-                    other->instruction = CSYNC_INSTRUCTION_RENAME;
-                    other->destpath = c_strdup( cur->path );
-                    if( !c_streq(cur->file_id, "") ) {
-                        csync_vio_set_file_id( other->file_id, cur->file_id );
-                    }
-                    other->inode = cur->inode;
-                    cur->instruction = CSYNC_INSTRUCTION_NONE;
-                } else if (other->instruction == CSYNC_INSTRUCTION_REMOVE) {
-                    other->instruction = CSYNC_INSTRUCTION_RENAME;
-                    other->destpath = c_strdup( cur->path );
-
-                    if( !c_streq(cur->file_id, "") ) {
-                        csync_vio_set_file_id( other->file_id, cur->file_id );
-                    }
-                    other->inode = cur->inode;
-                    cur->instruction = CSYNC_INSTRUCTION_NONE;
-                } else if (other->instruction == CSYNC_INSTRUCTION_NEW) {
-                    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "OOOO=> NEW detected in other tree!");
-                    cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
-                } else {
-                    assert(other->type != CSYNC_FTW_TYPE_DIR);
-                    cur->instruction = CSYNC_INSTRUCTION_NONE;
-                    other->instruction = CSYNC_INSTRUCTION_SYNC;
-                }
-                csync_file_stat_free(tmp);
-           }
-
-            break;
-        default:
-            break;
-        }
-    } else {
-        bool is_conflict = true;
-        /*
-     * file found on the other replica
-     */
-        other = (csync_file_stat_t *) node->data;
-
-        switch (cur->instruction) {
-        case CSYNC_INSTRUCTION_UPDATE_METADATA:
-            if (other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA && ctx->current == LOCAL_REPLICA) {
-                // Remote wins, the SyncEngine will pick relevant local metadata since the remote tree is walked last.
-                cur->instruction = CSYNC_INSTRUCTION_NONE;
-            }
-            break;
-        case CSYNC_INSTRUCTION_EVAL_RENAME:
-            /* If the file already exist on the other side, we have a conflict.
-               Abort the rename and consider it is a new file. */
-            cur->instruction = CSYNC_INSTRUCTION_NEW;
-            /* fall trough */
-        /* file on current replica is changed or new */
-        case CSYNC_INSTRUCTION_EVAL:
-        case CSYNC_INSTRUCTION_NEW:
-            // This operation is usually a no-op and will by default return false
-            if (csync_file_locked_or_open(ctx->local.uri, cur->path)) {
-                CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "[Reconciler] IGNORING file %s/%s since it is locked / open", ctx->local.uri, cur->path);
-                cur->instruction = CSYNC_INSTRUCTION_ERROR;
-                if (cur->error_status == CSYNC_STATUS_OK) // don't overwrite error
-                    cur->error_status = CYSNC_STATUS_FILE_LOCKED_OR_OPEN;
-                break;
-            } else {
-                //CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "[Reconciler] not ignoring file %s/%s", ctx->local.uri, cur->path);
-            }
-            switch (other->instruction) {
-            /* file on other replica is changed or new */
-            case CSYNC_INSTRUCTION_NEW:
-            case CSYNC_INSTRUCTION_EVAL:
-                if (other->type == CSYNC_FTW_TYPE_DIR &&
-                        cur->type == CSYNC_FTW_TYPE_DIR) {
-                    // Folders of the same path are always considered equals
-                    is_conflict = false;
-                } else {
-                    // If the size or mtime is different, it's definitely a conflict.
-                    is_conflict = ((other->size != cur->size) || (other->modtime != cur->modtime));
-
-                    // It could be a conflict even if size and mtime match!
-                    //
-                    // In older client versions we always treated these cases as a
-                    // non-conflict. This behavior is preserved in case the server
-                    // doesn't provide a suitable content hash.
-                    //
-                    // When it does have one, however, we do create a job, but the job
-                    // will compare hashes and avoid the download if they are equal.
-                    const char *remoteChecksumHeader =
-                        (ctx->current == REMOTE_REPLICA ? cur->checksumHeader : other->checksumHeader);
-                    if (remoteChecksumHeader) {
-                        is_conflict |= _csync_is_collision_safe_hash(remoteChecksumHeader);
-                    }
-
-                    // SO: If there is no checksum, we can have !is_conflict here
-                    // even though the files have different content! This is an
-                    // intentional tradeoff. Downloading and comparing files would
-                    // be technically correct in this situation but leads to too
-                    // much waste.
-                    // In particular this kind of NEW/NEW situation with identical
-                    // sizes and mtimes pops up when the local database is lost for
-                    // whatever reason.
-                }
-                if (ctx->current == REMOTE_REPLICA) {
-                    // If the files are considered equal, only update the DB with the etag from remote
-                    cur->instruction = is_conflict ? CSYNC_INSTRUCTION_CONFLICT : CSYNC_INSTRUCTION_UPDATE_METADATA;
-                    other->instruction = CSYNC_INSTRUCTION_NONE;
-                } else {
-                    cur->instruction = CSYNC_INSTRUCTION_NONE;
-                    other->instruction = is_conflict ? CSYNC_INSTRUCTION_CONFLICT : CSYNC_INSTRUCTION_UPDATE_METADATA;
-                }
-
-                break;
-                /* file on the other replica has not been modified */
-            case CSYNC_INSTRUCTION_NONE:
-            case CSYNC_INSTRUCTION_UPDATE_METADATA:
-                if (cur->type != other->type) {
-                    // If the type of the entity changed, it's like NEW, but
-                    // needs to delete the other entity first.
-                    cur->instruction = CSYNC_INSTRUCTION_TYPE_CHANGE;
-                    other->instruction = CSYNC_INSTRUCTION_NONE;
-                } else if (cur->type == CSYNC_FTW_TYPE_DIR) {
-                    cur->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
-                    other->instruction = CSYNC_INSTRUCTION_NONE;
-                } else {
-                    cur->instruction = CSYNC_INSTRUCTION_SYNC;
-                    other->instruction = CSYNC_INSTRUCTION_NONE;
-                }
-                break;
-            case CSYNC_INSTRUCTION_IGNORE:
-                cur->instruction = CSYNC_INSTRUCTION_IGNORE;
-            break;
-            default:
-                break;
-            }
-        default:
-            break;
-        }
-    }
-
-    //hide instruction NONE messages when log level is set to debug,
-    //only show these messages on log level trace
-    const char *repo = ctx->current == REMOTE_REPLICA ? "server" : "client";
-    if(cur->instruction ==CSYNC_INSTRUCTION_NONE)
-    {
-        if(cur->type == CSYNC_FTW_TYPE_DIR)
-        {
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
-                      "%-30s %s dir:  %s",
-                      csync_instruction_str(cur->instruction),
-                      repo,
-                      cur->path);
-        }
-        else
-        {
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
-                      "%-30s %s file: %s",
-                      csync_instruction_str(cur->instruction),
-                      repo,
-                      cur->path);
-        }
-    }
-    else
-    {
-        if(cur->type == CSYNC_FTW_TYPE_DIR)
-        {
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO,
-                      "%-30s %s dir:  %s",
-                      csync_instruction_str(cur->instruction),
-                      repo,
-                      cur->path);
-        }
-        else
-        {
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO,
-                      "%-30s %s file: %s",
-                      csync_instruction_str(cur->instruction),
-                      repo,
-                      cur->path);
-        }
-    }
-
-    return 0;
-}
-
-int csync_reconcile_updates(CSYNC *ctx) {
-  int rc;
-  c_rbtree_t *tree = NULL;
-
-  switch (ctx->current) {
-    case LOCAL_REPLICA:
-      tree = ctx->local.tree;
-      break;
-    case REMOTE_REPLICA:
-      tree = ctx->remote.tree;
-      break;
-    default:
-      break;
-  }
-
-  rc = c_rbtree_walk(tree, (void *) ctx, _csync_merge_algorithm_visitor);
-  if( rc < 0 ) {
-    ctx->status_code = CSYNC_STATUS_RECONCILE_ERROR;
-  }
-  return rc;
-}
-
-/* vim: set ts=8 sw=2 et cindent: */
diff --git a/csync/src/csync_reconcile.h b/csync/src/csync_reconcile.h
deleted file mode 100644 (file)
index f333adb..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _CSYNC_RECONCILE_H
-#define _CSYNC_RECONCILE_H
-
-/**
- * @file csync_reconcile.h
- *
- * @brief Reconciliation
- *
- * The most important component is the update detector, because the reconciler
- * depends on it. The correctness of reconciler is mandatory because it can
- * damage a filesystem. It decides which file:
- *
- *       - stays untouched
- *       - has a conflict
- *       - gets synchronized
- *       - or is deleted.
- *
- * @defgroup csyncReconcilationInternals csync reconciliation internals
- * @ingroup csyncInternalAPI
- *
- * @{
- */
-
-/**
- * @brief Reconcile the files.
- *
- * @param  ctx          The csync context to use.
- *
- * @return 0 on success, < 0 on error.
- *
- * @todo Add an argument to set the algorithm to use.
- */
-int OCSYNC_EXPORT csync_reconcile_updates(CSYNC *ctx);
-
-/**
- * }@
- */
-#endif /* _CSYNC_RECONCILE_H */
-
-/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/csync/src/csync_rename.cc b/csync/src/csync_rename.cc
deleted file mode 100644 (file)
index 5cc43ce..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2012      by Olivier Goffart <ogoffart@woboq.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-extern "C" {
-#include "csync_private.h"
-#include "csync_rename.h"
-}
-
-#include <map>
-#include <string>
-#include <vector>
-#include <algorithm>
-
-static std::string _parentDir(const std::string &path) {
-    int len = path.length();
-    while(len > 0 && path[len-1]!='/') len--;
-    while(len > 0 && path[len-1]=='/') len--;
-    return path.substr(0, len);
-}
-
-struct csync_rename_s {
-    static csync_rename_s *get(CSYNC *ctx) {
-        if (!ctx->rename_info) {
-            ctx->rename_info = new csync_rename_s;
-        }
-        return reinterpret_cast<csync_rename_s *>(ctx->rename_info);
-    }
-
-    std::map<std::string, std::string> folder_renamed_to; // map from->to
-    std::map<std::string, std::string> folder_renamed_from; // map to->from
-
-    struct renameop {
-        csync_file_stat_t *st;
-        bool operator<(const renameop &other) const {
-            return strlen(st->destpath) < strlen(other.st->destpath);
-        }
-    };
-    std::vector<renameop> todo;
-};
-
-extern "C" {
-void csync_rename_destroy(CSYNC* ctx)
-{
-    delete reinterpret_cast<csync_rename_s *>(ctx->rename_info);
-    ctx->rename_info = 0;
-}
-
-void csync_rename_record(CSYNC* ctx, const char* from, const char* to)
-{
-    csync_rename_s::get(ctx)->folder_renamed_to[from] = to;
-    csync_rename_s::get(ctx)->folder_renamed_from[to] = from;
-}
-
-char* csync_rename_adjust_path(CSYNC* ctx, const char* path)
-{
-    csync_rename_s* d = csync_rename_s::get(ctx);
-    for (std::string p = _parentDir(path); !p.empty(); p = _parentDir(p)) {
-        std::map< std::string, std::string >::iterator it = d->folder_renamed_to.find(p);
-        if (it != d->folder_renamed_to.end()) {
-            std::string rep = it->second + (path + p.length());
-            return c_strdup(rep.c_str());
-        }
-    }
-    return c_strdup(path);
-}
-
-char* csync_rename_adjust_path_source(CSYNC* ctx, const char* path)
-{
-    csync_rename_s* d = csync_rename_s::get(ctx);
-    for (std::string p = _parentDir(path); !p.empty(); p = _parentDir(p)) {
-        std::map< std::string, std::string >::iterator it = d->folder_renamed_from.find(p);
-        if (it != d->folder_renamed_from.end()) {
-            std::string rep = it->second + (path + p.length());
-            return c_strdup(rep.c_str());
-        }
-    }
-    return c_strdup(path);
-}
-
-bool csync_rename_count(CSYNC *ctx) {
-    csync_rename_s* d = csync_rename_s::get(ctx);
-    return d->folder_renamed_from.size();
-}
-
-}
diff --git a/csync/src/csync_rename.h b/csync/src/csync_rename.h
deleted file mode 100644 (file)
index 5396832..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2012      by Olivier Goffart <ogoffart@woboq.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#pragma once
-
-#include "csync.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Return the final destination path of a given patch in case of renames */
-char OCSYNC_EXPORT *csync_rename_adjust_path(CSYNC *ctx, const char *path);
-/* Return the source of a given path in case of renames */
-char OCSYNC_EXPORT *csync_rename_adjust_path_source(CSYNC *ctx, const char *path);
-void OCSYNC_EXPORT csync_rename_destroy(CSYNC *ctx);
-void OCSYNC_EXPORT csync_rename_record(CSYNC *ctx, const char *from, const char *to);
-/*  Return the amount of renamed item recorded */
-bool OCSYNC_EXPORT csync_rename_count(CSYNC *ctx);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/csync/src/csync_statedb.c b/csync/src/csync_statedb.c
deleted file mode 100644 (file)
index 056ca48..0000000
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <sqlite3.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <inttypes.h>
-
-#include "c_lib.h"
-#include "csync_private.h"
-#include "csync_statedb.h"
-#include "csync_util.h"
-#include "csync_misc.h"
-#include "csync_exclude.h"
-
-#include "c_string.h"
-#include "c_jhash.h"
-#include "csync_time.h"
-
-#define CSYNC_LOG_CATEGORY_NAME "csync.statedb"
-#include "csync_log.h"
-#include "csync_rename.h"
-
-#define BUF_SIZE 16
-
-#define sqlite_open(A, B) sqlite3_open_v2(A,B, SQLITE_OPEN_READONLY+SQLITE_OPEN_NOMUTEX, NULL)
-
-#define SQLTM_TIME 150
-#define SQLTM_COUNT 10
-
-#define SQLITE_BUSY_HANDLED(F) if(1) { \
-    int n = 0; \
-    do { rc = F ; \
-      if( (rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED) ) { \
-         n++; \
-         csync_sleep(SQLTM_TIME); \
-      } \
-    }while( (n < SQLTM_COUNT) && ((rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED))); \
-  }
-
-
-void csync_set_statedb_exists(CSYNC *ctx, int val) {
-  ctx->statedb.exists = val;
-}
-
-int csync_get_statedb_exists(CSYNC *ctx) {
-  return ctx->statedb.exists;
-}
-
-static int _csync_check_db_integrity(sqlite3 *db) {
-    c_strlist_t *result = NULL;
-    int rc = -1;
-
-    result = csync_statedb_query(db, "PRAGMA quick_check;");
-    if (result != NULL) {
-        /* There is  a result */
-        if (result->count > 0) {
-            if (c_streq(result->vector[0], "ok")) {
-                rc = 0;
-            }
-        }
-        c_strlist_destroy(result);
-    }
-
-    if( sqlite3_threadsafe() == 0 ) {
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "* WARNING: SQLite module is not threadsafe!");
-        rc = -1;
-    }
-
-    return rc;
-}
-
-static int _csync_statedb_is_empty(sqlite3 *db) {
-  c_strlist_t *result = NULL;
-  int rc = 0;
-
-  result = csync_statedb_query(db, "SELECT COUNT(phash) FROM metadata LIMIT 1 OFFSET 0;");
-  if (result == NULL) {
-    rc = 1;
-  }
-  c_strlist_destroy(result);
-
-  return rc;
-}
-
-#ifndef NDEBUG
-static void sqlite_profile( void *x, const char* sql, sqlite3_uint64 time)
-{
-    (void)x;
-    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
-              "_SQL_ %s: %llu", sql, time);
-
-}
-#endif
-
-int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb) {
-  int rc = -1;
-  c_strlist_t *result = NULL;
-  sqlite3 *db = NULL;
-
-  if( !ctx ) {
-      return -1;
-  }
-
-  if (ctx->statedb.db) {
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: DB already open");
-      ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
-      return -1;
-  }
-
-  ctx->statedb.lastReturnValue = SQLITE_OK;
-
-  /* Openthe database */
-  if (sqlite_open(statedb, &db) != SQLITE_OK) {
-    const char *errmsg= sqlite3_errmsg(ctx->statedb.db);
-    CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: Failed to sqlite3 open statedb - bail out: %s.",
-              errmsg ? errmsg : "<no sqlite3 errormsg>");
-
-    rc = -1;
-    ctx->status_code = CSYNC_STATUS_STATEDB_LOAD_ERROR;
-    goto out;
-  }
-
-  if (_csync_check_db_integrity(db) != 0) {
-      const char *errmsg= sqlite3_errmsg(db);
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: sqlite3 integrity check failed - bail out: %s.",
-                errmsg ? errmsg : "<no sqlite3 errormsg>");
-      rc = -1;
-      ctx->status_code = CSYNC_STATUS_STATEDB_CORRUPTED;
-      goto out;
-  }
-
-  if (_csync_statedb_is_empty(db)) {
-    CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "statedb contents doesn't exist");
-    csync_set_statedb_exists(ctx, 0);
-  } else {
-    csync_set_statedb_exists(ctx, 1);
-  }
-
-  /* Print out the version */
-  //
-  result = csync_statedb_query(db, "SELECT sqlite_version();");
-  if (result && result->count >= 1) {
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "sqlite3 version \"%s\"", *result->vector);
-  }
-  c_strlist_destroy(result);
-
-  /* optimization for speeding up SQLite */
-  result = csync_statedb_query(db, "PRAGMA synchronous = NORMAL;");
-  c_strlist_destroy(result);
-  result = csync_statedb_query(db, "PRAGMA case_sensitive_like = ON;");
-  c_strlist_destroy(result);
-
-  /* set a busy handler with 5 seconds timeout */
-  sqlite3_busy_timeout(db, 5000);
-
-#ifndef NDEBUG
-  sqlite3_profile(db, sqlite_profile, 0 );
-#endif
-  *pdb = db;
-
-  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Success");
-
-  return 0;
-out:
-  sqlite3_close(db);
-  return rc;
-}
-
-int csync_statedb_close(CSYNC *ctx) {
-  int rc = 0;
-
-  if (!ctx) {
-      return -1;
-  }
-
-  /* deallocate query resources */
-  if( ctx->statedb.by_fileid_stmt ) {
-      sqlite3_finalize(ctx->statedb.by_fileid_stmt);
-      ctx->statedb.by_fileid_stmt = NULL;
-  }
-  if( ctx->statedb.by_hash_stmt ) {
-      sqlite3_finalize(ctx->statedb.by_hash_stmt);
-      ctx->statedb.by_hash_stmt = NULL;
-  }
-  if( ctx->statedb.by_inode_stmt) {
-      sqlite3_finalize(ctx->statedb.by_inode_stmt);
-      ctx->statedb.by_inode_stmt = NULL;
-  }
-
-  ctx->statedb.lastReturnValue = SQLITE_OK;
-
-  int sr = sqlite3_close(ctx->statedb.db);
-  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "sqlite3_close=%d", sr);
-
-  ctx->statedb.db = 0;
-
-  return rc;
-}
-
-#define METADATA_QUERY                                                                      \
-    "phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, " \
-    "filesize, ignoredChildrenRemote, "                                                     \
-    "contentchecksumtype.name || ':' || contentChecksum "                                   \
-    "FROM metadata "                                                                        \
-    "LEFT JOIN checksumtype as contentchecksumtype ON metadata.contentChecksumTypeId == contentchecksumtype.id"
-
-// This funciton parses a line from the metadata table into the given csync_file_stat
-// structure which it is also allocating.
-// Note that this function calls laso sqlite3_step to actually get the info from db and
-// returns the sqlite return type.
-static int _csync_file_stat_from_metadata_table( csync_file_stat_t **st, sqlite3_stmt *stmt )
-{
-    int rc = SQLITE_ERROR;
-    int column_count;
-    int len;
-
-    if( ! stmt ) {
-       CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Fatal: Statement is NULL.");
-       return SQLITE_ERROR;
-    }
-
-    column_count = sqlite3_column_count(stmt);
-
-    SQLITE_BUSY_HANDLED( sqlite3_step(stmt) );
-
-    if( rc == SQLITE_ROW ) {
-        if(column_count > 7) {
-            const char *name;
-
-            /* phash, pathlen, path, inode, uid, gid, mode, modtime */
-            len = sqlite3_column_int(stmt, 1);
-            *st = c_malloc(sizeof(csync_file_stat_t) + len + 1);
-            /* clear the whole structure */
-            ZERO_STRUCTP(*st);
-
-            /* The query suceeded so use the phash we pass to the function. */
-            (*st)->phash = sqlite3_column_int64(stmt, 0);
-
-            (*st)->pathlen = sqlite3_column_int(stmt, 1);
-            name = (const char*) sqlite3_column_text(stmt, 2);
-            memcpy((*st)->path, (len ? name : ""), len + 1);
-            (*st)->inode = sqlite3_column_int64(stmt,3);
-            (*st)->mode = sqlite3_column_int(stmt, 6);
-            (*st)->modtime = strtoul((char*)sqlite3_column_text(stmt, 7), NULL, 10);
-
-            if(*st && column_count > 8 ) {
-                (*st)->type = sqlite3_column_int(stmt, 8);
-            }
-
-            if(column_count > 9 && sqlite3_column_text(stmt, 9)) {
-                (*st)->etag = c_strdup( (char*) sqlite3_column_text(stmt, 9) );
-            }
-            if(column_count > 10 && sqlite3_column_text(stmt,10)) {
-                csync_vio_set_file_id((*st)->file_id, (char*) sqlite3_column_text(stmt, 10));
-            }
-            if(column_count > 11 && sqlite3_column_text(stmt,11)) {
-                strncpy((*st)->remotePerm,
-                        (char*) sqlite3_column_text(stmt, 11),
-                        REMOTE_PERM_BUF_SIZE);
-            }
-            if(column_count > 12 && sqlite3_column_int64(stmt,12)) {
-                (*st)->size = sqlite3_column_int64(stmt, 12);
-            }
-            if(column_count > 13) {
-                (*st)->has_ignored_files = sqlite3_column_int(stmt, 13);
-            }
-            if (column_count > 14 && sqlite3_column_text(stmt, 14)) {
-                (*st)->checksumHeader = c_strdup((char *)sqlite3_column_text(stmt, 14));
-            }
-
-        }
-    } else {
-        if( rc != SQLITE_DONE ) {
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Query results in %d", rc);
-        }
-    }
-    return rc;
-}
-
-/* caller must free the memory */
-csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx,
-                                                  uint64_t phash)
-{
-  csync_file_stat_t *st = NULL;
-  int rc;
-
-  if( !ctx || ctx->db_is_empty ) {
-      return NULL;
-  }
-
-  if( ctx->statedb.by_hash_stmt == NULL ) {
-      const char *hash_query = "SELECT " METADATA_QUERY " WHERE phash=?1";
-
-      SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, hash_query, strlen(hash_query), &ctx->statedb.by_hash_stmt, NULL));
-      ctx->statedb.lastReturnValue = rc;
-      if( rc != SQLITE_OK ) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for hash query.");
-          return NULL;
-      }
-  }
-
-  if( ctx->statedb.by_hash_stmt == NULL ) {
-    return NULL;
-  }
-
-  sqlite3_bind_int64(ctx->statedb.by_hash_stmt, 1, (long long signed int)phash);
-
-  rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_hash_stmt);
-  ctx->statedb.lastReturnValue = rc;
-  if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) )  {
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata: %d!", rc);
-  }
-  sqlite3_reset(ctx->statedb.by_hash_stmt);
-
-  return st;
-}
-
-csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx,
-                                                      const char *file_id ) {
-    csync_file_stat_t *st = NULL;
-    int rc = 0;
-
-    if (!file_id) {
-        return 0;
-    }
-    if (c_streq(file_id, "")) {
-        return 0;
-    }
-
-    if( !ctx || ctx->db_is_empty ) {
-        return NULL;
-    }
-
-    if( ctx->statedb.by_fileid_stmt == NULL ) {
-        const char *query = "SELECT " METADATA_QUERY " WHERE fileid=?1";
-
-        SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, query, strlen(query), &ctx->statedb.by_fileid_stmt, NULL));
-        ctx->statedb.lastReturnValue = rc;
-        if( rc != SQLITE_OK ) {
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for file id query.");
-            return NULL;
-        }
-    }
-
-    /* bind the query value */
-    sqlite3_bind_text(ctx->statedb.by_fileid_stmt, 1, file_id, -1, SQLITE_STATIC);
-
-    rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_fileid_stmt);
-    ctx->statedb.lastReturnValue = rc;
-    if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) ) {
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata: %d!", rc);
-    }
-    // clear the resources used by the statement.
-    sqlite3_reset(ctx->statedb.by_fileid_stmt);
-
-    return st;
-}
-
-/* caller must free the memory */
-csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx,
-                                                  uint64_t inode)
-{
-  csync_file_stat_t *st = NULL;
-  int rc;
-
-  if (!inode) {
-      return NULL;
-  }
-
-  if( !ctx || ctx->db_is_empty ) {
-      return NULL;
-  }
-
-  if( ctx->statedb.by_inode_stmt == NULL ) {
-      const char *inode_query = "SELECT " METADATA_QUERY " WHERE inode=?1";
-
-      SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, inode_query, strlen(inode_query), &ctx->statedb.by_inode_stmt, NULL));
-      ctx->statedb.lastReturnValue = rc;
-      if( rc != SQLITE_OK ) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for inode query.");
-          return NULL;
-      }
-  }
-
-  if( ctx->statedb.by_inode_stmt == NULL ) {
-    return NULL;
-  }
-
-  sqlite3_bind_int64(ctx->statedb.by_inode_stmt, 1, (long long signed int)inode);
-
-  rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_inode_stmt);
-  ctx->statedb.lastReturnValue = rc;
-  if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) ) {
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata by inode: %d!", rc);
-  }
-  sqlite3_reset(ctx->statedb.by_inode_stmt);
-
-  return st;
-}
-
-int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
-    int rc;
-    sqlite3_stmt *stmt = NULL;
-    int64_t cnt = 0;
-
-    if( !path ) {
-        return -1;
-    }
-
-    if( !ctx || ctx->db_is_empty ) {
-        return -1;
-    }
-
-    /*  Select the entries for anything that starts with  (path+'/')
-     * In other words, anything that is between  path+'/' and path+'0',
-     * (because '0' follows '/' in ascii)
-     */
-    const char *below_path_query = "SELECT " METADATA_QUERY " WHERE path > (?||'/') AND path < (?||'0') ORDER BY path||'/' ASC";
-    SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, below_path_query, -1, &stmt, NULL));
-    ctx->statedb.lastReturnValue = rc;
-    if( rc != SQLITE_OK ) {
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for below path query.");
-      return -1;
-    }
-
-    if (stmt == NULL) {
-      return -1;
-    }
-
-    sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
-    sqlite3_bind_text(stmt, 2, path, -1, SQLITE_STATIC);
-
-    cnt = 0;
-
-    ctx->statedb.lastReturnValue = rc;
-    do {
-        csync_file_stat_t *st = NULL;
-
-        rc = _csync_file_stat_from_metadata_table( &st, stmt);
-        if( st ) {
-            /* When selective sync is used, the database may have subtrees with a parent
-             * whose etag (md5) is _invalid_. These are ignored and shall not appear in the
-             * remote tree.
-             * Sometimes folders that are not ignored by selective sync get marked as
-             * _invalid_, but that is not a problem as the next discovery will retrieve
-             * their correct etags again and we don't run into this case.
-             */
-            if( c_streq(st->etag, "_invalid_") ) {
-                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s selective sync excluded", st->path);
-                char *skipbase = c_strdup(st->path);
-                skipbase[st->pathlen] = '/';
-                int skiplen = st->pathlen + 1;
-
-                /* Skip over all entries with the same base path. Note that this depends
-                 * strongly on the ordering of the retrieved items. */
-                do {
-                    csync_file_stat_free(st);
-                    rc = _csync_file_stat_from_metadata_table( &st, stmt);
-                    if( st && strncmp(st->path, skipbase, skiplen) != 0 ) {
-                        break;
-                    }
-                    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s selective sync excluded because the parent is", st->path);
-                } while( rc == SQLITE_ROW );
-
-                /* End of data? */
-                if( rc != SQLITE_ROW || !st ) {
-                    continue;
-                }
-            }
-
-            /* Check for exclusion from the tree.
-             * Note that this is only a safety net in case the ignore list changes
-             * without a full remote discovery being triggered. */
-            CSYNC_EXCLUDE_TYPE excluded = csync_excluded_traversal(ctx->excludes, st->path, st->type);
-            if (excluded != CSYNC_NOT_EXCLUDED) {
-                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", st->path, excluded);
-
-                if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE
-                        || excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
-                    csync_file_stat_free(st);
-                    continue;
-                }
-
-                st->instruction = CSYNC_INSTRUCTION_IGNORE;
-            }
-
-            /* store into result list. */
-            if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
-                csync_file_stat_free(st);
-                ctx->status_code = CSYNC_STATUS_TREE_ERROR;
-                break;
-            }
-            cnt++;
-        }
-    } while( rc == SQLITE_ROW );
-
-    ctx->statedb.lastReturnValue = rc;
-    if( rc != SQLITE_DONE ) {
-        ctx->status_code = CSYNC_STATUS_TREE_ERROR;
-    } else {
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "%" PRId64 " entries read below path %s from db.", cnt, path);
-    }
-    sqlite3_finalize(stmt);
-
-    return 0;
-}
-
-/* query the statedb, caller must free the memory */
-c_strlist_t *csync_statedb_query(sqlite3 *db,
-                                 const char *statement) {
-  int err = SQLITE_OK;
-  int rc = SQLITE_OK;
-  size_t i = 0;
-  size_t busy_count = 0;
-  size_t retry_count = 0;
-  size_t column_count = 0;
-  sqlite3_stmt *stmt;
-  const char *tail = NULL;
-  const char *field = NULL;
-  c_strlist_t *result = NULL;
-  int row = 0;
-
-  do {
-    /* compile SQL program into a virtual machine, reattempteing if busy */
-    do {
-      if (busy_count) {
-        csync_sleep(100);
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "sqlite3_prepare: BUSY counter: %zu", busy_count);
-      }
-      err = sqlite3_prepare(db, statement, -1, &stmt, &tail);
-    } while (err == SQLITE_BUSY && busy_count ++ < 120);
-
-    if (err != SQLITE_OK) {
-      if (err == SQLITE_BUSY) {
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Gave up waiting for lock to clear");
-      }
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN,
-                "sqlite3_compile error: %s - on query %s",
-                sqlite3_errmsg(db), statement);
-      break;
-    } else {
-      busy_count = 0;
-      column_count = sqlite3_column_count(stmt);
-
-      /* execute virtual machine by iterating over rows */
-      for(;;) {
-        err = sqlite3_step(stmt);
-
-        if (err == SQLITE_BUSY) {
-          if (busy_count++ > 120) {
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Busy counter has reached its maximum. Aborting this sql statement");
-            break;
-          }
-          csync_sleep(100);
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "sqlite3_step: BUSY counter: %zu", busy_count);
-          continue;
-        }
-
-        if (err == SQLITE_MISUSE) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "sqlite3_step: MISUSE!!");
-        }
-
-        if (err == SQLITE_DONE) {
-          if (result == NULL) {
-            result = c_strlist_new(1);
-          }
-          break;
-        }
-
-        if (err == SQLITE_ERROR) {
-          break;
-        }
-
-       row++;
-        if( result ) {
-            result = c_strlist_expand(result, row*column_count);
-        } else {
-            result = c_strlist_new(column_count);
-        }
-
-        if (result == NULL) {
-          return NULL;
-        }
-
-        /* iterate over columns */
-        for (i = 0; i < column_count; i++) {
-          field = (const char *) sqlite3_column_text(stmt, i);
-          if (!field)
-              field = "";
-          // CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "sqlite3_column_text: %s", field);
-          if (c_strlist_add(result, field) < 0) {
-            c_strlist_destroy(result);
-            return NULL;
-          }
-        }
-      } /* end infinite for loop */
-
-      /* deallocate vm resources */
-      rc = sqlite3_finalize(stmt);
-
-      if (err != SQLITE_DONE && rc != SQLITE_SCHEMA) {
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "sqlite_step error: %s - on query: %s", sqlite3_errmsg(db), statement);
-        if (result != NULL) {
-          c_strlist_destroy(result);
-        }
-        return NULL;
-      }
-
-      if (rc == SQLITE_SCHEMA) {
-        retry_count ++;
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "SQLITE_SCHEMA error occurred on query: %s", statement);
-        if (retry_count < 10) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Retrying now.");
-        } else {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "RETRY count has reached its maximum. Aborting statement: %s", statement);
-          if (result != NULL) {
-            c_strlist_destroy(result);
-          }
-          result = c_strlist_new(1);
-        }
-      }
-    }
-  } while (rc == SQLITE_SCHEMA && retry_count < 10);
-
-  return result;
-}
-
-/* vim: set ts=8 sw=2 et cindent: */
diff --git a/csync/src/csync_statedb.h b/csync/src/csync_statedb.h
deleted file mode 100644 (file)
index 601e34a..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file csync_private.h
- *
- * @brief Private interface of csync
- *
- * @defgroup csyncstatedbInternals csync statedb internals
- * @ingroup csyncInternalAPI
- *
- * @{
- */
-
-#ifndef _CSYNC_STATEDB_H
-#define _CSYNC_STATEDB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "c_lib.h"
-#include "csync_private.h"
-
-void csync_set_statedb_exists(CSYNC *ctx, int val);
-
-int csync_get_statedb_exists(CSYNC *ctx);
-
-/**
- * @brief Load the statedb.
- *
- * This function tries to load the statedb. If it doesn't exists it creates
- * the sqlite3 database, but doesn't create the tables. This will be done when
- * csync gets destroyed.
- *
- * @param ctx      The csync context.
- * @param statedb  Path to the statedb file (sqlite3 db).
- *
- * @return 0 on success, less than 0 if an error occurred with errno set.
- */
-OCSYNC_EXPORT int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb);
-
-OCSYNC_EXPORT int csync_statedb_close(CSYNC *ctx);
-
-OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx, uint64_t phash);
-
-OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, uint64_t inode);
-
-OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *file_id);
-
-/**
- * @brief Query all files metadata inside and below a path.
- * @param ctx        The csync context.
- * @param path       The path.
- *
- * This function queries all metadata of all files inside or below the
- * given path. The result is a linear string list with a multiple of 9
- * entries. For each result file there are 9 strings which are phash,
- * path, inode, uid, gid, mode, modtime, type and md5 (unique id).
- *
- * Note that not only the files in the given path are part of the result
- * but also the files in directories below the given path. Ie. if the
- * parameter path is /home/kf/test, we have /home/kf/test/file.txt in
- * the result but also /home/kf/test/homework/another_file.txt
- *
- * @return   A stringlist containing a multiple of 9 entries.
- */
-int csync_statedb_get_below_path(CSYNC *ctx, const char *path);
-
-/**
- * @brief A generic statedb query.
- *
- * @param ctx        The csync context.
- * @param statement  The SQL statement to execute
- * 
- * @return   A stringlist of the entries of a column. An emtpy stringlist if
- *           nothing has been found. NULL on error.
- */
-c_strlist_t *csync_statedb_query(sqlite3 *db, const char *statement);
-
-#ifdef __cplusplus
-}
-#endif
-
-/**
- * }@
- */
-#endif /* _CSYNC_STATEDB_H */
-/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/csync/src/csync_time.c b/csync/src/csync_time.c
deleted file mode 100644 (file)
index 85bdd5f..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <errno.h>
-#include <stdio.h>
-#include <time.h>
-
-#include "csync_time.h"
-#include "vio/csync_vio.h"
-
-#ifndef _WIN32
-#include <unistd.h>
-#include <sys/time.h>
-#endif
-
-#define CSYNC_LOG_CATEGORY_NAME "csync.time"
-#include "csync_log.h"
-
-#ifdef HAVE_CLOCK_GETTIME
-# ifdef _POSIX_MONOTONIC_CLOCK
-#  define CSYNC_CLOCK CLOCK_MONOTONIC
-# else
-#  define CSYNC_CLOCK CLOCK_REALTIME
-# endif
-#endif
-
-
-int csync_gettime(struct timespec *tp)
-{
-#if defined(_WIN32)
-       __int64 wintime;
-       GetSystemTimeAsFileTime((FILETIME*)&wintime);
-       wintime -= 116444736000000000ll;  //1jan1601 to 1jan1970
-       tp->tv_sec = wintime / 10000000ll;           //seconds
-       tp->tv_nsec = wintime % 10000000ll * 100;      //nano-seconds
-#elif defined(HAVE_CLOCK_GETTIME)
-       return clock_gettime(CSYNC_CLOCK, tp);
-#else
-       struct timeval tv;
-
-       if (gettimeofday(&tv, NULL) < 0) {
-               return -1;
-       }
-
-       tp->tv_sec = tv.tv_sec;
-       tp->tv_nsec = tv.tv_usec * 1000;
-#endif
-       return 0;
-}
-
-#undef CSYNC_CLOCK
-
-void csync_sleep(unsigned int msecs)
-{
-#if defined(_WIN32)
-       Sleep(msecs);
-#else
-    usleep(msecs * 1000);
-#endif
-}
diff --git a/csync/src/csync_time.h b/csync/src/csync_time.h
deleted file mode 100644 (file)
index 1492bef..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _CSYNC_TIME_H
-#define _CSYNC_TIME_H
-
-#include <time.h>
-
-#include "csync_private.h"
-
-int csync_gettime(struct timespec *tp);
-void csync_sleep(unsigned int msecs);
-
-#endif /* _CSYNC_TIME_H */
diff --git a/csync/src/csync_update.c b/csync/src/csync_update.c
deleted file mode 100644 (file)
index 1a06944..0000000
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <time.h>
-#include <math.h>
-
-#include "c_lib.h"
-#include "c_jhash.h"
-
-#include "csync_private.h"
-#include "csync_exclude.h"
-#include "csync_statedb.h"
-#include "csync_update.h"
-#include "csync_util.h"
-#include "csync_misc.h"
-
-#include "vio/csync_vio.h"
-
-#define CSYNC_LOG_CATEGORY_NAME "csync.updater"
-#include "csync_log.h"
-#include "csync_rename.h"
-
-/* calculate the hash of a given uri */
-static uint64_t _hash_of_file(CSYNC *ctx, const char *file) {
-  const char *path;
-  int len;
-  uint64_t h = 0;
-
-  if( ctx && file ) {
-    path = file;
-    if (ctx->current == LOCAL_REPLICA) {
-      if (strlen(path) <= strlen(ctx->local.uri)) {
-        return 0;
-      }
-      path += strlen(ctx->local.uri) + 1;
-    }
-    len = strlen(path);
-    h = c_jhash64((uint8_t *) path, len, 0);
-  }
-  return h;
-}
-
-#ifdef NO_RENAME_EXTENSION
-/* Return true if the two path have the same extension. false otherwise. */
-static bool _csync_sameextension(const char *p1, const char *p2) {
-    /* Find pointer to the extensions */
-    const char *e1 = strrchr(p1, '.');
-    const char *e2 = strrchr(p2, '.');
-
-    /* If the found extension contains a '/', it is because the . was in the folder name
-     *            => no extensions */
-    if (e1 && strchr(e1, '/')) e1 = NULL;
-    if (e2 && strchr(e2, '/')) e2 = NULL;
-
-    /* If none have extension, it is the same extension */
-    if (!e1 && !e2)
-        return true;
-
-    /* c_streq takes care of the rest */
-    return c_streq(e1, e2);
-}
-#endif
-
-static bool _last_db_return_error(CSYNC* ctx) {
-    return ctx->statedb.lastReturnValue != SQLITE_OK && ctx->statedb.lastReturnValue != SQLITE_DONE && ctx->statedb.lastReturnValue != SQLITE_ROW;
-}
-
-/*
- * This static method is needed because the type members of the two structs use
- * different enum values. A direct comparion is not neccessarily correct.
- *
- * tmp is csync_file_stat_t
- * fs  is csync_vio_file_stat_t with this vio type:
- *  enum csync_vio_file_type_e {
- *              CSYNC_VIO_FILE_TYPE_UNKNOWN,
- *              CSYNC_VIO_FILE_TYPE_REGULAR,
- *              CSYNC_VIO_FILE_TYPE_DIRECTORY,
- *              CSYNC_VIO_FILE_TYPE_FIFO,
- *              CSYNC_VIO_FILE_TYPE_SOCKET,
- *              CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE,
- *              CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE,
- *              CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK
- *            };
- *
- * csync_file_stat_t can be:
- * CSYNC_FTW_TYPE_SKIP, CSYNC_FTW_TYPE_FILE
- * CSYNC_FTW_TYPE_DIR, CSYNC_FTW_TYPE_SLINK
- */
-static bool _csync_filetype_different( const csync_file_stat_t *tmp, const csync_vio_file_stat_t *fs)
-{
-    if( !(tmp && fs)) return false;
-
-    if( tmp->type == CSYNC_FTW_TYPE_SKIP ) return true;
-
-    if( tmp->type == CSYNC_FTW_TYPE_DIR && fs->type != CSYNC_VIO_FILE_TYPE_DIRECTORY )
-        return true;
-    if( tmp->type == CSYNC_FTW_TYPE_FILE && fs->type != CSYNC_VIO_FILE_TYPE_REGULAR )
-        return true;
-    if( tmp->type == CSYNC_FTW_TYPE_SLINK && fs->type != CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK )
-        return true;
-
-    return false; // both are NOT different.
-}
-
-/* Return true if two mtime are considered equal
- * We consider mtime that are one hour difference to be equal if they are one hour appart
- * because on some system (FAT) the date is changing when the daylight saving is changing */
-static bool _csync_mtime_equal(time_t a, time_t b)
-{
-    if (a == b)
-        return true;
-
-    /* 1h of difference +- 1 second because the accuracy of FAT is 2 seconds (#2438) */
-    if (fabs(3600 - fabs(difftime(a, b))) < 2)
-        return true;
-
-    return false;
-}
-
-/**
- * The main function of the discovery/update pass.
- *
- * It's called (indirectly) by csync_update(), once for each entity in the
- * local filesystem and once for each entity in the server data.
- *
- * It has two main jobs:
- * - figure out whether anything happened compared to the sync journal
- *   and set (primarily) the instruction flag accordingly
- * - build the ctx->local.tree / ctx->remote.tree
- *
- * See doc/dev/sync-algorithm.md for an overview.
- */
-static int _csync_detect_update(CSYNC *ctx, const char *file,
-    const csync_vio_file_stat_t *fs, const int type) {
-  uint64_t h = 0;
-  size_t len = 0;
-  size_t size = 0;
-  const char *path = NULL;
-  csync_file_stat_t *st = NULL;
-  csync_file_stat_t *tmp = NULL;
-  CSYNC_EXCLUDE_TYPE excluded;
-
-  if ((file == NULL) || (fs == NULL)) {
-    errno = EINVAL;
-    ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
-    return -1;
-  }
-
-  path = file;
-  if (ctx->current == LOCAL_REPLICA) {
-      if (strlen(path) <= strlen(ctx->local.uri)) {
-        ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
-        return -1;
-      }
-      path += strlen(ctx->local.uri) + 1;
-  }
-
-  len = strlen(path);
-
-  if (type == CSYNC_FTW_TYPE_SKIP) {
-      excluded =CSYNC_FILE_EXCLUDE_STAT_FAILED;
-  } else {
-    /* Check if file is excluded */
-    excluded = csync_excluded_traversal(ctx->excludes, path, type);
-  }
-
-  if( excluded == CSYNC_NOT_EXCLUDED ) {
-      /* Even if it is not excluded by a pattern, maybe it is to be ignored
-       * because it's a hidden file that should not be synced.
-       * This code should probably be in csync_exclude, but it does not have the fs parameter.
-       * Keep it here for now */
-      if (ctx->ignore_hidden_files && (fs->flags & CSYNC_VIO_FILE_FLAGS_HIDDEN)) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file excluded because it is a hidden file: %s", path);
-          excluded = CSYNC_FILE_EXCLUDE_HIDDEN;
-      }
-  } else {
-      /* File is ignored because it's matched by a user- or system exclude pattern. */
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded  (%d)", path, excluded);
-      if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) {
-          return 1;
-      }
-      if (excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
-          return 1;
-      }
-  }
-
-  if (ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncBlackListHook) {
-      if (ctx->callbacks.checkSelectiveSyncBlackListHook(ctx->callbacks.update_callback_userdata, path)) {
-          return 1;
-      }
-  }
-
-  h = _hash_of_file(ctx, file );
-  if( h == 0 ) {
-    return -1;
-  }
-  size = sizeof(csync_file_stat_t) + len + 1;
-
-  st = c_malloc(size);
-
-  /* Set instruction by default to none */
-  st->instruction = CSYNC_INSTRUCTION_NONE;
-  st->etag = NULL;
-  st->child_modified = 0;
-  st->has_ignored_files = 0;
-  if (type == CSYNC_FTW_TYPE_FILE ) {
-    if (fs->mtime == 0) {
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - mtime is zero!", path);
-    }
-  }
-
-  if (excluded > CSYNC_NOT_EXCLUDED || type == CSYNC_FTW_TYPE_SLINK) {
-      st->instruction = CSYNC_INSTRUCTION_IGNORE;
-      if (ctx->current_fs) {
-          ctx->current_fs->has_ignored_files = true;
-      }
-
-      goto out;
-  }
-
-  /* Update detection: Check if a database entry exists.
-   * If not, the file is either new or has been renamed. To see if it is
-   * renamed, the db gets queried by the inode of the file as that one
-   * does not change on rename.
-   */
-  if (csync_get_statedb_exists(ctx)) {
-    tmp = csync_statedb_get_stat_by_hash(ctx, h);
-
-    if(_last_db_return_error(ctx)) {
-        csync_file_stat_free(st);
-        csync_file_stat_free(tmp);
-        ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
-        return -1;
-    }
-
-    if(tmp && tmp->phash == h ) { /* there is an entry in the database */
-        /* we have an update! */
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Database entry found, compare: %" PRId64 " <-> %" PRId64
-                                            ", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64
-                                            ", size: %" PRId64 " <-> %" PRId64 ", perms: %s <-> %s, ignore: %d",
-                  ((int64_t) fs->mtime), ((int64_t) tmp->modtime),
-                  fs->etag, tmp->etag, (uint64_t) fs->inode, (uint64_t) tmp->inode,
-                  (uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm, tmp->remotePerm, tmp->has_ignored_files );
-        if (ctx->current == REMOTE_REPLICA && !c_streq(fs->etag, tmp->etag)) {
-            st->instruction = CSYNC_INSTRUCTION_EVAL;
-
-            // Preserve the EVAL flag later on if the type has changed.
-            if (_csync_filetype_different(tmp, fs)) {
-                st->child_modified = 1;
-            }
-
-            goto out;
-        }
-        if (ctx->current == LOCAL_REPLICA &&
-                (!_csync_mtime_equal(fs->mtime, tmp->modtime)
-                 // zero size in statedb can happen during migration
-                 || (tmp->size != 0 && fs->size != tmp->size))) {
-
-            // Checksum comparison at this stage is only enabled for .eml files,
-            // check #4754 #4755
-            bool isEmlFile = csync_fnmatch("*.eml", file, FNM_CASEFOLD) == 0;
-            if (isEmlFile && fs->size == tmp->size && tmp->checksumHeader) {
-                if (ctx->callbacks.checksum_hook) {
-                    st->checksumHeader = ctx->callbacks.checksum_hook(
-                        file, tmp->checksumHeader,
-                        ctx->callbacks.checksum_userdata);
-                }
-                bool checksumIdentical = false;
-                if (st->checksumHeader) {
-                    checksumIdentical = strncmp(st->checksumHeader, tmp->checksumHeader, 1000) == 0;
-                }
-                if (checksumIdentical) {
-                    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "NOTE: Checksums are identical, file did not actually change: %s", path);
-                    st->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
-                    goto out;
-                }
-            }
-
-            // Preserve the EVAL flag later on if the type has changed.
-            if (_csync_filetype_different(tmp, fs)) {
-                st->child_modified = 1;
-            }
-
-            st->instruction = CSYNC_INSTRUCTION_EVAL;
-            goto out;
-        }
-        bool metadata_differ = (ctx->current == REMOTE_REPLICA && (!c_streq(fs->file_id, tmp->file_id)
-                                                            || !c_streq(fs->remotePerm, tmp->remotePerm)))
-                             || (ctx->current == LOCAL_REPLICA && fs->inode != tmp->inode);
-        if (type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA
-                && !metadata_differ && ctx->read_remote_from_db) {
-            /* If both etag and file id are equal for a directory, read all contents from
-             * the database.
-             * The metadata comparison ensure that we fetch all the file id or permission when
-             * upgrading owncloud
-             */
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Reading from database: %s", path);
-            ctx->remote.read_from_db = true;
-        }
-        /* If it was remembered in the db that the remote dir has ignored files, store
-         * that so that the reconciler can make advantage of.
-         */
-        if( ctx->current == REMOTE_REPLICA ) {
-            st->has_ignored_files = tmp->has_ignored_files;
-        }
-        if (metadata_differ) {
-            /* file id or permissions has changed. Which means we need to update them in the DB. */
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Need to update metadata for: %s", path);
-            st->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
-        } else {
-            st->instruction = CSYNC_INSTRUCTION_NONE;
-        }
-    } else {
-        enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
-
-        /* tmp might point to malloc mem, so free it here before reusing tmp  */
-        csync_file_stat_free(tmp);
-
-        /* check if it's a file and has been renamed */
-        if (ctx->current == LOCAL_REPLICA) {
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
-
-            tmp = csync_statedb_get_stat_by_inode(ctx, fs->inode);
-
-            if(_last_db_return_error(ctx)) {
-                csync_file_stat_free(st);
-                ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
-                return -1;
-            }
-
-            /* translate the file type between the two stat types csync has. */
-            if( tmp && tmp->type == CSYNC_FTW_TYPE_FILE ) {
-                tmp_vio_type = CSYNC_VIO_FILE_TYPE_REGULAR;
-            } else if( tmp && tmp->type == CSYNC_FTW_TYPE_DIR) {
-                tmp_vio_type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
-            } else if( tmp && tmp->type == CSYNC_FTW_TYPE_SLINK ) {
-                tmp_vio_type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
-            } else {
-                tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
-            }
-
-            // Default to NEW unless we're sure it's a rename.
-            st->instruction = CSYNC_INSTRUCTION_NEW;
-
-            bool isRename =
-                tmp && tmp->inode == fs->inode && tmp_vio_type == fs->type
-                    && (tmp->modtime == fs->mtime || fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY)
-#ifdef NO_RENAME_EXTENSION
-                    && _csync_sameextension(tmp->path, path)
-#endif
-                ;
-
-
-            // Verify the checksum where possible
-            if (isRename && tmp->checksumHeader && ctx->callbacks.checksum_hook
-                && fs->type == CSYNC_VIO_FILE_TYPE_REGULAR) {
-                st->checksumHeader = ctx->callbacks.checksum_hook(
-                    file, tmp->checksumHeader,
-                    ctx->callbacks.checksum_userdata);
-                if (st->checksumHeader) {
-                    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "checking checksum of potential rename %s %s <-> %s", path, st->checksumHeader, tmp->checksumHeader);
-                    isRename = strncmp(st->checksumHeader, tmp->checksumHeader, 1000) == 0;
-                }
-            }
-
-            if (isRename) {
-                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
-                /* inode found so the file has been renamed */
-                st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
-                if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {
-                    csync_rename_record(ctx, tmp->path, path);
-                }
-            }
-            goto out;
-
-        } else {
-            /* Remote Replica Rename check */
-            tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id);
-
-            if(_last_db_return_error(ctx)) {
-                csync_file_stat_free(st);
-                ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
-                return -1;
-            }
-            if(tmp ) {                           /* tmp existing at all */
-                if ( _csync_filetype_different(tmp, fs)) {
-                    CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "file types different is not!");
-                    st->instruction = CSYNC_INSTRUCTION_NEW;
-                    goto out;
-                }
-                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "remote rename detected based on fileid %s %s", tmp->path, file);
-                st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
-                if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {
-                    csync_rename_record(ctx, tmp->path, path);
-                } else {
-                    if( !c_streq(tmp->etag, fs->etag) ) {
-                        /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "ETags are different!"); */
-                        /* File with different etag, don't do a rename, but download the file again */
-                        st->instruction = CSYNC_INSTRUCTION_NEW;
-                    }
-                }
-                goto out;
-
-            } else {
-                /* file not found in statedb */
-                st->instruction = CSYNC_INSTRUCTION_NEW;
-
-                if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) {
-                    if (ctx->callbacks.checkSelectiveSyncNewFolderHook(ctx->callbacks.update_callback_userdata, path, fs->remotePerm)) {
-                        csync_file_stat_free(st);
-                        return 1;
-                    }
-                }
-                goto out;
-            }
-        }
-    }
-  } else  {
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Unable to open statedb" );
-      csync_file_stat_free(st);
-      ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
-      return -1;
-  }
-
-out:
-
-  /* Set the ignored error string. */
-  if (st->instruction == CSYNC_INSTRUCTION_IGNORE) {
-      if( type == CSYNC_FTW_TYPE_SLINK ) {
-          st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK; /* Symbolic links are ignored. */
-      } else {
-          if (excluded == CSYNC_FILE_EXCLUDE_LIST) {
-              st->error_status = CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST; /* File listed on ignore list. */
-          } else if (excluded == CSYNC_FILE_EXCLUDE_INVALID_CHAR) {
-              st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS;  /* File contains invalid characters. */
-          } else if (excluded == CSYNC_FILE_EXCLUDE_TRAILING_SPACE) {
-              st->error_status = CSYNC_STATUS_INDIVIDUAL_TRAILING_SPACE; /* File ends with a trailing space. */
-          } else if (excluded == CSYNC_FILE_EXCLUDE_LONG_FILENAME) {
-              st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME; /* File name is too long. */
-          } else if (excluded == CSYNC_FILE_EXCLUDE_HIDDEN ) {
-              st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN;
-          } else if (excluded == CSYNC_FILE_EXCLUDE_STAT_FAILED) {
-              st->error_status = CSYNC_STATUS_INDIVIDUAL_STAT_FAILED;
-          } else if (excluded == CSYNC_FILE_EXCLUDE_CONFLICT) {
-              st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE;
-          }
-      }
-  }
-  if (st->instruction != CSYNC_INSTRUCTION_NONE
-      && st->instruction != CSYNC_INSTRUCTION_IGNORE
-      && st->instruction != CSYNC_INSTRUCTION_UPDATE_METADATA
-      && type != CSYNC_FTW_TYPE_DIR) {
-    st->child_modified = 1;
-  }
-  ctx->current_fs = st;
-
-  csync_file_stat_free(tmp);
-  st->inode = fs->inode;
-  st->mode  = fs->mode;
-  st->size  = fs->size;
-  st->modtime = fs->mtime;
-  st->type  = type;
-  st->etag   = NULL;
-  if( fs->etag ) {
-      SAFE_FREE(st->etag);
-      st->etag  = c_strdup(fs->etag);
-  }
-  csync_vio_set_file_id(st->file_id, fs->file_id);
-  if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADURL) {
-      SAFE_FREE(st->directDownloadUrl);
-      st->directDownloadUrl = c_strdup(fs->directDownloadUrl);
-  }
-  if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADCOOKIES) {
-      SAFE_FREE(st->directDownloadCookies);
-      st->directDownloadCookies = c_strdup(fs->directDownloadCookies);
-  }
-  if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_PERM) {
-      strncpy(st->remotePerm, fs->remotePerm, REMOTE_PERM_BUF_SIZE);
-  }
-
-  // For the remote: propagate the discovered checksum
-  if (fs->checksumHeader && ctx->current == REMOTE_REPLICA) {
-      st->checksumHeader = c_strdup(fs->checksumHeader);
-  }
-
-  st->phash = h;
-  st->pathlen = len;
-  memcpy(st->path, (len ? path : ""), len + 1);
-
-  switch (ctx->current) {
-    case LOCAL_REPLICA:
-      if (c_rbtree_insert(ctx->local.tree, (void *) st) < 0) {
-        csync_file_stat_free(st);
-        ctx->status_code = CSYNC_STATUS_TREE_ERROR;
-        return -1;
-      }
-      break;
-    case REMOTE_REPLICA:
-      if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
-        csync_file_stat_free(st);
-        ctx->status_code = CSYNC_STATUS_TREE_ERROR;
-        return -1;
-      }
-      break;
-    default:
-      break;
-  }
-  CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "file: %s, instruction: %s <<=", st->path,
-      csync_instruction_str(st->instruction));
-
-  return 0;
-}
-
-int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
-    enum csync_ftw_flags_e flag) {
-  int rc = -1;
-  int type = CSYNC_FTW_TYPE_SKIP;
-  csync_file_stat_t *st = NULL;
-  uint64_t h;
-
-  if (ctx->abort) {
-    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Aborted!");
-    ctx->status_code = CSYNC_STATUS_ABORTED;
-    return -1;
-  }
-
-  switch (flag) {
-    case CSYNC_FTW_FLAG_FILE:
-      if (ctx->current == REMOTE_REPLICA) {
-          if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE) {
-              CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=%" PRIu64 "]", file, fs->file_id, fs->size);
-          } else {
-              CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=UNKNOWN]", file, fs->file_id);
-          }
-      } else {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [inode=%" PRIu64 " size=%" PRIu64 "]", file, fs->inode, fs->size);
-      }
-      type = CSYNC_FTW_TYPE_FILE;
-      break;
-  case CSYNC_FTW_FLAG_DIR: /* enter directory */
-      if (ctx->current == REMOTE_REPLICA) {
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [file_id=%s]", file, fs->file_id);
-      } else {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [inode=%" PRIu64 "]", file, fs->inode);
-      }
-      type = CSYNC_FTW_TYPE_DIR;
-      break;
-  case CSYNC_FTW_FLAG_NSTAT: /* not statable file */
-    /* if file was here before and now is not longer stat-able, still
-     * add it to the db, otherwise not. */
-    h = _hash_of_file( ctx, file );
-    if( h == 0 ) {
-      return 0;
-    }
-    st = csync_statedb_get_stat_by_hash(ctx, h);
-    if( !st ) {
-      return 0;
-    }
-    csync_file_stat_free(st);
-    st = NULL;
-
-    type = CSYNC_FTW_TYPE_SKIP;
-    break;
-  case CSYNC_FTW_FLAG_SLINK:
-    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "symlink: %s - not supported", file);
-    type = CSYNC_FTW_TYPE_SLINK;
-    break;
-  case CSYNC_FTW_FLAG_DNR:
-  case CSYNC_FTW_FLAG_DP:
-  case CSYNC_FTW_FLAG_SLN:
-  default:
-    return 0;
-    break;
-  }
-
-  rc = _csync_detect_update(ctx, file, fs, type );
-
-  return rc;
-}
-
-static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
-{
-    if( csync_statedb_get_below_path(ctx, uri) < 0 ) {
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "StateDB could not be read!");
-        return false;
-    }
-
-    return true;
-}
-
-/* set the current item to an ignored state.
- * If the item is set to ignored, the update phase continues, ie. its not a hard error */
-static bool mark_current_item_ignored( CSYNC *ctx, csync_file_stat_t *previous_fs, CSYNC_STATUS status )
-{
-    if(!ctx) {
-        return false;
-    }
-
-    if (ctx->current_fs) {
-        ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE;
-        ctx->current_fs->error_status = status;
-        /* If a directory has ignored files, put the flag on the parent directory as well */
-        if( previous_fs ) {
-            previous_fs->has_ignored_files = true;
-        }
-        return true;
-    }
-    return false;
-}
-
-/* File tree walker */
-int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
-    unsigned int depth) {
-  char *filename = NULL;
-  char *d_name = NULL;
-  csync_vio_handle_t *dh = NULL;
-  csync_vio_file_stat_t *dirent = NULL;
-  csync_file_stat_t *previous_fs = NULL;
-  int read_from_db = 0;
-  int rc = 0;
-  int res = 0;
-
-  if (!depth) {
-    mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_INDIVIDUAL_TOO_DEEP);
-    goto done;
-  }
-
-  bool do_read_from_db = (ctx->current == REMOTE_REPLICA && ctx->remote.read_from_db);
-
-  read_from_db = ctx->remote.read_from_db;
-
-  // if the etag of this dir is still the same, its content is restored from the
-  // database.
-  if( do_read_from_db ) {
-      if( ! fill_tree_from_db(ctx, uri) ) {
-        errno = ENOENT;
-        ctx->status_code = CSYNC_STATUS_OPENDIR_ERROR;
-        goto error;
-      }
-      goto done;
-  }
-
-  if ((dh = csync_vio_opendir(ctx, uri)) == NULL) {
-      if (ctx->abort) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Aborted!");
-          ctx->status_code = CSYNC_STATUS_ABORTED;
-          goto error;
-      }
-      int asp = 0;
-      /* permission denied */
-      ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_OPENDIR_ERROR);
-      if (errno == EACCES) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Permission denied.");
-          if (mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_PERMISSION_DENIED)) {
-              goto done;
-          }
-      } else if(errno == ENOENT) {
-          asp = asprintf( &ctx->error_string, "%s", uri);
-          if (asp < 0) {
-              CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
-          }
-      }
-      // 403 Forbidden can be sent by the server if the file firewall is active.
-      // A file or directory should be ignored and sync must continue. See #3490
-      else if(errno == ERRNO_FORBIDDEN) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Directory access Forbidden (File Firewall?)");
-          if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_FORBIDDEN) ) {
-              goto done;
-          }
-          /* if current_fs is not defined here, better throw an error */
-      }
-      // The server usually replies with the custom "503 Storage not available"
-      // if some path is temporarily unavailable. But in some cases a standard 503
-      // is returned too. Thus we can't distinguish the two and will treat any
-      // 503 as request to ignore the folder. See #3113 #2884.
-      else if(errno == ERRNO_STORAGE_UNAVAILABLE || errno == ERRNO_SERVICE_UNAVAILABLE) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Storage was not available!");
-          if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_STORAGE_UNAVAILABLE ) ) {
-              goto done;
-          }
-          /* if current_fs is not defined here, better throw an error */
-      } else {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "opendir failed for %s - errno %d", uri, errno);
-      }
-      goto error;
-  }
-
-  while ((dirent = csync_vio_readdir(ctx, dh))) {
-    int flen;
-    int flag;
-
-    /* Conversion error */
-    if (dirent->name == NULL && dirent->original_name) {
-        ctx->status_code = CSYNC_STATUS_INVALID_CHARACTERS;
-        ctx->error_string = dirent->original_name; // take ownership
-        dirent->original_name = NULL;
-        goto error;
-    }
-
-    d_name = dirent->name;
-    if (d_name == NULL) {
-      ctx->status_code = CSYNC_STATUS_READDIR_ERROR;
-      goto error;
-    }
-
-    /* skip "." and ".." */
-    if ( (d_name[0] == '.' && d_name[1] == '\0')
-          || (d_name[0] == '.' && d_name[1] == '.' && d_name[2] == '\0')) {
-      csync_vio_file_stat_destroy(dirent);
-      dirent = NULL;
-      continue;
-    }
-
-    if (uri[0] == '\0') {
-      filename = c_strdup(d_name);
-      flen = strlen(d_name);
-    } else {
-      flen = asprintf(&filename, "%s/%s", uri, d_name);
-    }
-    if (flen < 0 || !filename) {
-      csync_vio_file_stat_destroy(dirent);
-      dirent = NULL;
-      ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
-      goto error;
-    }
-
-    /* Only for the local replica we have to stat(), for the remote one we have all data already */
-    if (ctx->replica == LOCAL_REPLICA) {
-        res = csync_vio_stat(ctx, filename, dirent);
-    } else {
-        res = 0;
-    }
-
-    /* if the filename starts with a . we consider it a hidden file
-     * For windows, the hidden state is also discovered within the vio
-     * local stat function.
-     */
-    if( d_name[0] == '.' ) {
-        if (strcmp(".sys.admin#recall#", d_name) != 0) { /* recall file shall not be ignored (#4420) */
-            dirent->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
-        }
-    }
-
-    if( res == 0) {
-      switch (dirent->type) {
-        case CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK:
-          flag = CSYNC_FTW_FLAG_SLINK;
-          break;
-        case CSYNC_VIO_FILE_TYPE_DIRECTORY:
-          flag = CSYNC_FTW_FLAG_DIR;
-          break;
-        case CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE:
-        case CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE:
-        case CSYNC_VIO_FILE_TYPE_SOCKET:
-          flag = CSYNC_FTW_FLAG_SPEC;
-          break;
-        case CSYNC_VIO_FILE_TYPE_FIFO:
-          flag = CSYNC_FTW_FLAG_SPEC;
-          break;
-        default:
-          flag = CSYNC_FTW_FLAG_FILE;
-          break;
-      };
-    } else {
-      flag = CSYNC_FTW_FLAG_NSTAT;
-    }
-
-    previous_fs = ctx->current_fs;
-
-    /* Call walker function for each file */
-    rc = fn(ctx, filename, dirent, flag);
-    /* this function may update ctx->current and ctx->read_from_db */
-
-    if (rc < 0) {
-      if (CSYNC_STATUS_IS_OK(ctx->status_code)) {
-          ctx->status_code = CSYNC_STATUS_UPDATE_ERROR;
-      }
-
-      ctx->current_fs = previous_fs;
-      goto error;
-    }
-
-    if (flag == CSYNC_FTW_FLAG_DIR && rc == 0
-        && (!ctx->current_fs || ctx->current_fs->instruction != CSYNC_INSTRUCTION_IGNORE)) {
-      rc = csync_ftw(ctx, filename, fn, depth - 1);
-      if (rc < 0) {
-        ctx->current_fs = previous_fs;
-        goto error;
-      }
-
-      if (ctx->current_fs && !ctx->current_fs->child_modified
-          && ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL) {
-          if (ctx->current == REMOTE_REPLICA) {
-              ctx->current_fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
-          } else {
-              ctx->current_fs->instruction = CSYNC_INSTRUCTION_NONE;
-          }
-      }
-
-      if (ctx->current_fs && previous_fs && ctx->current_fs->has_ignored_files) {
-          /* If a directory has ignored files, put the flag on the parent directory as well */
-          previous_fs->has_ignored_files = ctx->current_fs->has_ignored_files;
-      }
-    }
-
-    if (ctx->current_fs && previous_fs && ctx->current_fs->child_modified) {
-        /* If a directory has modified files, put the flag on the parent directory as well */
-        previous_fs->child_modified = ctx->current_fs->child_modified;
-    }
-
-    ctx->current_fs = previous_fs;
-    ctx->remote.read_from_db = read_from_db;
-    SAFE_FREE(filename);
-    csync_vio_file_stat_destroy(dirent);
-    dirent = NULL;
-  }
-
-  csync_vio_closedir(ctx, dh);
-  CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, " <= Closing walk for %s with read_from_db %d", uri, read_from_db);
-
-done:
-  csync_vio_file_stat_destroy(dirent);
-  SAFE_FREE(filename);
-  return rc;
-error:
-  ctx->remote.read_from_db = read_from_db;
-  if (dh != NULL) {
-    csync_vio_closedir(ctx, dh);
-  }
-  SAFE_FREE(filename);
-  return -1;
-}
-
-/* vim: set ts=8 sw=2 et cindent: */
diff --git a/csync/src/csync_update.h b/csync/src/csync_update.h
deleted file mode 100644 (file)
index 4a7495e..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _CSYNC_UPDATE_H
-#define _CSYNC_UPDATE_H
-
-#include "csync.h"
-
-/**
- * @file csync_update.h
- *
- * @brief Update Detection
- *
- * TODO
- *
- * @defgroup csyncUpdateDetectionInternals csync update detection internals
- * @ingroup csyncInternalAPI
- *
- * @{
- */
-
-/**
- * Types for files
- */
-enum csync_ftw_flags_e {
-  CSYNC_FTW_FLAG_FILE,         /* Regular file.  */
-  CSYNC_FTW_FLAG_DIR,          /* Directory.  */
-  CSYNC_FTW_FLAG_DNR,          /* Unreadable directory.  */
-  CSYNC_FTW_FLAG_NSTAT,                /* Unstatable file.  */
-  CSYNC_FTW_FLAG_SLINK,                /* Symbolic link.  */
-  CSYNC_FTW_FLAG_SPEC,         /* Special file (fifo, ...).  */
-  /* These flags are only passed from the `nftw' function.  */
-  CSYNC_FTW_FLAG_DP,           /* Directory, all subdirs have been visited. */
-  CSYNC_FTW_FLAG_SLN           /* Symbolic link naming non-existing file.  */
-};
-
-typedef int (*csync_walker_fn) (CSYNC *ctx, const char *file,
-    const csync_vio_file_stat_t *fs, enum csync_ftw_flags_e flag);
-
-/**
- * @brief The walker function to use in the file tree walker.
- *
- * @param  ctx          The used csync context.
- *
- * @param  file         The file we are researching.
- *
- * @param  fs           The stat information we got.
- *
- * @param  flag         The flag describing the type of the file.
- *
- * @return 0 on success, < 0 on error.
- */
-int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
-    enum csync_ftw_flags_e flag);
-
-/**
- * @brief The file tree walker.
- *
- * This function walks through the directory tree that is located under the uri
- * specified. It calls a walker function which is provided as a function pointer
- * once for each entry in the tree. By default, directories are handled before
- * the files and subdirectories they contain (pre-order traversal).
- *
- * @param  ctx          The csync context to use.
- *
- * @param  uri          The uri/path to the directory tree to walk.
- *
- * @param  fn           The walker function to call once for each entry.
- *
- * @param  depth        The max depth to walk down the tree.
- *
- * @return 0 on success, < 0 on error. If fn() returns non-zero, then the tree
- *         walk is terminated and the value returned by fn() is returned as the
- *         result.
- */
-int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
-    unsigned int depth);
-
-#endif /* _CSYNC_UPDATE_H */
-
-/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/csync/src/csync_util.c b/csync/src/csync_util.c
deleted file mode 100644 (file)
index 1bc09c3..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-
-#include "c_jhash.h"
-#include "csync_util.h"
-#include "vio/csync_vio.h"
-
-#define CSYNC_LOG_CATEGORY_NAME "csync.util"
-#include "csync_log.h"
-#include "csync_statedb.h"
-
-typedef struct {
-  const char *instr_str;
-  enum csync_instructions_e instr_code;
-} _instr_code_struct;
-
-static const _instr_code_struct _instr[] =
-{
-  { "INSTRUCTION_NONE", CSYNC_INSTRUCTION_NONE },
-  { "INSTRUCTION_EVAL", CSYNC_INSTRUCTION_EVAL },
-  { "INSTRUCTION_REMOVE", CSYNC_INSTRUCTION_REMOVE },
-  { "INSTRUCTION_RENAME", CSYNC_INSTRUCTION_RENAME },
-  { "INSTRUCTION_EVAL_RENAME", CSYNC_INSTRUCTION_EVAL_RENAME },
-  { "INSTRUCTION_NEW", CSYNC_INSTRUCTION_NEW },
-  { "INSTRUCTION_CONFLICT", CSYNC_INSTRUCTION_CONFLICT },
-  { "INSTRUCTION_IGNORE", CSYNC_INSTRUCTION_IGNORE },
-  { "INSTRUCTION_SYNC", CSYNC_INSTRUCTION_SYNC },
-  { "INSTRUCTION_STAT_ERR", CSYNC_INSTRUCTION_STAT_ERROR },
-  { "INSTRUCTION_ERROR", CSYNC_INSTRUCTION_ERROR },
-  { "INSTRUCTION_TYPE_CHANGE", CSYNC_INSTRUCTION_TYPE_CHANGE },
-  { "INSTRUCTION_UPDATE_METADATA", CSYNC_INSTRUCTION_UPDATE_METADATA },
-  { NULL, CSYNC_INSTRUCTION_ERROR }
-};
-
-struct csync_memstat_s {
-  int size;
-  int resident;
-  int shared;
-  int trs;
-  int drs;
-  int lrs;
-  int dt;
-};
-
-const char *csync_instruction_str(enum csync_instructions_e instr)
-{
-  int idx = 0;
-
-  while (_instr[idx].instr_str != NULL) {
-    if (_instr[idx].instr_code == instr) {
-      return _instr[idx].instr_str;
-    }
-    idx++;
-  }
-
-  return "ERROR!";
-}
-
-
-void csync_memstat_check(void) {
-  int s = 0;
-  struct csync_memstat_s m;
-  FILE* fp;
-
-  /* get process memory stats */
-  fp = fopen("/proc/self/statm","r");
-  if (fp == NULL) {
-    return;
-  }
-  s = fscanf(fp, "%d%d%d%d%d%d%d", &m.size, &m.resident, &m.shared, &m.trs,
-      &m.drs, &m.lrs, &m.dt);
-  fclose(fp);
-  if (s == EOF) {
-    return;
-  }
-
-  CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Memory: %dK total size, %dK resident, %dK shared",
-                 m.size * 4, m.resident * 4, m.shared * 4);
-}
-
-bool (*csync_file_locked_or_open_ext) (const char*) = 0; // filled in by library user
-void set_csync_file_locked_or_open_ext(bool (*f) (const char*));
-void set_csync_file_locked_or_open_ext(bool (*f) (const char*)) {
-    csync_file_locked_or_open_ext = f;
-}
-
-bool csync_file_locked_or_open( const char *dir, const char *fname) {
-    char *tmp_uri = NULL;
-    bool ret;
-    if (!csync_file_locked_or_open_ext) {
-        return false;
-    }
-    if (asprintf(&tmp_uri, "%s/%s", dir, fname) < 0) {
-        return -1;
-    }
-    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "csync_file_locked_or_open %s", tmp_uri);
-    ret = csync_file_locked_or_open_ext(tmp_uri);
-    SAFE_FREE(tmp_uri);
-    return ret;
-}
-
-#ifndef HAVE_TIMEGM
-#ifdef _WIN32
-static int is_leap(unsigned y) {
-    y += 1900;
-    return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
-}
-
-static time_t timegm(struct tm *tm) {
-    static const unsigned ndays[2][12] = {
-    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
-    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };
-
-    time_t res = 0;
-    int i;
-
-    for (i = 70; i < tm->tm_year; ++i)
-        res += is_leap(i) ? 366 : 365;
-
-    for (i = 0; i < tm->tm_mon; ++i)
-        res += ndays[is_leap(tm->tm_year)][i];
-     res += tm->tm_mday - 1;
-     res *= 24;
-     res += tm->tm_hour;
-     res *= 60;
-     res += tm->tm_min;
-     res *= 60;
-     res += tm->tm_sec;
-     return res;
-}
-#else
-/* A hopefully portable version of timegm */
-static time_t timegm(struct tm *tm ) {
-     time_t ret;
-     char *tz;
-
-     tz = getenv("TZ");
-     setenv("TZ", "", 1);
-     tzset();
-     ret = mktime(tm);
-     if (tz)
-         setenv("TZ", tz, 1);
-     else
-         unsetenv("TZ");
-     tzset();
-     return ret;
-}
-#endif /* Platform switch */
-#endif /* HAVE_TIMEGM */
-
-#define RFC1123_FORMAT "%3s, %02d %3s %4d %02d:%02d:%02d GMT"
-static const char short_months[12][4] = {
-    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-/*
- * This function is borrowed from libneon's ne_httpdate_parse.
- * Unfortunately that one converts to local time but here UTC is
- * needed.
- * This one uses timegm instead, which returns UTC.
- */
-time_t oc_httpdate_parse( const char *date ) {
-    struct tm gmt;
-    char wkday[4], mon[4];
-    int n;
-    time_t result = 0;
-
-    memset(&gmt, 0, sizeof(struct tm));
-
-    /*  it goes: Sun, 06 Nov 1994 08:49:37 GMT */
-    n = sscanf(date, RFC1123_FORMAT,
-               wkday, &gmt.tm_mday, mon, &gmt.tm_year, &gmt.tm_hour,
-               &gmt.tm_min, &gmt.tm_sec);
-    /* Is it portable to check n==7 here? */
-    gmt.tm_year -= 1900;
-    for (n=0; n<12; n++)
-        if (strcmp(mon, short_months[n]) == 0)
-            break;
-    /* tm_mon comes out as 12 if the month is corrupt, which is desired,
-     * since the mktime will then fail */
-    gmt.tm_mon = n;
-    gmt.tm_isdst = -1;
-    result = timegm(&gmt);
-    return result;
-}
diff --git a/csync/src/csync_util.h b/csync/src/csync_util.h
deleted file mode 100644 (file)
index f65ada5..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _CSYNC_UTIL_H
-#define _CSYNC_UTIL_H
-
-#include <stdint.h>
-
-#include "csync_private.h"
-
-const char OCSYNC_EXPORT *csync_instruction_str(enum csync_instructions_e instr);
-
-void OCSYNC_EXPORT csync_memstat_check(void);
-
-bool OCSYNC_EXPORT csync_file_locked_or_open( const char *dir, const char *fname);
-#endif /* _CSYNC_UTIL_H */
diff --git a/csync/src/csync_version.h.in b/csync/src/csync_version.h.in
deleted file mode 100644 (file)
index 9471734..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2006-2012 by Andreas Schneider <asn@cryptomilk.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-#ifndef _CSYNC_VERSION_H
-#define _CSYNC_VERSION_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define CSYNC_STRINGIFY(s) CSYNC_TOSTRING(s)
-#define CSYNC_TOSTRING(s) #s
-
-#define MIRALL_VERSION @MIRALL_VERSION@
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CSYNC_VERSION_H
diff --git a/csync/src/std/CMakeLists.txt b/csync/src/std/CMakeLists.txt
deleted file mode 100644 (file)
index 519cada..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-project(cstdlib)
-
-set(CSTDLIB_PUBLIC_INCLUDE_DIRS
-  ${CMAKE_CURRENT_SOURCE_DIR}
-  CACHE INTERNAL "cstdlib public include directories"
-)
-
-set(CSTDLIB_LIBRARY
-  cstdlib
-  CACHE INTERNAL "cstdlib library"
-)
-
-set(CSTDLIB_LINK_LIBRARIES
-  ${CSTDLIB_LIBRARY}
-)
-
-set(cstdlib_SRCS
-  c_alloc.c
-  c_path.c
-  c_rbtree.c
-  c_string.c
-  c_time.c
-  c_utf8.cc
-)
-
-if(NOT HAVE_ASPRINTF AND NOT HAVE___MINGW_ASPRINTF)
-    list(APPEND cstdlib_SRCS
-        asprintf.c
-    )
-endif()
-
-include_directories(
-  ${CSTDLIB_PUBLIC_INCLUDE_DIRS}
-)
-
-add_library(${CSTDLIB_LIBRARY} STATIC ${cstdlib_SRCS})
-if(NOT WIN32)
-    add_definitions( -fPIC )
-    qt5_use_modules(${CSTDLIB_LIBRARY} Core)
-endif()
-if(NOT HAVE_FNMATCH AND WIN32)
-  # needed for PathMatchSpec for our fnmatch replacement
-  target_link_libraries(${CSTDLIB_LIBRARY} ${SHLWAPI_LIBRARY})
-endif()
diff --git a/csync/src/std/asprintf.c b/csync/src/std/asprintf.c
deleted file mode 100644 (file)
index 8738df9..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-  https://raw.githubusercontent.com/littlstar/asprintf.c/20ce5207a4ecb24017b5a17e6cd7d006e3047146/asprintf.c
-
-  The MIT License (MIT)
-
-  Copyright (c) 2014 Little Star Media, Inc.
-
-  Permission is hereby granted, free of charge, to any person obtaining a copy
-  of this software and associated documentation files (the "Software"), to deal
-  in the Software without restriction, including without limitation the rights
-  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-  copies of the Software, and to permit persons to whom the Software is
-  furnished to do so, subject to the following conditions:
-
-  The above copyright notice and this permission notice shall be included in all
-  copies or substantial portions of the Software.
-
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-  SOFTWARE.
-*/
-
-/**
- * `asprintf.c' - asprintf
- *
- * copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
- */
-
-#ifndef HAVE_ASPRINTF
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "asprintf.h"
-
-int
-asprintf (char **str, const char *fmt, ...) {
-  int size = 0;
-  va_list args;
-
-  // init variadic argumens
-  va_start(args, fmt);
-
-  // format and get size
-  size = vasprintf(str, fmt, args);
-
-  // toss args
-  va_end(args);
-
-  return size;
-}
-
-int
-vasprintf (char **str, const char *fmt, va_list args) {
-  int size = 0;
-  va_list tmpa;
-
-  // copy
-  va_copy(tmpa, args);
-
-  // apply variadic arguments to
-  // sprintf with format to get size
-  size = vsnprintf(NULL, size, fmt, tmpa);
-
-  // toss args
-  va_end(tmpa);
-
-  // return -1 to be compliant if
-  // size is less than 0
-  if (size < 0) { return -1; }
-
-  // alloc with size plus 1 for `\0'
-  *str = (char *) malloc(size + 1);
-
-  // return -1 to be compliant
-  // if pointer is `NULL'
-  if (NULL == *str) { return -1; }
-
-  // format string with original
-  // variadic arguments and set new size
-  size = vsprintf(*str, fmt, args);
-  return size;
-}
-
-#endif
diff --git a/csync/src/std/asprintf.h b/csync/src/std/asprintf.h
deleted file mode 100644 (file)
index d6dd2e8..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-  https://raw.githubusercontent.com/littlstar/asprintf.c/20ce5207a4ecb24017b5a17e6cd7d006e3047146/asprintf.h
-
-  The MIT License (MIT)
-
-  Copyright (c) 2014 Little Star Media, Inc.
-
-  Permission is hereby granted, free of charge, to any person obtaining a copy
-  of this software and associated documentation files (the "Software"), to deal
-  in the Software without restriction, including without limitation the rights
-  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-  copies of the Software, and to permit persons to whom the Software is
-  furnished to do so, subject to the following conditions:
-
-  The above copyright notice and this permission notice shall be included in all
-  copies or substantial portions of the Software.
-
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-  SOFTWARE.
-*/
-
-/**
- * `asprintf.h' - asprintf.c
- *
- * copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
- */
-
-#ifndef HAVE_ASPRINTF
-#ifndef ASPRINTF_H
-#define ASPRINTF_H 1
-
-#include <stdarg.h>
-
-/**
- * Sets `char **' pointer to be a buffer
- * large enough to hold the formatted string
- * accepting a `va_list' args of variadic
- * arguments.
- */
-
-int
-vasprintf (char **, const char *, va_list);
-
-/**
- * Sets `char **' pointer to be a buffer
- * large enough to hold the formatted
- * string accepting `n' arguments of
- * variadic arguments.
- */
-
-int
-asprintf (char **, const char *, ...);
-
-#endif
-#endif
diff --git a/csync/src/std/c_alloc.c b/csync/src/std/c_alloc.c
deleted file mode 100644 (file)
index b87a383..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <string.h>
-
-#include "c_macro.h"
-#include "c_alloc.h"
-
-void *c_calloc(size_t count, size_t size) {
-  if (size == 0 || count == 0) {
-    return NULL;
-  }
-
-#ifdef CSYNC_MEM_NULL_TESTS
-  if (getenv("CSYNC_NOMEMORY")) {
-    return NULL;
-  }
-#endif /* CSYNC_MEM_NULL_TESTS */
-
-#undef calloc
-  return calloc(count, size);
-#define calloc(x,y) DO_NOT_CALL_CALLOC__USE_XCALLOC_INSTEAD
-}
-
-void *c_malloc(size_t size) {
-  if (size == 0) {
-    return NULL;
-  }
-#undef malloc
-  return c_calloc(1, size);
-#define malloc(x) DO_NOT_CALL_MALLOC__USE_XMALLOC_INSTEAD
-}
-
-void *c_realloc(void *ptr, size_t size) {
-
-#ifdef CSYNC_MEM_NULL_TESTS
-  if (getenv("CSYNC_NOMEMORY")) {
-    return NULL;
-  }
-#endif /* CSYNC_MEM_NULL_TESTS */
-
-#undef realloc
-  return realloc(ptr, size);
-#define realloc(x,y) DO_NOT_CALL_REALLOC__USE_XREALLOC_INSTEAD
-}
-
-char *c_strdup(const char *str) {
-  char *ret;
-  ret = (char *) c_malloc(strlen(str) + 1);
-  if (ret == NULL) {
-    return NULL;
-  }
-  strcpy(ret, str);
-  return ret;
-}
-
-char *c_strndup(const char *str, size_t size) {
-  char *ret;
-  size_t len;
-  len = strlen(str);
-  if (len > size) {
-    len = size;
-  }
-  ret = (char *) c_malloc(len + 1);
-  if (ret == NULL) {
-    return NULL;
-  }
-  strncpy(ret, str, len);
-  ret[size] = '\0';
-  return ret;
-}
-
diff --git a/csync/src/std/c_alloc.h b/csync/src/std/c_alloc.h
deleted file mode 100644 (file)
index 6eeccd6..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file c_alloc.h
- *
- * @brief Interface of the cynapses libc alloc function
- *
- * @defgroup cynLibraryAPI cynapses libc API (internal)
- *
- * @defgroup cynAllocInternals cynapses libc alloc functions
- * @ingroup cynLibraryAPI
- *
- * @{
- */
-
-#ifndef _C_ALLOC_H
-#define _C_ALLOC_H
-
-#include <stdlib.h>
-
-#include "c_macro.h"
-
-/**
- * @brief Allocates memory for an array.
- *
- * Allocates memory for an array of <count> elements of <size> bytes each and
- * returns a pointer to the allocated memory. The memory is set to zero.
- *
- * @param count   Amount of elements to allocate
- * @param size    Size in bytes of each element to allocate.
- *
- * @return A unique pointer value that can later be successfully passed to
- *         free(). If size or count is 0, NULL will be returned.
- */
-void *c_calloc(size_t count, size_t size);
-
-/**
- * @brief Allocates memory for an array.
- *
- * Allocates <size> bytes of memory. The memory is set to zero.
- *
- * @param size    Size in bytes to allocate.
- *
- * @return A unique pointer value that can later be successfully passed to
- *         free(). If size or count is 0, NULL will be returned.
- */
-void *c_malloc(size_t size);
-
-/**
- * @brief Changes the size of the memory block pointed to.
- *
- * Newly allocated memory will be uninitialized.
- *
- * @param ptr   Pointer to the memory which should be resized.
- * @param size  Value to resize.
- *
- * @return If ptr is NULL, the call is equivalent to c_malloc(size); if size
- *         is equal to zero, the call is equivalent to free(ptr). Unless ptr
- *         is NULL, it must have been returned by an earlier call to
- *         c_malloc(), c_calloc() or c_realloc(). If the area pointed to was
- *         moved, a free(ptr) is done.
- */
-void *c_realloc(void *ptr, size_t size);
-
-/**
- * @brief Duplicate a string.
- *
- * The function returns a pointer to a newly allocated string which is a
- * duplicate of the string str.
- *
- * @param str   String to duplicate.
- *
- * @return Returns a pointer to the duplicated string, or NULL if insufficient
- * memory was available.
- *
- */
-char *c_strdup(const char *str);
-
-/**
- * @brief Duplicate a string.
- *
- * The function returns a pointer to a newly allocated string which is a
- * duplicate of the string str of size bytes.
- *
- * @param str   String to duplicate.
- *
- * @param size  Size of the string to duplicate.
- *
- * @return Returns a pointer to the duplicated string, or NULL if insufficient
- * memory was available. A terminating null byte '\0' is added.
- *
- */
-char *c_strndup(const char *str, size_t size);
-
-/**
- * }@
- */
-#endif /* _C_ALLOC_H */
diff --git a/csync/src/std/c_jhash.h b/csync/src/std/c_jhash.h
deleted file mode 100644 (file)
index 261a0a4..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * c_jhash.c Jenkins Hash
- *
- * Copyright (c) 1997 Bob Jenkins <bob_jenkins@burtleburtle.net>
- *
- * lookup8.c, by Bob Jenkins, January 4 1997, Public Domain.
- * hash(), hash2(), hash3, and _c_mix() are externally useful functions.
- * Routines to test the hash are included if SELF_TEST is defined.
- * You can use this free for any purpose.  It has no warranty.
- *
- * See http://burtleburtle.net/bob/hash/evahash.html
- */
-
-/**
- * @file c_jhash.h
- *
- * @brief Interface of the cynapses jhash implementation
- *
- * @defgroup cynJHashInternals cynapses libc jhash function
- * @ingroup cynLibraryAPI
- *
- * @{
- */
-#ifndef _C_JHASH_H
-#define _C_JHASH_H
-
-#include <stdint.h>
-
-#define c_hashsize(n) ((uint8_t) 1 << (n))
-#define c_hashmask(n) (xhashsize(n) - 1)
-
-/**
- * _c_mix -- Mix 3 32-bit values reversibly.
- *
- * For every delta with one or two bit set, and the deltas of all three
- * high bits or all three low bits, whether the original value of a,b,c
- * is almost all zero or is uniformly distributed,
- * If _c_mix() is run forward or backward, at least 32 bits in a,b,c
- * have at least 1/4 probability of changing.
- * If _c_mix() is run forward, every bit of c will change between 1/3 and
- * 2/3 of the time.  (Well, 22/100 and 78/100 for some 2-bit deltas.)
- * _c_mix() was built out of 36 single-cycle latency instructions in a 
- * structure that could supported 2x parallelism, like so:
- *     a -= b;
- *     a -= c; x = (c>>13);
- *     b -= c; a ^= x;
- *     b -= a; x = (a<<8);
- *     c -= a; b ^= x;
- *     c -= b; x = (b>>13);
- *     ...
- *
- * Unfortunately, superscalar Pentiums and Sparcs can't take advantage
- * of that parallelism.  They've also turned some of those single-cycle
- * latency instructions into multi-cycle latency instructions.  Still,
- * this is the fastest good hash I could find.  There were about 2^^68
- * to choose from.  I only looked at a billion or so.
- */
-#define _c_mix(a,b,c) \
-{ \
-  a -= b; a -= c; a ^= (c>>13); \
-  b -= c; b -= a; b ^= (a<<8); \
-  c -= a; c -= b; c ^= (b>>13); \
-  a -= b; a -= c; a ^= (c>>12);  \
-  b -= c; b -= a; b ^= (a<<16); \
-  c -= a; c -= b; c ^= (b>>5); \
-  a -= b; a -= c; a ^= (c>>3);  \
-  b -= c; b -= a; b ^= (a<<10); \
-  c -= a; c -= b; c ^= (b>>15); \
-}
-
-/**
- * _c_mix64 -- Mix 3 64-bit values reversibly.
- *
- * _c_mix64() takes 48 machine instructions, but only 24 cycles on a superscalar
- * machine (like Intel's new MMX architecture).  It requires 4 64-bit
- * registers for 4::2 parallelism.
- * All 1-bit deltas, all 2-bit deltas, all deltas composed of top bits of
- * (a,b,c), and all deltas of bottom bits were tested.  All deltas were
- * tested both on random keys and on keys that were nearly all zero.
- * These deltas all cause every bit of c to change between 1/3 and 2/3
- * of the time (well, only 113/400 to 287/400 of the time for some
- * 2-bit delta).  These deltas all cause at least 80 bits to change
- * among (a,b,c) when the _c_mix is run either forward or backward (yes it
- * is reversible).
- * This implies that a hash using _c_mix64 has no funnels.  There may be
- * characteristics with 3-bit deltas or bigger, I didn't test for
- * those.
- */
-#define _c_mix64(a,b,c) \
-{ \
-  a -= b; a -= c; a ^= (c>>43); \
-  b -= c; b -= a; b ^= (a<<9); \
-  c -= a; c -= b; c ^= (b>>8); \
-  a -= b; a -= c; a ^= (c>>38); \
-  b -= c; b -= a; b ^= (a<<23); \
-  c -= a; c -= b; c ^= (b>>5); \
-  a -= b; a -= c; a ^= (c>>35); \
-  b -= c; b -= a; b ^= (a<<49); \
-  c -= a; c -= b; c ^= (b>>11); \
-  a -= b; a -= c; a ^= (c>>12); \
-  b -= c; b -= a; b ^= (a<<18); \
-  c -= a; c -= b; c ^= (b>>22); \
-}
-
-/**
- * @brief hash a variable-length key into a 32-bit value
- *
- * The best hash table sizes are powers of 2.  There is no need to do
- * mod a prime (mod is sooo slow!).  If you need less than 32 bits,
- * use a bitmask.  For example, if you need only 10 bits, do
- *   h = (h & hashmask(10));
- * In which case, the hash table should have hashsize(10) elements.
- *
- * Use for hash table lookup, or anything where one collision in 2^32 is
- * acceptable.  Do NOT use for cryptographic purposes.
- *
- * @param k        The key (the unaligned variable-length array of bytes).
- *
- * @param length   The length of the key, counting by bytes.
- *
- * @param initval  Initial value, can be any 4-byte value.
- *
- * @return    Returns a 32-bit value.  Every bit of the key affects every bit
- *            of the return value.  Every 1-bit and 2-bit delta achieves
- *            avalanche. About 36+6len instructions.
- */
-static inline uint32_t c_jhash(const uint8_t *k, uint32_t length, uint32_t initval) {
-   uint32_t a,b,c,len;
-
-   /* Set up the internal state */
-   len = length;
-   a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
-   c = initval; /* the previous hash value */
-
-   while (len >= 12) {
-      a += (k[0] +((uint32_t)k[1]<<8) +((uint32_t)k[2]<<16) +((uint32_t)k[3]<<24));
-      b += (k[4] +((uint32_t)k[5]<<8) +((uint32_t)k[6]<<16) +((uint32_t)k[7]<<24));
-      c += (k[8] +((uint32_t)k[9]<<8) +((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24));
-      _c_mix(a,b,c);
-      k += 12; len -= 12;
-   }
-
-   /* handle the last 11 bytes */
-   c += length;
-   /* all the case statements fall through */
-   switch(len) {
-     case 11: c+=((uint32_t)k[10]<<24);
-     case 10: c+=((uint32_t)k[9]<<16);
-     case 9 : c+=((uint32_t)k[8]<<8);
-     /* the first byte of c is reserved for the length */
-     case 8 : b+=((uint32_t)k[7]<<24);
-     case 7 : b+=((uint32_t)k[6]<<16);
-     case 6 : b+=((uint32_t)k[5]<<8);
-     case 5 : b+=k[4];
-     case 4 : a+=((uint32_t)k[3]<<24);
-     case 3 : a+=((uint32_t)k[2]<<16);
-     case 2 : a+=((uint32_t)k[1]<<8);
-     case 1 : a+=k[0];
-     /* case 0: nothing left to add */
-   }
-   _c_mix(a,b,c);
-
-   return c;
-}
-
-/**
- * @brief hash a variable-length key into a 64-bit value
- *
- * The best hash table sizes are powers of 2.  There is no need to do
- * mod a prime (mod is sooo slow!).  If you need less than 64 bits,
- * use a bitmask.  For example, if you need only 10 bits, do
- *   h = (h & hashmask(10));
- * In which case, the hash table should have hashsize(10) elements.
- *
- * Use for hash table lookup, or anything where one collision in 2^^64
- * is acceptable.  Do NOT use for cryptographic purposes.
- *
- * @param k       The key (the unaligned variable-length array of bytes).
- * @param length  The length of the key, counting by bytes.
- * @param intval  Initial value, can be any 8-byte value.
- *
- * @return    A 64-bit value. Every bit of the key affects every bit of
- *            the return value.  No funnels.  Every 1-bit and 2-bit delta
- *            achieves avalanche. About 41+5len instructions.
- */
-static inline uint64_t c_jhash64(const uint8_t *k, uint64_t length, uint64_t intval) {
-  uint64_t a,b,c,len;
-
-  /* Set up the internal state */
-  len = length;
-  a = b = intval; /* the previous hash value */
-  c = 0x9e3779b97f4a7c13LL; /* the golden ratio; an arbitrary value */
-
-  /* handle most of the key */
-  while (len >= 24)
-  {
-    a += (k[0]        +((uint64_t)k[ 1]<< 8)+((uint64_t)k[ 2]<<16)+((uint64_t)k[ 3]<<24)
-     +((uint64_t)k[4 ]<<32)+((uint64_t)k[ 5]<<40)+((uint64_t)k[ 6]<<48)+((uint64_t)k[ 7]<<56));
-    b += (k[8]        +((uint64_t)k[ 9]<< 8)+((uint64_t)k[10]<<16)+((uint64_t)k[11]<<24)
-     +((uint64_t)k[12]<<32)+((uint64_t)k[13]<<40)+((uint64_t)k[14]<<48)+((uint64_t)k[15]<<56));
-    c += (k[16]       +((uint64_t)k[17]<< 8)+((uint64_t)k[18]<<16)+((uint64_t)k[19]<<24)
-     +((uint64_t)k[20]<<32)+((uint64_t)k[21]<<40)+((uint64_t)k[22]<<48)+((uint64_t)k[23]<<56));
-    _c_mix64(a,b,c);
-    k += 24; len -= 24;
-  }
-
-  /* handle the last 23 bytes */
-  c += length;
-  switch(len) {
-    case 23: c+=((uint64_t)k[22]<<56);
-    case 22: c+=((uint64_t)k[21]<<48);
-    case 21: c+=((uint64_t)k[20]<<40);
-    case 20: c+=((uint64_t)k[19]<<32);
-    case 19: c+=((uint64_t)k[18]<<24);
-    case 18: c+=((uint64_t)k[17]<<16);
-    case 17: c+=((uint64_t)k[16]<<8);
-    /* the first byte of c is reserved for the length */
-    case 16: b+=((uint64_t)k[15]<<56);
-    case 15: b+=((uint64_t)k[14]<<48);
-    case 14: b+=((uint64_t)k[13]<<40);
-    case 13: b+=((uint64_t)k[12]<<32);
-    case 12: b+=((uint64_t)k[11]<<24);
-    case 11: b+=((uint64_t)k[10]<<16);
-    case 10: b+=((uint64_t)k[ 9]<<8);
-    case  9: b+=((uint64_t)k[ 8]);
-    case  8: a+=((uint64_t)k[ 7]<<56);
-    case  7: a+=((uint64_t)k[ 6]<<48);
-    case  6: a+=((uint64_t)k[ 5]<<40);
-    case  5: a+=((uint64_t)k[ 4]<<32);
-    case  4: a+=((uint64_t)k[ 3]<<24);
-    case  3: a+=((uint64_t)k[ 2]<<16);
-    case  2: a+=((uint64_t)k[ 1]<<8);
-    case  1: a+=((uint64_t)k[ 0]);
-    /* case 0: nothing left to add */
-  }
-  _c_mix64(a,b,c);
-
-  return c;
-}
-
-/**
- * }@
- */
-#endif /* _C_JHASH_H */
-
diff --git a/csync/src/std/c_lib.h b/csync/src/std/c_lib.h
deleted file mode 100644 (file)
index b9c1ea8..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "c_macro.h"
-#include "c_alloc.h"
-#include "c_path.h"
-#include "c_rbtree.h"
-#include "c_string.h"
-#include "c_time.h"
-#include "c_private.h"
diff --git a/csync/src/std/c_macro.h b/csync/src/std/c_macro.h
deleted file mode 100644 (file)
index a4a0e1c..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file c_macro.h
- *
- * @brief cynapses libc macro definitions
- *
- * @defgroup cynMacroInternals cynapses libc macro definitions
- * @ingroup cynLibraryAPI
- *
- * @{
- */
-#ifndef _C_MACRO_H
-#define _C_MACRO_H
-
-#include <stdint.h>
-#include <string.h>
-
-#define INT_TO_POINTER(i) (void *) i
-#define POINTER_TO_INT(p) *((int *) (p))
-
-/** Zero a structure */
-#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
-
-/** Zero a structure given a pointer to the structure */
-#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
-
-/** Free memory and zero the pointer */
-#define SAFE_FREE(x) do { if ((x) != NULL) {free((void*)x); x=NULL;} } while(0)
-
-/** Get the smaller value */
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-
-/** Get the bigger value */
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-
-/** Get the size of an array */
-#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
-
-/**
- * This is a hack to fix warnings. The idea is to use this everywhere that we
- * get the "discarding const" warning by the compiler. That doesn't actually
- * fix the real issue, but marks the place and you can search the code for
- * discard_const.
- *
- * Please use this macro only when there is no other way to fix the warning.
- * We should use this function in only in a very few places.
- *
- * Also, please call this via the discard_const_p() macro interface, as that
- * makes the return type safe.
- */
-#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
-
-/**
- * Type-safe version of discard_const
- */
-#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
-
-#if (__GNUC__ >= 3)
-# ifndef likely
-#  define likely(x)   __builtin_expect(!!(x), 1)
-# endif
-# ifndef unlikely
-#  define unlikely(x) __builtin_expect(!!(x), 0)
-# endif
-#else /* __GNUC__ */
-# ifndef likely
-#  define likely(x) (x)
-# endif
-# ifndef unlikely
-#  define unlikely(x) (x)
-# endif
-#endif /* __GNUC__ */
-
-/**
- * }@
- */
-
-#ifdef _WIN32
-/* missing errno codes on mingw */
-#ifndef ENOTBLK
-#define        ENOTBLK                15
-#endif
-#ifndef ETXTBSY
-#define        ETXTBSY                26
-#endif
-#ifndef ENOBUFS
-#define        ENOBUFS                WSAENOBUFS
-#endif
-#endif /* _WIN32 */
-
-#endif /* _C_MACRO_H */
-
diff --git a/csync/src/std/c_path.c b/csync/src/std/c_path.c
deleted file mode 100644 (file)
index 1094a1c..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <errno.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "c_private.h"
-#include "c_alloc.h"
-#include "c_path.h"
-#include "c_string.h"
-
-/*
- * dirname - parse directory component.
- */
-char *c_dirname (const char *path) {
-  char *newbuf = NULL;
-  unsigned int len;
-
-  if (path == NULL || *path == '\0') {
-    return c_strdup(".");
-  }
-
-  len = strlen(path);
-
-  /* Remove trailing slashes */
-  while(len > 0 && path[len - 1] == '/') --len;
-
-  /* We have only slashes */
-  if (len == 0) {
-    return c_strdup("/");
-  }
-
-  /* goto next slash */
-  while(len > 0 && path[len - 1] != '/') --len;
-
-  if (len == 0) {
-    return c_strdup(".");
-  } else if (len == 1) {
-    return c_strdup("/");
-  }
-
-  /* Remove slashes again */
-  while(len > 0 && path[len - 1] == '/') --len;
-
-  newbuf = c_malloc(len + 1);
-
-  strncpy(newbuf, path, len);
-  newbuf[len] = '\0';
-
-  return newbuf;
-}
-
-char *c_basename (const char *path) {
-  char *newbuf = NULL;
-  const char *s;
-  unsigned int len;
-
-  if (path == NULL || *path == '\0') {
-    return c_strdup(".");
-  }
-
-  len = strlen(path);
-  /* Remove trailing slashes */
-  while(len > 0 && path[len - 1] == '/') --len;
-
-  /* We have only slashes */
-  if (len == 0) {
-    return c_strdup("/");
-  }
-
-  while(len > 0 && path[len - 1] != '/') --len;
-
-  if (len > 0) {
-    s = path + len;
-    len = strlen(s);
-
-    while(len > 0 && s[len - 1] == '/') --len;
-  } else {
-    return c_strdup(path);
-  }
-
-  newbuf = c_malloc(len + 1);
-
-  strncpy(newbuf, s, len);
-  newbuf[len] = '\0';
-
-  return newbuf;
-}
-
-int c_parse_uri(const char *uri,
-    char **scheme,
-    char **user, char **passwd,
-    char **host, unsigned int *port,
-    char **path) {
-  const char *p, *z;
-
-  if (uri == NULL || *uri == '\0') {
-    return -1;
-  }
-
-  /*
-   * uri = scheme://user:password@host:port/path
-   * p   = ^
-   * z   = ^
-   */
-  p = z = uri;
-
-  /* check for valid scheme; git+ssh, pop3 */
-  while (isalpha((int) *p) || isdigit((int) *p) ||
-      *p == '+' || *p == '-') {
-    /*
-     * uri = scheme://user:password@host:port/path
-     * p   =       ^
-     * z   = ^
-     */
-    p++;
-  }
-
-  /* get scheme */
-  if (*p == ':') {
-    if (scheme != NULL) {
-      *scheme = c_strndup(z, p - z);
-
-      if (*scheme == NULL) {
-        errno = ENOMEM;
-        return -1;
-      }
-    }
-    p++;
-    z = p;
-  }
-
-  /*
-   * uri = scheme://user:password@host:port/path
-   * p =          ^
-   * z =          ^
-   */
-  p = z;
-
-  /* do we have a hostname */
-  if (p[0] == '/' && p[1] == '/') {
-    /*
-     * uri = scheme://user:password@host:port/path
-     * p   =          ^
-     * z   =          ^
-     */
-    z += 2;
-    p = z;
-
-    /* check for user and passwd */
-    while (*p && *p != '@' && *p != '/') {
-      /*
-       * uri = scheme://user:password@host:port/path
-       * p   =                       ^    or   ^
-       * z   =          ^
-       */
-      p++;
-    }
-
-    /* check for user and password */
-    if (*p == '@') {
-      const char *q;
-
-      q = p;
-
-      /* check if we have a password */
-      while (q > z && *q != ':') {
-        /*
-         * uri = scheme://user:password@host:port/path
-         * p   =                       ^
-         * z   =          ^
-         * q   =              ^
-         */
-        q--;
-      }
-
-      /* password found */
-      if (*q == ':') {
-        if (user != NULL) {
-          *user = c_strndup(z, q - z);
-          if (*user == NULL) {
-            errno = ENOMEM;
-            if (scheme != NULL) SAFE_FREE(*scheme);
-            return -1;
-          }
-        }
-
-        if (passwd != NULL) {
-          *passwd = c_strndup(q + 1, p - (q + 1));
-          if (*passwd == NULL) {
-            if (scheme != NULL) SAFE_FREE(*scheme);
-            if (user   != NULL) SAFE_FREE(*user);
-            errno = ENOMEM;
-            return -1;
-          }
-        }
-      } else {
-        /* user only */
-        if (user != NULL) {
-          *user = c_strndup(z, p - z);
-          if( *user == NULL) {
-            if (scheme != NULL) SAFE_FREE(*scheme);
-            errno = ENOMEM;
-            return -1;
-          }
-        }
-      }
-
-      p++;
-      z = p;
-    }
-
-    /*
-     * uri = scheme://user:password@host:port/path
-     * p =                          ^
-     * z =                          ^
-     */
-    p = z;
-
-    /* check for IPv6 address */
-    if (*p == '[') {
-      /*
-       * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
-       * p   =                         ^
-       * z   =                        ^
-       */
-      p++;
-
-      /* check if we have a valid IPv6 address */
-      while (*p && (isxdigit((int) *p) || *p == '.' || *p == ':')) {
-        /*
-         * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
-         * p   =                                                                ^
-         * z   =                        ^
-         */
-        p++;
-      }
-
-      /* valid IPv6 address found */
-      if (*p == ']') {
-        /*
-         * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
-         * p   =                                                                ^
-         * z   =                         ^
-         */
-        z++;
-
-        if (host != NULL) {
-          *host = c_strndup(z, p - z);
-          if (*host == NULL) {
-            if (scheme != NULL) SAFE_FREE(*scheme);
-            if (user   != NULL) SAFE_FREE(*user);
-            if (passwd != NULL) SAFE_FREE(*passwd);
-            errno = ENOMEM;
-            return -1;
-          }
-        }
-
-        /*
-         * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
-         * p   =                                                                 ^
-         * z   =                         ^
-         */
-        p++;
-      } else {
-        /* invalid IPv6 address, assume a hostname */
-        p = z;
-
-        while (*p && *p != ':' && *p != '/') {
-          p++;
-          /*
-           * uri = scheme://user:password@host:port/path
-           * p   =                            ^ or ^
-           * z   =                        ^
-           */
-        }
-
-        if (host != NULL) {
-          *host = c_strndup(z, p - z);
-          if (*host == NULL) {
-            if (scheme != NULL) SAFE_FREE(*scheme);
-            if (user   != NULL) SAFE_FREE(*user);
-            if (passwd != NULL) SAFE_FREE(*passwd);
-            errno = ENOMEM;
-            return -1;
-          }
-        }
-      }
-    } else {
-      /* check for hostname */
-      while (*p && *p != ':' && *p != '/') {
-        /*
-         * uri = scheme://user:password@host:port/path
-         * p   =                            ^    ^
-         * z   =                        ^
-         */
-        p++;
-      }
-
-      if (host != NULL) {
-        *host = c_strndup(z, p - z);
-        if (*host == NULL) {
-          if (scheme != NULL) SAFE_FREE(*scheme);
-          if (user   != NULL) SAFE_FREE(*user);
-          if (passwd != NULL) SAFE_FREE(*passwd);
-          errno = ENOMEM;
-          return -1;
-        }
-      }
-    }
-
-    /* check for port */
-    if (*p == ':') {
-      char **e = NULL;
-      /*
-       * uri = scheme://user:password@host:port/path
-       * p =                               ^
-       * z =                               ^
-       */
-      z = ++p;
-
-      /* get only the digits */
-      while (isdigit((int) *p)) {
-        /*
-         * uri = scheme://user:password@host:port/path
-         * p   =                                 ^
-         * z   =                             ^
-         */
-        e = (char **) &p;
-        p++;
-      }
-
-      if (port != NULL) {
-        *port = strtoul(z, e, 0);
-      }
-
-      /*
-       * uri   = scheme://user:password@host:port/path
-       * p =                                     ^
-       */
-    }
-  }
-
-  if (*p == '\0') {
-    return 0;
-  }
-
-  /* get the path with the leading slash */
-  if (*p == '/') {
-    if (path != NULL) {
-      *path = c_strdup(p);
-      if (*path == NULL) {
-        if (scheme != NULL) SAFE_FREE(*scheme);
-        if (user   != NULL) SAFE_FREE(*user);
-        if (passwd != NULL) SAFE_FREE(*passwd);
-        if (host   != NULL) SAFE_FREE(*host);
-        errno = ENOMEM;
-        return -1;
-      }
-    }
-
-    return 0;
-  }
-
-  return -1;
-}
-
-
-/*
- * This function takes a path and converts it to a UNC representation of the
- * string. That means that it prepends a \\?\ (unless already UNC) and converts
- * all slashes to backslashes.
- *
- * Note the following:
- *  - The string must be absolute.
- *  - it needs to contain a drive character to be a valid UNC
- *  - A conversion is only done if the path len is larger than 245. Otherwise
- *    the windows API functions work with the normal "unixoid" representation too.
- *
- *  This function allocates memory that must be freed by the caller.
- */
- const char *c_path_to_UNC(const char *str)
- {
-     int len = 0;
-     char *longStr = NULL;
-
-     len = strlen(str);
-     longStr = c_malloc(len+5);
-     *longStr = '\0';
-
-     // prepend \\?\ and convert '/' => '\' to support long names
-     if( str[0] == '/' || str[0] == '\\' ) {
-         // Don't prepend if already UNC
-         if( !(len > 1 && (str[1] == '/' || str[1] == '\\')) ) {
-            strcpy( longStr, "\\\\?");
-         }
-     } else {
-         strcpy( longStr, "\\\\?\\"); // prepend string by this four magic chars.
-     }
-     strncat( longStr, str, len );
-
-     /* replace all occurences of / with the windows native \ */
-     char *c = longStr;
-     for (; *c; ++c) {
-         if(*c == '/') {
-             *c = '\\';
-         }
-     }
-     return longStr;
- }
-
- mbchar_t* c_utf8_path_to_locale(const char *str)
- {
-     if( str == NULL ) {
-         return NULL;
-     } else {
- #ifdef _WIN32
-         const char *unc_str = c_path_to_UNC(str);
-         mbchar_t *dst = c_utf8_string_to_locale(unc_str);
-         SAFE_FREE(unc_str);
-         return dst;
- #else
-         return c_utf8_string_to_locale(str);
- #endif
-     }
- }
diff --git a/csync/src/std/c_path.h b/csync/src/std/c_path.h
deleted file mode 100644 (file)
index 291b1b8..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file c_path.h
- *
- * @brief Interface of the cynapses libc path functions
- *
- * @defgroup cynPathInternals cynapses libc path functions
- * @ingroup cynLibraryAPI
- *
- * @{
- */
-
-#ifndef _C_PATH_H
-#define _C_PATH_H
-
-#include "c_macro.h"
-#include "c_private.h"
-
-/**
- * @brief Parse directory component.
- *
- * dirname breaks a null-terminated pathname string into a directory component.
- * In the usual case, c_dirname() returns the string up to, but not including,
- * the final '/'. Trailing '/' characters are  not  counted as part of the
- * pathname. The caller must free the memory.
- *
- * @param path  The path to parse.
- *
- * @return  The dirname of path or NULL if we can't allocate memory. If path
- *          does not contain a slash, c_dirname() returns the string ".".  If
- *          path is the string "/", it returns the string "/". If path is
- *          NULL or an empty string, "." is returned.
- */
-char *c_dirname(const char *path);
-
-/**
- * @brief basename - parse filename component.
- *
- * basename breaks a null-terminated pathname string into a filename component.
- * c_basename() returns the component following the final '/'.  Trailing '/'
- * characters are not counted as part of the pathname.
- *
- * @param path The path to parse.
- *
- * @return  The filename of path or NULL if we can't allocate memory. If path
- *          is a the string "/", basename returns the string "/". If path is
- *          NULL or an empty string, "." is returned.
- */
-char *c_basename (const char *path);
-
-/**
- * @brief parse a uri and split it into components.
- *
- * parse_uri parses an uri in the format
- *
- * [<scheme>:][//[<user>[:<password>]@]<host>[:<port>]]/[<path>]
- *
- * into its compoments. If you only want a special component,
- * pass NULL for all other components. All components will be allocated if they have
- * been found.
- *
- * @param uri       The uri to parse.
- * @param scheme    String for the scheme component
- * @param user      String for the username component
- * @param passwd    String for the password component
- * @param host      String for the password component
- * @param port      Integer for the port
- * @param path      String for the path component with a leading slash.
- *
- * @return  0 on success, < 0 on error.
- */
-int c_parse_uri(const char *uri, char **scheme, char **user, char **passwd,
-    char **host, unsigned int *port, char **path);
-
-/**
- * @brief Parts of a path.
- *
- * @param directory '\0' terminated path including the final '/'
- *
- * @param filename '\0' terminated string
- *
- * @param extension '\0' terminated string
- *
- */
-typedef struct
-{
-    char * directory;
-    char * filename;
-    char * extension;
-} C_PATHINFO;
-
-/**
- * @brief c_path_to_UNC converts a unixoid path to UNC format.
- *
- * It converts the '/' to '\' and prepends \\?\ to the path.
- *
- * A proper windows path has to have a drive letter, otherwise it is not
- * valid UNC.
- *
- * @param str The path to convert
- *
- * @return a pointer to the converted string. Caller has to free it.
- */
-const char *c_path_to_UNC(const char *str);
-
-/**
- * @brief c_utf8_path_to_locale converts a unixoid path to the locale aware format
- *
- * On windows, it converts to UNC and multibyte.
- * On Mac, it converts to the correct utf8 using iconv.
- * On Linux, it returns utf8
- *
- * @param str The path to convert
- *
- * @return a pointer to the converted string. Caller has to free it using the
- *         function c_free_locale_string.
- */
-mbchar_t* c_utf8_path_to_locale(const char *str);
-
-/**
- * }@
- */
-#endif /* _C_PATH_H */
diff --git a/csync/src/std/c_private.h b/csync/src/std/c_private.h
deleted file mode 100644 (file)
index 26bba70..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Dominik Schmidt <dev@dominik-schmidt.de>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _C_PRIVATE_H
-#define _C_PRIVATE_H
-
-#include "config_csync.h"
-
-/* cross platform defines */
-#include "config_csync.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef _WIN32
-#include <windows.h>
-#include <windef.h>
-#include <winbase.h>
-#include <wchar.h>
-#else
-#include <unistd.h>
-#endif
-
-#include <errno.h>
-
-#ifdef __MINGW32__
-#define EDQUOT 0
-#define ENODATA 0
-#ifndef S_IRGRP
-#define S_IRGRP 0
-#endif
-#ifndef S_IROTH
-#define S_IROTH 0
-#endif
-#ifndef S_IXGRP
-#define S_IXGRP 0
-#endif
-#ifndef S_IXOTH
-#define S_IXOTH 0
-#endif
-
-#define S_IFSOCK 10000 /* dummy val on Win32 */
-#define S_IFLNK 10001  /* dummy val on Win32 */
-
-#define O_NOFOLLOW 0
-#define O_NOCTTY 0
-
-#define uid_t int
-#define gid_t int
-#define nlink_t int
-#define getuid() 0
-#define geteuid() 0
-#elif defined(_WIN32)
-#define mode_t int
-#else
-#include <fcntl.h>
-#endif
-
-#ifndef ENODATA
-#define ENODATA EPIPE
-#endif
-
-
-#ifdef _WIN32
-typedef struct stat64 csync_stat_t;
-#define _FILE_OFFSET_BITS 64
-#else
-typedef struct stat csync_stat_t;
-#endif
-
-#ifndef O_NOATIME
-#define O_NOATIME 0
-#endif
-
-#ifndef ENODATA
-#define ENODATA EBADF
-#endif
-
-#if !defined(HAVE_ASPRINTF)
-#if defined(HAVE___MINGW_ASPRINTF)
-#define asprintf __mingw_asprintf
-#else
-#include "asprintf.h"
-#endif
-#endif
-
-#ifndef HAVE_STRERROR_R
-#define strerror_r(errnum, buf, buflen) snprintf(buf, buflen, "%s", strerror(errnum))
-#endif
-
-#ifndef HAVE_LSTAT
-#define lstat _stat
-#endif
-
-/* tchar definitions for clean win32 filenames */
-#ifndef _UNICODE
-#define _UNICODE
-#endif
-
-#if defined _WIN32 && defined _UNICODE
-typedef  wchar_t         mbchar_t;
-#define _topen           _wopen
-#define _tdirent         _wdirent
-#define _topendir        _wopendir
-#define _tclosedir       _wclosedir
-#define _treaddir        _wreaddir
-#define _trewinddir      _wrewinddir
-#define _ttelldir        _wtelldir
-#define _tseekdir        _wseekdir
-#define _tcreat          _wcreat
-#define _tstat           _wstat64
-#define _tfstat          _fstat64
-#define _tunlink         _wunlink
-#define _tmkdir(X,Y)     _wmkdir(X)
-#define _trmdir                 _wrmdir
-#define _tchmod          _wchmod
-#define _trewinddir      _wrewinddir
-#define _tchown(X, Y, Z)  0 /* no chown on Win32 */
-#define _tchdir          _wchdir
-#define _tgetcwd         _wgetcwd
-#else
-typedef char           mbchar_t;
-#define _tdirent       dirent
-#define _topen         open
-#define _topendir      opendir
-#define _tclosedir     closedir
-#define _treaddir      readdir
-#define _trewinddir    rewinddir
-#define _ttelldir      telldir
-#define _tseekdir      seekdir
-#define _tcreat        creat
-#define _tstat         lstat
-#define _tfstat        fstat
-#define _tunlink       unlink
-#define _tmkdir(X,Y)   mkdir(X,Y)
-#define _trmdir               rmdir
-#define _tchmod        chmod
-#define _trewinddir    rewinddir
-#define _tchown(X,Y,Z) chown(X,Y,Z)
-#define _tchdir        chdir
-#define _tgetcwd       getcwd
-#endif
-
-/* FIXME: Implement TLS for OS X */
-#if defined(__GNUC__) && !defined(__APPLE__)
-# define CSYNC_THREAD __thread
-#elif defined(_MSC_VER)
-# define CSYNC_THREAD __declspec(thread)
-#else
-# define CSYNC_THREAD
-#endif
-
-#endif //_C_PRIVATE_H
-
-/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/csync/src/std/c_rbtree.c b/csync/src/std/c_rbtree.c
deleted file mode 100644 (file)
index 9a38fd0..0000000
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2003-2004 by Andrew Suffield <asuffield@debian.org>
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * This code was originally released under GPL but Andrew Suffield agreed to
- * change it to LGPL.
- */
-
-/*
- * static function don't have NULL pointer checks, segfaults are intended.
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include "c_alloc.h"
-#include "c_rbtree.h"
-
-#define NIL &_sentinel /* all leafs are sentinels */
-static c_rbnode_t _sentinel = {NULL, NIL, NIL, NULL, NULL, BLACK};
-
-void c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_rbtree_compare_func *data_compare) {
-  assert(rbtree);
-  assert(key_compare);
-  assert(data_compare);
-
-  c_rbtree_t *tree = NULL;
-
-  tree = c_malloc(sizeof(*tree));
-  tree->root = NIL;
-  tree->key_compare = key_compare;
-  tree->data_compare = data_compare;
-  tree->size = 0;
-
-  *rbtree = tree;
-}
-
-static c_rbnode_t *_rbtree_subtree_dup(const c_rbnode_t *node, c_rbtree_t *new_tree, c_rbnode_t *new_parent) {
-  c_rbnode_t *new_node = NULL;
-
-  new_node = (c_rbnode_t*) c_malloc(sizeof(c_rbnode_t));
-
-  new_node->tree = new_tree;
-  new_node->data = node->data;
-  new_node->color = node->color;
-  new_node->parent = new_parent;
-
-  if (node->left == NIL) {
-    new_node->left = NIL;
-  } else {
-    new_node->left = _rbtree_subtree_dup(node->left, new_tree, new_node);
-  }
-
-  if (node->right == NIL) {
-    new_node->right = NIL;
-  } else {
-    new_node->right = _rbtree_subtree_dup(node->right, new_tree, new_node);
-  }
-
-  return new_node;
-}
-
-c_rbtree_t *c_rbtree_dup(const c_rbtree_t *tree) {
-  c_rbtree_t *new_tree = NULL;
-
-  new_tree = (c_rbtree_t*) c_malloc(sizeof(c_rbtree_t));
-
-  new_tree->key_compare = tree->key_compare;
-  new_tree->data_compare = tree->data_compare;
-  new_tree->size = tree->size;
-  new_tree->root = _rbtree_subtree_dup(tree->root, new_tree, NULL);
-
-  return new_tree;
-}
-
-static int _rbtree_subtree_free(c_rbnode_t *node) {
-  assert(node);
-
-  if (node->left != NIL) {
-    if (_rbtree_subtree_free(node->left) < 0) {
-      /* TODO: set errno? ECANCELED? */
-      return -1;
-    }
-  }
-
-  if (node->right != NIL) {
-    if (_rbtree_subtree_free(node->right) < 0) {
-      /* TODO: set errno? ECANCELED? */
-      return -1;
-    }
-  }
-
-  SAFE_FREE(node);
-
-  return 0;
-}
-
-int c_rbtree_free(c_rbtree_t *tree) {
-  if (tree == NULL) {
-    errno = EINVAL;
-    return -1;
-  }
-
-  if (tree->root != NIL) {
-    _rbtree_subtree_free(tree->root);
-  }
-
-  SAFE_FREE(tree);
-
-  return 0;
-}
-
-static int _rbtree_subtree_walk(c_rbnode_t *node, void *data, c_rbtree_visit_func *visitor) {
-  assert(node);
-  assert(data);
-  assert(visitor);
-
-  if (node == NIL) {
-    return 0;
-  }
-
-  if (_rbtree_subtree_walk(node->left, data, visitor) < 0) {
-    return -1;
-  }
-
-  if ((*visitor)(node->data, data) < 0) {
-    return -1;
-  }
-
-  if (_rbtree_subtree_walk(node->right, data, visitor) < 0) {
-    return -1;
-  }
-
-  return 0;
-}
-
-int c_rbtree_walk(c_rbtree_t *tree, void *data, c_rbtree_visit_func *visitor) {
-  if (tree == NULL || data == NULL || visitor == NULL) {
-    errno = EINVAL;
-    return -1;
-  }
-
-  if (_rbtree_subtree_walk(tree->root, data, visitor) < 0) {
-    return -1;
-  }
-
-  return 0;
-}
-
-static c_rbnode_t *_rbtree_subtree_head(c_rbnode_t *node) {
-  assert(node);
-
-  if (node == NIL) {
-    return node;
-  }
-
-  while (node->left != NIL) {
-    node = node->left;
-  }
-
-  return node;
-}
-
-static c_rbnode_t *_rbtree_subtree_tail(c_rbnode_t *node) {
-  assert(node);
-
-  if (node == NIL) {
-    return node;
-  }
-
-  while (node->right != NIL) {
-    node = node->right;
-  }
-
-  return node;
-}
-
-c_rbnode_t *c_rbtree_head(c_rbtree_t *tree) {
-  c_rbnode_t *node = NULL;
-
-  if (tree == NULL) {
-    errno = EINVAL;
-    return NULL;
-  }
-
-  node = _rbtree_subtree_head(tree->root);
-
-  return node != NIL ? node : NULL;
-}
-
-c_rbnode_t *c_rbtree_tail(c_rbtree_t *tree) {
-  c_rbnode_t *node = NULL;
-
-  if (tree == NULL) {
-    errno = EINVAL;
-    return NULL;
-  }
-
-  node = _rbtree_subtree_tail(tree->root);
-
-  return node != NIL ? node : NULL;
-}
-
-c_rbnode_t *c_rbtree_node_next(c_rbnode_t *node) {
-  c_rbnode_t *parent = NULL;
-
-  if (node == NULL) {
-    errno = EINVAL;
-    return NULL;
-  }
-
-  if (node->right != NIL) {
-    c_rbnode_t *next = NULL;
-    next = _rbtree_subtree_head(node->right);
-
-    return next != NIL ? next : NULL;
-  }
-
-  parent = node->parent;
-  while (parent && node == parent->right) {
-    node = parent;
-    parent = node->parent;
-  }
-
-  return parent != NULL ? parent : NULL;
-}
-
-c_rbnode_t *c_rbtree_node_prev(c_rbnode_t *node) {
-  c_rbnode_t *parent = NULL;
-
-  if (node == NULL) {
-    return NULL;
-  }
-
-  if (node->left != NIL) {
-    c_rbnode_t *prev = NULL;
-    prev = _rbtree_subtree_tail(node->left);
-    return prev != NIL ? prev : NULL;
-  }
-
-  parent = node->parent;
-  while (parent && node == parent->left) {
-    node = parent;
-    parent = node->parent;
-  }
-
-  return parent != NULL ? parent : NULL;
-}
-
-c_rbnode_t *c_rbtree_find(c_rbtree_t *tree, const void *key) {
-  int cmp = 0;
-  c_rbnode_t *node = NULL;
-
-  if (tree == NULL) {
-    errno = EINVAL;
-    return NULL;
-  }
-  node = tree->root;
-
-  while (node != NIL) {
-    cmp = tree->key_compare(key, node->data);
-    if (cmp == 0) {
-      return node;
-    }
-
-    if (cmp < 0) {
-      node = node->left;
-    } else {
-        node = node->right;
-    }
-  }
-
-  return NULL;
-}
-
-static void _rbtree_subtree_left_rotate(c_rbnode_t *x) {
-  c_rbnode_t *y = NULL;
-
-  assert(x);
-
-  y = x->right;
-
-  /* establish x-right link */
-  x->right = y->left;
-
-  if (y->left != NIL) {
-    y->left->parent = x;
-  }
-
-  /* establish y->parent link */
-  if (y != NIL) {
-    y->parent = x->parent;
-  }
-
-  if (x->parent) {
-    if (x == x->parent->left) {
-      x->parent->left = y;
-    } else {
-      x->parent->right = y;
-    }
-  } else {
-    x->tree->root = y;
-  }
-
-  /* link x and y */
-  y->left = x;
-  if (x != NIL) {
-    x->parent = y;
-  }
-}
-
-/* rotat node x to the right */
-static void _rbtree_subtree_right_rotate(c_rbnode_t *x) {
-  c_rbnode_t *y = NULL;
-
-  assert(x);
-
-  y = x->left;
-
-  /* establish x->left link */
-  x->left = y->right;
-
-  if (y->right != NIL) {
-    y->right->parent = x;
-  }
-
-  /* establish y->parent link */
-  if (y != NIL) {
-    y->parent = x->parent;
-  }
-
-  if (x->parent) {
-    if (x == x->parent->right) {
-        x->parent->right = y;
-    } else {
-      x->parent->left = y;
-    }
-  } else {
-    x->tree->root = y;
-  }
-
-  /* link x and y */
-  y->right = x;
-  if (x != NIL) {
-    x->parent = y;
-  }
-}
-
-int c_rbtree_insert(c_rbtree_t *tree, void *data) {
-  int cmp = 0;
-  c_rbnode_t *current = NULL;
-  c_rbnode_t *parent = NULL;
-  c_rbnode_t *x = NULL;
-
-  if (tree == NULL) {
-    errno = EINVAL;
-    return -1;
-  }
-
-  /* First we do a classic binary tree insert */
-  current = tree->root;
-  parent = NULL;
-
-  while (current != NIL) {
-    cmp = tree->data_compare(data, current->data);
-    parent = current;
-    if (cmp == 0) {
-      return 1;
-    } else if (cmp < 0) {
-      current = current->left;
-    } else {
-      current = current->right;
-    }
-  }
-
-  x = (c_rbnode_t *) c_malloc(sizeof(c_rbnode_t));
-
-  x->tree = tree;
-  x->data = data;
-  x->parent = parent;
-  x->left = NIL;
-  x->right = NIL;
-  x->color = RED;
-
-  if (parent) {
-    /* Note that cmp still contains the comparison of data with
-     * parent->data, from the last pass through the loop above
-     */
-    if (cmp < 0) {
-        parent->left = x;
-    } else {
-        parent->right = x;
-    }
-  } else {
-    tree->root = x;
-  }
-
-  /* Insert fixup - check red-black properties */
-  while (x != tree->root && x->parent->color == RED) {
-    /* we have a violation */
-    if (x->parent == x->parent->parent->left) {
-      c_rbnode_t *y = NULL;
-
-      y = x->parent->parent->right;
-      if (y->color == RED) {
-        x->parent->color = BLACK;
-        y->color = BLACK;
-        x->parent->parent->color = RED;
-        x = x->parent->parent;
-      } else {
-        /* uncle is back */
-        if (x == x->parent->right) {
-          /* make x a left child */
-          x = x->parent;
-          _rbtree_subtree_left_rotate(x);
-        }
-        x->parent->color = BLACK;
-        x->parent->parent->color = RED;
-        _rbtree_subtree_right_rotate(x->parent->parent);
-      }
-    } else {
-      c_rbnode_t *y = NULL;
-
-      y = x->parent->parent->left;
-      if (y->color == RED) {
-        x->parent->color = BLACK;
-        y->color = BLACK;
-        x->parent->parent->color = RED;
-        x = x->parent->parent;
-      } else {
-        /* uncle is back */
-        if (x == x->parent->left) {
-          x = x->parent;
-          _rbtree_subtree_right_rotate(x);
-        }
-        x->parent->color = BLACK;
-        x->parent->parent->color = RED;
-        _rbtree_subtree_left_rotate(x->parent->parent);
-      }
-    }
-  } /* end while */
-  tree->root->color = BLACK;
-
-  tree->size++;
-
-  return 0;
-}
-
-int c_rbtree_node_delete(c_rbnode_t *node) {
-  c_rbtree_t *tree;
-  c_rbnode_t *y;
-  c_rbnode_t *x;
-
-  if (node == NULL || node == NIL) {
-    errno = EINVAL;
-    return -1;
-  }
-
-  tree = node->tree;
-
-  if (node->left == NIL || node->right == NIL) {
-    /* y has a NIL node as a child */
-    y = node;
-  } else {
-    /* find tree successor with a NIL node as a child */
-    y = node;
-    while(y->left != NIL) {
-      y = y->left;
-    }
-  }
-
-  /* x is y's only child */
-  if (y->left != NIL) {
-    x = y->left;
-  } else {
-    x = y->right;
-  }
-
-  /* remove y from the parent chain */
-  x->parent = y->parent;
-
-  if (y->parent) {
-    if (y == y->parent->left) {
-        y->parent->left = x;
-    } else {
-      y->parent->right = x;
-    }
-  } else {
-    y->tree->root = x;
-  }
-
-  /* If y is not the node we're deleting, splice it in place of that
-   * node
-   *
-   * The traditional code would call for us to simply copy y->data, but
-   * that would invalidate the wrong pointer - there might be external
-   * references to this node, and we must preserve its address.
-   */
-  if (y != node) {
-    /* Update y */
-    y->parent = node->parent;
-    y->left = node->left;
-    y->right = node->right;
-
-    /* Update the children and the parent */
-    if (y->left != NIL) {
-        y->left->parent = y;
-    }
-    if (y->right != NIL) {
-      y->right->parent = y;
-    }
-    if (y->parent != NULL) {
-      if (node == y->parent->left) {
-        y->parent->left = y;
-      } else {
-        y->parent->right = y;
-      }
-    } else {
-      y->tree->root = y;
-    }
-  }
-
-  if (y->color == BLACK) {
-    while (x != y->tree->root && x->color == BLACK) {
-      if (x == x->parent->left) {
-        c_rbnode_t *w = NULL;
-
-        w = x->parent->right;
-
-        if (w->color == RED) {
-          w->color = BLACK;
-          x->parent->color = RED;
-          _rbtree_subtree_left_rotate(x->parent);
-          w = x->parent->right;
-        }
-
-        if (w->left->color == BLACK && w->right->color == BLACK) {
-          w->color = RED;
-          x = x->parent;
-        } else {
-          if (w->right->color == BLACK) {
-            w->left->color = BLACK;
-            w->color = RED;
-            _rbtree_subtree_right_rotate(w);
-            w = x->parent->right;
-          }
-          w->color = x->parent->color;
-          x->parent->color = BLACK;
-          w->right->color = BLACK;
-          _rbtree_subtree_left_rotate(x->parent);
-          x = y->tree->root;
-        }
-      } else {
-        c_rbnode_t *w = NULL;
-
-        w = x->parent->left;
-        if (w->color == RED) {
-          w->color = BLACK;
-          x->parent->color = RED;
-          _rbtree_subtree_right_rotate(x->parent);
-          w = x->parent->left;
-        }
-
-        if (w->right->color == BLACK && w->left->color == BLACK) {
-          w->color = RED;
-          x = x->parent;
-        } else {
-          if (w->left->color == BLACK) {
-            w->right->color = BLACK;
-            w->color = RED;
-            _rbtree_subtree_left_rotate(w);
-            w = x->parent->left;
-          }
-          w->color = x->parent->color;
-          x->parent->color = BLACK;
-          w->left->color = BLACK;
-          _rbtree_subtree_right_rotate(x->parent);
-          x = y->tree->root;
-        }
-      }
-    }
-    x->color = BLACK;
-  } /* end if: y->color == BLACK */
-
-  /* node has now been spliced out of the tree */
-  SAFE_FREE(y);
-  tree->size--;
-
-  return 0;
-}
-
-static int _rbtree_subtree_check_black_height(c_rbnode_t *node) {
-  int left = 0;
-  int right = 0;
-
-  assert(node);
-
-  if (node == NIL) {
-    return 0;
-  }
-
-  left = _rbtree_subtree_check_black_height(node->left);
-  right = _rbtree_subtree_check_black_height(node->right);
-  if (left != right) {
-    return -1;
-  }
-
-  return left + (node->color == BLACK);
-}
-
-int c_rbtree_check_sanity(c_rbtree_t *tree) {
-  c_rbnode_t *node = NULL;
-  c_rbnode_t *prev = NULL;
-  c_rbnode_t *next = NULL;
-  c_rbnode_t *tail = NULL;
-  size_t size = 0;
-
-  if (tree == NULL) {
-    errno = EINVAL;
-    return -1;
-  }
-
-  if (! tree->key_compare || ! tree->data_compare) {
-    errno = EINVAL;
-    return -2;
-  }
-
-  /* Iterate the tree */
-  tail = c_rbtree_tail(tree);
-  for (node = c_rbtree_head(tree); node; node = next) {
-    if (node->tree != tree) {
-      return -4;
-    }
-
-    /* We should never see a nil while iterating */
-    if (node == NIL) {
-      return -5;
-    }
-
-    /* node == tree-root iff node->parent == NIL */
-    if (node == tree->root) {
-      if (node->parent != NULL) {
-        return -6;
-      }
-    } else {
-      if (node->parent == NULL) {
-        return -7;
-      }
-    }
-
-    /* Invertability of the iterate functions */
-    if (prev != c_rbtree_node_prev(node)) {
-      return -8;
-    }
-
-    /* Check the iteration sequence */
-    if (prev) {
-      if (tree->data_compare(prev->data, node->data) > 0) {
-        return -9;
-      }
-
-      /* And the other way around, to make sure data_compare is stable */
-      if (tree->data_compare(node->data, prev->data) < 0) {
-        return -10;
-      }
-    }
-
-    /* The binary tree property */
-    if (node->left != NIL) {
-      if (tree->data_compare(node->left->data, node->data) > 0) {
-        return -11;
-      }
-
-      if (tree->data_compare(node->data, node->left->data) < 0) {
-        return -11;
-      }
-    }
-
-    if (node->right != NIL) {
-      if (tree->data_compare(node->data, node->right->data) > 0) {
-        return -12;
-      }
-
-      if (tree->data_compare(node->right->data, node->data) < 0) {
-        return -13;
-      }
-    }
-
-    /* Red-black tree property 3: red nodes have black children */
-    if (node->color == RED) {
-      if (node->left->color == RED) {
-        return -14;
-      }
-      if (node->right->color == RED) {
-        return -15;
-      }
-    }
-
-    /* next == NULL if node == tail */
-    next = c_rbtree_node_next(node);
-    if (next) {
-      if (node == tail) {
-        return -16;
-      }
-    } else {
-      if (node != tail) {
-        return -17;
-      }
-    }
-
-    prev = node;
-    size++;
-  } /* end for loop */
-
-  if (size != tree->size) {
-    return -18;
-  }
-
-  if (_rbtree_subtree_check_black_height(tree->root) < 0) {
-    return -19;
-  }
-
-  return 0;
-}
diff --git a/csync/src/std/c_rbtree.h b/csync/src/std/c_rbtree.h
deleted file mode 100644 (file)
index 635458f..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2003-2004 by Andrew Suffield <asuffield@debian.org>
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file c_rbtree.h
- *
- * @brief Interface of the cynapses libc red-black tree implementation
- *
- * A red-black tree is a type of self-balancing binary search tree. It is
- * complex, but has good worst-case running time for its operations and is
- * efficient in practice: it can search, insert, and delete in O(log n)
- * time, where n is the number of elements in the tree.
- *
- * In red-black trees, the leaf nodes are not relevant and do not contain
- * data. Therefore we use a sentinal node to save memory. All references
- * from internal nodes to leaf nodes instead point to the sentinel node.
- *
- * In a red-black tree each node has a color attribute, the value of which
- * is either red or black. In addition to the ordinary requirements imposed
- * on binary search trees, the following additional requirements of any
- * valid red-black tree apply:
- *
- *    1. A node is either red or black.
- *    2. The root is black.
- *    3. All leaves are black, even when the parent is black
- *       (The leaves are the null children.)
- *    4. Both children of every red node are black.
- *    5. Every simple path from a node to a descendant leaf contains the same
- *       number of black nodes, either counting or not counting the null black
- *       nodes. (Counting or not counting the null black nodes does not affect
- *       the structure as long as the choice is used consistently.).
- *
- * These constraints enforce a critical property of red-black trees: that the
- * longest path from the root to a leaf is no more than twice as long as the
- * shortest path from the root to a leaf in that tree. The result is that the
- * tree is roughly balanced. Since operations such as inserting, deleting, and
- * finding values requires worst-case time proportional to the height of the
- * tree, this theoretical upper bound on the height allows red-black trees to
- * be efficient in the worst-case, unlike ordinary binary search trees.
- *
- * http://en.wikipedia.org/wiki/Red-black_tree
- *
- * @defgroup cynRBTreeInternals cynapses libc red-black tree functions
- * @ingroup cynLibraryAPI
- *
- * @{
- */
-#ifndef _C_RBTREE_H
-#define _C_RBTREE_H
-
-/* Forward declarations */
-struct c_rbtree_s; typedef struct c_rbtree_s c_rbtree_t;
-struct c_rbnode_s; typedef struct c_rbnode_s c_rbnode_t;
-
-/**
- * Define the two colors for the red-black tree
- */
-enum xrbcolor_e { BLACK = 0, RED }; typedef enum xrbcolor_e xrbcolor_t;
-
-/**
- * @brief Callback function to compare a key with the data from a
- *        red-black tree node.
- *
- * @param key   key as a generic pointer
- * @param data  data as a generic pointer
- *
- * @return   It returns an integer less than, equal to, or greater than zero
- *           depending on the key or data you use. The function is similar
- *           to strcmp().
- */
-typedef int c_rbtree_compare_func(const void *key, const void *data);
-
-/**
- * @brief Visit function for the c_rbtree_walk() function.
- *
- * This function will be called by c_rbtree_walk() for every node. It is up to
- * the developer what the function does. The fist parameter is a node object
- * the second can be of any kind.
- *
- * @param obj    The node data that will be passed by c_rbtree_walk().
- * @param data   Generic data pointer.
- *
- * @return 0 on success, < 0 on error. You should set errno.
- *
- */
-typedef int c_rbtree_visit_func(void *, void *);
-
-/**
- * Structure that represents a red-black tree
- */
-struct c_rbtree_s {
-  c_rbnode_t *root;
-  c_rbtree_compare_func *key_compare;
-  c_rbtree_compare_func *data_compare;
-  size_t size;
-};
-
-/**
- * Structure that represents a node of a red-black tree
- */
-struct c_rbnode_s {
-  c_rbtree_t *tree;
-  c_rbnode_t *left;
-  c_rbnode_t *right;
-  c_rbnode_t *parent;
-  void *data;
-  xrbcolor_t color;
-};
-
-/**
- * @brief Create the red-black tree
- *
- * @param rbtree        The pointer to assign the allocated memory.
- *
- * @param key_compare   Callback function to compare a key with the data
- *                      inside a reb-black tree node.
- *
- * @param data_compare  Callback function to compare a key as data with thee
- *                      data inside a red-black tree node.
- */
-void c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_rbtree_compare_func *data_compare);
-
-/**
- * @brief Duplicate a red-black tree.
- *
- * @param tree Tree to duplicate.
- *
- * @return   Pointer to a new allocated duplicated rbtree. NULL if an error
- *           occurred.
- */
-c_rbtree_t *c_rbtree_dup(const c_rbtree_t *tree);
-
-/**
- * @brief Free the structure of a red-black tree.
- *
- * You should call c_rbtree_destroy() before you call this function.
- *
- * @param tree  The tree to free.
- *
- * @return   0 on success, less than 0 if an error occurred.
- */
-int c_rbtree_free(c_rbtree_t *tree);
-
-/**
- * @brief Destroy the content and the nodes of an red-black tree.
- *
- * This is far from the most efficient way to walk a tree, but it is
- * the *safest* way to destroy a tree - the destructor can do almost
- * anything (as long as it does not create an infinite loop) to the
- * tree structure without risk.
- *
- * If for some strange reason you need a faster destructor (think
- * twice - speed and memory deallocation don't mix well) then consider
- * stashing an llist of dataects and destroying that instead, and just
- * using c_rbtree_free() on your tree.
- *
- * @param T            The tree to destroy.
- * @param DESTRUCTOR   The destructor to call on a node to destroy.
- */
-#define c_rbtree_destroy(T, DESTRUCTOR)                 \
-  do {                                                  \
-    if (T) {                                            \
-      c_rbnode_t *_c_rbtree_temp;                       \
-      while ((_c_rbtree_temp = c_rbtree_head(T))) {     \
-        (DESTRUCTOR)(_c_rbtree_temp->data);             \
-        if (_c_rbtree_temp == c_rbtree_head(T)) {       \
-          c_rbtree_node_delete(_c_rbtree_temp);         \
-        }                                               \
-      }                                                 \
-    }                                                   \
-    SAFE_FREE(T);                                       \
-  } while (0);
-
-/**
- * @brief Inserts a node into a red black tree.
- *
- * @param tree  The red black tree to insert the node.
- * @param data  The data to insert into the tree.
- *
- * @return  0 on success, 1 if a duplicate has been found and < 0 if an error
- *          occurred with errno set.
- *          EINVAL if a null pointer has been passed as the tree.
- *          ENOMEM if there is no memory left.
- */
-int c_rbtree_insert(c_rbtree_t *tree, void *data);
-
-/**
- * @brief Find a node in a red-black tree.
- *
- * c_rbtree_find() is searching for the given  key  in a red-black tree and
- * returns the node if the key has been found.
- *
- * @param tree   The tree to search.
- * @param key    The key to search for.
- *
- * @return   If the key was found the node will be returned. On error NULL
- *           will be returned.
- */
-c_rbnode_t *c_rbtree_find(c_rbtree_t *tree, const void *key);
-
-/**
- * @brief Get the head of the red-black tree.
- *
- * @param tree   The tree to get the head for.
- *
- * @return   The head node. NULL if an error occurred.
- */
-c_rbnode_t *c_rbtree_head(c_rbtree_t *tree);
-
-/**
- * @brief Get the tail of the red-black tree.
- *
- * @param tree   The tree to get the tail for.
- *
- * @return   The tail node. NULL if an error occurred.
- */
-c_rbnode_t *c_rbtree_tail(c_rbtree_t *tree);
-
-/**
- * @brief Get the size of the red-black tree.
- *
- * @param T  The tree to get the size from.
- *
- * @return  The size of the red-black tree.
- */
-#define c_rbtree_size(T) (T) == NULL ? 0 : ((T)->size)
-
-/**
- * @brief Walk over a red-black tree.
- * 
- * Walk over a red-black tree calling a visitor function for each node found.
- *
- * @param tree     Tree to walk.
- * @param data     Data which should be passed to the visitor function.
- * @param visitor  Visitor function. This will be called for each node passed.
- *
- * @return   0 on sucess, less than 0 if an error occurred.
- */
-int c_rbtree_walk(c_rbtree_t *tree, void *data, c_rbtree_visit_func *visitor);
-
-/**
- * @brief Delete a node in a red-black tree.
- *
- * @param node  Node which should be deleted.
- *
- * @return  0 on success, -1 if an error occurred.
- */
-int c_rbtree_node_delete(c_rbnode_t *node);
-
-/**
- * @brief Get the next node.
- *
- * @param node  The node of which you want the next node.
- *
- * @return  The next node, NULL if an error occurred.
- */
-c_rbnode_t *c_rbtree_node_next(c_rbnode_t *node);
-
-/**
- * @brief Get the previous node.
- *
- * @param node  The node of which you want the previous node.
- *
- * @return  The previous node, NULL if an error occurred.
- */
-c_rbnode_t *c_rbtree_node_prev(c_rbnode_t *node);
-
-/**
- * @brief Get the data of a node.
- *
- * @param N  The node to get the data from.
- *
- * @return  The data, NULL if an error occurred.
- */
-#define c_rbtree_node_data(N) ((N) ? ((N)->data) : NULL)
-
-/**
- * @brief Perform a sanity check for a red-black tree.
- *
- * This is mostly for testing purposes.
- *
- * @param tree  The tree to check.
- *
- * @return 0 on success, less than 0 if an error occurred.
- */
-int c_rbtree_check_sanity(c_rbtree_t *tree);
-
-/**
- * }@
- */
-#endif /* _C_RBTREE_H */
diff --git a/csync/src/std/c_string.c b/csync/src/std/c_string.c
deleted file mode 100644 (file)
index 8929f24..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <limits.h>
-#include <sys/types.h>
-#include <wchar.h>
-
-#include "c_string.h"
-#include "c_path.h"
-#include "c_alloc.h"
-#include "c_macro.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-int c_strncasecmp(const char *a, const char *b, size_t n) {
-#ifdef _WIN32
-    return _strnicmp(a, b, n);
-#else
-    return strncasecmp(a, b, n);
-#endif
-}
-
-int c_streq(const char *a, const char *b) {
-  register const char *s1 = a;
-  register const char *s2 = b;
-
-  if (s1 == NULL || s2 ==  NULL) {
-    return 0;
-  }
-
-  while (*s1 == *s2++) {
-    if (*s1++ == '\0') {
-      return 1;
-    }
-  }
-
-  return 0;
-}
-
-c_strlist_t *c_strlist_new(size_t size) {
-  c_strlist_t *strlist = NULL;
-
-  if (size == 0) {
-    errno = EINVAL;
-    return NULL;
-  }
-
-  strlist = c_malloc(sizeof(c_strlist_t));
-  if (strlist == NULL) {
-    return NULL;
-  }
-
-  strlist->vector = (char **) c_malloc(size * sizeof(char *));
-  strlist->count = 0;
-  strlist->size = size;
-
-  return strlist;
-}
-
-c_strlist_t *c_strlist_expand(c_strlist_t *strlist, size_t size) {
-  if (strlist == NULL || size == 0) {
-    errno = EINVAL;
-    return NULL;
-  }
-
-  if (strlist->size >= size) {
-    return strlist;
-  }
-
-  strlist->vector = (char **) c_realloc(strlist->vector, size * sizeof(char *));
-  if (strlist->vector == NULL) {
-    return NULL;
-  }
-
-  strlist->size = size;
-
-  return strlist;
-}
-
-int c_strlist_add(c_strlist_t *strlist, const char *string) {
-  if (strlist == NULL || string == NULL) {
-    return -1;
-  }
-
-  if (strlist->count < strlist->size) {
-    strlist->vector[strlist->count] = c_strdup(string);
-    if (strlist->vector[strlist->count] == NULL) {
-      return -1;
-    }
-    strlist->count++;
-  } else {
-    errno = ENOBUFS;
-    return -1;
-  }
-
-  return 0;
-}
-
-int c_strlist_add_grow(c_strlist_t **strlist, const char *string) {
-  if (*strlist == NULL) {
-    *strlist = c_strlist_new(32);
-    if (*strlist == NULL) {
-      return -1;
-    }
-  }
-
-  if ((*strlist)->count == (*strlist)->size) {
-    c_strlist_t *list = c_strlist_expand(*strlist, 2 * (*strlist)->size);
-    if (list == NULL) {
-      return -1;
-    }
-    *strlist = list;
-  }
-
-  return c_strlist_add(*strlist, string);
-}
-
-void c_strlist_clear(c_strlist_t *strlist) {
-  size_t i = 0;
-
-  if (strlist == NULL) {
-    return;
-  }
-
-  for (i = 0; i < strlist->count; i++) {
-    SAFE_FREE(strlist->vector[i]);
-  }
-
-  strlist->count = 0;
-}
-
-void c_strlist_destroy(c_strlist_t *strlist) {
-
-  if (strlist == NULL) {
-    return;
-  }
-
-  c_strlist_clear(strlist);
-  SAFE_FREE(strlist->vector);
-  SAFE_FREE(strlist);
-}
diff --git a/csync/src/std/c_string.h b/csync/src/std/c_string.h
deleted file mode 100644 (file)
index 304c598..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file c_string.h
- *
- * @brief Interface of the cynapses string implementations
- *
- * @defgroup cynStringInternals cynapses libc string functions
- * @ingroup cynLibraryAPI
- *
- * @{
- */
-#ifndef _C_STR_H
-#define _C_STR_H
-
-#include "c_private.h"
-#include "c_macro.h"
-
-#include <stdlib.h>
-
-struct c_strlist_s; typedef struct c_strlist_s c_strlist_t;
-
-/**
- * @brief Structure for a stringlist
- *
- * Using a for loop you can access the strings saved in the vector.
- *
- * c_strlist_t strlist;
- * int i;
- * for (i = 0; i < strlist->count; i++) {
- *   printf("value: %s", strlist->vector[i];
- * }
- */
-struct c_strlist_s {
-  /** The string vector */
-  char **vector;
-  /** The count of the strings saved in the vector */
-  size_t count;
-  /** Size of strings allocated */
-  size_t size;
-};
-
-/**
- * @brief Compare to strings case insensitively.
- *
- * @param a  First string to compare.
- * @param b  Second string to compare.
- * @param n  Max comparison length.
- *
- * @return see strncasecmp
- */
-int c_strncasecmp(const char *a, const char *b, size_t n);
-
-/**
- * @brief Compare to strings if they are equal.
- *
- * @param a  First string to compare.
- * @param b  Second string to compare.
- *
- * @return  1 if they are equal, 0 if not.
- */
-int c_streq(const char *a, const char *b);
-
-/**
- * @brief Create a new stringlist.
- *
- * @param size  Size to allocate.
- *
- * @return  Pointer to the newly allocated stringlist. NULL if an error occured.
- */
-c_strlist_t *c_strlist_new(size_t size);
-
-/**
- * @brief Expand the stringlist
- *
- * @param strlist  Stringlist to expand
- * @param size     New size of the strlinglist to expand
- *
- * @return  Pointer to the expanded stringlist. NULL if an error occured.
- */
-c_strlist_t *c_strlist_expand(c_strlist_t *strlist, size_t size);
-
-/**
- * @brief  Add a string to the stringlist.
- *
- * Duplicates the string and stores it in the stringlist.
- *
- * @param strlist  Stringlist to add the string.
- * @param string   String to add.
- *
- * @return  0 on success, less than 0 and errno set if an error occured.
- *          ENOBUFS if the list is full.
- */
-int c_strlist_add(c_strlist_t *strlist, const char *string);
-
-/**
- * @brief  Add a string to the stringlist, growing it if necessary
- *
- * Duplicates the string and stores it in the stringlist.
- * It also initializes the stringlist if it starts out as null.
- *
- * @param strlist  Stringlist to add the string.
- * @param string   String to add.
- *
- * @return  0 on success, less than 0 and errno set if an error occured.
- */
-int c_strlist_add_grow(c_strlist_t **strlist, const char *string);
-
-/**
- * @brief Removes all strings from the list.
- *
- * Frees the strings.
- *
- * @param strlist  Stringlist to clear
- */
-void c_strlist_clear(c_strlist_t *strlist);
-
-/**
- * @brief Destroy the memory of the stringlist.
- *
- * Frees the strings and the stringlist.
- *
- * @param strlist  Stringlist to destroy
- */
-void c_strlist_destroy(c_strlist_t *strlist);
-
-/**
- * @brief Convert a platform locale string to utf8.
- *
- * This function is part of the multi platform abstraction of basic file
- * operations to handle various platform encoding correctly.
- *
- * Instead of using the standard file operations the multi platform aliases
- * defined in c_private.h have to be used instead.
- *
- * To convert path names returned by these functions to the internally used
- * utf8 format this function has to be used. The returned string has to
- * be freed by c_free_locale_string(). On some platforms this method allocates
- * memory and on others not but it has never to be cared about.
- *
- * @param  str     The multibyte encoded string to convert
- *
- * @return The malloced converted string or NULL on error.
- *
- * @see c_free_locale_string()
- * @see c_utf8_to_locale()
- *
- */
- char*   c_utf8_from_locale(const mbchar_t *str);
-
-/**
- * @brief Convert a utf8 encoded string to platform specific locale.
- *
- * This function is part of the multi platform abstraction of basic file
- * operations to handle various platform encoding correctly.
- *
- * Instead of using the standard file operations the multi platform aliases
- * defined in c_private.h have to be used instead.
- *
- * To convert strings as input for the cross platform functions from the
- * internally used utf8 format, this function has to be used.
- * The returned string has to be freed by c_free_locale_string(). On some
- * platforms this method allocates memory and on others not but it has never
- * sto be cared about.
- *
- * If the string to convert is a path, consider using c_utf8_path_to_locale().
- *
- * @param  str     The utf8 string to convert.
- *
- * @return The malloced converted multibyte string or NULL on error.
- *
- * @see c_free_locale_string()
- * @see c_utf8_from_locale()
- *
- */
-mbchar_t* c_utf8_string_to_locale(const char *wstr);
-
-/**
- * @brief Free buffer malloced by c_utf8_from_locale or c_utf8_to_locale().
- *
- * This function is part of the multi platform abstraction of basic file
- * operations to handle various platform encoding correctly.
- *
- * Instead of using the standard file operations the multi platform aliases
- * defined in c_private.h have to be used instead.
- *
- * This function frees the memory that was allocated by a previous call to
- * c_utf8_to_locale() or c_utf8_from_locale().
- *
- * @param  buf     The buffer to free.
- *
- * @see c_utf8_from_locale(), c_utf8_to_locale()
- *
- */
-#define c_free_locale_string(x) SAFE_FREE(x)
-
-
-/**
- * }@
- */
-#endif /* _C_STR_H */
-
diff --git a/csync/src/std/c_time.c b/csync/src/std/c_time.c
deleted file mode 100644 (file)
index ad43fed..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * c_time - time functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-#include "c_private.h"
-#include "c_string.h"
-
-#include "c_path.h"
-#include "c_time.h"
-
-#ifndef _WIN32
-#include <sys/time.h>
-#endif
-
-struct timespec c_tspecdiff(struct timespec time1, struct timespec time0) {
-  struct timespec ret;
-  int xsec = 0;
-  int sign = 1;
-
-  if (time0.tv_nsec > time1.tv_nsec) {
-    xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
-    time0.tv_nsec -= (long int) (1E9 * xsec);
-    time0.tv_sec += xsec;
-  }
-
-  if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
-    xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
-    time0.tv_nsec += (long int) (1E9 * xsec);
-    time0.tv_sec -= xsec;
-  }
-
-  ret.tv_sec = time1.tv_sec - time0.tv_sec;
-  ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
-
-  if (time1.tv_sec < time0.tv_sec) {
-    sign = -1;
-  }
-
-  ret.tv_sec = ret.tv_sec * sign;
-
-  return ret;
-}
-
-double c_secdiff(struct timespec clock1, struct timespec clock0) {
-  double ret;
-  struct timespec diff;
-
-  diff = c_tspecdiff(clock1, clock0);
-
-  ret = diff.tv_sec;
-  ret += (double) diff.tv_nsec / (double) 1E9;
-
-  return ret;
-}
-
-
-#ifdef HAVE_UTIMES
-int c_utimes(const char *uri, const struct timeval *times) {
-    mbchar_t *wuri = c_utf8_path_to_locale(uri);
-    int ret = utimes(wuri, times);
-    c_free_locale_string(wuri);
-    return ret;
-}
-#else // HAVE_UTIMES
-
-#ifdef _WIN32
-// implementation for utimes taken from KDE mingw headers
-
-#include <errno.h>
-#include <wtypes.h>
-#define CSYNC_SECONDS_SINCE_1601 11644473600LL
-#define CSYNC_USEC_IN_SEC            1000000LL
-//after Microsoft KB167296
-static void UnixTimevalToFileTime(struct timeval t, LPFILETIME pft)
-{
-    LONGLONG ll;
-    ll = Int32x32To64(t.tv_sec, CSYNC_USEC_IN_SEC*10) + t.tv_usec*10 + CSYNC_SECONDS_SINCE_1601*CSYNC_USEC_IN_SEC*10;
-    pft->dwLowDateTime = (DWORD)ll;
-    pft->dwHighDateTime = ll >> 32;
-}
-
-int c_utimes(const char *uri, const struct timeval *times) {
-    FILETIME LastAccessTime;
-    FILETIME LastModificationTime;
-    HANDLE hFile;
-
-    mbchar_t *wuri = c_utf8_path_to_locale( uri );
-
-    if(times) {
-        UnixTimevalToFileTime(times[0], &LastAccessTime);
-        UnixTimevalToFileTime(times[1], &LastModificationTime);
-    }
-    else {
-        GetSystemTimeAsFileTime(&LastAccessTime);
-        GetSystemTimeAsFileTime(&LastModificationTime);
-    }
-
-    hFile=CreateFileW(wuri, FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
-                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, NULL);
-    if(hFile==INVALID_HANDLE_VALUE) {
-        switch(GetLastError()) {
-            case ERROR_FILE_NOT_FOUND:
-                errno=ENOENT;
-                break;
-            case ERROR_PATH_NOT_FOUND:
-            case ERROR_INVALID_DRIVE:
-                errno=ENOTDIR;
-                break;
-                /*case ERROR_WRITE_PROTECT:   //CreateFile sets ERROR_ACCESS_DENIED on read-only devices
-                 *                errno=EROFS;
-                 *                break;*/
-                case ERROR_ACCESS_DENIED:
-                    errno=EACCES;
-                    break;
-                default:
-                    errno=ENOENT;   //what other errors can occur?
-        }
-
-        return -1;
-    }
-
-    if(!SetFileTime(hFile, NULL, &LastAccessTime, &LastModificationTime)) {
-        //can this happen?
-        errno=ENOENT;
-        CloseHandle(hFile);
-        c_free_locale_string(wuri);
-        return -1;
-    }
-
-    CloseHandle(hFile);
-    c_free_locale_string(wuri);
-
-    return 0;
-}
-
-#endif // _WIN32
-#endif // HAVE_UTIMES
diff --git a/csync/src/std/c_time.h b/csync/src/std/c_time.h
deleted file mode 100644 (file)
index aa8ef2f..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * c_time - time functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _C_TIME_H
-#define _C_TIME_H
-
-#include <time.h>
-
-/**
- * @brief Calculate time difference
- *
- * The c_tspecdiff function returns the time elapsed between time time1 and time
- * time0 represented as timespec.
- *
- * @param time1 The time.
- * @param time0 The time.
- *
- * @return time elapsed between time1 and time0.
- */
-struct timespec c_tspecdiff(struct timespec time1, struct timespec time0);
-
-/**
- * @brief Calculate time difference.
- *
- * The function returns the time elapsed between time clock1 and time
- * clock0 represented as double (in seconds and milliseconds).
- *
- * @param clock1 The time.
- * @param clock0 The time.
- *
- * @return time elapsed between clock1 and clock0 in seconds and
- *         milliseconds.
- */
-double c_secdiff(struct timespec clock1, struct timespec clock0);
-
-int c_utimes(const char *uri, const struct timeval *times);
-
-#endif /* _C_TIME_H */
diff --git a/csync/src/std/c_utf8.cc b/csync/src/std/c_utf8.cc
deleted file mode 100644 (file)
index 4bd5d75..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * cynapses libc functions
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config_csync.h"
-
-#ifdef _WIN32
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <wchar.h>
-#include <windows.h>
-#else
-#include <QtCore/QTextCodec>
-#include <QtCore/QFile>
-#endif
-
-extern "C" {
-#include "c_alloc.h"
-#include "c_string.h"
-
-/* Convert a locale String to UTF8 */
-char* c_utf8_from_locale(const mbchar_t *wstr)
-{
-  if (wstr == NULL) {
-    return NULL;
-  }
-
-#ifdef _WIN32
-  char *dst = NULL;
-  char *mdst = NULL;
-  int size_needed;
-  size_t len;
-  len = wcslen(wstr);
-  /* Call once to get the required size. */
-  size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, len, NULL, 0, NULL, NULL);
-  if (size_needed > 0) {
-    mdst = (char*)c_malloc(size_needed + 1);
-
-    memset(mdst, 0, size_needed + 1);
-    WideCharToMultiByte(CP_UTF8, 0, wstr, len, mdst, size_needed, NULL, NULL);
-    dst = mdst;
-  }
-  return dst;
-#else
-    QTextDecoder dec(QTextCodec::codecForLocale());
-    QString s = dec.toUnicode(wstr, qstrlen(wstr));
-    if (s.isEmpty() || dec.hasFailure()) {
-        /* Conversion error: since we can't report error from this function, just return the original
-            string.  We take care of invalid utf-8 in SyncEngine::treewalkFile */
-        return c_strdup(wstr);
-    }
-#ifdef __APPLE__
-    s = s.normalized(QString::NormalizationForm_C);
-#endif
-    return c_strdup(std::move(s).toUtf8().constData());
-#endif
-}
-
-/* Convert a an UTF8 string to locale */
-mbchar_t* c_utf8_string_to_locale(const char *str)
-{
-    if (str == NULL ) {
-        return NULL;
-    }
-#ifdef _WIN32
-    mbchar_t *dst = NULL;
-    size_t len;
-    int size_needed;
-
-    len = strlen(str);
-    size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
-    if (size_needed > 0) {
-        int size_char = (size_needed + 1) * sizeof(mbchar_t);
-        dst = (mbchar_t*)c_malloc(size_char);
-        memset((void*)dst, 0, size_char);
-        MultiByteToWideChar(CP_UTF8, 0, str, -1, dst, size_needed);
-    }
-    return dst;
-#else
-    return c_strdup(QFile::encodeName(QString::fromUtf8(str)));
-#endif
-}
-
-}
diff --git a/csync/src/vio/csync_vio.c b/csync/src/vio/csync_vio.c
deleted file mode 100644 (file)
index 9091178..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <errno.h>
-#include <stdio.h>
-#include <assert.h>
-
-#include "csync_private.h"
-#include "csync_util.h"
-#include "vio/csync_vio.h"
-#include "vio/csync_vio_local.h"
-#include "csync_statedb.h"
-#include "std/c_jhash.h"
-
-#define CSYNC_LOG_CATEGORY_NAME "csync.vio.main"
-
-#include "csync_log.h"
-
-csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name) {
-  switch(ctx->replica) {
-    case REMOTE_REPLICA:
-      if(ctx->remote.read_from_db) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Read from db flag is true, should not!" );
-      }
-      return ctx->callbacks.remote_opendir_hook(name, ctx->callbacks.vio_userdata);
-      break;
-    case LOCAL_REPLICA:
-       if( ctx->callbacks.update_callback ) {
-        ctx->callbacks.update_callback(ctx->replica, name, ctx->callbacks.update_callback_userdata);
-       }
-      return csync_vio_local_opendir(name);
-      break;
-    default:
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
-      break;
-  }
-  return NULL;
-}
-
-int csync_vio_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
-  int rc = -1;
-
-  if (dhandle == NULL) {
-    errno = EBADF;
-    return -1;
-  }
-
-  switch(ctx->replica) {
-  case REMOTE_REPLICA:
-      if( ctx->remote.read_from_db ) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Remote ReadFromDb is true, should not!");
-      }
-      ctx->callbacks.remote_closedir_hook(dhandle, ctx->callbacks.vio_userdata);
-      rc = 0;
-      break;
-  case LOCAL_REPLICA:
-      rc = csync_vio_local_closedir(dhandle);
-      break;
-  default:
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
-      break;
-  }
-  return rc;
-}
-
-csync_vio_file_stat_t *csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
-  switch(ctx->replica) {
-    case REMOTE_REPLICA:
-      if( ctx->remote.read_from_db ) {
-          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Remote readfromdb is true, should not!");
-      }
-      return ctx->callbacks.remote_readdir_hook(dhandle, ctx->callbacks.vio_userdata);
-      break;
-    case LOCAL_REPLICA:
-      return csync_vio_local_readdir(dhandle);
-      break;
-    default:
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
-      break;
-  }
-
-  return NULL;
-}
-
-
-int csync_vio_stat(CSYNC *ctx, const char *uri, csync_vio_file_stat_t *buf) {
-  int rc = -1;
-
-  switch(ctx->replica) {
-    case REMOTE_REPLICA:
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "ERROR: Cannot call remote stat, not implemented");
-      assert(ctx->replica != REMOTE_REPLICA);
-      break;
-    case LOCAL_REPLICA:
-      rc = csync_vio_local_stat(uri, buf);
-      if (rc < 0) {
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Local stat failed, errno %d for %s", errno, uri);
-      }
-      break;
-    default:
-      break;
-  }
-
-  return rc;
-}
-
-char *csync_vio_get_status_string(CSYNC *ctx) {
-  if(ctx->error_string) {
-    return ctx->error_string;
-  }
-  return 0;
-}
diff --git a/csync/src/vio/csync_vio.h b/csync/src/vio/csync_vio.h
deleted file mode 100644 (file)
index 715b185..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _CSYNC_VIO_H
-#define _CSYNC_VIO_H
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include "c_private.h"
-#include "csync.h"
-#include "csync_private.h"
-
-typedef struct fhandle_s {
-  int fd;
-} fhandle_t;
-
-csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name);
-int csync_vio_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle);
-csync_vio_file_stat_t *csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle);
-
-int csync_vio_stat(CSYNC *ctx, const char *uri, csync_vio_file_stat_t *buf);
-
-char *csync_vio_get_status_string(CSYNC *ctx);
-
-
-#endif /* _CSYNC_VIO_H */
diff --git a/csync/src/vio/csync_vio_file_stat.c b/csync/src/vio/csync_vio_file_stat.c
deleted file mode 100644 (file)
index 8ebb64f..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "c_lib.h"
-#include "csync.h"
-#include "csync_log.h"
-
-csync_vio_file_stat_t *csync_vio_file_stat_new(void) {
-  csync_vio_file_stat_t *file_stat = (csync_vio_file_stat_t *) c_malloc(sizeof(csync_vio_file_stat_t));
-  ZERO_STRUCTP(file_stat);
-  return file_stat;
-}
-
-csync_vio_file_stat_t* csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat) {
-    csync_vio_file_stat_t *file_stat_cpy = csync_vio_file_stat_new();
-    memcpy(file_stat_cpy, file_stat, sizeof(csync_vio_file_stat_t));
-    if (file_stat_cpy->fields & CSYNC_VIO_FILE_STAT_FIELDS_ETAG) {
-        file_stat_cpy->etag = c_strdup(file_stat_cpy->etag);
-    }
-    if (file_stat_cpy->directDownloadCookies) {
-        file_stat_cpy->directDownloadCookies = c_strdup(file_stat_cpy->directDownloadCookies);
-    }
-    if (file_stat_cpy->directDownloadUrl) {
-        file_stat_cpy->directDownloadUrl = c_strdup(file_stat_cpy->directDownloadUrl);
-    }
-    if (file_stat_cpy->checksumHeader) {
-        file_stat_cpy->checksumHeader = c_strdup(file_stat_cpy->checksumHeader);
-    }
-    file_stat_cpy->name = c_strdup(file_stat_cpy->name);
-    return file_stat_cpy;
-}
-
-void csync_vio_file_stat_destroy(csync_vio_file_stat_t *file_stat) {
-  /* FIXME: free rest */
-  if (file_stat == NULL) {
-    return;
-  }
-
-  if (file_stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_ETAG) {
-    SAFE_FREE(file_stat->etag);
-  }
-  SAFE_FREE(file_stat->directDownloadUrl);
-  SAFE_FREE(file_stat->directDownloadCookies);
-  SAFE_FREE(file_stat->name);
-  SAFE_FREE(file_stat->original_name);
-  SAFE_FREE(file_stat->checksumHeader);
-  SAFE_FREE(file_stat);
-}
-
-void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t *dst, const char* src ) {
-
-    csync_vio_set_file_id( dst->file_id, src );
-    if( c_streq( dst->file_id, "" )) {
-        return;
-    }
-    dst->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FILE_ID;
-}
-
-void csync_vio_set_file_id( char* dst, const char *src ) {
-    if( src && dst ) {
-        if( strlen(src) > FILE_ID_BUF_SIZE ) {
-            CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Ignoring file_id because it is too long: %s", src);
-            strcpy(dst, "");
-        } else {
-            strcpy(dst, src);
-        }
-    }
-}
diff --git a/csync/src/vio/csync_vio_local.h b/csync/src/vio/csync_vio_local.h
deleted file mode 100644 (file)
index 2943831..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _CSYNC_VIO_LOCAL_H
-#define _CSYNC_VIO_LOCAL_H
-
-csync_vio_handle_t OCSYNC_EXPORT *csync_vio_local_opendir(const char *name);
-int OCSYNC_EXPORT csync_vio_local_closedir(csync_vio_handle_t *dhandle);
-csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_local_readdir(csync_vio_handle_t *dhandle);
-
-int OCSYNC_EXPORT csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf);
-
-#endif /* _CSYNC_VIO_LOCAL_H */
diff --git a/csync/src/vio/csync_vio_local_unix.c b/csync/src/vio/csync_vio_local_unix.c
deleted file mode 100644 (file)
index 5d56666..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2013- by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <stdio.h>
-
-#include "c_private.h"
-#include "c_lib.h"
-#include "c_string.h"
-#include "csync_util.h"
-#include "csync_log.h"
-#include "csync_vio.h"
-
-#include "vio/csync_vio_local.h"
-
-/*
- * directory functions
- */
-
-typedef struct dhandle_s {
-  DIR *dh;
-  char *path;
-} dhandle_t;
-
-csync_vio_handle_t *csync_vio_local_opendir(const char *name) {
-  dhandle_t *handle = NULL;
-  mbchar_t *dirname = NULL;
-
-  handle = c_malloc(sizeof(dhandle_t));
-
-  dirname = c_utf8_path_to_locale(name);
-
-  handle->dh = _topendir( dirname );
-  if (handle->dh == NULL) {
-    c_free_locale_string(dirname);
-    SAFE_FREE(handle);
-    return NULL;
-  }
-
-  handle->path = c_strdup(name);
-  c_free_locale_string(dirname);
-
-  return (csync_vio_handle_t *) handle;
-}
-
-int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
-  dhandle_t *handle = NULL;
-  int rc = -1;
-
-  if (dhandle == NULL) {
-    errno = EBADF;
-    return -1;
-  }
-
-  handle = (dhandle_t *) dhandle;
-  rc = _tclosedir(handle->dh);
-
-  SAFE_FREE(handle->path);
-  SAFE_FREE(handle);
-
-  return rc;
-}
-
-csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
-
-  dhandle_t *handle = NULL;
-  csync_vio_file_stat_t *file_stat = NULL;
-
-  handle = (dhandle_t *) dhandle;
-
-  errno = 0;
-  file_stat = csync_vio_file_stat_new();
-  if (file_stat == NULL) {
-    goto err;
-  }
-  file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
-
-  struct _tdirent *dirent = NULL;
-
-  dirent = _treaddir(handle->dh);
-  if (dirent == NULL) {
-      goto err;
-  }
-  file_stat->name = c_utf8_from_locale(dirent->d_name);
-  if (file_stat->name == NULL) {
-      //file_stat->original_name = c_strdup(dirent->d_name);
-      if (asprintf(&file_stat->original_name, "%s/%s", handle->path, dirent->d_name) < 0) {
-          goto err;
-      }
-      CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Invalid characters in file/directory name, please rename: \"%s\" (%s)",
-                dirent->d_name, handle->path);
-  }
-
-  /* Check for availability of d_type, see manpage. */
-#if defined(_DIRENT_HAVE_D_TYPE) || defined(__APPLE__)
-  switch (dirent->d_type) {
-    case DT_FIFO:
-    case DT_SOCK:
-    case DT_CHR:
-    case DT_BLK:
-      break;
-    case DT_DIR:
-    case DT_REG:
-      file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
-      if (dirent->d_type == DT_DIR) {
-        file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
-      } else {
-        file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
-      }
-      break;
-    case DT_UNKNOWN:
-      file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
-      file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
-    default:
-      break;
-  }
-#endif
-
-  return file_stat;
-
-err:
-  csync_vio_file_stat_destroy(file_stat);
-
-  return NULL;
-}
-
-
-int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
-  csync_stat_t sb;
-
-  mbchar_t *wuri = c_utf8_path_to_locale( uri );
-
-  if( _tstat(wuri, &sb) < 0) {
-    c_free_locale_string(wuri);
-    return -1;
-  }
-
-  buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
-
-  switch(sb.st_mode & S_IFMT) {
-    case S_IFBLK:
-      buf->type = CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE;
-      break;
-    case S_IFCHR:
-      buf->type = CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE;
-      break;
-    case S_IFDIR:
-      buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
-      break;
-    case S_IFIFO:
-      buf->type = CSYNC_VIO_FILE_TYPE_FIFO;
-      break;
-    case S_IFREG:
-      buf->type = CSYNC_VIO_FILE_TYPE_REGULAR;
-      break;
-    case S_IFLNK:
-      buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
-      break;
-    case S_IFSOCK:
-      buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
-      break;
-    default:
-      buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
-      break;
-  }
-  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
-
-  buf->mode = sb.st_mode;
-  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MODE;
-
-  if (buf->type == CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK) {
-    /* FIXME: handle symlink */
-    buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK;
-  } else {
-    buf->flags = CSYNC_VIO_FILE_FLAGS_NONE;
-  }
-#ifdef __APPLE__
-  if (sb.st_flags & UF_HIDDEN) {
-      buf->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
-  }
-#endif
-  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
-
-  buf->inode = sb.st_ino;
-  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
-
-  buf->atime = sb.st_atime;
-  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
-
-  buf->mtime = sb.st_mtime;
-  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
-
-  buf->ctime = sb.st_ctime;
-  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
-
-  buf->size = sb.st_size;
-  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
-
-  c_free_locale_string(wuri);
-  return 0;
-}
diff --git a/csync/src/vio/csync_vio_local_win.c b/csync/src/vio/csync_vio_local_win.c
deleted file mode 100644 (file)
index fc4eea5..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- * Copyright (c) 2013- by Klaas Freitag <freitag@owncloud.com>
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-#include "windows.h"
-
-#include "c_private.h"
-#include "c_lib.h"
-#include "c_string.h"
-#include "csync_util.h"
-#include "csync_log.h"
-#include "csync_vio.h"
-
-#include "vio/csync_vio_local.h"
-
-
-/*
- * directory functions
- */
-
-typedef struct dhandle_s {
-  WIN32_FIND_DATA ffd;
-  HANDLE hFind;
-  int firstFind;
-  char *path;
-} dhandle_t;
-
-csync_vio_handle_t *csync_vio_local_opendir(const char *name) {
-  dhandle_t *handle = NULL;
-  mbchar_t *dirname = NULL;
-
-  handle = c_malloc(sizeof(dhandle_t));
-
-  // the file wildcard has to be attached
-  int len_name = strlen(name);
-  if( len_name ) {
-      char *h = NULL;
-
-      // alloc an enough large buffer to take the name + '/*' + the closing zero.
-      h = c_malloc(len_name+3);
-      strncpy( h, name, 1+len_name);
-      strncat(h, "/*", 2);
-
-      dirname = c_utf8_path_to_locale(h);
-      SAFE_FREE(h);
-  }
-
-  if( dirname ) {
-      handle->hFind = FindFirstFile(dirname, &(handle->ffd));
-  }
-
-  if (!dirname || handle->hFind == INVALID_HANDLE_VALUE) {
-      int retcode = GetLastError();
-      if( retcode == ERROR_FILE_NOT_FOUND ) {
-          errno = ENOENT;
-      } else {
-          errno = EACCES;
-      }
-      SAFE_FREE(handle);
-      return NULL;
-  }
-
-  handle->firstFind = 1; // Set a flag that there first fileinfo is available.
-
-  handle->path = c_strdup(name);
-  c_free_locale_string(dirname);
-
-  return (csync_vio_handle_t *) handle;
-}
-
-int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
-  dhandle_t *handle = NULL;
-  int rc = -1;
-
-  if (dhandle == NULL) {
-    errno = EBADF;
-    return -1;
-  }
-
-  handle = (dhandle_t *) dhandle;
-  // FindClose returns non-zero on success
-  if( FindClose(handle->hFind) != 0 ) {
-      rc = 0;
-  } else {
-      // error case, set errno
-      errno = EBADF;
-  }
-
-  SAFE_FREE(handle->path);
-  SAFE_FREE(handle);
-
-  return rc;
-}
-
-
-static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder)
-{
-    long long int t = filetime->dwHighDateTime;
-    t <<= 32;
-    t += (UINT32)filetime->dwLowDateTime;
-    t -= 116444736000000000LL;
-    if (t < 0)
-    {
-        if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
-        return -1 - ((-t - 1) / 10000000);
-    }
-    else
-    {
-        if (remainder) *remainder = t % 10000000;
-        return t / 10000000;
-    }
-}
-
-csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
-
-  dhandle_t *handle = NULL;
-  csync_vio_file_stat_t *file_stat = NULL;
-  DWORD rem;
-
-  handle = (dhandle_t *) dhandle;
-
-  errno = 0;
-  file_stat = csync_vio_file_stat_new();
-  if (file_stat == NULL) {
-      errno = ENOMEM;
-      goto err;
-  }
-  file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
-
-  // the win32 functions get the first valid entry with the opendir
-  // thus we must not jump to next entry if it was the first find.
-  if( handle->firstFind ) {
-      handle->firstFind = 0;
-  } else {
-      if( FindNextFile(handle->hFind, &(handle->ffd)) == 0 ) {
-          // might be error, check!
-          int dwError = GetLastError();
-          if (dwError != ERROR_NO_MORE_FILES) {
-              errno = EACCES; // no more files is fine. Otherwise EACCESS
-          }
-          goto err;
-      }
-  }
-  file_stat->name = c_utf8_from_locale(handle->ffd.cFileName);
-
-    file_stat->flags = CSYNC_VIO_FILE_FLAGS_NONE;
-    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
-    if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
-        // Detect symlinks, and treat junctions as symlinks too.
-        if (handle->ffd.dwReserved0 == IO_REPARSE_TAG_SYMLINK
-                || handle->ffd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT) {
-            file_stat->flags |= CSYNC_VIO_FILE_FLAGS_SYMLINK;
-            file_stat->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
-        } else {
-            // The SIS and DEDUP reparse points should be treated as
-            // regular files. We don't know about the other ones yet,
-            // but will also treat them normally for now.
-            file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
-        }
-    } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
-                || handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
-                || handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
-        file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
-    } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
-        file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
-    } else {
-        file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
-    }
-
-    /* Check for the hidden flag */
-    if( handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) {
-        file_stat->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
-    }
-
-    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
-    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
-
-    file_stat->size = (handle->ffd.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + handle->ffd.nFileSizeLow;
-    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
-
-    file_stat->atime = FileTimeToUnixTime(&handle->ffd.ftLastAccessTime, &rem);
-    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
-
-    file_stat->mtime = FileTimeToUnixTime(&handle->ffd.ftLastWriteTime, &rem);
-      /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
-    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
-
-    file_stat->ctime = FileTimeToUnixTime(&handle->ffd.ftCreationTime, &rem);
-    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
-
-    return file_stat;
-
-err:
-  SAFE_FREE(file_stat);
-
-  return NULL;
-}
-
-
-
-int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
-    /* Almost nothing to do since csync_vio_local_readdir already filled up most of the information
-       But we still need to fetch the file ID.
-       Possible optimisation: only fetch the file id when we need it (for new files)
-      */
-
-    HANDLE h;
-    BY_HANDLE_FILE_INFORMATION fileInfo;
-    ULARGE_INTEGER FileIndex;
-    mbchar_t *wuri = c_utf8_path_to_locale( uri );
-
-    h = CreateFileW( wuri, 0, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
-                     NULL, OPEN_EXISTING,
-                     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
-                     NULL );
-    if( h == INVALID_HANDLE_VALUE ) {
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "CreateFileW failed on %s", uri );
-        errno = GetLastError();
-        c_free_locale_string(wuri);
-        return -1;
-    }
-
-    if(!GetFileInformationByHandle( h, &fileInfo ) ) {
-        CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "GetFileInformationByHandle failed on %s", uri );
-        errno = GetLastError();
-        c_free_locale_string(wuri);
-        CloseHandle(h);
-        return -1;
-    }
-
-    /* Get the Windows file id as an inode replacement. */
-    FileIndex.HighPart = fileInfo.nFileIndexHigh;
-    FileIndex.LowPart = fileInfo.nFileIndexLow;
-    FileIndex.QuadPart &= 0x0000FFFFFFFFFFFF;
-    /* printf("Index: %I64i\n", FileIndex.QuadPart); */
-    buf->inode = FileIndex.QuadPart;
-
-    if (!(buf->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE)) {
-        buf->size = (fileInfo.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + fileInfo.nFileSizeLow;
-        buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
-    }
-    if (!(buf->fields & CSYNC_VIO_FILE_STAT_FIELDS_MTIME)) {
-        DWORD rem;
-        buf->mtime = FileTimeToUnixTime(&fileInfo.ftLastWriteTime, &rem);
-        /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
-        buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
-    }
-
-    c_free_locale_string(wuri);
-    CloseHandle(h);
-    return 0;
-}
index 3cbacd537f87a1d072b81db215aa71b89ed98818..f871836cff9a8ae829e28db9a3322019366b3524 100644 (file)
@@ -8,6 +8,7 @@ if(NOT TOKEN_AUTH_ONLY)
     find_package(Qt5Keychain REQUIRED)
 endif()
 
+add_subdirectory(csync)
 add_subdirectory(libsync)
 if (NOT BUILD_LIBRARIES_ONLY)
     add_subdirectory(gui)
index 4a0d76d71f2d8952833568a366f75922c4321700..26b641f217dfa67c13aceaab30bec2f9ba949344 100644 (file)
@@ -12,9 +12,8 @@ include_directories(${CMAKE_SOURCE_DIR}/src/libsync
                    )
 
 # csync is required.
-include_directories(${CMAKE_SOURCE_DIR}/csync/src
-                    ${CMAKE_BINARY_DIR}/csync
-                    ${CMAKE_BINARY_DIR}/csync/src
+include_directories(${CMAKE_SOURCE_DIR}/src/csync
+                    ${CMAKE_BINARY_DIR}/src/csync
                    )
 
 # Need tokenizer for netrc parser
diff --git a/src/csync/AUTHORS b/src/csync/AUTHORS
new file mode 100644 (file)
index 0000000..5fd81c0
--- /dev/null
@@ -0,0 +1,3 @@
+Andreas Schneider <asn@cryptomilk.org>
+Klaas Freitag <freitag@owncloud.com>
+Olivier Goffart <olivier>
diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt
new file mode 100644 (file)
index 0000000..db99a88
--- /dev/null
@@ -0,0 +1,166 @@
+project(libcsync)
+# global needed variables
+set(APPLICATION_NAME "ocsync")
+
+set(LIBRARY_VERSION ${MIRALL_VERSION})
+set(LIBRARY_SOVERSION "0")
+
+# add definitions
+include(DefineCMakeDefaults)
+include(DefinePlatformDefaults)
+include(DefineCompilerFlags)
+include(DefineOptions.cmake)
+
+include(DefineInstallationPaths)
+
+# add macros
+include(MacroAddPlugin)
+include(MacroCopyFile)
+
+find_package(SQLite3 3.8.0 REQUIRED)
+
+include(ConfigureChecks.cmake)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+if (MEM_NULL_TESTS)
+  add_definitions(-DCSYNC_MEM_NULL_TESTS)
+endif (MEM_NULL_TESTS)
+
+add_subdirectory(std)
+
+# Statically include sqlite
+
+set(CSYNC_PUBLIC_INCLUDE_DIRS
+  ${CMAKE_CURRENT_BINARY_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_SOURCE_DIR}
+  CACHE INTERNAL "csync public include directories"
+)
+
+set(CSYNC_PRIVATE_INCLUDE_DIRS
+  ${SQLITE3_INCLUDE_DIRS}
+  ${CSTDLIB_PUBLIC_INCLUDE_DIRS}
+  ${CMAKE_BINARY_DIR}
+)
+
+set(CSYNC_LIBRARY
+  ocsync
+  CACHE INTERNAL "ocsync library"
+)
+
+set(CSYNC_LINK_LIBRARIES
+  ${CSTDLIB_LIBRARY}
+  ${CSYNC_REQUIRED_LIBRARIES}
+  ${SQLITE3_LIBRARIES}
+)
+
+# Specific option for builds tied to servers that do not support renaming extensions
+set(NO_RENAME_EXTENSION 0 CACHE BOOL "Do not issue rename if the extension changes")
+if(NO_RENAME_EXTENSION)
+    add_definitions(-DNO_RENAME_EXTENSION)
+endif()
+
+set(csync_SRCS
+  csync.c
+  csync_exclude.c
+  csync_log.c
+  csync_statedb.c
+  csync_time.c
+  csync_util.c
+  csync_misc.c
+
+  csync_update.c
+  csync_reconcile.c
+
+  csync_rename.cc
+
+  vio/csync_vio.c
+  vio/csync_vio_file_stat.c
+)
+
+if (WIN32)
+    list(APPEND csync_SRCS
+        vio/csync_vio_local_win.c
+    )
+else()
+    list(APPEND csync_SRCS
+        vio/csync_vio_local_unix.c
+    )
+endif()
+
+
+configure_file(csync_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h)
+
+set(csync_HDRS
+  ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h
+  csync.h
+  vio/csync_vio.h
+  vio/csync_vio_method.h
+  vio/csync_vio_module.h
+)
+
+# Statically include sqlite
+if (USE_OUR_OWN_SQLITE3)
+    list(APPEND csync_SRCS ${SQLITE3_SOURCE})
+    if (WIN32)
+        # We want to export sqlite symbols from the ocsync DLL without
+        # having to patch both sqlite3.h and the amalgation sqlite3.c,
+        # so do the import/export magic manually through the build system.
+        remove_definitions(-DSQLITE_API=__declspec\(dllimport\))
+        add_definitions(-DSQLITE_API=__declspec\(dllexport\))
+    endif()
+endif()
+
+include_directories(
+  ${CSYNC_PUBLIC_INCLUDE_DIRS}
+  ${CSYNC_PRIVATE_INCLUDE_DIRS}
+)
+
+add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS})
+#add_library(${CSYNC_LIBRARY}_static STATIC ${csync_SRCS})
+
+generate_export_header( ${CSYNC_LIBRARY}
+  BASE_NAME ${CSYNC_LIBRARY}
+  EXPORT_MACRO_NAME OCSYNC_EXPORT
+  EXPORT_FILE_NAME ocsynclib.h
+)
+
+target_link_libraries(${CSYNC_LIBRARY} ${CSYNC_LINK_LIBRARIES})
+#target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES})
+
+set_target_properties(
+  ${CSYNC_LIBRARY}
+    PROPERTIES
+      VERSION
+        ${LIBRARY_VERSION}
+      SOVERSION
+        ${LIBRARY_SOVERSION}
+      RUNTIME_OUTPUT_DIRECTORY
+        ${BIN_OUTPUT_DIRECTORY}
+)
+if(BUILD_OWNCLOUD_OSX_BUNDLE)
+  INSTALL(
+    TARGETS
+      ${CSYNC_LIBRARY}
+    LIBRARY DESTINATION
+       ${LIB_INSTALL_DIR}
+    ARCHIVE DESTINATION
+       ${LIB_INSTALL_DIR}
+    RUNTIME DESTINATION
+       ${BIN_INSTALL_DIR}
+    )
+else()
+  INSTALL(
+  TARGETS
+    ${CSYNC_LIBRARY}
+  LIBRARY DESTINATION
+    ${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
+  ARCHIVE DESTINATION
+    ${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
+  RUNTIME DESTINATION
+    ${BIN_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
+  )
+endif()
+
+configure_file(config_csync.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config_csync.h)
diff --git a/src/csync/COPYING b/src/csync/COPYING
new file mode 100644 (file)
index 0000000..4362b49
--- /dev/null
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, 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.
+\f
+  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.
+\f
+                  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/src/csync/ChangeLog b/src/csync/ChangeLog
new file mode 100644 (file)
index 0000000..a95a075
--- /dev/null
@@ -0,0 +1,355 @@
+ChangeLog
+==========
+version 0.91.4  (released 2013-12-12, ownCloud Cleint 1.5.0)
+ * changelog added, version bumped.
+
+version 0.91.3  (released 2013-12-11, ownCloud Client 1.5.0rc1) 
+ * Fix progress bar on win32
+ * Fix network rate limiting on win32
+ * Do not check for etag during failing requests
+ * Start quota timer only after the predecessor returned
+ * Remove tmp files in case of certain download problems
+ * Some valgrind fixes
+ * Theming fix: button behaviour
+ * Fix a case where a sync loop could happen.
+ * Multi-linguar installer
+ * Fix handling of quotes in etags written by older ownClouds
+ * Fix errno handling in update phase
+ * Make csync compile on FreeBSD
+ * Minor cleanups.
+
+version 0.91.2 (released 2013-12-10, ownCloud Client 1.5.0beta3)
+ * have translatable error message for indiv. file errors.
+ * Use uint64_t for inode on win32 to fix a type glitch.
+ * Add test that directories are properly moved.
+ * Handle symlinks correctly.
+ * No longer recurse into ignored directories in update 
+   phase.
+ * Added proper symlink detection for win32 platform.
+
+version 0.91.1 (released 2013-12-03, ownCloud Client 1.5.0beta2)
+ * Close database correctly to fix a potential crash (mirall#1229)
+ * Handle invalid inodes correctly.
+ * Use lstat rather than stat to detect symlinks correctly. 
+   (core#6146)
+
+version 0.91.0 (released 2013-11-28, ownCloud Client 1.5.0beta1)
+ * fix ascii to int conversion for large numbers.
+ * add support for file ids, needed to detect server side moves.
+ * removed unused code, ie. database writing code that went to 
+   mirall.
+ * add functions to query the database by fileid.
+ * add functions to read fileids from PUT replies.
+ * add server side move detection.
+ * enhanced test scripts
+ * Remove ne_sock_init and ne_sock_exit from owncloud module 
+   (mirall#1115)
+ * Renamed 'md5' to 'etag' in code identifiers to avoid confusion.
+ * add new state EVAL_RENAME 
+ * link the owncloud module directly rather than dl-loading it.
+ * add a content type header 'application/octet-stream' to PUTs.
+ * remove -gzip from etag header if its there. (mirall#1195)
+ * Many minor fixes, refactorings and improvements.
+
+version 0.90.4  (released 2013-10-18, ownCloud Client 1.4.2)
+
+  * Count renamed and deleted files for progress information.
+  * Do not reset csync internal error state in helper funcs 
+    and do not overwrite error messages.
+    That fixes error reporting to the client.
+  * Disable check on inodes on all platforms as inodes are not 
+    reliable.
+  * Fix resuming after user aborting the sync process.
+  * enabled HBF debugging permanently.
+
+version 0.90.1  (released 2013-09-24, ownCloud Client 1.4.1)
+  * no more check on the local inode in updater for win32 (bug #779)
+  * detect if server does not send an etag after an upload 
+    completed.
+  * fix crash in case of network timeout, reported as
+    https://github.comowncloud/client/issues/1010
+  * compile and cmake fixes for win32
+  * fixed behaviour of csync_exclude
+  * documentation and spelling fixes.
+
+version 0.90.0  (released 2013-09-04, ownCloud Client 1.4.0)
+  * Added API to get progress information from csync.
+  * Added c_rename function to csync std.
+  * Fix: Do renames of files before any puts.
+  * Improved database integrity checks.
+  * Improvements of database writing efficiency.
+  * Fix: stat file on win32 even if its opened by application.
+  * httpbf: configurable block size and threshold.
+  * Many fixes found by a Coverity check.
+  * Fix: use correct stat struct on all platforms
+  * Fix: download resuming.
+  * ownCloud module: Bandwith limitation added.
+  * Added ability to remove ignored files automatically.
+  * Fix: Use int64_t and friends
+  * Fix: Removed all compile warnings.
+  * Left excluded files and links in csync's tree to be able to show.
+    them to the user.
+  * Add OC-Total-Length header for better quota handling.
+  * Report inbetween progress
+
+version 0.80.0  (released 2013-06-25)
+  * Big file chunking (e.g. up/download of big files should now be no
+    problem anymore)
+  * Resuming (download of big files will resume)
+  * Fix false conflicts when database is corrupt/missing
+  * Fix false conflicts when file is locked
+  * Put legitimate conflict files only on client side
+  * Fix unreliable sync after push_file failed
+  * Fix rename due to inode cast error
+  * Make chunking work on nginx setups or through nginx proxies
+  * Improve error reporting in csync_update
+  * Clean progress database on csync_commit
+  * Fix issues detected by Coverity
+  * Fix conflict file appearing when a file cannot be stated
+  * Do not shadow server errors by not downloading files that have
+    failed to download in the past
+
+version 0.70.6  (released 2013-04-11)
+  * [Fixes] Try to avoid to upload incomplete files
+  * [Fixes] Increase read timeout to 300 seconds
+  * [Fixes] Handle IGNORE status correctly
+  * [Fixes] Set path and phash for ignored files
+  * [Fixes] Fix some issues discovered by Coverity
+  * [Fixes] Make sure to never allow empty pathes in rmdir
+  * [Fixes] Fix a crash caused by superfluous free() calls
+
+version 0.70.5  (released 2013-04-02)
+  * detect 'wrong' conflict files on client side. 
+  * [Fixes] Give context to module to enable logging (cmd client).
+  * [Fixes] Fix version table contents.
+  * [Fixes] Fix handling of non statable files on Win32.
+  * [Fixes] Fix renames on clientside on read only shares.
+  * [Fixes] Various small fixes and improvements.
+
+version 0.70.4  (released 2013-02-26)
+  * [Win32] Ship with upto-date openssl version to fix SSL problems we saw.
+  * [Fixes] Fix crash during mkdir.
+  * [Fixes] Added workaround for problem that server sometimes does
+            not respond properly to PROPFIND (mirall#285)
+  * [Fixes] Fix handling of deletion of non empty or locked
+            directories.
+  * [Fixes] Fixed some potential memory leaks.
+  * [Fixes] Files with filenames with unix extensions
+           are ignored now.
+
+version 0.70.3  (released 2013-01-24)
+  * [Platform] Fix session cookie extraction (mirall bug #260).
+
+version 0.70.2  (released 2013-01-23)
+  * [Platform] Improved module parameter system.
+  * [Platform] New logging framework. Dropped log4c dependency.
+  * [Platform] New API to provide sync progress information.
+  * [Fixes] More efficiency for the ownCloud plugin through less HTTP requests to
+            the server.
+  * [Fixes] ownCloud plugin: Improved upload performance.
+  * [Fixes] Improved error reporting to mirall.
+  * [Fixes] ownCloud plugin: Improved interpretation of HTTP error codes.
+  * [Fixes] ownCloud plugin: Do not abort on errors with individual files any
+            more.
+  * [Fixes] Lots of other minor fixes.
+  * [MacOSX] Use libneon with proper big file support.
+  * [Win32] Use libneon with openSSL support now.
+
+version 0.70.0 and 0.70.1 were beta versions.
+
+version 0.60.2  (released 2012-11-26)
+  * Migration to cross platform testing system cmocka.
+  * Fixed various minor things incl. potential mem leaks.
+  * Clang fixes.
+  * Moved journal database to sync directory.
+  * Fixed more csync->ocsync renaming issues.
+  * Fixed statedb query below path.
+  * Fixed win32 Daylight Saving Time issues.
+  * Allow static linking with iniparser and sqlite.
+  * Win32: Fix CreateHandle function in local stat.
+  * Win32: More wide char fixes.
+  * Added version table to journal database.
+  * Fixes for HTTP reply computation.
+  * Stricter error checks on PROPFIND results.
+  * Workaround for DST influenced times from previous versions.
+  * Detect looping in mkdirs to fix sharing.
+
+version 0.60.1  (released 2012-10-18)
+  * Fix improper memory cleanup which could
+            cause memory leaks and crashes
+  * Fix memory leak
+  * Allow single quote (') in file names
+  * Remove stray temporary files
+
+version 0.60.0  (released 2012-10-10)
+  * simplification of pac based proxy support. 
+  * syncing algorithm based on ids rather than on timestamps
+  * make it possible to relocate database
+
+version 0.50.11 (third beta version, released 2012-10-05)
+  * Renamed ownCloud version of csync to ocsync for ownCloud.
+  * Migration paths for csync database and config.
+  * Fixed that exclude patterns are also tested on files basenames.
+  * Fixed return type for query function if no database exists.
+  * minor code fixes
+
+version 0.50.10 (second beta version, released 2012-09-20)
+  * Fixed crash by removing a bogus free.
+  * More useful logging.
+  * ownCloud: Maintain the http session by handling the HTTP Cookie.
+
+version 0.50.9 (first beta version, released 2012-08-30)
+  * Fixed strncpy handling (mkdir on windows problem).
+  * extend database with columns uniq id and type.
+  * Use server maintained uniq IDs for update detection instead of 
+    mtimes. 
+  * Maintain uniq IDs in local database
+  * Handle change propagation through the file tree locally and remote.
+  * Added module to build a file tree from the local database (dbtree.c)
+  * Added methods to query IDs from the server and maintain it locally.
+
+version 0.50.8 (released 2012-08-10)
+  * Inode equivalent support for Win32 platforms to support rename
+  * ownCloud supports propagates renames from local to webdav MOVE
+  * ownCloud module works with proxy, settings from mirall.
+  * improved CMake modules (openSSL)
+  * Fixed namespace for lastmodified propset.
+  * Added cmocka based tests for ownCloud module.
+  * Added a config_test.h config_csync.header file.
+  * Fix link handling: Ignore symlinks.
+  * Modules can now report their capabilities to csync core.
+  * A lot of minor fixes and improvements.
+
+version 0.50.7 (released 2012-06-19)
+  * Added ability to log to a callback, ie. let the app 
+    catch the log output
+  * Added push to remote without pushing to temp file first.
+  * Fixed file copy function to use wide character (win32).
+  * Fixed loading of statedb if user has special char (win32).
+
+version 0.50.6 (released 2012-05-18)
+  * Directories with 'strange' characters broke sync. (oC bug #613)
+  * Special characters in Windows did not sync correctly. (oC bug #478)
+  * Make neon redirecting
+  * Switch logging off on Apple to not fill the syslog. (oC bug #622)
+
+version 0.50.5 (released 2012-04-18)
+  * removed argp lib dependency
+  * simplified and fixed CMake files
+  * MacOS porting efforts
+  * more granular error reports, thread save
+
+version 0.50.0 (released 2013-08-01)
+  * Added owncloud module.
+  * Added support for more platforms: FreeBSD, Windows and MacOSX
+  * Added support for more compilers: CLang, MinGW and latest GCC
+  * Added a backup mode to the reconciler.
+  * Added new logging framework (removed log4c dependency).
+  * Added new config parser (removed iniparser dependency).
+  * Added cmocka tests.
+  * Added a way to export file_tree_walk functions.
+  * Added capabilities for modules.
+  * Added possiblity to push information to the modules.
+  * Added iconv support to support various char sets.
+  * Added csync_commit() to rerun on the same context.
+  * Added content checking in conflict case.
+  * Added callbacks for progress information.
+  * Added get() and put() functions for modules.
+  * Improved database: more performance, more integrity checks
+  * Improved error reporting: status codes, custom errnos
+  * Fixed serveral bugs.
+  * Relicensed libcsync to LGPLv2.1+.
+
+version 0.44.0 (released 2010-02-15)
+  * Migrated sftp module to libssh 0.4.
+  * Added more cache entries to the default config.
+  * Added missing requirements.
+  * Fixed build warnings.
+  * Fixed some memory leaks using sftp attributes.
+  * Some code cleanups.
+
+version 0.43.0 (released 2009-05-25)
+  * Added SFTP support with libssh 0.3.
+  * Added possibility to pass userdata to the auth function.
+  * Added a better version function.
+  * Fixed CMake build.
+  * Fixed CMake find modules.
+  * Fixed some flaws in cstd functions.
+  * Documented all public functions.
+
+version 0.42.0 (released 2009-02-10)
+  * Small fix in the userguide.
+
+version 0.42.0 rc3 (released 2009-01-23)
+  libcsync:
+  * Added checks for unix extensions.
+  * Added more documentation to the userguide.
+  * Fixed loading of plugins.
+  * Fixed call for deletion functions.
+  * Normalize the path to <hostname>/<path> for the statedb filename.
+  * More change name of client options to be more descriptive.
+
+version 0.42.0 rc2 (released 2009-01-07)
+  libcsync:
+  * Fixed a bug in the creation of the statedb
+  * Completed userguide
+
+version 0.42.0 rc1 (released 2008-12-04)
+  libcsync:
+  * Reduced calls of syscall functions.
+  * Added own function to create a temporary filename.
+  * Fixed libsmbclient 3.0.x support.
+
+version 0.42.0 beta1 (released 2008-09-10)
+
+  libcsync:
+  * Added a sftp module using libssh
+  * Added user guide (just a start)
+  * Added testcase for update detection
+  * Added a function to parse an uri to cstdlib
+  * Updated the manpage
+  * Fixed some segfaults in cstdlib
+  * Fixed some memory leaks
+
+  csync:
+  * Improved the auth callback
+
+version 0.42.0 alpha4 (released 2008-07-02)
+
+  libcsync:
+  * Added the possibility to run csync completely without a journal
+  * Improved chmod calls during propagation. Most of the time we use the
+    default mode and don't need to call chmod.
+  * Improved the exclude list handling in the file tree walker. This
+    increased the speed of the update detection.
+  * Fixed csync on PPC
+  * Fixed serveral small bugs
+
+  csync:
+  * Added commandline option to run csync completely without a journal
+  * Added a manpage
+
+version 0.42.0 alpha3 (released 2008-06-25)
+
+  libcsync:
+  * Added a tree merger to write a complete journal
+  * Added support to run csync without a journal
+  * Fixed kerberos support in csync_smb module
+  * Fixed closing of files after the copy
+  * Fixed update detection to detect special files (fifo, pipes,
+    char devices, ..)
+  * Fixed O_NOATIME flag on open() if we don't have the permission
+
+  csync:
+  * Add a variable to run csync completely without a journal
+
+version 0.42.0 alpha2 (released 2008-06-16)
+
+  libcsync:
+  * Peformance improvements
+  * Add more directories to the standard exclude file
+  * Bugfixes
+
+version 0.42.0 alpha1 (released 2008-06-02)
+
+  * Initial release
diff --git a/src/csync/ConfigureChecks.cmake b/src/csync/ConfigureChecks.cmake
new file mode 100644 (file)
index 0000000..6d64d5a
--- /dev/null
@@ -0,0 +1,65 @@
+include(CheckIncludeFile)
+include(CheckSymbolExists)
+include(CheckFunctionExists)
+include(CheckLibraryExists)
+include(CheckTypeSize)
+include(CheckCXXSourceCompiles)
+
+set(PACKAGE ${APPLICATION_NAME})
+set(VERSION ${APPLICATION_VERSION})
+set(DATADIR ${DATA_INSTALL_DIR})
+set(LIBDIR ${LIB_INSTALL_DIR})
+set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
+
+set(BINARYDIR ${CMAKE_CURRENT_BINARY_DIR})
+set(SOURCEDIR ${CMAKE_CURRENT_SOURCE_DIR})
+
+# HEADER FILES
+check_include_file(argp.h HAVE_ARGP_H)
+
+# FUNCTIONS
+if (NOT LINUX)
+    # librt
+    check_library_exists(rt nanosleep "" HAVE_LIBRT)
+
+    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} )
+endif (NOT LINUX)
+
+check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
+if (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
+    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} rt)
+endif (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
+
+check_library_exists(dl dlopen "" HAVE_LIBDL)
+if (HAVE_LIBDL)
+    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} dl)
+endif (HAVE_LIBDL)
+
+check_function_exists(asprintf HAVE_ASPRINTF)
+
+check_function_exists(fnmatch HAVE_FNMATCH)
+if(NOT HAVE_FNMATCH AND WIN32)
+  find_library(SHLWAPI_LIBRARY shlwapi)
+  set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} shlwapi)
+endif()
+
+if(WIN32)
+  set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} psapi kernel32)
+endif()
+
+check_function_exists(timegm HAVE_TIMEGM)
+check_function_exists(strerror_r HAVE_STRERROR_R)
+check_function_exists(utimes HAVE_UTIMES)
+check_function_exists(lstat HAVE_LSTAT)
+check_function_exists(asprintf HAVE_ASPRINTF)
+if (WIN32)
+       check_function_exists(__mingw_asprintf HAVE___MINGW_ASPRINTF)
+endif(WIN32)
+if (UNIX AND HAVE_ASPRINTF)
+  add_definitions(-D_GNU_SOURCE)
+endif (UNIX AND HAVE_ASPRINTF)
+if (WIN32)
+  check_function_exists(__mingw_asprintf HAVE___MINGW_ASPRINTF)
+endif(WIN32)
+
+set(CSYNC_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "csync required system libraries")
diff --git a/src/csync/DefineOptions.cmake b/src/csync/DefineOptions.cmake
new file mode 100644 (file)
index 0000000..485e183
--- /dev/null
@@ -0,0 +1,2 @@
+option(UNIT_TESTING "Build with unit tests" OFF)
+option(MEM_NULL_TESTS "Enable NULL memory testing" OFF)
diff --git a/src/csync/INSTALL b/src/csync/INSTALL
new file mode 100644 (file)
index 0000000..caf65c2
--- /dev/null
@@ -0,0 +1,84 @@
+# How to build from source
+
+## Requirements
+
+### Common requirements
+
+In order to build csync, you need to install several components:
+
+- A C compiler
+- [CMake](http://www.cmake.org) >= 2.6.0.
+- [check](http://check.sourceforge.net) >= 0.9.5
+- [sqlite3](http://www.sqlite.org) >= 3.4
+- [libneon](http://www.webdav.org/neon/) >= 0.29.0
+
+optional:
+- [libsmbclient](http://www.samba.org) >= 3.5
+- [libssh](http://www.libssh.org) >= 0.5
+
+sqlite3 is a runtime requirement. libsmbclient is needed for
+the smb plugin, libssh for the sftp plugin. libneon is required for the 
+ownCloud plugin.
+
+Note that these version numbers are versions we know work correctly. If you
+build and run csync successfully with an older version, please let us know.
+
+
+## Building
+First, you need to configure the compilation, using CMake. Go inside the
+`build` dir. Create it if it doesn't exist.
+
+GNU/Linux and MacOS X:
+
+    cmake -DCMAKE_BUILD_TYPE=Debug ..
+    make
+
+### CMake standard options
+Here is a list of the most interesting options provided out of the box by CMake.
+
+- CMAKE_BUILD_TYPE: The type of build (can be Debug Release MinSizeRel RelWithDebInfo)
+- CMAKE_INSTALL_PREFIX: The prefix to use when running make install (Default to
+  /usr/local on GNU/Linux and MacOS X)
+- CMAKE_C_COMPILER: The path to the C compiler
+- CMAKE_CXX_COMPILER: The path to the C++ compiler
+
+### CMake options defined for csync
+
+Options are defined in the following files:
+
+- DefineOptions.cmake
+
+They can be changed with the -D option:
+
+`cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_LOG4C=OFF ..`
+
+### Browsing/editing CMake options
+
+In addition to passing options on the command line, you can browse and edit
+CMake options using `cmakesetup` (Windows) or `ccmake` (GNU/Linux and MacOS X).
+
+- Go to the build dir
+- On Windows: run `cmakesetup`
+- On GNU/Linux and MacOS X: run `ccmake ..`
+
+## Installing
+
+Before installing you can run the tests if everything is working:
+
+    make test
+
+If you want to install csync after compilation run:
+
+    make install
+
+## Running
+
+The csync binary can be found in the `build/client` directory.
+
+## About this document
+
+This document is written using [Markdown][] syntax, making it possible to
+provide usable information in both plain text and HTML format. Whenever
+modifying this document please use [Markdown][] syntax.
+
+[markdown]: http://www.daringfireball.net/projects/markdown
diff --git a/src/csync/README b/src/csync/README
new file mode 100644 (file)
index 0000000..2487e24
--- /dev/null
@@ -0,0 +1,34 @@
+WHAT IS CSYNC?
+==============
+
+csync is a lightweight utility to synchronize files between two directories on
+a system or between multiple systems.
+
+It synchronizes bidirectionally and allows the user to keep two copies of files
+and directories in sync. csync uses widely adopted protocols, such as smb or
+sftp, so that there is no need for a server component. It is a user-level
+program which means you don’t need to be a superuser or administrator.
+
+CONTRIBUTIONS
+=============
+
+If you want to contribute to the development of the software then please join
+the mailing list. Patches are accepted preferably created with git and we are
+always glad to receive feedback or suggestions to the address
+csync-devel@csync.org.
+More information on the various mailing lists can be found at
+http://www.csync.org/communication/.
+
+You can also get the sourcecode straight from the git repository - see
+http://git.csync.org/
+
+DOCUMENTATION
+=============
+
+As a user you can find a userguide which is shipped with this package or is
+available at the website. For developers there is doxygen documentation and
+comments in the source code itself. See
+
+http://www.csync.org/userguide/
+and
+http://www.csync.org/api/
diff --git a/src/csync/config_csync.h.cmake b/src/csync/config_csync.h.cmake
new file mode 100644 (file)
index 0000000..f5c9f09
--- /dev/null
@@ -0,0 +1,24 @@
+#cmakedefine PACKAGE "${APPLICATION_NAME}"
+#cmakedefine VERSION "${APPLICATION_VERSION}"
+#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
+#cmakedefine LIBDIR "${LIBDIR}"
+#cmakedefine SYSCONFDIR "${SYSCONFDIR}"
+#cmakedefine BINARYDIR "${BINARYDIR}"
+#cmakedefine SOURCEDIR "${SOURCEDIR}"
+
+#cmakedefine HAVE_CLOCK_GETTIME
+
+#cmakedefine WITH_LOG4C 1
+
+#cmakedefine HAVE_ARGP_H 1
+
+#cmakedefine HAVE_TIMEGM 1
+#cmakedefine HAVE_STRERROR_R 1
+#cmakedefine HAVE_UTIMES 1
+#cmakedefine HAVE_LSTAT 1
+#cmakedefine HAVE_FNMATCH 1
+
+#cmakedefine HAVE___MINGW_ASPRINTF 1
+#cmakedefine HAVE_ASPRINTF 1
+
+#cmakedefine WITH_TESTING 1
diff --git a/src/csync/csync.c b/src/csync/csync.c
new file mode 100644 (file)
index 0000000..1f75ac3
--- /dev/null
@@ -0,0 +1,651 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <stdbool.h>
+
+#include "c_lib.h"
+#include "csync_private.h"
+#include "csync_exclude.h"
+#include "csync_statedb.h"
+#include "csync_time.h"
+#include "csync_util.h"
+#include "csync_misc.h"
+#include "std/c_private.h"
+
+#include "csync_update.h"
+#include "csync_reconcile.h"
+
+#include "vio/csync_vio.h"
+
+#include "csync_log.h"
+#include "csync_rename.h"
+#include "c_jhash.h"
+
+static int _key_cmp(const void *key, const void *data) {
+  uint64_t a;
+  csync_file_stat_t *b;
+
+  a = *(uint64_t *) (key);
+  b = (csync_file_stat_t *) data;
+
+  if (a < b->phash) {
+    return -1;
+  } else if (a > b->phash) {
+    return 1;
+  }
+
+  return 0;
+}
+
+static int _data_cmp(const void *key, const void *data) {
+  csync_file_stat_t *a, *b;
+
+  a = (csync_file_stat_t *) key;
+  b = (csync_file_stat_t *) data;
+
+  if (a->phash < b->phash) {
+    return -1;
+  } else if (a->phash > b->phash) {
+    return 1;
+  }
+
+  return 0;
+}
+
+void csync_create(CSYNC **csync, const char *local) {
+  CSYNC *ctx;
+  size_t len = 0;
+
+  ctx = c_malloc(sizeof(CSYNC));
+
+  ctx->status_code = CSYNC_STATUS_OK;
+
+  /* remove trailing slashes */
+  len = strlen(local);
+  while(len > 0 && local[len - 1] == '/') --len;
+
+  ctx->local.uri = c_strndup(local, len);
+
+  ctx->status_code = CSYNC_STATUS_OK;
+
+  ctx->current_fs = NULL;
+
+  ctx->abort = false;
+
+  ctx->ignore_hidden_files = true;
+
+  *csync = ctx;
+}
+
+void csync_init(CSYNC *ctx, const char *db_file) {
+  assert(ctx);
+  /* Do not initialize twice */
+
+  assert(!(ctx->status & CSYNC_STATUS_INIT));
+  ctx->status_code = CSYNC_STATUS_OK;
+
+  ctx->local.type = LOCAL_REPLICA;
+
+  ctx->remote.type = REMOTE_REPLICA;
+
+  SAFE_FREE(ctx->statedb.file);
+  ctx->statedb.file = c_strdup(db_file);
+
+  c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
+  c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);
+
+  ctx->remote.root_perms = 0;
+
+  ctx->status = CSYNC_STATUS_INIT;
+
+  /* initialize random generator */
+  srand(time(NULL));
+}
+
+int csync_update(CSYNC *ctx) {
+  int rc = -1;
+  struct timespec start, finish;
+
+  if (ctx == NULL) {
+    errno = EBADF;
+    return -1;
+  }
+  ctx->status_code = CSYNC_STATUS_OK;
+
+  /* Path of database file is set in csync_init */
+  if (csync_statedb_load(ctx, ctx->statedb.file, &ctx->statedb.db) < 0) {
+      rc = -1;
+      return rc;
+  }
+
+  ctx->status_code = CSYNC_STATUS_OK;
+
+  csync_memstat_check();
+
+  if (!ctx->excludes) {
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "No exclude file loaded or defined!");
+  }
+
+  /* update detection for local replica */
+  csync_gettime(&start);
+  ctx->current = LOCAL_REPLICA;
+  ctx->replica = ctx->local.type;
+
+  rc = csync_ftw(ctx, ctx->local.uri, csync_walker, MAX_DEPTH);
+  if (rc < 0) {
+    if(ctx->status_code == CSYNC_STATUS_OK) {
+        ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_UPDATE_ERROR);
+    }
+    goto out;
+  }
+
+  csync_gettime(&finish);
+
+  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
+            "Update detection for local replica took %.2f seconds walking %zu files.",
+            c_secdiff(finish, start), c_rbtree_size(ctx->local.tree));
+  csync_memstat_check();
+
+  /* update detection for remote replica */
+  csync_gettime(&start);
+  ctx->current = REMOTE_REPLICA;
+  ctx->replica = ctx->remote.type;
+
+  rc = csync_ftw(ctx, "", csync_walker, MAX_DEPTH);
+  if (rc < 0) {
+      if(ctx->status_code == CSYNC_STATUS_OK) {
+          ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_UPDATE_ERROR);
+      }
+      goto out;
+  }
+
+  csync_gettime(&finish);
+
+  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
+            "Update detection for remote replica took %.2f seconds "
+            "walking %zu files.",
+            c_secdiff(finish, start), c_rbtree_size(ctx->remote.tree));
+  csync_memstat_check();
+
+  ctx->status |= CSYNC_STATUS_UPDATE;
+
+  rc = 0;
+
+out:
+  csync_statedb_close(ctx);
+  return rc;
+}
+
+int csync_reconcile(CSYNC *ctx) {
+  int rc = -1;
+  struct timespec start, finish;
+
+  if (ctx == NULL) {
+    errno = EBADF;
+    return -1;
+  }
+  ctx->status_code = CSYNC_STATUS_OK;
+
+  /* Reconciliation for local replica */
+  csync_gettime(&start);
+
+  if (csync_statedb_load(ctx, ctx->statedb.file, &ctx->statedb.db) < 0) {
+    rc = -1;
+    return rc;
+  }
+
+  ctx->current = LOCAL_REPLICA;
+  ctx->replica = ctx->local.type;
+
+  rc = csync_reconcile_updates(ctx);
+
+  csync_gettime(&finish);
+
+  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
+      "Reconciliation for local replica took %.2f seconds visiting %zu files.",
+      c_secdiff(finish, start), c_rbtree_size(ctx->local.tree));
+
+  if (rc < 0) {
+      if (!CSYNC_STATUS_IS_OK(ctx->status_code)) {
+          ctx->status_code = csync_errno_to_status( errno, CSYNC_STATUS_RECONCILE_ERROR );
+      }
+      goto out;
+  }
+
+  /* Reconciliation for remote replica */
+  csync_gettime(&start);
+
+  ctx->current = REMOTE_REPLICA;
+  ctx->replica = ctx->remote.type;
+
+  rc = csync_reconcile_updates(ctx);
+
+  csync_gettime(&finish);
+
+  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
+      "Reconciliation for remote replica took %.2f seconds visiting %zu files.",
+      c_secdiff(finish, start), c_rbtree_size(ctx->remote.tree));
+
+  if (rc < 0) {
+      if (!CSYNC_STATUS_IS_OK(ctx->status_code)) {
+          ctx->status_code = csync_errno_to_status(errno,  CSYNC_STATUS_RECONCILE_ERROR );
+      }
+      goto out;
+  }
+
+  ctx->status |= CSYNC_STATUS_RECONCILE;
+
+  rc = 0;
+
+out:
+  csync_statedb_close(ctx);
+  return 0;
+}
+
+/*
+ * local visitor which calls the user visitor with repacked stat info.
+ */
+static int _csync_treewalk_visitor(void *obj, void *data) {
+    int rc = 0;
+    csync_file_stat_t *cur         = NULL;
+    CSYNC *ctx                     = NULL;
+    c_rbtree_visit_func *visitor   = NULL;
+    _csync_treewalk_context *twctx = NULL;
+    TREE_WALK_FILE trav;
+    c_rbtree_t *other_tree = NULL;
+    c_rbnode_t *other_node = NULL;
+
+    cur = (csync_file_stat_t *) obj;
+    ctx = (CSYNC *) data;
+
+    if (ctx == NULL) {
+      return -1;
+    }
+
+    /* we need the opposite tree! */
+    switch (ctx->current) {
+    case LOCAL_REPLICA:
+        other_tree = ctx->remote.tree;
+        break;
+    case REMOTE_REPLICA:
+        other_tree = ctx->local.tree;
+        break;
+    default:
+        break;
+    }
+
+    other_node = c_rbtree_find(other_tree, &cur->phash);
+
+    if (!other_node) {
+        /* Check the renamed path as well. */
+        int len;
+        uint64_t h = 0;
+        char *renamed_path = csync_rename_adjust_path(ctx, cur->path);
+
+        if (!c_streq(renamed_path, cur->path)) {
+            len = strlen( renamed_path );
+            h = c_jhash64((uint8_t *) renamed_path, len, 0);
+            other_node = c_rbtree_find(other_tree, &h);
+        }
+        SAFE_FREE(renamed_path);
+    }
+
+    if (!other_node) {
+        /* Check the source path as well. */
+        int len;
+        uint64_t h = 0;
+        char *renamed_path = csync_rename_adjust_path_source(ctx, cur->path);
+
+        if (!c_streq(renamed_path, cur->path)) {
+            len = strlen( renamed_path );
+            h = c_jhash64((uint8_t *) renamed_path, len, 0);
+            other_node = c_rbtree_find(other_tree, &h);
+        }
+        SAFE_FREE(renamed_path);
+    }
+
+    if (obj == NULL || data == NULL) {
+      ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
+      return -1;
+    }
+    ctx->status_code = CSYNC_STATUS_OK;
+
+    twctx = (_csync_treewalk_context*) ctx->callbacks.userdata;
+    if (twctx == NULL) {
+      ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
+      return -1;
+    }
+
+    if (twctx->instruction_filter > 0 &&
+        !(twctx->instruction_filter & cur->instruction) ) {
+        return 0;
+    }
+
+    visitor = (c_rbtree_visit_func*)(twctx->user_visitor);
+    if (visitor != NULL) {
+      trav.path         = cur->path;
+      trav.size         = cur->size;
+      trav.modtime      = cur->modtime;
+      trav.mode         = cur->mode;
+      trav.type         = cur->type;
+      trav.instruction  = cur->instruction;
+      trav.rename_path  = cur->destpath;
+      trav.etag         = cur->etag;
+      trav.file_id      = cur->file_id;
+      trav.remotePerm = cur->remotePerm;
+      trav.directDownloadUrl = cur->directDownloadUrl;
+      trav.directDownloadCookies = cur->directDownloadCookies;
+      trav.inode        = cur->inode;
+
+      trav.error_status = cur->error_status;
+      trav.has_ignored_files = cur->has_ignored_files;
+      trav.checksumHeader = cur->checksumHeader;
+
+      if( other_node ) {
+          csync_file_stat_t *other_stat = (csync_file_stat_t*)other_node->data;
+          trav.other.etag = other_stat->etag;
+          trav.other.file_id = other_stat->file_id;
+          trav.other.instruction = other_stat->instruction;
+          trav.other.modtime = other_stat->modtime;
+          trav.other.size = other_stat->size;
+      } else {
+          trav.other.etag = 0;
+          trav.other.file_id = 0;
+          trav.other.instruction = CSYNC_INSTRUCTION_NONE;
+          trav.other.modtime = 0;
+          trav.other.size = 0;
+      }
+
+      rc = (*visitor)(&trav, twctx->userdata);
+      cur->instruction = trav.instruction;
+      if (trav.etag != cur->etag) { // FIXME It would be nice to have this documented
+          SAFE_FREE(cur->etag);
+          cur->etag = c_strdup(trav.etag);
+      }
+
+      return rc;
+    }
+    ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
+    return -1;
+}
+
+/*
+ * treewalk function, called from its wrappers below.
+ *
+ * it encapsulates the user visitor function, the filter and the userdata
+ * into a treewalk_context structure and calls the rb treewalk function,
+ * which calls the local _csync_treewalk_visitor in this module.
+ * The user visitor is called from there.
+ */
+static int _csync_walk_tree(CSYNC *ctx, c_rbtree_t *tree, csync_treewalk_visit_func *visitor, int filter)
+{
+    _csync_treewalk_context tw_ctx;
+    int rc = -1;
+
+    if (ctx == NULL) {
+        errno = EBADF;
+        return rc;
+    }
+
+    if (visitor == NULL || tree == NULL) {
+        ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
+        return rc;
+    }
+    
+    tw_ctx.userdata = ctx->callbacks.userdata;
+    tw_ctx.user_visitor = visitor;
+    tw_ctx.instruction_filter = filter;
+
+    ctx->callbacks.userdata = &tw_ctx;
+
+    rc = c_rbtree_walk(tree, (void*) ctx, _csync_treewalk_visitor);
+    if( rc < 0 ) {
+      if( ctx->status_code == CSYNC_STATUS_OK )
+          ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_TREE_ERROR);
+    }
+    ctx->callbacks.userdata = tw_ctx.userdata;
+
+    return rc;
+}
+
+/*
+ * wrapper function for treewalk on the remote tree
+ */
+int csync_walk_remote_tree(CSYNC *ctx,  csync_treewalk_visit_func *visitor, int filter)
+{
+    c_rbtree_t *tree = NULL;
+    int rc = -1;
+
+    if(ctx != NULL) {
+        ctx->status_code = CSYNC_STATUS_OK;
+        ctx->current = REMOTE_REPLICA;
+        tree = ctx->remote.tree;
+    }
+
+    /* all error handling in the called function */
+    rc = _csync_walk_tree(ctx, tree, visitor, filter);
+    return rc;
+}
+
+/*
+ * wrapper function for treewalk on the local tree
+ */
+int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter)
+{
+    c_rbtree_t *tree = NULL;
+    int rc = -1;
+
+    if (ctx != NULL) {
+        ctx->status_code = CSYNC_STATUS_OK;
+        ctx->current = LOCAL_REPLICA;
+        tree = ctx->local.tree;
+    }
+
+    /* all error handling in the called function */
+    rc = _csync_walk_tree(ctx, tree, visitor, filter);
+    return rc;  
+}
+
+static void _tree_destructor(void *data) {
+  csync_file_stat_t *freedata = NULL;
+
+  freedata = (csync_file_stat_t *) data;
+  csync_file_stat_free(freedata);
+}
+
+/* reset all the list to empty.
+ * used by csync_commit and csync_destroy */
+static void _csync_clean_ctx(CSYNC *ctx)
+{
+    /* destroy the rbtrees */
+    if (c_rbtree_size(ctx->local.tree) > 0) {
+        c_rbtree_destroy(ctx->local.tree, _tree_destructor);
+    }
+
+    if (c_rbtree_size(ctx->remote.tree) > 0) {
+        c_rbtree_destroy(ctx->remote.tree, _tree_destructor);
+    }
+
+    csync_rename_destroy(ctx);
+
+    /* free memory */
+    c_rbtree_free(ctx->local.tree);
+    c_rbtree_free(ctx->remote.tree);
+
+    SAFE_FREE(ctx->remote.root_perms);
+}
+
+int csync_commit(CSYNC *ctx) {
+  int rc = 0;
+
+  if (ctx == NULL) {
+    return -1;
+  }
+
+  ctx->status_code = CSYNC_STATUS_OK;
+
+  if (ctx->statedb.db != NULL
+      && csync_statedb_close(ctx) < 0) {
+    CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "ERR: closing of statedb failed.");
+    rc = -1;
+  }
+  ctx->statedb.db = NULL;
+
+  _csync_clean_ctx(ctx);
+
+  ctx->remote.read_from_db = 0;
+  ctx->read_remote_from_db = true;
+  ctx->db_is_empty = false;
+
+
+  /* Create new trees */
+  c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
+  c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);
+
+
+  ctx->status = CSYNC_STATUS_INIT;
+  SAFE_FREE(ctx->error_string);
+
+  rc = 0;
+  return rc;
+}
+
+int csync_destroy(CSYNC *ctx) {
+  int rc = 0;
+
+  if (ctx == NULL) {
+    errno = EBADF;
+    return -1;
+  }
+  ctx->status_code = CSYNC_STATUS_OK;
+
+  if (ctx->statedb.db != NULL
+      && csync_statedb_close(ctx) < 0) {
+    CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "ERR: closing of statedb failed.");
+    rc = -1;
+  }
+  ctx->statedb.db = NULL;
+
+  _csync_clean_ctx(ctx);
+
+  SAFE_FREE(ctx->statedb.file);
+  SAFE_FREE(ctx->local.uri);
+  SAFE_FREE(ctx->error_string);
+
+  SAFE_FREE(ctx);
+
+  return rc;
+}
+
+void *csync_get_userdata(CSYNC *ctx) {
+  if (ctx == NULL) {
+    return NULL;
+  }
+  return ctx->callbacks.userdata;
+}
+
+int csync_set_userdata(CSYNC *ctx, void *userdata) {
+  if (ctx == NULL) {
+    return -1;
+  }
+
+  ctx->callbacks.userdata = userdata;
+
+  return 0;
+}
+
+csync_auth_callback csync_get_auth_callback(CSYNC *ctx) {
+  if (ctx == NULL) {
+    return NULL;
+  }
+
+  return ctx->callbacks.auth_function;
+}
+
+int csync_set_status(CSYNC *ctx, int status) {
+  if (ctx == NULL || status < 0) {
+    return -1;
+  }
+
+  ctx->status = status;
+
+  return 0;
+}
+
+CSYNC_STATUS csync_get_status(CSYNC *ctx) {
+  if (ctx == NULL) {
+    return -1;
+  }
+
+  return ctx->status_code;
+}
+
+const char *csync_get_status_string(CSYNC *ctx)
+{
+  return csync_vio_get_status_string(ctx);
+}
+
+void csync_request_abort(CSYNC *ctx)
+{
+  if (ctx != NULL) {
+    ctx->abort = true;
+  }
+}
+
+void csync_resume(CSYNC *ctx)
+{
+  if (ctx != NULL) {
+    ctx->abort = false;
+  }
+}
+
+int  csync_abort_requested(CSYNC *ctx)
+{
+  if (ctx != NULL) {
+    return ctx->abort;
+  } else {
+    return (1 == 0);
+  }
+}
+
+void csync_file_stat_free(csync_file_stat_t *st)
+{
+  if (st) {
+    SAFE_FREE(st->directDownloadUrl);
+    SAFE_FREE(st->directDownloadCookies);
+    SAFE_FREE(st->etag);
+    SAFE_FREE(st->destpath);
+    SAFE_FREE(st->checksumHeader);
+    SAFE_FREE(st);
+  }
+}
diff --git a/src/csync/csync.h b/src/csync/csync.h
new file mode 100644 (file)
index 0000000..daf778c
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file csync.h
+ *
+ * @brief Application developer interface for csync.
+ *
+ * @defgroup csyncPublicAPI csync public API
+ *
+ * @{
+ */
+
+#ifndef _CSYNC_H
+#define _CSYNC_H
+
+#include "std/c_private.h"
+#include "ocsynclib.h"
+#include <sys/stat.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <config_csync.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum csync_status_codes_e {
+  CSYNC_STATUS_OK         = 0,
+
+  CSYNC_STATUS_ERROR      = 1024, /* don't use this code,
+                                     */
+  CSYNC_STATUS_UNSUCCESSFUL,       /* Unspecific problem happend */
+  CSYNC_STATUS_NO_LOCK,            /* OBSOLETE  does not happen anymore */
+  CSYNC_STATUS_STATEDB_LOAD_ERROR, /* Statedb can not be loaded. */
+  CSYNC_STATUS_STATEDB_CORRUPTED,  /* Statedb is corrupted */
+  CSYNC_STATUS_NO_MODULE,          /* URL passed to csync does not start with owncloud:// or ownclouds:// */
+  CSYNC_STATUS_TIMESKEW,           /* OBSOLETE */
+  CSYNC_STATUS_FILESYSTEM_UNKNOWN, /* UNUSED */
+  CSYNC_STATUS_TREE_ERROR,         /* csync trees could not be created */
+  CSYNC_STATUS_MEMORY_ERROR,       /* not enough memory problem */
+  CSYNC_STATUS_PARAM_ERROR,        /* parameter is zero where not expected */
+  CSYNC_STATUS_UPDATE_ERROR,       /* general update or discovery error */
+  CSYNC_STATUS_RECONCILE_ERROR,    /* general reconcile error */
+  CSYNC_STATUS_PROPAGATE_ERROR,    /* OBSOLETE */
+  CSYNC_STATUS_REMOTE_ACCESS_ERROR, /* UNUSED */
+  CSYNC_STATUS_REMOTE_CREATE_ERROR, /* UNUSED */
+  CSYNC_STATUS_REMOTE_STAT_ERROR,  /* UNUSED */
+  CSYNC_STATUS_LOCAL_CREATE_ERROR, /* UNUSED */
+  CSYNC_STATUS_LOCAL_STAT_ERROR,   /* UNUSED */
+  CSYNC_STATUS_PROXY_ERROR,        /* UNUSED */
+  CSYNC_STATUS_LOOKUP_ERROR,       /* Neon fails to find proxy. Almost OBSOLETE */
+  CSYNC_STATUS_SERVER_AUTH_ERROR,  /* UNUSED */
+  CSYNC_STATUS_PROXY_AUTH_ERROR,   /* UNUSED */
+  CSYNC_STATUS_CONNECT_ERROR,      /* neon driven connection failed */
+  CSYNC_STATUS_TIMEOUT,            /* UNUSED */
+  CSYNC_STATUS_HTTP_ERROR,         /* UNUSED */
+  CSYNC_STATUS_PERMISSION_DENIED,  /*  */
+  CSYNC_STATUS_NOT_FOUND,
+  CSYNC_STATUS_FILE_EXISTS,
+  CSYNC_STATUS_OUT_OF_SPACE,
+  CSYNC_STATUS_QUOTA_EXCEEDED, /* UNUSED */
+  CSYNC_STATUS_SERVICE_UNAVAILABLE,
+  CSYNC_STATUS_STORAGE_UNAVAILABLE,
+  CSYNC_STATUS_FILE_SIZE_ERROR,
+  CSYNC_STATUS_CONTEXT_LOST,
+  CSYNC_STATUS_MERGE_FILETREE_ERROR,
+  CSYNC_STATUS_CSYNC_STATUS_ERROR,
+  CSYNC_STATUS_OPENDIR_ERROR,
+  CSYNC_STATUS_READDIR_ERROR,
+  CSYNC_STATUS_OPEN_ERROR,
+  CSYNC_STATUS_ABORTED,
+    /* Codes for file individual status: */
+    CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK,
+    CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST,
+    CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS,
+    CSYNC_STATUS_INDIVIDUAL_TRAILING_SPACE,
+    CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME,
+    CYSNC_STATUS_FILE_LOCKED_OR_OPEN,
+    CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN,
+    CSYNC_STATUS_INVALID_CHARACTERS,
+    CSYNC_STATUS_INDIVIDUAL_STAT_FAILED,
+    CSYNC_STATUS_FORBIDDEN,
+    CSYNC_STATUS_INDIVIDUAL_TOO_DEEP,
+    CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE
+};
+
+typedef enum csync_status_codes_e CSYNC_STATUS;
+
+#ifndef likely
+# define likely(x) (x)
+#endif
+#ifndef unlikely
+# define unlikely(x) (x)
+#endif
+
+#define CSYNC_STATUS_IS_OK(x) (likely((x) == CSYNC_STATUS_OK))
+#define CSYNC_STATUS_IS_ERR(x) (unlikely((x) >= CSYNC_STATUS_ERROR))
+#define CSYNC_STATUS_IS_EQUAL(x, y) ((x) == (y))
+
+/**
+  * Instruction enum. In the file traversal structure, it describes
+  * the csync state of a file.
+  */
+enum csync_instructions_e {
+  CSYNC_INSTRUCTION_NONE            = 0x00000000,  /* Nothing to do (UPDATE|RECONCILE) */
+  CSYNC_INSTRUCTION_EVAL            = 0x00000001,  /* There was changed compared to the DB (UPDATE) */
+  CSYNC_INSTRUCTION_REMOVE          = 0x00000002,  /* The file need to be removed (RECONCILE) */
+  CSYNC_INSTRUCTION_RENAME          = 0x00000004,  /* The file need to be renamed (RECONCILE) */
+  CSYNC_INSTRUCTION_EVAL_RENAME     = 0x00000800,  /* The file is new, it is the destination of a rename (UPDATE) */
+  CSYNC_INSTRUCTION_NEW             = 0x00000008,  /* The file is new compared to the db (UPDATE) */
+  CSYNC_INSTRUCTION_CONFLICT        = 0x00000010,  /* The file need to be downloaded because it is a conflict (RECONCILE) */
+  CSYNC_INSTRUCTION_IGNORE          = 0x00000020,  /* The file is ignored (UPDATE|RECONCILE) */
+  CSYNC_INSTRUCTION_SYNC            = 0x00000040,  /* The file need to be pushed to the other remote (RECONCILE) */
+  CSYNC_INSTRUCTION_STAT_ERROR      = 0x00000080,
+  CSYNC_INSTRUCTION_ERROR           = 0x00000100,
+  CSYNC_INSTRUCTION_TYPE_CHANGE     = 0x00000200,  /* Like NEW, but deletes the old entity first (RECONCILE)
+                                                      Used when the type of something changes from directory to file
+                                                      or back. */
+  CSYNC_INSTRUCTION_UPDATE_METADATA = 0x00000400,  /* If the etag has been updated and need to be writen to the db,
+                                                      but without any propagation (UPDATE|RECONCILE) */
+};
+
+enum csync_ftw_type_e {
+    CSYNC_FTW_TYPE_FILE,
+    CSYNC_FTW_TYPE_SLINK,
+    CSYNC_FTW_TYPE_DIR,
+    CSYNC_FTW_TYPE_SKIP
+};
+
+
+#define FILE_ID_BUF_SIZE 36
+
+// currently specified at https://github.com/owncloud/core/issues/8322 are 9 to 10
+#define REMOTE_PERM_BUF_SIZE 15
+
+typedef struct csync_vio_file_stat_s csync_vio_file_stat_t;
+
+enum csync_vio_file_flags_e {
+  CSYNC_VIO_FILE_FLAGS_NONE = 0,
+  CSYNC_VIO_FILE_FLAGS_SYMLINK = 1 << 0,
+  CSYNC_VIO_FILE_FLAGS_HIDDEN = 1 << 1
+};
+
+enum csync_vio_file_type_e {
+  CSYNC_VIO_FILE_TYPE_UNKNOWN,
+  CSYNC_VIO_FILE_TYPE_REGULAR,
+  CSYNC_VIO_FILE_TYPE_DIRECTORY,
+  CSYNC_VIO_FILE_TYPE_FIFO,
+  CSYNC_VIO_FILE_TYPE_SOCKET,
+  CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE,
+  CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE,
+  CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK
+};
+
+enum csync_vio_file_stat_fields_e {
+  CSYNC_VIO_FILE_STAT_FIELDS_NONE = 0,
+  CSYNC_VIO_FILE_STAT_FIELDS_TYPE = 1 << 0,
+  CSYNC_VIO_FILE_STAT_FIELDS_MODE = 1 << 1, // local POSIX mode
+  CSYNC_VIO_FILE_STAT_FIELDS_FLAGS = 1 << 2,
+//  CSYNC_VIO_FILE_STAT_FIELDS_DEVICE = 1 << 3,
+  CSYNC_VIO_FILE_STAT_FIELDS_INODE = 1 << 4,
+//  CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT = 1 << 5,
+  CSYNC_VIO_FILE_STAT_FIELDS_SIZE = 1 << 6,
+//  CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_COUNT = 1 << 7, /* will be removed */
+//  CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_SIZE = 1 << 8,  /* will be removed */
+  CSYNC_VIO_FILE_STAT_FIELDS_ATIME = 1 << 9,
+  CSYNC_VIO_FILE_STAT_FIELDS_MTIME = 1 << 10,
+  CSYNC_VIO_FILE_STAT_FIELDS_CTIME = 1 << 11,
+//  CSYNC_VIO_FILE_STAT_FIELDS_SYMLINK_NAME = 1 << 12,
+//  CSYNC_VIO_FILE_STAT_FIELDS_CHECKSUM = 1 << 13,
+//  CSYNC_VIO_FILE_STAT_FIELDS_ACL = 1 << 14,
+//  CSYNC_VIO_FILE_STAT_FIELDS_UID = 1 << 15,
+//  CSYNC_VIO_FILE_STAT_FIELDS_GID = 1 << 16,
+  CSYNC_VIO_FILE_STAT_FIELDS_ETAG = 1 << 17,
+  CSYNC_VIO_FILE_STAT_FIELDS_FILE_ID = 1 << 18,
+  CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADURL = 1 << 19,
+  CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADCOOKIES = 1 << 20,
+  CSYNC_VIO_FILE_STAT_FIELDS_PERM = 1 << 21 // remote oC perm
+
+};
+
+
+struct csync_vio_file_stat_s {
+  char *name;
+  char *etag; // FIXME: Should this be inlined like file_id and perm?
+  char file_id[FILE_ID_BUF_SIZE+1];
+  char *directDownloadUrl;
+  char *directDownloadCookies;
+  char remotePerm[REMOTE_PERM_BUF_SIZE+1];
+
+  time_t atime;
+  time_t mtime;
+  time_t ctime;
+
+  int64_t size;
+
+  mode_t mode;
+
+  uint64_t inode;
+
+  int fields; // actually enum csync_vio_file_stat_fields_e fields;
+  enum csync_vio_file_type_e type;
+
+  enum csync_vio_file_flags_e flags;
+
+  char *original_name; // only set if locale conversion fails
+
+  // For remote file stats: the highest quality checksum the server provided
+  // in the "SHA1:324315da2143" form.
+  char *checksumHeader;
+};
+
+csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_new(void);
+csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
+
+void OCSYNC_EXPORT csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat);
+
+void OCSYNC_EXPORT csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src );
+
+void OCSYNC_EXPORT csync_vio_set_file_id(char* dst, const char *src );
+
+
+/**
+ * CSync File Traversal structure.
+ *
+ * This structure is passed to the visitor function for every file
+ * which is seen.
+ *
+ */
+
+struct csync_tree_walk_file_s {
+    const char *path;
+    int64_t     size;
+    int64_t     inode;
+    time_t      modtime;
+    mode_t      mode;
+    enum csync_ftw_type_e     type;
+    enum csync_instructions_e instruction;
+
+    /* For directories: Does it have children that were ignored (hidden or ignore pattern) */
+    int         has_ignored_files;
+
+    const char *rename_path;
+    const char *etag;
+    const char *file_id;
+    const char *remotePerm;
+    char *directDownloadUrl;
+    char *directDownloadCookies;
+
+    const char *checksumHeader;
+
+    struct {
+        int64_t     size;
+        time_t      modtime;
+        const char *etag;
+        const char *file_id;
+        enum csync_instructions_e instruction;
+    } other;
+
+    CSYNC_STATUS error_status;
+};
+typedef struct csync_tree_walk_file_s TREE_WALK_FILE;
+
+/**
+ * csync handle
+ */
+typedef struct csync_s CSYNC;
+
+typedef int (*csync_auth_callback) (const char *prompt, char *buf, size_t len,
+    int echo, int verify, void *userdata);
+
+typedef void (*csync_log_callback) (int verbosity,
+                                    const char *function,
+                                    const char *buffer);
+
+typedef void (*csync_update_callback) (bool local,
+                                    const char *dirUrl,
+                                    void *userdata);
+
+typedef void csync_vio_handle_t;
+typedef csync_vio_handle_t* (*csync_vio_opendir_hook) (const char *url,
+                                    void *userdata);
+typedef csync_vio_file_stat_t* (*csync_vio_readdir_hook) (csync_vio_handle_t *dhhandle,
+                                                              void *userdata);
+typedef void (*csync_vio_closedir_hook) (csync_vio_handle_t *dhhandle,
+                                                              void *userdata);
+typedef int (*csync_vio_stat_hook) (csync_vio_handle_t *dhhandle,
+                                                              void *userdata);
+
+/* Compute the checksum of the given \a checksumTypeId for \a path. */
+typedef const char *(*csync_checksum_hook)(
+    const char *path, const char *otherChecksumHeader, void *userdata);
+
+/**
+ * @brief Allocate a csync context.
+ *
+ * @param csync  The context variable to allocate.
+ */
+void OCSYNC_EXPORT csync_create(CSYNC **csync, const char *local);
+
+/**
+ * @brief Initialize the file synchronizer.
+ *
+ * This function loads the configuration
+ *
+ * @param ctx  The context to initialize.
+ */
+void OCSYNC_EXPORT csync_init(CSYNC *ctx, const char *db_file);
+
+/**
+ * @brief Update detection
+ *
+ * @param ctx  The context to run the update detection on.
+ *
+ * @return  0 on success, less than 0 if an error occurred.
+ */
+int OCSYNC_EXPORT csync_update(CSYNC *ctx);
+
+/**
+ * @brief Reconciliation
+ *
+ * @param ctx  The context to run the reconciliation on.
+ *
+ * @return  0 on success, less than 0 if an error occurred.
+ */
+int OCSYNC_EXPORT csync_reconcile(CSYNC *ctx);
+
+/**
+ * @brief Re-initializes the csync context
+ *
+ * @param ctx  The context to commit.
+ *
+ * @return  0 on success, less than 0 if an error occurred.
+ */
+int OCSYNC_EXPORT csync_commit(CSYNC *ctx);
+
+/**
+ * @brief Destroy the csync context
+ *
+ * frees the memory.
+ *
+ * @param ctx  The context to destroy.
+ *
+ * @return  0 on success, less than 0 if an error occurred.
+ */
+int OCSYNC_EXPORT csync_destroy(CSYNC *ctx);
+
+/**
+ * @brief Get the userdata saved in the context.
+ *
+ * @param ctx           The csync context.
+ *
+ * @return              The userdata saved in the context, NULL if an error
+ *                      occurred.
+ */
+void *csync_get_userdata(CSYNC *ctx);
+
+/**
+ * @brief Save userdata to the context which is passed to the auth
+ * callback function.
+ *
+ * @param ctx           The csync context.
+ *
+ * @param userdata      The userdata to be stored in the context.
+ *
+ * @return              0 on success, less than 0 if an error occurred.
+ */
+int OCSYNC_EXPORT csync_set_userdata(CSYNC *ctx, void *userdata);
+
+/**
+ * @brief Get the authentication callback set.
+ *
+ * @param ctx           The csync context.
+ *
+ * @return              The authentication callback set or NULL if an error
+ *                      occurred.
+ */
+csync_auth_callback OCSYNC_EXPORT csync_get_auth_callback(CSYNC *ctx);
+
+/**
+ * @brief Set the authentication callback.
+ *
+ * @param ctx           The csync context.
+ *
+ * @param cb            The authentication callback.
+ *
+ * @return              0 on success, less than 0 if an error occurred.
+ */
+int OCSYNC_EXPORT csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
+
+/**
+ * @brief Set the log level.
+ *
+ * @param[in]  level  The log verbosity.
+ *
+ * @return 0 on success, < 0 if an error occurred.
+ */
+int OCSYNC_EXPORT csync_set_log_level(int level);
+
+/**
+ * @brief Get the log verbosity
+ *
+ * @return            The log verbosity, -1 on error.
+ */
+int OCSYNC_EXPORT csync_get_log_level(void);
+
+/**
+ * @brief Get the logging callback set.
+ *
+ * @return              The logging callback set or NULL if an error
+ *                      occurred.
+ */
+csync_log_callback OCSYNC_EXPORT csync_get_log_callback(void);
+
+/**
+ * @brief Set the logging callback.
+ *
+ * @param cb            The logging callback.
+ *
+ * @return              0 on success, less than 0 if an error occurred.
+ */
+int OCSYNC_EXPORT csync_set_log_callback(csync_log_callback cb);
+
+/* Used for special modes or debugging */
+CSYNC_STATUS OCSYNC_EXPORT csync_get_status(CSYNC *ctx);
+
+/* Used for special modes or debugging */
+int OCSYNC_EXPORT csync_set_status(CSYNC *ctx, int status);
+
+typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
+
+/**
+ * @brief Walk the local file tree and call a visitor function for each file.
+ *
+ * @param ctx           The csync context.
+ * @param visitor       A callback function to handle the file info.
+ * @param filter        A filter, built from or'ed csync_instructions_e
+ *
+ * @return              0 on success, less than 0 if an error occurred.
+ */
+int OCSYNC_EXPORT csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
+
+/**
+ * @brief Walk the remote file tree and call a visitor function for each file.
+ *
+ * @param ctx           The csync context.
+ * @param visitor       A callback function to handle the file info.
+ * @param filter        A filter, built from and'ed csync_instructions_e
+ *
+ * @return              0 on success, less than 0 if an error occurred.
+ */
+int OCSYNC_EXPORT csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
+
+/**
+ * @brief Get the csync status string.
+ *
+ * @param ctx            The csync context.
+ *
+ * @return               A const pointer to a string with more precise status info.
+ */
+const char OCSYNC_EXPORT *csync_get_status_string(CSYNC *ctx);
+
+/**
+ * @brief Aborts the current sync run as soon as possible. Can be called from another thread.
+ *
+ * @param ctx           The csync context.
+ */
+void OCSYNC_EXPORT csync_request_abort(CSYNC *ctx);
+
+/**
+ * @brief Clears the abort flag. Can be called from another thread.
+ *
+ * @param ctx           The csync context.
+ */
+void OCSYNC_EXPORT csync_resume(CSYNC *ctx);
+
+/**
+ * @brief Checks for the abort flag, to be used from the modules.
+ *
+ * @param ctx           The csync context.
+ */
+int  OCSYNC_EXPORT csync_abort_requested(CSYNC *ctx);
+
+char OCSYNC_EXPORT *csync_normalize_etag(const char *);
+time_t OCSYNC_EXPORT oc_httpdate_parse( const char *date );
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * }@
+ */
+#endif /* _CSYNC_H */
+/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/src/csync/csync_exclude.c b/src/csync/csync_exclude.c
new file mode 100644 (file)
index 0000000..fea6625
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "c_lib.h"
+#include "c_private.h"
+
+#include "csync_private.h"
+#include "csync_exclude.h"
+#include "csync_misc.h"
+
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#define CSYNC_LOG_CATEGORY_NAME "csync.exclude"
+#include "csync_log.h"
+
+#ifndef WITH_TESTING
+static
+#endif
+int _csync_exclude_add(c_strlist_t **inList, const char *string) {
+    size_t i = 0;
+
+    // We never want duplicates, so check whether the string is already
+    // in the list first.
+    if (*inList) {
+        for (i = 0; i < (*inList)->count; ++i) {
+            char *pattern = (*inList)->vector[i];
+            if (c_streq(pattern, string)) {
+                return 1;
+            }
+        }
+    }
+    return c_strlist_add_grow(inList, string);
+}
+
+/** Expands C-like escape sequences.
+ *
+ * The returned string is heap-allocated and owned by the caller.
+ */
+static const char *csync_exclude_expand_escapes(const char * input)
+{
+    size_t i_len = strlen(input) + 1;
+    char *out = c_malloc(i_len); // out can only be shorter
+
+    size_t i = 0;
+    size_t o = 0;
+    for (; i < i_len; ++i) {
+        if (input[i] == '\\') {
+            // at worst input[i+1] is \0
+            switch (input[i+1]) {
+            case '\'': out[o++] = '\''; break;
+            case '"': out[o++] = '"'; break;
+            case '?': out[o++] = '?'; break;
+            case '\\': out[o++] = '\\'; break;
+            case 'a': out[o++] = '\a'; break;
+            case 'b': out[o++] = '\b'; break;
+            case 'f': out[o++] = '\f'; break;
+            case 'n': out[o++] = '\n'; break;
+            case 'r': out[o++] = '\r'; break;
+            case 't': out[o++] = '\t'; break;
+            case 'v': out[o++] = '\v'; break;
+            default:
+                out[o++] = input[i];
+                out[o++] = input[i+1];
+                break;
+            }
+            ++i;
+        } else {
+            out[o++] = input[i];
+        }
+    }
+    return out;
+}
+
+int csync_exclude_load(const char *fname, c_strlist_t **list) {
+  int fd = -1;
+  int i = 0;
+  int rc = -1;
+  int64_t size;
+  char *buf = NULL;
+  char *entry = NULL;
+  mbchar_t *w_fname;
+
+  if (fname == NULL) {
+      return -1;
+  }
+
+#ifdef _WIN32
+  _fmode = _O_BINARY;
+#endif
+
+  w_fname = c_utf8_path_to_locale(fname);
+  if (w_fname == NULL) {
+      return -1;
+  }
+
+  fd = _topen(w_fname, O_RDONLY);
+  c_free_locale_string(w_fname);
+  if (fd < 0) {
+    return -1;
+  }
+
+  size = lseek(fd, 0, SEEK_END);
+  if (size < 0) {
+    rc = -1;
+    goto out;
+  }
+  lseek(fd, 0, SEEK_SET);
+  if (size == 0) {
+    rc = 0;
+    goto out;
+  }
+  buf = c_malloc(size + 1);
+  if (read(fd, buf, size) != size) {
+    rc = -1;
+    goto out;
+  }
+  buf[size] = '\0';
+
+  /* FIXME: Use fgets and don't add duplicates */
+  entry = buf;
+  for (i = 0; i < size; i++) {
+    if (buf[i] == '\n' || buf[i] == '\r') {
+      if (entry != buf + i) {
+        buf[i] = '\0';
+        if (*entry != '#') {
+          const char *unescaped = csync_exclude_expand_escapes(entry);
+          rc = _csync_exclude_add(list, unescaped);
+          if( rc == 0 ) {
+              CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
+          }
+          SAFE_FREE(unescaped);
+          if (rc < 0) {
+              goto out;
+          }
+        }
+      }
+      entry = buf + i + 1;
+    }
+  }
+
+  rc = 0;
+out:
+  SAFE_FREE(buf);
+  close(fd);
+  return rc;
+}
+
+// See http://support.microsoft.com/kb/74496 and
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
+// Additionally, we ignore '$Recycle.Bin', see https://github.com/owncloud/client/issues/2955
+static const char* win_reserved_words[] = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5",
+                                           "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4",
+                                           "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", "CLOCK$", "$Recycle.Bin" };
+
+bool csync_is_windows_reserved_word(const char* filename) {
+
+  size_t win_reserve_words_len = sizeof(win_reserved_words) / sizeof(char*);
+  size_t j;
+
+  for (j = 0; j < win_reserve_words_len; j++) {
+    int len_reserved_word = strlen(win_reserved_words[j]);
+    int len_filename = strlen(filename);
+    if (len_filename == 2 && filename[1] == ':') {
+        if (filename[0] >= 'a' && filename[0] <= 'z') {
+            return true;
+        }
+        if (filename[0] >= 'A' && filename[0] <= 'Z') {
+            return true;
+        }
+    }
+    if (c_strncasecmp(filename, win_reserved_words[j], len_reserved_word) == 0) {
+        if (len_filename == len_reserved_word) {
+            return true;
+        }
+        if ((len_filename > len_reserved_word) && (filename[len_reserved_word] == '.')) {
+            return true;
+        }
+    }
+  }
+  return false;
+}
+
+static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const char *path, int filetype, bool check_leading_dirs) {
+    size_t i = 0;
+    const char *bname = NULL;
+    size_t blen = 0;
+    char *conflict = NULL;
+    int rc = -1;
+    CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED;
+    CSYNC_EXCLUDE_TYPE type  = CSYNC_NOT_EXCLUDED;
+
+    /* split up the path */
+    bname = strrchr(path, '/');
+    if (bname) {
+        bname += 1; // don't include the /
+    } else {
+        bname = path;
+    }
+    blen = strlen(bname);
+
+    rc = csync_fnmatch("._sync_*.db*", bname, 0);
+    if (rc == 0) {
+        match = CSYNC_FILE_SILENTLY_EXCLUDED;
+        goto out;
+    }
+    rc = csync_fnmatch(".sync_*.db*", bname, 0);
+    if (rc == 0) {
+        match = CSYNC_FILE_SILENTLY_EXCLUDED;
+        goto out;
+    }
+    rc = csync_fnmatch(".csync_journal.db*", bname, 0);
+    if (rc == 0) {
+        match = CSYNC_FILE_SILENTLY_EXCLUDED;
+        goto out;
+    }
+
+    // check the strlen and ignore the file if its name is longer than 254 chars.
+    // whenever changing this also check createDownloadTmpFileName
+    if (blen > 254) {
+        match = CSYNC_FILE_EXCLUDE_LONG_FILENAME;
+        goto out;
+    }
+
+#ifdef _WIN32
+    // Windows cannot sync files ending in spaces (#2176). It also cannot
+    // distinguish files ending in '.' from files without an ending,
+    // as '.' is a separator that is not stored internally, so let's
+    // not allow to sync those to avoid file loss/ambiguities (#416)
+    if (blen > 1) {
+        if (bname[blen-1]== ' ') {
+            match = CSYNC_FILE_EXCLUDE_TRAILING_SPACE;
+            goto out;
+        } else if (bname[blen-1]== '.' ) {
+            match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
+            goto out;
+        }
+    }
+
+    if (csync_is_windows_reserved_word(bname)) {
+      match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
+      goto out;
+    }
+
+    // Filter out characters not allowed in a filename on windows
+    const char *p = NULL;
+    for (p = path; *p; p++) {
+        switch (*p) {
+        case '\\':
+        case ':':
+        case '?':
+        case '*':
+        case '"':
+        case '>':
+        case '<':
+        case '|':
+            match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
+            goto out;
+        default:
+            break;
+        }
+    }
+#endif
+
+    /* We create a desktop.ini on Windows for the sidebar icon, make sure we don't sync them. */
+    rc = csync_fnmatch("Desktop.ini", bname, 0);
+    if (rc == 0) {
+        match = CSYNC_FILE_SILENTLY_EXCLUDED;
+        goto out;
+    }
+
+    rc = csync_fnmatch(".owncloudsync.log*", bname, 0);
+    if (rc == 0) {
+        match = CSYNC_FILE_SILENTLY_EXCLUDED;
+        goto out;
+    }
+
+    /* Always ignore conflict files, not only via the exclude list */
+    rc = csync_fnmatch("*_conflict-*", bname, 0);
+    if (rc == 0) {
+        match = CSYNC_FILE_EXCLUDE_CONFLICT;
+        goto out;
+    }
+
+    if (getenv("CSYNC_CONFLICT_FILE_USERNAME")) {
+        rc = asprintf(&conflict, "*_conflict_%s-*", getenv("CSYNC_CONFLICT_FILE_USERNAME"));
+        if (rc < 0) {
+            goto out;
+        }
+        rc = csync_fnmatch(conflict, path, 0);
+        if (rc == 0) {
+            match = CSYNC_FILE_EXCLUDE_CONFLICT;
+            SAFE_FREE(conflict);
+            goto out;
+        }
+        SAFE_FREE(conflict);
+    }
+
+    if( ! excludes ) {
+        goto out;
+    }
+
+    c_strlist_t *path_components = NULL;
+    if (check_leading_dirs) {
+        /* Build a list of path components to check. */
+        path_components = c_strlist_new(32);
+        char *path_split = strdup(path);
+        size_t len = strlen(path_split);
+        for (i = len; ; --i) {
+            // read backwards until a path separator is found
+            if (i != 0 && path_split[i-1] != '/') {
+                continue;
+            }
+
+            // check 'basename', i.e. for "/foo/bar/fi" we'd check 'fi', 'bar', 'foo'
+            if (path_split[i] != 0) {
+                c_strlist_add_grow(&path_components, path_split + i);
+            }
+
+            if (i == 0) {
+                break;
+            }
+
+            // check 'dirname', i.e. for "/foo/bar/fi" we'd check '/foo/bar', '/foo'
+            path_split[i-1] = '\0';
+            c_strlist_add_grow(&path_components, path_split);
+        }
+        SAFE_FREE(path_split);
+    }
+
+    /* Loop over all exclude patterns and evaluate the given path */
+    for (i = 0; match == CSYNC_NOT_EXCLUDED && i < excludes->count; i++) {
+        bool match_dirs_only = false;
+        char *pattern = excludes->vector[i];
+
+        type = CSYNC_FILE_EXCLUDE_LIST;
+        if (!pattern[0]) { /* empty pattern */
+            continue;
+        }
+        /* Excludes starting with ']' means it can be cleanup */
+        if (pattern[0] == ']') {
+            ++pattern;
+            if (filetype == CSYNC_FTW_TYPE_FILE) {
+                type = CSYNC_FILE_EXCLUDE_AND_REMOVE;
+            }
+        }
+        /* Check if the pattern applies to pathes only. */
+        if (pattern[strlen(pattern)-1] == '/') {
+            if (!check_leading_dirs && filetype == CSYNC_FTW_TYPE_FILE) {
+                continue;
+            }
+            match_dirs_only = true;
+            pattern[strlen(pattern)-1] = '\0'; /* Cut off the slash */
+        }
+
+        /* check if the pattern contains a / and if, compare to the whole path */
+        if (strchr(pattern, '/')) {
+            rc = csync_fnmatch(pattern, path, FNM_PATHNAME);
+            if( rc == 0 ) {
+                match = type;
+            }
+            /* if the pattern requires a dir, but path is not, its still not excluded. */
+            if (match_dirs_only && filetype != CSYNC_FTW_TYPE_DIR) {
+                match = CSYNC_NOT_EXCLUDED;
+            }
+        }
+
+        /* if still not excluded, check each component and leading directory of the path */
+        if (match == CSYNC_NOT_EXCLUDED && check_leading_dirs) {
+            size_t j = 0;
+            if (match_dirs_only && filetype == CSYNC_FTW_TYPE_FILE) {
+                j = 1; // skip the first entry, which is bname
+            }
+            for (; j < path_components->count; ++j) {
+                rc = csync_fnmatch(pattern, path_components->vector[j], 0);
+                if (rc == 0) {
+                    match = type;
+                    break;
+                }
+            }
+        } else if (match == CSYNC_NOT_EXCLUDED && !check_leading_dirs) {
+            rc = csync_fnmatch(pattern, bname, 0);
+            if (rc == 0) {
+                match = type;
+            }
+        }
+        if (match_dirs_only) {
+            /* restore the '/' */
+            pattern[strlen(pattern)] = '/';
+        }
+    }
+    c_strlist_destroy(path_components);
+
+  out:
+
+    return match;
+}
+
+CSYNC_EXCLUDE_TYPE csync_excluded_traversal(c_strlist_t *excludes, const char *path, int filetype) {
+  return _csync_excluded_common(excludes, path, filetype, false);
+}
+
+CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype) {
+  return _csync_excluded_common(excludes, path, filetype, true);
+}
+
diff --git a/src/csync/csync_exclude.h b/src/csync/csync_exclude.h
new file mode 100644 (file)
index 0000000..722d27c
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CSYNC_EXCLUDE_H
+#define _CSYNC_EXCLUDE_H
+
+#include "ocsynclib.h"
+
+enum csync_exclude_type_e {
+  CSYNC_NOT_EXCLUDED   = 0,
+  CSYNC_FILE_SILENTLY_EXCLUDED,
+  CSYNC_FILE_EXCLUDE_AND_REMOVE,
+  CSYNC_FILE_EXCLUDE_LIST,
+  CSYNC_FILE_EXCLUDE_INVALID_CHAR,
+  CSYNC_FILE_EXCLUDE_TRAILING_SPACE,
+  CSYNC_FILE_EXCLUDE_LONG_FILENAME,
+  CSYNC_FILE_EXCLUDE_HIDDEN,
+  CSYNC_FILE_EXCLUDE_STAT_FAILED,
+  CSYNC_FILE_EXCLUDE_CONFLICT
+};
+typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
+
+#ifdef WITH_TESTING
+int OCSYNC_EXPORT _csync_exclude_add(c_strlist_t **inList, const char *string);
+#endif
+
+/**
+ * @brief Load exclude list
+ *
+ * @param ctx    The context of the synchronizer.
+ * @param fname  The filename to load.
+ *
+ * @return  0 on success, -1 if an error occurred with errno set.
+ */
+int OCSYNC_EXPORT csync_exclude_load(const char *fname, c_strlist_t **list);
+
+/**
+ * @brief Check if the given path should be excluded in a traversal situation.
+ *
+ * It does only part of the work that csync_excluded does because it's assumed
+ * that all leading directories have been run through csync_excluded_traversal()
+ * before. This can be significantly faster.
+ *
+ * That means for '/foo/bar/file' only ('/foo/bar/file', 'file') is checked
+ * against the exclude patterns.
+ *
+ * @param ctx   The synchronizer context.
+ * @param path  The patch to check.
+ *
+ * @return  2 if excluded and needs cleanup, 1 if excluded, 0 if not.
+ */
+CSYNC_EXCLUDE_TYPE csync_excluded_traversal(c_strlist_t *excludes, const char *path, int filetype);
+
+/**
+ * @brief csync_excluded_no_ctx
+ * @param excludes
+ * @param path
+ * @param filetype
+ * @return
+ */
+CSYNC_EXCLUDE_TYPE OCSYNC_EXPORT csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
+#endif /* _CSYNC_EXCLUDE_H */
+
+/**
+ * @brief Checks if filename is considered reserved by Windows
+ * @param file_name filename
+ * @return true if file is reserved, false otherwise
+ */
+bool csync_is_windows_reserved_word(const char *file_name);
+
+
+/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/src/csync/csync_log.c b/src/csync/csync_log.c
new file mode 100644 (file)
index 0000000..4a2e24a
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "csync_private.h"
+#include "csync_log.h"
+
+CSYNC_THREAD int csync_log_level;
+CSYNC_THREAD csync_log_callback csync_log_cb;
+
+void csync_log(int verbosity,
+               const char *function,
+               const char *format, ...)
+{
+    csync_log_callback log_fn = csync_get_log_callback();
+    if (log_fn && verbosity <= csync_get_log_level()) {
+        char buffer[1024];
+        va_list va;
+        va_start(va, format);
+        vsnprintf(buffer, sizeof(buffer), format, va);
+        va_end(va);
+
+        log_fn(verbosity, function, buffer);
+        return;
+    }
+}
+
+int csync_set_log_level(int level) {
+  if (level < 0) {
+    return -1;
+  }
+
+  csync_log_level = level;
+
+  return 0;
+}
+
+int csync_get_log_level(void) {
+  return csync_log_level;
+}
+
+int csync_set_log_callback(csync_log_callback cb) {
+  if (cb == NULL) {
+    return -1;
+  }
+
+  csync_log_cb = cb;
+
+  return 0;
+}
+
+csync_log_callback csync_get_log_callback(void) {
+  return csync_log_cb;
+}
diff --git a/src/csync/csync_log.h b/src/csync/csync_log.h
new file mode 100644 (file)
index 0000000..0cd0d01
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file csync_log.h
+ *
+ * @brief Logging interface of csync
+ *
+ * @defgroup csyncLogInternals csync logging internals
+ * @ingroup csyncInternalAPI
+ *
+ * @{
+ */
+
+#ifndef _CSYNC_LOG_H
+#define _CSYNC_LOG_H
+
+/* GCC have printf type attribute check.  */
+#ifndef PRINTF_ATTRIBUTE
+#ifdef __GNUC__
+#ifdef _WIN32
+#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__gnu_printf__, a, b)))
+#else
+#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
+#endif
+#else
+#define PRINTF_ATTRIBUTE(a,b)
+#endif /* __GNUC__ */
+#endif /* ndef PRINTF_ATTRIBUTE */
+
+enum csync_log_priority_e {
+    CSYNC_LOG_PRIORITY_NOLOG = 0,
+    CSYNC_LOG_PRIORITY_FATAL,
+    CSYNC_LOG_PRIORITY_ALERT,
+    CSYNC_LOG_PRIORITY_CRIT,
+    CSYNC_LOG_PRIORITY_ERROR,
+    CSYNC_LOG_PRIORITY_WARN,
+    CSYNC_LOG_PRIORITY_NOTICE,
+    CSYNC_LOG_PRIORITY_INFO,
+    CSYNC_LOG_PRIORITY_DEBUG,
+    CSYNC_LOG_PRIORITY_TRACE,
+    CSYNC_LOG_PRIORITY_NOTSET,
+    CSYNC_LOG_PRIORITY_UNKNOWN,
+};
+
+#define CSYNC_LOG(priority, ...) \
+  csync_log(priority, __func__, __VA_ARGS__)
+
+void csync_log(int verbosity,
+               const char *function,
+               const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
+
+/**
+ * }@
+ */
+#endif /* _CSYNC_LOG_H */
+
+/* vim: set ft=c.doxygen ts=4 sw=4 et cindent: */
diff --git a/src/csync/csync_macros.h b/src/csync/csync_macros.h
new file mode 100644 (file)
index 0000000..f128b43
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CSYNC_MACROS_H
+#define _CSYNC_MACROS_H
+
+#include <stdlib.h>
+#include <string.h>
+
+/* How many elements there are in a static array */
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+/* Some special custom errno values to report bugs properly. The BASE value
+ * should always be larger than the highest system errno. */
+#define CSYNC_CUSTOM_ERRNO_BASE 10000
+
+#define ERRNO_GENERAL_ERROR          CSYNC_CUSTOM_ERRNO_BASE+2
+#define ERRNO_LOOKUP_ERROR           CSYNC_CUSTOM_ERRNO_BASE+3
+#define ERRNO_USER_UNKNOWN_ON_SERVER CSYNC_CUSTOM_ERRNO_BASE+4
+#define ERRNO_PROXY_AUTH             CSYNC_CUSTOM_ERRNO_BASE+5
+#define ERRNO_CONNECT                CSYNC_CUSTOM_ERRNO_BASE+6
+#define ERRNO_TIMEOUT                CSYNC_CUSTOM_ERRNO_BASE+7
+#define ERRNO_PRECONDITION           CSYNC_CUSTOM_ERRNO_BASE+8
+#define ERRNO_RETRY                  CSYNC_CUSTOM_ERRNO_BASE+9
+#define ERRNO_REDIRECT               CSYNC_CUSTOM_ERRNO_BASE+10
+#define ERRNO_WRONG_CONTENT          CSYNC_CUSTOM_ERRNO_BASE+11
+#define ERRNO_ERROR_STRING           CSYNC_CUSTOM_ERRNO_BASE+13
+#define ERRNO_SERVICE_UNAVAILABLE    CSYNC_CUSTOM_ERRNO_BASE+14
+#define ERRNO_USER_ABORT             CSYNC_CUSTOM_ERRNO_BASE+16
+#define ERRNO_STORAGE_UNAVAILABLE    CSYNC_CUSTOM_ERRNO_BASE+17
+#define ERRNO_FORBIDDEN              CSYNC_CUSTOM_ERRNO_BASE+18
+
+#endif /* _CSYNC_MACROS_H */
+/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/src/csync/csync_misc.c b/src/csync/csync_misc.c
new file mode 100644 (file)
index 0000000..d232361
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#if _WIN32
+# ifndef _WIN32_IE
+#  define _WIN32_IE 0x0501 // SHGetSpecialFolderPath
+# endif
+# include <shlobj.h>
+#else /* _WIN32 */
+# include <pwd.h>
+#endif /* _WIN32 */
+
+#include "c_lib.h"
+#include "csync_misc.h"
+#include "csync_macros.h"
+#include "csync_log.h"
+
+#ifdef HAVE_FNMATCH
+#include <fnmatch.h>
+
+int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags) {
+    return fnmatch(__pattern, __name, __flags);
+}
+
+#else /* HAVE_FNMATCH */
+
+#include <shlwapi.h>
+int csync_fnmatch(const char *pattern, const char *name, int flags) {
+    BOOL match;
+
+    (void) flags;
+
+    match = PathMatchSpecA(name, pattern);
+
+    if(match)
+        return 0;
+    else
+        return 1;
+}
+#endif /* HAVE_FNMATCH */
+
+CSYNC_STATUS csync_errno_to_status(int error, CSYNC_STATUS default_status)
+{
+  CSYNC_STATUS status = CSYNC_STATUS_OK;
+
+  switch (error) {
+  case 0:
+    status = CSYNC_STATUS_OK;
+    break;
+    /* The custom errnos first. */
+  case ERRNO_GENERAL_ERROR:
+    status = CSYNC_STATUS_UNSUCCESSFUL;
+    break;
+  case ERRNO_LOOKUP_ERROR: /* In Neon: Server or proxy hostname lookup failed */
+    status = CSYNC_STATUS_LOOKUP_ERROR;
+    break;
+  case ERRNO_USER_UNKNOWN_ON_SERVER: /* Neon: User authentication on server failed. */
+    status = CSYNC_STATUS_SERVER_AUTH_ERROR;
+    break;
+  case ERRNO_PROXY_AUTH:
+    status = CSYNC_STATUS_PROXY_AUTH_ERROR; /* Neon: User authentication on proxy failed */
+    break;
+  case ERRNO_CONNECT:
+    status = CSYNC_STATUS_CONNECT_ERROR; /* Network: Connection error */
+    break;
+  case ERRNO_TIMEOUT:
+    status = CSYNC_STATUS_TIMEOUT; /* Network: Timeout error */
+    break;
+  case ERRNO_SERVICE_UNAVAILABLE:
+    status = CSYNC_STATUS_SERVICE_UNAVAILABLE;  /* Service temporarily down */
+    break;
+  case ERRNO_STORAGE_UNAVAILABLE:
+    status = CSYNC_STATUS_STORAGE_UNAVAILABLE;  /* Storage temporarily unavailable */
+    break;
+  case EFBIG:
+    status = CSYNC_STATUS_FILE_SIZE_ERROR;          /* File larger than 2MB */
+    break;
+  case ERRNO_PRECONDITION:
+  case ERRNO_RETRY:
+  case ERRNO_REDIRECT:
+  case ERRNO_WRONG_CONTENT:
+    status = CSYNC_STATUS_HTTP_ERROR;
+    break;
+
+  case EPERM:                  /* Operation not permitted */
+  case EACCES:                /* Permission denied */
+    status = CSYNC_STATUS_PERMISSION_DENIED;
+    break;
+  case ENOENT:                 /* No such file or directory */
+    status = CSYNC_STATUS_NOT_FOUND;
+    break;
+  case EAGAIN:                /* Try again */
+    status = CSYNC_STATUS_TIMEOUT;
+    break;
+  case EEXIST:                /* File exists */
+    status = CSYNC_STATUS_FILE_EXISTS;
+    break;
+  case EINVAL:
+    status = CSYNC_STATUS_PARAM_ERROR;
+    break;
+  case ENOSPC:
+    status = CSYNC_STATUS_OUT_OF_SPACE;
+    break;
+
+    /* All the remaining basic errnos: */
+  case EIO:                    /* I/O error */
+  case ESRCH:                  /* No such process */
+  case EINTR:                  /* Interrupted system call */
+  case ENXIO:                  /* No such device or address */
+  case E2BIG:                  /* Argument list too long */
+  case ENOEXEC:                /* Exec format error */
+  case EBADF:                  /* Bad file number */
+  case ECHILD:                /* No child processes */
+  case ENOMEM:                /* Out of memory */
+  case EFAULT:                /* Bad address */
+#ifndef _WIN32
+  case ENOTBLK:               /* Block device required */
+#endif
+  case EBUSY:                 /* Device or resource busy */
+  case EXDEV:                 /* Cross-device link */
+  case ENODEV:                /* No such device */
+  case ENOTDIR:               /* Not a directory */
+  case EISDIR:                /* Is a directory */
+  case ENFILE:                /* File table overflow */
+  case EMFILE:                /* Too many open files */
+  case ENOTTY:                /* Not a typewriter */
+#ifndef _WIN32
+  case ETXTBSY:               /* Text file busy */
+#endif
+  case ESPIPE:                /* Illegal seek */
+  case EROFS:                 /* Read-only file system */
+  case EMLINK:                /* Too many links */
+  case EPIPE:                 /* Broken pipe */
+
+  case ERRNO_ERROR_STRING:
+  default:
+    status = default_status;
+  }
+
+  return status;
+}
+
+/* Remove possible quotes, and also the -gzip at the end
+ * Remove "-gzip" at the end (cf. https://github.comowncloud/client/issues/1195)
+ * The caller must take ownership of the resulting string.
+ */
+char *csync_normalize_etag(const char *etag)
+{
+    int len = 0;
+    char *buf = NULL;
+    if (!etag)
+        return NULL;
+
+    len = strlen(etag);
+    /* strip "XXXX-gzip" */
+    if(len >= 7 && etag[0] == '"' && c_streq(etag + len - 6, "-gzip\"")) {
+        etag++;
+        len -= 7;
+    }
+    /* strip leading -gzip */
+    if(len >= 5 && c_streq(etag + len - 5, "-gzip")) {
+        len -= 5;
+    }
+    /* strip normal quotes */
+    if (etag[0] == '"' && etag[len-1] == '"') {
+        etag++;
+        len -= 2;
+    }
+
+    buf = c_malloc( len+1 );
+    strncpy( buf, etag, len );
+    buf[len] = '\0';
+    return buf;
+}
+
diff --git a/src/csync/csync_misc.h b/src/csync/csync_misc.h
new file mode 100644 (file)
index 0000000..6b9f984
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CSYNC_MISC_H
+#define _CSYNC_MISC_H
+
+#include <config_csync.h>
+#include <csync.h>
+
+#ifdef HAVE_FNMATCH
+#include <fnmatch.h>
+#else
+/* Steal this define to make csync_exclude compile. Note that if fnmatch
+ * is not defined it's probably Win32 which uses a different implementation
+ * than fmmatch anyway, which does not care for flags.
+ **/
+#define FNM_PATHNAME    (1 << 0) /* No wildcard can ever match `/'.  */
+#define FNM_CASEFOLD    (1 << 4) /* Compare without regard to case.  */
+#endif
+
+int csync_fnmatch(const char *pattern, const char *name, int flags);
+
+/**
+ * @brief csync_errno_to_status - errno to csync status code
+ *
+ * This function tries to convert the value of the current set errno
+ * to a csync status code.
+ *
+ * @return the corresponding csync error code.
+ */
+CSYNC_STATUS csync_errno_to_status(int error, CSYNC_STATUS default_status);
+
+#endif /* _CSYNC_MISC_H */
diff --git a/src/csync/csync_private.h b/src/csync/csync_private.h
new file mode 100644 (file)
index 0000000..2edc260
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file csync_private.h
+ *
+ * @brief Private interface of csync
+ *
+ * @defgroup csyncInternalAPI csync internal API
+ *
+ * @{
+ */
+
+#ifndef _CSYNC_PRIVATE_H
+#define _CSYNC_PRIVATE_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sqlite3.h>
+
+#include "config_csync.h"
+#include "std/c_lib.h"
+#include "std/c_private.h"
+#include "csync.h"
+#include "csync_misc.h"
+
+#include "csync_macros.h"
+
+/**
+ * How deep to scan directories.
+ */
+#define MAX_DEPTH 100
+
+#define CSYNC_STATUS_INIT 1 << 0
+#define CSYNC_STATUS_UPDATE 1 << 1
+#define CSYNC_STATUS_RECONCILE 1 << 2
+#define CSYNC_STATUS_PROPAGATE 1 << 3
+
+#define CSYNC_STATUS_DONE (CSYNC_STATUS_INIT | \
+                           CSYNC_STATUS_UPDATE | \
+                           CSYNC_STATUS_RECONCILE | \
+                           CSYNC_STATUS_PROPAGATE)
+
+enum csync_replica_e {
+  LOCAL_REPLICA,
+  REMOTE_REPLICA
+};
+
+typedef struct csync_file_stat_s csync_file_stat_t;
+
+/**
+ * @brief csync public structure
+ */
+struct csync_s {
+  struct {
+      csync_auth_callback auth_function;
+      void *userdata;
+      csync_update_callback update_callback;
+      void *update_callback_userdata;
+
+      /* hooks for checking the white list (uses the update_callback_userdata) */
+      int (*checkSelectiveSyncBlackListHook)(void*, const char*);
+      int (*checkSelectiveSyncNewFolderHook)(void*, const char* /* path */, const char* /* remotePerm */);
+
+
+      csync_vio_opendir_hook remote_opendir_hook;
+      csync_vio_readdir_hook remote_readdir_hook;
+      csync_vio_closedir_hook remote_closedir_hook;
+      void *vio_userdata;
+
+      /* hook for comparing checksums of files during discovery */
+      csync_checksum_hook checksum_hook;
+      void *checksum_userdata;
+
+  } callbacks;
+  c_strlist_t *excludes;
+  
+  struct {
+    char *file;
+    sqlite3 *db;
+    int exists;
+
+    sqlite3_stmt* by_hash_stmt;
+    sqlite3_stmt* by_fileid_stmt;
+    sqlite3_stmt* by_inode_stmt;
+
+    int lastReturnValue;
+  } statedb;
+
+  struct {
+    char *uri;
+    c_rbtree_t *tree;
+    enum csync_replica_e type;
+  } local;
+
+  struct {
+    c_rbtree_t *tree;
+    enum csync_replica_e type;
+    int  read_from_db;
+    const char *root_perms; /* Permission of the root folder. (Since the root folder is not in the db tree, we need to keep a separate entry.) */
+  } remote;
+
+
+  /* replica we are currently walking */
+  enum csync_replica_e current;
+
+  /* replica we want to work on */
+  enum csync_replica_e replica;
+
+  /* Used in the update phase so changes in the sub directories can be notified to
+     parent directories */
+  csync_file_stat_t *current_fs;
+
+  /* csync error code */
+  enum csync_status_codes_e status_code;
+
+  char *error_string;
+
+  int status;
+  volatile int abort;
+  void *rename_info;
+
+  /**
+   * Specify if it is allowed to read the remote tree from the DB (default to enabled)
+   */
+  bool read_remote_from_db;
+
+  /**
+   * If true, the DB is considered empty and all reads are skipped. (default is false)
+   * This is useful during the initial local discovery as it speeds it up significantly.
+   */
+  bool db_is_empty;
+
+  bool ignore_hidden_files;
+};
+
+
+#ifdef _MSC_VER
+#pragma pack(1)
+#endif
+struct csync_file_stat_s {
+  uint64_t phash;   /* u64 */
+  time_t modtime;   /* u64 */
+  int64_t size;       /* u64 */
+  size_t pathlen;   /* u64 */
+  uint64_t inode;   /* u64 */
+  mode_t mode;      /* u32 */
+  unsigned int type                   : 4;
+  unsigned int child_modified         : 1;
+  unsigned int has_ignored_files      : 1; /* specify that a directory, or child directory contains ignored files */
+
+  char *destpath;   /* for renames */
+  const char *etag;
+  char file_id[FILE_ID_BUF_SIZE+1];  /* the ownCloud file id is fixed width in ownCloud. */
+  char *directDownloadUrl;
+  char *directDownloadCookies;
+  char remotePerm[REMOTE_PERM_BUF_SIZE+1];
+
+  // In the local tree, this can hold a checksum and its type if it is
+  //   computed during discovery for some reason.
+  // In the remote tree, this will have the server checksum, if available.
+  // In both cases, the format is "SHA1:baff".
+  const char *checksumHeader;
+
+  CSYNC_STATUS error_status;
+
+  enum csync_instructions_e instruction; /* u32 */
+  char path[1]; /* u8 */
+}
+#if !defined(__SUNPRO_C) && !defined(_MSC_VER)
+__attribute__ ((packed))
+#endif
+#ifdef _MSC_VER
+#pragma pack()
+#endif
+;
+
+OCSYNC_EXPORT void csync_file_stat_free(csync_file_stat_t *st);
+
+/*
+ * context for the treewalk function
+ */
+struct _csync_treewalk_context_s
+{
+    csync_treewalk_visit_func *user_visitor;
+    int instruction_filter;
+    void *userdata;
+};
+typedef struct _csync_treewalk_context_s _csync_treewalk_context;
+
+void set_errno_from_http_errcode( int err );
+
+/**
+ * }@
+ */
+#endif /* _CSYNC_PRIVATE_H */
+/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/src/csync/csync_reconcile.c b/src/csync/csync_reconcile.c
new file mode 100644 (file)
index 0000000..59156e8
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#include <assert.h>
+#include "csync_private.h"
+#include "csync_reconcile.h"
+#include "csync_util.h"
+#include "csync_statedb.h"
+#include "csync_rename.h"
+#include "c_jhash.h"
+
+#define CSYNC_LOG_CATEGORY_NAME "csync.reconciler"
+#include "csync_log.h"
+
+#include "inttypes.h"
+
+/* Check if a file is ignored because one parent is ignored.
+ * return the node of the ignored directoy if it's the case, or NULL if it is not ignored */
+static c_rbnode_t *_csync_check_ignored(c_rbtree_t *tree, const char *path, int pathlen) {
+    uint64_t h = 0;
+    c_rbnode_t *node = NULL;
+
+    /* compute the size of the parent directory */
+    int parentlen = pathlen - 1;
+    while (parentlen > 0 && path[parentlen] != '/') {
+        parentlen--;
+    }
+    if (parentlen <= 0) {
+        return NULL;
+    }
+
+    h = c_jhash64((uint8_t *) path, parentlen, 0);
+    node = c_rbtree_find(tree, &h);
+    if (node) {
+        csync_file_stat_t *n = (csync_file_stat_t*)node->data;
+        if (n->instruction == CSYNC_INSTRUCTION_IGNORE) {
+            /* Yes, we are ignored */
+            return node;
+        } else {
+            /* Not ignored */
+            return NULL;
+        }
+    } else {
+        /* Try if the parent itself is ignored */
+        return _csync_check_ignored(tree, path, parentlen);
+    }
+}
+
+/* Returns true if we're reasonably certain that hash equality
+ * for the header means content equality.
+ *
+ * Cryptographic safety is not required - this is mainly
+ * intended to rule out checksums like Adler32 that are not intended for
+ * hashing and have high likelihood of collision with particular inputs.
+ */
+static bool _csync_is_collision_safe_hash(const char *checksum_header)
+{
+    return strncmp(checksum_header, "SHA1:", 5) == 0
+        || strncmp(checksum_header, "MD5:", 4) == 0;
+}
+
+/**
+ * The main function in the reconcile pass.
+ *
+ * It's called for each entry in the local and remote rbtrees by
+ * csync_reconcile()
+ *
+ * Before the reconcile phase the trees already know about changes
+ * relative to the sync journal. This function's job is to spot conflicts
+ * between local and remote changes and adjust the nodes accordingly.
+ *
+ * See doc/dev/sync-algorithm.md for an overview.
+ *
+ *
+ * Older detail comment:
+ *
+ * We merge replicas at the file level. The merged replica contains the
+ * superset of files that are on the local machine and server copies of
+ * the replica. In the case where the same file is in both the local
+ * and server copy, the file that was modified most recently is used.
+ * This means that new files are not deleted, and updated versions of
+ * existing files are not overwritten.
+ *
+ * When a file is updated, the merge algorithm compares the destination
+ * file with the the source file. If the destination file is newer
+ * (timestamp is newer), it is not overwritten. If both files, on the
+ * source and the destination, have been changed, the newer file wins.
+ */
+static int _csync_merge_algorithm_visitor(void *obj, void *data) {
+    csync_file_stat_t *cur = NULL;
+    csync_file_stat_t *other = NULL;
+    csync_file_stat_t *tmp = NULL;
+    uint64_t h = 0;
+    int len = 0;
+
+    CSYNC *ctx = NULL;
+    c_rbtree_t *tree = NULL;
+    c_rbnode_t *node = NULL;
+
+    cur = (csync_file_stat_t *) obj;
+    ctx = (CSYNC *) data;
+
+    /* we need the opposite tree! */
+    switch (ctx->current) {
+    case LOCAL_REPLICA:
+        tree = ctx->remote.tree;
+        break;
+    case REMOTE_REPLICA:
+        tree = ctx->local.tree;
+        break;
+    default:
+        break;
+    }
+
+    node = c_rbtree_find(tree, &cur->phash);
+
+    if (!node) {
+        /* Check the renamed path as well. */
+        char *renamed_path = csync_rename_adjust_path(ctx, cur->path);
+        if (!c_streq(renamed_path, cur->path)) {
+            len = strlen( renamed_path );
+            h = c_jhash64((uint8_t *) renamed_path, len, 0);
+            node = c_rbtree_find(tree, &h);
+        }
+        SAFE_FREE(renamed_path);
+    }
+    if (!node) {
+        /* Check if it is ignored */
+        node = _csync_check_ignored(tree, cur->path, cur->pathlen);
+        /* If it is ignored, other->instruction will be  IGNORE so this one will also be ignored */
+    }
+
+    /* file only found on current replica */
+    if (node == NULL) {
+        switch(cur->instruction) {
+        /* file has been modified */
+        case CSYNC_INSTRUCTION_EVAL:
+            cur->instruction = CSYNC_INSTRUCTION_NEW;
+            break;
+            /* file has been removed on the opposite replica */
+        case CSYNC_INSTRUCTION_NONE:
+        case CSYNC_INSTRUCTION_UPDATE_METADATA:
+            if (cur->has_ignored_files) {
+                /* Do not remove a directory that has ignored files */
+                break;
+            }
+            if (cur->child_modified) {
+                /* re-create directory that has modified contents */
+                cur->instruction = CSYNC_INSTRUCTION_NEW;
+                break;
+            }
+            cur->instruction = CSYNC_INSTRUCTION_REMOVE;
+            break;
+        case CSYNC_INSTRUCTION_EVAL_RENAME:
+            if(ctx->current == LOCAL_REPLICA ) {
+                /* use the old name to find the "other" node */
+                tmp = csync_statedb_get_stat_by_inode(ctx, cur->inode);
+                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Finding opposite temp through inode %" PRIu64 ": %s",
+                          cur->inode, tmp ? "true":"false");
+            } else if( ctx->current == REMOTE_REPLICA ) {
+                tmp = csync_statedb_get_stat_by_file_id(ctx, cur->file_id);
+                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Finding opposite temp through file ID %s: %s",
+                          cur->file_id, tmp ? "true":"false");
+            } else {
+                CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Unknown replica...");
+            }
+
+            if( tmp ) {
+                len = strlen( tmp->path );
+                if( len > 0 ) {
+                    h = c_jhash64((uint8_t *) tmp->path, len, 0);
+                    /* First, check that the file is NOT in our tree (another file with the same name was added) */
+                    node = c_rbtree_find(ctx->current == REMOTE_REPLICA ? ctx->remote.tree : ctx->local.tree, &h);
+                    if (node) {
+                        CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Origin found in our tree : %s", tmp->path);
+                    } else {
+                        /* Find the temporar file in the other tree. */
+                        node = c_rbtree_find(tree, &h);
+                        CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "PHash of temporary opposite (%s): %" PRIu64 " %s",
+                                tmp->path , h, node ? "found": "not found" );
+                        if (node) {
+                            other = (csync_file_stat_t*)node->data;
+                        } else {
+                            /* the renamed file could not be found in the opposite tree. That is because it
+                            * is not longer existing there, maybe because it was renamed or deleted.
+                            * The journal is cleaned up later after propagation.
+                            */
+                        }
+                    }
+                }
+
+                if(!other) {
+                    cur->instruction = CSYNC_INSTRUCTION_NEW;
+                } else if (other->instruction == CSYNC_INSTRUCTION_NONE
+                           || other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
+                           || cur->type == CSYNC_FTW_TYPE_DIR) {
+                    other->instruction = CSYNC_INSTRUCTION_RENAME;
+                    other->destpath = c_strdup( cur->path );
+                    if( !c_streq(cur->file_id, "") ) {
+                        csync_vio_set_file_id( other->file_id, cur->file_id );
+                    }
+                    other->inode = cur->inode;
+                    cur->instruction = CSYNC_INSTRUCTION_NONE;
+                } else if (other->instruction == CSYNC_INSTRUCTION_REMOVE) {
+                    other->instruction = CSYNC_INSTRUCTION_RENAME;
+                    other->destpath = c_strdup( cur->path );
+
+                    if( !c_streq(cur->file_id, "") ) {
+                        csync_vio_set_file_id( other->file_id, cur->file_id );
+                    }
+                    other->inode = cur->inode;
+                    cur->instruction = CSYNC_INSTRUCTION_NONE;
+                } else if (other->instruction == CSYNC_INSTRUCTION_NEW) {
+                    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "OOOO=> NEW detected in other tree!");
+                    cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
+                } else {
+                    assert(other->type != CSYNC_FTW_TYPE_DIR);
+                    cur->instruction = CSYNC_INSTRUCTION_NONE;
+                    other->instruction = CSYNC_INSTRUCTION_SYNC;
+                }
+                csync_file_stat_free(tmp);
+           }
+
+            break;
+        default:
+            break;
+        }
+    } else {
+        bool is_conflict = true;
+        /*
+     * file found on the other replica
+     */
+        other = (csync_file_stat_t *) node->data;
+
+        switch (cur->instruction) {
+        case CSYNC_INSTRUCTION_UPDATE_METADATA:
+            if (other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA && ctx->current == LOCAL_REPLICA) {
+                // Remote wins, the SyncEngine will pick relevant local metadata since the remote tree is walked last.
+                cur->instruction = CSYNC_INSTRUCTION_NONE;
+            }
+            break;
+        case CSYNC_INSTRUCTION_EVAL_RENAME:
+            /* If the file already exist on the other side, we have a conflict.
+               Abort the rename and consider it is a new file. */
+            cur->instruction = CSYNC_INSTRUCTION_NEW;
+            /* fall trough */
+        /* file on current replica is changed or new */
+        case CSYNC_INSTRUCTION_EVAL:
+        case CSYNC_INSTRUCTION_NEW:
+            // This operation is usually a no-op and will by default return false
+            if (csync_file_locked_or_open(ctx->local.uri, cur->path)) {
+                CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "[Reconciler] IGNORING file %s/%s since it is locked / open", ctx->local.uri, cur->path);
+                cur->instruction = CSYNC_INSTRUCTION_ERROR;
+                if (cur->error_status == CSYNC_STATUS_OK) // don't overwrite error
+                    cur->error_status = CYSNC_STATUS_FILE_LOCKED_OR_OPEN;
+                break;
+            } else {
+                //CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "[Reconciler] not ignoring file %s/%s", ctx->local.uri, cur->path);
+            }
+            switch (other->instruction) {
+            /* file on other replica is changed or new */
+            case CSYNC_INSTRUCTION_NEW:
+            case CSYNC_INSTRUCTION_EVAL:
+                if (other->type == CSYNC_FTW_TYPE_DIR &&
+                        cur->type == CSYNC_FTW_TYPE_DIR) {
+                    // Folders of the same path are always considered equals
+                    is_conflict = false;
+                } else {
+                    // If the size or mtime is different, it's definitely a conflict.
+                    is_conflict = ((other->size != cur->size) || (other->modtime != cur->modtime));
+
+                    // It could be a conflict even if size and mtime match!
+                    //
+                    // In older client versions we always treated these cases as a
+                    // non-conflict. This behavior is preserved in case the server
+                    // doesn't provide a suitable content hash.
+                    //
+                    // When it does have one, however, we do create a job, but the job
+                    // will compare hashes and avoid the download if they are equal.
+                    const char *remoteChecksumHeader =
+                        (ctx->current == REMOTE_REPLICA ? cur->checksumHeader : other->checksumHeader);
+                    if (remoteChecksumHeader) {
+                        is_conflict |= _csync_is_collision_safe_hash(remoteChecksumHeader);
+                    }
+
+                    // SO: If there is no checksum, we can have !is_conflict here
+                    // even though the files have different content! This is an
+                    // intentional tradeoff. Downloading and comparing files would
+                    // be technically correct in this situation but leads to too
+                    // much waste.
+                    // In particular this kind of NEW/NEW situation with identical
+                    // sizes and mtimes pops up when the local database is lost for
+                    // whatever reason.
+                }
+                if (ctx->current == REMOTE_REPLICA) {
+                    // If the files are considered equal, only update the DB with the etag from remote
+                    cur->instruction = is_conflict ? CSYNC_INSTRUCTION_CONFLICT : CSYNC_INSTRUCTION_UPDATE_METADATA;
+                    other->instruction = CSYNC_INSTRUCTION_NONE;
+                } else {
+                    cur->instruction = CSYNC_INSTRUCTION_NONE;
+                    other->instruction = is_conflict ? CSYNC_INSTRUCTION_CONFLICT : CSYNC_INSTRUCTION_UPDATE_METADATA;
+                }
+
+                break;
+                /* file on the other replica has not been modified */
+            case CSYNC_INSTRUCTION_NONE:
+            case CSYNC_INSTRUCTION_UPDATE_METADATA:
+                if (cur->type != other->type) {
+                    // If the type of the entity changed, it's like NEW, but
+                    // needs to delete the other entity first.
+                    cur->instruction = CSYNC_INSTRUCTION_TYPE_CHANGE;
+                    other->instruction = CSYNC_INSTRUCTION_NONE;
+                } else if (cur->type == CSYNC_FTW_TYPE_DIR) {
+                    cur->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
+                    other->instruction = CSYNC_INSTRUCTION_NONE;
+                } else {
+                    cur->instruction = CSYNC_INSTRUCTION_SYNC;
+                    other->instruction = CSYNC_INSTRUCTION_NONE;
+                }
+                break;
+            case CSYNC_INSTRUCTION_IGNORE:
+                cur->instruction = CSYNC_INSTRUCTION_IGNORE;
+            break;
+            default:
+                break;
+            }
+        default:
+            break;
+        }
+    }
+
+    //hide instruction NONE messages when log level is set to debug,
+    //only show these messages on log level trace
+    const char *repo = ctx->current == REMOTE_REPLICA ? "server" : "client";
+    if(cur->instruction ==CSYNC_INSTRUCTION_NONE)
+    {
+        if(cur->type == CSYNC_FTW_TYPE_DIR)
+        {
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
+                      "%-30s %s dir:  %s",
+                      csync_instruction_str(cur->instruction),
+                      repo,
+                      cur->path);
+        }
+        else
+        {
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
+                      "%-30s %s file: %s",
+                      csync_instruction_str(cur->instruction),
+                      repo,
+                      cur->path);
+        }
+    }
+    else
+    {
+        if(cur->type == CSYNC_FTW_TYPE_DIR)
+        {
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO,
+                      "%-30s %s dir:  %s",
+                      csync_instruction_str(cur->instruction),
+                      repo,
+                      cur->path);
+        }
+        else
+        {
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO,
+                      "%-30s %s file: %s",
+                      csync_instruction_str(cur->instruction),
+                      repo,
+                      cur->path);
+        }
+    }
+
+    return 0;
+}
+
+int csync_reconcile_updates(CSYNC *ctx) {
+  int rc;
+  c_rbtree_t *tree = NULL;
+
+  switch (ctx->current) {
+    case LOCAL_REPLICA:
+      tree = ctx->local.tree;
+      break;
+    case REMOTE_REPLICA:
+      tree = ctx->remote.tree;
+      break;
+    default:
+      break;
+  }
+
+  rc = c_rbtree_walk(tree, (void *) ctx, _csync_merge_algorithm_visitor);
+  if( rc < 0 ) {
+    ctx->status_code = CSYNC_STATUS_RECONCILE_ERROR;
+  }
+  return rc;
+}
+
+/* vim: set ts=8 sw=2 et cindent: */
diff --git a/src/csync/csync_reconcile.h b/src/csync/csync_reconcile.h
new file mode 100644 (file)
index 0000000..f333adb
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CSYNC_RECONCILE_H
+#define _CSYNC_RECONCILE_H
+
+/**
+ * @file csync_reconcile.h
+ *
+ * @brief Reconciliation
+ *
+ * The most important component is the update detector, because the reconciler
+ * depends on it. The correctness of reconciler is mandatory because it can
+ * damage a filesystem. It decides which file:
+ *
+ *       - stays untouched
+ *       - has a conflict
+ *       - gets synchronized
+ *       - or is deleted.
+ *
+ * @defgroup csyncReconcilationInternals csync reconciliation internals
+ * @ingroup csyncInternalAPI
+ *
+ * @{
+ */
+
+/**
+ * @brief Reconcile the files.
+ *
+ * @param  ctx          The csync context to use.
+ *
+ * @return 0 on success, < 0 on error.
+ *
+ * @todo Add an argument to set the algorithm to use.
+ */
+int OCSYNC_EXPORT csync_reconcile_updates(CSYNC *ctx);
+
+/**
+ * }@
+ */
+#endif /* _CSYNC_RECONCILE_H */
+
+/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/src/csync/csync_rename.cc b/src/csync/csync_rename.cc
new file mode 100644 (file)
index 0000000..5cc43ce
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2012      by Olivier Goffart <ogoffart@woboq.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+extern "C" {
+#include "csync_private.h"
+#include "csync_rename.h"
+}
+
+#include <map>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+static std::string _parentDir(const std::string &path) {
+    int len = path.length();
+    while(len > 0 && path[len-1]!='/') len--;
+    while(len > 0 && path[len-1]=='/') len--;
+    return path.substr(0, len);
+}
+
+struct csync_rename_s {
+    static csync_rename_s *get(CSYNC *ctx) {
+        if (!ctx->rename_info) {
+            ctx->rename_info = new csync_rename_s;
+        }
+        return reinterpret_cast<csync_rename_s *>(ctx->rename_info);
+    }
+
+    std::map<std::string, std::string> folder_renamed_to; // map from->to
+    std::map<std::string, std::string> folder_renamed_from; // map to->from
+
+    struct renameop {
+        csync_file_stat_t *st;
+        bool operator<(const renameop &other) const {
+            return strlen(st->destpath) < strlen(other.st->destpath);
+        }
+    };
+    std::vector<renameop> todo;
+};
+
+extern "C" {
+void csync_rename_destroy(CSYNC* ctx)
+{
+    delete reinterpret_cast<csync_rename_s *>(ctx->rename_info);
+    ctx->rename_info = 0;
+}
+
+void csync_rename_record(CSYNC* ctx, const char* from, const char* to)
+{
+    csync_rename_s::get(ctx)->folder_renamed_to[from] = to;
+    csync_rename_s::get(ctx)->folder_renamed_from[to] = from;
+}
+
+char* csync_rename_adjust_path(CSYNC* ctx, const char* path)
+{
+    csync_rename_s* d = csync_rename_s::get(ctx);
+    for (std::string p = _parentDir(path); !p.empty(); p = _parentDir(p)) {
+        std::map< std::string, std::string >::iterator it = d->folder_renamed_to.find(p);
+        if (it != d->folder_renamed_to.end()) {
+            std::string rep = it->second + (path + p.length());
+            return c_strdup(rep.c_str());
+        }
+    }
+    return c_strdup(path);
+}
+
+char* csync_rename_adjust_path_source(CSYNC* ctx, const char* path)
+{
+    csync_rename_s* d = csync_rename_s::get(ctx);
+    for (std::string p = _parentDir(path); !p.empty(); p = _parentDir(p)) {
+        std::map< std::string, std::string >::iterator it = d->folder_renamed_from.find(p);
+        if (it != d->folder_renamed_from.end()) {
+            std::string rep = it->second + (path + p.length());
+            return c_strdup(rep.c_str());
+        }
+    }
+    return c_strdup(path);
+}
+
+bool csync_rename_count(CSYNC *ctx) {
+    csync_rename_s* d = csync_rename_s::get(ctx);
+    return d->folder_renamed_from.size();
+}
+
+}
diff --git a/src/csync/csync_rename.h b/src/csync/csync_rename.h
new file mode 100644 (file)
index 0000000..5396832
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2012      by Olivier Goffart <ogoffart@woboq.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+#include "csync.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Return the final destination path of a given patch in case of renames */
+char OCSYNC_EXPORT *csync_rename_adjust_path(CSYNC *ctx, const char *path);
+/* Return the source of a given path in case of renames */
+char OCSYNC_EXPORT *csync_rename_adjust_path_source(CSYNC *ctx, const char *path);
+void OCSYNC_EXPORT csync_rename_destroy(CSYNC *ctx);
+void OCSYNC_EXPORT csync_rename_record(CSYNC *ctx, const char *from, const char *to);
+/*  Return the amount of renamed item recorded */
+bool OCSYNC_EXPORT csync_rename_count(CSYNC *ctx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/csync/csync_statedb.c b/src/csync/csync_statedb.c
new file mode 100644 (file)
index 0000000..056ca48
--- /dev/null
@@ -0,0 +1,656 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <sqlite3.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include "c_lib.h"
+#include "csync_private.h"
+#include "csync_statedb.h"
+#include "csync_util.h"
+#include "csync_misc.h"
+#include "csync_exclude.h"
+
+#include "c_string.h"
+#include "c_jhash.h"
+#include "csync_time.h"
+
+#define CSYNC_LOG_CATEGORY_NAME "csync.statedb"
+#include "csync_log.h"
+#include "csync_rename.h"
+
+#define BUF_SIZE 16
+
+#define sqlite_open(A, B) sqlite3_open_v2(A,B, SQLITE_OPEN_READONLY+SQLITE_OPEN_NOMUTEX, NULL)
+
+#define SQLTM_TIME 150
+#define SQLTM_COUNT 10
+
+#define SQLITE_BUSY_HANDLED(F) if(1) { \
+    int n = 0; \
+    do { rc = F ; \
+      if( (rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED) ) { \
+         n++; \
+         csync_sleep(SQLTM_TIME); \
+      } \
+    }while( (n < SQLTM_COUNT) && ((rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED))); \
+  }
+
+
+void csync_set_statedb_exists(CSYNC *ctx, int val) {
+  ctx->statedb.exists = val;
+}
+
+int csync_get_statedb_exists(CSYNC *ctx) {
+  return ctx->statedb.exists;
+}
+
+static int _csync_check_db_integrity(sqlite3 *db) {
+    c_strlist_t *result = NULL;
+    int rc = -1;
+
+    result = csync_statedb_query(db, "PRAGMA quick_check;");
+    if (result != NULL) {
+        /* There is  a result */
+        if (result->count > 0) {
+            if (c_streq(result->vector[0], "ok")) {
+                rc = 0;
+            }
+        }
+        c_strlist_destroy(result);
+    }
+
+    if( sqlite3_threadsafe() == 0 ) {
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "* WARNING: SQLite module is not threadsafe!");
+        rc = -1;
+    }
+
+    return rc;
+}
+
+static int _csync_statedb_is_empty(sqlite3 *db) {
+  c_strlist_t *result = NULL;
+  int rc = 0;
+
+  result = csync_statedb_query(db, "SELECT COUNT(phash) FROM metadata LIMIT 1 OFFSET 0;");
+  if (result == NULL) {
+    rc = 1;
+  }
+  c_strlist_destroy(result);
+
+  return rc;
+}
+
+#ifndef NDEBUG
+static void sqlite_profile( void *x, const char* sql, sqlite3_uint64 time)
+{
+    (void)x;
+    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
+              "_SQL_ %s: %llu", sql, time);
+
+}
+#endif
+
+int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb) {
+  int rc = -1;
+  c_strlist_t *result = NULL;
+  sqlite3 *db = NULL;
+
+  if( !ctx ) {
+      return -1;
+  }
+
+  if (ctx->statedb.db) {
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: DB already open");
+      ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
+      return -1;
+  }
+
+  ctx->statedb.lastReturnValue = SQLITE_OK;
+
+  /* Openthe database */
+  if (sqlite_open(statedb, &db) != SQLITE_OK) {
+    const char *errmsg= sqlite3_errmsg(ctx->statedb.db);
+    CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: Failed to sqlite3 open statedb - bail out: %s.",
+              errmsg ? errmsg : "<no sqlite3 errormsg>");
+
+    rc = -1;
+    ctx->status_code = CSYNC_STATUS_STATEDB_LOAD_ERROR;
+    goto out;
+  }
+
+  if (_csync_check_db_integrity(db) != 0) {
+      const char *errmsg= sqlite3_errmsg(db);
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: sqlite3 integrity check failed - bail out: %s.",
+                errmsg ? errmsg : "<no sqlite3 errormsg>");
+      rc = -1;
+      ctx->status_code = CSYNC_STATUS_STATEDB_CORRUPTED;
+      goto out;
+  }
+
+  if (_csync_statedb_is_empty(db)) {
+    CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "statedb contents doesn't exist");
+    csync_set_statedb_exists(ctx, 0);
+  } else {
+    csync_set_statedb_exists(ctx, 1);
+  }
+
+  /* Print out the version */
+  //
+  result = csync_statedb_query(db, "SELECT sqlite_version();");
+  if (result && result->count >= 1) {
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "sqlite3 version \"%s\"", *result->vector);
+  }
+  c_strlist_destroy(result);
+
+  /* optimization for speeding up SQLite */
+  result = csync_statedb_query(db, "PRAGMA synchronous = NORMAL;");
+  c_strlist_destroy(result);
+  result = csync_statedb_query(db, "PRAGMA case_sensitive_like = ON;");
+  c_strlist_destroy(result);
+
+  /* set a busy handler with 5 seconds timeout */
+  sqlite3_busy_timeout(db, 5000);
+
+#ifndef NDEBUG
+  sqlite3_profile(db, sqlite_profile, 0 );
+#endif
+  *pdb = db;
+
+  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Success");
+
+  return 0;
+out:
+  sqlite3_close(db);
+  return rc;
+}
+
+int csync_statedb_close(CSYNC *ctx) {
+  int rc = 0;
+
+  if (!ctx) {
+      return -1;
+  }
+
+  /* deallocate query resources */
+  if( ctx->statedb.by_fileid_stmt ) {
+      sqlite3_finalize(ctx->statedb.by_fileid_stmt);
+      ctx->statedb.by_fileid_stmt = NULL;
+  }
+  if( ctx->statedb.by_hash_stmt ) {
+      sqlite3_finalize(ctx->statedb.by_hash_stmt);
+      ctx->statedb.by_hash_stmt = NULL;
+  }
+  if( ctx->statedb.by_inode_stmt) {
+      sqlite3_finalize(ctx->statedb.by_inode_stmt);
+      ctx->statedb.by_inode_stmt = NULL;
+  }
+
+  ctx->statedb.lastReturnValue = SQLITE_OK;
+
+  int sr = sqlite3_close(ctx->statedb.db);
+  CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "sqlite3_close=%d", sr);
+
+  ctx->statedb.db = 0;
+
+  return rc;
+}
+
+#define METADATA_QUERY                                                                      \
+    "phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, " \
+    "filesize, ignoredChildrenRemote, "                                                     \
+    "contentchecksumtype.name || ':' || contentChecksum "                                   \
+    "FROM metadata "                                                                        \
+    "LEFT JOIN checksumtype as contentchecksumtype ON metadata.contentChecksumTypeId == contentchecksumtype.id"
+
+// This funciton parses a line from the metadata table into the given csync_file_stat
+// structure which it is also allocating.
+// Note that this function calls laso sqlite3_step to actually get the info from db and
+// returns the sqlite return type.
+static int _csync_file_stat_from_metadata_table( csync_file_stat_t **st, sqlite3_stmt *stmt )
+{
+    int rc = SQLITE_ERROR;
+    int column_count;
+    int len;
+
+    if( ! stmt ) {
+       CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Fatal: Statement is NULL.");
+       return SQLITE_ERROR;
+    }
+
+    column_count = sqlite3_column_count(stmt);
+
+    SQLITE_BUSY_HANDLED( sqlite3_step(stmt) );
+
+    if( rc == SQLITE_ROW ) {
+        if(column_count > 7) {
+            const char *name;
+
+            /* phash, pathlen, path, inode, uid, gid, mode, modtime */
+            len = sqlite3_column_int(stmt, 1);
+            *st = c_malloc(sizeof(csync_file_stat_t) + len + 1);
+            /* clear the whole structure */
+            ZERO_STRUCTP(*st);
+
+            /* The query suceeded so use the phash we pass to the function. */
+            (*st)->phash = sqlite3_column_int64(stmt, 0);
+
+            (*st)->pathlen = sqlite3_column_int(stmt, 1);
+            name = (const char*) sqlite3_column_text(stmt, 2);
+            memcpy((*st)->path, (len ? name : ""), len + 1);
+            (*st)->inode = sqlite3_column_int64(stmt,3);
+            (*st)->mode = sqlite3_column_int(stmt, 6);
+            (*st)->modtime = strtoul((char*)sqlite3_column_text(stmt, 7), NULL, 10);
+
+            if(*st && column_count > 8 ) {
+                (*st)->type = sqlite3_column_int(stmt, 8);
+            }
+
+            if(column_count > 9 && sqlite3_column_text(stmt, 9)) {
+                (*st)->etag = c_strdup( (char*) sqlite3_column_text(stmt, 9) );
+            }
+            if(column_count > 10 && sqlite3_column_text(stmt,10)) {
+                csync_vio_set_file_id((*st)->file_id, (char*) sqlite3_column_text(stmt, 10));
+            }
+            if(column_count > 11 && sqlite3_column_text(stmt,11)) {
+                strncpy((*st)->remotePerm,
+                        (char*) sqlite3_column_text(stmt, 11),
+                        REMOTE_PERM_BUF_SIZE);
+            }
+            if(column_count > 12 && sqlite3_column_int64(stmt,12)) {
+                (*st)->size = sqlite3_column_int64(stmt, 12);
+            }
+            if(column_count > 13) {
+                (*st)->has_ignored_files = sqlite3_column_int(stmt, 13);
+            }
+            if (column_count > 14 && sqlite3_column_text(stmt, 14)) {
+                (*st)->checksumHeader = c_strdup((char *)sqlite3_column_text(stmt, 14));
+            }
+
+        }
+    } else {
+        if( rc != SQLITE_DONE ) {
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Query results in %d", rc);
+        }
+    }
+    return rc;
+}
+
+/* caller must free the memory */
+csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx,
+                                                  uint64_t phash)
+{
+  csync_file_stat_t *st = NULL;
+  int rc;
+
+  if( !ctx || ctx->db_is_empty ) {
+      return NULL;
+  }
+
+  if( ctx->statedb.by_hash_stmt == NULL ) {
+      const char *hash_query = "SELECT " METADATA_QUERY " WHERE phash=?1";
+
+      SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, hash_query, strlen(hash_query), &ctx->statedb.by_hash_stmt, NULL));
+      ctx->statedb.lastReturnValue = rc;
+      if( rc != SQLITE_OK ) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for hash query.");
+          return NULL;
+      }
+  }
+
+  if( ctx->statedb.by_hash_stmt == NULL ) {
+    return NULL;
+  }
+
+  sqlite3_bind_int64(ctx->statedb.by_hash_stmt, 1, (long long signed int)phash);
+
+  rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_hash_stmt);
+  ctx->statedb.lastReturnValue = rc;
+  if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) )  {
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata: %d!", rc);
+  }
+  sqlite3_reset(ctx->statedb.by_hash_stmt);
+
+  return st;
+}
+
+csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx,
+                                                      const char *file_id ) {
+    csync_file_stat_t *st = NULL;
+    int rc = 0;
+
+    if (!file_id) {
+        return 0;
+    }
+    if (c_streq(file_id, "")) {
+        return 0;
+    }
+
+    if( !ctx || ctx->db_is_empty ) {
+        return NULL;
+    }
+
+    if( ctx->statedb.by_fileid_stmt == NULL ) {
+        const char *query = "SELECT " METADATA_QUERY " WHERE fileid=?1";
+
+        SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, query, strlen(query), &ctx->statedb.by_fileid_stmt, NULL));
+        ctx->statedb.lastReturnValue = rc;
+        if( rc != SQLITE_OK ) {
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for file id query.");
+            return NULL;
+        }
+    }
+
+    /* bind the query value */
+    sqlite3_bind_text(ctx->statedb.by_fileid_stmt, 1, file_id, -1, SQLITE_STATIC);
+
+    rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_fileid_stmt);
+    ctx->statedb.lastReturnValue = rc;
+    if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) ) {
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata: %d!", rc);
+    }
+    // clear the resources used by the statement.
+    sqlite3_reset(ctx->statedb.by_fileid_stmt);
+
+    return st;
+}
+
+/* caller must free the memory */
+csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx,
+                                                  uint64_t inode)
+{
+  csync_file_stat_t *st = NULL;
+  int rc;
+
+  if (!inode) {
+      return NULL;
+  }
+
+  if( !ctx || ctx->db_is_empty ) {
+      return NULL;
+  }
+
+  if( ctx->statedb.by_inode_stmt == NULL ) {
+      const char *inode_query = "SELECT " METADATA_QUERY " WHERE inode=?1";
+
+      SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, inode_query, strlen(inode_query), &ctx->statedb.by_inode_stmt, NULL));
+      ctx->statedb.lastReturnValue = rc;
+      if( rc != SQLITE_OK ) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for inode query.");
+          return NULL;
+      }
+  }
+
+  if( ctx->statedb.by_inode_stmt == NULL ) {
+    return NULL;
+  }
+
+  sqlite3_bind_int64(ctx->statedb.by_inode_stmt, 1, (long long signed int)inode);
+
+  rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_inode_stmt);
+  ctx->statedb.lastReturnValue = rc;
+  if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) ) {
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata by inode: %d!", rc);
+  }
+  sqlite3_reset(ctx->statedb.by_inode_stmt);
+
+  return st;
+}
+
+int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
+    int rc;
+    sqlite3_stmt *stmt = NULL;
+    int64_t cnt = 0;
+
+    if( !path ) {
+        return -1;
+    }
+
+    if( !ctx || ctx->db_is_empty ) {
+        return -1;
+    }
+
+    /*  Select the entries for anything that starts with  (path+'/')
+     * In other words, anything that is between  path+'/' and path+'0',
+     * (because '0' follows '/' in ascii)
+     */
+    const char *below_path_query = "SELECT " METADATA_QUERY " WHERE path > (?||'/') AND path < (?||'0') ORDER BY path||'/' ASC";
+    SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, below_path_query, -1, &stmt, NULL));
+    ctx->statedb.lastReturnValue = rc;
+    if( rc != SQLITE_OK ) {
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for below path query.");
+      return -1;
+    }
+
+    if (stmt == NULL) {
+      return -1;
+    }
+
+    sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC);
+    sqlite3_bind_text(stmt, 2, path, -1, SQLITE_STATIC);
+
+    cnt = 0;
+
+    ctx->statedb.lastReturnValue = rc;
+    do {
+        csync_file_stat_t *st = NULL;
+
+        rc = _csync_file_stat_from_metadata_table( &st, stmt);
+        if( st ) {
+            /* When selective sync is used, the database may have subtrees with a parent
+             * whose etag (md5) is _invalid_. These are ignored and shall not appear in the
+             * remote tree.
+             * Sometimes folders that are not ignored by selective sync get marked as
+             * _invalid_, but that is not a problem as the next discovery will retrieve
+             * their correct etags again and we don't run into this case.
+             */
+            if( c_streq(st->etag, "_invalid_") ) {
+                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s selective sync excluded", st->path);
+                char *skipbase = c_strdup(st->path);
+                skipbase[st->pathlen] = '/';
+                int skiplen = st->pathlen + 1;
+
+                /* Skip over all entries with the same base path. Note that this depends
+                 * strongly on the ordering of the retrieved items. */
+                do {
+                    csync_file_stat_free(st);
+                    rc = _csync_file_stat_from_metadata_table( &st, stmt);
+                    if( st && strncmp(st->path, skipbase, skiplen) != 0 ) {
+                        break;
+                    }
+                    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s selective sync excluded because the parent is", st->path);
+                } while( rc == SQLITE_ROW );
+
+                /* End of data? */
+                if( rc != SQLITE_ROW || !st ) {
+                    continue;
+                }
+            }
+
+            /* Check for exclusion from the tree.
+             * Note that this is only a safety net in case the ignore list changes
+             * without a full remote discovery being triggered. */
+            CSYNC_EXCLUDE_TYPE excluded = csync_excluded_traversal(ctx->excludes, st->path, st->type);
+            if (excluded != CSYNC_NOT_EXCLUDED) {
+                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", st->path, excluded);
+
+                if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE
+                        || excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
+                    csync_file_stat_free(st);
+                    continue;
+                }
+
+                st->instruction = CSYNC_INSTRUCTION_IGNORE;
+            }
+
+            /* store into result list. */
+            if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
+                csync_file_stat_free(st);
+                ctx->status_code = CSYNC_STATUS_TREE_ERROR;
+                break;
+            }
+            cnt++;
+        }
+    } while( rc == SQLITE_ROW );
+
+    ctx->statedb.lastReturnValue = rc;
+    if( rc != SQLITE_DONE ) {
+        ctx->status_code = CSYNC_STATUS_TREE_ERROR;
+    } else {
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "%" PRId64 " entries read below path %s from db.", cnt, path);
+    }
+    sqlite3_finalize(stmt);
+
+    return 0;
+}
+
+/* query the statedb, caller must free the memory */
+c_strlist_t *csync_statedb_query(sqlite3 *db,
+                                 const char *statement) {
+  int err = SQLITE_OK;
+  int rc = SQLITE_OK;
+  size_t i = 0;
+  size_t busy_count = 0;
+  size_t retry_count = 0;
+  size_t column_count = 0;
+  sqlite3_stmt *stmt;
+  const char *tail = NULL;
+  const char *field = NULL;
+  c_strlist_t *result = NULL;
+  int row = 0;
+
+  do {
+    /* compile SQL program into a virtual machine, reattempteing if busy */
+    do {
+      if (busy_count) {
+        csync_sleep(100);
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "sqlite3_prepare: BUSY counter: %zu", busy_count);
+      }
+      err = sqlite3_prepare(db, statement, -1, &stmt, &tail);
+    } while (err == SQLITE_BUSY && busy_count ++ < 120);
+
+    if (err != SQLITE_OK) {
+      if (err == SQLITE_BUSY) {
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Gave up waiting for lock to clear");
+      }
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN,
+                "sqlite3_compile error: %s - on query %s",
+                sqlite3_errmsg(db), statement);
+      break;
+    } else {
+      busy_count = 0;
+      column_count = sqlite3_column_count(stmt);
+
+      /* execute virtual machine by iterating over rows */
+      for(;;) {
+        err = sqlite3_step(stmt);
+
+        if (err == SQLITE_BUSY) {
+          if (busy_count++ > 120) {
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Busy counter has reached its maximum. Aborting this sql statement");
+            break;
+          }
+          csync_sleep(100);
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "sqlite3_step: BUSY counter: %zu", busy_count);
+          continue;
+        }
+
+        if (err == SQLITE_MISUSE) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "sqlite3_step: MISUSE!!");
+        }
+
+        if (err == SQLITE_DONE) {
+          if (result == NULL) {
+            result = c_strlist_new(1);
+          }
+          break;
+        }
+
+        if (err == SQLITE_ERROR) {
+          break;
+        }
+
+       row++;
+        if( result ) {
+            result = c_strlist_expand(result, row*column_count);
+        } else {
+            result = c_strlist_new(column_count);
+        }
+
+        if (result == NULL) {
+          return NULL;
+        }
+
+        /* iterate over columns */
+        for (i = 0; i < column_count; i++) {
+          field = (const char *) sqlite3_column_text(stmt, i);
+          if (!field)
+              field = "";
+          // CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "sqlite3_column_text: %s", field);
+          if (c_strlist_add(result, field) < 0) {
+            c_strlist_destroy(result);
+            return NULL;
+          }
+        }
+      } /* end infinite for loop */
+
+      /* deallocate vm resources */
+      rc = sqlite3_finalize(stmt);
+
+      if (err != SQLITE_DONE && rc != SQLITE_SCHEMA) {
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "sqlite_step error: %s - on query: %s", sqlite3_errmsg(db), statement);
+        if (result != NULL) {
+          c_strlist_destroy(result);
+        }
+        return NULL;
+      }
+
+      if (rc == SQLITE_SCHEMA) {
+        retry_count ++;
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "SQLITE_SCHEMA error occurred on query: %s", statement);
+        if (retry_count < 10) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Retrying now.");
+        } else {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "RETRY count has reached its maximum. Aborting statement: %s", statement);
+          if (result != NULL) {
+            c_strlist_destroy(result);
+          }
+          result = c_strlist_new(1);
+        }
+      }
+    }
+  } while (rc == SQLITE_SCHEMA && retry_count < 10);
+
+  return result;
+}
+
+/* vim: set ts=8 sw=2 et cindent: */
diff --git a/src/csync/csync_statedb.h b/src/csync/csync_statedb.h
new file mode 100644 (file)
index 0000000..601e34a
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file csync_private.h
+ *
+ * @brief Private interface of csync
+ *
+ * @defgroup csyncstatedbInternals csync statedb internals
+ * @ingroup csyncInternalAPI
+ *
+ * @{
+ */
+
+#ifndef _CSYNC_STATEDB_H
+#define _CSYNC_STATEDB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "c_lib.h"
+#include "csync_private.h"
+
+void csync_set_statedb_exists(CSYNC *ctx, int val);
+
+int csync_get_statedb_exists(CSYNC *ctx);
+
+/**
+ * @brief Load the statedb.
+ *
+ * This function tries to load the statedb. If it doesn't exists it creates
+ * the sqlite3 database, but doesn't create the tables. This will be done when
+ * csync gets destroyed.
+ *
+ * @param ctx      The csync context.
+ * @param statedb  Path to the statedb file (sqlite3 db).
+ *
+ * @return 0 on success, less than 0 if an error occurred with errno set.
+ */
+OCSYNC_EXPORT int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb);
+
+OCSYNC_EXPORT int csync_statedb_close(CSYNC *ctx);
+
+OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx, uint64_t phash);
+
+OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, uint64_t inode);
+
+OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *file_id);
+
+/**
+ * @brief Query all files metadata inside and below a path.
+ * @param ctx        The csync context.
+ * @param path       The path.
+ *
+ * This function queries all metadata of all files inside or below the
+ * given path. The result is a linear string list with a multiple of 9
+ * entries. For each result file there are 9 strings which are phash,
+ * path, inode, uid, gid, mode, modtime, type and md5 (unique id).
+ *
+ * Note that not only the files in the given path are part of the result
+ * but also the files in directories below the given path. Ie. if the
+ * parameter path is /home/kf/test, we have /home/kf/test/file.txt in
+ * the result but also /home/kf/test/homework/another_file.txt
+ *
+ * @return   A stringlist containing a multiple of 9 entries.
+ */
+int csync_statedb_get_below_path(CSYNC *ctx, const char *path);
+
+/**
+ * @brief A generic statedb query.
+ *
+ * @param ctx        The csync context.
+ * @param statement  The SQL statement to execute
+ * 
+ * @return   A stringlist of the entries of a column. An emtpy stringlist if
+ *           nothing has been found. NULL on error.
+ */
+c_strlist_t *csync_statedb_query(sqlite3 *db, const char *statement);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * }@
+ */
+#endif /* _CSYNC_STATEDB_H */
+/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/src/csync/csync_time.c b/src/csync/csync_time.c
new file mode 100644 (file)
index 0000000..85bdd5f
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <time.h>
+
+#include "csync_time.h"
+#include "vio/csync_vio.h"
+
+#ifndef _WIN32
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+
+#define CSYNC_LOG_CATEGORY_NAME "csync.time"
+#include "csync_log.h"
+
+#ifdef HAVE_CLOCK_GETTIME
+# ifdef _POSIX_MONOTONIC_CLOCK
+#  define CSYNC_CLOCK CLOCK_MONOTONIC
+# else
+#  define CSYNC_CLOCK CLOCK_REALTIME
+# endif
+#endif
+
+
+int csync_gettime(struct timespec *tp)
+{
+#if defined(_WIN32)
+       __int64 wintime;
+       GetSystemTimeAsFileTime((FILETIME*)&wintime);
+       wintime -= 116444736000000000ll;  //1jan1601 to 1jan1970
+       tp->tv_sec = wintime / 10000000ll;           //seconds
+       tp->tv_nsec = wintime % 10000000ll * 100;      //nano-seconds
+#elif defined(HAVE_CLOCK_GETTIME)
+       return clock_gettime(CSYNC_CLOCK, tp);
+#else
+       struct timeval tv;
+
+       if (gettimeofday(&tv, NULL) < 0) {
+               return -1;
+       }
+
+       tp->tv_sec = tv.tv_sec;
+       tp->tv_nsec = tv.tv_usec * 1000;
+#endif
+       return 0;
+}
+
+#undef CSYNC_CLOCK
+
+void csync_sleep(unsigned int msecs)
+{
+#if defined(_WIN32)
+       Sleep(msecs);
+#else
+    usleep(msecs * 1000);
+#endif
+}
diff --git a/src/csync/csync_time.h b/src/csync/csync_time.h
new file mode 100644 (file)
index 0000000..1492bef
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CSYNC_TIME_H
+#define _CSYNC_TIME_H
+
+#include <time.h>
+
+#include "csync_private.h"
+
+int csync_gettime(struct timespec *tp);
+void csync_sleep(unsigned int msecs);
+
+#endif /* _CSYNC_TIME_H */
diff --git a/src/csync/csync_update.c b/src/csync/csync_update.c
new file mode 100644 (file)
index 0000000..1a06944
--- /dev/null
@@ -0,0 +1,862 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <time.h>
+#include <math.h>
+
+#include "c_lib.h"
+#include "c_jhash.h"
+
+#include "csync_private.h"
+#include "csync_exclude.h"
+#include "csync_statedb.h"
+#include "csync_update.h"
+#include "csync_util.h"
+#include "csync_misc.h"
+
+#include "vio/csync_vio.h"
+
+#define CSYNC_LOG_CATEGORY_NAME "csync.updater"
+#include "csync_log.h"
+#include "csync_rename.h"
+
+/* calculate the hash of a given uri */
+static uint64_t _hash_of_file(CSYNC *ctx, const char *file) {
+  const char *path;
+  int len;
+  uint64_t h = 0;
+
+  if( ctx && file ) {
+    path = file;
+    if (ctx->current == LOCAL_REPLICA) {
+      if (strlen(path) <= strlen(ctx->local.uri)) {
+        return 0;
+      }
+      path += strlen(ctx->local.uri) + 1;
+    }
+    len = strlen(path);
+    h = c_jhash64((uint8_t *) path, len, 0);
+  }
+  return h;
+}
+
+#ifdef NO_RENAME_EXTENSION
+/* Return true if the two path have the same extension. false otherwise. */
+static bool _csync_sameextension(const char *p1, const char *p2) {
+    /* Find pointer to the extensions */
+    const char *e1 = strrchr(p1, '.');
+    const char *e2 = strrchr(p2, '.');
+
+    /* If the found extension contains a '/', it is because the . was in the folder name
+     *            => no extensions */
+    if (e1 && strchr(e1, '/')) e1 = NULL;
+    if (e2 && strchr(e2, '/')) e2 = NULL;
+
+    /* If none have extension, it is the same extension */
+    if (!e1 && !e2)
+        return true;
+
+    /* c_streq takes care of the rest */
+    return c_streq(e1, e2);
+}
+#endif
+
+static bool _last_db_return_error(CSYNC* ctx) {
+    return ctx->statedb.lastReturnValue != SQLITE_OK && ctx->statedb.lastReturnValue != SQLITE_DONE && ctx->statedb.lastReturnValue != SQLITE_ROW;
+}
+
+/*
+ * This static method is needed because the type members of the two structs use
+ * different enum values. A direct comparion is not neccessarily correct.
+ *
+ * tmp is csync_file_stat_t
+ * fs  is csync_vio_file_stat_t with this vio type:
+ *  enum csync_vio_file_type_e {
+ *              CSYNC_VIO_FILE_TYPE_UNKNOWN,
+ *              CSYNC_VIO_FILE_TYPE_REGULAR,
+ *              CSYNC_VIO_FILE_TYPE_DIRECTORY,
+ *              CSYNC_VIO_FILE_TYPE_FIFO,
+ *              CSYNC_VIO_FILE_TYPE_SOCKET,
+ *              CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE,
+ *              CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE,
+ *              CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK
+ *            };
+ *
+ * csync_file_stat_t can be:
+ * CSYNC_FTW_TYPE_SKIP, CSYNC_FTW_TYPE_FILE
+ * CSYNC_FTW_TYPE_DIR, CSYNC_FTW_TYPE_SLINK
+ */
+static bool _csync_filetype_different( const csync_file_stat_t *tmp, const csync_vio_file_stat_t *fs)
+{
+    if( !(tmp && fs)) return false;
+
+    if( tmp->type == CSYNC_FTW_TYPE_SKIP ) return true;
+
+    if( tmp->type == CSYNC_FTW_TYPE_DIR && fs->type != CSYNC_VIO_FILE_TYPE_DIRECTORY )
+        return true;
+    if( tmp->type == CSYNC_FTW_TYPE_FILE && fs->type != CSYNC_VIO_FILE_TYPE_REGULAR )
+        return true;
+    if( tmp->type == CSYNC_FTW_TYPE_SLINK && fs->type != CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK )
+        return true;
+
+    return false; // both are NOT different.
+}
+
+/* Return true if two mtime are considered equal
+ * We consider mtime that are one hour difference to be equal if they are one hour appart
+ * because on some system (FAT) the date is changing when the daylight saving is changing */
+static bool _csync_mtime_equal(time_t a, time_t b)
+{
+    if (a == b)
+        return true;
+
+    /* 1h of difference +- 1 second because the accuracy of FAT is 2 seconds (#2438) */
+    if (fabs(3600 - fabs(difftime(a, b))) < 2)
+        return true;
+
+    return false;
+}
+
+/**
+ * The main function of the discovery/update pass.
+ *
+ * It's called (indirectly) by csync_update(), once for each entity in the
+ * local filesystem and once for each entity in the server data.
+ *
+ * It has two main jobs:
+ * - figure out whether anything happened compared to the sync journal
+ *   and set (primarily) the instruction flag accordingly
+ * - build the ctx->local.tree / ctx->remote.tree
+ *
+ * See doc/dev/sync-algorithm.md for an overview.
+ */
+static int _csync_detect_update(CSYNC *ctx, const char *file,
+    const csync_vio_file_stat_t *fs, const int type) {
+  uint64_t h = 0;
+  size_t len = 0;
+  size_t size = 0;
+  const char *path = NULL;
+  csync_file_stat_t *st = NULL;
+  csync_file_stat_t *tmp = NULL;
+  CSYNC_EXCLUDE_TYPE excluded;
+
+  if ((file == NULL) || (fs == NULL)) {
+    errno = EINVAL;
+    ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
+    return -1;
+  }
+
+  path = file;
+  if (ctx->current == LOCAL_REPLICA) {
+      if (strlen(path) <= strlen(ctx->local.uri)) {
+        ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
+        return -1;
+      }
+      path += strlen(ctx->local.uri) + 1;
+  }
+
+  len = strlen(path);
+
+  if (type == CSYNC_FTW_TYPE_SKIP) {
+      excluded =CSYNC_FILE_EXCLUDE_STAT_FAILED;
+  } else {
+    /* Check if file is excluded */
+    excluded = csync_excluded_traversal(ctx->excludes, path, type);
+  }
+
+  if( excluded == CSYNC_NOT_EXCLUDED ) {
+      /* Even if it is not excluded by a pattern, maybe it is to be ignored
+       * because it's a hidden file that should not be synced.
+       * This code should probably be in csync_exclude, but it does not have the fs parameter.
+       * Keep it here for now */
+      if (ctx->ignore_hidden_files && (fs->flags & CSYNC_VIO_FILE_FLAGS_HIDDEN)) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file excluded because it is a hidden file: %s", path);
+          excluded = CSYNC_FILE_EXCLUDE_HIDDEN;
+      }
+  } else {
+      /* File is ignored because it's matched by a user- or system exclude pattern. */
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded  (%d)", path, excluded);
+      if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) {
+          return 1;
+      }
+      if (excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
+          return 1;
+      }
+  }
+
+  if (ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncBlackListHook) {
+      if (ctx->callbacks.checkSelectiveSyncBlackListHook(ctx->callbacks.update_callback_userdata, path)) {
+          return 1;
+      }
+  }
+
+  h = _hash_of_file(ctx, file );
+  if( h == 0 ) {
+    return -1;
+  }
+  size = sizeof(csync_file_stat_t) + len + 1;
+
+  st = c_malloc(size);
+
+  /* Set instruction by default to none */
+  st->instruction = CSYNC_INSTRUCTION_NONE;
+  st->etag = NULL;
+  st->child_modified = 0;
+  st->has_ignored_files = 0;
+  if (type == CSYNC_FTW_TYPE_FILE ) {
+    if (fs->mtime == 0) {
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - mtime is zero!", path);
+    }
+  }
+
+  if (excluded > CSYNC_NOT_EXCLUDED || type == CSYNC_FTW_TYPE_SLINK) {
+      st->instruction = CSYNC_INSTRUCTION_IGNORE;
+      if (ctx->current_fs) {
+          ctx->current_fs->has_ignored_files = true;
+      }
+
+      goto out;
+  }
+
+  /* Update detection: Check if a database entry exists.
+   * If not, the file is either new or has been renamed. To see if it is
+   * renamed, the db gets queried by the inode of the file as that one
+   * does not change on rename.
+   */
+  if (csync_get_statedb_exists(ctx)) {
+    tmp = csync_statedb_get_stat_by_hash(ctx, h);
+
+    if(_last_db_return_error(ctx)) {
+        csync_file_stat_free(st);
+        csync_file_stat_free(tmp);
+        ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
+        return -1;
+    }
+
+    if(tmp && tmp->phash == h ) { /* there is an entry in the database */
+        /* we have an update! */
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Database entry found, compare: %" PRId64 " <-> %" PRId64
+                                            ", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64
+                                            ", size: %" PRId64 " <-> %" PRId64 ", perms: %s <-> %s, ignore: %d",
+                  ((int64_t) fs->mtime), ((int64_t) tmp->modtime),
+                  fs->etag, tmp->etag, (uint64_t) fs->inode, (uint64_t) tmp->inode,
+                  (uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm, tmp->remotePerm, tmp->has_ignored_files );
+        if (ctx->current == REMOTE_REPLICA && !c_streq(fs->etag, tmp->etag)) {
+            st->instruction = CSYNC_INSTRUCTION_EVAL;
+
+            // Preserve the EVAL flag later on if the type has changed.
+            if (_csync_filetype_different(tmp, fs)) {
+                st->child_modified = 1;
+            }
+
+            goto out;
+        }
+        if (ctx->current == LOCAL_REPLICA &&
+                (!_csync_mtime_equal(fs->mtime, tmp->modtime)
+                 // zero size in statedb can happen during migration
+                 || (tmp->size != 0 && fs->size != tmp->size))) {
+
+            // Checksum comparison at this stage is only enabled for .eml files,
+            // check #4754 #4755
+            bool isEmlFile = csync_fnmatch("*.eml", file, FNM_CASEFOLD) == 0;
+            if (isEmlFile && fs->size == tmp->size && tmp->checksumHeader) {
+                if (ctx->callbacks.checksum_hook) {
+                    st->checksumHeader = ctx->callbacks.checksum_hook(
+                        file, tmp->checksumHeader,
+                        ctx->callbacks.checksum_userdata);
+                }
+                bool checksumIdentical = false;
+                if (st->checksumHeader) {
+                    checksumIdentical = strncmp(st->checksumHeader, tmp->checksumHeader, 1000) == 0;
+                }
+                if (checksumIdentical) {
+                    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "NOTE: Checksums are identical, file did not actually change: %s", path);
+                    st->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
+                    goto out;
+                }
+            }
+
+            // Preserve the EVAL flag later on if the type has changed.
+            if (_csync_filetype_different(tmp, fs)) {
+                st->child_modified = 1;
+            }
+
+            st->instruction = CSYNC_INSTRUCTION_EVAL;
+            goto out;
+        }
+        bool metadata_differ = (ctx->current == REMOTE_REPLICA && (!c_streq(fs->file_id, tmp->file_id)
+                                                            || !c_streq(fs->remotePerm, tmp->remotePerm)))
+                             || (ctx->current == LOCAL_REPLICA && fs->inode != tmp->inode);
+        if (type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA
+                && !metadata_differ && ctx->read_remote_from_db) {
+            /* If both etag and file id are equal for a directory, read all contents from
+             * the database.
+             * The metadata comparison ensure that we fetch all the file id or permission when
+             * upgrading owncloud
+             */
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Reading from database: %s", path);
+            ctx->remote.read_from_db = true;
+        }
+        /* If it was remembered in the db that the remote dir has ignored files, store
+         * that so that the reconciler can make advantage of.
+         */
+        if( ctx->current == REMOTE_REPLICA ) {
+            st->has_ignored_files = tmp->has_ignored_files;
+        }
+        if (metadata_differ) {
+            /* file id or permissions has changed. Which means we need to update them in the DB. */
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Need to update metadata for: %s", path);
+            st->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
+        } else {
+            st->instruction = CSYNC_INSTRUCTION_NONE;
+        }
+    } else {
+        enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
+
+        /* tmp might point to malloc mem, so free it here before reusing tmp  */
+        csync_file_stat_free(tmp);
+
+        /* check if it's a file and has been renamed */
+        if (ctx->current == LOCAL_REPLICA) {
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
+
+            tmp = csync_statedb_get_stat_by_inode(ctx, fs->inode);
+
+            if(_last_db_return_error(ctx)) {
+                csync_file_stat_free(st);
+                ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
+                return -1;
+            }
+
+            /* translate the file type between the two stat types csync has. */
+            if( tmp && tmp->type == CSYNC_FTW_TYPE_FILE ) {
+                tmp_vio_type = CSYNC_VIO_FILE_TYPE_REGULAR;
+            } else if( tmp && tmp->type == CSYNC_FTW_TYPE_DIR) {
+                tmp_vio_type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
+            } else if( tmp && tmp->type == CSYNC_FTW_TYPE_SLINK ) {
+                tmp_vio_type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
+            } else {
+                tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
+            }
+
+            // Default to NEW unless we're sure it's a rename.
+            st->instruction = CSYNC_INSTRUCTION_NEW;
+
+            bool isRename =
+                tmp && tmp->inode == fs->inode && tmp_vio_type == fs->type
+                    && (tmp->modtime == fs->mtime || fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY)
+#ifdef NO_RENAME_EXTENSION
+                    && _csync_sameextension(tmp->path, path)
+#endif
+                ;
+
+
+            // Verify the checksum where possible
+            if (isRename && tmp->checksumHeader && ctx->callbacks.checksum_hook
+                && fs->type == CSYNC_VIO_FILE_TYPE_REGULAR) {
+                st->checksumHeader = ctx->callbacks.checksum_hook(
+                    file, tmp->checksumHeader,
+                    ctx->callbacks.checksum_userdata);
+                if (st->checksumHeader) {
+                    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "checking checksum of potential rename %s %s <-> %s", path, st->checksumHeader, tmp->checksumHeader);
+                    isRename = strncmp(st->checksumHeader, tmp->checksumHeader, 1000) == 0;
+                }
+            }
+
+            if (isRename) {
+                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
+                /* inode found so the file has been renamed */
+                st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
+                if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {
+                    csync_rename_record(ctx, tmp->path, path);
+                }
+            }
+            goto out;
+
+        } else {
+            /* Remote Replica Rename check */
+            tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id);
+
+            if(_last_db_return_error(ctx)) {
+                csync_file_stat_free(st);
+                ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
+                return -1;
+            }
+            if(tmp ) {                           /* tmp existing at all */
+                if ( _csync_filetype_different(tmp, fs)) {
+                    CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "file types different is not!");
+                    st->instruction = CSYNC_INSTRUCTION_NEW;
+                    goto out;
+                }
+                CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "remote rename detected based on fileid %s %s", tmp->path, file);
+                st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
+                if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {
+                    csync_rename_record(ctx, tmp->path, path);
+                } else {
+                    if( !c_streq(tmp->etag, fs->etag) ) {
+                        /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "ETags are different!"); */
+                        /* File with different etag, don't do a rename, but download the file again */
+                        st->instruction = CSYNC_INSTRUCTION_NEW;
+                    }
+                }
+                goto out;
+
+            } else {
+                /* file not found in statedb */
+                st->instruction = CSYNC_INSTRUCTION_NEW;
+
+                if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) {
+                    if (ctx->callbacks.checkSelectiveSyncNewFolderHook(ctx->callbacks.update_callback_userdata, path, fs->remotePerm)) {
+                        csync_file_stat_free(st);
+                        return 1;
+                    }
+                }
+                goto out;
+            }
+        }
+    }
+  } else  {
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Unable to open statedb" );
+      csync_file_stat_free(st);
+      ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
+      return -1;
+  }
+
+out:
+
+  /* Set the ignored error string. */
+  if (st->instruction == CSYNC_INSTRUCTION_IGNORE) {
+      if( type == CSYNC_FTW_TYPE_SLINK ) {
+          st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK; /* Symbolic links are ignored. */
+      } else {
+          if (excluded == CSYNC_FILE_EXCLUDE_LIST) {
+              st->error_status = CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST; /* File listed on ignore list. */
+          } else if (excluded == CSYNC_FILE_EXCLUDE_INVALID_CHAR) {
+              st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS;  /* File contains invalid characters. */
+          } else if (excluded == CSYNC_FILE_EXCLUDE_TRAILING_SPACE) {
+              st->error_status = CSYNC_STATUS_INDIVIDUAL_TRAILING_SPACE; /* File ends with a trailing space. */
+          } else if (excluded == CSYNC_FILE_EXCLUDE_LONG_FILENAME) {
+              st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME; /* File name is too long. */
+          } else if (excluded == CSYNC_FILE_EXCLUDE_HIDDEN ) {
+              st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN;
+          } else if (excluded == CSYNC_FILE_EXCLUDE_STAT_FAILED) {
+              st->error_status = CSYNC_STATUS_INDIVIDUAL_STAT_FAILED;
+          } else if (excluded == CSYNC_FILE_EXCLUDE_CONFLICT) {
+              st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE;
+          }
+      }
+  }
+  if (st->instruction != CSYNC_INSTRUCTION_NONE
+      && st->instruction != CSYNC_INSTRUCTION_IGNORE
+      && st->instruction != CSYNC_INSTRUCTION_UPDATE_METADATA
+      && type != CSYNC_FTW_TYPE_DIR) {
+    st->child_modified = 1;
+  }
+  ctx->current_fs = st;
+
+  csync_file_stat_free(tmp);
+  st->inode = fs->inode;
+  st->mode  = fs->mode;
+  st->size  = fs->size;
+  st->modtime = fs->mtime;
+  st->type  = type;
+  st->etag   = NULL;
+  if( fs->etag ) {
+      SAFE_FREE(st->etag);
+      st->etag  = c_strdup(fs->etag);
+  }
+  csync_vio_set_file_id(st->file_id, fs->file_id);
+  if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADURL) {
+      SAFE_FREE(st->directDownloadUrl);
+      st->directDownloadUrl = c_strdup(fs->directDownloadUrl);
+  }
+  if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADCOOKIES) {
+      SAFE_FREE(st->directDownloadCookies);
+      st->directDownloadCookies = c_strdup(fs->directDownloadCookies);
+  }
+  if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_PERM) {
+      strncpy(st->remotePerm, fs->remotePerm, REMOTE_PERM_BUF_SIZE);
+  }
+
+  // For the remote: propagate the discovered checksum
+  if (fs->checksumHeader && ctx->current == REMOTE_REPLICA) {
+      st->checksumHeader = c_strdup(fs->checksumHeader);
+  }
+
+  st->phash = h;
+  st->pathlen = len;
+  memcpy(st->path, (len ? path : ""), len + 1);
+
+  switch (ctx->current) {
+    case LOCAL_REPLICA:
+      if (c_rbtree_insert(ctx->local.tree, (void *) st) < 0) {
+        csync_file_stat_free(st);
+        ctx->status_code = CSYNC_STATUS_TREE_ERROR;
+        return -1;
+      }
+      break;
+    case REMOTE_REPLICA:
+      if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
+        csync_file_stat_free(st);
+        ctx->status_code = CSYNC_STATUS_TREE_ERROR;
+        return -1;
+      }
+      break;
+    default:
+      break;
+  }
+  CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "file: %s, instruction: %s <<=", st->path,
+      csync_instruction_str(st->instruction));
+
+  return 0;
+}
+
+int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
+    enum csync_ftw_flags_e flag) {
+  int rc = -1;
+  int type = CSYNC_FTW_TYPE_SKIP;
+  csync_file_stat_t *st = NULL;
+  uint64_t h;
+
+  if (ctx->abort) {
+    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Aborted!");
+    ctx->status_code = CSYNC_STATUS_ABORTED;
+    return -1;
+  }
+
+  switch (flag) {
+    case CSYNC_FTW_FLAG_FILE:
+      if (ctx->current == REMOTE_REPLICA) {
+          if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE) {
+              CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=%" PRIu64 "]", file, fs->file_id, fs->size);
+          } else {
+              CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=UNKNOWN]", file, fs->file_id);
+          }
+      } else {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [inode=%" PRIu64 " size=%" PRIu64 "]", file, fs->inode, fs->size);
+      }
+      type = CSYNC_FTW_TYPE_FILE;
+      break;
+  case CSYNC_FTW_FLAG_DIR: /* enter directory */
+      if (ctx->current == REMOTE_REPLICA) {
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [file_id=%s]", file, fs->file_id);
+      } else {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [inode=%" PRIu64 "]", file, fs->inode);
+      }
+      type = CSYNC_FTW_TYPE_DIR;
+      break;
+  case CSYNC_FTW_FLAG_NSTAT: /* not statable file */
+    /* if file was here before and now is not longer stat-able, still
+     * add it to the db, otherwise not. */
+    h = _hash_of_file( ctx, file );
+    if( h == 0 ) {
+      return 0;
+    }
+    st = csync_statedb_get_stat_by_hash(ctx, h);
+    if( !st ) {
+      return 0;
+    }
+    csync_file_stat_free(st);
+    st = NULL;
+
+    type = CSYNC_FTW_TYPE_SKIP;
+    break;
+  case CSYNC_FTW_FLAG_SLINK:
+    CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "symlink: %s - not supported", file);
+    type = CSYNC_FTW_TYPE_SLINK;
+    break;
+  case CSYNC_FTW_FLAG_DNR:
+  case CSYNC_FTW_FLAG_DP:
+  case CSYNC_FTW_FLAG_SLN:
+  default:
+    return 0;
+    break;
+  }
+
+  rc = _csync_detect_update(ctx, file, fs, type );
+
+  return rc;
+}
+
+static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
+{
+    if( csync_statedb_get_below_path(ctx, uri) < 0 ) {
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "StateDB could not be read!");
+        return false;
+    }
+
+    return true;
+}
+
+/* set the current item to an ignored state.
+ * If the item is set to ignored, the update phase continues, ie. its not a hard error */
+static bool mark_current_item_ignored( CSYNC *ctx, csync_file_stat_t *previous_fs, CSYNC_STATUS status )
+{
+    if(!ctx) {
+        return false;
+    }
+
+    if (ctx->current_fs) {
+        ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE;
+        ctx->current_fs->error_status = status;
+        /* If a directory has ignored files, put the flag on the parent directory as well */
+        if( previous_fs ) {
+            previous_fs->has_ignored_files = true;
+        }
+        return true;
+    }
+    return false;
+}
+
+/* File tree walker */
+int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
+    unsigned int depth) {
+  char *filename = NULL;
+  char *d_name = NULL;
+  csync_vio_handle_t *dh = NULL;
+  csync_vio_file_stat_t *dirent = NULL;
+  csync_file_stat_t *previous_fs = NULL;
+  int read_from_db = 0;
+  int rc = 0;
+  int res = 0;
+
+  if (!depth) {
+    mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_INDIVIDUAL_TOO_DEEP);
+    goto done;
+  }
+
+  bool do_read_from_db = (ctx->current == REMOTE_REPLICA && ctx->remote.read_from_db);
+
+  read_from_db = ctx->remote.read_from_db;
+
+  // if the etag of this dir is still the same, its content is restored from the
+  // database.
+  if( do_read_from_db ) {
+      if( ! fill_tree_from_db(ctx, uri) ) {
+        errno = ENOENT;
+        ctx->status_code = CSYNC_STATUS_OPENDIR_ERROR;
+        goto error;
+      }
+      goto done;
+  }
+
+  if ((dh = csync_vio_opendir(ctx, uri)) == NULL) {
+      if (ctx->abort) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Aborted!");
+          ctx->status_code = CSYNC_STATUS_ABORTED;
+          goto error;
+      }
+      int asp = 0;
+      /* permission denied */
+      ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_OPENDIR_ERROR);
+      if (errno == EACCES) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Permission denied.");
+          if (mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_PERMISSION_DENIED)) {
+              goto done;
+          }
+      } else if(errno == ENOENT) {
+          asp = asprintf( &ctx->error_string, "%s", uri);
+          if (asp < 0) {
+              CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
+          }
+      }
+      // 403 Forbidden can be sent by the server if the file firewall is active.
+      // A file or directory should be ignored and sync must continue. See #3490
+      else if(errno == ERRNO_FORBIDDEN) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Directory access Forbidden (File Firewall?)");
+          if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_FORBIDDEN) ) {
+              goto done;
+          }
+          /* if current_fs is not defined here, better throw an error */
+      }
+      // The server usually replies with the custom "503 Storage not available"
+      // if some path is temporarily unavailable. But in some cases a standard 503
+      // is returned too. Thus we can't distinguish the two and will treat any
+      // 503 as request to ignore the folder. See #3113 #2884.
+      else if(errno == ERRNO_STORAGE_UNAVAILABLE || errno == ERRNO_SERVICE_UNAVAILABLE) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Storage was not available!");
+          if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_STORAGE_UNAVAILABLE ) ) {
+              goto done;
+          }
+          /* if current_fs is not defined here, better throw an error */
+      } else {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "opendir failed for %s - errno %d", uri, errno);
+      }
+      goto error;
+  }
+
+  while ((dirent = csync_vio_readdir(ctx, dh))) {
+    int flen;
+    int flag;
+
+    /* Conversion error */
+    if (dirent->name == NULL && dirent->original_name) {
+        ctx->status_code = CSYNC_STATUS_INVALID_CHARACTERS;
+        ctx->error_string = dirent->original_name; // take ownership
+        dirent->original_name = NULL;
+        goto error;
+    }
+
+    d_name = dirent->name;
+    if (d_name == NULL) {
+      ctx->status_code = CSYNC_STATUS_READDIR_ERROR;
+      goto error;
+    }
+
+    /* skip "." and ".." */
+    if ( (d_name[0] == '.' && d_name[1] == '\0')
+          || (d_name[0] == '.' && d_name[1] == '.' && d_name[2] == '\0')) {
+      csync_vio_file_stat_destroy(dirent);
+      dirent = NULL;
+      continue;
+    }
+
+    if (uri[0] == '\0') {
+      filename = c_strdup(d_name);
+      flen = strlen(d_name);
+    } else {
+      flen = asprintf(&filename, "%s/%s", uri, d_name);
+    }
+    if (flen < 0 || !filename) {
+      csync_vio_file_stat_destroy(dirent);
+      dirent = NULL;
+      ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
+      goto error;
+    }
+
+    /* Only for the local replica we have to stat(), for the remote one we have all data already */
+    if (ctx->replica == LOCAL_REPLICA) {
+        res = csync_vio_stat(ctx, filename, dirent);
+    } else {
+        res = 0;
+    }
+
+    /* if the filename starts with a . we consider it a hidden file
+     * For windows, the hidden state is also discovered within the vio
+     * local stat function.
+     */
+    if( d_name[0] == '.' ) {
+        if (strcmp(".sys.admin#recall#", d_name) != 0) { /* recall file shall not be ignored (#4420) */
+            dirent->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
+        }
+    }
+
+    if( res == 0) {
+      switch (dirent->type) {
+        case CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK:
+          flag = CSYNC_FTW_FLAG_SLINK;
+          break;
+        case CSYNC_VIO_FILE_TYPE_DIRECTORY:
+          flag = CSYNC_FTW_FLAG_DIR;
+          break;
+        case CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE:
+        case CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE:
+        case CSYNC_VIO_FILE_TYPE_SOCKET:
+          flag = CSYNC_FTW_FLAG_SPEC;
+          break;
+        case CSYNC_VIO_FILE_TYPE_FIFO:
+          flag = CSYNC_FTW_FLAG_SPEC;
+          break;
+        default:
+          flag = CSYNC_FTW_FLAG_FILE;
+          break;
+      };
+    } else {
+      flag = CSYNC_FTW_FLAG_NSTAT;
+    }
+
+    previous_fs = ctx->current_fs;
+
+    /* Call walker function for each file */
+    rc = fn(ctx, filename, dirent, flag);
+    /* this function may update ctx->current and ctx->read_from_db */
+
+    if (rc < 0) {
+      if (CSYNC_STATUS_IS_OK(ctx->status_code)) {
+          ctx->status_code = CSYNC_STATUS_UPDATE_ERROR;
+      }
+
+      ctx->current_fs = previous_fs;
+      goto error;
+    }
+
+    if (flag == CSYNC_FTW_FLAG_DIR && rc == 0
+        && (!ctx->current_fs || ctx->current_fs->instruction != CSYNC_INSTRUCTION_IGNORE)) {
+      rc = csync_ftw(ctx, filename, fn, depth - 1);
+      if (rc < 0) {
+        ctx->current_fs = previous_fs;
+        goto error;
+      }
+
+      if (ctx->current_fs && !ctx->current_fs->child_modified
+          && ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL) {
+          if (ctx->current == REMOTE_REPLICA) {
+              ctx->current_fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
+          } else {
+              ctx->current_fs->instruction = CSYNC_INSTRUCTION_NONE;
+          }
+      }
+
+      if (ctx->current_fs && previous_fs && ctx->current_fs->has_ignored_files) {
+          /* If a directory has ignored files, put the flag on the parent directory as well */
+          previous_fs->has_ignored_files = ctx->current_fs->has_ignored_files;
+      }
+    }
+
+    if (ctx->current_fs && previous_fs && ctx->current_fs->child_modified) {
+        /* If a directory has modified files, put the flag on the parent directory as well */
+        previous_fs->child_modified = ctx->current_fs->child_modified;
+    }
+
+    ctx->current_fs = previous_fs;
+    ctx->remote.read_from_db = read_from_db;
+    SAFE_FREE(filename);
+    csync_vio_file_stat_destroy(dirent);
+    dirent = NULL;
+  }
+
+  csync_vio_closedir(ctx, dh);
+  CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, " <= Closing walk for %s with read_from_db %d", uri, read_from_db);
+
+done:
+  csync_vio_file_stat_destroy(dirent);
+  SAFE_FREE(filename);
+  return rc;
+error:
+  ctx->remote.read_from_db = read_from_db;
+  if (dh != NULL) {
+    csync_vio_closedir(ctx, dh);
+  }
+  SAFE_FREE(filename);
+  return -1;
+}
+
+/* vim: set ts=8 sw=2 et cindent: */
diff --git a/src/csync/csync_update.h b/src/csync/csync_update.h
new file mode 100644 (file)
index 0000000..4a7495e
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CSYNC_UPDATE_H
+#define _CSYNC_UPDATE_H
+
+#include "csync.h"
+
+/**
+ * @file csync_update.h
+ *
+ * @brief Update Detection
+ *
+ * TODO
+ *
+ * @defgroup csyncUpdateDetectionInternals csync update detection internals
+ * @ingroup csyncInternalAPI
+ *
+ * @{
+ */
+
+/**
+ * Types for files
+ */
+enum csync_ftw_flags_e {
+  CSYNC_FTW_FLAG_FILE,         /* Regular file.  */
+  CSYNC_FTW_FLAG_DIR,          /* Directory.  */
+  CSYNC_FTW_FLAG_DNR,          /* Unreadable directory.  */
+  CSYNC_FTW_FLAG_NSTAT,                /* Unstatable file.  */
+  CSYNC_FTW_FLAG_SLINK,                /* Symbolic link.  */
+  CSYNC_FTW_FLAG_SPEC,         /* Special file (fifo, ...).  */
+  /* These flags are only passed from the `nftw' function.  */
+  CSYNC_FTW_FLAG_DP,           /* Directory, all subdirs have been visited. */
+  CSYNC_FTW_FLAG_SLN           /* Symbolic link naming non-existing file.  */
+};
+
+typedef int (*csync_walker_fn) (CSYNC *ctx, const char *file,
+    const csync_vio_file_stat_t *fs, enum csync_ftw_flags_e flag);
+
+/**
+ * @brief The walker function to use in the file tree walker.
+ *
+ * @param  ctx          The used csync context.
+ *
+ * @param  file         The file we are researching.
+ *
+ * @param  fs           The stat information we got.
+ *
+ * @param  flag         The flag describing the type of the file.
+ *
+ * @return 0 on success, < 0 on error.
+ */
+int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
+    enum csync_ftw_flags_e flag);
+
+/**
+ * @brief The file tree walker.
+ *
+ * This function walks through the directory tree that is located under the uri
+ * specified. It calls a walker function which is provided as a function pointer
+ * once for each entry in the tree. By default, directories are handled before
+ * the files and subdirectories they contain (pre-order traversal).
+ *
+ * @param  ctx          The csync context to use.
+ *
+ * @param  uri          The uri/path to the directory tree to walk.
+ *
+ * @param  fn           The walker function to call once for each entry.
+ *
+ * @param  depth        The max depth to walk down the tree.
+ *
+ * @return 0 on success, < 0 on error. If fn() returns non-zero, then the tree
+ *         walk is terminated and the value returned by fn() is returned as the
+ *         result.
+ */
+int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
+    unsigned int depth);
+
+#endif /* _CSYNC_UPDATE_H */
+
+/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/src/csync/csync_util.c b/src/csync/csync_util.c
new file mode 100644 (file)
index 0000000..1bc09c3
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+
+#include "c_jhash.h"
+#include "csync_util.h"
+#include "vio/csync_vio.h"
+
+#define CSYNC_LOG_CATEGORY_NAME "csync.util"
+#include "csync_log.h"
+#include "csync_statedb.h"
+
+typedef struct {
+  const char *instr_str;
+  enum csync_instructions_e instr_code;
+} _instr_code_struct;
+
+static const _instr_code_struct _instr[] =
+{
+  { "INSTRUCTION_NONE", CSYNC_INSTRUCTION_NONE },
+  { "INSTRUCTION_EVAL", CSYNC_INSTRUCTION_EVAL },
+  { "INSTRUCTION_REMOVE", CSYNC_INSTRUCTION_REMOVE },
+  { "INSTRUCTION_RENAME", CSYNC_INSTRUCTION_RENAME },
+  { "INSTRUCTION_EVAL_RENAME", CSYNC_INSTRUCTION_EVAL_RENAME },
+  { "INSTRUCTION_NEW", CSYNC_INSTRUCTION_NEW },
+  { "INSTRUCTION_CONFLICT", CSYNC_INSTRUCTION_CONFLICT },
+  { "INSTRUCTION_IGNORE", CSYNC_INSTRUCTION_IGNORE },
+  { "INSTRUCTION_SYNC", CSYNC_INSTRUCTION_SYNC },
+  { "INSTRUCTION_STAT_ERR", CSYNC_INSTRUCTION_STAT_ERROR },
+  { "INSTRUCTION_ERROR", CSYNC_INSTRUCTION_ERROR },
+  { "INSTRUCTION_TYPE_CHANGE", CSYNC_INSTRUCTION_TYPE_CHANGE },
+  { "INSTRUCTION_UPDATE_METADATA", CSYNC_INSTRUCTION_UPDATE_METADATA },
+  { NULL, CSYNC_INSTRUCTION_ERROR }
+};
+
+struct csync_memstat_s {
+  int size;
+  int resident;
+  int shared;
+  int trs;
+  int drs;
+  int lrs;
+  int dt;
+};
+
+const char *csync_instruction_str(enum csync_instructions_e instr)
+{
+  int idx = 0;
+
+  while (_instr[idx].instr_str != NULL) {
+    if (_instr[idx].instr_code == instr) {
+      return _instr[idx].instr_str;
+    }
+    idx++;
+  }
+
+  return "ERROR!";
+}
+
+
+void csync_memstat_check(void) {
+  int s = 0;
+  struct csync_memstat_s m;
+  FILE* fp;
+
+  /* get process memory stats */
+  fp = fopen("/proc/self/statm","r");
+  if (fp == NULL) {
+    return;
+  }
+  s = fscanf(fp, "%d%d%d%d%d%d%d", &m.size, &m.resident, &m.shared, &m.trs,
+      &m.drs, &m.lrs, &m.dt);
+  fclose(fp);
+  if (s == EOF) {
+    return;
+  }
+
+  CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Memory: %dK total size, %dK resident, %dK shared",
+                 m.size * 4, m.resident * 4, m.shared * 4);
+}
+
+bool (*csync_file_locked_or_open_ext) (const char*) = 0; // filled in by library user
+void set_csync_file_locked_or_open_ext(bool (*f) (const char*));
+void set_csync_file_locked_or_open_ext(bool (*f) (const char*)) {
+    csync_file_locked_or_open_ext = f;
+}
+
+bool csync_file_locked_or_open( const char *dir, const char *fname) {
+    char *tmp_uri = NULL;
+    bool ret;
+    if (!csync_file_locked_or_open_ext) {
+        return false;
+    }
+    if (asprintf(&tmp_uri, "%s/%s", dir, fname) < 0) {
+        return -1;
+    }
+    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "csync_file_locked_or_open %s", tmp_uri);
+    ret = csync_file_locked_or_open_ext(tmp_uri);
+    SAFE_FREE(tmp_uri);
+    return ret;
+}
+
+#ifndef HAVE_TIMEGM
+#ifdef _WIN32
+static int is_leap(unsigned y) {
+    y += 1900;
+    return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
+}
+
+static time_t timegm(struct tm *tm) {
+    static const unsigned ndays[2][12] = {
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };
+
+    time_t res = 0;
+    int i;
+
+    for (i = 70; i < tm->tm_year; ++i)
+        res += is_leap(i) ? 366 : 365;
+
+    for (i = 0; i < tm->tm_mon; ++i)
+        res += ndays[is_leap(tm->tm_year)][i];
+     res += tm->tm_mday - 1;
+     res *= 24;
+     res += tm->tm_hour;
+     res *= 60;
+     res += tm->tm_min;
+     res *= 60;
+     res += tm->tm_sec;
+     return res;
+}
+#else
+/* A hopefully portable version of timegm */
+static time_t timegm(struct tm *tm ) {
+     time_t ret;
+     char *tz;
+
+     tz = getenv("TZ");
+     setenv("TZ", "", 1);
+     tzset();
+     ret = mktime(tm);
+     if (tz)
+         setenv("TZ", tz, 1);
+     else
+         unsetenv("TZ");
+     tzset();
+     return ret;
+}
+#endif /* Platform switch */
+#endif /* HAVE_TIMEGM */
+
+#define RFC1123_FORMAT "%3s, %02d %3s %4d %02d:%02d:%02d GMT"
+static const char short_months[12][4] = {
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+/*
+ * This function is borrowed from libneon's ne_httpdate_parse.
+ * Unfortunately that one converts to local time but here UTC is
+ * needed.
+ * This one uses timegm instead, which returns UTC.
+ */
+time_t oc_httpdate_parse( const char *date ) {
+    struct tm gmt;
+    char wkday[4], mon[4];
+    int n;
+    time_t result = 0;
+
+    memset(&gmt, 0, sizeof(struct tm));
+
+    /*  it goes: Sun, 06 Nov 1994 08:49:37 GMT */
+    n = sscanf(date, RFC1123_FORMAT,
+               wkday, &gmt.tm_mday, mon, &gmt.tm_year, &gmt.tm_hour,
+               &gmt.tm_min, &gmt.tm_sec);
+    /* Is it portable to check n==7 here? */
+    gmt.tm_year -= 1900;
+    for (n=0; n<12; n++)
+        if (strcmp(mon, short_months[n]) == 0)
+            break;
+    /* tm_mon comes out as 12 if the month is corrupt, which is desired,
+     * since the mktime will then fail */
+    gmt.tm_mon = n;
+    gmt.tm_isdst = -1;
+    result = timegm(&gmt);
+    return result;
+}
diff --git a/src/csync/csync_util.h b/src/csync/csync_util.h
new file mode 100644 (file)
index 0000000..f65ada5
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CSYNC_UTIL_H
+#define _CSYNC_UTIL_H
+
+#include <stdint.h>
+
+#include "csync_private.h"
+
+const char OCSYNC_EXPORT *csync_instruction_str(enum csync_instructions_e instr);
+
+void OCSYNC_EXPORT csync_memstat_check(void);
+
+bool OCSYNC_EXPORT csync_file_locked_or_open( const char *dir, const char *fname);
+#endif /* _CSYNC_UTIL_H */
diff --git a/src/csync/csync_version.h.in b/src/csync/csync_version.h.in
new file mode 100644 (file)
index 0000000..9471734
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2006-2012 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _CSYNC_VERSION_H
+#define _CSYNC_VERSION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CSYNC_STRINGIFY(s) CSYNC_TOSTRING(s)
+#define CSYNC_TOSTRING(s) #s
+
+#define MIRALL_VERSION @MIRALL_VERSION@
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CSYNC_VERSION_H
diff --git a/src/csync/std/CMakeLists.txt b/src/csync/std/CMakeLists.txt
new file mode 100644 (file)
index 0000000..519cada
--- /dev/null
@@ -0,0 +1,44 @@
+project(cstdlib)
+
+set(CSTDLIB_PUBLIC_INCLUDE_DIRS
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  CACHE INTERNAL "cstdlib public include directories"
+)
+
+set(CSTDLIB_LIBRARY
+  cstdlib
+  CACHE INTERNAL "cstdlib library"
+)
+
+set(CSTDLIB_LINK_LIBRARIES
+  ${CSTDLIB_LIBRARY}
+)
+
+set(cstdlib_SRCS
+  c_alloc.c
+  c_path.c
+  c_rbtree.c
+  c_string.c
+  c_time.c
+  c_utf8.cc
+)
+
+if(NOT HAVE_ASPRINTF AND NOT HAVE___MINGW_ASPRINTF)
+    list(APPEND cstdlib_SRCS
+        asprintf.c
+    )
+endif()
+
+include_directories(
+  ${CSTDLIB_PUBLIC_INCLUDE_DIRS}
+)
+
+add_library(${CSTDLIB_LIBRARY} STATIC ${cstdlib_SRCS})
+if(NOT WIN32)
+    add_definitions( -fPIC )
+    qt5_use_modules(${CSTDLIB_LIBRARY} Core)
+endif()
+if(NOT HAVE_FNMATCH AND WIN32)
+  # needed for PathMatchSpec for our fnmatch replacement
+  target_link_libraries(${CSTDLIB_LIBRARY} ${SHLWAPI_LIBRARY})
+endif()
diff --git a/src/csync/std/asprintf.c b/src/csync/std/asprintf.c
new file mode 100644 (file)
index 0000000..8738df9
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+  https://raw.githubusercontent.com/littlstar/asprintf.c/20ce5207a4ecb24017b5a17e6cd7d006e3047146/asprintf.c
+
+  The MIT License (MIT)
+
+  Copyright (c) 2014 Little Star Media, Inc.
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in all
+  copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+*/
+
+/**
+ * `asprintf.c' - asprintf
+ *
+ * copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
+ */
+
+#ifndef HAVE_ASPRINTF
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "asprintf.h"
+
+int
+asprintf (char **str, const char *fmt, ...) {
+  int size = 0;
+  va_list args;
+
+  // init variadic argumens
+  va_start(args, fmt);
+
+  // format and get size
+  size = vasprintf(str, fmt, args);
+
+  // toss args
+  va_end(args);
+
+  return size;
+}
+
+int
+vasprintf (char **str, const char *fmt, va_list args) {
+  int size = 0;
+  va_list tmpa;
+
+  // copy
+  va_copy(tmpa, args);
+
+  // apply variadic arguments to
+  // sprintf with format to get size
+  size = vsnprintf(NULL, size, fmt, tmpa);
+
+  // toss args
+  va_end(tmpa);
+
+  // return -1 to be compliant if
+  // size is less than 0
+  if (size < 0) { return -1; }
+
+  // alloc with size plus 1 for `\0'
+  *str = (char *) malloc(size + 1);
+
+  // return -1 to be compliant
+  // if pointer is `NULL'
+  if (NULL == *str) { return -1; }
+
+  // format string with original
+  // variadic arguments and set new size
+  size = vsprintf(*str, fmt, args);
+  return size;
+}
+
+#endif
diff --git a/src/csync/std/asprintf.h b/src/csync/std/asprintf.h
new file mode 100644 (file)
index 0000000..d6dd2e8
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+  https://raw.githubusercontent.com/littlstar/asprintf.c/20ce5207a4ecb24017b5a17e6cd7d006e3047146/asprintf.h
+
+  The MIT License (MIT)
+
+  Copyright (c) 2014 Little Star Media, Inc.
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in all
+  copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+*/
+
+/**
+ * `asprintf.h' - asprintf.c
+ *
+ * copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
+ */
+
+#ifndef HAVE_ASPRINTF
+#ifndef ASPRINTF_H
+#define ASPRINTF_H 1
+
+#include <stdarg.h>
+
+/**
+ * Sets `char **' pointer to be a buffer
+ * large enough to hold the formatted string
+ * accepting a `va_list' args of variadic
+ * arguments.
+ */
+
+int
+vasprintf (char **, const char *, va_list);
+
+/**
+ * Sets `char **' pointer to be a buffer
+ * large enough to hold the formatted
+ * string accepting `n' arguments of
+ * variadic arguments.
+ */
+
+int
+asprintf (char **, const char *, ...);
+
+#endif
+#endif
diff --git a/src/csync/std/c_alloc.c b/src/csync/std/c_alloc.c
new file mode 100644 (file)
index 0000000..b87a383
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "c_macro.h"
+#include "c_alloc.h"
+
+void *c_calloc(size_t count, size_t size) {
+  if (size == 0 || count == 0) {
+    return NULL;
+  }
+
+#ifdef CSYNC_MEM_NULL_TESTS
+  if (getenv("CSYNC_NOMEMORY")) {
+    return NULL;
+  }
+#endif /* CSYNC_MEM_NULL_TESTS */
+
+#undef calloc
+  return calloc(count, size);
+#define calloc(x,y) DO_NOT_CALL_CALLOC__USE_XCALLOC_INSTEAD
+}
+
+void *c_malloc(size_t size) {
+  if (size == 0) {
+    return NULL;
+  }
+#undef malloc
+  return c_calloc(1, size);
+#define malloc(x) DO_NOT_CALL_MALLOC__USE_XMALLOC_INSTEAD
+}
+
+void *c_realloc(void *ptr, size_t size) {
+
+#ifdef CSYNC_MEM_NULL_TESTS
+  if (getenv("CSYNC_NOMEMORY")) {
+    return NULL;
+  }
+#endif /* CSYNC_MEM_NULL_TESTS */
+
+#undef realloc
+  return realloc(ptr, size);
+#define realloc(x,y) DO_NOT_CALL_REALLOC__USE_XREALLOC_INSTEAD
+}
+
+char *c_strdup(const char *str) {
+  char *ret;
+  ret = (char *) c_malloc(strlen(str) + 1);
+  if (ret == NULL) {
+    return NULL;
+  }
+  strcpy(ret, str);
+  return ret;
+}
+
+char *c_strndup(const char *str, size_t size) {
+  char *ret;
+  size_t len;
+  len = strlen(str);
+  if (len > size) {
+    len = size;
+  }
+  ret = (char *) c_malloc(len + 1);
+  if (ret == NULL) {
+    return NULL;
+  }
+  strncpy(ret, str, len);
+  ret[size] = '\0';
+  return ret;
+}
+
diff --git a/src/csync/std/c_alloc.h b/src/csync/std/c_alloc.h
new file mode 100644 (file)
index 0000000..6eeccd6
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file c_alloc.h
+ *
+ * @brief Interface of the cynapses libc alloc function
+ *
+ * @defgroup cynLibraryAPI cynapses libc API (internal)
+ *
+ * @defgroup cynAllocInternals cynapses libc alloc functions
+ * @ingroup cynLibraryAPI
+ *
+ * @{
+ */
+
+#ifndef _C_ALLOC_H
+#define _C_ALLOC_H
+
+#include <stdlib.h>
+
+#include "c_macro.h"
+
+/**
+ * @brief Allocates memory for an array.
+ *
+ * Allocates memory for an array of <count> elements of <size> bytes each and
+ * returns a pointer to the allocated memory. The memory is set to zero.
+ *
+ * @param count   Amount of elements to allocate
+ * @param size    Size in bytes of each element to allocate.
+ *
+ * @return A unique pointer value that can later be successfully passed to
+ *         free(). If size or count is 0, NULL will be returned.
+ */
+void *c_calloc(size_t count, size_t size);
+
+/**
+ * @brief Allocates memory for an array.
+ *
+ * Allocates <size> bytes of memory. The memory is set to zero.
+ *
+ * @param size    Size in bytes to allocate.
+ *
+ * @return A unique pointer value that can later be successfully passed to
+ *         free(). If size or count is 0, NULL will be returned.
+ */
+void *c_malloc(size_t size);
+
+/**
+ * @brief Changes the size of the memory block pointed to.
+ *
+ * Newly allocated memory will be uninitialized.
+ *
+ * @param ptr   Pointer to the memory which should be resized.
+ * @param size  Value to resize.
+ *
+ * @return If ptr is NULL, the call is equivalent to c_malloc(size); if size
+ *         is equal to zero, the call is equivalent to free(ptr). Unless ptr
+ *         is NULL, it must have been returned by an earlier call to
+ *         c_malloc(), c_calloc() or c_realloc(). If the area pointed to was
+ *         moved, a free(ptr) is done.
+ */
+void *c_realloc(void *ptr, size_t size);
+
+/**
+ * @brief Duplicate a string.
+ *
+ * The function returns a pointer to a newly allocated string which is a
+ * duplicate of the string str.
+ *
+ * @param str   String to duplicate.
+ *
+ * @return Returns a pointer to the duplicated string, or NULL if insufficient
+ * memory was available.
+ *
+ */
+char *c_strdup(const char *str);
+
+/**
+ * @brief Duplicate a string.
+ *
+ * The function returns a pointer to a newly allocated string which is a
+ * duplicate of the string str of size bytes.
+ *
+ * @param str   String to duplicate.
+ *
+ * @param size  Size of the string to duplicate.
+ *
+ * @return Returns a pointer to the duplicated string, or NULL if insufficient
+ * memory was available. A terminating null byte '\0' is added.
+ *
+ */
+char *c_strndup(const char *str, size_t size);
+
+/**
+ * }@
+ */
+#endif /* _C_ALLOC_H */
diff --git a/src/csync/std/c_jhash.h b/src/csync/std/c_jhash.h
new file mode 100644 (file)
index 0000000..261a0a4
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * c_jhash.c Jenkins Hash
+ *
+ * Copyright (c) 1997 Bob Jenkins <bob_jenkins@burtleburtle.net>
+ *
+ * lookup8.c, by Bob Jenkins, January 4 1997, Public Domain.
+ * hash(), hash2(), hash3, and _c_mix() are externally useful functions.
+ * Routines to test the hash are included if SELF_TEST is defined.
+ * You can use this free for any purpose.  It has no warranty.
+ *
+ * See http://burtleburtle.net/bob/hash/evahash.html
+ */
+
+/**
+ * @file c_jhash.h
+ *
+ * @brief Interface of the cynapses jhash implementation
+ *
+ * @defgroup cynJHashInternals cynapses libc jhash function
+ * @ingroup cynLibraryAPI
+ *
+ * @{
+ */
+#ifndef _C_JHASH_H
+#define _C_JHASH_H
+
+#include <stdint.h>
+
+#define c_hashsize(n) ((uint8_t) 1 << (n))
+#define c_hashmask(n) (xhashsize(n) - 1)
+
+/**
+ * _c_mix -- Mix 3 32-bit values reversibly.
+ *
+ * For every delta with one or two bit set, and the deltas of all three
+ * high bits or all three low bits, whether the original value of a,b,c
+ * is almost all zero or is uniformly distributed,
+ * If _c_mix() is run forward or backward, at least 32 bits in a,b,c
+ * have at least 1/4 probability of changing.
+ * If _c_mix() is run forward, every bit of c will change between 1/3 and
+ * 2/3 of the time.  (Well, 22/100 and 78/100 for some 2-bit deltas.)
+ * _c_mix() was built out of 36 single-cycle latency instructions in a 
+ * structure that could supported 2x parallelism, like so:
+ *     a -= b;
+ *     a -= c; x = (c>>13);
+ *     b -= c; a ^= x;
+ *     b -= a; x = (a<<8);
+ *     c -= a; b ^= x;
+ *     c -= b; x = (b>>13);
+ *     ...
+ *
+ * Unfortunately, superscalar Pentiums and Sparcs can't take advantage
+ * of that parallelism.  They've also turned some of those single-cycle
+ * latency instructions into multi-cycle latency instructions.  Still,
+ * this is the fastest good hash I could find.  There were about 2^^68
+ * to choose from.  I only looked at a billion or so.
+ */
+#define _c_mix(a,b,c) \
+{ \
+  a -= b; a -= c; a ^= (c>>13); \
+  b -= c; b -= a; b ^= (a<<8); \
+  c -= a; c -= b; c ^= (b>>13); \
+  a -= b; a -= c; a ^= (c>>12);  \
+  b -= c; b -= a; b ^= (a<<16); \
+  c -= a; c -= b; c ^= (b>>5); \
+  a -= b; a -= c; a ^= (c>>3);  \
+  b -= c; b -= a; b ^= (a<<10); \
+  c -= a; c -= b; c ^= (b>>15); \
+}
+
+/**
+ * _c_mix64 -- Mix 3 64-bit values reversibly.
+ *
+ * _c_mix64() takes 48 machine instructions, but only 24 cycles on a superscalar
+ * machine (like Intel's new MMX architecture).  It requires 4 64-bit
+ * registers for 4::2 parallelism.
+ * All 1-bit deltas, all 2-bit deltas, all deltas composed of top bits of
+ * (a,b,c), and all deltas of bottom bits were tested.  All deltas were
+ * tested both on random keys and on keys that were nearly all zero.
+ * These deltas all cause every bit of c to change between 1/3 and 2/3
+ * of the time (well, only 113/400 to 287/400 of the time for some
+ * 2-bit delta).  These deltas all cause at least 80 bits to change
+ * among (a,b,c) when the _c_mix is run either forward or backward (yes it
+ * is reversible).
+ * This implies that a hash using _c_mix64 has no funnels.  There may be
+ * characteristics with 3-bit deltas or bigger, I didn't test for
+ * those.
+ */
+#define _c_mix64(a,b,c) \
+{ \
+  a -= b; a -= c; a ^= (c>>43); \
+  b -= c; b -= a; b ^= (a<<9); \
+  c -= a; c -= b; c ^= (b>>8); \
+  a -= b; a -= c; a ^= (c>>38); \
+  b -= c; b -= a; b ^= (a<<23); \
+  c -= a; c -= b; c ^= (b>>5); \
+  a -= b; a -= c; a ^= (c>>35); \
+  b -= c; b -= a; b ^= (a<<49); \
+  c -= a; c -= b; c ^= (b>>11); \
+  a -= b; a -= c; a ^= (c>>12); \
+  b -= c; b -= a; b ^= (a<<18); \
+  c -= a; c -= b; c ^= (b>>22); \
+}
+
+/**
+ * @brief hash a variable-length key into a 32-bit value
+ *
+ * The best hash table sizes are powers of 2.  There is no need to do
+ * mod a prime (mod is sooo slow!).  If you need less than 32 bits,
+ * use a bitmask.  For example, if you need only 10 bits, do
+ *   h = (h & hashmask(10));
+ * In which case, the hash table should have hashsize(10) elements.
+ *
+ * Use for hash table lookup, or anything where one collision in 2^32 is
+ * acceptable.  Do NOT use for cryptographic purposes.
+ *
+ * @param k        The key (the unaligned variable-length array of bytes).
+ *
+ * @param length   The length of the key, counting by bytes.
+ *
+ * @param initval  Initial value, can be any 4-byte value.
+ *
+ * @return    Returns a 32-bit value.  Every bit of the key affects every bit
+ *            of the return value.  Every 1-bit and 2-bit delta achieves
+ *            avalanche. About 36+6len instructions.
+ */
+static inline uint32_t c_jhash(const uint8_t *k, uint32_t length, uint32_t initval) {
+   uint32_t a,b,c,len;
+
+   /* Set up the internal state */
+   len = length;
+   a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
+   c = initval; /* the previous hash value */
+
+   while (len >= 12) {
+      a += (k[0] +((uint32_t)k[1]<<8) +((uint32_t)k[2]<<16) +((uint32_t)k[3]<<24));
+      b += (k[4] +((uint32_t)k[5]<<8) +((uint32_t)k[6]<<16) +((uint32_t)k[7]<<24));
+      c += (k[8] +((uint32_t)k[9]<<8) +((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24));
+      _c_mix(a,b,c);
+      k += 12; len -= 12;
+   }
+
+   /* handle the last 11 bytes */
+   c += length;
+   /* all the case statements fall through */
+   switch(len) {
+     case 11: c+=((uint32_t)k[10]<<24);
+     case 10: c+=((uint32_t)k[9]<<16);
+     case 9 : c+=((uint32_t)k[8]<<8);
+     /* the first byte of c is reserved for the length */
+     case 8 : b+=((uint32_t)k[7]<<24);
+     case 7 : b+=((uint32_t)k[6]<<16);
+     case 6 : b+=((uint32_t)k[5]<<8);
+     case 5 : b+=k[4];
+     case 4 : a+=((uint32_t)k[3]<<24);
+     case 3 : a+=((uint32_t)k[2]<<16);
+     case 2 : a+=((uint32_t)k[1]<<8);
+     case 1 : a+=k[0];
+     /* case 0: nothing left to add */
+   }
+   _c_mix(a,b,c);
+
+   return c;
+}
+
+/**
+ * @brief hash a variable-length key into a 64-bit value
+ *
+ * The best hash table sizes are powers of 2.  There is no need to do
+ * mod a prime (mod is sooo slow!).  If you need less than 64 bits,
+ * use a bitmask.  For example, if you need only 10 bits, do
+ *   h = (h & hashmask(10));
+ * In which case, the hash table should have hashsize(10) elements.
+ *
+ * Use for hash table lookup, or anything where one collision in 2^^64
+ * is acceptable.  Do NOT use for cryptographic purposes.
+ *
+ * @param k       The key (the unaligned variable-length array of bytes).
+ * @param length  The length of the key, counting by bytes.
+ * @param intval  Initial value, can be any 8-byte value.
+ *
+ * @return    A 64-bit value. Every bit of the key affects every bit of
+ *            the return value.  No funnels.  Every 1-bit and 2-bit delta
+ *            achieves avalanche. About 41+5len instructions.
+ */
+static inline uint64_t c_jhash64(const uint8_t *k, uint64_t length, uint64_t intval) {
+  uint64_t a,b,c,len;
+
+  /* Set up the internal state */
+  len = length;
+  a = b = intval; /* the previous hash value */
+  c = 0x9e3779b97f4a7c13LL; /* the golden ratio; an arbitrary value */
+
+  /* handle most of the key */
+  while (len >= 24)
+  {
+    a += (k[0]        +((uint64_t)k[ 1]<< 8)+((uint64_t)k[ 2]<<16)+((uint64_t)k[ 3]<<24)
+     +((uint64_t)k[4 ]<<32)+((uint64_t)k[ 5]<<40)+((uint64_t)k[ 6]<<48)+((uint64_t)k[ 7]<<56));
+    b += (k[8]        +((uint64_t)k[ 9]<< 8)+((uint64_t)k[10]<<16)+((uint64_t)k[11]<<24)
+     +((uint64_t)k[12]<<32)+((uint64_t)k[13]<<40)+((uint64_t)k[14]<<48)+((uint64_t)k[15]<<56));
+    c += (k[16]       +((uint64_t)k[17]<< 8)+((uint64_t)k[18]<<16)+((uint64_t)k[19]<<24)
+     +((uint64_t)k[20]<<32)+((uint64_t)k[21]<<40)+((uint64_t)k[22]<<48)+((uint64_t)k[23]<<56));
+    _c_mix64(a,b,c);
+    k += 24; len -= 24;
+  }
+
+  /* handle the last 23 bytes */
+  c += length;
+  switch(len) {
+    case 23: c+=((uint64_t)k[22]<<56);
+    case 22: c+=((uint64_t)k[21]<<48);
+    case 21: c+=((uint64_t)k[20]<<40);
+    case 20: c+=((uint64_t)k[19]<<32);
+    case 19: c+=((uint64_t)k[18]<<24);
+    case 18: c+=((uint64_t)k[17]<<16);
+    case 17: c+=((uint64_t)k[16]<<8);
+    /* the first byte of c is reserved for the length */
+    case 16: b+=((uint64_t)k[15]<<56);
+    case 15: b+=((uint64_t)k[14]<<48);
+    case 14: b+=((uint64_t)k[13]<<40);
+    case 13: b+=((uint64_t)k[12]<<32);
+    case 12: b+=((uint64_t)k[11]<<24);
+    case 11: b+=((uint64_t)k[10]<<16);
+    case 10: b+=((uint64_t)k[ 9]<<8);
+    case  9: b+=((uint64_t)k[ 8]);
+    case  8: a+=((uint64_t)k[ 7]<<56);
+    case  7: a+=((uint64_t)k[ 6]<<48);
+    case  6: a+=((uint64_t)k[ 5]<<40);
+    case  5: a+=((uint64_t)k[ 4]<<32);
+    case  4: a+=((uint64_t)k[ 3]<<24);
+    case  3: a+=((uint64_t)k[ 2]<<16);
+    case  2: a+=((uint64_t)k[ 1]<<8);
+    case  1: a+=((uint64_t)k[ 0]);
+    /* case 0: nothing left to add */
+  }
+  _c_mix64(a,b,c);
+
+  return c;
+}
+
+/**
+ * }@
+ */
+#endif /* _C_JHASH_H */
+
diff --git a/src/csync/std/c_lib.h b/src/csync/std/c_lib.h
new file mode 100644 (file)
index 0000000..b9c1ea8
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "c_macro.h"
+#include "c_alloc.h"
+#include "c_path.h"
+#include "c_rbtree.h"
+#include "c_string.h"
+#include "c_time.h"
+#include "c_private.h"
diff --git a/src/csync/std/c_macro.h b/src/csync/std/c_macro.h
new file mode 100644 (file)
index 0000000..a4a0e1c
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file c_macro.h
+ *
+ * @brief cynapses libc macro definitions
+ *
+ * @defgroup cynMacroInternals cynapses libc macro definitions
+ * @ingroup cynLibraryAPI
+ *
+ * @{
+ */
+#ifndef _C_MACRO_H
+#define _C_MACRO_H
+
+#include <stdint.h>
+#include <string.h>
+
+#define INT_TO_POINTER(i) (void *) i
+#define POINTER_TO_INT(p) *((int *) (p))
+
+/** Zero a structure */
+#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
+
+/** Zero a structure given a pointer to the structure */
+#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
+
+/** Free memory and zero the pointer */
+#define SAFE_FREE(x) do { if ((x) != NULL) {free((void*)x); x=NULL;} } while(0)
+
+/** Get the smaller value */
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+/** Get the bigger value */
+#define MAX(a,b) ((a) < (b) ? (b) : (a))
+
+/** Get the size of an array */
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+/**
+ * This is a hack to fix warnings. The idea is to use this everywhere that we
+ * get the "discarding const" warning by the compiler. That doesn't actually
+ * fix the real issue, but marks the place and you can search the code for
+ * discard_const.
+ *
+ * Please use this macro only when there is no other way to fix the warning.
+ * We should use this function in only in a very few places.
+ *
+ * Also, please call this via the discard_const_p() macro interface, as that
+ * makes the return type safe.
+ */
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
+
+/**
+ * Type-safe version of discard_const
+ */
+#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
+
+#if (__GNUC__ >= 3)
+# ifndef likely
+#  define likely(x)   __builtin_expect(!!(x), 1)
+# endif
+# ifndef unlikely
+#  define unlikely(x) __builtin_expect(!!(x), 0)
+# endif
+#else /* __GNUC__ */
+# ifndef likely
+#  define likely(x) (x)
+# endif
+# ifndef unlikely
+#  define unlikely(x) (x)
+# endif
+#endif /* __GNUC__ */
+
+/**
+ * }@
+ */
+
+#ifdef _WIN32
+/* missing errno codes on mingw */
+#ifndef ENOTBLK
+#define        ENOTBLK                15
+#endif
+#ifndef ETXTBSY
+#define        ETXTBSY                26
+#endif
+#ifndef ENOBUFS
+#define        ENOBUFS                WSAENOBUFS
+#endif
+#endif /* _WIN32 */
+
+#endif /* _C_MACRO_H */
+
diff --git a/src/csync/std/c_path.c b/src/csync/std/c_path.c
new file mode 100644 (file)
index 0000000..1094a1c
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "c_private.h"
+#include "c_alloc.h"
+#include "c_path.h"
+#include "c_string.h"
+
+/*
+ * dirname - parse directory component.
+ */
+char *c_dirname (const char *path) {
+  char *newbuf = NULL;
+  unsigned int len;
+
+  if (path == NULL || *path == '\0') {
+    return c_strdup(".");
+  }
+
+  len = strlen(path);
+
+  /* Remove trailing slashes */
+  while(len > 0 && path[len - 1] == '/') --len;
+
+  /* We have only slashes */
+  if (len == 0) {
+    return c_strdup("/");
+  }
+
+  /* goto next slash */
+  while(len > 0 && path[len - 1] != '/') --len;
+
+  if (len == 0) {
+    return c_strdup(".");
+  } else if (len == 1) {
+    return c_strdup("/");
+  }
+
+  /* Remove slashes again */
+  while(len > 0 && path[len - 1] == '/') --len;
+
+  newbuf = c_malloc(len + 1);
+
+  strncpy(newbuf, path, len);
+  newbuf[len] = '\0';
+
+  return newbuf;
+}
+
+char *c_basename (const char *path) {
+  char *newbuf = NULL;
+  const char *s;
+  unsigned int len;
+
+  if (path == NULL || *path == '\0') {
+    return c_strdup(".");
+  }
+
+  len = strlen(path);
+  /* Remove trailing slashes */
+  while(len > 0 && path[len - 1] == '/') --len;
+
+  /* We have only slashes */
+  if (len == 0) {
+    return c_strdup("/");
+  }
+
+  while(len > 0 && path[len - 1] != '/') --len;
+
+  if (len > 0) {
+    s = path + len;
+    len = strlen(s);
+
+    while(len > 0 && s[len - 1] == '/') --len;
+  } else {
+    return c_strdup(path);
+  }
+
+  newbuf = c_malloc(len + 1);
+
+  strncpy(newbuf, s, len);
+  newbuf[len] = '\0';
+
+  return newbuf;
+}
+
+int c_parse_uri(const char *uri,
+    char **scheme,
+    char **user, char **passwd,
+    char **host, unsigned int *port,
+    char **path) {
+  const char *p, *z;
+
+  if (uri == NULL || *uri == '\0') {
+    return -1;
+  }
+
+  /*
+   * uri = scheme://user:password@host:port/path
+   * p   = ^
+   * z   = ^
+   */
+  p = z = uri;
+
+  /* check for valid scheme; git+ssh, pop3 */
+  while (isalpha((int) *p) || isdigit((int) *p) ||
+      *p == '+' || *p == '-') {
+    /*
+     * uri = scheme://user:password@host:port/path
+     * p   =       ^
+     * z   = ^
+     */
+    p++;
+  }
+
+  /* get scheme */
+  if (*p == ':') {
+    if (scheme != NULL) {
+      *scheme = c_strndup(z, p - z);
+
+      if (*scheme == NULL) {
+        errno = ENOMEM;
+        return -1;
+      }
+    }
+    p++;
+    z = p;
+  }
+
+  /*
+   * uri = scheme://user:password@host:port/path
+   * p =          ^
+   * z =          ^
+   */
+  p = z;
+
+  /* do we have a hostname */
+  if (p[0] == '/' && p[1] == '/') {
+    /*
+     * uri = scheme://user:password@host:port/path
+     * p   =          ^
+     * z   =          ^
+     */
+    z += 2;
+    p = z;
+
+    /* check for user and passwd */
+    while (*p && *p != '@' && *p != '/') {
+      /*
+       * uri = scheme://user:password@host:port/path
+       * p   =                       ^    or   ^
+       * z   =          ^
+       */
+      p++;
+    }
+
+    /* check for user and password */
+    if (*p == '@') {
+      const char *q;
+
+      q = p;
+
+      /* check if we have a password */
+      while (q > z && *q != ':') {
+        /*
+         * uri = scheme://user:password@host:port/path
+         * p   =                       ^
+         * z   =          ^
+         * q   =              ^
+         */
+        q--;
+      }
+
+      /* password found */
+      if (*q == ':') {
+        if (user != NULL) {
+          *user = c_strndup(z, q - z);
+          if (*user == NULL) {
+            errno = ENOMEM;
+            if (scheme != NULL) SAFE_FREE(*scheme);
+            return -1;
+          }
+        }
+
+        if (passwd != NULL) {
+          *passwd = c_strndup(q + 1, p - (q + 1));
+          if (*passwd == NULL) {
+            if (scheme != NULL) SAFE_FREE(*scheme);
+            if (user   != NULL) SAFE_FREE(*user);
+            errno = ENOMEM;
+            return -1;
+          }
+        }
+      } else {
+        /* user only */
+        if (user != NULL) {
+          *user = c_strndup(z, p - z);
+          if( *user == NULL) {
+            if (scheme != NULL) SAFE_FREE(*scheme);
+            errno = ENOMEM;
+            return -1;
+          }
+        }
+      }
+
+      p++;
+      z = p;
+    }
+
+    /*
+     * uri = scheme://user:password@host:port/path
+     * p =                          ^
+     * z =                          ^
+     */
+    p = z;
+
+    /* check for IPv6 address */
+    if (*p == '[') {
+      /*
+       * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
+       * p   =                         ^
+       * z   =                        ^
+       */
+      p++;
+
+      /* check if we have a valid IPv6 address */
+      while (*p && (isxdigit((int) *p) || *p == '.' || *p == ':')) {
+        /*
+         * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
+         * p   =                                                                ^
+         * z   =                        ^
+         */
+        p++;
+      }
+
+      /* valid IPv6 address found */
+      if (*p == ']') {
+        /*
+         * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
+         * p   =                                                                ^
+         * z   =                         ^
+         */
+        z++;
+
+        if (host != NULL) {
+          *host = c_strndup(z, p - z);
+          if (*host == NULL) {
+            if (scheme != NULL) SAFE_FREE(*scheme);
+            if (user   != NULL) SAFE_FREE(*user);
+            if (passwd != NULL) SAFE_FREE(*passwd);
+            errno = ENOMEM;
+            return -1;
+          }
+        }
+
+        /*
+         * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
+         * p   =                                                                 ^
+         * z   =                         ^
+         */
+        p++;
+      } else {
+        /* invalid IPv6 address, assume a hostname */
+        p = z;
+
+        while (*p && *p != ':' && *p != '/') {
+          p++;
+          /*
+           * uri = scheme://user:password@host:port/path
+           * p   =                            ^ or ^
+           * z   =                        ^
+           */
+        }
+
+        if (host != NULL) {
+          *host = c_strndup(z, p - z);
+          if (*host == NULL) {
+            if (scheme != NULL) SAFE_FREE(*scheme);
+            if (user   != NULL) SAFE_FREE(*user);
+            if (passwd != NULL) SAFE_FREE(*passwd);
+            errno = ENOMEM;
+            return -1;
+          }
+        }
+      }
+    } else {
+      /* check for hostname */
+      while (*p && *p != ':' && *p != '/') {
+        /*
+         * uri = scheme://user:password@host:port/path
+         * p   =                            ^    ^
+         * z   =                        ^
+         */
+        p++;
+      }
+
+      if (host != NULL) {
+        *host = c_strndup(z, p - z);
+        if (*host == NULL) {
+          if (scheme != NULL) SAFE_FREE(*scheme);
+          if (user   != NULL) SAFE_FREE(*user);
+          if (passwd != NULL) SAFE_FREE(*passwd);
+          errno = ENOMEM;
+          return -1;
+        }
+      }
+    }
+
+    /* check for port */
+    if (*p == ':') {
+      char **e = NULL;
+      /*
+       * uri = scheme://user:password@host:port/path
+       * p =                               ^
+       * z =                               ^
+       */
+      z = ++p;
+
+      /* get only the digits */
+      while (isdigit((int) *p)) {
+        /*
+         * uri = scheme://user:password@host:port/path
+         * p   =                                 ^
+         * z   =                             ^
+         */
+        e = (char **) &p;
+        p++;
+      }
+
+      if (port != NULL) {
+        *port = strtoul(z, e, 0);
+      }
+
+      /*
+       * uri   = scheme://user:password@host:port/path
+       * p =                                     ^
+       */
+    }
+  }
+
+  if (*p == '\0') {
+    return 0;
+  }
+
+  /* get the path with the leading slash */
+  if (*p == '/') {
+    if (path != NULL) {
+      *path = c_strdup(p);
+      if (*path == NULL) {
+        if (scheme != NULL) SAFE_FREE(*scheme);
+        if (user   != NULL) SAFE_FREE(*user);
+        if (passwd != NULL) SAFE_FREE(*passwd);
+        if (host   != NULL) SAFE_FREE(*host);
+        errno = ENOMEM;
+        return -1;
+      }
+    }
+
+    return 0;
+  }
+
+  return -1;
+}
+
+
+/*
+ * This function takes a path and converts it to a UNC representation of the
+ * string. That means that it prepends a \\?\ (unless already UNC) and converts
+ * all slashes to backslashes.
+ *
+ * Note the following:
+ *  - The string must be absolute.
+ *  - it needs to contain a drive character to be a valid UNC
+ *  - A conversion is only done if the path len is larger than 245. Otherwise
+ *    the windows API functions work with the normal "unixoid" representation too.
+ *
+ *  This function allocates memory that must be freed by the caller.
+ */
+ const char *c_path_to_UNC(const char *str)
+ {
+     int len = 0;
+     char *longStr = NULL;
+
+     len = strlen(str);
+     longStr = c_malloc(len+5);
+     *longStr = '\0';
+
+     // prepend \\?\ and convert '/' => '\' to support long names
+     if( str[0] == '/' || str[0] == '\\' ) {
+         // Don't prepend if already UNC
+         if( !(len > 1 && (str[1] == '/' || str[1] == '\\')) ) {
+            strcpy( longStr, "\\\\?");
+         }
+     } else {
+         strcpy( longStr, "\\\\?\\"); // prepend string by this four magic chars.
+     }
+     strncat( longStr, str, len );
+
+     /* replace all occurences of / with the windows native \ */
+     char *c = longStr;
+     for (; *c; ++c) {
+         if(*c == '/') {
+             *c = '\\';
+         }
+     }
+     return longStr;
+ }
+
+ mbchar_t* c_utf8_path_to_locale(const char *str)
+ {
+     if( str == NULL ) {
+         return NULL;
+     } else {
+ #ifdef _WIN32
+         const char *unc_str = c_path_to_UNC(str);
+         mbchar_t *dst = c_utf8_string_to_locale(unc_str);
+         SAFE_FREE(unc_str);
+         return dst;
+ #else
+         return c_utf8_string_to_locale(str);
+ #endif
+     }
+ }
diff --git a/src/csync/std/c_path.h b/src/csync/std/c_path.h
new file mode 100644 (file)
index 0000000..291b1b8
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file c_path.h
+ *
+ * @brief Interface of the cynapses libc path functions
+ *
+ * @defgroup cynPathInternals cynapses libc path functions
+ * @ingroup cynLibraryAPI
+ *
+ * @{
+ */
+
+#ifndef _C_PATH_H
+#define _C_PATH_H
+
+#include "c_macro.h"
+#include "c_private.h"
+
+/**
+ * @brief Parse directory component.
+ *
+ * dirname breaks a null-terminated pathname string into a directory component.
+ * In the usual case, c_dirname() returns the string up to, but not including,
+ * the final '/'. Trailing '/' characters are  not  counted as part of the
+ * pathname. The caller must free the memory.
+ *
+ * @param path  The path to parse.
+ *
+ * @return  The dirname of path or NULL if we can't allocate memory. If path
+ *          does not contain a slash, c_dirname() returns the string ".".  If
+ *          path is the string "/", it returns the string "/". If path is
+ *          NULL or an empty string, "." is returned.
+ */
+char *c_dirname(const char *path);
+
+/**
+ * @brief basename - parse filename component.
+ *
+ * basename breaks a null-terminated pathname string into a filename component.
+ * c_basename() returns the component following the final '/'.  Trailing '/'
+ * characters are not counted as part of the pathname.
+ *
+ * @param path The path to parse.
+ *
+ * @return  The filename of path or NULL if we can't allocate memory. If path
+ *          is a the string "/", basename returns the string "/". If path is
+ *          NULL or an empty string, "." is returned.
+ */
+char *c_basename (const char *path);
+
+/**
+ * @brief parse a uri and split it into components.
+ *
+ * parse_uri parses an uri in the format
+ *
+ * [<scheme>:][//[<user>[:<password>]@]<host>[:<port>]]/[<path>]
+ *
+ * into its compoments. If you only want a special component,
+ * pass NULL for all other components. All components will be allocated if they have
+ * been found.
+ *
+ * @param uri       The uri to parse.
+ * @param scheme    String for the scheme component
+ * @param user      String for the username component
+ * @param passwd    String for the password component
+ * @param host      String for the password component
+ * @param port      Integer for the port
+ * @param path      String for the path component with a leading slash.
+ *
+ * @return  0 on success, < 0 on error.
+ */
+int c_parse_uri(const char *uri, char **scheme, char **user, char **passwd,
+    char **host, unsigned int *port, char **path);
+
+/**
+ * @brief Parts of a path.
+ *
+ * @param directory '\0' terminated path including the final '/'
+ *
+ * @param filename '\0' terminated string
+ *
+ * @param extension '\0' terminated string
+ *
+ */
+typedef struct
+{
+    char * directory;
+    char * filename;
+    char * extension;
+} C_PATHINFO;
+
+/**
+ * @brief c_path_to_UNC converts a unixoid path to UNC format.
+ *
+ * It converts the '/' to '\' and prepends \\?\ to the path.
+ *
+ * A proper windows path has to have a drive letter, otherwise it is not
+ * valid UNC.
+ *
+ * @param str The path to convert
+ *
+ * @return a pointer to the converted string. Caller has to free it.
+ */
+const char *c_path_to_UNC(const char *str);
+
+/**
+ * @brief c_utf8_path_to_locale converts a unixoid path to the locale aware format
+ *
+ * On windows, it converts to UNC and multibyte.
+ * On Mac, it converts to the correct utf8 using iconv.
+ * On Linux, it returns utf8
+ *
+ * @param str The path to convert
+ *
+ * @return a pointer to the converted string. Caller has to free it using the
+ *         function c_free_locale_string.
+ */
+mbchar_t* c_utf8_path_to_locale(const char *str);
+
+/**
+ * }@
+ */
+#endif /* _C_PATH_H */
diff --git a/src/csync/std/c_private.h b/src/csync/std/c_private.h
new file mode 100644 (file)
index 0000000..26bba70
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Dominik Schmidt <dev@dominik-schmidt.de>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _C_PRIVATE_H
+#define _C_PRIVATE_H
+
+#include "config_csync.h"
+
+/* cross platform defines */
+#include "config_csync.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <windef.h>
+#include <winbase.h>
+#include <wchar.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+
+#ifdef __MINGW32__
+#define EDQUOT 0
+#define ENODATA 0
+#ifndef S_IRGRP
+#define S_IRGRP 0
+#endif
+#ifndef S_IROTH
+#define S_IROTH 0
+#endif
+#ifndef S_IXGRP
+#define S_IXGRP 0
+#endif
+#ifndef S_IXOTH
+#define S_IXOTH 0
+#endif
+
+#define S_IFSOCK 10000 /* dummy val on Win32 */
+#define S_IFLNK 10001  /* dummy val on Win32 */
+
+#define O_NOFOLLOW 0
+#define O_NOCTTY 0
+
+#define uid_t int
+#define gid_t int
+#define nlink_t int
+#define getuid() 0
+#define geteuid() 0
+#elif defined(_WIN32)
+#define mode_t int
+#else
+#include <fcntl.h>
+#endif
+
+#ifndef ENODATA
+#define ENODATA EPIPE
+#endif
+
+
+#ifdef _WIN32
+typedef struct stat64 csync_stat_t;
+#define _FILE_OFFSET_BITS 64
+#else
+typedef struct stat csync_stat_t;
+#endif
+
+#ifndef O_NOATIME
+#define O_NOATIME 0
+#endif
+
+#ifndef ENODATA
+#define ENODATA EBADF
+#endif
+
+#if !defined(HAVE_ASPRINTF)
+#if defined(HAVE___MINGW_ASPRINTF)
+#define asprintf __mingw_asprintf
+#else
+#include "asprintf.h"
+#endif
+#endif
+
+#ifndef HAVE_STRERROR_R
+#define strerror_r(errnum, buf, buflen) snprintf(buf, buflen, "%s", strerror(errnum))
+#endif
+
+#ifndef HAVE_LSTAT
+#define lstat _stat
+#endif
+
+/* tchar definitions for clean win32 filenames */
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+
+#if defined _WIN32 && defined _UNICODE
+typedef  wchar_t         mbchar_t;
+#define _topen           _wopen
+#define _tdirent         _wdirent
+#define _topendir        _wopendir
+#define _tclosedir       _wclosedir
+#define _treaddir        _wreaddir
+#define _trewinddir      _wrewinddir
+#define _ttelldir        _wtelldir
+#define _tseekdir        _wseekdir
+#define _tcreat          _wcreat
+#define _tstat           _wstat64
+#define _tfstat          _fstat64
+#define _tunlink         _wunlink
+#define _tmkdir(X,Y)     _wmkdir(X)
+#define _trmdir                 _wrmdir
+#define _tchmod          _wchmod
+#define _trewinddir      _wrewinddir
+#define _tchown(X, Y, Z)  0 /* no chown on Win32 */
+#define _tchdir          _wchdir
+#define _tgetcwd         _wgetcwd
+#else
+typedef char           mbchar_t;
+#define _tdirent       dirent
+#define _topen         open
+#define _topendir      opendir
+#define _tclosedir     closedir
+#define _treaddir      readdir
+#define _trewinddir    rewinddir
+#define _ttelldir      telldir
+#define _tseekdir      seekdir
+#define _tcreat        creat
+#define _tstat         lstat
+#define _tfstat        fstat
+#define _tunlink       unlink
+#define _tmkdir(X,Y)   mkdir(X,Y)
+#define _trmdir               rmdir
+#define _tchmod        chmod
+#define _trewinddir    rewinddir
+#define _tchown(X,Y,Z) chown(X,Y,Z)
+#define _tchdir        chdir
+#define _tgetcwd       getcwd
+#endif
+
+/* FIXME: Implement TLS for OS X */
+#if defined(__GNUC__) && !defined(__APPLE__)
+# define CSYNC_THREAD __thread
+#elif defined(_MSC_VER)
+# define CSYNC_THREAD __declspec(thread)
+#else
+# define CSYNC_THREAD
+#endif
+
+#endif //_C_PRIVATE_H
+
+/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
diff --git a/src/csync/std/c_rbtree.c b/src/csync/std/c_rbtree.c
new file mode 100644 (file)
index 0000000..9a38fd0
--- /dev/null
@@ -0,0 +1,743 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2003-2004 by Andrew Suffield <asuffield@debian.org>
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * This code was originally released under GPL but Andrew Suffield agreed to
+ * change it to LGPL.
+ */
+
+/*
+ * static function don't have NULL pointer checks, segfaults are intended.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "c_alloc.h"
+#include "c_rbtree.h"
+
+#define NIL &_sentinel /* all leafs are sentinels */
+static c_rbnode_t _sentinel = {NULL, NIL, NIL, NULL, NULL, BLACK};
+
+void c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_rbtree_compare_func *data_compare) {
+  assert(rbtree);
+  assert(key_compare);
+  assert(data_compare);
+
+  c_rbtree_t *tree = NULL;
+
+  tree = c_malloc(sizeof(*tree));
+  tree->root = NIL;
+  tree->key_compare = key_compare;
+  tree->data_compare = data_compare;
+  tree->size = 0;
+
+  *rbtree = tree;
+}
+
+static c_rbnode_t *_rbtree_subtree_dup(const c_rbnode_t *node, c_rbtree_t *new_tree, c_rbnode_t *new_parent) {
+  c_rbnode_t *new_node = NULL;
+
+  new_node = (c_rbnode_t*) c_malloc(sizeof(c_rbnode_t));
+
+  new_node->tree = new_tree;
+  new_node->data = node->data;
+  new_node->color = node->color;
+  new_node->parent = new_parent;
+
+  if (node->left == NIL) {
+    new_node->left = NIL;
+  } else {
+    new_node->left = _rbtree_subtree_dup(node->left, new_tree, new_node);
+  }
+
+  if (node->right == NIL) {
+    new_node->right = NIL;
+  } else {
+    new_node->right = _rbtree_subtree_dup(node->right, new_tree, new_node);
+  }
+
+  return new_node;
+}
+
+c_rbtree_t *c_rbtree_dup(const c_rbtree_t *tree) {
+  c_rbtree_t *new_tree = NULL;
+
+  new_tree = (c_rbtree_t*) c_malloc(sizeof(c_rbtree_t));
+
+  new_tree->key_compare = tree->key_compare;
+  new_tree->data_compare = tree->data_compare;
+  new_tree->size = tree->size;
+  new_tree->root = _rbtree_subtree_dup(tree->root, new_tree, NULL);
+
+  return new_tree;
+}
+
+static int _rbtree_subtree_free(c_rbnode_t *node) {
+  assert(node);
+
+  if (node->left != NIL) {
+    if (_rbtree_subtree_free(node->left) < 0) {
+      /* TODO: set errno? ECANCELED? */
+      return -1;
+    }
+  }
+
+  if (node->right != NIL) {
+    if (_rbtree_subtree_free(node->right) < 0) {
+      /* TODO: set errno? ECANCELED? */
+      return -1;
+    }
+  }
+
+  SAFE_FREE(node);
+
+  return 0;
+}
+
+int c_rbtree_free(c_rbtree_t *tree) {
+  if (tree == NULL) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  if (tree->root != NIL) {
+    _rbtree_subtree_free(tree->root);
+  }
+
+  SAFE_FREE(tree);
+
+  return 0;
+}
+
+static int _rbtree_subtree_walk(c_rbnode_t *node, void *data, c_rbtree_visit_func *visitor) {
+  assert(node);
+  assert(data);
+  assert(visitor);
+
+  if (node == NIL) {
+    return 0;
+  }
+
+  if (_rbtree_subtree_walk(node->left, data, visitor) < 0) {
+    return -1;
+  }
+
+  if ((*visitor)(node->data, data) < 0) {
+    return -1;
+  }
+
+  if (_rbtree_subtree_walk(node->right, data, visitor) < 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int c_rbtree_walk(c_rbtree_t *tree, void *data, c_rbtree_visit_func *visitor) {
+  if (tree == NULL || data == NULL || visitor == NULL) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  if (_rbtree_subtree_walk(tree->root, data, visitor) < 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+static c_rbnode_t *_rbtree_subtree_head(c_rbnode_t *node) {
+  assert(node);
+
+  if (node == NIL) {
+    return node;
+  }
+
+  while (node->left != NIL) {
+    node = node->left;
+  }
+
+  return node;
+}
+
+static c_rbnode_t *_rbtree_subtree_tail(c_rbnode_t *node) {
+  assert(node);
+
+  if (node == NIL) {
+    return node;
+  }
+
+  while (node->right != NIL) {
+    node = node->right;
+  }
+
+  return node;
+}
+
+c_rbnode_t *c_rbtree_head(c_rbtree_t *tree) {
+  c_rbnode_t *node = NULL;
+
+  if (tree == NULL) {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  node = _rbtree_subtree_head(tree->root);
+
+  return node != NIL ? node : NULL;
+}
+
+c_rbnode_t *c_rbtree_tail(c_rbtree_t *tree) {
+  c_rbnode_t *node = NULL;
+
+  if (tree == NULL) {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  node = _rbtree_subtree_tail(tree->root);
+
+  return node != NIL ? node : NULL;
+}
+
+c_rbnode_t *c_rbtree_node_next(c_rbnode_t *node) {
+  c_rbnode_t *parent = NULL;
+
+  if (node == NULL) {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  if (node->right != NIL) {
+    c_rbnode_t *next = NULL;
+    next = _rbtree_subtree_head(node->right);
+
+    return next != NIL ? next : NULL;
+  }
+
+  parent = node->parent;
+  while (parent && node == parent->right) {
+    node = parent;
+    parent = node->parent;
+  }
+
+  return parent != NULL ? parent : NULL;
+}
+
+c_rbnode_t *c_rbtree_node_prev(c_rbnode_t *node) {
+  c_rbnode_t *parent = NULL;
+
+  if (node == NULL) {
+    return NULL;
+  }
+
+  if (node->left != NIL) {
+    c_rbnode_t *prev = NULL;
+    prev = _rbtree_subtree_tail(node->left);
+    return prev != NIL ? prev : NULL;
+  }
+
+  parent = node->parent;
+  while (parent && node == parent->left) {
+    node = parent;
+    parent = node->parent;
+  }
+
+  return parent != NULL ? parent : NULL;
+}
+
+c_rbnode_t *c_rbtree_find(c_rbtree_t *tree, const void *key) {
+  int cmp = 0;
+  c_rbnode_t *node = NULL;
+
+  if (tree == NULL) {
+    errno = EINVAL;
+    return NULL;
+  }
+  node = tree->root;
+
+  while (node != NIL) {
+    cmp = tree->key_compare(key, node->data);
+    if (cmp == 0) {
+      return node;
+    }
+
+    if (cmp < 0) {
+      node = node->left;
+    } else {
+        node = node->right;
+    }
+  }
+
+  return NULL;
+}
+
+static void _rbtree_subtree_left_rotate(c_rbnode_t *x) {
+  c_rbnode_t *y = NULL;
+
+  assert(x);
+
+  y = x->right;
+
+  /* establish x-right link */
+  x->right = y->left;
+
+  if (y->left != NIL) {
+    y->left->parent = x;
+  }
+
+  /* establish y->parent link */
+  if (y != NIL) {
+    y->parent = x->parent;
+  }
+
+  if (x->parent) {
+    if (x == x->parent->left) {
+      x->parent->left = y;
+    } else {
+      x->parent->right = y;
+    }
+  } else {
+    x->tree->root = y;
+  }
+
+  /* link x and y */
+  y->left = x;
+  if (x != NIL) {
+    x->parent = y;
+  }
+}
+
+/* rotat node x to the right */
+static void _rbtree_subtree_right_rotate(c_rbnode_t *x) {
+  c_rbnode_t *y = NULL;
+
+  assert(x);
+
+  y = x->left;
+
+  /* establish x->left link */
+  x->left = y->right;
+
+  if (y->right != NIL) {
+    y->right->parent = x;
+  }
+
+  /* establish y->parent link */
+  if (y != NIL) {
+    y->parent = x->parent;
+  }
+
+  if (x->parent) {
+    if (x == x->parent->right) {
+        x->parent->right = y;
+    } else {
+      x->parent->left = y;
+    }
+  } else {
+    x->tree->root = y;
+  }
+
+  /* link x and y */
+  y->right = x;
+  if (x != NIL) {
+    x->parent = y;
+  }
+}
+
+int c_rbtree_insert(c_rbtree_t *tree, void *data) {
+  int cmp = 0;
+  c_rbnode_t *current = NULL;
+  c_rbnode_t *parent = NULL;
+  c_rbnode_t *x = NULL;
+
+  if (tree == NULL) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  /* First we do a classic binary tree insert */
+  current = tree->root;
+  parent = NULL;
+
+  while (current != NIL) {
+    cmp = tree->data_compare(data, current->data);
+    parent = current;
+    if (cmp == 0) {
+      return 1;
+    } else if (cmp < 0) {
+      current = current->left;
+    } else {
+      current = current->right;
+    }
+  }
+
+  x = (c_rbnode_t *) c_malloc(sizeof(c_rbnode_t));
+
+  x->tree = tree;
+  x->data = data;
+  x->parent = parent;
+  x->left = NIL;
+  x->right = NIL;
+  x->color = RED;
+
+  if (parent) {
+    /* Note that cmp still contains the comparison of data with
+     * parent->data, from the last pass through the loop above
+     */
+    if (cmp < 0) {
+        parent->left = x;
+    } else {
+        parent->right = x;
+    }
+  } else {
+    tree->root = x;
+  }
+
+  /* Insert fixup - check red-black properties */
+  while (x != tree->root && x->parent->color == RED) {
+    /* we have a violation */
+    if (x->parent == x->parent->parent->left) {
+      c_rbnode_t *y = NULL;
+
+      y = x->parent->parent->right;
+      if (y->color == RED) {
+        x->parent->color = BLACK;
+        y->color = BLACK;
+        x->parent->parent->color = RED;
+        x = x->parent->parent;
+      } else {
+        /* uncle is back */
+        if (x == x->parent->right) {
+          /* make x a left child */
+          x = x->parent;
+          _rbtree_subtree_left_rotate(x);
+        }
+        x->parent->color = BLACK;
+        x->parent->parent->color = RED;
+        _rbtree_subtree_right_rotate(x->parent->parent);
+      }
+    } else {
+      c_rbnode_t *y = NULL;
+
+      y = x->parent->parent->left;
+      if (y->color == RED) {
+        x->parent->color = BLACK;
+        y->color = BLACK;
+        x->parent->parent->color = RED;
+        x = x->parent->parent;
+      } else {
+        /* uncle is back */
+        if (x == x->parent->left) {
+          x = x->parent;
+          _rbtree_subtree_right_rotate(x);
+        }
+        x->parent->color = BLACK;
+        x->parent->parent->color = RED;
+        _rbtree_subtree_left_rotate(x->parent->parent);
+      }
+    }
+  } /* end while */
+  tree->root->color = BLACK;
+
+  tree->size++;
+
+  return 0;
+}
+
+int c_rbtree_node_delete(c_rbnode_t *node) {
+  c_rbtree_t *tree;
+  c_rbnode_t *y;
+  c_rbnode_t *x;
+
+  if (node == NULL || node == NIL) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  tree = node->tree;
+
+  if (node->left == NIL || node->right == NIL) {
+    /* y has a NIL node as a child */
+    y = node;
+  } else {
+    /* find tree successor with a NIL node as a child */
+    y = node;
+    while(y->left != NIL) {
+      y = y->left;
+    }
+  }
+
+  /* x is y's only child */
+  if (y->left != NIL) {
+    x = y->left;
+  } else {
+    x = y->right;
+  }
+
+  /* remove y from the parent chain */
+  x->parent = y->parent;
+
+  if (y->parent) {
+    if (y == y->parent->left) {
+        y->parent->left = x;
+    } else {
+      y->parent->right = x;
+    }
+  } else {
+    y->tree->root = x;
+  }
+
+  /* If y is not the node we're deleting, splice it in place of that
+   * node
+   *
+   * The traditional code would call for us to simply copy y->data, but
+   * that would invalidate the wrong pointer - there might be external
+   * references to this node, and we must preserve its address.
+   */
+  if (y != node) {
+    /* Update y */
+    y->parent = node->parent;
+    y->left = node->left;
+    y->right = node->right;
+
+    /* Update the children and the parent */
+    if (y->left != NIL) {
+        y->left->parent = y;
+    }
+    if (y->right != NIL) {
+      y->right->parent = y;
+    }
+    if (y->parent != NULL) {
+      if (node == y->parent->left) {
+        y->parent->left = y;
+      } else {
+        y->parent->right = y;
+      }
+    } else {
+      y->tree->root = y;
+    }
+  }
+
+  if (y->color == BLACK) {
+    while (x != y->tree->root && x->color == BLACK) {
+      if (x == x->parent->left) {
+        c_rbnode_t *w = NULL;
+
+        w = x->parent->right;
+
+        if (w->color == RED) {
+          w->color = BLACK;
+          x->parent->color = RED;
+          _rbtree_subtree_left_rotate(x->parent);
+          w = x->parent->right;
+        }
+
+        if (w->left->color == BLACK && w->right->color == BLACK) {
+          w->color = RED;
+          x = x->parent;
+        } else {
+          if (w->right->color == BLACK) {
+            w->left->color = BLACK;
+            w->color = RED;
+            _rbtree_subtree_right_rotate(w);
+            w = x->parent->right;
+          }
+          w->color = x->parent->color;
+          x->parent->color = BLACK;
+          w->right->color = BLACK;
+          _rbtree_subtree_left_rotate(x->parent);
+          x = y->tree->root;
+        }
+      } else {
+        c_rbnode_t *w = NULL;
+
+        w = x->parent->left;
+        if (w->color == RED) {
+          w->color = BLACK;
+          x->parent->color = RED;
+          _rbtree_subtree_right_rotate(x->parent);
+          w = x->parent->left;
+        }
+
+        if (w->right->color == BLACK && w->left->color == BLACK) {
+          w->color = RED;
+          x = x->parent;
+        } else {
+          if (w->left->color == BLACK) {
+            w->right->color = BLACK;
+            w->color = RED;
+            _rbtree_subtree_left_rotate(w);
+            w = x->parent->left;
+          }
+          w->color = x->parent->color;
+          x->parent->color = BLACK;
+          w->left->color = BLACK;
+          _rbtree_subtree_right_rotate(x->parent);
+          x = y->tree->root;
+        }
+      }
+    }
+    x->color = BLACK;
+  } /* end if: y->color == BLACK */
+
+  /* node has now been spliced out of the tree */
+  SAFE_FREE(y);
+  tree->size--;
+
+  return 0;
+}
+
+static int _rbtree_subtree_check_black_height(c_rbnode_t *node) {
+  int left = 0;
+  int right = 0;
+
+  assert(node);
+
+  if (node == NIL) {
+    return 0;
+  }
+
+  left = _rbtree_subtree_check_black_height(node->left);
+  right = _rbtree_subtree_check_black_height(node->right);
+  if (left != right) {
+    return -1;
+  }
+
+  return left + (node->color == BLACK);
+}
+
+int c_rbtree_check_sanity(c_rbtree_t *tree) {
+  c_rbnode_t *node = NULL;
+  c_rbnode_t *prev = NULL;
+  c_rbnode_t *next = NULL;
+  c_rbnode_t *tail = NULL;
+  size_t size = 0;
+
+  if (tree == NULL) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  if (! tree->key_compare || ! tree->data_compare) {
+    errno = EINVAL;
+    return -2;
+  }
+
+  /* Iterate the tree */
+  tail = c_rbtree_tail(tree);
+  for (node = c_rbtree_head(tree); node; node = next) {
+    if (node->tree != tree) {
+      return -4;
+    }
+
+    /* We should never see a nil while iterating */
+    if (node == NIL) {
+      return -5;
+    }
+
+    /* node == tree-root iff node->parent == NIL */
+    if (node == tree->root) {
+      if (node->parent != NULL) {
+        return -6;
+      }
+    } else {
+      if (node->parent == NULL) {
+        return -7;
+      }
+    }
+
+    /* Invertability of the iterate functions */
+    if (prev != c_rbtree_node_prev(node)) {
+      return -8;
+    }
+
+    /* Check the iteration sequence */
+    if (prev) {
+      if (tree->data_compare(prev->data, node->data) > 0) {
+        return -9;
+      }
+
+      /* And the other way around, to make sure data_compare is stable */
+      if (tree->data_compare(node->data, prev->data) < 0) {
+        return -10;
+      }
+    }
+
+    /* The binary tree property */
+    if (node->left != NIL) {
+      if (tree->data_compare(node->left->data, node->data) > 0) {
+        return -11;
+      }
+
+      if (tree->data_compare(node->data, node->left->data) < 0) {
+        return -11;
+      }
+    }
+
+    if (node->right != NIL) {
+      if (tree->data_compare(node->data, node->right->data) > 0) {
+        return -12;
+      }
+
+      if (tree->data_compare(node->right->data, node->data) < 0) {
+        return -13;
+      }
+    }
+
+    /* Red-black tree property 3: red nodes have black children */
+    if (node->color == RED) {
+      if (node->left->color == RED) {
+        return -14;
+      }
+      if (node->right->color == RED) {
+        return -15;
+      }
+    }
+
+    /* next == NULL if node == tail */
+    next = c_rbtree_node_next(node);
+    if (next) {
+      if (node == tail) {
+        return -16;
+      }
+    } else {
+      if (node != tail) {
+        return -17;
+      }
+    }
+
+    prev = node;
+    size++;
+  } /* end for loop */
+
+  if (size != tree->size) {
+    return -18;
+  }
+
+  if (_rbtree_subtree_check_black_height(tree->root) < 0) {
+    return -19;
+  }
+
+  return 0;
+}
diff --git a/src/csync/std/c_rbtree.h b/src/csync/std/c_rbtree.h
new file mode 100644 (file)
index 0000000..635458f
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2003-2004 by Andrew Suffield <asuffield@debian.org>
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file c_rbtree.h
+ *
+ * @brief Interface of the cynapses libc red-black tree implementation
+ *
+ * A red-black tree is a type of self-balancing binary search tree. It is
+ * complex, but has good worst-case running time for its operations and is
+ * efficient in practice: it can search, insert, and delete in O(log n)
+ * time, where n is the number of elements in the tree.
+ *
+ * In red-black trees, the leaf nodes are not relevant and do not contain
+ * data. Therefore we use a sentinal node to save memory. All references
+ * from internal nodes to leaf nodes instead point to the sentinel node.
+ *
+ * In a red-black tree each node has a color attribute, the value of which
+ * is either red or black. In addition to the ordinary requirements imposed
+ * on binary search trees, the following additional requirements of any
+ * valid red-black tree apply:
+ *
+ *    1. A node is either red or black.
+ *    2. The root is black.
+ *    3. All leaves are black, even when the parent is black
+ *       (The leaves are the null children.)
+ *    4. Both children of every red node are black.
+ *    5. Every simple path from a node to a descendant leaf contains the same
+ *       number of black nodes, either counting or not counting the null black
+ *       nodes. (Counting or not counting the null black nodes does not affect
+ *       the structure as long as the choice is used consistently.).
+ *
+ * These constraints enforce a critical property of red-black trees: that the
+ * longest path from the root to a leaf is no more than twice as long as the
+ * shortest path from the root to a leaf in that tree. The result is that the
+ * tree is roughly balanced. Since operations such as inserting, deleting, and
+ * finding values requires worst-case time proportional to the height of the
+ * tree, this theoretical upper bound on the height allows red-black trees to
+ * be efficient in the worst-case, unlike ordinary binary search trees.
+ *
+ * http://en.wikipedia.org/wiki/Red-black_tree
+ *
+ * @defgroup cynRBTreeInternals cynapses libc red-black tree functions
+ * @ingroup cynLibraryAPI
+ *
+ * @{
+ */
+#ifndef _C_RBTREE_H
+#define _C_RBTREE_H
+
+/* Forward declarations */
+struct c_rbtree_s; typedef struct c_rbtree_s c_rbtree_t;
+struct c_rbnode_s; typedef struct c_rbnode_s c_rbnode_t;
+
+/**
+ * Define the two colors for the red-black tree
+ */
+enum xrbcolor_e { BLACK = 0, RED }; typedef enum xrbcolor_e xrbcolor_t;
+
+/**
+ * @brief Callback function to compare a key with the data from a
+ *        red-black tree node.
+ *
+ * @param key   key as a generic pointer
+ * @param data  data as a generic pointer
+ *
+ * @return   It returns an integer less than, equal to, or greater than zero
+ *           depending on the key or data you use. The function is similar
+ *           to strcmp().
+ */
+typedef int c_rbtree_compare_func(const void *key, const void *data);
+
+/**
+ * @brief Visit function for the c_rbtree_walk() function.
+ *
+ * This function will be called by c_rbtree_walk() for every node. It is up to
+ * the developer what the function does. The fist parameter is a node object
+ * the second can be of any kind.
+ *
+ * @param obj    The node data that will be passed by c_rbtree_walk().
+ * @param data   Generic data pointer.
+ *
+ * @return 0 on success, < 0 on error. You should set errno.
+ *
+ */
+typedef int c_rbtree_visit_func(void *, void *);
+
+/**
+ * Structure that represents a red-black tree
+ */
+struct c_rbtree_s {
+  c_rbnode_t *root;
+  c_rbtree_compare_func *key_compare;
+  c_rbtree_compare_func *data_compare;
+  size_t size;
+};
+
+/**
+ * Structure that represents a node of a red-black tree
+ */
+struct c_rbnode_s {
+  c_rbtree_t *tree;
+  c_rbnode_t *left;
+  c_rbnode_t *right;
+  c_rbnode_t *parent;
+  void *data;
+  xrbcolor_t color;
+};
+
+/**
+ * @brief Create the red-black tree
+ *
+ * @param rbtree        The pointer to assign the allocated memory.
+ *
+ * @param key_compare   Callback function to compare a key with the data
+ *                      inside a reb-black tree node.
+ *
+ * @param data_compare  Callback function to compare a key as data with thee
+ *                      data inside a red-black tree node.
+ */
+void c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_rbtree_compare_func *data_compare);
+
+/**
+ * @brief Duplicate a red-black tree.
+ *
+ * @param tree Tree to duplicate.
+ *
+ * @return   Pointer to a new allocated duplicated rbtree. NULL if an error
+ *           occurred.
+ */
+c_rbtree_t *c_rbtree_dup(const c_rbtree_t *tree);
+
+/**
+ * @brief Free the structure of a red-black tree.
+ *
+ * You should call c_rbtree_destroy() before you call this function.
+ *
+ * @param tree  The tree to free.
+ *
+ * @return   0 on success, less than 0 if an error occurred.
+ */
+int c_rbtree_free(c_rbtree_t *tree);
+
+/**
+ * @brief Destroy the content and the nodes of an red-black tree.
+ *
+ * This is far from the most efficient way to walk a tree, but it is
+ * the *safest* way to destroy a tree - the destructor can do almost
+ * anything (as long as it does not create an infinite loop) to the
+ * tree structure without risk.
+ *
+ * If for some strange reason you need a faster destructor (think
+ * twice - speed and memory deallocation don't mix well) then consider
+ * stashing an llist of dataects and destroying that instead, and just
+ * using c_rbtree_free() on your tree.
+ *
+ * @param T            The tree to destroy.
+ * @param DESTRUCTOR   The destructor to call on a node to destroy.
+ */
+#define c_rbtree_destroy(T, DESTRUCTOR)                 \
+  do {                                                  \
+    if (T) {                                            \
+      c_rbnode_t *_c_rbtree_temp;                       \
+      while ((_c_rbtree_temp = c_rbtree_head(T))) {     \
+        (DESTRUCTOR)(_c_rbtree_temp->data);             \
+        if (_c_rbtree_temp == c_rbtree_head(T)) {       \
+          c_rbtree_node_delete(_c_rbtree_temp);         \
+        }                                               \
+      }                                                 \
+    }                                                   \
+    SAFE_FREE(T);                                       \
+  } while (0);
+
+/**
+ * @brief Inserts a node into a red black tree.
+ *
+ * @param tree  The red black tree to insert the node.
+ * @param data  The data to insert into the tree.
+ *
+ * @return  0 on success, 1 if a duplicate has been found and < 0 if an error
+ *          occurred with errno set.
+ *          EINVAL if a null pointer has been passed as the tree.
+ *          ENOMEM if there is no memory left.
+ */
+int c_rbtree_insert(c_rbtree_t *tree, void *data);
+
+/**
+ * @brief Find a node in a red-black tree.
+ *
+ * c_rbtree_find() is searching for the given  key  in a red-black tree and
+ * returns the node if the key has been found.
+ *
+ * @param tree   The tree to search.
+ * @param key    The key to search for.
+ *
+ * @return   If the key was found the node will be returned. On error NULL
+ *           will be returned.
+ */
+c_rbnode_t *c_rbtree_find(c_rbtree_t *tree, const void *key);
+
+/**
+ * @brief Get the head of the red-black tree.
+ *
+ * @param tree   The tree to get the head for.
+ *
+ * @return   The head node. NULL if an error occurred.
+ */
+c_rbnode_t *c_rbtree_head(c_rbtree_t *tree);
+
+/**
+ * @brief Get the tail of the red-black tree.
+ *
+ * @param tree   The tree to get the tail for.
+ *
+ * @return   The tail node. NULL if an error occurred.
+ */
+c_rbnode_t *c_rbtree_tail(c_rbtree_t *tree);
+
+/**
+ * @brief Get the size of the red-black tree.
+ *
+ * @param T  The tree to get the size from.
+ *
+ * @return  The size of the red-black tree.
+ */
+#define c_rbtree_size(T) (T) == NULL ? 0 : ((T)->size)
+
+/**
+ * @brief Walk over a red-black tree.
+ * 
+ * Walk over a red-black tree calling a visitor function for each node found.
+ *
+ * @param tree     Tree to walk.
+ * @param data     Data which should be passed to the visitor function.
+ * @param visitor  Visitor function. This will be called for each node passed.
+ *
+ * @return   0 on sucess, less than 0 if an error occurred.
+ */
+int c_rbtree_walk(c_rbtree_t *tree, void *data, c_rbtree_visit_func *visitor);
+
+/**
+ * @brief Delete a node in a red-black tree.
+ *
+ * @param node  Node which should be deleted.
+ *
+ * @return  0 on success, -1 if an error occurred.
+ */
+int c_rbtree_node_delete(c_rbnode_t *node);
+
+/**
+ * @brief Get the next node.
+ *
+ * @param node  The node of which you want the next node.
+ *
+ * @return  The next node, NULL if an error occurred.
+ */
+c_rbnode_t *c_rbtree_node_next(c_rbnode_t *node);
+
+/**
+ * @brief Get the previous node.
+ *
+ * @param node  The node of which you want the previous node.
+ *
+ * @return  The previous node, NULL if an error occurred.
+ */
+c_rbnode_t *c_rbtree_node_prev(c_rbnode_t *node);
+
+/**
+ * @brief Get the data of a node.
+ *
+ * @param N  The node to get the data from.
+ *
+ * @return  The data, NULL if an error occurred.
+ */
+#define c_rbtree_node_data(N) ((N) ? ((N)->data) : NULL)
+
+/**
+ * @brief Perform a sanity check for a red-black tree.
+ *
+ * This is mostly for testing purposes.
+ *
+ * @param tree  The tree to check.
+ *
+ * @return 0 on success, less than 0 if an error occurred.
+ */
+int c_rbtree_check_sanity(c_rbtree_t *tree);
+
+/**
+ * }@
+ */
+#endif /* _C_RBTREE_H */
diff --git a/src/csync/std/c_string.c b/src/csync/std/c_string.c
new file mode 100644 (file)
index 0000000..8929f24
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <limits.h>
+#include <sys/types.h>
+#include <wchar.h>
+
+#include "c_string.h"
+#include "c_path.h"
+#include "c_alloc.h"
+#include "c_macro.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+int c_strncasecmp(const char *a, const char *b, size_t n) {
+#ifdef _WIN32
+    return _strnicmp(a, b, n);
+#else
+    return strncasecmp(a, b, n);
+#endif
+}
+
+int c_streq(const char *a, const char *b) {
+  register const char *s1 = a;
+  register const char *s2 = b;
+
+  if (s1 == NULL || s2 ==  NULL) {
+    return 0;
+  }
+
+  while (*s1 == *s2++) {
+    if (*s1++ == '\0') {
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+c_strlist_t *c_strlist_new(size_t size) {
+  c_strlist_t *strlist = NULL;
+
+  if (size == 0) {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  strlist = c_malloc(sizeof(c_strlist_t));
+  if (strlist == NULL) {
+    return NULL;
+  }
+
+  strlist->vector = (char **) c_malloc(size * sizeof(char *));
+  strlist->count = 0;
+  strlist->size = size;
+
+  return strlist;
+}
+
+c_strlist_t *c_strlist_expand(c_strlist_t *strlist, size_t size) {
+  if (strlist == NULL || size == 0) {
+    errno = EINVAL;
+    return NULL;
+  }
+
+  if (strlist->size >= size) {
+    return strlist;
+  }
+
+  strlist->vector = (char **) c_realloc(strlist->vector, size * sizeof(char *));
+  if (strlist->vector == NULL) {
+    return NULL;
+  }
+
+  strlist->size = size;
+
+  return strlist;
+}
+
+int c_strlist_add(c_strlist_t *strlist, const char *string) {
+  if (strlist == NULL || string == NULL) {
+    return -1;
+  }
+
+  if (strlist->count < strlist->size) {
+    strlist->vector[strlist->count] = c_strdup(string);
+    if (strlist->vector[strlist->count] == NULL) {
+      return -1;
+    }
+    strlist->count++;
+  } else {
+    errno = ENOBUFS;
+    return -1;
+  }
+
+  return 0;
+}
+
+int c_strlist_add_grow(c_strlist_t **strlist, const char *string) {
+  if (*strlist == NULL) {
+    *strlist = c_strlist_new(32);
+    if (*strlist == NULL) {
+      return -1;
+    }
+  }
+
+  if ((*strlist)->count == (*strlist)->size) {
+    c_strlist_t *list = c_strlist_expand(*strlist, 2 * (*strlist)->size);
+    if (list == NULL) {
+      return -1;
+    }
+    *strlist = list;
+  }
+
+  return c_strlist_add(*strlist, string);
+}
+
+void c_strlist_clear(c_strlist_t *strlist) {
+  size_t i = 0;
+
+  if (strlist == NULL) {
+    return;
+  }
+
+  for (i = 0; i < strlist->count; i++) {
+    SAFE_FREE(strlist->vector[i]);
+  }
+
+  strlist->count = 0;
+}
+
+void c_strlist_destroy(c_strlist_t *strlist) {
+
+  if (strlist == NULL) {
+    return;
+  }
+
+  c_strlist_clear(strlist);
+  SAFE_FREE(strlist->vector);
+  SAFE_FREE(strlist);
+}
diff --git a/src/csync/std/c_string.h b/src/csync/std/c_string.h
new file mode 100644 (file)
index 0000000..304c598
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file c_string.h
+ *
+ * @brief Interface of the cynapses string implementations
+ *
+ * @defgroup cynStringInternals cynapses libc string functions
+ * @ingroup cynLibraryAPI
+ *
+ * @{
+ */
+#ifndef _C_STR_H
+#define _C_STR_H
+
+#include "c_private.h"
+#include "c_macro.h"
+
+#include <stdlib.h>
+
+struct c_strlist_s; typedef struct c_strlist_s c_strlist_t;
+
+/**
+ * @brief Structure for a stringlist
+ *
+ * Using a for loop you can access the strings saved in the vector.
+ *
+ * c_strlist_t strlist;
+ * int i;
+ * for (i = 0; i < strlist->count; i++) {
+ *   printf("value: %s", strlist->vector[i];
+ * }
+ */
+struct c_strlist_s {
+  /** The string vector */
+  char **vector;
+  /** The count of the strings saved in the vector */
+  size_t count;
+  /** Size of strings allocated */
+  size_t size;
+};
+
+/**
+ * @brief Compare to strings case insensitively.
+ *
+ * @param a  First string to compare.
+ * @param b  Second string to compare.
+ * @param n  Max comparison length.
+ *
+ * @return see strncasecmp
+ */
+int c_strncasecmp(const char *a, const char *b, size_t n);
+
+/**
+ * @brief Compare to strings if they are equal.
+ *
+ * @param a  First string to compare.
+ * @param b  Second string to compare.
+ *
+ * @return  1 if they are equal, 0 if not.
+ */
+int c_streq(const char *a, const char *b);
+
+/**
+ * @brief Create a new stringlist.
+ *
+ * @param size  Size to allocate.
+ *
+ * @return  Pointer to the newly allocated stringlist. NULL if an error occured.
+ */
+c_strlist_t *c_strlist_new(size_t size);
+
+/**
+ * @brief Expand the stringlist
+ *
+ * @param strlist  Stringlist to expand
+ * @param size     New size of the strlinglist to expand
+ *
+ * @return  Pointer to the expanded stringlist. NULL if an error occured.
+ */
+c_strlist_t *c_strlist_expand(c_strlist_t *strlist, size_t size);
+
+/**
+ * @brief  Add a string to the stringlist.
+ *
+ * Duplicates the string and stores it in the stringlist.
+ *
+ * @param strlist  Stringlist to add the string.
+ * @param string   String to add.
+ *
+ * @return  0 on success, less than 0 and errno set if an error occured.
+ *          ENOBUFS if the list is full.
+ */
+int c_strlist_add(c_strlist_t *strlist, const char *string);
+
+/**
+ * @brief  Add a string to the stringlist, growing it if necessary
+ *
+ * Duplicates the string and stores it in the stringlist.
+ * It also initializes the stringlist if it starts out as null.
+ *
+ * @param strlist  Stringlist to add the string.
+ * @param string   String to add.
+ *
+ * @return  0 on success, less than 0 and errno set if an error occured.
+ */
+int c_strlist_add_grow(c_strlist_t **strlist, const char *string);
+
+/**
+ * @brief Removes all strings from the list.
+ *
+ * Frees the strings.
+ *
+ * @param strlist  Stringlist to clear
+ */
+void c_strlist_clear(c_strlist_t *strlist);
+
+/**
+ * @brief Destroy the memory of the stringlist.
+ *
+ * Frees the strings and the stringlist.
+ *
+ * @param strlist  Stringlist to destroy
+ */
+void c_strlist_destroy(c_strlist_t *strlist);
+
+/**
+ * @brief Convert a platform locale string to utf8.
+ *
+ * This function is part of the multi platform abstraction of basic file
+ * operations to handle various platform encoding correctly.
+ *
+ * Instead of using the standard file operations the multi platform aliases
+ * defined in c_private.h have to be used instead.
+ *
+ * To convert path names returned by these functions to the internally used
+ * utf8 format this function has to be used. The returned string has to
+ * be freed by c_free_locale_string(). On some platforms this method allocates
+ * memory and on others not but it has never to be cared about.
+ *
+ * @param  str     The multibyte encoded string to convert
+ *
+ * @return The malloced converted string or NULL on error.
+ *
+ * @see c_free_locale_string()
+ * @see c_utf8_to_locale()
+ *
+ */
+ char*   c_utf8_from_locale(const mbchar_t *str);
+
+/**
+ * @brief Convert a utf8 encoded string to platform specific locale.
+ *
+ * This function is part of the multi platform abstraction of basic file
+ * operations to handle various platform encoding correctly.
+ *
+ * Instead of using the standard file operations the multi platform aliases
+ * defined in c_private.h have to be used instead.
+ *
+ * To convert strings as input for the cross platform functions from the
+ * internally used utf8 format, this function has to be used.
+ * The returned string has to be freed by c_free_locale_string(). On some
+ * platforms this method allocates memory and on others not but it has never
+ * sto be cared about.
+ *
+ * If the string to convert is a path, consider using c_utf8_path_to_locale().
+ *
+ * @param  str     The utf8 string to convert.
+ *
+ * @return The malloced converted multibyte string or NULL on error.
+ *
+ * @see c_free_locale_string()
+ * @see c_utf8_from_locale()
+ *
+ */
+mbchar_t* c_utf8_string_to_locale(const char *wstr);
+
+/**
+ * @brief Free buffer malloced by c_utf8_from_locale or c_utf8_to_locale().
+ *
+ * This function is part of the multi platform abstraction of basic file
+ * operations to handle various platform encoding correctly.
+ *
+ * Instead of using the standard file operations the multi platform aliases
+ * defined in c_private.h have to be used instead.
+ *
+ * This function frees the memory that was allocated by a previous call to
+ * c_utf8_to_locale() or c_utf8_from_locale().
+ *
+ * @param  buf     The buffer to free.
+ *
+ * @see c_utf8_from_locale(), c_utf8_to_locale()
+ *
+ */
+#define c_free_locale_string(x) SAFE_FREE(x)
+
+
+/**
+ * }@
+ */
+#endif /* _C_STR_H */
+
diff --git a/src/csync/std/c_time.c b/src/csync/std/c_time.c
new file mode 100644 (file)
index 0000000..ad43fed
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * c_time - time functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+#include "c_private.h"
+#include "c_string.h"
+
+#include "c_path.h"
+#include "c_time.h"
+
+#ifndef _WIN32
+#include <sys/time.h>
+#endif
+
+struct timespec c_tspecdiff(struct timespec time1, struct timespec time0) {
+  struct timespec ret;
+  int xsec = 0;
+  int sign = 1;
+
+  if (time0.tv_nsec > time1.tv_nsec) {
+    xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
+    time0.tv_nsec -= (long int) (1E9 * xsec);
+    time0.tv_sec += xsec;
+  }
+
+  if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
+    xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
+    time0.tv_nsec += (long int) (1E9 * xsec);
+    time0.tv_sec -= xsec;
+  }
+
+  ret.tv_sec = time1.tv_sec - time0.tv_sec;
+  ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
+
+  if (time1.tv_sec < time0.tv_sec) {
+    sign = -1;
+  }
+
+  ret.tv_sec = ret.tv_sec * sign;
+
+  return ret;
+}
+
+double c_secdiff(struct timespec clock1, struct timespec clock0) {
+  double ret;
+  struct timespec diff;
+
+  diff = c_tspecdiff(clock1, clock0);
+
+  ret = diff.tv_sec;
+  ret += (double) diff.tv_nsec / (double) 1E9;
+
+  return ret;
+}
+
+
+#ifdef HAVE_UTIMES
+int c_utimes(const char *uri, const struct timeval *times) {
+    mbchar_t *wuri = c_utf8_path_to_locale(uri);
+    int ret = utimes(wuri, times);
+    c_free_locale_string(wuri);
+    return ret;
+}
+#else // HAVE_UTIMES
+
+#ifdef _WIN32
+// implementation for utimes taken from KDE mingw headers
+
+#include <errno.h>
+#include <wtypes.h>
+#define CSYNC_SECONDS_SINCE_1601 11644473600LL
+#define CSYNC_USEC_IN_SEC            1000000LL
+//after Microsoft KB167296
+static void UnixTimevalToFileTime(struct timeval t, LPFILETIME pft)
+{
+    LONGLONG ll;
+    ll = Int32x32To64(t.tv_sec, CSYNC_USEC_IN_SEC*10) + t.tv_usec*10 + CSYNC_SECONDS_SINCE_1601*CSYNC_USEC_IN_SEC*10;
+    pft->dwLowDateTime = (DWORD)ll;
+    pft->dwHighDateTime = ll >> 32;
+}
+
+int c_utimes(const char *uri, const struct timeval *times) {
+    FILETIME LastAccessTime;
+    FILETIME LastModificationTime;
+    HANDLE hFile;
+
+    mbchar_t *wuri = c_utf8_path_to_locale( uri );
+
+    if(times) {
+        UnixTimevalToFileTime(times[0], &LastAccessTime);
+        UnixTimevalToFileTime(times[1], &LastModificationTime);
+    }
+    else {
+        GetSystemTimeAsFileTime(&LastAccessTime);
+        GetSystemTimeAsFileTime(&LastModificationTime);
+    }
+
+    hFile=CreateFileW(wuri, FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, NULL);
+    if(hFile==INVALID_HANDLE_VALUE) {
+        switch(GetLastError()) {
+            case ERROR_FILE_NOT_FOUND:
+                errno=ENOENT;
+                break;
+            case ERROR_PATH_NOT_FOUND:
+            case ERROR_INVALID_DRIVE:
+                errno=ENOTDIR;
+                break;
+                /*case ERROR_WRITE_PROTECT:   //CreateFile sets ERROR_ACCESS_DENIED on read-only devices
+                 *                errno=EROFS;
+                 *                break;*/
+                case ERROR_ACCESS_DENIED:
+                    errno=EACCES;
+                    break;
+                default:
+                    errno=ENOENT;   //what other errors can occur?
+        }
+
+        return -1;
+    }
+
+    if(!SetFileTime(hFile, NULL, &LastAccessTime, &LastModificationTime)) {
+        //can this happen?
+        errno=ENOENT;
+        CloseHandle(hFile);
+        c_free_locale_string(wuri);
+        return -1;
+    }
+
+    CloseHandle(hFile);
+    c_free_locale_string(wuri);
+
+    return 0;
+}
+
+#endif // _WIN32
+#endif // HAVE_UTIMES
diff --git a/src/csync/std/c_time.h b/src/csync/std/c_time.h
new file mode 100644 (file)
index 0000000..aa8ef2f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * c_time - time functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _C_TIME_H
+#define _C_TIME_H
+
+#include <time.h>
+
+/**
+ * @brief Calculate time difference
+ *
+ * The c_tspecdiff function returns the time elapsed between time time1 and time
+ * time0 represented as timespec.
+ *
+ * @param time1 The time.
+ * @param time0 The time.
+ *
+ * @return time elapsed between time1 and time0.
+ */
+struct timespec c_tspecdiff(struct timespec time1, struct timespec time0);
+
+/**
+ * @brief Calculate time difference.
+ *
+ * The function returns the time elapsed between time clock1 and time
+ * clock0 represented as double (in seconds and milliseconds).
+ *
+ * @param clock1 The time.
+ * @param clock0 The time.
+ *
+ * @return time elapsed between clock1 and clock0 in seconds and
+ *         milliseconds.
+ */
+double c_secdiff(struct timespec clock1, struct timespec clock0);
+
+int c_utimes(const char *uri, const struct timeval *times);
+
+#endif /* _C_TIME_H */
diff --git a/src/csync/std/c_utf8.cc b/src/csync/std/c_utf8.cc
new file mode 100644 (file)
index 0000000..4bd5d75
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config_csync.h"
+
+#ifdef _WIN32
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <wchar.h>
+#include <windows.h>
+#else
+#include <QtCore/QTextCodec>
+#include <QtCore/QFile>
+#endif
+
+extern "C" {
+#include "c_alloc.h"
+#include "c_string.h"
+
+/* Convert a locale String to UTF8 */
+char* c_utf8_from_locale(const mbchar_t *wstr)
+{
+  if (wstr == NULL) {
+    return NULL;
+  }
+
+#ifdef _WIN32
+  char *dst = NULL;
+  char *mdst = NULL;
+  int size_needed;
+  size_t len;
+  len = wcslen(wstr);
+  /* Call once to get the required size. */
+  size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, len, NULL, 0, NULL, NULL);
+  if (size_needed > 0) {
+    mdst = (char*)c_malloc(size_needed + 1);
+
+    memset(mdst, 0, size_needed + 1);
+    WideCharToMultiByte(CP_UTF8, 0, wstr, len, mdst, size_needed, NULL, NULL);
+    dst = mdst;
+  }
+  return dst;
+#else
+    QTextDecoder dec(QTextCodec::codecForLocale());
+    QString s = dec.toUnicode(wstr, qstrlen(wstr));
+    if (s.isEmpty() || dec.hasFailure()) {
+        /* Conversion error: since we can't report error from this function, just return the original
+            string.  We take care of invalid utf-8 in SyncEngine::treewalkFile */
+        return c_strdup(wstr);
+    }
+#ifdef __APPLE__
+    s = s.normalized(QString::NormalizationForm_C);
+#endif
+    return c_strdup(std::move(s).toUtf8().constData());
+#endif
+}
+
+/* Convert a an UTF8 string to locale */
+mbchar_t* c_utf8_string_to_locale(const char *str)
+{
+    if (str == NULL ) {
+        return NULL;
+    }
+#ifdef _WIN32
+    mbchar_t *dst = NULL;
+    size_t len;
+    int size_needed;
+
+    len = strlen(str);
+    size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
+    if (size_needed > 0) {
+        int size_char = (size_needed + 1) * sizeof(mbchar_t);
+        dst = (mbchar_t*)c_malloc(size_char);
+        memset((void*)dst, 0, size_char);
+        MultiByteToWideChar(CP_UTF8, 0, str, -1, dst, size_needed);
+    }
+    return dst;
+#else
+    return c_strdup(QFile::encodeName(QString::fromUtf8(str)));
+#endif
+}
+
+}
diff --git a/src/csync/vio/csync_vio.c b/src/csync/vio/csync_vio.c
new file mode 100644 (file)
index 0000000..9091178
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "csync_private.h"
+#include "csync_util.h"
+#include "vio/csync_vio.h"
+#include "vio/csync_vio_local.h"
+#include "csync_statedb.h"
+#include "std/c_jhash.h"
+
+#define CSYNC_LOG_CATEGORY_NAME "csync.vio.main"
+
+#include "csync_log.h"
+
+csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name) {
+  switch(ctx->replica) {
+    case REMOTE_REPLICA:
+      if(ctx->remote.read_from_db) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Read from db flag is true, should not!" );
+      }
+      return ctx->callbacks.remote_opendir_hook(name, ctx->callbacks.vio_userdata);
+      break;
+    case LOCAL_REPLICA:
+       if( ctx->callbacks.update_callback ) {
+        ctx->callbacks.update_callback(ctx->replica, name, ctx->callbacks.update_callback_userdata);
+       }
+      return csync_vio_local_opendir(name);
+      break;
+    default:
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
+      break;
+  }
+  return NULL;
+}
+
+int csync_vio_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
+  int rc = -1;
+
+  if (dhandle == NULL) {
+    errno = EBADF;
+    return -1;
+  }
+
+  switch(ctx->replica) {
+  case REMOTE_REPLICA:
+      if( ctx->remote.read_from_db ) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Remote ReadFromDb is true, should not!");
+      }
+      ctx->callbacks.remote_closedir_hook(dhandle, ctx->callbacks.vio_userdata);
+      rc = 0;
+      break;
+  case LOCAL_REPLICA:
+      rc = csync_vio_local_closedir(dhandle);
+      break;
+  default:
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
+      break;
+  }
+  return rc;
+}
+
+csync_vio_file_stat_t *csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
+  switch(ctx->replica) {
+    case REMOTE_REPLICA:
+      if( ctx->remote.read_from_db ) {
+          CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Remote readfromdb is true, should not!");
+      }
+      return ctx->callbacks.remote_readdir_hook(dhandle, ctx->callbacks.vio_userdata);
+      break;
+    case LOCAL_REPLICA:
+      return csync_vio_local_readdir(dhandle);
+      break;
+    default:
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_ALERT, "Invalid replica (%d)", (int)ctx->replica);
+      break;
+  }
+
+  return NULL;
+}
+
+
+int csync_vio_stat(CSYNC *ctx, const char *uri, csync_vio_file_stat_t *buf) {
+  int rc = -1;
+
+  switch(ctx->replica) {
+    case REMOTE_REPLICA:
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "ERROR: Cannot call remote stat, not implemented");
+      assert(ctx->replica != REMOTE_REPLICA);
+      break;
+    case LOCAL_REPLICA:
+      rc = csync_vio_local_stat(uri, buf);
+      if (rc < 0) {
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Local stat failed, errno %d for %s", errno, uri);
+      }
+      break;
+    default:
+      break;
+  }
+
+  return rc;
+}
+
+char *csync_vio_get_status_string(CSYNC *ctx) {
+  if(ctx->error_string) {
+    return ctx->error_string;
+  }
+  return 0;
+}
diff --git a/src/csync/vio/csync_vio.h b/src/csync/vio/csync_vio.h
new file mode 100644 (file)
index 0000000..715b185
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CSYNC_VIO_H
+#define _CSYNC_VIO_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "c_private.h"
+#include "csync.h"
+#include "csync_private.h"
+
+typedef struct fhandle_s {
+  int fd;
+} fhandle_t;
+
+csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name);
+int csync_vio_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle);
+csync_vio_file_stat_t *csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle);
+
+int csync_vio_stat(CSYNC *ctx, const char *uri, csync_vio_file_stat_t *buf);
+
+char *csync_vio_get_status_string(CSYNC *ctx);
+
+
+#endif /* _CSYNC_VIO_H */
diff --git a/src/csync/vio/csync_vio_file_stat.c b/src/csync/vio/csync_vio_file_stat.c
new file mode 100644 (file)
index 0000000..8ebb64f
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "c_lib.h"
+#include "csync.h"
+#include "csync_log.h"
+
+csync_vio_file_stat_t *csync_vio_file_stat_new(void) {
+  csync_vio_file_stat_t *file_stat = (csync_vio_file_stat_t *) c_malloc(sizeof(csync_vio_file_stat_t));
+  ZERO_STRUCTP(file_stat);
+  return file_stat;
+}
+
+csync_vio_file_stat_t* csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat) {
+    csync_vio_file_stat_t *file_stat_cpy = csync_vio_file_stat_new();
+    memcpy(file_stat_cpy, file_stat, sizeof(csync_vio_file_stat_t));
+    if (file_stat_cpy->fields & CSYNC_VIO_FILE_STAT_FIELDS_ETAG) {
+        file_stat_cpy->etag = c_strdup(file_stat_cpy->etag);
+    }
+    if (file_stat_cpy->directDownloadCookies) {
+        file_stat_cpy->directDownloadCookies = c_strdup(file_stat_cpy->directDownloadCookies);
+    }
+    if (file_stat_cpy->directDownloadUrl) {
+        file_stat_cpy->directDownloadUrl = c_strdup(file_stat_cpy->directDownloadUrl);
+    }
+    if (file_stat_cpy->checksumHeader) {
+        file_stat_cpy->checksumHeader = c_strdup(file_stat_cpy->checksumHeader);
+    }
+    file_stat_cpy->name = c_strdup(file_stat_cpy->name);
+    return file_stat_cpy;
+}
+
+void csync_vio_file_stat_destroy(csync_vio_file_stat_t *file_stat) {
+  /* FIXME: free rest */
+  if (file_stat == NULL) {
+    return;
+  }
+
+  if (file_stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_ETAG) {
+    SAFE_FREE(file_stat->etag);
+  }
+  SAFE_FREE(file_stat->directDownloadUrl);
+  SAFE_FREE(file_stat->directDownloadCookies);
+  SAFE_FREE(file_stat->name);
+  SAFE_FREE(file_stat->original_name);
+  SAFE_FREE(file_stat->checksumHeader);
+  SAFE_FREE(file_stat);
+}
+
+void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t *dst, const char* src ) {
+
+    csync_vio_set_file_id( dst->file_id, src );
+    if( c_streq( dst->file_id, "" )) {
+        return;
+    }
+    dst->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FILE_ID;
+}
+
+void csync_vio_set_file_id( char* dst, const char *src ) {
+    if( src && dst ) {
+        if( strlen(src) > FILE_ID_BUF_SIZE ) {
+            CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Ignoring file_id because it is too long: %s", src);
+            strcpy(dst, "");
+        } else {
+            strcpy(dst, src);
+        }
+    }
+}
diff --git a/src/csync/vio/csync_vio_local.h b/src/csync/vio/csync_vio_local.h
new file mode 100644 (file)
index 0000000..2943831
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CSYNC_VIO_LOCAL_H
+#define _CSYNC_VIO_LOCAL_H
+
+csync_vio_handle_t OCSYNC_EXPORT *csync_vio_local_opendir(const char *name);
+int OCSYNC_EXPORT csync_vio_local_closedir(csync_vio_handle_t *dhandle);
+csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_local_readdir(csync_vio_handle_t *dhandle);
+
+int OCSYNC_EXPORT csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf);
+
+#endif /* _CSYNC_VIO_LOCAL_H */
diff --git a/src/csync/vio/csync_vio_local_unix.c b/src/csync/vio/csync_vio_local_unix.c
new file mode 100644 (file)
index 0000000..5d56666
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2013- by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdio.h>
+
+#include "c_private.h"
+#include "c_lib.h"
+#include "c_string.h"
+#include "csync_util.h"
+#include "csync_log.h"
+#include "csync_vio.h"
+
+#include "vio/csync_vio_local.h"
+
+/*
+ * directory functions
+ */
+
+typedef struct dhandle_s {
+  DIR *dh;
+  char *path;
+} dhandle_t;
+
+csync_vio_handle_t *csync_vio_local_opendir(const char *name) {
+  dhandle_t *handle = NULL;
+  mbchar_t *dirname = NULL;
+
+  handle = c_malloc(sizeof(dhandle_t));
+
+  dirname = c_utf8_path_to_locale(name);
+
+  handle->dh = _topendir( dirname );
+  if (handle->dh == NULL) {
+    c_free_locale_string(dirname);
+    SAFE_FREE(handle);
+    return NULL;
+  }
+
+  handle->path = c_strdup(name);
+  c_free_locale_string(dirname);
+
+  return (csync_vio_handle_t *) handle;
+}
+
+int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
+  dhandle_t *handle = NULL;
+  int rc = -1;
+
+  if (dhandle == NULL) {
+    errno = EBADF;
+    return -1;
+  }
+
+  handle = (dhandle_t *) dhandle;
+  rc = _tclosedir(handle->dh);
+
+  SAFE_FREE(handle->path);
+  SAFE_FREE(handle);
+
+  return rc;
+}
+
+csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
+
+  dhandle_t *handle = NULL;
+  csync_vio_file_stat_t *file_stat = NULL;
+
+  handle = (dhandle_t *) dhandle;
+
+  errno = 0;
+  file_stat = csync_vio_file_stat_new();
+  if (file_stat == NULL) {
+    goto err;
+  }
+  file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
+
+  struct _tdirent *dirent = NULL;
+
+  dirent = _treaddir(handle->dh);
+  if (dirent == NULL) {
+      goto err;
+  }
+  file_stat->name = c_utf8_from_locale(dirent->d_name);
+  if (file_stat->name == NULL) {
+      //file_stat->original_name = c_strdup(dirent->d_name);
+      if (asprintf(&file_stat->original_name, "%s/%s", handle->path, dirent->d_name) < 0) {
+          goto err;
+      }
+      CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Invalid characters in file/directory name, please rename: \"%s\" (%s)",
+                dirent->d_name, handle->path);
+  }
+
+  /* Check for availability of d_type, see manpage. */
+#if defined(_DIRENT_HAVE_D_TYPE) || defined(__APPLE__)
+  switch (dirent->d_type) {
+    case DT_FIFO:
+    case DT_SOCK:
+    case DT_CHR:
+    case DT_BLK:
+      break;
+    case DT_DIR:
+    case DT_REG:
+      file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
+      if (dirent->d_type == DT_DIR) {
+        file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
+      } else {
+        file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
+      }
+      break;
+    case DT_UNKNOWN:
+      file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
+      file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
+    default:
+      break;
+  }
+#endif
+
+  return file_stat;
+
+err:
+  csync_vio_file_stat_destroy(file_stat);
+
+  return NULL;
+}
+
+
+int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
+  csync_stat_t sb;
+
+  mbchar_t *wuri = c_utf8_path_to_locale( uri );
+
+  if( _tstat(wuri, &sb) < 0) {
+    c_free_locale_string(wuri);
+    return -1;
+  }
+
+  buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
+
+  switch(sb.st_mode & S_IFMT) {
+    case S_IFBLK:
+      buf->type = CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE;
+      break;
+    case S_IFCHR:
+      buf->type = CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE;
+      break;
+    case S_IFDIR:
+      buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
+      break;
+    case S_IFIFO:
+      buf->type = CSYNC_VIO_FILE_TYPE_FIFO;
+      break;
+    case S_IFREG:
+      buf->type = CSYNC_VIO_FILE_TYPE_REGULAR;
+      break;
+    case S_IFLNK:
+      buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
+      break;
+    case S_IFSOCK:
+      buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
+      break;
+    default:
+      buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
+      break;
+  }
+  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
+
+  buf->mode = sb.st_mode;
+  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MODE;
+
+  if (buf->type == CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK) {
+    /* FIXME: handle symlink */
+    buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK;
+  } else {
+    buf->flags = CSYNC_VIO_FILE_FLAGS_NONE;
+  }
+#ifdef __APPLE__
+  if (sb.st_flags & UF_HIDDEN) {
+      buf->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
+  }
+#endif
+  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
+
+  buf->inode = sb.st_ino;
+  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
+
+  buf->atime = sb.st_atime;
+  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
+
+  buf->mtime = sb.st_mtime;
+  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
+
+  buf->ctime = sb.st_ctime;
+  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
+
+  buf->size = sb.st_size;
+  buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
+
+  c_free_locale_string(wuri);
+  return 0;
+}
diff --git a/src/csync/vio/csync_vio_local_win.c b/src/csync/vio/csync_vio_local_win.c
new file mode 100644 (file)
index 0000000..fc4eea5
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * libcsync -- a library to sync a directory with another
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2013- by Klaas Freitag <freitag@owncloud.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+#include "windows.h"
+
+#include "c_private.h"
+#include "c_lib.h"
+#include "c_string.h"
+#include "csync_util.h"
+#include "csync_log.h"
+#include "csync_vio.h"
+
+#include "vio/csync_vio_local.h"
+
+
+/*
+ * directory functions
+ */
+
+typedef struct dhandle_s {
+  WIN32_FIND_DATA ffd;
+  HANDLE hFind;
+  int firstFind;
+  char *path;
+} dhandle_t;
+
+csync_vio_handle_t *csync_vio_local_opendir(const char *name) {
+  dhandle_t *handle = NULL;
+  mbchar_t *dirname = NULL;
+
+  handle = c_malloc(sizeof(dhandle_t));
+
+  // the file wildcard has to be attached
+  int len_name = strlen(name);
+  if( len_name ) {
+      char *h = NULL;
+
+      // alloc an enough large buffer to take the name + '/*' + the closing zero.
+      h = c_malloc(len_name+3);
+      strncpy( h, name, 1+len_name);
+      strncat(h, "/*", 2);
+
+      dirname = c_utf8_path_to_locale(h);
+      SAFE_FREE(h);
+  }
+
+  if( dirname ) {
+      handle->hFind = FindFirstFile(dirname, &(handle->ffd));
+  }
+
+  if (!dirname || handle->hFind == INVALID_HANDLE_VALUE) {
+      int retcode = GetLastError();
+      if( retcode == ERROR_FILE_NOT_FOUND ) {
+          errno = ENOENT;
+      } else {
+          errno = EACCES;
+      }
+      SAFE_FREE(handle);
+      return NULL;
+  }
+
+  handle->firstFind = 1; // Set a flag that there first fileinfo is available.
+
+  handle->path = c_strdup(name);
+  c_free_locale_string(dirname);
+
+  return (csync_vio_handle_t *) handle;
+}
+
+int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
+  dhandle_t *handle = NULL;
+  int rc = -1;
+
+  if (dhandle == NULL) {
+    errno = EBADF;
+    return -1;
+  }
+
+  handle = (dhandle_t *) dhandle;
+  // FindClose returns non-zero on success
+  if( FindClose(handle->hFind) != 0 ) {
+      rc = 0;
+  } else {
+      // error case, set errno
+      errno = EBADF;
+  }
+
+  SAFE_FREE(handle->path);
+  SAFE_FREE(handle);
+
+  return rc;
+}
+
+
+static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder)
+{
+    long long int t = filetime->dwHighDateTime;
+    t <<= 32;
+    t += (UINT32)filetime->dwLowDateTime;
+    t -= 116444736000000000LL;
+    if (t < 0)
+    {
+        if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
+        return -1 - ((-t - 1) / 10000000);
+    }
+    else
+    {
+        if (remainder) *remainder = t % 10000000;
+        return t / 10000000;
+    }
+}
+
+csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
+
+  dhandle_t *handle = NULL;
+  csync_vio_file_stat_t *file_stat = NULL;
+  DWORD rem;
+
+  handle = (dhandle_t *) dhandle;
+
+  errno = 0;
+  file_stat = csync_vio_file_stat_new();
+  if (file_stat == NULL) {
+      errno = ENOMEM;
+      goto err;
+  }
+  file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
+
+  // the win32 functions get the first valid entry with the opendir
+  // thus we must not jump to next entry if it was the first find.
+  if( handle->firstFind ) {
+      handle->firstFind = 0;
+  } else {
+      if( FindNextFile(handle->hFind, &(handle->ffd)) == 0 ) {
+          // might be error, check!
+          int dwError = GetLastError();
+          if (dwError != ERROR_NO_MORE_FILES) {
+              errno = EACCES; // no more files is fine. Otherwise EACCESS
+          }
+          goto err;
+      }
+  }
+  file_stat->name = c_utf8_from_locale(handle->ffd.cFileName);
+
+    file_stat->flags = CSYNC_VIO_FILE_FLAGS_NONE;
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
+    if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+        // Detect symlinks, and treat junctions as symlinks too.
+        if (handle->ffd.dwReserved0 == IO_REPARSE_TAG_SYMLINK
+                || handle->ffd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT) {
+            file_stat->flags |= CSYNC_VIO_FILE_FLAGS_SYMLINK;
+            file_stat->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
+        } else {
+            // The SIS and DEDUP reparse points should be treated as
+            // regular files. We don't know about the other ones yet,
+            // but will also treat them normally for now.
+            file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
+        }
+    } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
+                || handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
+                || handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
+        file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
+    } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
+    } else {
+        file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
+    }
+
+    /* Check for the hidden flag */
+    if( handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) {
+        file_stat->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
+    }
+
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
+
+    file_stat->size = (handle->ffd.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + handle->ffd.nFileSizeLow;
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
+
+    file_stat->atime = FileTimeToUnixTime(&handle->ffd.ftLastAccessTime, &rem);
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
+
+    file_stat->mtime = FileTimeToUnixTime(&handle->ffd.ftLastWriteTime, &rem);
+      /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
+
+    file_stat->ctime = FileTimeToUnixTime(&handle->ffd.ftCreationTime, &rem);
+    file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
+
+    return file_stat;
+
+err:
+  SAFE_FREE(file_stat);
+
+  return NULL;
+}
+
+
+
+int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
+    /* Almost nothing to do since csync_vio_local_readdir already filled up most of the information
+       But we still need to fetch the file ID.
+       Possible optimisation: only fetch the file id when we need it (for new files)
+      */
+
+    HANDLE h;
+    BY_HANDLE_FILE_INFORMATION fileInfo;
+    ULARGE_INTEGER FileIndex;
+    mbchar_t *wuri = c_utf8_path_to_locale( uri );
+
+    h = CreateFileW( wuri, 0, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
+                     NULL, OPEN_EXISTING,
+                     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
+                     NULL );
+    if( h == INVALID_HANDLE_VALUE ) {
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "CreateFileW failed on %s", uri );
+        errno = GetLastError();
+        c_free_locale_string(wuri);
+        return -1;
+    }
+
+    if(!GetFileInformationByHandle( h, &fileInfo ) ) {
+        CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "GetFileInformationByHandle failed on %s", uri );
+        errno = GetLastError();
+        c_free_locale_string(wuri);
+        CloseHandle(h);
+        return -1;
+    }
+
+    /* Get the Windows file id as an inode replacement. */
+    FileIndex.HighPart = fileInfo.nFileIndexHigh;
+    FileIndex.LowPart = fileInfo.nFileIndexLow;
+    FileIndex.QuadPart &= 0x0000FFFFFFFFFFFF;
+    /* printf("Index: %I64i\n", FileIndex.QuadPart); */
+    buf->inode = FileIndex.QuadPart;
+
+    if (!(buf->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE)) {
+        buf->size = (fileInfo.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + fileInfo.nFileSizeLow;
+        buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
+    }
+    if (!(buf->fields & CSYNC_VIO_FILE_STAT_FIELDS_MTIME)) {
+        DWORD rem;
+        buf->mtime = FileTimeToUnixTime(&fileInfo.ftLastWriteTime, &rem);
+        /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
+        buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
+    }
+
+    c_free_locale_string(wuri);
+    CloseHandle(h);
+    return 0;
+}
index 2157d3cd6833b42d30f99ddc4d5042a14bb48d56..f7cc0a9db6fb96105a186ecb9447570eb35465a8 100644 (file)
@@ -181,11 +181,9 @@ set(3rdparty_INC
 include_directories(${3rdparty_INC})
 
 # csync is required.
-include_directories(${CMAKE_SOURCE_DIR}/csync/src
-                    ${CMAKE_BINARY_DIR}/csync
-                    ${CMAKE_BINARY_DIR}/csync/src
+include_directories(${CMAKE_SOURCE_DIR}/src/csync
+                    ${CMAKE_BINARY_DIR}/src/csync
                    )
-
 include_directories(../libsync ${CMAKE_CURRENT_BINARY_DIR}/../libsync)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}
                     ${CMAKE_CURRENT_BINARY_DIR}
index 65d68823d1e7c7de15ccfc44d5dfcba827765ae6..865dad895e876bcc57b53fd35c0509c253ed5607 100644 (file)
@@ -5,9 +5,8 @@ configure_file( version.h.in "${CMAKE_CURRENT_BINARY_DIR}/version.h" )
 
 include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
 # csync is required.
-include_directories(${CMAKE_SOURCE_DIR}/csync/src
-                    ${CMAKE_BINARY_DIR}/csync
-                    ${CMAKE_BINARY_DIR}/csync/src
+include_directories(${CMAKE_SOURCE_DIR}/src/csync
+                    ${CMAKE_BINARY_DIR}/src/csync
                    )
 
 if ( APPLE )
index 0eb34e6097f07ccbd2e9705817e199f7c1f574d1..203c149889dc953b992ebcf53cc60d4095ccada8 100644 (file)
@@ -31,7 +31,7 @@
 #include "asserts.h"
 #include "checksums.h"
 
-#include "../../csync/src/std/c_jhash.h"
+#include "std/c_jhash.h"
 
 namespace OCC {
 
index ebf34920760c7b6e845bfd0838ee24a0958fdb88..d6b68cb5c27af8d42e76b2d641c2877f9738b6d1 100644 (file)
@@ -1,7 +1,17 @@
-include_directories(${CMAKE_BINARY_DIR}/csync ${CMAKE_BINARY_DIR}/csync/src ${CMAKE_BINARY_DIR}/src)
-include_directories(${CMAKE_SOURCE_DIR}/csync/src/)
-include_directories(${CMAKE_SOURCE_DIR}/csync/src/std ${CMAKE_SOURCE_DIR}/src)
-include_directories(${CMAKE_SOURCE_DIR}/src/3rdparty/qtokenizer)
+include_directories(${QT_INCLUDES}
+                    ${CMAKE_SOURCE_DIR}/src
+                    ${CMAKE_SOURCE_DIR}/src/3rdparty/qtokenizer
+                    ${CMAKE_SOURCE_DIR}/src/csync
+                    ${CMAKE_SOURCE_DIR}/src/csync/std
+                    ${CMAKE_SOURCE_DIR}/src/gui
+                    ${CMAKE_SOURCE_DIR}/src/libsync
+                    ${CMAKE_BINARY_DIR}/src/csync
+                    ${CMAKE_BINARY_DIR}/src/libsync
+                    ${CMAKE_CURRENT_SOURCE_DIR}
+                    ${CMAKE_CURRENT_BINARY_DIR}
+                   )
+
+include_directories()
 
 include(QtVersionAbstraction)
 setup_qt()
index ea9ca0e2f64afd8132388735cfdd15e5fd261d23..1d145b2409ded6c8944be1e924946fffaae5127d 100644 (file)
@@ -27,7 +27,7 @@
 #define CSYNC_TEST 1
 #include "csync_exclude.c"
 
-#define EXCLUDE_LIST_FILE SOURCEDIR"/../sync-exclude.lst"
+#define EXCLUDE_LIST_FILE SOURCEDIR"/../../sync-exclude.lst"
 
 static int setup(void **state) {
     CSYNC *csync;
index cefe264eac316aa5f72e6557fb960870cc152d56..7e7cc50577033eff6df5dd032076d19f6e5d856e 100644 (file)
@@ -1,11 +1,4 @@
 macro(owncloud_add_test test_class additional_cpp)
-    include_directories(${QT_INCLUDES}
-                        "${PROJECT_SOURCE_DIR}/src/gui"
-                        "${PROJECT_SOURCE_DIR}/src/libsync"
-                        "${CMAKE_BINARY_DIR}/src/libsync"
-                        "${CMAKE_CURRENT_BINARY_DIR}"
-                       )
-
     set(CMAKE_AUTOMOC TRUE)
     set(OWNCLOUD_TEST_CLASS ${test_class})
     string(TOLOWER "${OWNCLOUD_TEST_CLASS}" OWNCLOUD_TEST_CLASS_LOWERCASE)
@@ -27,14 +20,6 @@ macro(owncloud_add_test test_class additional_cpp)
 endmacro()
 
 macro(owncloud_add_benchmark test_class additional_cpp)
-    include_directories(${CMAKE_CURRENT_SOURCE_DIR}
-                        ${QT_INCLUDES}
-                        "${PROJECT_SOURCE_DIR}/src/gui"
-                        "${PROJECT_SOURCE_DIR}/src/libsync"
-                        "${CMAKE_BINARY_DIR}/src/libsync"
-                        "${CMAKE_CURRENT_BINARY_DIR}"
-                       )
-
     set(CMAKE_AUTOMOC TRUE)
     set(OWNCLOUD_TEST_CLASS ${test_class})
     string(TOLOWER "${OWNCLOUD_TEST_CLASS}" OWNCLOUD_TEST_CLASS_LOWERCASE)
index b52bfb5a9bbbd45c1424e803f1ccfc35ef67d0f7..cfaf734994504d24d7dd2c5a0d878b229a8b97f8 100644 (file)
@@ -11,7 +11,7 @@
 
 using namespace OCC;
 
-#define EXCLUDE_LIST_FILE SOURCEDIR"/../sync-exclude.lst"
+#define EXCLUDE_LIST_FILE SOURCEDIR"/../../sync-exclude.lst"
 
 class TestExcludedFiles: public QObject
 {
index 881bb865d2e0b332b28b89a3ebba383d0143a997..9e412aa85f2c76f028c3e0f72dc46ee76e9eda01 100644 (file)
@@ -8,8 +8,8 @@
 
 #include <sqlite3.h>
 
-#include "libsync/syncjournaldb.h"
-#include "libsync/syncjournalfilerecord.h"
+#include "syncjournaldb.h"
+#include "syncjournalfilerecord.h"
 
 using namespace OCC;