diff -Nru owncloud-client-1.8.1+dfsg/binary.rej owncloud-client-2.1.1+dfsg/binary.rej --- owncloud-client-1.8.1+dfsg/binary.rej 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/binary.rej 2016-02-09 15:07:08.000000000 +0000 @@ -0,0 +1,5 @@ +--- binary ++++ binary +@@ -1 +1 @@ +-Subproject commit 1fb9ddfa9a9a1b4dbc447eee10dbed89172d968a ++Subproject commit 01d73965dc8b862d1b2310d3ef801c297b697ec7 diff -Nru owncloud-client-1.8.1+dfsg/ChangeLog owncloud-client-2.1.1+dfsg/ChangeLog --- owncloud-client-1.8.1+dfsg/ChangeLog 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/ChangeLog 2016-02-09 15:07:08.000000000 +0000 @@ -1,5 +1,200 @@ ChangeLog ========= +version 2.1.1 (release 2016-02-10) + * UI improvements for HiDPI screens, error messages, RTL languages + * Fix occurences of "Connection Closed" when a new unauthenticated TCP socket is used + * Fix undeliberate WiFi scanning done by Qt Network classes + * Several fixes/improvements to the sharing dialog + * Several fixes/improvements to the server activity tab + * Create the directory when using --confdir and it does not exist + * Windows Overlay icons: Fix DLL and icon oddities + * Mac Overlay icons: Don't install legacy Finder plugin on >= 10.10 + * Linux Overlay icons: Nemo plugin + * Overlay icons: Fix several wrong icon state computations + * Allow changeable upload chunk size in owncloud.cfg + * Crash fixes on account deletion + * Forget password on explicit sign-out + * OS X: Fix the file system watcher ignoring unicode paths (#4424) + * Windows Installer: Update to NSIS 2.50, fixes possible DLL injection + * Sync Engine: .lnk files + * Sync Engine: symlinked syn directories + * Sync Engine: Windows: Fix deleting and replacing of read-only files (#4308, #4277) + * Sync Engine: Fixes for files becoming directories and vice versa (#4302) + * Misc other fixes/improvements + +version 2.1 (release 2015-12-03) + * GUI: Added a display of server activities + * GUI: Added a separate view for not synced items, ignores, errors + * GUI: Improved upload/download progress UI (#3403, #3569) + * Allowed sharing with ownCloud internal users and groups from Desktop + * Changed files starting in .* to be considered hidden on all platforms (#4023) + * Reflect read-only permissions in filesystem (#3244) + * Blacklist: Clear on successful chunk upload (#3934) + * Improved reconnecting after network change/disconnect (#4167 #3969 ...) + * Improved performance in Windows file system discovery + * Removed libneon-based propagator. As a consequence, The client can no + longer provide bandwith limiting on Linux-distributions where it is + using Qt < 5.4 + * Performance improvements in the logging functions + * Ensured that local disk space problems are handled gracefully (#2939) + * Improved handling of checksums: transport validation, db (#3735) + * For *eml-files don't reupload if size and checksum are unchanged (#3235) + * Ensured 403 reply code is handled properly (File Firewall) (#3490) + * Reduced number of PROPFIND requests to server(#3964) + * GUI: Added Account toolbox widget to keep account actions (#4139) + * Tray Menu: Added fixes for Recent Activity menu (#4093, #3969) + * FolderMan: Fixed infinite wait on pause (#4093) + * Renamed env variables to include unit (#2939) + * FolderStatusModel: Attempt to detect removed undecided files (#3612) + * SyncEngine: Don't whipe the white list if the sync was aborted (#4018) + * Quota: Handle special negative value for the quota (#3940) + * State app name in update notification (#4020) + * PropagateUpload: Fixed double-emission of finished (#3844) + * GUI: Ensured folder names which are excluded from sync can be clicked + * Shell Integration: Dolphin support, requires KF 5.16 and KDE Application 15.12 + * FolderStatusModel: Ensured reset also if a folder was renamed (#4011) + * GUI: Fixed accessiblity of remaing items in full settings toolbar (#3795) + * Introduced the term "folder sync connection" in more places (#3757) + * AccountSettings: Don't disable pause when offline (#4010) + * Fixed handling of hidden files (#3980) + * Handle download errors while resuming as soft errors (#4000) + * SocketAPI: Ensured that the command isn't trimmed (#3297) + * Shutdown socket API before removing the db (#3824) + * GUI: Made "Keep" default in the delete-all dialog (#3824) + * owncloudcmd: Introduced return code 0 for --version and --help + * owncloudcmd: Added --max-sync-retries (#4037) + * owncloudcmd: Don't do a check that file are older than 2s (#4160) + * Fixed getting size for selective sync (#3986) + * Re-added close button in the settings window (#3713) + * Added abililty to handle storage limitations gracefully (#3736) + * Updated 3rdparty dependencies: sqlite version 3.9.1 + * Organized patches to our base Qt version into admin/qt/patches + * Plus: A lot of unmentioned improvements and fixes + +version 2.0.2 (release 2015-10-21) + * csync_file_stat_s: Save a bit of memory + * Shibboleth: Add our base user agent to WebKit + * SelectiveSync: Increase folder list timeout to 60 + * Propagation: Try another sync on 423 Locked (#3387) + * Propagation: Make 423 Locked a soft error (#3387) + * Propagation: Reset upload blacklist if a chunk succeeds + * Application: Fix crash on early shutdown (#3898) + * Linux: Don't show settings dialog always when launched twice (#3273, #3771, #3485) + * win32 vio: Add the OPEN_REPARSE_POINTS flag to the CreateFileW call. (#3813) + * AccountSettings: only expand root elements on single click. + * AccountSettings: Do not allow to expand the folder list when disconnected. + * Use application SHORT name for the name of the MacOSX pkg file (ownBrander). + * FolderMan: Fix for removing a syncing folder (#3843) + * ConnectionMethodDialog: Don't be insecure on close (#3863) + * Updater: Ensure folders are not removed (#3747) + * Folder settings: Ensure path is cleaned (#3811) + * Propagator: Simplify sub job finished counting (#3844) + * Share dialog: Hide settings dialog before showing (#3783) + * UI: Only expand 1 level in folder list (#3585) + * UI: Allow folder expanding from button click (#3585) + * UI: Expand folder treeview on single click (#3585) + * GUI: Change tray menu order (#3657) + * GUI: Replace term "sign in" with "Log in" and friends. + * SetupPage: Fix crash caused by uninitialized Account object. + * Use a themable WebDAV path all over. + * Units: Back to the "usual" mix units (JEDEC standard). + * csync io: Full UNC path support on Win (#3748) + * Tray: Don't use the tray workaround with the KDE theme (#3706, #3765) + * ShareDialog: Fix folder display (#3659) + * AccountSettings: Restore from legacy only once (#3565) + * SSL Certificate Error Dialog: show account name (#3729) + * Tray notification: Don't show a message about modified folder (#3613) + * PropagateLocalRemove: remove entries from the DB even if there was an error. + * Settings UI improvements (eg. #3713, #3721, #3619 and others) + * Folder: Do not create the sync folder if it does not exist (#3692) + * Shell integration: don't show share menu item for top level folders + * Tray: Hide while modifying menus (#3656, #3672) + * AddFolder: Improve remote path selection error handling (#3573) + * csync_update: Use excluded_traversal() to improve performance (#3638) + * csync_excluded: Add fast _traversal() function (#3638) + * csync_exclude: Speed up significantly (#3638) + * AccountSettings: Adjust quota info design (#3644, #3651) + * Adjust buttons on remove folder/account questions (#3654) + +version 2.0.1 (release 2015-09-01) + * AccountWizard: fix when the theme specify a override URL (#3699) + +version 2.0.0 (release 2015-08-25) + * Add support for multiple accounts (#3084) + * Do not sync down new big folders from server without users consent (#3148) + * Integrate Selective Sync into the default UI + * OS X: Support native finder integration for 10.10 Yosemite (#2340) + * Fix situation where client would not reconnect after timeout (#2321) + * Use SI units for the file sizes + * Improve progress reporting during sync (better estimations, show all files, show all bandwidth) + * Windows: Support paths >255 characters (#57) by using Windows API instead of POSIX API + * Windows, OS X: Allow to not sync hidden files (#2086) + * OS X: Show file name in UI if file has invalid UTF-8 in file name + * Sharing: Make use of Capability API (#3439) + * Sharing: Do not allow sharing the root folder (#3495) + * Sharing: Show thumbnail + * Client Updater: Check for updates periodically, not only once per run (#3044) + * Windows: Remove misleading option to remove sync data (#3461) + * Windows: Do not provoke AD account locking if password changes (#2186) + * Windows: Fix installer when installing unprivileged (#2616, #2568) + * Quota: Only refresh from server when UI is shown + * SSL Button: Show more information + * owncloudcmd: Fix --httpproxy (#3465) + * System proxy: Ask user for credentials if needed + * Several fixes and performance improvements in the sync engine + * Network: Try to use SSL session tickets/identifiers. Check the SSL button to see if they are used. + * Bandwidth Throttling: Provide automatic limit setting for downloads (#3084) + * Systray: Workaround for issue with Qt 5.5.0 #3656 + +version 1.8.4 (release 2015-07-13) + * Release to ship a security release of openSSL. No source changes of the ownCloud Client code. + +version 1.8.3 (release 2015-06-23) + * Fix a bug in the Windows Installer that could crash explorer (#3320) + * Reduce 'Connection closed' errors (#3318, #3313, #3298) + * Ignores: Force a remote discovery after ignore list change (#3172) + * Shibboleth: Avoid crash by letting the webview use its own QNAM (#3359) + * System Ignores: Removed *.tmp from system ignore again. If a user + wants to ignore *.tmp, it needs to be added to the user ignore list. + +version 1.8.2 (release 2015-06-08) + * Improve reporting of server error messages (#3220) + * Discovery: Ignore folders with any 503 (#3113) + * Wizard: Show server error message if possible (#3220) + * QNAM: Fix handling of mitm cert changes (#3283) + * Win32: Installer translations added (#3277) + * Win32: Allow concurrent OEM (un-)installers (#3272) + * Win32: Make Setup/Update Mutex theme-unique (#3272) + * HTTP: Add the branding name to the UserAgent string + * ConnectonValidator: Always run with new credentials (#3266) + * Recall Feature: Admins can trigger an upload of a file from + client to server again (#3246) + * Propagator: Add 'Content-Length: 0' header to MKCOL request (#3256) + * Switch on checksum verification through branding or config + * Add ability for checksum verification of up and download + * Fix opening external links for some labels (#3135) + * AccountState: Run only a single validator, allow error message + overriding (#3236, #3153) + * SyncJournalDB: Minor fixes and simplificatons + * SyncEngine: Force re-read of folder Etags for upgrades from + 1.8.0 and 1.8.1 + * Propagator: Limit length of temporary file name (#2789) + * ShareDialog: Password ui fixes (#3189) + * Fix startup hang by removing QSettings lock file (#3175) + * Wizard: Allow SSL cert dialog to show twice (#3168) + * ProtocolWidget: Fix rename message (#3210) + * Discovery: Test better, treat invalid hrefs as error (#3176) + * Propagator: Overwrite local data only if unchanged (#3156) + * ShareDialog: Improve error reporting for share API fails + * OSX Updater: Only allow updates only if in /Applications (#2931) + * Wizard: Fix lock icon (#1447) + * Fix compilation with GCC 5 + * Treat any 503 error as temporary (#3113) + * Work around for the Qt PUT corruption bug (#2425) + * OSX Shell integration: Optimizations + * Windows Shell integration: Optimizations + .. more than 250 commits since 1.8.1 + version 1.8.1 (release 2015-05-07) * Make "operation canceled" error a soft error * Do not throw an error for files that are scheduled to be removed, diff -Nru owncloud-client-1.8.1+dfsg/client.qrc owncloud-client-2.1.1+dfsg/client.qrc --- owncloud-client-1.8.1+dfsg/client.qrc 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/client.qrc 2016-02-09 15:07:08.000000000 +0000 @@ -10,12 +10,17 @@ resources/warning.png resources/warning@2x.png resources/settings.png + resources/settings@2x.png resources/activity.png + resources/activity@2x.png resources/network.png + resources/network@2x.png resources/lock-http.png resources/lock-http@2x.png resources/lock-https.png resources/lock-https@2x.png resources/account.png + resources/more.png + resources/delete.png diff -Nru owncloud-client-1.8.1+dfsg/cmake/modules/AddCMockaTest.cmake owncloud-client-2.1.1+dfsg/cmake/modules/AddCMockaTest.cmake --- owncloud-client-1.8.1+dfsg/cmake/modules/AddCMockaTest.cmake 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/modules/AddCMockaTest.cmake 2016-02-09 15:07:08.000000000 +0000 @@ -20,4 +20,15 @@ add_executable(${_testName} ${_testSource}) target_link_libraries(${_testName} ${ARGN}) add_test(${_testName} ${CMAKE_CURRENT_BINARY_DIR}/${_testName}) + + if(UNIT_TESTING) + INSTALL( + TARGETS + ${_testName} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + endif(UNIT_TESTING) + endfunction (ADD_CMOCKA_TEST) diff -Nru owncloud-client-1.8.1+dfsg/cmake/modules/DefineCompilerFlags.cmake owncloud-client-2.1.1+dfsg/cmake/modules/DefineCompilerFlags.cmake --- owncloud-client-1.8.1+dfsg/cmake/modules/DefineCompilerFlags.cmake 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/modules/DefineCompilerFlags.cmake 2016-02-09 15:07:08.000000000 +0000 @@ -85,7 +85,7 @@ endif (UNIX AND NOT WIN32) if (MSVC) - # Use secure functions by defaualt and suppress warnings about + # Use secure functions by default 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") diff -Nru owncloud-client-1.8.1+dfsg/cmake/modules/DefineInstallationPaths.cmake owncloud-client-2.1.1+dfsg/cmake/modules/DefineInstallationPaths.cmake --- owncloud-client-1.8.1+dfsg/cmake/modules/DefineInstallationPaths.cmake 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/modules/DefineInstallationPaths.cmake 2016-02-09 15:07:08.000000000 +0000 @@ -41,10 +41,6 @@ "${LIB_INSTALL_DIR}" CACHE PATH "The subdirectory relative to the install prefix where private libs are installed" ) - SET(PLUGIN_INSTALL_DIR - "${LIB_INSTALL_DIR}" - CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_SHORTNAME})" - ) SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The subdirectory to the header prefix (default prefix/include)" @@ -106,7 +102,6 @@ set(SBIN_INSTALL_DIR "." CACHE PATH "-") set(LIB_INSTALL_DIR "lib" CACHE PATH "-") set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-") - set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-") set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-") set(ICON_INSTALL_DIR "." CACHE PATH "-") set(SOUND_INSTALL_DIR "." CACHE PATH "-") diff -Nru owncloud-client-1.8.1+dfsg/cmake/modules/FindINotify.cmake owncloud-client-2.1.1+dfsg/cmake/modules/FindINotify.cmake --- owncloud-client-1.8.1+dfsg/cmake/modules/FindINotify.cmake 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/modules/FindINotify.cmake 2016-02-09 15:07:08.000000000 +0000 @@ -4,20 +4,27 @@ # This module defines # INOTIFY_INCLUDE_DIR, where to find inotify.h, etc. +# INOTIFY_LIBRARY_DIR, the directory holding the inotify library. # INOTIFY_FOUND, If false, do not try to use inotify. # also defined, but not for general use are # INOTIFY_LIBRARY, where to find the inotify library. find_path(INOTIFY_INCLUDE_DIR sys/inotify.h - HINTS /usr/include/${CMAKE_LIBRARY_ARCHITECTURE}) + PATH_SUFFIXES inotify) mark_as_advanced(INOTIFY_INCLUDE_DIR) +find_library(INOTIFY_LIBRARY inotify PATH_SUFFIXES lib/inotify) + +get_filename_component(INOTIFY_LIBRARY_DIR ${INOTIFY_LIBRARY} PATH) +mark_as_advanced(INOTIFY_LIBRARY_DIR) + # all listed variables are TRUE # handle the QUIETLY and REQUIRED arguments and set INOTIFY_FOUND to TRUE if include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(INOTIFY DEFAULT_MSG INOTIFY_INCLUDE_DIR) +find_package_handle_standard_args(INOTIFY DEFAULT_MSG INOTIFY_INCLUDE_DIR INOTIFY_LIBRARY_DIR) IF(INOTIFY_FOUND) SET(INotify_INCLUDE_DIRS ${INOTIFY_INCLUDE_DIR}) + SET(INotify_LIBRARY_DIRS ${INOTIFY_LIBRARY_DIR}) ENDIF(INOTIFY_FOUND) diff -Nru owncloud-client-1.8.1+dfsg/cmake/modules/FindNeon.cmake owncloud-client-2.1.1+dfsg/cmake/modules/FindNeon.cmake --- owncloud-client-1.8.1+dfsg/cmake/modules/FindNeon.cmake 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/modules/FindNeon.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -# - Try to find Neon -# Once done this will define -# -# NEON_FOUND - system has Neon -# NEON_INCLUDE_DIRS - the Neon include directory -# NEON_LIBRARIES - Link these to use Neon -# NEON_DEFINITIONS - Compiler switches required for using Neon -# -# Copyright (c) 2011-2013 Andreas Schneider -# -# Redistribution and use is allowed according to the terms of the New -# BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -# - - -find_package(PkgConfig) -if (PKG_CONFIG_FOUND) - pkg_check_modules(_NEON neon) -endif (PKG_CONFIG_FOUND) - -include(GNUInstallDirs) - -find_path(NEON_INCLUDE_DIRS -NAMES - neon/ne_basic.h -HINTS - ${_NEON_INCLUDEDIR} - ${CMAKE_INSTALL_INCLUDEDIR} -) - -find_library(NEON_LIBRARIES -NAMES - neon neon-27 -HINTS - ${_NEON_LIBDIR} - ${CMAKE_INSTALL_LIBDIR} - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 -) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Neon DEFAULT_MSG NEON_LIBRARIES NEON_INCLUDE_DIRS) - -# show the NEON_INCLUDE_DIRS and NEON_LIBRARIES variables only in the advanced view -mark_as_advanced(NEON_INCLUDE_DIRS NEON_LIBRARIES) - -# Check if neon was compiled with LFS support, if so, the NE_LFS variable has to -# be defined in the owncloud module. -# If neon was not compiled with LFS its also ok since the underlying system -# than probably supports large files anyway. -IF( CMAKE_FIND_ROOT_PATH ) - FIND_PROGRAM( NEON_CONFIG_EXECUTABLE NAMES neon-config HINTS ${CMAKE_FIND_ROOT_PATH}/bin ) -ELSE( CMAKE_FIND_ROOT_PATH ) - FIND_PROGRAM( NEON_CONFIG_EXECUTABLE NAMES neon-config ) -ENDIF( CMAKE_FIND_ROOT_PATH ) - -IF ( NEON_CONFIG_EXECUTABLE ) - MESSAGE(STATUS "neon-config executable: ${NEON_CONFIG_EXECUTABLE}") - # neon-config --support lfs - EXECUTE_PROCESS( COMMAND ${NEON_CONFIG_EXECUTABLE} "--support" "lfs" - RESULT_VARIABLE LFS - OUTPUT_STRIP_TRAILING_WHITESPACE ) - - IF (LFS EQUAL 0) - MESSAGE(STATUS "libneon has been compiled with LFS support") - SET(NEON_WITH_LFS 1) - ELSE (LFS EQUAL 0) - MESSAGE(STATUS "libneon has not been compiled with LFS support, rely on OS") - ENDIF (LFS EQUAL 0) -ELSE ( NEON_CONFIG_EXECUTABLE ) - MESSAGE(STATUS, "neon-config could not be found.") -ENDIF ( NEON_CONFIG_EXECUTABLE ) diff -Nru owncloud-client-1.8.1+dfsg/cmake/modules/GNUInstallDirs.cmake owncloud-client-2.1.1+dfsg/cmake/modules/GNUInstallDirs.cmake --- owncloud-client-1.8.1+dfsg/cmake/modules/GNUInstallDirs.cmake 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/modules/GNUInstallDirs.cmake 2016-02-09 15:07:08.000000000 +0000 @@ -134,13 +134,7 @@ AND NOT CMAKE_CROSSCOMPILING) if (EXISTS "/etc/debian_version") # is this a debian system ? if(CMAKE_LIBRARY_ARCHITECTURE) - if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$") - set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}") - endif() - if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX - AND "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$") - set(__LAST_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}") - endif() + set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}") endif() else() # not debian, rely on CMAKE_SIZEOF_VOID_P: if(NOT DEFINED CMAKE_SIZEOF_VOID_P) diff -Nru owncloud-client-1.8.1+dfsg/cmake/modules/MacOSXBundleInfo.plist.in owncloud-client-2.1.1+dfsg/cmake/modules/MacOSXBundleInfo.plist.in --- owncloud-client-1.8.1+dfsg/cmake/modules/MacOSXBundleInfo.plist.in 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/modules/MacOSXBundleInfo.plist.in 2016-02-09 15:07:08.000000000 +0000 @@ -27,7 +27,7 @@ CFBundleShortVersionString @MIRALL_VERSION_STRING@ NSHumanReadableCopyright - (C) 2014 @APPLICATION_VENDOR@ + (C) 2014-2015 @APPLICATION_VENDOR@ SUShowReleaseNotes LSMinimumBundleVersion diff -Nru owncloud-client-1.8.1+dfsg/cmake/modules/NSIS.template.in owncloud-client-2.1.1+dfsg/cmake/modules/NSIS.template.in --- owncloud-client-1.8.1+dfsg/cmake/modules/NSIS.template.in 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/modules/NSIS.template.in 2016-02-09 15:07:08.000000000 +0000 @@ -89,7 +89,6 @@ ; Include some required header files. ;----------------------------------------------------------------------------- !include LogicLib.nsh ;Used by APPDATA uninstaller. -!include nsDialogs.nsh ;Used by APPDATA uninstaller. !include MUI2.nsh ;Used by APPDATA uninstaller. !include InstallOptions.nsh ;Required by MUI2 to support old MUI_INSTALLOPTIONS. !include Memento.nsh ;Remember user selections. @@ -97,6 +96,7 @@ !include WordFunc.nsh ;Used by VersionCompare macro function. !include FileFunc.nsh ;Used to read out parameters !include UAC.nsh ;Used by the UAC elevation to install as user or admin. +!include nsProcess.nsh ;Used to kill the running process !include Library.nsh ;Used by the COM registration for shell extensions !include x64.nsh ;Used to determine the right arch for the shell extensions @@ -107,7 +107,7 @@ !define MEMENTO_REGISTRY_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPLICATION_NAME}" ;----------------------------------------------------------------------------- -; Modern User Interface (MUI) defintions and setup. +; Modern User Interface (MUI) definitions and setup. ;----------------------------------------------------------------------------- !define MUI_ABORTWARNING !define MUI_ICON ${NSI_PATH}\installer.ico @@ -145,7 +145,6 @@ !insertmacro MUI_PAGE_FINISH !endif !insertmacro MUI_UNPAGE_CONFIRM -UninstPage custom un.UnPageUserAppData un.UnPageUserAppDataLeave !insertmacro MUI_UNPAGE_INSTFILES ;----------------------------------------------------------------------------- @@ -175,10 +174,11 @@ StrCmp $LANGUAGE ${LANG_ITALIAN} Italian 0 StrCmp $LANGUAGE ${LANG_ESTONIAN} Estonian 0 StrCmp $LANGUAGE ${LANG_GREEK} Greek 0 - StrCmp $LANGUAGE ${LANG_GREEK} Basque 0 - StrCmp $LANGUAGE ${LANG_GREEK} Galician 0 - StrCmp $LANGUAGE ${LANG_GREEK} Slovak 0 - StrCmp $LANGUAGE ${LANG_GREEK} Turkish 0 + StrCmp $LANGUAGE ${LANG_BASQUE} Basque 0 + StrCmp $LANGUAGE ${LANG_GALICIAN} Galician 0 + StrCmp $LANGUAGE ${LANG_POLISH} Polish 0 + StrCmp $LANGUAGE ${LANG_TURKISH} Turkish 0 + StrCmp $LANGUAGE ${LANG_NORWEGIAN} Norwegian 0 StrCmp $LANGUAGE ${LANG_PORTUGUESEBR} Brazilian EndLanguageCmp German: !include "${source_path}/admin/win/nsi/l10n\German.nsh" @@ -213,14 +213,17 @@ Galician: !include "${source_path}/admin/win/nsi/l10n\Galician.nsh" Goto EndLanguageCmp - Slovak: - !include "${source_path}/admin/win/nsi/l10n\Slovak.nsh" + Polish: + !include "${source_path}/admin/win/nsi/l10n\Polish.nsh" Goto EndLanguageCmp Turkish: !include "${source_path}/admin/win/nsi/l10n\Turkish.nsh" Goto EndLanguageCmp Brazilian: !include "${source_path}/admin/win/nsi/l10n\PortugueseBR.nsh" + Goto EndLanguageCmp + Norwegian: + !include "${source_path}/admin/win/nsi/l10n\Norwegian.nsh" EndLanguageCmp: FunctionEnd @@ -243,11 +246,7 @@ ############################################################################## Function LaunchApplication - ${UAC.CallFunctionAsUser} LaunchApplicationAsUser -FunctionEnd - -Function LaunchApplicationAsUser - Exec "$INSTDIR\${APPLICATION_EXECUTABLE}" + !insertmacro UAC_AsUser_ExecShell "" "$INSTDIR\${APPLICATION_EXECUTABLE}" "" "" "" FunctionEnd ############################################################################## @@ -257,8 +256,8 @@ ############################################################################## !macro CheckForProcess processName gotoWhenFound gotoWhenNotFound - Processes::FindProcess ${processName} - StrCmp $R0 "0" ${gotoWhenNotFound} ${gotoWhenFound} + ${nsProcess::FindProcess} ${processName} $R0 + StrCmp $R0 0 ${gotoWhenFound} ${gotoWhenNotFound} !macroend !macro ConfirmEndProcess processName @@ -267,7 +266,7 @@ /SD IDYES IDYES process_${processName}_kill IDNO process_${processName}_ended process_${processName}_kill: DetailPrint $ConfirmEndProcess_KILLING_PROCESSES_TEXT - Processes::KillProcess ${processName} + ${nsProcess::KillProcess} ${processName} $R0 Sleep 1500 StrCmp $R0 "1" process_${processName}_ended DetailPrint $ConfirmEndProcess_KILL_NOT_FOUND_TEXT @@ -362,7 +361,6 @@ RMDir $INSTDIR no_remove_uninstaller: StrCmp $R0 "2" 0 +3 - UAC::Unload Quit BringToFront reinst_done: @@ -475,6 +473,7 @@ CreateDirectory "$INSTDIR\shellext" !define LIBRARY_COM !define LIBRARY_SHELL_EXTENSION + !define LIBRARY_IGNORE_VERSION ${If} ${RunningX64} !define LIBRARY_X64 !insertmacro InstallLib DLL NOTSHARED REBOOT_PROTECTED "${SOURCE_PATH}\binary\shell_integration\windows\Release\x64\OCUtil_x64.dll" "$INSTDIR\shellext\OCUtil_x64.dll" "$INSTDIR\shellext" @@ -488,6 +487,7 @@ ${Endif} !undef LIBRARY_COM !undef LIBRARY_SHELL_EXTENSION + !undef LIBRARY_IGNORE_VERSION ${MementoSectionEnd} !endif @@ -556,7 +556,7 @@ DetailPrint $UNINSTALLER_REGISTRY_Detail SetDetailsPrint listonly - ;Version numbers used to detect existing installation version for comparisson. + ;Version numbers used to detect existing installation version for comparison. WriteRegStr HKLM "Software\${APPLICATION_VENDOR}\${APPLICATION_NAME}" "" $INSTDIR WriteRegDWORD HKLM "Software\${APPLICATION_VENDOR}\${APPLICATION_NAME}" "VersionMajor" "${VER_MAJOR}" WriteRegDWORD HKLM "Software\${APPLICATION_VENDOR}\${APPLICATION_NAME}" "VersionMinor" "${VER_MINOR}" @@ -588,40 +588,6 @@ # # ############################################################################## -Var UnPageUserAppDataDialog -Var UnPageUserAppDataCheckbox -Var UnPageUserAppDataCheckbox_State -Var UnPageUserAppDataEditBox - -Function un.UnPageUserAppData - !insertmacro MUI_HEADER_TEXT $UNINSTALLER_APPDATA_TITLE $UNINSTALLER_APPDATA_SUBTITLE - nsDialogs::Create /NOUNLOAD 1018 - Pop $UnPageUserAppDataDialog - - ${If} $UnPageUserAppDataDialog == error - Abort - ${EndIf} - - ${NSD_CreateLabel} 0 0 100% 12u $UNINSTALLER_APPDATA_LABEL_1 - Pop $0 - - ${NSD_CreateText} 0 13u 100% 12u "$LOCALAPPDATA\${APPLICATION_NAME}" - Pop $UnPageUserAppDataEditBox - SendMessage $UnPageUserAppDataEditBox ${EM_SETREADONLY} 1 0 - - ${NSD_CreateLabel} 0 46u 100% 24u $UNINSTALLER_APPDATA_LABEL_2 - Pop $0 - - ${NSD_CreateCheckbox} 0 71u 100% 8u $UNINSTALLER_APPDATA_CHECKBOX - Pop $UnPageUserAppDataCheckbox - - nsDialogs::Show -FunctionEnd - -Function un.UnPageUserAppDataLeave - ${NSD_GetState} $UnPageUserAppDataCheckbox $UnPageUserAppDataCheckbox_State -FunctionEnd - Function un.EnsureOwncloudShutdown !insertmacro CheckAndConfirmEndProcess "${APPLICATION_EXECUTABLE}" FunctionEnd @@ -646,6 +612,7 @@ !ifdef OPTION_SECTION_SC_SHELL_EXT !define LIBRARY_COM !define LIBRARY_SHELL_EXTENSION + !define LIBRARY_IGNORE_VERSION ${If} ${HasSection} SEC_SHELL_EXT DetailPrint "Uninstalling x64 overlay DLLs" !define LIBRARY_X64 @@ -661,6 +628,7 @@ ${EndIf} !undef LIBRARY_COM !undef LIBRARY_SHELL_EXTENSION + !undef LIBRARY_IGNORE_VERSION !endif ;Start menu shortcut @@ -697,11 +665,6 @@ ;Remove all the Program Files. RMDir /r $INSTDIR - ;Uninstall User Data if option is checked, otherwise skip. - ${If} $UnPageUserAppDataCheckbox_State == ${BST_CHECKED} - RMDir /r "$LOCALAPPDATA\${APPLICATION_NAME}" - ${EndIf} - DeleteRegKey ${MEMENTO_REGISTRY_ROOT} "${MEMENTO_REGISTRY_KEY}" SetDetailsPrint textonly @@ -756,28 +719,30 @@ ${MementoSectionRestore} - UAC_Elevate: - UAC::RunElevated - StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user? - StrCmp 0 $0 0 UAC_Err ; Error? - StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper? - Quit - - UAC_Err: - MessageBox MB_ICONSTOP "$UAC_ERROR_ELEVATE $0" - Abort - - UAC_ElevationAborted: - Abort - - UAC_Success: - StrCmp 1 $3 +4 ;Admin? - StrCmp 3 $1 0 UAC_ElevationAborted ;Try again? - MessageBox MB_ICONSTOP $UAC_INSTALLER_REQUIRE_ADMIN - goto UAC_Elevate + UAC_TryAgain: + !insertmacro UAC_RunElevated + ${Switch} $0 + ${Case} 0 + ${IfThen} $1 = 1 ${|} Quit ${|} ;we are the outer process, the inner process has done its work, we are done + ${IfThen} $3 <> 0 ${|} ${Break} ${|} ;we are admin, let the show go on + ${If} $1 = 3 ;RunAs completed successfully, but with a non-admin user + MessageBox mb_YesNo|mb_ICONEXCLAMATION|MB_TOPMOST|MB_SETFOREGROUND $UAC_INSTALLER_REQUIRE_ADMIN /SD IDNO IDYES UAC_TryAgain IDNO 0 + ${EndIf} + ;fall-through and die + ${Case} 1223 + MessageBox MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND $UAC_INSTALLER_REQUIRE_ADMIN + Quit + ${Case} 1062 + MessageBox MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND $UAC_ERROR_LOGON_SERVICE + Quit + ${Default} + MessageBox MB_ICONSTOP "$UAC_ERROR_ELEVATE $0" + Abort + Quit + ${EndSwitch} ;Prevent multiple instances. - System::Call 'kernel32::CreateMutexA(i 0, i 0, t "owncloudInstaller") i .r1 ?e' + System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${APPLICATION_SHORTNAME}Installer") i .r1 ?e' Pop $R0 StrCmp $R0 0 +3 MessageBox MB_OK|MB_ICONEXCLAMATION $INIT_INSTALLER_RUNNING @@ -805,11 +770,9 @@ ${AndIf} $InstallRunIfSilent == "yes" Call LaunchApplication ${EndIf} - UAC::Unload ;Must call unload! FunctionEnd Function .onInstFailed - UAC::Unload ;Must call unload! FunctionEnd ############################################################################## @@ -821,28 +784,30 @@ Function un.onInit Call un.SetLang - UAC_Elevate: - UAC::RunElevated - StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user? - StrCmp 0 $0 0 UAC_Err ; Error? - StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper? - Quit - - UAC_Err: - MessageBox MB_ICONSTOP "$UAC_ERROR_ELEVATE $0" - Abort - - UAC_ElevationAborted: - Abort - - UAC_Success: - StrCmp 1 $3 +4 ;Admin? - StrCmp 3 $1 0 UAC_ElevationAborted ;Try again? - MessageBox MB_ICONSTOP $UAC_UNINSTALLER_REQUIRE_ADMIN - goto UAC_Elevate + UAC_TryAgain: + !insertmacro UAC_RunElevated + ${Switch} $0 + ${Case} 0 + ${IfThen} $1 = 1 ${|} Quit ${|} ;we are the outer process, the inner process has done its work, we are done + ${IfThen} $3 <> 0 ${|} ${Break} ${|} ;we are admin, let the show go on + ${If} $1 = 3 ;RunAs completed successfully, but with a non-admin user + MessageBox mb_YesNo|mb_ICONEXCLAMATION|MB_TOPMOST|MB_SETFOREGROUND $UAC_UNINSTALLER_REQUIRE_ADMIN /SD IDNO IDYES UAC_TryAgain IDNO 0 + ${EndIf} + ;fall-through and die + ${Case} 1223 + MessageBox MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND $UAC_UNINSTALLER_REQUIRE_ADMIN + Quit + ${Case} 1062 + MessageBox MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND $UAC_ERROR_LOGON_SERVICE + Quit + ${Default} + MessageBox MB_ICONSTOP "$UAC_ERROR_ELEVATE $0" + Abort + Quit + ${EndSwitch} ;Prevent multiple instances. - System::Call 'kernel32::CreateMutexA(i 0, i 0, t "owncloudUninstaller") i .r1 ?e' + System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${APPLICATION_SHORTNAME}Uninstaller") i .r1 ?e' Pop $R0 StrCmp $R0 0 +3 MessageBox MB_OK|MB_ICONEXCLAMATION $INIT_UNINSTALLER_RUNNING @@ -853,9 +818,7 @@ FunctionEnd Function un.onUnInstSuccess - UAC::Unload ;Must call unload! FunctionEnd Function un.onUnInstFailed - UAC::Unload ;Must call unload! FunctionEnd diff -Nru owncloud-client-1.8.1+dfsg/cmake/modules/QtVersionAbstraction.cmake owncloud-client-2.1.1+dfsg/cmake/modules/QtVersionAbstraction.cmake --- owncloud-client-1.8.1+dfsg/cmake/modules/QtVersionAbstraction.cmake 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/modules/QtVersionAbstraction.cmake 2016-02-09 15:07:08.000000000 +0000 @@ -17,11 +17,10 @@ message(STATUS "Found Qt5 core, checking for further dependencies...") find_package(Qt5Network REQUIRED) find_package(Qt5Xml REQUIRED) + find_package(Qt5Concurrent REQUIRED) if(NOT TOKEN_AUTH_ONLY) find_package(Qt5WebKitWidgets REQUIRED) find_package(Qt5WebKit REQUIRED) - find_package(Qt5PrintSupport REQUIRED) - find_package(Qt5Quick REQUIRED) find_package(Qt5Widgets REQUIRED) if(APPLE) find_package(Qt5MacExtras REQUIRED) @@ -30,7 +29,9 @@ else( Qt5Core_FOUND ) if(WIN32 OR APPLE) + if (NOT BUILD_WITH_QT4) message(FATAL_ERROR "Qt 5 not found, but application depends on Qt5 on Windows and Mac OS X") + endif () endif(WIN32 OR APPLE) endif( Qt5Core_FOUND ) @@ -71,11 +72,16 @@ endmacro() if(NOT TOKEN_AUTH_ONLY) - find_package(Qt5LinguistTools REQUIRED) - macro(qt_add_translation) - qt5_add_translation(${ARGN}) - endmacro() - else() + find_package(Qt5LinguistTools) + if(Qt5LinguistTools_FOUND) + macro(qt_add_translation) + qt5_add_translation(${ARGN}) + endmacro() + else() + macro(qt_add_translation) + endmacro() + endif() +else() macro(qt_add_translation) endmacro() endif() diff -Nru owncloud-client-1.8.1+dfsg/cmake/modules/UseDoxygen.cmake owncloud-client-2.1.1+dfsg/cmake/modules/UseDoxygen.cmake --- owncloud-client-1.8.1+dfsg/cmake/modules/UseDoxygen.cmake 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/modules/UseDoxygen.cmake 2016-02-09 15:07:08.000000000 +0000 @@ -37,7 +37,7 @@ # 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.") + MESSAGE(STATUS "latex command LATEX_COMPILER not found but usually required. You will probably get warnings and user interaction on doxy run.") ENDIF (NOT LATEX_COMPILER) IF (NOT MAKEINDEX_COMPILER) MESSAGE(STATUS "makeindex command MAKEINDEX_COMPILER not found but usually required.") diff -Nru owncloud-client-1.8.1+dfsg/cmake/scripts/generate_lib_file owncloud-client-2.1.1+dfsg/cmake/scripts/generate_lib_file --- owncloud-client-1.8.1+dfsg/cmake/scripts/generate_lib_file 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/cmake/scripts/generate_lib_file 2016-02-09 15:07:08.000000000 +0000 @@ -29,12 +29,12 @@ printf("\n") -print("Other projects to includes (e.g. \"owutil tinyxml\", leave emtpy to skip): ") +print("Other projects to include (e.g. \"owutil tinyxml\", leave emtpy to skip): ") otherprojects=gets.chomp printf("\n") -print("Defininitions (leave empty to skip): ") +print("Definitions (leave empty to skip): ") definitions=gets.chomp cmakePublicIncDirName = project.upcase+"_PUBLIC_INCLUDE_DIRS" diff -Nru owncloud-client-1.8.1+dfsg/CMakeLists.txt owncloud-client-2.1.1+dfsg/CMakeLists.txt --- owncloud-client-1.8.1+dfsg/CMakeLists.txt 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/CMakeLists.txt 2016-02-09 15:07:08.000000000 +0000 @@ -32,7 +32,7 @@ include(${CMAKE_SOURCE_DIR}/VERSION.cmake) include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_BINARY_DIR}/src/mirall/") -# disable the crashrepoter if libcrashreporter-qt is not available or we're building for ARM +# disable the crashreporter if libcrashreporter-qt is not available or we're building for ARM if( CMAKE_SYSTEM_PROCESSOR MATCHES "arm" OR NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/3rdparty/libcrashreporter-qt/CMakeLists.txt") set( WITH_CRASHREPORTER OFF ) endif() @@ -74,6 +74,10 @@ set(SYSCONFDIR ${SYSCONF_INSTALL_DIR}) set(DATADIR ${DATA_INSTALL_DIR}) +if(WIN32) +set(DATADIR "share") +endif(WIN32) +set(SHAREDIR ${DATADIR}) ##### ## handle BUILD_OWNCLOUD_OSX_BUNDLE @@ -110,14 +114,18 @@ # this option creates only libocsync and libowncloudsync option(BUILD_LIBRARIES_ONLY "BUILD_LIBRARIES_ONLY" OFF) -# When this option is enabled, 5xx errors are not added to the clacklist -# Normaly you don't want to enable this option because if a particular file -# trigger a bug on the server, you want the file to be blacklisted. +# When this option is enabled, 5xx errors are not added to the blacklist +# Normally you don't want to enable this option because if a particular file +# triggers a bug on the server, you want the file to be blacklisted. option(OWNCLOUD_5XX_NO_BLACKLIST "OWNCLOUD_5XX_NO_BLACKLIST" OFF) if(OWNCLOUD_5XX_NO_BLACKLIST) add_definitions(-DOWNCLOUD_5XX_NO_BLACKLIST=1) endif() +if(APPLE) + set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesign key's TeamIdentifier/Organizational Unit" ) +endif() + #### find libs #find_package(Qt4 4.7.0 COMPONENTS QtCore QtGui QtXml QtNetwork QtTest QtWebkit REQUIRED ) #if( UNIX AND NOT APPLE ) # Fdo notifications @@ -125,24 +133,17 @@ #endif() -set(USE_NEON TRUE) if(HAVE_QT5) - message(STATUS "Using Qt ${Qt5Core_VERSION_MAJOR}.${Qt5Core_VERSION_MINOR}.x") if (${Qt5Core_VERSION_MAJOR} EQUAL "5") if (${Qt5Core_VERSION_MINOR} EQUAL "4" OR ${Qt5Core_VERSION_MINOR} GREATER 4) - message(STATUS "We would not require Neon in this setup, compile without!") - set(USE_NEON FALSE) else() - message(STATUS "Still requiring Neon with this Qt version :-( Qt 5.4 is better!") + message(STATUS "If possible compile me with Qt 5.4 or higher.") endif() endif() else() -message(STATUS "If possible compile me with Qt 5.4 which is much faster/better.") + message(STATUS "If possible compile me with Qt 5.4 or higher.") endif() -if (USE_NEON) - find_package(Neon REQUIRED) -endif(USE_NEON) find_package(OpenSSL 1.0.0 REQUIRED) if(NOT TOKEN_AUTH_ONLY) @@ -165,13 +166,13 @@ find_package(Sphinx) find_package(PdfLatex) - find_package(SQLite3 3.8.0 REQUIRED) # On some OS, we want to use our own, not the system sqlite if (USE_OUR_OWN_SQLITE3) include_directories(BEFORE ${SQLITE3_INCLUDE_DIR}) endif() +find_package(ZLIB) configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) @@ -194,6 +195,7 @@ if(NOT BUILD_LIBRARIES_ONLY) add_subdirectory(shell_integration) add_subdirectory(doc) +add_subdirectory(doc/dev) add_subdirectory(admin) endif(NOT BUILD_LIBRARIES_ONLY) @@ -205,6 +207,7 @@ if(BUILD_OWNCLOUD_OSX_BUNDLE) install(FILES sync-exclude.lst DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/) + configure_file(sync-exclude.lst bin/${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/sync-exclude.lst COPYONLY) else() install( FILES sync-exclude.lst DESTINATION ${SYSCONFDIR}/${APPLICATION_SHORTNAME} ) configure_file(sync-exclude.lst bin/sync-exclude.lst COPYONLY) diff -Nru owncloud-client-1.8.1+dfsg/config.h.in owncloud-client-2.1.1+dfsg/config.h.in --- owncloud-client-1.8.1+dfsg/config.h.in 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/config.h.in 2016-02-09 15:07:08.000000000 +0000 @@ -5,9 +5,8 @@ #cmakedefine WITH_QTKEYCHAIN 1 #cmakedefine WITH_CRASHREPORTER #cmakedefine CRASHREPORTER_EXECUTABLE "@CRASHREPORTER_EXECUTABLE@" +#define SOCKETAPI_TEAM_IDENTIFIER_PREFIX "@SOCKETAPI_TEAM_IDENTIFIER_PREFIX@" - -#cmakedefine GIT_SHA1 "@GIT_SHA1@" #cmakedefine APPLICATION_DOMAIN @APPLICATION_DOMAIN@ #cmakedefine THEME_CLASS @THEME_CLASS@ #cmakedefine THEME_INCLUDE @THEME_INCLUDE@ @@ -19,11 +18,9 @@ #cmakedefine APPLICATION_EXECUTABLE "@APPLICATION_EXECUTABLE@" #cmakedefine APPLICATION_UPDATE_URL "@APPLICATION_UPDATE_URL@" -#cmakedefine SYSCONFDIR "@SYSCONFDIR@" -#cmakedefine DATADIR "@DATADIR@" +#cmakedefine ZLIB_FOUND @ZLIB_FOUND@ -#ifndef NEON_WITH_LFS -#cmakedefine NEON_WITH_LFS "@NEON_WITH_LFS@" -#endif +#cmakedefine SYSCONFDIR "@SYSCONFDIR@" +#cmakedefine SHAREDIR "@SHAREDIR@" #endif diff -Nru owncloud-client-1.8.1+dfsg/CONTRIBUTING.md owncloud-client-2.1.1+dfsg/CONTRIBUTING.md --- owncloud-client-1.8.1+dfsg/CONTRIBUTING.md 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/CONTRIBUTING.md 2016-02-09 15:07:08.000000000 +0000 @@ -6,9 +6,10 @@ ### Bug Reporting Guidelines * __Important__: Report the issue using our [template][template], it includes all the - informations we need to track down the issue. + information we need to track down the issue. +* __SECURITY__: Report any potential security bug to security@owncloud.com following our [security policy](https://owncloud.org/security/) instead of filing an issue in our bug tracker * This repository is *only* for issues within the ownCloud desktop client. - Issues in other compontents should be reported in their own repositores: + Issues in other components should be reported in their own repositores: - [ownCloud server](https://github.com/owncloud/core/issues) - [ownCloud apps](https://github.com/owncloud/apps/issues) (e.g. Calendar, Contacts...) @@ -35,7 +36,7 @@ our [Contributor Agreement][agreement]. Please read the [Desktop Client Manual][desktopman] and the [Developer -Manuals][devmanual] to get useful infos like how to create your first +Manuals][devmanual] to get useful info like how to create your first application or how to test the ownCloud code with phpunit. [agreement]: http://owncloud.org/about/contributor-agreement/ diff -Nru owncloud-client-1.8.1+dfsg/csync/ChangeLog owncloud-client-2.1.1+dfsg/csync/ChangeLog --- owncloud-client-1.8.1+dfsg/csync/ChangeLog 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/ChangeLog 2016-02-09 15:07:08.000000000 +0000 @@ -21,9 +21,9 @@ 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. + * Add test that directories are properly moved. * Handle symlinks correctly. - * Do not longer recurse into ignored directories in update + * No longer recurse into ignored directories in update phase. * Added proper symlink detection for win32 platform. @@ -77,7 +77,7 @@ * Added c_rename function to csync std. * Fix: Do renames of files before any puts. * Improved database integrity checks. - * Improvements of database writing efficiendy. + * Improvements of database writing efficiency. * Fix: stat file on win32 even if its opened by application. * httpbf: configurable block size and threshold. * Many fixes found by a Coverity check. @@ -159,7 +159,7 @@ version 0.60.2 (released 2012-11-26) * Migration to cross platform testing system cmocka. - * Fixed variuos minor things incl. potential mem leaks. + * Fixed various minor things incl. potential mem leaks. * Clang fixes. * Moved journal database to sync directory. * Fixed more csync->ocsync renaming issues. @@ -247,7 +247,7 @@ * 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 a way to export file_tree_walk functions. * Added capabilities for modules. * Added possiblity to push information to the modules. * Added iconv support to support various char sets. diff -Nru owncloud-client-1.8.1+dfsg/csync/config_csync.h.cmake owncloud-client-2.1.1+dfsg/csync/config_csync.h.cmake --- owncloud-client-1.8.1+dfsg/csync/config_csync.h.cmake 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/config_csync.h.cmake 2016-02-09 15:07:08.000000000 +0000 @@ -1,9 +1,7 @@ #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}" @@ -25,10 +23,6 @@ #cmakedefine HAVE_ICONV 1 #cmakedefine HAVE_ICONV_CONST 1 -#ifndef NEON_WITH_LFS -#cmakedefine NEON_WITH_LFS 1 -#endif - #cmakedefine HAVE___MINGW_ASPRINTF 1 #cmakedefine HAVE_ASPRINTF 1 diff -Nru owncloud-client-1.8.1+dfsg/csync/ConfigureChecks.cmake owncloud-client-2.1.1+dfsg/csync/ConfigureChecks.cmake --- owncloud-client-1.8.1+dfsg/csync/ConfigureChecks.cmake 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/ConfigureChecks.cmake 2016-02-09 15:07:08.000000000 +0000 @@ -9,7 +9,6 @@ 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_CURRENT_BINARY_DIR}) diff -Nru owncloud-client-1.8.1+dfsg/csync/INSTALL owncloud-client-2.1.1+dfsg/csync/INSTALL --- owncloud-client-1.8.1+dfsg/csync/INSTALL 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/INSTALL 2016-02-09 15:07:08.000000000 +0000 @@ -20,7 +20,7 @@ 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 +Note that these version numbers are versions we know work correctly. If you build and run csync successfully with an older version, please let us know. @@ -63,7 +63,7 @@ ## Installing -Befor installing you can run the tests if everything is working: +Before installing you can run the tests if everything is working: make test diff -Nru owncloud-client-1.8.1+dfsg/csync/README owncloud-client-2.1.1+dfsg/csync/README --- owncloud-client-1.8.1+dfsg/csync/README 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/README 2016-02-09 15:07:08.000000000 +0000 @@ -13,7 +13,7 @@ ============= 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 +the mailing list. Patches are accepted preferably created with git and we are always glad to receive feedback or suggestions to the address csync-devel@csync.org. More information on the various mailing lists can be found at diff -Nru owncloud-client-1.8.1+dfsg/csync/src/CMakeLists.txt owncloud-client-2.1.1+dfsg/csync/src/CMakeLists.txt --- owncloud-client-1.8.1+dfsg/csync/src/CMakeLists.txt 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/CMakeLists.txt 2016-02-09 15:07:08.000000000 +0000 @@ -1,9 +1,6 @@ project(libcsync) add_subdirectory(std) -if(USE_NEON) - add_subdirectory(httpbf) -endif() # Statically include sqlite @@ -58,20 +55,17 @@ vio/csync_vio.c vio/csync_vio_file_stat.c - vio/csync_vio_local.c ) -if(USE_NEON) +if (WIN32) list(APPEND csync_SRCS - csync_owncloud.c - csync_owncloud_util.c + vio/csync_vio_local_win.c ) - list(APPEND CSYNC_LINK_LIBRARIES - ${NEON_LIBRARIES} +else() + list(APPEND csync_SRCS + vio/csync_vio_local_unix.c ) - include_directories(${NEON_INCLUDE_DIRS}) - add_definitions(-DUSE_NEON) -endif(USE_NEON) +endif() configure_file(csync_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h) diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync.c owncloud-client-2.1.1+dfsg/csync/src/csync.c --- owncloud-client-1.8.1+dfsg/csync/src/csync.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync.c 2016-02-09 15:07:08.000000000 +0000 @@ -58,12 +58,6 @@ #include "csync_rename.h" #include "c_jhash.h" - -#ifdef USE_NEON -// Breaking the abstraction for fun and profit. -#include "csync_owncloud.h" -#endif - static int _key_cmp(const void *key, const void *data) { uint64_t a; csync_file_stat_t *b; @@ -124,6 +118,8 @@ ctx->abort = false; + ctx->ignore_hidden_files = true; + *csync = ctx; return 0; } @@ -152,9 +148,6 @@ ctx->local.type = LOCAL_REPLICA; -#ifdef USE_NEON - owncloud_init(ctx); -#endif ctx->remote.type = REMOTE_REPLICA; if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) { @@ -214,14 +207,6 @@ CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "No exclude file loaded or defined!"); } -#ifdef USE_NEON - /* This is not actually connecting, just setting the info for neon. The legacy propagator can use it.. */ - if (dav_connect( ctx, ctx->remote.uri ) < 0) { - ctx->status_code = CSYNC_STATUS_CONNECT_ERROR; - return -1; - } -#endif - /* update detection for local replica */ csync_gettime(&start); ctx->current = LOCAL_REPLICA; @@ -386,6 +371,20 @@ SAFE_FREE(renamed_path); } + if (!other_node) { + /* Check the source path as well. */ + int len; + uint64_t h = 0; + char *renamed_path = csync_rename_adjust_path_source(ctx, cur->path); + + if (!c_streq(renamed_path, cur->path)) { + len = strlen( renamed_path ); + h = c_jhash64((uint8_t *) renamed_path, len, 0); + other_node = c_rbtree_find(other_tree, &h); + } + SAFE_FREE(renamed_path); + } + if (obj == NULL || data == NULL) { ctx->status_code = CSYNC_STATUS_PARAM_ERROR; return -1; @@ -420,7 +419,10 @@ trav.inode = cur->inode; trav.error_status = cur->error_status; - trav.should_update_etag = cur->should_update_etag; + trav.should_update_metadata = cur->should_update_metadata; + trav.has_ignored_files = cur->has_ignored_files; + trav.checksum = cur->checksum; + trav.checksumTypeId = cur->checksumTypeId; if( other_node ) { csync_file_stat_t *other_stat = (csync_file_stat_t*)other_node->data; @@ -578,6 +580,7 @@ ctx->remote.read_from_db = 0; ctx->read_remote_from_db = true; ctx->db_is_empty = false; + ctx->ignore_hidden_files = true; // do NOT sync hidden files by default. /* Create new trees */ @@ -628,10 +631,6 @@ SAFE_FREE(ctx->remote.uri); SAFE_FREE(ctx->error_string); -#ifdef USE_NEON - owncloud_destroy(ctx); -#endif - #ifdef WITH_ICONV c_close_iconv(); #endif @@ -654,21 +653,6 @@ csync_exclude_clear(ctx); } -int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb) { - if (ctx == NULL || cb == NULL) { - return -1; - } - - if (ctx->status & CSYNC_STATUS_INIT) { - ctx->status_code = CSYNC_STATUS_CSYNC_STATUS_ERROR; - fprintf(stderr, "This function must be called before initialization."); - return -1; - } - ctx->callbacks.auth_function = cb; - - return 0; -} - void *csync_get_userdata(CSYNC *ctx) { if (ctx == NULL) { return NULL; @@ -760,17 +744,7 @@ SAFE_FREE(st->directDownloadCookies); SAFE_FREE(st->etag); SAFE_FREE(st->destpath); + SAFE_FREE(st->checksum); SAFE_FREE(st); } } - -int csync_set_module_property(CSYNC* ctx, const char* key, void* value) -{ -#ifdef USE_NEON - return owncloud_set_property(ctx, key, value); -#else - (void)ctx, (void)key, (void)value; - return 0; -#endif -} - diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_exclude.c owncloud-client-2.1.1+dfsg/csync/src/csync_exclude.c --- owncloud-client-1.8.1+dfsg/csync/src/csync_exclude.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_exclude.c 2016-02-09 15:07:08.000000000 +0000 @@ -44,24 +44,7 @@ static #endif int _csync_exclude_add(c_strlist_t **inList, const char *string) { - c_strlist_t *list; - - if (*inList == NULL) { - *inList = c_strlist_new(32); - if (*inList == NULL) { - return -1; - } - } - - if ((*inList)->count == (*inList)->size) { - list = c_strlist_expand(*inList, 2 * (*inList)->size); - if (list == NULL) { - return -1; - } - *inList = list; - } - - return c_strlist_add(*inList, string); + return c_strlist_add_grow(inList, string); } int csync_exclude_load(const char *fname, c_strlist_t **list) { @@ -81,7 +64,7 @@ _fmode = _O_BINARY; #endif - w_fname = c_utf8_to_locale(fname); + w_fname = c_utf8_path_to_locale(fname); if (w_fname == NULL) { return -1; } @@ -186,19 +169,56 @@ return false; } -CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype) { - size_t i = 0; - const char *p = NULL; - char *bname = NULL; - char *dname = NULL; - char *prev_dname = NULL; - char *conflict = NULL; - int rc = -1; - CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED; - CSYNC_EXCLUDE_TYPE type = CSYNC_NOT_EXCLUDED; +static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const char *path, int filetype, bool check_leading_dirs) { + size_t i = 0; + const char *bname = NULL; + size_t blen = 0; + char *conflict = NULL; + int rc = -1; + CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED; + CSYNC_EXCLUDE_TYPE type = CSYNC_NOT_EXCLUDED; + + /* split up the path */ + bname = strrchr(path, '/'); + if (bname) { + bname += 1; // don't include the / + } else { + bname = path; + } + blen = strlen(bname); + + rc = csync_fnmatch(".csync_journal.db*", bname, 0); + if (rc == 0) { + match = CSYNC_FILE_SILENTLY_EXCLUDED; + goto out; + } + + // check the strlen and ignore the file if its name is longer than 254 chars. + // whenever changing this also check createDownloadTmpFileName + if (blen > 254) { + match = CSYNC_FILE_EXCLUDE_LONG_FILENAME; + goto out; + } + +#ifdef _WIN32 + // Windows cannot sync files ending in spaces (#2176). It also cannot + // distinguish files ending in '.' from files without an ending, + // as '.' is a separator that is not stored internally, so let's + // not allow to sync those to avoid file loss/ambiguities (#416) + if (blen > 1 && (bname[blen-1]== ' ' || bname[blen-1]== '.' )) { + match = CSYNC_FILE_EXCLUDE_INVALID_CHAR; + goto out; + } + + if (csync_is_windows_reserved_word(bname)) { + match = CSYNC_FILE_EXCLUDE_INVALID_CHAR; + goto out; + } + // Filter out characters not allowed in a filename on windows + const char *p = NULL; for (p = path; *p; p++) { - switch (*p) { + switch (*p) { case '\\': case ':': case '?': @@ -207,186 +227,146 @@ case '>': case '<': case '|': - return CSYNC_FILE_EXCLUDE_INVALID_CHAR; + match = CSYNC_FILE_EXCLUDE_INVALID_CHAR; + goto out; default: - break; - } + 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; - } - - // check the strlen and ignore the file if its name is longer than 254 chars. - if (strlen(bname) > 254) { - match = CSYNC_FILE_EXCLUDE_LONG_FILENAME; - SAFE_FREE(bname); - SAFE_FREE(dname); - goto out; - } - -#ifdef _WIN32 - // Windows cannot sync files ending in spaces (#2176). It also cannot - // distinguish files ending in '.' from files without an ending, - // as '.' is a separator that is not stored internally, so let's - // not allow to sync those to avoid file loss/ambiguities (#416) - size_t blen = strlen(bname); - if (blen > 1 && (bname[blen-1]== ' ' || bname[blen-1]== '.' )) { - match = CSYNC_FILE_EXCLUDE_INVALID_CHAR; - SAFE_FREE(bname); - SAFE_FREE(dname); - goto out; - } - - if (csync_is_windows_reserved_word(bname)) { - match = CSYNC_FILE_EXCLUDE_INVALID_CHAR; - SAFE_FREE(bname); - SAFE_FREE(dname); - goto out; - } #endif - rc = csync_fnmatch(".owncloudsync.log*", bname, 0); - if (rc == 0) { - match = CSYNC_FILE_SILENTLY_EXCLUDED; - SAFE_FREE(bname); - SAFE_FREE(dname); - goto out; - } - - /* Always ignore conflict files, not only via the exclude list */ - rc = csync_fnmatch("*_conflict-*", bname, 0); - if (rc == 0) { - match = CSYNC_FILE_SILENTLY_EXCLUDED; - SAFE_FREE(bname); - SAFE_FREE(dname); - goto out; - } + rc = csync_fnmatch(".owncloudsync.log*", bname, 0); + if (rc == 0) { + match = CSYNC_FILE_SILENTLY_EXCLUDED; + goto out; + } - if (getenv("CSYNC_CONFLICT_FILE_USERNAME")) { - rc = asprintf(&conflict, "*_conflict_%s-*", getenv("CSYNC_CONFLICT_FILE_USERNAME")); - if (rc < 0) { - goto out; - } - rc = csync_fnmatch(conflict, path, 0); - if (rc == 0) { - match = CSYNC_FILE_SILENTLY_EXCLUDED; - SAFE_FREE(conflict); - SAFE_FREE(bname); - SAFE_FREE(dname); - goto out; - } - SAFE_FREE(conflict); - } + /* Always ignore conflict files, not only via the exclude list */ + rc = csync_fnmatch("*_conflict-*", bname, 0); + if (rc == 0) { + match = CSYNC_FILE_SILENTLY_EXCLUDED; + goto out; + } - SAFE_FREE(bname); - SAFE_FREE(dname); + if (getenv("CSYNC_CONFLICT_FILE_USERNAME")) { + rc = asprintf(&conflict, "*_conflict_%s-*", getenv("CSYNC_CONFLICT_FILE_USERNAME")); + if (rc < 0) { + goto out; + } + rc = csync_fnmatch(conflict, path, 0); + if (rc == 0) { + match = CSYNC_FILE_SILENTLY_EXCLUDED; + SAFE_FREE(conflict); + goto out; + } + SAFE_FREE(conflict); + } - if( ! excludes ) { - goto out; - } + if( ! excludes ) { + goto out; + } - /* Loop over all exclude patterns and evaluate the given path */ - for (i = 0; match == CSYNC_NOT_EXCLUDED && i < excludes->count; i++) { - bool match_dirs_only = false; - char *pattern_stored = c_strdup(excludes->vector[i]); - char* pattern = pattern_stored; - - type = CSYNC_FILE_EXCLUDE_LIST; - if (strlen(pattern) < 1) { - SAFE_FREE(pattern_stored); - 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 */ - } + c_strlist_t *path_components = NULL; + if (check_leading_dirs) { + /* Build a list of path components to check. */ + path_components = c_strlist_new(32); + char *path_split = strdup(path); + size_t len = strlen(path_split); + for (i = len; ; --i) { + // read backwards until a path separator is found + if (i != 0 && path_split[i-1] != '/') { + continue; + } + + // check 'basename', i.e. for "/foo/bar/fi" we'd check 'fi', 'bar', 'foo' + if (path_split[i] != 0) { + c_strlist_add_grow(&path_components, path_split + i); + } + + if (i == 0) { + break; + } + + // check 'dirname', i.e. for "/foo/bar/fi" we'd check '/foo/bar', '/foo' + path_split[i-1] = '\0'; + c_strlist_add_grow(&path_components, path_split); + } + SAFE_FREE(path_split); + } - /* 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; - } - } + /* Loop over all exclude patterns and evaluate the given path */ + for (i = 0; match == CSYNC_NOT_EXCLUDED && i < excludes->count; i++) { + bool match_dirs_only = false; + char *pattern = excludes->vector[i]; + + type = CSYNC_FILE_EXCLUDE_LIST; + if (!pattern[0]) { /* empty pattern */ + continue; + } + /* Excludes starting with ']' means it can be cleanup */ + if (pattern[0] == ']') { + ++pattern; + if (filetype == CSYNC_FTW_TYPE_FILE) { + type = CSYNC_FILE_EXCLUDE_AND_REMOVE; + } + } + /* Check if the pattern applies to pathes only. */ + if (pattern[strlen(pattern)-1] == '/') { + if (!check_leading_dirs && filetype == CSYNC_FTW_TYPE_FILE) { + continue; + } + match_dirs_only = true; + pattern[strlen(pattern)-1] = '\0'; /* Cut off the slash */ + } - /* 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; - SAFE_FREE(bname); - SAFE_FREE(dname); - SAFE_FREE(pattern_stored); - goto out; - } + /* 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; + } + } - /* 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); + /* if still not excluded, check each component and leading directory of the path */ + if (match == CSYNC_NOT_EXCLUDED && check_leading_dirs) { + size_t j = 0; + if (match_dirs_only && filetype == CSYNC_FTW_TYPE_FILE) { + j = 1; // skip the first entry, which is bname + } + for (; j < path_components->count; ++j) { + rc = csync_fnmatch(pattern, path_components->vector[j], 0); + if (rc == 0) { + match = type; + break; + } + } + } else if (match == CSYNC_NOT_EXCLUDED && !check_leading_dirs) { + rc = csync_fnmatch(pattern, bname, 0); + if (rc == 0) { + match = type; + } + } + if (match_dirs_only) { + /* restore the '/' */ + pattern[strlen(pattern)] = '/'; + } + } + c_strlist_destroy(path_components); - } while( match == CSYNC_NOT_EXCLUDED && !c_streq(dname, ".") - && !c_streq(dname, "/") ); - } - SAFE_FREE(pattern_stored); - SAFE_FREE(bname); - SAFE_FREE(dname); - } + out: + return match; +} -out: +CSYNC_EXCLUDE_TYPE csync_excluded_traversal(c_strlist_t *excludes, const char *path, int filetype) { + return _csync_excluded_common(excludes, path, filetype, false); +} - return match; +CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype) { + return _csync_excluded_common(excludes, path, filetype, true); } diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_exclude.h owncloud-client-2.1.1+dfsg/csync/src/csync_exclude.h --- owncloud-client-1.8.1+dfsg/csync/src/csync_exclude.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_exclude.h 2016-02-09 15:07:08.000000000 +0000 @@ -27,7 +27,9 @@ CSYNC_FILE_EXCLUDE_AND_REMOVE, CSYNC_FILE_EXCLUDE_LIST, CSYNC_FILE_EXCLUDE_INVALID_CHAR, - CSYNC_FILE_EXCLUDE_LONG_FILENAME + CSYNC_FILE_EXCLUDE_LONG_FILENAME, + CSYNC_FILE_EXCLUDE_HIDDEN, + CSYNC_FILE_EXCLUDE_STAT_FAILED }; typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE; @@ -64,6 +66,11 @@ * * This excludes also paths which can't be used without unix extensions. * + * The exclude list is checked against the full path, each component of + * the path and all leading directory strings, e.g. + * '/foo/bar/file' checks ('/foo/bar/file', 'foo', 'bar', 'file', + * '/foo/bar', '/foo'). + * * @param ctx The synchronizer context. * @param path The patch to check. * @@ -72,6 +79,23 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype); /** + * @brief Check if the given path should be excluded in a traversal situation. + * + * It does only part of the work that csync_excluded does because it's assumed + * that all leading directories have been run through csync_excluded_traversal() + * before. This can be significantly faster. + * + * That means for '/foo/bar/file' only ('/foo/bar/file', 'file') is checked + * against the exclude patterns. + * + * @param ctx The synchronizer context. + * @param path The patch to check. + * + * @return 2 if excluded and needs cleanup, 1 if excluded, 0 if not. + */ +CSYNC_EXCLUDE_TYPE csync_excluded_traversal(c_strlist_t *excludes, const char *path, int filetype); + +/** * @brief csync_excluded_no_ctx * @param excludes * @param path diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync.h owncloud-client-2.1.1+dfsg/csync/src/csync.h --- owncloud-client-1.8.1+dfsg/csync/src/csync.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync.h 2016-02-09 15:07:08.000000000 +0000 @@ -49,41 +49,37 @@ char *certificatePasswd; }; -/** - * 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, */ - CSYNC_STATUS_UNSUCCESSFUL, - CSYNC_STATUS_NO_LOCK, /* OBSOLETE does not happen anymore */ - CSYNC_STATUS_STATEDB_LOAD_ERROR, - CSYNC_STATUS_STATEDB_CORRUPTED, - CSYNC_STATUS_NO_MODULE, - CSYNC_STATUS_TIMESKEW, /* OBSOLETE */ + CSYNC_STATUS_UNSUCCESSFUL, /* Unspecific problem happend */ + CSYNC_STATUS_NO_LOCK, /* OBSOLETE does not happen anymore */ + CSYNC_STATUS_STATEDB_LOAD_ERROR, /* Statedb can not be loaded. */ + CSYNC_STATUS_STATEDB_CORRUPTED, /* Statedb is corrupted */ + CSYNC_STATUS_NO_MODULE, /* URL passed to csync does not start with owncloud:// or ownclouds:// */ + CSYNC_STATUS_TIMESKEW, /* OBSOLETE */ CSYNC_STATUS_FILESYSTEM_UNKNOWN, /* UNUSED */ - CSYNC_STATUS_TREE_ERROR, - CSYNC_STATUS_MEMORY_ERROR, - CSYNC_STATUS_PARAM_ERROR, - CSYNC_STATUS_UPDATE_ERROR, - CSYNC_STATUS_RECONCILE_ERROR, - CSYNC_STATUS_PROPAGATE_ERROR, /* OBSOLETE */ + CSYNC_STATUS_TREE_ERROR, /* csync trees could not be created */ + CSYNC_STATUS_MEMORY_ERROR, /* not enough memory problem */ + CSYNC_STATUS_PARAM_ERROR, /* parameter is zero where not expected */ + CSYNC_STATUS_UPDATE_ERROR, /* general update or discovery error */ + CSYNC_STATUS_RECONCILE_ERROR, /* general reconcile error */ + CSYNC_STATUS_PROPAGATE_ERROR, /* OBSOLETE */ CSYNC_STATUS_REMOTE_ACCESS_ERROR, /* UNUSED */ CSYNC_STATUS_REMOTE_CREATE_ERROR, /* UNUSED */ - CSYNC_STATUS_REMOTE_STAT_ERROR, /* UNUSED */ + CSYNC_STATUS_REMOTE_STAT_ERROR, /* UNUSED */ CSYNC_STATUS_LOCAL_CREATE_ERROR, /* UNUSED */ - CSYNC_STATUS_LOCAL_STAT_ERROR, /* UNUSED */ - CSYNC_STATUS_PROXY_ERROR, /* UNUSED */ - CSYNC_STATUS_LOOKUP_ERROR, - 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_LOCAL_STAT_ERROR, /* UNUSED */ + CSYNC_STATUS_PROXY_ERROR, /* UNUSED */ + CSYNC_STATUS_LOOKUP_ERROR, /* Neon fails to find proxy. Almost OBSOLETE */ + CSYNC_STATUS_SERVER_AUTH_ERROR, /* UNUSED */ + CSYNC_STATUS_PROXY_AUTH_ERROR, /* UNUSED */ + CSYNC_STATUS_CONNECT_ERROR, /* neon driven connection failed */ + CSYNC_STATUS_TIMEOUT, /* UNUSED */ + CSYNC_STATUS_HTTP_ERROR, /* UNUSED */ + CSYNC_STATUS_PERMISSION_DENIED, /* */ CSYNC_STATUS_NOT_FOUND, CSYNC_STATUS_FILE_EXISTS, CSYNC_STATUS_OUT_OF_SPACE, @@ -100,11 +96,14 @@ CSYNC_STATUS_ABORTED, /* Codes for file individual status: */ CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK, - CSYNC_STATUS_INDIVIDUAL_IS_HARDLINK, CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST, CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS, CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME, - CYSNC_STATUS_FILE_LOCKED_OR_OPEN + CYSNC_STATUS_FILE_LOCKED_OR_OPEN, + CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN, + CSYNC_STATUS_INVALID_CHARACTERS, + CSYNC_STATUS_INDIVIDUAL_STAT_FAILED, + CSYNC_STATUS_FORBIDDEN }; typedef enum csync_status_codes_e CSYNC_STATUS; @@ -120,7 +119,10 @@ #define CSYNC_STATUS_IS_ERR(x) (unlikely((x) >= CSYNC_STATUS_ERROR)) #define CSYNC_STATUS_IS_EQUAL(x, y) ((x) == (y)) - +/** + * Instruction enum. In the file traversal structure, it describes + * the csync state of a file. + */ enum csync_instructions_e { CSYNC_INSTRUCTION_NONE = 0x00000000, /* Nothing to do (UPDATE|RECONCILE) */ CSYNC_INSTRUCTION_EVAL = 0x00000001, /* There was changed compared to the DB (UPDATE) */ @@ -132,7 +134,10 @@ CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */ CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */ CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080, - CSYNC_INSTRUCTION_ERROR = 0x00000100 + CSYNC_INSTRUCTION_ERROR = 0x00000100, + CSYNC_INSTRUCTION_TYPE_CHANGE = 0x0000200, /* Like NEW, but deletes the old entity first (RECONCILE) + Used when the type of something changes from directory to file + or back. */ }; enum csync_ftw_type_e { @@ -143,7 +148,7 @@ }; -#define FILE_ID_BUF_SIZE 21 +#define FILE_ID_BUF_SIZE 36 // currently specified at https://github.com/owncloud/core/issues/8322 are 9 to 10 #define REMOTE_PERM_BUF_SIZE 15 @@ -172,9 +177,9 @@ CSYNC_VIO_FILE_STAT_FIELDS_TYPE = 1 << 0, CSYNC_VIO_FILE_STAT_FIELDS_MODE = 1 << 1, // local POSIX mode CSYNC_VIO_FILE_STAT_FIELDS_FLAGS = 1 << 2, - CSYNC_VIO_FILE_STAT_FIELDS_DEVICE = 1 << 3, +// CSYNC_VIO_FILE_STAT_FIELDS_DEVICE = 1 << 3, CSYNC_VIO_FILE_STAT_FIELDS_INODE = 1 << 4, - CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT = 1 << 5, +// CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT = 1 << 5, CSYNC_VIO_FILE_STAT_FIELDS_SIZE = 1 << 6, // CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_COUNT = 1 << 7, /* will be removed */ // CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_SIZE = 1 << 8, /* will be removed */ @@ -211,14 +216,14 @@ mode_t mode; - dev_t device; uint64_t inode; - nlink_t nlink; int fields; // actually enum csync_vio_file_stat_fields_e fields; enum csync_vio_file_type_e type; enum csync_vio_file_flags_e flags; + + char *original_name; // only set if locale conversion fails }; csync_vio_file_stat_t *csync_vio_file_stat_new(void); @@ -249,7 +254,10 @@ 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; + int should_update_metadata; + + /* For directories: Does it have children that were ignored (hidden or ignore pattern) */ + int has_ignored_files; const char *rename_path; const char *etag; @@ -257,6 +265,10 @@ const char *remotePerm; char *directDownloadUrl; char *directDownloadCookies; + + const char *checksum; + uint32_t checksumTypeId; + struct { int64_t size; time_t modtime; @@ -296,6 +308,10 @@ typedef int (*csync_vio_stat_hook) (csync_vio_handle_t *dhhandle, void *userdata); +/* Compute the checksum of the given \a checksumTypeId for \a path. */ +typedef const char* (*csync_checksum_hook) ( + const char *path, uint32_t checksumTypeId, void *userdata); + /** * @brief Allocate a csync context. * @@ -515,19 +531,6 @@ #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 Aborts the current sync run as soon as possible. Can be called from another thread. * * @param ctx The csync context. diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_log.h owncloud-client-2.1.1+dfsg/csync/src/csync_log.h --- owncloud-client-1.8.1+dfsg/csync/src/csync_log.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_log.h 2016-02-09 15:07:08.000000000 +0000 @@ -61,7 +61,7 @@ }; #define CSYNC_LOG(priority, ...) \ - csync_log(priority, __FUNCTION__, __VA_ARGS__) + csync_log(priority, __func__, __VA_ARGS__) void csync_log(int verbosity, const char *function, diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_macros.h owncloud-client-2.1.1+dfsg/csync/src/csync_macros.h --- owncloud-client-1.8.1+dfsg/csync/src/csync_macros.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_macros.h 2016-02-09 15:07:08.000000000 +0000 @@ -46,6 +46,7 @@ #define ERRNO_SERVICE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+14 #define ERRNO_USER_ABORT CSYNC_CUSTOM_ERRNO_BASE+16 #define ERRNO_STORAGE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+17 +#define ERRNO_FORBIDDEN CSYNC_CUSTOM_ERRNO_BASE+18 #endif /* _CSYNC_MACROS_H */ /* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */ diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_misc.c owncloud-client-2.1.1+dfsg/csync/src/csync_misc.c --- owncloud-client-1.8.1+dfsg/csync/src/csync_misc.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_misc.c 2016-02-09 15:07:08.000000000 +0000 @@ -57,20 +57,13 @@ #else /* HAVE_FNMATCH */ #include -int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags) { - wchar_t *pat = NULL; - wchar_t *name = NULL; +int csync_fnmatch(const char *pattern, const char *name, int flags) { BOOL match; - (void) __flags; + (void) flags; - name = c_utf8_to_locale(__name); - pat = c_utf8_to_locale(__pattern); + match = PathMatchSpecA(name, pattern); - match = PathMatchSpec(name, pat); - - c_free_locale_string(pat); - c_free_locale_string(name); if(match) return 0; else diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_owncloud.c owncloud-client-2.1.1+dfsg/csync/src/csync_owncloud.c --- owncloud-client-1.8.1+dfsg/csync/src/csync_owncloud.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_owncloud.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,617 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2011 by Andreas Schneider - * Copyright (c) 2012 by Klaas Freitag - * - * 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_owncloud_private.h" - -#include - -#include "csync_private.h" - -#include "csync_version.h" - - -/* - * helper method to build up a user text for SSL problems, called from the - * verify_sslcert callback. - */ -static void addSSLWarning( char *ptr, const char *warn, int len ) -{ - char *concatHere = ptr; - int remainingLen = 0; - - if( ! (warn && ptr )) return; - remainingLen = len - strlen(ptr); - if( remainingLen <= 0 ) return; - concatHere = ptr + strlen(ptr); /* put the write pointer to the end. */ - strncpy( concatHere, warn, remainingLen ); -} - -/* - * Callback to verify the SSL certificate, called from libneon. - * It analyzes the SSL problem, creates a user information text and passes - * it to the csync callback to ask the user. - */ -#define LEN 4096 -static int ssl_callback_by_neon(void *userdata, int failures, - const ne_ssl_certificate *certificate) -{ - char problem[LEN]; - char buf[MAX(NE_SSL_DIGESTLEN, NE_ABUFSIZ)]; - int ret = -1; - const ne_ssl_certificate *cert = certificate; - csync_auth_callback authcb = NULL; - csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata; - - memset( problem, 0, LEN ); - - while( cert ) { - - addSSLWarning( problem, "There are problems with the SSL certificate:\n", LEN ); - if( failures & NE_SSL_NOTYETVALID ) { - addSSLWarning( problem, " * The certificate is not yet valid.\n", LEN ); - } - if( failures & NE_SSL_EXPIRED ) { - addSSLWarning( problem, " * The certificate has expired.\n", LEN ); - } - - if( failures & NE_SSL_UNTRUSTED ) { - addSSLWarning( problem, " * The certificate is not trusted!\n", LEN ); - } - if( failures & NE_SSL_IDMISMATCH ) { - addSSLWarning( problem, " * The hostname for which the certificate was " - "issued does not match the hostname of the server\n", LEN ); - } - if( failures & NE_SSL_BADCHAIN ) { - addSSLWarning( problem, " * The certificate chain contained a certificate other than the server cert\n", LEN ); - } - if( failures & NE_SSL_REVOKED ) { - addSSLWarning( problem, " * The server certificate has been revoked by the issuing authority.\n", LEN ); - } - - if (ne_ssl_cert_digest(cert, buf) == 0) { - addSSLWarning( problem, "Certificate fingerprint: ", LEN ); - addSSLWarning( problem, buf, LEN ); - addSSLWarning( problem, "\n", LEN ); - } - cert = ne_ssl_cert_signedby( cert ); - } - addSSLWarning( problem, "Do you want to accept the certificate chain anyway?\nAnswer yes to do so and take the risk: ", LEN ); - - if( ctx->csync_ctx ) { - authcb = csync_get_auth_callback( ctx->csync_ctx ); - } - if( authcb ){ - /* call the csync callback */ - DEBUG_WEBDAV("Call the csync callback for SSL problems"); - memset( buf, 0, NE_ABUFSIZ ); - (*authcb) ( problem, buf, NE_ABUFSIZ-1, 1, 0, csync_get_userdata(ctx->csync_ctx) ); - if( buf[0] == 'y' || buf[0] == 'Y') { - ret = 0; - } else { - DEBUG_WEBDAV("Authentication callback replied %s", buf ); - - } - } - DEBUG_WEBDAV("## VERIFY_SSL CERT: %d", ret ); - return ret; -} - -/* - * Authentication callback. Is set by ne_set_server_auth to be called - * from the neon lib to authenticate a request. - */ -static int authentication_callback_by_neon( void *userdata, const char *realm, int attempt, - char *username, char *password) -{ - char buf[NE_ABUFSIZ]; - csync_auth_callback authcb = NULL; - int re = attempt; - csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata; - - (void) realm; - - /* DEBUG_WEBDAV( "Authentication required %s", realm ); */ - if( username && password ) { - DEBUG_WEBDAV( "Authentication required %s", username ); - if( ctx->dav_session.user ) { - /* allow user without password */ - if( strlen( ctx->dav_session.user ) < NE_ABUFSIZ ) { - strcpy( username, ctx->dav_session.user ); - } - if( ctx->dav_session.pwd && strlen( ctx->dav_session.pwd ) < NE_ABUFSIZ ) { - strcpy( password, ctx->dav_session.pwd ); - } - } else { - authcb = csync_get_auth_callback( ctx->csync_ctx ); - if( authcb != NULL ){ - /* call the csync callback */ - DEBUG_WEBDAV("Call the csync callback for %s", realm ); - memset( buf, 0, NE_ABUFSIZ ); - (*authcb) ("Enter your username: ", buf, NE_ABUFSIZ-1, 1, 0, csync_get_userdata(ctx->csync_ctx) ); - if( strlen(buf) < NE_ABUFSIZ ) { - strcpy( username, buf ); - } - memset( buf, 0, NE_ABUFSIZ ); - (*authcb) ("Enter your password: ", buf, NE_ABUFSIZ-1, 0, 0, csync_get_userdata(ctx->csync_ctx) ); - if( strlen(buf) < NE_ABUFSIZ) { - strcpy( password, buf ); - } - } else { - re = 1; - } - } - } - return re; -} - -/* - * Authentication callback. Is set by ne_set_proxy_auth to be called - * from the neon lib to authenticate against a proxy. The data to authenticate - * against comes from mirall throught vio_module_init function. - */ -static int proxy_authentication_callback_by_neon( void *userdata, const char *realm, int attempt, - char *username, char *password) -{ - csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata; - (void) realm; - if( ctx->dav_session.proxy_user && strlen( ctx->dav_session.proxy_user ) < NE_ABUFSIZ) { - strcpy( username, ctx->dav_session.proxy_user ); - if( ctx->dav_session.proxy_pwd && strlen( ctx->dav_session.proxy_pwd ) < NE_ABUFSIZ) { - strcpy( password, ctx->dav_session.proxy_pwd ); - } - } - /* NTLM needs several attempts */ - return (attempt < 3) ? 0 : -1; -} - -/* Configure the proxy depending on the variables */ -static int configureProxy( csync_owncloud_ctx_t *ctx, ne_session *session ) -{ - int port = 8080; - int re = -1; - - if( ! session ) return -1; - if( ! ctx->dav_session.proxy_type ) return 0; /* Go by NoProxy per default */ - - if( ctx->dav_session.proxy_port > 0 ) { - port = ctx->dav_session.proxy_port; - } - - if( c_streq(ctx->dav_session.proxy_type, "NoProxy" )) { - DEBUG_WEBDAV("No proxy configured."); - re = 0; - } else if( c_streq(ctx->dav_session.proxy_type, "DefaultProxy") || - c_streq(ctx->dav_session.proxy_type, "HttpProxy") || - c_streq(ctx->dav_session.proxy_type, "HttpCachingProxy") || - c_streq(ctx->dav_session.proxy_type, "Socks5Proxy")) { - - if( ctx->dav_session.proxy_host ) { - DEBUG_WEBDAV("%s at %s:%d", ctx->dav_session.proxy_type, ctx->dav_session.proxy_host, port ); - if (c_streq(ctx->dav_session.proxy_type, "Socks5Proxy")) { - ne_session_socks_proxy(session, NE_SOCK_SOCKSV5, ctx->dav_session.proxy_host, port, - ctx->dav_session.proxy_user, ctx->dav_session.proxy_pwd); - } else { - ne_session_proxy(session, ctx->dav_session.proxy_host, port ); - } - re = 2; - } else { - DEBUG_WEBDAV("%s requested but no proxy host defined.", ctx->dav_session.proxy_type ); - /* we used to try ne_system_session_proxy here, but we should rather err out - to behave exactly like the caller. */ - } - } else { - DEBUG_WEBDAV( "Unsupported Proxy: %s", ctx->dav_session.proxy_type ); - } - - return re; -} - -/* - * This hook is called for with the response of a request. Here its checked - * if a Set-Cookie header is there for the PHPSESSID. The key is stored into - * the webdav session to be added to subsequent requests. - */ -static void post_request_hook(ne_request *req, void *userdata, const ne_status *status) -{ - const char *set_cookie_header = NULL; - const char *sc = NULL; - char *key = NULL; - - csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata; - - if (ctx->dav_session.session_key) - return; /* We already have a session cookie, and we should ignore other ones */ - - if(!(status && req)) return; - if( status->klass == 2 || status->code == 401 ) { - /* successful request */ - set_cookie_header = ne_get_response_header( req, "Set-Cookie" ); - if( set_cookie_header ) { - DEBUG_WEBDAV(" Set-Cookie found: %s", set_cookie_header); - /* try to find a ', ' sequence which is the separator of neon if multiple Set-Cookie - * headers are there. - * The following code parses a string like this: - * Set-Cookie: 50ace6bd8a669=p537brtt048jh8srlp2tuep7em95nh9u98mj992fbqc47d1aecp1; - */ - sc = set_cookie_header; - while(sc) { - const char *sc_val = sc; - const char *sc_end = sc_val; - int cnt = 0; - int len = strlen(sc_val); /* The length of the rest of the header string. */ - - while( cnt < len && *sc_end != ';' && *sc_end != ',') { - cnt++; - sc_end++; - } - if( cnt == len ) { - /* exit: We are at the end. */ - sc = NULL; - } else if( *sc_end == ';' ) { - /* We are at the end of the session key. */ - int keylen = sc_end-sc_val; - if( key ) { - int oldlen = strlen(key); - key = c_realloc(key, oldlen + 2 + keylen+1); - strcpy(key + oldlen, "; "); - strncpy(key + oldlen + 2, sc_val, keylen); - key[oldlen + 2 + keylen] = '\0'; - } else { - key = c_malloc(keylen+1); - strncpy( key, sc_val, keylen ); - key[keylen] = '\0'; - } - - /* now search for a ',' to find a potential other header entry */ - while(cnt < len && *sc_end != ',') { - cnt++; - sc_end++; - } - if( cnt < len ) - sc = sc_end+2; /* mind the space after the comma */ - else - sc = NULL; - } else if( *sc_end == ',' ) { - /* A new entry is to check. */ - if( *(sc_end + 1) == ' ') { - sc = sc_end+2; - } else { - /* error condition */ - sc = NULL; - } - } - } - } - } else { - DEBUG_WEBDAV("Request failed, don't take session header."); - } - if( key ) { - DEBUG_WEBDAV("----> Session-key: %s", key); - SAFE_FREE(ctx->dav_session.session_key); - ctx->dav_session.session_key = key; - } -} - -/* - * this hook is called just after a request has been created, before its sent. - * Here it is used to set the proxy connection header if available. - */ -static void request_created_hook(ne_request *req, void *userdata, - const char *method, const char *requri) -{ - // FIXME Can possibly be merged with pre_send_hook - csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata; - (void) method; - (void) requri; - - if( !req ) return; - - if(ctx->dav_session.proxy_type) { - /* required for NTLM */ - ne_add_request_header(req, "Proxy-Connection", "Keep-Alive"); - } -} - -/* - * this hook is called just before a request has been sent. - * Here it is used to set the session cookie if available. - */ -static void pre_send_hook(ne_request *req, void *userdata, - ne_buffer *header) -{ - csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata; - - if( !req ) return; - - if(ctx->dav_session.session_key) { - ne_buffer_concat(header, "Cookie: ", ctx->dav_session.session_key, "\r\n", NULL); - } else { - DEBUG_WEBDAV("csync pre_send_hook We don't have a Auth Cookie (session_key), this is wrong!"); - } -} - -static int post_send_hook(ne_request *req, void *userdata, - const ne_status *status) -{ - const char *location; - csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata; - (void) status; - - location = ne_get_response_header(req, "Location"); - - if( !location ) return NE_OK; - - if( ctx->dav_session.redir_callback ) { - if( ctx->dav_session.redir_callback( ctx->csync_ctx, location ) ) { - return NE_REDIRECT; - } else { - return NE_RETRY; - } - } - - return NE_REDIRECT; -} - -/* - * Connect to a DAV server - * This function sets the flag _connected if the connection is established - * and returns if the flag is set, so calling it frequently is save. - */ -int dav_connect(CSYNC *csyncCtx, const char *base_url) { - int useSSL = 0; - int rc; - char protocol[6] = {'\0'}; - char uaBuf[256]; - char *path = NULL; - char *scheme = NULL; - char *host = NULL; - unsigned int port = 0; - int proxystate = -1; - csync_owncloud_ctx_t *ctx = csyncCtx->owncloud_context; - struct csync_client_certs_s* clientCerts = csyncCtx->clientCerts; - - if (ctx->_connected) { - return 0; - } - - rc = c_parse_uri( base_url, &scheme, - &ctx->dav_session.user, - &ctx->dav_session.pwd, - &host, &port, &path ); - if( rc < 0 ) { - DEBUG_WEBDAV("Failed to parse uri %s", base_url ); - goto out; - } - - DEBUG_WEBDAV("* scheme %s", scheme ); - DEBUG_WEBDAV("* host %s", host ); - DEBUG_WEBDAV("* port %u", port ); - DEBUG_WEBDAV("* path %s", path ); - - if( strcmp( scheme, "owncloud" ) == 0 || strcmp( scheme, "http" ) == 0 ) { - strcpy( protocol, "http"); - } else if( strcmp( scheme, "ownclouds" ) == 0 || strcmp( scheme, "https") == 0 ) { - strcpy( protocol, "https"); - useSSL = 1; - } else { - DEBUG_WEBDAV("Invalid scheme %s, go out here!", scheme ); - rc = -1; - goto out; - } - - DEBUG_WEBDAV("* user %s", ctx->dav_session.user ? ctx->dav_session.user : ""); - - if (port == 0) { - port = ne_uri_defaultport(protocol); - } - - ctx->dav_session.ctx = ne_session_create( protocol, host, port); - - if (ctx->dav_session.ctx == NULL) { - DEBUG_WEBDAV("Session create with protocol %s failed", protocol ); - rc = -1; - goto out; - } - - if (ctx->dav_session.read_timeout != 0) { - ne_set_read_timeout(ctx->dav_session.ctx, ctx->dav_session.read_timeout); - DEBUG_WEBDAV("Timeout set to %u seconds", ctx->dav_session.read_timeout ); - } - // Should never take more than some seconds, 30 is really a max. - ne_set_connect_timeout(ctx->dav_session.ctx, 30); - - snprintf( uaBuf, sizeof(uaBuf), "Mozilla/5.0 (%s) mirall/%s (csyncoC)", - CSYNC_STRINGIFY( MIRALL_VERSION ), csync_owncloud_get_platform() ); - ne_set_useragent( ctx->dav_session.ctx, uaBuf); - ne_set_server_auth(ctx->dav_session.ctx, authentication_callback_by_neon, ctx); - - if( useSSL ) { - if (!ne_has_support(NE_FEATURE_SSL)) { - DEBUG_WEBDAV("Error: SSL is not enabled."); - rc = -1; - goto out; - } - - if(clientCerts != NULL) { - ne_ssl_client_cert *clicert; - - DEBUG_WEBDAV("dav_connect: certificatePath and certificatePasswd are set, so we use it" ); - DEBUG_WEBDAV(" with certificatePath: %s", clientCerts->certificatePath ); - DEBUG_WEBDAV(" with certificatePasswd: %s", clientCerts->certificatePasswd ); - clicert = ne_ssl_clicert_read ( clientCerts->certificatePath ); - if ( clicert == NULL ) { - DEBUG_WEBDAV ( "Error read certificate : %s", ne_get_error ( ctx->dav_session.ctx ) ); - } else { - if ( ne_ssl_clicert_encrypted ( clicert ) ) { - int rtn = ne_ssl_clicert_decrypt ( clicert, clientCerts->certificatePasswd ); - if ( !rtn ) { - DEBUG_WEBDAV ( "Certificate was deciphered successfully." ); - ne_ssl_set_clicert ( ctx->dav_session.ctx, clicert ); - } else { - DEBUG_WEBDAV ( "Errors while deciphering certificate: %s", ne_get_error ( ctx->dav_session.ctx ) ); - } - } - } - } else { - DEBUG_WEBDAV("dav_connect: error with csync_client_certs_s* clientCerts"); - } - ne_ssl_trust_default_ca( ctx->dav_session.ctx ); - ne_ssl_set_verify( ctx->dav_session.ctx, ssl_callback_by_neon, ctx); - } - - /* Hook called when a request is created. It sets the proxy connection header. */ - ne_hook_create_request( ctx->dav_session.ctx, request_created_hook, ctx ); - /* Hook called after response headers are read. It gets the Session ID. */ - ne_hook_post_headers( ctx->dav_session.ctx, post_request_hook, ctx ); - /* Hook called before a request is sent. It sets the cookies. */ - ne_hook_pre_send( ctx->dav_session.ctx, pre_send_hook, ctx ); - /* Hook called after request is dispatched. Used for handling possible redirections. */ - ne_hook_post_send( ctx->dav_session.ctx, post_send_hook, ctx ); - - /* Proxy support */ - proxystate = configureProxy( ctx, ctx->dav_session.ctx ); - if( proxystate < 0 ) { - DEBUG_WEBDAV("Error: Proxy-Configuration failed."); - } else if( proxystate > 0 ) { - ne_set_proxy_auth( ctx->dav_session.ctx, proxy_authentication_callback_by_neon, ctx ); - } - - ctx->_connected = 1; - rc = 0; -out: - SAFE_FREE(path); - SAFE_FREE(host); - SAFE_FREE(scheme); - return rc; -} - - -char *owncloud_error_string(CSYNC* ctx) -{ - return ctx->owncloud_context->dav_session.error_string; -} - -int owncloud_commit(CSYNC* ctx) { - if (!ctx->owncloud_context) { - return 0; - } - - if( ctx->owncloud_context->dav_session.ctx ) { - ne_forget_auth(ctx->owncloud_context->dav_session.ctx); - ne_session_destroy(ctx->owncloud_context->dav_session.ctx ); - ctx->owncloud_context->dav_session.ctx = 0; - } - - /* DEBUG_WEBDAV( "********** vio_module_shutdown" ); */ - - ctx->owncloud_context->dav_session.ctx = 0; - - // ne_sock_exit(); - ctx->owncloud_context->_connected = 0; /* triggers dav_connect to go through the whole neon setup */ - - SAFE_FREE( ctx->owncloud_context->dav_session.user ); - SAFE_FREE( ctx->owncloud_context->dav_session.pwd ); - SAFE_FREE( ctx->owncloud_context->dav_session.session_key); - SAFE_FREE( ctx->owncloud_context->dav_session.error_string ); - return 0; -} - -void owncloud_destroy(CSYNC* ctx) -{ - owncloud_commit(ctx); - SAFE_FREE(ctx->owncloud_context); - - if (ctx->clientCerts) { - SAFE_FREE(ctx->clientCerts->certificatePasswd); - SAFE_FREE(ctx->clientCerts->certificatePath); - SAFE_FREE(ctx->clientCerts); - } - ne_sock_exit(); -} - -int owncloud_set_property(CSYNC* ctx, const char *key, void *data) { -#define READ_STRING_PROPERTY(P) \ - if (c_streq(key, #P)) { \ - SAFE_FREE(ctx->owncloud_context->dav_session.P); \ - ctx->owncloud_context->dav_session.P = c_strdup((const char*)data); \ - return 0; \ - } - READ_STRING_PROPERTY(session_key) - READ_STRING_PROPERTY(proxy_type) - READ_STRING_PROPERTY(proxy_host) - READ_STRING_PROPERTY(proxy_user) - READ_STRING_PROPERTY(proxy_pwd) -#undef READ_STRING_PROPERTY - - if (c_streq(key, "proxy_port")) { - ctx->owncloud_context->dav_session.proxy_port = *(int*)(data); - return 0; - } - if (c_streq(key, "read_timeout") || c_streq(key, "timeout")) { - ctx->owncloud_context->dav_session.read_timeout = *(int*)(data); - return 0; - } - if( c_streq(key, "get_dav_session")) { - /* Give the ne_session to the caller */ - *(ne_session**)data = ctx->owncloud_context->dav_session.ctx; - return 0; - } - if( c_streq(key, "redirect_callback")) { - if (data) { - csync_owncloud_redirect_callback_t* cb_wrapper = data; - ctx->owncloud_context->dav_session.redir_callback = *cb_wrapper; - } else { - ctx->owncloud_context->dav_session.redir_callback = NULL; - } - } - if( c_streq(key, "SSLClientCerts")) { - if(ctx->clientCerts != NULL) { - SAFE_FREE(ctx->clientCerts->certificatePasswd); - SAFE_FREE(ctx->clientCerts->certificatePath); - SAFE_FREE(ctx->clientCerts); - ctx->clientCerts = NULL; - } - if (data) { - struct csync_client_certs_s* clientCerts = (struct csync_client_certs_s*) data; - struct csync_client_certs_s* newCerts = c_malloc(sizeof(struct csync_client_certs_s)); - newCerts->certificatePath = c_strdup(clientCerts->certificatePath); - newCerts->certificatePasswd = c_strdup(clientCerts->certificatePasswd); - ctx->clientCerts = newCerts; - } else { - DEBUG_WEBDAV("error: in owncloud_set_property for 'SSLClientCerts'" ); - } - } - - return -1; -} - -void owncloud_init(CSYNC* ctx) { - - ne_sock_init(); - - ctx->owncloud_context = c_malloc( sizeof( struct csync_owncloud_ctx_s )); - ctx->owncloud_context->csync_ctx = ctx; // back reference - -} - -/* vim: set ts=4 sw=4 et cindent: */ - diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_owncloud.h owncloud-client-2.1.1+dfsg/csync/src/csync_owncloud.h --- owncloud-client-1.8.1+dfsg/csync/src/csync_owncloud.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_owncloud.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2011 by Andreas Schneider - * Copyright (c) 2012 by Klaas Freitag - * - * 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 "csync.h" -#include "vio/csync_vio.h" - -// Public API used by csync -int owncloud_commit(CSYNC* ctx); -void owncloud_destroy(CSYNC* ctx); -char *owncloud_error_string(CSYNC* ctx); -int owncloud_set_property(CSYNC* ctx, const char *key, void *data); -void owncloud_init(CSYNC* ctx); - -int dav_connect(CSYNC* ctx, const char *base_url); - -#endif /* CSYNC_OWNCLOUD_H */ diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_owncloud_private.h owncloud-client-2.1.1+dfsg/csync/src/csync_owncloud_private.h --- owncloud-client-1.8.1+dfsg/csync/src/csync_owncloud_private.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_owncloud_private.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2011 by Andreas Schneider - * Copyright (c) 2012 by Klaas Freitag - * - * 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_PRIVATE_H -#define CSYNC_OWNCLOUD_PRIVATE_H - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "config_csync.h" -#ifdef NEON_WITH_LFS /* Switch on LFS in libneon. Never remove the NE_LFS! */ -#define NE_LFS -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "c_rbtree.h" - -#include "c_lib.h" -#include "csync.h" -#include "csync_misc.h" -#include "csync_macros.h" -#include "c_private.h" - -#include "vio/csync_vio.h" - -#include "csync_log.h" - -#include "csync_owncloud.h" - - -#define DEBUG_WEBDAV(...) csync_log( 9, "oc_module", __VA_ARGS__); - -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_owncloud_redirect_callback_t redir_callback; -}; - -struct csync_owncloud_ctx_s { - CSYNC *csync_ctx; - - // For the WebDAV connection - struct dav_session_s dav_session; /* The DAV Session, initialised in dav_connect */ - int _connected; /* flag to indicate if a connection exists, ie. - the dav_session is valid */ -}; - -typedef struct csync_owncloud_ctx_s csync_owncloud_ctx_t; -//typedef csync_owncloud_ctx_t* csync_owncloud_ctx_p; - -void set_errno_from_http_errcode( int err ); -void set_error_message( csync_owncloud_ctx_t *ctx, const char *msg ); -void set_errno_from_neon_errcode(csync_owncloud_ctx_t *ctx, int neon_code ); -int http_result_code_from_session(csync_owncloud_ctx_t *ctx); -void set_errno_from_session(csync_owncloud_ctx_t *ctx); - -time_t oc_httpdate_parse( const char *date ); - -const char* csync_owncloud_get_platform(void); - -char *_cleanPath( const char* uri ); - -#endif // CSYNC_OWNCLOUD_PRIVATE_H diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_owncloud_util.c owncloud-client-2.1.1+dfsg/csync/src/csync_owncloud_util.c --- owncloud-client-1.8.1+dfsg/csync/src/csync_owncloud_util.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_owncloud_util.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2011 by Andreas Schneider - * Copyright (c) 2012 by Klaas Freitag - * - * 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_owncloud_private.h" - -#include "csync_misc.h" - -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; -} - -// as per http://sourceforge.net/p/predef/wiki/OperatingSystems/ -// extend as required -const char* csync_owncloud_get_platform() { -#if defined (_WIN32) - return "Windows"; -#elif defined(__APPLE__) - return "Macintosh"; -#elif defined(__gnu_linux__) - return "Linux"; -#elif defined(__DragonFly__) - /* might also define __FreeBSD__ */ - return "DragonFlyBSD"; -#elif defined(__FreeBSD__) - return "FreeBSD"; -#elif defined(__NetBSD__) - return "NetBSD"; -#elif defined(__OpenBSD__) - return "OpenBSD"; -#elif defined(sun) || defined(__sun) - return "Solaris"; -#else - return "Unknown OS"; -#endif -} diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_private.h owncloud-client-2.1.1+dfsg/csync/src/csync_private.h --- owncloud-client-1.8.1+dfsg/csync/src/csync_private.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_private.h 2016-02-09 15:07:08.000000000 +0000 @@ -77,9 +77,6 @@ typedef struct csync_file_stat_s csync_file_stat_t; -struct csync_owncloud_ctx_s; // csync_owncloud.c - - /** * @brief csync public structure */ @@ -90,10 +87,20 @@ csync_update_callback update_callback; void *update_callback_userdata; + /* hooks for checking the white list (uses the update_callback_userdata) */ + int (*checkSelectiveSyncBlackListHook)(void*, const char*); + int (*checkSelectiveSyncNewFolderHook)(void*, const char*); + + csync_vio_opendir_hook remote_opendir_hook; csync_vio_readdir_hook remote_readdir_hook; csync_vio_closedir_hook remote_closedir_hook; void *vio_userdata; + + /* hook for comparing checksums of files during discovery */ + csync_checksum_hook checksum_hook; + void *checksum_userdata; + } callbacks; c_strlist_t *excludes; @@ -163,11 +170,7 @@ */ bool db_is_empty; - struct csync_owncloud_ctx_s *owncloud_context; - - /* hooks for checking the white list */ - void *checkSelectiveSyncBlackListData; - int (*checkSelectiveSyncBlackListHook)(void*, const char*); + bool ignore_hidden_files; }; @@ -181,19 +184,22 @@ size_t pathlen; /* u64 */ uint64_t inode; /* u64 */ mode_t mode; /* u32 */ - int nlink; /* u32 */ - int type; /* u32 */ - int child_modified;/*bool*/ - int should_update_etag; /*bool */ - int has_ignored_files; /*bool: specify that a directory, or child directory contains ignored files */ + unsigned int type : 4; + unsigned int child_modified : 1; + unsigned int should_update_metadata : 1; /*specify that the etag, or the remote perm or fileid has + changed and need to be updated on the db even for INSTRUCTION_NONE */ + unsigned int has_ignored_files : 1; /* specify that a directory, or child directory contains ignored files */ char *destpath; /* for renames */ const char *etag; - char file_id[FILE_ID_BUF_SIZE+1]; /* the ownCloud file id is fixed width of 21 byte. */ + char file_id[FILE_ID_BUF_SIZE+1]; /* the ownCloud file id is fixed width in ownCloud. */ char *directDownloadUrl; char *directDownloadCookies; char remotePerm[REMOTE_PERM_BUF_SIZE+1]; + const char *checksum; + uint32_t checksumTypeId; + CSYNC_STATUS error_status; enum csync_instructions_e instruction; /* u32 */ diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_reconcile.c owncloud-client-2.1.1+dfsg/csync/src/csync_reconcile.c --- owncloud-client-1.8.1+dfsg/csync/src/csync_reconcile.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_reconcile.c 2016-02-09 15:07:08.000000000 +0000 @@ -181,6 +181,12 @@ if(!other) { cur->instruction = CSYNC_INSTRUCTION_NEW; + if (cur->type == CSYNC_FTW_TYPE_DIR) { + // For new directories we always want to update the etag once + // the directory has been propagated. Otherwise the directory + // could appear locally without being added to the database. + cur->should_update_metadata = true; + } } else if (other->instruction == CSYNC_INSTRUCTION_NONE || cur->type == CSYNC_FTW_TYPE_DIR) { other->instruction = CSYNC_INSTRUCTION_RENAME; @@ -189,7 +195,7 @@ csync_vio_set_file_id( other->file_id, cur->file_id ); } other->inode = cur->inode; - other->should_update_etag = true; + other->should_update_metadata = true; cur->instruction = CSYNC_INSTRUCTION_NONE; } else if (other->instruction == CSYNC_INSTRUCTION_REMOVE) { other->instruction = CSYNC_INSTRUCTION_RENAME; @@ -199,7 +205,7 @@ csync_vio_set_file_id( other->file_id, cur->file_id ); } other->inode = cur->inode; - other->should_update_etag = true; + other->should_update_metadata = true; cur->instruction = CSYNC_INSTRUCTION_NONE; } else if (other->instruction == CSYNC_INSTRUCTION_NEW) { CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "OOOO=> NEW detected in other tree!"); @@ -262,9 +268,9 @@ /* update DB with new etag from remote */ if (ctx->current == LOCAL_REPLICA) { - other->should_update_etag = true; + other->should_update_metadata = true; } else { - cur->should_update_etag = true; + cur->should_update_metadata = true; } } else if(ctx->current == REMOTE_REPLICA) { cur->instruction = CSYNC_INSTRUCTION_CONFLICT; @@ -277,7 +283,13 @@ break; /* file on the other replica has not been modified */ case CSYNC_INSTRUCTION_NONE: - cur->instruction = CSYNC_INSTRUCTION_SYNC; + if (cur->type != other->type) { + // If the type of the entity changed, it's like NEW, but + // needs to delete the other entity first. + cur->instruction = CSYNC_INSTRUCTION_TYPE_CHANGE; + } else { + cur->instruction = CSYNC_INSTRUCTION_SYNC; + } break; case CSYNC_INSTRUCTION_IGNORE: cur->instruction = CSYNC_INSTRUCTION_IGNORE; @@ -292,20 +304,23 @@ //hide instruction NONE messages when log level is set to debug, //only show these messages on log level trace + const char *repo = ctx->current == REMOTE_REPLICA ? "server" : "client"; if(cur->instruction ==CSYNC_INSTRUCTION_NONE) { if(cur->type == CSYNC_FTW_TYPE_DIR) { CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, - "%-20s dir: %s", + "%-20s %s dir: %s", csync_instruction_str(cur->instruction), + repo, cur->path); } else { CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, - "%-20s file: %s", + "%-20s %s file: %s", csync_instruction_str(cur->instruction), + repo, cur->path); } } @@ -314,15 +329,17 @@ if(cur->type == CSYNC_FTW_TYPE_DIR) { CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, - "%-20s dir: %s", + "%-20s %s dir: %s", csync_instruction_str(cur->instruction), + repo, cur->path); } else { CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, - "%-20s file: %s", + "%-20s %s file: %s", csync_instruction_str(cur->instruction), + repo, cur->path); } } diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_rename.cc owncloud-client-2.1.1+dfsg/csync/src/csync_rename.cc --- owncloud-client-1.8.1+dfsg/csync/src/csync_rename.cc 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_rename.cc 2016-02-09 15:07:08.000000000 +0000 @@ -43,6 +43,7 @@ } std::map folder_renamed_to; // map from->to + std::map folder_renamed_from; // map to->from struct renameop { csync_file_stat_t *st; @@ -63,6 +64,7 @@ void csync_rename_record(CSYNC* ctx, const char* from, const char* to) { csync_rename_s::get(ctx)->folder_renamed_to[from] = to; + csync_rename_s::get(ctx)->folder_renamed_from[to] = from; } char* csync_rename_adjust_path(CSYNC* ctx, const char* path) @@ -78,4 +80,18 @@ return c_strdup(path); } +char* csync_rename_adjust_path_source(CSYNC* ctx, const char* path) +{ + csync_rename_s* d = csync_rename_s::get(ctx); + for (std::string p = _parentDir(path); !p.empty(); p = _parentDir(p)) { + std::map< std::string, std::string >::iterator it = d->folder_renamed_from.find(p); + if (it != d->folder_renamed_from.end()) { + std::string rep = it->second + (path + p.length()); + return c_strdup(rep.c_str()); + } + } + return c_strdup(path); +} + + } diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_rename.h owncloud-client-2.1.1+dfsg/csync/src/csync_rename.h --- owncloud-client-1.8.1+dfsg/csync/src/csync_rename.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_rename.h 2016-02-09 15:07:08.000000000 +0000 @@ -26,7 +26,10 @@ extern "C" { #endif +/* Return the final destination path of a given patch in case of renames */ char *csync_rename_adjust_path(CSYNC *ctx, const char *path); +/* Return the source of a given path in case of renames */ +char *csync_rename_adjust_path_source(CSYNC *ctx, const char *path); void csync_rename_destroy(CSYNC *ctx); void csync_rename_record(CSYNC *ctx, const char *from, const char *to); diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_statedb.c owncloud-client-2.1.1+dfsg/csync/src/csync_statedb.c --- owncloud-client-1.8.1+dfsg/csync/src/csync_statedb.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_statedb.c 2016-02-09 15:07:08.000000000 +0000 @@ -39,6 +39,7 @@ #include "csync_statedb.h" #include "csync_util.h" #include "csync_misc.h" +#include "csync_exclude.h" #include "c_string.h" #include "c_jhash.h" @@ -225,6 +226,8 @@ return rc; } +#define METADATA_COLUMNS "phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote, contentChecksum, contentChecksumTypeId" + // This funciton parses a line from the metadata table into the given csync_file_stat // structure which it is also allocating. // Note that this function calls laso sqlite3_step to actually get the info from db and @@ -282,6 +285,14 @@ if(column_count > 12 && sqlite3_column_int64(stmt,12)) { (*st)->size = sqlite3_column_int64(stmt, 12); } + if(column_count > 13) { + (*st)->has_ignored_files = sqlite3_column_int(stmt, 13); + } + if(column_count > 15 && sqlite3_column_int(stmt, 15)) { + (*st)->checksum = c_strdup( (char*) sqlite3_column_text(stmt, 14)); + (*st)->checksumTypeId = sqlite3_column_int(stmt, 15); + } + } } else { if( rc != SQLITE_DONE ) { @@ -303,7 +314,7 @@ } if( ctx->statedb.by_hash_stmt == NULL ) { - const char *hash_query = "SELECT * FROM metadata WHERE phash=?1"; + const char *hash_query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE phash=?1"; SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, hash_query, strlen(hash_query), &ctx->statedb.by_hash_stmt, NULL)); ctx->statedb.lastReturnValue = rc; @@ -346,7 +357,7 @@ } if( ctx->statedb.by_fileid_stmt == NULL ) { - const char *query = "SELECT * FROM metadata WHERE fileid=?1"; + const char *query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE fileid=?1"; SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, query, strlen(query), &ctx->statedb.by_fileid_stmt, NULL)); ctx->statedb.lastReturnValue = rc; @@ -386,7 +397,7 @@ } if( ctx->statedb.by_inode_stmt == NULL ) { - const char *inode_query = "SELECT * FROM metadata WHERE inode=?1"; + const char *inode_query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE inode=?1"; SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, inode_query, strlen(inode_query), &ctx->statedb.by_inode_stmt, NULL)); ctx->statedb.lastReturnValue = rc; @@ -412,37 +423,10 @@ return st; } -/* Get the etag. */ -char *csync_statedb_get_etag( CSYNC *ctx, uint64_t jHash ) { - char *ret = NULL; - csync_file_stat_t *fs = NULL; - - if( !ctx ) { - return NULL; - } - - if( ! csync_get_statedb_exists(ctx)) return ret; - - fs = csync_statedb_get_stat_by_hash(ctx, jHash ); - if( fs ) { - if( fs->etag ) { - ret = c_strdup(fs->etag); - } - csync_file_stat_free(fs); - } - - return ret; -} - -#define BELOW_PATH_QUERY "SELECT phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize FROM metadata WHERE pathlen>? AND path LIKE(?)" - int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) { int rc; sqlite3_stmt *stmt = NULL; int64_t cnt = 0; - char *likepath; - int asp; - int min_path_len; if( !path ) { return -1; @@ -452,7 +436,12 @@ return -1; } - SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, BELOW_PATH_QUERY, -1, &stmt, NULL)); + /* Select the entries for anything that starts with (path+'/') + * In other words, anything that is between path+'/' and path+'0', + * (because '0' follows '/' in ascii) + */ + const char *below_path_query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE path > (?||'/') AND path < (?||'0')"; + SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, below_path_query, -1, &stmt, NULL)); ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_OK ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for below path query."); @@ -463,15 +452,8 @@ return -1; } - asp = asprintf( &likepath, "%s/%%%%", path); - if (asp < 0) { - CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!"); - return -1; - } - - min_path_len = strlen(path); - sqlite3_bind_int(stmt, 1, min_path_len); - sqlite3_bind_text(stmt, 2, likepath, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 1, path, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, path, -1, SQLITE_STATIC); cnt = 0; @@ -481,6 +463,22 @@ rc = _csync_file_stat_from_metadata_table( &st, stmt); if( st ) { + /* Check for exclusion from the tree. + * Note that this is only a safety net in case the ignore list changes + * without a full remote discovery being triggered. */ + CSYNC_EXCLUDE_TYPE excluded = csync_excluded_traversal(ctx->excludes, st->path, st->type); + if (excluded != CSYNC_NOT_EXCLUDED) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", st->path, excluded); + + if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE + || excluded == CSYNC_FILE_SILENTLY_EXCLUDED) { + SAFE_FREE(st); + continue; + } + + st->instruction = CSYNC_INSTRUCTION_IGNORE; + } + /* store into result list. */ if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) { SAFE_FREE(st); @@ -498,7 +496,6 @@ CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "%" PRId64 " entries read below path %s from db.", cnt, path); } sqlite3_finalize(stmt); - SAFE_FREE(likepath); return 0; } diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_update.c owncloud-client-2.1.1+dfsg/csync/src/csync_update.c --- owncloud-client-1.8.1+dfsg/csync/src/csync_update.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_update.c 2016-02-09 15:07:08.000000000 +0000 @@ -106,6 +106,42 @@ return ctx->statedb.lastReturnValue != SQLITE_OK && ctx->statedb.lastReturnValue != SQLITE_DONE && ctx->statedb.lastReturnValue != SQLITE_ROW; } +/* + * This static method is needed because the type members of the two structs use + * different enum values. A direct comparion is not neccessarily correct. + * + * tmp is csync_file_stat_t + * fs is csync_vio_file_stat_t with this vio type: + * enum csync_vio_file_type_e { + * CSYNC_VIO_FILE_TYPE_UNKNOWN, + * CSYNC_VIO_FILE_TYPE_REGULAR, + * CSYNC_VIO_FILE_TYPE_DIRECTORY, + * CSYNC_VIO_FILE_TYPE_FIFO, + * CSYNC_VIO_FILE_TYPE_SOCKET, + * CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE, + * CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE, + * CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK + * }; + * + * csync_file_stat_t can be: + * CSYNC_FTW_TYPE_SKIP, CSYNC_FTW_TYPE_FILE + * CSYNC_FTW_TYPE_DIR, CSYNC_FTW_TYPE_SLINK + */ +static bool _csync_filetype_different( const csync_file_stat_t *tmp, const csync_vio_file_stat_t *fs) +{ + if( !(tmp && fs)) return false; + + if( tmp->type == CSYNC_FTW_TYPE_SKIP ) return true; + + if( tmp->type == CSYNC_FTW_TYPE_DIR && fs->type != CSYNC_VIO_FILE_TYPE_DIRECTORY ) + return true; + if( tmp->type == CSYNC_FTW_TYPE_FILE && fs->type != CSYNC_VIO_FILE_TYPE_REGULAR ) + return true; + if( tmp->type == CSYNC_FTW_TYPE_SLINK && fs->type != CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK ) + return true; + + return false; // both are NOT different. +} /* Return true if two mtime are considered equal * We consider mtime that are one hour difference to be equal if they are one hour appart @@ -163,33 +199,35 @@ len = strlen(path); - /* This code should probably be in csync_exclude, but it does not have the fs parameter. - Keep it here for now and TODO also find out if we want this for Windows - https://github.com/owncloud/mirall/issues/2086 */ - if (fs->flags & CSYNC_VIO_FILE_FLAGS_HIDDEN) { - CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file excluded because it is a hidden file: %s", path); - return 0; - } - - /* Check if file is excluded */ - excluded = csync_excluded(ctx, path,type); - - if (excluded != CSYNC_NOT_EXCLUDED) { - CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", path, excluded); - if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) { - return 1; - } - if (excluded == CSYNC_FILE_SILENTLY_EXCLUDED) { - return 1; - } - - if (ctx->current_fs) { - ctx->current_fs->has_ignored_files = true; - } + if (type == CSYNC_FTW_TYPE_SKIP) { + excluded =CSYNC_FILE_EXCLUDE_STAT_FAILED; + } else { + /* Check if file is excluded */ + excluded = csync_excluded_traversal(ctx->excludes, path, type); + } + + if( excluded == CSYNC_NOT_EXCLUDED ) { + /* Even if it is not excluded by a pattern, maybe it is to be ignored + * because it's a hidden file that should not be synced. + * This code should probably be in csync_exclude, but it does not have the fs parameter. + * Keep it here for now */ + if (ctx->ignore_hidden_files && (fs->flags & CSYNC_VIO_FILE_FLAGS_HIDDEN)) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file excluded because it is a hidden file: %s", path); + excluded = CSYNC_FILE_EXCLUDE_HIDDEN; + } + } else { + /* File is ignored because it's matched by a user- or system exclude pattern. */ + CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", path, excluded); + if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) { + return 1; + } + if (excluded == CSYNC_FILE_SILENTLY_EXCLUDED) { + return 1; + } } - if (ctx->current == REMOTE_REPLICA && ctx->checkSelectiveSyncBlackListHook) { - if (ctx->checkSelectiveSyncBlackListHook(ctx->checkSelectiveSyncBlackListData, path)) { + if (ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncBlackListHook) { + if (ctx->callbacks.checkSelectiveSyncBlackListHook(ctx->callbacks.update_callback_userdata, path)) { return 1; } } @@ -208,20 +246,16 @@ st->child_modified = 0; st->has_ignored_files = 0; - /* check hardlink count */ + /* FIXME: Under which conditions are the following two ifs true and the code + * is executed? */ if (type == CSYNC_FTW_TYPE_FILE ) { - if( fs->nlink > 1) { - st->instruction = CSYNC_INSTRUCTION_IGNORE; - st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_HARDLINK; - goto out; - } - if (fs->mtime == 0) { CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - mtime is zero!", path); tmp = csync_statedb_get_stat_by_hash(ctx, h); if(_last_db_return_error(ctx)) { SAFE_FREE(st); + SAFE_FREE(tmp); ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL; return -1; } @@ -241,17 +275,13 @@ } } - /* Ignore non statable files and other strange cases. */ - if (type == CSYNC_FTW_TYPE_SKIP) { - st->instruction = CSYNC_INSTRUCTION_NONE; - goto out; - } if (excluded > CSYNC_NOT_EXCLUDED || type == CSYNC_FTW_TYPE_SLINK) { - if( type == CSYNC_FTW_TYPE_SLINK ) { - st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK; /* Symbolic links are ignored. */ - } st->instruction = CSYNC_INSTRUCTION_IGNORE; - goto out; + if (ctx->current_fs) { + ctx->current_fs->has_ignored_files = true; + } + + goto out; } /* Update detection: Check if a database entry exists. @@ -272,33 +302,48 @@ /* we have an update! */ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Database entry found, compare: %" PRId64 " <-> %" PRId64 ", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64 - ", size: %" PRId64 " <-> %" PRId64 ", perms: %s <-> %s", + ", size: %" PRId64 " <-> %" PRId64 ", perms: %s <-> %s, ignore: %d", ((int64_t) fs->mtime), ((int64_t) tmp->modtime), fs->etag, tmp->etag, (uint64_t) fs->inode, (uint64_t) tmp->inode, - (uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm, tmp->remotePerm ); - if( !fs->etag) { + (uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm, tmp->remotePerm, tmp->has_ignored_files ); + if (ctx->current == REMOTE_REPLICA && !c_streq(fs->etag, tmp->etag)) { st->instruction = CSYNC_INSTRUCTION_EVAL; + + // Preserve the EVAL flag later on if the type has changed. + if (_csync_filetype_different(tmp, fs)) { + st->child_modified = 1; + } + goto out; } - if((ctx->current == REMOTE_REPLICA && !c_streq(fs->etag, tmp->etag )) - || (ctx->current == LOCAL_REPLICA && (!_csync_mtime_equal(fs->mtime, tmp->modtime) - // zero size in statedb can happen during migration - || (tmp->size != 0 && fs->size != tmp->size) -#if 0 - || fs->inode != tmp->inode -#endif - ))) { - /* Comparison of the local inode is disabled because people reported problems - * on windows with flacky inode values, see github bug #779 - * - * The inode needs to be observed because: - * $> echo a > a.txt ; echo b > b.txt - * both files have the same mtime - * sync them. - * $> rm a.txt && mv b.txt a.txt - * makes b.txt appearing as a.txt yet a sync is not performed because - * both have the same modtime as mv does not change that. - */ + if (ctx->current == LOCAL_REPLICA && + (!_csync_mtime_equal(fs->mtime, tmp->modtime) + // zero size in statedb can happen during migration + || (tmp->size != 0 && fs->size != tmp->size))) { + + if (fs->size == tmp->size && tmp->checksumTypeId) { + if (ctx->callbacks.checksum_hook) { + st->checksum = ctx->callbacks.checksum_hook( + file, tmp->checksumTypeId, + ctx->callbacks.checksum_userdata); + } + bool checksumIdentical = false; + if (st->checksum) { + st->checksumTypeId = tmp->checksumTypeId; + checksumIdentical = strncmp(st->checksum, tmp->checksum, 1000) == 0; + } + if (checksumIdentical) { + st->instruction = CSYNC_INSTRUCTION_NONE; + st->should_update_metadata = true; + goto out; + } + } + + // Preserve the EVAL flag later on if the type has changed. + if (_csync_filetype_different(tmp, fs)) { + st->child_modified = 1; + } + st->instruction = CSYNC_INSTRUCTION_EVAL; goto out; } @@ -318,7 +363,13 @@ if (metadata_differ) { /* file id or permissions has changed. Which means we need to update them in the DB. */ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Need to update metadata for: %s", path); - st->should_update_etag = true; + st->should_update_metadata = true; + } + /* If it was remembered in the db that the remote dir has ignored files, store + * that so that the reconciler can make advantage of. + */ + if( ctx->current == REMOTE_REPLICA ) { + st->has_ignored_files = tmp->has_ignored_files; } st->instruction = CSYNC_INSTRUCTION_NONE; } else { @@ -340,10 +391,12 @@ } /* translate the file type between the two stat types csync has. */ - if( tmp && tmp->type == 0 ) { + if( tmp && tmp->type == CSYNC_FTW_TYPE_FILE ) { tmp_vio_type = CSYNC_VIO_FILE_TYPE_REGULAR; - } else if( tmp && tmp->type == 2 ) { + } else if( tmp && tmp->type == CSYNC_FTW_TYPE_DIR) { tmp_vio_type = CSYNC_VIO_FILE_TYPE_DIRECTORY; + } else if( tmp && tmp->type == CSYNC_FTW_TYPE_SLINK ) { + tmp_vio_type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; } else { tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN; } @@ -376,8 +429,7 @@ return -1; } if(tmp ) { /* tmp existing at all */ - if ((tmp->type == CSYNC_FTW_TYPE_DIR && fs->type != CSYNC_VIO_FILE_TYPE_DIRECTORY) || - (tmp->type == CSYNC_FTW_TYPE_FILE && fs->type != CSYNC_VIO_FILE_TYPE_REGULAR)) { + if ( _csync_filetype_different(tmp, fs)) { CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "WARN: file types different is not!"); st->instruction = CSYNC_INSTRUCTION_NEW; goto out; @@ -398,12 +450,20 @@ } else { /* file not found in statedb */ st->instruction = CSYNC_INSTRUCTION_NEW; + + if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) { + if (ctx->callbacks.checkSelectiveSyncNewFolderHook(ctx->callbacks.update_callback_userdata, path)) { + SAFE_FREE(st); + return 1; + } + } goto out; } } } } else { CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Unable to open statedb" ); + SAFE_FREE(st); ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL; return -1; } @@ -412,13 +472,21 @@ /* Set the ignored error string. */ if (st->instruction == CSYNC_INSTRUCTION_IGNORE) { - if (excluded == CSYNC_FILE_EXCLUDE_LIST) { - st->error_status = CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST; /* File listed on ignore list. */ - } else if (excluded == CSYNC_FILE_EXCLUDE_INVALID_CHAR) { - st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS; /* File contains invalid characters. */ - } else if (excluded == CSYNC_FILE_EXCLUDE_LONG_FILENAME) { - st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME; /* File name is too long. */ - } + if( type == CSYNC_FTW_TYPE_SLINK ) { + st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK; /* Symbolic links are ignored. */ + } else { + if (excluded == CSYNC_FILE_EXCLUDE_LIST) { + st->error_status = CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST; /* File listed on ignore list. */ + } else if (excluded == CSYNC_FILE_EXCLUDE_INVALID_CHAR) { + st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS; /* File contains invalid characters. */ + } else if (excluded == CSYNC_FILE_EXCLUDE_LONG_FILENAME) { + st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME; /* File name is too long. */ + } else if (excluded == CSYNC_FILE_EXCLUDE_HIDDEN ) { + st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN; + } else if (excluded == CSYNC_FILE_EXCLUDE_STAT_FAILED) { + st->error_status = CSYNC_STATUS_INDIVIDUAL_STAT_FAILED; + } + } } if (st->instruction != CSYNC_INSTRUCTION_NONE && st->instruction != CSYNC_INSTRUCTION_IGNORE && type != CSYNC_FTW_TYPE_DIR) { @@ -431,7 +499,6 @@ st->mode = fs->mode; st->size = fs->size; st->modtime = fs->mtime; - st->nlink = fs->nlink; st->type = type; st->etag = NULL; if( fs->etag ) { @@ -562,6 +629,26 @@ return true; } +/* set the current item to an ignored state. + * If the item is set to ignored, the update phase continues, ie. its not a hard error */ +static bool mark_current_item_ignored( CSYNC *ctx, csync_file_stat_t *previous_fs, CSYNC_STATUS status ) +{ + if(!ctx) { + return false; + } + + if (ctx->current_fs) { + ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE; + ctx->current_fs->error_status = status; + /* If a directory has ignored files, put the flag on the parent directory as well */ + if( previous_fs ) { + previous_fs->has_ignored_files = true; + } + return true; + } + return false; +} + /* File tree walker */ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn, unsigned int depth) { @@ -569,7 +656,6 @@ char *d_name = NULL; csync_vio_handle_t *dh = NULL; csync_vio_file_stat_t *dirent = NULL; - csync_vio_file_stat_t *fs = NULL; csync_file_stat_t *previous_fs = NULL; int read_from_db = 0; int rc = 0; @@ -615,23 +701,35 @@ /* permission denied */ ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_OPENDIR_ERROR); if (errno == EACCES) { - return 0; + CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Permission denied."); + if (mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_PERMISSION_DENIED)) { + goto done; + } } else if(errno == ENOENT) { asp = asprintf( &ctx->error_string, "%s", uri); if (asp < 0) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!"); } - } else if(errno == ERRNO_STORAGE_UNAVAILABLE) { + } + // 403 Forbidden can be sent by the server if the file firewall is active. + // A file or directory should be ignored and sync must continue. See #3490 + else if(errno == ERRNO_FORBIDDEN) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Directory access Forbidden (File Firewall?)"); + if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_FORBIDDEN) ) { + goto done; + } + /* if current_fs is not defined here, better throw an error */ + } + // The server usually replies with the custom "503 Storage not available" + // if some path is temporarily unavailable. But in some cases a standard 503 + // is returned too. Thus we can't distinguish the two and will treat any + // 503 as request to ignore the folder. See #3113 #2884. + else if(errno == ERRNO_STORAGE_UNAVAILABLE || errno == ERRNO_SERVICE_UNAVAILABLE) { CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Storage was not available!"); - if (ctx->current_fs) { - ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE; - ctx->current_fs->error_status = CSYNC_STATUS_STORAGE_UNAVAILABLE; - /* If a directory has ignored files, put the flag on the parent directory as well */ - if( previous_fs ) { - previous_fs->has_ignored_files = true; - } + if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_STORAGE_UNAVAILABLE ) ) { goto done; } + /* if current_fs is not defined here, better throw an error */ } else { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "opendir failed for %s - errno %d", uri, errno); } @@ -644,6 +742,14 @@ int flen; int flag; + /* Conversion error */ + if (dirent->name == NULL && dirent->original_name) { + ctx->status_code = CSYNC_STATUS_INVALID_CHARACTERS; + ctx->error_string = dirent->original_name; // take ownership + dirent->original_name = NULL; + goto error; + } + d_name = dirent->name; if (d_name == NULL) { ctx->status_code = CSYNC_STATUS_READDIR_ERROR; @@ -651,8 +757,8 @@ } /* skip "." and ".." */ - if (d_name[0] == '.' && (d_name[1] == '\0' - || (d_name[1] == '.' && d_name[2] == '\0'))) { + if ( (d_name[0] == '.' && d_name[1] == '\0') + || (d_name[0] == '.' && d_name[1] == '.' && d_name[2] == '\0')) { csync_vio_file_stat_destroy(dirent); dirent = NULL; continue; @@ -704,15 +810,23 @@ /* Only for the local replica we have to stat(), for the remote one we have all data already */ if (ctx->replica == LOCAL_REPLICA) { - fs = csync_vio_file_stat_new(); - res = csync_vio_stat(ctx, filename, fs); + res = csync_vio_stat(ctx, filename, dirent); } else { - fs = dirent; res = 0; } + /* if the filename starts with a . we consider it a hidden file + * For windows, the hidden state is also discovered within the vio + * local stat function. + */ + if( d_name[0] == '.' ) { + if (strcmp(".sys.admin#recall#", d_name) != 0) { /* recall file shall not be ignored (#4420) */ + dirent->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN; + } + } + if( res == 0) { - switch (fs->type) { + switch (dirent->type) { case CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK: flag = CSYNC_FTW_FLAG_SLINK; break; @@ -735,41 +849,12 @@ flag = CSYNC_FTW_FLAG_NSTAT; } - if( ctx->current == LOCAL_REPLICA ) { - char *etag = NULL; - int len = strlen( path ); - uint64_t h = c_jhash64((uint8_t *) path, len, 0); - etag = csync_statedb_get_etag( ctx, h ); - - if(_last_db_return_error(ctx)) { - ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL; - goto error; - } - - if( etag ) { - SAFE_FREE(fs->etag); - fs->etag = etag; - fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG; - - if( c_streq(etag, "")) { - CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Uniq ID from Database is EMPTY: %s", path); - } else { - CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Uniq ID from Database: %s -> %s", path, fs->etag ? fs->etag : "" ); - } - } - } - previous_fs = ctx->current_fs; /* Call walker function for each file */ - rc = fn(ctx, filename, fs, flag); + rc = fn(ctx, filename, dirent, flag); /* this function may update ctx->current and ctx->read_from_db */ - /* Only for the local replica we have to destroy stat(), for the remote one it is a pointer to dirent */ - if (ctx->replica == LOCAL_REPLICA) { - csync_vio_file_stat_destroy(fs); - } - if (rc < 0) { if (CSYNC_STATUS_IS_OK(ctx->status_code)) { ctx->status_code = CSYNC_STATUS_UPDATE_ERROR; @@ -791,7 +876,7 @@ && ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL) { ctx->current_fs->instruction = CSYNC_INSTRUCTION_NONE; if (ctx->current == REMOTE_REPLICA) { - ctx->current_fs->should_update_etag = true; + ctx->current_fs->should_update_metadata = true; } } @@ -809,7 +894,7 @@ if (flag == CSYNC_FTW_FLAG_DIR && ctx->current_fs && (ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL || ctx->current_fs->instruction == CSYNC_INSTRUCTION_NEW)) { - ctx->current_fs->should_update_etag = true; + ctx->current_fs->should_update_metadata = true; } ctx->current_fs = previous_fs; diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_util.c owncloud-client-2.1.1+dfsg/csync/src/csync_util.c --- owncloud-client-1.8.1+dfsg/csync/src/csync_util.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_util.c 2016-02-09 15:07:08.000000000 +0000 @@ -55,6 +55,7 @@ { "INSTRUCTION_SYNC", CSYNC_INSTRUCTION_SYNC }, { "INSTRUCTION_STAT_ERR", CSYNC_INSTRUCTION_STAT_ERROR }, { "INSTRUCTION_ERROR", CSYNC_INSTRUCTION_ERROR }, + { "INSTRUCTION_TYPE_CHANGE", CSYNC_INSTRUCTION_TYPE_CHANGE }, { NULL, CSYNC_INSTRUCTION_ERROR } }; @@ -104,30 +105,6 @@ m.size * 4, m.resident * 4, m.shared * 4); } -void csync_win32_set_file_hidden( const char *file, bool h ) { -#ifdef _WIN32 - const mbchar_t *fileName; - DWORD dwAttrs; - if( !file ) return; - - fileName = c_utf8_to_locale( file ); - dwAttrs = GetFileAttributesW(fileName); - - if (dwAttrs != INVALID_FILE_ATTRIBUTES) { - if (h && !(dwAttrs & FILE_ATTRIBUTE_HIDDEN)) { - SetFileAttributesW(fileName, dwAttrs | FILE_ATTRIBUTE_HIDDEN ); - } else if (!h && (dwAttrs & FILE_ATTRIBUTE_HIDDEN)) { - SetFileAttributesW(fileName, dwAttrs & ~FILE_ATTRIBUTE_HIDDEN ); - } - } - - c_free_locale_string(fileName); -#else - (void) h; - (void) file; -#endif -} - bool (*csync_file_locked_or_open_ext) (const char*) = 0; // filled in by library user void set_csync_file_locked_or_open_ext(bool (*f) (const char*)); void set_csync_file_locked_or_open_ext(bool (*f) (const char*)) { diff -Nru owncloud-client-1.8.1+dfsg/csync/src/csync_util.h owncloud-client-2.1.1+dfsg/csync/src/csync_util.h --- owncloud-client-1.8.1+dfsg/csync/src/csync_util.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/csync_util.h 2016-02-09 15:07:08.000000000 +0000 @@ -30,7 +30,5 @@ void csync_memstat_check(void); -void csync_win32_set_file_hidden( const char *file, bool hidden ); - bool csync_file_locked_or_open( const char *dir, const char *fname); #endif /* _CSYNC_UTIL_H */ diff -Nru owncloud-client-1.8.1+dfsg/csync/src/httpbf/client/CMakeLists.txt owncloud-client-2.1.1+dfsg/csync/src/httpbf/client/CMakeLists.txt --- owncloud-client-1.8.1+dfsg/csync/src/httpbf/client/CMakeLists.txt 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/httpbf/client/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -project(client C) - -set(CLIENT_EXECUTABLE httpbfclient CACHE INTERNAL "httpbf client") - -set(CLIENT_LINK_LIBRARIES ${NEON_LIBRARIES} ${HBF_LIBRARY}) - -set(HTTPBF_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/src}) - -if(NOT LINUX) - list(APPEND CLIENT_LINK_LIBRARIES ${ARGP_LIBRARIES}) -endif() - -set(client_SRCS - httpbf_client.c -) - -include_directories( - ${HTTPBF_INCLUDE_DIR} - ${HTTPBF_PUBLIC_INCLUDE_DIRS} -) - -add_executable(${CLIENT_EXECUTABLE} ${client_SRCS}) - -target_link_libraries(${CLIENT_EXECUTABLE} ${CLIENT_LINK_LIBRARIES}) - -set_target_properties( - ${CLIENT_EXECUTABLE} - PROPERTIES - OUTPUT_NAME - httpbf -) - -# install( TARGETS ${CLIENT_EXECUTABLE} DESTINATION ${BIN_INSTALL_DIR} ) -install(TARGETS ${CLIENT_EXECUTABLE} DESTINATION bin) - - diff -Nru owncloud-client-1.8.1+dfsg/csync/src/httpbf/client/httpbf_client.c owncloud-client-2.1.1+dfsg/csync/src/httpbf/client/httpbf_client.c --- owncloud-client-1.8.1+dfsg/csync/src/httpbf/client/httpbf_client.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/httpbf/client/httpbf_client.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,225 +0,0 @@ -/* - * httpbf - send big files via http - * - * Copyright (c) 2012 Klaas Freitag - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "httpbf.h" - -/* Program documentation. */ -static char doc[] = "Usage: httpbf [OPTION...] LOCAL REMOTEDIR\n\ -httpbf - command line client to upload big files via http.\n\ -\n\ -Transfer a big file to a remote directory on ownCloud.\n\ -\n\ --?, --help Give this help list\n\ - --usage Give a short usage message\n\ --V, --version Print program version\n\ -"; - -static char _user[NE_ABUFSIZ]; -static char _pwd[NE_ABUFSIZ]; - -/* The options we understand. */ -static const struct option long_options[] = -{ - {"version", no_argument, 0, 'V' }, - {"usage", no_argument, 0, 'h' }, - {0, 0, 0, 0} -}; - -static const char* httpbf_version = "0.1"; - -static void print_version() -{ - printf( "%s\n", httpbf_version ); - exit(0); -} - -static void print_help() -{ - printf( "%s\n", doc ); - exit(0); -} - -static int ne_auth( void *userdata, const char *realm, int attempt, - char *username, char *password) -{ - (void) userdata; - (void) realm; - - if( username && password ) { - if( _user ) { - /* allow user without password */ - if( strlen( _user ) < NE_ABUFSIZ ) { - strcpy( username, _user ); - } - if( _pwd && strlen( _pwd ) < NE_ABUFSIZ ) { - strcpy( password, _pwd ); - } - } - } - return attempt; -} - - -static int parse_args(int argc, char **argv) -{ - while(optind < argc) { - int c = -1; - struct option *opt = NULL; - int result = getopt_long( argc, argv, "Vh", long_options, &c ); - - if( result == -1 ) { - break; - } - - switch(result) { - case 'V': - print_version(); - break; - case 'h': - print_help(); - break; - case 0: - opt = (struct option*)&(long_options[c]); - if(strcmp(opt->name, "no-name-yet")) { - - } else { - fprintf(stderr, "Argument: No idea what!\n"); - } - break; - default: - break; - } - } - return optind; -} - -static ne_session* create_neon_session( const char *url ) -{ - ne_uri uri; - ne_session *sess = NULL; - - memset( _user, 0, NE_ABUFSIZ ); - memset( _pwd, 0, NE_ABUFSIZ ); - - if( ne_uri_parse( url, &uri ) == 0 ) { - unsigned int port = ne_uri_defaultport(uri.scheme); - if( uri.userinfo ) { - char *slash = NULL; - strcpy( _user, uri.userinfo ); - slash = strchr( _user, ':'); - if( slash ) { - strcpy( _pwd, slash+1); - *slash = 0; - } - } - sess = ne_session_create(uri.scheme, uri.host, port); - ne_set_server_auth(sess, ne_auth, 0 ); - - ne_uri_free(&uri); - } - return sess; -} - -static int open_local_file( const char *file ) -{ - int fd = -1; - - if( !file ) return -1; - - fd = open(file, O_RDONLY); - return fd; -} - -static void transfer( const char* local, const char* uri ) -{ - if( !(local && uri )) return; - char *whole_url; - int len; - char *filename = basename(local); - if( ! filename ) { - return; - } - - len = strlen(filename)+strlen(uri)+2; - whole_url = malloc( len ); - strcpy(whole_url, uri); - strcat(whole_url, "/"); - strcat(whole_url, filename); - - hbf_transfer_t *trans = hbf_init_transfer( whole_url ); - Hbf_State state; - - if( trans ) { - ne_session *session = create_neon_session(uri); - if( session ) { - int fd = open_local_file( local ); - if( fd > -1 ) { - state = hbf_splitlist(trans, fd ); - if( state == HBF_SUCCESS ) { - state = hbf_transfer( session, trans, "PUT" ); - } - } - ne_session_destroy(session); - } - } - - if( state != HBF_SUCCESS ) { - printf("Upload failed: %s\n", hbf_error_string(state)); - printf(" HTTP result %d, Server Error: %s\n", - trans->status_code, trans->error_string ? trans->error_string : "" ); - } - /* Print the result of the recent transfer */ - hbf_free_transfer( trans ); - free(whole_url); -} - -int main(int argc, char **argv) { - int rc = 0; - char errbuf[256] = {0}; - - parse_args(argc, argv); - /* two options must remain as source and target */ - /* printf("ARGC: %d -> optind: %d\n", argc, optind ); */ - if( argc - optind < 2 ) { - print_help(); - } - - transfer( argv[optind], argv[optind+1]); - -} - -/* vim: set ts=8 sw=2 et cindent: */ diff -Nru owncloud-client-1.8.1+dfsg/csync/src/httpbf/CMakeLists.txt owncloud-client-2.1.1+dfsg/csync/src/httpbf/CMakeLists.txt --- owncloud-client-1.8.1+dfsg/csync/src/httpbf/CMakeLists.txt 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/httpbf/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -project(httpbflib C) - -find_package(Neon) - - -set(HTTPBF_PUBLIC_INCLUDE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR}/src - ${NEON_INCLUDE_DIRS} - CACHE INTERNAL "httpbflib public include directories" -) - -set(HTTPBF_LIBRARY - httpbf - CACHE INTERNAL "httpbf library" -) - -set(HTTPBF_LINK_LIBRARIES - ${HTTPBF_LIBRARY} -) - -set(httpbf_SRCS - src/httpbf.c -) -set(httpbf_HEADERS - src/httpbf.h -) - -include_directories( - ${HTTPBF_PUBLIC_INCLUDE_DIRS} -) - -add_library(${HTTPBF_LIBRARY} STATIC ${httpbf_SRCS}) -target_link_libraries(${HTTPBF_LIBRARY} ${NEON_LIBRARIES}) - -if(NOT WIN32) - add_definitions( -fPIC ) -endif() - -INSTALL( - TARGETS - ${HTTPBF_LIBRARY} - LIBRARY DESTINATION - ${LIB_INSTALL_DIR} - ARCHIVE DESTINATION - ${LIB_INSTALL_DIR} - RUNTIME DESTINATION - ${BIN_INSTALL_DIR} -) - -if (NOT APPLE) - INSTALL( - FILES - ${httpbf_HEADERS} - DESTINATION - ${CMAKE_INSTALL_INCLUDEDIR} - ) -endif (NOT APPLE) diff -Nru owncloud-client-1.8.1+dfsg/csync/src/httpbf/README owncloud-client-2.1.1+dfsg/csync/src/httpbf/README --- owncloud-client-1.8.1+dfsg/csync/src/httpbf/README 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/httpbf/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -This is a little code that does ownCloud file chunking. - -Basically to put a local file to an url: -(Also see the client example code in client dir.) - -/* Initialize the transfer, get a transfer struct. */ -hbf_transfer_t *trans = hbf_init_transfer( url ); - -Hbf_State state; -if( trans ) { - int fd = open_local_file( file ); - - /* create a neon session to use for the transfer */ - ne_session *session = create_neon_session(uri); - - if( session && fd > -1 ) { - /* Prepare the list of chunks, ie. calculate chunks and write back to trans. */ - state = hbf_splitlist(trans, fd); - - if( state == HBF_SUCCESS ) { - /* Transfer all the chunks through the HTTP session using PUT. */ - state = hbf_transfer( session, trans, "PUT" ); - } - } -} - -GET a large file: -Do GET Range requests. - diff -Nru owncloud-client-1.8.1+dfsg/csync/src/httpbf/src/CMakeLists.txt owncloud-client-2.1.1+dfsg/csync/src/httpbf/src/CMakeLists.txt --- owncloud-client-1.8.1+dfsg/csync/src/httpbf/src/CMakeLists.txt 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/httpbf/src/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -project(httpbf C) - -# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked - -set(HTTPBF_PUBLIC_INCLUDE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR} - CACHE INTERNAL "httpbf public include directories" -) - -set(HTTPBFLIB_PRIVATE_INCLUDE_DIRS -) - -set(HBF_LIBRARY - httpbf - CACHE INTERNAL "httpbflib library" -) - -set(HTTPBFLIB_LINK_LIBRARIES - ${HBF_LIBRARY} -) - -set(httpbflib_SRCS - httpbf.c -) - -include_directories( - ${NEON_INCLUDE_DIRS} - ${GLIB2_INCLUDE_DIRS} -) - -if(NOT WIN32) - add_definitions( -fPIC ) -endif() - -add_library(${HBF_LIBRARY} SHARED ${httpbflib_SRCS} ) - -target_link_libraries(${HBF_LIBRARY} ${NEON_LIBRARIES}) - diff -Nru owncloud-client-1.8.1+dfsg/csync/src/httpbf/src/httpbf.c owncloud-client-2.1.1+dfsg/csync/src/httpbf/src/httpbf.c --- owncloud-client-1.8.1+dfsg/csync/src/httpbf/src/httpbf.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/httpbf/src/httpbf.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,688 +0,0 @@ -/* - * httpbf - send big files via http - * - * Copyright (c) 2012 Klaas Freitag - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "httpbf.h" - -#include -#include -#include - -// #ifdef NDEBUG -// #define DEBUG_HBF(...) -// #else -#define DEBUG_HBF(...) { if(transfer->log_cb) { \ - char buf[1024]; \ - snprintf(buf, 1024, __VA_ARGS__); \ - transfer->log_cb(__FUNCTION__, buf, transfer->user_data); \ - } } - -// #endif - -#define DEFAULT_BLOCK_SIZE (10*1024*1024) - -/* Platform specific defines go here. */ -#ifdef _WIN32 -#define _hbf_fstat _fstat64 -typedef struct stat64 hbf_stat_t; -#else -#define _hbf_fstat fstat -typedef struct stat hbf_stat_t; -#endif - -static int transfer_id( hbf_stat_t *sb ) { - struct timeval tp; - int res; - int r; - - if( gettimeofday(&tp, 0) < 0 ) { - return 0; - } - - /* build a Unique ID: - * take the current epoch and shift 8 bits up to keep the least bits. - * than add the milliseconds, again shift by 8 - * and finally add the least 8 bit of the inode of the file. - */ - res = tp.tv_sec; /* epoche value in seconds */ - res = res << 8; - r = (sb->st_ino & 0xFF); - res += r; /* least six bit of inode */ - res = res << sizeof(tp.tv_usec); - res += tp.tv_usec; /* milliseconds */ - - return res; -} - -hbf_transfer_t *hbf_init_transfer( const char *dest_uri ) { - hbf_transfer_t * transfer = NULL; - - transfer = malloc( sizeof(hbf_transfer_t) ); - memset(transfer, 0, sizeof(hbf_transfer_t)); - - /* store the target uri */ - transfer->url = strdup(dest_uri); - transfer->status_code = 200; - transfer->error_string = NULL; - transfer->start_id = 0; - transfer->block_size = DEFAULT_BLOCK_SIZE; - transfer->threshold = transfer->block_size; - transfer->modtime_accepted = 0; - transfer->oc_header_modtime = 0; - - return transfer; -} - -/* Create the splitlist of a given file descriptor */ -Hbf_State hbf_splitlist(hbf_transfer_t *transfer, int fd ) { - hbf_stat_t sb; - int64_t num_blocks; - int64_t blk_size; - int64_t remainder = 0; - - if( ! transfer ) { - return HBF_PARAM_FAIL; - } - - if( fd <= 0 ) { - DEBUG_HBF("File descriptor is invalid."); - return HBF_PARAM_FAIL; - } - - if( _hbf_fstat(fd, &sb) < 0 ) { - DEBUG_HBF("Failed to stat the file descriptor: errno = %d", errno); - return HBF_FILESTAT_FAIL; - } - - /* Store the file characteristics. */ - transfer->fd = fd; - transfer->stat_size = sb.st_size; - transfer->modtime = sb.st_mtime; - transfer->previous_etag = NULL; -#ifndef NDEBUG - transfer->calc_size = 0; -#endif - - DEBUG_HBF("block_size: %" PRId64 " threshold: %" PRId64 " st_size: %" PRId64, transfer->block_size, transfer->threshold, sb.st_size ); - - - /* calc the number of blocks to split in */ - blk_size = transfer->block_size; - if (sb.st_size < transfer->threshold) { - blk_size = transfer->threshold; - } - - num_blocks = sb.st_size / blk_size; - - /* there migth be a remainder. */ - remainder = sb.st_size - num_blocks * blk_size; - - /* if there is a remainder, add one block */ - if( remainder > 0 ) { - num_blocks++; - } - - /* The file has size 0. There still needs to be at least one block. */ - if( sb.st_size == 0 ) { - num_blocks = 1; - blk_size = 0; - } - - DEBUG_HBF("num_blocks: %" PRId64 " rmainder: %" PRId64 " blk_size: %" PRId64, num_blocks, remainder, blk_size ); - - - if( num_blocks ) { - int cnt; - int64_t overall = 0; - /* create a datastructure for the transfer data */ - transfer->block_arr = calloc(num_blocks, sizeof(hbf_block_t*)); - transfer->block_cnt = num_blocks; - transfer->transfer_id = transfer_id(&sb); - transfer->start_id = 0; - - for( cnt=0; cnt < num_blocks; cnt++ ) { - /* allocate a block struct and fill */ - hbf_block_t *block = malloc( sizeof(hbf_block_t) ); - memset(block, 0, sizeof(hbf_block_t)); - - block->seq_number = cnt; - if( cnt > 0 ) { - block->start = cnt * blk_size; - } - block->size = blk_size; - block->state = HBF_NOT_TRANSFERED; - - /* consider the remainder if we're already at the end */ - if( cnt == num_blocks-1 && remainder > 0 ) { - block->size = remainder; - } - overall += block->size; - /* store the block data into the result array in the transfer */ - *((transfer->block_arr)+cnt) = block; - - DEBUG_HBF("created block %d (start: %" PRId64 " size: %" PRId64 ")", cnt, block->start, block->size ); - } - -#ifndef NDEBUG - transfer->calc_size = overall; -#endif - } - return HBF_SUCCESS; -} - -void hbf_free_transfer( hbf_transfer_t *transfer ) { - int cnt; - - if( !transfer ) return; - - for( cnt = 0; cnt < transfer->block_cnt; cnt++ ) { - hbf_block_t *block = transfer->block_arr[cnt]; - if( !block ) continue; - if( block->http_error_msg ) free( block->http_error_msg ); - if( block->etag ) free( block->etag ); - } - free( transfer->block_arr ); - free( transfer->url ); - free( transfer->file_id ); - if( transfer->error_string) free( (void*) transfer->error_string ); - - free( transfer ); -} - -static char* get_transfer_url( hbf_transfer_t *transfer, int indx ) { - char *res = NULL; - - hbf_block_t *block = NULL; - - if( ! transfer ) return NULL; - if( indx >= transfer->block_cnt ) return NULL; - - block = transfer->block_arr[indx]; - if( ! block ) return NULL; - - if( transfer->block_cnt == 1 ) { - /* Just one chunk. We send as an ordinary request without chunking. */ - res = strdup( transfer->url ); - } else { - char trans_id_str[32]; - char trans_block_str[32]; - char indx_str[32]; - int len = 1; /* trailing zero. */ - int tlen = 0; - - tlen = sprintf( trans_id_str, "%u", transfer->transfer_id ); - if( tlen < 0 ) { - return NULL; - } - len += tlen; - - tlen = sprintf( trans_block_str, "%u", transfer->block_cnt ); - if( tlen < 0 ) { - return NULL; - } - len += tlen; - - tlen = sprintf( indx_str, "%u", indx ); - if( tlen < 0 ) { - return NULL; - } - len += tlen; - - len += strlen(transfer->url); - len += strlen("-chunking---"); - - res = malloc(len); - - /* Note: must be %u for unsigned because one does not want '--' */ - if( sprintf(res, "%s-chunking-%u-%u-%u", transfer->url, transfer->transfer_id, - transfer->block_cnt, indx ) < 0 ) { - return NULL; - } - } - return res; -} - -/* - * perform one transfer of one block. - * returns HBF_TRANSFER_SUCCESS if the transfer of this block was a success - * returns HBF_SUCCESS if the server aknoweldge that he received all the blocks - */ -static int _hbf_dav_request(hbf_transfer_t *transfer, ne_request *req, int fd, hbf_block_t *blk ) { - Hbf_State state = HBF_TRANSFER_SUCCESS; - int res; - const ne_status *req_status = NULL; - const char *etag = NULL; - - (void) transfer; - - if( ! (blk && req) ) return HBF_PARAM_FAIL; - - ne_set_request_body_fd(req, fd, blk->start, blk->size); - DEBUG_HBF("Block: %d , Start: %" PRId64 " and Size: %" PRId64 "", blk->seq_number, blk->start, blk->size ); - res = ne_request_dispatch(req); - - req_status = ne_get_status( req ); - - switch(res) { - case NE_OK: - blk->state = HBF_TRANSFER_FAILED; - state = HBF_FAIL; - etag = 0; - if( req_status->klass == 2 ) { - state = HBF_TRANSFER_SUCCESS; - blk->state = HBF_TRANSFER_SUCCESS; - etag = ne_get_response_header(req, "ETag"); - if (etag && etag[0]) { - /* When there is an etag, it means the transfer was complete */ - state = HBF_SUCCESS; - - if( etag[0] == '"' && etag[ strlen(etag)-1] == '"') { - int len = strlen( etag )-2; - blk->etag = malloc( len+1 ); - strncpy( blk->etag, etag+1, len ); - blk->etag[len] = '\0'; - } else { - blk->etag = strdup( etag ); - } - } else { - /* DEBUG_HBF("OOOOOOOO No etag returned!"); */ - } - - /* check if the server was able to set the mtime already. */ - etag = ne_get_response_header(req, "X-OC-MTime"); - if( etag && strcmp(etag, "accepted") == 0 ) { - /* the server acknowledged that the mtime was set. */ - transfer->modtime_accepted = 1; - } - - etag = ne_get_response_header(req, "OC-FileID"); - if( etag ) { - transfer->file_id = strdup( etag ); - } - } - break; - case NE_AUTH: - state = HBF_AUTH_FAIL; - blk->state = HBF_TRANSFER_FAILED; - break; - case NE_PROXYAUTH: - state = HBF_PROXY_AUTH_FAIL; - blk->state = HBF_TRANSFER_FAILED; - break; - case NE_CONNECT: - state = HBF_CONNECT_FAIL; - blk->state = HBF_TRANSFER_FAILED; - break; - case NE_TIMEOUT: - state = HBF_TIMEOUT_FAIL; - blk->state = HBF_TRANSFER_FAILED; - break; - case NE_ERROR: - state = HBF_FAIL; - blk->state = HBF_TRANSFER_FAILED; - break; - } - - blk->http_result_code = req_status->code; - if( req_status->reason_phrase ) { - blk->http_error_msg = strdup(req_status->reason_phrase); - } - - return state; -} - -Hbf_State hbf_validate_source_file( hbf_transfer_t *transfer ) { - Hbf_State state = HBF_SUCCESS; - hbf_stat_t sb; - - if( transfer == NULL ) { - state = HBF_PARAM_FAIL; - } - - if( state == HBF_SUCCESS ) { - if( transfer->fd <= 0 ) { - state = HBF_PARAM_FAIL; - } - } - - if( state == HBF_SUCCESS ) { - int rc = _hbf_fstat( transfer->fd, &sb ); - if( rc != 0 ) { - state = HBF_STAT_FAIL; - } - } - - if( state == HBF_SUCCESS ) { - if( sb.st_mtime != transfer->modtime || sb.st_size != transfer->stat_size ) { - state = HBF_SOURCE_FILE_CHANGE; - } - } - return state; -} - -/* Get the HTTP error code for the last request */ -static int _hbf_http_error_code(ne_session *session) { - const char *msg = ne_get_error( session ); - char *msg2; - int err; - err = strtol(msg, &msg2, 10); - if (msg == msg2) { - err = 0; - } - return err; -} - -static Hbf_State _hbf_transfer_no_chunk(ne_session *session, hbf_transfer_t *transfer, const char *verb) { - int res; - const ne_status* req_status; - - ne_request *req = ne_request_create(session, verb ? verb : "PUT", transfer->url); - if (!req) - return HBF_MEMORY_FAIL; - - ne_add_request_header( req, "Content-Type", "application/octet-stream"); - - ne_set_request_body_fd(req, transfer->fd, 0, transfer->stat_size); - DEBUG_HBF("HBF: chunking not supported for %s", transfer->url); - res = ne_request_dispatch(req); - req_status = ne_get_status( req ); - - if (res == NE_OK && req_status->klass == 2) { - ne_request_destroy(req); - return HBF_SUCCESS; - } - - if( transfer->error_string ) free( transfer->error_string ); - transfer->error_string = strdup( ne_get_error(session) ); - transfer->status_code = req_status->code; - ne_request_destroy(req); - return HBF_FAIL; -} - -Hbf_State hbf_transfer( ne_session *session, hbf_transfer_t *transfer, const char *verb ) { - Hbf_State state = HBF_TRANSFER_SUCCESS; - int cnt; - - if( ! session ) { - state = HBF_SESSION_FAIL; - } - if( ! transfer ) { - state = HBF_SPLITLIST_FAIL; - } - if( ! verb ) { - state = HBF_PARAM_FAIL; - } - - if(state == HBF_TRANSFER_SUCCESS) { - DEBUG_HBF("%s request to %s", verb, transfer->url); - } - - for( cnt=0; state == HBF_TRANSFER_SUCCESS && cnt < transfer->block_cnt; cnt++ ) { - /* cnt goes from O to block_cnt, but block_id starts at start_id and wrap around - * That way if we have not finished uploaded when we reach block_cnt, we re-upload - * the beginning of the file that the server did not have in cache anymore. - */ - int block_id = (cnt + transfer->start_id) % transfer->block_cnt; - hbf_block_t *block = transfer->block_arr[block_id]; - char *transfer_url = NULL; - - if( ! block ) state = HBF_PARAM_FAIL; - - if( transfer->abort_cb ) { - int do_abort = (transfer->abort_cb)(transfer->user_data); - if( do_abort ) { - state = HBF_USER_ABORTED; - transfer->start_id = block_id % transfer->block_cnt; - } - } - - if( state == HBF_TRANSFER_SUCCESS ) { - transfer_url = get_transfer_url( transfer, block_id ); - if( ! transfer_url ) { - state = HBF_PARAM_FAIL; - } - } - - if( state == HBF_TRANSFER_SUCCESS ) { - if( transfer->block_cnt > 1 && cnt > 0 ) { - /* The block count is > 1, check size and mtime before transmitting. */ - state = hbf_validate_source_file(transfer); - if( state == HBF_SOURCE_FILE_CHANGE ) { - /* The source file has changed meanwhile */ - } - } - } - - if( state == HBF_TRANSFER_SUCCESS || state == HBF_SUCCESS ) { - ne_request *req = ne_request_create(session, verb, transfer_url); - - if( req ) { - char buf[21]; - - snprintf(buf, sizeof(buf), "%"PRId64, transfer->stat_size); - ne_add_request_header(req, "OC-Total-Length", buf); - if( transfer->oc_header_modtime > 0 ) { - snprintf(buf, sizeof(buf), "%"PRId64, transfer->oc_header_modtime); - ne_add_request_header(req, "X-OC-Mtime", buf); - } - - if( transfer->previous_etag ) { - ne_add_request_header(req, "If-Match", transfer->previous_etag); - } - - if( transfer->block_cnt > 1 ) { - ne_add_request_header(req, "OC-Chunked", "1"); - snprintf(buf, sizeof(buf), "%"PRId64, transfer->threshold); - ne_add_request_header(req, "OC-Chunk-Size", buf); - } - ne_add_request_header( req, "Content-Type", "application/octet-stream"); - - state = _hbf_dav_request(transfer, req, transfer->fd, block ); - - if( state != HBF_TRANSFER_SUCCESS && state != HBF_SUCCESS) { - if( transfer->error_string ) free( transfer->error_string ); - transfer->error_string = strdup( ne_get_error(session) ); - transfer->start_id = block_id % transfer->block_cnt; - /* Set the code of the last transmission. */ - state = HBF_FAIL; - transfer->status_code = transfer->block_arr[block_id]->http_result_code; - } - ne_request_destroy(req); - - if (transfer->block_cnt > 1 && state == HBF_SUCCESS && cnt == 0) { - /* Success on the first chunk is suspicious. - It could happen that the server did not support chunking */ - int rc = ne_delete(session, transfer_url); - if (rc == NE_OK && _hbf_http_error_code(session) == 204) { - /* If delete suceeded, it means some proxy strips the OC_CHUNKING header - start again without chunking: */ - free( transfer_url ); - return _hbf_transfer_no_chunk(session, transfer, verb); - } - } - - if (state == HBF_TRANSFER_SUCCESS && transfer->chunk_finished_cb) { - transfer->chunk_finished_cb(transfer, block_id, transfer->user_data); - } - - } else { - state = HBF_MEMORY_FAIL; - } - } - free( transfer_url ); - } - - /* do the source file validation finally (again). */ - if( state == HBF_TRANSFER_SUCCESS ) { - /* This means that no etag was returned on one of the chunks to indicate - * that the upload was finished. */ - state = HBF_TRANSFER_NOT_ACKED; - } - - return state; -} - -int hbf_fail_http_code( hbf_transfer_t *transfer ) -{ - int cnt; - - if( ! transfer ) return 0; - - for( cnt = 0; cnt < transfer->block_cnt; cnt++ ) { - int block_id = (cnt + transfer->start_id) % transfer->block_cnt; - hbf_block_t *block = transfer->block_arr[block_id]; - - if( block->state != HBF_NOT_TRANSFERED && block->state != HBF_TRANSFER_SUCCESS ) { - return block->http_result_code; - } - } - return 200; -} - -const char *hbf_transfer_etag( hbf_transfer_t *transfer ) -{ - int cnt; - const char *etag = NULL; - - if( ! transfer ) return 0; - - /* Loop over all parts and do a assertion that there is only one etag. */ - for( cnt = 0; cnt < transfer->block_cnt; cnt++ ) { - int block_id = (cnt + transfer->start_id) % transfer->block_cnt; - hbf_block_t *block = transfer->block_arr[block_id]; - if( block->etag ) { - if( etag && strcmp(etag, block->etag) != 0 ) { - /* multiple etags in the transfer, not equal. */ - DEBUG_HBF( "WARN: etags are not equal in blocks of one single transfer." ); - } - etag = block->etag; - } - } - return etag; -} - -const char *hbf_transfer_file_id( hbf_transfer_t *transfer ) -{ - const char *re = NULL; - if(transfer) { - re = transfer->file_id; - } - return re; -} - -const char *hbf_error_string(hbf_transfer_t *transfer, Hbf_State state) -{ - const char *re; - int cnt; - switch( state ) { - case HBF_SUCCESS: - re = "Ok."; - break; - case HBF_NOT_TRANSFERED: /* never tried to transfer */ - re = "Block was not yet tried to transfer."; - break; - case HBF_TRANSFER: /* transfer currently running */ - re = "Block is currently transferred."; - break; - case HBF_TRANSFER_FAILED: /* transfer tried but failed */ - re = "Block transfer failed."; - break; - case HBF_TRANSFER_SUCCESS: /* transfer succeeded. */ - re = "Block transfer successful."; - break; - case HBF_SPLITLIST_FAIL: /* the file could not be split */ - re = "Splitlist could not be computed."; - break; - case HBF_SESSION_FAIL: - re = "No valid session in transfer."; - break; - case HBF_FILESTAT_FAIL: - re = "Source file could not be stat'ed."; - break; - case HBF_PARAM_FAIL: - re = "Parameter fail."; - break; - case HBF_AUTH_FAIL: - re = "Authentication fail."; - break; - case HBF_PROXY_AUTH_FAIL: - re = "Proxy Authentication fail."; - break; - case HBF_CONNECT_FAIL: - re = "Connection could not be established."; - break; - case HBF_TIMEOUT_FAIL: - re = "Network timeout."; - break; - case HBF_MEMORY_FAIL: - re = "Out of memory."; - break; - case HBF_STAT_FAIL: - re = "Filesystem stat on file failed."; - break; - case HBF_SOURCE_FILE_CHANGE: - re = "Source file changed too often during upload."; - break; - case HBF_USER_ABORTED: - re = "Transmission aborted by user."; - break; - case HBF_TRANSFER_NOT_ACKED: - re = "The server did not provide an Etag."; - break; - case HBF_FAIL: - default: - for( cnt = 0; cnt < transfer->block_cnt; cnt++ ) { - int block_id = (cnt + transfer->start_id) % transfer->block_cnt; - hbf_block_t *block = transfer->block_arr[block_id]; - - if( block->state != HBF_NOT_TRANSFERED && block->state != HBF_TRANSFER_SUCCESS - && block->http_error_msg != NULL) { - return block->http_error_msg; - } - } - re = "Unknown error."; - } - return re; -} - -void hbf_set_abort_callback( hbf_transfer_t *transfer, hbf_abort_callback cb) -{ - if( transfer ) { - transfer->abort_cb = cb; - } -} - -void hbf_set_log_callback(hbf_transfer_t* transfer, hbf_log_callback cb) -{ - if( transfer ) { - transfer->log_cb = cb; - } -} diff -Nru owncloud-client-1.8.1+dfsg/csync/src/httpbf/src/httpbf.h owncloud-client-2.1.1+dfsg/csync/src/httpbf/src/httpbf.h --- owncloud-client-1.8.1+dfsg/csync/src/httpbf/src/httpbf.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/httpbf/src/httpbf.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,142 +0,0 @@ -/** - * http big file functions - * - * Copyright (c) 2012 by Klaas Freitag - * - * 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 _HBF_SEND_H -#define _HBF_SEND_H - -#include "config_csync.h" -#ifdef NEON_WITH_LFS /* Switch on LFS in libneon. Never remove the NE_LFS! */ -#define NE_LFS -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -enum hbf_state_e { - HBF_SUCCESS, - HBF_NOT_TRANSFERED, /* never tried to transfer */ - HBF_TRANSFER, /* transfer currently running */ - HBF_TRANSFER_FAILED, /* transfer tried but failed */ - HBF_TRANSFER_SUCCESS, /* block transfer succeeded. */ - HBF_SPLITLIST_FAIL, /* the file could not be split */ - HBF_SESSION_FAIL, - HBF_FILESTAT_FAIL, - HBF_PARAM_FAIL, - HBF_AUTH_FAIL, - HBF_PROXY_AUTH_FAIL, - HBF_CONNECT_FAIL, - HBF_TIMEOUT_FAIL, - HBF_MEMORY_FAIL, - HBF_STAT_FAIL, - HBF_SOURCE_FILE_CHANGE, - HBF_USER_ABORTED, - HBF_TRANSFER_NOT_ACKED, - HBF_FAIL -}; - -typedef enum hbf_state_e Hbf_State; - -typedef struct hbf_block_s hbf_block_t; - -struct hbf_block_s { - int seq_number; - - int64_t start; - int64_t size; - - Hbf_State state; - int http_result_code; - char *http_error_msg; - char *etag; - - int tries; -}; - -typedef struct hbf_transfer_s hbf_transfer_t; - -/* Callback for to check on abort */ -typedef int (*hbf_abort_callback) (void *); -typedef void (*hbf_log_callback) (const char *, const char *, void*); -typedef void (*hbf_chunk_finished_callback) (hbf_transfer_t*,int, void*); - -struct hbf_transfer_s { - hbf_block_t **block_arr; - int block_cnt; - int fd; - int transfer_id; - char *url; - int start_id; - - int status_code; - char *error_string; - - int64_t stat_size; - time_t modtime; - time_t oc_header_modtime; - int64_t block_size; - int64_t threshold; - - void *user_data; - hbf_abort_callback abort_cb; - hbf_log_callback log_cb; - hbf_chunk_finished_callback chunk_finished_cb; - int modtime_accepted; - const char *previous_etag; /* etag send as the If-Match http header */ - char *file_id; - -#ifndef NDEBUG - int64_t calc_size; -#endif -}; - -hbf_transfer_t *hbf_init_transfer( const char *dest_uri ); - -Hbf_State hbf_transfer( ne_session *session, hbf_transfer_t *transfer, const char *verb ); - -Hbf_State hbf_splitlist( hbf_transfer_t *transfer, int fd ); - -void hbf_free_transfer( hbf_transfer_t *transfer ); - -const char *hbf_error_string(hbf_transfer_t* transfer, Hbf_State state); - -const char *hbf_transfer_etag( hbf_transfer_t *transfer ); - -const char *hbf_transfer_file_id( hbf_transfer_t *transfer ); - -void hbf_set_abort_callback( hbf_transfer_t *transfer, hbf_abort_callback cb); -void hbf_set_log_callback( hbf_transfer_t *transfer, hbf_log_callback cb); - -/* returns an http (error) code of the transmission. If the transmission - * succeeded, the code is 200. If it failed, its the error code of the - * first part transmission that failed. - */ -int hbf_fail_http_code( hbf_transfer_t *transfer ); - -Hbf_State hbf_validate_source_file( hbf_transfer_t *transfer ); - -#ifdef __cplusplus -} -#endif - - -#endif Binary files /tmp/tmp23P1OM/gzky69FL3e/owncloud-client-1.8.1+dfsg/csync/src/httpbf/tests/church.jpg and /tmp/tmp23P1OM/MBnkbCE2fg/owncloud-client-2.1.1+dfsg/csync/src/httpbf/tests/church.jpg differ diff -Nru owncloud-client-1.8.1+dfsg/csync/src/httpbf/tests/CMakeLists.txt owncloud-client-2.1.1+dfsg/csync/src/httpbf/tests/CMakeLists.txt --- owncloud-client-1.8.1+dfsg/csync/src/httpbf/tests/CMakeLists.txt 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/httpbf/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -project(hbf_test C ) - -add_definitions(-DUNIT_TESTING=1) - -find_package(CMocka REQUIRED) - -include_directories( - ${CMAKE_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMOCKA_INCLUDE_DIRS} - ${NEON_INCLUDE_DIRS} - ${HTTPBF_PUBLIC_INCLUDE_DIRS} -) - -add_executable(send_test hbf_send_test.c) -target_link_libraries(send_test ${CMOCKA_LIBRARIES} ${NEON_LIBRARIES} ${HBF_LIBRARY} ) - - diff -Nru owncloud-client-1.8.1+dfsg/csync/src/httpbf/tests/hbf_send_test.c owncloud-client-2.1.1+dfsg/csync/src/httpbf/tests/hbf_send_test.c --- owncloud-client-1.8.1+dfsg/csync/src/httpbf/tests/hbf_send_test.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/httpbf/tests/hbf_send_test.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,162 +0,0 @@ -/* - * httpbf - send big files via http - * - * Copyright (c) 2012 Klaas Freitag - * - * 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 - */ - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "config_csync.h" - -#include - - -// A test case that does nothing and succeeds. -static void null_test_success(void **state) { - (void) state; -} - - -static char* test_file( const char* name ) { - if( ! name ) return 0; - - char path[260]; - strcpy( path, TESTFILEDIR); - if(path[strlen(TESTFILEDIR)-1] != '/') - strcat( path, "/"); - strcat( path, name ); - - return strdup(path); -} - -static void test_get_transfer_url( void **state ) { - const char *url = "http://example.org/owncloud"; - const char *turl = NULL; - char res[256]; - int i; - Hbf_State hbf_state; - - hbf_transfer_t *list = NULL; - list = hbf_init_transfer( url ); - assert_non_null( list ); - - /* open a file */ - int fd = open( test_file("church.jpg"), O_RDONLY ); - assert_true(fd >= 0); - - hbf_state = hbf_splitlist(list, fd); - assert_true( hbf_state == HBF_SUCCESS); - - for( i=0; i < list->block_cnt; i++ ) { - turl = get_transfer_url( list, i ); - - sprintf(res, "%s-chunking-%d-%d-%d", url, list->transfer_id, - list->block_cnt, i ); - printf( "XX: %s\n", res ); - assert_string_equal( turl, res ); - - } -} - -static void test_hbf_init_transfer( void **state ) { - hbf_transfer_t *list = NULL; - const char *url = "http://example.org/owncloud"; - - list = hbf_init_transfer( url ); - assert_non_null( list ); - assert_string_equal( url, list->url ); -} - -/* test with a file size that is not a multiply of the slize size. */ -static void test_hbf_splitlist_odd( void **state ){ - - hbf_transfer_t *list = NULL; - const char *dest_url = "http://localhost/ocm/remote.php/webdav/big/church.jpg"; - - /* open a file */ - int fd = open(test_file("church.jpg"), O_RDONLY); - assert_true(fd >= 0); - - int prev_id = 0; - int i; - - Hbf_State hbf_state; - - /* do a smoke test for uniqueness */ - for( i=0; i < 10000; i++) { - list = hbf_init_transfer(dest_url); - assert_non_null(list); - usleep(1); - hbf_state = hbf_splitlist(list, fd); - - assert_int_not_equal(list->transfer_id, prev_id); - prev_id = list->transfer_id; - hbf_free_transfer(list); - } - - list = hbf_init_transfer(dest_url); - assert_non_null(list); - - hbf_state = hbf_splitlist(list, fd); - assert_non_null(list); - assert_int_equal(list->calc_size, list->stat_size); - assert_int_not_equal(list->block_cnt, 0); - assert_true( hbf_state == HBF_SUCCESS); - - /* checks on the block list */ - int seen_zero_seq = 0; - int prev_seq = -1; - int64_t prev_block_end = -1; - - for( i=0; i < list->block_cnt; i++) { - hbf_block_t *blk = list->block_arr[i]; - assert_non_null(blk); - if( blk->seq_number == 0 ) seen_zero_seq++; - - assert_int_equal(prev_seq, blk->seq_number -1 ); - prev_seq = blk->seq_number; - - assert_true((prev_block_end+1) == (blk->start)); - prev_block_end = blk->start + blk->size; - } - /* Make sure we exactly saw blk->seq_number == 0 exactly one times */ - assert_int_equal( seen_zero_seq, 1 ); - - hbf_free_transfer( list ); -} - -int main(void) { - const UnitTest tests[] = { - unit_test(null_test_success), - unit_test(test_hbf_splitlist_odd), - unit_test(test_hbf_init_transfer), - unit_test(test_get_transfer_url) - }; - return run_tests(tests); -} diff -Nru owncloud-client-1.8.1+dfsg/csync/src/std/c_path.c owncloud-client-2.1.1+dfsg/csync/src/std/c_path.c --- owncloud-client-1.8.1+dfsg/csync/src/std/c_path.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/std/c_path.c 2016-02-09 15:07:08.000000000 +0000 @@ -32,6 +32,7 @@ #include "c_private.h" #include "c_alloc.h" #include "c_path.h" +#include "c_string.h" /* * dirname - parse directory component. @@ -389,3 +390,62 @@ return -1; } + +/* + * This function takes a path and converts it to a UNC representation of the + * string. That means that it prepends a \\?\ (unless already UNC) and converts + * all slashes to backslashes. + * + * Note the following: + * - The string must be absolute. + * - it needs to contain a drive character to be a valid UNC + * - A conversion is only done if the path len is larger than 245. Otherwise + * the windows API functions work with the normal "unixoid" representation too. + * + * This function allocates memory that must be freed by the caller. + */ + const char *c_path_to_UNC(const char *str) + { + int len = 0; + char *longStr = NULL; + + len = strlen(str); + longStr = c_malloc(len+5); + *longStr = '\0'; + + // prepend \\?\ and convert '/' => '\' to support long names + if( str[0] == '/' || str[0] == '\\' ) { + // Don't prepend if already UNC + if( !(len > 1 && (str[1] == '/' || str[1] == '\\')) ) { + strcpy( longStr, "\\\\?"); + } + } else { + strcpy( longStr, "\\\\?\\"); // prepend string by this four magic chars. + } + strncat( longStr, str, len ); + + /* replace all occurences of / with the windows native \ */ + char *c = longStr; + for (; *c; ++c) { + if(*c == '/') { + *c = '\\'; + } + } + return longStr; + } + + mbchar_t* c_utf8_path_to_locale(const char *str) + { + if( str == NULL ) { + return NULL; + } else { + #ifdef _WIN32 + const char *unc_str = c_path_to_UNC(str); + mbchar_t *dst = c_utf8_string_to_locale(unc_str); + SAFE_FREE(unc_str); + return dst; + #else + return c_utf8_string_to_locale(str); + #endif + } + } diff -Nru owncloud-client-1.8.1+dfsg/csync/src/std/c_path.h owncloud-client-2.1.1+dfsg/csync/src/std/c_path.h --- owncloud-client-1.8.1+dfsg/csync/src/std/c_path.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/std/c_path.h 2016-02-09 15:07:08.000000000 +0000 @@ -33,6 +33,7 @@ #define _C_PATH_H #include "c_macro.h" +#include "c_private.h" /** * @brief Parse directory component. @@ -96,9 +97,9 @@ * @param directory '\0' terminated path including the final '/' * * @param filename '\0' terminated string - * + * * @param extension '\0' terminated string - * + * */ typedef struct { @@ -107,6 +108,33 @@ char * extension; } C_PATHINFO; +/** + * @brief c_path_to_UNC converts a unixoid path to UNC format. + * + * It converts the '/' to '\' and prepends \\?\ to the path. + * + * A proper windows path has to have a drive letter, otherwise it is not + * valid UNC. + * + * @param str The path to convert + * + * @return a pointer to the converted string. Caller has to free it. + */ +const char *c_path_to_UNC(const char *str); + +/** + * @brief c_utf8_path_to_locale converts a unixoid path to the locale aware format + * + * On windows, it converts to UNC and multibyte. + * On Mac, it converts to the correct utf8 using iconv. + * On Linux, it returns utf8 + * + * @param str The path to convert + * + * @return a pointer to the converted string. Caller has to free it using the + * function c_free_locale_string. + */ +mbchar_t* c_utf8_path_to_locale(const char *str); /** * }@ diff -Nru owncloud-client-1.8.1+dfsg/csync/src/std/c_private.h owncloud-client-2.1.1+dfsg/csync/src/std/c_private.h --- owncloud-client-1.8.1+dfsg/csync/src/std/c_private.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/std/c_private.h 2016-02-09 15:07:08.000000000 +0000 @@ -41,10 +41,18 @@ #ifdef _WIN32 #define EDQUOT 0 #define ENODATA 0 +#ifndef S_IRGRP #define S_IRGRP 0 +#endif +#ifndef S_IROTH #define S_IROTH 0 +#endif +#ifndef S_IXGRP #define S_IXGRP 0 +#endif +#ifndef S_IXOTH #define S_IXOTH 0 +#endif #define S_IFSOCK 10000 /* dummy val on Win32 */ #define S_IFLNK 10001 /* dummy val on Win32 */ @@ -102,7 +110,6 @@ typedef wchar_t mbchar_t; #define _topen _wopen #define _tdirent _wdirent -#define _TDIR _WDIR #define _topendir _wopendir #define _tclosedir _wclosedir #define _treaddir _wreaddir @@ -118,11 +125,12 @@ #define _tchmod _wchmod #define _trewinddir _wrewinddir #define _tchown(X, Y, Z) 0 /* no chown on Win32 */ +#define _tchdir _wchdir +#define _tgetcwd _wgetcwd #else typedef char mbchar_t; #define _tdirent dirent #define _topen open -#define _TDIR DIR #define _topendir opendir #define _tclosedir closedir #define _treaddir readdir @@ -138,6 +146,8 @@ #define _tchmod chmod #define _trewinddir rewinddir #define _tchown(X,Y,Z) chown(X,Y,Z) +#define _tchdir chdir +#define _tgetcwd getcwd #endif #ifdef WITH_ICONV diff -Nru owncloud-client-1.8.1+dfsg/csync/src/std/c_string.c owncloud-client-2.1.1+dfsg/csync/src/std/c_string.c --- owncloud-client-1.8.1+dfsg/csync/src/std/c_string.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/std/c_string.c 2016-02-09 15:07:08.000000000 +0000 @@ -32,6 +32,7 @@ #include #include "c_string.h" +#include "c_path.h" #include "c_alloc.h" #include "c_macro.h" @@ -214,6 +215,25 @@ return 0; } +int c_strlist_add_grow(c_strlist_t **strlist, const char *string) { + if (*strlist == NULL) { + *strlist = c_strlist_new(32); + if (*strlist == NULL) { + return -1; + } + } + + if ((*strlist)->count == (*strlist)->size) { + c_strlist_t *list = c_strlist_expand(*strlist, 2 * (*strlist)->size); + if (list == NULL) { + return -1; + } + *strlist = list; + } + + return c_strlist_add(*strlist, string); +} + void c_strlist_clear(c_strlist_t *strlist) { size_t i = 0; @@ -275,33 +295,33 @@ } /* Convert a an UTF8 string to multibyte */ -mbchar_t* c_utf8_to_locale(const char *str) +mbchar_t* c_utf8_string_to_locale(const char *str) { - mbchar_t *dst = NULL; + mbchar_t *dst = NULL; #ifdef _WIN32 - size_t len; - int size_needed; + size_t len; + int size_needed; #endif - if (str == NULL ) { - return NULL; - } + if (str == NULL ) { + return NULL; + } #ifdef _WIN32 - len = strlen(str); - size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0); - if (size_needed > 0) { - int size_char = (size_needed + 1) * sizeof(mbchar_t); - dst = c_malloc(size_char); - memset((void*)dst, 0, size_char); - MultiByteToWideChar(CP_UTF8, 0, str, -1, dst, size_needed); - } + len = strlen(str); + size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0); + if (size_needed > 0) { + int size_char = (size_needed + 1) * sizeof(mbchar_t); + dst = c_malloc(size_char); + memset((void*)dst, 0, size_char); + MultiByteToWideChar(CP_UTF8, 0, str, -1, dst, size_needed); + } #else #ifdef WITH_ICONV - dst = c_iconv(str, iconv_to_native); + dst = c_iconv(str, iconv_to_native); #else - dst = (_TCHAR*) str; + dst = (_TCHAR*) str; #endif #endif - return dst; + return dst; } diff -Nru owncloud-client-1.8.1+dfsg/csync/src/std/c_string.h owncloud-client-2.1.1+dfsg/csync/src/std/c_string.h --- owncloud-client-1.8.1+dfsg/csync/src/std/c_string.h 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/std/c_string.h 2016-02-09 15:07:08.000000000 +0000 @@ -113,6 +113,19 @@ int c_strlist_add(c_strlist_t *strlist, const char *string); /** + * @brief Add a string to the stringlist, growing it if necessary + * + * Duplicates the string and stores it in the stringlist. + * It also initializes the stringlist if it starts out as null. + * + * @param strlist Stringlist to add the string. + * @param string String to add. + * + * @return 0 on success, less than 0 and errno set if an error occured. + */ +int c_strlist_add_grow(c_strlist_t **strlist, const char *string); + +/** * @brief Removes all strings from the list. * * Frees the strings. @@ -163,12 +176,14 @@ * Instead of using the standard file operations the multi platform aliases * defined in c_private.h have to be used instead. * - * To convert path names as input for the cross platform functions from the + * To convert strings as input for the cross platform functions from the * internally used utf8 format, this function has to be used. * The returned string has to be freed by c_free_locale_string(). On some * platforms this method allocates memory and on others not but it has never * sto be cared about. * + * If the string to convert is a path, consider using c_utf8_path_to_locale(). + * * @param str The utf8 string to convert. * * @return The malloced converted multibyte string or NULL on error. @@ -177,7 +192,7 @@ * @see c_utf8_from_locale() * */ -mbchar_t* c_utf8_to_locale(const char *wstr); +mbchar_t* c_utf8_string_to_locale(const char *wstr); #if defined(_WIN32) || defined(WITH_ICONV) diff -Nru owncloud-client-1.8.1+dfsg/csync/src/std/c_time.c owncloud-client-2.1.1+dfsg/csync/src/std/c_time.c --- owncloud-client-1.8.1+dfsg/csync/src/std/c_time.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/std/c_time.c 2016-02-09 15:07:08.000000000 +0000 @@ -22,7 +22,7 @@ #include "c_private.h" #include "c_string.h" -#include "c_string.h" +#include "c_path.h" #include "c_time.h" struct timespec c_tspecdiff(struct timespec time1, struct timespec time0) { @@ -69,7 +69,7 @@ #ifdef HAVE_UTIMES int c_utimes(const char *uri, const struct timeval *times) { - mbchar_t *wuri = c_utf8_to_locale(uri); + mbchar_t *wuri = c_utf8_path_to_locale(uri); int ret = utimes(wuri, times); c_free_locale_string(wuri); return ret; @@ -97,7 +97,7 @@ FILETIME LastModificationTime; HANDLE hFile; - mbchar_t *wuri = c_utf8_to_locale( uri ); + mbchar_t *wuri = c_utf8_path_to_locale( uri ); if(times) { UnixTimevalToFileTime(times[0], &LastAccessTime); diff -Nru owncloud-client-1.8.1+dfsg/csync/src/vio/csync_vio.c owncloud-client-2.1.1+dfsg/csync/src/vio/csync_vio.c --- owncloud-client-1.8.1+dfsg/csync/src/vio/csync_vio.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/vio/csync_vio.c 2016-02-09 15:07:08.000000000 +0000 @@ -36,9 +36,6 @@ #define CSYNC_LOG_CATEGORY_NAME "csync.vio.main" #include "csync_log.h" -#if USE_NEON -#include "csync_owncloud.h" -#endif csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name) { switch(ctx->replica) { @@ -132,8 +129,5 @@ if(ctx->error_string) { return ctx->error_string; } -#ifdef USE_NEON - return owncloud_error_string(ctx); -#endif return 0; } diff -Nru owncloud-client-1.8.1+dfsg/csync/src/vio/csync_vio_local.c owncloud-client-2.1.1+dfsg/csync/src/vio/csync_vio_local.c --- owncloud-client-1.8.1+dfsg/csync/src/vio/csync_vio_local.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/vio/csync_vio_local.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,354 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2008-2013 by Andreas Schneider - * - * 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 -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include "windows.h" -#endif - -#include "c_private.h" -#include "c_lib.h" -#include "c_string.h" -#include "csync_util.h" -#include "csync_log.h" -#include "csync_vio.h" - -#include "vio/csync_vio_local.h" - - -/* - * directory functions - */ - -typedef struct dhandle_s { - _TDIR *dh; - char *path; -} dhandle_t; - -csync_vio_handle_t *csync_vio_local_opendir(const char *name) { - dhandle_t *handle = NULL; - mbchar_t *dirname = c_utf8_to_locale(name); - - handle = c_malloc(sizeof(dhandle_t)); - - handle->dh = _topendir( dirname ); - if (handle->dh == NULL) { - c_free_locale_string(dirname); - SAFE_FREE(handle); - return NULL; - } - - handle->path = c_strdup(name); - c_free_locale_string(dirname); - - return (csync_vio_handle_t *) handle; -} - -int csync_vio_local_closedir(csync_vio_handle_t *dhandle) { - dhandle_t *handle = NULL; - int rc = -1; - - if (dhandle == NULL) { - errno = EBADF; - return -1; - } - - handle = (dhandle_t *) dhandle; - rc = _tclosedir(handle->dh); - - SAFE_FREE(handle->path); - SAFE_FREE(handle); - - return rc; -} - -csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) { - struct _tdirent *dirent = NULL; - - dhandle_t *handle = NULL; - csync_vio_file_stat_t *file_stat = NULL; - - handle = (dhandle_t *) dhandle; - - errno = 0; - dirent = _treaddir(handle->dh); - if (dirent == NULL) { - if (errno) { - goto err; - } else { - return NULL; - } - } - - file_stat = csync_vio_file_stat_new(); - if (file_stat == NULL) { - goto err; - } - - file_stat->name = c_utf8_from_locale(dirent->d_name); - file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; - - /* Check for availability of d_type, see manpage. */ -#ifdef _DIRENT_HAVE_D_TYPE - switch (dirent->d_type) { - case DT_FIFO: - case DT_SOCK: - case DT_CHR: - case DT_BLK: - break; - case DT_DIR: - case DT_REG: - file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; - if (dirent->d_type == DT_DIR) { - file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; - } else { - file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR; - } - break; - case DT_UNKNOWN: - file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; - file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN; - default: - break; - } -#endif - - return file_stat; - -err: - SAFE_FREE(file_stat); - - return NULL; -} - - -#ifdef _WIN32 -static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder) -{ - long long int t = filetime->dwHighDateTime; - t <<= 32; - t += (UINT32)filetime->dwLowDateTime; - t -= 116444736000000000LL; - if (t < 0) - { - if (remainder) *remainder = 9999999 - (-t - 1) % 10000000; - return -1 - ((-t - 1) / 10000000); - } - else - { - if (remainder) *remainder = t % 10000000; - return t / 10000000; - } -} - -int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) { - HANDLE h, hFind; - FILETIME ftCreate, ftAccess, ftWrite; - BY_HANDLE_FILE_INFORMATION fileInfo; - WIN32_FIND_DATAW FindFileData; - ULARGE_INTEGER FileIndex; - mbchar_t *wuri = c_utf8_to_locale( uri ); - - h = CreateFileW( wuri, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, NULL ); - if( h == INVALID_HANDLE_VALUE ) { - CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "CreateFileW failed on %s", uri ); - errno = GetLastError(); - c_free_locale_string(wuri); - return -1; - } - - if(!GetFileInformationByHandle( h, &fileInfo ) ) { - CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "GetFileInformationByHandle failed on %s", uri ); - errno = GetLastError(); - c_free_locale_string(wuri); - CloseHandle(h); - return -1; - } - - buf->flags = CSYNC_VIO_FILE_FLAGS_NONE; - do { - // Check first if it is a symlink (code from c_islink) - if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - hFind = FindFirstFileW(wuri, &FindFileData ); - if (hFind != INVALID_HANDLE_VALUE) { - if( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && - (FindFileData.dwReserved0 & IO_REPARSE_TAG_SYMLINK) ) { - buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK; - buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; - break; - } - } - FindClose(hFind); - } - if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DEVICE - || fileInfo.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE - || fileInfo.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) { - buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN; - break; - } - if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; - break; - } - // fallthrough: - buf->type = CSYNC_VIO_FILE_TYPE_REGULAR; - break; - } while (0); - /* TODO Do we want to parse for CSYNC_VIO_FILE_FLAGS_HIDDEN ? */ - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; - - buf->device = fileInfo.dwVolumeSerialNumber; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DEVICE; - - /* Get the Windows file id as an inode replacement. */ - FileIndex.HighPart = fileInfo.nFileIndexHigh; - FileIndex.LowPart = fileInfo.nFileIndexLow; - FileIndex.QuadPart &= 0x0000FFFFFFFFFFFF; - /* printf("Index: %I64i\n", FileIndex.QuadPart); */ - buf->inode = FileIndex.QuadPart; - - buf->size = (fileInfo.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + fileInfo.nFileSizeLow; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; - - /* Get the file time with a win32 call rather than through stat. See - * http://www.codeproject.com/Articles/1144/Beating-the-Daylight-Savings-Time-bug-and-getting - * for deeper explanation. - */ - if( GetFileTime(h, &ftCreate, &ftAccess, &ftWrite) ) { - DWORD rem; - buf->atime = FileTimeToUnixTime(&ftAccess, &rem); - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME; - - buf->mtime = FileTimeToUnixTime(&ftWrite, &rem); - /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */ - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; - - buf->ctime = FileTimeToUnixTime(&ftCreate, &rem); - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME; - } - - c_free_locale_string(wuri); - CloseHandle(h); - - return 0; -} - -#else - -int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) { - csync_stat_t sb; - - mbchar_t *wuri = c_utf8_to_locale( uri ); - - if( _tstat(wuri, &sb) < 0) { - c_free_locale_string(wuri); - return -1; - } - - buf->name = c_basename(uri); - - if (buf->name == NULL) { - csync_vio_file_stat_destroy(buf); - c_free_locale_string(wuri); - return -1; - } - buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; - - switch(sb.st_mode & S_IFMT) { - case S_IFBLK: - buf->type = CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE; - break; - case S_IFCHR: - buf->type = CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE; - break; - case S_IFDIR: - buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; - break; - case S_IFIFO: - buf->type = CSYNC_VIO_FILE_TYPE_FIFO; - break; - case S_IFREG: - buf->type = CSYNC_VIO_FILE_TYPE_REGULAR; - break; - case S_IFLNK: - buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; - break; - case S_IFSOCK: - buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; - break; - default: - buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN; - break; - } - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; - - buf->mode = sb.st_mode; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MODE; - - if (buf->type == CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK) { - /* FIXME: handle symlink */ - buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK; - } else { - buf->flags = CSYNC_VIO_FILE_FLAGS_NONE; - } -#ifdef __APPLE__ - if (sb.st_flags & UF_HIDDEN) { - buf->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN; - } -#endif - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS; - - buf->device = sb.st_dev; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DEVICE; - - buf->inode = sb.st_ino; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE; - - buf->atime = sb.st_atime; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME; - - buf->mtime = sb.st_mtime; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; - - buf->ctime = sb.st_ctime; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME; - - buf->nlink = sb.st_nlink; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT; - - buf->size = sb.st_size; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; - - c_free_locale_string(wuri); - return 0; -} -#endif - - - - diff -Nru owncloud-client-1.8.1+dfsg/csync/src/vio/csync_vio_local_unix.c owncloud-client-2.1.1+dfsg/csync/src/vio/csync_vio_local_unix.c --- owncloud-client-1.8.1+dfsg/csync/src/vio/csync_vio_local_unix.c 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/vio/csync_vio_local_unix.c 2016-02-09 15:07:08.000000000 +0000 @@ -0,0 +1,223 @@ +/* + * libcsync -- a library to sync a directory with another + * + * Copyright (c) 2008-2013 by Andreas Schneider + * Copyright (c) 2013- by Klaas Freitag + * + * 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 +#include +#include +#include +#include +#include + +#include "c_private.h" +#include "c_lib.h" +#include "c_string.h" +#include "csync_util.h" +#include "csync_log.h" +#include "csync_vio.h" + +#include "vio/csync_vio_local.h" + +/* + * directory functions + */ + +typedef struct dhandle_s { + DIR *dh; + char *path; +} dhandle_t; + +csync_vio_handle_t *csync_vio_local_opendir(const char *name) { + dhandle_t *handle = NULL; + mbchar_t *dirname = NULL; + + handle = c_malloc(sizeof(dhandle_t)); + + dirname = c_utf8_path_to_locale(name); + + handle->dh = _topendir( dirname ); + if (handle->dh == NULL) { + c_free_locale_string(dirname); + SAFE_FREE(handle); + return NULL; + } + + handle->path = c_strdup(name); + c_free_locale_string(dirname); + + return (csync_vio_handle_t *) handle; +} + +int csync_vio_local_closedir(csync_vio_handle_t *dhandle) { + dhandle_t *handle = NULL; + int rc = -1; + + if (dhandle == NULL) { + errno = EBADF; + return -1; + } + + handle = (dhandle_t *) dhandle; + rc = _tclosedir(handle->dh); + + SAFE_FREE(handle->path); + SAFE_FREE(handle); + + return rc; +} + +csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) { + + dhandle_t *handle = NULL; + csync_vio_file_stat_t *file_stat = NULL; + + handle = (dhandle_t *) dhandle; + + errno = 0; + file_stat = csync_vio_file_stat_new(); + if (file_stat == NULL) { + goto err; + } + file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; + + struct _tdirent *dirent = NULL; + + dirent = _treaddir(handle->dh); + if (dirent == NULL) { + goto err; + } + file_stat->name = c_utf8_from_locale(dirent->d_name); + if (file_stat->name == NULL) { + //file_stat->original_name = c_strdup(dirent->d_name); + if (asprintf(&file_stat->original_name, "%s/%s", handle->path, dirent->d_name) < 0) { + goto err; + } + CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Invalid characters in file/directory name, please rename: \"%s\" (%s)", + dirent->d_name, handle->path); + } + + /* Check for availability of d_type, see manpage. */ +#if defined(_DIRENT_HAVE_D_TYPE) || defined(__APPLE__) + switch (dirent->d_type) { + case DT_FIFO: + case DT_SOCK: + case DT_CHR: + case DT_BLK: + break; + case DT_DIR: + case DT_REG: + file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; + if (dirent->d_type == DT_DIR) { + file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; + } else { + file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR; + } + break; + case DT_UNKNOWN: + file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; + file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN; + default: + break; + } +#endif + + return file_stat; + +err: + SAFE_FREE(file_stat); + + return NULL; +} + + +int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) { + csync_stat_t sb; + + mbchar_t *wuri = c_utf8_path_to_locale( uri ); + + if( _tstat(wuri, &sb) < 0) { + c_free_locale_string(wuri); + return -1; + } + + buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; + + switch(sb.st_mode & S_IFMT) { + case S_IFBLK: + buf->type = CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE; + break; + case S_IFCHR: + buf->type = CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE; + break; + case S_IFDIR: + buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; + break; + case S_IFIFO: + buf->type = CSYNC_VIO_FILE_TYPE_FIFO; + break; + case S_IFREG: + buf->type = CSYNC_VIO_FILE_TYPE_REGULAR; + break; + case S_IFLNK: + buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; + break; + case S_IFSOCK: + buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; + break; + default: + buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN; + break; + } + buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; + + buf->mode = sb.st_mode; + buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MODE; + + if (buf->type == CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK) { + /* FIXME: handle symlink */ + buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK; + } else { + buf->flags = CSYNC_VIO_FILE_FLAGS_NONE; + } +#ifdef __APPLE__ + if (sb.st_flags & UF_HIDDEN) { + buf->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN; + } +#endif + buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS; + + buf->inode = sb.st_ino; + buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE; + + buf->atime = sb.st_atime; + buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME; + + buf->mtime = sb.st_mtime; + buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; + + buf->ctime = sb.st_ctime; + buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME; + + buf->size = sb.st_size; + buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; + + c_free_locale_string(wuri); + return 0; +} diff -Nru owncloud-client-1.8.1+dfsg/csync/src/vio/csync_vio_local_win.c owncloud-client-2.1.1+dfsg/csync/src/vio/csync_vio_local_win.c --- owncloud-client-1.8.1+dfsg/csync/src/vio/csync_vio_local_win.c 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/src/vio/csync_vio_local_win.c 2016-02-09 15:07:08.000000000 +0000 @@ -0,0 +1,267 @@ +/* + * libcsync -- a library to sync a directory with another + * + * Copyright (c) 2008-2013 by Andreas Schneider + * Copyright (c) 2013- by Klaas Freitag + * + * 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 +#include +#include +#include +#include +#include + +#include "windows.h" + +#include "c_private.h" +#include "c_lib.h" +#include "c_string.h" +#include "csync_util.h" +#include "csync_log.h" +#include "csync_vio.h" + +#include "vio/csync_vio_local.h" + + +/* + * directory functions + */ + +typedef struct dhandle_s { + WIN32_FIND_DATA ffd; + HANDLE hFind; + int firstFind; + char *path; +} dhandle_t; + +csync_vio_handle_t *csync_vio_local_opendir(const char *name) { + dhandle_t *handle = NULL; + mbchar_t *dirname = NULL; + + handle = c_malloc(sizeof(dhandle_t)); + + // the file wildcard has to be attached + int len_name = strlen(name); + if( len_name ) { + char *h = NULL; + + // alloc an enough large buffer to take the name + '/*' + the closing zero. + h = c_malloc(len_name+3); + strncpy( h, name, 1+len_name); + strncat(h, "/*", 2); + + dirname = c_utf8_path_to_locale(h); + SAFE_FREE(h); + } + + if( dirname ) { + handle->hFind = FindFirstFile(dirname, &(handle->ffd)); + } + + if (!dirname || handle->hFind == INVALID_HANDLE_VALUE) { + int retcode = GetLastError(); + if( retcode == ERROR_FILE_NOT_FOUND ) { + errno = ENOENT; + } else { + errno = EACCES; + } + SAFE_FREE(handle); + return NULL; + } + + handle->firstFind = 1; // Set a flag that there first fileinfo is available. + + handle->path = c_strdup(name); + c_free_locale_string(dirname); + + return (csync_vio_handle_t *) handle; +} + +int csync_vio_local_closedir(csync_vio_handle_t *dhandle) { + dhandle_t *handle = NULL; + int rc = -1; + + if (dhandle == NULL) { + errno = EBADF; + return -1; + } + + handle = (dhandle_t *) dhandle; + // FindClose returns non-zero on success + if( FindClose(handle->hFind) != 0 ) { + rc = 0; + } else { + // error case, set errno + errno = EBADF; + } + + SAFE_FREE(handle->path); + SAFE_FREE(handle); + + return rc; +} + + +static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder) +{ + long long int t = filetime->dwHighDateTime; + t <<= 32; + t += (UINT32)filetime->dwLowDateTime; + t -= 116444736000000000LL; + if (t < 0) + { + if (remainder) *remainder = 9999999 - (-t - 1) % 10000000; + return -1 - ((-t - 1) / 10000000); + } + else + { + if (remainder) *remainder = t % 10000000; + return t / 10000000; + } +} + +csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) { + + dhandle_t *handle = NULL; + csync_vio_file_stat_t *file_stat = NULL; + ULARGE_INTEGER FileIndex; + DWORD rem; + + handle = (dhandle_t *) dhandle; + + errno = 0; + file_stat = csync_vio_file_stat_new(); + if (file_stat == NULL) { + errno = ENOMEM; + goto err; + } + file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; + + // the win32 functions get the first valid entry with the opendir + // thus we must not jump to next entry if it was the first find. + if( handle->firstFind ) { + handle->firstFind = 0; + } else { + if( FindNextFile(handle->hFind, &(handle->ffd)) == 0 ) { + // might be error, check! + int dwError = GetLastError(); + if (dwError != ERROR_NO_MORE_FILES) { + errno = EACCES; // no more files is fine. Otherwise EACCESS + } + goto err; + } + } + file_stat->name = c_utf8_from_locale(handle->ffd.cFileName); + + file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; + if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT + && handle->ffd.dwReserved0 & IO_REPARSE_TAG_SYMLINK) { + file_stat->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK; + file_stat->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; + } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE + || handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE + || handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) { + file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN; + } else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; + } else { + file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR; + } + + file_stat->flags = CSYNC_VIO_FILE_FLAGS_NONE; + /* Check for the hidden flag */ + if( handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) { + file_stat->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN; + } + + file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS; + file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; + + file_stat->size = (handle->ffd.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + handle->ffd.nFileSizeLow; + file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; + + file_stat->atime = FileTimeToUnixTime(&handle->ffd.ftLastAccessTime, &rem); + file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME; + + file_stat->mtime = FileTimeToUnixTime(&handle->ffd.ftLastWriteTime, &rem); + /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */ + file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; + + file_stat->ctime = FileTimeToUnixTime(&handle->ffd.ftCreationTime, &rem); + file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME; + + return file_stat; + +err: + SAFE_FREE(file_stat); + + return NULL; +} + + + +int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) { + /* Almost nothing to do since csync_vio_local_readdir already filled up most of the information + But we still need to fetch the file ID. + Possible optimisation: only fetch the file id when we need it (for new files) + */ + + HANDLE h; + BY_HANDLE_FILE_INFORMATION fileInfo; + ULARGE_INTEGER FileIndex; + mbchar_t *wuri = c_utf8_path_to_locale( uri ); + + h = CreateFileW( wuri, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS+FILE_FLAG_OPEN_REPARSE_POINT, NULL ); + if( h == INVALID_HANDLE_VALUE ) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "CreateFileW failed on %s", uri ); + errno = GetLastError(); + c_free_locale_string(wuri); + return -1; + } + + if(!GetFileInformationByHandle( h, &fileInfo ) ) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "GetFileInformationByHandle failed on %s", uri ); + errno = GetLastError(); + c_free_locale_string(wuri); + CloseHandle(h); + return -1; + } + + /* Get the Windows file id as an inode replacement. */ + FileIndex.HighPart = fileInfo.nFileIndexHigh; + FileIndex.LowPart = fileInfo.nFileIndexLow; + FileIndex.QuadPart &= 0x0000FFFFFFFFFFFF; + /* printf("Index: %I64i\n", FileIndex.QuadPart); */ + buf->inode = FileIndex.QuadPart; + + if (!(buf->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE)) { + buf->size = (fileInfo.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + fileInfo.nFileSizeLow; + buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; + } + if (!(buf->fields & CSYNC_VIO_FILE_STAT_FIELDS_MTIME)) { + DWORD rem; + buf->mtime = FileTimeToUnixTime(&fileInfo.ftLastWriteTime, &rem); + /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */ + buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; + } + + c_free_locale_string(wuri); + CloseHandle(h); + return 0; +} diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/CMakeLists.txt owncloud-client-2.1.1+dfsg/csync/tests/CMakeLists.txt --- owncloud-client-1.8.1+dfsg/csync/tests/CMakeLists.txt 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/CMakeLists.txt 2016-02-09 15:07:08.000000000 +0000 @@ -7,7 +7,6 @@ ${CSTDLIB_PUBLIC_INCLUDE_DIRS} ${CMAKE_BINARY_DIR} ${CMOCKA_INCLUDE_DIR} - ${HTTPBF_PUBLIC_INCLUDE_DIRS} ) include_directories(${CHECK_INCLUDE_DIRS}) @@ -46,6 +45,7 @@ # vio add_cmocka_test(check_vio_file_stat vio_tests/check_vio_file_stat.c ${TEST_TARGET_LIBRARIES}) add_cmocka_test(check_vio vio_tests/check_vio.c ${TEST_TARGET_LIBRARIES}) +add_cmocka_test(check_vio_ext vio_tests/check_vio_ext.c ${TEST_TARGET_LIBRARIES}) # sync add_cmocka_test(check_csync_update csync_tests/check_csync_update.c ${TEST_TARGET_LIBRARIES}) @@ -53,8 +53,7 @@ # encoding add_cmocka_test(check_encoding_functions encoding_tests/check_encoding.c ${TEST_TARGET_LIBRARIES}) -# httpbf -set(TEST_HTTPBF_LIBRARIES ${TEST_TARGET_LIBRARIES} ${NEON_LIBRARIES}) -add_cmocka_test(check_httpbf httpbf_tests/hbf_send_test.c ${TEST_HTTPBF_LIBRARIES} ) - +if(UNIT_TESTING) + INSTALL( FILES "${CMOCKA_LIBRARIES}" DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif(UNIT_TESTING) diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/csync_tests/check_csync_exclude.c owncloud-client-2.1.1+dfsg/csync/tests/csync_tests/check_csync_exclude.c --- owncloud-client-1.8.1+dfsg/csync/tests/csync_tests/check_csync_exclude.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/csync_tests/check_csync_exclude.c 2016-02-09 15:07:08.000000000 +0000 @@ -19,6 +19,7 @@ */ #include "config_csync.h" #include +#include #include "torture.h" @@ -47,6 +48,18 @@ rc = csync_exclude_load(EXCLUDE_LIST_FILE, &(csync->excludes)); assert_int_equal(rc, 0); + /* and add some unicode stuff */ + rc = _csync_exclude_add(&(csync->excludes), "*.💩"); + assert_int_equal(rc, 0); + rc = _csync_exclude_add(&(csync->excludes), "пятницы.*"); + assert_int_equal(rc, 0); + rc = _csync_exclude_add(&(csync->excludes), "*/*.out"); + assert_int_equal(rc, 0); + rc = _csync_exclude_add(&(csync->excludes), "latex*/*.run.xml"); + assert_int_equal(rc, 0); + rc = _csync_exclude_add(&(csync->excludes), "latex/*/*.tex.tmp"); + assert_int_equal(rc, 0); + *state = csync; } @@ -80,7 +93,7 @@ rc = csync_exclude_load(EXCLUDE_LIST_FILE, &(csync->excludes) ); assert_int_equal(rc, 0); - assert_string_equal(csync->excludes->vector[0], "*.filepart"); + assert_string_equal(csync->excludes->vector[0], "*~"); assert_int_not_equal(csync->excludes->count, 0); } @@ -89,6 +102,11 @@ CSYNC *csync = *state; int rc; + rc = csync_excluded(csync, "", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + rc = csync_excluded(csync, "/", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + rc = csync_excluded(csync, "krawel_krawel", CSYNC_FTW_TYPE_FILE); assert_int_equal(rc, CSYNC_NOT_EXCLUDED); rc = csync_excluded(csync, ".kde/share/config/kwin.eventsrc", CSYNC_FTW_TYPE_FILE); @@ -139,6 +157,80 @@ rc = csync_excluded(csync, ".netscape/cache", CSYNC_FTW_TYPE_FILE); assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + /* Not excluded */ + rc = csync_excluded(csync, "unicode/中文.hé", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + /* excluded */ + rc = csync_excluded(csync, "unicode/пятницы.txt", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + rc = csync_excluded(csync, "unicode/中文.💩", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + /* path wildcards */ + rc = csync_excluded(csync, "foobar/my_manuscript.out", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + rc = csync_excluded(csync, "latex_tmp/my_manuscript.run.xml", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + rc = csync_excluded(csync, "word_tmp/my_manuscript.run.xml", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + + rc = csync_excluded(csync, "latex/my_manuscript.tex.tmp", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + + rc = csync_excluded(csync, "latex/songbook/my_manuscript.tex.tmp", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); +} + +static void check_csync_excluded_traversal(void **state) +{ + CSYNC *csync = *state; + int rc; + + _csync_exclude_add( &(csync->excludes), "/exclude" ); + + /* Check toplevel dir, the pattern only works for toplevel dir. */ + rc = csync_excluded_traversal(csync->excludes, "/exclude", CSYNC_FTW_TYPE_DIR); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + rc = csync_excluded_traversal(csync->excludes, "/foo/exclude", CSYNC_FTW_TYPE_DIR); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + + /* check for a file called exclude. Must still work */ + rc = csync_excluded_traversal(csync->excludes, "/exclude", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + rc = csync_excluded_traversal(csync->excludes, "/foo/exclude", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + + /* Add an exclude for directories only: excl/ */ + _csync_exclude_add( &(csync->excludes), "excl/" ); + rc = csync_excluded_traversal(csync->excludes, "/excl", CSYNC_FTW_TYPE_DIR); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + rc = csync_excluded_traversal(csync->excludes, "meep/excl", CSYNC_FTW_TYPE_DIR); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + rc = csync_excluded_traversal(csync->excludes, "meep/excl/file", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); // because leading dirs aren't checked! + + rc = csync_excluded_traversal(csync->excludes, "/excl", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + + _csync_exclude_add(&csync->excludes, "/excludepath/withsubdir"); + + rc = csync_excluded_traversal(csync->excludes, "/excludepath/withsubdir", CSYNC_FTW_TYPE_DIR); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + rc = csync_excluded_traversal(csync->excludes, "/excludepath/withsubdir", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + rc = csync_excluded_traversal(csync->excludes, "/excludepath/withsubdir2", CSYNC_FTW_TYPE_DIR); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + + rc = csync_excluded_traversal(csync->excludes, "/excludepath/withsubdir/foo", CSYNC_FTW_TYPE_DIR); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); // because leading dirs aren't checked! } static void check_csync_pathes(void **state) @@ -170,8 +262,25 @@ rc = csync_excluded(csync, "meep/excl", CSYNC_FTW_TYPE_DIR); assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + rc = csync_excluded(csync, "meep/excl/file", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + rc = csync_excluded(csync, "/excl", CSYNC_FTW_TYPE_FILE); assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + + _csync_exclude_add(&csync->excludes, "/excludepath/withsubdir"); + + rc = csync_excluded(csync, "/excludepath/withsubdir", CSYNC_FTW_TYPE_DIR); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + rc = csync_excluded(csync, "/excludepath/withsubdir", CSYNC_FTW_TYPE_FILE); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); + + rc = csync_excluded(csync, "/excludepath/withsubdir2", CSYNC_FTW_TYPE_DIR); + assert_int_equal(rc, CSYNC_NOT_EXCLUDED); + + rc = csync_excluded(csync, "/excludepath/withsubdir/foo", CSYNC_FTW_TYPE_DIR); + assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST); } static void check_csync_is_windows_reserved_word() { @@ -190,7 +299,51 @@ assert_true(csync_is_windows_reserved_word("Z:")); assert_true(csync_is_windows_reserved_word("M:")); assert_true(csync_is_windows_reserved_word("m:")); +} + +static void check_csync_excluded_performance(void **state) +{ + CSYNC *csync = *state; + + const int N = 10000; + int totalRc = 0; + // Being able to use QElapsedTimer for measurement would be nice... + { + struct timeval before, after; + gettimeofday(&before, 0); + + for (int i = 0; i < N; ++i) { + totalRc += csync_excluded(csync, "/this/is/quite/a/long/path/with/many/components", CSYNC_FTW_TYPE_DIR); + totalRc += csync_excluded(csync, "/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/29", CSYNC_FTW_TYPE_FILE); + } + assert_int_equal(totalRc, CSYNC_NOT_EXCLUDED); // mainly to avoid optimization + + gettimeofday(&after, 0); + + const double total = (after.tv_sec - before.tv_sec) + + (after.tv_usec - before.tv_usec) / 1.0e6; + const double perCallMs = total / 2 / N * 1000; + printf("csync_excluded: %f ms per call\n", perCallMs); + } + + { + struct timeval before, after; + gettimeofday(&before, 0); + + for (int i = 0; i < N; ++i) { + totalRc += csync_excluded_traversal(csync->excludes, "/this/is/quite/a/long/path/with/many/components", CSYNC_FTW_TYPE_DIR); + totalRc += csync_excluded_traversal(csync->excludes, "/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/29", CSYNC_FTW_TYPE_FILE); + } + assert_int_equal(totalRc, CSYNC_NOT_EXCLUDED); // mainly to avoid optimization + + gettimeofday(&after, 0); + + const double total = (after.tv_sec - before.tv_sec) + + (after.tv_usec - before.tv_usec) / 1.0e6; + const double perCallMs = total / 2 / N * 1000; + printf("csync_excluded_traversal: %f ms per call\n", perCallMs); + } } int torture_run_tests(void) @@ -199,8 +352,10 @@ unit_test_setup_teardown(check_csync_exclude_add, setup, teardown), unit_test_setup_teardown(check_csync_exclude_load, setup, teardown), unit_test_setup_teardown(check_csync_excluded, setup_init, teardown), + unit_test_setup_teardown(check_csync_excluded_traversal, setup_init, teardown), unit_test_setup_teardown(check_csync_pathes, setup_init, teardown), unit_test_setup_teardown(check_csync_is_windows_reserved_word, setup_init, teardown), + unit_test_setup_teardown(check_csync_excluded_performance, setup_init, teardown), }; return run_tests(tests); diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/csync_tests/check_csync_log.c owncloud-client-2.1.1+dfsg/csync/tests/csync_tests/check_csync_log.c --- owncloud-client-1.8.1+dfsg/csync/tests/csync_tests/check_csync_log.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/csync_tests/check_csync_log.c 2016-02-09 15:07:08.000000000 +0000 @@ -119,7 +119,7 @@ int rc; csync_stat_t sb; mbchar_t *path; - path = c_utf8_to_locale("/tmp/check_csync1/cb_called"); + path = c_utf8_path_to_locale("/tmp/check_csync1/cb_called"); (void) state; /* unused */ @@ -131,7 +131,7 @@ rc = csync_set_log_callback(check_log_callback); assert_int_equal(rc, 0); - csync_log(1, __FUNCTION__, "rc = %d", rc); + csync_log(1, __func__, "rc = %d", rc); rc = _tstat(path, &sb); diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/csync_tests/check_csync_statedb_load.c owncloud-client-2.1.1+dfsg/csync/tests/csync_tests/check_csync_statedb_load.c --- owncloud-client-1.8.1+dfsg/csync/tests/csync_tests/check_csync_statedb_load.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/csync_tests/check_csync_statedb_load.c 2016-02-09 15:07:08.000000000 +0000 @@ -80,7 +80,7 @@ CSYNC *csync = *state; csync_stat_t sb; time_t modtime; - mbchar_t *testdb = c_utf8_to_locale(TESTDB); + mbchar_t *testdb = c_utf8_path_to_locale(TESTDB); int rc; /* statedb not written */ diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/csync_tests/check_csync_update.c owncloud-client-2.1.1+dfsg/csync/tests/csync_tests/check_csync_update.c --- owncloud-client-1.8.1+dfsg/csync/tests/csync_tests/check_csync_update.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/csync_tests/check_csync_update.c 2016-02-09 15:07:08.000000000 +0000 @@ -41,6 +41,12 @@ "modtime INTEGER(8)," "type INTEGER," "md5 VARCHAR(32)," + "fileid VARCHAR(128)," + "remotePerm VARCHAR(128)," + "filesize BIGINT," + "ignoredChildrenRemote INT," + "contentChecksum TEXT," + "contentChecksumTypeId INTEGER," "PRIMARY KEY(phash));"; rc = sqlite3_exec(db, sql, NULL, NULL, NULL); @@ -167,7 +173,6 @@ /* create a file stat, caller must free memory */ static csync_vio_file_stat_t* create_fstat(const char *name, ino_t inode, - nlink_t nlink, time_t mtime) { csync_vio_file_stat_t *fs = NULL; @@ -202,17 +207,10 @@ } fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE; - fs->device = 0; fs->size = 157459; fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; - if (nlink == 0) { - fs->nlink = 1; - } else { - fs->nlink = nlink; - } - fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT; if (mtime == 0) { @@ -248,7 +246,7 @@ csync_vio_file_stat_t *fs; int rc; - fs = create_fstat("file.txt", 0, 1, 1217597845); + fs = create_fstat("file.txt", 0, 1217597845); assert_non_null(fs); rc = _csync_detect_update(csync, @@ -277,7 +275,7 @@ csync_vio_file_stat_t *fs; int rc; - fs = create_fstat("file.txt", 0, 1, 1217597845); + fs = create_fstat("file.txt", 0, 1217597845); assert_non_null(fs); rc = _csync_detect_update(csync, @@ -304,7 +302,7 @@ csync_vio_file_stat_t *fs; int rc; - fs = create_fstat("file.txt", 0, 1, 42); + fs = create_fstat("file.txt", 0, 42); assert_non_null(fs); rc = _csync_detect_update(csync, @@ -332,7 +330,7 @@ csync_vio_file_stat_t *fs; int rc = 0; - fs = create_fstat("wurst.txt", 0, 1, 42); + fs = create_fstat("wurst.txt", 0, 42); assert_non_null(fs); csync_set_statedb_exists(csync, 1); @@ -363,7 +361,7 @@ csync_vio_file_stat_t *fs; int rc; - fs = create_fstat("file.txt", 42000, 1, 0); + fs = create_fstat("file.txt", 42000, 0); assert_non_null(fs); rc = _csync_detect_update(csync, @@ -383,38 +381,13 @@ csync_vio_file_stat_destroy(fs); } -static void check_csync_detect_update_nlink(void **state) -{ - CSYNC *csync = *state; - csync_file_stat_t *st; - csync_vio_file_stat_t *fs; - int rc; - - /* create vio file stat with nlink greater than 1 */ - fs = create_fstat("file.txt", 0, 7, 0); - assert_non_null(fs); - - /* add it to local tree */ - rc = _csync_detect_update(csync, - "/tmp/check_csync1/file.txt", - fs, - CSYNC_FTW_TYPE_FILE); - assert_int_equal(rc, 0); - - /* the instruction should be set to ignore */ - st = c_rbtree_node_data(csync->local.tree->root); - assert_int_equal(st->instruction, CSYNC_INSTRUCTION_IGNORE); - - csync_vio_file_stat_destroy(fs); -} - static void check_csync_detect_update_null(void **state) { CSYNC *csync = *state; csync_vio_file_stat_t *fs; int rc; - fs = create_fstat("file.txt", 0, 1, 0); + fs = create_fstat("file.txt", 0, 0); assert_non_null(fs); rc = _csync_detect_update(csync, @@ -467,7 +440,6 @@ unit_test_setup_teardown(check_csync_detect_update_db_eval, setup, teardown), unit_test_setup_teardown(check_csync_detect_update_db_rename, setup, teardown), unit_test_setup_teardown(check_csync_detect_update_db_new, setup, teardown_rm), - unit_test_setup_teardown(check_csync_detect_update_nlink, setup, teardown_rm), unit_test_setup_teardown(check_csync_detect_update_null, setup, teardown_rm), unit_test_setup_teardown(check_csync_ftw, setup_ftw, teardown_rm), diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/encoding_tests/check_encoding.c owncloud-client-2.1.1+dfsg/csync/tests/encoding_tests/check_encoding.c --- owncloud-client-1.8.1+dfsg/csync/tests/encoding_tests/check_encoding.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/encoding_tests/check_encoding.c 2016-02-09 15:07:08.000000000 +0000 @@ -18,13 +18,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "torture.h" - +#include #include "c_string.h" +#include "c_path.h" #ifdef _WIN32 #include #endif + static void setup(void **state) { int rc = 0; @@ -63,7 +65,7 @@ const char *exp_out = "\x48\xc3\xa4"; // UTF8 #endif - out = c_utf8_to_locale(in); + out = c_utf8_path_to_locale(in); assert_string_equal(out, exp_out); c_free_locale_string(out); @@ -125,8 +127,8 @@ { int rc = -1; - mbchar_t *mb_string = c_utf8_to_locale( TESTSTRING ); - mbchar_t *mb_null = c_utf8_to_locale( NULL ); + mbchar_t *mb_string = c_utf8_path_to_locale( TESTSTRING ); + mbchar_t *mb_null = c_utf8_path_to_locale( NULL ); (void) state; @@ -142,13 +144,78 @@ c_free_locale_string(mb_null); } +static void check_long_win_path(void **state) +{ + (void) state; /* unused */ + + { + const char *path = "C://DATA/FILES/MUSIC/MY_MUSIC.mp3"; // check a short path + const char *exp_path = "\\\\?\\C:\\\\DATA\\FILES\\MUSIC\\MY_MUSIC.mp3"; + const char *new_short = c_path_to_UNC(path); + assert_string_equal(new_short, exp_path); + SAFE_FREE(new_short); + } + + { + const char *path = "\\\\foo\\bar/MY_MUSIC.mp3"; + const char *exp_path = "\\\\foo\\bar\\MY_MUSIC.mp3"; + const char *new_short = c_path_to_UNC(path); + assert_string_equal(new_short, exp_path); + SAFE_FREE(new_short); + } + + { + const char *path = "//foo\\bar/MY_MUSIC.mp3"; + const char *exp_path = "\\\\foo\\bar\\MY_MUSIC.mp3"; + const char *new_short = c_path_to_UNC(path); + assert_string_equal(new_short, exp_path); + SAFE_FREE(new_short); + } + + { + const char *path = "\\foo\\bar"; + const char *exp_path = "\\\\?\\foo\\bar"; + const char *new_short = c_path_to_UNC(path); + assert_string_equal(new_short, exp_path); + SAFE_FREE(new_short); + } + + { + const char *path = "/foo/bar"; + const char *exp_path = "\\\\?\\foo\\bar"; + const char *new_short = c_path_to_UNC(path); + assert_string_equal(new_short, exp_path); + SAFE_FREE(new_short); + } + + const char *longPath = "D://alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/" + "elonglonglonglong/flonglonglonglong/glonglonglonglong/hlonglonglonglong/ilonglonglonglong/" + "jlonglonglonglong/klonglonglonglong/llonglonglonglong/mlonglonglonglong/nlonglonglonglong/" + "olonglonglonglong/file.txt"; + const char *longPathConv = "\\\\?\\D:\\\\alonglonglonglong\\blonglonglonglong\\clonglonglonglong\\dlonglonglonglong\\" + "elonglonglonglong\\flonglonglonglong\\glonglonglonglong\\hlonglonglonglong\\ilonglonglonglong\\" + "jlonglonglonglong\\klonglonglonglong\\llonglonglonglong\\mlonglonglonglong\\nlonglonglonglong\\" + "olonglonglonglong\\file.txt"; + + const char *new_long = c_path_to_UNC(longPath); + // printf( "XXXXXXXXXXXX %s %d\n", new_long, mem_reserved); + + assert_string_equal(new_long, longPathConv); + + // printf( "YYYYYYYYYYYY %ld\n", strlen(new_long)); + assert_int_equal( strlen(new_long), 286); + SAFE_FREE(new_long); +} + int torture_run_tests(void) { const UnitTest tests[] = { + unit_test_setup_teardown(check_long_win_path, setup, teardown), unit_test_setup_teardown(check_to_multibyte, setup, teardown), unit_test_setup_teardown(check_iconv_ascii, setup, teardown), unit_test_setup_teardown(check_iconv_to_native_normalization, setup, teardown), unit_test_setup_teardown(check_iconv_from_native_normalization, setup, teardown), + }; return run_tests(tests); diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/httpbf_tests/hbf_send_test.c owncloud-client-2.1.1+dfsg/csync/tests/httpbf_tests/hbf_send_test.c --- owncloud-client-1.8.1+dfsg/csync/tests/httpbf_tests/hbf_send_test.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/httpbf_tests/hbf_send_test.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,241 +0,0 @@ -/* - * libcsync -- a library to sync a directory with another - * - * Copyright (c) 2013 by Klaas Freitag - * - * 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 - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "config_test.h" - -#if USE_NEON -#include "httpbf.c" -#endif - -// A test case that does nothing and succeeds. -static void null_test_success(void **state) { - (void) state; -} - -#if USE_NEON - -static char* test_file( const char* name ) { - char path[260]; - - if( ! name ) return 0; - - strcpy( path, TESTFILES_DIR); - if(path[strlen(TESTFILES_DIR)-1] != '/') - strcat( path, "/"); - strcat( path, name ); - - return strdup(path); -} - -static void test_get_transfer_url( void **state ) { - const char *url = "http://example.org/owncloud"; - const char *turl = NULL; - int fd; - Hbf_State hbf_state; - - hbf_transfer_t *list = NULL; - - (void) state; - list = hbf_init_transfer( url ); - assert_non_null( list ); - - /* open a file */ - fd = open( test_file("church.jpg"), O_RDONLY ); - assert_true(fd >= 0); - - hbf_state = hbf_splitlist(list, fd); - assert_true( hbf_state == HBF_SUCCESS); - assert_true( list->block_cnt == 1); - - turl = get_transfer_url( list, 0 ); - assert_non_null( turl ); - assert_string_equal( url, turl ); - - hbf_free_transfer( list ); -} - - -static void test_get_transfer_url_bigfile( void **state ) { - const char *url = "http://example.org/big_file"; - const char *turl = NULL; - char res[256]; - int i, fd; - Hbf_State hbf_state; - hbf_transfer_t *list = NULL; - - (void) state; - - list = hbf_init_transfer( url ); - assert_non_null( list ); - - list->threshold = list->block_size = (1024*1024); /* block size 1 MB */ - - /* open a file */ - fd = open( test_file("church.jpg"), O_RDONLY ); - assert_true(fd >= 0); - - hbf_state = hbf_splitlist(list, fd); - assert_true( hbf_state == HBF_SUCCESS); - assert_true( list->block_cnt == 2 ); - - for( i=0; i < list->block_cnt; i++ ) { - turl = get_transfer_url( list, i ); - assert_non_null(turl); - - sprintf(res, "%s-chunking-%u-%u-%u", url, list->transfer_id, - list->block_cnt, i ); - /* printf( "XX: %s\n", res ); */ - assert_string_equal( turl, res ); - } - hbf_free_transfer(list); -} - -static void test_hbf_init_transfer( void **state ) { - hbf_transfer_t *list = NULL; - const char *url = "http://example.org/owncloud"; - - (void) state; - - list = hbf_init_transfer( url ); - assert_non_null( list ); - assert_string_equal( url, list->url ); -} - -/* test with a file size that is not a multiply of the slize size. */ -static void test_hbf_splitlist_odd( void **state ){ - - hbf_transfer_t *list = NULL; - const char *dest_url = "http://localhost/ocm/remote.php/webdav/big/church.jpg"; - int prev_id = 0; - int i, fd; - Hbf_State hbf_state; - - (void) state; - - /* open a file */ - fd = open(test_file("church.jpg"), O_RDONLY); - assert_true(fd >= 0); - - /* do a smoke test for uniqueness */ - for( i=0; i < 10000; i++) { - list = hbf_init_transfer(dest_url); - assert_non_null(list); - usleep(1); - hbf_state = hbf_splitlist(list, fd); - - assert_int_not_equal(list->transfer_id, prev_id); - prev_id = list->transfer_id; - hbf_free_transfer(list); - } - - list = hbf_init_transfer(dest_url); - assert_non_null(list); - - hbf_state = hbf_splitlist(list, fd); - assert_non_null(list); -#ifndef NDEBUG - assert_int_equal(list->calc_size, list->stat_size); -#endif - assert_int_not_equal(list->block_cnt, 0); - assert_true( hbf_state == HBF_SUCCESS); - - /* checks on the block list */ - if( 1 ) { - int seen_zero_seq = 0; - int prev_seq = -1; - int64_t prev_block_end = -1; - - for( i=0; i < list->block_cnt; i++) { - hbf_block_t *blk = list->block_arr[i]; - assert_non_null(blk); - if( blk->seq_number == 0 ) seen_zero_seq++; - - assert_int_equal(prev_seq, blk->seq_number -1 ); - prev_seq = blk->seq_number; - - assert_true((prev_block_end+1) == (blk->start)); - prev_block_end = blk->start + blk->size; - } - /* Make sure we exactly saw blk->seq_number == 0 exactly one times */ - assert_int_equal( seen_zero_seq, 1 ); - } - hbf_free_transfer( list ); -} - -/* test with a file size that is not a multiply of the slize size. */ -static void test_hbf_splitlist_zero( void **state ){ - - hbf_transfer_t *list = NULL; - const char *dest_url = "http://localhost/ocm/remote.php/webdav/big/zerofile.txt"; - int fd; - Hbf_State hbf_state; - - (void) state; - - /* open a file */ - fd = open(test_file("zerofile.txt"), O_RDONLY); - assert_true(fd >= 0); - - list = hbf_init_transfer(dest_url); - assert_non_null(list); - - hbf_state = hbf_splitlist(list, fd); - assert_non_null(list); - assert_int_equal(list->stat_size, 0); -#ifndef NDEBUG - assert_int_equal(list->calc_size, list->stat_size); -#endif - assert_int_equal(list->block_cnt, 1); - - assert_true( hbf_state == HBF_SUCCESS); - - hbf_free_transfer( list ); -} - -#endif - - -int main(void) { - const UnitTest tests[] = { - unit_test(null_test_success), -#if USE_NEON - unit_test(test_hbf_splitlist_odd), - unit_test(test_hbf_splitlist_zero), - unit_test(test_hbf_init_transfer), - unit_test(test_get_transfer_url), - unit_test(test_get_transfer_url_bigfile) -#endif - }; - return run_tests(tests); -} - diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/ownCloud/ownCloud/Test.pm owncloud-client-2.1.1+dfsg/csync/tests/ownCloud/ownCloud/Test.pm --- owncloud-client-1.8.1+dfsg/csync/tests/ownCloud/ownCloud/Test.pm 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/ownCloud/ownCloud/Test.pm 2016-02-09 15:07:08.000000000 +0000 @@ -66,7 +66,7 @@ assertLocalDirs assertLocalAndRemoteDir glob_put put_to_dir putToDirLWP localDir remoteDir localCleanup createLocalFile md5OfFile remoteCleanup server initLocalDir initRemoteDir moveRemoteFile - printInfo remoteFileId createShare removeShare assert + printInfo remoteFileProp remoteFileId createShare removeShare assert configValue testDirUrl getToFileLWP getToFileCurl); sub server @@ -124,7 +124,8 @@ $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0 } - $d = HTTP::DAV->new(); + my $ua = HTTP::DAV::UserAgent->new(keep_alive => 1 ); + $d = HTTP::DAV->new(-useragent => $ua); $d->credentials( -url=> $owncloud, -realm=>"ownCloud", -user=> $user, @@ -191,7 +192,6 @@ my ($dir, $optionsRef) = @_; my $url = testDirUrl() . $dir; - if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) { $d->credentials( -url=> $owncloud, -realm=>"ownCloud", -user=> $optionsRef->{user}, @@ -326,11 +326,11 @@ opendir(my $dh, $dir1 ) || die; while(readdir $dh) { - assert( -e "$dir2/$_" ); + assert( -e "$dir2/$_", " $dir2/$_ do not exist" ); next if( -d "$dir1/$_"); # don't compare directory sizes. my $s1 = -s "$dir1/$_"; my $s2 = -s "$dir2/$_"; - assert( $s1 == $s2, "$dir1/$_ <-> $dir2/$_" ); + assert( $s1 == $s2, "$dir1/$_ <-> $dir2/$_ size not equal ($s1 != $s2)" ); } closedir $dh; } @@ -524,7 +524,9 @@ my $filename = $file; $filename =~ s/^.*\///; + $filename =~ s/#/%23/g; # poor man's URI encoder my $puturl = $targetUrl . $dir. $filename; + print "put_to_dir puts to $puturl\n"; unless ($d->put( -local => $file, -url => $puturl )) { print " ### FAILED to put a single file!\n"; @@ -677,28 +679,38 @@ $infoCnt++; } -sub remoteFileId($$) +sub remoteFileProp($$) { my ($fromDir, $file) = @_; my $fromUrl = testDirUrl() . $fromDir; - my $id; + my $result; if( my $r = $d->propfind( -url => $fromUrl, -depth => 1 ) ) { if ( $r->is_collection ) { # print "Collection\n"; foreach my $res ( $r->get_resourcelist->get_resources() ) { - my $filename = $res->get_property("rel_uri"); - # print "OOOOOOOOOOOOOO $filename " . $res->get_property('id') . "\n"; - if( $file eq $filename || $filename eq $file . "/" ) { - $id = $res->get_property('id') || ""; - } + my $filename = $res->get_property("rel_uri"); + # print "OOOOOOOOOOOOOO $filename " . $res->get_property('id') . "\n"; + if( $file eq $filename || $filename eq $file . "/" ) { + $result = $res; + } } } else { # print "OOOOOOOOOOOOOOOOOOO " . $r->get_property("rel_uri"); - $id = $r->get_property('id') || ""; + $result = $r; } } + return $result; +} + +sub remoteFileId($$) +{ + my ($fromDir, $file) = @_; + my $id; + if( my $res = remoteFileProp($fromDir, $file) ) { + $id = $res->get_property('id') || ""; + } print "## ID of $file: $id\n"; return $id; } diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/ownCloud/t4.pl owncloud-client-2.1.1+dfsg/csync/tests/ownCloud/t4.pl --- owncloud-client-1.8.1+dfsg/csync/tests/ownCloud/t4.pl 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/ownCloud/t4.pl 2016-02-09 15:07:08.000000000 +0000 @@ -29,7 +29,16 @@ use strict; -print "Hello, this is t4, a tester for A) files that cannot be stated and B) excluded files\n"; +sub getInode($) +{ + my ($filename) = @_; + my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, + $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename); + + return $ino; +} + +print "Hello, this is t4, a tester for A) files that cannot be stated and B) excluded files C) hard links\n"; # stat error occours on windsows when the file is busy for example initTesting(); @@ -167,6 +176,48 @@ assert(! -e localDir(). 'anotherdir' ); +printInfo("Test hardlinks\n"); +#make a hard link +mkdir( localDir() . 'subdir' ); +createLocalFile( localDir() .'subdir/original.data', 1568 ); +system( "ln " . localDir() . 'subdir/original.data ' . localDir() . 'file.link'); +csync(); +assertLocalAndRemoteDir( '', 0 ); +my $inode = getInode(localDir() . 'subdir/original.data'); +my $inode2 = getInode(localDir() . 'file.link'); +assert( $inode == $inode2, "Inode is not the same!"); + + +printInfo("Modify hard link\n"); +system( "echo 'another line' >> " . localDir() . 'file.link'); +csync(); +assertLocalAndRemoteDir( '', 0 ); +my $inode1 = getInode(localDir() .'subdir/original.data'); +$inode2 = getInode( localDir() .'file.link'); +assert( $inode == $inode1, "Inode is not the same!"); +assert( $inode == $inode2, "Inode is not the same!"); + + +printInfo("Rename a hard link\n"); +move( localDir() . 'subdir/original.data', localDir() . 'subdir/kernelcrash.txt' ); +csync(); +assertLocalAndRemoteDir( '', 0 ); +$inode1 = getInode(localDir() .'subdir/kernelcrash.txt'); +$inode2 = getInode(localDir() .'file.link'); +assert( $inode == $inode1, "Inode is not the same!"); +assert( $inode == $inode2, "Inode is not the same!"); + +printInfo("Modify a hard link on the server\n"); +put_to_dir( '/tmp/kernelcrash.txt', 'subdir' ); +csync(); +assertLocalAndRemoteDir( '', 0 ); +$inode1 = getInode(localDir() .'subdir/kernelcrash.txt'); +$inode2 = getInode( localDir() .'file.link'); +# only the first inode must change +print(" $inode $inode1 $inode2" ); +assert( $inode != $inode1, "Inode did not change"); +assert( $inode == $inode2, "Inode is not the same!"); + cleanup(); # -- diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/ownCloud/t9.pl owncloud-client-2.1.1+dfsg/csync/tests/ownCloud/t9.pl --- owncloud-client-1.8.1+dfsg/csync/tests/ownCloud/t9.pl 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/ownCloud/t9.pl 2016-02-09 15:07:08.000000000 +0000 @@ -0,0 +1,91 @@ +#!/usr/bin/perl +# +# Test script for the ownCloud module of csync. +# This script requires a running ownCloud instance accessible via HTTP. +# It does quite some fancy tests and asserts the results. +# +# Copyright (C) by Klaas Freitag +# +# 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 +# + +use lib "."; + +use File::Copy; +use ownCloud::Test; + +use strict; + +print "Hello, this is t9, a tester for content checksums.\n"; + +initTesting(); + +printInfo( "Add some files to local"); +my $locDir = localDir(); +copy( "testfiles/test.txt", "$locDir/test.txt"); +copy( "testfiles/test.txt", "$locDir/test.eml"); + +csync( ); +print "\nAssert local and remote dirs.\n"; +assertLocalAndRemoteDir( '', 0); + +# Get file properties before syncing again +my $txtpropbefore = remoteFileProp("", "test.txt"); +my $emlpropbefore = remoteFileProp("", "test.eml"); +assert($txtpropbefore); +assert($emlpropbefore); + +printInfo( "Touch local files"); +system( "touch $locDir/test.txt" ); +system( "touch $locDir/test.eml" ); + +csync( ); + +# Get file properties afterwards +my $txtpropafter = remoteFileProp("", "test.txt"); +my $emlpropafter = remoteFileProp("", "test.eml"); +assert($txtpropafter); +assert($emlpropafter); + +# The txt file is uploaded normally, etag and mtime differ +assert($txtpropafter->get_property( "getetag" ) ne + $txtpropbefore->get_property( "getetag" )); +assert($txtpropafter->get_property( "getlastmodified" ) ne + $txtpropbefore->get_property( "getlastmodified" )); +# The eml was not uploaded, nothing differs +assert($emlpropafter->get_property( "getetag" ) eq + $emlpropbefore->get_property( "getetag" )); +assert($emlpropafter->get_property( "getlastmodified" ) eq + $emlpropbefore->get_property( "getlastmodified" )); + +printInfo( "Change content of eml file (but not size)"); +system( "sed -i -e 's/in/IN/' $locDir/test.eml" ); + +csync( ); + +# Get file properties afterwards +my $emlpropchanged = remoteFileProp("", "test.eml"); +assert($emlpropchanged); +assert($emlpropafter->get_property( "getetag" ) ne + $emlpropchanged->get_property( "getetag" )); +assert($emlpropafter->get_property( "getlastmodified" ) ne + $emlpropchanged->get_property( "getlastmodified" )); + +# ================================================================== + +cleanup(); + +# -- + diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/ownCloud/t_recall.pl owncloud-client-2.1.1+dfsg/csync/tests/ownCloud/t_recall.pl --- owncloud-client-1.8.1+dfsg/csync/tests/ownCloud/t_recall.pl 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/ownCloud/t_recall.pl 2016-02-09 15:07:08.000000000 +0000 @@ -0,0 +1,85 @@ +#!/usr/bin/perl +# +# Test script for the ownCloud module of csync. +# This script requires a running ownCloud instance accessible via HTTP. +# It does quite some fancy tests and asserts the results. +# +# Copyright (C) by Olivier Goffart +# +# 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 +# + +use lib "."; + + +use File::Copy; +use ownCloud::Test; + +use strict; + +print "Hello, this is t_recall, a tester for the recall feature\n"; + +initTesting(); + +printInfo( "Syncing two files with the same name that differ with case" ); + +#create some files +my $tmpdir = "/tmp/t_recall/"; +mkdir($tmpdir); +createLocalFile( $tmpdir . "file1.dat", 100 ); +createLocalFile( $tmpdir . "file2.dat", 150 ); +createLocalFile( $tmpdir . "file3.dat", 110 ); +createLocalFile( $tmpdir . "file4.dat", 170 ); + +#put them in some directories +createRemoteDir( "dir" ); +glob_put( "$tmpdir/*", "dir" ); + +csync(); + +assertLocalAndRemoteDir( '', 0); + + + +printInfo( "Testing with a .sys.admin#recall#" ); +system("echo 'dir/file2.dat' > ". $tmpdir . ".sys.admin\#recall\#"); +system("echo 'dir/file3.dat' >> ". $tmpdir . ".sys.admin\#recall\#"); +glob_put( "$tmpdir/.sys.admin\#recall\#", "" ); + +csync(); + +#test that the recall files have been created +assert( -e glob(localDir().'dir/file2_.sys.admin#recall#-*.dat' ) ); +assert( -e glob(localDir().'dir/file3_.sys.admin#recall#-*.dat' ) ); + +#Remove the recall file +unlink(localDir() . ".sys.admin#recall#"); + +# 2 sync necessary for the recall to be uploaded +csync(); + +assertLocalAndRemoteDir( '', 0); + +printInfo( "Testing with a dir/.sys.admin#recall#" ); +system("echo 'file4.dat' > ". $tmpdir . ".sys.admin\#recall\#"); +glob_put( "$tmpdir/.sys.admin\#recall\#", "dir" ); + +csync(); +assert( -e glob(localDir().'dir/file4_.sys.admin#recall#-*.dat' ) ); + + +cleanup(); +system("rm -r " . $tmpdir); + diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/vio_tests/check_vio.c owncloud-client-2.1.1+dfsg/csync/tests/vio_tests/check_vio.c --- owncloud-client-1.8.1+dfsg/csync/tests/vio_tests/check_vio.c 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/vio_tests/check_vio.c 2016-02-09 15:07:08.000000000 +0000 @@ -59,7 +59,7 @@ static void setup_dir(void **state) { int rc; - mbchar_t *dir = c_utf8_to_locale(CSYNC_TEST_DIR); + mbchar_t *dir = c_utf8_path_to_locale(CSYNC_TEST_DIR); setup(state); @@ -73,15 +73,6 @@ assert_int_equal(rc, 0); } -static void setup_file(void **state) { - int rc; - - setup_dir(state); - - rc = system("echo \"This is a test\" > /tmp/csync_test/file.txt"); - assert_int_equal(rc, 0); -} - static void teardown(void **state) { CSYNC *csync = *state; int rc; @@ -121,7 +112,7 @@ CSYNC *csync = *state; csync_vio_handle_t *dh; int rc; - mbchar_t *dir = c_utf8_to_locale(CSYNC_TEST_DIR); + mbchar_t *dir = c_utf8_path_to_locale(CSYNC_TEST_DIR); assert_non_null(dir); @@ -164,46 +155,6 @@ } -/* - * Test for general functions (stat, chmod, chown, ...) - */ - -static void check_csync_vio_stat_dir(void **state) -{ - CSYNC *csync = *state; - csync_vio_file_stat_t *fs; - int rc; - - fs = csync_vio_file_stat_new(); - assert_non_null(fs); - - rc = csync_vio_stat(csync, CSYNC_TEST_DIR, fs); - assert_int_equal(rc, 0); - - assert_string_equal(fs->name, "csync_test"); - assert_int_equal(fs->type, CSYNC_VIO_FILE_TYPE_DIRECTORY); - - csync_vio_file_stat_destroy(fs); -} - -static void check_csync_vio_stat_file(void **state) -{ - CSYNC *csync = *state; - csync_vio_file_stat_t *fs; - int rc; - - fs = csync_vio_file_stat_new(); - assert_non_null(fs); - - rc = csync_vio_stat(csync, CSYNC_TEST_FILE, fs); - assert_int_equal(rc, 0); - - assert_string_equal(fs->name, "file.txt"); - assert_int_equal(fs->type, CSYNC_VIO_FILE_TYPE_REGULAR); - - csync_vio_file_stat_destroy(fs); -} - int torture_run_tests(void) { const UnitTest tests[] = { @@ -211,9 +162,6 @@ unit_test_setup_teardown(check_csync_vio_opendir_perm, setup, teardown), unit_test(check_csync_vio_closedir_null), unit_test_setup_teardown(check_csync_vio_readdir, setup_dir, teardown), - - unit_test_setup_teardown(check_csync_vio_stat_dir, setup_dir, teardown), - unit_test_setup_teardown(check_csync_vio_stat_file, setup_file, teardown), }; return run_tests(tests); diff -Nru owncloud-client-1.8.1+dfsg/csync/tests/vio_tests/check_vio_ext.c owncloud-client-2.1.1+dfsg/csync/tests/vio_tests/check_vio_ext.c --- owncloud-client-1.8.1+dfsg/csync/tests/vio_tests/check_vio_ext.c 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/csync/tests/vio_tests/check_vio_ext.c 2016-02-09 15:07:08.000000000 +0000 @@ -0,0 +1,474 @@ +/* + * libcsync -- a library to sync a directory with another + * + * Copyright (c) 2015-2013 by Klaas Freitag + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "torture.h" + +#include "csync_private.h" +#include "vio/csync_vio.h" + +#ifdef _WIN32 +#include + +#define CSYNC_TEST_DIR "C:/tmp/csync_test" +#else +#define CSYNC_TEST_DIR "/tmp/csync_test" +#endif +#define MKDIR_MASK (S_IRWXU |S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) + +#define WD_BUFFER_SIZE 255 + +static mbchar_t wd_buffer[WD_BUFFER_SIZE]; + +typedef struct { + CSYNC *csync; + char *result; + char *ignored_dir; +} statevar; + +/* remove the complete test dir */ +static int wipe_testdir() +{ + int rc = 0; + +#ifdef _WIN32 + /* The windows system call to rd bails out if the dir is not existing + * Check first. + */ + WIN32_FIND_DATA FindFileData; + + mbchar_t *dir = c_utf8_path_to_locale(CSYNC_TEST_DIR); + HANDLE handle = FindFirstFile(dir, &FindFileData); + c_free_locale_string(dir); + int found = handle != INVALID_HANDLE_VALUE; + + if(found) { + FindClose(handle); + rc = system("rd /s /q C:\\tmp\\csync_test"); + } +#else + rc = system("rm -rf /tmp/csync_test/"); +#endif + return rc; +} + +static void setup_testenv(void **state) { + int rc; + + rc = wipe_testdir(); + assert_int_equal(rc, 0); + + mbchar_t *dir = c_utf8_path_to_locale(CSYNC_TEST_DIR); + + rc = _tmkdir(dir, MKDIR_MASK); + assert_int_equal(rc, 0); + + assert_non_null(_tgetcwd(wd_buffer, WD_BUFFER_SIZE)); + + rc = _tchdir(dir); + assert_int_equal(rc, 0); + + c_free_locale_string(dir); + + /* --- initialize csync */ + statevar *mystate = malloc( sizeof(statevar) ); + mystate->result = NULL; + + rc = csync_create(&(mystate->csync), "/tmp/csync1", "/tmp/csync2"); + assert_int_equal(rc, 0); + + mystate->csync->replica = LOCAL_REPLICA; + + *state = mystate; +} + +static void output( const char *text ) +{ + mbchar_t *wtext = c_utf8_string_to_locale(text); + + #ifdef _WIN32 + wprintf(L"OOOO %ls (%ld)\n", wtext, strlen(text)); + #else + printf("%s\n", wtext); + #endif + c_free_locale_string(wtext); +} + +static void teardown(void **state) { + statevar *sv = (statevar*) *state; + CSYNC *csync = sv->csync; + int rc; + + output("================== Tearing down!\n"); + + rc = csync_destroy(csync); + assert_int_equal(rc, 0); + + rc = _tchdir(wd_buffer); + assert_int_equal(rc, 0); + + rc = wipe_testdir(); + assert_int_equal(rc, 0); + + *state = NULL; +} + +/* This function takes a relative path, prepends it with the CSYNC_TEST_DIR + * and creates each sub directory. + */ +static void create_dirs( const char *path ) +{ + int rc; + char *mypath = c_malloc( 2+strlen(CSYNC_TEST_DIR)+strlen(path)); + *mypath = '\0'; + strcat(mypath, CSYNC_TEST_DIR); + strcat(mypath, "/"); + strcat(mypath, path); + + char *p = mypath+strlen(CSYNC_TEST_DIR)+1; /* start behind the offset */ + int i = 0; + + assert_non_null(path); + + while( *(p+i) ) { + if( *(p+i) == '/' ) { + p[i] = '\0'; + + mbchar_t *mb_dir = c_utf8_path_to_locale(mypath); + /* wprintf(L"OOOO %ls (%ld)\n", mb_dir, strlen(mypath)); */ + rc = _tmkdir(mb_dir, MKDIR_MASK); + c_free_locale_string(mb_dir); + + assert_int_equal(rc, 0); + p[i] = '/'; + } + i++; + } + SAFE_FREE(mypath); +} + +/* + * This function uses the vio_opendir, vio_readdir and vio_closedir functions + * to traverse a file tree that was created before by the create_dir function. + * + * It appends a listing to the result member of the incoming struct in *state + * that can be compared later to what was expected in the calling functions. + * + * The int parameter cnt contains the number of seen files (not dirs) in the + * whole tree. + * + */ +static void traverse_dir(void **state, const char *dir, int *cnt) +{ + csync_vio_handle_t *dh; + csync_vio_file_stat_t *dirent; + statevar *sv = (statevar*) *state; + CSYNC *csync = sv->csync; + char *subdir; + char *subdir_out; + int rc; + int is_dir; + + /* Format: Smuggle in the C: for unix platforms as its urgently needed + * on Windows and the test can be nicely cross platform this way. */ +#ifdef _WIN32 + const char *format_str = "%s %s"; +#else + const char *format_str = "%s C:%s"; +#endif + + dh = csync_vio_opendir(csync, dir); + assert_non_null(dh); + + while( (dirent = csync_vio_readdir(csync, dh)) ) { + assert_non_null(dirent); + if (dirent->original_name) { + sv->ignored_dir = c_strdup(dirent->original_name); + continue; + } + + assert_non_null(dirent->name); + assert_int_equal( dirent->fields & CSYNC_VIO_FILE_STAT_FIELDS_TYPE, CSYNC_VIO_FILE_STAT_FIELDS_TYPE ); + + if( c_streq( dirent->name, "..") || c_streq( dirent->name, "." )) { + continue; + } + + is_dir = (dirent->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) ? 1:0; + + assert_int_not_equal( asprintf( &subdir, "%s/%s", dir, dirent->name ), -1 ); + + assert_int_not_equal( asprintf( &subdir_out, format_str, + is_dir ? "":" ", + subdir), -1 ); + + if( is_dir ) { + if( !sv->result ) { + sv->result = c_strdup( subdir_out); + } else { + int newlen = 1+strlen(sv->result)+strlen(subdir_out); + char *tmp = sv->result; + sv->result = c_malloc(newlen); + strcpy( sv->result, tmp); + SAFE_FREE(tmp); + + strcat( sv->result, subdir_out ); + } + } else { + *cnt = *cnt +1; + } + output(subdir_out); + if( is_dir ) { + traverse_dir( state, subdir, cnt); + } + + SAFE_FREE(subdir); + SAFE_FREE(subdir_out); + } + + csync_vio_file_stat_destroy(dirent); + rc = csync_vio_closedir(csync, dh); + assert_int_equal(rc, 0); + +} + +static void create_file( const char *path, const char *name, const char *content) +{ +#ifdef _WIN32 + + char *filepath = c_malloc( 2+strlen(CSYNC_TEST_DIR)+strlen(path) + strlen(name) ); + *filepath = '\0'; + strcpy(filepath, CSYNC_TEST_DIR); + strcat(filepath, "/"); + strcat(filepath, path); + strcat(filepath, name); + + DWORD dwWritten; // number of bytes written to file + HANDLE hFile; + + mbchar_t *w_fname = c_utf8_path_to_locale(filepath); + + hFile=CreateFile(w_fname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + + assert_int_equal( 0, hFile==INVALID_HANDLE_VALUE ); + + int len = strlen(content); + mbchar_t *dst = NULL; + + dst = c_utf8_string_to_locale(content); + WriteFile(hFile, dst, len * sizeof(mbchar_t), &dwWritten, 0); + + CloseHandle(hFile); + SAFE_FREE(dst); + c_free_locale_string(w_fname); +#else + char *filepath = c_malloc( 1+strlen(path) + strlen(name) ); + *filepath = '\0'; + + strcpy(filepath, path); + strcat(filepath, name); + + FILE *sink; + sink = fopen(filepath,"w"); + + fprintf (sink, "we got: %s",content); + fclose(sink); + SAFE_FREE(filepath); +#endif + +} + +static void check_readdir_shorttree(void **state) +{ + statevar *sv = (statevar*) *state; + + const char *t1 = "alibaba/und/die/vierzig/räuber/"; + create_dirs( t1 ); + int files_cnt = 0; + + traverse_dir(state, CSYNC_TEST_DIR, &files_cnt); + + assert_string_equal( sv->result, + " C:/tmp/csync_test/alibaba" + " C:/tmp/csync_test/alibaba/und" + " C:/tmp/csync_test/alibaba/und/die" + " C:/tmp/csync_test/alibaba/und/die/vierzig" + " C:/tmp/csync_test/alibaba/und/die/vierzig/räuber" ); + assert_int_equal(files_cnt, 0); +} + +static void check_readdir_with_content(void **state) +{ + statevar *sv = (statevar*) *state; + int files_cnt = 0; + + const char *t1 = "warum/nur/40/Räuber/"; + create_dirs( t1 ); + + create_file( t1, "Räuber Max.txt", "Der Max ist ein schlimmer finger"); + create_file( t1, "пя́тница.txt", "Am Freitag tanzt der Ürk"); + + + traverse_dir(state, CSYNC_TEST_DIR, &files_cnt); + + assert_string_equal( sv->result, + " C:/tmp/csync_test/warum" + " C:/tmp/csync_test/warum/nur" + " C:/tmp/csync_test/warum/nur/40" + " C:/tmp/csync_test/warum/nur/40/Räuber"); + /* " C:/tmp/csync_test/warum/nur/40/Räuber/Räuber Max.txt" + " C:/tmp/csync_test/warum/nur/40/Räuber/пя́тница.txt"); */ + assert_int_equal(files_cnt, 2); /* Two files in the sub dir */ +} + +static void check_readdir_longtree(void **state) +{ + statevar *sv = (statevar*) *state; + + /* Strange things here: Compilers only support strings with length of 4k max. + * The expected result string is longer, so it needs to be split up in r1, r2 and r3 + */ + + /* create the test tree */ + const char *t1 = "vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen/VierZig/MannaufDesTotenManns/KISTE/ooooooooooooooooooooooooooohhhhhh/und/BESSER/ZWEI/Butteln/VOLL RUM/"; + create_dirs( t1 ); + + const char *r1 = +" C:/tmp/csync_test/vierzig" +" C:/tmp/csync_test/vierzig/mann" +" C:/tmp/csync_test/vierzig/mann/auf" +" C:/tmp/csync_test/vierzig/mann/auf/des" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum"; + + + const char *r2 = +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH"; + + + const char *r3 = +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen/VierZig" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen/VierZig/MannaufDesTotenManns" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen/VierZig/MannaufDesTotenManns/KISTE" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen/VierZig/MannaufDesTotenManns/KISTE/ooooooooooooooooooooooooooohhhhhh" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen/VierZig/MannaufDesTotenManns/KISTE/ooooooooooooooooooooooooooohhhhhh/und" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen/VierZig/MannaufDesTotenManns/KISTE/ooooooooooooooooooooooooooohhhhhh/und/BESSER" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen/VierZig/MannaufDesTotenManns/KISTE/ooooooooooooooooooooooooooohhhhhh/und/BESSER/ZWEI" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen/VierZig/MannaufDesTotenManns/KISTE/ooooooooooooooooooooooooooohhhhhh/und/BESSER/ZWEI/Butteln" +" C:/tmp/csync_test/vierzig/mann/auf/des/toten/Mann/kiste/ooooooooooooooooooooooh/and/ne/bottle/voll/rum/und/so/singen/wir/VIERZIG/MANN/AUF/DES/TOTEN/MANNS/KISTE/OOOOOOOOH/AND/NE/BOTTLE/VOLL/RUM/undnochmalallezusammen/VierZig/MannaufDesTotenManns/KISTE/ooooooooooooooooooooooooooohhhhhh/und/BESSER/ZWEI/Butteln/VOLL RUM"; + + /* assemble the result string ... */ + int overall_len = 1+strlen(r1)+strlen(r2)+strlen(r3); + int files_cnt = 0; + char *result = c_malloc(overall_len); + *result = '\0'; + + strcat(result, r1); + strcat(result, r2); + strcat(result, r3); + + traverse_dir(state, CSYNC_TEST_DIR, &files_cnt); + assert_int_equal(files_cnt, 0); + /* and compare. */ + assert_string_equal( sv->result, result); +} + +// https://github.com/owncloud/client/issues/3128 https://github.com/owncloud/client/issues/2777 +static void check_readdir_bigunicode(void **state) +{ + statevar *sv = (statevar*) *state; +// 1: ? ASCII: 239 - EF +// 2: ? ASCII: 187 - BB +// 3: ? ASCII: 191 - BF +// 4: ASCII: 32 - 20 + + char *p = 0; + asprintf( &p, "%s/%s", CSYNC_TEST_DIR, "goodone/" ); + int rc = _tmkdir(p, MKDIR_MASK); + assert_int_equal(rc, 0); + SAFE_FREE(p); + + const char *t1 = "goodone/ugly\xEF\xBB\xBF\x32" ".txt"; + asprintf( &p, "%s/%s", CSYNC_TEST_DIR, t1 ); + rc = _tmkdir(p, MKDIR_MASK); + SAFE_FREE(p); + + assert_int_equal(rc, 0); + + int files_cnt = 0; + traverse_dir(state, CSYNC_TEST_DIR, &files_cnt); + const char *expected_result = " C:/tmp/csync_test/goodone" +#ifndef __APPLE__ + // On Mac, iconv will not return some files with fancy unicode. + // Linux is not so picky about it and return everything and let the sync engine deal with it. + " C:/tmp/csync_test/goodone/ugly\xEF\xBB\xBF\x32" ".txt" +#endif + ; + assert_string_equal( sv->result, expected_result); + +#ifdef __APPLE__ + // Bad one is recognized though.. ! + assert_string_equal( sv->ignored_dir, CSYNC_TEST_DIR "/goodone/" "ugly\xEF\xBB\xBF\x32" ".txt"); +#endif + assert_int_equal(files_cnt, 0); +} + +int torture_run_tests(void) +{ + const UnitTest tests[] = { + unit_test_setup_teardown(check_readdir_shorttree, setup_testenv, teardown), + unit_test_setup_teardown(check_readdir_with_content, setup_testenv, teardown), + unit_test_setup_teardown(check_readdir_longtree, setup_testenv, teardown), + unit_test_setup_teardown(check_readdir_bigunicode, setup_testenv, teardown), + }; + + return run_tests(tests); +} diff -Nru owncloud-client-1.8.1+dfsg/debian/changelog owncloud-client-2.1.1+dfsg/debian/changelog --- owncloud-client-1.8.1+dfsg/debian/changelog 2015-08-04 10:35:40.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/changelog 2016-04-12 08:13:32.000000000 +0000 @@ -1,8 +1,89 @@ -owncloud-client (1.8.1+dfsg-1ubuntu1) wily; urgency=medium +owncloud-client (2.1.1+dfsg-1ubuntu1) xenial; urgency=medium - * Rename library packages for g++5 ABI transition. + * Sync from Debian (LP: #1515731) + * control: Add Breaks/Replaces on libowncloudsync0v5. - -- Iain Lane Tue, 04 Aug 2015 11:35:40 +0100 + -- Timo Aaltonen Tue, 12 Apr 2016 11:09:35 +0300 + +owncloud-client (2.1.1+dfsg-1) unstable; urgency=medium + + * New upstream release. + * Updated patch hunks + + -- Sandro Knauß Wed, 17 Feb 2016 11:00:56 +0100 + +owncloud-client (2.1.0+dfsg-1) unstable; urgency=medium + + * New upstream release. + * Delete non used patch: 004-shell_integration_copyright + * Updated patch hunks + * Updated patches (small updates) + * Remove unnessary lintian-override + * Updated copyright file + + -- Sandro Knauß Tue, 15 Dec 2015 18:48:08 +0100 + +owncloud-client (2.0.2+dfsg-1) unstable; urgency=medium + + * New upstream release. + * Update patch hunks + * Added patch to use system build flags. + * Added override hardening-no-fortify-functions for libowncloudsync0 + * Updated debian/rules: + - use /usr/share/dpkg/default.mk + - remove own hacks to get debian version + - use hardening=+all + + -- Sandro Knauß Sat, 24 Oct 2015 03:16:40 +0200 + +owncloud-client (2.0.0+dfsg-1) unstable; urgency=medium + + * New upstream release (release to unstable). + * Deleted upstream applied patch. + * Updated patch hunks. + + -- Sandro Knauß Fri, 28 Aug 2015 11:35:16 +0200 + +owncloud-client (2.0.0~rc1+dfsg-2) experimental; urgency=medium + + * Added upstream patch for build on 32bit systems + + -- Sandro Knauß Mon, 24 Aug 2015 19:24:26 +0200 + +owncloud-client (2.0.0~rc1+dfsg-1) experimental; urgency=medium + + * New upstream release. + * Updated patch hunks + * Reproducible: + - optipng images before sending them to pdflatex + - Added patch to get reproducible to get rid of time in C++ + * Added optipng to build-deps + * Removed unused lintian override for /usr/bin/owncloud + + -- Sandro Knauß Sat, 22 Aug 2015 16:36:41 +0200 + +owncloud-client (2.0.0~beta1+dfsg-1) experimental; urgency=medium + + * New upstream release. + * Patches: + - Refresh 0001-disable-updatecheck.patch + - Delete patches, that came from upstream + - update patch hunks + * Updated copyright + + -- Sandro Knauß Tue, 11 Aug 2015 14:52:00 +0200 + +owncloud-client (1.8.4+dfsg-1) unstable; urgency=medium + + * New upstream release. + * Updated copyright file. + * Update patch hunks. + * Delete upstream applied patch. + * Build-deps: remove libneon27-gnutls-dev, with qtbase 5.4.x in + unstable/testing, we don't need neon anymore + * Added a patch to pass all tests (backported from upstream) + + -- Sandro Knauß Sat, 08 Aug 2015 14:28:51 +0200 owncloud-client (1.8.1+dfsg-1) unstable; urgency=medium diff -Nru owncloud-client-1.8.1+dfsg/debian/control owncloud-client-2.1.1+dfsg/debian/control --- owncloud-client-1.8.1+dfsg/debian/control 2015-08-04 10:35:39.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/control 2016-04-12 08:09:07.000000000 +0000 @@ -1,8 +1,7 @@ Source: owncloud-client Section: net Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: ownCloud for Debian maintainers +Maintainer: ownCloud for Debian maintainers Uploaders: Sandro Knauß Build-Depends: cmake, debhelper (>= 9), @@ -11,11 +10,11 @@ libcmocka-dev, libhttp-dav-perl, libinotify-dev [kfreebsd-any], - libneon27-gnutls-dev, libqt5webkit5-dev, libssl-dev (>> 1.0.0), libsqlite3-dev, pkg-kde-tools, + optipng, python3-all, python-sphinx | python3-sphinx, qt5keychain-dev, @@ -34,7 +33,7 @@ Package: owncloud-client Architecture: any -Depends: libowncloudsync0v5 (= ${binary:Version}), +Depends: libowncloudsync0 (= ${binary:Version}), libqt5sql5-sqlite, owncloud-client-l10n, ${misc:Depends}, @@ -62,13 +61,12 @@ . This package provides the documentation. -Package: libowncloudsync0v5 +Package: libowncloudsync0 Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends} -Replaces: libowncloudsync0, libocsync0 -Breaks: libocsync0 +Replaces: libocsync0, libowncloudsync0v5 +Breaks: libocsync0, libowncloudsync0v5 Section: libs -Conflicts: libowncloudsync0 Description: ownCloudSync folder synchronization - libraries The ownCloudSync system lets you always have your latest files wherever you are. Just specify one or more folders on the local machine to and a server @@ -81,7 +79,7 @@ Package: libowncloudsync-dev Architecture: any -Depends: libowncloudsync0v5 (= ${binary:Version}), ${misc:Depends} +Depends: libowncloudsync0 (= ${binary:Version}), ${misc:Depends} Replaces: libocsync-dev Breaks: libocsync-dev Section: libdevel @@ -109,7 +107,7 @@ Package: owncloud-client-cmd Architecture: any -Depends: libowncloudsync0v5 (= ${binary:Version}), +Depends: libowncloudsync0 (= ${binary:Version}), libqt5sql5-sqlite, owncloud-client-l10n, ${misc:Depends}, diff -Nru owncloud-client-1.8.1+dfsg/debian/copyright owncloud-client-2.1.1+dfsg/debian/copyright --- owncloud-client-1.8.1+dfsg/debian/copyright 2015-05-07 14:40:55.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/copyright 2016-02-17 09:41:51.000000000 +0000 @@ -9,20 +9,29 @@ src/3rdparty/sqlite3 Files: * -Copyright: 2014, Daniel Molkentin +Copyright: 2006 Alexander Neundorf + 2015 Christian Kamm + 2006-2012 Andreas Schneider + Cédric Bellegarde + 2014 Daniel Molkentin Denis Dzyubenko - 2011-2015 Klaas Freitag + 2015 Jeroen Hoek + Dominik Schmidt + Duncan Mac-Vicar P. + Jocelyn Turcotte + 2015 Klaas Freitag Krzesimir Nowak Markus Goetz - Olivier Goffart + 2015 Olivier Goffart Pierre MOREAU + Roeland Jago Douma nocteau - Roeland Douma - Jeroen Hoek + ownCloud, Inc. License: GPL-2 Files: debian/* -Copyright: 2012 Sandro Knauß +Copyright: Gaudenz Steinlin + Sandro Knauß License: GPL-2+ Files: csync/* @@ -34,15 +43,19 @@ License: LGPL-2.1+ Files: cmake/scripts/* - shell_integration/dolphin/ownclouddolphinplugin.cpp - shell_integration/dolphin_kf5/ownclouddolphinplugin.cpp + csync/src/csync_version.h.in + shell_integration/dolphin/* shell_integration/nautilus/syncstate.py src/cmd/cmd.* src/cmd/netrcparser.* src/crashreporter/main.cpp + src/gui/activityitemdelegate.* src/gui/application.* + src/gui/creds/httpcredentialsgui.* + src/gui/creds/shibboleth/shibbolethuserjob.* src/gui/folder.* src/gui/folderman.* + src/gui/folderstatusdelegate.* src/gui/folderstatusmodel.* src/gui/folderwizard.* src/gui/logbrowser.* @@ -50,53 +63,54 @@ src/gui/owncloudsetupwizard.* src/gui/selectivesyncdialog.* src/gui/socketapi.* + src/gui/socketapisocket_mac.h src/gui/sslerrordialog.cpp src/gui/sslerrordialog.h src/gui/systray.cpp src/gui/systray.h src/gui/updater/ocupdater.* - src/gui/wizard/owncloudadvancedsetuppage.cpp - src/gui/wizard/owncloudadvancedsetuppage.h - src/gui/wizard/owncloudhttpcredspage.cpp - src/gui/wizard/owncloudhttpcredspage.h + src/gui/wizard/owncloudadvancedsetuppage.* + src/gui/wizard/owncloudhttpcredspage.* src/gui/wizard/owncloudsetuppage.* src/gui/wizard/owncloudwizard.* src/gui/wizard/owncloudwizardcommon.* - src/gui/wizard/owncloudwizardresultpage.cpp - src/gui/wizard/owncloudwizardresultpage.h + src/gui/wizard/owncloudwizardresultpage.* + src/libsync/abstractnetworkjob.* src/libsync/bandwidthmanager.* + src/libsync/checksums.* src/libsync/configfile.* src/libsync/creds/credentialscommon.* src/libsync/creds/httpcredentials.* - src/libsync/creds/shibboleth/shibbolethuserjob.* src/libsync/creds/tokencredentials.* src/libsync/discoveryphase.* src/libsync/logger.* src/libsync/networkjobs.* src/libsync/owncloudpropagator.* src/libsync/owncloudpropagator_p.h - src/libsync/owncloudtheme.* + src/libsync/owncloudtheme.h src/libsync/propagatedownload.* src/libsync/propagateremotedelete.* src/libsync/propagateremotemkdir.* src/libsync/propagateremotemove.* src/libsync/propagateupload.* - src/libsync/propagator_legacy.* src/libsync/propagatorjobs.* src/libsync/syncengine.* src/libsync/syncresult.* src/libsync/theme.* + src/libsync/version.h.in Copyright: Alexander Neundorf Andreas Schneider Cédric Bellegarde Daniel Molkentin Dominik Schmidt Duncan Mac-Vicar P. + Jocelyn Turcotte Klaas Freitag Krzesimir Nowak Markus Goetz Olivier Goffart ownCloud, Inc. + Roeland Jago Douma License: GPL-2+ Files: src/3rdparty/qtlockedfile/* diff -Nru owncloud-client-1.8.1+dfsg/debian/gbp.conf owncloud-client-2.1.1+dfsg/debian/gbp.conf --- owncloud-client-1.8.1+dfsg/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/gbp.conf 2016-02-17 09:34:43.000000000 +0000 @@ -0,0 +1,2 @@ +[DEFAULT] +pristine-tar = true diff -Nru owncloud-client-1.8.1+dfsg/debian/libowncloudsync0.install owncloud-client-2.1.1+dfsg/debian/libowncloudsync0.install --- owncloud-client-1.8.1+dfsg/debian/libowncloudsync0.install 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/libowncloudsync0.install 2016-02-17 09:34:43.000000000 +0000 @@ -0,0 +1,2 @@ +usr/lib/*/libowncloudsync.so.* +usr/lib/*/owncloud/libocsync.so.* diff -Nru owncloud-client-1.8.1+dfsg/debian/libowncloudsync0.lintian-overrides owncloud-client-2.1.1+dfsg/debian/libowncloudsync0.lintian-overrides --- owncloud-client-1.8.1+dfsg/debian/libowncloudsync0.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/libowncloudsync0.lintian-overrides 2016-02-17 09:34:43.000000000 +0000 @@ -0,0 +1,2 @@ +#The lib is so unstable, that it makes no sense to ship symbolfiles +libowncloudsync0: no-symbols-control-file usr/lib/*/libowncloudsync.so.* diff -Nru owncloud-client-1.8.1+dfsg/debian/libowncloudsync0v5.install owncloud-client-2.1.1+dfsg/debian/libowncloudsync0v5.install --- owncloud-client-1.8.1+dfsg/debian/libowncloudsync0v5.install 2015-08-04 10:35:39.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/libowncloudsync0v5.install 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -usr/lib/*/libowncloudsync.so.* -usr/lib/*/owncloud/libocsync.so.* diff -Nru owncloud-client-1.8.1+dfsg/debian/libowncloudsync0v5.lintian-overrides owncloud-client-2.1.1+dfsg/debian/libowncloudsync0v5.lintian-overrides --- owncloud-client-1.8.1+dfsg/debian/libowncloudsync0v5.lintian-overrides 2015-08-04 10:35:39.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/libowncloudsync0v5.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -#The lib is so unstable, that it makes no sense to ship symbolfiles -libowncloudsync0v5: no-symbols-control-file usr/lib/*/libowncloudsync.so.* -# G++5 ABI transition -libowncloudsync0v5: package-name-doesnt-match-sonames libowncloudsync0 diff -Nru owncloud-client-1.8.1+dfsg/debian/owncloud-client.lintian-overrides owncloud-client-2.1.1+dfsg/debian/owncloud-client.lintian-overrides --- owncloud-client-1.8.1+dfsg/debian/owncloud-client.lintian-overrides 2015-05-01 10:56:12.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/owncloud-client.lintian-overrides 2016-02-17 09:34:43.000000000 +0000 @@ -1,4 +1,2 @@ #Owncloud-client depends on libowncloudsync, that depends on libocsync owncloud-client: binary-or-shlib-defines-rpath usr/bin/owncloud /usr/lib/*/owncloud -#According to our knowlege this is a false positive -owncloud-client: hardening-no-fortify-functions usr/bin/owncloud diff -Nru owncloud-client-1.8.1+dfsg/debian/patches/0001-disable-updatecheck.patch owncloud-client-2.1.1+dfsg/debian/patches/0001-disable-updatecheck.patch --- owncloud-client-1.8.1+dfsg/debian/patches/0001-disable-updatecheck.patch 2015-05-07 14:41:24.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/patches/0001-disable-updatecheck.patch 2016-02-17 09:34:43.000000000 +0000 @@ -8,9 +8,9 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ Index: owncloud-client/src/libsync/configfile.cpp =================================================================== ---- owncloud-client.orig/src/libsync/configfile.cpp 2015-05-01 13:19:44.407780748 +0200 -+++ owncloud-client/src/libsync/configfile.cpp 2015-05-01 13:19:44.394447295 +0200 -@@ -371,11 +371,14 @@ +--- owncloud-client.orig/src/libsync/configfile.cpp 2016-02-05 14:36:48.485447473 +0100 ++++ owncloud-client/src/libsync/configfile.cpp 2016-02-05 14:36:48.485447473 +0100 +@@ -412,11 +412,14 @@ QString con( connection ); if( connection.isEmpty() ) con = defaultConnection(); @@ -29,23 +29,26 @@ void ConfigFile::setSkipUpdateCheck( bool skip, const QString& connection ) Index: owncloud-client/src/gui/generalsettings.cpp =================================================================== ---- owncloud-client.orig/src/gui/generalsettings.cpp 2015-05-01 13:19:44.407780748 +0200 -+++ owncloud-client/src/gui/generalsettings.cpp 2015-05-01 13:19:44.397780659 +0200 -@@ -85,17 +85,7 @@ +--- owncloud-client.orig/src/gui/generalsettings.cpp 2016-02-05 14:36:48.485447473 +0100 ++++ owncloud-client/src/gui/generalsettings.cpp 2016-02-05 14:36:48.485447473 +0100 +@@ -109,6 +109,7 @@ void GeneralSettings::slotUpdateInfo() { -- if (OCUpdater *updater = dynamic_cast(Updater::instance())) -- { -- connect(updater, SIGNAL(downloadStateChanged()), SLOT(slotUpdateInfo()), Qt::UniqueConnection); -- connect(_ui->restartButton, SIGNAL(clicked()), updater, SLOT(slotStartInstaller()), Qt::UniqueConnection); -- connect(_ui->restartButton, SIGNAL(clicked()), qApp, SLOT(quit()), Qt::UniqueConnection); -- _ui->updateStateLabel->setText(updater->statusString()); -- _ui->restartButton->setVisible(updater->downloadState() == OCUpdater::DownloadComplete); -- } else { -- // can't have those infos from sparkle currently ++ /* Debian don't want an autoupdater + if (OCUpdater *updater = dynamic_cast(Updater::instance())) { + connect(updater, SIGNAL(downloadStateChanged()), SLOT(slotUpdateInfo()), Qt::UniqueConnection); + connect(_ui->restartButton, SIGNAL(clicked()), updater, SLOT(slotStartInstaller()), Qt::UniqueConnection); +@@ -116,9 +117,12 @@ + _ui->updateStateLabel->setText(updater->statusString()); + _ui->restartButton->setVisible(updater->downloadState() == OCUpdater::DownloadComplete); + } else { ++ */ + // can't have those infos from sparkle currently _ui->updatesGroupBox->setVisible(false); -- } ++ /* Debian don't want an autoupdater + } ++ */ } void GeneralSettings::saveMiscSettings() diff -Nru owncloud-client-1.8.1+dfsg/debian/patches/0002-debian_version.patch owncloud-client-2.1.1+dfsg/debian/patches/0002-debian_version.patch --- owncloud-client-1.8.1+dfsg/debian/patches/0002-debian_version.patch 2015-05-06 23:04:49.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/patches/0002-debian_version.patch 2016-02-17 09:34:43.000000000 +0000 @@ -6,8 +6,8 @@ --- Index: owncloud-client/OWNCLOUD.cmake =================================================================== ---- owncloud-client.orig/OWNCLOUD.cmake 2015-03-22 14:28:48.639865886 +0100 -+++ owncloud-client/OWNCLOUD.cmake 2015-03-22 14:28:48.633199155 +0100 +--- owncloud-client.orig/OWNCLOUD.cmake 2015-12-15 19:09:45.858065932 +0100 ++++ owncloud-client/OWNCLOUD.cmake 2015-12-15 19:09:45.858065932 +0100 @@ -1,6 +1,8 @@ set( APPLICATION_NAME "ownCloud" ) set( APPLICATION_EXECUTABLE "owncloud" ) @@ -19,30 +19,28 @@ Index: owncloud-client/config.h.in =================================================================== ---- owncloud-client.orig/config.h.in 2015-03-22 14:28:48.639865886 +0100 -+++ owncloud-client/config.h.in 2015-03-22 14:28:48.633199155 +0100 -@@ -22,6 +22,11 @@ +--- owncloud-client.orig/config.h.in 2015-12-15 19:09:45.858065932 +0100 ++++ owncloud-client/config.h.in 2015-12-15 19:10:42.630272867 +0100 +@@ -23,4 +23,9 @@ #cmakedefine SYSCONFDIR "@SYSCONFDIR@" - #cmakedefine DATADIR "@DATADIR@" + #cmakedefine SHAREDIR "@SHAREDIR@" +//debian specific +#cmakedefine DEBIAN_VERSION "@DEBIAN_VERSION@" +#cmakedefine DEBIAN_URL "@DEBIAN_URL@" +#cmakedefine DEBIAN_DOMAIN "@DEBIAN_DOMAIN@" + - #ifndef NEON_WITH_LFS - #cmakedefine NEON_WITH_LFS "@NEON_WITH_LFS@" #endif Index: owncloud-client/src/libsync/owncloudtheme.cpp =================================================================== ---- owncloud-client.orig/src/libsync/owncloudtheme.cpp 2015-03-22 14:28:48.639865886 +0100 -+++ owncloud-client/src/libsync/owncloudtheme.cpp 2015-03-22 14:28:48.633199155 +0100 +--- owncloud-client.orig/src/libsync/owncloudtheme.cpp 2015-12-15 19:09:45.858065932 +0100 ++++ owncloud-client/src/libsync/owncloudtheme.cpp 2015-12-15 19:09:45.858065932 +0100 @@ -52,9 +52,9 @@ "ownCloud and the ownCloud Logo are registered trademarks of ownCloud, " "Inc. in the United States, other countries, or both.

" ) - .arg(MIRALL_VERSION_STRING) -- .arg("http://" MIRALL_STRINGIFY(APPLICATION_DOMAIN)) +- .arg("https://" MIRALL_STRINGIFY(APPLICATION_DOMAIN)) - .arg(MIRALL_STRINGIFY(APPLICATION_DOMAIN)); + .arg(DEBIAN_VERSION) + .arg(DEBIAN_URL) diff -Nru owncloud-client-1.8.1+dfsg/debian/patches/0004-shell_integration_copyright.patch owncloud-client-2.1.1+dfsg/debian/patches/0004-shell_integration_copyright.patch --- owncloud-client-1.8.1+dfsg/debian/patches/0004-shell_integration_copyright.patch 2015-05-06 23:04:49.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/patches/0004-shell_integration_copyright.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -Description: Skip shell_integration/MaxOSX directory - Because of copyright isses we had to strip shell_integration/MaxOSX - and shell_integration/windows out. - So we have to update cmake not to include these directories. -Author: Sandro Knauß -Origin: debian -Bug: https://github.com/owncloud/mirall/issues/2068 -Last-Update: 2014-08-16 ---- -This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ -Index: owncloud-client/shell_integration/CMakeLists.txt -=================================================================== ---- owncloud-client.orig/shell_integration/CMakeLists.txt 2015-02-20 01:02:20.868846043 +0100 -+++ owncloud-client/shell_integration/CMakeLists.txt 2015-02-20 01:02:43.549060746 +0100 -@@ -1,4 +1,3 @@ --add_subdirectory(MacOSX) - add_subdirectory(icons) - - if( UNIX AND NOT APPLE ) diff -Nru owncloud-client-1.8.1+dfsg/debian/patches/0004-use_system_buildflags.patch owncloud-client-2.1.1+dfsg/debian/patches/0004-use_system_buildflags.patch --- owncloud-client-1.8.1+dfsg/debian/patches/0004-use_system_buildflags.patch 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/patches/0004-use_system_buildflags.patch 2016-02-17 09:34:43.000000000 +0000 @@ -0,0 +1,21 @@ +Description: Don't modify build flags within the package + For beeing able to have full control over the build process, we need + full control over the build flags set. That's why it is recommended to disable + any modification from these flags from package side. +Author: Sandro Knauß +Origin: debian +Last-Update: 2015-10-24 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: owncloud-client/csync/CMakeLists.txt +=================================================================== +--- owncloud-client.orig/csync/CMakeLists.txt 2015-10-24 03:02:40.576620062 +0200 ++++ owncloud-client/csync/CMakeLists.txt 2015-10-24 03:02:40.573286695 +0200 +@@ -9,7 +9,6 @@ + # add definitions + include(DefineCMakeDefaults) + include(DefinePlatformDefaults) +-include(DefineCompilerFlags) + include(DefineOptions.cmake) + + include(DefineInstallationPaths) diff -Nru owncloud-client-1.8.1+dfsg/debian/patches/0005-remove_admin.patch owncloud-client-2.1.1+dfsg/debian/patches/0005-remove_admin.patch --- owncloud-client-1.8.1+dfsg/debian/patches/0005-remove_admin.patch 2015-05-06 23:04:49.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/patches/0005-remove_admin.patch 2016-02-17 09:34:43.000000000 +0000 @@ -8,12 +8,12 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ Index: owncloud-client/CMakeLists.txt =================================================================== ---- owncloud-client.orig/CMakeLists.txt 2015-03-22 14:28:56.619942175 +0100 -+++ owncloud-client/CMakeLists.txt 2015-03-22 14:28:56.613275444 +0100 -@@ -194,7 +194,6 @@ - if(NOT BUILD_LIBRARIES_ONLY) +--- owncloud-client.orig/CMakeLists.txt 2015-12-15 19:10:53.310312533 +0100 ++++ owncloud-client/CMakeLists.txt 2015-12-15 19:10:53.306312517 +0100 +@@ -196,7 +196,6 @@ add_subdirectory(shell_integration) add_subdirectory(doc) + add_subdirectory(doc/dev) -add_subdirectory(admin) endif(NOT BUILD_LIBRARIES_ONLY) diff -Nru owncloud-client-1.8.1+dfsg/debian/patches/0006-move-configfile.patch owncloud-client-2.1.1+dfsg/debian/patches/0006-move-configfile.patch --- owncloud-client-1.8.1+dfsg/debian/patches/0006-move-configfile.patch 2015-05-06 23:04:49.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/patches/0006-move-configfile.patch 2016-02-17 09:34:43.000000000 +0000 @@ -8,11 +8,11 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ Index: owncloud-client/CMakeLists.txt =================================================================== ---- owncloud-client.orig/CMakeLists.txt 2015-05-01 13:19:56.397888238 +0200 -+++ owncloud-client/CMakeLists.txt 2015-05-01 13:19:56.391221511 +0200 -@@ -205,6 +205,6 @@ - if(BUILD_OWNCLOUD_OSX_BUNDLE) +--- owncloud-client.orig/CMakeLists.txt 2016-02-05 14:37:14.101524409 +0100 ++++ owncloud-client/CMakeLists.txt 2016-02-05 14:37:14.097524397 +0100 +@@ -208,6 +208,6 @@ install(FILES sync-exclude.lst DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/) + configure_file(sync-exclude.lst bin/${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/sync-exclude.lst COPYONLY) else() - install( FILES sync-exclude.lst DESTINATION ${SYSCONFDIR}/${APPLICATION_SHORTNAME} ) + install( FILES sync-exclude.lst DESTINATION ${SYSCONFDIR}/${APPLICATION_EXECUTABLE}-client ) @@ -20,9 +20,9 @@ endif() Index: owncloud-client/src/libsync/configfile.cpp =================================================================== ---- owncloud-client.orig/src/libsync/configfile.cpp 2015-05-01 13:19:56.397888238 +0200 -+++ owncloud-client/src/libsync/configfile.cpp 2015-05-01 13:19:56.391221511 +0200 -@@ -245,7 +245,7 @@ +--- owncloud-client.orig/src/libsync/configfile.cpp 2016-02-05 14:37:14.101524409 +0100 ++++ owncloud-client/src/libsync/configfile.cpp 2016-02-05 14:37:14.097524397 +0100 +@@ -268,7 +268,7 @@ fi.setFile( QCoreApplication::applicationDirPath(), exclFile ); #endif #ifdef Q_OS_UNIX diff -Nru owncloud-client-1.8.1+dfsg/debian/patches/0007-move-translations.patch owncloud-client-2.1.1+dfsg/debian/patches/0007-move-translations.patch --- owncloud-client-1.8.1+dfsg/debian/patches/0007-move-translations.patch 2015-05-06 23:04:49.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/patches/0007-move-translations.patch 2016-02-17 09:34:43.000000000 +0000 @@ -9,27 +9,27 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ Index: owncloud-client/src/gui/application.cpp =================================================================== ---- owncloud-client.orig/src/gui/application.cpp 2015-05-01 13:20:02.394608675 +0200 -+++ owncloud-client/src/gui/application.cpp 2015-05-01 13:20:02.384608585 +0200 -@@ -76,7 +76,7 @@ +--- owncloud-client.orig/src/gui/application.cpp 2015-12-15 19:12:34.750699715 +0100 ++++ owncloud-client/src/gui/application.cpp 2015-12-15 19:12:34.750699715 +0100 +@@ -84,7 +84,7 @@ #elif defined(Q_OS_MAC) return QApplication::applicationDirPath()+QLatin1String("/../Resources/Translations"); // path defaults to app dir. #elif defined(Q_OS_UNIX) -- return QString::fromLatin1(DATADIR "/" APPLICATION_EXECUTABLE "/i18n/"); -+ return QString::fromLatin1(DATADIR "/" APPLICATION_EXECUTABLE "-client/i18n/"); +- return QString::fromLatin1(SHAREDIR "/" APPLICATION_EXECUTABLE "/i18n/"); ++ return QString::fromLatin1(SHAREDIR "/" APPLICATION_EXECUTABLE "-client/i18n/"); #endif } } Index: owncloud-client/src/gui/CMakeLists.txt =================================================================== ---- owncloud-client.orig/src/gui/CMakeLists.txt 2015-05-01 13:20:02.394608675 +0200 -+++ owncloud-client/src/gui/CMakeLists.txt 2015-05-01 13:20:02.384608585 +0200 -@@ -204,7 +204,7 @@ +--- owncloud-client.orig/src/gui/CMakeLists.txt 2015-12-15 19:12:34.750699715 +0100 ++++ owncloud-client/src/gui/CMakeLists.txt 2015-12-15 19:12:51.358764758 +0100 +@@ -237,7 +237,7 @@ endforeach( _file ) endif(NOT WIN32) -- install(FILES ${client_I18N} DESTINATION share/${APPLICATION_EXECUTABLE}/i18n) -+ install(FILES ${client_I18N} DESTINATION share/${APPLICATION_EXECUTABLE}-client/i18n) +- install(FILES ${client_I18N} DESTINATION ${SHAREDIR}/${APPLICATION_EXECUTABLE}/i18n) ++ install(FILES ${client_I18N} DESTINATION ${SHAREDIR}/${APPLICATION_EXECUTABLE}-client/i18n) # we may not add MACOSX_BUNDLE here, if not building one diff -Nru owncloud-client-1.8.1+dfsg/debian/patches/0008-Built-with-GCC-5.patch owncloud-client-2.1.1+dfsg/debian/patches/0008-Built-with-GCC-5.patch --- owncloud-client-1.8.1+dfsg/debian/patches/0008-Built-with-GCC-5.patch 2015-05-06 23:25:43.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/patches/0008-Built-with-GCC-5.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -From: =?utf-8?q?Sandro_Knau=C3=9F?= -Date: Thu, 7 May 2015 01:00:22 +0200 -Subject: Built with GCC-5 - -this fixes the error: -error: ISO C does not support '__FUNCTION__' predefined identifier -[-Wpedantic] - -According to the porting guide: -The fix is either to use the standard predefined identifier __func__ -(since C99), or to use the __extension__ keyword. ---- - csync/src/csync_log.h | 2 +- - csync/src/httpbf/src/httpbf.c | 2 +- - csync/tests/csync_tests/check_csync_log.c | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/csync/src/csync_log.h b/csync/src/csync_log.h -index 38f5f9c..0cd0d01 100644 ---- a/csync/src/csync_log.h -+++ b/csync/src/csync_log.h -@@ -61,7 +61,7 @@ enum csync_log_priority_e { - }; - - #define CSYNC_LOG(priority, ...) \ -- csync_log(priority, __FUNCTION__, __VA_ARGS__) -+ csync_log(priority, __func__, __VA_ARGS__) - - void csync_log(int verbosity, - const char *function, -diff --git a/csync/src/httpbf/src/httpbf.c b/csync/src/httpbf/src/httpbf.c -index 815b07e..2489e8d 100644 ---- a/csync/src/httpbf/src/httpbf.c -+++ b/csync/src/httpbf/src/httpbf.c -@@ -42,7 +42,7 @@ - #define DEBUG_HBF(...) { if(transfer->log_cb) { \ - char buf[1024]; \ - snprintf(buf, 1024, __VA_ARGS__); \ -- transfer->log_cb(__FUNCTION__, buf, transfer->user_data); \ -+ transfer->log_cb(__func__, buf, transfer->user_data); \ - } } - - // #endif -diff --git a/csync/tests/csync_tests/check_csync_log.c b/csync/tests/csync_tests/check_csync_log.c -index 4c88c14..65a8ae9 100644 ---- a/csync/tests/csync_tests/check_csync_log.c -+++ b/csync/tests/csync_tests/check_csync_log.c -@@ -131,7 +131,7 @@ static void check_logging(void **state) - rc = csync_set_log_callback(check_log_callback); - assert_int_equal(rc, 0); - -- csync_log(1, __FUNCTION__, "rc = %d", rc); -+ csync_log(1, __func__, "rc = %d", rc); - - rc = _tstat(path, &sb); - diff -Nru owncloud-client-1.8.1+dfsg/debian/patches/0008-make-reproducable.patch owncloud-client-2.1.1+dfsg/debian/patches/0008-make-reproducable.patch --- owncloud-client-1.8.1+dfsg/debian/patches/0008-make-reproducable.patch 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/patches/0008-make-reproducable.patch 2016-02-17 09:34:43.000000000 +0000 @@ -0,0 +1,40 @@ +Description: timestamps_from_cpp_macros + The C pre-processor macros `__DATE__`, `__TIME__`, and `__TIMESTAMP__` + captures the current time, and thus will obviously make a build + unreproducible. + . + In debian we don't build owncloud from a random git hash, so we can remove + the line, of which git hash we create the software and when can be removed + completly. +Author: Sandro Knauß +Origin: Debian +Last-Update: 2015-08-22 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: owncloud-client/src/libsync/theme.cpp +=================================================================== +--- owncloud-client.orig/src/libsync/theme.cpp 2015-08-22 16:39:29.591478611 +0200 ++++ owncloud-client/src/libsync/theme.cpp 2015-08-22 16:39:29.584811875 +0200 +@@ -262,20 +262,8 @@ + + QString Theme::gitSHA1() const + { +- QString devString; +-#ifdef GIT_SHA1 +- const QString githubPrefix(QLatin1String( +- "https://github.com/owncloud/client/commit/")); +- const QString gitSha1(QLatin1String(GIT_SHA1)); +- devString = QCoreApplication::translate("ownCloudTheme::about()", +- "

Built from Git revision %2" +- " on %3, %4 using Qt %5, %6

") +- .arg(githubPrefix+gitSha1).arg(gitSha1.left(6)) +- .arg(__DATE__).arg(__TIME__) +- .arg(QT_VERSION_STR) +- .arg(QString::fromAscii(OPENSSL_VERSION_TEXT)); +-#endif +- return devString; ++ // On Debian we don't want the line build from git line in about dialog ++ return QString(); + } + + QString Theme::about() const diff -Nru owncloud-client-1.8.1+dfsg/debian/patches/series owncloud-client-2.1.1+dfsg/debian/patches/series --- owncloud-client-1.8.1+dfsg/debian/patches/series 2015-05-07 14:41:24.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/patches/series 2016-02-17 09:55:13.000000000 +0000 @@ -1,8 +1,8 @@ 0001-disable-updatecheck.patch 0002-debian_version.patch 0003-skip_tests_freebsd.patch -0004-shell_integration_copyright.patch +0004-use_system_buildflags.patch 0005-remove_admin.patch 0006-move-configfile.patch 0007-move-translations.patch -0008-Built-with-GCC-5.patch +0008-make-reproducable.patch diff -Nru owncloud-client-1.8.1+dfsg/debian/rules owncloud-client-2.1.1+dfsg/debian/rules --- owncloud-client-1.8.1+dfsg/debian/rules 2015-08-04 10:35:39.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/debian/rules 2016-02-17 09:55:13.000000000 +0000 @@ -1,8 +1,9 @@ #!/usr/bin/make -f -export DEB_BUILD_MAINT_OPTIONS = hardening=+all,-pie +export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed -DEBVERS := $(shell dpkg-parsechangelog | sed -n -e 's/^Version: //p') +DPKG_EXPORT_BUILDFLAGS = 1 +include /usr/share/dpkg/default.mk %: dh $@ --parallel --with sphinxdoc --with pkgkde_symbolshelper --with python3 @@ -17,13 +18,15 @@ endif override_dh_auto_configure: - dh_auto_configure -- -DCMAKE_INSTALL_PREFIX=/usr -DUNIT_TESTING=ON -DDEBIAN_VERSION=$(DEBVERS) + dh_auto_configure -- -DCMAKE_INSTALL_PREFIX=/usr -DUNIT_TESTING=ON -DDEBIAN_VERSION=$(DEB_VERSION) override_dh_auto_build: + optipng doc/images/*png dh_auto_build -- doc dh_auto_build -- override_dh_auto_build-indep: + optipng doc/images/*png dh_auto_build -- doc override_dh_auto_build-arch: diff -Nru owncloud-client-1.8.1+dfsg/doc/advancedusage.rst owncloud-client-2.1.1+dfsg/doc/advancedusage.rst --- owncloud-client-1.8.1+dfsg/doc/advancedusage.rst 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/doc/advancedusage.rst 2016-02-09 15:07:08.000000000 +0000 @@ -9,12 +9,12 @@ .. index:: command line switches, command line, options, parameters .. include:: options.rst -Config File ------------ +Configuration File +------------------ .. index:: config file .. include:: conffile.rst -ownCloud Commandline Client ---------------------------- +ownCloud Command Line Client +---------------------------- .. index:: owncloudcmd .. include:: owncloudcmd.rst diff -Nru owncloud-client-1.8.1+dfsg/doc/architecture.rst owncloud-client-2.1.1+dfsg/doc/architecture.rst --- owncloud-client-1.8.1+dfsg/doc/architecture.rst 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/doc/architecture.rst 2016-02-09 15:07:08.000000000 +0000 @@ -25,9 +25,9 @@ same. When synchronized: - If a file is added to one repository it is copied to the other synchronized repository. -- When a file is changed in one repository, the change is propagated to any - synchronized other repositories- If a file is deleted in one repository, it - is deleted in any other. +- When a file is changed in one repository, the change is propagated to any other + synchronized repository. +- If a file is deleted in one repository, it is deleted in any other. It is important to note that the ownCloud synchronization process does not use a typical client/server system where the server is always master. This is a @@ -47,7 +47,7 @@ .. index:: time stamps, file times, etag, unique id Until the release of ownCloud 4.5 and ownCloud Client 1.1, the ownCloud -synchronization process employed a single file property -- the file modificatin +synchronization process employed a single file property -- the file modification time -- to decide which file was newer and needed to be synchronized to the other repository. @@ -76,7 +76,7 @@ not support using the file ID functionality. Before the 1.3.0 release of the Desktop Client, the synchronization process -might create faux conflict files if time deviates. Original and changed files +might create false conflict files if time deviates. Original and changed files conflict only in their timestamp, but not in their content. This behaviour was changed to employ a binary check if files differ. @@ -104,11 +104,11 @@ +--------------------+-------------------+----------------------------+ We strongly recommend using ownCloud Server release 4.5 or later when using -ownCloud Client 1.1 or later. Using incompatible time stamp-based +ownCloud Client 1.1 or later. Using an incompatible time stamp-based synchronization mechanism can lead to data loss in rare cases, especially when multiple clients are involved and one utilizes a non-synchronized NTP time. -.. _`NTP time synchronisation`: http://en.wikipedia.org/wiki/Network_Time_Protocol +.. _`NTP time synchronization`: http://en.wikipedia.org/wiki/Network_Time_Protocol .. _Etag: http://en.wikipedia.org/wiki/HTTP_ETag Comparison and Conflict Cases @@ -120,7 +120,7 @@ expected value stored in its database. If the value is not the same, the client determines that the file has been modified in the local repository. -.. note:: On the local side, the modification time a good attribute to use for +.. note:: On the local side, the modification time is a good attribute to use for detecting changes, because the value does not depend on time shifts and such. @@ -131,8 +131,8 @@ In the event a file has changed on both the local and the remote repository since the last sync run, it can not easily be decided which version of the file -is the one that should be used. However, changes to any side be lost. Instead, -a *conflict case* is created. The client resolves this conflic by creating a +is the one that should be used. However, changes to any side will not be lost. Instead, +a *conflict case* is created. The client resolves this conflict by creating a conflict file of the older of the two files and saving the newer file under the original file name. Conflict files are always created on the client and never on the server. The conflict file uses the same name as the original file, but @@ -153,21 +153,21 @@ * Files matched by one of the patterns defined in the Ignored Files Editor * Files containing characters that do not work on certain file systems ``(`\, /, :, ?, *, ", >, <, |`)``. -* Files starting in ``.csync_journal.db``, as these files are reserved for journalling. +* Files starting with ``.csync_journal.db``, as these files are reserved for journalling. If a pattern selected using a checkbox in the `ignoredFilesEditor-label` (or if -a line in the exclude file starts with the character `]` directly followed by +a line in the exclude file starts with the character ``]`` directly followed by the file pattern), files matching the pattern are considered *fleeting meta -data*. These files are ingored and *removed* by the client if found in the +data*. These files are ignored and *removed* by the client if found in the synchronized folder. This is suitable for meta files created by some applications that have no sustainable meaning. -If a pattern ends with the backslash (`/`) character, only directories are +If a pattern ends with the forwardslash (``/``) character, only directories are matched. The pattern is only applied for directory components of filenames selected using the checkbox. To match filenames against the exclude patterns, the unix standard C library -function fnmatch is used. This procesx checks the filename against the +function fnmatch is used. This process checks the filename against the specified pattern using standard shell wildcard pattern matching. For more information, please refer to `The opengroup website `_. diff -Nru owncloud-client-1.8.1+dfsg/doc/autoupdate.rst owncloud-client-2.1.1+dfsg/doc/autoupdate.rst --- owncloud-client-1.8.1+dfsg/doc/autoupdate.rst 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/doc/autoupdate.rst 2016-02-09 15:07:08.000000000 +0000 @@ -11,8 +11,8 @@ available. .. note:: Because of various technical issues, desktop sync clients older than - 1.7 will not be allowed to connect and sync with the ownCloud 8.1 server. It is - highly recommended to keep your client updated. + 1.7 will not be allowed to connect and sync with the ownCloud 8.1+ server. It + is highly recommended to keep your client updated. Basic Workflow -------------- @@ -31,9 +31,6 @@ client starts a silent update prior to its next launch and then restarts itself. Should the silent update fail, the client offers a manual download. -When you upgrade from 1.7 you should restart Windows to ensure that all the new -features in 1.8 are enabled. - .. note:: Administrative privileges are required to perform the update. Mac OS X @@ -65,16 +62,22 @@ Preventing Automatic Updates in Windows Environments ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You can prevent automatic updates from occuring in Windows environments using -one of two methods. The first method allows users to override the automatic -update check mechanism whereas the second method prevents any manual overrides. +Users may disable automatic updates by adding this line to the [General] +section of their ``owncloud.cfg`` files:: + + skipUpdateCheck=true + +Windows administrators have more options for preventing automatic updates in +Windows environments by using one of two methods. The first method allows users +to override the automatic update check mechanism, whereas the second method +prevents any manual overrides. To prevent automatic updates, but allow manual overrides: 1. Edit these Registry keys: - a. (32-bit) ``HKEY_LOCAL_MACHINE\Software\ownCloud\ownCloud`` - b. (64-bit) ``HKEY_LOCAL_MACHINE\Software\Wow6432Node\ownCloud\ownCloud`` + a. (32-bit-Windows) ``HKEY_LOCAL_MACHINE\Software\ownCloud\ownCloud`` + b. (64-bit-Windows) ``HKEY_LOCAL_MACHINE\Software\Wow6432Node\ownCloud\ownCloud`` 2. Add the key ``skipUpdateCheck`` (of type DWORD). @@ -87,9 +90,9 @@ .. note::This is the preferred method of controlling the updater behavior using Group Policies. -1. Migrate to the following directory:: +1. Edit this Registry key: - HKEY_LOCAL_MACHINE\Software\Policies\ownCloud\ownCloud + ``HKEY_LOCAL_MACHINE\Software\Policies\ownCloud\ownCloud`` 2. Add the key ``skipUpdateCheck`` (of type DWORD). @@ -106,7 +109,7 @@ /Library/Preferences/ - 2. Locate and open the following file:: +2. Locate and open the following file:: com.owncloud.desktopclient.plist @@ -125,8 +128,7 @@ Because the Linux client does not provide automatic updating functionality, there is no need to remove the automatic-update check. However, if you want to disable it edit your desktop -client configuration file, ``$HOME/.local/share/data/ownCloud/owncloud.cfg``. Add these lines: +client configuration file, ``$HOME/.local/share/data/ownCloud/owncloud.cfg``. +Add this line to the [General] section:: - [General] skipUpdateCheck=true - diff -Nru owncloud-client-1.8.1+dfsg/doc/building.rst owncloud-client-2.1.1+dfsg/doc/building.rst --- owncloud-client-1.8.1+dfsg/doc/building.rst 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/doc/building.rst 2016-02-09 15:07:08.000000000 +0000 @@ -1,5 +1,6 @@ .. _building-label: +=============================== Appendix A: Building the Client =============================== @@ -7,7 +8,7 @@ major platforms. You should read this section if you want to develop for the desktop client. -.. note:: Building instruction are subject to change as development proceeds. +.. note:: Build instructions are subject to change as development proceeds. Please check the version for which you want to build. The instructions contained in this topic were updated to work with version 1.7 of the ownCloud Client. @@ -23,13 +24,10 @@ * openSUSE: ``zypper ref; zypper si -d owncloud-client`` * Fedora/CentOS: ``yum install yum-utils; yum-builddep owncloud-client`` -3. Follow the `generic build instructions`_. +3. Follow the :ref:`generic-build-instructions`. 4. (Optional) Call ``make install`` to install the client to the ``/usr/local/bin`` directory. -.. note:: This step requires the ``mingw32-cross-nsis`` packages be installed on - Windows. - Mac OS X -------- @@ -43,7 +41,7 @@ of HomeBrew_. The ownCloud team has its own repository containing non-standard recipes. -To set up your build enviroment for development using HomeBrew_: +To set up your build environment for development using HomeBrew_: 1. Add the ownCloud repository using the following command:: @@ -60,17 +58,19 @@ Where ``x.z`` is the current version of Qt 5 that brew has installed on your machine. -5. For compilation of the client, follow the `generic build instructions`_. +5. For compilation of the client, follow the :ref:`generic-build-instructions`. + +6. Install the Packages_ package creation tool. -6. In the build directory, run ``admin/osx/create_mac.sh +7. In the build directory, run ``admin/osx/create_mac.sh ``. If you have a developer signing certificate, you can specify its Common Name as a third parameter (use quotes) to have the package signed automatically. -.. note:: Contrary to earlier versions, ownCloud 1.7 and later are packaged - as a ``pkg`` installer. Do not call "make package" at any time when - compiling for OS X, as this will build a disk image, and will not - work correctly. + .. note:: Contrary to earlier versions, ownCloud 1.7 and later are packaged + as a ``pkg`` installer. Do not call "make package" at any time when + compiling for OS X, as this will build a disk image, and will not + work correctly. Windows Development Build ----------------------- @@ -110,84 +110,62 @@ 6. Create the build directory:: - mkdir client-build - cd client-build + mkdir client-build + cd client-build 7. Build the client:: - cmake -G "MinGW Makefiles" ../client - mingw32-make + cmake -G "MinGW Makefiles" ../client + mingw32-make - .. note:: You can try using ninja to build parallelly using - ``cmake -G Ninja ../client`` and ``ninja`` instead. - .. note:: Refer to the `generic build instructions`_ section for additional options. + .. note:: You can try using ninja to build in parallel using + ``cmake -G Ninja ../client`` and ``ninja`` instead. + .. note:: Refer to the :ref:`generic-build-instructions` section for additional options. - The owncloud binary will appear in the ``bin`` directory. + The ownCloud binary will appear in the ``bin`` directory. Windows Installer Build (Cross-Compile) ------------------------ +--------------------------------------- Due to the large number of dependencies, building the client installer for Windows is **currently only officially supported on openSUSE**, by using the MinGW cross compiler. -You can set up openSUSE 13.1, 13.2 or openSUSE Factory in a virtual machine if you do not +You can set up any currently supported version of openSUSE in a virtual machine if you do not have it installed already. -To cross-compile: - -1. Add the following repositories using YaST or ``zypper ar`` (adjust when using another openSUSE version):: - - zypper ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_13.2/windows:mingw.repo - zypper ar http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_13.2/windows:mingw:win32.repo - -2. Install the cross-compiler packages and the cross-compiled dependencies:: - - zypper install cmake make mingw32-cross-binutils mingw32-cross-cpp mingw32-cross-gcc \ - mingw32-cross-gcc-c++ mingw32-cross-pkg-config mingw32-filesystem \ - mingw32-headers mingw32-runtime site-config \ - mingw32-cross-libqt5-qmake mingw32-cross-libqt5-qttools mingw32-libqt5* \ - mingw32-cross-nsis +In order to make setup simple, you can use the provided Dockerfile to build your own image. -3. For the installer, install the NSIS installer package:: +1. Assuming you are in the root of the ownCloud Client's source tree, you can + build an image from this Dockerfile like this:: - zypper install mingw32-cross-nsis + cd admin/win32/docker + docker build . -t ownCloud-client-win32: -4. Install the following plugin:: + Replace ```` by the version of the client you are building, e.g. + |version| for the release of the client that this document describes. + If you do not wish to use docker, you can run the commands in ``RUN`` manually + in a shell, e.g. to create your own build environment in a virtual machine. - mingw32-cross-nsis-plugin-processes mingw32-cross-nsis-plugin-uac + .. note:: Docker images are specific to releases. This one refers to |version|. + Newer releases may have different dependencies, and thus require a later + version of the docker image! Always pick the docker image fitting your release + of ownCloud client! - .. note:: This plugin is typically required. However, due to a current bug - in ``mingw``, the plugins do not currently build properly from source. +2. From within the source tree Run the docker instance:: -5. Manually download and install the following files using ``rpm -ivh ``: + docker run ownCloud-client-win32: -v "$PWD:/home/jenkins/client" \ + admin/win32/docker/build.sh $(id -u) - .. note:: These files also work for more recent openSUSE versions! + It will run the build, create an NSIS based installer, as well as run tests. + You will find the resulting binary in an newly created ``build-win32`` subfolder. - :: - # RPM depends on curl for installs from HTTP - zypper install curl + If you do not wish to use docker, and ran the ``RUN`` commands above in a virtual machine, + you can run the indented commands in the lower section of ``build.sh`` manually in your + source tree. - rpm -ivh http://download.tomahawk-player.org/packman/mingw:32/openSUSE_12.1/x86_64/mingw32-cross-nsis-plugin-processes-0-1.1.x86_64.rpm - rpm -ivh http://download.tomahawk-player.org/packman/mingw:32/openSUSE_12.1/x86_64/mingw32-cross-nsis-plugin-uac-0-3.1.x86_64.rpm +4. Finally, you should sign the installer to avoid warnings upon installation. + This requires a `Microsoft Authenticode`_ Certificate ``osslsigncode`` to sign the installer:: -6. Follow the `generic build instructions`_ - -.. note:: When building for Windows platforms, you must specify a special - toolchain file that enables cmake to locate the platform-specific tools. To add - this parameter to the call to cmake, enter - ``-DCMAKE_TOOLCHAIN_FILE=../client/admin/win/Toolchain-mingw32-openSUSE.cmake``. - -7. Build by running ``make``. - -.. note:: Using ``make package`` produces an NSIS-based installer, provided - the NSIS mingw32 packages are installed. - -8. If you want to sign the installer, acquire a `Microsoft Authenticode`_ Certificate and install ``osslsigncode`` to sign the installer:: - - zypper install osslsigncode - -9. Sign the package:: - - osslsigncode -pkcs12 $HOME/.codesign/packages.pfx -h sha1 \ + osslsigncode -pkcs12 $HOME/.codesign/packages.pfx -h sha256 \ -pass yourpass \ -n "ACME Client" \ -i "http://acme.com" \ @@ -195,11 +173,13 @@ -in ${unsigned_file} \ -out ${installer_file} - for ``-in``, use URL to the time stamping server provided by your CA along with the Authenticode certificate. Alternatively, + for ``-in``, use the URL to the time stamping server provided by your CA along with the Authenticode certificate. Alternatively, you may use the official Microsoft ``signtool`` utility on Microsoft Windows. + If you're familiar with docker, you can use the version of ``osslsigncode`` that is part of the docker image. + +.. _generic-build-instructions: -.. _`generic build instructions`: Generic Build Instructions -------------------------- @@ -211,29 +191,31 @@ To build the most up to date version of the client: -1. Clone the latest versions of the client from Git_ as follows: +1. Clone the latest versions of the client from Git_ as follows:: - ``git clone git://github.com/owncloud/client.git`` + git clone git://github.com/owncloud/client.git + git submodule init + git submodule update -2. Create the build directory: +2. Create the build directory:: - ``mkdir client-build`` - ``cd client-build`` + mkdir client-build + cd client-build -3. Configure the client build: +3. Configure the client build:: - ``cmake -DCMAKE_BUILD_TYPE="Debug" ../client`` + cmake -DCMAKE_BUILD_TYPE="Debug" ../client - ..note:: You must use absolute paths for the ``include`` and ``library`` - directories. + .. note:: You must use absolute paths for the ``include`` and ``library`` + directories. - ..note:: On Mac OS X, you need to specify ``-DCMAKE_INSTALL_PREFIX=target``, - where ``target`` is a private location, i.e. in parallel to your build - dir by specifying ``../install``. + .. note:: On Mac OS X, you need to specify ``-DCMAKE_INSTALL_PREFIX=target``, + where ``target`` is a private location, i.e. in parallel to your build + dir by specifying ``../install``. 4. Call ``make``. - The owncloud binary will appear in the ``bin`` directory. + The owncloud binary will appear in the ``bin`` directory. The following are known cmake parameters: @@ -257,3 +239,4 @@ .. _Qt: http://www.qt.io/download .. _`Microsoft Authenticode`: https://msdn.microsoft.com/en-us/library/ie/ms537361%28v=vs.85%29.aspx .. _QtKeychain: https://github.com/frankosterfeld/qtkeychain +.. _Packages: http://s.sudre.free.fr/Software/Packages/about.html diff -Nru owncloud-client-1.8.1+dfsg/doc/conffile.rst owncloud-client-2.1.1+dfsg/doc/conffile.rst --- owncloud-client-1.8.1+dfsg/doc/conffile.rst 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/doc/conffile.rst 2016-02-09 15:07:08.000000000 +0000 @@ -1,4 +1,4 @@ -The ownCloud Client reads a configuration file. You can locate this configuration files as follows: +The ownCloud Client reads a configuration file. You can locate this configuration file as follows: On Linux distributions: ``$HOME/.local/share/data/ownCloud/owncloud.cfg`` @@ -16,7 +16,7 @@ .. note:: Use caution when making changes to the ownCloud Client configuration file. Incorrect settings can produce unintended results. -You can change the following configuration settings: +You can change the following configuration settings (must be under the ``[ownCloud]`` section) - ``remotePollInterval`` (default: ``30000``) -- Specifies the poll time for the remote repository in milliseconds. diff -Nru owncloud-client-1.8.1+dfsg/doc/conf.py.in owncloud-client-2.1.1+dfsg/doc/conf.py.in --- owncloud-client-1.8.1+dfsg/doc/conf.py.in 2015-05-06 09:43:58.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/doc/conf.py.in 2016-02-09 15:07:08.000000000 +0000 @@ -48,9 +48,9 @@ # built documents. # # The short X.Y version. -version = '@VERSION_MAJOR@.@VERSION_MINOR@' +version = '@MIRALL_VERSION_MAJOR@.@MIRALL_VERSION_MINOR@' # The full version, including alpha/beta/rc tags. -release = '@VERSION@' +release = '@MIRALL_VERSION@' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -189,7 +189,7 @@ # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +latex_logo = '@LATEX_LOGO@' # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. @@ -288,3 +288,5 @@ # Include todos? todo_include_todos = True + +rst_epilog = '.. |version| replace:: %s' % version diff -Nru owncloud-client-1.8.1+dfsg/doc/dev/CMakeLists.txt owncloud-client-2.1.1+dfsg/doc/dev/CMakeLists.txt --- owncloud-client-1.8.1+dfsg/doc/dev/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/doc/dev/CMakeLists.txt 2016-02-09 15:07:08.000000000 +0000 @@ -0,0 +1,11 @@ +# add a target to generate API documentation with Doxygen +find_package(Doxygen) +if(DOXYGEN_FOUND) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + add_custom_target(doc-dev + ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen" VERBATIM +) +endif(DOXYGEN_FOUND) + diff -Nru owncloud-client-1.8.1+dfsg/doc/dev/Doxyfile.in owncloud-client-2.1.1+dfsg/doc/dev/Doxyfile.in --- owncloud-client-1.8.1+dfsg/doc/dev/Doxyfile.in 1970-01-01 00:00:00.000000000 +0000 +++ owncloud-client-2.1.1+dfsg/doc/dev/Doxyfile.in 2016-02-09 15:07:08.000000000 +0000 @@ -0,0 +1,2307 @@ +# Doxyfile 1.8.6 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "ownCloud Desktop Client Developer Documentation" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = @MIRALL_VERSION@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "APIs, Designs and Concepts" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a +# new page for each member. If set to NO, the documentation of a member will be +# part of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. +# +# Note For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the +# todo list. This list is created by putting \todo commands in the +# documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the +# test list. This list is created by putting \test commands in the +# documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES the list +# will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. Do not use file names with spaces, bibtex cannot handle them. See +# also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO doxygen will only warn about wrong or incomplete parameter +# documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = @CMAKE_SOURCE_DIR@/src/cmd \ + @CMAKE_SOURCE_DIR@/src/crashreporter \ + @CMAKE_SOURCE_DIR@/src/gui \ + @CMAKE_SOURCE_DIR@/src/libsync \ + @CMAKE_CURRENT_SOURCE_DIR@ # for main README.md + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER ) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- +# defined cascading style sheet that is included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefor more robust against future updates. +# Doxygen will copy the style sheet file to the output directory. For an example +# see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the stylesheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated ( +# YES) or that it should be included in the master .chm file ( NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated ( +# YES) or a normal table of contents ( NO) in the .chm file. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /