Comparar commits
1 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 22e31b2232 |
@@ -7,6 +7,7 @@ CMakeLists.txt.user*
|
||||
doc/_build/*
|
||||
*.kate-swp
|
||||
*.kdev4
|
||||
win/
|
||||
admin/win/nsi/l10n/pofiles/*.po
|
||||
*.swp
|
||||
*~$
|
||||
|
||||
+1
-4
@@ -3,13 +3,10 @@
|
||||
url = https://github.com/owncloud/documentation
|
||||
[submodule "src/3rdparty/qtmacgoodies"]
|
||||
path = src/3rdparty/qtmacgoodies
|
||||
url = https://github.com/guruz/qtmacgoodies.git
|
||||
url = git://github.com/guruz/qtmacgoodies.git
|
||||
[submodule "binary"]
|
||||
path = binary
|
||||
url = git://github.com/owncloud/owncloud-client-binary.git
|
||||
[submodule "src/3rdparty/libcrashreporter-qt"]
|
||||
path = src/3rdparty/libcrashreporter-qt
|
||||
url = git://github.com/dschmidt/libcrashreporter-qt.git
|
||||
[submodule "src/3rdparty/qtkeychain"]
|
||||
path = src/3rdparty/qtkeychain
|
||||
url = https://github.com/frankosterfeld/qtkeychain.git
|
||||
|
||||
+4
-10
@@ -1,21 +1,15 @@
|
||||
sudo: required
|
||||
|
||||
language: cpp
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
branches:
|
||||
only:
|
||||
- coverity_scan
|
||||
|
||||
before_install:
|
||||
- sudo sh -c "echo 'deb http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Ubuntu_14.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list"
|
||||
- sudo sh -c "echo 'deb-src http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Ubuntu_14.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list"
|
||||
- wget http://download.opensuse.org/repositories/isv:ownCloud:desktop/Ubuntu_14.04/Release.key
|
||||
- sudo sh -c "echo 'deb http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/xUbuntu_12.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list"
|
||||
- sudo sh -c "echo 'deb-src http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/xUbuntu_12.04/ /' >> /etc/apt/sources.list.d/owncloud-client.list"
|
||||
- wget http://download.opensuse.org/repositories/isv:ownCloud:desktop/xUbuntu_12.04/Release.key
|
||||
- sudo apt-key add - < Release.key
|
||||
- sudo apt-get update
|
||||
- sudo apt-get -y build-dep owncloud-client
|
||||
- sudo apt-get build-dep owncloud-client
|
||||
- checkout=$(git show-ref --head --hash head)
|
||||
- cd ../
|
||||
- wget https://scan.coverity.com/download/linux-64 --post-data "token=$token&project=owncloud%2Fmirall" -O coverity_tool.tgz
|
||||
|
||||
+31
-37
@@ -1,9 +1,5 @@
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(VERSION 2.8.0)
|
||||
if(POLICY CMP0020)
|
||||
cmake_policy(SET CMP0020 NEW)
|
||||
endif()
|
||||
|
||||
project(client)
|
||||
|
||||
@@ -24,11 +20,6 @@ if (NOT DEFINED APPLICATION_SHORTNAME)
|
||||
set ( APPLICATION_SHORTNAME ${APPLICATION_NAME} )
|
||||
endif()
|
||||
|
||||
# For usage in XML files we preprocess
|
||||
string(REPLACE "&" "&" APPLICATION_NAME_XML_ESCAPED "${APPLICATION_NAME}")
|
||||
string(REPLACE "<" "<" APPLICATION_NAME_XML_ESCAPED "${APPLICATION_NAME_XML_ESCAPED}")
|
||||
string(REPLACE ">" ">" APPLICATION_NAME_XML_ESCAPED "${APPLICATION_NAME_XML_ESCAPED}")
|
||||
|
||||
set(PACKAGE "${APPLICATION_SHORTNAME}-client")
|
||||
set( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules )
|
||||
|
||||
@@ -39,7 +30,7 @@ endif()
|
||||
include(Warnings)
|
||||
|
||||
include(${CMAKE_SOURCE_DIR}/VERSION.cmake)
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_BINARY_DIR}/src/mirall/")
|
||||
|
||||
# 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")
|
||||
@@ -58,12 +49,11 @@ if( UNIX AND NOT APPLE )
|
||||
endif()
|
||||
####
|
||||
|
||||
# Enable Q_ASSERT etc. in all builds
|
||||
add_definitions( -DQT_FORCE_ASSERTS )
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(DefineInstallationPaths)
|
||||
include(GenerateExportHeader)
|
||||
include(QtVersionAbstraction)
|
||||
|
||||
setup_qt()
|
||||
|
||||
include(GetGitRevisionDescription)
|
||||
|
||||
@@ -72,7 +62,7 @@ get_git_head_revision(GIT_REFSPEC GIT_SHA1)
|
||||
# if we cannot get it from git, directly try .tag (packages)
|
||||
# this will work if the tar balls have been properly created
|
||||
# via git-archive.
|
||||
if ("${GIT_SHA1}" STREQUAL "GITDIR-NOTFOUND")
|
||||
if (${GIT_SHA1} STREQUAL "GITDIR-NOTFOUND")
|
||||
file(READ ${CMAKE_SOURCE_DIR}/.tag sha1_candidate)
|
||||
string(REPLACE "\n" "" sha1_candidate ${sha1_candidate})
|
||||
if (NOT ${sha1_candidate} STREQUAL "$Format:%H$")
|
||||
@@ -132,30 +122,38 @@ if(OWNCLOUD_5XX_NO_BLACKLIST)
|
||||
add_definitions(-DOWNCLOUD_5XX_NO_BLACKLIST=1)
|
||||
endif()
|
||||
|
||||
# When this option is enabled, a rename that is not allowed will be renamed back
|
||||
# do the original as a restoration step. Withut this option, the restoration will
|
||||
# re-download the file instead.
|
||||
# The default is off because we don't want to rename the files back behind the user's back
|
||||
# Added for IL issue #550
|
||||
option(OWNCLOUD_RESTORE_RENAME "OWNCLOUD_RESTORE_RENAME" OFF)
|
||||
if(OWNCLOUD_RESTORE_RENAME)
|
||||
add_definitions(-DOWNCLOUD_RESTORE_RENAME=1)
|
||||
endif()
|
||||
|
||||
# Disable shibboleth.
|
||||
# So the client can be built without QtWebKit
|
||||
option(NO_SHIBBOLETH "Build without Shibboleth support. Allow to build the client without QtWebKit" OFF)
|
||||
if(NO_SHIBBOLETH)
|
||||
message("Compiling without shibboleth")
|
||||
add_definitions(-DNO_SHIBBOLETH=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
|
||||
# find_package(Qt4 4.7.0 COMPONENTS QtDBus REQUIRED )
|
||||
#endif()
|
||||
|
||||
|
||||
if(HAVE_QT5)
|
||||
if (${Qt5Core_VERSION_MAJOR} EQUAL "5")
|
||||
if (${Qt5Core_VERSION_MINOR} EQUAL "4" OR ${Qt5Core_VERSION_MINOR} GREATER 4)
|
||||
else()
|
||||
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 or higher.")
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL 1.0.0 REQUIRED)
|
||||
|
||||
if(NOT TOKEN_AUTH_ONLY)
|
||||
if (Qt5Core_DIR)
|
||||
find_package(Qt5Keychain REQUIRED)
|
||||
else()
|
||||
find_package(QtKeychain REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
find_package(Sparkle)
|
||||
endif(APPLE)
|
||||
@@ -172,9 +170,6 @@ 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})
|
||||
if (WIN32)
|
||||
add_definitions(-DSQLITE_API=__declspec\(dllimport\))
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(ZLIB)
|
||||
@@ -189,7 +184,6 @@ add_definitions(-DUNICODE)
|
||||
add_definitions(-D_UNICODE)
|
||||
if( WIN32 )
|
||||
add_definitions( -D__USE_MINGW_ANSI_STDIO=1 )
|
||||
add_definitions( -DNOMINMAX )
|
||||
endif( WIN32 )
|
||||
|
||||
# Handle Translations, pick all client_* files from trans directory.
|
||||
|
||||
+5
-175
@@ -1,180 +1,10 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
version 2.3.0 (2017-0x-xx)
|
||||
* WiP!
|
||||
* WiP Switch Windows and OS X build to 5.6.2
|
||||
* WiP Performance improvements for exclude detection
|
||||
* Switch to new ownCloud server WebDAV endpoint
|
||||
* Chunking NG: New file upload chunking algorithmn for ownCloud server 9.2
|
||||
* Allow to sync a folder to multiple different servers (Filename change from .csync_journal.db to _sync_$HASH.db)
|
||||
* Conflicts: Use the local mtime for the conflict file name (#5273)
|
||||
* "Sync now" menu item
|
||||
* SSL Client certificate support improved (Show UI, Store keys in keychain)
|
||||
* Propagator: Upload more small files in parallel
|
||||
* Sync Engine: Read data-fingerprint property to detect backups (#2325)
|
||||
* GUI: Show link to ceate an app password/token for syncing
|
||||
* Share dialog: Add 'Mail link' button
|
||||
* Caja file manager plugin
|
||||
* Make "backup detected" message to not trigger in wrong cases
|
||||
* SyncEngine: Fix renaming of folder when file are changed (#5192)
|
||||
* Fix reconnect bug if status.php intermittently returns wrong data (#5188)
|
||||
* Improve sync scheduling (#5317)
|
||||
* Overlay icons: Improvements in correctnes
|
||||
* Tray menu: Only update on demand to fix Linux desktop integration glitches
|
||||
* Progress: Better time/bandwidth estimations
|
||||
* Network: Follow certain HTTP redirects (#2791)
|
||||
* Network: Remove all cookies (including load balancers etc) when logging out
|
||||
* Discovery thread: Low priority
|
||||
* owncloudsync.log: Write during propagation
|
||||
* Better error message for files with trailing spaces on Windows
|
||||
* Excludes: Consider files in hidden folders excluded (#5163)
|
||||
* Allow sync directory to be a symlinked directory
|
||||
* Add manifest file on Windows to make the application UAC aware
|
||||
* macOS: Improve monochrome tray icons
|
||||
* Don't blacklist 507 Insufficent Storage #5346 (#5424)
|
||||
* Shibboleth bugfixes
|
||||
* Fixes with regards to low disk space
|
||||
* A ton of other bugfixes
|
||||
* Refactorings
|
||||
* Improved documentation
|
||||
* Crash fixes
|
||||
|
||||
version 2.2.4 (release 2016-09-27)
|
||||
* Dolphin Plugin: Use the Application name for the socket path (#5172)
|
||||
* SyncEngine: Fix renaming of folder when file are changed (#5195)
|
||||
* Selective Sync: Fix HTTP request loop and show error in view (#5154)
|
||||
* ConnectionValidator: properly handle error in status.php request (#5188)
|
||||
* Discovery: Set thread priority to low (#5017)
|
||||
* ExcludeFiles: Fix when the folder casing is not the same in the settings and in the FS
|
||||
* ShareLink: Ensure the password line edit is enabled (#5117)
|
||||
|
||||
version 2.2.3 (release 2016-08-08)
|
||||
* SyncEngine: Fix detection of backup (#5104)
|
||||
* Fix bug with overriding URL in config (#5016)
|
||||
* Sharing: Fix bug with file names containing percent encodes (#5042, #5043)
|
||||
* Sharing: Permissions for federated shares on servers >=9.1 (#4996, #5001)
|
||||
* Overlays: Fix issues with file name casing on OS X and Windows
|
||||
* Windows: Skip symlinks and junctions again (#5019)
|
||||
* Only accept notification API Capability if endpoint is OCS-enabled (#5034)
|
||||
* Fix windows HiDPI (#4994)
|
||||
* SocketAPI: Use different pipe name to avoid unusual delay (#4977)
|
||||
* Tray: Add minimal mode as workaround and testing tool for Linux issues (#4985, #4990)
|
||||
* owncloudcmd: Fix --exclude regression #4979
|
||||
* Small memleak: Use the full file stat destructors (#4992)
|
||||
* Fix small QAction memleak (#5008)
|
||||
* Fix crash on shutting down during propagation (#4979)
|
||||
* Decrease memory usage during sync #4979
|
||||
* Setup csync logging earlier to get all log output (#4991)
|
||||
* Enable Shibboleth debug view with OWNCLOUD_SHIBBOLETH_DEBUG env
|
||||
|
||||
version 2.2.2 (release 2016-06-21)
|
||||
* Excludes: Don't redundantly add the same exclude files (memleak) (#4967, #4988)
|
||||
* Excludes: Only log if the pattern was really logged. (#4989)
|
||||
|
||||
version 2.2.1 (release 2016-06-06)
|
||||
* Fix out of memory error when too many uploads happen (#4611)
|
||||
* Fix display errors in progress display (#4803 #4856)
|
||||
* LockWatcher: Remember to upload files after they become unlocked (#4865)
|
||||
* Fix overlay icons for files with umlauts (#4884)
|
||||
* Certs: Re-ask for different cert after rejection (#4898, #4911)
|
||||
* Progress: Don't count items without propagation jobs (#4856, #4910)
|
||||
* Utility: Fix for the translation of minutes, second (#4855)
|
||||
* SyncEngine: invalid the blacklist entry when the rename destination change
|
||||
|
||||
version 2.2.0 (release 2016-05-12)
|
||||
* Overlay icons: Refactoring - mainly for performance improvements
|
||||
* Improved error handling with Sync Journal on USB storages (#4632)
|
||||
* Sharing Completion: Improved UI of completion in sharing from desktop. (#3737)
|
||||
* Show server notifications on the client (#3733)
|
||||
* Improved Speed with small files by dynamic parallel request count (#4529)
|
||||
* LockWatcher: Make sure to sync files after apps released exclusive locks on Windows.
|
||||
* Improved handling of Win32 file locks and network files
|
||||
* Workaround Ubuntu 16.04 tray icon bug (#4693)
|
||||
* Removed the Alias field from the folder definition (#4695)
|
||||
* Improved netrc parser (#4691)
|
||||
* Improved user notifications about ignored files and conflicts (#4761, #3222)
|
||||
* Add warnings for old server versions (#4523)
|
||||
* Enable tranportation checksums if the server supports based on server capabilities (#3735)
|
||||
|
||||
* Default Chunk-size changed to 10MB (#4354)
|
||||
* Documentation Improvements, ie. about overlay icons
|
||||
* Translation fixes
|
||||
* Countless other bugfixes
|
||||
* Sqlite Update to recent version
|
||||
* Update of QtKeyChain to support Windows credential store
|
||||
* Packaging of dolphin overlay icon module for bleeding edge distros
|
||||
|
||||
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.1 (release 2015-yy-zz)
|
||||
* We removed the old libneon-based propagator.
|
||||
It was already disabled on OS X and Windows and only used on
|
||||
Linux when building with Qt < 5.4 and having bandwidth limiting enabled.
|
||||
So now you need Qt 5.4 on Linux if you want bandwidth limiting.
|
||||
|
||||
version 2.0.2 (release 2015-10-21)
|
||||
* csync_file_stat_s: Save a bit of memory
|
||||
|
||||
externo
-58
@@ -1,58 +0,0 @@
|
||||
#!groovy
|
||||
|
||||
node('CLIENT') {
|
||||
stage 'Checkout'
|
||||
checkout scm
|
||||
sh '''git submodule update --init'''
|
||||
|
||||
stage 'Qt4'
|
||||
sh '''rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DUNIT_TESTING=1 -DBUILD_WITH_QT4=ON ..
|
||||
make
|
||||
ctest --output-on-failure'''
|
||||
|
||||
stage 'Qt4 - clang'
|
||||
sh '''rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DUNIT_TESTING=1 -DBUILD_WITH_QT4=ON ..
|
||||
make
|
||||
ctest --output-on-failure'''
|
||||
|
||||
stage 'Qt5'
|
||||
sh '''rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DUNIT_TESTING=1 -DBUILD_WITH_QT4=OFF ..
|
||||
make
|
||||
ctest --output-on-failure'''
|
||||
|
||||
stage 'Qt5 - clang'
|
||||
sh '''rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DUNIT_TESTING=1 -DBUILD_WITH_QT4=OFF ..
|
||||
make
|
||||
ctest --output-on-failure'''
|
||||
|
||||
|
||||
stage 'Win32'
|
||||
def win32 = docker.image('deepdiver/docker-owncloud-client-win32:latest')
|
||||
win32.pull() // make sure we have the latest available from Docker Hub
|
||||
win32.inside {
|
||||
sh '''
|
||||
rm -rf build-win32
|
||||
mkdir build-win32
|
||||
cd build-win32
|
||||
../admin/win/download_runtimes.sh
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../admin/win/Toolchain-mingw32-openSUSE.cmake -DWITH_CRASHREPORTER=ON
|
||||
make -j4
|
||||
make package
|
||||
ctest .
|
||||
'''
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ with your computer.
|
||||
|
||||
### Binary packages
|
||||
|
||||
* Refer to the download page https://owncloud.org/install/#install-clients
|
||||
* Refer to the download page http://owncloud.org/sync-clients/
|
||||
|
||||
### Source code
|
||||
|
||||
@@ -27,7 +27,7 @@ https://github.com/owncloud/client.
|
||||
|
||||
## Building the source code
|
||||
|
||||
[Building the Client](http://doc.owncloud.org/desktop/2.2/building.html)
|
||||
[Building the Client](http://doc.owncloud.org/desktop/2.0/building.html)
|
||||
in the ownCloud Desktop Client manual.
|
||||
|
||||
## Maintainers and Contributors
|
||||
|
||||
+2
-3
@@ -1,11 +1,10 @@
|
||||
set( MIRALL_VERSION_MAJOR 2 )
|
||||
set( MIRALL_VERSION_MINOR 3 )
|
||||
set( MIRALL_VERSION_MINOR 1 )
|
||||
set( MIRALL_VERSION_PATCH 0 )
|
||||
set( MIRALL_VERSION_YEAR 2016 )
|
||||
set( MIRALL_SOVERSION 0 )
|
||||
|
||||
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
set( MIRALL_VERSION_SUFFIX "git") #e.g. beta1, beta2, rc1
|
||||
set( MIRALL_VERSION_SUFFIX "beta1") #e.g. beta1, beta2, rc1
|
||||
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
|
||||
if( NOT DEFINED MIRALL_VERSION_BUILD )
|
||||
|
||||
@@ -25,8 +25,6 @@ def extractDeps(macho):
|
||||
deps = [macho]
|
||||
otool = subprocess.Popen(['otool', '-L', macho], stdout=subprocess.PIPE)
|
||||
for l in otool.communicate()[0].splitlines():
|
||||
if 'is not an object file' in l:
|
||||
return []
|
||||
m = re.search(r'@[^\s]+', l)
|
||||
if m:
|
||||
path = resolvePath(m.group(0))
|
||||
|
||||
+24
-25
@@ -5,8 +5,7 @@
|
||||
#
|
||||
# ownCloud is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
# the Free Software Foundation; version 2 of the License.
|
||||
#
|
||||
# ownCLoud is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -39,7 +38,10 @@ QT_PLUGINS = [
|
||||
'imageformats/libqgif.dylib',
|
||||
'imageformats/libqico.dylib',
|
||||
'imageformats/libqjpeg.dylib',
|
||||
'bearer/libqcorewlanbearer.dylib',
|
||||
'bearer/libqgenericbearer.dylib',
|
||||
'imageformats/libqsvg.dylib',
|
||||
'imageformats/libqmng.dylib',
|
||||
]
|
||||
|
||||
QT_PLUGINS_SEARCH_PATH=[
|
||||
@@ -249,38 +251,35 @@ def CopyPlugin(path, subdir):
|
||||
commands.append(args)
|
||||
return new_path
|
||||
|
||||
def CopyFramework(source_dylib):
|
||||
parts = source_dylib.split(os.sep)
|
||||
print "CopyFramework:", source_dylib
|
||||
def CopyFramework(path):
|
||||
parts = path.split(os.sep)
|
||||
print "CopyFramework:", path
|
||||
for i, part in enumerate(parts):
|
||||
matchObj = re.match(r'(\w+\.framework)', part)
|
||||
if matchObj:
|
||||
full_path = os.path.join(frameworks_dir, *parts[i:-1])
|
||||
framework = matchObj.group(1)
|
||||
dylib_name = parts[-1]
|
||||
source_path = os.path.join('/', *parts[:i+1])
|
||||
dest_path = os.path.join(frameworks_dir, framework)
|
||||
dest_dylib_path = os.path.join(frameworks_dir, *parts[i:-1])
|
||||
break
|
||||
if os.path.exists(dest_path):
|
||||
print dest_path, "already exists, skipping copy..."
|
||||
return os.path.join(dest_dylib_path, dylib_name)
|
||||
args = ['mkdir', '-p', full_path]
|
||||
commands.append(args)
|
||||
args = ['ditto', '--arch=x86_64', path, full_path]
|
||||
commands.append(args)
|
||||
args = ['chmod', 'u+w', os.path.join(full_path, parts[-1])]
|
||||
commands.append(args)
|
||||
resources_dir = os.path.join(frameworks_dir, framework, "Resources")
|
||||
|
||||
args = ['mkdir', '-p', dest_dylib_path]
|
||||
args = ['mkdir', resources_dir]
|
||||
commands.append(args)
|
||||
args = ['ditto', '--arch=x86_64', source_dylib, dest_dylib_path]
|
||||
commands.append(args)
|
||||
args = ['chmod', 'u+w', os.path.join(dest_dylib_path, parts[-1])]
|
||||
commands.append(args)
|
||||
args = ['ln', '-s', '5', os.path.join(dest_path, 'Versions', 'Current')]
|
||||
commands.append(args)
|
||||
args = ['ln', '-s', os.path.join('Versions', 'Current', dylib_name), os.path.join(dest_path, dylib_name)]
|
||||
commands.append(args)
|
||||
args = ['ln', '-s', os.path.join('Versions', 'Current', 'Resources'), os.path.join(dest_path, 'Resources')]
|
||||
commands.append(args)
|
||||
args = ['cp', '-r', os.path.join(source_path, 'Versions', '5', 'Resources'), os.path.join(dest_path, 'Versions', '5')]
|
||||
args = ['chmod', 'u+w', resources_dir]
|
||||
commands.append(args)
|
||||
|
||||
return os.path.join(dest_dylib_path, dylib_name)
|
||||
info_plist = os.path.join(os.path.split(path)[0], '..', '..', 'Contents', 'Info.plist')
|
||||
if not os.path.exists(info_plist):
|
||||
info_plist = os.path.join(os.path.split(path)[0], 'Resources', 'Info.plist')
|
||||
if os.path.exists(info_plist):
|
||||
args = ['cp', '-r', info_plist, resources_dir]
|
||||
commands.append(args)
|
||||
return os.path.join(full_path, parts[-1])
|
||||
|
||||
def FixId(path, library_name):
|
||||
id = '@executable_path/../Frameworks/%s' % library_name
|
||||
|
||||
@@ -497,7 +497,7 @@
|
||||
<key>IDENTIFIER</key>
|
||||
<string>@APPLICATION_REV_DOMAIN_INSTALLER@</string>
|
||||
<key>NAME</key>
|
||||
<string>@APPLICATION_NAME_XML_ESCAPED@</string>
|
||||
<string>@APPLICATION_NAME@</string>
|
||||
<key>OVERWRITE_PERMISSIONS</key>
|
||||
<false/>
|
||||
<key>VERSION</key>
|
||||
@@ -1115,28 +1115,6 @@
|
||||
</dict>
|
||||
<key>PACKAGE_UUID</key>
|
||||
<string>39F61FCD-6EAA-4F3A-81C6-25E3F667DFB5</string>
|
||||
<key>REQUIREMENTS</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>BEHAVIOR</key>
|
||||
<integer>1</integer>
|
||||
<key>DICTIONARY</key>
|
||||
<dict>
|
||||
<key>IC_REQUIREMENT_JAVASCRIPT_FUNCTION</key>
|
||||
<string>olderOsx</string>
|
||||
<key>IC_REQUIREMENT_JAVASCRIPT_PARAMETERS</key>
|
||||
<array/>
|
||||
</dict>
|
||||
<key>IDENTIFIER</key>
|
||||
<string>fr.whitebox.Packages.requirement.javascript</string>
|
||||
<key>MESSAGE</key>
|
||||
<array/>
|
||||
<key>NAME</key>
|
||||
<string>JavaScript</string>
|
||||
<key>STATE</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>TITLE</key>
|
||||
<array/>
|
||||
<key>TOOLTIP</key>
|
||||
@@ -1245,7 +1223,7 @@
|
||||
<key>LANGUAGE</key>
|
||||
<string>English</string>
|
||||
<key>VALUE</key>
|
||||
<string>@APPLICATION_NAME_XML_ESCAPED@ Client</string>
|
||||
<string>@APPLICATION_NAME@ Client</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
@@ -1445,23 +1423,11 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>NAME</key>
|
||||
<string>@APPLICATION_NAME_XML_ESCAPED@ Installer</string>
|
||||
<string>@APPLICATION_NAME@ Installer</string>
|
||||
<key>REFERENCE_FOLDER_PATH</key>
|
||||
<string>@CMAKE_INSTALL_DIR@</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SHARED_GLOBAL_DATA</key>
|
||||
<dict>
|
||||
<key>IC_REQUIREMENT_JAVASCRIPT_SHARED_SOURCE_CODE</key>
|
||||
<string>
|
||||
function olderOsx() {
|
||||
if(system.compareVersions(system.version.ProductVersion, '10.10') == -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
</string>
|
||||
</dict>
|
||||
<key>TYPE</key>
|
||||
<integer>0</integer>
|
||||
<key>VERSION</key>
|
||||
|
||||
@@ -12,10 +12,8 @@ EOF
|
||||
if [ -x "$(command -v pluginkit)" ]; then
|
||||
# add it to DB. This happens automatically too but we try to push it a bit harder for issue #3463
|
||||
pluginkit -a "/Applications/@APPLICATION_EXECUTABLE@.app/Contents/PlugIns/FinderSyncExt.appex/"
|
||||
# Since El Capitan we need to sleep #4650
|
||||
sleep 10s
|
||||
# enable it
|
||||
pluginkit -e use -i @APPLICATION_REV_DOMAIN@.FinderSyncExt
|
||||
fi
|
||||
|
||||
exit 0
|
||||
exit 0
|
||||
@@ -9,9 +9,8 @@ team_identifier="$3"
|
||||
codesign -s "$identity" --force --preserve-metadata=entitlements --verbose=4 --deep "$src_app"
|
||||
|
||||
# Verify the signature
|
||||
codesign -dv $src_app
|
||||
codesign --verify -v $src_app
|
||||
spctl -a -t exec -vv $src_app
|
||||
codesign -dv $src_app
|
||||
|
||||
# Validate that the key used for signing the binary matches the expected TeamIdentifier
|
||||
# needed to pass the SocketApi through the sandbox
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
## Patches used
|
||||
|
||||
There are our patches on top of Qt 5.6.2, which we are currently
|
||||
using for our binary packages on Windows and macOS. Most of them
|
||||
have been sent upstream and are part of newer Qt releases.
|
||||
|
||||
All changes are designed to be upstream, and all those that are
|
||||
special hacks to Qt will bear a NOUPSTREAM in their name
|
||||
|
||||
You can apply those patches on a git clone using:
|
||||
|
||||
```
|
||||
git am <client>/admin/qt/patches/qtbase/*.patch
|
||||
```
|
||||
|
||||
You can update them using:
|
||||
|
||||
```
|
||||
git format-patch -N --no-signature -o <client>/admin/qt/patches/qtbase/ <v5.x.y>
|
||||
```
|
||||
@@ -1,27 +0,0 @@
|
||||
From 96c34ce85136cbdc16ef83effa8a13137f7ae4c5 Mon Sep 17 00:00:00 2001
|
||||
From: Jocelyn Turcotte <jturcotte@woboq.com>
|
||||
Date: Fri, 6 Mar 2015 16:12:37 +0100
|
||||
Subject: [PATCH] [NOUPSTREAM] Fix -force-debug-info with macx-clang
|
||||
|
||||
---
|
||||
mkspecs/common/clang.conf | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf
|
||||
index e003b94..e9b3291 100644
|
||||
--- a/mkspecs/common/clang.conf
|
||||
+++ b/mkspecs/common/clang.conf
|
||||
@@ -21,11 +21,13 @@ QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_
|
||||
QMAKE_CFLAGS_USE_PRECOMPILE = -Xclang -include-pch -Xclang ${QMAKE_PCH_OUTPUT}
|
||||
QMAKE_CFLAGS_LTCG = -flto
|
||||
QMAKE_CFLAGS_DISABLE_LTCG = -fno-lto
|
||||
+QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = $$QMAKE_CFLAGS_OPTIMIZE -g
|
||||
|
||||
QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
|
||||
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
|
||||
QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
|
||||
QMAKE_CXXFLAGS_DISABLE_LTCG = $$QMAKE_CFLAGS_DISABLE_LTCG
|
||||
+QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
|
||||
QMAKE_CXXFLAGS_CXX11 = -std=c++11
|
||||
QMAKE_CXXFLAGS_CXX14 = -std=c++1y
|
||||
QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
|
||||
-148
@@ -1,148 +0,0 @@
|
||||
From e6bccb1f0d8ca59acb1ffdac74a823c06346e7f3 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Molkentin <daniel@molkentin.de>
|
||||
Date: Mon, 16 Nov 2015 15:02:37 +0100
|
||||
Subject: [PATCH] Remove legacy platform code in QSslSocket for OS X < 10.5
|
||||
|
||||
This avoids manual symbol lookups and makes the code more readable.
|
||||
Mark identical code.
|
||||
|
||||
Also use smart pointers instead of manual memory management.
|
||||
|
||||
(Backport of d42d7781f1cd62c3c7c008859507f24a1ff5bb2a to Qt 5.4)
|
||||
|
||||
Change-Id: I62820313dce87de6623cdc87b6e1361200ed7822
|
||||
Reviewed-by: Markus Goetz (Woboq GmbH) <markus@woboq.com>
|
||||
|
||||
Conflicts:
|
||||
src/network/ssl/qsslsocket_openssl.cpp
|
||||
---
|
||||
src/network/ssl/qsslsocket_openssl.cpp | 81 +++++++++++-----------------------
|
||||
src/network/ssl/qsslsocket_p.h | 6 +--
|
||||
2 files changed, 26 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
|
||||
index 82644c1..415f147 100644
|
||||
--- a/src/network/ssl/qsslsocket_openssl.cpp
|
||||
+++ b/src/network/ssl/qsslsocket_openssl.cpp
|
||||
@@ -76,14 +76,17 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
+#ifdef Q_OS_DARWIN
|
||||
+# include <private/qcore_mac_p.h>
|
||||
+#endif
|
||||
+
|
||||
+#ifdef Q_OS_OSX
|
||||
+# include <Security/Security.h>
|
||||
+#endif
|
||||
+
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
-#if defined(Q_OS_MACX)
|
||||
-#define kSecTrustSettingsDomainSystem 2 // so we do not need to include the header file
|
||||
- PtrSecCertificateCopyData QSslSocketPrivate::ptrSecCertificateCopyData = 0;
|
||||
- PtrSecTrustSettingsCopyCertificates QSslSocketPrivate::ptrSecTrustSettingsCopyCertificates = 0;
|
||||
- PtrSecTrustCopyAnchorCertificates QSslSocketPrivate::ptrSecTrustCopyAnchorCertificates = 0;
|
||||
-#elif defined(Q_OS_WIN)
|
||||
+#if defined(Q_OS_WIN)
|
||||
PtrCertOpenSystemStoreW QSslSocketPrivate::ptrCertOpenSystemStoreW = 0;
|
||||
PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = 0;
|
||||
PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = 0;
|
||||
@@ -509,23 +512,7 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
|
||||
|
||||
#ifndef QT_NO_LIBRARY
|
||||
//load symbols needed to receive certificates from system store
|
||||
-#if defined(Q_OS_MACX)
|
||||
- QLibrary securityLib("/System/Library/Frameworks/Security.framework/Versions/Current/Security");
|
||||
- if (securityLib.load()) {
|
||||
- ptrSecCertificateCopyData = (PtrSecCertificateCopyData) securityLib.resolve("SecCertificateCopyData");
|
||||
- if (!ptrSecCertificateCopyData)
|
||||
- qCWarning(lcSsl, "could not resolve symbols in security library"); // should never happen
|
||||
-
|
||||
- ptrSecTrustSettingsCopyCertificates = (PtrSecTrustSettingsCopyCertificates) securityLib.resolve("SecTrustSettingsCopyCertificates");
|
||||
- if (!ptrSecTrustSettingsCopyCertificates) { // method was introduced in Leopard, use legacy method if it's not there
|
||||
- ptrSecTrustCopyAnchorCertificates = (PtrSecTrustCopyAnchorCertificates) securityLib.resolve("SecTrustCopyAnchorCertificates");
|
||||
- if (!ptrSecTrustCopyAnchorCertificates)
|
||||
- qCWarning(lcSsl, "could not resolve symbols in security library"); // should never happen
|
||||
- }
|
||||
- } else {
|
||||
- qCWarning(lcSsl, "could not load security library");
|
||||
- }
|
||||
-#elif defined(Q_OS_WIN)
|
||||
+#if defined(Q_OS_WIN)
|
||||
HINSTANCE hLib = LoadLibraryW(L"Crypt32");
|
||||
if (hLib) {
|
||||
#if defined(Q_OS_WINCE)
|
||||
@@ -693,40 +680,22 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
|
||||
timer.start();
|
||||
#endif
|
||||
QList<QSslCertificate> systemCerts;
|
||||
-#if defined(Q_OS_MACX)
|
||||
- CFArrayRef cfCerts;
|
||||
- OSStatus status = 1;
|
||||
-
|
||||
- CFDataRef SecCertificateCopyData (
|
||||
- SecCertificateRef certificate
|
||||
- );
|
||||
-
|
||||
- if (ptrSecCertificateCopyData) {
|
||||
- if (ptrSecTrustSettingsCopyCertificates)
|
||||
- status = ptrSecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts);
|
||||
- else if (ptrSecTrustCopyAnchorCertificates)
|
||||
- status = ptrSecTrustCopyAnchorCertificates(&cfCerts);
|
||||
- if (!status) {
|
||||
- CFIndex size = CFArrayGetCount(cfCerts);
|
||||
- for (CFIndex i = 0; i < size; ++i) {
|
||||
- SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i);
|
||||
- CFDataRef data;
|
||||
-
|
||||
- data = ptrSecCertificateCopyData(cfCert);
|
||||
-
|
||||
- if (data == NULL) {
|
||||
- qCWarning(lcSsl, "error retrieving a CA certificate from the system store");
|
||||
- } else {
|
||||
- QByteArray rawCert = QByteArray::fromRawData((const char *)CFDataGetBytePtr(data), CFDataGetLength(data));
|
||||
- systemCerts.append(QSslCertificate::fromData(rawCert, QSsl::Der));
|
||||
- CFRelease(data);
|
||||
- }
|
||||
+ // note: also check implementation in openssl_mac.cpp
|
||||
+#if defined(Q_OS_OSX)
|
||||
+ // SecTrustSettingsCopyCertificates is not defined on iOS.
|
||||
+ QCFType<CFArrayRef> cfCerts;
|
||||
+
|
||||
+ OSStatus status = SecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts);
|
||||
+ if (status == noErr ) {
|
||||
+ const CFIndex size = CFArrayGetCount(cfCerts);
|
||||
+ for (CFIndex i = 0; i < size; ++i) {
|
||||
+ SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i);
|
||||
+ QCFType<CFDataRef> derData = SecCertificateCopyData(cfCert);
|
||||
+ if (derData == NULL) {
|
||||
+ qWarning("error retrieving a CA certificate from the system store");
|
||||
+ } else {
|
||||
+ systemCerts << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
|
||||
}
|
||||
- CFRelease(cfCerts);
|
||||
- }
|
||||
- else {
|
||||
- // no detailed error handling here
|
||||
- qCWarning(lcSsl, "could not retrieve system CA certificates");
|
||||
}
|
||||
}
|
||||
#elif defined(Q_OS_WIN)
|
||||
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
|
||||
index d651971..17cc7b4 100644
|
||||
--- a/src/network/ssl/qsslsocket_p.h
|
||||
+++ b/src/network/ssl/qsslsocket_p.h
|
||||
@@ -151,11 +151,7 @@ public:
|
||||
static bool isMatchingHostname(const QSslCertificate &cert, const QString &peerName);
|
||||
Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname);
|
||||
|
||||
-#if defined(Q_OS_MACX)
|
||||
- static PtrSecCertificateCopyData ptrSecCertificateCopyData;
|
||||
- static PtrSecTrustSettingsCopyCertificates ptrSecTrustSettingsCopyCertificates;
|
||||
- static PtrSecTrustCopyAnchorCertificates ptrSecTrustCopyAnchorCertificates;
|
||||
-#elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||
static PtrCertOpenSystemStoreW ptrCertOpenSystemStoreW;
|
||||
static PtrCertFindCertificateInStore ptrCertFindCertificateInStore;
|
||||
static PtrCertCloseStore ptrCertCloseStore;
|
||||
-276
@@ -1,276 +0,0 @@
|
||||
From 9d1120db0973ea7741b13a6555b20ae61f6d037e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Molkentin <danimo@owncloud.com>
|
||||
Date: Wed, 25 Nov 2015 12:37:27 +0100
|
||||
Subject: [PATCH] QSslSocket: evaluate CAs in all keychain categories
|
||||
|
||||
This will make sure that certs in the domainUser (login),
|
||||
and domainAdmin (per machine) keychain are being picked up
|
||||
in systemCaCertificates() in addition to the (usually immutable)
|
||||
DomainSystem keychain.
|
||||
|
||||
Also consider the trust settings on OS X: If a certificate
|
||||
is either fully trusted or trusted for the purpose of SSL,
|
||||
it will be accepted.
|
||||
|
||||
[ChangeLog][Platform Specific Changes] OS X now accepts trusted
|
||||
certificates from the login and system keychains.
|
||||
|
||||
(Backport of fe3a84138e266c425f11353f7d8dc28a588af89e)
|
||||
|
||||
Task-number: QTBUG-32898
|
||||
Change-Id: Ia23083d5af74388eeee31ba07239735cbbe64368
|
||||
Reviewed-by: Markus Goetz (Woboq GmbH) <markus@woboq.com>
|
||||
---
|
||||
src/network/ssl/qsslsocket.cpp | 4 +
|
||||
src/network/ssl/qsslsocket_mac_shared.cpp | 148 ++++++++++++++++++++++++++++++
|
||||
src/network/ssl/qsslsocket_openssl.cpp | 30 +-----
|
||||
src/network/ssl/ssl.pri | 4 +-
|
||||
4 files changed, 158 insertions(+), 28 deletions(-)
|
||||
create mode 100644 src/network/ssl/qsslsocket_mac_shared.cpp
|
||||
|
||||
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
|
||||
index 549906a..7b202b0 100644
|
||||
--- a/src/network/ssl/qsslsocket.cpp
|
||||
+++ b/src/network/ssl/qsslsocket.cpp
|
||||
@@ -1508,6 +1508,10 @@ QList<QSslCertificate> QSslSocket::defaultCaCertificates()
|
||||
returned by defaultCaCertificates(). You can replace that database
|
||||
with your own with setDefaultCaCertificates().
|
||||
|
||||
+ \note: On OS X, only certificates that are either trusted for all
|
||||
+ purposes or trusted for the purpose of SSL in the keychain will be
|
||||
+ returned.
|
||||
+
|
||||
\sa caCertificates(), defaultCaCertificates(), setDefaultCaCertificates()
|
||||
*/
|
||||
QList<QSslCertificate> QSslSocket::systemCaCertificates()
|
||||
diff --git a/src/network/ssl/qsslsocket_mac_shared.cpp b/src/network/ssl/qsslsocket_mac_shared.cpp
|
||||
new file mode 100644
|
||||
index 0000000..60fea4c
|
||||
--- /dev/null
|
||||
+++ b/src/network/ssl/qsslsocket_mac_shared.cpp
|
||||
@@ -0,0 +1,148 @@
|
||||
+/****************************************************************************
|
||||
+**
|
||||
+** Copyright (C) 2015 The Qt Company Ltd.
|
||||
+** Copyright (C) 2015 ownCloud Inc
|
||||
+** Contact: http://www.qt.io/licensing/
|
||||
+**
|
||||
+** This file is part of the QtNetwork module of the Qt Toolkit.
|
||||
+**
|
||||
+** $QT_BEGIN_LICENSE:LGPL21$
|
||||
+** Commercial License Usage
|
||||
+** Licensees holding valid commercial Qt licenses may use this file in
|
||||
+** accordance with the commercial license agreement provided with the
|
||||
+** Software or, alternatively, in accordance with the terms contained in
|
||||
+** a written agreement between you and The Qt Company. For licensing terms
|
||||
+** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
+** information use the contact form at http://www.qt.io/contact-us.
|
||||
+**
|
||||
+** GNU Lesser General Public License Usage
|
||||
+** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
+** General Public License version 2.1 or version 3 as published by the Free
|
||||
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
+** following information to ensure the GNU Lesser General Public License
|
||||
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
+**
|
||||
+** As a special exception, The Qt Company gives you certain additional
|
||||
+** rights. These rights are described in The Qt Company LGPL Exception
|
||||
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
+**
|
||||
+** $QT_END_LICENSE$
|
||||
+**
|
||||
+****************************************************************************/
|
||||
+
|
||||
+//#define QSSLSOCKET_DEBUG
|
||||
+//#define QT_DECRYPT_SSL_TRAFFIC
|
||||
+
|
||||
+#include "qsslsocket.h"
|
||||
+
|
||||
+#ifndef QT_NO_OPENSSL
|
||||
+# include "qsslsocket_openssl_p.h"
|
||||
+# include "qsslsocket_openssl_symbols_p.h"
|
||||
+#endif
|
||||
+
|
||||
+#include "qsslcertificate_p.h"
|
||||
+
|
||||
+#ifdef Q_OS_DARWIN
|
||||
+# include <private/qcore_mac_p.h>
|
||||
+#endif
|
||||
+
|
||||
+#include <QtCore/qdebug.h>
|
||||
+
|
||||
+#ifdef Q_OS_OSX
|
||||
+# include <Security/Security.h>
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+QT_BEGIN_NAMESPACE
|
||||
+
|
||||
+#ifdef Q_OS_OSX
|
||||
+namespace {
|
||||
+
|
||||
+bool hasTrustedSslServerPolicy(SecPolicyRef policy, CFDictionaryRef props) {
|
||||
+ QCFType<CFDictionaryRef> policyProps = SecPolicyCopyProperties(policy);
|
||||
+ // only accept certificates with policies for SSL server validation for now
|
||||
+ if (CFEqual(CFDictionaryGetValue(policyProps, kSecPolicyOid), kSecPolicyAppleSSL)) {
|
||||
+ CFBooleanRef policyClient;
|
||||
+ if (CFDictionaryGetValueIfPresent(policyProps, kSecPolicyClient, reinterpret_cast<const void**>(&policyClient)) &&
|
||||
+ CFEqual(policyClient, kCFBooleanTrue)) {
|
||||
+ return false; // no client certs
|
||||
+ }
|
||||
+ if (!CFDictionaryContainsKey(props, kSecTrustSettingsResult)) {
|
||||
+ // as per the docs, no trust settings result implies full trust
|
||||
+ return true;
|
||||
+ }
|
||||
+ CFNumberRef number = static_cast<CFNumberRef>(CFDictionaryGetValue(props, kSecTrustSettingsResult));
|
||||
+ SecTrustSettingsResult settingsResult;
|
||||
+ CFNumberGetValue(number, kCFNumberSInt32Type, &settingsResult);
|
||||
+ switch (settingsResult) {
|
||||
+ case kSecTrustSettingsResultTrustRoot:
|
||||
+ case kSecTrustSettingsResultTrustAsRoot:
|
||||
+ return true;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+bool isCaCertificateTrusted(SecCertificateRef cfCert, int domain)
|
||||
+{
|
||||
+ QCFType<CFArrayRef> cfTrustSettings;
|
||||
+ OSStatus status = SecTrustSettingsCopyTrustSettings(cfCert, domain, &cfTrustSettings);
|
||||
+ if (status == noErr) {
|
||||
+ CFIndex size = CFArrayGetCount(cfTrustSettings);
|
||||
+ // if empty, trust for everything (as per the Security Framework documentation)
|
||||
+ if (size == 0) {
|
||||
+ return true;
|
||||
+ } else {
|
||||
+ for (CFIndex i = 0; i < size; ++i) {
|
||||
+ CFDictionaryRef props = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(cfTrustSettings, i));
|
||||
+ if (CFDictionaryContainsKey(props, kSecTrustSettingsPolicy)) {
|
||||
+ if (hasTrustedSslServerPolicy((SecPolicyRef)CFDictionaryGetValue(props, kSecTrustSettingsPolicy), props))
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ qWarning("Error receiving trust for a CA certificate");
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+} // anon namespace
|
||||
+#endif // Q_OS_OSX
|
||||
+
|
||||
+QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
|
||||
+{
|
||||
+ ensureInitialized();
|
||||
+
|
||||
+ QList<QSslCertificate> systemCerts;
|
||||
+ // SecTrustSettingsCopyCertificates is not defined on iOS.
|
||||
+#ifdef Q_OS_OSX
|
||||
+ QCFType<CFArrayRef> cfCerts;
|
||||
+ // iterate through all enum members, order:
|
||||
+ // kSecTrustSettingsDomainUser, kSecTrustSettingsDomainAdmin, kSecTrustSettingsDomainSystem
|
||||
+ for (int dom = kSecTrustSettingsDomainUser; dom <= kSecTrustSettingsDomainSystem; dom++) {
|
||||
+ OSStatus status = SecTrustSettingsCopyCertificates(dom, &cfCerts);
|
||||
+ if (status == noErr) {
|
||||
+ const CFIndex size = CFArrayGetCount(cfCerts);
|
||||
+ for (CFIndex i = 0; i < size; ++i) {
|
||||
+ SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i);
|
||||
+ QCFType<CFDataRef> derData = SecCertificateCopyData(cfCert);
|
||||
+ if (::isCaCertificateTrusted(cfCert, dom)) {
|
||||
+ if (derData == NULL) {
|
||||
+ qWarning("Error retrieving a CA certificate from the system store");
|
||||
+ } else {
|
||||
+ systemCerts << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+ return systemCerts;
|
||||
+}
|
||||
+
|
||||
+QT_END_NAMESPACE
|
||||
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
|
||||
index 415f147..7a3cb42 100644
|
||||
--- a/src/network/ssl/qsslsocket_openssl.cpp
|
||||
+++ b/src/network/ssl/qsslsocket_openssl.cpp
|
||||
@@ -76,14 +76,6 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
-#ifdef Q_OS_DARWIN
|
||||
-# include <private/qcore_mac_p.h>
|
||||
-#endif
|
||||
-
|
||||
-#ifdef Q_OS_OSX
|
||||
-# include <Security/Security.h>
|
||||
-#endif
|
||||
-
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
@@ -672,6 +664,7 @@ void QSslSocketPrivate::resetDefaultEllipticCurves()
|
||||
setDefaultSupportedEllipticCurves(curves);
|
||||
}
|
||||
|
||||
+#ifndef Q_OS_DARWIN // Apple implementation in qsslsocket_mac_shared.cpp
|
||||
QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
|
||||
{
|
||||
ensureInitialized();
|
||||
@@ -680,25 +673,7 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
|
||||
timer.start();
|
||||
#endif
|
||||
QList<QSslCertificate> systemCerts;
|
||||
- // note: also check implementation in openssl_mac.cpp
|
||||
-#if defined(Q_OS_OSX)
|
||||
- // SecTrustSettingsCopyCertificates is not defined on iOS.
|
||||
- QCFType<CFArrayRef> cfCerts;
|
||||
-
|
||||
- OSStatus status = SecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts);
|
||||
- if (status == noErr ) {
|
||||
- const CFIndex size = CFArrayGetCount(cfCerts);
|
||||
- for (CFIndex i = 0; i < size; ++i) {
|
||||
- SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i);
|
||||
- QCFType<CFDataRef> derData = SecCertificateCopyData(cfCert);
|
||||
- if (derData == NULL) {
|
||||
- qWarning("error retrieving a CA certificate from the system store");
|
||||
- } else {
|
||||
- systemCerts << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-#elif defined(Q_OS_WIN)
|
||||
+#if defined(Q_OS_WIN)
|
||||
if (ptrCertOpenSystemStoreW && ptrCertFindCertificateInStore && ptrCertCloseStore) {
|
||||
HCERTSTORE hSystemStore;
|
||||
#if defined(Q_OS_WINCE)
|
||||
@@ -775,6 +750,7 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
|
||||
|
||||
return systemCerts;
|
||||
}
|
||||
+#endif // Q_OS_DARWIN
|
||||
|
||||
void QSslSocketBackendPrivate::startClientEncryption()
|
||||
{
|
||||
diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri
|
||||
index 29c47cd..8eb605b 100644
|
||||
--- a/src/network/ssl/ssl.pri
|
||||
+++ b/src/network/ssl/ssl.pri
|
||||
@@ -62,7 +62,9 @@ contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
|
||||
ssl/qsslsocket_openssl.cpp \
|
||||
ssl/qsslsocket_openssl_symbols.cpp
|
||||
|
||||
-android:!android-no-sdk: SOURCES += ssl/qsslsocket_openssl_android.cpp
|
||||
+ darwin:SOURCES += ssl/qsslsocket_mac_shared.cpp
|
||||
+
|
||||
+ android:!android-no-sdk: SOURCES += ssl/qsslsocket_openssl_android.cpp
|
||||
|
||||
# Add optional SSL libs
|
||||
# Static linking of OpenSSL with msvc:
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# This script creates a new windows toolchain repository in OBS.
|
||||
# It only works for versions that do not yet exist.
|
||||
#
|
||||
# Make sure to adopt the variable stableversion.
|
||||
|
||||
# Set the new stable version accordingly:
|
||||
stableversion=2.1
|
||||
targetproject="isv:ownCloud:toolchains:mingw:win32:${stableversion}"
|
||||
|
||||
# Create the new repo
|
||||
|
||||
# get the xml build description of the stable repo
|
||||
xml=`osc meta prj isv:ownCloud:toolchains:mingw:win32:stable`
|
||||
stable_xml="${xml/stable/$stableversion}"
|
||||
|
||||
echo $stable_xml
|
||||
|
||||
echo $stable_xml | osc meta prj -F - ${targetproject}
|
||||
|
||||
|
||||
# now copy all packages
|
||||
packs=`osc ls isv:ownCloud:toolchains:mingw:win32:stable`
|
||||
|
||||
for pack in $packs
|
||||
do
|
||||
osc copypac isv:ownCloud:toolchains:mingw:win32:stable $pack $targetproject
|
||||
done
|
||||
@@ -1,37 +0,0 @@
|
||||
FROM opensuse:42.1
|
||||
|
||||
MAINTAINER Daniel Molkentin <danimo@owncloud.com>
|
||||
|
||||
ENV TERM ansi
|
||||
ENV HOME /root
|
||||
|
||||
ENV REFRESHED_AT 20160421
|
||||
|
||||
RUN zypper --non-interactive --gpg-auto-import-keys refresh
|
||||
RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_42.1/windows:mingw.repo
|
||||
RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse.org/repositories/isv:ownCloud:toolchains:mingw:win32:2.2/openSUSE_Leap_42.1/isv:ownCloud:toolchains:mingw:win32:2.2.repo
|
||||
RUN zypper --non-interactive --gpg-auto-import-keys 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-libwebp \
|
||||
mingw32-cross-libqt5-qmake mingw32-cross-libqt5-qttools mingw32-libqt5* \
|
||||
mingw32-qt5keychain* mingw32-angleproject* \
|
||||
mingw32-cross-nsis mingw32-libopenssl* \
|
||||
mingw32-sqlite* kdewin-png2ico \
|
||||
osslsigncode wget
|
||||
|
||||
# RPM depends on curl for installs from HTTP
|
||||
RUN zypper --non-interactive --gpg-auto-import-keys install curl
|
||||
|
||||
# sudo needed for building as user
|
||||
RUN zypper --non-interactive --gpg-auto-import-keys install sudo
|
||||
|
||||
# Use packaged UAC dependencies
|
||||
RUN zypper --non-interactive --gpg-auto-import-keys install mingw32-cross-nsis-plugin-uac mingw32-cross-nsis-plugin-nsprocess
|
||||
|
||||
# Required for checksumming
|
||||
RUN zypper --non-interactive --gpg-auto-import-keys install mingw32-zlib-devel
|
||||
|
||||
# Required for windres not to crash
|
||||
RUN zypper --non-interactive --gpg-auto-import-keys install glibc-locale
|
||||
|
||||
CMD /bin/bash
|
||||
@@ -7,13 +7,13 @@ fi
|
||||
|
||||
useradd user -u ${2:-1000}
|
||||
su - user << EOF
|
||||
cd /home/user/$1
|
||||
rm -rf build-win32
|
||||
mkdir build-win32
|
||||
cd build-win32
|
||||
../admin/win/download_runtimes.sh
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../admin/win/Toolchain-mingw32-openSUSE.cmake -DWITH_CRASHREPORTER=ON
|
||||
make -j4
|
||||
make package
|
||||
ctest .
|
||||
cd /home/user/$1
|
||||
rm -rf build-win32
|
||||
mkdir build-win32
|
||||
cd build-win32
|
||||
../admin/win/download_runtimes.sh
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../admin/win/Toolchain-mingw32-openSUSE.cmake -DWITH_CRASHREPORTER=ON
|
||||
make -j4
|
||||
make package
|
||||
ctest .
|
||||
EOF
|
||||
|
||||
@@ -29,15 +29,15 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "${APPLICATION_NAME}erako Abiarazle
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Desinstalatzailea idazten"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Instalatzaileko Erregistroko Giltzak idazten"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Bukatuta"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Ez dirudi ${APPLICATION_NAME} '$INSTDIR'.$ direktorioan instalatuta dagoenik.$\n$\nJarraitu hala ere (ez da aholkatzen)?"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Ez dirudi ${APPLICATION_NAME} '$INSTDIR'.$ direktorioan instalatuta dagoenik.\n$\nJarraitu hala ere (ez da aholkatzen)?"
|
||||
StrCpy $UNINSTALL_ABORT "Desinstalazioak erabiltzaileak bertan behera utzi du"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Abiarazle Bizkorreko Lasterbidea (E/E)"
|
||||
StrCpy $INIT_NO_DESKTOP "Mahaigaineko Lasterbidea (dagoena berridazten du)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Ezin izan da goratu, errorea:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Instalatzaileak administratzaile baimenak behar ditu, saiatu berriro"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Instalatzailea dagoeneko martxan da."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Desinstalatzaile honek administratzaile baimenak behar ditu, saiatu berriro"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Saioa hasteko zerbitzua ez dago martxan, bertan behera uzten!"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Desinstalatzailea dagoeneko martxan da."
|
||||
StrCpy $SectionGroup_Shortcuts "Lasterbideak"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $UAC_ERROR_ELEVATE "Unable to elevate, error:"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -9,7 +9,6 @@ StrCpy $PageReinstall_NEW_Field_3 "No instal·lar"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Ja instal·lat"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Trieu la manera com voleu instal·lar ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Una versió més recent de ${APPLICATION_NAME} ja està instal.lada!! No es recomana instal.lar una versió més antiga. Si realment voleu instal.lar una versió més antiga, és millor primer desinstal.lar la versió actual. Seleccioni l'operació que desitjeu realitzar i feu clic a Següent per a continuar."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} ja està instal·lat.$\n$\nSeleccioneu la operació que voleu fer i feu clic a Següent per continuar."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Afegir/Reinstal.lar components"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Desinstal.lar ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Desinstal.lar ${APPLICATION_NAME}"
|
||||
@@ -38,6 +37,7 @@ StrCpy $UAC_ERROR_ELEVATE "No es pot elevar, error:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Aquest instal·lador requereix accés d'administrador, intenteu-ho de nou"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "L'instal·lador ja s'està executant."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Aquest desinstal·lador requereix accés d'administrador, intenteu-ho de nou."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "El servei de inici de sessió no s'està executant, s'està abortant!"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "El desinstal·lador ja s'està executant."
|
||||
StrCpy $SectionGroup_Shortcuts "Dreceres"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -30,7 +30,7 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Z
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Zapisuji odinstal tor"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Zapisuji instal tor do registr…"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "DokonŸeno"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Nezd se, §e ${APPLICATION_NAME} je nainstalov na v adres ýi '$INSTDIR'.$\n$\nChcete pokraŸovat (nedoporuŸuje se)?"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Nezd se, §e ${APPLICATION_NAME} je nainstalov na ve slo§ce '$INSTDIR'.$\n$\nChcete pokraŸovat (nedoporuŸuje se)?"
|
||||
StrCpy $UNINSTALL_ABORT "Odinstalace zruçena u§ivatelem"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Z stupce rychl‚ho spuçtØn¡ (nen¡ k dispozici)"
|
||||
StrCpy $INIT_NO_DESKTOP "Z stupce na ploçe (pýep¡çe existuj¡c¡)"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Toon opmerkingen bij deze versie"
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Toon releaseopmerkingen"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Gevonden ${APPLICATION_EXECUTABLE} proces(sen) moet worden gestopt.$\nWilt u dat het installatieprogramma dat voor u doet?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Stoppen ${APPLICATION_EXECUTABLE} processen."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Het te stoppen proces is niet gevonden!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Er is een oudere versie van ${APPLICATION_NAME} geïnstalleerd op uw systeem. geadviseerd wordt om de huidige versie te de-installeren voordat de nieuwe versie wordt geïnstalleerd. Selecteer de uit te voeren actie en klik op Verder om door te gaan."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Verwijder oude versie"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Behoud oude versie"
|
||||
StrCpy $PageReinstall_NEW_Field_2 "De-installeren voor installeren"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Niet de-installeren"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Al geïnstalleerd"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Kies hoe u ${APPLICATION_NAME} wilt installeren."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Er is al een recentere versie van ${APPLICATION_NAME} geïnstalleerd! Installeren van een oudere versie wordt niet aangeraden. Als u echt de oudere versie wilt installeren, adviseren we de huidige versie eerst te verwijderen. Kies de actie die u wilt uitvoeren en druk op Verder om door te gaan."
|
||||
|
||||
@@ -30,7 +30,7 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "میانبر اجرای سریع ب
|
||||
StrCpy $UNINSTALLER_FILE_Detail "نوشتن حذف کننده"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "در حال نوشتن کلید های رجیستری نصاب"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "اتمام"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "به نظر نمی رسد نرم افزار ${APPLICATION_NAME} در '$INSTDIR'.$\n$\nنصب شده باشد.$\nآیا می خواهید ادامه دهید ( توصیه نشده است ) ؟"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "به نظر نمی رسد نرم افزار ${APPLICATION_NAME} در '$INSTDIR'.$\n$\nنصب شده باشد.\nآیا می خواهید ادامه دهید ( توصیه نشده است ) ؟"
|
||||
StrCpy $UNINSTALL_ABORT "عمل حذف توسط کاربر متوقف شد"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "میانبر بازکردن سریع ( N/A )"
|
||||
StrCpy $INIT_NO_DESKTOP "میانبر دسکتاپ (رونویسی وجود دارد)"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Näytä julkaisutiedot"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Havaittiin sovelluksen ${APPLICATION_EXECUTABLE} prosessi (tai prosesseja) jotka pitäisi pysäyttää.$\nHaluatko että asennusohjelma pysäyttää nämä puolestasi?"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Havaittiin sovelluksen ${APPLICATION_EXECUTABLE} prosessi (tai prosesseja) jotka pitäisi pysäyttää.\nHaluatko että asennusohjelma pysäyttää nämä puolestasi?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Pysäytetään sovelluksen ${APPLICATION_EXECUTABLE} prosessit."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Tapettavaa prosessia ei löytynyt!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Vanhempi versio sovelluksesta ${APPLICATION_NAME} on jo asennettu. On suositeltavaa että poistat vanhan asennuksen ensin. Valitse mikä toiminto suoritetaan ja napsauta Seuraava jatkaaksesi."
|
||||
@@ -30,7 +30,7 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Pikak
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Kirjoitetaan poisto-ohjelmaa"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Kirjoitetaan asennusohjelman rekisteriavaimia"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Valmis"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Vaikuttaa siltä että sovellus ${APPLICATION_NAME} on asennettu kansioon '$INSTDIR'.$\n$\nHaluatko jatkaa tästä huolimatta (ei suositeltavaa)?"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Vaikuttaa siltä että sovellus ${APPLICATION_NAME} on asennettu kansioon '$INSTDIR'.\n\nHaluatko jatkaa tästä huolimatta (ei suositeltavaa)?"
|
||||
StrCpy $UNINSTALL_ABORT "Poistaminen keskeytettiin käyttäjän toimesta"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Pikakäynnistyksen pikakuvake (-)"
|
||||
StrCpy $INIT_NO_DESKTOP "Työpöydän pikakuvake (korvaa nykyinen)"
|
||||
|
||||
@@ -9,7 +9,6 @@ StrCpy $PageReinstall_NEW_Field_3 "Nicht entfernen"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Bereits installiert"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Wählen Sie die Methode, mit der sie ${APPLICATION_NAME} installieren wollen."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Eine neuere Version von ${APPLICATION_NAME} ist bereits installiert! Es wird nicht empfohlen, eine ältere Version zu installieren. Wollen Sie dies trotzdem tun, so sollten Sie die aktuelle Version zunächst entfernen. Wählen Sie eine Vorgehensweise und wählen dann $\"Weiter$\"."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} ist bereits installiert. $\nWählen Sie eine Vorgehensweise und klicken Sie auf $\"Weiter$\"."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Komponenten hinzufügen"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} entfernen"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} entfernen"
|
||||
@@ -38,6 +37,7 @@ StrCpy $UAC_ERROR_ELEVATE "Rechte k
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Dieses Installationsprogramm erfordert Administrator-Rechte, bitte erneut versuchen"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Das Installationsprogramm wird bereits ausgeführt."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Das Deinstallationsprogramm erfordert Administrator-Rechte. Bitte erneut versuchen."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Anmeldedienst läuft nicht, abbruch!"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Das Deinstallationsprogramm wird bereits ausgeführt."
|
||||
StrCpy $SectionGroup_Shortcuts "Verknüpfungen"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Kiadási jegyzetek megtekintése"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "A következő folyamatot(okat) meg kell állítani ${APPLICATION_EXECUTABLE}.$\nSzeretné ha a telepítő program megállítani ezeket a folyamatokat?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "${APPLICATION_EXECUTABLE} folyamat kilövése."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "A kilövésre szánt folyamat nem található!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Az ${APPLICATION_NAME} alkalmazás egy régebbi verziója telepítve van a rendszeren. Ajánlott a régi alkalmazás eltávolítása mielőtt a legfrissebb verziót telepítené. Válassza ki milyen műveletet szeretne végrehajtani, és nyomja meg a $\"Következő$\" gombot a folytatáshoz."
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Folyamat ${APPLICATION_EXECUTABLE} kilövése."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Kilövésre szánt folyamat nem található."
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Az ${APPLICATION_NAME} alkalmazás egy régebbi verziója telepítva van a rendszeren. Ajánlott a régi alkalmazás eltávolítása mielőtt a legfrissebb verziót telepítané. Válassza ki milyen műveletet szeretne végrehajtani, és nyomja meg a $\"Következő$\" gombot a folytatáshoz."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Eltávolítás telepítés előtt"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Ne távolítsa el"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Már telepítve"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Válassza ki, hogy szeretné telepíteni a következő alkalmazást: ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Az ${APPLICATION_NAME} alkalmazás egy újabb verziója már megtalálható a rendszeren. Nem ajánlott egy régebbi verzió telepítése. Ha valóban szeretné a régebbi verziót telepíteni, akkor ajánlott a jelenleg telepített verzió eltávolítása. Válassza ki milyen műveletet szeretne végrehajtani, és nyomja meg a $\"Következő$\" gombot a folytatáshoz."
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Válaszd ki, hogy szeretnéd telepíteni a következő alkalmazást ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Az ${APPLICATION_NAME} alklamazás egy újabb verziója már megtalálható a rendszeren. Nem ajánlott egy régebbi verzió telepítése. Ha valóban szeretné a régebbi verziót telepíteni, akkor ajánlott a jelenleg telepített verzió eltávolítása. Válassza ki milyen műveletet szeretne végrehajtani, és nyomja meg a $\"Következő$\" gombot a folytatáshoz."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "Az ${APPLICATION_NAME} alkalmazás ${VERSION} verziója már telepítve van.$↩$\nKérjük válaszd ki milyen műveletet szeretnél végrehajtani, és nyomd meg a „Következő” gombot."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Komponens hozzáadása/újratelepítése"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} eltávolítása"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} eltávolítása"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Válassza ki milyen karbantartási műveletet szeretne elvégezni."
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Kérem válassza ki milyen karbantartási műveletet szeretne elvégezni?"
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Az ${APPLICATION_NAME} alkalmazás lényeges komponenseinek telepítése."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Windows Explorer integráció"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Windows Explorer integráció telepítése"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Start Menü parancsikonok"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Windows Explorer Integráció"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Windows Explorer Integráció Telepítése"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Start Menü Parancsikonok"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "A ${APPLICATION_NAME} parancsikon hozzáadása a Start Menühöz"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Asztali parancsikon"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Asztali parancsikon létrehozása"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Gyorsindító eszköztár parancsikon"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Gyorsindító eszköztár parancsikon létrehozása"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Asztali Parancsikon"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Asztali Parancsikon Létrehozása"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Gyorsindítás Eszköztár Parancsikon"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Gyorsindítás Eszköztár Parancsikon Létrehozása"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} lényeges komponensek."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "${APPLICATION_NAME} parancsikon"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Asztali parancsikon a ${APPLICATION_NAME} alkalmazásnak."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Gyorsindítás eszköztár parancsikon a ${APPLICATION_NAME} alkalmazásnak."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Elltávolító írása"
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Program Eltávolító Írása"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Telepítési registry kulcsok írása"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Befejezve!"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Befejezve"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Nem sikerült az ${APPLICATION_NAME} alkalmazás telepítése a '$INSTDIR' könyvtárba.$\n$\nSzeretné mindenképpen folytatni (nem ajánlott)?"
|
||||
StrCpy $UNINSTALL_ABORT "Az eltávolítást a felhasználó megszakította"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Gyorsindító hivatkozás (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Asztali hivatkozás (felülírja a meglévőt)"
|
||||
StrCpy $UNINSTALL_ABORT "Az eltávolítást egy felhasználó megszakította"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Gyorsindító Hivatkozás (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Asztali Hivatkozás (felülírja a meglévőt)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Nem sikerült felemelni, hiba:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "A telepítő futtatásához adminisztrátori hozzáférés szükséges, próbálja újra."
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "A telepítő futtatásához adminisztrátori hozzáférés szükséges, próbáld újra."
|
||||
StrCpy $INIT_INSTALLER_RUNNING "A telepítő már fut."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Az eltávolító futtatásához adminisztrátori hozzáférés szükséges, próbálja újra."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Az eltávolító futtatásához adminisztrátori hozzáférés szükséges, próbáld újra."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "A bejelentkező szolgáltatás nem fut, megszakítás!"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Az eltávolító már fut."
|
||||
StrCpy $SectionGroup_Shortcuts "Parancsikonok"
|
||||
|
||||
@@ -30,7 +30,7 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Scorciatoia per ${APPLICATION_NAME}
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Creazione del programma di disinstallazione"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Scrittura delle chiavi di registro del programma di installazione"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Completato"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Non sembra che ${APPLICATION_NAME} sia installato nella cartella '$INSTDIR'.$$\nVuoi continuare comunque (non consigliato)?"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Non sembra che ${APPLICATION_NAME} sia installato nella cartella '$INSTDIR'.$\nVuoi continuare comunque (non consigliato)?"
|
||||
StrCpy $UNINSTALL_ABORT "Disinstallazione interrotta dall'utente"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Scorciatoia dell'avvio veloce (N/D)"
|
||||
StrCpy $INIT_NO_DESKTOP "Scorciatoia del desktop (sovrascrivi se esistente)"
|
||||
|
||||
@@ -3,13 +3,13 @@ StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "${APPLICATION_EXECUTABLE} のプロセスを終了する必要があります。$\nインストーラーがそのプロセスを停止してもよろしいですか?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "${APPLICATION_EXECUTABLE} プロセスを停止しています。"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "終了するプロセスがありません"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "システムに ${APPLICATION_NAME} の旧バージョンがインストールされています。$\n旧バージョンをアンインストールし、最新バージョンをインストールするのをお勧めします。$\nオペレーションを選択し、次へをクリックする。"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "システムに ${APPLICATION_NAME} の旧バージョンがインストールされています。\n旧バージョンをアンインストールし、最新バージョンをインストールするのをお勧めします。\nオペレーションを選択し、次へをクリックする。"
|
||||
StrCpy $PageReinstall_NEW_Field_2 "インストール前にアンインストールする"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "アンインストールしない"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "インストール済"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "${APPLICATION_NAME} のインストール方法を選択する"
|
||||
StrCpy $PageReinstall_OLD_Field_1 "${APPLICATION_NAME} の最新バージョンがすでにインストールされています。$\n旧バージョンのインストールはお勧めしません。旧バージョンのインストールが本当に必要な場合は、まず最新バージョンをアンインストールしてから、旧バージョンをインストールしてください。$\nオペレーションを選択し、次へをクリックする。"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} は、${VERSION} がすでにインストールされています。$\n$\n実行したい操作を選択して、次へをクリックしてください。"
|
||||
StrCpy $PageReinstall_OLD_Field_1 "${APPLICATION_NAME} の最新バージョンがすでにインストールされています。\n旧バージョンのインストールはお勧めしません。旧バージョンのインストールが本当に必要な場合は、まず最新バージョンをアンインストールしてから、旧バージョンをインストールしてください。\nオペレーションを選択し、次へをクリックする。"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} は、${VERSION} が既にインストールされています。$\n$\n実行したい操作を選択し、次へをクリックする。"
|
||||
StrCpy $PageReinstall_SAME_Field_2 "追加/再インストールコンポーネント"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} をアンインストール"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} をアンインストール"
|
||||
|
||||
@@ -9,7 +9,6 @@ StrCpy $PageReinstall_NEW_Field_3 "Nie usuwaj "
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Ju¿ zainstalowane"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Wybierz jak chcesz zainstalowaæ ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Zainstalowana jest nowsza wersja ${APPLICATION_NAME}! Niezalecane jest instalowanie starszej wersji. Jeœli naprawdê chcesz zainstalowaæ starsz¹ wersjê lepiej najpierw odinstalowaæ obecn¹ aplikacjê. Wybierz operacjê któr¹ chcesz wykonaæ i naciœnij przycisk Dalej."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} jest ju¿ zainstalowany.$\nWybierz operacjê któr¹ chcesz wykonaæ i naciœnij przycisk Dalej."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Doda/Przeinstaluj komponenty"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Odinstaluj ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Odinstaluj ${APPLICATION_NAME}"
|
||||
@@ -38,6 +37,7 @@ StrCpy $UAC_ERROR_ELEVATE "Niemo
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Ten instalator potrzebuje uprawnieñ administratora, spróbuj ponownie"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Instalator ju¿ jest uruchomiony."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Ten dezinstalator potrzebuje uprawnieñ administratora, spróbuj ponownie"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Proces logowania nie jest uruchomiony, przerywam !"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Dezinstalator ju¿ jest uruchomiony."
|
||||
StrCpy $SectionGroup_Shortcuts "Skróty"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar notas de lançamento"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Encontrados ${APPLICATION_EXECUTABLE} processo(s) em execução que precisa(m) de ser interrompido(s).$\nDeseja que o instalador o(s) termine por si?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "A terminar os processos de ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Não foi encontrado o processo para terminar!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Está instalada no sistema uma versão antiga de ${APPLICATION_NAME}. É recomendado que desinstale a versão atual antes de instalar a mais recente. Selecione a operação que deseja executar e clique em $\"Seguinte$\" para continuar."
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Processos(s) ${APPLICATION_EXECUTABLE} em execução. Estes processos precisam de ser interrompidos.$\\nDeseja que o instalador os termine automaticamente?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "A terminar os processos ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Não foi encontrado o processo a terminar!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Uma versão antiga de ${APPLICATION_NAME} está instalada no sistema. É recomendado que você desinstale a versão atual antes de instalar. Selecione a operação que deseja executar e clique em $\"Avançar$\" para continuar."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "Não desinstale"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Já instalado"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Escolha como pretende instalar ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Uma versão mais recente da aplicação ${APPLICATION_NAME} já está instalada! Não é recomendada a instalação de uma versão mais antiga. Se realmente deseja instalar esta versão, aconselha-se a desinstalação da versão atual primeiro. Selecione a operação que deseja executar e clique em Avançar para continuar."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} já está instalada.$\nSelecione a operação que deseja realizar e clique em 'Seguinte' para continuar."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Uma versão mais recente do ${APPLICATION_NAME} já está instalada! Não é recomendada a instalação de uma versão mais antiga. Se realmente deseja instalar esta versão, aconselha-se a desinstalação da versão atual primeiro. Selecione a operação que deseja executar e clique em Avançar para continuar."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} já está instalada.\nSelecione a operação que deseja realizar e clique em 'Seguinte' para continuar."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Adicionar/Reinstalar Componentes"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Desinstalar ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Desinstalar ${APPLICATION_NAME}"
|
||||
@@ -20,17 +20,17 @@ StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "A instalar integração para Wi
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Atalho do progama no Menu Inicial"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "A adicionar o atalho de ${APPLICATION_NAME} ao Menu Inicial."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Atalho da área de trabalho"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "A criar atalhos na área de trabalho"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "A criar atalhos da área de trabalho"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Atalho de início rápido"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "A criar atalho de início rápido"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "O essencial de ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "Atalho de ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Atalho do ambiente de trabalho para ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Atalho no ambiente de trabalho de ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Atalho de início rápido de ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "A escrever o Desinstalador"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "A escrever chaves de registo do instalador"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Terminado"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Não parece que a aplicação ${APPLICATION_NAME} esteja instalada no diretório '$INSTDIR'.$\n$\nContinuar na mesma (não recomendado)?"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Não parece que ${APPLICATION_NAME} esteja instalado no diretório '$INSTDIR'.$\n$\nContinuar na mesma (não recomendado)?"
|
||||
StrCpy $UNINSTALL_ABORT "Desinstalação cancelada pelo utilizador"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Atalho de Início Rápido (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Atalho do Ambiente de Trabalho (sobrepõe o existente)"
|
||||
|
||||
@@ -30,7 +30,7 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Ярлык в меню быстро
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Сохранение деинсталлятора"
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Запись ключей реестра установщика"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Завершено"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Похоже, что приложение ${APPLICATION_NAME} не установлено в каталог '$INSTDIR'.$\nВсе равно продолжить (не рекомендуется)?"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Похоже, что приложение ${APPLICATION_NAME} не установлено в каталог '$INSTDIR'.\nВсе равно продолжить (не рекомендуется)?"
|
||||
StrCpy $UNINSTALL_ABORT "Удаление отменено пользователем"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Ярлык быстрого запуска (не доступен)"
|
||||
StrCpy $INIT_NO_DESKTOP "Ярлык на рабочем столе (перезапись существующего)"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "查看版本日志"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "有 ${APPLICATION_EXECUTABLE} 项进程需要关闭。$\n您想让安装程序关闭这些进程吗?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "停止${APPLICATION_EXECUTABLE}进程。"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "未找到要停止的进程!"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "杀死${APPLICATION_EXECUTABLE}进程。"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "未找到要杀死的进程!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "您的系统已经安装${APPLICATION_NAME}较老版本。建议安装前卸载当前版本。选择将要执行的操作,点击下一步继续。"
|
||||
StrCpy $PageReinstall_NEW_Field_2 "在安装前先卸载"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "不要卸载"
|
||||
@@ -38,6 +38,6 @@ StrCpy $UAC_ERROR_ELEVATE "无法获得权限,错误:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "安装程序需要管理员权限,请重试"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "安装程序已经运行。"
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "卸载程序需要管理员权限,请重试"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "登录服务器未运行!"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "卸载程序已经运行。"
|
||||
StrCpy $SectionGroup_Shortcuts "快捷方式"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -9,7 +9,6 @@ StrCpy $PageReinstall_NEW_Field_3 "Neodin
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Už je nainštalovaný"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Vyberte si, ako chcete nainštalova� ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Novšia verzia ${APPLICATION_NAME} je už nainštalovaná! Neodporúèam vám nainštalova� staršiu verziu. Ak naozaj chcete nainštalova� túto staršiu verziu, je lepšie najprv odinštalova� aktuálnu verziu. Vyberte operáciu, ktorú chcete vykona�, a kliknite na tlaèidlo Ïalej pre pokraèovanie."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} je už nainštalovaná.$\n$\nVyberte operáciu, ktorú chcete vykona�, a kliknite na tlaèidlo Ïalej pre pokraèovanie."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Prida�/Preinštalova� komponenty"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Odinštalova� ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Odinštalova� ${APPLICATION_NAME}"
|
||||
@@ -38,6 +37,7 @@ StrCpy $UAC_ERROR_ELEVATE "Nemo
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Tento inštalátor vyžaduje admin prístup, skúste to znova"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Inštalátor je už spustený."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Tento odinštalátor vyžaduje admin prístup, skúste to znova"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Prihlasovacia služba nebeží! Prerušuje sa."
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Odinštalátor je už spustený."
|
||||
StrCpy $SectionGroup_Shortcuts "Zástupcovia"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -9,7 +9,6 @@ StrCpy $PageReinstall_NEW_Field_3 "Ne odstrani namestitve"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Program je že nameščen"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Izberite način namestitve programa ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Novejša različica programa ${APPLICATION_NAME} je že nameščena! Ni priporočljivo namestiti starejše. V kolikor želite vseeno nadaljevati z namestitvijo, prej odstranite obstoječo različico. Izberite opravilo in pritisnite gumb za nadaljevanje."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "Program ${APPLICATION_NAME} ${VERSION} je že nameščen.$\n$\nIzberite opravilo, ki ga želite izvesti in kliknite za nadaljevanje."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Dodaj/Ponovno namesti programe"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Odstrani ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Odstrani ${APPLICATION_NAME}"
|
||||
@@ -38,6 +37,7 @@ StrCpy $UAC_ERROR_ELEVATE "Ni mogo
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Namestilnik zahteva skrbniška dovoljenja."
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Namestilnik je že zagnan."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Program za odstranjevanje namestitve zahteva skrbniška dovoljenja."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Storitev za prijavo ni zagnana. Opravilo je ustavljeno!"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Program za odstranjevanje namestitve je že zagnan."
|
||||
StrCpy $SectionGroup_Shortcuts "Bližnjice"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar las notas de la versión"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "El/los proceso/s ${APPLICATION_EXECUTABLE} debe/n ser detenidos.$\n¿Quiere que el instalador lo haga por usted?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Deteniendo el/los proceso/s ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "¡Proceso a finalizar no encontrado!"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "¡Proceso para detener no encontrado!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Una versión anterior de ${APPLICATION_NAME} se encuentra instalada en el sistema. Se recomienda de instalar la versión actual antes de instalar la nueva. Seleccione la operacion deseada y haga click en Siguiente para continuar."
|
||||
StrCpy $PageReinstall_NEW_Field_2 "Desinstalar antes de instalar"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "No desinstalar"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar notas de la versión"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Se encontrarion ${APPLICATION_EXECUTABLE} proceso(s) que debe/n ser detenidos.$\"$\n$\"¿Quiere que el instalador lo haga por usted?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Parando el proceso ${APPLICATION_EXECUTABLE}."
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Proceso a detener no encontrado!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "Una versión anterior de ${APPLICATION_NAME} esta instalada en el sistema. Es recomendado que quite esta versión antes de instalar. Elija la operación a realizar y seleccione Siguiente para continuar."
|
||||
@@ -9,35 +8,36 @@ StrCpy $PageReinstall_NEW_Field_3 "No des-instalar."
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Actualmente Instalado."
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Elija como desea instalar ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Una versión mas reciente de ${APPLICATION_NAME} esta actualmente instalada! No es recomendado que instale una versión antigua. Si realmente desea instalar esta versión obsoleta, es mejor que des-instale la versión actual primero. Seleccione la operación que desea realizar y presione en Siguiente para continuar. "
|
||||
StrCpy $PageReinstall_SAME_Field_1 "La ${APPLICATION_NAME} ${VERSION} ya está instalado.$\n$\nSeleccione la operación que desea realizar y haga click en Siguiente para continuar."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Agregar/Re-Instalar componentes"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Des-instalar ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Des-instalar ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Elija la opción de mantenimiento a realizar."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Instalar esenciales ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integración para Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Instalando la integración para Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Acceso Directo en Menú de Programas"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Agregando el Acceso Directo al Menú de Inicio para ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Acceso directo en Escritorio"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Creando Accesos Directos en Escritorio"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Atajo de Acceso Rápido"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Creando Atajo de Acceso Rápido"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} esencial."
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "Acceso directo de ${APPLICATION_NAME}"
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Acceso Directo al Escritorio para ${APPLICATION_NAME}."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Atajo de Acceso Rápido para ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALLER_FILE_Detail "Escribiendo Des-Instalador."
|
||||
StrCpy $UNINSTALLER_REGISTRY_Detail "Escribiendo claves de Registro del Instalador"
|
||||
StrCpy $UNINSTALLER_FINISHED_Detail "Terminado"
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "Parece que ${APPLICATION_NAME} no esta instalado en el directorio '$INSTDIR'.$\n$\n¿Continuar de todos modos? (No recomendado)"
|
||||
StrCpy $UNINSTALL_ABORT "Des-instalación abortada por el usuario"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Atajo de Acceso Rápido (N/A)"
|
||||
StrCpy $INIT_NO_DESKTOP "Acceso Directo en Escritorio (Sobrescribe existentes)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "No se ha podido elevar, error:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Este instalador requiere acceso Administrador, intente de nuevo. "
|
||||
StrCpy $INIT_INSTALLER_RUNNING "El instalador ya esta corriendo."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Este des-instalador requiere acceso administrador, intente de nuevo"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Servicio Inicio de sesión no se está ejecutando, abortando!"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "El des-instalador ya esta corriendo"
|
||||
StrCpy $SectionGroup_Shortcuts "Accesos Directos"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installing Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Quick Launch Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Creating Quick Launch Shortcut"
|
||||
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} essentials."
|
||||
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Quick Launch shortcut for ${APPLICATION_NAME}."
|
||||
StrCpy $UNINSTALL_MESSAGEBOX "It does not appear that ${APPLICATION_NAME} is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?"
|
||||
StrCpy $INIT_NO_QUICK_LAUNCH "Quick Launch Shortcut (N/A)"
|
||||
StrCpy $UAC_ERROR_ELEVATE "Unable to elevate, error:"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -9,14 +9,11 @@ StrCpy $PageReinstall_NEW_Field_3 "Avinstallera inte"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Redan installerad"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Välj hur du vill installera ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "En nyare version av ${APPLICATION_NAME} är redan installerad! Det rekommenderas inte att du installerar en äldre version. Om du verkligen vill installera denna äldre versionen, är det bättre att du avinstallerar den nuvarande versionen först. Välj den åtgärd du vill utföra och klicka Nästa för att fortsätta."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} är redan installerad.$\n$\nVälj den åtgärd du vill utföra och klicka på Nästa för att fortsätta."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Lägg till/Ominstallera komponenter"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Avinstallera ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Avinstallera ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Välj underhålls alternativ att utföra."
|
||||
StrCpy $SEC_APPLICATION_DETAILS "Installerar ${APPLICATION_NAME} väsentligheter."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integration för Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installerar integration för Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Start-meny program genväg"
|
||||
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Lägger till genväg för ${APPLICATION_NAME} till Start-menyn."
|
||||
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Skrivbordsgenväg"
|
||||
@@ -38,6 +35,9 @@ StrCpy $UAC_ERROR_ELEVATE "Kunde inte få förhöjda rättigheter, fel:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Detta installationsprogram kräver adminstratörs rättigheter, försök igen"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Installationsprogrammet körs redan."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Detta avinstallationsprogram kräver administratörsrättigheter, försök igen"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Login-service körs inte, avbryter!"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Avinstallationsprogrammet körs redan."
|
||||
StrCpy $SectionGroup_Shortcuts "Genvägar"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integration for Windows Explorer"
|
||||
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installing Integration for Windows Explorer"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# Auto-generated - do not modify
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "แสดงบันทึกที่มี"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "พบว่ากระบวนการ ${APPLICATION_EXECUTABLE} จะต้องหยุดทำงาน$\nคุณต้องการติดตั้งเพื่อหยุดการทำงานเหล่านี้ของคุณ?"
|
||||
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "แสดงบันทึกประจำรุ่น"
|
||||
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "พบว่ากระบวนการ ${APPLICATION_EXECUTABLE} จะต้องหยุดทำงาน\nคุณต้องการติดตั้งเพื่อหยุดการทำงานเหล่านี้ของคุณ?"
|
||||
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "ฆ่ากระบวนการทำงาน ${APPLICATION_EXECUTABLE}"
|
||||
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "ไม่พบการฆ่ากระบวนการ!"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "รุ่นเก่าของ ${APPLICATION_NAME} ได้ถูกติดตั้งในระบบของคุณ ขอแนะนำให้คุณถอนการติดตั้งรุ่นปัจจุบันออกก่อน แล้วเลือกการดำเนินการที่คุณต้องการหลังจากนั้นคลิกถัดไปเพื่อดำเนินการต่อ"
|
||||
StrCpy $PageReinstall_NEW_Field_1 "รุ่นเก่าของ ${APPLICATION_NAME} มีการติดตั้งในระบบของคุณ ขอแนะนำให้คุณถอนการติดตั้งรุ่นปัจจุบันออกก่อน เลือกการดำเนินการที่คุณต้องการที่จะดำเนินการและคลิกถัดไปเพื่อดำเนินการต่อ"
|
||||
StrCpy $PageReinstall_NEW_Field_2 "ถอนการติดตั้งก่อนการติดตั้ง"
|
||||
StrCpy $PageReinstall_NEW_Field_3 "อย่าถอนการติดตั้ง"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "ติดตั้งแล้ว"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "เลือกวิธีที่คุณต้องการติดตั้ง ${APPLICATION_NAME}"
|
||||
StrCpy $PageReinstall_OLD_Field_1 "รุ่นใหม่ของ ${APPLICATION_NAME} ถูกติดตั้งแล้ว! เราไม่แนะนำให้คุณติดตั้งรุ่นที่เก่ากว่า ถ้าคุณอยากจะติดตั้งรุ่นเก่าก็สามารถถอนการติดตั้งได้"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} รุ่น ${VERSION} ถูกติดตั้งไปแล้ว$ $\nเลือกดำเนินงานที่คุณต้องการและคลิกถัดไปเพื่อดำเนินการต่อ"
|
||||
StrCpy $PageReinstall_OLD_Field_1 "รุ่นใหม่ของ ${APPLICATION_NAME} ถูกติดตั้งแล้ว! เราไม่แนะนำให้คุณติดตั้งรุ่นเก่า ถ้าคุณอยากจะติดตั้งรุ่นเก่าก็สามารถสอนการติดตั้งได้"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} ถูกติดตั้งไปแล้ว$ $\nเลือกดำเนินงานที่คุณต้องการและคลิกถัดไปเพื่อดำเนินการต่อ"
|
||||
StrCpy $PageReinstall_SAME_Field_2 "ส่วนประกอบ เพิ่ม/ติดตั้งใหม่ "
|
||||
StrCpy $PageReinstall_SAME_Field_3 "ถอนการติดตั้ง ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "ถอนการติดตั้ง ${APPLICATION_NAME}"
|
||||
|
||||
@@ -9,7 +9,6 @@ StrCpy $PageReinstall_NEW_Field_3 "Не видаляти"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Установлено"
|
||||
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Оберіть, як ви хочете установити ${APPLICATION_NAME}."
|
||||
StrCpy $PageReinstall_OLD_Field_1 "Знайдено новішу версію ${APPLICATION_NAME}! Ми не рекомендуємо встановлювати стару версію. Якщо ви все ж бажаєте встановити цю версію, спочатку видаліть поточну версію. Оберіть подальшу дію та натисніть $\"Далі$\"."
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} вже встановлено.$\n$\nОберіть подальшу дію та натисніть $\"Далі$\" для продовження."
|
||||
StrCpy $PageReinstall_SAME_Field_2 "Додати/Перевстановити компоненти"
|
||||
StrCpy $PageReinstall_SAME_Field_3 "Видалити ${APPLICATION_NAME}"
|
||||
StrCpy $UNINSTALLER_APPDATA_TITLE "Видалити ${APPLICATION_NAME}"
|
||||
@@ -38,6 +37,7 @@ StrCpy $UAC_ERROR_ELEVATE "Неможливо підняти, помилка:"
|
||||
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Для установки потрібні права адміністратора, спробуйте ще раз"
|
||||
StrCpy $INIT_INSTALLER_RUNNING "Установка вже запущена."
|
||||
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Для видалення потрібні права адміністратора, спробуйте ще раз"
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Сервіс авторизації не запущений, припиняю!"
|
||||
StrCpy $INIT_UNINSTALLER_RUNNING "Програма видалення вже запущено."
|
||||
StrCpy $SectionGroup_Shortcuts "Ярлики"
|
||||
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.$\r$\nSelect the operation you want to perform and click Next to continue."
|
||||
StrCpy $UAC_ERROR_LOGON_SERVICE "Logon service is not running, aborting!"
|
||||
|
||||
@@ -104,13 +104,10 @@ localeToName = {
|
||||
def escapeNSIS(st):
|
||||
return st.replace('\\', r'$\\')\
|
||||
.replace('\t', r'$\t')\
|
||||
.replace('\r', r'$\r')\
|
||||
.replace('\n', r'$\n')\
|
||||
.replace('\r', r'\r')\
|
||||
.replace('\n', r'\n')\
|
||||
.replace('\"', r'$\"')\
|
||||
.replace('$$\\', '$\\')\
|
||||
.replace('$\\n', r'$\n')\
|
||||
.replace('$\\\\n', r'$\n')
|
||||
|
||||
.replace('$$\\', '$\\')
|
||||
|
||||
translationCache = {}
|
||||
|
||||
|
||||
@@ -2,27 +2,27 @@
|
||||
!insertmacro MUI_LANGUAGE "Swedish"
|
||||
!insertmacro MUI_LANGUAGE "Estonian"
|
||||
!insertmacro MUI_LANGUAGE "Turkish"
|
||||
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
||||
!insertmacro MUI_LANGUAGE "Slovenian"
|
||||
!insertmacro MUI_LANGUAGE "SpanishInternational"
|
||||
!insertmacro MUI_LANGUAGE "Dutch"
|
||||
!insertmacro MUI_LANGUAGE "Norwegian"
|
||||
!insertmacro MUI_LANGUAGE "Hungarian"
|
||||
!insertmacro MUI_LANGUAGE "Ukrainian"
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
!insertmacro MUI_LANGUAGE "Catalan"
|
||||
!insertmacro MUI_LANGUAGE "Norwegian"
|
||||
!insertmacro MUI_LANGUAGE "Russian"
|
||||
!insertmacro MUI_LANGUAGE "Thai"
|
||||
!insertmacro MUI_LANGUAGE "Finnish"
|
||||
!insertmacro MUI_LANGUAGE "Basque"
|
||||
!insertmacro MUI_LANGUAGE "Greek"
|
||||
!insertmacro MUI_LANGUAGE "SimpChinese"
|
||||
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
||||
!insertmacro MUI_LANGUAGE "Catalan"
|
||||
!insertmacro MUI_LANGUAGE "Italian"
|
||||
!insertmacro MUI_LANGUAGE "Portuguese"
|
||||
!insertmacro MUI_LANGUAGE "Czech"
|
||||
!insertmacro MUI_LANGUAGE "German"
|
||||
!insertmacro MUI_LANGUAGE "Japanese"
|
||||
!insertmacro MUI_LANGUAGE "Galician"
|
||||
!insertmacro MUI_LANGUAGE "German"
|
||||
!insertmacro MUI_LANGUAGE "Czech"
|
||||
!insertmacro MUI_LANGUAGE "Slovak"
|
||||
!insertmacro MUI_LANGUAGE "Spanish"
|
||||
!insertmacro MUI_LANGUAGE "Polish"
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
[Paths]
|
||||
Prefix = .
|
||||
Plugins = .
|
||||
Binaries = .
|
||||
Imports = .
|
||||
Qml2Imports = .
|
||||
LibraryExecutables = .
|
||||
+1
-1
Submodule binary updated: 0d89ac7766...8b72648a93
@@ -0,0 +1,5 @@
|
||||
--- binary
|
||||
+++ binary
|
||||
@@ -1 +1 @@
|
||||
-Subproject commit 1fb9ddfa9a9a1b4dbc447eee10dbed89172d968a
|
||||
+Subproject commit 01d73965dc8b862d1b2310d3ef801c297b697ec7
|
||||
@@ -22,6 +22,5 @@
|
||||
<file>resources/account.png</file>
|
||||
<file>resources/more.png</file>
|
||||
<file>resources/delete.png</file>
|
||||
<file>resources/bell.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -20,4 +20,15 @@ function (ADD_CMOCKA_TEST _testName _testSource)
|
||||
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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
@@ -41,6 +41,10 @@ if (UNIX)
|
||||
"${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)"
|
||||
@@ -102,6 +106,7 @@ if (WIN32)
|
||||
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 "-")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ find_library(CMOCKA_LIBRARY
|
||||
NAMES
|
||||
cmocka
|
||||
PATHS
|
||||
${CMOCKA_ROOT_DIR}/lib
|
||||
${CMOCKA_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
if (CMOCKA_LIBRARY)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>@APPLICATION_NAME_XML_ESCAPED@ @MIRALL_VERSION_STRING@</string>
|
||||
<string>@APPLICATION_NAME@ @MIRALL_VERSION_STRING@</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
@@ -27,7 +27,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>@MIRALL_VERSION_STRING@</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>(C) 2014-2016 @APPLICATION_VENDOR@</string>
|
||||
<string>(C) 2014-2015 @APPLICATION_VENDOR@</string>
|
||||
<key>SUShowReleaseNotes</key>
|
||||
<false/>
|
||||
<key>LSMinimumBundleVersion</key>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
!define QT_DLL_PATH "${MING_BIN}"
|
||||
!define ACCESSIBLE_DLL_PATH "${MING_LIB}/qt5/plugins/accessible"
|
||||
!define SQLITE_DLL_PATH "${MING_LIB}/qt5/plugins/sqldrivers"
|
||||
!define BEARER_DLL_PATH "${MING_LIB}/qt5/plugins/bearer"
|
||||
!define IMAGEFORMATS_DLL_PATH "${MING_LIB}/qt5/plugins/imageformats"
|
||||
!define PLATFORMS_DLL_PATH "${MING_LIB}/qt5/plugins/platforms"
|
||||
|
||||
@@ -406,14 +407,15 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
|
||||
SetOutPath "$INSTDIR\sqldrivers"
|
||||
File "${SQLITE_DLL_PATH}\qsqlite.dll"
|
||||
|
||||
SetOutPath "$INSTDIR\bearer"
|
||||
File "${BEARER_DLL_PATH}\qgenericbearer.dll"
|
||||
File "${BEARER_DLL_PATH}\qnativewifibearer.dll"
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
;License & release notes.
|
||||
File "@CPACK_RESOURCE_FILE_LICENSE@"
|
||||
;File /oname=NOTES.txt ${NSI_PATH}\RELEASE_NOTES.txt
|
||||
|
||||
;Qt config:
|
||||
File "${NSI_PATH}\qt.conf"
|
||||
|
||||
;Qt stuff:
|
||||
File "${QT_DLL_PATH}\Qt5Core.dll"
|
||||
File "${QT_DLL_PATH}\Qt5Gui.dll"
|
||||
@@ -623,6 +625,7 @@ Section Uninstall
|
||||
!insertmacro UnInstallLib REGDLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCOverlays_x64.dll"
|
||||
!insertmacro UnInstallLib DLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCUtil_x64.dll"
|
||||
!undef LIBRARY_X64
|
||||
${Else}
|
||||
DetailPrint "Uninstalling x86 overlay DLLs"
|
||||
!insertmacro UnInstallLib REGDLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCContextMenu_x86.dll"
|
||||
!insertmacro UnInstallLib REGDLL NOTSHARED REBOOT_PROTECTED "$INSTDIR\shellext\OCOverlays_x86.dll"
|
||||
@@ -759,12 +762,6 @@ Function .onInit
|
||||
|
||||
;Shutdown ${APPLICATION_NAME} in case Add/Remove re-installer option used.
|
||||
Call EnsureOwncloudShutdown
|
||||
|
||||
ReadRegStr $R0 ${MEMENTO_REGISTRY_ROOT} "${MEMENTO_REGISTRY_KEY}" "InstallLocation"
|
||||
${If} ${Silent}
|
||||
${AndIf} $R0 != ""
|
||||
ExecWait '"$R0\Uninstall.exe" /S _?=$R0'
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
Function .onInstSuccess
|
||||
@@ -774,11 +771,6 @@ Function .onInstSuccess
|
||||
WriteRegDWORD HKLM "Software\${APPLICATION_VENDOR}\${APPLICATION_NAME}" "skipUpdateCheck" "1"
|
||||
${EndIf}
|
||||
|
||||
; TODO: Only needed to when updating from 2.1.{0,1}. Remove in due time.
|
||||
Delete /REBOOTOK $INSTDIR\bearer\qgenericbearer.dll
|
||||
Delete /REBOOTOK $INSTDIR\bearer\qnativewifibearer.dll
|
||||
RMDir /REBOOTOK $INSTDIR\bearer
|
||||
|
||||
${If} ${Silent}
|
||||
${AndIf} $InstallRunIfSilent == "yes"
|
||||
Call LaunchApplication
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
@@ -18,22 +18,17 @@ if( Qt5Core_FOUND )
|
||||
find_package(Qt5Network REQUIRED)
|
||||
find_package(Qt5Xml REQUIRED)
|
||||
find_package(Qt5Concurrent REQUIRED)
|
||||
if(UNIT_TESTING)
|
||||
find_package(Qt5Test REQUIRED)
|
||||
endif()
|
||||
if(NOT TOKEN_AUTH_ONLY)
|
||||
find_package(Qt5WebKitWidgets REQUIRED)
|
||||
find_package(Qt5WebKit REQUIRED)
|
||||
find_package(Qt5PrintSupport REQUIRED)
|
||||
if(NOT APPLE)
|
||||
find_package(Qt5Quick REQUIRED) # only needed on Windows because of OBS dependencies(?)
|
||||
endif()
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
if(APPLE)
|
||||
find_package(Qt5MacExtras REQUIRED)
|
||||
endif(APPLE)
|
||||
|
||||
if(NOT NO_SHIBBOLETH)
|
||||
find_package(Qt5WebKitWidgets)
|
||||
find_package(Qt5WebKit)
|
||||
if(NOT Qt5WebKitWidgets_FOUND)
|
||||
message(FATAL_ERROR "Qt5WebKit required for Shibboleth. Use -DNO_SHIBBOLETH=1 to disable it.")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
else( Qt5Core_FOUND )
|
||||
@@ -81,16 +76,11 @@ endif()
|
||||
endmacro()
|
||||
|
||||
if(NOT TOKEN_AUTH_ONLY)
|
||||
find_package(Qt5LinguistTools)
|
||||
if(Qt5LinguistTools_FOUND)
|
||||
macro(qt_add_translation)
|
||||
qt5_add_translation(${ARGN})
|
||||
endmacro()
|
||||
else()
|
||||
macro(qt_add_translation)
|
||||
endmacro()
|
||||
endif()
|
||||
else()
|
||||
find_package(Qt5LinguistTools REQUIRED)
|
||||
macro(qt_add_translation)
|
||||
qt5_add_translation(${ARGN})
|
||||
endmacro()
|
||||
else()
|
||||
macro(qt_add_translation)
|
||||
endmacro()
|
||||
endif()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
if(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
|
||||
else(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||
endif(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
else()
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
if(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
|
||||
else(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||
endif()
|
||||
endif(GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
if(DEFINED MIRALL_FATAL_WARNINGS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||
endif(DEFINED MIRALL_FATAL_WARNINGS)
|
||||
endif()
|
||||
if(DEFINED MIRALL_FATAL_WARNINGS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||
endif(DEFINED MIRALL_FATAL_WARNINGS)
|
||||
|
||||
@@ -23,6 +23,4 @@
|
||||
#cmakedefine SYSCONFDIR "@SYSCONFDIR@"
|
||||
#cmakedefine SHAREDIR "@SHAREDIR@"
|
||||
|
||||
#cmakedefine WITH_UNIT_TESTING 1
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,8 +41,6 @@ endif (MEM_NULL_TESTS)
|
||||
add_subdirectory(src)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
set(WITH_UNIT_TESTING ON)
|
||||
|
||||
find_package(CMocka)
|
||||
if (CMOCKA_FOUND)
|
||||
include(AddCMockaTest)
|
||||
|
||||
@@ -9,6 +9,7 @@ set(PACKAGE ${APPLICATION_NAME})
|
||||
set(VERSION ${APPLICATION_VERSION})
|
||||
set(DATADIR ${DATA_INSTALL_DIR})
|
||||
set(LIBDIR ${LIB_INSTALL_DIR})
|
||||
set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
|
||||
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
|
||||
|
||||
set(BINARYDIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
@@ -62,4 +63,8 @@ if (WIN32)
|
||||
check_function_exists(__mingw_asprintf HAVE___MINGW_ASPRINTF)
|
||||
endif(WIN32)
|
||||
|
||||
if (UNIT_TESTING)
|
||||
set(WITH_UNIT_TESTING ON)
|
||||
endif (UNIT_TESTING)
|
||||
|
||||
set(CSYNC_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "csync required system libraries")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#cmakedefine VERSION "${APPLICATION_VERSION}"
|
||||
#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
|
||||
#cmakedefine LIBDIR "${LIBDIR}"
|
||||
#cmakedefine PLUGINDIR "${PLUGINDIR}"
|
||||
#cmakedefine SYSCONFDIR "${SYSCONFDIR}"
|
||||
#cmakedefine BINARYDIR "${BINARYDIR}"
|
||||
#cmakedefine SOURCEDIR "${SOURCEDIR}"
|
||||
|
||||
@@ -81,13 +81,6 @@ set(csync_HDRS
|
||||
# Statically include sqlite
|
||||
if (USE_OUR_OWN_SQLITE3)
|
||||
list(APPEND csync_SRCS ${SQLITE3_SOURCE})
|
||||
if (WIN32)
|
||||
# We want to export sqlite symbols from the ocsync DLL without
|
||||
# having to patch both sqlite3.h and the amalgation sqlite3.c,
|
||||
# so do the import/export magic manually through the build system.
|
||||
remove_definitions(-DSQLITE_API=__declspec\(dllimport\))
|
||||
add_definitions(-DSQLITE_API=__declspec\(dllexport\))
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
@@ -98,12 +91,6 @@ include_directories(
|
||||
add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS})
|
||||
#add_library(${CSYNC_LIBRARY}_static STATIC ${csync_SRCS})
|
||||
|
||||
generate_export_header( ${CSYNC_LIBRARY}
|
||||
BASE_NAME ${CSYNC_LIBRARY}
|
||||
EXPORT_MACRO_NAME OCSYNC_EXPORT
|
||||
EXPORT_FILE_NAME ocsynclib.h
|
||||
)
|
||||
|
||||
target_link_libraries(${CSYNC_LIBRARY} ${CSYNC_LINK_LIBRARIES})
|
||||
#target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES})
|
||||
|
||||
@@ -141,4 +128,10 @@ else()
|
||||
)
|
||||
endif()
|
||||
|
||||
# INSTALL(
|
||||
# FILES
|
||||
# ${csync_HDRS}
|
||||
# DESTINATION
|
||||
# ${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}
|
||||
# )
|
||||
|
||||
|
||||
+91
-20
@@ -25,11 +25,11 @@
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -89,11 +89,14 @@ static int _data_cmp(const void *key, const void *data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void csync_create(CSYNC **csync, const char *local) {
|
||||
int csync_create(CSYNC **csync, const char *local, const char *remote) {
|
||||
CSYNC *ctx;
|
||||
size_t len = 0;
|
||||
|
||||
ctx = c_malloc(sizeof(CSYNC));
|
||||
if (ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
|
||||
@@ -103,6 +106,12 @@ void csync_create(CSYNC **csync, const char *local) {
|
||||
|
||||
ctx->local.uri = c_strndup(local, len);
|
||||
|
||||
/* remove trailing slashes */
|
||||
len = strlen(remote);
|
||||
while(len > 0 && remote[len - 1] == '/') --len;
|
||||
|
||||
ctx->remote.uri = c_strndup(remote, len);
|
||||
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
|
||||
ctx->current_fs = NULL;
|
||||
@@ -112,24 +121,46 @@ void csync_create(CSYNC **csync, const char *local) {
|
||||
ctx->ignore_hidden_files = true;
|
||||
|
||||
*csync = ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void csync_init(CSYNC *ctx, const char *db_file) {
|
||||
assert(ctx);
|
||||
/* Do not initialize twice */
|
||||
int csync_init(CSYNC *ctx) {
|
||||
int rc;
|
||||
|
||||
if (ctx == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(!(ctx->status & CSYNC_STATUS_INIT));
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
|
||||
/* Do not initialize twice */
|
||||
if (ctx->status & CSYNC_STATUS_INIT) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check for uri */
|
||||
if (csync_fnmatch("owncloud://*", ctx->remote.uri, 0) == 0 && csync_fnmatch("ownclouds://*", ctx->remote.uri, 0) == 0) {
|
||||
ctx->status_code = CSYNC_STATUS_NO_MODULE;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx->local.type = LOCAL_REPLICA;
|
||||
|
||||
ctx->remote.type = REMOTE_REPLICA;
|
||||
|
||||
SAFE_FREE(ctx->statedb.file);
|
||||
ctx->statedb.file = c_strdup(db_file);
|
||||
if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
|
||||
c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);
|
||||
if (c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp) < 0) {
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx->remote.root_perms = 0;
|
||||
|
||||
@@ -137,6 +168,11 @@ void csync_init(CSYNC *ctx, const char *db_file) {
|
||||
|
||||
/* initialize random generator */
|
||||
srand(time(NULL));
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_update(CSYNC *ctx) {
|
||||
@@ -149,11 +185,19 @@ int csync_update(CSYNC *ctx) {
|
||||
}
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
|
||||
/* Path of database file is set in csync_init */
|
||||
if (csync_statedb_load(ctx, ctx->statedb.file, &ctx->statedb.db) < 0) {
|
||||
/* create/load statedb */
|
||||
rc = asprintf(&ctx->statedb.file, "%s/.csync_journal.db",
|
||||
ctx->local.uri);
|
||||
if (rc < 0) {
|
||||
ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
|
||||
return rc;
|
||||
}
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Journal: %s", ctx->statedb.file);
|
||||
|
||||
if (csync_statedb_load(ctx, ctx->statedb.file, &ctx->statedb.db) < 0) {
|
||||
rc = -1;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
|
||||
@@ -188,7 +232,7 @@ int csync_update(CSYNC *ctx) {
|
||||
ctx->current = REMOTE_REPLICA;
|
||||
ctx->replica = ctx->remote.type;
|
||||
|
||||
rc = csync_ftw(ctx, "", csync_walker, MAX_DEPTH);
|
||||
rc = csync_ftw(ctx, ctx->remote.uri, csync_walker, MAX_DEPTH);
|
||||
if (rc < 0) {
|
||||
if(ctx->status_code == CSYNC_STATUS_OK) {
|
||||
ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_UPDATE_ERROR);
|
||||
@@ -375,9 +419,8 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
|
||||
trav.inode = cur->inode;
|
||||
|
||||
trav.error_status = cur->error_status;
|
||||
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;
|
||||
@@ -510,6 +553,7 @@ static void _csync_clean_ctx(CSYNC *ctx)
|
||||
c_rbtree_free(ctx->local.tree);
|
||||
c_rbtree_free(ctx->remote.tree);
|
||||
|
||||
SAFE_FREE(ctx->statedb.file);
|
||||
SAFE_FREE(ctx->remote.root_perms);
|
||||
}
|
||||
|
||||
@@ -534,17 +578,29 @@ int csync_commit(CSYNC *ctx) {
|
||||
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 */
|
||||
c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
|
||||
c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);
|
||||
rc = c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
|
||||
if (rc < 0) {
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp);
|
||||
if (rc < 0) {
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
ctx->status = CSYNC_STATUS_INIT;
|
||||
SAFE_FREE(ctx->error_string);
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -564,10 +620,13 @@ int csync_destroy(CSYNC *ctx) {
|
||||
}
|
||||
ctx->statedb.db = NULL;
|
||||
|
||||
/* destroy exclude list */
|
||||
csync_exclude_destroy(ctx);
|
||||
|
||||
_csync_clean_ctx(ctx);
|
||||
|
||||
SAFE_FREE(ctx->statedb.file);
|
||||
SAFE_FREE(ctx->local.uri);
|
||||
SAFE_FREE(ctx->remote.uri);
|
||||
SAFE_FREE(ctx->error_string);
|
||||
|
||||
#ifdef WITH_ICONV
|
||||
@@ -579,6 +638,19 @@ int csync_destroy(CSYNC *ctx) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
int csync_add_exclude_list(CSYNC *ctx, const char *path) {
|
||||
if (ctx == NULL || path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return csync_exclude_load(path, &ctx->excludes);
|
||||
}
|
||||
|
||||
void csync_clear_exclude_list(CSYNC *ctx)
|
||||
{
|
||||
csync_exclude_clear(ctx);
|
||||
}
|
||||
|
||||
void *csync_get_userdata(CSYNC *ctx) {
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
@@ -670,7 +742,6 @@ void csync_file_stat_free(csync_file_stat_t *st)
|
||||
SAFE_FREE(st->directDownloadCookies);
|
||||
SAFE_FREE(st->etag);
|
||||
SAFE_FREE(st->destpath);
|
||||
SAFE_FREE(st->checksum);
|
||||
SAFE_FREE(st);
|
||||
}
|
||||
}
|
||||
|
||||
+88
-73
@@ -33,10 +33,10 @@
|
||||
#define _CSYNC_H
|
||||
|
||||
#include "std/c_private.h"
|
||||
#include "ocsynclib.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <config_csync.h>
|
||||
|
||||
@@ -44,6 +44,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct csync_client_certs_s {
|
||||
char *certificatePath;
|
||||
char *certificatePasswd;
|
||||
};
|
||||
|
||||
enum csync_status_codes_e {
|
||||
CSYNC_STATUS_OK = 0,
|
||||
|
||||
@@ -93,13 +98,11 @@ enum csync_status_codes_e {
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK,
|
||||
CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST,
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS,
|
||||
CSYNC_STATUS_INDIVIDUAL_TRAILING_SPACE,
|
||||
CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME,
|
||||
CYSNC_STATUS_FILE_LOCKED_OR_OPEN,
|
||||
CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN,
|
||||
CSYNC_STATUS_INVALID_CHARACTERS,
|
||||
CSYNC_STATUS_INDIVIDUAL_STAT_FAILED,
|
||||
CSYNC_STATUS_FORBIDDEN
|
||||
CSYNC_STATUS_INDIVIDUAL_STAT_FAILED
|
||||
};
|
||||
|
||||
typedef enum csync_status_codes_e CSYNC_STATUS;
|
||||
@@ -120,22 +123,17 @@ typedef enum csync_status_codes_e CSYNC_STATUS;
|
||||
* the csync state of a file.
|
||||
*/
|
||||
enum csync_instructions_e {
|
||||
CSYNC_INSTRUCTION_NONE = 0x00000000, /* Nothing to do (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_EVAL = 0x00000001, /* There was changed compared to the DB (UPDATE) */
|
||||
CSYNC_INSTRUCTION_REMOVE = 0x00000002, /* The file need to be removed (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_RENAME = 0x00000004, /* The file need to be renamed (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_EVAL_RENAME = 0x00000800, /* The file is new, it is the destination of a rename (UPDATE) */
|
||||
CSYNC_INSTRUCTION_NEW = 0x00000008, /* The file is new compared to the db (UPDATE) */
|
||||
CSYNC_INSTRUCTION_CONFLICT = 0x00000010, /* The file need to be downloaded because it is a conflict (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080,
|
||||
CSYNC_INSTRUCTION_ERROR = 0x00000100,
|
||||
CSYNC_INSTRUCTION_TYPE_CHANGE = 0x00000200, /* Like NEW, but deletes the old entity first (RECONCILE)
|
||||
Used when the type of something changes from directory to file
|
||||
or back. */
|
||||
CSYNC_INSTRUCTION_UPDATE_METADATA = 0x00000400, /* If the etag has been updated and need to be writen to the db,
|
||||
but without any propagation (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_NONE = 0x00000000, /* Nothing to do (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_EVAL = 0x00000001, /* There was changed compared to the DB (UPDATE) */
|
||||
CSYNC_INSTRUCTION_REMOVE = 0x00000002, /* The file need to be removed (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_RENAME = 0x00000004, /* The file need to be renamed (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_EVAL_RENAME= 0x00000800, /* The file is new, it is the destination of a rename (UPDATE) */
|
||||
CSYNC_INSTRUCTION_NEW = 0x00000008, /* The file is new compared to the db (UPDATE) */
|
||||
CSYNC_INSTRUCTION_CONFLICT = 0x00000010, /* The file need to be downloaded because it is a conflict (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */
|
||||
CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */
|
||||
CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080,
|
||||
CSYNC_INSTRUCTION_ERROR = 0x00000100
|
||||
};
|
||||
|
||||
enum csync_ftw_type_e {
|
||||
@@ -224,14 +222,14 @@ struct csync_vio_file_stat_s {
|
||||
char *original_name; // only set if locale conversion fails
|
||||
};
|
||||
|
||||
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_new(void);
|
||||
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
|
||||
csync_vio_file_stat_t *csync_vio_file_stat_new(void);
|
||||
csync_vio_file_stat_t *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
|
||||
|
||||
void OCSYNC_EXPORT csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat);
|
||||
void csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat);
|
||||
|
||||
void OCSYNC_EXPORT csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src );
|
||||
void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src );
|
||||
|
||||
void OCSYNC_EXPORT csync_vio_set_file_id(char* dst, const char *src );
|
||||
void csync_vio_set_file_id(char* dst, const char *src );
|
||||
|
||||
|
||||
/**
|
||||
@@ -251,6 +249,9 @@ struct csync_tree_walk_file_s {
|
||||
enum csync_ftw_type_e type;
|
||||
enum csync_instructions_e instruction;
|
||||
|
||||
/* For directories: If the etag has been updated and need to be writen on the db */
|
||||
int should_update_metadata;
|
||||
|
||||
/* For directories: Does it have children that were ignored (hidden or ignore pattern) */
|
||||
int has_ignored_files;
|
||||
|
||||
@@ -260,10 +261,6 @@ struct csync_tree_walk_file_s {
|
||||
const char *remotePerm;
|
||||
char *directDownloadUrl;
|
||||
char *directDownloadCookies;
|
||||
|
||||
const char *checksum;
|
||||
uint32_t checksumTypeId;
|
||||
|
||||
struct {
|
||||
int64_t size;
|
||||
time_t modtime;
|
||||
@@ -303,16 +300,14 @@ typedef void (*csync_vio_closedir_hook) (csync_vio_handle_t *dhhandle,
|
||||
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.
|
||||
*
|
||||
* @param csync The context variable to allocate.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
void OCSYNC_EXPORT csync_create(CSYNC **csync, const char *local);
|
||||
int csync_create(CSYNC **csync, const char *local, const char *remote);
|
||||
|
||||
/**
|
||||
* @brief Initialize the file synchronizer.
|
||||
@@ -320,35 +315,37 @@ void OCSYNC_EXPORT csync_create(CSYNC **csync, const char *local);
|
||||
* This function loads the configuration
|
||||
*
|
||||
* @param ctx The context to initialize.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
void OCSYNC_EXPORT csync_init(CSYNC *ctx, const char *db_file);
|
||||
int csync_init(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Update detection
|
||||
*
|
||||
* @param ctx The context to run the update detection on.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_update(CSYNC *ctx);
|
||||
int csync_update(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Reconciliation
|
||||
*
|
||||
* @param ctx The context to run the reconciliation on.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_reconcile(CSYNC *ctx);
|
||||
int csync_reconcile(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Re-initializes the csync context
|
||||
*
|
||||
* @param ctx The context to commit.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_commit(CSYNC *ctx);
|
||||
int csync_commit(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Destroy the csync context
|
||||
@@ -357,9 +354,27 @@ int OCSYNC_EXPORT csync_commit(CSYNC *ctx);
|
||||
*
|
||||
* @param ctx The context to destroy.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_destroy(CSYNC *ctx);
|
||||
int csync_destroy(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Add an additional exclude list.
|
||||
*
|
||||
* @param ctx The context to add the exclude list.
|
||||
*
|
||||
* @param path The path pointing to the file.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int csync_add_exclude_list(CSYNC *ctx, const char *path);
|
||||
|
||||
/**
|
||||
* @brief Removes all items imported from exclude lists.
|
||||
*
|
||||
* @param ctx The context to add the exclude list.
|
||||
*/
|
||||
void csync_clear_exclude_list(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Get the userdata saved in the context.
|
||||
@@ -367,7 +382,7 @@ int OCSYNC_EXPORT csync_destroy(CSYNC *ctx);
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return The userdata saved in the context, NULL if an error
|
||||
* occurred.
|
||||
* occured.
|
||||
*/
|
||||
void *csync_get_userdata(CSYNC *ctx);
|
||||
|
||||
@@ -379,9 +394,9 @@ void *csync_get_userdata(CSYNC *ctx);
|
||||
*
|
||||
* @param userdata The userdata to be stored in the context.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_userdata(CSYNC *ctx, void *userdata);
|
||||
int csync_set_userdata(CSYNC *ctx, void *userdata);
|
||||
|
||||
/**
|
||||
* @brief Get the authentication callback set.
|
||||
@@ -389,9 +404,9 @@ int OCSYNC_EXPORT csync_set_userdata(CSYNC *ctx, void *userdata);
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return The authentication callback set or NULL if an error
|
||||
* occurred.
|
||||
* occured.
|
||||
*/
|
||||
csync_auth_callback OCSYNC_EXPORT csync_get_auth_callback(CSYNC *ctx);
|
||||
csync_auth_callback csync_get_auth_callback(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Set the authentication callback.
|
||||
@@ -400,64 +415,64 @@ csync_auth_callback OCSYNC_EXPORT csync_get_auth_callback(CSYNC *ctx);
|
||||
*
|
||||
* @param cb The authentication callback.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
||||
int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
||||
|
||||
/**
|
||||
* @brief Set the log level.
|
||||
*
|
||||
* @param[in] level The log verbosity.
|
||||
*
|
||||
* @return 0 on success, < 0 if an error occurred.
|
||||
* @return 0 on success, < 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_log_level(int level);
|
||||
int csync_set_log_level(int level);
|
||||
|
||||
/**
|
||||
* @brief Get the log verbosity
|
||||
*
|
||||
* @return The log verbosity, -1 on error.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_get_log_level(void);
|
||||
int csync_get_log_level(void);
|
||||
|
||||
/**
|
||||
* @brief Get the logging callback set.
|
||||
*
|
||||
* @return The logging callback set or NULL if an error
|
||||
* occurred.
|
||||
* occured.
|
||||
*/
|
||||
csync_log_callback OCSYNC_EXPORT csync_get_log_callback(void);
|
||||
csync_log_callback csync_get_log_callback(void);
|
||||
|
||||
/**
|
||||
* @brief Set the logging callback.
|
||||
*
|
||||
* @param cb The logging callback.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_log_callback(csync_log_callback cb);
|
||||
int csync_set_log_callback(csync_log_callback cb);
|
||||
|
||||
/**
|
||||
* @brief get the userdata set for the logging callback.
|
||||
*
|
||||
* @return The userdata or NULL.
|
||||
*/
|
||||
void OCSYNC_EXPORT *csync_get_log_userdata(void);
|
||||
void *csync_get_log_userdata(void);
|
||||
|
||||
/**
|
||||
* @brief Set the userdata passed to the logging callback.
|
||||
*
|
||||
* @param[in] data The userdata to set.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_log_userdata(void *data);
|
||||
int csync_set_log_userdata(void *data);
|
||||
|
||||
/* Used for special modes or debugging */
|
||||
CSYNC_STATUS OCSYNC_EXPORT csync_get_status(CSYNC *ctx);
|
||||
CSYNC_STATUS csync_get_status(CSYNC *ctx);
|
||||
|
||||
/* Used for special modes or debugging */
|
||||
int OCSYNC_EXPORT csync_set_status(CSYNC *ctx, int status);
|
||||
int csync_set_status(CSYNC *ctx, int status);
|
||||
|
||||
typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
|
||||
|
||||
@@ -468,9 +483,9 @@ typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
|
||||
* @param visitor A callback function to handle the file info.
|
||||
* @param filter A filter, built from or'ed csync_instructions_e
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||
int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||
|
||||
/**
|
||||
* @brief Walk the remote file tree and call a visitor function for each file.
|
||||
@@ -479,9 +494,9 @@ int OCSYNC_EXPORT csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *v
|
||||
* @param visitor A callback function to handle the file info.
|
||||
* @param filter A filter, built from and'ed csync_instructions_e
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||
int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||
|
||||
/**
|
||||
* @brief Get the csync status string.
|
||||
@@ -490,7 +505,7 @@ int OCSYNC_EXPORT csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *
|
||||
*
|
||||
* @return A const pointer to a string with more precise status info.
|
||||
*/
|
||||
const char OCSYNC_EXPORT *csync_get_status_string(CSYNC *ctx);
|
||||
const char *csync_get_status_string(CSYNC *ctx);
|
||||
|
||||
#ifdef WITH_ICONV
|
||||
/**
|
||||
@@ -500,7 +515,7 @@ const char OCSYNC_EXPORT *csync_get_status_string(CSYNC *ctx);
|
||||
*
|
||||
* @return 0 on success, or an iconv error number.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_set_iconv_codec(const char *from);
|
||||
int csync_set_iconv_codec(const char *from);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -508,24 +523,24 @@ int OCSYNC_EXPORT csync_set_iconv_codec(const char *from);
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*/
|
||||
void OCSYNC_EXPORT csync_request_abort(CSYNC *ctx);
|
||||
void csync_request_abort(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Clears the abort flag. Can be called from another thread.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*/
|
||||
void OCSYNC_EXPORT csync_resume(CSYNC *ctx);
|
||||
void csync_resume(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Checks for the abort flag, to be used from the modules.
|
||||
*
|
||||
* @param ctx The csync context.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_abort_requested(CSYNC *ctx);
|
||||
int csync_abort_requested(CSYNC *ctx);
|
||||
|
||||
char OCSYNC_EXPORT *csync_normalize_etag(const char *);
|
||||
time_t OCSYNC_EXPORT oc_httpdate_parse( const char *date );
|
||||
char *csync_normalize_etag(const char *);
|
||||
time_t oc_httpdate_parse( const char *date );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+24
-77
@@ -28,6 +28,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "c_private.h"
|
||||
@@ -36,73 +37,16 @@
|
||||
#include "csync_exclude.h"
|
||||
#include "csync_misc.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.exclude"
|
||||
#include "csync_log.h"
|
||||
|
||||
#ifndef WITH_UNIT_TESTING
|
||||
#ifndef NDEBUG
|
||||
static
|
||||
#endif
|
||||
int _csync_exclude_add(c_strlist_t **inList, const char *string) {
|
||||
size_t i = 0;
|
||||
|
||||
// We never want duplicates, so check whether the string is already
|
||||
// in the list first.
|
||||
if (*inList) {
|
||||
for (i = 0; i < (*inList)->count; ++i) {
|
||||
char *pattern = (*inList)->vector[i];
|
||||
if (c_streq(pattern, string)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return c_strlist_add_grow(inList, string);
|
||||
}
|
||||
|
||||
/** Expands C-like escape sequences.
|
||||
*
|
||||
* The returned string is heap-allocated and owned by the caller.
|
||||
*/
|
||||
static const char *csync_exclude_expand_escapes(const char * input)
|
||||
{
|
||||
size_t i_len = strlen(input) + 1;
|
||||
char *out = c_malloc(i_len); // out can only be shorter
|
||||
|
||||
size_t i = 0;
|
||||
size_t o = 0;
|
||||
for (; i < i_len; ++i) {
|
||||
if (input[i] == '\\') {
|
||||
// at worst input[i+1] is \0
|
||||
switch (input[i+1]) {
|
||||
case '\'': out[o++] = '\''; break;
|
||||
case '"': out[o++] = '"'; break;
|
||||
case '?': out[o++] = '?'; break;
|
||||
case '\\': out[o++] = '\\'; break;
|
||||
case 'a': out[o++] = '\a'; break;
|
||||
case 'b': out[o++] = '\b'; break;
|
||||
case 'f': out[o++] = '\f'; break;
|
||||
case 'n': out[o++] = '\n'; break;
|
||||
case 'r': out[o++] = '\r'; break;
|
||||
case 't': out[o++] = '\t'; break;
|
||||
case 'v': out[o++] = '\v'; break;
|
||||
default:
|
||||
out[o++] = input[i];
|
||||
out[o++] = input[i+1];
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
} else {
|
||||
out[o++] = input[i];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
int csync_exclude_load(const char *fname, c_strlist_t **list) {
|
||||
int fd = -1;
|
||||
int i = 0;
|
||||
@@ -155,12 +99,8 @@ int csync_exclude_load(const char *fname, c_strlist_t **list) {
|
||||
if (entry != buf + i) {
|
||||
buf[i] = '\0';
|
||||
if (*entry != '#') {
|
||||
const char *unescaped = csync_exclude_expand_escapes(entry);
|
||||
rc = _csync_exclude_add(list, unescaped);
|
||||
if( rc == 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
|
||||
}
|
||||
SAFE_FREE(unescaped);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", entry);
|
||||
rc = _csync_exclude_add(list, entry);
|
||||
if (rc < 0) {
|
||||
goto out;
|
||||
}
|
||||
@@ -177,6 +117,23 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void csync_exclude_clear(CSYNC *ctx) {
|
||||
c_strlist_clear(ctx->excludes);
|
||||
}
|
||||
|
||||
void csync_exclude_destroy(CSYNC *ctx) {
|
||||
c_strlist_destroy(ctx->excludes);
|
||||
}
|
||||
|
||||
CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
|
||||
|
||||
CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED;
|
||||
|
||||
match = csync_excluded_no_ctx( ctx->excludes, path, filetype );
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
// See http://support.microsoft.com/kb/74496 and
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
|
||||
// Additionally, we ignore '$Recycle.Bin', see https://github.com/owncloud/client/issues/2955
|
||||
@@ -230,11 +187,6 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
|
||||
}
|
||||
blen = strlen(bname);
|
||||
|
||||
rc = csync_fnmatch("._sync_*.db*", bname, 0);
|
||||
if (rc == 0) {
|
||||
match = CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
goto out;
|
||||
}
|
||||
rc = csync_fnmatch(".csync_journal.db*", bname, 0);
|
||||
if (rc == 0) {
|
||||
match = CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
@@ -253,14 +205,9 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
|
||||
// distinguish files ending in '.' from files without an ending,
|
||||
// as '.' is a separator that is not stored internally, so let's
|
||||
// not allow to sync those to avoid file loss/ambiguities (#416)
|
||||
if (blen > 1) {
|
||||
if (bname[blen-1]== ' ') {
|
||||
match = CSYNC_FILE_EXCLUDE_TRAILING_SPACE;
|
||||
goto out;
|
||||
} else if (bname[blen-1]== '.' ) {
|
||||
match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
|
||||
goto out;
|
||||
}
|
||||
if (blen > 1 && (bname[blen-1]== ' ' || bname[blen-1]== '.' )) {
|
||||
match = CSYNC_FILE_EXCLUDE_INVALID_CHAR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (csync_is_windows_reserved_word(bname)) {
|
||||
|
||||
@@ -21,23 +21,20 @@
|
||||
#ifndef _CSYNC_EXCLUDE_H
|
||||
#define _CSYNC_EXCLUDE_H
|
||||
|
||||
#include "ocsynclib.h"
|
||||
|
||||
enum csync_exclude_type_e {
|
||||
CSYNC_NOT_EXCLUDED = 0,
|
||||
CSYNC_FILE_SILENTLY_EXCLUDED,
|
||||
CSYNC_FILE_EXCLUDE_AND_REMOVE,
|
||||
CSYNC_FILE_EXCLUDE_LIST,
|
||||
CSYNC_FILE_EXCLUDE_INVALID_CHAR,
|
||||
CSYNC_FILE_EXCLUDE_TRAILING_SPACE,
|
||||
CSYNC_FILE_EXCLUDE_LONG_FILENAME,
|
||||
CSYNC_FILE_EXCLUDE_HIDDEN,
|
||||
CSYNC_FILE_EXCLUDE_STAT_FAILED
|
||||
};
|
||||
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
|
||||
|
||||
#ifdef WITH_UNIT_TESTING
|
||||
int OCSYNC_EXPORT _csync_exclude_add(c_strlist_t **inList, const char *string);
|
||||
#ifdef NDEBUG
|
||||
int _csync_exclude_add(c_strlist_t **inList, const char *string);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -46,9 +43,40 @@ int OCSYNC_EXPORT _csync_exclude_add(c_strlist_t **inList, const char *string);
|
||||
* @param ctx The context of the synchronizer.
|
||||
* @param fname The filename to load.
|
||||
*
|
||||
* @return 0 on success, -1 if an error occurred with errno set.
|
||||
* @return 0 on success, -1 if an error occured with errno set.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_exclude_load(const char *fname, c_strlist_t **list);
|
||||
int csync_exclude_load(const char *fname, c_strlist_t **list);
|
||||
|
||||
/**
|
||||
* @brief Clear the exclude list in memory.
|
||||
*
|
||||
* @param ctx The synchronizer context.
|
||||
*/
|
||||
void csync_exclude_clear(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Destroy the exclude list in memory.
|
||||
*
|
||||
* @param ctx The synchronizer context.
|
||||
*/
|
||||
void csync_exclude_destroy(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* @brief Check if the given path should be excluded.
|
||||
*
|
||||
* This excludes also paths which can't be used without unix extensions.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @return 2 if excluded and needs cleanup, 1 if excluded, 0 if not.
|
||||
*/
|
||||
CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype);
|
||||
|
||||
/**
|
||||
* @brief Check if the given path should be excluded in a traversal situation.
|
||||
@@ -74,7 +102,7 @@ CSYNC_EXCLUDE_TYPE csync_excluded_traversal(c_strlist_t *excludes, const char *p
|
||||
* @param filetype
|
||||
* @return
|
||||
*/
|
||||
CSYNC_EXCLUDE_TYPE OCSYNC_EXPORT csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
|
||||
CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path, int filetype);
|
||||
#endif /* _CSYNC_EXCLUDE_H */
|
||||
|
||||
/**
|
||||
|
||||
+42
-1
@@ -23,6 +23,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <sys/utime.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
#include "csync_private.h"
|
||||
#include "csync_log.h"
|
||||
@@ -31,11 +37,46 @@ CSYNC_THREAD int csync_log_level;
|
||||
CSYNC_THREAD csync_log_callback csync_log_cb;
|
||||
CSYNC_THREAD void *csync_log_userdata;
|
||||
|
||||
static int current_timestring(int hires, char *buf, size_t len)
|
||||
{
|
||||
char tbuf[64];
|
||||
struct timeval tv;
|
||||
struct tm *tm;
|
||||
time_t t;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
t = (time_t) tv.tv_sec;
|
||||
|
||||
tm = localtime(&t);
|
||||
if (tm == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hires) {
|
||||
strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm);
|
||||
snprintf(buf, len, "%s.%06ld", tbuf, (long) tv.tv_usec);
|
||||
} else {
|
||||
strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm);
|
||||
snprintf(buf, len, "%s", tbuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void csync_log_stderr(int verbosity,
|
||||
const char *function,
|
||||
const char *buffer)
|
||||
{
|
||||
fprintf(stderr, "[%d] %s", verbosity, function);
|
||||
char date[64] = {0};
|
||||
int rc;
|
||||
|
||||
rc = current_timestring(1, date, sizeof(date));
|
||||
if (rc == 0) {
|
||||
fprintf(stderr, "[%s, %d] %s:", date+5, verbosity, function);
|
||||
} else {
|
||||
fprintf(stderr, "[%d] %s", verbosity, function);
|
||||
}
|
||||
|
||||
fprintf(stderr, " %s\n", buffer);
|
||||
}
|
||||
static void csync_log_function(int verbosity,
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#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: */
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
# include <shlobj.h>
|
||||
#else /* _WIN32 */
|
||||
# include <pwd.h>
|
||||
# include <unistd.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "c_lib.h"
|
||||
|
||||
@@ -33,10 +33,9 @@
|
||||
* than fmmatch anyway, which does not care for flags.
|
||||
**/
|
||||
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
||||
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||
#endif
|
||||
|
||||
int csync_fnmatch(const char *pattern, const char *name, int flags);
|
||||
int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags);
|
||||
|
||||
/**
|
||||
* @brief csync_errno_to_status - errno to csync status code
|
||||
|
||||
@@ -96,13 +96,11 @@ struct csync_s {
|
||||
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;
|
||||
|
||||
// needed for SSL client certificate support
|
||||
struct csync_client_certs_s *clientCerts;
|
||||
|
||||
struct {
|
||||
char *file;
|
||||
@@ -123,6 +121,7 @@ struct csync_s {
|
||||
} local;
|
||||
|
||||
struct {
|
||||
char *uri;
|
||||
c_rbtree_t *tree;
|
||||
enum csync_replica_e type;
|
||||
int read_from_db;
|
||||
@@ -182,18 +181,17 @@ struct csync_file_stat_s {
|
||||
mode_t mode; /* u32 */
|
||||
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 in ownCloud. */
|
||||
char file_id[FILE_ID_BUF_SIZE+1]; /* the ownCloud file id is fixed width of 21 byte. */
|
||||
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 */
|
||||
@@ -220,6 +218,9 @@ struct _csync_treewalk_context_s
|
||||
};
|
||||
typedef struct _csync_treewalk_context_s _csync_treewalk_context;
|
||||
|
||||
|
||||
time_t oc_httpdate_parse( const char *date );
|
||||
|
||||
void set_errno_from_http_errcode( int err );
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "config_csync.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "csync_private.h"
|
||||
#include "csync_reconcile.h"
|
||||
#include "csync_util.h"
|
||||
@@ -65,21 +64,7 @@ static c_rbnode_t *_csync_check_ignored(c_rbtree_t *tree, const char *path, int
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The main function in the reconcile pass.
|
||||
*
|
||||
* It's called for each entry in the local and remote rbtrees by
|
||||
* csync_reconcile()
|
||||
*
|
||||
* Before the reconcile phase the trees already know about changes
|
||||
* relative to the sync journal. This function's job is to spot conflicts
|
||||
* between local and remote changes and adjust the nodes accordingly.
|
||||
*
|
||||
* See doc/dev/sync-algorithm.md for an overview.
|
||||
*
|
||||
*
|
||||
* Older detail comment:
|
||||
*
|
||||
/*
|
||||
* We merge replicas at the file level. The merged replica contains the
|
||||
* superset of files that are on the local machine and server copies of
|
||||
* the replica. In the case where the same file is in both the local
|
||||
@@ -145,7 +130,6 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
break;
|
||||
/* file has been removed on the opposite replica */
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
case CSYNC_INSTRUCTION_UPDATE_METADATA:
|
||||
if (cur->has_ignored_files) {
|
||||
/* Do not remove a directory that has ignored files */
|
||||
break;
|
||||
@@ -197,8 +181,13 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
|
||||
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
|
||||
|| other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
|
||||
|| cur->type == CSYNC_FTW_TYPE_DIR) {
|
||||
other->instruction = CSYNC_INSTRUCTION_RENAME;
|
||||
other->destpath = c_strdup( cur->path );
|
||||
@@ -206,6 +195,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
csync_vio_set_file_id( other->file_id, cur->file_id );
|
||||
}
|
||||
other->inode = cur->inode;
|
||||
other->should_update_metadata = true;
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else if (other->instruction == CSYNC_INSTRUCTION_REMOVE) {
|
||||
other->instruction = CSYNC_INSTRUCTION_RENAME;
|
||||
@@ -215,12 +205,12 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
csync_vio_set_file_id( other->file_id, cur->file_id );
|
||||
}
|
||||
other->inode = cur->inode;
|
||||
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!");
|
||||
cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
} else {
|
||||
assert(other->type != CSYNC_FTW_TYPE_DIR);
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
}
|
||||
@@ -232,19 +222,13 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
bool is_conflict = true;
|
||||
bool is_equal_files = false;
|
||||
/*
|
||||
* file found on the other replica
|
||||
*/
|
||||
other = (csync_file_stat_t *) node->data;
|
||||
|
||||
switch (cur->instruction) {
|
||||
case CSYNC_INSTRUCTION_UPDATE_METADATA:
|
||||
if (other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA && ctx->current == LOCAL_REPLICA) {
|
||||
// Remote wins, the SyncEngine will pick relevant local metadata since the remote tree is walked last.
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_EVAL_RENAME:
|
||||
/* If the file already exist on the other side, we have a conflict.
|
||||
Abort the rename and consider it is a new file. */
|
||||
@@ -269,40 +253,37 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
case CSYNC_INSTRUCTION_EVAL:
|
||||
if (other->type == CSYNC_FTW_TYPE_DIR &&
|
||||
cur->type == CSYNC_FTW_TYPE_DIR) {
|
||||
// Folders of the same path are always considered equals
|
||||
is_conflict = false;
|
||||
is_equal_files = (other->modtime == cur->modtime);
|
||||
} else {
|
||||
is_conflict = ((other->size != cur->size) || (other->modtime != cur->modtime));
|
||||
is_equal_files = ((other->size == cur->size) && (other->modtime == cur->modtime));
|
||||
// FIXME: do a binary comparision of the file here because of the following
|
||||
// edge case:
|
||||
// The files could still have different content, even though the mtime
|
||||
// and size are the same.
|
||||
}
|
||||
if (ctx->current == REMOTE_REPLICA) {
|
||||
// If the files are considered equal, only update the DB with the etag from remote
|
||||
cur->instruction = is_conflict ? CSYNC_INSTRUCTION_CONFLICT : CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
if (is_equal_files) {
|
||||
/* The files are considered equal. */
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = is_conflict ? CSYNC_INSTRUCTION_CONFLICT : CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
|
||||
/* update DB with new etag from remote */
|
||||
if (ctx->current == LOCAL_REPLICA) {
|
||||
other->should_update_metadata = true;
|
||||
} else {
|
||||
cur->should_update_metadata = true;
|
||||
}
|
||||
} else if(ctx->current == REMOTE_REPLICA) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
}
|
||||
|
||||
break;
|
||||
/* file on the other replica has not been modified */
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
case CSYNC_INSTRUCTION_UPDATE_METADATA:
|
||||
if (cur->type != other->type) {
|
||||
// If the type of the entity changed, it's like NEW, but
|
||||
// needs to delete the other entity first.
|
||||
cur->instruction = CSYNC_INSTRUCTION_TYPE_CHANGE;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else if (cur->type == CSYNC_FTW_TYPE_DIR) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
cur->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
other->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
cur->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_IGNORE:
|
||||
cur->instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
@@ -323,7 +304,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
if(cur->type == CSYNC_FTW_TYPE_DIR)
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
|
||||
"%-30s %s dir: %s",
|
||||
"%-20s %s dir: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
repo,
|
||||
cur->path);
|
||||
@@ -331,7 +312,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
else
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,
|
||||
"%-30s %s file: %s",
|
||||
"%-20s %s file: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
repo,
|
||||
cur->path);
|
||||
@@ -342,7 +323,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
if(cur->type == CSYNC_FTW_TYPE_DIR)
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"%-30s %s dir: %s",
|
||||
"%-20s %s dir: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
repo,
|
||||
cur->path);
|
||||
@@ -350,7 +331,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
else
|
||||
{
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"%-30s %s file: %s",
|
||||
"%-20s %s file: %s",
|
||||
csync_instruction_str(cur->instruction),
|
||||
repo,
|
||||
cur->path);
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
*
|
||||
* @todo Add an argument to set the algorithm to use.
|
||||
*/
|
||||
int OCSYNC_EXPORT csync_reconcile_updates(CSYNC *ctx);
|
||||
int csync_reconcile_updates(CSYNC *ctx);
|
||||
|
||||
/**
|
||||
* }@
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
extern "C" {
|
||||
#include "csync_private.h"
|
||||
#include "csync_rename.h"
|
||||
}
|
||||
|
||||
#include <map>
|
||||
@@ -94,9 +93,5 @@ char* csync_rename_adjust_path_source(CSYNC* ctx, const char* path)
|
||||
return c_strdup(path);
|
||||
}
|
||||
|
||||
bool csync_rename_count(CSYNC *ctx) {
|
||||
csync_rename_s* d = csync_rename_s::get(ctx);
|
||||
return d->folder_renamed_from.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,13 +27,11 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Return the final destination path of a given patch in case of renames */
|
||||
char OCSYNC_EXPORT *csync_rename_adjust_path(CSYNC *ctx, const char *path);
|
||||
char *csync_rename_adjust_path(CSYNC *ctx, const char *path);
|
||||
/* Return the source of a given path in case of renames */
|
||||
char OCSYNC_EXPORT *csync_rename_adjust_path_source(CSYNC *ctx, const char *path);
|
||||
void OCSYNC_EXPORT csync_rename_destroy(CSYNC *ctx);
|
||||
void OCSYNC_EXPORT csync_rename_record(CSYNC *ctx, const char *from, const char *to);
|
||||
/* Return the amount of renamed item recorded */
|
||||
bool OCSYNC_EXPORT csync_rename_count(CSYNC *ctx);
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+13
-17
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@@ -52,7 +53,7 @@
|
||||
|
||||
#define sqlite_open(A, B) sqlite3_open_v2(A,B, SQLITE_OPEN_READONLY+SQLITE_OPEN_NOMUTEX, NULL)
|
||||
|
||||
#define SQLTM_TIME 150
|
||||
#define SQLTM_TIME 150000
|
||||
#define SQLTM_COUNT 10
|
||||
|
||||
#define SQLITE_BUSY_HANDLED(F) if(1) { \
|
||||
@@ -60,7 +61,7 @@
|
||||
do { rc = F ; \
|
||||
if( (rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED) ) { \
|
||||
n++; \
|
||||
csync_sleep(SQLTM_TIME); \
|
||||
usleep(SQLTM_TIME); \
|
||||
} \
|
||||
}while( (n < SQLTM_COUNT) && ((rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED))); \
|
||||
}
|
||||
@@ -225,8 +226,6 @@ int csync_statedb_close(CSYNC *ctx) {
|
||||
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
|
||||
@@ -287,11 +286,6 @@ static int _csync_file_stat_from_metadata_table( csync_file_stat_t **st, sqlite3
|
||||
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 ) {
|
||||
@@ -313,7 +307,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx,
|
||||
}
|
||||
|
||||
if( ctx->statedb.by_hash_stmt == NULL ) {
|
||||
const char *hash_query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE phash=?1";
|
||||
const char *hash_query = "SELECT * 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;
|
||||
@@ -356,7 +350,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx,
|
||||
}
|
||||
|
||||
if( ctx->statedb.by_fileid_stmt == NULL ) {
|
||||
const char *query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE fileid=?1";
|
||||
const char *query = "SELECT * 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;
|
||||
@@ -396,7 +390,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx,
|
||||
}
|
||||
|
||||
if( ctx->statedb.by_inode_stmt == NULL ) {
|
||||
const char *inode_query = "SELECT " METADATA_COLUMNS " FROM metadata WHERE inode=?1";
|
||||
const char *inode_query = "SELECT * 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;
|
||||
@@ -439,7 +433,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *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')";
|
||||
const char *below_path_query = "SELECT phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote 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 ) {
|
||||
@@ -471,7 +465,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
|
||||
|
||||
if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE
|
||||
|| excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
|
||||
csync_file_stat_free(st);
|
||||
SAFE_FREE(st);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -480,7 +474,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
|
||||
|
||||
/* store into result list. */
|
||||
if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
|
||||
csync_file_stat_free(st);
|
||||
SAFE_FREE(st);
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
break;
|
||||
}
|
||||
@@ -518,7 +512,8 @@ c_strlist_t *csync_statedb_query(sqlite3 *db,
|
||||
/* compile SQL program into a virtual machine, reattempteing if busy */
|
||||
do {
|
||||
if (busy_count) {
|
||||
csync_sleep(100);
|
||||
/* sleep 100 msec */
|
||||
usleep(100000);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "sqlite3_prepare: BUSY counter: %zu", busy_count);
|
||||
}
|
||||
err = sqlite3_prepare(db, statement, -1, &stmt, &tail);
|
||||
@@ -545,7 +540,8 @@ c_strlist_t *csync_statedb_query(sqlite3 *db,
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Busy counter has reached its maximum. Aborting this sql statement");
|
||||
break;
|
||||
}
|
||||
csync_sleep(100);
|
||||
/* sleep 100 msec */
|
||||
usleep(100000);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "sqlite3_step: BUSY counter: %zu", busy_count);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ int csync_get_statedb_exists(CSYNC *ctx);
|
||||
* @param ctx The csync context.
|
||||
* @param statedb Path to the statedb file (sqlite3 db).
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred with errno set.
|
||||
* @return 0 on success, less than 0 if an error occured with errno set.
|
||||
*/
|
||||
int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb);
|
||||
|
||||
|
||||
@@ -31,11 +31,6 @@
|
||||
#include "csync_time.h"
|
||||
#include "vio/csync_vio.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.time"
|
||||
#include "csync_log.h"
|
||||
|
||||
@@ -50,13 +45,7 @@
|
||||
|
||||
int csync_gettime(struct timespec *tp)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
__int64 wintime;
|
||||
GetSystemTimeAsFileTime((FILETIME*)&wintime);
|
||||
wintime -= 116444736000000000ll; //1jan1601 to 1jan1970
|
||||
tp->tv_sec = wintime / 10000000ll; //seconds
|
||||
tp->tv_nsec = wintime % 10000000ll * 100; //nano-seconds
|
||||
#elif defined(HAVE_CLOCK_GETTIME)
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
return clock_gettime(CSYNC_CLOCK, tp);
|
||||
#else
|
||||
struct timeval tv;
|
||||
@@ -73,11 +62,4 @@ int csync_gettime(struct timespec *tp)
|
||||
|
||||
#undef CSYNC_CLOCK
|
||||
|
||||
void csync_sleep(unsigned int msecs)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
Sleep(msecs);
|
||||
#else
|
||||
usleep(msecs * 1000);
|
||||
#endif
|
||||
}
|
||||
/* vim: set ts=8 sw=2 et cindent: */
|
||||
|
||||
@@ -26,6 +26,5 @@
|
||||
#include "csync_private.h"
|
||||
|
||||
int csync_gettime(struct timespec *tp);
|
||||
void csync_sleep(unsigned int msecs);
|
||||
|
||||
#endif /* _CSYNC_TIME_H */
|
||||
|
||||
+191
-196
@@ -56,13 +56,26 @@ static uint64_t _hash_of_file(CSYNC *ctx, const char *file) {
|
||||
|
||||
if( ctx && file ) {
|
||||
path = file;
|
||||
if (ctx->current == LOCAL_REPLICA) {
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
if (strlen(path) <= strlen(ctx->local.uri)) {
|
||||
return 0;
|
||||
}
|
||||
path += strlen(ctx->local.uri) + 1;
|
||||
break;
|
||||
case REMOTE_REPLICA:
|
||||
if (strlen(path) <= strlen(ctx->remote.uri)) {
|
||||
return 0;
|
||||
}
|
||||
path += strlen(ctx->remote.uri) + 1;
|
||||
break;
|
||||
default:
|
||||
path = NULL;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
len = strlen(path);
|
||||
|
||||
h = c_jhash64((uint8_t *) path, len, 0);
|
||||
}
|
||||
return h;
|
||||
@@ -93,42 +106,6 @@ static bool _last_db_return_error(CSYNC* ctx) {
|
||||
return ctx->statedb.lastReturnValue != SQLITE_OK && ctx->statedb.lastReturnValue != SQLITE_DONE && ctx->statedb.lastReturnValue != SQLITE_ROW;
|
||||
}
|
||||
|
||||
/*
|
||||
* This static method is needed because the type members of the two structs use
|
||||
* different enum values. A direct comparion is not neccessarily correct.
|
||||
*
|
||||
* tmp is csync_file_stat_t
|
||||
* fs is csync_vio_file_stat_t with this vio type:
|
||||
* enum csync_vio_file_type_e {
|
||||
* CSYNC_VIO_FILE_TYPE_UNKNOWN,
|
||||
* CSYNC_VIO_FILE_TYPE_REGULAR,
|
||||
* CSYNC_VIO_FILE_TYPE_DIRECTORY,
|
||||
* CSYNC_VIO_FILE_TYPE_FIFO,
|
||||
* CSYNC_VIO_FILE_TYPE_SOCKET,
|
||||
* CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE,
|
||||
* CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE,
|
||||
* CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK
|
||||
* };
|
||||
*
|
||||
* csync_file_stat_t can be:
|
||||
* CSYNC_FTW_TYPE_SKIP, CSYNC_FTW_TYPE_FILE
|
||||
* CSYNC_FTW_TYPE_DIR, CSYNC_FTW_TYPE_SLINK
|
||||
*/
|
||||
static bool _csync_filetype_different( const csync_file_stat_t *tmp, const csync_vio_file_stat_t *fs)
|
||||
{
|
||||
if( !(tmp && fs)) return false;
|
||||
|
||||
if( tmp->type == CSYNC_FTW_TYPE_SKIP ) return true;
|
||||
|
||||
if( tmp->type == CSYNC_FTW_TYPE_DIR && fs->type != CSYNC_VIO_FILE_TYPE_DIRECTORY )
|
||||
return true;
|
||||
if( tmp->type == CSYNC_FTW_TYPE_FILE && fs->type != CSYNC_VIO_FILE_TYPE_REGULAR )
|
||||
return true;
|
||||
if( tmp->type == CSYNC_FTW_TYPE_SLINK && fs->type != CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK )
|
||||
return true;
|
||||
|
||||
return false; // both are NOT different.
|
||||
}
|
||||
|
||||
/* Return true if two mtime are considered equal
|
||||
* We consider mtime that are one hour difference to be equal if they are one hour appart
|
||||
@@ -145,19 +122,7 @@ static bool _csync_mtime_equal(time_t a, time_t b)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main function of the discovery/update pass.
|
||||
*
|
||||
* It's called (indirectly) by csync_update(), once for each entity in the
|
||||
* local filesystem and once for each entity in the server data.
|
||||
*
|
||||
* It has two main jobs:
|
||||
* - figure out whether anything happened compared to the sync journal
|
||||
* and set (primarily) the instruction flag accordingly
|
||||
* - build the ctx->local.tree / ctx->remote.tree
|
||||
*
|
||||
* See doc/dev/sync-algorithm.md for an overview.
|
||||
*/
|
||||
|
||||
static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
const csync_vio_file_stat_t *fs, const int type) {
|
||||
uint64_t h = 0;
|
||||
@@ -175,12 +140,25 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
}
|
||||
|
||||
path = file;
|
||||
if (ctx->current == LOCAL_REPLICA) {
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
if (strlen(path) <= strlen(ctx->local.uri)) {
|
||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
||||
return -1;
|
||||
}
|
||||
path += strlen(ctx->local.uri) + 1;
|
||||
break;
|
||||
case REMOTE_REPLICA:
|
||||
if (strlen(path) <= strlen(ctx->remote.uri)) {
|
||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
||||
return -1;
|
||||
}
|
||||
path += strlen(ctx->remote.uri) + 1;
|
||||
break;
|
||||
default:
|
||||
path = NULL;
|
||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen(path);
|
||||
@@ -231,9 +209,33 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
st->etag = NULL;
|
||||
st->child_modified = 0;
|
||||
st->has_ignored_files = 0;
|
||||
|
||||
/* FIXME: Under which conditions are the following two ifs true and the code
|
||||
* is executed? */
|
||||
if (type == CSYNC_FTW_TYPE_FILE ) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (tmp == NULL) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - not found in db, IGNORE!", path);
|
||||
st->instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
} else {
|
||||
SAFE_FREE(st);
|
||||
st = tmp;
|
||||
st->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - tmp non zero, mtime %lu", path, st->modtime );
|
||||
tmp = NULL;
|
||||
}
|
||||
goto fastout; /* Skip copying of the etag. That's an important difference to upstream
|
||||
* without etags. */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,8 +257,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
tmp = csync_statedb_get_stat_by_hash(ctx, h);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
csync_file_stat_free(st);
|
||||
csync_file_stat_free(tmp);
|
||||
SAFE_FREE(st);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
@@ -269,47 +270,25 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
((int64_t) fs->mtime), ((int64_t) tmp->modtime),
|
||||
fs->etag, tmp->etag, (uint64_t) fs->inode, (uint64_t) tmp->inode,
|
||||
(uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm, tmp->remotePerm, tmp->has_ignored_files );
|
||||
if (ctx->current == REMOTE_REPLICA && !c_streq(fs->etag, tmp->etag)) {
|
||||
st->instruction = CSYNC_INSTRUCTION_EVAL;
|
||||
|
||||
// Preserve the EVAL flag later on if the type has changed.
|
||||
if (_csync_filetype_different(tmp, fs)) {
|
||||
st->child_modified = 1;
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
if (ctx->current == LOCAL_REPLICA &&
|
||||
(!_csync_mtime_equal(fs->mtime, tmp->modtime)
|
||||
// zero size in statedb can happen during migration
|
||||
|| (tmp->size != 0 && fs->size != tmp->size))) {
|
||||
|
||||
// Checksum comparison at this stage is only enabled for .eml files,
|
||||
// check #4754 #4755
|
||||
bool isEmlFile = csync_fnmatch("*.eml", file, FNM_CASEFOLD) == 0;
|
||||
if (isEmlFile && fs->size == tmp->size && tmp->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) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "NOTE: Checksums are identical, file did not actually change: %s", path);
|
||||
st->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve the EVAL flag later on if the type has changed.
|
||||
if (_csync_filetype_different(tmp, fs)) {
|
||||
st->child_modified = 1;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
st->instruction = CSYNC_INSTRUCTION_EVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -326,24 +305,23 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Reading from database: %s", path);
|
||||
ctx->remote.read_from_db = true;
|
||||
}
|
||||
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_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;
|
||||
}
|
||||
if (metadata_differ) {
|
||||
/* file id or permissions has changed. Which means we need to update them in the DB. */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Need to update metadata for: %s", path);
|
||||
st->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
} else {
|
||||
st->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
st->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
|
||||
|
||||
/* tmp might point to malloc mem, so free it here before reusing tmp */
|
||||
csync_file_stat_free(tmp);
|
||||
SAFE_FREE(tmp);
|
||||
|
||||
/* check if it's a file and has been renamed */
|
||||
if (ctx->current == LOCAL_REPLICA) {
|
||||
@@ -352,68 +330,50 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
tmp = csync_statedb_get_stat_by_inode(ctx, fs->inode);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
csync_file_stat_free(st);
|
||||
SAFE_FREE(st);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* translate the file type between the two stat types csync has. */
|
||||
if( tmp && tmp->type == CSYNC_FTW_TYPE_FILE ) {
|
||||
if( tmp && tmp->type == 0 ) {
|
||||
tmp_vio_type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
} else if( tmp && tmp->type == CSYNC_FTW_TYPE_DIR) {
|
||||
} else if( tmp && tmp->type == 2 ) {
|
||||
tmp_vio_type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
|
||||
} else if( tmp && tmp->type == CSYNC_FTW_TYPE_SLINK ) {
|
||||
tmp_vio_type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
} else {
|
||||
tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
// Default to NEW unless we're sure it's a rename.
|
||||
st->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
|
||||
bool isRename =
|
||||
tmp && tmp->inode == fs->inode && tmp_vio_type == fs->type
|
||||
if (tmp && tmp->inode == fs->inode && tmp_vio_type == fs->type
|
||||
&& (tmp->modtime == fs->mtime || fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY)
|
||||
#ifdef NO_RENAME_EXTENSION
|
||||
&& _csync_sameextension(tmp->path, path)
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
// Verify the checksum where possible
|
||||
if (isRename && tmp->checksumTypeId && ctx->callbacks.checksum_hook
|
||||
&& fs->type == CSYNC_VIO_FILE_TYPE_REGULAR) {
|
||||
st->checksum = ctx->callbacks.checksum_hook(
|
||||
file, tmp->checksumTypeId,
|
||||
ctx->callbacks.checksum_userdata);
|
||||
if (st->checksum) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "checking checksum of potential rename %s %s <-> %s", path, st->checksum, tmp->checksum);
|
||||
st->checksumTypeId = tmp->checksumTypeId;
|
||||
isRename = strncmp(st->checksum, tmp->checksum, 1000) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (isRename) {
|
||||
) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
||||
/* inode found so the file has been renamed */
|
||||
st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
|
||||
if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {
|
||||
csync_rename_record(ctx, tmp->path, path);
|
||||
}
|
||||
goto out;
|
||||
} else {
|
||||
/* file not found in statedb */
|
||||
st->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
|
||||
} else {
|
||||
/* Remote Replica Rename check */
|
||||
tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
csync_file_stat_free(st);
|
||||
SAFE_FREE(st);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
if(tmp ) { /* tmp existing at all */
|
||||
if ( _csync_filetype_different(tmp, fs)) {
|
||||
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)) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "WARN: file types different is not!");
|
||||
st->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
goto out;
|
||||
@@ -437,7 +397,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
|
||||
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)) {
|
||||
csync_file_stat_free(st);
|
||||
SAFE_FREE(st);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -447,7 +407,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
}
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Unable to open statedb" );
|
||||
csync_file_stat_free(st);
|
||||
SAFE_FREE(st);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
@@ -463,8 +423,6 @@ out:
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST; /* File listed on ignore list. */
|
||||
} else if (excluded == CSYNC_FILE_EXCLUDE_INVALID_CHAR) {
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS; /* File contains invalid characters. */
|
||||
} else if (excluded == CSYNC_FILE_EXCLUDE_TRAILING_SPACE) {
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_TRAILING_SPACE; /* File ends with a trailing space. */
|
||||
} else if (excluded == CSYNC_FILE_EXCLUDE_LONG_FILENAME) {
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME; /* File name is too long. */
|
||||
} else if (excluded == CSYNC_FILE_EXCLUDE_HIDDEN ) {
|
||||
@@ -474,9 +432,7 @@ out:
|
||||
}
|
||||
}
|
||||
}
|
||||
if (st->instruction != CSYNC_INSTRUCTION_NONE
|
||||
&& st->instruction != CSYNC_INSTRUCTION_IGNORE
|
||||
&& st->instruction != CSYNC_INSTRUCTION_UPDATE_METADATA
|
||||
if (st->instruction != CSYNC_INSTRUCTION_NONE && st->instruction != CSYNC_INSTRUCTION_IGNORE
|
||||
&& type != CSYNC_FTW_TYPE_DIR) {
|
||||
st->child_modified = 1;
|
||||
}
|
||||
@@ -506,6 +462,7 @@ out:
|
||||
strncpy(st->remotePerm, fs->remotePerm, REMOTE_PERM_BUF_SIZE);
|
||||
}
|
||||
|
||||
fastout: /* target if the file information is read from database into st */
|
||||
st->phash = h;
|
||||
st->pathlen = len;
|
||||
memcpy(st->path, (len ? path : ""), len + 1);
|
||||
@@ -513,14 +470,14 @@ out:
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
if (c_rbtree_insert(ctx->local.tree, (void *) st) < 0) {
|
||||
csync_file_stat_free(st);
|
||||
SAFE_FREE(st);
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case REMOTE_REPLICA:
|
||||
if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
|
||||
csync_file_stat_free(st);
|
||||
SAFE_FREE(st);
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
return -1;
|
||||
}
|
||||
@@ -550,11 +507,7 @@ int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
|
||||
switch (flag) {
|
||||
case CSYNC_FTW_FLAG_FILE:
|
||||
if (ctx->current == REMOTE_REPLICA) {
|
||||
if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=%" PRIu64 "]", file, fs->file_id, fs->size);
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=UNKNOWN]", file, fs->file_id);
|
||||
}
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=%" PRIu64 "]", file, fs->file_id, fs->size);
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [inode=%" PRIu64 " size=%" PRIu64 "]", file, fs->inode, fs->size);
|
||||
}
|
||||
@@ -603,7 +556,16 @@ int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
|
||||
|
||||
static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
|
||||
{
|
||||
if( csync_statedb_get_below_path(ctx, uri) < 0 ) {
|
||||
const char *path = NULL;
|
||||
|
||||
if( strlen(uri) < strlen(ctx->remote.uri)+1) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "name does not contain remote uri!");
|
||||
return false;
|
||||
}
|
||||
|
||||
path = uri + strlen(ctx->remote.uri)+1;
|
||||
|
||||
if( csync_statedb_get_below_path(ctx, path) < 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "StateDB could not be read!");
|
||||
return false;
|
||||
}
|
||||
@@ -611,26 +573,6 @@ static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
|
||||
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) {
|
||||
@@ -645,6 +587,12 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
|
||||
bool do_read_from_db = (ctx->current == REMOTE_REPLICA && ctx->remote.read_from_db);
|
||||
|
||||
if (uri[0] == '\0') {
|
||||
errno = ENOENT;
|
||||
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
read_from_db = ctx->remote.read_from_db;
|
||||
|
||||
// if the etag of this dir is still the same, its content is restored from the
|
||||
@@ -658,7 +606,16 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((dh = csync_vio_opendir(ctx, uri)) == NULL) {
|
||||
const char *uri_for_vio = uri;
|
||||
if (ctx->current == REMOTE_REPLICA) {
|
||||
uri_for_vio += strlen(ctx->remote.uri);
|
||||
if (strlen(uri_for_vio) > 0 && uri_for_vio[0] == '/') {
|
||||
uri_for_vio++; // cut leading slash
|
||||
}
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "URI without fuzz for %s is \"%s\"", uri, uri_for_vio);
|
||||
}
|
||||
|
||||
if ((dh = csync_vio_opendir(ctx, uri_for_vio)) == NULL) {
|
||||
if (ctx->abort) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Aborted!");
|
||||
ctx->status_code = CSYNC_STATUS_ABORTED;
|
||||
@@ -668,8 +625,13 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
/* permission denied */
|
||||
ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_OPENDIR_ERROR);
|
||||
if (errno == EACCES) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Permission denied.");
|
||||
if (mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_PERMISSION_DENIED)) {
|
||||
if (ctx->current_fs) {
|
||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
ctx->current_fs->error_status = CSYNC_STATUS_PERMISSION_DENIED;
|
||||
/* If a directory has ignored files, put the flag on the parent directory as well */
|
||||
if( previous_fs ) {
|
||||
previous_fs->has_ignored_files = true;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
} else if(errno == ENOENT) {
|
||||
@@ -678,22 +640,19 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
|
||||
}
|
||||
}
|
||||
// 403 Forbidden can be sent by the server if the file firewall is active.
|
||||
// A file or directory should be ignored and sync must continue. See #3490
|
||||
else if(errno == ERRNO_FORBIDDEN) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Directory access Forbidden (File Firewall?)");
|
||||
if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_FORBIDDEN) ) {
|
||||
goto done;
|
||||
}
|
||||
/* if current_fs is not defined here, better throw an error */
|
||||
}
|
||||
// The server usually replies with the custom "503 Storage not available"
|
||||
// if some path is temporarily unavailable. But in some cases a standard 503
|
||||
// is returned too. Thus we can't distinguish the two and will treat any
|
||||
// 503 as request to ignore the folder. See #3113 #2884.
|
||||
else if(errno == ERRNO_STORAGE_UNAVAILABLE || errno == ERRNO_SERVICE_UNAVAILABLE) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Storage was not available!");
|
||||
if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_STORAGE_UNAVAILABLE ) ) {
|
||||
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;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
/* if current_fs is not defined here, better throw an error */
|
||||
@@ -704,6 +663,8 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
}
|
||||
|
||||
while ((dirent = csync_vio_readdir(ctx, dh))) {
|
||||
const char *path = NULL;
|
||||
size_t ulen = 0;
|
||||
int flen;
|
||||
int flag;
|
||||
|
||||
@@ -729,19 +690,50 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (uri[0] == '\0') {
|
||||
filename = c_strdup(d_name);
|
||||
flen = strlen(d_name);
|
||||
} else {
|
||||
flen = asprintf(&filename, "%s/%s", uri, d_name);
|
||||
}
|
||||
if (flen < 0 || !filename) {
|
||||
flen = asprintf(&filename, "%s/%s", uri, d_name);
|
||||
if (flen < 0) {
|
||||
csync_vio_file_stat_destroy(dirent);
|
||||
dirent = NULL;
|
||||
ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Create relative path */
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
ulen = strlen(ctx->local.uri) + 1;
|
||||
break;
|
||||
case REMOTE_REPLICA:
|
||||
ulen = strlen(ctx->remote.uri) + 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (((size_t)flen) < ulen) {
|
||||
csync_vio_file_stat_destroy(dirent);
|
||||
dirent = NULL;
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
path = filename + ulen;
|
||||
|
||||
/* skip ".csync_journal.db" and ".csync_journal.db.ctmp" */
|
||||
/* Isn't this done via csync_exclude already? */
|
||||
if (c_streq(path, ".csync_journal.db")
|
||||
|| c_streq(path, ".csync_journal.db.ctmp")
|
||||
|| c_streq(path, ".csync_journal.db.ctmp-journal")
|
||||
|| c_streq(path, ".csync-progressdatabase")
|
||||
|| c_streq(path, ".csync_journal.db-shm")
|
||||
|| c_streq(path, ".csync_journal.db-wal")
|
||||
|| c_streq(path, ".csync_journal.db-journal")) {
|
||||
csync_vio_file_stat_destroy(dirent);
|
||||
dirent = NULL;
|
||||
SAFE_FREE(filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only for the local replica we have to stat(), for the remote one we have all data already */
|
||||
if (ctx->replica == LOCAL_REPLICA) {
|
||||
res = csync_vio_stat(ctx, filename, dirent);
|
||||
@@ -754,9 +746,7 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
* 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;
|
||||
}
|
||||
dirent->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
|
||||
}
|
||||
|
||||
if( res == 0) {
|
||||
@@ -808,11 +798,10 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
|
||||
if (ctx->current_fs && !ctx->current_fs->child_modified
|
||||
&& ctx->current_fs->instruction == CSYNC_INSTRUCTION_EVAL) {
|
||||
if (ctx->current == REMOTE_REPLICA) {
|
||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
} else {
|
||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
if (ctx->current == REMOTE_REPLICA) {
|
||||
ctx->current_fs->should_update_metadata = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->current_fs && previous_fs && ctx->current_fs->has_ignored_files) {
|
||||
@@ -826,6 +815,12 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||
previous_fs->child_modified = ctx->current_fs->child_modified;
|
||||
}
|
||||
|
||||
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_metadata = true;
|
||||
}
|
||||
|
||||
ctx->current_fs = previous_fs;
|
||||
ctx->remote.read_from_db = read_from_db;
|
||||
SAFE_FREE(filename);
|
||||
|
||||
@@ -55,8 +55,6 @@ static const _instr_code_struct _instr[] =
|
||||
{ "INSTRUCTION_SYNC", CSYNC_INSTRUCTION_SYNC },
|
||||
{ "INSTRUCTION_STAT_ERR", CSYNC_INSTRUCTION_STAT_ERROR },
|
||||
{ "INSTRUCTION_ERROR", CSYNC_INSTRUCTION_ERROR },
|
||||
{ "INSTRUCTION_TYPE_CHANGE", CSYNC_INSTRUCTION_TYPE_CHANGE },
|
||||
{ "INSTRUCTION_UPDATE_METADATA", CSYNC_INSTRUCTION_UPDATE_METADATA },
|
||||
{ NULL, CSYNC_INSTRUCTION_ERROR }
|
||||
};
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
|
||||
#include "csync_private.h"
|
||||
|
||||
const char OCSYNC_EXPORT *csync_instruction_str(enum csync_instructions_e instr);
|
||||
const char *csync_instruction_str(enum csync_instructions_e instr);
|
||||
|
||||
void OCSYNC_EXPORT csync_memstat_check(void);
|
||||
void csync_memstat_check(void);
|
||||
|
||||
bool OCSYNC_EXPORT csync_file_locked_or_open( const char *dir, const char *fname);
|
||||
bool csync_file_locked_or_open( const char *dir, const char *fname);
|
||||
#endif /* _CSYNC_UTIL_H */
|
||||
|
||||
@@ -26,12 +26,6 @@ set(cstdlib_SRCS
|
||||
c_time.c
|
||||
)
|
||||
|
||||
if(NOT HAVE_ASPRINTF AND NOT HAVE___MINGW_ASPRINTF)
|
||||
list(APPEND cstdlib_SRCS
|
||||
asprintf.c
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CSTDLIB_PUBLIC_INCLUDE_DIRS}
|
||||
${CSTDLIB_PRIVATE_INCLUDE_DIRS}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
https://raw.githubusercontent.com/littlstar/asprintf.c/20ce5207a4ecb24017b5a17e6cd7d006e3047146/asprintf.c
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Little Star Media, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* `asprintf.c' - asprintf
|
||||
*
|
||||
* copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "asprintf.h"
|
||||
|
||||
int
|
||||
asprintf (char **str, const char *fmt, ...) {
|
||||
int size = 0;
|
||||
va_list args;
|
||||
|
||||
// init variadic argumens
|
||||
va_start(args, fmt);
|
||||
|
||||
// format and get size
|
||||
size = vasprintf(str, fmt, args);
|
||||
|
||||
// toss args
|
||||
va_end(args);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int
|
||||
vasprintf (char **str, const char *fmt, va_list args) {
|
||||
int size = 0;
|
||||
va_list tmpa;
|
||||
|
||||
// copy
|
||||
va_copy(tmpa, args);
|
||||
|
||||
// apply variadic arguments to
|
||||
// sprintf with format to get size
|
||||
size = vsnprintf(NULL, size, fmt, tmpa);
|
||||
|
||||
// toss args
|
||||
va_end(tmpa);
|
||||
|
||||
// return -1 to be compliant if
|
||||
// size is less than 0
|
||||
if (size < 0) { return -1; }
|
||||
|
||||
// alloc with size plus 1 for `\0'
|
||||
*str = (char *) malloc(size + 1);
|
||||
|
||||
// return -1 to be compliant
|
||||
// if pointer is `NULL'
|
||||
if (NULL == *str) { return -1; }
|
||||
|
||||
// format string with original
|
||||
// variadic arguments and set new size
|
||||
size = vsprintf(*str, fmt, args);
|
||||
return size;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
https://raw.githubusercontent.com/littlstar/asprintf.c/20ce5207a4ecb24017b5a17e6cd7d006e3047146/asprintf.h
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Little Star Media, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* `asprintf.h' - asprintf.c
|
||||
*
|
||||
* copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
#ifndef ASPRINTF_H
|
||||
#define ASPRINTF_H 1
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/**
|
||||
* Sets `char **' pointer to be a buffer
|
||||
* large enough to hold the formatted string
|
||||
* accepting a `va_list' args of variadic
|
||||
* arguments.
|
||||
*/
|
||||
|
||||
int
|
||||
vasprintf (char **, const char *, va_list);
|
||||
|
||||
/**
|
||||
* Sets `char **' pointer to be a buffer
|
||||
* large enough to hold the formatted
|
||||
* string accepting `n' arguments of
|
||||
* variadic arguments.
|
||||
*/
|
||||
|
||||
int
|
||||
asprintf (char **, const char *, ...);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -31,17 +31,14 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <wchar.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#ifdef _WIN32
|
||||
#define EDQUOT 0
|
||||
#define ENODATA 0
|
||||
#ifndef S_IRGRP
|
||||
@@ -68,8 +65,6 @@
|
||||
#define nlink_t int
|
||||
#define getuid() 0
|
||||
#define geteuid() 0
|
||||
#elif defined(_WIN32)
|
||||
#define mode_t int
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
@@ -94,12 +89,8 @@ typedef struct stat csync_stat_t;
|
||||
#define ENODATA EBADF
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_ASPRINTF)
|
||||
#if defined(HAVE___MINGW_ASPRINTF)
|
||||
#if !defined(HAVE_ASPRINTF) && defined(HAVE___MINGW_ASPRINTF)
|
||||
#define asprintf __mingw_asprintf
|
||||
#else
|
||||
#include "asprintf.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRERROR_R
|
||||
|
||||
@@ -38,13 +38,14 @@
|
||||
#define NIL &_sentinel /* all leafs are sentinels */
|
||||
static c_rbnode_t _sentinel = {NULL, NIL, NIL, NULL, NULL, BLACK};
|
||||
|
||||
void c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_rbtree_compare_func *data_compare) {
|
||||
assert(rbtree);
|
||||
assert(key_compare);
|
||||
assert(data_compare);
|
||||
|
||||
int c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_rbtree_compare_func *data_compare) {
|
||||
c_rbtree_t *tree = NULL;
|
||||
|
||||
if (rbtree == NULL || key_compare == NULL || data_compare == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tree = c_malloc(sizeof(*tree));
|
||||
tree->root = NIL;
|
||||
tree->key_compare = key_compare;
|
||||
@@ -52,6 +53,8 @@ void c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_
|
||||
tree->size = 0;
|
||||
|
||||
*rbtree = tree;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static c_rbnode_t *_rbtree_subtree_dup(const c_rbnode_t *node, c_rbtree_t *new_tree, c_rbnode_t *new_parent) {
|
||||
|
||||
+14
-12
@@ -135,8 +135,10 @@ struct c_rbnode_s {
|
||||
*
|
||||
* @param data_compare Callback function to compare a key as data with thee
|
||||
* data inside a red-black tree node.
|
||||
*
|
||||
* @return 0 on success, -1 if an error occured with errno set.
|
||||
*/
|
||||
void c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_rbtree_compare_func *data_compare);
|
||||
int c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_rbtree_compare_func *data_compare);
|
||||
|
||||
/**
|
||||
* @brief Duplicate a red-black tree.
|
||||
@@ -144,7 +146,7 @@ void c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_
|
||||
* @param tree Tree to duplicate.
|
||||
*
|
||||
* @return Pointer to a new allocated duplicated rbtree. NULL if an error
|
||||
* occurred.
|
||||
* occured.
|
||||
*/
|
||||
c_rbtree_t *c_rbtree_dup(const c_rbtree_t *tree);
|
||||
|
||||
@@ -155,7 +157,7 @@ c_rbtree_t *c_rbtree_dup(const c_rbtree_t *tree);
|
||||
*
|
||||
* @param tree The tree to free.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int c_rbtree_free(c_rbtree_t *tree);
|
||||
|
||||
@@ -196,7 +198,7 @@ int c_rbtree_free(c_rbtree_t *tree);
|
||||
* @param data The data to insert into the tree.
|
||||
*
|
||||
* @return 0 on success, 1 if a duplicate has been found and < 0 if an error
|
||||
* occurred with errno set.
|
||||
* occured with errno set.
|
||||
* EINVAL if a null pointer has been passed as the tree.
|
||||
* ENOMEM if there is no memory left.
|
||||
*/
|
||||
@@ -221,7 +223,7 @@ c_rbnode_t *c_rbtree_find(c_rbtree_t *tree, const void *key);
|
||||
*
|
||||
* @param tree The tree to get the head for.
|
||||
*
|
||||
* @return The head node. NULL if an error occurred.
|
||||
* @return The head node. NULL if an error occured.
|
||||
*/
|
||||
c_rbnode_t *c_rbtree_head(c_rbtree_t *tree);
|
||||
|
||||
@@ -230,7 +232,7 @@ c_rbnode_t *c_rbtree_head(c_rbtree_t *tree);
|
||||
*
|
||||
* @param tree The tree to get the tail for.
|
||||
*
|
||||
* @return The tail node. NULL if an error occurred.
|
||||
* @return The tail node. NULL if an error occured.
|
||||
*/
|
||||
c_rbnode_t *c_rbtree_tail(c_rbtree_t *tree);
|
||||
|
||||
@@ -252,7 +254,7 @@ c_rbnode_t *c_rbtree_tail(c_rbtree_t *tree);
|
||||
* @param data Data which should be passed to the visitor function.
|
||||
* @param visitor Visitor function. This will be called for each node passed.
|
||||
*
|
||||
* @return 0 on sucess, less than 0 if an error occurred.
|
||||
* @return 0 on sucess, less than 0 if an error occured.
|
||||
*/
|
||||
int c_rbtree_walk(c_rbtree_t *tree, void *data, c_rbtree_visit_func *visitor);
|
||||
|
||||
@@ -261,7 +263,7 @@ int c_rbtree_walk(c_rbtree_t *tree, void *data, c_rbtree_visit_func *visitor);
|
||||
*
|
||||
* @param node Node which should be deleted.
|
||||
*
|
||||
* @return 0 on success, -1 if an error occurred.
|
||||
* @return 0 on success, -1 if an error occured.
|
||||
*/
|
||||
int c_rbtree_node_delete(c_rbnode_t *node);
|
||||
|
||||
@@ -270,7 +272,7 @@ int c_rbtree_node_delete(c_rbnode_t *node);
|
||||
*
|
||||
* @param node The node of which you want the next node.
|
||||
*
|
||||
* @return The next node, NULL if an error occurred.
|
||||
* @return The next node, NULL if an error occured.
|
||||
*/
|
||||
c_rbnode_t *c_rbtree_node_next(c_rbnode_t *node);
|
||||
|
||||
@@ -279,7 +281,7 @@ c_rbnode_t *c_rbtree_node_next(c_rbnode_t *node);
|
||||
*
|
||||
* @param node The node of which you want the previous node.
|
||||
*
|
||||
* @return The previous node, NULL if an error occurred.
|
||||
* @return The previous node, NULL if an error occured.
|
||||
*/
|
||||
c_rbnode_t *c_rbtree_node_prev(c_rbnode_t *node);
|
||||
|
||||
@@ -288,7 +290,7 @@ c_rbnode_t *c_rbtree_node_prev(c_rbnode_t *node);
|
||||
*
|
||||
* @param N The node to get the data from.
|
||||
*
|
||||
* @return The data, NULL if an error occurred.
|
||||
* @return The data, NULL if an error occured.
|
||||
*/
|
||||
#define c_rbtree_node_data(N) ((N) ? ((N)->data) : NULL)
|
||||
|
||||
@@ -299,7 +301,7 @@ c_rbnode_t *c_rbtree_node_prev(c_rbnode_t *node);
|
||||
*
|
||||
* @param tree The tree to check.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
*/
|
||||
int c_rbtree_check_sanity(c_rbtree_t *tree);
|
||||
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
#include "c_path.h"
|
||||
#include "c_time.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
struct timespec c_tspecdiff(struct timespec time1, struct timespec time0) {
|
||||
struct timespec ret;
|
||||
int xsec = 0;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define _C_TIME_H
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/**
|
||||
* @brief Calculate time difference
|
||||
|
||||
@@ -56,7 +56,6 @@ void csync_vio_file_stat_destroy(csync_vio_file_stat_t *file_stat) {
|
||||
SAFE_FREE(file_stat->directDownloadUrl);
|
||||
SAFE_FREE(file_stat->directDownloadCookies);
|
||||
SAFE_FREE(file_stat->name);
|
||||
SAFE_FREE(file_stat->original_name);
|
||||
SAFE_FREE(file_stat);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,12 @@
|
||||
#ifndef _CSYNC_VIO_LOCAL_H
|
||||
#define _CSYNC_VIO_LOCAL_H
|
||||
|
||||
csync_vio_handle_t OCSYNC_EXPORT *csync_vio_local_opendir(const char *name);
|
||||
int OCSYNC_EXPORT csync_vio_local_closedir(csync_vio_handle_t *dhandle);
|
||||
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_local_readdir(csync_vio_handle_t *dhandle);
|
||||
#include <sys/time.h>
|
||||
|
||||
int OCSYNC_EXPORT csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf);
|
||||
csync_vio_handle_t *csync_vio_local_opendir(const char *name);
|
||||
int csync_vio_local_closedir(csync_vio_handle_t *dhandle);
|
||||
csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle);
|
||||
|
||||
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf);
|
||||
|
||||
#endif /* _CSYNC_VIO_LOCAL_H */
|
||||
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário