Merge csync inside the mirall repository
|
@ -6,9 +6,13 @@ CMakeLists.txt.user*
|
|||
*~
|
||||
*.autosave
|
||||
doc/_build/*
|
||||
*~
|
||||
*.kate-swp
|
||||
*.kdev4
|
||||
win/
|
||||
|
||||
admin/win/nsi/l10n/pofiles/*.po
|
||||
*.swp
|
||||
*~$
|
||||
build*
|
||||
cscope.*
|
||||
tags
|
||||
t1.cfg
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# - ADD_CHECK_TEST(test_name test_source linklib1 ... linklibN)
|
||||
|
||||
# Copyright (c) 2007 Daniel Gollub <dgollub@suse.de>
|
||||
# Copyright (c) 2007-2010 Andreas Schneider <asn@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
enable_testing()
|
||||
include(CTest)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
|
||||
set(CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
|
||||
set(CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
|
||||
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
|
||||
|
||||
function (ADD_CMOCKA_TEST _testName _testSource)
|
||||
add_executable(${_testName} ${_testSource})
|
||||
target_link_libraries(${_testName} ${ARGN})
|
||||
add_test(${_testName} ${CMAKE_CURRENT_BINARY_DIR}/${_testName})
|
||||
endfunction (ADD_CMOCKA_TEST)
|
|
@ -0,0 +1,22 @@
|
|||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,26 @@
|
|||
# - Check whether the C compiler supports a given flag in the
|
||||
# context of a stack checking compiler option.
|
||||
|
||||
# CHECK_C_COMPILER_FLAG_SSP(FLAG VARIABLE)
|
||||
#
|
||||
# FLAG - the compiler flag
|
||||
# VARIABLE - variable to store the result
|
||||
#
|
||||
# This actually calls check_c_source_compiles.
|
||||
# See help for CheckCSourceCompiles for a listing of variables
|
||||
# that can modify the build.
|
||||
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
function(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT)
|
||||
set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
|
||||
check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT})
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
|
||||
endfunction(CHECK_C_COMPILER_FLAG_SSP)
|
|
@ -0,0 +1,29 @@
|
|||
@CHECK_PROTOTYPE_DEFINITION_HEADER@
|
||||
|
||||
static void cmakeRequireSymbol(int dummy, ...) {
|
||||
(void) dummy;
|
||||
}
|
||||
|
||||
static void checkSymbol(void) {
|
||||
#ifndef @CHECK_PROTOTYPE_DEFINITION_SYMBOL@
|
||||
cmakeRequireSymbol(0, &@CHECK_PROTOTYPE_DEFINITION_SYMBOL@);
|
||||
#endif
|
||||
}
|
||||
|
||||
@CHECK_PROTOTYPE_DEFINITION_PROTO@ {
|
||||
return @CHECK_PROTOTYPE_DEFINITION_RETURN@;
|
||||
}
|
||||
|
||||
#ifdef __CLASSIC_C__
|
||||
int main() {
|
||||
int ac;
|
||||
char*av[];
|
||||
#else
|
||||
int main(int ac, char *av[]) {
|
||||
#endif
|
||||
checkSymbol();
|
||||
if (ac > 1000) {
|
||||
return *av[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
# - Check if the protoype we expect is correct.
|
||||
# check_prototype_definition(FUNCTION PROTOTYPE RETURN HEADER VARIABLE)
|
||||
# FUNCTION - The name of the function (used to check if prototype exists)
|
||||
# PROTOTYPE- The prototype to check.
|
||||
# RETURN - The return value of the function.
|
||||
# HEADER - The header files required.
|
||||
# VARIABLE - The variable to store the result.
|
||||
# Example:
|
||||
# check_prototype_definition(getpwent_r
|
||||
# "struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)"
|
||||
# "NULL"
|
||||
# "unistd.h;pwd.h"
|
||||
# SOLARIS_GETPWENT_R)
|
||||
# The following variables may be set before calling this macro to
|
||||
# modify the way the check is run:
|
||||
#
|
||||
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
|
||||
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
|
||||
# CMAKE_REQUIRED_INCLUDES = list of include directories
|
||||
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2005-2009 Kitware, Inc.
|
||||
# Copyright 2010-2011 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
#
|
||||
|
||||
|
||||
get_filename_component(__check_proto_def_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
|
||||
|
||||
function(CHECK_PROTOTYPE_DEFINITION _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE)
|
||||
|
||||
if ("${_VARIABLE}" MATCHES "^${_VARIABLE}$")
|
||||
set(CHECK_PROTOTYPE_DEFINITION_CONTENT "/* */\n")
|
||||
|
||||
set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
if (CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CHECK_PROTOTYPE_DEFINITION_LIBS
|
||||
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
|
||||
else()
|
||||
set(CHECK_PROTOTYPE_DEFINITION_LIBS)
|
||||
endif()
|
||||
if (CMAKE_REQUIRED_INCLUDES)
|
||||
set(CMAKE_SYMBOL_EXISTS_INCLUDES
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
||||
else()
|
||||
set(CMAKE_SYMBOL_EXISTS_INCLUDES)
|
||||
endif()
|
||||
|
||||
foreach(_FILE ${_HEADER})
|
||||
set(CHECK_PROTOTYPE_DEFINITION_HEADER
|
||||
"${CHECK_PROTOTYPE_DEFINITION_HEADER}#include <${_FILE}>\n")
|
||||
endforeach()
|
||||
|
||||
set(CHECK_PROTOTYPE_DEFINITION_SYMBOL ${_FUNCTION})
|
||||
set(CHECK_PROTOTYPE_DEFINITION_PROTO ${_PROTOTYPE})
|
||||
set(CHECK_PROTOTYPE_DEFINITION_RETURN ${_RETURN})
|
||||
|
||||
configure_file("${__check_proto_def_dir}/CheckPrototypeDefinition.c.in"
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c" @ONLY)
|
||||
|
||||
file(READ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c _SOURCE)
|
||||
|
||||
try_compile(${_VARIABLE}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
|
||||
${CHECK_PROTOTYPE_DEFINITION_LIBS}
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CHECK_PROTOTYPE_DEFINITION_FLAGS}
|
||||
"${CMAKE_SYMBOL_EXISTS_INCLUDES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
|
||||
if (${_VARIABLE})
|
||||
set(${_VARIABLE} 1 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
|
||||
message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - True")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} passed with the following output:\n"
|
||||
"${OUTPUT}\n\n")
|
||||
else ()
|
||||
message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - False")
|
||||
set(${_VARIABLE} 0 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} failed with the following output:\n"
|
||||
"${OUTPUT}\n\n${_SOURCE}\n\n")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
endfunction()
|
|
@ -0,0 +1,30 @@
|
|||
# Always include srcdir and builddir in include path
|
||||
# This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in
|
||||
# about every subdir
|
||||
# since cmake 2.4.0
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
# Put the include dirs which are in the source or build tree
|
||||
# before all other include dirs, so the headers in the sources
|
||||
# are prefered over the already installed ones
|
||||
# since cmake 2.4.1
|
||||
set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON)
|
||||
|
||||
# Use colored output
|
||||
# since cmake 2.4.0
|
||||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
|
||||
# Define the generic version of the libraries here
|
||||
set(GENERIC_LIB_VERSION "0.1.0")
|
||||
set(GENERIC_LIB_SOVERSION "0")
|
||||
|
||||
# set -Werror
|
||||
set(CMAKE_ENABLE_WERROR ON)
|
||||
|
||||
# Set the default build type to release with debug info
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo
|
||||
CACHE STRING
|
||||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
|
||||
)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
|
@ -0,0 +1,88 @@
|
|||
# define system dependent compiler flags
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCCompilerFlagSSP)
|
||||
|
||||
#
|
||||
# Define GNUCC compiler flags
|
||||
#
|
||||
if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
|
||||
|
||||
# add -Wconversion ?
|
||||
# cannot be pedantic with sqlite3 directly linked
|
||||
if (NOT CSYNC_STATIC_COMPILE_DIR)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -pedantic -pedantic-errors")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wshadow -Wmissing-prototypes -Wdeclaration-after-statement")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -Wfloat-equal -Wpointer-arith -Wwrite-strings -Wformat-security")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute -D_GNU_SOURCE")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__STDC_FORMAT_MACROS=1")
|
||||
|
||||
set(CSYNC_STRICT OFF CACHE BOOL "Strict error checking, enabled -Werror and friends")
|
||||
if (CSYNC_STRICT)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
||||
endif(CSYNC_STRICT)
|
||||
|
||||
# with -fPIC
|
||||
check_c_compiler_flag("-fPIC" WITH_FPIC)
|
||||
if (WITH_FPIC AND NOT WIN32)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
endif (WITH_FPIC AND NOT WIN32)
|
||||
|
||||
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
|
||||
if (WITH_STACK_PROTECTOR AND NOT WIN32)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
|
||||
endif (WITH_STACK_PROTECTOR AND NOT WIN32)
|
||||
|
||||
if (CMAKE_BUILD_TYPE)
|
||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
|
||||
if (CMAKE_BUILD_TYPE_LOWER MATCHES "(release|relwithdebinfo|minsizerel)")
|
||||
check_c_compiler_flag("-Wp,-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
|
||||
if (WITH_FORTIFY_SOURCE)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wp,-D_FORTIFY_SOURCE=2")
|
||||
endif (WITH_FORTIFY_SOURCE)
|
||||
endif()
|
||||
endif()
|
||||
endif (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
|
||||
|
||||
if (UNIX AND NOT WIN32)
|
||||
#
|
||||
# Check for large filesystem support
|
||||
#
|
||||
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
# with large file support
|
||||
execute_process(
|
||||
COMMAND
|
||||
getconf LFS64_CFLAGS
|
||||
OUTPUT_VARIABLE
|
||||
_lfs_CFLAGS
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
else (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
# with large file support
|
||||
execute_process(
|
||||
COMMAND
|
||||
getconf LFS_CFLAGS
|
||||
OUTPUT_VARIABLE
|
||||
_lfs_CFLAGS
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
if (_lfs_CFLAGS)
|
||||
string(REGEX REPLACE "[\r\n]" " " "${_lfs_CFLAGS}" "${${_lfs_CFLAGS}}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_lfs_CFLAGS}")
|
||||
endif (_lfs_CFLAGS)
|
||||
else(UNIX AND NOT WIN32)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FILE_OFFSET_BITS=64")
|
||||
endif (UNIX AND NOT WIN32)
|
||||
|
||||
if (MSVC)
|
||||
# Use secure functions by defaualt and suppress warnings about
|
||||
#"deprecated" functions
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
|
||||
endif (MSVC)
|
|
@ -0,0 +1,28 @@
|
|||
# Set system vars
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(LINUX TRUE)
|
||||
endif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
set(FREEBSD TRUE)
|
||||
set(BSD TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
|
||||
set(OPENBSD TRUE)
|
||||
set(BSD TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||
set(NETBSD TRUE)
|
||||
set(BSD TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
set(SOLARIS TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
||||
set(OS2 TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
|
@ -0,0 +1,49 @@
|
|||
# - Try to find CMocka
|
||||
# Once done this will define
|
||||
#
|
||||
# CMOCKA_ROOT_DIR - Set this variable to the root installation of CMocka
|
||||
#
|
||||
# Read-Only variables:
|
||||
# CMOCKA_FOUND - system has CMocka
|
||||
# CMOCKA_INCLUDE_DIR - the CMocka include directory
|
||||
# CMOCKA_LIBRARIES - Link these to use CMocka
|
||||
# CMOCKA_DEFINITIONS - Compiler switches required for using CMocka
|
||||
#
|
||||
#=============================================================================
|
||||
# Copyright (c) 2011-2012 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
#
|
||||
|
||||
find_path(CMOCKA_INCLUDE_DIR
|
||||
NAMES
|
||||
cmocka.h
|
||||
PATHS
|
||||
${CMOCKA_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
find_library(CMOCKA_LIBRARY
|
||||
NAMES
|
||||
cmocka
|
||||
PATHS
|
||||
${CMOCKA_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
if (CMOCKA_LIBRARY)
|
||||
set(CMOCKA_LIBRARIES
|
||||
${CMOCKA_LIBRARIES}
|
||||
${CMOCKA_LIBRARY}
|
||||
)
|
||||
endif (CMOCKA_LIBRARY)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(CMocka DEFAULT_MSG CMOCKA_LIBRARIES CMOCKA_INCLUDE_DIR)
|
||||
|
||||
# show the CMOCKA_INCLUDE_DIR and CMOCKA_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(CMOCKA_INCLUDE_DIR CMOCKA_LIBRARIES)
|
|
@ -0,0 +1,82 @@
|
|||
# - Try to find Iconv
|
||||
# Once done this will define
|
||||
#
|
||||
# ICONV_FOUND - system has Iconv
|
||||
# ICONV_INCLUDE_DIRS - the Iconv include directory
|
||||
# ICONV_LIBRARIES - Link these to use Iconv
|
||||
# ICONV_DEFINITIONS - Compiler switches required for using Iconv
|
||||
#
|
||||
# Copyright (c) 2013 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
include(CheckIncludeFile)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckPrototypeDefinition)
|
||||
|
||||
find_path(ICONV_INCLUDE_DIR
|
||||
NAMES
|
||||
iconv.h sys/iconv.h
|
||||
)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
|
||||
check_include_file(iconv.h HAVE_ICONV_H)
|
||||
check_include_file(sys/iconv.h HAVE_SYS_ICONV_H)
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
|
||||
find_library(ICONV_LIBRARY
|
||||
NAMES
|
||||
iconv
|
||||
libiconv
|
||||
PATHS
|
||||
)
|
||||
|
||||
if (ICONV_LIBRARY)
|
||||
get_filename_component(_ICONV_NAME ${ICONV_LIBRARY} NAME)
|
||||
get_filename_component(_ICONV_PATH ${ICONV_LIBRARY} PATH)
|
||||
check_library_exists(${_ICONV_NAME} iconv ${_ICONV_PATH} HAVE_ICONV)
|
||||
else()
|
||||
check_function_exists(iconv HAVE_ICONV)
|
||||
endif()
|
||||
|
||||
if (HAVE_ICONV_H OR HAVE_SYS_ICONV_H)
|
||||
if (HAVE_ICONV_H)
|
||||
set(_ICONV_PROTO_INCLUDE "iconv.h")
|
||||
endif (HAVE_ICONV_H)
|
||||
if (HAVE_SYS_ICONV_H)
|
||||
set(_ICONV_PROTO_INCLUDE "sys/iconv.h")
|
||||
endif (HAVE_SYS_ICONV_H)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
|
||||
check_prototype_definition(iconv
|
||||
"size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)"
|
||||
"-1"
|
||||
${_ICONV_PROTO_INCLUDE}
|
||||
HAVE_ICONV_CONST)
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
endif (HAVE_ICONV_H OR HAVE_SYS_ICONV_H)
|
||||
|
||||
set(ICONV_INCLUDE_DIRS
|
||||
${ICONV_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if (ICONV_LIBRARY)
|
||||
set(ICONV_LIBRARIES
|
||||
${ICONV_LIBRARIES}
|
||||
${ICONV_LIBRARY}
|
||||
)
|
||||
endif (ICONV_LIBRARY)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
if (ICONV_LIBRARIES)
|
||||
find_package_handle_standard_args(Iconv DEFAULT_MSG ICONV_LIBRARIES ICONV_INCLUDE_DIRS)
|
||||
else()
|
||||
find_package_handle_standard_args(Iconv DEFAULT_MSG ICONV_INCLUDE_DIRS)
|
||||
endif()
|
||||
|
||||
# show the ICONV_INCLUDE_DIRS and ICONV_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(ICONV_INCLUDE_DIRS ICONV_LIBRARIES)
|
|
@ -0,0 +1,96 @@
|
|||
# - Try to find LibSSH
|
||||
# Once done this will define
|
||||
#
|
||||
# LIBSSH_FOUND - system has LibSSH
|
||||
# LIBSSH_INCLUDE_DIRS - the LibSSH include directory
|
||||
# LIBSSH_LIBRARIES - Link these to use LibSSH
|
||||
# LIBSSH_DEFINITIONS - Compiler switches required for using LibSSH
|
||||
#
|
||||
# Copyright (c) 2009 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
if (LIBSSH_LIBRARIES AND LIBSSH_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(LIBSSH_FOUND TRUE)
|
||||
else (LIBSSH_LIBRARIES AND LIBSSH_INCLUDE_DIRS)
|
||||
|
||||
find_path(LIBSSH_INCLUDE_DIR
|
||||
NAMES
|
||||
libssh/libssh.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
${CMAKE_INCLUDE_PATH}
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
)
|
||||
|
||||
find_library(SSH_LIBRARY
|
||||
NAMES
|
||||
ssh
|
||||
libssh
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
${CMAKE_LIBRARY_PATH}
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
)
|
||||
|
||||
if (LIBSSH_INCLUDE_DIR AND SSH_LIBRARY)
|
||||
set(SSH_FOUND TRUE)
|
||||
endif (LIBSSH_INCLUDE_DIR AND SSH_LIBRARY)
|
||||
|
||||
set(LIBSSH_INCLUDE_DIRS
|
||||
${LIBSSH_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if (SSH_FOUND)
|
||||
set(LIBSSH_LIBRARIES
|
||||
${LIBSSH_LIBRARIES}
|
||||
${SSH_LIBRARY}
|
||||
)
|
||||
|
||||
if (LibSSH_FIND_VERSION)
|
||||
file(STRINGS ${LIBSSH_INCLUDE_DIR}/libssh/libssh.h LIBSSH_VERSION_MAJOR
|
||||
REGEX "#define[ ]+LIBSSH_VERSION_MAJOR[ ]+[0-9]+")
|
||||
# Older versions of libssh like libssh-0.2 have LIBSSH_VERSION but not LIBSSH_VERSION_MAJOR
|
||||
if (LIBSSH_VERSION_MAJOR)
|
||||
string(REGEX MATCH "[0-9]+" LIBSSH_VERSION_MAJOR ${LIBSSH_VERSION_MAJOR})
|
||||
file(STRINGS ${LIBSSH_INCLUDE_DIR}/libssh/libssh.h LIBSSH_VERSION_MINOR
|
||||
REGEX "#define[ ]+LIBSSH_VERSION_MINOR[ ]+[0-9]+")
|
||||
string(REGEX MATCH "[0-9]+" LIBSSH_VERSION_MINOR ${LIBSSH_VERSION_MINOR})
|
||||
file(STRINGS ${LIBSSH_INCLUDE_DIR}/libssh/libssh.h LIBSSH_VERSION_PATCH
|
||||
REGEX "#define[ ]+LIBSSH_VERSION_MICRO[ ]+[0-9]+")
|
||||
string(REGEX MATCH "[0-9]+" LIBSSH_VERSION_PATCH ${LIBSSH_VERSION_PATCH})
|
||||
|
||||
set(LibSSH_VERSION ${LIBSSH_VERSION_MAJOR}.${LIBSSH_VERSION_MINOR}.${LIBSSH_VERSION_PATCH})
|
||||
|
||||
include(FindPackageVersionCheck)
|
||||
find_package_version_check(LibSSH DEFAULT_MSG)
|
||||
else (LIBSSH_VERSION_MAJOR)
|
||||
message(STATUS "LIBSSH_VERSION_MAJOR not found in ${LIBSSH_INCLUDE_DIR}/libssh/libssh.h, assuming libssh is too old")
|
||||
set(LIBSSH_FOUND FALSE)
|
||||
endif (LIBSSH_VERSION_MAJOR)
|
||||
endif (LibSSH_FIND_VERSION)
|
||||
endif (SSH_FOUND)
|
||||
|
||||
# If the version is too old, but libs and includes are set,
|
||||
# find_package_handle_standard_args will set LIBSSH_FOUND to TRUE again,
|
||||
# so we need this if() here.
|
||||
if (LIBSSH_FOUND)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(LibSSH DEFAULT_MSG LIBSSH_LIBRARIES LIBSSH_INCLUDE_DIRS)
|
||||
endif (LIBSSH_FOUND)
|
||||
|
||||
# show the LIBSSH_INCLUDE_DIRS and LIBSSH_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(LIBSSH_INCLUDE_DIRS LIBSSH_LIBRARIES)
|
||||
|
||||
endif (LIBSSH_LIBRARIES AND LIBSSH_INCLUDE_DIRS)
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
# NEON_LIBRARIES - Link these to use Neon
|
||||
# NEON_DEFINITIONS - Compiler switches required for using Neon
|
||||
#
|
||||
# Copyright (c) 2011 Andreas Schneider <asn@cryptomilk.org>
|
||||
# Copyright (c) 2011-2013 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
|
|
|
@ -0,0 +1,306 @@
|
|||
# - Try to find the OpenSSL encryption library
|
||||
# Once done this will define
|
||||
#
|
||||
# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL
|
||||
#
|
||||
# Read-Only variables:
|
||||
# OPENSSL_FOUND - system has the OpenSSL library
|
||||
# OPENSSL_INCLUDE_DIR - the OpenSSL include directory
|
||||
# OPENSSL_LIBRARIES - The libraries needed to use OpenSSL
|
||||
# OPENSSL_VERSION - This is set to $major.$minor.$revision$path (eg. 0.9.8s)
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2006-2009 Kitware, Inc.
|
||||
# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
|
||||
# Copyright 2009-2011 Mathieu Malaterre <mathieu.malaterre@gmail.com>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
if (UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(_OPENSSL QUIET openssl)
|
||||
endif (UNIX)
|
||||
|
||||
# http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
SET(_OPENSSL_ROOT_HINTS
|
||||
$ENV{OPENSSL_ROOT_DIR}
|
||||
${OPENSSL_ROOT_DIR}
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
|
||||
)
|
||||
SET(_OPENSSL_ROOT_PATHS
|
||||
"$ENV{PROGRAMFILES}/OpenSSL"
|
||||
"$ENV{PROGRAMFILES}/OpenSSL-Win32"
|
||||
"$ENV{PROGRAMFILES}/OpenSSL-Win64"
|
||||
"C:/OpenSSL/"
|
||||
"C:/OpenSSL-Win32/"
|
||||
"C:/OpenSSL-Win64/"
|
||||
)
|
||||
SET(_OPENSSL_ROOT_HINTS_AND_PATHS
|
||||
HINTS ${_OPENSSL_ROOT_HINTS}
|
||||
PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
)
|
||||
|
||||
FIND_PATH(OPENSSL_INCLUDE_DIR
|
||||
NAMES
|
||||
openssl/ssl.h
|
||||
HINTS
|
||||
${_OPENSSL_INCLUDEDIR}
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
||||
IF(WIN32 AND NOT CYGWIN)
|
||||
# MINGW should go here too
|
||||
IF(MSVC)
|
||||
# /MD and /MDd are the standard values - if someone wants to use
|
||||
# others, the libnames have to change here too
|
||||
# use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b
|
||||
# TODO: handle /MT and static lib
|
||||
# In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix:
|
||||
# * MD for dynamic-release
|
||||
# * MDd for dynamic-debug
|
||||
# * MT for static-release
|
||||
# * MTd for static-debug
|
||||
|
||||
# Implementation details:
|
||||
# We are using the libraries located in the VC subdir instead of the parent directory eventhough :
|
||||
# libeay32MD.lib is identical to ../libeay32.lib, and
|
||||
# ssleay32MD.lib is identical to ../ssleay32.lib
|
||||
FIND_LIBRARY(LIB_EAY_DEBUG
|
||||
NAMES
|
||||
libeay32MDd
|
||||
libeay32
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"VC"
|
||||
"lib/VC"
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LIB_EAY_RELEASE
|
||||
NAMES
|
||||
libeay32MD
|
||||
libeay32
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"VC"
|
||||
"lib/VC"
|
||||
)
|
||||
|
||||
FIND_LIBRARY(SSL_EAY_DEBUG
|
||||
NAMES
|
||||
ssleay32MDd
|
||||
ssleay32
|
||||
ssl
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"VC"
|
||||
"lib/VC"
|
||||
)
|
||||
|
||||
FIND_LIBRARY(SSL_EAY_RELEASE
|
||||
NAMES
|
||||
ssleay32MD
|
||||
ssleay32
|
||||
ssl
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"VC"
|
||||
"lib/VC"
|
||||
)
|
||||
|
||||
if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
|
||||
set( OPENSSL_LIBRARIES
|
||||
optimized ${SSL_EAY_RELEASE} debug ${SSL_EAY_DEBUG}
|
||||
optimized ${LIB_EAY_RELEASE} debug ${LIB_EAY_DEBUG}
|
||||
)
|
||||
else()
|
||||
set( OPENSSL_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
|
||||
endif()
|
||||
MARK_AS_ADVANCED(SSL_EAY_DEBUG SSL_EAY_RELEASE)
|
||||
MARK_AS_ADVANCED(LIB_EAY_DEBUG LIB_EAY_RELEASE)
|
||||
ELSEIF(MINGW)
|
||||
# same player, for MingW
|
||||
FIND_LIBRARY(LIB_EAY
|
||||
NAMES
|
||||
libeay32
|
||||
crypto
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"lib/MinGW"
|
||||
)
|
||||
|
||||
FIND_LIBRARY(SSL_EAY
|
||||
NAMES
|
||||
ssleay32
|
||||
ssl
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
"lib"
|
||||
"lib/MinGW"
|
||||
)
|
||||
|
||||
MARK_AS_ADVANCED(SSL_EAY LIB_EAY)
|
||||
set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
|
||||
ELSE(MSVC)
|
||||
# Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues:
|
||||
FIND_LIBRARY(LIB_EAY
|
||||
NAMES
|
||||
libeay32
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
FIND_LIBRARY(SSL_EAY
|
||||
NAMES
|
||||
ssleay32
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
MARK_AS_ADVANCED(SSL_EAY LIB_EAY)
|
||||
set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
|
||||
ENDIF(MSVC)
|
||||
ELSE(WIN32 AND NOT CYGWIN)
|
||||
|
||||
FIND_LIBRARY(OPENSSL_SSL_LIBRARY
|
||||
NAMES
|
||||
ssl
|
||||
ssleay32
|
||||
ssleay32MD
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
FIND_LIBRARY(OPENSSL_CRYPTO_LIBRARY
|
||||
NAMES
|
||||
crypto
|
||||
HINTS
|
||||
${_OPENSSL_LIBDIR}
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES
|
||||
lib
|
||||
)
|
||||
|
||||
MARK_AS_ADVANCED(OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY)
|
||||
|
||||
# compat defines
|
||||
SET(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY})
|
||||
SET(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
|
||||
SET(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
|
||||
|
||||
ENDIF(WIN32 AND NOT CYGWIN)
|
||||
|
||||
function(from_hex HEX DEC)
|
||||
string(TOUPPER "${HEX}" HEX)
|
||||
set(_res 0)
|
||||
string(LENGTH "${HEX}" _strlen)
|
||||
|
||||
while (_strlen GREATER 0)
|
||||
math(EXPR _res "${_res} * 16")
|
||||
string(SUBSTRING "${HEX}" 0 1 NIBBLE)
|
||||
string(SUBSTRING "${HEX}" 1 -1 HEX)
|
||||
if (NIBBLE STREQUAL "A")
|
||||
math(EXPR _res "${_res} + 10")
|
||||
elseif (NIBBLE STREQUAL "B")
|
||||
math(EXPR _res "${_res} + 11")
|
||||
elseif (NIBBLE STREQUAL "C")
|
||||
math(EXPR _res "${_res} + 12")
|
||||
elseif (NIBBLE STREQUAL "D")
|
||||
math(EXPR _res "${_res} + 13")
|
||||
elseif (NIBBLE STREQUAL "E")
|
||||
math(EXPR _res "${_res} + 14")
|
||||
elseif (NIBBLE STREQUAL "F")
|
||||
math(EXPR _res "${_res} + 15")
|
||||
else()
|
||||
math(EXPR _res "${_res} + ${NIBBLE}")
|
||||
endif()
|
||||
|
||||
string(LENGTH "${HEX}" _strlen)
|
||||
endwhile()
|
||||
|
||||
set(${DEC} ${_res} PARENT_SCOPE)
|
||||
endfunction(from_hex)
|
||||
|
||||
if (OPENSSL_INCLUDE_DIR)
|
||||
if (_OPENSSL_VERSION)
|
||||
set(OPENSSL_VERSION "${_OPENSSL_VERSION}")
|
||||
elseif(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h")
|
||||
file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str
|
||||
REGEX "^#define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*")
|
||||
|
||||
# The version number is encoded as 0xMNNFFPPS: major minor fix patch status
|
||||
# The status gives if this is a developer or prerelease and is ignored here.
|
||||
# Major, minor, and fix directly translate into the version numbers shown in
|
||||
# the string. The patch field translates to the single character suffix that
|
||||
# indicates the bug fix state, which 00 -> nothing, 01 -> a, 02 -> b and so
|
||||
# on.
|
||||
|
||||
string(REGEX REPLACE "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F]).*$"
|
||||
"\\1;\\2;\\3;\\4;\\5" OPENSSL_VERSION_LIST "${openssl_version_str}")
|
||||
list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR)
|
||||
list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR)
|
||||
from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR)
|
||||
list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX)
|
||||
from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX)
|
||||
list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH)
|
||||
|
||||
if (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
||||
from_hex("${OPENSSL_VERSION_PATCH}" _tmp)
|
||||
# 96 is the ASCII code of 'a' minus 1
|
||||
math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96")
|
||||
unset(_tmp)
|
||||
# Once anyone knows how OpenSSL would call the patch versions beyond 'z'
|
||||
# this should be updated to handle that, too. This has not happened yet
|
||||
# so it is simply ignored here for now.
|
||||
string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING)
|
||||
endif (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
||||
|
||||
set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}")
|
||||
endif (_OPENSSL_VERSION)
|
||||
endif (OPENSSL_INCLUDE_DIR)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
if (OPENSSL_VERSION)
|
||||
find_package_handle_standard_args(OpenSSL
|
||||
REQUIRED_VARS
|
||||
OPENSSL_LIBRARIES
|
||||
OPENSSL_INCLUDE_DIR
|
||||
VERSION_VAR
|
||||
OPENSSL_VERSION
|
||||
FAIL_MESSAGE
|
||||
"Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
|
||||
)
|
||||
else (OPENSSL_VERSION)
|
||||
find_package_handle_standard_args(OpenSSL "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
|
||||
OPENSSL_LIBRARIES
|
||||
OPENSSL_INCLUDE_DIR
|
||||
)
|
||||
endif (OPENSSL_VERSION)
|
||||
|
||||
MARK_AS_ADVANCED(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
|
|
@ -0,0 +1,68 @@
|
|||
# FIND_PACKAGE_VERSION_CHECK(NAME (DEFAULT_MSG|"Custom failure message"))
|
||||
# This function is intended to be used in FindXXX.cmake modules files.
|
||||
# It handles NAME_FIND_VERSION and NAME_VERSION variables in a Module.
|
||||
#
|
||||
# Example:
|
||||
# find_package(LibSSH 0.3.2)
|
||||
#
|
||||
# # check for the version and set it
|
||||
# set(LibSSH_VERSION 0.3.0)
|
||||
# find_package_version_check(LibSSH DEFAULT_MSG)
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2009 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
|
||||
function(FIND_PACKAGE_VERSION_CHECK _NAME _FAIL_MSG)
|
||||
string(TOUPPER ${_NAME} _NAME_UPPER)
|
||||
set(_AGE "old")
|
||||
|
||||
if(${_NAME}_FIND_VERSION_EXACT)
|
||||
if (${_NAME}_FIND_VERSION VERSION_EQUAL ${_NAME}_VERSION)
|
||||
# exact version found
|
||||
set(${_NAME_UPPER}_FOUND TRUE)
|
||||
else (${_NAME}_FIND_VERSION VERSION_EQUAL ${_NAME}_VERSION)
|
||||
# exect version not found
|
||||
set(${_NAME_UPPER}_FOUND FALSE)
|
||||
# check if newer or older
|
||||
if (${_NAME}_FIND_VERSION VERSION_LESS ${_NAME}_VERSION)
|
||||
set(_AGE "new")
|
||||
else (${_NAME}_FIND_VERSION VERSION_LESS ${_NAME}_VERSION)
|
||||
set(_AGE "old")
|
||||
endif (${_NAME}_FIND_VERSION VERSION_LESS ${_NAME}_VERSION)
|
||||
endif (${_NAME}_FIND_VERSION VERSION_EQUAL ${_NAME}_VERSION)
|
||||
else (${_NAME}_FIND_VERSION_EXACT)
|
||||
if (${_NAME}_FIND_VERSION)
|
||||
if (${_NAME}_VERSION VERSION_LESS ${_NAME}_FIND_VERSION)
|
||||
set(${_NAME_UPPER}_FOUND FALSE)
|
||||
set(_AGE "old")
|
||||
else (${_NAME}_VERSION VERSION_LESS ${_NAME}_FIND_VERSION)
|
||||
set(${_NAME_UPPER}_FOUND TRUE)
|
||||
endif (${_NAME}_VERSION VERSION_LESS ${_NAME}_FIND_VERSION)
|
||||
endif (${_NAME}_FIND_VERSION)
|
||||
endif(${_NAME}_FIND_VERSION_EXACT)
|
||||
|
||||
if ("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")
|
||||
if (${_NAME}_FIND_VERSION_EXACT)
|
||||
set(_FAIL_MESSAGE "The installed ${_NAME} version ${${_NAME}_VERSION} is too ${_AGE}, version ${${_NAME}_FIND_VERSION} is required.")
|
||||
else (${_NAME}_FIND_VERSION_EXACT)
|
||||
set(_FAIL_MESSAGE "The installed ${_NAME} version ${${_NAME}_VERSION} is too ${_AGE}, at least version ${${_NAME}_FIND_VERSION} is required.")
|
||||
endif (${_NAME}_FIND_VERSION_EXACT)
|
||||
else ("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")
|
||||
set(_FAIL_MESSAGE "${_FAIL_MSG}")
|
||||
endif ("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")
|
||||
|
||||
if (NOT ${_NAME_UPPER}_FOUND)
|
||||
if (${_NAME}_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "${_FAIL_MESSAGE}")
|
||||
else (${_NAME}_FIND_REQUIRED)
|
||||
if (NOT ${_NAME}_FIND_QUIETLY)
|
||||
message(STATUS "${_FAIL_MESSAGE}")
|
||||
endif (NOT ${_NAME}_FIND_QUIETLY)
|
||||
endif (${_NAME}_FIND_REQUIRED)
|
||||
endif (NOT ${_NAME_UPPER}_FOUND)
|
||||
|
||||
set(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE)
|
||||
endfunction(FIND_PACKAGE_VERSION_CHECK)
|
|
@ -0,0 +1,66 @@
|
|||
# - Try to find SMBClient
|
||||
# Once done this will define
|
||||
#
|
||||
# SMBCLIENT_FOUND - system has SMBClient
|
||||
# SMBCLIENT_INCLUDE_DIRS - the SMBClient include directory
|
||||
# SMBCLIENT_LIBRARIES - Link these to use SMBClient
|
||||
# SMBCLIENT_DEFINITIONS - Compiler switches required for using SMBClient
|
||||
#
|
||||
# Copyright (c) 2013 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (SMBCLIENT_LIBRARIES AND SMBCLIENT_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(SMBCLIENT_FOUND TRUE)
|
||||
else (SMBCLIENT_LIBRARIES AND SMBCLIENT_INCLUDE_DIRS)
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(_SMBCLIENT smbclient)
|
||||
endif (PKG_CONFIG_FOUND)
|
||||
|
||||
find_path(SMBCLIENT_INCLUDE_DIR
|
||||
NAMES
|
||||
libsmbclient.h
|
||||
PATHS
|
||||
${_SMBCLIENT_INCLUDEDIR}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
)
|
||||
|
||||
find_library(SMBCLIENT_LIBRARY
|
||||
NAMES
|
||||
smbclient
|
||||
PATHS
|
||||
${_SMBCLIENT_LIBDIR}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
set(SMBCLIENT_INCLUDE_DIRS
|
||||
${SMBCLIENT_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if (SMBCLIENT_LIBRARY)
|
||||
set(SMBCLIENT_LIBRARIES
|
||||
${SMBCLIENT_LIBRARIES}
|
||||
${SMBCLIENT_LIBRARY}
|
||||
)
|
||||
endif (SMBCLIENT_LIBRARY)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(SMBClient DEFAULT_MSG SMBCLIENT_LIBRARIES SMBCLIENT_INCLUDE_DIRS)
|
||||
|
||||
# show the SMBCLIENT_INCLUDE_DIRS and SMBCLIENT_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(SMBCLIENT_INCLUDE_DIRS SMBCLIENT_LIBRARIES)
|
||||
|
||||
endif (SMBCLIENT_LIBRARIES AND SMBCLIENT_INCLUDE_DIRS)
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# - Try to find SQLite3
|
||||
# Once done this will define
|
||||
#
|
||||
# SQLITE3_FOUND - system has SQLite3
|
||||
# SQLITE3_INCLUDE_DIRS - the SQLite3 include directory
|
||||
# SQLITE3_LIBRARIES - Link these to use SQLite3
|
||||
# SQLITE3_DEFINITIONS - Compiler switches required for using SQLite3
|
||||
#
|
||||
# Copyright (c) 2009-2013 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (UNIX)
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(_SQLITE3 sqlite3)
|
||||
endif (PKG_CONFIG_FOUND)
|
||||
endif (UNIX)
|
||||
|
||||
find_path(SQLITE3_INCLUDE_DIR
|
||||
NAMES
|
||||
sqlite3.h
|
||||
PATHS
|
||||
${_SQLITE3_INCLUDEDIR}
|
||||
)
|
||||
|
||||
find_library(SQLITE3_LIBRARY
|
||||
NAMES
|
||||
sqlite3
|
||||
PATHS
|
||||
${_SQLITE3_LIBDIR}
|
||||
)
|
||||
|
||||
set(SQLITE3_INCLUDE_DIRS
|
||||
${SQLITE3_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if (SQLITE3_LIBRARY)
|
||||
set(SQLITE3_LIBRARIES
|
||||
${SQLITE3_LIBRARIES}
|
||||
${SQLITE3_LIBRARY}
|
||||
)
|
||||
endif (SQLITE3_LIBRARY)
|
||||
|
||||
if (SQLite3_FIND_VERSION AND _SQLITE3_VERSION)
|
||||
set(SQLite3_VERSION _SQLITE3_VERSION)
|
||||
endif (SQLite3_FIND_VERSION AND _SQLITE3_VERSION)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(SQLite3 DEFAULT_MSG SQLITE3_LIBRARIES SQLITE3_INCLUDE_DIRS)
|
||||
|
||||
# show the SQLITE3_INCLUDE_DIRS and SQLITE3_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# - MACRO_ADD_COMPILE_FLAGS(target_name flag1 ... flagN)
|
||||
|
||||
# Copyright (c) 2006, Oswald Buddenhagen, <ossi@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
macro (MACRO_ADD_COMPILE_FLAGS _target)
|
||||
|
||||
get_target_property(_flags ${_target} COMPILE_FLAGS)
|
||||
if (_flags)
|
||||
set(_flags ${_flags} ${ARGN})
|
||||
else (_flags)
|
||||
set(_flags ${ARGN})
|
||||
endif (_flags)
|
||||
|
||||
set_target_properties(${_target} PROPERTIES COMPILE_FLAGS ${_flags})
|
||||
|
||||
endmacro (MACRO_ADD_COMPILE_FLAGS)
|
|
@ -0,0 +1,20 @@
|
|||
# - MACRO_ADD_LINK_FLAGS(target_name flag1 ... flagN)
|
||||
|
||||
# Copyright (c) 2006, Oswald Buddenhagen, <ossi@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
macro (MACRO_ADD_LINK_FLAGS _target)
|
||||
|
||||
get_target_property(_flags ${_target} LINK_FLAGS)
|
||||
if (_flags)
|
||||
set(_flags "${_flags} ${ARGN}")
|
||||
else (_flags)
|
||||
set(_flags "${ARGN}")
|
||||
endif (_flags)
|
||||
|
||||
set_target_properties(${_target} PROPERTIES LINK_FLAGS "${_flags}")
|
||||
|
||||
endmacro (MACRO_ADD_LINK_FLAGS)
|
|
@ -0,0 +1,30 @@
|
|||
# - MACRO_ADD_PLUGIN(name [WITH_PREFIX] file1 .. fileN)
|
||||
#
|
||||
# Create a plugin from the given source files.
|
||||
# If WITH_PREFIX is given, the resulting plugin will have the
|
||||
# prefix "lib", otherwise it won't.
|
||||
#
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
# Copyright (c) 2006, Laurent Montel, <montel@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
macro (MACRO_ADD_PLUGIN _target_NAME _with_PREFIX)
|
||||
|
||||
if (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
set(_first_SRC)
|
||||
else (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
set(_first_SRC ${_with_PREFIX})
|
||||
endif (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
|
||||
add_library(${_target_NAME} MODULE ${_first_SRC} ${ARGN})
|
||||
|
||||
if (_first_SRC)
|
||||
set_target_properties(${_target_NAME} PROPERTIES PREFIX "")
|
||||
endif (_first_SRC)
|
||||
|
||||
endmacro (MACRO_ADD_PLUGIN _name _sources)
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# - macro_copy_file(_src _dst)
|
||||
# Copies a file to ${_dst} only if ${_src} is different (newer) than ${_dst}
|
||||
#
|
||||
# Example:
|
||||
# macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/icon.png ${CMAKE_CURRENT_BINARY_DIR}/.)
|
||||
# Copies file icon.png to ${CMAKE_CURRENT_BINARY_DIR} directory
|
||||
#
|
||||
# Copyright (c) 2006-2007 Wengo
|
||||
# Copyright (c) 2006-2008 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING file.
|
||||
|
||||
|
||||
macro (macro_copy_file _src _dst)
|
||||
# Removes all path containing .svn or CVS or CMakeLists.txt during the copy
|
||||
if (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*")
|
||||
|
||||
if (CMAKE_VERBOSE_MAKEFILE)
|
||||
message(STATUS "Copy file from ${_src} to ${_dst}")
|
||||
endif (CMAKE_VERBOSE_MAKEFILE)
|
||||
|
||||
# Creates directory if necessary
|
||||
get_filename_component(_path ${_dst} PATH)
|
||||
file(MAKE_DIRECTORY ${_path})
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_if_different ${_src} ${_dst}
|
||||
OUTPUT_QUIET
|
||||
)
|
||||
endif (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*")
|
||||
endmacro (macro_copy_file)
|
|
@ -0,0 +1,17 @@
|
|||
# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
|
||||
# MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>)
|
||||
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
macro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage)
|
||||
|
||||
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource)
|
||||
if (_insource)
|
||||
message(SEND_ERROR "${_errorMessage}")
|
||||
message(FATAL_ERROR "Remove the file CMakeCache.txt in ${CMAKE_SOURCE_DIR} first.")
|
||||
endif (_insource)
|
||||
|
||||
endmacro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD)
|
|
@ -0,0 +1,58 @@
|
|||
# - macro_asciidoc2man(inputfile outputfile)
|
||||
#
|
||||
# Create a manpage with asciidoc.
|
||||
# Example: macro_asciidoc2man(foo.txt foo.1)
|
||||
#
|
||||
# Copyright (c) 2006, Andreas Schneider, <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
include(MacroCopyFile)
|
||||
|
||||
macro(MACRO_ASCIIDOC2MAN _a2m_input _a2m_output)
|
||||
find_program(A2X
|
||||
NAMES
|
||||
a2x
|
||||
)
|
||||
#message("+++ A2X: ${A2X}")
|
||||
|
||||
if (A2X)
|
||||
|
||||
#message("+++ ${A2X} --doctype=manpage --format=manpage --destination-dir=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${_a2m_input}")
|
||||
macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/${_a2m_input} ${CMAKE_CURRENT_BINARY_DIR}/${_a2m_input})
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${A2X} --doctype=manpage --format=manpage ${_a2m_input}
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
RESULT_VARIABLE
|
||||
A2M_MAN_GENERATED
|
||||
ERROR_QUIET
|
||||
)
|
||||
|
||||
#message("+++ A2M_MAN_GENERATED: ${A2M_MAN_GENERATED}")
|
||||
if (A2M_MAN_GENERATED EQUAL 0)
|
||||
find_file(A2M_MAN_FILE
|
||||
NAME
|
||||
${_a2m_output}
|
||||
PATHS
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
if (A2M_MAN_FILE)
|
||||
get_filename_component(A2M_MAN_CATEGORY ${A2M_MAN_FILE} EXT)
|
||||
string(SUBSTRING ${A2M_MAN_CATEGORY} 1 1 A2M_MAN_CATEGORY)
|
||||
install(
|
||||
FILES
|
||||
${A2M_MAN_FILE}
|
||||
DESTINATION
|
||||
${MAN_INSTALL_DIR}/man${A2M_MAN_CATEGORY}
|
||||
)
|
||||
endif (A2M_MAN_FILE)
|
||||
endif (A2M_MAN_GENERATED EQUAL 0)
|
||||
|
||||
endif (A2X)
|
||||
endmacro(MACRO_ASCIIDOC2MAN _a2m_input _a2m_file)
|
|
@ -0,0 +1,127 @@
|
|||
# -helper macro to add a "doc" target with CMake build system.
|
||||
# and configure doxy.config.in to doxy.config
|
||||
#
|
||||
# target "doc" allows building the documentation with doxygen/dot on WIN32 and Linux
|
||||
# Creates .chm windows help file if MS HTML help workshop
|
||||
# (available from http://msdn.microsoft.com/workshop/author/htmlhelp)
|
||||
# is installed with its DLLs in PATH.
|
||||
#
|
||||
#
|
||||
# Please note, that the tools, e.g.:
|
||||
# doxygen, dot, latex, dvips, makeindex, gswin32, etc.
|
||||
# must be in path.
|
||||
#
|
||||
# Note about Visual Studio Projects:
|
||||
# MSVS has its own path environment which may differ from the shell.
|
||||
# See "Menu Tools/Options/Projects/VC++ Directories" in VS 7.1
|
||||
#
|
||||
# author Jan Woetzel 2004-2006
|
||||
# www.mip.informatik.uni-kiel.de/~jw
|
||||
|
||||
|
||||
FIND_PACKAGE(Doxygen)
|
||||
|
||||
IF (DOXYGEN_FOUND)
|
||||
|
||||
# click+jump in Emacs and Visual Studio (for doxy.config) (jw)
|
||||
IF (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
|
||||
SET(DOXY_WARN_FORMAT "\"$file($line) : $text \"")
|
||||
ELSE (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
|
||||
SET(DOXY_WARN_FORMAT "\"$file:$line: $text \"")
|
||||
ENDIF (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
|
||||
|
||||
# we need latex for doxygen because of the formulas
|
||||
FIND_PACKAGE(LATEX)
|
||||
IF (NOT LATEX_COMPILER)
|
||||
MESSAGE(STATUS "latex command LATEX_COMPILER not found but usually required. You will probably get warnings and user inetraction on doxy run.")
|
||||
ENDIF (NOT LATEX_COMPILER)
|
||||
IF (NOT MAKEINDEX_COMPILER)
|
||||
MESSAGE(STATUS "makeindex command MAKEINDEX_COMPILER not found but usually required.")
|
||||
ENDIF (NOT MAKEINDEX_COMPILER)
|
||||
IF (NOT DVIPS_CONVERTER)
|
||||
MESSAGE(STATUS "dvips command DVIPS_CONVERTER not found but usually required.")
|
||||
ENDIF (NOT DVIPS_CONVERTER)
|
||||
FIND_PROGRAM(DOXYGEN_DOT_EXECUTABLE_PATH NAMES dot)
|
||||
IF (DOXYGEN_DOT_EXECUTABLE_PATH)
|
||||
SET(DOXYGEN_DOT_FOUND "YES")
|
||||
ENDIF (DOXYGEN_DOT_EXECUTABLE_PATH)
|
||||
|
||||
IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in")
|
||||
MESSAGE(STATUS "Generate ${CMAKE_CURRENT_BINARY_DIR}/doxy.config from doxy.config.in")
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/doxy.config
|
||||
@ONLY )
|
||||
# use (configured) doxy.config from (out of place) BUILD tree:
|
||||
SET(DOXY_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/doxy.config")
|
||||
ELSE (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in")
|
||||
# use static hand-edited doxy.config from SOURCE tree:
|
||||
SET(DOXY_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
|
||||
IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
|
||||
MESSAGE(STATUS "WARNING: using existing ${CMAKE_CURRENT_SOURCE_DIR}/doxy.config instead of configuring from doxy.config.in file.")
|
||||
ELSE (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
|
||||
IF (EXISTS "${CMAKE_MODULE_PATH}/doxy.config.in")
|
||||
# using template doxy.config.in
|
||||
MESSAGE(STATUS "Generate ${CMAKE_CURRENT_BINARY_DIR}/doxy.config from doxy.config.in")
|
||||
CONFIGURE_FILE(${CMAKE_MODULE_PATH}/doxy.config.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/doxy.config
|
||||
@ONLY )
|
||||
SET(DOXY_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/doxy.config")
|
||||
ELSE (EXISTS "${CMAKE_MODULE_PATH}/doxy.config.in")
|
||||
# failed completely...
|
||||
MESSAGE(SEND_ERROR "Please create ${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in (or doxy.config as fallback)")
|
||||
ENDIF(EXISTS "${CMAKE_MODULE_PATH}/doxy.config.in")
|
||||
|
||||
ENDIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config")
|
||||
ENDIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in")
|
||||
|
||||
ADD_CUSTOM_TARGET(doc ${DOXYGEN_EXECUTABLE} ${DOXY_CONFIG} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doxy.config)
|
||||
|
||||
# create a windows help .chm file using hhc.exe
|
||||
# HTMLHelp DLL must be in path!
|
||||
# fallback: use hhw.exe interactively
|
||||
IF (WIN32)
|
||||
FIND_PACKAGE(HTMLHelp)
|
||||
IF (HTML_HELP_COMPILER)
|
||||
SET (TMP "${CMAKE_CURRENT_BINARY_DIR}\\doc\\html\\index.hhp")
|
||||
STRING(REGEX REPLACE "[/]" "\\\\" HHP_FILE ${TMP} )
|
||||
# MESSAGE(SEND_ERROR "DBG HHP_FILE=${HHP_FILE}")
|
||||
ADD_CUSTOM_TARGET(winhelp ${HTML_HELP_COMPILER} ${HHP_FILE})
|
||||
ADD_DEPENDENCIES (winhelp doc)
|
||||
|
||||
IF (NOT TARGET_DOC_SKIP_INSTALL)
|
||||
# install windows help?
|
||||
# determine useful name for output file
|
||||
# should be project and version unique to allow installing
|
||||
# multiple projects into one global directory
|
||||
IF (EXISTS "${PROJECT_BINARY_DIR}/doc/html/index.chm")
|
||||
IF (PROJECT_NAME)
|
||||
SET(OUT "${PROJECT_NAME}")
|
||||
ELSE (PROJECT_NAME)
|
||||
SET(OUT "Documentation") # default
|
||||
ENDIF(PROJECT_NAME)
|
||||
IF (${PROJECT_NAME}_VERSION_MAJOR)
|
||||
SET(OUT "${OUT}-${${PROJECT_NAME}_VERSION_MAJOR}")
|
||||
IF (${PROJECT_NAME}_VERSION_MINOR)
|
||||
SET(OUT "${OUT}.${${PROJECT_NAME}_VERSION_MINOR}")
|
||||
IF (${PROJECT_NAME}_VERSION_PATCH)
|
||||
SET(OUT "${OUT}.${${PROJECT_NAME}_VERSION_PATCH}")
|
||||
ENDIF(${PROJECT_NAME}_VERSION_PATCH)
|
||||
ENDIF(${PROJECT_NAME}_VERSION_MINOR)
|
||||
ENDIF(${PROJECT_NAME}_VERSION_MAJOR)
|
||||
# keep suffix
|
||||
SET(OUT "${OUT}.chm")
|
||||
|
||||
#MESSAGE("DBG ${PROJECT_BINARY_DIR}/doc/html/index.chm \n${OUT}")
|
||||
# create target used by install and package commands
|
||||
INSTALL(FILES "${PROJECT_BINARY_DIR}/doc/html/index.chm"
|
||||
DESTINATION "doc"
|
||||
RENAME "${OUT}"
|
||||
)
|
||||
ENDIF(EXISTS "${PROJECT_BINARY_DIR}/doc/html/index.chm")
|
||||
ENDIF(NOT TARGET_DOC_SKIP_INSTALL)
|
||||
|
||||
ENDIF(HTML_HELP_COMPILER)
|
||||
# MESSAGE(SEND_ERROR "HTML_HELP_COMPILER=${HTML_HELP_COMPILER}")
|
||||
ENDIF (WIN32)
|
||||
ENDIF(DOXYGEN_FOUND)
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
# Simple script to generate simple cmake modules for finding
|
||||
# libraries (packages)
|
||||
#
|
||||
# usage: generate_findpackage_file
|
||||
# then you will be prompted to enter the required parameters
|
||||
#
|
||||
#####################################################################
|
||||
#
|
||||
# Copyright (c) 2006 Alexander Neundorf <neundorf@kde.org>
|
||||
# Copyright (c) 2006 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.
|
||||
#
|
||||
|
||||
require 'readline'
|
||||
|
||||
package=Readline.readline("Name of package: ")
|
||||
|
||||
name=Readline.readline("\nYour Name (for copyright): ")
|
||||
|
||||
email=Readline.readline("\nYour mail (for copyright): ")
|
||||
|
||||
pkgconfig=Readline.readline("\npkgconfig package name (e.g. \"libxml-2.0\", leave empty to skip pkgconfig): ")
|
||||
|
||||
header=Readline.readline("\nLook for header (e.g. \"jpeglib.h\" or \"libxml/xpath.h\"): ")
|
||||
|
||||
incSubDir=Readline.readline("\nLook for header subdir (e.g. \"libxml2\", empty to skip ): ")
|
||||
|
||||
libs=Readline.readline("\nLook for library (e.g. \"xml2\" or \"avcodec avutil\"): ")
|
||||
|
||||
t = Time.now
|
||||
|
||||
cmakeIncDirName=package.upcase+"_INCLUDE_DIR"
|
||||
cmakeIncDirNames=package.upcase+"_INCLUDE_DIRS"
|
||||
cmakeLibNames=package.upcase+"_LIBRARIES"
|
||||
cmakeDefsName=package.upcase+"_DEFINITIONS"
|
||||
cmakeFoundName=package.upcase+"_FOUND"
|
||||
cmakeQuietName=package+"_FIND_QUIETLY"
|
||||
cmakeRequiredName=package+"_FIND_REQUIRED"
|
||||
|
||||
file=File.new("Find#{package}.cmake", "w+")
|
||||
|
||||
|
||||
file.printf("# - Try to find #{package}\n")
|
||||
file.printf("# Once done this will define\n")
|
||||
file.printf("#\n")
|
||||
file.printf("# #{cmakeFoundName} - system has #{package}\n")
|
||||
file.printf("# #{cmakeIncDirNames} - the #{package} include directory\n")
|
||||
file.printf("# #{cmakeLibNames} - Link these to use #{package}\n")
|
||||
file.printf("# #{cmakeDefsName} - Compiler switches required for using #{package}\n")
|
||||
file.printf("#\n")
|
||||
file.printf("# Copyright (c) #{t.year} #{name} <#{email}>\n")
|
||||
file.printf("#\n")
|
||||
file.printf("# Redistribution and use is allowed according to the terms of the New\n")
|
||||
file.printf("# BSD license.\n")
|
||||
file.printf("# For details see the accompanying COPYING-CMAKE-SCRIPTS file.\n")
|
||||
file.printf("#\n")
|
||||
|
||||
file.printf("\n")
|
||||
file.printf("\n")
|
||||
|
||||
file.printf("if (#{cmakeLibNames} AND #{cmakeIncDirNames})\n")
|
||||
file.printf(" # in cache already\n")
|
||||
file.printf(" set(#{cmakeFoundName} TRUE)\n")
|
||||
file.printf("else (#{cmakeLibNames} AND #{cmakeIncDirNames})\n")
|
||||
|
||||
if not pkgconfig.empty?
|
||||
file.printf(" find_package(PkgConfig)\n")
|
||||
file.printf(" if (PKG_CONFIG_FOUND)\n")
|
||||
file.printf(" pkg_check_modules(_#{package.upcase} #{pkgconfig})\n")
|
||||
file.printf(" endif (PKG_CONFIG_FOUND)\n")
|
||||
end
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
file.printf(" find_path(#{cmakeIncDirName}\n")
|
||||
file.printf(" NAMES\n")
|
||||
file.printf(" #{header}\n")
|
||||
file.printf(" PATHS\n")
|
||||
if not pkgconfig.empty?
|
||||
file.printf(" ${_#{package.upcase}_INCLUDEDIR}\n")
|
||||
end
|
||||
file.printf(" /usr/include\n")
|
||||
file.printf(" /usr/local/include\n")
|
||||
file.printf(" /opt/local/include\n")
|
||||
file.printf(" /sw/include\n")
|
||||
|
||||
if not incSubDir.empty?
|
||||
file.printf(" PATH_SUFFIXES\n")
|
||||
file.printf(" #{incSubDir}\n")
|
||||
end
|
||||
file.printf(" )\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
libs.split(" ").each do |lib|
|
||||
file.printf(" find_library(#{lib.upcase}_LIBRARY\n")
|
||||
file.printf(" NAMES\n")
|
||||
file.printf(" #{lib}\n")
|
||||
file.printf(" PATHS\n")
|
||||
if not pkgconfig.empty?
|
||||
file.printf(" ${_#{package.upcase}_LIBDIR}\n")
|
||||
end
|
||||
file.printf(" /usr/lib\n")
|
||||
file.printf(" /usr/local/lib\n")
|
||||
file.printf(" /opt/local/lib\n")
|
||||
file.printf(" /sw/lib\n")
|
||||
file.printf(" )\n")
|
||||
file.printf("\n")
|
||||
end
|
||||
|
||||
file.printf(" set(#{cmakeIncDirNames}\n")
|
||||
file.printf(" ${#{cmakeIncDirName}}\n")
|
||||
file.printf(" )\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
libs.split(" ").each do |lib|
|
||||
file.printf(" if (#{lib.upcase}_LIBRARY)\n")
|
||||
file.printf(" set(#{cmakeLibNames}\n")
|
||||
file.printf(" ${#{cmakeLibNames}}\n")
|
||||
file.printf(" ${#{lib.upcase}_LIBRARY}\n")
|
||||
file.printf(" )\n")
|
||||
file.printf(" endif (#{lib.upcase}_LIBRARY)\n")
|
||||
file.printf("\n")
|
||||
end
|
||||
|
||||
file.printf(" include(FindPackageHandleStandardArgs)\n")
|
||||
file.printf(" find_package_handle_standard_args(#{package} DEFAULT_MSG #{cmakeLibNames} #{cmakeIncDirNames})\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
file.printf(" # show the #{cmakeIncDirNames} and #{cmakeLibNames} variables only in the advanced view\n")
|
||||
file.printf(" mark_as_advanced(#{cmakeIncDirNames} #{cmakeLibNames})\n\n")
|
||||
|
||||
file.printf("endif (#{cmakeLibNames} AND #{cmakeIncDirNames})\n\n")
|
||||
|
||||
printf("Done, generated Find#{package}.cmake\n")
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
# simple script to generate CMakeLists.txt for wengophone libs
|
||||
#
|
||||
# usage: generate_lib_file
|
||||
# then you will be prompted to enter the required parameters
|
||||
#
|
||||
#####################################################################
|
||||
#
|
||||
# Copyright (c) 2006 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.
|
||||
#
|
||||
|
||||
print("Name of project: ")
|
||||
project=gets.chomp
|
||||
|
||||
printf("\n")
|
||||
|
||||
print("Other projects to includes (e.g. \"owutil tinyxml\", leave emtpy to skip): ")
|
||||
otherprojects=gets.chomp
|
||||
|
||||
printf("\n")
|
||||
|
||||
print("Defininitions (leave empty to skip): ")
|
||||
definitions=gets.chomp
|
||||
|
||||
cmakePublicIncDirName = project.upcase+"_PUBLIC_INCLUDE_DIRS"
|
||||
cmakePrivateIncDirName = project.upcase+"_PRIVATE_INCLUDE_DIRS"
|
||||
cmakeLibName = project.upcase+"_LIBRARY"
|
||||
cmakeLibNames = project.upcase+"_LINK_LIBRARIES"
|
||||
cmakePublicDefsName = project.upcase+"_PUBLIC_DEFINITIONS"
|
||||
cmakePrivateDefsName = project.upcase+"_PRIVATE_DEFINITIONS"
|
||||
|
||||
file=File.new("CMakeLists.txt", "w+")
|
||||
|
||||
file.printf("project(#{project})\n")
|
||||
file.printf("\n")
|
||||
file.printf("# needed include directories to build #{project}\n")
|
||||
file.printf("# saves the variable in internal cache for later use\n")
|
||||
file.printf("set(#{cmakePublicIncDirName}\n")
|
||||
file.printf(" ${CMAKE_CURRENT_SOURCE_DIR}\n")
|
||||
file.printf(" ${CMAKE_CURRENT_SOURCE_DIR}/include\n")
|
||||
file.printf(" CACHE INTERNAL \"#{project} public include directories\"\n")
|
||||
file.printf(")\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
file.printf("set(#{cmakePrivateIncDirName}\n")
|
||||
otherprojects.split(" ").each do |otherproject|
|
||||
file.printf(" ${#{otherproject.upcase}_PUBLIC_INCLUDE_DIRS}\n")
|
||||
end
|
||||
file.printf(" ${CMAKE_CURRENT_BINARY_DIR}\n")
|
||||
file.printf(")\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
file.printf("set(#{cmakeLibName}\n")
|
||||
file.printf(" #{project}\n")
|
||||
file.printf(" CACHE INTERNAL \"#{project} library\"\n")
|
||||
file.printf(")\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
file.printf("# #{project} lib and dependencies\n")
|
||||
file.printf("set(#{cmakeLibNames}\n")
|
||||
file.printf(" #{cmakeLibName}\n")
|
||||
otherprojects.split(" ").each do |otherproject|
|
||||
file.printf(" ${#{otherproject.upcase}_LIBRARIES}\n")
|
||||
end
|
||||
file.printf(")\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
if not definitions.empty?
|
||||
file.printf("set(#{cmakePublicDefsName}\n")
|
||||
file.printf(" #{definitions}\n")
|
||||
file.printf(" CACHE INTERNAL \"#{project} public definitions\"\n")
|
||||
file.printf(")\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
file.printf("set(#{cmakePrivateDefsName}\n")
|
||||
file.printf(" #{definitions}\n")
|
||||
file.printf(")\n")
|
||||
|
||||
file.printf("\n")
|
||||
end
|
||||
|
||||
file.printf("set(#{project}_SRCS\n")
|
||||
file.printf(" files.c\n")
|
||||
file.printf(")\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
file.printf("include_directories(\n")
|
||||
file.printf(" ${#{cmakePublicIncDirName}}\n")
|
||||
file.printf(" ${#{cmakePrivateIncDirName}}\n")
|
||||
file.printf(")\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
if not definitions.empty?
|
||||
file.printf("add_definitions(\n")
|
||||
file.printf(" ${#{cmakePublicDefsName}}\n")
|
||||
file.printf(" ${#{cmakePrivateDefsName}}\n")
|
||||
file.printf(")\n")
|
||||
|
||||
file.printf("\n")
|
||||
end
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
file.printf("add_library(${#{cmakeLibName}} STATIC ${#{project}_SRCS})\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
file.printf("target_link_libraries(${#{cmakeLibNames}})\n")
|
||||
|
||||
file.printf("\n")
|
||||
|
||||
printf("Generated CMakeLists.txt for #{project}\n")
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#cmakedefine PACKAGE "${APPLICATION_NAME}"
|
||||
#cmakedefine VERSION "${APPLICATION_VERSION}"
|
||||
#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
|
||||
#cmakedefine DATADIR "${DATADIR}"
|
||||
#cmakedefine LIBDIR "${LIBDIR}"
|
||||
#cmakedefine PLUGINDIR "${PLUGINDIR}"
|
||||
#cmakedefine SYSCONFDIR "${SYSCONFDIR}"
|
||||
#cmakedefine BINARYDIR "${BINARYDIR}"
|
||||
#cmakedefine SOURCEDIR "${SOURCEDIR}"
|
||||
|
||||
#cmakedefine HAVE_CLOCK_GETTIME
|
||||
|
||||
#cmakedefine WITH_LOG4C 1
|
||||
#cmakedefine WITH_ICONV 1
|
||||
|
||||
#cmakedefine HAVE_ARGP_H 1
|
||||
#cmakedefine HAVE_ICONV_H 1
|
||||
#cmakedefine HAVE_SYS_ICONV_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_ICONV 1
|
||||
#cmakedefine HAVE_ICONV_CONST 1
|
||||
|
||||
#cmakedefine NEON_WITH_LFS 1
|
||||
#cmakedefine HAVE___MINGW_ASPRINTF 1
|
||||
|
||||
#cmakedefine WITH_UNIT_TESTING 1
|
|
@ -0,0 +1,10 @@
|
|||
macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/ocsync.conf ${CMAKE_CURRENT_BINARY_DIR}/ocsync.conf)
|
||||
macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/ocsync_exclude.conf ${CMAKE_CURRENT_BINARY_DIR}/ocsync_exclude.conf)
|
||||
|
||||
install(
|
||||
FILES
|
||||
ocsync.conf
|
||||
ocsync_exclude.conf
|
||||
DESTINATION
|
||||
${SYSCONF_INSTALL_DIR}/ocsync
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
# max diff time between two recplicas in seconds
|
||||
max_time_difference = 10
|
||||
|
||||
# max directory depth recursion
|
||||
max_depth = 50
|
||||
|
||||
# NOT IN USE:
|
||||
# sync symbolic links if the remote filesystem supports it.
|
||||
#sync_symbolic_links = false
|
||||
|
||||
# connection timeout in seconds
|
||||
timeout = 30
|
||||
|
||||
# create a copy for backup for the file which has a conflict
|
||||
#with_confilct_copies = no
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
# Exclude patterns (one per line). Blank lines in the file and
|
||||
# lines starting with '#' are ignored.
|
||||
#
|
||||
# You can use shell wildcard patterns. See the manpage of sh(1)
|
||||
#
|
||||
# If a pattern starts with ']', the ']' is removed from the pattern,
|
||||
# And the files that matches that pattern will be ignored, but if
|
||||
# their parent directory is removed on the other side, the file will
|
||||
# be removed. Otherwise, ignored file prevent the directory from
|
||||
# being removed.
|
||||
|
||||
.beagle
|
||||
.ccache
|
||||
.csync*
|
||||
.fontconfig
|
||||
.java/
|
||||
.jpi_cache
|
||||
.kde*/cache-*
|
||||
.kde*/socket-*
|
||||
.kde*/tmp-*
|
||||
.mozilla/plugins
|
||||
.mozilla/firefox/*/Cache
|
||||
.netscape/cache/
|
||||
.snapshot
|
||||
.thumbnails
|
||||
|
||||
*.~*
|
||||
]*.directory
|
||||
|
||||
# exclude all object file
|
||||
# *.o
|
||||
|
||||
# exclude all bak files
|
||||
# *.bak
|
||||
#
|
||||
|
||||
# ignore conflict files.
|
||||
*_conflict-*
|
||||
|
||||
.Temporary Items
|
||||
.Trashes
|
||||
.Document Revisions-V100
|
||||
.fseventd
|
||||
.apdisk
|
||||
|
||||
.htaccess
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
/* mind to have trailing slashes! */
|
||||
|
||||
#define TESTFILES_DIR "@SOURCE_DIR@/tests/ownCloud/testfiles/"
|
||||
|
||||
#define TEST_CONFIG_DIR "@SOURCE_DIR@/tests/ownCloud/"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
Andreas Schneider <asn@cryptomilk.org>
|
||||
Klaas Freitag <freitag@owncloud.com>
|
||||
Olivier Goffart <olivier>
|
|
@ -0,0 +1,71 @@
|
|||
project(ocsync C)
|
||||
|
||||
# Required cmake version
|
||||
cmake_minimum_required(VERSION 2.6.0)
|
||||
|
||||
# global needed variables
|
||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
|
||||
set(APPLICATION_VERSION_MAJOR "0")
|
||||
set(APPLICATION_VERSION_MINOR "91")
|
||||
set(APPLICATION_VERSION_PATCH "4")
|
||||
|
||||
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
|
||||
|
||||
set(LIBRARY_VERSION "0.2.1")
|
||||
set(LIBRARY_SOVERSION "0")
|
||||
|
||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||
set(CMAKE_MODULE_PATH
|
||||
${CMAKE_SOURCE_DIR}/cmake/Modules
|
||||
)
|
||||
|
||||
# add definitions
|
||||
include(DefineCMakeDefaults)
|
||||
include(DefinePlatformDefaults)
|
||||
include(DefineCompilerFlags)
|
||||
include(DefineOptions.cmake)
|
||||
|
||||
include(DefineInstallationPaths)
|
||||
|
||||
# disallow in-source build
|
||||
include(MacroEnsureOutOfSourceBuild)
|
||||
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
|
||||
|
||||
# add macros
|
||||
include(MacroAddPlugin)
|
||||
include(MacroCopyFile)
|
||||
|
||||
if (NOT WIN32)
|
||||
find_package(Iconv)
|
||||
endif (NOT WIN32)
|
||||
find_package(CMocka)
|
||||
if (CMOCKA_FOUND AND UNIT_TESTING)
|
||||
include(AddCMockaTest)
|
||||
endif (CMOCKA_FOUND AND UNIT_TESTING)
|
||||
|
||||
include(ConfigureChecks.cmake)
|
||||
|
||||
|
||||
set(SOURCE_DIR ${CMAKE_SOURCE_DIR})
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake)
|
||||
|
||||
if (MEM_NULL_TESTS)
|
||||
add_definitions(-DCSYNC_MEM_NULL_TESTS)
|
||||
endif (MEM_NULL_TESTS)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(config)
|
||||
add_subdirectory(doc)
|
||||
|
||||
if (CMOCKA_FOUND AND UNIT_TESTING)
|
||||
add_subdirectory(tests)
|
||||
endif (CMOCKA_FOUND AND UNIT_TESTING)
|
||||
|
||||
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
configure_file(config_test.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config_test.h)
|
||||
|
||||
|
|
@ -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.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
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!
|
|
@ -0,0 +1,12 @@
|
|||
set(UPDATE_TYPE "true")
|
||||
|
||||
set(MEMORYCHECK_SUPPRESSIONS_FILE ${CMAKE_SOURCE_DIR}/tests/valgrind-csync.supp)
|
||||
|
||||
set(CTEST_PROJECT_NAME "csync")
|
||||
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
|
||||
|
||||
set(CTEST_DROP_METHOD "http")
|
||||
set(CTEST_DROP_SITE "mock.cryptomilk.org")
|
||||
set(CTEST_DROP_LOCATION "/submit.php?project=${CTEST_PROJECT_NAME}")
|
||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
set(CTEST_CUSTOM_MEMCHECK_IGNORE
|
||||
${CTEST_CUSTOM_MEMCHECK_IGNORE}
|
||||
check_std_c_jhash
|
||||
)
|
|
@ -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 directrories are properly moved.
|
||||
* Handle symlinks correctly.
|
||||
* Do not 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.com/owncloud/mirall/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 efficiendy.
|
||||
* 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 variuos 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 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 exported 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
|
|
@ -0,0 +1,75 @@
|
|||
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(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
|
||||
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
|
||||
|
||||
set(BINARYDIR ${CMAKE_BINARY_DIR})
|
||||
set(SOURCEDIR ${CMAKE_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)
|
||||
if(NOT HAVE_ASPRINTF)
|
||||
if(MINGW)
|
||||
add_definitions( -D__USE_MINGW_ANSI_STDIO=1 )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
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)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
set(WITH_UNIT_TESTING ON)
|
||||
endif (UNIT_TESTING)
|
||||
|
||||
set(CSYNC_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "csync required system libraries")
|
|
@ -0,0 +1,5 @@
|
|||
if ( NOT WIN32 )
|
||||
option(WITH_ICONV "Build csync with iconv support" ON)
|
||||
endif()
|
||||
option(UNIT_TESTING "Build with unit tests" OFF)
|
||||
option(MEM_NULL_TESTS "Enable NULL memory testing" OFF)
|
|
@ -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 version we know works 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
|
||||
|
||||
Befor 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
|
|
@ -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 preferebly 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/
|
|
@ -0,0 +1,41 @@
|
|||
project(doc C)
|
||||
# Build the documentation
|
||||
#
|
||||
|
||||
include(UseDoxygen OPTIONAL)
|
||||
|
||||
file(GLOB _manpages *.[0-9].txt)
|
||||
add_custom_target(man
|
||||
COMMAND
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makeman.sh ${_manpages}
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
add_custom_target(userguide
|
||||
COMMAND
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makeguide.sh ocsync.txt
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
if (UNIX)
|
||||
install(
|
||||
FILES
|
||||
ocsync.1
|
||||
DESTINATION
|
||||
${MAN_INSTALL_DIR}/man1
|
||||
)
|
||||
set(DOC_INSTALL_PATH ${SHARE_INSTALL_PREFIX}/doc/ocsync)
|
||||
endif(UNIX)
|
||||
|
||||
if (WIN32)
|
||||
set(DOC_INSTALL_PATH ${SHARE_INSTALL_PREFIX}/doc)
|
||||
endif (WIN32)
|
||||
|
||||
install(
|
||||
DIRECTORY
|
||||
userguide
|
||||
DESTINATION
|
||||
${DOC_INSTALL_PATH}
|
||||
)
|
|
@ -0,0 +1,8 @@
|
|||
#
|
||||
# Customization for csync documentation.
|
||||
#
|
||||
[specialwords]
|
||||
ifndef::doctype-manpage[]
|
||||
emphasizedwords=(?u)\\?\bCSYNC\b
|
||||
monospacedwords=(?u)\\?\bcsync\(1\)
|
||||
endif::doctype-manpage[]
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* 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_X_H
|
||||
#define _CSYNC_X_H
|
||||
|
||||
#endif /* _CSYNC_X_H */
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
# Last Change: 2008-07-03 11:08:54
|
||||
|
||||
for f in $@; do
|
||||
test "${f##*/}" = "CMakeLists.txt" && continue
|
||||
echo -e "\e[32mCreating asciidoc html document ${f%.*}.html\e[0m"
|
||||
asciidoc \
|
||||
--attribute=numbered \
|
||||
--attribute=icons \
|
||||
--attribute="iconsdir=./images/icons" \
|
||||
--attribute=toc \
|
||||
--backend=xhtml11 \
|
||||
--out-file="$(dirname $f)/userguide/${f%.*}.html" \
|
||||
$f
|
||||
rm -f ${f%.*}.xml
|
||||
done
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
# Last Change: 2008-07-03 11:08:54
|
||||
|
||||
for f in $@; do
|
||||
test "${f##*/}" = "CMakeLists.txt" && continue
|
||||
echo -e "\e[32mCreating manpage ${f%.*}\e[0m"
|
||||
a2x --doctype=manpage --format=manpage $f
|
||||
rm -f ${f%.*}.xml
|
||||
done
|
|
@ -0,0 +1,183 @@
|
|||
'\" t
|
||||
.\" Title: ocsync
|
||||
.\" Author: [see the "AUTHORS" section]
|
||||
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
|
||||
.\" Date: 12/22/2012
|
||||
.\" Manual: \ \&
|
||||
.\" Source: \ \&
|
||||
.\" Language: English
|
||||
.\"
|
||||
.TH "OCSYNC" "1" "12/22/2012" "\ \&" "\ \&"
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * Define some portability stuff
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
.\" http://bugs.debian.org/507673
|
||||
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
|
||||
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
.ie \n(.g .ds Aq \(aq
|
||||
.el .ds Aq '
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * set default formatting
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" disable hyphenation
|
||||
.nh
|
||||
.\" disable justification (adjust text to left margin only)
|
||||
.ad l
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * MAIN CONTENT STARTS HERE *
|
||||
.\" -----------------------------------------------------------------
|
||||
.SH "NAME"
|
||||
ocsync \- A commandline frontent for csync a user level bidirectional file synchronizer\&.
|
||||
.SH "SYNOPSIS"
|
||||
.sp
|
||||
\fBocsync\fR [\fIOPTION\fR\&...] \fISOURCE\fR \fIDESTINATION\fR
|
||||
.SH "DESCRIPTION"
|
||||
.sp
|
||||
ocsync is a client only bidirectional file synchronizer\&. It synchronizes the content of \fISOURCE\fR with \fIDESTINATION\fR and vice versa\&. The \fIDESTINATION\fR can be a local directory or a remote file server\&.
|
||||
.sp
|
||||
You can use ocsync for different things\&. The intention is to provide Roaming Home Directories for Linux but you can use it to synchronize your music collection or create a backup of a directory\&.
|
||||
.SH "OPTIONS"
|
||||
.PP
|
||||
\fB\-\-create\-statedb\fR
|
||||
.RS 4
|
||||
Run update detection and write the statedb (TESTING ONLY!)
|
||||
.RE
|
||||
.PP
|
||||
\fB\-d, \-\-disable\-statedb\fR
|
||||
.RS 4
|
||||
Disable the usage and creation of a statedb\&.
|
||||
.RE
|
||||
.PP
|
||||
\fB\-\-exclude\-file=\fR\fB\fI<file>\fR\fR
|
||||
.RS 4
|
||||
Add an additional exclude file
|
||||
.RE
|
||||
.PP
|
||||
\fB\-r, \-\-reconcile\fR
|
||||
.RS 4
|
||||
Run ONLY update detection and reconcilation This option is for debugging
|
||||
.RE
|
||||
.PP
|
||||
\fB\-u, \-\-update\fR
|
||||
.RS 4
|
||||
Run ONLY the update detection This option is for debugging
|
||||
.RE
|
||||
.PP
|
||||
\fB\-?, \-\-help\fR
|
||||
.RS 4
|
||||
Print the help list
|
||||
.RE
|
||||
.PP
|
||||
\fB\-V, \-\-version\fR
|
||||
.RS 4
|
||||
Print program version
|
||||
.RE
|
||||
.SH "EXIT STATUS"
|
||||
.PP
|
||||
\fB0\fR
|
||||
.RS 4
|
||||
Success
|
||||
.RE
|
||||
.PP
|
||||
\fB1\fR
|
||||
.RS 4
|
||||
Failure (syntax or usage error; configuration error; unexpected error)\&.
|
||||
.RE
|
||||
.SH "EXAMPLES"
|
||||
.sp
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
ocsync /home/user /backup/home/user
|
||||
.sp
|
||||
.if n \{\
|
||||
.RS 4
|
||||
.\}
|
||||
.nf
|
||||
Synchronizer two local directories\&.
|
||||
.fi
|
||||
.if n \{\
|
||||
.RE
|
||||
.\}
|
||||
.RE
|
||||
.sp
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
ocsync /home/user smb://server/share/user
|
||||
.sp
|
||||
.if n \{\
|
||||
.RS 4
|
||||
.\}
|
||||
.nf
|
||||
Synchronize a home directory with a SMB share\&.
|
||||
.fi
|
||||
.if n \{\
|
||||
.RE
|
||||
.\}
|
||||
.RE
|
||||
.sp
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
ocsync /home/user smb://user:password@server/share/user
|
||||
.sp
|
||||
.if n \{\
|
||||
.RS 4
|
||||
.\}
|
||||
.nf
|
||||
Synchronize a home directory with a SMB share and provide username and
|
||||
password directly\&.
|
||||
.fi
|
||||
.if n \{\
|
||||
.RE
|
||||
.\}
|
||||
.RE
|
||||
.SH "BUGS"
|
||||
.sp
|
||||
Please report bugs at https://dev\&.csync\&.org/\&.
|
||||
.SH "SEE ALSO"
|
||||
.sp
|
||||
\fBlibocsync\fR(7)
|
||||
.SH "AUTHORS"
|
||||
.sp
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
Andreas Schneider <mail@cynapses\&.org>
|
||||
.RE
|
||||
.sp
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
Klaas Freitag <freitag@owncloud\&.com>
|
||||
.RE
|
||||
.SH "COPYING"
|
||||
.sp
|
||||
Copyright \e(c) 2006\-2008 Andreas Schneider\&. Free use of this software is granted under the terms of the GNU General Public License (GPL)\&.
|
|
@ -0,0 +1,104 @@
|
|||
ocsync(1)
|
||||
========
|
||||
|
||||
NAME
|
||||
----
|
||||
|
||||
ocsync - A commandline frontent for csync a user level bidirectional file
|
||||
synchronizer.
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
*ocsync* ['OPTION'...] 'SOURCE' 'DESTINATION'
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
ocsync is a client only bidirectional file synchronizer. It synchronizes the
|
||||
content of 'SOURCE' with 'DESTINATION' and vice versa. The 'DESTINATION' can
|
||||
be a local directory or a remote file server.
|
||||
|
||||
You can use ocsync for different things. The intention is to provide Roaming
|
||||
Home Directories for Linux but you can use it to synchronize your music
|
||||
collection or create a backup of a directory.
|
||||
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
*--create-statedb*::
|
||||
Run update detection and write the statedb
|
||||
(TESTING ONLY!)
|
||||
*-d, --disable-statedb*::
|
||||
Disable the usage and creation of a statedb.
|
||||
|
||||
*--exclude-file='<file>'*::
|
||||
Add an additional exclude file
|
||||
|
||||
*-r, --reconcile*::
|
||||
Run ONLY update detection and reconcilation
|
||||
This option is for debugging
|
||||
|
||||
*-u, --update*::
|
||||
Run ONLY the update detection
|
||||
This option is for debugging
|
||||
|
||||
*-?, --help*::
|
||||
Print the help list
|
||||
|
||||
*-V, --version*::
|
||||
Print program version
|
||||
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
*0*::
|
||||
Success
|
||||
|
||||
*1*::
|
||||
Failure (syntax or usage error; configuration error;
|
||||
unexpected error).
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
* ocsync /home/user /backup/home/user
|
||||
|
||||
Synchronizer two local directories.
|
||||
|
||||
* ocsync /home/user smb://server/share/user
|
||||
|
||||
Synchronize a home directory with a SMB share.
|
||||
|
||||
* ocsync /home/user smb://user:password@server/share/user
|
||||
|
||||
Synchronize a home directory with a SMB share and provide username and
|
||||
password directly.
|
||||
|
||||
BUGS
|
||||
----
|
||||
|
||||
Please report bugs at https://dev.csync.org/.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
*libocsync*(7)
|
||||
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
|
||||
* Andreas Schneider <mail@cynapses.org>
|
||||
* Klaas Freitag <freitag@owncloud.com>
|
||||
|
||||
COPYING
|
||||
-------
|
||||
Copyright \(c) 2006-2008 Andreas Schneider. Free use of this software is
|
||||
granted under the terms of the GNU General Public License (GPL).
|
||||
|
|
@ -0,0 +1,315 @@
|
|||
CSYNC User Guide
|
||||
================
|
||||
Andreas Schneider <asn@cryptomilk.org>
|
||||
:Author Initials: ADS
|
||||
|
||||
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.
|
||||
|
||||
Together with a Pluggable Authentication Module (PAM), the intent is to provide
|
||||
Roaming Home Directories for Linux (see <<X80, The PAM Module>>).
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
It is often the case that we have multiple copies (called replicas) of a
|
||||
filesystem or part of a filesystem (for example on a notebook and desktop
|
||||
computer). Changes to each replica are often made independently, and as a
|
||||
result, they do not contain the same information. In that case, a file
|
||||
synchronizer is used to make them consistent again, without losing any
|
||||
information.
|
||||
|
||||
The goal is to detect conflicting updates (files which have been modified) and
|
||||
propagate non-conflicting updates to each replica. If there are no conflicts
|
||||
left, we are done, and the replicas are identical. To resolve or handle
|
||||
conflicts there are several algorithms available. They will be discussed
|
||||
one of the following sections.
|
||||
|
||||
Basics
|
||||
------
|
||||
|
||||
This section describes some basics of file synchronization.
|
||||
|
||||
Paths
|
||||
~~~~~
|
||||
A path normally refers to a point which contains a set of files which should be
|
||||
synchronized. It is specified relative to the root of the replica locally, but
|
||||
has to be absolute if you use a protocol. The path is just a sequence of names
|
||||
separated by '/'.
|
||||
|
||||
NOTE: The path separator is always a forward slash '/', even for Windows.
|
||||
|
||||
csync always uses the absolute path on remote replicas. This could
|
||||
'sftp://gladiac:secret@myserver/home/gladiac' for sftp.
|
||||
|
||||
What is an update?
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
The contents of a path could be a file, a directory or a symbolic link
|
||||
(symbolic links are not supported yet). To be more precise, if the path refers
|
||||
to:
|
||||
|
||||
- a regular file: the contents of the file are the byte stream and the
|
||||
metadata of the file.
|
||||
- a directory: then the content is the metadata of the directory.
|
||||
- a symbolic link: the content is the named file the link points to.
|
||||
|
||||
csync keeps a record of each path which has been successfully synchronized. The
|
||||
path gets compared with the record and if it has changed since the last
|
||||
synchronization, we have an update. This is done by comparing the modification
|
||||
or change (modification time of the metadata) time. This is the way how updates
|
||||
are detected.
|
||||
|
||||
What is a conflict?
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
A path is conflicting if it fulfills the following conditions:
|
||||
|
||||
1. it has been updated in one replica,
|
||||
2. it or any of its descendants has been updated on the other replica too, and
|
||||
3. its contents in are not identical.
|
||||
|
||||
File Synchronization
|
||||
--------------------
|
||||
|
||||
The primary goal of the file synchronizer is correctness. It may change
|
||||
scattered or large parts of the filesystem. Since this in mostly not monitored
|
||||
by the user, and the file synchronizer is in a position to harm the system,
|
||||
csync must be safe, even in the case of unexpected errors (e.g. disk full).
|
||||
What was done to make csync safe is described in the following sections.
|
||||
|
||||
|
||||
One problem concerning correctness is the handling of conflicts. Each file
|
||||
synchronizer tries to propagate conflicting changes to the other replica. At
|
||||
the end both replicas should be identical. There are different strategies to
|
||||
fulfill these goals.
|
||||
|
||||
csync is a three-phase file synchronizer. The decision for this design was that
|
||||
user interaction should be possible and it should be easy to understand the
|
||||
process. The three phases are update detection, reconciliation and propagation.
|
||||
These will be described in the following sections.
|
||||
|
||||
Update detection
|
||||
~~~~~~~~~~~~~~~~
|
||||
There are different strategies for update detection. csync uses a state-based
|
||||
modtime-inode update detector. This means it uses the modification time to
|
||||
detect updates. It doesn't require many resources. A record of each file is
|
||||
stored in a database (called statedb) and compared with the current
|
||||
modification time during update detection. If the file has changed since the
|
||||
last synchronization an instruction is set to evaluate it during the
|
||||
reconciliation phase. If we don't have a record for a file we investigate, it
|
||||
is marked as new.
|
||||
|
||||
It can be difficult to detect renaming of files. This problem is also solved
|
||||
by the record we store in the statedb. If we don't find the file by the name
|
||||
in the database, we search for the inode number. If the inode number is found
|
||||
then the file has been renamed.
|
||||
|
||||
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*
|
||||
|
||||
A wrong decision of the reconciler leads in most cases to a loss of data. So
|
||||
there are several conditions which a file synchronizer has to follow.
|
||||
|
||||
Algorithms
|
||||
^^^^^^^^^^
|
||||
|
||||
For conflict resolution several different algorithms could be implemented. The
|
||||
most common algorithms are the merge and the conflict algorithm. The first
|
||||
is a batch algorithm and the second is one which needs user interaction.
|
||||
|
||||
Merge algorithm
|
||||
+++++++++++++++
|
||||
|
||||
The merge algorithm is an algorithm which doesn't need any user interaction. It
|
||||
is simple and used for example by Microsoft for Roaming Profiles. If it detects
|
||||
a conflict (the same file changed on both replicas) then it will use the most
|
||||
recent file and overwrite the other. This means you can loose some data, but
|
||||
normally you want the latest file.
|
||||
|
||||
Conflict algorithm
|
||||
++++++++++++++++++
|
||||
|
||||
This is not implemented yet.
|
||||
|
||||
If a file has a conflict the user has to decide which file should be used.
|
||||
|
||||
Propagation
|
||||
~~~~~~~~~~~
|
||||
|
||||
The next instance of the file synchronizer is the propagator. It uses the
|
||||
calculated records to apply them on the current replica.
|
||||
|
||||
|
||||
The propagator uses a two-phase-commit mechanism to simulate an atomic
|
||||
filesystem operation.
|
||||
|
||||
In the first phase we copy the file to a temporary file on the opposite
|
||||
replica. This has the advantage that we can check if the file which has been
|
||||
copied to the opposite replica has been transferred successfully. If the
|
||||
connection gets interrupted during the transfer we still have the original
|
||||
states of the file. This means no data will be lost.
|
||||
|
||||
In the second phase the file on the opposite replica will be overwritten by
|
||||
the temporary file.
|
||||
|
||||
After a successful propagation we have to merge the trees to reflect the
|
||||
current state of the filesystem tree. This updated tree will be written as a
|
||||
journal into the state database. It will be used during the update detection of
|
||||
the next synchronization. See above for a description of the state database
|
||||
during synchronization.
|
||||
|
||||
Robustness
|
||||
~~~~~~~~~~
|
||||
|
||||
This is a very important topic. The file synchronizer should not crash, and if
|
||||
it has crashed, there should be no loss of data. To achieve this goal there are
|
||||
several mechanisms which will be discussed in the following sections.
|
||||
|
||||
Crash resistance
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
The synchronization process can be interrupted by different events, this can
|
||||
be:
|
||||
|
||||
* the system could be halted due to errors.
|
||||
* the disk could be full or the quota exceeded.
|
||||
* the network or power cable could be pulled out.
|
||||
* the user could force a stop of the synchronization process.
|
||||
* various communication errors could occur.
|
||||
|
||||
That no data will be lost due to an event we enforce the following invariant:
|
||||
|
||||
IMPORTANT: At every moment of the synchronization each file, has either its
|
||||
original content or its correct final content.
|
||||
|
||||
This means that the original content can not be incorrect, no data can be lost
|
||||
until we overwrite it after a successful synchronization. Therefore, each
|
||||
interrupted synchronization process is a partial sync and can be continued and
|
||||
completed by simply running csync again. The only problem could be an error of
|
||||
the filesystem, so we reach this invariant only approximately.
|
||||
|
||||
Transfer errors
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
With the Two-Phase-Commit we check the file size after the file has transferred
|
||||
and we are able to detect transfer errors. A more robust approach would be a
|
||||
transfer protocol with checksums, but this is not doable at the moment. We may
|
||||
add this in the future.
|
||||
|
||||
Future filesystems, like btrfs, will help to compare checksums instead of the
|
||||
filesize. This will make the synchronization safer. This does not imply that it
|
||||
is unsafe now, but checksums are safer than simple filesize checks.
|
||||
|
||||
Database loss
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
It is possible that the state database could get corrupted. If this happens,
|
||||
all files get evaluated. In this case the file synchronizer wont delete any
|
||||
file, but it could occur that deleted files will be restored from the other
|
||||
replica.
|
||||
|
||||
To prevent a corruption or loss of the database if an error occurs or the user
|
||||
forces an abort, the synchronizer is working on a copy of the database and will
|
||||
use a Two-Phase-Commit to save it at the end.
|
||||
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
Installing csync
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
See the `README` and `INSTALL` files for install prerequisites and
|
||||
procedures. Packagers should take a look at <<X90, Appendix A: Packager Notes>>.
|
||||
|
||||
Using the commandline client
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The synopsis of the commandline client is
|
||||
|
||||
csync [OPTION...] SOURCE DESTINATION
|
||||
|
||||
It synchronizes the content of SOURCE with DESTINATION and vice versa. The
|
||||
DESTINATION can be a local directory or a remote file server.
|
||||
|
||||
csync /home/csync scheme://user:password@server:port/full/path
|
||||
|
||||
Examples
|
||||
^^^^^^^^
|
||||
|
||||
To synchronize two local directories:
|
||||
|
||||
csync /home/csync/replica1 /home/csync/relplica2
|
||||
|
||||
Two synchronizer a local directory with an smb server, use
|
||||
|
||||
csync /home/csync smb://rupert.galaxy.site/Users/csync
|
||||
|
||||
If you use kerberos, you don't have to specify a username or a password. If you
|
||||
don't use kerberos, the commandline client will ask about the user and the
|
||||
password. If you don't want to be prompted, you can specify it on the
|
||||
commandline:
|
||||
|
||||
csync /home/csync smb://csync:secret@rupert.galaxy.site/Users/csync
|
||||
|
||||
If you use the sftp protocol and want to specify a port, you do it the
|
||||
following way:
|
||||
|
||||
csync /home/csync sftp://csync@krikkit.galaxy.site:2222/home/csync
|
||||
|
||||
The remote destination is supported by plugins. By default csync ships with smb
|
||||
and sftp support. For more information, see the manpage of csync(1).
|
||||
|
||||
Exclude lists
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
csync provides exclude lists with simple shell wildcard patterns. There is a
|
||||
global exclude list, which is normally located in
|
||||
'/etc/csync/csync_exclude.conf' and it has already some sane defaults. If you
|
||||
run csync the first time, it will create an empty exclude list for the user.
|
||||
This file will be '~/.csync/csync_exclude.conf'. csync considers both
|
||||
configuration files and an additional one if you specify it.
|
||||
|
||||
The entries in the file are newline separated. Use
|
||||
'/etc/csync/csync_exclude.conf' as an example.
|
||||
|
||||
Debug messages and dry run
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By default the csync client logs to stderr and you can increase the debug
|
||||
level with a commandline options.
|
||||
|
||||
To simulate a run of the file synchronizer, you should set the priority to
|
||||
'debug' for the categories 'csync.updater' and 'csync.reconciler' in the config
|
||||
file '~/.csync/csync_log.conf'. Then run csync with the '--dry-run' option.
|
||||
This will only run update detection and reconciliation.
|
||||
|
||||
[[X80]]
|
||||
The PAM module
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
pam_csync is a PAM module to provide roaming home directories for a user
|
||||
session. This module is aimed at environments with central file servers where a
|
||||
user wishes to store his home directory. The Authentication Module verifies the
|
||||
identity of a user and triggers a synchronization with the server on the first
|
||||
login and the last logout. More information can be found in the manpage of the
|
||||
module pam_csync(8) or pam itself pam(8).
|
||||
|
||||
|
||||
[[X90]]
|
||||
Appendix A: Packager Notes
|
||||
--------------------------
|
||||
|
||||
Read the `README`, `INSTALL` and `FAQ` files (in the distribution root
|
||||
directory).
|
|
@ -0,0 +1,5 @@
|
|||
Replaced the plain DocBook XSL admonition icons with Jimmac's DocBook
|
||||
icons (http://jimmac.musichall.cz/ikony.php3). I dropped transparency
|
||||
from the Jimmac icons to get round MS IE and FOP PNG incompatibilies.
|
||||
|
||||
Stuart Rackham
|
После Ширина: | Высота: | Размер: 329 B |
После Ширина: | Высота: | Размер: 361 B |
После Ширина: | Высота: | Размер: 565 B |
После Ширина: | Высота: | Размер: 617 B |
После Ширина: | Высота: | Размер: 623 B |
После Ширина: | Высота: | Размер: 411 B |
После Ширина: | Высота: | Размер: 640 B |
После Ширина: | Высота: | Размер: 353 B |
После Ширина: | Высота: | Размер: 350 B |
После Ширина: | Высота: | Размер: 345 B |
После Ширина: | Высота: | Размер: 348 B |
После Ширина: | Высота: | Размер: 355 B |
После Ширина: | Высота: | Размер: 344 B |
После Ширина: | Высота: | Размер: 357 B |
После Ширина: | Высота: | Размер: 357 B |
После Ширина: | Высота: | Размер: 2.5 KiB |
После Ширина: | Высота: | Размер: 2.3 KiB |
После Ширина: | Высота: | Размер: 1.3 KiB |
После Ширина: | Высота: | Размер: 2.6 KiB |
После Ширина: | Высота: | Размер: 1.3 KiB |
После Ширина: | Высота: | Размер: 2.7 KiB |
После Ширина: | Высота: | Размер: 1.3 KiB |
После Ширина: | Высота: | Размер: 2.5 KiB |
После Ширина: | Высота: | Размер: 1.3 KiB |
После Ширина: | Высота: | Размер: 2.8 KiB |
|
@ -0,0 +1,137 @@
|
|||
project(libcsync)
|
||||
|
||||
add_subdirectory(std)
|
||||
add_subdirectory(httpbf)
|
||||
|
||||
# Statically include sqlite
|
||||
if (CSYNC_STATIC_COMPILE_DIR)
|
||||
set(SQLITE3_INCLUDE_DIRS "")
|
||||
set(SQLITE3_LIBRARIES "")
|
||||
include_directories(${CSYNC_STATIC_COMPILE_DIR})
|
||||
else (CSYNC_STATIC_COMPILE_DIR)
|
||||
find_package(SQLite3 3.3.9 REQUIRED)
|
||||
endif()
|
||||
|
||||
find_package(Neon 0.29.0 REQUIRED)
|
||||
|
||||
|
||||
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}
|
||||
${HTTPBF_PUBLIC_INCLUDE_DIRS}
|
||||
${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
set(CSYNC_LIBRARY
|
||||
ocsync
|
||||
CACHE INTERNAL "ocsync library"
|
||||
)
|
||||
|
||||
set(CSYNC_LINK_LIBRARIES
|
||||
${CSYNC_LIBRARY}
|
||||
${CSTDLIB_LIBRARY}
|
||||
${CSYNC_REQUIRED_LIBRARIES}
|
||||
${SQLITE3_LIBRARIES}
|
||||
${NEON_LIBRARIES}
|
||||
${HTTPBF_LIBRARY}
|
||||
)
|
||||
|
||||
if(HAVE_ICONV AND WITH_ICONV)
|
||||
list(APPEND CSYNC_PRIVATE_INCLUDE_DIRS ${ICONV_INCLUDE_DIR})
|
||||
list(APPEND CSYNC_LINK_LIBRARIES ${ICONV_LIBRARIES})
|
||||
endif()
|
||||
|
||||
set(BLACKLIST_ON_ERROR 0 CACHE BOOL
|
||||
"If an errors occurs three times on the same file, do not attempt to process that file any further.")
|
||||
|
||||
if(BLACKLIST_ON_ERROR)
|
||||
add_definitions(-DBLACKLIST_ON_ERROR)
|
||||
endif()
|
||||
|
||||
set(csync_SRCS
|
||||
csync.c
|
||||
csync_config.c
|
||||
csync_exclude.c
|
||||
csync_log.c
|
||||
csync_statedb.c
|
||||
csync_dbtree.c
|
||||
csync_time.c
|
||||
csync_util.c
|
||||
csync_misc.c
|
||||
csync_lock.c
|
||||
|
||||
csync_update.c
|
||||
csync_reconcile.c
|
||||
|
||||
csync_rename.cc
|
||||
|
||||
vio/csync_vio.c
|
||||
vio/csync_vio_handle.c
|
||||
vio/csync_vio_file_stat.c
|
||||
vio/csync_vio_local.c
|
||||
|
||||
csync_owncloud.c
|
||||
csync_owncloud_recursive_propfind.c
|
||||
csync_owncloud_util.c
|
||||
)
|
||||
|
||||
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_file_stat.h
|
||||
vio/csync_vio_handle.h
|
||||
vio/csync_vio_method.h
|
||||
vio/csync_vio_module.h
|
||||
)
|
||||
|
||||
# Statically include sqlite
|
||||
if (CSYNC_STATIC_COMPILE_DIR)
|
||||
list(APPEND csync_SRCS ${CSYNC_STATIC_COMPILE_DIR}/dictionary.c ${CSYNC_STATIC_COMPILE_DIR}/sqlite3.c)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CSYNC_PUBLIC_INCLUDE_DIRS}
|
||||
${CSYNC_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS})
|
||||
|
||||
target_link_libraries(${CSYNC_LINK_LIBRARIES})
|
||||
|
||||
set_target_properties(
|
||||
${CSYNC_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
TARGETS
|
||||
${CSYNC_LIBRARY}
|
||||
LIBRARY DESTINATION
|
||||
${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION
|
||||
${LIB_INSTALL_DIR}
|
||||
RUNTIME DESTINATION
|
||||
${BIN_INSTALL_DIR}
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${csync_HDRS}
|
||||
DESTINATION
|
||||
${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}
|
||||
)
|
||||
|
|
@ -0,0 +1,636 @@
|
|||
/*
|
||||
* 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <config.h>
|
||||
|
||||
#include "csync_version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* csync file declarations
|
||||
*/
|
||||
#define CSYNC_CONF_DIR ".ocsync"
|
||||
#define CSYNC_CONF_FILE "ocsync.conf"
|
||||
#define CSYNC_EXCLUDE_FILE "ocsync_exclude.conf"
|
||||
#define CSYNC_LOCK_FILE ".csync.lock"
|
||||
|
||||
/**
|
||||
* Instruction enum. In the file traversal structure, it describes
|
||||
* the csync state of a file.
|
||||
*/
|
||||
enum csync_status_codes_e {
|
||||
CSYNC_STATUS_OK = 0,
|
||||
|
||||
CSYNC_STATUS_ERROR = 1024, /* don't use this code,
|
||||
just use in csync_status_ok */
|
||||
CSYNC_STATUS_UNSUCCESSFUL,
|
||||
CSYNC_STATUS_NO_LOCK,
|
||||
CSYNC_STATUS_STATEDB_LOAD_ERROR,
|
||||
CSYNC_STATUS_STATEDB_WRITE_ERROR,
|
||||
CSYNC_STATUS_NO_MODULE,
|
||||
CSYNC_STATUS_TIMESKEW,
|
||||
CSYNC_STATUS_FILESYSTEM_UNKNOWN,
|
||||
CSYNC_STATUS_TREE_ERROR,
|
||||
CSYNC_STATUS_MEMORY_ERROR,
|
||||
CSYNC_STATUS_PARAM_ERROR,
|
||||
CSYNC_STATUS_UPDATE_ERROR,
|
||||
CSYNC_STATUS_RECONCILE_ERROR,
|
||||
CSYNC_STATUS_PROPAGATE_ERROR,
|
||||
CSYNC_STATUS_REMOTE_ACCESS_ERROR,
|
||||
CSYNC_STATUS_REMOTE_CREATE_ERROR,
|
||||
CSYNC_STATUS_REMOTE_STAT_ERROR,
|
||||
CSYNC_STATUS_LOCAL_CREATE_ERROR,
|
||||
CSYNC_STATUS_LOCAL_STAT_ERROR,
|
||||
CSYNC_STATUS_PROXY_ERROR,
|
||||
CSYNC_STATUS_LOOKUP_ERROR,
|
||||
CSYNC_STATUS_SERVER_AUTH_ERROR,
|
||||
CSYNC_STATUS_PROXY_AUTH_ERROR,
|
||||
CSYNC_STATUS_CONNECT_ERROR,
|
||||
CSYNC_STATUS_TIMEOUT,
|
||||
CSYNC_STATUS_HTTP_ERROR,
|
||||
CSYNC_STATUS_PERMISSION_DENIED,
|
||||
CSYNC_STATUS_NOT_FOUND,
|
||||
CSYNC_STATUS_FILE_EXISTS,
|
||||
CSYNC_STATUS_OUT_OF_SPACE,
|
||||
CSYNC_STATUS_QUOTA_EXCEEDED,
|
||||
CSYNC_STATUS_SERVICE_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
|
||||
};
|
||||
|
||||
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))
|
||||
|
||||
|
||||
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,
|
||||
/* instructions for the propagator */
|
||||
CSYNC_INSTRUCTION_DELETED = 0x00000200,
|
||||
CSYNC_INSTRUCTION_UPDATED = 0x00000400
|
||||
};
|
||||
|
||||
enum csync_ftw_type_e {
|
||||
CSYNC_FTW_TYPE_FILE,
|
||||
CSYNC_FTW_TYPE_SLINK,
|
||||
CSYNC_FTW_TYPE_DIR,
|
||||
CSYNC_FTW_TYPE_SKIP
|
||||
};
|
||||
|
||||
enum csync_notify_type_e {
|
||||
CSYNC_NOTIFY_INVALID,
|
||||
CSYNC_NOTIFY_START_SYNC_SEQUENCE,
|
||||
CSYNC_NOTIFY_START_DOWNLOAD,
|
||||
CSYNC_NOTIFY_START_UPLOAD,
|
||||
CSYNC_NOTIFY_PROGRESS,
|
||||
CSYNC_NOTIFY_FINISHED_DOWNLOAD,
|
||||
CSYNC_NOTIFY_FINISHED_UPLOAD,
|
||||
CSYNC_NOTIFY_FINISHED_SYNC_SEQUENCE,
|
||||
CSYNC_NOTIFY_START_DELETE,
|
||||
CSYNC_NOTIFY_END_DELETE,
|
||||
CSYNC_NOTIFY_ERROR
|
||||
};
|
||||
|
||||
struct csync_progress_s {
|
||||
enum csync_notify_type_e kind;
|
||||
|
||||
/* individual file progress information */
|
||||
const char *path;
|
||||
int64_t curr_bytes;
|
||||
int64_t file_size;
|
||||
|
||||
/* overall progress */
|
||||
int64_t overall_transmission_size;
|
||||
int64_t current_overall_bytes;
|
||||
int64_t overall_file_count;
|
||||
int64_t current_file_no;
|
||||
|
||||
};
|
||||
typedef struct csync_progress_s CSYNC_PROGRESS;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
time_t modtime;
|
||||
#ifdef _WIN32
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
#else
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
#endif
|
||||
mode_t mode;
|
||||
enum csync_ftw_type_e type;
|
||||
enum csync_instructions_e instruction;
|
||||
|
||||
/* For directories: If the etag has been updated and need to be writen on the db */
|
||||
int should_update_etag;
|
||||
|
||||
const char *rename_path;
|
||||
const char *etag;
|
||||
const char *file_id;
|
||||
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,
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
* @brief Check internal csync status.
|
||||
*
|
||||
* @param csync The context to check.
|
||||
*
|
||||
* @return true if status is error free, false for error states.
|
||||
*/
|
||||
bool csync_status_ok(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Allocate a csync context.
|
||||
*
|
||||
* @param csync The context variable to allocate.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_create(CSYNC **csync, const char *local, const char *remote);
|
||||
|
||||
/**
|
||||
* @brief Initialize the file synchronizer.
|
||||
*
|
||||
* This function loads the configuration, the statedb and locks the client.
|
||||
*
|
||||
* @param ctx The context to initialize.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_init(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Update detection
|
||||
*
|
||||
* @param ctx The context to run the update detection on.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int 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 occured.
|
||||
*/
|
||||
int csync_reconcile(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Propagation
|
||||
*
|
||||
* @param ctx The context to run the propagation on.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_propagate(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Commit the sync results to journal
|
||||
*
|
||||
* @param ctx The context to commit.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_commit(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Destroy the csync context
|
||||
*
|
||||
* Writes the statedb, unlocks csync and frees the memory.
|
||||
*
|
||||
* @param ctx The context to destroy.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_destroy(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Check if csync is the required version or get the version
|
||||
* string.
|
||||
*
|
||||
* @param req_version The version required.
|
||||
*
|
||||
* @return If the version of csync is newer than the version
|
||||
* required it will return a version string.
|
||||
* NULL if the version is older.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* @code
|
||||
* if (csync_version(CSYNC_VERSION_INT(0,42,1)) == NULL) {
|
||||
* fprintf(stderr, "libcsync version is too old!\n");
|
||||
* exit(1);
|
||||
* }
|
||||
*
|
||||
* if (debug) {
|
||||
* printf("csync %s\n", csync_version(0));
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
const char *csync_version(int req_version);
|
||||
|
||||
/**
|
||||
* @brief Add an additional exclude list.
|
||||
*
|
||||
* @param ctx The context to add the exclude list.
|
||||
*
|
||||
* @param path The path pointing to the file.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_add_exclude_list(CSYNC *ctx, const char *path);
|
||||
|
||||
/**
|
||||
* @brief Removes all items imported from exclude lists.
|
||||
*
|
||||
* @param ctx The context to add the exclude list.
|
||||
*/
|
||||
void csync_clear_exclude_list(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Get the config directory.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return The path of the config directory or NULL on error.
|
||||
*/
|
||||
const char *csync_get_config_dir(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Change the config directory.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @param path The path to the new config directory.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_set_config_dir(CSYNC *ctx, const char *path);
|
||||
|
||||
/**
|
||||
* @brief Remove the complete config directory.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_remove_config_dir(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Enable the usage of the statedb. It is enabled by default.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_enable_statedb(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Disable the usage of the statedb. It is enabled by default.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_disable_statedb(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Check if the statedb usage is enabled.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return 1 if it is enabled, 0 if it is disabled.
|
||||
*/
|
||||
int csync_is_statedb_disabled(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
|
||||
* occured.
|
||||
*/
|
||||
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 occured.
|
||||
*/
|
||||
int 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
|
||||
* occured.
|
||||
*/
|
||||
csync_auth_callback 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 occured.
|
||||
*/
|
||||
int 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 occured.
|
||||
*/
|
||||
int csync_set_log_level(int level);
|
||||
|
||||
/**
|
||||
* @brief Get the log verbosity
|
||||
*
|
||||
* @return The log verbosity, -1 on error.
|
||||
*/
|
||||
int csync_get_log_level(void);
|
||||
|
||||
/**
|
||||
* @brief Get the logging callback set.
|
||||
*
|
||||
* @return The logging callback set or NULL if an error
|
||||
* occured.
|
||||
*/
|
||||
csync_log_callback 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 occured.
|
||||
*/
|
||||
int csync_set_log_callback(csync_log_callback cb);
|
||||
|
||||
/**
|
||||
* @brief get the userdata set for the logging callback.
|
||||
*
|
||||
* @return The userdata or NULL.
|
||||
*/
|
||||
void *csync_get_log_userdata(void);
|
||||
|
||||
/**
|
||||
* @brief Set the userdata passed to the logging callback.
|
||||
*
|
||||
* @param[in] data The userdata to set.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_set_log_userdata(void *data);
|
||||
|
||||
/**
|
||||
* @brief Get the path of the statedb file used.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return The path to the statedb file, NULL if an error occured.
|
||||
*/
|
||||
const char *csync_get_statedb_file(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Enable the creation of backup copys if files are changed on both sides
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_enable_conflictcopys(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Flag to tell csync that only a local run is intended. Call before csync_init
|
||||
*
|
||||
* @param local_only Bool flag to indicate local only mode.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_set_local_only( CSYNC *ctx, bool local_only );
|
||||
|
||||
/**
|
||||
* @brief Retrieve the flag to tell csync that only a local run is intended.
|
||||
*
|
||||
* @return 1: stay local only, 0: local and remote mode
|
||||
*/
|
||||
bool csync_get_local_only( CSYNC *ctx );
|
||||
|
||||
/* Used for special modes or debugging */
|
||||
CSYNC_STATUS csync_get_status(CSYNC *ctx);
|
||||
|
||||
/* Used for special modes or debugging */
|
||||
int 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 occured.
|
||||
*/
|
||||
int 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 occured.
|
||||
*/
|
||||
int 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 *csync_get_status_string(CSYNC *ctx);
|
||||
|
||||
#ifdef WITH_ICONV
|
||||
/**
|
||||
* @brief Set iconv source codec for filenames.
|
||||
*
|
||||
* @param from Source codec.
|
||||
*
|
||||
* @return 0 on success, or an iconv error number.
|
||||
*/
|
||||
int csync_set_iconv_codec(const char *from);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set a property to module
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @param key The property key
|
||||
*
|
||||
* @param value An opaque pointer to the data.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_set_module_property(CSYNC *ctx, const char *key, void *value);
|
||||
|
||||
/**
|
||||
* @brief Callback definition for file progress callback.
|
||||
*
|
||||
* @param progress A struct containing progress information.
|
||||
*
|
||||
* @param userdata User defined data for the callback.
|
||||
*/
|
||||
typedef void (*csync_progress_callback)( CSYNC_PROGRESS *progress, void *userdata);
|
||||
|
||||
/**
|
||||
* @brief Set a progress callback.
|
||||
*
|
||||
* This callback reports about up- or download progress of a individual file
|
||||
* as well as overall progress.
|
||||
*/
|
||||
int csync_set_progress_callback( CSYNC *ctx, csync_progress_callback cb);
|
||||
|
||||
csync_progress_callback csync_get_progress_callback(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Aborts the current sync run as soon as possible. Can be called from another thread.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*/
|
||||
void csync_request_abort(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Clears the abort flag. Can be called from another thread.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*/
|
||||
void csync_resume(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Checks for the abort flag, to be used from the modules.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*/
|
||||
int csync_abort_requested(CSYNC *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* }@
|
||||
*/
|
||||
#endif /* _CSYNC_H */
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
|
@ -0,0 +1,362 @@
|
|||
/*
|
||||
* 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.h"
|
||||
|
||||
/* #define _GNU_SOURCE */
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "c_private.h"
|
||||
#include "csync_private.h"
|
||||
#include "csync_config.h"
|
||||
#include "csync_misc.h"
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.config"
|
||||
#include "csync_log.h"
|
||||
|
||||
enum csync_config_opcode_e {
|
||||
COC_UNSUPPORTED = -1,
|
||||
COC_MAX_TIMEDIFF,
|
||||
COC_MAX_DEPTH,
|
||||
COC_WITH_CONFLICT_COPY,
|
||||
COC_TIMEOUT
|
||||
};
|
||||
|
||||
struct csync_config_keyword_table_s {
|
||||
const char *name;
|
||||
enum csync_config_opcode_e opcode;
|
||||
};
|
||||
|
||||
static struct csync_config_keyword_table_s csync_config_keyword_table[] = {
|
||||
{ "max_depth", COC_MAX_DEPTH },
|
||||
{ "max_time_difference", COC_MAX_TIMEDIFF },
|
||||
{ "with_confilct_copies", COC_WITH_CONFLICT_COPY },
|
||||
{ "timeout", COC_TIMEOUT },
|
||||
{ NULL, COC_UNSUPPORTED }
|
||||
};
|
||||
|
||||
static enum csync_config_opcode_e csync_config_get_opcode(char *keyword) {
|
||||
int i;
|
||||
|
||||
for (i = 0; csync_config_keyword_table[i].name != NULL; i++) {
|
||||
if (strcasecmp(keyword, csync_config_keyword_table[i].name) == 0) {
|
||||
return csync_config_keyword_table[i].opcode;
|
||||
}
|
||||
}
|
||||
|
||||
return COC_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static int _csync_config_copy_default (const char *config) {
|
||||
int rc = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* For win32, try to copy the conf file from the directory from where the app was started. */
|
||||
mbchar_t tcharbuf[MAX_PATH+1];
|
||||
char *buf;
|
||||
int len = 0;
|
||||
|
||||
|
||||
/* Get the path from where the application was started */
|
||||
len = GetModuleFileNameW(NULL, tcharbuf, MAX_PATH);
|
||||
if(len== 0) {
|
||||
rc = -1;
|
||||
} else {
|
||||
char *last_bslash;
|
||||
|
||||
buf = c_utf8_from_locale(tcharbuf);
|
||||
/* cut the trailing filename off */
|
||||
if ((last_bslash = strrchr(buf, '\\')) != NULL) {
|
||||
*last_bslash='\0';
|
||||
}
|
||||
|
||||
strncat(buf, "\\" CSYNC_CONF_FILE, MAX_PATH);
|
||||
if(c_copy(buf, config, 0644) < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Could not copy /%s to %s", buf, config );
|
||||
rc = -1;
|
||||
}
|
||||
c_free_locale_string(buf);
|
||||
}
|
||||
#else
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Copy %s/config/%s to %s", SYSCONFDIR,
|
||||
CSYNC_CONF_FILE, config);
|
||||
# ifdef WITH_UNIT_TESTING
|
||||
rc = c_copy(BINARYDIR "/config/" CSYNC_CONF_FILE, config, 0644);
|
||||
# else
|
||||
rc = 0;
|
||||
# endif
|
||||
if (c_copy(SYSCONFDIR "/ocsync/" CSYNC_CONF_FILE, config, 0644) < 0) {
|
||||
if (c_copy(BINARYDIR "/config/" CSYNC_CONF_FILE, config, 0644) < 0) {
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
static char *csync_config_get_cmd(char **str) {
|
||||
register char *c;
|
||||
char *r;
|
||||
|
||||
/* Ignore leading spaces */
|
||||
for (c = *str; *c; c++) {
|
||||
if (! isblank(*c)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*c == '\"') {
|
||||
for (r = ++c; *c; c++) {
|
||||
if (*c == '\"') {
|
||||
*c = '\0';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (r = c; *c; c++) {
|
||||
if (*c == '\n') {
|
||||
*c = '\0';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
*str = c + 1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static char *csync_config_get_token(char **str) {
|
||||
register char *c;
|
||||
char *r;
|
||||
|
||||
c = csync_config_get_cmd(str);
|
||||
|
||||
for (r = c; *c; c++) {
|
||||
if (isblank(*c)) {
|
||||
*c = '\0';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
*str = c + 1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int csync_config_get_int(char **str, int notfound) {
|
||||
char *p, *endp;
|
||||
int i;
|
||||
|
||||
p = csync_config_get_token(str);
|
||||
if (p && *p) {
|
||||
i = strtol(p, &endp, 10);
|
||||
if (p == endp) {
|
||||
return notfound;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
return notfound;
|
||||
}
|
||||
|
||||
static const char *csync_config_get_str_tok(char **str, const char *def) {
|
||||
char *p;
|
||||
p = csync_config_get_token(str);
|
||||
if (p && *p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
static int csync_config_get_yesno(char **str, int notfound) {
|
||||
const char *p;
|
||||
|
||||
p = csync_config_get_str_tok(str, NULL);
|
||||
if (p == NULL) {
|
||||
return notfound;
|
||||
}
|
||||
|
||||
if (strncasecmp(p, "yes", 3) == 0) {
|
||||
return 1;
|
||||
} else if (strncasecmp(p, "no", 2) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return notfound;
|
||||
}
|
||||
|
||||
static int csync_config_parse_line(CSYNC *ctx,
|
||||
const char *line,
|
||||
unsigned int count)
|
||||
{
|
||||
enum csync_config_opcode_e opcode;
|
||||
char *s, *x;
|
||||
char *keyword;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
x = s = c_strdup(line);
|
||||
if (s == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Remove trailing spaces */
|
||||
for (len = strlen(s) - 1; len > 0; len--) {
|
||||
if (! isspace(s[len])) {
|
||||
break;
|
||||
}
|
||||
s[len] = '\0';
|
||||
}
|
||||
|
||||
keyword = csync_config_get_token(&s);
|
||||
if (keyword == NULL || keyword[0] == '#' ||
|
||||
keyword[0] == '\0' || keyword[0] == '\n') {
|
||||
free(x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
opcode = csync_config_get_opcode(keyword);
|
||||
|
||||
switch (opcode) {
|
||||
case COC_MAX_DEPTH:
|
||||
i = csync_config_get_int(&s, 50);
|
||||
if (i > 0) {
|
||||
ctx->options.max_depth = i;
|
||||
}
|
||||
break;
|
||||
case COC_MAX_TIMEDIFF:
|
||||
i = csync_config_get_int(&s, 10);
|
||||
if (i >= 0) {
|
||||
ctx->options.max_time_difference = i;
|
||||
}
|
||||
break;
|
||||
case COC_WITH_CONFLICT_COPY:
|
||||
i = csync_config_get_yesno(&s, -1);
|
||||
if (i > 0) {
|
||||
ctx->options.with_conflict_copys = true;
|
||||
} else {
|
||||
ctx->options.with_conflict_copys = false;
|
||||
}
|
||||
break;
|
||||
case COC_TIMEOUT:
|
||||
i = csync_config_get_int(&s, 0);
|
||||
if (i > 0) {
|
||||
ctx->options.timeout = i;
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Config: timeout = %d",
|
||||
ctx->options.timeout);
|
||||
}
|
||||
break;
|
||||
case COC_UNSUPPORTED:
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"Unsupported option: %s, line: %d\n",
|
||||
keyword, count);
|
||||
break;
|
||||
}
|
||||
|
||||
free(x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int csync_config_parse_file(CSYNC *ctx, const char *config)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
char line[1024] = {0};
|
||||
char *s;
|
||||
FILE *f;
|
||||
|
||||
/* copy default config, if no config exists */
|
||||
if (! c_isfile(config)) {
|
||||
/* check if there is still one csync.conf left over in $HOME/.csync
|
||||
* and copy it over (migration path)
|
||||
*/
|
||||
char *home = NULL;
|
||||
char *home_config = NULL;
|
||||
char *config_file = NULL;
|
||||
|
||||
/* there is no statedb at the expected place. */
|
||||
home = csync_get_user_home_dir();
|
||||
if( !c_streq(home, ctx->options.config_dir) ) {
|
||||
int rc = -1;
|
||||
|
||||
config_file = c_basename(config);
|
||||
if( config_file ) {
|
||||
rc = asprintf(&home_config, "%s/%s/%s", home, CSYNC_CONF_DIR, config_file);
|
||||
SAFE_FREE(config_file);
|
||||
}
|
||||
|
||||
if (rc >= 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "config file %s not found, checking %s",
|
||||
config, home_config);
|
||||
|
||||
/* check the home file and copy to new statedb if existing. */
|
||||
if(c_isfile(home_config)) {
|
||||
if (c_copy(home_config, config, 0644) < 0) {
|
||||
/* copy failed, but that is not reason to die. */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Could not copy config %s => %s",
|
||||
home_config, config);
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "Copied %s => %s",
|
||||
home_config, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
SAFE_FREE(home_config);
|
||||
}
|
||||
SAFE_FREE(home);
|
||||
/* Still install the default one if nothing is there. */
|
||||
if( ! c_isfile(config)) {
|
||||
if (_csync_config_copy_default(config) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f = fopen(config, "r");
|
||||
if (f == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"Reading configuration data from %s",
|
||||
config);
|
||||
|
||||
s = fgets(line, sizeof(line), f);
|
||||
while (s != NULL) {
|
||||
int rc;
|
||||
count++;
|
||||
|
||||
rc = csync_config_parse_line(ctx, line, count);
|
||||
if (rc < 0) {
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
s = fgets(line, sizeof(line), f);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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_CONFIG_H
|
||||
#define _CSYNC_CONFIG_H
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Load the csync configuration.
|
||||
*
|
||||
* @param ctx The csync context to use.
|
||||
*
|
||||
* @param config The path to the config file.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
int csync_config_load(CSYNC *ctx, const char *config);
|
||||
|
||||
int csync_config_parse_file(CSYNC *ctx, const char *config);
|
||||
|
||||
#endif /* _CSYNC_X_H */
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2012 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.h"
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "csync_dbtree.h"
|
||||
#include "c_lib.h"
|
||||
#include "csync_private.h"
|
||||
#include "csync_statedb.h"
|
||||
#include "csync_util.h"
|
||||
#include "c_macro.h"
|
||||
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.dbtree"
|
||||
#include "csync_log.h"
|
||||
|
||||
struct dir_listing {
|
||||
c_list_t *list;
|
||||
unsigned int cnt;
|
||||
c_list_t *entry;
|
||||
char *dir;
|
||||
};
|
||||
|
||||
csync_vio_method_handle_t *csync_dbtree_opendir(CSYNC *ctx, const char *name)
|
||||
{
|
||||
|
||||
char *column = NULL;
|
||||
const char *path = NULL;
|
||||
csync_vio_file_stat_t *fs = NULL;
|
||||
unsigned int c = 0;
|
||||
c_strlist_t *list = NULL;
|
||||
struct dir_listing *listing = NULL;
|
||||
|
||||
/* "phash INTEGER(8),"
|
||||
"pathlen INTEGER,"
|
||||
"path VARCHAR(4096),"
|
||||
"inode INTEGER,"
|
||||
"uid INTEGER,"
|
||||
"gid INTEGER,"
|
||||
"mode INTEGER,"
|
||||
"modtime INTEGER(8),"
|
||||
"type INTEGER,"
|
||||
"md5 VARCHAR(32)," // That's the etag
|
||||
*/
|
||||
|
||||
int col_count = 10;
|
||||
if( strlen(name) < strlen(ctx->remote.uri)+1) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "name does not contain remote uri!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
path = name + strlen(ctx->remote.uri)+1;
|
||||
|
||||
list = csync_statedb_get_below_path(ctx, path);
|
||||
|
||||
if( ! list ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Query result list is NULL!");
|
||||
return NULL;
|
||||
}
|
||||
/* list count must be a multiple of col_count */
|
||||
if( list->count % col_count != 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Wrong size of query result list");
|
||||
c_strlist_destroy( list );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
listing = c_malloc(sizeof(struct dir_listing));
|
||||
ZERO_STRUCTP(listing);
|
||||
if( listing == NULL ) {
|
||||
c_strlist_destroy( list );
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
listing->dir = c_strdup(path);
|
||||
|
||||
for( c = 0; c < (list->count / col_count); c++) {
|
||||
int base = c*col_count;
|
||||
int cnt = 0;
|
||||
int tpath_len = 0;
|
||||
int type = 0;
|
||||
|
||||
char *tpath = list->vector[base+1];
|
||||
/* check if the result points to a file directly below the search path
|
||||
* by checking if there is another / in the result.
|
||||
* If yes, skip it.
|
||||
* FIXME: Find a better filter solution here.
|
||||
*/
|
||||
tpath += strlen(path)+1; /* jump over the search path */
|
||||
tpath_len = strlen( tpath );
|
||||
while( cnt < tpath_len ) {
|
||||
if(*(tpath+cnt) == '/') {
|
||||
/* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Skipping entry: %s", list->vector[base+1]); */
|
||||
break;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
if( cnt < tpath_len ) continue;
|
||||
|
||||
if (!list->vector[base+8][0])
|
||||
continue; /* If etag is empty, the file was removed on the server */
|
||||
|
||||
fs = csync_vio_file_stat_new();
|
||||
fs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
|
||||
|
||||
column = list->vector[base+0]; /* phash */
|
||||
|
||||
column = list->vector[base+1]; /* path */
|
||||
fs->name = c_strdup(column+strlen(path)+1);
|
||||
|
||||
column = list->vector[base+2]; /* inode */
|
||||
fs->inode = atoll(column);
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
|
||||
|
||||
column = list->vector[base+3]; /* uid */
|
||||
fs->uid = atoi(column);
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_UID;
|
||||
|
||||
column = list->vector[base+4]; /* gid */
|
||||
fs->gid = atoi(column);
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_GID;
|
||||
|
||||
column = list->vector[base+5]; /* mode */
|
||||
fs->mode = atoi(column);
|
||||
// fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_M;
|
||||
|
||||
column = list->vector[base+6]; /* modtime */
|
||||
fs->mtime = strtoul(column, NULL, 10);
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
|
||||
|
||||
column = list->vector[base+7]; /* type */
|
||||
type = atoi(column);
|
||||
/* Attention: the type of csync_ftw_type_e which is the source for
|
||||
* the database entry is different from csync_vio_file_type_e which
|
||||
* is the target file type here. Mapping is needed!
|
||||
*/
|
||||
switch( type ) {
|
||||
case CSYNC_FTW_TYPE_DIR:
|
||||
fs->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
|
||||
break;
|
||||
case CSYNC_FTW_TYPE_FILE:
|
||||
fs->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
break;
|
||||
case CSYNC_FTW_TYPE_SLINK:
|
||||
fs->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
break;
|
||||
default:
|
||||
fs->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
|
||||
}
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
|
||||
|
||||
column = list->vector[base+8]; /* etag */
|
||||
fs->etag = c_strdup(column);
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG;
|
||||
|
||||
column = list->vector[base+9]; /* file id */
|
||||
csync_vio_file_stat_set_file_id(fs, column);
|
||||
|
||||
/* store into result list. */
|
||||
listing->list = c_list_append( listing->list, fs );
|
||||
listing->cnt++;
|
||||
}
|
||||
|
||||
if(listing->cnt)
|
||||
listing->entry = c_list_first( listing->list );
|
||||
|
||||
c_strlist_destroy( list );
|
||||
|
||||
return listing;
|
||||
}
|
||||
|
||||
int csync_dbtree_closedir(CSYNC *ctx, csync_vio_method_handle_t *dhandle)
|
||||
{
|
||||
struct dir_listing *dl = NULL;
|
||||
int rc = 0;
|
||||
(void) ctx;
|
||||
|
||||
if( dhandle != NULL ) {
|
||||
dl = (struct dir_listing*) dhandle;
|
||||
|
||||
c_list_free(dl->list);
|
||||
SAFE_FREE(dl->dir);
|
||||
SAFE_FREE(dl);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
csync_vio_file_stat_t *csync_dbtree_readdir(CSYNC *ctx, csync_vio_method_handle_t *dhandle)
|
||||
{
|
||||
csync_vio_file_stat_t *fs = NULL;
|
||||
struct dir_listing *dl = NULL;
|
||||
(void) ctx;
|
||||
|
||||
if( dhandle != NULL ) {
|
||||
dl = (struct dir_listing*) dhandle;
|
||||
if( dl->entry != NULL ) {
|
||||
fs = (csync_vio_file_stat_t*) dl->entry->data;
|
||||
|
||||
dl->entry = c_list_next( dl->entry);
|
||||
}
|
||||
}
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
/* vim: set ts=8 sw=2 et cindent: */
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2012 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_dbtree.h
|
||||
*
|
||||
* @brief Private interface of csync
|
||||
*
|
||||
* @defgroup csyncdbtreeInternals csync statedb internals
|
||||
* @ingroup csyncInternalAPI
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CSYNC_DBTREE_H
|
||||
#define _CSYNC_DBTREE_H
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "csync_private.h"
|
||||
#include "vio/csync_vio_handle.h"
|
||||
|
||||
/**
|
||||
* @brief Open a directory based on the statedb.
|
||||
*
|
||||
* This function reads the list of files within a directory from statedb and
|
||||
* builds up a list in memory.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
* @param name The directory name.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured with errno set.
|
||||
*/
|
||||
csync_vio_method_handle_t *csync_dbtree_opendir(CSYNC *ctx, const char *name);
|
||||
|
||||
int csync_dbtree_closedir(CSYNC *ctx, csync_vio_method_handle_t *dhandle);
|
||||
|
||||
csync_vio_file_stat_t *csync_dbtree_readdir(CSYNC *ctx, csync_vio_method_handle_t *dhandle);
|
||||
|
||||
/**
|
||||
* }@
|
||||
*/
|
||||
#endif /* _CSYNC_DBTREE_H */
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* 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.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "c_lib.h"
|
||||
|
||||
#include "csync_private.h"
|
||||
#include "csync_exclude.h"
|
||||
#include "csync_misc.h"
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.exclude"
|
||||
#include "csync_log.h"
|
||||
|
||||
static int _csync_exclude_add(CSYNC *ctx, const char *string) {
|
||||
c_strlist_t *list;
|
||||
|
||||
if (ctx->excludes == NULL) {
|
||||
ctx->excludes = c_strlist_new(32);
|
||||
if (ctx->excludes == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->excludes->count == ctx->excludes->size) {
|
||||
list = c_strlist_expand(ctx->excludes, 2 * ctx->excludes->size);
|
||||
if (list == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ctx->excludes = list;
|
||||
}
|
||||
|
||||
return c_strlist_add(ctx->excludes, string);
|
||||
}
|
||||
|
||||
int csync_exclude_load(CSYNC *ctx, const char *fname) {
|
||||
int fd = -1;
|
||||
int i = 0;
|
||||
int rc = -1;
|
||||
int64_t size;
|
||||
char *buf = NULL;
|
||||
char *entry = NULL;
|
||||
mbchar_t *w_fname;
|
||||
|
||||
if (ctx == NULL || fname == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
_fmode = _O_BINARY;
|
||||
#endif
|
||||
|
||||
w_fname = c_utf8_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 (buf == NULL) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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 != '#') {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", entry);
|
||||
rc = _csync_exclude_add(ctx, entry);
|
||||
if (rc < 0) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
entry = buf + i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
out:
|
||||
SAFE_FREE(buf);
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void csync_exclude_clear(CSYNC *ctx) {
|
||||
c_strlist_clear(ctx->excludes);
|
||||
}
|
||||
|
||||
void csync_exclude_destroy(CSYNC *ctx) {
|
||||
c_strlist_destroy(ctx->excludes);
|
||||
}
|
||||
|
||||
CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
|
||||
size_t i = 0;
|
||||
const char *p = NULL;
|
||||
char *bname = NULL;
|
||||
char *dname = NULL;
|
||||
char *prev_dname = NULL;
|
||||
int rc = -1;
|
||||
CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED;
|
||||
CSYNC_EXCLUDE_TYPE type = CSYNC_NOT_EXCLUDED;
|
||||
|
||||
/* exclude the lock file */
|
||||
if (c_streq( path, CSYNC_LOCK_FILE )) {
|
||||
return CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
}
|
||||
|
||||
if (! ctx->options.unix_extensions) {
|
||||
for (p = path; *p; p++) {
|
||||
switch (*p) {
|
||||
case '\\':
|
||||
case ':':
|
||||
case '?':
|
||||
case '*':
|
||||
case '"':
|
||||
case '>':
|
||||
case '<':
|
||||
case '|':
|
||||
return CSYNC_FILE_EXCLUDE_INVALID_CHAR;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* split up the path */
|
||||
dname = c_dirname(path);
|
||||
bname = c_basename(path);
|
||||
|
||||
if (bname == NULL || dname == NULL) {
|
||||
match = CSYNC_NOT_EXCLUDED;
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = csync_fnmatch(".csync_journal.db*", bname, 0);
|
||||
if (rc == 0) {
|
||||
match = CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
goto out;
|
||||
}
|
||||
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
|
||||
if (ctx->excludes == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Loop over all exclude patterns and evaluate the given path */
|
||||
for (i = 0; match == CSYNC_NOT_EXCLUDED && i < ctx->excludes->count; i++) {
|
||||
bool match_dirs_only = false;
|
||||
char *pattern_stored = c_strdup(ctx->excludes->vector[i]);
|
||||
char* pattern = pattern_stored;
|
||||
|
||||
type = CSYNC_FILE_EXCLUDE_LIST;
|
||||
if (strlen(pattern) < 1) {
|
||||
continue;
|
||||
}
|
||||
/* Ecludes 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] == '/') {
|
||||
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 of the path */
|
||||
if (match == CSYNC_NOT_EXCLUDED) {
|
||||
int trailing_component = 1;
|
||||
dname = c_dirname(path);
|
||||
bname = c_basename(path);
|
||||
|
||||
if (bname == NULL || dname == NULL) {
|
||||
match = CSYNC_NOT_EXCLUDED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Check each component of the path */
|
||||
do {
|
||||
/* Do not check the bname if its a file and the pattern matches dirs only. */
|
||||
if ( !(trailing_component == 1 /* it is the trailing component */
|
||||
&& match_dirs_only /* but only directories are matched by the pattern */
|
||||
&& filetype == CSYNC_FTW_TYPE_FILE) ) {
|
||||
/* Check the name component against the pattern */
|
||||
rc = csync_fnmatch(pattern, bname, 0);
|
||||
if (rc == 0) {
|
||||
match = type;
|
||||
}
|
||||
}
|
||||
if (!(c_streq(dname, ".") || c_streq(dname, "/"))) {
|
||||
rc = csync_fnmatch(pattern, dname, 0);
|
||||
if (rc == 0) {
|
||||
match = type;
|
||||
}
|
||||
}
|
||||
trailing_component = 0;
|
||||
prev_dname = dname;
|
||||
SAFE_FREE(bname);
|
||||
bname = c_basename(prev_dname);
|
||||
dname = c_dirname(prev_dname);
|
||||
SAFE_FREE(prev_dname);
|
||||
|
||||
} while( match == CSYNC_NOT_EXCLUDED && !c_streq(dname, ".")
|
||||
&& !c_streq(dname, "/") );
|
||||
}
|
||||
SAFE_FREE(pattern_stored);
|
||||
SAFE_FREE(bname);
|
||||
SAFE_FREE(dname);
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
return match;
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
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
|
||||
};
|
||||
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
|
||||
/**
|
||||
* @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 occured with errno set.
|
||||
*/
|
||||
int csync_exclude_load(CSYNC *ctx, const char *fname);
|
||||
|
||||
/**
|
||||
* @brief Clear the exclude list in memory.
|
||||
*
|
||||
* @param ctx The synchronizer context.
|
||||
*/
|
||||
void csync_exclude_clear(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Destroy the exclude list in memory.
|
||||
*
|
||||
* @param ctx The synchronizer context.
|
||||
*/
|
||||
void csync_exclude_destroy(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Check if the given path should be excluded.
|
||||
*
|
||||
* This excludes also paths which can't be used without unix extensions.
|
||||
*
|
||||
* @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(CSYNC *ctx, const char *path, int filetype);
|
||||
|
||||
#endif /* _CSYNC_EXCLUDE_H */
|
||||
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* 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.h"
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "csync_lock.h"
|
||||
#include "csync.h"
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.lock"
|
||||
#include "csync_log.h"
|
||||
|
||||
#ifdef _DO_CREATE_A_LOCK_FILE
|
||||
static int _csync_lock_create(const char *lockfile) {
|
||||
int fd = -1;
|
||||
pid_t pid = 0;
|
||||
int rc = -1;
|
||||
char errbuf[256] = {0};
|
||||
char *ctmpfile = NULL;
|
||||
char *dir = NULL;
|
||||
char *buf = NULL;
|
||||
mode_t mask;
|
||||
|
||||
pid = getpid();
|
||||
|
||||
dir = c_dirname(lockfile);
|
||||
if (dir == NULL) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (asprintf(&ctmpfile, "%s/tmp_lock_XXXXXX", dir) < 0) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Create temporary lock file: %s", ctmpfile);
|
||||
mask = umask(0077);
|
||||
fd = mkstemp(ctmpfile);
|
||||
umask(mask);
|
||||
if (fd < 0) {
|
||||
strerror_r(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
|
||||
"Unable to create temporary lock file: %s - %s",
|
||||
ctmpfile,
|
||||
errbuf);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Write pid (%d) to temporary lock file: %s", pid, ctmpfile);
|
||||
pid = asprintf(&buf, "%d\n", pid);
|
||||
if (write(fd, buf, pid) == pid) {
|
||||
/* Create lock file */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Create a hardlink from %s to %s.", ctmpfile, lockfile);
|
||||
if (link(ctmpfile, lockfile) < 0 ) {
|
||||
/* Oops, alredy locked */
|
||||
strerror_r(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO,
|
||||
"Already locked: %s - %s",
|
||||
lockfile,
|
||||
errbuf);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
strerror_r(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
|
||||
"Can't create %s - %s",
|
||||
ctmpfile,
|
||||
errbuf);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
if (fd > 0) {
|
||||
close(fd);
|
||||
}
|
||||
if (ctmpfile) {
|
||||
unlink(ctmpfile);
|
||||
}
|
||||
|
||||
SAFE_FREE(buf);
|
||||
SAFE_FREE(dir);
|
||||
SAFE_FREE(ctmpfile);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static pid_t _csync_lock_read(const char *lockfile) {
|
||||
char errbuf[256] = {0};
|
||||
char buf[8] = {0};
|
||||
long int tmp;
|
||||
ssize_t rc;
|
||||
int fd;
|
||||
pid_t pid;
|
||||
mbchar_t *wlockfile;
|
||||
|
||||
/* Read PID from existing lock */
|
||||
#ifdef _WIN32
|
||||
_fmode = _O_BINARY;
|
||||
#endif
|
||||
|
||||
wlockfile = c_utf8_to_locale(lockfile);
|
||||
if (wlockfile == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = _topen(wlockfile, O_RDONLY);
|
||||
c_free_locale_string(wlockfile);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
|
||||
if (rc <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
tmp = strtol(buf, NULL, 10);
|
||||
if (tmp == 0 || tmp > 0xFFFF || errno == ERANGE) {
|
||||
/* Broken lock file */
|
||||
strerror_r(ERANGE, errbuf, sizeof(errbuf));
|
||||
if (unlink(lockfile) < 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
|
||||
"Unable to remove broken lock %s - %s",
|
||||
lockfile,
|
||||
errbuf);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
pid = (pid_t)(tmp & 0xFFFF);
|
||||
|
||||
/* Check if process is still alive */
|
||||
if (kill(pid, 0) < 0 && errno == ESRCH) {
|
||||
/* Process is dead. Remove stale lock. */
|
||||
wlockfile = c_utf8_to_locale(lockfile);
|
||||
|
||||
if (_tunlink(wlockfile) < 0) {
|
||||
strerror_r(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
|
||||
"Unable to remove stale lock %s - %s",
|
||||
lockfile,
|
||||
errbuf);
|
||||
}
|
||||
c_free_locale_string(wlockfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
#endif
|
||||
|
||||
int csync_lock(const char *lockfile) {
|
||||
#ifdef _DO_CREATE_A_LOCK_FILE /* disable lock file for ownCloud client, not only _WIN32 */
|
||||
/* Check if lock already exists. */
|
||||
if (_csync_lock_read(lockfile) > 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Aborting, another synchronization process is running.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Creating lock file: %s", lockfile);
|
||||
|
||||
return _csync_lock_create(lockfile);
|
||||
#else
|
||||
(void) lockfile;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void csync_lock_remove(const char *lockfile) {
|
||||
#ifdef _DO_CREATE_A_LOCK_FILE
|
||||
#ifndef _WIN32
|
||||
char errbuf[256] = {0};
|
||||
mbchar_t *wlockfile;
|
||||
|
||||
/* You can't remove the lock if it is from another process */
|
||||
if (_csync_lock_read(lockfile) == getpid()) {
|
||||
wlockfile = c_utf8_to_locale(lockfile);
|
||||
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Removing lock file: %s", lockfile);
|
||||
if (_tunlink(wlockfile) < 0) {
|
||||
strerror_r(errno, errbuf, sizeof(errbuf));
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR,
|
||||
"Unable to remove lock %s - %s",
|
||||
lockfile,
|
||||
errbuf);
|
||||
}
|
||||
c_free_locale_string(wlockfile);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
(void) lockfile;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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_LOCK_H
|
||||
#define _CSYNC_LOCK_H
|
||||
|
||||
#include "csync.h"
|
||||
|
||||
/**
|
||||
* @file csync_lock.h
|
||||
*
|
||||
* @brief File locking
|
||||
*
|
||||
* This prevents csync to start the same synchronization task twice which could
|
||||
* lead to several problems.
|
||||
*
|
||||
* @defgroup csyncLockingInternals csync file lockling internals
|
||||
* @ingroup csyncInternalAPI
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Lock the client if possible.
|
||||
*
|
||||
* This functiion tries to lock the client with a lock file.
|
||||
*
|
||||
* @param lockfile The lock file to create.
|
||||
*
|
||||
* @return 0 if the lock was successfull, less than 0 if the lock file
|
||||
* couldn't be created or if it is already locked.
|
||||
*/
|
||||
int csync_lock(const char *lockfile);
|
||||
|
||||
/**
|
||||
* @brief Remove the lockfile
|
||||
*
|
||||
* Only our own lock can be removed. This function can't remove a lock from
|
||||
* another client.
|
||||
*
|
||||
* @param lockfile The lock file to remove.
|
||||
*/
|
||||
void csync_lock_remove(const char *lockfile);
|
||||
|
||||
/**
|
||||
* }@
|
||||
*/
|
||||
#endif /* _CSYNC_LOCK_H */
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* 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.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <sys/utime.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
#include "csync_private.h"
|
||||
#include "csync_log.h"
|
||||
|
||||
CSYNC_THREAD int csync_log_level;
|
||||
CSYNC_THREAD csync_log_callback csync_log_cb;
|
||||
CSYNC_THREAD void *csync_log_userdata;
|
||||
|
||||
static int current_timestring(int hires, char *buf, size_t len)
|
||||
{
|
||||
char tbuf[64];
|
||||
struct timeval tv;
|
||||
struct tm *tm;
|
||||
time_t t;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
t = (time_t) tv.tv_sec;
|
||||
|
||||
tm = localtime(&t);
|
||||
if (tm == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hires) {
|
||||
strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm);
|
||||
snprintf(buf, len, "%s.%06ld", tbuf, (long) tv.tv_usec);
|
||||
} else {
|
||||
strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm);
|
||||
snprintf(buf, len, "%s", tbuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void csync_log_stderr(int verbosity,
|
||||
const char *function,
|
||||
const char *buffer)
|
||||
{
|
||||
char date[64] = {0};
|
||||
int rc;
|
||||
|
||||
rc = current_timestring(1, date, sizeof(date));
|
||||
if (rc == 0) {
|
||||
fprintf(stderr, "[%s, %d] %s:", date+5, verbosity, function);
|
||||
} else {
|
||||
fprintf(stderr, "[%d] %s", verbosity, function);
|
||||
}
|
||||
|
||||
fprintf(stderr, " %s\n", buffer);
|
||||
}
|
||||
static void csync_log_function(int verbosity,
|
||||
const char *function,
|
||||
const char *buffer)
|
||||
{
|
||||
csync_log_callback log_fn = csync_get_log_callback();
|
||||
if (log_fn) {
|
||||
char buf[1024];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s: %s", function, buffer);
|
||||
|
||||
log_fn(verbosity,
|
||||
function,
|
||||
buf,
|
||||
csync_get_log_userdata());
|
||||
return;
|
||||
}
|
||||
|
||||
csync_log_stderr(verbosity, function, buffer);
|
||||
}
|
||||
|
||||
|
||||
void csync_log(int verbosity,
|
||||
const char *function,
|
||||
const char *format, ...)
|
||||
{
|
||||
char buffer[1024];
|
||||
va_list va;
|
||||
|
||||
if (verbosity <= csync_get_log_level()) {
|
||||
va_start(va, format);
|
||||
vsnprintf(buffer, sizeof(buffer), format, va);
|
||||
va_end(va);
|
||||
csync_log_function(verbosity, function, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void *csync_get_log_userdata(void)
|
||||
{
|
||||
return csync_log_userdata;
|
||||
}
|
||||
|
||||
int csync_set_log_userdata(void *data)
|
||||
{
|
||||
csync_log_userdata = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -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, __FUNCTION__, __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: */
|
|
@ -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_TIMEDELTA CSYNC_CUSTOM_ERRNO_BASE+12
|
||||
#define ERRNO_ERROR_STRING CSYNC_CUSTOM_ERRNO_BASE+13
|
||||
#define ERRNO_SERVICE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+14
|
||||
#define ERRNO_QUOTA_EXCEEDED CSYNC_CUSTOM_ERRNO_BASE+15
|
||||
#define ERRNO_USER_ABORT CSYNC_CUSTOM_ERRNO_BASE+16
|
||||
|
||||
#endif /* _CSYNC_MACROS_H */
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* 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.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>
|
||||
# include <unistd.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "csync_misc.h"
|
||||
#include "csync_macros.h"
|
||||
#include "csync_log.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
char *csync_get_user_home_dir(void) {
|
||||
wchar_t tmp[MAX_PATH];
|
||||
char *szPath = NULL;
|
||||
|
||||
if( SHGetFolderPathW( NULL,
|
||||
CSIDL_PROFILE|CSIDL_FLAG_CREATE,
|
||||
NULL,
|
||||
0,
|
||||
tmp) == S_OK ) {
|
||||
szPath = c_utf8_from_locale(tmp);
|
||||
return szPath;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *csync_get_local_username(void) {
|
||||
DWORD size = 0;
|
||||
char *user;
|
||||
|
||||
/* get the size */
|
||||
GetUserName(NULL, &size);
|
||||
|
||||
user = (char *) c_malloc(size);
|
||||
if (user == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (GetUserName(user, &size)) {
|
||||
return user;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else /* ************* !WIN32 ************ */
|
||||
|
||||
#ifndef NSS_BUFLEN_PASSWD
|
||||
#define NSS_BUFLEN_PASSWD 4096
|
||||
#endif /* NSS_BUFLEN_PASSWD */
|
||||
|
||||
char *csync_get_user_home_dir(void) {
|
||||
const char *envp;
|
||||
struct passwd pwd;
|
||||
struct passwd *pwdbuf;
|
||||
char buf[NSS_BUFLEN_PASSWD];
|
||||
int rc;
|
||||
|
||||
envp = getenv("HOME");
|
||||
if (envp != NULL && envp[0] != '\0') {
|
||||
return c_strdup(envp);
|
||||
}
|
||||
|
||||
/* Still nothing found, read the password file */
|
||||
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
|
||||
if (rc != 0) {
|
||||
return c_strdup(pwd.pw_dir);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *csync_get_local_username(void) {
|
||||
struct passwd pwd;
|
||||
struct passwd *pwdbuf;
|
||||
char buf[NSS_BUFLEN_PASSWD];
|
||||
char *name;
|
||||
int rc;
|
||||
|
||||
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
|
||||
if (rc != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name = c_strdup(pwd.pw_name);
|
||||
|
||||
if (name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
#endif /* ************* WIN32 ************ */
|
||||
|
||||
#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) {
|
||||
(void) __flags;
|
||||
/* FIXME check if we rather should use the PathMatchSpecW variant here? */
|
||||
if(PathMatchSpec(__name, __pattern))
|
||||
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_QUOTA_EXCEEDED:
|
||||
status = CSYNC_STATUS_QUOTA_EXCEEDED; /* Quota exceeded */
|
||||
break;
|
||||
case ERRNO_SERVICE_UNAVAILABLE:
|
||||
status = CSYNC_STATUS_SERVICE_UNAVAILABLE; /* Service temporarily down */
|
||||
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 ERRNO_TIMEDELTA:
|
||||
status = CSYNC_STATUS_TIMESKEW;
|
||||
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.com/owncloud/mirall/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;
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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.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 `/'. */
|
||||
#endif
|
||||
|
||||
char *csync_get_user_home_dir(void);
|
||||
char *csync_get_local_username(void);
|
||||
|
||||
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);
|
||||
|
||||
struct csync_hbf_info_s {
|
||||
int start_id;
|
||||
int transfer_id;
|
||||
};
|
||||
typedef struct csync_hbf_info_s csync_hbf_info_t;
|
||||
|
||||
typedef struct {
|
||||
int64_t file_count;
|
||||
int64_t current_file_no;
|
||||
int64_t byte_sum;
|
||||
int64_t byte_current;
|
||||
} csync_overall_progress_t;
|
||||
|
||||
|
||||
char *csync_normalize_etag(const char *);
|
||||
|
||||
#endif /* _CSYNC_MISC_H */
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2011 by Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2012 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_OWNCLOUD_H
|
||||
#define CSYNC_OWNCLOUD_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "config.h"
|
||||
#ifdef NEON_WITH_LFS /* Switch on LFS in libneon. Never remove the NE_LFS! */
|
||||
#define NE_LFS
|
||||
#endif
|
||||
|
||||
#include <neon/ne_basic.h>
|
||||
#include <neon/ne_socket.h>
|
||||
#include <neon/ne_session.h>
|
||||
#include <neon/ne_request.h>
|
||||
#include <neon/ne_props.h>
|
||||
#include <neon/ne_auth.h>
|
||||
#include <neon/ne_dates.h>
|
||||
#include <neon/ne_compress.h>
|
||||
#include <neon/ne_redirect.h>
|
||||
|
||||
|
||||
#include "c_rbtree.h"
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "csync.h"
|
||||
#include "csync_misc.h"
|
||||
#include "csync_macros.h"
|
||||
#include "c_private.h"
|
||||
#include "httpbf.h"
|
||||
|
||||
#include "vio/csync_vio_module.h"
|
||||
#include "vio/csync_vio_file_stat.h"
|
||||
#include "vio/csync_vio.h"
|
||||
|
||||
#include "csync_log.h"
|
||||
|
||||
|
||||
#define DEBUG_WEBDAV(...) csync_log( 9, "oc_module", __VA_ARGS__);
|
||||
|
||||
enum resource_type {
|
||||
resr_normal = 0,
|
||||
resr_collection,
|
||||
resr_reference,
|
||||
resr_error
|
||||
};
|
||||
|
||||
/* Struct to store data for each resource found during an opendir operation.
|
||||
* It represents a single file entry.
|
||||
*/
|
||||
|
||||
typedef struct resource {
|
||||
char *uri; /* The complete uri */
|
||||
char *name; /* The filename only */
|
||||
|
||||
enum resource_type type;
|
||||
int64_t size;
|
||||
time_t modtime;
|
||||
char* md5;
|
||||
char file_id[FILE_ID_BUF_SIZE+1];
|
||||
|
||||
struct resource *next;
|
||||
} resource;
|
||||
|
||||
/* Struct to hold the context of a WebDAV PropFind operation to fetch
|
||||
* a directory listing from the server.
|
||||
*/
|
||||
struct listdir_context {
|
||||
struct resource *list; /* The list of result resources */
|
||||
struct resource *currResource; /* A pointer to the current resource */
|
||||
char *target; /* Request-URI of the PROPFIND */
|
||||
unsigned int result_count; /* number of elements stored in list */
|
||||
int ref; /* reference count, only destroy when it reaches 0 */
|
||||
};
|
||||
|
||||
|
||||
/* Our cache, key is a char* */
|
||||
extern c_rbtree_t *propfind_recursive_cache;
|
||||
/* Values are propfind_recursive_element: */
|
||||
struct propfind_recursive_element {
|
||||
struct resource *self;
|
||||
struct resource *children;
|
||||
struct propfind_recursive_element *parent;
|
||||
};
|
||||
typedef struct propfind_recursive_element propfind_recursive_element_t;
|
||||
void clear_propfind_recursive_cache(void);
|
||||
struct listdir_context *get_listdir_context_from_recursive_cache(const char *curi);
|
||||
void fill_recursive_propfind_cache(const char *uri, const char *curi);
|
||||
struct listdir_context *get_listdir_context_from_cache(const char *curi);
|
||||
void fetch_resource_list_recursive(const char *uri, const char *curi);
|
||||
|
||||
typedef int (*csync_owncloud_redirect_callback_t)(CSYNC* ctx, const char* uri);
|
||||
|
||||
/* Struct with the WebDAV session */
|
||||
struct dav_session_s {
|
||||
ne_session *ctx;
|
||||
char *user;
|
||||
char *pwd;
|
||||
|
||||
char *proxy_type;
|
||||
char *proxy_host;
|
||||
int proxy_port;
|
||||
char *proxy_user;
|
||||
char *proxy_pwd;
|
||||
|
||||
char *session_key;
|
||||
|
||||
char *error_string;
|
||||
|
||||
int read_timeout;
|
||||
|
||||
CSYNC *csync_ctx;
|
||||
|
||||
csync_hbf_info_t *chunk_info;
|
||||
|
||||
bool no_recursive_propfind;
|
||||
int64_t hbf_block_size;
|
||||
int64_t hbf_threshold;
|
||||
|
||||
/* If 0, it is disabled. If >0, in Byte/seconds. If < 0, in % of the available bandwidth*/
|
||||
int bandwidth_limit_upload;
|
||||
int bandwidth_limit_download;
|
||||
|
||||
csync_overall_progress_t *overall_progress_data;
|
||||
csync_owncloud_redirect_callback_t redir_callback;
|
||||
};
|
||||
extern struct dav_session_s dav_session;
|
||||
|
||||
/* The list of properties that is fetched in PropFind on a collection */
|
||||
static const ne_propname ls_props[] = {
|
||||
{ "DAV:", "getlastmodified" },
|
||||
{ "DAV:", "getcontentlength" },
|
||||
{ "DAV:", "resourcetype" },
|
||||
{ "DAV:", "getetag"},
|
||||
{ "http://owncloud.org/ns", "id"},
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
void set_errno_from_http_errcode( int err );
|
||||
void set_error_message( const char *msg );
|
||||
void set_errno_from_neon_errcode( int neon_code );
|
||||
int http_result_code_from_session(void);
|
||||
void set_errno_from_session(void);
|
||||
|
||||
time_t oc_httpdate_parse( const char *date );
|
||||
|
||||
char *_cleanPath( const char* uri );
|
||||
|
||||
int _stat_perms( int type );
|
||||
csync_vio_file_stat_t *resourceToFileStat( struct resource *res );
|
||||
|
||||
void oc_notify_progress(const char *file, enum csync_notify_type_e kind, int64_t current_size, int64_t full_size);
|
||||
|
||||
#endif /* CSYNC_OWNCLOUD_H */
|
|
@ -0,0 +1,339 @@
|
|||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2011 by Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2012 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 "csync_owncloud.h"
|
||||
|
||||
c_rbtree_t *propfind_recursive_cache = NULL;
|
||||
int propfind_recursive_cache_depth = 0;
|
||||
int propfind_recursive_cache_file_count = 0;
|
||||
int propfind_recursive_cache_folder_count = 0;
|
||||
|
||||
|
||||
static struct resource* resource_dup(struct resource* o) {
|
||||
struct resource *r = c_malloc (sizeof( struct resource ));
|
||||
ZERO_STRUCTP(r);
|
||||
|
||||
r->uri = c_strdup(o->uri);
|
||||
r->name = c_strdup(o->name);
|
||||
r->type = o->type;
|
||||
r->size = o->size;
|
||||
r->modtime = o->modtime;
|
||||
if( o->md5 ) {
|
||||
r->md5 = c_strdup(o->md5);
|
||||
}
|
||||
r->next = o->next;
|
||||
csync_vio_set_file_id(r->file_id, o->file_id);
|
||||
|
||||
return r;
|
||||
}
|
||||
static void resource_free(struct resource* o) {
|
||||
struct resource* old = NULL;
|
||||
while (o)
|
||||
{
|
||||
old = o;
|
||||
o = o->next;
|
||||
SAFE_FREE(old->uri);
|
||||
SAFE_FREE(old->name);
|
||||
SAFE_FREE(old->md5);
|
||||
SAFE_FREE(old);
|
||||
}
|
||||
}
|
||||
|
||||
static void _tree_destructor(void *data) {
|
||||
propfind_recursive_element_t *element = data;
|
||||
resource_free(element->self);
|
||||
resource_free(element->children);
|
||||
SAFE_FREE(element);
|
||||
}
|
||||
|
||||
void clear_propfind_recursive_cache(void)
|
||||
{
|
||||
if (propfind_recursive_cache) {
|
||||
DEBUG_WEBDAV("clear_propfind_recursive_cache Invalidating..");
|
||||
c_rbtree_destroy(propfind_recursive_cache, _tree_destructor);
|
||||
propfind_recursive_cache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct listdir_context *get_listdir_context_from_recursive_cache(const char *curi)
|
||||
{
|
||||
propfind_recursive_element_t *element = NULL;
|
||||
struct listdir_context *fetchCtx = NULL;
|
||||
struct resource *iterator, *r;
|
||||
|
||||
if (!propfind_recursive_cache) {
|
||||
DEBUG_WEBDAV("get_listdir_context_from_recursive_cache No cache");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
element = c_rbtree_node_data(c_rbtree_find(propfind_recursive_cache, curi));
|
||||
if (!element) {
|
||||
DEBUG_WEBDAV("get_listdir_context_from_recursive_cache No element %s in cache found", curi);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Out of the element, create a listdir_context.. if we could be sure that it is immutable, we could ref instead.. need to investigate */
|
||||
fetchCtx = c_malloc( sizeof( struct listdir_context ));
|
||||
ZERO_STRUCTP(fetchCtx);
|
||||
fetchCtx->list = NULL;
|
||||
fetchCtx->target = c_strdup(curi);
|
||||
fetchCtx->currResource = NULL;
|
||||
fetchCtx->ref = 1;
|
||||
|
||||
iterator = element->children;
|
||||
r = NULL;
|
||||
while (iterator) {
|
||||
r = resource_dup(iterator);
|
||||
r->next = fetchCtx->list;
|
||||
fetchCtx->list = r;
|
||||
iterator = iterator->next;
|
||||
fetchCtx->result_count++;
|
||||
/* DEBUG_WEBDAV("get_listdir_context_from_cache Returning cache for %s element %s", fetchCtx->target, fetchCtx->list->uri); */
|
||||
}
|
||||
|
||||
r = resource_dup(element->self);
|
||||
r->next = fetchCtx->list;
|
||||
fetchCtx->result_count++;
|
||||
fetchCtx->list = r;
|
||||
fetchCtx->currResource = fetchCtx->list;
|
||||
DEBUG_WEBDAV("get_listdir_context_from_cache Returning cache for %s (%d elements)", fetchCtx->target, fetchCtx->result_count);
|
||||
return fetchCtx;
|
||||
}
|
||||
|
||||
static int _key_cmp(const void *key, const void *b) {
|
||||
const char *elementAUri = (char*)key;
|
||||
const propfind_recursive_element_t *elementB = b;
|
||||
return ne_path_compare(elementAUri, elementB->self->uri);
|
||||
}
|
||||
static int _data_cmp(const void *a, const void *b) {
|
||||
const propfind_recursive_element_t *elementA = a;
|
||||
const propfind_recursive_element_t *elementB = b;
|
||||
return ne_path_compare(elementA->self->uri, elementB->self->uri);
|
||||
}
|
||||
static void propfind_results_recursive(void *userdata,
|
||||
const ne_uri *uri,
|
||||
const ne_prop_result_set *set)
|
||||
{
|
||||
struct resource *newres = 0;
|
||||
const char *clength, *modtime, *file_id = NULL;
|
||||
const char *resourcetype = NULL;
|
||||
const char *md5sum = NULL;
|
||||
const ne_status *status = NULL;
|
||||
char *path = ne_path_unescape( uri->path );
|
||||
char *parentPath;
|
||||
char *propfindRootUri = (char*) userdata;
|
||||
propfind_recursive_element_t *element = NULL;
|
||||
propfind_recursive_element_t *pElement = NULL;
|
||||
int depth = 0;
|
||||
|
||||
(void) status;
|
||||
(void) propfindRootUri;
|
||||
|
||||
if (!propfind_recursive_cache) {
|
||||
c_rbtree_create(&propfind_recursive_cache, _key_cmp, _data_cmp);
|
||||
}
|
||||
|
||||
/* Fill the resource structure with the data about the file */
|
||||
newres = c_malloc(sizeof(struct resource));
|
||||
ZERO_STRUCTP(newres);
|
||||
|
||||
newres->uri = path; /* no need to strdup because ne_path_unescape already allocates */
|
||||
newres->name = c_basename( path );
|
||||
|
||||
modtime = ne_propset_value( set, &ls_props[0] );
|
||||
clength = ne_propset_value( set, &ls_props[1] );
|
||||
resourcetype = ne_propset_value( set, &ls_props[2] );
|
||||
md5sum = ne_propset_value( set, &ls_props[3] );
|
||||
file_id = ne_propset_value( set, &ls_props[4] );
|
||||
|
||||
newres->type = resr_normal;
|
||||
if( resourcetype && strncmp( resourcetype, "<DAV:collection>", 16 ) == 0) {
|
||||
newres->type = resr_collection;
|
||||
propfind_recursive_cache_folder_count++;
|
||||
} else {
|
||||
/* DEBUG_WEBDAV("propfind_results_recursive %s [%d]", newres->uri, newres->type); */
|
||||
propfind_recursive_cache_file_count++;
|
||||
}
|
||||
|
||||
if (modtime) {
|
||||
newres->modtime = oc_httpdate_parse(modtime);
|
||||
}
|
||||
|
||||
/* DEBUG_WEBDAV("Parsing Modtime: %s -> %llu", modtime, (unsigned long long) newres->modtime ); */
|
||||
newres->size = 0;
|
||||
if (clength) {
|
||||
newres->size = atoll(clength);
|
||||
/* DEBUG_WEBDAV("Parsed File size for %s from %s: %lld", newres->name, clength, (long long)newres->size ); */
|
||||
}
|
||||
|
||||
if( md5sum ) {
|
||||
newres->md5 = csync_normalize_etag(md5sum);
|
||||
}
|
||||
|
||||
csync_vio_set_file_id(newres->file_id, file_id);
|
||||
/*
|
||||
DEBUG_WEBDAV("propfind_results_recursive %s [%s] %s", newres->uri, newres->type == resr_collection ? "collection" : "file", newres->md5);
|
||||
*/
|
||||
|
||||
/* Create new item in rb tree */
|
||||
if (newres->type == resr_collection) {
|
||||
DEBUG_WEBDAV("propfind_results_recursive %s is a folder", newres->uri);
|
||||
/* Check if in rb tree */
|
||||
element = c_rbtree_node_data(c_rbtree_find(propfind_recursive_cache,uri->path));
|
||||
/* If not, create a new item and insert it */
|
||||
if (!element) {
|
||||
element = c_malloc(sizeof(propfind_recursive_element_t));
|
||||
element->self = resource_dup(newres);
|
||||
element->children = NULL;
|
||||
element->parent = NULL;
|
||||
c_rbtree_insert(propfind_recursive_cache, element);
|
||||
/* DEBUG_WEBDAV("results_recursive Added collection %s", newres->uri); */
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for parent in tree. If exists: Insert it into the children elements there */
|
||||
parentPath = ne_path_parent(uri->path);
|
||||
if (parentPath) {
|
||||
propfind_recursive_element_t *parentElement = NULL;
|
||||
|
||||
parentElement = c_rbtree_node_data(c_rbtree_find(propfind_recursive_cache,parentPath));
|
||||
free(parentPath);
|
||||
|
||||
if (parentElement) {
|
||||
newres->next = parentElement->children;
|
||||
parentElement->children = newres;
|
||||
|
||||
/* If the current result is a collection we also need to set its parent */
|
||||
if (element)
|
||||
element->parent = parentElement;
|
||||
|
||||
pElement = element;
|
||||
while (pElement) {
|
||||
depth++;
|
||||
pElement = pElement->parent;
|
||||
}
|
||||
if (depth > propfind_recursive_cache_depth) {
|
||||
DEBUG_WEBDAV("propfind_results_recursive %s new maximum tree depth %d", newres->uri, depth);
|
||||
propfind_recursive_cache_depth = depth;
|
||||
}
|
||||
|
||||
/* DEBUG_WEBDAV("results_recursive Added child %s to collection %s", newres->uri, element->self->uri); */
|
||||
} else {
|
||||
/* DEBUG_WEBDAV("results_recursive No parent %s found for child %s", parentPath, newres->uri); */
|
||||
resource_free(newres);
|
||||
newres = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void fetch_resource_list_recursive(const char *uri, const char *curi)
|
||||
{
|
||||
int ret = 0;
|
||||
ne_propfind_handler *hdl = NULL;
|
||||
ne_request *request = NULL;
|
||||
const char *content_type = NULL;
|
||||
const ne_status *req_status = NULL;
|
||||
int depth = NE_DEPTH_INFINITE;
|
||||
|
||||
DEBUG_WEBDAV("fetch_resource_list_recursive Starting recursive propfind %s %s", uri, curi);
|
||||
|
||||
/* do a propfind request and parse the results in the results function, set as callback */
|
||||
hdl = ne_propfind_create(dav_session.ctx, curi, depth);
|
||||
|
||||
if(hdl) {
|
||||
ret = ne_propfind_named(hdl, ls_props, propfind_results_recursive, (void*)curi);
|
||||
request = ne_propfind_get_request( hdl );
|
||||
req_status = ne_get_status( request );
|
||||
}
|
||||
|
||||
if( ret == NE_OK ) {
|
||||
/* Check the request status. */
|
||||
if( req_status && req_status->klass != 2 ) {
|
||||
set_errno_from_http_errcode(req_status->code);
|
||||
DEBUG_WEBDAV("ERROR: Request failed: status %d (%s)", req_status->code,
|
||||
req_status->reason_phrase);
|
||||
ret = NE_CONNECT;
|
||||
set_error_message(req_status->reason_phrase);
|
||||
oc_notify_progress(uri, CSYNC_NOTIFY_ERROR, req_status->code, (intptr_t)(req_status->reason_phrase));
|
||||
}
|
||||
DEBUG_WEBDAV("Recursive propfind result code %d.", req_status ? req_status->code : 0);
|
||||
} else {
|
||||
if( ret == NE_ERROR && req_status->code == 404) {
|
||||
errno = ENOENT;
|
||||
} else {
|
||||
set_errno_from_neon_errcode(ret);
|
||||
}
|
||||
}
|
||||
|
||||
if( ret == NE_OK ) {
|
||||
/* Check the content type. If the server has a problem, ie. database is gone or such,
|
||||
* the content type is not xml but a html error message. Stop on processing if it's
|
||||
* not XML.
|
||||
* FIXME: Generate user error message from the reply content.
|
||||
*/
|
||||
content_type = ne_get_response_header( request, "Content-Type" );
|
||||
if( !(content_type && c_streq(content_type, "application/xml; charset=utf-8") ) ) {
|
||||
DEBUG_WEBDAV("ERROR: Content type of propfind request not XML: %s.",
|
||||
content_type ? content_type: "<empty>");
|
||||
errno = ERRNO_WRONG_CONTENT;
|
||||
set_error_message("Server error: PROPFIND reply is not XML formatted!");
|
||||
ret = NE_CONNECT;
|
||||
}
|
||||
}
|
||||
|
||||
if( ret != NE_OK ) {
|
||||
const char *err = NULL;
|
||||
|
||||
err = ne_get_error( dav_session.ctx );
|
||||
DEBUG_WEBDAV("WRN: propfind named failed with %d, request error: %s", ret, err ? err : "<nil>");
|
||||
}
|
||||
|
||||
if( hdl )
|
||||
ne_propfind_destroy(hdl);
|
||||
|
||||
if( ret != NE_OK ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Called by owncloud_opendir()->fetch_resource_list() to fill the cache */
|
||||
extern struct listdir_context *propfind_cache;
|
||||
void fill_recursive_propfind_cache(const char *uri, const char *curi) {
|
||||
fetch_resource_list_recursive(uri, curi);
|
||||
|
||||
if (propfind_recursive_cache_depth <= 2) {
|
||||
DEBUG_WEBDAV("fill_recursive_propfind_cache %s Server maybe did not give us an 'infinity' depth result", curi);
|
||||
/* transform the cache to the normal cache in propfind_cache */
|
||||
propfind_cache = get_listdir_context_from_recursive_cache(curi);
|
||||
/* clear the cache, it is bogus since the server returned only results for Depth 1 */
|
||||
clear_propfind_recursive_cache();
|
||||
} else {
|
||||
DEBUG_WEBDAV("fill_recursive_propfind_cache %s We received %d elements deep for 'infinity' depth (%d folders, %d files)",
|
||||
curi,
|
||||
propfind_recursive_cache_depth,
|
||||
propfind_recursive_cache_folder_count,
|
||||
propfind_recursive_cache_file_count);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2011 by Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2012 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 "csync_owncloud.h"
|
||||
#include "csync_misc.h"
|
||||
|
||||
void set_error_message( const char *msg )
|
||||
{
|
||||
SAFE_FREE(dav_session.error_string);
|
||||
if( msg )
|
||||
dav_session.error_string = c_strdup(msg);
|
||||
}
|
||||
|
||||
void set_errno_from_http_errcode( int err ) {
|
||||
int new_errno = 0;
|
||||
|
||||
switch(err) {
|
||||
case 200: /* OK */
|
||||
case 201: /* Created */
|
||||
case 202: /* Accepted */
|
||||
case 203: /* Non-Authoritative Information */
|
||||
case 204: /* No Content */
|
||||
case 205: /* Reset Content */
|
||||
case 207: /* Multi-Status */
|
||||
case 304: /* Not Modified */
|
||||
new_errno = 0;
|
||||
break;
|
||||
case 401: /* Unauthorized */
|
||||
case 402: /* Payment Required */
|
||||
case 407: /* Proxy Authentication Required */
|
||||
case 405:
|
||||
new_errno = EPERM;
|
||||
break;
|
||||
case 301: /* Moved Permanently */
|
||||
case 303: /* See Other */
|
||||
case 404: /* Not Found */
|
||||
case 410: /* Gone */
|
||||
new_errno = ENOENT;
|
||||
break;
|
||||
case 408: /* Request Timeout */
|
||||
case 504: /* Gateway Timeout */
|
||||
new_errno = EAGAIN;
|
||||
break;
|
||||
case 423: /* Locked */
|
||||
new_errno = EACCES;
|
||||
break;
|
||||
case 400: /* Bad Request */
|
||||
case 403: /* Forbidden */
|
||||
case 409: /* Conflict */
|
||||
case 411: /* Length Required */
|
||||
case 412: /* Precondition Failed */
|
||||
case 414: /* Request-URI Too Long */
|
||||
case 415: /* Unsupported Media Type */
|
||||
case 424: /* Failed Dependency */
|
||||
case 501: /* Not Implemented */
|
||||
new_errno = EINVAL;
|
||||
break;
|
||||
case 507: /* Insufficient Storage */
|
||||
new_errno = ENOSPC;
|
||||
break;
|
||||
case 206: /* Partial Content */
|
||||
case 300: /* Multiple Choices */
|
||||
case 302: /* Found */
|
||||
case 305: /* Use Proxy */
|
||||
case 306: /* (Unused) */
|
||||
case 307: /* Temporary Redirect */
|
||||
case 406: /* Not Acceptable */
|
||||
case 416: /* Requested Range Not Satisfiable */
|
||||
case 417: /* Expectation Failed */
|
||||
case 422: /* Unprocessable Entity */
|
||||
case 500: /* Internal Server Error */
|
||||
case 502: /* Bad Gateway */
|
||||
case 505: /* HTTP Version Not Supported */
|
||||
new_errno = EIO;
|
||||
break;
|
||||
case 503: /* Service Unavailable */
|
||||
new_errno = ERRNO_SERVICE_UNAVAILABLE;
|
||||
break;
|
||||
case 413: /* Request Entity too Large */
|
||||
new_errno = EFBIG;
|
||||
break;
|
||||
default:
|
||||
new_errno = EIO;
|
||||
}
|
||||
|
||||
errno = new_errno;
|
||||
}
|
||||
|
||||
int http_result_code_from_session() {
|
||||
const char *p = ne_get_error( dav_session.ctx );
|
||||
char *q;
|
||||
int err;
|
||||
|
||||
set_error_message(p); /* remember the error message */
|
||||
|
||||
err = strtol(p, &q, 10);
|
||||
if (p == q) {
|
||||
err = ERRNO_ERROR_STRING;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void set_errno_from_session() {
|
||||
int err = http_result_code_from_session();
|
||||
|
||||
if( err == EIO || err == ERRNO_ERROR_STRING) {
|
||||
errno = err;
|
||||
} else {
|
||||
set_errno_from_http_errcode(err);
|
||||
}
|
||||
}
|
||||
|
||||
void set_errno_from_neon_errcode( int neon_code ) {
|
||||
|
||||
if( neon_code != NE_OK ) {
|
||||
DEBUG_WEBDAV("Neon error code was %d", neon_code);
|
||||
}
|
||||
|
||||
switch(neon_code) {
|
||||
case NE_OK: /* Success, but still the possiblity of problems */
|
||||
case NE_ERROR: /* Generic error; use ne_get_error(session) for message */
|
||||
set_errno_from_session(); /* Something wrong with http communication */
|
||||
break;
|
||||
case NE_LOOKUP: /* Server or proxy hostname lookup failed */
|
||||
errno = ERRNO_LOOKUP_ERROR;
|
||||
break;
|
||||
case NE_AUTH: /* User authentication failed on server */
|
||||
errno = ERRNO_USER_UNKNOWN_ON_SERVER;
|
||||
break;
|
||||
case NE_PROXYAUTH: /* User authentication failed on proxy */
|
||||
errno = ERRNO_PROXY_AUTH;
|
||||
break;
|
||||
case NE_CONNECT: /* Could not connect to server */
|
||||
errno = ERRNO_CONNECT;
|
||||
break;
|
||||
case NE_TIMEOUT: /* Connection timed out */
|
||||
errno = ERRNO_TIMEOUT;
|
||||
break;
|
||||
case NE_FAILED: /* The precondition failed */
|
||||
errno = ERRNO_PRECONDITION;
|
||||
break;
|
||||
case NE_RETRY: /* Retry request (ne_end_request ONLY) */
|
||||
errno = ERRNO_RETRY;
|
||||
break;
|
||||
|
||||
case NE_REDIRECT: /* See ne_redirect.h */
|
||||
errno = ERRNO_REDIRECT;
|
||||
break;
|
||||
default:
|
||||
errno = ERRNO_GENERAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanPath to return an escaped path of an uri */
|
||||
char *_cleanPath( const char* uri ) {
|
||||
int rc = 0;
|
||||
char *path = NULL;
|
||||
char *re = NULL;
|
||||
|
||||
rc = c_parse_uri( uri, NULL, NULL, NULL, NULL, NULL, &path );
|
||||
if( rc < 0 ) {
|
||||
DEBUG_WEBDAV("Unable to cleanPath %s", uri ? uri: "<zero>" );
|
||||
re = NULL;
|
||||
} else {
|
||||
if(path) {
|
||||
re = ne_path_escape( path );
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE( path );
|
||||
return re;
|
||||
}
|
||||
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* helper: convert a resource struct to file_stat struct.
|
||||
*/
|
||||
csync_vio_file_stat_t *resourceToFileStat( struct resource *res )
|
||||
{
|
||||
csync_vio_file_stat_t *lfs = NULL;
|
||||
|
||||
if( ! res ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lfs = c_malloc(sizeof(csync_vio_file_stat_t));
|
||||
if (lfs == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lfs->name = c_strdup( res->name );
|
||||
|
||||
lfs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
|
||||
if( res->type == resr_normal ) {
|
||||
lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
|
||||
lfs->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
} else if( res->type == resr_collection ) {
|
||||
lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
|
||||
lfs->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
|
||||
} else {
|
||||
DEBUG_WEBDAV("ERROR: Unknown resource type %d", res->type);
|
||||
}
|
||||
|
||||
lfs->mtime = res->modtime;
|
||||
lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
|
||||
lfs->size = res->size;
|
||||
lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
|
||||
if( res->md5 ) {
|
||||
lfs->etag = c_strdup(res->md5);
|
||||
}
|
||||
lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG;
|
||||
csync_vio_file_stat_set_file_id(lfs, res->file_id);
|
||||
|
||||
return lfs;
|
||||
}
|
||||
|
||||
/* WebDAV does not deliver permissions. Set a default here. */
|
||||
int _stat_perms( int type ) {
|
||||
int ret = 0;
|
||||
|
||||
if( type == CSYNC_VIO_FILE_TYPE_DIRECTORY ) {
|
||||
/* DEBUG_WEBDAV("Setting mode in stat (dir)"); */
|
||||
/* directory permissions */
|
||||
ret = S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR /* directory, rwx for user */
|
||||
| S_IRGRP | S_IXGRP /* rx for group */
|
||||
| S_IROTH | S_IXOTH; /* rx for others */
|
||||
} else {
|
||||
/* regualar file permissions */
|
||||
/* DEBUG_WEBDAV("Setting mode in stat (file)"); */
|
||||
ret = S_IFREG | S_IRUSR | S_IWUSR /* regular file, user read & write */
|
||||
| S_IRGRP /* group read perm */
|
||||
| S_IROTH; /* others read perm */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void oc_notify_progress(const char *file, enum csync_notify_type_e kind, int64_t current_size, int64_t full_size)
|
||||
{
|
||||
csync_progress_callback progress_cb = csync_get_progress_callback(dav_session.csync_ctx);
|
||||
|
||||
csync_overall_progress_t overall_progress;
|
||||
ZERO_STRUCT(overall_progress);
|
||||
|
||||
if( dav_session.overall_progress_data) {
|
||||
overall_progress = *dav_session.overall_progress_data;
|
||||
}
|
||||
|
||||
if (progress_cb) {
|
||||
CSYNC_PROGRESS progress;
|
||||
progress.kind = kind;
|
||||
progress.path = file;
|
||||
progress.curr_bytes = current_size;
|
||||
progress.file_size = full_size;
|
||||
progress.overall_transmission_size = overall_progress.byte_sum;
|
||||
progress.current_overall_bytes = overall_progress.byte_current+current_size;
|
||||
progress.overall_file_count = overall_progress.file_count;
|
||||
progress.current_file_no = overall_progress.current_file_no;
|
||||
|
||||
progress_cb(&progress, csync_get_userdata(dav_session.csync_ctx));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* 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.h"
|
||||
#include "c_lib.h"
|
||||
#include "c_private.h"
|
||||
#include "csync.h"
|
||||
#include "csync_misc.h"
|
||||
#include "vio/csync_vio_file_stat.h"
|
||||
|
||||
#ifdef WITH_ICONV
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ICONV_H
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ICONV_H
|
||||
#include <sys/iconv.h>
|
||||
#endif
|
||||
|
||||
#include "vio/csync_vio_method.h"
|
||||
#include "csync_macros.h"
|
||||
|
||||
/**
|
||||
* How deep to scan directories.
|
||||
*/
|
||||
#define MAX_DEPTH 50
|
||||
|
||||
/**
|
||||
* Maximum time difference between two replicas in seconds
|
||||
*/
|
||||
#define MAX_TIME_DIFFERENCE 10
|
||||
|
||||
/**
|
||||
* Maximum size of a buffer for transfer
|
||||
*/
|
||||
#ifndef MAX_XFER_BUF_SIZE
|
||||
#define MAX_XFER_BUF_SIZE (16 * 1024)
|
||||
#endif
|
||||
|
||||
#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;
|
||||
csync_progress_callback progress_cb;
|
||||
void *userdata;
|
||||
} callbacks;
|
||||
c_strlist_t *excludes;
|
||||
|
||||
struct {
|
||||
char *file;
|
||||
sqlite3 *db;
|
||||
int exists;
|
||||
int disabled;
|
||||
} statedb;
|
||||
|
||||
struct {
|
||||
char *uri;
|
||||
c_rbtree_t *tree;
|
||||
c_list_t *list;
|
||||
enum csync_replica_e type;
|
||||
c_list_t *ignored_cleanup;
|
||||
} local;
|
||||
|
||||
struct {
|
||||
char *uri;
|
||||
c_rbtree_t *tree;
|
||||
c_list_t *list;
|
||||
enum csync_replica_e type;
|
||||
int read_from_db;
|
||||
c_list_t *ignored_cleanup;
|
||||
} remote;
|
||||
|
||||
struct {
|
||||
csync_vio_method_t *method;
|
||||
csync_vio_method_finish_fn finish_fn;
|
||||
csync_vio_capabilities_t capabilities;
|
||||
} module;
|
||||
|
||||
struct {
|
||||
int max_depth;
|
||||
int max_time_difference;
|
||||
int sync_symbolic_links;
|
||||
int unix_extensions;
|
||||
char *config_dir;
|
||||
bool with_conflict_copys;
|
||||
bool local_only_mode;
|
||||
int timeout;
|
||||
#if defined(HAVE_ICONV) && defined(WITH_ICONV)
|
||||
iconv_t iconv_cd;
|
||||
#endif
|
||||
} options;
|
||||
|
||||
struct {
|
||||
uid_t uid;
|
||||
uid_t euid;
|
||||
} pwd;
|
||||
|
||||
csync_overall_progress_t overall_progress;
|
||||
|
||||
struct csync_progressinfo_s *progress_info;
|
||||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
|
||||
#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 */
|
||||
uid_t uid; /* u32 */
|
||||
gid_t gid; /* u32 */
|
||||
mode_t mode; /* u32 */
|
||||
int nlink; /* u32 */
|
||||
int type; /* u32 */
|
||||
int child_modified;/*bool*/
|
||||
int should_update_etag; /*bool */
|
||||
|
||||
char *destpath; /* for renames */
|
||||
const char *etag;
|
||||
char file_id[FILE_ID_BUF_SIZE+1]; /* the ownCloud file id is fixed width of 21 byte. */
|
||||
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
|
||||
;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* }@
|
||||
*/
|
||||
#endif /* _CSYNC_PRIVATE_H */
|
||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* 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.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"
|
||||
|
||||
#define ACCEPTED_TIME_DIFF 5
|
||||
#define ONE_HOUR 3600
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/* 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:
|
||||
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->statedb.db, 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->statedb.db, 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 ) {
|
||||
if( tmp->path ) {
|
||||
/* Find the temporar file in the other tree. */
|
||||
len = strlen( tmp->path );
|
||||
h = c_jhash64((uint8_t *) tmp->path, len, 0);
|
||||
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) {
|
||||
/* 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(node) {
|
||||
other = (csync_file_stat_t*)node->data;
|
||||
}
|
||||
|
||||
if(!other) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
} else if (other->instruction == CSYNC_INSTRUCTION_NONE
|
||||
|| 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 );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
|
||||
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 {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
}
|
||||
|
||||
SAFE_FREE(tmp->etag);
|
||||
SAFE_FREE(tmp);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
bool is_equal_files = false;
|
||||
/*
|
||||
* file found on the other replica
|
||||
*/
|
||||
other = (csync_file_stat_t *) node->data;
|
||||
|
||||
switch (cur->instruction) {
|
||||
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:
|
||||
switch (other->instruction) {
|
||||
/* file on other replica is changed or new */
|
||||
case CSYNC_INSTRUCTION_NEW:
|
||||
case CSYNC_INSTRUCTION_EVAL:
|
||||
if (other->type == CSYNC_VIO_FILE_TYPE_DIRECTORY &&
|
||||
cur->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {
|
||||
is_equal_files = (other->modtime == cur->modtime);
|
||||
} else {
|
||||
is_equal_files = ((other->size == cur->size) && (other->modtime == cur->modtime));
|
||||
}
|
||||
if (is_equal_files) {
|
||||
/* The files are considered equal. */
|
||||
cur->instruction = CSYNC_INSTRUCTION_UPDATED; /* update the DB */
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
|
||||
if( !cur->etag && other->etag ) cur->etag = c_strdup(other->etag);
|
||||
} else if(ctx->current == REMOTE_REPLICA) {
|
||||
if(ctx->options.with_conflict_copys) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
cur->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
} else {
|
||||
if(ctx->options.with_conflict_copys) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
} else {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
/* file on the other replica has not been modified */
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
cur->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
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
|
||||
if(cur->instruction ==CSYNC_INSTRUCTION_NONE)
|
||||
{
|
||||
if(cur->type == CSYNC_FTW_TYPE_DIR)
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
|
||||
"%-20s dir: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
cur->path);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
|
||||
"%-20s file: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
cur->path);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cur->type == CSYNC_FTW_TYPE_DIR)
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"%-20s dir: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
cur->path);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"%-20s file: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
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: */
|