Comparar commits
28 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| f6b35e5d58 | |||
| fc1933803e | |||
| 46e4ec3183 | |||
| 9aed8dbce8 | |||
| 5676685f58 | |||
| db9ccb40a4 | |||
| d4c15d2c38 | |||
| 11b144957b | |||
| 434d16941b | |||
| 3d157cbb02 | |||
| 80b5f3f43d | |||
| 4900703970 | |||
| ecd44f70de | |||
| 9d5307d04c | |||
| 9460aa7f21 | |||
| 6493421109 | |||
| 0052386b41 | |||
| e1909c3bd1 | |||
| 8ce9388d29 | |||
| c13637b105 | |||
| 424bf6f06a | |||
| 46c3c9e0fc | |||
| 85f6c5fda8 | |||
| 74f74e0363 | |||
| bd72408e7a | |||
| a32381a2a4 | |||
| cd83772112 | |||
| 893e22691d |
+1
-1
@@ -3,7 +3,7 @@
|
||||
url = https://github.com/owncloud/documentation
|
||||
[submodule "src/3rdparty/qtmacgoodies"]
|
||||
path = src/3rdparty/qtmacgoodies
|
||||
url = git://github.com/guruz/qtmacgoodies.git
|
||||
url = https://github.com/guruz/qtmacgoodies.git
|
||||
[submodule "binary"]
|
||||
path = binary
|
||||
url = git://github.com/owncloud/owncloud-client-binary.git
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(VERSION 2.8.0)
|
||||
|
||||
@@ -122,6 +123,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()
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ set( MIRALL_VERSION_PATCH 1 )
|
||||
set( MIRALL_SOVERSION 0 )
|
||||
|
||||
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
set( MIRALL_VERSION_SUFFIX "") #e.g. beta1, beta2, rc1
|
||||
set( MIRALL_VERSION_SUFFIX "git") #e.g. beta1, beta2, rc1
|
||||
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
|
||||
if( NOT DEFINED MIRALL_VERSION_BUILD )
|
||||
|
||||
+17
-17
@@ -317,7 +317,7 @@ typedef const char* (*csync_checksum_hook) (
|
||||
*
|
||||
* @param csync The context variable to allocate.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_create(CSYNC **csync, const char *local, const char *remote);
|
||||
|
||||
@@ -328,7 +328,7 @@ int csync_create(CSYNC **csync, const char *local, const char *remote);
|
||||
*
|
||||
* @param ctx The context to initialize.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_init(CSYNC *ctx);
|
||||
|
||||
@@ -337,7 +337,7 @@ int csync_init(CSYNC *ctx);
|
||||
*
|
||||
* @param ctx The context to run the update detection on.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_update(CSYNC *ctx);
|
||||
|
||||
@@ -346,7 +346,7 @@ int csync_update(CSYNC *ctx);
|
||||
*
|
||||
* @param ctx The context to run the reconciliation on.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_reconcile(CSYNC *ctx);
|
||||
|
||||
@@ -355,7 +355,7 @@ int csync_reconcile(CSYNC *ctx);
|
||||
*
|
||||
* @param ctx The context to commit.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_commit(CSYNC *ctx);
|
||||
|
||||
@@ -366,7 +366,7 @@ int csync_commit(CSYNC *ctx);
|
||||
*
|
||||
* @param ctx The context to destroy.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_destroy(CSYNC *ctx);
|
||||
|
||||
@@ -377,7 +377,7 @@ int csync_destroy(CSYNC *ctx);
|
||||
*
|
||||
* @param path The path pointing to the file.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_add_exclude_list(CSYNC *ctx, const char *path);
|
||||
|
||||
@@ -394,7 +394,7 @@ void csync_clear_exclude_list(CSYNC *ctx);
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return The userdata saved in the context, NULL if an error
|
||||
* occured.
|
||||
* occurred.
|
||||
*/
|
||||
void *csync_get_userdata(CSYNC *ctx);
|
||||
|
||||
@@ -406,7 +406,7 @@ void *csync_get_userdata(CSYNC *ctx);
|
||||
*
|
||||
* @param userdata The userdata to be stored in the context.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_set_userdata(CSYNC *ctx, void *userdata);
|
||||
|
||||
@@ -416,7 +416,7 @@ int csync_set_userdata(CSYNC *ctx, void *userdata);
|
||||
* @param ctx The csync context.
|
||||
*
|
||||
* @return The authentication callback set or NULL if an error
|
||||
* occured.
|
||||
* occurred.
|
||||
*/
|
||||
csync_auth_callback csync_get_auth_callback(CSYNC *ctx);
|
||||
|
||||
@@ -427,7 +427,7 @@ csync_auth_callback csync_get_auth_callback(CSYNC *ctx);
|
||||
*
|
||||
* @param cb The authentication callback.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
||||
|
||||
@@ -436,7 +436,7 @@ int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
||||
*
|
||||
* @param[in] level The log verbosity.
|
||||
*
|
||||
* @return 0 on success, < 0 if an error occured.
|
||||
* @return 0 on success, < 0 if an error occurred.
|
||||
*/
|
||||
int csync_set_log_level(int level);
|
||||
|
||||
@@ -451,7 +451,7 @@ int csync_get_log_level(void);
|
||||
* @brief Get the logging callback set.
|
||||
*
|
||||
* @return The logging callback set or NULL if an error
|
||||
* occured.
|
||||
* occurred.
|
||||
*/
|
||||
csync_log_callback csync_get_log_callback(void);
|
||||
|
||||
@@ -460,7 +460,7 @@ csync_log_callback csync_get_log_callback(void);
|
||||
*
|
||||
* @param cb The logging callback.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_set_log_callback(csync_log_callback cb);
|
||||
|
||||
@@ -476,7 +476,7 @@ void *csync_get_log_userdata(void);
|
||||
*
|
||||
* @param[in] data The userdata to set.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_set_log_userdata(void *data);
|
||||
|
||||
@@ -495,7 +495,7 @@ typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
|
||||
* @param visitor A callback function to handle the file info.
|
||||
* @param filter A filter, built from or'ed csync_instructions_e
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||
|
||||
@@ -506,7 +506,7 @@ int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int fi
|
||||
* @param visitor A callback function to handle the file info.
|
||||
* @param filter A filter, built from and'ed csync_instructions_e
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
||||
|
||||
|
||||
@@ -47,6 +47,45 @@ int _csync_exclude_add(c_strlist_t **inList, const char *string) {
|
||||
return c_strlist_add_grow(inList, string);
|
||||
}
|
||||
|
||||
/** Expands C-like escape sequences.
|
||||
*
|
||||
* The returned string is heap-allocated and owned by the caller.
|
||||
*/
|
||||
static const char *csync_exclude_expand_escapes(const char * input)
|
||||
{
|
||||
size_t i_len = strlen(input) + 1;
|
||||
char *out = c_malloc(i_len); // out can only be shorter
|
||||
|
||||
size_t i = 0;
|
||||
size_t o = 0;
|
||||
for (; i < i_len; ++i) {
|
||||
if (input[i] == '\\') {
|
||||
// at worst input[i+1] is \0
|
||||
switch (input[i+1]) {
|
||||
case '\'': out[o++] = '\''; break;
|
||||
case '"': out[o++] = '"'; break;
|
||||
case '?': out[o++] = '?'; break;
|
||||
case '\\': out[o++] = '\\'; break;
|
||||
case 'a': out[o++] = '\a'; break;
|
||||
case 'b': out[o++] = '\b'; break;
|
||||
case 'f': out[o++] = '\f'; break;
|
||||
case 'n': out[o++] = '\n'; break;
|
||||
case 'r': out[o++] = '\r'; break;
|
||||
case 't': out[o++] = '\t'; break;
|
||||
case 'v': out[o++] = '\v'; break;
|
||||
default:
|
||||
out[o++] = input[i];
|
||||
out[o++] = input[i+1];
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
} else {
|
||||
out[o++] = input[i];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
int csync_exclude_load(const char *fname, c_strlist_t **list) {
|
||||
int fd = -1;
|
||||
int i = 0;
|
||||
@@ -99,8 +138,10 @@ int csync_exclude_load(const char *fname, c_strlist_t **list) {
|
||||
if (entry != buf + i) {
|
||||
buf[i] = '\0';
|
||||
if (*entry != '#') {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", entry);
|
||||
rc = _csync_exclude_add(list, 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);
|
||||
SAFE_FREE(unescaped);
|
||||
if (rc < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ int _csync_exclude_add(c_strlist_t **inList, const char *string);
|
||||
* @param ctx The context of the synchronizer.
|
||||
* @param fname The filename to load.
|
||||
*
|
||||
* @return 0 on success, -1 if an error occured with errno set.
|
||||
* @return 0 on success, -1 if an error occurred with errno set.
|
||||
*/
|
||||
int csync_exclude_load(const char *fname, c_strlist_t **list);
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ int csync_get_statedb_exists(CSYNC *ctx);
|
||||
* @param ctx The csync context.
|
||||
* @param statedb Path to the statedb file (sqlite3 db).
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured with errno set.
|
||||
* @return 0 on success, less than 0 if an error occurred with errno set.
|
||||
*/
|
||||
int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb);
|
||||
|
||||
|
||||
+12
-12
@@ -136,7 +136,7 @@ struct c_rbnode_s {
|
||||
* @param data_compare Callback function to compare a key as data with thee
|
||||
* data inside a red-black tree node.
|
||||
*
|
||||
* @return 0 on success, -1 if an error occured with errno set.
|
||||
* @return 0 on success, -1 if an error occurred with errno set.
|
||||
*/
|
||||
int c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_rbtree_compare_func *data_compare);
|
||||
|
||||
@@ -146,7 +146,7 @@ int c_rbtree_create(c_rbtree_t **rbtree, c_rbtree_compare_func *key_compare, c_r
|
||||
* @param tree Tree to duplicate.
|
||||
*
|
||||
* @return Pointer to a new allocated duplicated rbtree. NULL if an error
|
||||
* occured.
|
||||
* occurred.
|
||||
*/
|
||||
c_rbtree_t *c_rbtree_dup(const c_rbtree_t *tree);
|
||||
|
||||
@@ -157,7 +157,7 @@ c_rbtree_t *c_rbtree_dup(const c_rbtree_t *tree);
|
||||
*
|
||||
* @param tree The tree to free.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int c_rbtree_free(c_rbtree_t *tree);
|
||||
|
||||
@@ -198,7 +198,7 @@ int c_rbtree_free(c_rbtree_t *tree);
|
||||
* @param data The data to insert into the tree.
|
||||
*
|
||||
* @return 0 on success, 1 if a duplicate has been found and < 0 if an error
|
||||
* occured with errno set.
|
||||
* occurred with errno set.
|
||||
* EINVAL if a null pointer has been passed as the tree.
|
||||
* ENOMEM if there is no memory left.
|
||||
*/
|
||||
@@ -223,7 +223,7 @@ c_rbnode_t *c_rbtree_find(c_rbtree_t *tree, const void *key);
|
||||
*
|
||||
* @param tree The tree to get the head for.
|
||||
*
|
||||
* @return The head node. NULL if an error occured.
|
||||
* @return The head node. NULL if an error occurred.
|
||||
*/
|
||||
c_rbnode_t *c_rbtree_head(c_rbtree_t *tree);
|
||||
|
||||
@@ -232,7 +232,7 @@ c_rbnode_t *c_rbtree_head(c_rbtree_t *tree);
|
||||
*
|
||||
* @param tree The tree to get the tail for.
|
||||
*
|
||||
* @return The tail node. NULL if an error occured.
|
||||
* @return The tail node. NULL if an error occurred.
|
||||
*/
|
||||
c_rbnode_t *c_rbtree_tail(c_rbtree_t *tree);
|
||||
|
||||
@@ -254,7 +254,7 @@ c_rbnode_t *c_rbtree_tail(c_rbtree_t *tree);
|
||||
* @param data Data which should be passed to the visitor function.
|
||||
* @param visitor Visitor function. This will be called for each node passed.
|
||||
*
|
||||
* @return 0 on sucess, less than 0 if an error occured.
|
||||
* @return 0 on sucess, less than 0 if an error occurred.
|
||||
*/
|
||||
int c_rbtree_walk(c_rbtree_t *tree, void *data, c_rbtree_visit_func *visitor);
|
||||
|
||||
@@ -263,7 +263,7 @@ int c_rbtree_walk(c_rbtree_t *tree, void *data, c_rbtree_visit_func *visitor);
|
||||
*
|
||||
* @param node Node which should be deleted.
|
||||
*
|
||||
* @return 0 on success, -1 if an error occured.
|
||||
* @return 0 on success, -1 if an error occurred.
|
||||
*/
|
||||
int c_rbtree_node_delete(c_rbnode_t *node);
|
||||
|
||||
@@ -272,7 +272,7 @@ int c_rbtree_node_delete(c_rbnode_t *node);
|
||||
*
|
||||
* @param node The node of which you want the next node.
|
||||
*
|
||||
* @return The next node, NULL if an error occured.
|
||||
* @return The next node, NULL if an error occurred.
|
||||
*/
|
||||
c_rbnode_t *c_rbtree_node_next(c_rbnode_t *node);
|
||||
|
||||
@@ -281,7 +281,7 @@ c_rbnode_t *c_rbtree_node_next(c_rbnode_t *node);
|
||||
*
|
||||
* @param node The node of which you want the previous node.
|
||||
*
|
||||
* @return The previous node, NULL if an error occured.
|
||||
* @return The previous node, NULL if an error occurred.
|
||||
*/
|
||||
c_rbnode_t *c_rbtree_node_prev(c_rbnode_t *node);
|
||||
|
||||
@@ -290,7 +290,7 @@ c_rbnode_t *c_rbtree_node_prev(c_rbnode_t *node);
|
||||
*
|
||||
* @param N The node to get the data from.
|
||||
*
|
||||
* @return The data, NULL if an error occured.
|
||||
* @return The data, NULL if an error occurred.
|
||||
*/
|
||||
#define c_rbtree_node_data(N) ((N) ? ((N)->data) : NULL)
|
||||
|
||||
@@ -301,7 +301,7 @@ c_rbnode_t *c_rbtree_node_prev(c_rbnode_t *node);
|
||||
*
|
||||
* @param tree The tree to check.
|
||||
*
|
||||
* @return 0 on success, less than 0 if an error occured.
|
||||
* @return 0 on success, less than 0 if an error occurred.
|
||||
*/
|
||||
int c_rbtree_check_sanity(c_rbtree_t *tree);
|
||||
|
||||
|
||||
@@ -346,6 +346,25 @@ static void check_csync_excluded_performance(void **state)
|
||||
}
|
||||
}
|
||||
|
||||
static void check_csync_exclude_expand_escapes(void **state)
|
||||
{
|
||||
(void)state;
|
||||
|
||||
const char *str = csync_exclude_expand_escapes(
|
||||
"keep \\' \\\" \\? \\\\ \\a \\b \\f \\n \\r \\t \\v \\z");
|
||||
assert_true(0 == strcmp(
|
||||
str, "keep ' \" ? \\ \a \b \f \n \r \t \v \\z"));
|
||||
SAFE_FREE(str);
|
||||
|
||||
str = csync_exclude_expand_escapes("");
|
||||
assert_true(0 == strcmp(str, ""));
|
||||
SAFE_FREE(str);
|
||||
|
||||
str = csync_exclude_expand_escapes("\\");
|
||||
assert_true(0 == strcmp(str, "\\"));
|
||||
SAFE_FREE(str);
|
||||
}
|
||||
|
||||
int torture_run_tests(void)
|
||||
{
|
||||
const UnitTest tests[] = {
|
||||
@@ -356,6 +375,7 @@ int torture_run_tests(void)
|
||||
unit_test_setup_teardown(check_csync_pathes, setup_init, teardown),
|
||||
unit_test_setup_teardown(check_csync_is_windows_reserved_word, setup_init, teardown),
|
||||
unit_test_setup_teardown(check_csync_excluded_performance, setup_init, teardown),
|
||||
unit_test(check_csync_exclude_expand_escapes),
|
||||
};
|
||||
|
||||
return run_tests(tests);
|
||||
|
||||
@@ -87,7 +87,7 @@ To manually override this key, use the same value in ``HKEY_CURRENT_USER``.
|
||||
|
||||
To prevent automatic updates and disallow manual overrides:
|
||||
|
||||
.. note::This is the preferred method of controlling the updater behavior using
|
||||
.. note:: This is the preferred method of controlling the updater behavior using
|
||||
Group Policies.
|
||||
|
||||
1. Edit this Registry key:
|
||||
@@ -98,6 +98,14 @@ To prevent automatic updates and disallow manual overrides:
|
||||
|
||||
3. Specify a value of ``1`` to the machine.
|
||||
|
||||
.. note:: Enterprise branded clients
|
||||
(see `Building Branded ownCloud Clients
|
||||
<https://doc.owncloud.org/branded_clients/>`_) have different key names,
|
||||
which are set in ownBrander using the Application Vendor and Application
|
||||
Name fields. Your key names look like this::
|
||||
|
||||
``HKEY_LOCAL_MACHINE\Software\Policies\myCompanyName\myAppName``
|
||||
|
||||
|
||||
Preventing Automatic Updates in Mac OS X Environments
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
+41
-16
@@ -11,22 +11,44 @@ desktop client.
|
||||
.. note:: Build instructions are subject to change as development proceeds.
|
||||
Please check the version for which you want to build.
|
||||
|
||||
The instructions contained in this topic were updated to work with version 1.7 of the ownCloud Client.
|
||||
These instructions are updated to work with version 2.1 of the ownCloud Client.
|
||||
|
||||
Getting Source Code
|
||||
-------------------
|
||||
|
||||
The :ref:`generic-build-instructions` pull the latest code directly from
|
||||
GitHub, and work on Linux, Mac OS X, and Windows.
|
||||
|
||||
See the next section for instructions on getting source code from Linux
|
||||
packages.
|
||||
|
||||
Linux
|
||||
-----
|
||||
|
||||
1. Add the `ownCloud repository from OBS`_.
|
||||
2. Install the dependencies (as root, or using ``sudo``) using the following
|
||||
commands for your specific Linux distribution:
|
||||
You may wish to use source packages for your Linux distribution, as these give
|
||||
you the exact sources from which the binary packages are built. These are
|
||||
hosted on the `ownCloud repository from OBS`_. Go to the `Index of
|
||||
repositories`_ to see all the Linux client repos.
|
||||
|
||||
1. At the `bottom of the page for each distribution
|
||||
<https://software.opensuse.org/download/package?project=isv:ownCloud:desktop&
|
||||
package=owncloud-client>`_ is a "Grab binary packages directly" section.
|
||||
These contain source RPMs for CentOS, RHEL, Fedora, SLES, and openSUSE.
|
||||
|
||||
To get the .deb source packages add the source
|
||||
repo for your Debian or Ubuntu version, like this example for Debian 8
|
||||
(run as root)::
|
||||
|
||||
echo 'deb-src
|
||||
http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Debian_8.0/ /' >> /etc/apt/sources.list.d/owncloud-client.list
|
||||
|
||||
2. Install the dependencies using the following commands for your specific Linux distribution:
|
||||
|
||||
* Debian/Ubuntu: ``apt-get update; apt-get build-dep owncloud-client``
|
||||
* openSUSE: ``zypper ref; zypper si -d owncloud-client``
|
||||
* Fedora/CentOS: ``yum install yum-utils; yum-builddep owncloud-client``
|
||||
* openSUSE/SLES: ``zypper ref; zypper si -d owncloud-client``
|
||||
* Fedora/CentOS/RHEL: ``yum install yum-utils; yum-builddep owncloud-client``
|
||||
|
||||
3. Follow the :ref:`generic-build-instructions`.
|
||||
|
||||
4. (Optional) Call ``make install`` to install the client to the ``/usr/local/bin`` directory.
|
||||
3. Follow the :ref:`generic-build-instructions`, starting with step 2.
|
||||
|
||||
Mac OS X
|
||||
--------
|
||||
@@ -187,9 +209,7 @@ Compared to previous versions, building the desktop sync client has become easie
|
||||
earlier versions, CSync, which is the sync engine library of the client, is now
|
||||
part of the client source repository and not a separate module.
|
||||
|
||||
You can download the desktop sync client from the ownCloud `Client Download Page`_.
|
||||
|
||||
To build the most up to date version of the client:
|
||||
To build the most up-to-date version of the client:
|
||||
|
||||
1. Clone the latest versions of the client from Git_ as follows::
|
||||
|
||||
@@ -216,6 +236,9 @@ To build the most up to date version of the client:
|
||||
4. Call ``make``.
|
||||
|
||||
The owncloud binary will appear in the ``bin`` directory.
|
||||
|
||||
5. (Optional) Call ``make install`` to install the client to the
|
||||
``/usr/local/bin`` directory.
|
||||
|
||||
The following are known cmake parameters:
|
||||
|
||||
@@ -228,15 +251,17 @@ The following are known cmake parameters:
|
||||
* ``BUILD_WITH_QT4=ON``: Builds using Qt4 (even if Qt5 is found).
|
||||
* ``CMAKE_INSTALL_PREFIX=path``: Set an install prefix. This is mandatory on Mac OS
|
||||
|
||||
.. _`ownCloud repository from OBS`: http://software.opensuse.org/download/package?project=isv:ownCloud:desktop&package=owncloud-client
|
||||
.. _ownCloud repository from OBS: http://software.opensuse.org/download/package?
|
||||
project=isv:ownCloud:desktop&package=owncloud-client
|
||||
.. _CMake: http://www.cmake.org/download
|
||||
.. _CSync: http://www.csync.org
|
||||
.. _`Client Download Page`: http://owncloud.org/sync-clients/
|
||||
.. _Client Download Page: https://owncloud.org/install/#desktop
|
||||
.. _Git: http://git-scm.com
|
||||
.. _MacPorts: http://www.macports.org
|
||||
.. _Homebrew: http://mxcl.github.com/homebrew/
|
||||
.. _`OpenSSL Windows Build`: http://slproweb.com/products/Win32OpenSSL.html
|
||||
.. _OpenSSL Windows Build: http://slproweb.com/products/Win32OpenSSL.html
|
||||
.. _Qt: http://www.qt.io/download
|
||||
.. _`Microsoft Authenticode`: https://msdn.microsoft.com/en-us/library/ie/ms537361%28v=vs.85%29.aspx
|
||||
.. _Microsoft Authenticode: https://msdn.microsoft.com/en-us/library/ie/ms537361%28v=vs.85%29.aspx
|
||||
.. _QtKeychain: https://github.com/frankosterfeld/qtkeychain
|
||||
.. _Packages: http://s.sudre.free.fr/Software/Packages/about.html
|
||||
.. _Index of repositories: http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/
|
||||
|
||||
Arquivo binário não exibido.
|
Antes Largura: | Altura: | Tamanho: 82 KiB Depois Largura: | Altura: | Tamanho: 72 KiB |
Arquivo binário não exibido.
|
Antes Largura: | Altura: | Tamanho: 52 KiB Depois Largura: | Altura: | Tamanho: 86 KiB |
Arquivo binário não exibido.
|
Antes Largura: | Altura: | Tamanho: 99 KiB Depois Largura: | Altura: | Tamanho: 23 KiB |
@@ -22,8 +22,16 @@ Improvements and New Features
|
||||
The 2.1 release of the ownCloud desktop sync client has many new features and
|
||||
improvements. (See the `complete changelog
|
||||
<https://owncloud.org/changelog/desktop/>`_.)
|
||||
|
||||
|
||||
* Improved appearance on HiDPI screens
|
||||
* Improved error messages
|
||||
* Several fixes/improvements to the sharing dialog
|
||||
* Several fixes/improvements to the server activity tab
|
||||
* Allow changeable upload chunk size in owncloud.cfg
|
||||
* Forget password on explicit sign-out
|
||||
* Windows: Fix deleting and replacing of read-only files
|
||||
* Share with internal ownCloud users from your desktop
|
||||
* Separate views for server activity, sync activity, and errors
|
||||
* Don't re-upload *eml-files if size and checksum are unchanged
|
||||
* Improved upload/download progress indicator
|
||||
|
||||
+12
-7
@@ -58,11 +58,12 @@ operations.
|
||||
This menu provides the following options:
|
||||
|
||||
* Quick access to your accounts
|
||||
* Sync status
|
||||
* Recent Changes, showing latest activities
|
||||
* Status of your client version (whether it is up to date)
|
||||
* Settings
|
||||
* Help menu
|
||||
* An option to log in or log out of all of your accounts at once
|
||||
* Quit ownCloud
|
||||
* Quit ownCloud, logging out and closing the client
|
||||
|
||||
A left-click on your systray icon opens the desktop client to the account
|
||||
settings window.
|
||||
@@ -82,7 +83,7 @@ have the following features:
|
||||
* Connection status, showing which ownCloud server you are connected to, and
|
||||
your ownCloud username.
|
||||
* An **Account** button, which contains a dropdown menu with **Add New**,
|
||||
**Sign In/Sign Out**, and **Remove**.
|
||||
**Log In/Log Out**, and **Remove**.
|
||||
* Used and available space on the server.
|
||||
* Current synchronization status.
|
||||
* **Add Folder Sync Connection** button, which is active only when you have
|
||||
@@ -124,10 +125,12 @@ button, and re-select the folder tree that you want to sync.
|
||||
Adding New Accounts
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You may configure multiple ownCloud accounts in your desktop sync client. Simply
|
||||
You may configure multiple ownCloud accounts in your desktop sync client.
|
||||
Simply
|
||||
click the **Account** > **Add New** button on any account tab to add a new
|
||||
account, and then follow the account creation wizard. The new account will
|
||||
appear as a new tab in the settings dialog, where you can adjust its settings at
|
||||
appear as a new tab in the settings dialog, where you can adjust its settings
|
||||
at
|
||||
any time. Use **Account** > **Remove** to delete accounts.
|
||||
|
||||
Sharing From Your Desktop
|
||||
@@ -206,10 +209,12 @@ can use the *Ignored Files Editor* (General tab.)
|
||||
|
||||
.. figure:: images/ignored_files_editor.png
|
||||
|
||||
For your convenience, the editor is pre-populated with a default list of typical
|
||||
For your convenience, the editor is pre-populated with a default list of
|
||||
typical
|
||||
ignore patterns. These patterns are contained in a system file (typically
|
||||
``sync-exclude.lst``) located in the ownCloud Client application directory. You
|
||||
cannot modify these pre-populated patterns directly from the editor. However, if
|
||||
cannot modify these pre-populated patterns directly from the editor. However,
|
||||
if
|
||||
necessary, you can hover over any pattern in the list to show the path and
|
||||
filename associated with that pattern, locate the file, and edit the
|
||||
``sync-exclude.lst`` file.
|
||||
|
||||
@@ -249,7 +249,7 @@ void SelectiveSyncTreeView::slotLscolFinishedWithError(QNetworkReply *r)
|
||||
if (r->error() == QNetworkReply::ContentNotFoundError) {
|
||||
_loading->setText(tr("No subfolders currently on the server."));
|
||||
} else {
|
||||
_loading->setText(tr("An error occured while loading the list of sub folders."));
|
||||
_loading->setText(tr("An error occurred while loading the list of sub folders."));
|
||||
}
|
||||
_loading->resize(_loading->sizeHint()); // because it's not in a layout
|
||||
}
|
||||
|
||||
@@ -545,7 +545,7 @@ SyncJournalFileRecord SocketApi::dbFileRecord_capi( Folder *folder, QString file
|
||||
rec._fileId = query->baValue(4);
|
||||
rec._remotePerm = query->baValue(5);
|
||||
}
|
||||
query->reset();
|
||||
query->reset_and_clear_bindings();
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ void ConnectionValidator::checkAuthentication()
|
||||
job->setTimeout(timeoutToUseMsec);
|
||||
job->setProperties(QList<QByteArray>() << "getlastmodified");
|
||||
connect(job, SIGNAL(result(QVariantMap)), SLOT(slotAuthSuccess()));
|
||||
connect(job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotAuthFailed(QNetworkReply*)));
|
||||
connect(job, SIGNAL(finishedWithError(QNetworkReply*)), SLOT(slotAuthFailed(QNetworkReply*)));
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
@@ -558,7 +558,7 @@ bool PropfindJob::finished()
|
||||
} else {
|
||||
qDebug() << "PROPFIND request *not* successful, http result code is" << http_result_code
|
||||
<< (http_result_code == 302 ? reply()->header(QNetworkRequest::LocationHeader).toString() : QLatin1String(""));
|
||||
emit finishedWithError();
|
||||
emit finishedWithError(reply());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
|
||||
signals:
|
||||
void result(const QVariantMap &values);
|
||||
void finishedWithError();
|
||||
void finishedWithError(QNetworkReply *reply = 0);
|
||||
|
||||
private slots:
|
||||
virtual bool finished() Q_DECL_OVERRIDE;
|
||||
|
||||
@@ -300,8 +300,7 @@ void SqlQuery::bindValue(int pos, const QVariant& value)
|
||||
res = sqlite3_bind_text16(_stmt, pos, str->utf16(),
|
||||
(str->size()) * sizeof(QChar), SQLITE_TRANSIENT);
|
||||
} else {
|
||||
// unbound value create a null entry.
|
||||
res = SQLITE_OK;
|
||||
res = sqlite3_bind_null(_stmt, pos);
|
||||
}
|
||||
break; }
|
||||
default: {
|
||||
@@ -365,9 +364,10 @@ void SqlQuery::finish()
|
||||
_stmt = 0;
|
||||
}
|
||||
|
||||
void SqlQuery::reset()
|
||||
void SqlQuery::reset_and_clear_bindings()
|
||||
{
|
||||
SQLITE_DO(sqlite3_reset(_stmt));
|
||||
SQLITE_DO(sqlite3_clear_bindings(_stmt));
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
void bindValue(int pos, const QVariant& value);
|
||||
QString lastQuery() const;
|
||||
int numRowsAffected();
|
||||
void reset();
|
||||
void reset_and_clear_bindings();
|
||||
void finish();
|
||||
|
||||
private:
|
||||
|
||||
@@ -543,12 +543,20 @@ void PropagateDownloadFileQNAM::slotGetFinished()
|
||||
return;
|
||||
}
|
||||
|
||||
if (_tmpFile.size() == 0 && _item->_size > 0) {
|
||||
FileSystem::remove(_tmpFile.fileName());
|
||||
done(SyncFileItem::NormalError,
|
||||
tr("The downloaded file is empty despite the server announced it should have been %1.")
|
||||
.arg(Utility::octetsToString(_item->_size)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Do checksum validation for the download. If there is no checksum header, the validator
|
||||
// will also emit the validated() signal to continue the flow in slot downloadFinished()
|
||||
// will also emit the validated() signal to continue the flow in slot transmissionChecksumValidated()
|
||||
// as this is (still) also correct.
|
||||
ValidateChecksumHeader *validator = new ValidateChecksumHeader(this);
|
||||
connect(validator, SIGNAL(validated(QByteArray,QByteArray)),
|
||||
SLOT(downloadFinished()));
|
||||
SLOT(transmissionChecksumValidated(QByteArray,QByteArray)));
|
||||
connect(validator, SIGNAL(validationFailed(QString)),
|
||||
SLOT(slotChecksumFail(QString)));
|
||||
auto checksumHeader = job->reply()->rawHeader(checkSumHeaderC);
|
||||
@@ -636,6 +644,35 @@ static void handleRecallFile(const QString &fn)
|
||||
}
|
||||
} // end namespace
|
||||
|
||||
void PropagateDownloadFileQNAM::transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum)
|
||||
{
|
||||
const auto theContentChecksumType = QByteArray("SHA1");
|
||||
|
||||
// Reuse transmission checksum as content checksum.
|
||||
//
|
||||
// We could do this more aggressively and accept both MD5 and SHA1
|
||||
// instead of insisting on the exactly correct checksum type.
|
||||
if (theContentChecksumType == checksumType || theContentChecksumType.isEmpty()) {
|
||||
return contentChecksumComputed(checksumType, checksum);
|
||||
}
|
||||
|
||||
// Compute the content checksum.
|
||||
auto computeChecksum = new ComputeChecksum(this);
|
||||
computeChecksum->setChecksumType(theContentChecksumType);
|
||||
|
||||
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
|
||||
SLOT(contentChecksumComputed(QByteArray,QByteArray)));
|
||||
computeChecksum->start(_tmpFile.fileName());
|
||||
}
|
||||
|
||||
void PropagateDownloadFileQNAM::contentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum)
|
||||
{
|
||||
_item->_contentChecksum = checksum;
|
||||
_item->_contentChecksumType = checksumType;
|
||||
|
||||
downloadFinished();
|
||||
}
|
||||
|
||||
void PropagateDownloadFileQNAM::downloadFinished()
|
||||
{
|
||||
QString fn = _propagator->getFilePath(_item->_file);
|
||||
|
||||
@@ -128,6 +128,8 @@ public:
|
||||
private slots:
|
||||
void slotGetFinished();
|
||||
void abort() Q_DECL_OVERRIDE;
|
||||
void transmissionChecksumValidated(const QByteArray& checksumType, const QByteArray& checksum);
|
||||
void contentChecksumComputed(const QByteArray& checksumType, const QByteArray& checksum);
|
||||
void downloadFinished();
|
||||
void slotDownloadProgress(qint64,qint64);
|
||||
void slotChecksumFail( const QString& errMsg );
|
||||
|
||||
@@ -160,6 +160,10 @@ void PropagateRemoteMove::finalize()
|
||||
record._path = _item->_renameTarget;
|
||||
record._contentChecksum = oldRecord._contentChecksum;
|
||||
record._contentChecksumType = oldRecord._contentChecksumType;
|
||||
if (record._fileSize != oldRecord._fileSize) {
|
||||
qDebug() << "Warning: file sizes differ on server vs csync_journal: " << record._fileSize << oldRecord._fileSize;
|
||||
record._fileSize = oldRecord._fileSize; // server might have claimed different size, we take the old one from the DB
|
||||
}
|
||||
|
||||
_propagator->_journal->setFileRecord(record);
|
||||
_propagator->_journal->commit("Remote Rename");
|
||||
|
||||
@@ -222,8 +222,9 @@ void PropagateUploadFileQNAM::slotComputeContentChecksum()
|
||||
QByteArray contentChecksumType;
|
||||
// We currently only do content checksums for the particular .eml case
|
||||
// This should be done more generally in the future!
|
||||
if (filePath.endsWith(QLatin1String(".eml"), Qt::CaseInsensitive)) {
|
||||
contentChecksumType = "MD5";
|
||||
if (filePath.endsWith(QLatin1String(".eml"), Qt::CaseInsensitive)
|
||||
|| filePath.endsWith(QLatin1String(".msg"), Qt::CaseInsensitive)) {
|
||||
contentChecksumType = "SHA1";
|
||||
}
|
||||
|
||||
// Maybe the discovery already computed the checksum?
|
||||
|
||||
@@ -183,6 +183,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 ) {
|
||||
@@ -214,6 +220,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.
|
||||
@@ -494,6 +503,8 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
// Even if the mtime is different on the server, we always want to keep the mtime from
|
||||
// the file system in the DB, this is to avoid spurious upload on the next sync
|
||||
item->_modtime = file->other.modtime;
|
||||
// same for the size
|
||||
item->_size = file->other.size;
|
||||
|
||||
// If the 'W' remote permission changed, update the local filesystem
|
||||
SyncJournalFileRecord prev = _journal->getFileRecord(item->_file);
|
||||
@@ -523,6 +534,8 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
item->_isDirectory = isDirectory;
|
||||
_syncItemMap.insert(key, item);
|
||||
}
|
||||
item->_isDirectory = isDirectory;
|
||||
emit syncItemDiscovered(*item);
|
||||
return re;
|
||||
}
|
||||
break;
|
||||
@@ -1040,8 +1053,17 @@ void SyncEngine::checkForPermission()
|
||||
(*it)->_status = SyncFileItem::NormalError;
|
||||
(*it)->_errorString = tr("Not allowed because you don't have permission to add subfolders to that folder");
|
||||
|
||||
for (SyncFileItemVector::iterator it_next = it + 1; it_next != _syncedItems.end() && (*it_next)->_file.startsWith(path); ++it_next) {
|
||||
for (SyncFileItemVector::iterator it_next = it + 1; it_next != _syncedItems.end() && (*it_next)->destination().startsWith(path); ++it_next) {
|
||||
it = it_next;
|
||||
if ((*it)->_instruction == CSYNC_INSTRUCTION_RENAME) {
|
||||
// The file was most likely moved in this directory.
|
||||
// If the file was read only or could not be moved or removed, it should
|
||||
// be restored. Do that in the next sync by not considering as a rename
|
||||
// but delete and upload. It will then be restored if needed.
|
||||
_journal->avoidRenamesOnNextSync((*it)->_file);
|
||||
_anotherSyncNeeded = true;
|
||||
qDebug() << "Moving of " << (*it)->_file << " canceled because no permission to add parent folder";
|
||||
}
|
||||
(*it)->_instruction = CSYNC_INSTRUCTION_ERROR;
|
||||
(*it)->_status = SyncFileItem::NormalError;
|
||||
(*it)->_errorString = tr("Not allowed because you don't have permission to add parent folder");
|
||||
@@ -1170,15 +1192,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) {
|
||||
|
||||
@@ -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,22 @@ 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);");
|
||||
if( !query.exec()) {
|
||||
sqlFail("updateErrorBlacklistTableStructure: create index blacklit", query);
|
||||
re = false;
|
||||
}
|
||||
|
||||
return re;
|
||||
}
|
||||
@@ -686,7 +702,7 @@ bool SyncJournalDb::setFileRecord( const SyncJournalFileRecord& _record )
|
||||
QString remotePerm (record._remotePerm);
|
||||
if (remotePerm.isEmpty()) remotePerm = QString(); // have NULL in DB (vs empty)
|
||||
int contentChecksumTypeId = mapChecksumType(record._contentChecksumType);
|
||||
_setFileRecordQuery->reset();
|
||||
_setFileRecordQuery->reset_and_clear_bindings();
|
||||
_setFileRecordQuery->bindValue(1, QString::number(phash));
|
||||
_setFileRecordQuery->bindValue(2, plen);
|
||||
_setFileRecordQuery->bindValue(3, record._path );
|
||||
@@ -715,7 +731,7 @@ bool SyncJournalDb::setFileRecord( const SyncJournalFileRecord& _record )
|
||||
<< record._etag << record._fileId << record._remotePerm << record._fileSize << (record._serverHasIgnoredFiles ? 1:0)
|
||||
<< record._contentChecksum << record._contentChecksumType << contentChecksumTypeId;
|
||||
|
||||
_setFileRecordQuery->reset();
|
||||
_setFileRecordQuery->reset_and_clear_bindings();
|
||||
return true;
|
||||
} else {
|
||||
qDebug() << "Failed to connect database.";
|
||||
@@ -732,7 +748,7 @@ bool SyncJournalDb::deleteFileRecord(const QString& filename, bool recursively)
|
||||
// always delete the actual file.
|
||||
|
||||
qlonglong phash = getPHash(filename);
|
||||
_deleteFileRecordPhash->reset();
|
||||
_deleteFileRecordPhash->reset_and_clear_bindings();
|
||||
_deleteFileRecordPhash->bindValue( 1, QString::number(phash) );
|
||||
|
||||
if( !_deleteFileRecordPhash->exec() ) {
|
||||
@@ -742,9 +758,9 @@ bool SyncJournalDb::deleteFileRecord(const QString& filename, bool recursively)
|
||||
return false;
|
||||
}
|
||||
qDebug() << _deleteFileRecordPhash->lastQuery() << phash << filename;
|
||||
_deleteFileRecordPhash->reset();
|
||||
_deleteFileRecordPhash->reset_and_clear_bindings();
|
||||
if( recursively) {
|
||||
_deleteFileRecordRecursively->reset();
|
||||
_deleteFileRecordRecursively->reset_and_clear_bindings();
|
||||
_deleteFileRecordRecursively->bindValue(1, filename);
|
||||
if( !_deleteFileRecordRecursively->exec() ) {
|
||||
qWarning() << "Exec error of SQL statement: "
|
||||
@@ -753,7 +769,7 @@ bool SyncJournalDb::deleteFileRecord(const QString& filename, bool recursively)
|
||||
return false;
|
||||
}
|
||||
qDebug() << _deleteFileRecordRecursively->lastQuery() << filename;
|
||||
_deleteFileRecordRecursively->reset();
|
||||
_deleteFileRecordRecursively->reset_and_clear_bindings();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
@@ -771,7 +787,7 @@ SyncJournalFileRecord SyncJournalDb::getFileRecord( const QString& filename )
|
||||
SyncJournalFileRecord rec;
|
||||
|
||||
if( checkConnect() ) {
|
||||
_getFileRecordQuery->reset();
|
||||
_getFileRecordQuery->reset_and_clear_bindings();
|
||||
_getFileRecordQuery->bindValue(1, QString::number(phash));
|
||||
|
||||
if (!_getFileRecordQuery->exec()) {
|
||||
@@ -801,7 +817,7 @@ SyncJournalFileRecord SyncJournalDb::getFileRecord( const QString& filename )
|
||||
QString err = _getFileRecordQuery->error();
|
||||
qDebug() << "No journal entry found for " << filename;
|
||||
}
|
||||
_getFileRecordQuery->reset();
|
||||
_getFileRecordQuery->reset_and_clear_bindings();
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
@@ -900,7 +916,7 @@ bool SyncJournalDb::updateFileRecordChecksum(const QString& filename,
|
||||
int checksumTypeId = mapChecksumType(contentChecksumType);
|
||||
auto & query = _setFileRecordChecksumQuery;
|
||||
|
||||
query->reset();
|
||||
query->reset_and_clear_bindings();
|
||||
query->bindValue(1, QString::number(phash));
|
||||
query->bindValue(2, contentChecksum);
|
||||
query->bindValue(3, checksumTypeId);
|
||||
@@ -915,7 +931,7 @@ bool SyncJournalDb::updateFileRecordChecksum(const QString& filename,
|
||||
qDebug() << query->lastQuery() << phash << contentChecksum
|
||||
<< contentChecksumType << checksumTypeId;
|
||||
|
||||
query->reset();
|
||||
query->reset_and_clear_bindings();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -957,7 +973,7 @@ static bool deleteBatch(SqlQuery & query, const QStringList & entries, const QSt
|
||||
qDebug() << "Removing stale " << qPrintable(name) << " entries: " << entries.join(", ");
|
||||
// FIXME: Was ported from execBatch, check if correct!
|
||||
foreach( const QString& entry, entries ) {
|
||||
query.reset();
|
||||
query.reset_and_clear_bindings();
|
||||
query.bindValue(1, entry);
|
||||
if (!query.exec()) {
|
||||
QString err = query.error();
|
||||
@@ -966,7 +982,7 @@ static bool deleteBatch(SqlQuery & query, const QStringList & entries, const QSt
|
||||
return false;
|
||||
}
|
||||
}
|
||||
query.reset(); // viel hilft viel ;-)
|
||||
query.reset_and_clear_bindings(); // viel hilft viel ;-)
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -978,7 +994,7 @@ SyncJournalDb::DownloadInfo SyncJournalDb::getDownloadInfo(const QString& file)
|
||||
DownloadInfo res;
|
||||
|
||||
if( checkConnect() ) {
|
||||
_getDownloadInfoQuery->reset();
|
||||
_getDownloadInfoQuery->reset_and_clear_bindings();
|
||||
_getDownloadInfoQuery->bindValue(1, file);
|
||||
|
||||
if (!_getDownloadInfoQuery->exec()) {
|
||||
@@ -992,7 +1008,7 @@ SyncJournalDb::DownloadInfo SyncJournalDb::getDownloadInfo(const QString& file)
|
||||
} else {
|
||||
res._valid = false;
|
||||
}
|
||||
_getDownloadInfoQuery->reset();
|
||||
_getDownloadInfoQuery->reset_and_clear_bindings();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -1006,7 +1022,7 @@ void SyncJournalDb::setDownloadInfo(const QString& file, const SyncJournalDb::Do
|
||||
}
|
||||
|
||||
if (i._valid) {
|
||||
_setDownloadInfoQuery->reset();
|
||||
_setDownloadInfoQuery->reset_and_clear_bindings();
|
||||
_setDownloadInfoQuery->bindValue(1, file);
|
||||
_setDownloadInfoQuery->bindValue(2, i._tmpfile);
|
||||
_setDownloadInfoQuery->bindValue(3, i._etag );
|
||||
@@ -1018,10 +1034,10 @@ void SyncJournalDb::setDownloadInfo(const QString& file, const SyncJournalDb::Do
|
||||
}
|
||||
|
||||
qDebug() << _setDownloadInfoQuery->lastQuery() << file << i._tmpfile << i._etag << i._errorCount;
|
||||
_setDownloadInfoQuery->reset();
|
||||
_setDownloadInfoQuery->reset_and_clear_bindings();
|
||||
|
||||
} else {
|
||||
_deleteDownloadInfoQuery->reset();
|
||||
_deleteDownloadInfoQuery->reset_and_clear_bindings();
|
||||
_deleteDownloadInfoQuery->bindValue( 1, file );
|
||||
|
||||
if( !_deleteDownloadInfoQuery->exec() ) {
|
||||
@@ -1029,7 +1045,7 @@ void SyncJournalDb::setDownloadInfo(const QString& file, const SyncJournalDb::Do
|
||||
return;
|
||||
}
|
||||
qDebug() << _deleteDownloadInfoQuery->lastQuery() << file;
|
||||
_deleteDownloadInfoQuery->reset();
|
||||
_deleteDownloadInfoQuery->reset_and_clear_bindings();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1097,7 +1113,7 @@ SyncJournalDb::UploadInfo SyncJournalDb::getUploadInfo(const QString& file)
|
||||
|
||||
if( checkConnect() ) {
|
||||
|
||||
_getUploadInfoQuery->reset();
|
||||
_getUploadInfoQuery->reset_and_clear_bindings();
|
||||
_getUploadInfoQuery->bindValue(1, file);
|
||||
|
||||
if (!_getUploadInfoQuery->exec()) {
|
||||
@@ -1115,7 +1131,7 @@ SyncJournalDb::UploadInfo SyncJournalDb::getUploadInfo(const QString& file)
|
||||
res._modtime = Utility::qDateTimeFromTime_t(_getUploadInfoQuery->int64Value(4));
|
||||
res._valid = ok;
|
||||
}
|
||||
_getUploadInfoQuery->reset();
|
||||
_getUploadInfoQuery->reset_and_clear_bindings();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -1129,7 +1145,7 @@ void SyncJournalDb::setUploadInfo(const QString& file, const SyncJournalDb::Uplo
|
||||
}
|
||||
|
||||
if (i._valid) {
|
||||
_setUploadInfoQuery->reset();
|
||||
_setUploadInfoQuery->reset_and_clear_bindings();
|
||||
_setUploadInfoQuery->bindValue(1, file);
|
||||
_setUploadInfoQuery->bindValue(2, i._chunk);
|
||||
_setUploadInfoQuery->bindValue(3, i._transferid );
|
||||
@@ -1143,9 +1159,9 @@ void SyncJournalDb::setUploadInfo(const QString& file, const SyncJournalDb::Uplo
|
||||
}
|
||||
|
||||
qDebug() << _setUploadInfoQuery->lastQuery() << file << i._chunk << i._transferid << i._errorCount;
|
||||
_setUploadInfoQuery->reset();
|
||||
_setUploadInfoQuery->reset_and_clear_bindings();
|
||||
} else {
|
||||
_deleteUploadInfoQuery->reset();
|
||||
_deleteUploadInfoQuery->reset_and_clear_bindings();
|
||||
_deleteUploadInfoQuery->bindValue(1, file);
|
||||
|
||||
if( !_deleteUploadInfoQuery->exec() ) {
|
||||
@@ -1153,7 +1169,7 @@ void SyncJournalDb::setUploadInfo(const QString& file, const SyncJournalDb::Uplo
|
||||
return;
|
||||
}
|
||||
qDebug() << _deleteUploadInfoQuery->lastQuery() << file;
|
||||
_deleteUploadInfoQuery->reset();
|
||||
_deleteUploadInfoQuery->reset_and_clear_bindings();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1196,7 +1212,7 @@ SyncJournalErrorBlacklistRecord SyncJournalDb::errorBlacklistEntry( const QStrin
|
||||
// SELECT lastTryEtag, lastTryModtime, retrycount, errorstring
|
||||
|
||||
if( checkConnect() ) {
|
||||
_getErrorBlacklistQuery->reset();
|
||||
_getErrorBlacklistQuery->reset_and_clear_bindings();
|
||||
_getErrorBlacklistQuery->bindValue( 1, file );
|
||||
if( _getErrorBlacklistQuery->exec() ){
|
||||
if( _getErrorBlacklistQuery->next() ) {
|
||||
@@ -1206,9 +1222,10 @@ 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();
|
||||
_getErrorBlacklistQuery->reset_and_clear_bindings();
|
||||
} else {
|
||||
qWarning() << "Exec error blacklist: " << _getErrorBlacklistQuery->lastQuery() << " : "
|
||||
<< _getErrorBlacklistQuery->error();
|
||||
@@ -1317,14 +1334,15 @@ 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;
|
||||
_setErrorBlacklistQuery->reset();
|
||||
<< item._lastTryModtime << item._lastTryEtag << item._renameTarget ;
|
||||
_setErrorBlacklistQuery->reset_and_clear_bindings();
|
||||
|
||||
}
|
||||
|
||||
@@ -1395,7 +1413,7 @@ QStringList SyncJournalDb::getSelectiveSyncList(SyncJournalDb::SelectiveSyncList
|
||||
return result;
|
||||
}
|
||||
|
||||
_getSelectiveSyncListQuery->reset();
|
||||
_getSelectiveSyncListQuery->reset_and_clear_bindings();
|
||||
_getSelectiveSyncListQuery->bindValue(1, int(type));
|
||||
if (!_getSelectiveSyncListQuery->exec()) {
|
||||
qWarning() << "SQL query failed: "<< _getSelectiveSyncListQuery->error();
|
||||
@@ -1427,7 +1445,7 @@ void SyncJournalDb::setSelectiveSyncList(SyncJournalDb::SelectiveSyncListType ty
|
||||
|
||||
SqlQuery insQuery("INSERT INTO selectivesync VALUES (?1, ?2)" , _db);
|
||||
foreach(const auto &path, list) {
|
||||
insQuery.reset();
|
||||
insQuery.reset_and_clear_bindings();
|
||||
insQuery.bindValue(1, path);
|
||||
insQuery.bindValue(2, int(type));
|
||||
if (!insQuery.exec()) {
|
||||
@@ -1519,7 +1537,7 @@ QByteArray SyncJournalDb::getChecksumType(int checksumTypeId)
|
||||
|
||||
// Retrieve the id
|
||||
auto & query = *_getChecksumTypeQuery;
|
||||
query.reset();
|
||||
query.reset_and_clear_bindings();
|
||||
query.bindValue(1, checksumTypeId);
|
||||
if( !query.exec() ) {
|
||||
qWarning() << "Error SQL statement getChecksumType: "
|
||||
@@ -1542,7 +1560,7 @@ int SyncJournalDb::mapChecksumType(const QByteArray& checksumType)
|
||||
}
|
||||
|
||||
// Ensure the checksum type is in the db
|
||||
_insertChecksumTypeQuery->reset();
|
||||
_insertChecksumTypeQuery->reset_and_clear_bindings();
|
||||
_insertChecksumTypeQuery->bindValue(1, checksumType);
|
||||
if( !_insertChecksumTypeQuery->exec() ) {
|
||||
qWarning() << "Error SQL statement insertChecksumType: "
|
||||
@@ -1552,7 +1570,7 @@ int SyncJournalDb::mapChecksumType(const QByteArray& checksumType)
|
||||
}
|
||||
|
||||
// Retrieve the id
|
||||
_getChecksumTypeIdQuery->reset();
|
||||
_getChecksumTypeIdQuery->reset_and_clear_bindings();
|
||||
_getChecksumTypeIdQuery->bindValue(1, checksumType);
|
||||
if( !_getChecksumTypeIdQuery->exec() ) {
|
||||
qWarning() << "Error SQL statement getChecksumTypeId: "
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ QByteArray Utility::userAgentString()
|
||||
{
|
||||
QString re = QString::fromLatin1("Mozilla/5.0 (%1) mirall/%2")
|
||||
.arg(platform())
|
||||
.arg(QLatin1String(MIRALL_STRINGIFY(MIRALL_VERSION)));
|
||||
.arg(QLatin1String(MIRALL_VERSION_STRING));
|
||||
|
||||
QLatin1String appName(APPLICATION_SHORTNAME);
|
||||
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário