Comparar commits
165 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 09bcfe8694 | |||
| b575ded464 | |||
| 03a90bf03f | |||
| ff7b2381e9 | |||
| 24cd8041a8 | |||
| 3eaadfe52f | |||
| ebcec44202 | |||
| 7b0b7fde51 | |||
| fa9ec12ae7 | |||
| 54aa4dce46 | |||
| 7c19f748b7 | |||
| 5aa82944a4 | |||
| 0d9cf26890 | |||
| a4837e9291 | |||
| 5672557a84 | |||
| 0b31f2601d | |||
| a5850d4515 | |||
| c39eb315dd | |||
| 6c8e88e2ed | |||
| eeea255104 | |||
| 8e2af57b57 | |||
| f3f387c36b | |||
| b53ce78eb6 | |||
| bc4753e938 | |||
| aefbca0787 | |||
| 653b42216f | |||
| 3ec9cd1d9e | |||
| 20d0c835b6 | |||
| 3335c733d7 | |||
| 4da55b69df | |||
| b7085987b8 | |||
| a1b44cd82a | |||
| 11b44358f6 | |||
| 651cc25e3f | |||
| a338b9f269 | |||
| 81ff4e02c5 | |||
| 8a1a2eb5b3 | |||
| 0c646b974f | |||
| e661bf2324 | |||
| 2abb5c95bb | |||
| c3ef1a996f | |||
| 7a2a439426 | |||
| ce26afb262 | |||
| 56e1737c61 | |||
| dff57362f9 | |||
| 05a7c18635 | |||
| 3a77074b97 | |||
| 446e7cbd93 | |||
| b4d26ba952 | |||
| 622017adcf | |||
| 088a4f0bbe | |||
| ba96fb89a5 | |||
| 70ae11fcad | |||
| 86fd982b00 | |||
| bdb304f8ec | |||
| 001075daf0 | |||
| 2a98aa7130 | |||
| 9904fb200e | |||
| 6822ae5bec | |||
| 440a804836 | |||
| 9b66dd7166 | |||
| 7601783553 | |||
| c0b0bd5b63 | |||
| 28d86cee17 | |||
| 32bb8295a2 | |||
| 5d71ad83ec | |||
| ab24980001 | |||
| 07dea72c37 | |||
| a734be347b | |||
| 1443ddc7c9 | |||
| 191177ff22 | |||
| 43a2aec92b | |||
| c848097c6b | |||
| 096e2cf233 | |||
| 7181aedb4b | |||
| edfd75949d | |||
| 7fb134b4e0 | |||
| 87e3553c85 | |||
| 6f3aaecb78 | |||
| 40e3653722 | |||
| 5a4f50a0ff | |||
| 3342ebfcc5 | |||
| b4900d60b7 | |||
| 92309013da | |||
| 4895589e4d | |||
| 05d199881e | |||
| 147cf798a6 | |||
| d40c56eda5 | |||
| 6dade0b114 | |||
| 5de44407bf | |||
| 2df741e456 | |||
| 8b5f71f49e | |||
| 77791ccb34 | |||
| a6e4f9939c | |||
| 523cdff1cf | |||
| c4d6277ce3 | |||
| 70196eb48c | |||
| 9b249716a3 | |||
| a4b46db91e | |||
| ebc44fa494 | |||
| 355a8a0a27 | |||
| ab050f9093 | |||
| bf9cffe4b3 | |||
| 43f727cf69 | |||
| 256331fbaa | |||
| 32e6585ae6 | |||
| d072e4a678 | |||
| b99c8fe28b | |||
| 5a3120bd52 | |||
| 9ea69be6ab | |||
| 801cb42d57 | |||
| 51f8a59a9a | |||
| ebbe5acf2b | |||
| 6ccd9e872d | |||
| da69756bb0 | |||
| 1787da8a9d | |||
| f0f82d02ff | |||
| ff20cd4d57 | |||
| 9ab812f89b | |||
| de82d8fcdb | |||
| af2b712dc6 | |||
| a507558dee | |||
| e73c3199c0 | |||
| d88ab4653b | |||
| 9a2450c4c1 | |||
| 3c1f5e662f | |||
| 100ee69ddd | |||
| d45d6ca9da | |||
| 2608c7007e | |||
| 06a88ea9a4 | |||
| 0194ebb222 | |||
| dc654ac846 | |||
| 370fd5062c | |||
| 00d20b4a42 | |||
| a2b238e2e5 | |||
| 0e2c16e827 | |||
| b9fdae6d67 | |||
| c34115610e | |||
| 275ad1e157 | |||
| 1855950fa1 | |||
| fff5c280b3 | |||
| e960b265a8 | |||
| f6b35e5d58 | |||
| 1d93af5f64 | |||
| 75efa8b252 | |||
| 009a0b03da | |||
| 8379a36a75 | |||
| 2f1a40ff7c | |||
| c041ca6163 | |||
| eacc0c8bd6 | |||
| 171de99e00 | |||
| bf02ccc1e8 | |||
| 7ba961c21a | |||
| cb7be78352 | |||
| 6cb194e0d5 | |||
| 552ba94c41 | |||
| fc1933803e | |||
| 46e4ec3183 | |||
| 03e3b3bf50 | |||
| 9aed8dbce8 | |||
| c6794cd338 | |||
| 65ec1b74d5 | |||
| 5676685f58 | |||
| db9ccb40a4 | |||
| d4c15d2c38 |
+10
-4
@@ -1,15 +1,21 @@
|
||||
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/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 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 apt-key add - < Release.key
|
||||
- sudo apt-get update
|
||||
- sudo apt-get build-dep owncloud-client
|
||||
- sudo apt-get -y 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
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(VERSION 2.8.0)
|
||||
|
||||
@@ -125,6 +126,17 @@ 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()
|
||||
|
||||
|
||||
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()
|
||||
|
||||
+34
@@ -1,5 +1,39 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
version 2.2.3 (release 2016-07-xx)
|
||||
* 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
|
||||
* Fix a deadlock when shutting down during discovery (#4993)
|
||||
* 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)
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ with your computer.
|
||||
|
||||
### Binary packages
|
||||
|
||||
* Refer to the download page http://owncloud.org/sync-clients/
|
||||
* Refer to the download page https://owncloud.org/install/#install-clients
|
||||
|
||||
### Source code
|
||||
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
set( MIRALL_VERSION_MAJOR 2 )
|
||||
set( MIRALL_VERSION_MINOR 2 )
|
||||
set( MIRALL_VERSION_PATCH 1 )
|
||||
set( MIRALL_VERSION_PATCH 3 )
|
||||
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 )
|
||||
|
||||
+1
-1
Submodule binary updated: d27d472817...0d89ac7766
@@ -1,5 +0,0 @@
|
||||
--- binary
|
||||
+++ binary
|
||||
@@ -1 +1 @@
|
||||
-Subproject commit 1fb9ddfa9a9a1b4dbc447eee10dbed89172d968a
|
||||
+Subproject commit 01d73965dc8b862d1b2310d3ef801c297b697ec7
|
||||
@@ -1,4 +1,4 @@
|
||||
# (c) 2014 Copyright ownCloud, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# 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, Inc.
|
||||
# (c) 2014 Copyright ownCloud GmbH
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING* file.
|
||||
|
||||
|
||||
@@ -44,6 +44,18 @@
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -139,8 +151,10 @@ int csync_exclude_load(const char *fname, c_strlist_t **list) {
|
||||
buf[i] = '\0';
|
||||
if (*entry != '#') {
|
||||
const char *unescaped = csync_exclude_expand_escapes(entry);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
|
||||
rc = _csync_exclude_add(list, unescaped);
|
||||
if( rc == 0 ) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", unescaped);
|
||||
}
|
||||
SAFE_FREE(unescaped);
|
||||
if (rc < 0) {
|
||||
goto out;
|
||||
|
||||
@@ -472,7 +472,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
|
||||
|
||||
if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE
|
||||
|| excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -481,7 +481,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) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -269,7 +269,8 @@ 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)) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
csync_file_stat_free(tmp);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
@@ -356,7 +357,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
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 */
|
||||
SAFE_FREE(tmp);
|
||||
csync_file_stat_free(tmp);
|
||||
|
||||
/* check if it's a file and has been renamed */
|
||||
if (ctx->current == LOCAL_REPLICA) {
|
||||
@@ -365,7 +366,7 @@ 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)) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
@@ -421,7 +422,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
@@ -450,7 +451,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)) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -460,7 +461,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
||||
}
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Unable to open statedb" );
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
@@ -522,14 +523,14 @@ out:
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
if (c_rbtree_insert(ctx->local.tree, (void *) st) < 0) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case REMOTE_REPLICA:
|
||||
if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
|
||||
SAFE_FREE(st);
|
||||
csync_file_stat_free(st);
|
||||
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
|
||||
return file_stat;
|
||||
|
||||
err:
|
||||
SAFE_FREE(file_stat);
|
||||
csync_vio_file_stat_destroy(file_stat);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -167,16 +167,20 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
|
||||
}
|
||||
file_stat->name = c_utf8_from_locale(handle->ffd.cFileName);
|
||||
|
||||
file_stat->flags = CSYNC_VIO_FILE_FLAGS_NONE;
|
||||
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
|
||||
if ( (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
&& (handle->ffd.dwReserved0 & IO_REPARSE_TAG_SYMLINK)
|
||||
// The SIS or DEDUP flag points to a MS deduplication feature of
|
||||
// certain file storage products. It is not a normal symlink
|
||||
// that should be ignored.
|
||||
&& (! (handle->ffd.dwReserved0 & IO_REPARSE_TAG_SIS))
|
||||
&& (! (handle->ffd.dwReserved0 & IO_REPARSE_TAG_DEDUP)) ) {
|
||||
file_stat->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK;
|
||||
file_stat->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
// Detect symlinks, and treat junctions as symlinks too.
|
||||
if (handle->ffd.dwReserved0 == IO_REPARSE_TAG_SYMLINK
|
||||
|| handle->ffd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT) {
|
||||
file_stat->flags |= CSYNC_VIO_FILE_FLAGS_SYMLINK;
|
||||
file_stat->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
|
||||
} else {
|
||||
// The SIS and DEDUP reparse points should be treated as
|
||||
// regular files. We don't know about the other ones yet,
|
||||
// but will also treat them normally for now.
|
||||
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
}
|
||||
} else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
|
||||
|| handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
|
||||
|| handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
|
||||
@@ -187,7 +191,6 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
|
||||
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
}
|
||||
|
||||
file_stat->flags = CSYNC_VIO_FILE_FLAGS_NONE;
|
||||
/* Check for the hidden flag */
|
||||
if( handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) {
|
||||
file_stat->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
|
||||
|
||||
+4
-4
@@ -159,8 +159,8 @@ In order to make setup simple, you can use the provided Dockerfile to build your
|
||||
1. Assuming you are in the root of the ownCloud Client's source tree, you can
|
||||
build an image from this Dockerfile like this::
|
||||
|
||||
cd admin/win32/docker
|
||||
docker build . -t ownCloud-client-win32:<version>
|
||||
cd admin/win/docker
|
||||
docker build . -t owncloud-client-win32:<version>
|
||||
|
||||
Replace ``<version>`` by the version of the client you are building, e.g.
|
||||
|version| for the release of the client that this document describes.
|
||||
@@ -174,8 +174,8 @@ In order to make setup simple, you can use the provided Dockerfile to build your
|
||||
|
||||
2. From within the source tree Run the docker instance::
|
||||
|
||||
docker run ownCloud-client-win32:<version> -v "$PWD:/home/jenkins/client" \
|
||||
admin/win32/docker/build.sh $(id -u)
|
||||
docker run -v "$PWD:/home/user/client" owncloud-client-win32:<version> \
|
||||
/home/user/client/admin/win/docker/build.sh client/ $(id -u)
|
||||
|
||||
It will run the build, create an NSIS based installer, as well as run tests.
|
||||
You will find the resulting binary in an newly created ``build-win32`` subfolder.
|
||||
|
||||
+336
-4
@@ -11,11 +11,343 @@ X-GNOME-Autostart-Delay=3
|
||||
|
||||
|
||||
# Translations
|
||||
Comment[sq]=Klient njëkohësimesh @APPLICATION_NAME@ për desktop
|
||||
GenericName[sq]=Njëkohësim Dosjesh
|
||||
Name[sq]=Klient njëkohësimesh @APPLICATION_NAME@ për desktop
|
||||
Icon[sq]=@APPLICATION_EXECUTABLE@
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
|
||||
GenericName[oc]=Dorsièr de Sincronizacion
|
||||
Name[oc]=@APPLICATION_NAME@ sincronizacion del client
|
||||
Icon[oc]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ar]=@APPLICATION_NAME@ زبون مزامنة مكتبي
|
||||
GenericName[ar]=مزامنة المجلد
|
||||
Name[ar]=@APPLICATION_NAME@ زبون مزامنة مكتبي
|
||||
Icon[ar]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ca]=Client de sincronització d'escriptori @APPLICATION_NAME@
|
||||
GenericName[ca]=Sincronització de carpetes
|
||||
Name[ca]=Client de sincronització d'escriptori @APPLICATION_NAME@
|
||||
Icon[ca]=@APPLICATION_EXECUTABLE@
|
||||
Comment[da]=@APPLICATION_NAME@ skrivebordsklient til synkronisering
|
||||
GenericName[da]=Mappesynkronisering
|
||||
Name[da]=@APPLICATION_NAME@ skrivebordsklient til synk
|
||||
Icon[da]=@APPLICATION_EXECUTABLE@
|
||||
Comment[de]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
|
||||
GenericName[de]=Ordner-Synchronisation
|
||||
Name[de]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
|
||||
Icon[de]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
|
||||
GenericName[ja_JP]=フォルダ同期
|
||||
Name[ja_JP]=@APPLICATION_NAME@ デスクトップ同期クライアント
|
||||
Icon[ja_JP]=@APPLICATION_EXECUTABLE@
|
||||
Comment[en_GB]=@APPLICATION_NAME@ desktop synchronisation client
|
||||
GenericName[en_GB]=Folder Sync
|
||||
Name[en_GB]=@APPLICATION_NAME@ desktop sync client
|
||||
Icon[en_GB]=@APPLICATION_EXECUTABLE@
|
||||
Comment[es]=@APPLICATION_NAME@ cliente de sincronización de escritorio
|
||||
GenericName[es]=Sincronización de carpeta
|
||||
Name[es]=@APPLICATION_NAME@ cliente de sincronización de escritorio
|
||||
Icon[es]=@APPLICATION_EXECUTABLE@
|
||||
Comment[de_DE]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
|
||||
GenericName[de_DE]=Ordner-Synchronisation
|
||||
Name[de_DE]=@APPLICATION_NAME@ Desktop-Synchronisationsclient
|
||||
Icon[de_DE]=@APPLICATION_EXECUTABLE@
|
||||
Comment[bg_BG]=@APPLICATION_NAME@ клиент за десктоп синхронизация
|
||||
GenericName[bg_BG]=Синхронизиране на папката
|
||||
Name[bg_BG]=@APPLICATION_NAME@ клиент десктоп синхронизация
|
||||
Icon[bg_BG]=@APPLICATION_EXECUTABLE@
|
||||
Comment[fr]=@APPLICATION_NAME@ synchronisation du client
|
||||
GenericName[fr]=Dossier de Synchronisation
|
||||
Name[fr]=@APPLICATION_NAME@ synchronisation du client
|
||||
Icon[fr]=@APPLICATION_EXECUTABLE@
|
||||
Comment[he]=@APPLICATION_NAME@ לקוח סנכון שולחן עבודה
|
||||
GenericName[he]=סנכון תיקייה
|
||||
Name[he]=@APPLICATION_NAME@ לקוח סנכרון שולחן עבודה
|
||||
Icon[he]=@APPLICATION_EXECUTABLE@
|
||||
Comment[id]=Klien sinkronisasi desktop @APPLICATION_NAME@
|
||||
GenericName[id]=Folder Sync
|
||||
Name[id]=Klien sync desktop @APPLICATION_NAME@
|
||||
Icon[id]=@APPLICATION_EXECUTABLE@
|
||||
Comment[is]=@APPLICATION_NAME@ skjáborðsforrit samstillingar
|
||||
GenericName[is]=Samstilling möppu
|
||||
Name[is]=@APPLICATION_NAME@ skjáborðsforrit samstillingar
|
||||
Icon[is]=@APPLICATION_EXECUTABLE@
|
||||
Comment[it]=Client di sincronizzazione del desktop di @APPLICATION_NAME@
|
||||
GenericName[it]=Sincronizzazione cartella
|
||||
Name[it]=Client di sincronizzazione del desktop di @APPLICATION_NAME@
|
||||
Icon[it]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
|
||||
GenericName[ko]=폴더 동기화
|
||||
Name[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
|
||||
Comment[hu_HU]=@APPLICATION_NAME@ asztali szinkronizációs kliens
|
||||
GenericName[hu_HU]=Könyvtár szinkronizálás
|
||||
Name[hu_HU]=@APPLICATION_NAME@ asztali szinkr. kliens
|
||||
Icon[hu_HU]=@APPLICATION_EXECUTABLE@
|
||||
Comment[nl]=@APPLICATION_NAME@ desktop synchronisatie client
|
||||
GenericName[nl]=Mappen sync
|
||||
Name[nl]=@APPLICATION_NAME@ desktop sync client
|
||||
Icon[nl]=@APPLICATION_EXECUTABLE@
|
||||
Comment[et_EE]=@APPLICATION_NAME@ sünkroonimise klient töölauale
|
||||
GenericName[et_EE]=Kaustade sünkroonimine
|
||||
Name[et_EE]=@APPLICATION_NAME@ sünkroonimise klient töölauale
|
||||
Icon[et_EE]=@APPLICATION_EXECUTABLE@
|
||||
Comment[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
|
||||
GenericName[pl]=Folder Synchronizacji
|
||||
Name[pl]=@APPLICATION_NAME@ klient synchronizacji dla komputerów stacjonarnych
|
||||
Icon[pl]=@APPLICATION_EXECUTABLE@
|
||||
Comment[pt_BR]=@APPLICATION_NAME@ cliente de sincronização do computador
|
||||
GenericName[pt_BR]=Sincronização de Pasta
|
||||
Name[pt_BR]=@APPLICATION_NAME@ cliente de sincronização de desktop
|
||||
Icon[pt_BR]=@APPLICATION_EXECUTABLE@
|
||||
Comment[cs_CZ]=@APPLICATION_NAME@ počítačový synchronizační klient
|
||||
GenericName[cs_CZ]=Synchronizace adresáře
|
||||
Name[cs_CZ]=@APPLICATION_NAME@ počítačový synchronizační klient
|
||||
Icon[cs_CZ]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ru]=Настольный клиент синхронизации @НАЗВАНИЕ_ПРИЛОЖЕНИЯ@
|
||||
GenericName[ru]=Синхронизация папки
|
||||
Name[ru]=Настольный клиент синхронизации @НАЗВАНИЕ_ПРИЛОЖЕНИЯ@
|
||||
Icon[ru]=@ВЫПОЛНЯЕМОЕ_ПРИЛОЖЕНИЕ@
|
||||
Comment[sl]=@APPLICATION_NAME@ ‒ Program za usklajevanje datotek z namizjem
|
||||
GenericName[sl]=Usklajevanje map
|
||||
Name[sl]=@APPLICATION_NAME@ ‒ Program za usklajevanje datotek z namizjem
|
||||
Icon[sl]=@APPLICATION_EXECUTABLE@
|
||||
Comment[sq]=Klient njëkohësimesh @APPLICATION_NAME@ për desktop
|
||||
GenericName[sq]=Njëkohësim Dosjesh
|
||||
Name[sq]=Klient njëkohësimesh @APPLICATION_NAME@ për desktop
|
||||
Icon[sq]=@APPLICATION_EXECUTABLE@
|
||||
Comment[sv]=@APPLICATION_NAME@ desktop synkroniseringsklient
|
||||
GenericName[sv]=Mappsynk
|
||||
Name[sv]=@APPLICATION_NAME@ desktop synk-klient
|
||||
Icon[sv]=@APPLICATION_EXECUTABLE@
|
||||
Comment[tr]=@APPLICATION_NAME@ masaüstü senkronizasyon istemcisi
|
||||
GenericName[tr]=Dosya Senkronizasyonu
|
||||
Name[tr]=@APPLICATION_NAME@ masaüstü senkronizasyon istemcisi
|
||||
Icon[tr]=@APPLICATION_EXECUTABLE@
|
||||
Comment[uk]=Настільний клієнт синхронізації @APPLICATION_NAME@
|
||||
GenericName[uk]=Синхронізація теки
|
||||
Name[uk]=Настільний клієнт синхронізації @APPLICATION_NAME@
|
||||
Icon[uk]=@APPLICATION_EXECUTABLE@
|
||||
Comment[ro]=@APPLICATION_NAME@ client de sincronizare pe desktop
|
||||
GenericName[ro]=Sincronizare director
|
||||
Name[ro]=@APPLICATION_NAME@ client de sincronizare pe desktop
|
||||
Icon[ro]=@APPLICATION_EXECUTABLE@
|
||||
Comment[zh_CN]=@APPLICATION_NAME@ 桌面同步客户端
|
||||
GenericName[zh_CN]=文件夹同步
|
||||
Name[zh_CN]=@APPLICATION_NAME@ 桌面同步客户端
|
||||
Icon[zh_CN]=@APPLICATION_EXECUTABLE@
|
||||
GenericName[zh_TW]=資料夾同步
|
||||
Comment[lt_LT]=@APPLICATION_NAME@ darbalaukio sinchronizavimo programa
|
||||
GenericName[lt_LT]=Katalogo sinchnorizacija
|
||||
Name[lt_LT]=@APPLICATION_NAME@ darbalaukio programa
|
||||
Icon[lt_LT]=@APPLICATION_EXECUTABLE@
|
||||
Comment[th_TH]=@APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
|
||||
GenericName[th_TH]=ประสานข้อมูลโฟลเดอร์
|
||||
Name[th_TH]= @APPLICATION_NAME@ ไคลเอนต์ประสานข้อมูลเดสก์ท็อป
|
||||
Icon[th_TH]=@APPLICATION_EXECUTABLE@
|
||||
Comment[nb_NO]=@APPLICATION_NAME@ skrivebordssynkroniseringsklient
|
||||
GenericName[nb_NO]=Mappesynkronisering
|
||||
Name[nb_NO]=@APPLICATION_NAME@ skrivebordssynkroniseringsklient
|
||||
Icon[nb_NO]=@APPLICATION_EXECUTABLE@
|
||||
Comment[nn_NO]=@APPLICATION_NAME@ klient for å synkronisera frå skrivebord
|
||||
GenericName[nn_NO]=Mappe synkronisering
|
||||
Name[nn_NO]=@APPLICATION_NAME@ klient for å synkronisera frå skrivebord
|
||||
Icon[nn_NO]=@APPLICATION_EXECUTABLE@
|
||||
Comment[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização para PC
|
||||
GenericName[pt_PT]=Sincronizar Pasta
|
||||
Name[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização para PC
|
||||
Icon[pt_PT]=@APPLICATION_EXECUTABLE@
|
||||
Icon[km]=@APPLICATION_EXECUTABLE@
|
||||
Comment[lb]=@APPLICATION_NAME@ Desktop Synchronisatioun Client
|
||||
GenericName[lb]=Dossier Dync
|
||||
Name[lb]=@APPLICATION_NAME@ Desktop Sync Client
|
||||
Icon[lb]=@APPLICATION_EXECUTABLE@
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2015 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2015 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
|
||||
Arquivo binário não exibido.
@@ -59,22 +59,22 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x86</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
</PropertyGroup>
|
||||
@@ -89,10 +89,13 @@
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x86.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@@ -108,14 +111,17 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x86.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>OCUtil_x64.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -127,6 +133,9 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PrecompiledHeader />
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@@ -134,12 +143,15 @@
|
||||
<PreprocessorDefinitions>NDEBUG;_USING_V110_SDK71_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x64.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCContextMenu.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
|
||||
@@ -110,17 +110,17 @@ IFACEMETHODIMP OCOverlay::GetPriority(int *pPriority)
|
||||
// we order this in terms of likelyhood
|
||||
switch (_state) {
|
||||
case State_OK:
|
||||
*pPriority = 0;
|
||||
*pPriority = 0; break;
|
||||
case State_OKShared:
|
||||
*pPriority = 1;
|
||||
*pPriority = 1; break;
|
||||
case State_Warning:
|
||||
*pPriority = 2;
|
||||
*pPriority = 2; break;
|
||||
case State_Sync:
|
||||
*pPriority = 3;
|
||||
*pPriority = 3; break;
|
||||
case State_Error:
|
||||
*pPriority = 4;
|
||||
*pPriority = 4; break;
|
||||
default:
|
||||
*pPriority = 5;
|
||||
*pPriority = 5; break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
Arquivo binário não exibido.
@@ -66,25 +66,25 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x86</TargetName>
|
||||
<TargetExt>.dll</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
<TargetExt>.dll</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x86</TargetName>
|
||||
<TargetExt>.dll</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
<TargetExt>.dll</TargetExt>
|
||||
@@ -99,11 +99,14 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x86.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCOverlays.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@@ -114,11 +117,14 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCOverlays.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@@ -133,11 +139,14 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x86.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCOverlays.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@@ -152,11 +161,14 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>..\$(Configuration)\$(Platform);</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>OCUtil_x64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>OCOverlays.def</ModuleDefinitionFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>..\OCUtil</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DllMain.cpp" />
|
||||
|
||||
@@ -45,7 +45,7 @@ std::wstring getUserName() {
|
||||
std::wstring CommunicationSocket::DefaultPipePath()
|
||||
{
|
||||
auto pipename = std::wstring(L"\\\\.\\pipe\\");
|
||||
pipename += L"ownCloud\\";
|
||||
pipename += L"ownCloud-";
|
||||
pipename += getUserName();
|
||||
return pipename;
|
||||
}
|
||||
|
||||
@@ -67,26 +67,26 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<TargetExt>.dll</TargetExt>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x86</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetExt>.dll</TargetExt>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetName>$(ProjectName)_x64</TargetName>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<TargetExt>.dll</TargetExt>
|
||||
<TargetName>$(ProjectName)_x86</TargetName>
|
||||
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
|
||||
<OutDir>$(SolutionDir)..\..\binary\shell_integration\windows\$(Configuration)\$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -155,6 +155,7 @@
|
||||
<ClInclude Include="CommunicationSocket.h" />
|
||||
<ClInclude Include="FileUtil.h" />
|
||||
<ClInclude Include="RegistryUtil.h" />
|
||||
<ClInclude Include="Version.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CommunicationSocket.cpp" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2014 ownCloud, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 ownCloud GmbH. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
// This is the number that will end up in the version window of the DLLs.
|
||||
// Increment this version before committing a new build if you are today's shell_integration build master.
|
||||
#define OCEXT_BUILD_NUM 43
|
||||
|
||||
#define STRINGIZE2(s) #s
|
||||
#define STRINGIZE(s) STRINGIZE2(s)
|
||||
|
||||
#define OCEXT_VERSION 1,0,0,OCEXT_BUILD_NUM
|
||||
#define OCEXT_VERSION_STRING STRINGIZE(OCEXT_VERSION)
|
||||
+3
-7
@@ -28,16 +28,12 @@
|
||||
* \return string PEM
|
||||
*/
|
||||
string x509ToString(BIO *o) {
|
||||
int len = 0;
|
||||
BUF_MEM *bptr;
|
||||
void* data;
|
||||
string ret = "";
|
||||
|
||||
BIO_get_mem_ptr(o, &bptr);
|
||||
len = bptr->length;
|
||||
data = calloc(len+10, sizeof(char));
|
||||
int len = bptr->length;
|
||||
void* data = calloc(len+10, sizeof(char));
|
||||
BIO_read(o, data, len);
|
||||
ret = strdup((char*)data);
|
||||
string ret = std::string(static_cast<char*>(data));
|
||||
free(data);
|
||||
|
||||
return ret;
|
||||
|
||||
externo
+9430
-1907
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
+1478
-23
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+14
-3
@@ -443,16 +443,27 @@ restart_sync:
|
||||
QObject::connect(&engine, SIGNAL(finished(bool)), &app, SLOT(quit()));
|
||||
QObject::connect(&engine, SIGNAL(transmissionProgress(ProgressInfo)), &cmd, SLOT(transmissionProgressSlot()));
|
||||
|
||||
|
||||
// Exclude lists
|
||||
engine.excludedFiles().addExcludeFilePath(ConfigFile::excludeFileFromSystem());
|
||||
if( QFile::exists(options.exclude) )
|
||||
|
||||
bool hasUserExcludeFile = !options.exclude.isEmpty();
|
||||
QString systemExcludeFile = ConfigFile::excludeFileFromSystem();
|
||||
|
||||
// Always try to load the user-provided exclude list if one is specified
|
||||
if ( hasUserExcludeFile ) {
|
||||
engine.excludedFiles().addExcludeFilePath(options.exclude);
|
||||
}
|
||||
// Load the system list if available, or if there's no user-provided list
|
||||
if ( !hasUserExcludeFile || QFile::exists(systemExcludeFile) ) {
|
||||
engine.excludedFiles().addExcludeFilePath(systemExcludeFile);
|
||||
}
|
||||
|
||||
if (!engine.excludedFiles().reloadExcludes()) {
|
||||
// Always make sure at least one list has been loaded
|
||||
qFatal("Cannot load system exclude list or list supplied via --exclude");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
// Have to be done async, else, an error before exec() does not terminate the event loop.
|
||||
QMetaObject::invokeMethod(&engine, "startSync", Qt::QueuedConnection);
|
||||
|
||||
|
||||
@@ -213,14 +213,12 @@ AccountPtr AccountManager::loadAccountHelper(QSettings& settings)
|
||||
|
||||
QString authType = settings.value(QLatin1String(authTypeC)).toString();
|
||||
QString overrideUrl = Theme::instance()->overrideServerUrl();
|
||||
if( !overrideUrl.isEmpty() ) {
|
||||
// if there is a overrideUrl, don't even bother reading from the config as all the accounts
|
||||
// must use the overrideUrl
|
||||
QString forceAuth = Theme::instance()->forceConfigAuthType();
|
||||
if(!forceAuth.isEmpty() && !overrideUrl.isEmpty() ) {
|
||||
// If forceAuth is set, this might also mean the overrideURL has changed.
|
||||
// See enterprise issues #1126
|
||||
acc->setUrl(overrideUrl);
|
||||
auto forceAuth = Theme::instance()->forceConfigAuthType();
|
||||
if (!forceAuth.isEmpty()) {
|
||||
authType = forceAuth;
|
||||
}
|
||||
authType = forceAuth;
|
||||
} else {
|
||||
acc->setUrl(settings.value(QLatin1String(urlC)).toUrl());
|
||||
}
|
||||
|
||||
@@ -159,7 +159,13 @@ void AccountSettings::createAccountToolbox()
|
||||
|
||||
void AccountSettings::slotOpenAccountWizard()
|
||||
{
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
if (
|
||||
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
|
||||
qgetenv("QT_QPA_PLATFORMTHEME") == "appmenu-qt5" ||
|
||||
// We can't call isSystemTrayAvailable with appmenu-qt5 because it breaks the systemtray
|
||||
// (issue #4693, #4944)
|
||||
#endif
|
||||
QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
topLevelWidget()->close();
|
||||
}
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
@@ -190,7 +190,8 @@ void AccountState::checkConnectivity()
|
||||
} else {
|
||||
// Check the server and then the auth.
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Let's try this for all OS and see if it fixes the Qt issues we have on Linux #4720 #3888 #4051
|
||||
//#ifdef Q_OS_WIN
|
||||
// There seems to be a bug in Qt on Windows where QNAM sometimes stops
|
||||
// working correctly after the computer woke up from sleep. See #2895 #2899
|
||||
// and #2973.
|
||||
@@ -201,7 +202,7 @@ void AccountState::checkConnectivity()
|
||||
// If we don't reset the ssl config a second CheckServerJob can produce a
|
||||
// ssl config that does not have a sensible certificate chain.
|
||||
account()->setSslConfiguration(QSslConfiguration());
|
||||
#endif
|
||||
//#endif
|
||||
conValidator->checkServerAndAuth();
|
||||
}
|
||||
}
|
||||
@@ -209,6 +210,7 @@ void AccountState::checkConnectivity()
|
||||
void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList& errors)
|
||||
{
|
||||
if (isSignedOut()) {
|
||||
qDebug() << "Signed out, ignoring" << connectionStatusString(status) << _account->url().toString();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@ Application::Application(int &argc, char **argv) :
|
||||
setupTranslations();
|
||||
|
||||
// Setup global excludes
|
||||
qDebug() << "Loading global exclude list";
|
||||
ConfigFile cfg;
|
||||
ExcludedFiles& excludes = ExcludedFiles::instance();
|
||||
excludes.addExcludeFilePath( cfg.excludeFile(ConfigFile::SystemScope) );
|
||||
@@ -335,6 +336,14 @@ void Application::slotownCloudWizardDone( int res )
|
||||
}
|
||||
}
|
||||
|
||||
static void csyncLogCatcher(int /*verbosity*/,
|
||||
const char */*function*/,
|
||||
const char *buffer,
|
||||
void */*userdata*/)
|
||||
{
|
||||
Logger::instance()->csyncLog( QString::fromUtf8(buffer) );
|
||||
}
|
||||
|
||||
void Application::setupLogging()
|
||||
{
|
||||
// might be called from second instance
|
||||
@@ -350,6 +359,9 @@ void Application::setupLogging()
|
||||
.arg(property("ui_lang").toString())
|
||||
.arg(_theme->version());
|
||||
|
||||
// Setup CSYNC logging to forward to our own logger
|
||||
csync_set_log_callback( csyncLogCatcher );
|
||||
csync_set_log_level( Logger::instance()->isNoop() ? 0 : 11 );
|
||||
}
|
||||
|
||||
void Application::slotUseMonoIconsChanged(bool)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkReply>
|
||||
#include <QSettings>
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "creds/shibboleth/shibbolethwebview.h"
|
||||
#include "creds/shibbolethcredentials.h"
|
||||
@@ -74,10 +75,23 @@ ShibbolethWebView::ShibbolethWebView(AccountPtr account, QWidget* parent)
|
||||
connect(page->networkAccessManager()->cookieJar(),
|
||||
SIGNAL(newCookiesForUrl (QList<QNetworkCookie>, QUrl)),
|
||||
this, SLOT(onNewCookiesForUrl (QList<QNetworkCookie>, QUrl)));
|
||||
|
||||
page->mainFrame()->load(account->url());
|
||||
this->setPage(page);
|
||||
setWindowTitle(tr("%1 - Authenticate").arg(Theme::instance()->appNameGUI()));
|
||||
|
||||
// Debug view to display the cipher suite
|
||||
if( !qgetenv("OWNCLOUD_SHIBBOLETH_DEBUG").isEmpty() ) {
|
||||
// open an additional window to display some cipher debug info
|
||||
QWebPage *debugPage = new UserAgentWebPage(this);
|
||||
debugPage->mainFrame()->load( QUrl("https://cc.dcsec.uni-hannover.de/"));
|
||||
QWebView *debugView = new QWebView(this);
|
||||
debugView->setPage(debugPage);
|
||||
QMainWindow *window = new QMainWindow(this);
|
||||
window->setWindowTitle(tr("SSL Chipher Debug View"));
|
||||
window->setCentralWidget(debugView);
|
||||
window->show();
|
||||
}
|
||||
// If we have a valid cookie, it's most likely expired. We can use this as
|
||||
// as a criteria to tell the user why the browser window pops up
|
||||
QNetworkCookie shibCookie = ShibbolethCredentials::findShibCookie(_account.data(), ShibbolethCredentials::accountCookies(_account.data()));
|
||||
@@ -142,7 +156,6 @@ void ShibbolethWebView::slotLoadFinished(bool success)
|
||||
|
||||
if (!success) {
|
||||
qDebug() << Q_FUNC_INFO << "Could not load Shibboleth login page to log you in.";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-25
@@ -46,14 +46,6 @@
|
||||
|
||||
namespace OCC {
|
||||
|
||||
static void csyncLogCatcher(int /*verbosity*/,
|
||||
const char */*function*/,
|
||||
const char *buffer,
|
||||
void */*userdata*/)
|
||||
{
|
||||
Logger::instance()->csyncLog( QString::fromUtf8(buffer) );
|
||||
}
|
||||
|
||||
|
||||
Folder::Folder(const FolderDefinition& definition,
|
||||
AccountState* accountState,
|
||||
@@ -121,6 +113,8 @@ Folder::Folder(const FolderDefinition& definition,
|
||||
|
||||
Folder::~Folder()
|
||||
{
|
||||
// Reset then engine first as it will abort and try to access members of the Folder
|
||||
_engine.reset();
|
||||
}
|
||||
|
||||
void Folder::checkLocalPath()
|
||||
@@ -320,6 +314,7 @@ void Folder::slotRunEtagJob()
|
||||
// sync if it's different.
|
||||
|
||||
_requestEtagJob = new RequestEtagJob(account, remotePath(), this);
|
||||
_requestEtagJob->setTimeout(60*1000);
|
||||
// check if the etag is different
|
||||
QObject::connect(_requestEtagJob, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString)));
|
||||
FolderMan::instance()->slotScheduleETagJob(alias(), _requestEtagJob);
|
||||
@@ -578,19 +573,10 @@ int Folder::slotWipeErrorBlacklist()
|
||||
|
||||
void Folder::slotWatchedPathChanged(const QString& path)
|
||||
{
|
||||
// When no sync is running or it's in the prepare phase, we can
|
||||
// always schedule a new sync.
|
||||
if (! _engine->isSyncRunning() || _syncResult.status() == SyncResult::SyncPrepare) {
|
||||
emit watchedFileChangedExternally(path);
|
||||
emit scheduleToSync(this);
|
||||
return;
|
||||
}
|
||||
|
||||
// The folder watcher fires a lot of bogus notifications during
|
||||
// a sync operation, both for actual user files and the database
|
||||
// and log. Therefore we check notifications against operations
|
||||
// the sync is doing to filter out our own changes.
|
||||
bool ownChange = false;
|
||||
#ifdef Q_OS_MAC
|
||||
Q_UNUSED(path)
|
||||
// On OSX the folder watcher does not report changes done by our
|
||||
@@ -600,14 +586,23 @@ void Folder::slotWatchedPathChanged(const QString& path)
|
||||
const auto maxNotificationDelay = 15*1000;
|
||||
qint64 time = _engine->timeSinceFileTouched(path);
|
||||
if (time != -1 && time < maxNotificationDelay) {
|
||||
ownChange = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! ownChange) {
|
||||
emit watchedFileChangedExternally(path);
|
||||
emit scheduleToSync(this);
|
||||
// Check that the mtime actually changed.
|
||||
if (path.startsWith(this->path())) {
|
||||
auto relativePath = path.mid(this->path().size());
|
||||
auto record = _journal.getFileRecord(relativePath);
|
||||
if (record.isValid() && !FileSystem::fileChanged(path, record._fileSize,
|
||||
Utility::qDateTimeToTime_t(record._modtime))) {
|
||||
qDebug() << "Ignoring spurious notification for file" << relativePath;
|
||||
return; // probably a spurious notification
|
||||
}
|
||||
}
|
||||
|
||||
emit watchedFileChangedExternally(path);
|
||||
emit scheduleToSync(this);
|
||||
}
|
||||
|
||||
void Folder::slotThreadTreeWalkResult(const SyncFileItemVector& items)
|
||||
@@ -630,7 +625,7 @@ void Folder::removeFromSettings() const
|
||||
{
|
||||
auto settings = _accountState->settings();
|
||||
settings->beginGroup(QLatin1String("Folders"));
|
||||
settings->remove(_definition.alias);
|
||||
settings->remove(FolderMan::escapeAlias(_definition.alias));
|
||||
}
|
||||
|
||||
bool Folder::isFileExcludedAbsolute(const QString& fullPath) const
|
||||
@@ -694,6 +689,10 @@ void Folder::wipe()
|
||||
|
||||
bool Folder::setIgnoredFiles()
|
||||
{
|
||||
// Note: Doing this on each sync run and on Folder construction is
|
||||
// unnecessary, because _engine->excludedFiles() persists between
|
||||
// sync runs. This is not a big problem because ExcludedFiles maintains
|
||||
// a QSet of files to load.
|
||||
ConfigFile cfg;
|
||||
QString systemList = cfg.excludeFile(ConfigFile::SystemScope);
|
||||
if( QFile::exists(systemList) ) {
|
||||
@@ -725,8 +724,6 @@ void Folder::startSync(const QStringList &pathList)
|
||||
if (proxyDirty()) {
|
||||
setProxyDirty(false);
|
||||
}
|
||||
csync_set_log_callback( csyncLogCatcher );
|
||||
csync_set_log_level( Logger::instance()->isNoop() ? 0 : 11 );
|
||||
|
||||
if (isBusy()) {
|
||||
qCritical() << "* ERROR csync is still running and new sync requested.";
|
||||
@@ -915,7 +912,7 @@ void Folder::slotFolderDiscovered(bool, QString folderName)
|
||||
// and hand the result over to the progress dispatcher.
|
||||
void Folder::slotTransmissionProgress(const ProgressInfo &pi)
|
||||
{
|
||||
if( !pi.hasStarted() ) {
|
||||
if( !pi.isUpdatingEstimates() ) {
|
||||
// this is the beginning of a sync, set the warning level to 0
|
||||
_syncResult.setWarnCount(0);
|
||||
}
|
||||
|
||||
@@ -849,7 +849,8 @@ Folder *FolderMan::folderForPath(const QString &path)
|
||||
foreach(Folder* folder, this->map().values()) {
|
||||
const QString folderPath = folder->cleanPath()+QLatin1Char('/');
|
||||
|
||||
if(absolutePath.startsWith(folderPath)) {
|
||||
if(absolutePath.startsWith(folderPath, (Utility::isWindows() || Utility::isMac())?
|
||||
Qt::CaseInsensitive : Qt::CaseSensitive)) {
|
||||
//qDebug() << "found folder: " << folder->path() << " for " << absolutePath;
|
||||
return folder;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,14 @@ static void callback(
|
||||
Q_UNUSED(eventFlags)
|
||||
Q_UNUSED(eventIds)
|
||||
|
||||
const FSEventStreamEventFlags c_interestingFlags
|
||||
= kFSEventStreamEventFlagItemCreated // for new folder/file
|
||||
| kFSEventStreamEventFlagItemRemoved // for rm
|
||||
| kFSEventStreamEventFlagItemInodeMetaMod // for mtime change
|
||||
| kFSEventStreamEventFlagItemRenamed // also coming for moves to trash in finder
|
||||
| kFSEventStreamEventFlagItemModified; // for content change
|
||||
//We ignore other flags, e.g. for owner change, xattr change, Finder label change etc
|
||||
|
||||
qDebug() << "FolderWatcherPrivate::callback by OS X";
|
||||
|
||||
QStringList paths;
|
||||
@@ -62,8 +70,14 @@ static void callback(
|
||||
CFIndex pathLength = CFStringGetLength(path);
|
||||
qstring.resize(pathLength);
|
||||
CFStringGetCharacters(path, CFRangeMake(0, pathLength), reinterpret_cast<UniChar *>(qstring.data()));
|
||||
QString fn = qstring.normalized(QString::NormalizationForm_C);
|
||||
|
||||
paths.append(qstring.normalized(QString::NormalizationForm_C));
|
||||
if (!(eventFlags[i] & c_interestingFlags)) {
|
||||
qDebug() << "Ignoring non-content changes for" << fn;
|
||||
continue;
|
||||
}
|
||||
|
||||
paths.append(fn);
|
||||
}
|
||||
|
||||
reinterpret_cast<FolderWatcherPrivate*>(clientCallBackInfo)->doNotifyParent(paths);
|
||||
|
||||
@@ -161,12 +161,4 @@ void GeneralSettings::slotIgnoreFilesEditor()
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralSettings::slotOpenAccountWizard()
|
||||
{
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
topLevelWidget()->close();
|
||||
}
|
||||
OwncloudSetupWizard::runWizard(qApp, SLOT(slotownCloudWizardDone(int)), 0);
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
@@ -44,7 +44,6 @@ private slots:
|
||||
void slotToggleOptionalDesktopNotifications(bool);
|
||||
void slotUpdateInfo();
|
||||
void slotIgnoreFilesEditor();
|
||||
void slotOpenAccountWizard();
|
||||
|
||||
private:
|
||||
void loadMiscSettings();
|
||||
|
||||
+8
-5
@@ -47,18 +47,21 @@ int main(int argc, char **argv)
|
||||
{
|
||||
Q_INIT_RESOURCE(client);
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
#ifdef Q_OS_WIN
|
||||
// If the font size ratio is set on Windows, we need to
|
||||
// enable the auto pixelRatio in Qt since we don't
|
||||
// want to use sizes relative to the font size everywhere.
|
||||
// This is automatic on OS X, but opt-in on Windows and Linux
|
||||
// https://doc-snapshots.qt.io/qt5-5.6/highdpi.html#qt-support
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
|
||||
qputenv("QT_DEVICE_PIXEL_RATIO", "auto");
|
||||
#else
|
||||
// We do not define it on linux so the behaviour is kept the same
|
||||
// as other Qt apps in the desktop environment. (which may or may
|
||||
// not set this envoronment variable)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
||||
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
|
||||
#else
|
||||
qputenv("QT_DEVICE_PIXEL_RATIO", "auto"); // See #4840, #4994
|
||||
#endif
|
||||
#endif // !Q_OS_MAC
|
||||
#endif // !Q_OS_WIN
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
Mac::CocoaInitializer cocoaInit; // RIIA
|
||||
|
||||
+19
-4
@@ -47,6 +47,19 @@ void OcsJob::appendPath(const QString &id)
|
||||
setPath(path() + QLatin1Char('/') + id);
|
||||
}
|
||||
|
||||
static QList<QPair<QByteArray, QByteArray>>
|
||||
percentEncodeQueryItems(
|
||||
const QList<QPair<QString, QString>> & items)
|
||||
{
|
||||
QList<QPair<QByteArray, QByteArray>> result;
|
||||
foreach (const auto& item, items) {
|
||||
result.append(qMakePair(
|
||||
QUrl::toPercentEncoding(item.first),
|
||||
QUrl::toPercentEncoding(item.second)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void OcsJob::start()
|
||||
{
|
||||
QNetworkRequest req;
|
||||
@@ -57,7 +70,9 @@ void OcsJob::start()
|
||||
QBuffer *buffer = new QBuffer;
|
||||
|
||||
if (_verb == "GET") {
|
||||
url.setQueryItems(_params);
|
||||
// Note: QUrl::setQueryItems() does not fully percent encode
|
||||
// the query items, see #5042
|
||||
url.setEncodedQueryItems(percentEncodeQueryItems(_params));
|
||||
} else if (_verb == "POST" || _verb == "PUT") {
|
||||
// Url encode the _postParams and put them in a buffer.
|
||||
QByteArray postData;
|
||||
@@ -73,9 +88,9 @@ void OcsJob::start()
|
||||
}
|
||||
|
||||
//We want json data
|
||||
auto queryItems = url.queryItems();
|
||||
queryItems.append(qMakePair(QString::fromLatin1("format"), QString::fromLatin1("json")));
|
||||
url.setQueryItems(queryItems);
|
||||
auto queryItems = url.encodedQueryItems();
|
||||
queryItems.append(qMakePair(QByteArray("format"), QByteArray("json")));
|
||||
url.setEncodedQueryItems(queryItems);
|
||||
|
||||
setReply(davRequest(_verb, url, req, buffer));
|
||||
setupConnections(reply());
|
||||
|
||||
@@ -367,7 +367,7 @@ void ownCloudGui::addAccountContextMenu(AccountStatePtr accountState, QMenu *men
|
||||
menu->addAction(tr("Managed Folders:"))->setDisabled(true);
|
||||
}
|
||||
|
||||
QAction *action = new QAction( tr("Open folder '%1'").arg(folder->shortGuiLocalPath()), this );
|
||||
QAction *action = new QAction( tr("Open folder '%1'").arg(folder->shortGuiLocalPath()), menu );
|
||||
connect(action, SIGNAL(triggered()),_folderOpenActionMapper, SLOT(map()));
|
||||
_folderOpenActionMapper->setMapping( action, folder->alias() );
|
||||
menu->addAction(action);
|
||||
@@ -399,8 +399,26 @@ void ownCloudGui::addAccountContextMenu(AccountStatePtr accountState, QMenu *men
|
||||
|
||||
}
|
||||
|
||||
static bool minimalTrayMenu()
|
||||
{
|
||||
static QByteArray var = qgetenv("OWNCLOUD_MINIMAL_TRAY_MENU");
|
||||
return !var.isEmpty();
|
||||
}
|
||||
|
||||
void ownCloudGui::setupContextMenu()
|
||||
{
|
||||
// The tray menu is surprisingly problematic. Being able to switch to
|
||||
// a minimal version of it is a useful workaround and testing tool.
|
||||
if (minimalTrayMenu()) {
|
||||
if (!_contextMenu) {
|
||||
_contextMenu.reset(new QMenu());
|
||||
_recentActionsMenu = new QMenu(tr("Recent Changes"), _contextMenu.data());
|
||||
_tray->setContextMenu(_contextMenu.data());
|
||||
_contextMenu->addAction(_actionQuit);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto accountList = AccountManager::instance()->accounts();
|
||||
|
||||
bool isConfigured = (!accountList.isEmpty());
|
||||
@@ -685,7 +703,7 @@ void ownCloudGui::slotUpdateProgress(const QString &folder, const ProgressInfo&
|
||||
slotRebuildRecentMenus();
|
||||
}
|
||||
|
||||
if (progress.hasStarted()
|
||||
if (progress.isUpdatingEstimates()
|
||||
&& progress.completedFiles() >= progress.totalFiles()
|
||||
&& progress._currentDiscoveredFolder.isEmpty()) {
|
||||
QTimer::singleShot(2000, this, SLOT(slotDisplayIdle()));
|
||||
|
||||
@@ -173,7 +173,7 @@ void OwncloudSetupWizard::slotNoOwnCloudFoundAuth(QNetworkReply *reply)
|
||||
|
||||
// Allow the credentials dialog to pop up again for the same URL.
|
||||
// Maybe the user just clicked 'Cancel' by accident or changed his mind.
|
||||
_ocWizard->account()->resetSslCertErrorState();
|
||||
_ocWizard->account()->resetRejectedCertificates();
|
||||
}
|
||||
|
||||
void OwncloudSetupWizard::slotNoOwnCloudFoundAuthTimeout(const QUrl&url)
|
||||
|
||||
@@ -121,17 +121,9 @@ void ProtocolWidget::hideEvent(QHideEvent *ev)
|
||||
|
||||
void ProtocolWidget::cleanItems(const QString& folder)
|
||||
{
|
||||
int itemCnt = _ui->_treeWidget->topLevelItemCount();
|
||||
|
||||
// Limit the number of items
|
||||
while(itemCnt > 2000) {
|
||||
delete _ui->_treeWidget->takeTopLevelItem(itemCnt - 1);
|
||||
itemCnt--;
|
||||
}
|
||||
|
||||
// The issue list is a state, clear it and let the next sync fill it
|
||||
// with ignored files and propagation errors.
|
||||
itemCnt = _issueItemView->topLevelItemCount();
|
||||
int itemCnt = _issueItemView->topLevelItemCount();
|
||||
for( int cnt = itemCnt-1; cnt >=0 ; cnt-- ) {
|
||||
QTreeWidgetItem *item = _issueItemView->topLevelItem(cnt);
|
||||
QString itemFolder = item->data(2, Qt::UserRole).toString();
|
||||
@@ -219,7 +211,7 @@ QTreeWidgetItem* ProtocolWidget::createCompletedTreewidgetItem(const QString& fo
|
||||
|
||||
void ProtocolWidget::slotProgressInfo( const QString& folder, const ProgressInfo& progress )
|
||||
{
|
||||
if( !progress.hasStarted() ) {
|
||||
if( !progress.isUpdatingEstimates() ) {
|
||||
// The sync is restarting, clean the old items
|
||||
cleanItems(folder);
|
||||
} else if (progress.completedFiles() >= progress.totalFiles()) {
|
||||
@@ -239,6 +231,12 @@ void ProtocolWidget::slotItemCompleted(const QString &folder, const SyncFileItem
|
||||
_issueItemView->insertTopLevelItem(0, line);
|
||||
emit issueItemCountUpdated(_issueItemView->topLevelItemCount());
|
||||
} else {
|
||||
// Limit the number of items
|
||||
int itemCnt = _ui->_treeWidget->topLevelItemCount();
|
||||
while(itemCnt > 2000) {
|
||||
delete _ui->_treeWidget->takeTopLevelItem(itemCnt - 1);
|
||||
itemCnt--;
|
||||
}
|
||||
_ui->_treeWidget->insertTopLevelItem(0, line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,9 +72,7 @@ ShareUserGroupWidget::ShareUserGroupWidget(AccountPtr account,
|
||||
|
||||
_completer->setModel(_completerModel);
|
||||
_completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
|
||||
_completer->setFilterMode(Qt::MatchContains);
|
||||
#endif
|
||||
_completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
|
||||
_ui->shareeLineEdit->setCompleter(_completer);
|
||||
|
||||
_manager = new ShareManager(_account, this);
|
||||
@@ -250,10 +248,12 @@ void ShareUserGroupWidget::slotCompleterActivated(const QModelIndex & index)
|
||||
layout->addWidget(indicator);
|
||||
|
||||
/*
|
||||
* Don't send the reshare permissions for federataed shares
|
||||
* Don't send the reshare permissions for federated shares for servers <9.1
|
||||
* https://github.com/owncloud/core/issues/22122#issuecomment-185637344
|
||||
* https://github.com/owncloud/client/issues/4996
|
||||
*/
|
||||
if (sharee->type() == Sharee::Federated) {
|
||||
if (sharee->type() == Sharee::Federated
|
||||
&& _account->serverVersionInt() < 0x090100) {
|
||||
int permissions = SharePermissionRead | SharePermissionUpdate;
|
||||
if (!_isFile) {
|
||||
permissions |= SharePermissionCreate | SharePermissionDelete;
|
||||
@@ -337,10 +337,12 @@ ShareWidget::ShareWidget(QSharedPointer<Share> share,
|
||||
connect(_ui->permissionsEdit, SIGNAL(clicked(bool)), SLOT(slotEditPermissionsChanged()));
|
||||
|
||||
/*
|
||||
* We don't show permssion share for federated shares
|
||||
* We don't show permssion share for federated shares with server <9.1
|
||||
* https://github.com/owncloud/core/issues/22122#issuecomment-185637344
|
||||
* https://github.com/owncloud/client/issues/4996
|
||||
*/
|
||||
if (share->getShareType() == Share::TypeRemote) {
|
||||
if (share->getShareType() == Share::TypeRemote
|
||||
&& share->account()->serverVersionInt() < 0x090100) {
|
||||
_ui->permissionShare->setVisible(false);
|
||||
_ui->permissionToolButton->setVisible(false);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ SocketApi::SocketApi(QObject* parent)
|
||||
|
||||
if (Utility::isWindows()) {
|
||||
socketPath = QLatin1String("\\\\.\\pipe\\")
|
||||
+ QLatin1String("ownCloud") + '\\'
|
||||
+ QLatin1String("ownCloud-")
|
||||
+ QString::fromLocal8Bit(qgetenv("USERNAME"));
|
||||
// TODO: once the windows extension supports multiple
|
||||
// client connections, switch back to the theme name
|
||||
|
||||
@@ -218,6 +218,7 @@ void OCUpdater::slotVersionInfoArrived()
|
||||
{
|
||||
_timeoutWatchdog->stop();
|
||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||
reply->deleteLater();
|
||||
if( reply->error() != QNetworkReply::NoError ) {
|
||||
qDebug() << "Failed to reach version check url: " << reply->errorString();
|
||||
return;
|
||||
@@ -258,6 +259,7 @@ void NSISUpdater::slotWriteFile()
|
||||
void NSISUpdater::slotDownloadFinished()
|
||||
{
|
||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||
reply->deleteLater();
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
setDownloadState(DownloadFailed);
|
||||
return;
|
||||
|
||||
@@ -242,6 +242,7 @@ void AbstractNetworkJob::slotTimeout()
|
||||
reply()->abort();
|
||||
} else {
|
||||
qDebug() << Q_FUNC_INFO << this << "Timeout reply was NULL";
|
||||
deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+45
-31
@@ -38,9 +38,6 @@ namespace OCC {
|
||||
Account::Account(QObject *parent)
|
||||
: QObject(parent)
|
||||
, _capabilities(QVariantMap())
|
||||
, _am(0)
|
||||
, _credentials(0)
|
||||
, _treatSslErrorsAsFailure(false)
|
||||
, _davPath( Theme::instance()->webDavPath() )
|
||||
, _wasMigrated(false)
|
||||
{
|
||||
@@ -56,8 +53,6 @@ AccountPtr Account::create()
|
||||
|
||||
Account::~Account()
|
||||
{
|
||||
delete _credentials;
|
||||
delete _am;
|
||||
}
|
||||
|
||||
QString Account::davPath() const
|
||||
@@ -118,14 +113,14 @@ bool Account::changed(AccountPtr other, bool ignoreUrlProtocol) const
|
||||
changes = (_url == other->_url);
|
||||
}
|
||||
|
||||
changes |= _credentials->changed(other->_credentials);
|
||||
changes |= _credentials->changed(other->credentials());
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
AbstractCredentials *Account::credentials() const
|
||||
{
|
||||
return _credentials;
|
||||
return _credentials.data();
|
||||
}
|
||||
|
||||
void Account::setCredentials(AbstractCredentials *cred)
|
||||
@@ -136,29 +131,27 @@ void Account::setCredentials(AbstractCredentials *cred)
|
||||
jar = _am->cookieJar();
|
||||
jar->setParent(0);
|
||||
|
||||
_am->deleteLater();
|
||||
}
|
||||
|
||||
if (_credentials) {
|
||||
credentials()->deleteLater();
|
||||
_am = QSharedPointer<QNetworkAccessManager>();
|
||||
}
|
||||
|
||||
// The order for these two is important! Reading the credential's
|
||||
// settings accesses the account as well as account->_credentials
|
||||
_credentials = cred;
|
||||
// settings accesses the account as well as account->_credentials,
|
||||
// so deleteLater must be used.
|
||||
_credentials = QSharedPointer<AbstractCredentials>(cred, &QObject::deleteLater);
|
||||
cred->setAccount(this);
|
||||
|
||||
_am = _credentials->getQNAM();
|
||||
_am = QSharedPointer<QNetworkAccessManager>(_credentials->getQNAM(), &QObject::deleteLater);
|
||||
|
||||
if (jar) {
|
||||
_am->setCookieJar(jar);
|
||||
}
|
||||
connect(_am, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
connect(_am.data(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
SLOT(slotHandleSslErrors(QNetworkReply*,QList<QSslError>)));
|
||||
connect(_am, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
|
||||
connect(_am.data(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
|
||||
SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
|
||||
connect(_credentials, SIGNAL(fetched()),
|
||||
connect(_credentials.data(), SIGNAL(fetched()),
|
||||
SLOT(slotCredentialsFetched()));
|
||||
connect(_credentials, SIGNAL(asked()),
|
||||
connect(_credentials.data(), SIGNAL(asked()),
|
||||
SLOT(slotCredentialsAsked()));
|
||||
}
|
||||
|
||||
@@ -197,18 +190,21 @@ void Account::resetNetworkAccessManager()
|
||||
|
||||
qDebug() << "Resetting QNAM";
|
||||
QNetworkCookieJar* jar = _am->cookieJar();
|
||||
_am->deleteLater();
|
||||
_am = _credentials->getQNAM();
|
||||
|
||||
// Use a QSharedPointer to allow locking the life of the QNAM on the stack.
|
||||
// Make it call deleteLater to make sure that we can return to any QNAM stack frames safely.
|
||||
_am = QSharedPointer<QNetworkAccessManager>(_credentials->getQNAM(), &QObject::deleteLater);
|
||||
|
||||
_am->setCookieJar(jar); // takes ownership of the old cookie jar
|
||||
connect(_am, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
connect(_am.data(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
SLOT(slotHandleSslErrors(QNetworkReply*,QList<QSslError>)));
|
||||
connect(_am, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
|
||||
connect(_am.data(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
|
||||
SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
|
||||
}
|
||||
|
||||
QNetworkAccessManager *Account::networkAccessManager()
|
||||
{
|
||||
return _am;
|
||||
return _am.data();
|
||||
}
|
||||
|
||||
QNetworkReply *Account::headRequest(const QString &relPath)
|
||||
@@ -329,9 +325,9 @@ void Account::addApprovedCerts(const QList<QSslCertificate> certs)
|
||||
_approvedCerts += certs;
|
||||
}
|
||||
|
||||
void Account::resetSslCertErrorState()
|
||||
void Account::resetRejectedCertificates()
|
||||
{
|
||||
_treatSslErrorsAsFailure = false;
|
||||
_rejectedCertificates.clear();
|
||||
}
|
||||
|
||||
void Account::setSslErrorHandler(AbstractSslErrorHandler *handler)
|
||||
@@ -412,8 +408,15 @@ void Account::slotHandleSslErrors(QNetworkReply *reply , QList<QSslError> errors
|
||||
<< error.errorString() << "("<< error.error() << ")" << "\n";
|
||||
}
|
||||
|
||||
if( _treatSslErrorsAsFailure ) {
|
||||
// User decided once not to trust. Honor this decision.
|
||||
bool allPreviouslyRejected = true;
|
||||
foreach (const QSslError &error, errors) {
|
||||
if (!_rejectedCertificates.contains(error.certificate())) {
|
||||
allPreviouslyRejected = false;
|
||||
}
|
||||
}
|
||||
|
||||
// If all certs have previously been rejected by the user, don't ask again.
|
||||
if( allPreviouslyRejected ) {
|
||||
qDebug() << out << "Certs not trusted by user decision, returning.";
|
||||
return;
|
||||
}
|
||||
@@ -424,6 +427,12 @@ void Account::slotHandleSslErrors(QNetworkReply *reply , QList<QSslError> errors
|
||||
return;
|
||||
}
|
||||
|
||||
// SslDialogErrorHandler::handleErrors will run an event loop that might execute
|
||||
// the deleteLater() of the QNAM before we have the chance of unwinding our stack.
|
||||
// Keep a ref here on our stackframe to make sure that it doesn't get deleted before
|
||||
// handleErrors returns.
|
||||
QSharedPointer<QNetworkAccessManager> qnamLock = _am;
|
||||
|
||||
if (_sslErrorHandler->handleErrors(errors, reply->sslConfiguration(), &approvedCerts, sharedFromThis())) {
|
||||
QSslSocket::addDefaultCaCertificates(approvedCerts);
|
||||
addApprovedCerts(approvedCerts);
|
||||
@@ -436,7 +445,12 @@ void Account::slotHandleSslErrors(QNetworkReply *reply , QList<QSslError> errors
|
||||
// certificate changes.
|
||||
reply->ignoreSslErrors(errors);
|
||||
} else {
|
||||
_treatSslErrorsAsFailure = true;
|
||||
// Mark all involved certificates as rejected, so we don't ask the user again.
|
||||
foreach (const QSslError &error, errors) {
|
||||
if (!_rejectedCertificates.contains(error.certificate())) {
|
||||
_rejectedCertificates.append(error.certificate());
|
||||
}
|
||||
}
|
||||
// if during normal operation, a new certificate was MITM'ed, and the user does not
|
||||
// ACK it, the running request must be aborted and the QNAM must be reset, to not
|
||||
// treat the new cert as granted. See bug #3283
|
||||
@@ -448,12 +462,12 @@ void Account::slotHandleSslErrors(QNetworkReply *reply , QList<QSslError> errors
|
||||
|
||||
void Account::slotCredentialsFetched()
|
||||
{
|
||||
emit credentialsFetched(_credentials);
|
||||
emit credentialsFetched(_credentials.data());
|
||||
}
|
||||
|
||||
void Account::slotCredentialsAsked()
|
||||
{
|
||||
emit credentialsAsked(_credentials);
|
||||
emit credentialsAsked(_credentials.data());
|
||||
}
|
||||
|
||||
void Account::handleInvalidCredentials()
|
||||
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
// Usually when a user explicitly rejects a certificate we don't
|
||||
// ask again. After this call, a dialog will again be shown when
|
||||
// the next unknown certificate is encountered.
|
||||
void resetSslCertErrorState();
|
||||
void resetRejectedCertificates();
|
||||
|
||||
// pluggable handler
|
||||
void setSslErrorHandler(AbstractSslErrorHandler *handler);
|
||||
@@ -214,9 +214,12 @@ private:
|
||||
QString _serverVersion;
|
||||
QScopedPointer<AbstractSslErrorHandler> _sslErrorHandler;
|
||||
QuotaInfo *_quotaInfo;
|
||||
QNetworkAccessManager *_am;
|
||||
AbstractCredentials* _credentials;
|
||||
bool _treatSslErrorsAsFailure;
|
||||
QSharedPointer<QNetworkAccessManager> _am;
|
||||
QSharedPointer<AbstractCredentials> _credentials;
|
||||
|
||||
/// Certificates that were explicitly rejected by the user
|
||||
QList<QSslCertificate> _rejectedCertificates;
|
||||
|
||||
static QString _configFileName;
|
||||
QByteArray _pemCertificate;
|
||||
QString _pemPrivateKey;
|
||||
|
||||
@@ -73,7 +73,8 @@ bool Capabilities::shareResharing() const
|
||||
|
||||
bool Capabilities::notificationsAvailable() const
|
||||
{
|
||||
return _capabilities.contains("notifications");
|
||||
// We require the OCS style API in 9.x, can't deal with the REST one only found in 8.2
|
||||
return _capabilities.contains("notifications") && _capabilities["notifications"].toMap().contains("ocs-endpoints");
|
||||
}
|
||||
|
||||
bool Capabilities::isValid() const
|
||||
|
||||
@@ -564,7 +564,7 @@ csync_vio_handle_t* DiscoveryJob::remote_vio_opendir_hook (const char *url,
|
||||
discoveryJob->_vioMutex.lock();
|
||||
const QString qurl = QString::fromUtf8(url);
|
||||
emit discoveryJob->doOpendirSignal(qurl, directoryResult.data());
|
||||
discoveryJob->_vioWaitCondition.wait(&discoveryJob->_vioMutex, ULONG_MAX); // FIXME timeout?
|
||||
discoveryJob->_vioWaitCondition.wait(&discoveryJob->_vioMutex, 30000);
|
||||
discoveryJob->_vioMutex.unlock();
|
||||
|
||||
qDebug() << discoveryJob << url << "...Returned from main thread";
|
||||
|
||||
@@ -42,7 +42,7 @@ ExcludedFiles& ExcludedFiles::instance()
|
||||
|
||||
void ExcludedFiles::addExcludeFilePath(const QString& path)
|
||||
{
|
||||
_excludeFiles.append(path);
|
||||
_excludeFiles.insert(path);
|
||||
}
|
||||
|
||||
bool ExcludedFiles::reloadExcludes()
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
#include "owncloudlib.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
|
||||
extern "C" {
|
||||
#include "std/c_string.h"
|
||||
@@ -66,7 +67,7 @@ private:
|
||||
// This is a pointer to the csync exclude list, its is owned by this class
|
||||
// but the pointer can be in a csync_context so that it can itself also query the list.
|
||||
c_strlist_t** _excludesPtr;
|
||||
QStringList _excludeFiles;
|
||||
QSet<QString> _excludeFiles;
|
||||
};
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
@@ -496,16 +496,16 @@ QString FileSystem::fileSystemForPath(const QString & path)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define BUFSIZE 1024*1024*10
|
||||
#define BUFSIZE qint64(500*1024) // 500 KiB
|
||||
|
||||
static QByteArray readToCrypto( const QString& filename, QCryptographicHash::Algorithm algo )
|
||||
{
|
||||
const qint64 bufSize = BUFSIZE;
|
||||
QByteArray buf(bufSize,0);
|
||||
QFile file(filename);
|
||||
const qint64 bufSize = qMin(BUFSIZE, file.size() + 1);
|
||||
QByteArray buf(bufSize, Qt::Uninitialized);
|
||||
QByteArray arr;
|
||||
QCryptographicHash crypto( algo );
|
||||
|
||||
QFile file(filename);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
qint64 size;
|
||||
while (!file.atEnd()) {
|
||||
@@ -532,11 +532,11 @@ QByteArray FileSystem::calcSha1( const QString& filename )
|
||||
#ifdef ZLIB_FOUND
|
||||
QByteArray FileSystem::calcAdler32( const QString& filename )
|
||||
{
|
||||
unsigned int adler = adler32(0L, Z_NULL, 0);
|
||||
const qint64 bufSize = BUFSIZE;
|
||||
QByteArray buf(bufSize, 0);
|
||||
|
||||
QFile file(filename);
|
||||
const qint64 bufSize = qMin(BUFSIZE, file.size() + 1);
|
||||
QByteArray buf(bufSize, Qt::Uninitialized);
|
||||
|
||||
unsigned int adler = adler32(0L, Z_NULL, 0);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
qint64 size;
|
||||
while (!file.atEnd()) {
|
||||
|
||||
@@ -111,9 +111,9 @@ bool OWNCLOUDSYNC_EXPORT rename(const QString& originFileName,
|
||||
*
|
||||
* @return true if the file's mtime or size are not what is expected.
|
||||
*/
|
||||
bool fileChanged(const QString& fileName,
|
||||
qint64 previousSize,
|
||||
time_t previousMtime);
|
||||
bool OWNCLOUDSYNC_EXPORT fileChanged(const QString& fileName,
|
||||
qint64 previousSize,
|
||||
time_t previousMtime);
|
||||
|
||||
/**
|
||||
* @brief Like !fileChanged() but with verbose logging if the file *did* change.
|
||||
|
||||
@@ -297,7 +297,12 @@ public:
|
||||
|
||||
QAtomicInt _abortRequested; // boolean set by the main thread to abort.
|
||||
|
||||
/* The list of currently active jobs */
|
||||
/** The list of currently active jobs.
|
||||
This list contains the jobs that are currently using ressources and is used purely to
|
||||
know how many jobs there is currently running for the scheduler.
|
||||
Jobs add themself to the list when they do an assynchronous operation.
|
||||
Jobs can be several time on the list (example, when several chunks are uploaded in parallel)
|
||||
*/
|
||||
QList<PropagateItemJob*> _activeJobList;
|
||||
|
||||
/** We detected that another sync is required after this one */
|
||||
@@ -383,6 +388,7 @@ private:
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||
// access to signals which are protected in Qt4
|
||||
friend class PropagateDownloadFileQNAM;
|
||||
friend class PropagateUploadFileQNAM;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -127,27 +127,65 @@ void ProgressDispatcher::setProgressInfo(const QString& folder, const ProgressIn
|
||||
emit progressInfo( folder, progress );
|
||||
}
|
||||
|
||||
void ProgressInfo::start()
|
||||
ProgressInfo::ProgressInfo()
|
||||
{
|
||||
connect(&_updateEstimatesTimer, SIGNAL(timeout()), SLOT(updateEstimates()));
|
||||
reset();
|
||||
}
|
||||
|
||||
void ProgressInfo::reset()
|
||||
{
|
||||
_currentItems.clear();
|
||||
_currentDiscoveredFolder.clear();
|
||||
_sizeProgress = Progress();
|
||||
_fileProgress = Progress();
|
||||
_totalSizeOfCompletedJobs = 0;
|
||||
_maxBytesPerSecond = 100000.0;
|
||||
_maxFilesPerSecond = 2.0;
|
||||
_updateEstimatesTimer.stop();
|
||||
}
|
||||
|
||||
void ProgressInfo::startEstimateUpdates()
|
||||
{
|
||||
_updateEstimatesTimer.start(1000);
|
||||
}
|
||||
|
||||
bool ProgressInfo::hasStarted() const
|
||||
bool ProgressInfo::isUpdatingEstimates() const
|
||||
{
|
||||
return _updateEstimatesTimer.isActive();
|
||||
}
|
||||
|
||||
static bool shouldCountProgress(const SyncFileItem &item)
|
||||
{
|
||||
const auto instruction = item._instruction;
|
||||
|
||||
// Don't worry about directories that won't have propagation
|
||||
// jobs associated with them.
|
||||
if (item._isDirectory
|
||||
&& (instruction == CSYNC_INSTRUCTION_NONE
|
||||
|| instruction == CSYNC_INSTRUCTION_SYNC
|
||||
|| instruction == CSYNC_INSTRUCTION_CONFLICT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip any ignored or error files, we do nothing with them.
|
||||
if (instruction == CSYNC_INSTRUCTION_IGNORE
|
||||
|| instruction == CSYNC_INSTRUCTION_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProgressInfo::adjustTotalsForFile(const SyncFileItem &item)
|
||||
{
|
||||
if (!item._isDirectory) {
|
||||
_fileProgress._total++;
|
||||
if (isSizeDependent(item)) {
|
||||
_sizeProgress._total += item._size;
|
||||
}
|
||||
} else if (item._instruction != CSYNC_INSTRUCTION_NONE) {
|
||||
// Added or removed directories certainly count.
|
||||
_fileProgress._total++;
|
||||
if (!shouldCountProgress(item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_fileProgress._total += item._affectedItems;
|
||||
if (isSizeDependent(item)) {
|
||||
_sizeProgress._total += item._size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,6 +216,10 @@ quint64 ProgressInfo::completedSize() const
|
||||
|
||||
void ProgressInfo::setProgressComplete(const SyncFileItem &item)
|
||||
{
|
||||
if (!shouldCountProgress(item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_currentItems.remove(item._file);
|
||||
_fileProgress.setCompleted(_fileProgress._completed + item._affectedItems);
|
||||
if (ProgressInfo::isSizeDependent(item)) {
|
||||
@@ -189,6 +231,10 @@ void ProgressInfo::setProgressComplete(const SyncFileItem &item)
|
||||
|
||||
void ProgressInfo::setProgressItem(const SyncFileItem &item, quint64 completed)
|
||||
{
|
||||
if (!shouldCountProgress(item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_currentItems[item._file]._item = item;
|
||||
_currentItems[item._file]._progress._total = item._size;
|
||||
_currentItems[item._file]._progress.setCompleted(completed);
|
||||
|
||||
@@ -37,27 +37,27 @@ class OWNCLOUDSYNC_EXPORT ProgressInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProgressInfo()
|
||||
: _totalSizeOfCompletedJobs(0)
|
||||
, _maxFilesPerSecond(2.0)
|
||||
, _maxBytesPerSecond(100000.0)
|
||||
{}
|
||||
ProgressInfo();
|
||||
|
||||
/** Resets for a new sync run.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Called when propagation starts.
|
||||
*
|
||||
* hasStarted() will return true afterwards.
|
||||
* isUpdatingEstimates() will return true afterwards.
|
||||
*/
|
||||
void start();
|
||||
void startEstimateUpdates();
|
||||
|
||||
/**
|
||||
* Returns true when propagation has started (start() was called).
|
||||
* Returns true when startEstimateUpdates() was called.
|
||||
*
|
||||
* This is used when the SyncEngine wants to indicate a new sync
|
||||
* is about to start via the transmissionProgress() signal. The
|
||||
* first ProgressInfo will have hasStarted() == false.
|
||||
* first ProgressInfo will have isUpdatingEstimates() == false.
|
||||
*/
|
||||
bool hasStarted() const;
|
||||
bool isUpdatingEstimates() const;
|
||||
|
||||
/**
|
||||
* Increase the file and size totals by the amount indicated in item.
|
||||
|
||||
@@ -654,7 +654,6 @@ static void preserveGroupOwnership(const QString& fileName, const QFileInfo& fi)
|
||||
}
|
||||
} // end namespace
|
||||
|
||||
|
||||
void PropagateDownloadFileQNAM::transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum)
|
||||
{
|
||||
const auto theContentChecksumType = contentChecksumType();
|
||||
|
||||
@@ -97,7 +97,9 @@ void PUTFileJob::start() {
|
||||
}
|
||||
|
||||
void PUTFileJob::slotTimeout() {
|
||||
qDebug() << "Timeout" << reply()->request().url();
|
||||
qDebug() << "Timeout" << (reply() ? reply()->request().url() : path());
|
||||
if (!reply())
|
||||
return;
|
||||
_errorString = tr("Connection Timeout");
|
||||
reply()->abort();
|
||||
}
|
||||
@@ -209,8 +211,6 @@ void PropagateUploadFileQNAM::slotComputeContentChecksum()
|
||||
return;
|
||||
}
|
||||
|
||||
_propagator->_activeJobList.removeOne(this);
|
||||
|
||||
const QString filePath = _propagator->getFilePath(_item->_file);
|
||||
|
||||
// remember the modtime before checksumming to be able to detect a file
|
||||
@@ -234,6 +234,8 @@ void PropagateUploadFileQNAM::slotComputeContentChecksum()
|
||||
|
||||
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
|
||||
SLOT(slotComputeTransmissionChecksum(QByteArray,QByteArray)));
|
||||
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
|
||||
computeChecksum, SLOT(deleteLater()));
|
||||
computeChecksum->start(filePath);
|
||||
}
|
||||
|
||||
@@ -268,12 +270,18 @@ void PropagateUploadFileQNAM::slotComputeTransmissionChecksum(const QByteArray&
|
||||
|
||||
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
|
||||
SLOT(slotStartUpload(QByteArray,QByteArray)));
|
||||
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
|
||||
computeChecksum, SLOT(deleteLater()));
|
||||
const QString filePath = _propagator->getFilePath(_item->_file);
|
||||
computeChecksum->start(filePath);
|
||||
}
|
||||
|
||||
void PropagateUploadFileQNAM::slotStartUpload(const QByteArray& transmissionChecksumType, const QByteArray& transmissionChecksum)
|
||||
{
|
||||
// Remove ourselfs from the list of active job, before any posible call to done()
|
||||
// When we start chunks, we will add it again, once for every chunks.
|
||||
_propagator->_activeJobList.removeOne(this);
|
||||
|
||||
_transmissionChecksum = transmissionChecksum;
|
||||
_transmissionChecksumType = transmissionChecksumType;
|
||||
|
||||
@@ -544,8 +552,16 @@ void PropagateUploadFileQNAM::startNextChunk()
|
||||
_transmissionChecksumType, _transmissionChecksum);
|
||||
}
|
||||
|
||||
if (! device->prepareAndOpen(_propagator->getFilePath(_item->_file), chunkStart, currentChunkSize)) {
|
||||
const QString fileName = _propagator->getFilePath(_item->_file);
|
||||
if (! device->prepareAndOpen(fileName, chunkStart, currentChunkSize)) {
|
||||
qDebug() << "ERR: Could not prepare upload device: " << device->errorString();
|
||||
|
||||
// If the file is currently locked, we want to retry the sync
|
||||
// when it becomes available again.
|
||||
if (FileSystem::isFileLocked(fileName)) {
|
||||
emit _propagator->seenLockedFile(fileName);
|
||||
}
|
||||
|
||||
// Soft error because this is likely caused by the user modifying his files while syncing
|
||||
abortWithError( SyncFileItem::SoftError, device->errorString() );
|
||||
delete device;
|
||||
@@ -763,6 +779,8 @@ void PropagateUploadFileQNAM::slotPutFinished()
|
||||
<< _stopWatch.durationOfLap(QLatin1String("ContentChecksum"))
|
||||
<< _stopWatch.durationOfLap(QLatin1String("TransmissionChecksum"))
|
||||
<< _item->_requestDuration;
|
||||
// The job might stay alive for the whole sync, release this tiny bit of memory.
|
||||
_stopWatch.reset();
|
||||
|
||||
finalize(*_item);
|
||||
}
|
||||
|
||||
@@ -101,10 +101,10 @@ SyncEngine::SyncEngine(AccountPtr account, const QString& localPath,
|
||||
SyncEngine::~SyncEngine()
|
||||
{
|
||||
abort();
|
||||
_excludedFiles.reset();
|
||||
csync_destroy(_csync_ctx);
|
||||
_thread.quit();
|
||||
_thread.wait();
|
||||
_excludedFiles.reset();
|
||||
csync_destroy(_csync_ctx);
|
||||
}
|
||||
|
||||
//Convert an error code from csync to a user readable string.
|
||||
@@ -203,6 +203,12 @@ QString SyncEngine::csyncErrorToString(CSYNC_STATUS err)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the item is in the blacklist.
|
||||
* If it should not be sync'ed because of the blacklist, update the item with the error instruction
|
||||
* and proper error message, and return true.
|
||||
* If the item is not in the blacklist, or the blacklist is stale, return false.
|
||||
*/
|
||||
bool SyncEngine::checkErrorBlacklisting( SyncFileItem &item )
|
||||
{
|
||||
if( !_journal ) {
|
||||
@@ -234,6 +240,9 @@ bool SyncEngine::checkErrorBlacklisting( SyncFileItem &item )
|
||||
} else if( item._modtime != entry._lastTryModtime ) {
|
||||
qDebug() << item._file << " is blacklisted, but has changed mtime!";
|
||||
return false;
|
||||
} else if( item._renameTarget != entry._renameTarget) {
|
||||
qDebug() << item._file << " is blacklisted, but rename target changed from" << entry._renameTarget;
|
||||
return false;
|
||||
}
|
||||
} else if( item._direction == SyncFileItem::Down ) {
|
||||
// download, check the etag.
|
||||
@@ -539,10 +548,10 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
bool directoryEtagUpdate = isDirectory && file->should_update_metadata;
|
||||
bool localMetadataUpdate = !remote && file->should_update_metadata;
|
||||
if (!directoryEtagUpdate) {
|
||||
item->_isDirectory = isDirectory;
|
||||
if (localMetadataUpdate) {
|
||||
// Hack, we want a local metadata update to happen, but only if the
|
||||
// remote tree doesn't ask us to do some kind of propagation.
|
||||
item->_isDirectory = isDirectory;
|
||||
_syncItemMap.insert(key, item);
|
||||
}
|
||||
emit syncItemDiscovered(*item);
|
||||
@@ -571,7 +580,7 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
// An upload of an existing file means that the file was left unchanged on the server
|
||||
// This counts as a NONE for detecting if all the files on the server were changed
|
||||
_hasNoneFiles = true;
|
||||
} else if (!item->_isDirectory) {
|
||||
} else if (!isDirectory) {
|
||||
if (std::difftime(file->modtime, file->other.modtime) < 0) {
|
||||
// We are going back on time
|
||||
_backInTimeFiles++;
|
||||
@@ -673,6 +682,8 @@ void SyncEngine::startSync()
|
||||
_syncRunning = true;
|
||||
_anotherSyncNeeded = false;
|
||||
|
||||
_progressInfo->reset();
|
||||
|
||||
if (!QDir(_localPath).exists()) {
|
||||
// No _tr, it should only occur in non-mirall
|
||||
emit csyncError("Unable to find local sync folder.");
|
||||
@@ -909,7 +920,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||
emit aboutToPropagate(_syncedItems);
|
||||
// it's important to do this before ProgressInfo::start(), to announce start of new sync
|
||||
emit transmissionProgress(*_progressInfo);
|
||||
_progressInfo->start();
|
||||
_progressInfo->startEstimateUpdates();
|
||||
|
||||
// post update phase script: allow to tweak stuff by a custom script in debug mode.
|
||||
if( !qgetenv("OWNCLOUD_POST_UPDATE_SCRIPT").isEmpty() ) {
|
||||
@@ -1244,15 +1255,18 @@ void SyncEngine::checkForPermission()
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* We don't like the idea of renaming behind user's back, as the user may be working with the files */
|
||||
|
||||
if (!sourceOK && !destinationOK) {
|
||||
#ifdef OWNCLOUD_RESTORE_RENAME /* We don't like the idea of renaming behind user's back, as the user may be working with the files */
|
||||
if (!sourceOK && (!destinationOK || isRename)
|
||||
// (not for directory because that's more complicated with the contents that needs to be adjusted)
|
||||
&& !(*it)->_isDirectory) {
|
||||
// Both the source and the destination won't allow move. Move back to the original
|
||||
std::swap((*it)->_file, (*it)->_renameTarget);
|
||||
(*it)->_direction = SyncFileItem::Down;
|
||||
(*it)->_errorString = tr("Move not allowed, item restored");
|
||||
(*it)->_isRestoration = true;
|
||||
qDebug() << "checkForPermission: MOVING BACK" << (*it)->_file;
|
||||
// in case something does wrong, we will not do it next time
|
||||
_journal->avoidRenamesOnNextSync((*it)->_file);
|
||||
} else
|
||||
#endif
|
||||
if (!sourceOK || !destinationOK) {
|
||||
@@ -1365,13 +1379,13 @@ AccountPtr SyncEngine::account() const
|
||||
|
||||
void SyncEngine::abort()
|
||||
{
|
||||
// Sets a flag for the update phase
|
||||
csync_request_abort(_csync_ctx);
|
||||
qDebug() << Q_FUNC_INFO << _discoveryMainThread;
|
||||
// Aborts the discovery phase job
|
||||
if (_discoveryMainThread) {
|
||||
_discoveryMainThread->abort();
|
||||
}
|
||||
// Sets a flag for the update phase
|
||||
csync_request_abort(_csync_ctx);
|
||||
// For the propagator
|
||||
if(_propagator) {
|
||||
_propagator->abort();
|
||||
|
||||
@@ -76,7 +76,6 @@ SyncFileStatusTracker::SyncFileStatusTracker(SyncEngine *syncEngine)
|
||||
SLOT(slotAboutToPropagate(SyncFileItemVector&)));
|
||||
connect(syncEngine, SIGNAL(itemCompleted(const SyncFileItem&, const PropagatorJob&)),
|
||||
SLOT(slotItemCompleted(const SyncFileItem&)));
|
||||
connect(syncEngine, SIGNAL(started()), SLOT(slotClearDirtyPaths()));
|
||||
connect(syncEngine, SIGNAL(started()), SLOT(slotSyncEngineRunningChanged()));
|
||||
connect(syncEngine, SIGNAL(finished(bool)), SLOT(slotSyncEngineRunningChanged()));
|
||||
}
|
||||
@@ -94,9 +93,11 @@ SyncFileItem SyncFileStatusTracker::rootSyncFileItem()
|
||||
|
||||
SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
|
||||
{
|
||||
Q_ASSERT(!relativePath.endsWith(QLatin1Char('/')));
|
||||
// normalization is required for OS X to match file names properly
|
||||
QString normalizedRelativePath = relativePath.normalized(QString::NormalizationForm_C);
|
||||
Q_ASSERT(!normalizedRelativePath.endsWith(QLatin1Char('/')));
|
||||
|
||||
if (relativePath.isEmpty()) {
|
||||
if (normalizedRelativePath.isEmpty()) {
|
||||
// This is the root sync folder, it doesn't have an entry in the database and won't be walked by csync, so create one manually.
|
||||
return syncFileItemStatus(rootSyncFileItem());
|
||||
}
|
||||
@@ -107,22 +108,22 @@ SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath)
|
||||
// update the exclude list at runtime and doing it statically here removes
|
||||
// our ability to notify changes through the fileStatusChanged signal,
|
||||
// it's an acceptable compromize to treat all exclude types the same.
|
||||
if( _syncEngine->excludedFiles().isExcluded(_syncEngine->localPath() + relativePath,
|
||||
if( _syncEngine->excludedFiles().isExcluded(_syncEngine->localPath() + normalizedRelativePath,
|
||||
_syncEngine->localPath(),
|
||||
_syncEngine->ignoreHiddenFiles()) ) {
|
||||
return SyncFileStatus(SyncFileStatus::StatusWarning);
|
||||
}
|
||||
|
||||
if ( _dirtyPaths.contains(relativePath) )
|
||||
if ( _dirtyPaths.contains(normalizedRelativePath) )
|
||||
return SyncFileStatus::StatusSync;
|
||||
|
||||
SyncFileItem* item = _syncEngine->findSyncItem(relativePath);
|
||||
SyncFileItem* item = _syncEngine->findSyncItem(normalizedRelativePath);
|
||||
if (item) {
|
||||
return syncFileItemStatus(*item);
|
||||
}
|
||||
|
||||
// If we're not currently syncing that file, look it up in the database to know if it's shared
|
||||
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(relativePath);
|
||||
SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(normalizedRelativePath);
|
||||
if (rec.isValid()) {
|
||||
return syncFileItemStatus(rec.toSyncFileItem());
|
||||
}
|
||||
@@ -154,9 +155,18 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items)
|
||||
} else if (showWarningInSocketApi(*item)) {
|
||||
_syncProblems[item->_file] = SyncFileStatus::StatusWarning;
|
||||
}
|
||||
_dirtyPaths.remove(item->destination());
|
||||
emit fileStatusChanged(getSystemDestination(item->destination()), syncFileItemStatus(*item));
|
||||
}
|
||||
|
||||
// Some metadata status won't trigger files to be synced, make sure that we
|
||||
// push the OK status for dirty files that don't need to be propagated.
|
||||
// Swap into a copy since fileStatus() reads _dirtyPaths to determine the status
|
||||
QSet<QString> oldDirtyPaths;
|
||||
std::swap(_dirtyPaths, oldDirtyPaths);
|
||||
for (auto it = oldDirtyPaths.begin(); it != oldDirtyPaths.end(); ++it)
|
||||
emit fileStatusChanged(getSystemDestination(*it), fileStatus(*it));
|
||||
|
||||
// Make sure to push any status that might have been resolved indirectly since the last sync
|
||||
// (like an error file being deleted from disk)
|
||||
for (auto it = _syncProblems.begin(); it != _syncProblems.end(); ++it)
|
||||
@@ -191,13 +201,6 @@ void SyncFileStatusTracker::slotSyncEngineRunningChanged()
|
||||
emit fileStatusChanged(_syncEngine->localPath(), syncFileItemStatus(rootSyncFileItem()));
|
||||
}
|
||||
|
||||
void SyncFileStatusTracker::slotClearDirtyPaths()
|
||||
{
|
||||
// We just assume that during a sync all dirty statuses will be resolved
|
||||
// one way or the other.
|
||||
_dirtyPaths.clear();
|
||||
}
|
||||
|
||||
SyncFileStatus SyncFileStatusTracker::syncFileItemStatus(const SyncFileItem& item)
|
||||
{
|
||||
// Hack to know if the item was taken from the sync engine (Sync), or from the database (UpToDate)
|
||||
|
||||
@@ -47,7 +47,6 @@ private slots:
|
||||
void slotAboutToPropagate(SyncFileItemVector& items);
|
||||
void slotItemCompleted(const SyncFileItem& item);
|
||||
void slotSyncEngineRunningChanged();
|
||||
void slotClearDirtyPaths();
|
||||
|
||||
private:
|
||||
SyncFileStatus syncFileItemStatus(const SyncFileItem& item);
|
||||
|
||||
@@ -409,7 +409,7 @@ bool SyncJournalDb::checkConnect()
|
||||
_deleteFileRecordRecursively.reset(new SqlQuery(_db));
|
||||
_deleteFileRecordRecursively->prepare("DELETE FROM metadata WHERE path LIKE(?||'/%')");
|
||||
|
||||
QString sql( "SELECT lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration "
|
||||
QString sql( "SELECT lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration, renameTarget "
|
||||
"FROM blacklist WHERE path=?1");
|
||||
if( Utility::fsCasePreserving() ) {
|
||||
// if the file system is case preserving we have to check the blacklist
|
||||
@@ -421,8 +421,8 @@ bool SyncJournalDb::checkConnect()
|
||||
|
||||
_setErrorBlacklistQuery.reset(new SqlQuery(_db));
|
||||
_setErrorBlacklistQuery->prepare("INSERT OR REPLACE INTO blacklist "
|
||||
"(path, lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration) "
|
||||
"VALUES ( ?1, ?2, ?3, ?4, ?5, ?6, ?7)");
|
||||
"(path, lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration, renameTarget) "
|
||||
"VALUES ( ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)");
|
||||
|
||||
_getSelectiveSyncListQuery.reset(new SqlQuery(_db));
|
||||
_getSelectiveSyncListQuery->prepare("SELECT path FROM selectivesync WHERE type=?1");
|
||||
@@ -612,6 +612,15 @@ bool SyncJournalDb::updateErrorBlacklistTableStructure()
|
||||
}
|
||||
commitInternal("update database structure: add lastTryTime, ignoreDuration cols");
|
||||
}
|
||||
if( columns.indexOf(QLatin1String("renameTarget")) == -1 ) {
|
||||
SqlQuery query(_db);
|
||||
query.prepare("ALTER TABLE blacklist ADD COLUMN renameTarget VARCHAR(4096);");
|
||||
if( !query.exec() ) {
|
||||
sqlFail("updateBlacklistTableStructure: Add renameTarget", query);
|
||||
re = false;
|
||||
}
|
||||
commitInternal("update database structure: add lastTryTime, ignoreDuration cols");
|
||||
}
|
||||
|
||||
SqlQuery query(_db);
|
||||
query.prepare("CREATE INDEX IF NOT EXISTS blacklist_index ON blacklist(path collate nocase);");
|
||||
@@ -1224,6 +1233,7 @@ SyncJournalErrorBlacklistRecord SyncJournalDb::errorBlacklistEntry( const QStrin
|
||||
entry._errorString = _getErrorBlacklistQuery->stringValue(3);
|
||||
entry._lastTryTime = _getErrorBlacklistQuery->int64Value(4);
|
||||
entry._ignoreDuration = _getErrorBlacklistQuery->int64Value(5);
|
||||
entry._renameTarget = _getErrorBlacklistQuery->stringValue(6);
|
||||
entry._file = file;
|
||||
}
|
||||
_getErrorBlacklistQuery->reset_and_clear_bindings();
|
||||
@@ -1335,13 +1345,14 @@ void SyncJournalDb::updateErrorBlacklistEntry( const SyncJournalErrorBlacklistRe
|
||||
_setErrorBlacklistQuery->bindValue(5, item._errorString);
|
||||
_setErrorBlacklistQuery->bindValue(6, QString::number(item._lastTryTime));
|
||||
_setErrorBlacklistQuery->bindValue(7, QString::number(item._ignoreDuration));
|
||||
_setErrorBlacklistQuery->bindValue(8, item._renameTarget);
|
||||
if( !_setErrorBlacklistQuery->exec() ) {
|
||||
QString bug = _setErrorBlacklistQuery->error();
|
||||
qDebug() << "SQL exec blacklistitem insert or replace failed: "<< bug;
|
||||
}
|
||||
qDebug() << "set blacklist entry for " << item._file << item._retryCount
|
||||
<< item._errorString << item._lastTryTime << item._ignoreDuration
|
||||
<< item._lastTryModtime << item._lastTryEtag;
|
||||
<< item._lastTryModtime << item._lastTryEtag << item._renameTarget ;
|
||||
_setErrorBlacklistQuery->reset_and_clear_bindings();
|
||||
|
||||
}
|
||||
|
||||
@@ -151,6 +151,7 @@ SyncJournalErrorBlacklistRecord SyncJournalErrorBlacklistRecord::update(
|
||||
// The factor of 5 feels natural: 25s, 2 min, 10 min, ~1h, ~5h, ~24h
|
||||
entry._ignoreDuration = old._ignoreDuration * 5;
|
||||
entry._file = item._file;
|
||||
entry._renameTarget = item._renameTarget;
|
||||
|
||||
if( item._httpErrorCode == 403 ) {
|
||||
qDebug() << "Probably firewall error: " << item._httpErrorCode << ", blacklisting up to 1h only";
|
||||
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
time_t _ignoreDuration;
|
||||
|
||||
QString _file;
|
||||
QString _renameTarget;
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
|
||||
@@ -310,13 +310,18 @@ namespace {
|
||||
value);
|
||||
}
|
||||
};
|
||||
// QTBUG-3945 and issue #4855: QT_TRANSLATE_NOOP does not work with plural form because lupdate
|
||||
// limitation unless we fake more arguments
|
||||
// (it must be in the form ("context", "source", "comment", n)
|
||||
#undef QT_TRANSLATE_NOOP
|
||||
#define QT_TRANSLATE_NOOP(ctx, str, ...) str
|
||||
Q_DECL_CONSTEXPR Period periods[] = {
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n year(s)") , 365*24*3600*1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n month(s)") , 30*24*3600*1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n day(s)") , 24*3600*1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n hour(s)") , 3600*1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n minute(s)") , 60*1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n second(s)") , 1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n year(s)" , 0, _) , 365*24*3600*1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n month(s)", 0, _) , 30*24*3600*1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n day(s)", 0, _) , 24*3600*1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n hour(s)", 0, _) , 3600*1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n minute(s)", 0, _) , 60*1000LL },
|
||||
{ QT_TRANSLATE_NOOP("Utility", "%n second(s)", 0, _ ), 1000LL },
|
||||
{ 0, 0 }
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <QByteArray>
|
||||
#include <QDateTime>
|
||||
#include <QElapsedTimer>
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
|
||||
namespace OCC {
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace Utility
|
||||
|
||||
class OWNCLOUDSYNC_EXPORT StopWatch {
|
||||
private:
|
||||
QHash<QString, quint64> _lapTimes;
|
||||
QMap<QString, quint64> _lapTimes;
|
||||
QDateTime _startTime;
|
||||
QElapsedTimer _timer;
|
||||
public:
|
||||
|
||||
+233
-225
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+253
-247
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+197
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+197
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+215
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+199
-193
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+197
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+197
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+197
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+197
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+197
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+197
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+197
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+197
-191
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
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