1
0
mirror of https://github.com/chylex/Nextcloud-Desktop.git synced 2026-04-07 01:34:16 +02:00

Compare commits

..

100 Commits

Author SHA1 Message Date
Olivier Goffart
d62deabf9b Fix updating mtime
Fixup commit 9193286fc1
Use the right URL for the PROPPATCH and HEAD, do not let other
jobs start when we wait for the UpdateMTimeAndETagJob
Update the etag and the fileid of the real item.
2014-04-30 10:24:17 +02:00
Jenkins for ownCloud
47c23dae30 [tx-robot] updated from transifex 2014-04-30 01:26:47 -04:00
Markus Goetz
3bf15541c6 Add set_csync_file_locked_or_open_ext
Without using function, there were problems with DLL import/export
2014-04-29 18:37:34 +02:00
Markus Goetz
876de8fd69 Networkjobs: Remove stray include 2014-04-29 17:55:26 +02:00
Olivier Goffart
983f9c5dde The job restore job need to be run with QMetaObject::invoke
Because the job might be in a different thread.
2014-04-29 16:58:24 +02:00
Olivier Goffart
9193286fc1 Support old server which do not have the x-oc-mtime support
Owncloud 4.5
Or owncloud 5 with chunking

Fixes https://github.com/owncloud/core/issues/8392
2014-04-29 16:58:24 +02:00
Olivier Goffart
1b8d11182b Add missing include
This was required so the compiler sees the declaration of
CredentialsFactory::create which should be exported
2014-04-29 16:04:24 +02:00
Olivier Goffart
dcc5c105eb fix forward declaration of CredentialsFactory::create 2014-04-29 15:50:19 +02:00
Klaas Freitag
64b42333b0 Fix typo. 2014-04-29 15:36:13 +02:00
Olivier Goffart
3ee729bc4a Add export macro to all classes that need to be exported 2014-04-29 15:31:14 +02:00
Daniel Molkentin
a268b03990 Try to not have windows stay-on-top 2014-04-29 15:31:03 +02:00
Klaas Freitag
6471a45a8a Added changelog beta1 -> beta2 2014-04-29 14:46:17 +02:00
Klaas Freitag
7c27638f36 Set release suffix to beta2 2014-04-29 14:09:43 +02:00
Olivier Goffart
0bffdfb256 Fix compiler warnings, and be less spammy in the log 2014-04-29 12:30:13 +02:00
Olivier Goffart
9f0848ba15 Merge remote-tracking branch 'origin/libowncloudsync_noqtgui' 2014-04-29 12:23:15 +02:00
Olivier Goffart
f159b028b4 Add a compile option to not blacklist error code 5xx 2014-04-29 11:39:46 +02:00
Olivier Goffart
7e702778a1 Add missing line break 2014-04-29 11:27:31 +02:00
Markus Goetz
4489a56c65 Csync: Set error at correct place 2014-04-28 17:25:18 +02:00
Markus Goetz
7f752c7e93 Csync: Plug code for csync_file_locked_or_open 2014-04-28 16:57:56 +02:00
Markus Goetz
b39359c929 Csync: Add hook for checking if a file is in use already 2014-04-28 14:18:58 +02:00
Klaas Freitag
b42d3ced15 Another fix for make install on MacOSX 2014-04-28 11:19:25 +02:00
Klaas Freitag
1c73a8d4ad Fix installation for MacOSX 2014-04-28 10:24:12 +02:00
Daniel Molkentin
2d3ea59755 Limit the mac workaround to the Mac OS X platform 2014-04-28 10:13:53 +02:00
Jenkins for ownCloud
b8b064836c [tx-robot] updated from transifex 2014-04-28 02:07:38 -04:00
Jenkins for ownCloud
3ab1330f63 [tx-robot] updated from transifex 2014-04-28 01:26:40 -04:00
Jenkins for ownCloud
ab711ddc36 [tx-robot] updated from transifex 2014-04-27 02:06:35 -04:00
Jenkins for ownCloud
2a1e67e587 [tx-robot] updated from transifex 2014-04-27 01:25:42 -04:00
Jenkins for ownCloud
1d3febe053 [tx-robot] updated from transifex 2014-04-26 01:25:42 -04:00
Olivier Goffart
165e35c750 t1.pl: change assertLocalAndRemoteDir so we actually test something 2014-04-25 14:35:20 +02:00
Olivier Goffart
9da261acd8 Do not read from the database when upgrading from 1.5
We need to make sure that the file id are updated (if the user
had upgraded from owncloud 5 to owncloud 6 while using owncloud 1.5)
2014-04-25 13:31:44 +02:00
Jenkins for ownCloud
7544f4d367 [tx-robot] updated from transifex 2014-04-25 02:06:36 -04:00
Jenkins for ownCloud
a29a56bce8 [tx-robot] updated from transifex 2014-04-25 01:25:42 -04:00
Olivier Goffart
642c16b09b Missing EXPORT 2014-04-24 23:57:42 +02:00
Olivier Goffart
5c92c190f0 Add EXPORT macro to owncloudsync library
Not all the class are exported currently, only the one that seems to be used
by the command line tools
2014-04-24 23:45:20 +02:00
Olivier Goffart
cc7826e087 Add a compile option to disable renaming when the extension changes
This is only used for a very specific server that do not support
changing the extension of files without re-uploading the file.

Since the change is small and self contained, it is guarded by a #ifdef

(Removed old BLACKLIST_ON_ERROR option that is no longer in use)
2014-04-24 11:51:48 +02:00
Jenkins for ownCloud
a154656311 [tx-robot] updated from transifex 2014-04-24 01:25:45 -04:00
hefee
9b7a3d00ee Using QFile::decodeName instead of QLatin1String 2014-04-23 18:59:40 +02:00
Sandro Knauß
1d862b77af merged 1.5 into master 2014-04-23 18:54:49 +02:00
Klaas Freitag
888843e655 Removed another file for Jenkins. 2014-04-23 13:22:06 +02:00
Klaas Freitag
28970393f6 Removed a test file as jenkins fails on it. 2014-04-23 13:18:28 +02:00
Klaas Freitag
1af7dc952c Update to latest GNUInstallDirs cmake module
This version correctly detects debians multiarch lib handling and
lets us remove the manually set CMAKE_LIB_INSTALL_DIRS from the rules
file.
2014-04-23 13:04:16 +02:00
Jenkins for ownCloud
62dcfe85e4 [tx-robot] updated from transifex 2014-04-23 01:25:49 -04:00
Markus Goetz
f6711b2842 CMake: Find libraries also on Win host compile 2014-04-22 21:02:08 +02:00
Olivier Goffart
f2519e9d87 Fix function signature: pass argument by const reference 2014-04-22 19:52:09 +02:00
Markus Goetz
94f380c1f0 Updater: Ignore files matching with CSYNC_CONFLICT_FILE_USERNAME 2014-04-22 17:05:59 +02:00
Markus Goetz
197d180cb9 Propagator: Add support for CSYNC_CONFLICT_FILE_USERNAME 2014-04-22 16:17:49 +02:00
Markus Goetz
4be20db670 Propagator: Add makeConflictFileName function 2014-04-22 16:07:18 +02:00
Olivier Goffart
46d6191bc2 Also list folder for which the alias starts with '.'
Fixes #1695
2014-04-22 14:26:08 +02:00
Olivier Goffart
ee22f377af Start the folder watcher when new folder are added
Before, we would only set up a file system watcher when we read the
config at startup.  But we also need to do it in the other case when
the user configure new folder to watch
2014-04-22 14:15:43 +02:00
Olivier Goffart
44a04227f1 Update dynamically the error message in the account settings
This let the error be shown when the conneciton is missing at startup

And also remove the red background when there is no longer an error
2014-04-22 14:08:37 +02:00
Olivier Goffart
707c6fcc5d An abort on the reply is not usually a password error.
Copy the code from HTTPCredidentials
2014-04-22 12:52:13 +02:00
Olivier Goffart
edb1f61241 Fix compilation without the BUILD_ONLY_LIBRARIES mode 2014-04-22 12:44:01 +02:00
Olivier Goffart
3fac5f91c8 In case of error, report the right error instead of missing etag
also, missing etag is not a fatal error
2014-04-22 12:43:38 +02:00
Olivier Goffart
1338c08622 Fix compilation on linux with BUILD_LIBRARIES_ONLY 2014-04-22 11:33:38 +02:00
Olivier Goffart
0cf8091705 Merge pull request #1700 from wakeup/master
Fix non-closed p tag
2014-04-22 10:08:29 +02:00
Klaas Freitag
521373f075 More specific log output. 2014-04-22 09:33:07 +02:00
Klaas Freitag
c24732f641 More debugable code. 2014-04-22 09:33:07 +02:00
Jenkins for ownCloud
655188d7b3 [tx-robot] updated from transifex 2014-04-22 01:25:41 -04:00
Markus Goetz
77ac092975 WiP: Attempt to compile without UI 2014-04-21 19:57:15 +02:00
Volkan Gezer
78e5e4ab66 Fix non-closed p tag 2014-04-21 15:29:42 +02:00
Jenkins for ownCloud
934eda128b [tx-robot] updated from transifex 2014-04-21 01:27:00 -04:00
Daniel Molkentin
ece41921ff Merge pull request #1697 from wakeup/master
Space fix
2014-04-20 15:44:03 +02:00
Volkan Gezer
9b71643c1c Space fix 2014-04-20 14:54:40 +02:00
Jenkins for ownCloud
ed48b4bbf2 [tx-robot] updated from transifex 2014-04-20 01:26:54 -04:00
Olivier Goffart
b08284e4cc Fix the background check job for the connection
We can't use the quota job for that as it needs the credidentials and therefore
may re-enter the credidential code when we are currently trying to fetch the credentials.

The quotainfo.cpp part of this patch is basically a revert of d836b80153
2014-04-19 09:49:52 +02:00
Jenkins for ownCloud
4731b506e5 [tx-robot] updated from transifex 2014-04-19 01:27:02 -04:00
Olivier Goffart
7d3b0fe0c5 Fix memory leak: Don't need to call strdup here
The other_node outlive the trav structure, so we can just use the same pointer
2014-04-18 19:16:10 +02:00
Olivier Goffart
fa38bf7029 Make sure the fileid are saved to the database when upgrading from owncloud5 to owncloud6
We fetch the id from the server, but don't save them in the database.

I Could have used INSTRUCTION_UPDATED for that, but then i would need to update the
reconcile algorithm to take in account the fact that UPDATED is possible there.

Instead, use should_update_etag  which means the db is going to be written again

Remove reference to old instruction _UPDATED and _DELETED which does not make sens with
the new propagator

Improve the test to test this case,  and that etags are properly writen to the DB
when there is a fake conflict
2014-04-18 18:27:27 +02:00
Olivier Goffart
bfdf638334 Add the files required by the tests.
Somehow they got removed with all the moving and merging.
Especially kernelcrash.txt is required for t1.pl
2014-04-18 17:20:42 +02:00
Jenkins for ownCloud
e6664c7790 [tx-robot] updated from transifex 2014-04-17 15:03:55 -04:00
Mr. Jenkins
a90779910a [tx-robot] updated from transifex 2014-04-17 01:26:53 -04:00
Mr. Jenkins
edc7a9596a [tx-robot] updated from transifex 2014-04-16 01:26:58 -04:00
Volkan Gezer
a7a19fad71 Fix note template label 2014-04-16 03:53:37 +02:00
Klaas Freitag
d143044f4a Add missing cases to avoid "unknown action" under some circumstances.
Most of the translations are not used because they translate pre
propagation states.

Fixes #1674
2014-04-15 16:54:49 +02:00
Klaas Freitag
aee7515d42 Do not dereference the _engine member variable without check.
This can cause the crash because the _engine member is deleted in the
sync finished slot. The solution is to store the stopWatch object
before the engine is destroyed.

Fixes bug #1675
2014-04-15 16:28:18 +02:00
Klaas Freitag
82ab5fdcb9 Fix condition if network limit change is logged or not. 2014-04-15 16:28:18 +02:00
Klaas Freitag
4c6e6f6302 Add initialisations for member variables.
Avoids some valgrind warnings.
2014-04-15 16:28:18 +02:00
Klaas Freitag
0a2791270a Add a reset method. 2014-04-15 16:28:18 +02:00
Klaas Freitag
c920f81562 Add braces. 2014-04-15 16:28:18 +02:00
Mr. Jenkins
9dcbafc307 [tx-robot] updated from transifex 2014-04-15 01:26:01 -04:00
Daniel Molkentin
d836b80153 Fix reconnect after server disconnect
Fixes #1679
Fixes #1568
Fixes #1659
2014-04-14 17:51:57 +02:00
Daniel Molkentin
efc4ff4d88 Fix redirects in CheckServerJob 2014-04-14 15:12:38 +02:00
Daniel Molkentin
dc043b5765 Try scheme://host/owncloud if scheme://host/ did not work
Fixes #1680
2014-04-14 15:10:08 +02:00
Daniel Molkentin
ef9a318cd9 AbstractNetworkJob Allow finished() to defer Job deletion
This allows to reuse the Job
2014-04-14 15:08:43 +02:00
Mr. Jenkins
9f4ffd44d6 [tx-robot] updated from transifex 2014-04-14 01:25:55 -04:00
Mr. Jenkins
598bfe6d1a [tx-robot] updated from transifex 2014-04-13 01:25:56 -04:00
Mr. Jenkins
5f37c7b1b8 [tx-robot] updated from transifex 2014-04-12 01:26:00 -04:00
Volkan Gezer
8250fb81b3 Fix typo. 2014-04-11 15:10:47 +02:00
Klaas Freitag
30a14b9f45 Install ocsync library to private lib directory, use rpath to find it. 2014-04-11 13:28:11 +02:00
Mr. Jenkins
b0734f2791 [tx-robot] updated from transifex 2014-04-11 01:25:58 -04:00
Mr. Jenkins
d66b0910c6 [tx-robot] updated from transifex 2014-04-10 01:26:05 -04:00
Klaas Freitag
09e05392bf Ignore all sync log files in the sync dir. 2014-04-09 22:02:28 +02:00
Daniel Molkentin
d3d202de68 Fix dataLocation on Linux/BSD
From the Qt 5 documentation:

  Note: when porting QDesktopServices::DataLocation(obsolete)
        to QStandardPaths::DataLocation, a different path will
        be returned.

        QDesktopServices::DataLocation was GenericDataLocation
        + "/data/organization/application", while
        QStandardPaths::DataLocation is GenericDataLocation
        + "/organization/application".

We'll resort to the deprecated version, since we'll need to fix
data locations to be XDG compliant sooner than later anyway
(currently scheduled for 1.8)
2014-04-09 14:59:08 +02:00
Daniel Molkentin
87010fbe1a SSL Button: Fix issues around printing Hash sums
- Use SHA 265 instead of obsolete MD5 where possible (Qt5)
- Remove <tt> formatting: that simply looked ugly
- Wrap SHA 265 hash
- Use spaces as separators

As usual, the default needs to remain ':' separation, because
it's needed to pass valid hashes to csync.
2014-04-09 14:30:51 +02:00
Jenkins for ownCloud
f302da81b1 [tx-robot] updated from transifex 2014-04-09 02:07:10 -04:00
Mr. Jenkins
3af53f5984 [tx-robot] updated from transifex 2014-04-09 01:26:26 -04:00
Klaas Freitag
08dd9796d1 HACK to avoid continuation: See task #1448
We do not know the _modtime from the server, at this point, so just set
the current one.  (rather than the one locally)
2014-04-04 10:50:40 +02:00
Sandro Knauß
47274f1075 Merge remote-tracking branch 'respect-XDG_CONFIG_HOME' into 1.5 2014-03-21 17:20:15 +01:00
Markus Goetz
f72e1cc837 Log: Don't override level for csync
The level shall be set from Folder or owncloudCmd only.
2014-03-21 13:52:35 +01:00
hefee
4e0496f74d respect XDG_CONFIG_HOME for getting user config dir.
Under linux the XDG Base Directory Specification define different
enviroment variables where to store what.
2013-12-31 02:10:44 +01:00
115 changed files with 8072 additions and 6893 deletions

View File

@@ -85,6 +85,14 @@ endif()
# this option creates only libocsync and libowncloudsync
option(BUILD_LIBRARIES_ONLY "BUILD_LIBRARIES_ONLY" OFF)
# When this option is enabled, 5xx errors are not added to the clacklist
# Normaly you don't want to enable this option because if a particular file
# trigger a bug on the server, you want the file to be blacklisted.
option(OWNCLOUD_5XX_NO_BLACKLIST "OWNCLOUD_5XX_NO_BLACKLIST" OFF)
if(OWNCLOUD_5XX_NO_BLACKLIST)
add_definitions(-DOWNCLOUD_5XX_NO_BLACKLIST=1)
endif()
#### find libs
#find_package(Qt4 4.7.0 COMPONENTS QtCore QtGui QtXml QtNetwork QtTest QtWebkit REQUIRED )
#if( UNIX AND NOT APPLE ) # Fdo notifications

View File

@@ -1,6 +1,18 @@
ChangeLog
=========
version 1.6.0 (release 2014-04- )
* Minor GUI improvements
* Qt5 compile issues fixed
* Ignore sync log file in filewatcher
* Install libocsync to private library dir and use rpath to localize
* Fix reconnect after server disconnect
* Fix crashes
* Fix "unknown action" display in Activity window
* Fix memory leaks
* Respect XDG_CONFIG_HOME environment var
* Handle empty fileids in the journal correctly
* Add abilility to compile libowncloudsync without GUI dependendy
* Job-based change propagation, enables faster parallel up/downloads
(right now only if no bandwidth limit is set and no proxy is used)
* Significantly reduced CPU load when checking for local and remote changes

View File

@@ -4,7 +4,7 @@ set( MIRALL_VERSION_PATCH 0 )
set( MIRALL_SOVERSION 0 )
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
set( MIRALL_VERSION_SUFFIX "beta1" ) #e.g. beta1, beta2, rc1
set( MIRALL_VERSION_SUFFIX "beta2" ) #e.g. beta1, beta2, rc1
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
if( NOT DEFINED MIRALL_VERSION_BUILD )

View File

@@ -1,17 +1,18 @@
# Auto-generated - do not modify
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Kiadási jegyzetek megtekintése"
StrCpy $PageReinstall_NEW_Field_2 "Eltávolítás telepítés előtt"
StrCpy $PageReinstall_NEW_Field_3 "Ne távolítsa el"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Már telepítve"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Válaszd ki, hogy szeretnéd telepíteni a következő alkalmazást ${APPLICATION_NAME}."
StrCpy $PageReinstall_SAME_Field_2 "Komponens hozzáadása/újratelepítése"
StrCpy $PageReinstall_SAME_Field_3 "Eltávolitani ${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "Eltávolitani ${APPLICATION_NAME}"
StrCpy $PageReinstall_SAME_Field_3 "${APPLICATION_NAME} eltávolítása"
StrCpy $UNINSTALLER_APPDATA_TITLE "${APPLICATION_NAME} eltávolítása"
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Igen, törölje ezt az adatkönyvtárat."
StrCpy $UNINSTALLER_FINISHED_Detail "Befejezve"
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Show release notes"
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Killing ${APPLICATION_EXECUTABLE} processes."
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Process to kill not found!"
StrCpy $PageReinstall_NEW_Field_1 "An older version of ${APPLICATION_NAME} is installed on your system. It is recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
StrCpy $PageReinstall_NEW_Field_2 "Uninstall before installing"
StrCpy $PageReinstall_NEW_Field_3 "Do not uninstall"
StrCpy $PageReinstall_OLD_Field_1 "A newer version of ${APPLICATION_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it is better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.\r\nSelect the operation you want to perform and click Next to continue."
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Choose the maintenance option to perform."
@@ -29,7 +30,6 @@ StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Quick Launch shortcut for ${APPLICA
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Remove ${APPLICATION_NAME}'s data folder from your computer."
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Do you want to delete ${APPLICATION_NAME}'s data folder?"
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Leave unchecked to keep the data folder for later use or check to delete the data folder."
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Yes, delete this data folder."
StrCpy $UNINSTALLER_FILE_Detail "Writing Uninstaller"
StrCpy $UNINSTALLER_REGISTRY_Detail "Writing Installer Registry Keys"
StrCpy $UNINSTALL_MESSAGEBOX "It does not appear that ${APPLICATION_NAME} is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?"

View File

@@ -1,6 +1,6 @@
# Auto-generated - do not modify
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostra le note di rilascio"
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Trovati ${APPLICATION_EXECUTABLE} processi che dovrebbero essere fermati.$\nVuoi che il programma di installazione li fermi per te?"
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Trovati ${APPLICATION_EXECUTABLE} processi che dovrebbero essere fermati.$\nVuoi che il programma di installazione li fermi al posto tuo?"
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Sto terminando ${APPLICATION_EXECUTABLE} processi."
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Il processo da terminare non è stato trovato!"
StrCpy $PageReinstall_NEW_Field_1 "Una versione più datata di ${APPLICATION_NAME} è installata sul tuo sistema. Si consiglia di disinstallare la versione attuale prima di installare. Seleziona l'operazione da eseguire e fai clic su Avanti per continuare."

View File

@@ -0,0 +1,44 @@
# Auto-generated - do not modify
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Mostrar notas de la versión"
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Parando el proceso ${APPLICATION_EXECUTABLE}."
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Proceso a detener no encontrado!"
StrCpy $PageReinstall_NEW_Field_1 "Una versión anterior de ${APPLICATION_NAME} esta instalada en el sistema. Es recomendado que quite esta versión antes de instalar. Elija la operación a realizar y seleccione Siguiente para continuar."
StrCpy $PageReinstall_NEW_Field_2 "Des-instale antes de Instalar."
StrCpy $PageReinstall_NEW_Field_3 "No des-instalar."
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Actualmente Instalado."
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Elija como desea instalar ${APPLICATION_NAME}."
StrCpy $PageReinstall_OLD_Field_1 "Una versión mas reciente de ${APPLICATION_NAME} esta actualmente instalada! No es recomendado que instale una versión antigua. Si realmente desea instalar esta versión obsoleta, es mejor que des-instale la versión actual primero. Seleccione la operación que desea realizar y presione en Siguiente para continuar. "
StrCpy $PageReinstall_SAME_Field_2 "Agregar/Re-Instalar componentes"
StrCpy $PageReinstall_SAME_Field_3 "Des-instalar ${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "Des-instalar ${APPLICATION_NAME}"
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Elija la opción de mantenimiento a realizar."
StrCpy $SEC_APPLICATION_DETAILS "Instalar esenciales ${APPLICATION_NAME}."
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Acceso Directo en Menú de Programas"
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Agregando el Acceso Directo al Menú de Inicio para ${APPLICATION_NAME}."
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Acceso directo en Escritorio"
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Creando Accesos Directos en Escritorio"
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "Acceso directo de ${APPLICATION_NAME}"
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Acceso Directo al Escritorio para ${APPLICATION_NAME}."
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Quitar la carpeta de datos ${APPLICATION_NAME} de la computadora."
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Desea borrar la carpeta de datos de ${APPLICATION_NAME}?"
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Dejar des-tildado para mantener la carpeta de datos para posterior uso o tildar para borrar la carpeta de datos."
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Si, eliminar esta carpeta de datos."
StrCpy $UNINSTALLER_FILE_Detail "Escribiendo Des-Instalador."
StrCpy $UNINSTALLER_REGISTRY_Detail "Escribiendo claves de Registro del Instalador"
StrCpy $UNINSTALLER_FINISHED_Detail "Terminado"
StrCpy $UNINSTALL_ABORT "Des-instalación abortada por el usuario"
StrCpy $INIT_NO_DESKTOP "Acceso Directo en Escritorio (Sobrescribe existentes)"
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Este instalador requiere acceso Administrador, intente de nuevo. "
StrCpy $INIT_INSTALLER_RUNNING "El instalador ya esta corriendo."
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Este des-instalador requiere acceso administrador, intente de nuevo"
StrCpy $INIT_UNINSTALLER_RUNNING "El des-instalador ya esta corriendo"
StrCpy $SectionGroup_Shortcuts "Accesos Directos"
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Found ${APPLICATION_EXECUTABLE} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?"
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} is already installed.\r\nSelect the operation you want to perform and click Next to continue."
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Quick Launch Shortcut"
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Creating Quick Launch Shortcut"
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} essentials."
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Quick Launch shortcut for ${APPLICATION_NAME}."
StrCpy $UNINSTALL_MESSAGEBOX "It does not appear that ${APPLICATION_NAME} is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?"
StrCpy $INIT_NO_QUICK_LAUNCH "Quick Launch Shortcut (N/A)"
StrCpy $UAC_ERROR_ELEVATE "Unable to elevate, error:"

View File

@@ -36,9 +36,9 @@ StrCpy $UNINSTALL_MESSAGEBOX "Det verkar inte som ${APPLICATION_NAME} är instal
StrCpy $UNINSTALL_ABORT "Avinstallering avbröts av användare"
StrCpy $INIT_NO_QUICK_LAUNCH "Snabbstartsgenväg (N/A)"
StrCpy $INIT_NO_DESKTOP "Skrivbordsgenväg (skriver över nuvarande)"
StrCpy $UAC_ERROR_ELEVATE "Kunde inte få förhöjda rättigheter, fel:"
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Detta installationsprogram kräver adminstratörs rättigheter, försök igen"
StrCpy $INIT_INSTALLER_RUNNING "Installationsprogrammet körs redan."
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Detta avinstallationsprogram kräver administratörs rättigheter, försök igen"
StrCpy $INIT_UNINSTALLER_RUNNING "Avinstallationsprogrammet körs redan."
StrCpy $SectionGroup_Shortcuts "Genvägar"
StrCpy $UAC_ERROR_ELEVATE "Unable to elevate, error:"

View File

@@ -3,6 +3,7 @@
!insertmacro MUI_LANGUAGE "Estonian"
!insertmacro MUI_LANGUAGE "Turkish"
!insertmacro MUI_LANGUAGE "Slovenian"
!insertmacro MUI_LANGUAGE "SpanishInternational"
!insertmacro MUI_LANGUAGE "Dutch"
!insertmacro MUI_LANGUAGE "Hungarian"
!insertmacro MUI_LANGUAGE "French"

View File

@@ -31,7 +31,7 @@ HINTS
find_library(NEON_LIBRARIES
NAMES
neon
neon neon-27
HINTS
${_NEON_LIBDIR}
${CMAKE_INSTALL_LIBDIR}

View File

@@ -30,7 +30,7 @@ find_path(SQLITE3_INCLUDE_DIR
find_library(SQLITE3_LIBRARY
NAMES
sqlite3
sqlite3 sqlite3-0
PATHS
${_SQLITE3_LIBDIR}
)

View File

@@ -1,32 +1,49 @@
# - Define GNU standard installation directories
#.rst:
# GNUInstallDirs
# --------------
#
# Define GNU standard installation directories
#
# Provides install directory variables as defined for GNU software:
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
#
# ::
#
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
#
# Inclusion of this module defines the following variables:
# CMAKE_INSTALL_<dir> - destination for files of a given type
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
#
# ::
#
# CMAKE_INSTALL_<dir> - destination for files of a given type
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
#
# where <dir> is one of:
# BINDIR - user executables (bin)
# SBINDIR - system admin executables (sbin)
# LIBEXECDIR - program executables (libexec)
# SYSCONFDIR - read-only single-machine data (etc)
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
# LOCALSTATEDIR - modifiable single-machine data (var)
# LIBDIR - object code libraries (lib or lib64)
# INCLUDEDIR - C header files (include)
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
# DATAROOTDIR - read-only architecture-independent data root (share)
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
# INFODIR - info documentation (DATAROOTDIR/info)
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
# MANDIR - man documentation (DATAROOTDIR/man)
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
# install() commands for the corresponding file type. If the includer does
# not define a value the above-shown default will be used and the value will
# appear in the cache for editing by the user.
# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
# from the corresponding destination by prepending (if necessary) the value
# of CMAKE_INSTALL_PREFIX.
#
# ::
#
# BINDIR - user executables (bin)
# SBINDIR - system admin executables (sbin)
# LIBEXECDIR - program executables (libexec)
# SYSCONFDIR - read-only single-machine data (etc)
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
# LOCALSTATEDIR - modifiable single-machine data (var)
# LIBDIR - object code libraries (lib or lib64 or lib/<multiarch-tuple> on Debian)
# INCLUDEDIR - C header files (include)
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
# DATAROOTDIR - read-only architecture-independent data root (share)
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
# INFODIR - info documentation (DATAROOTDIR/info)
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
# MANDIR - man documentation (DATAROOTDIR/man)
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
#
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION
# options of install() commands for the corresponding file type. If the
# includer does not define a value the above-shown default will be used
# and the value will appear in the cache for editing by the user. Each
# CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
# from the corresponding destination by prepending (if necessary) the
# value of CMAKE_INSTALL_PREFIX.
#=============================================================================
# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
@@ -68,30 +85,90 @@ if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
endif()
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
# We check if the variable was manually set and not cached, in order to
# allow projects to set the values as normal variables before including
# GNUInstallDirs to avoid having the entries cached or user-editable. It
# replaces the "if(NOT DEFINED CMAKE_INSTALL_XXX)" checks in all the
# other cases.
# If CMAKE_INSTALL_LIBDIR is defined, if _libdir_set is false, then the
# variable is a normal one, otherwise it is a cache one.
get_property(_libdir_set CACHE CMAKE_INSTALL_LIBDIR PROPERTY TYPE SET)
if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set
AND DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX
AND NOT "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" STREQUAL "${CMAKE_INSTALL_PREFIX}"))
# If CMAKE_INSTALL_LIBDIR is not defined, it is always executed.
# Otherwise:
# * if _libdir_set is false it is not executed (meaning that it is
# not a cache variable)
# * if _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX is not defined it is
# not executed
# * if _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX and
# CMAKE_INSTALL_PREFIX are the same string it is not executed.
# _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX is updated after the
# execution, of this part of code, therefore at the next inclusion
# of the file, CMAKE_INSTALL_LIBDIR is defined, and the 2 strings
# are equal, meaning that the if is not executed the code the
# second time.
set(_LIBDIR_DEFAULT "lib")
# Override this default 'lib' with 'lib64' iff:
# - we are on Linux system but NOT cross-compiling
# - we are NOT on debian
# - we are on a 64 bits system
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
# Note that the future of multi-arch handling may be even
# more complicated than that: http://wiki.debian.org/Multiarch
if(CMAKE_SYSTEM_NAME MATCHES "Linux"
AND NOT CMAKE_CROSSCOMPILING
AND NOT EXISTS "/etc/debian_version")
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
message(AUTHOR_WARNING
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
"Please enable at least one language before including GNUInstallDirs.")
else()
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(_LIBDIR_DEFAULT "lib64")
# For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
# CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
# and CMAKE_INSTALL_PREFIX is "/usr"
# See http://wiki.debian.org/Multiarch
if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX)
set(__LAST_LIBDIR_DEFAULT "lib")
# __LAST_LIBDIR_DEFAULT is the default value that we compute from
# _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX, not a cache entry for
# the value that was last used as the default.
# This value is used to figure out whether the user changed the
# CMAKE_INSTALL_LIBDIR value manually, or if the value was the
# default one. When CMAKE_INSTALL_PREFIX changes, the value is
# updated to the new default, unless the user explicitly changed it.
endif()
if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
AND NOT CMAKE_CROSSCOMPILING)
if (EXISTS "/etc/debian_version") # is this a debian system ?
if(CMAKE_LIBRARY_ARCHITECTURE)
if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX
AND "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
set(__LAST_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
endif()
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
message(AUTHOR_WARNING
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
"Please enable at least one language before including GNUInstallDirs.")
else()
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(_LIBDIR_DEFAULT "lib64")
if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX)
set(__LAST_LIBDIR_DEFAULT "lib64")
endif()
endif()
endif()
endif()
endif()
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
elseif(DEFINED __LAST_LIBDIR_DEFAULT
AND "${__LAST_LIBDIR_DEFAULT}" STREQUAL "${CMAKE_INSTALL_LIBDIR}")
set_property(CACHE CMAKE_INSTALL_LIBDIR PROPERTY VALUE "${_LIBDIR_DEFAULT}")
endif()
endif()
# Save for next run
set(_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE INTERNAL "CMAKE_INSTALL_PREFIX during last run")
unset(_libdir_set)
unset(__LAST_LIBDIR_DEFAULT)
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")

View File

@@ -11,13 +11,15 @@ endif( BUILD_WITH_QT4 )
if( Qt5Core_FOUND )
message(STATUS "Found Qt5 core, checking for further dependencies...")
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Quick REQUIRED)
find_package(Qt5PrintSupport REQUIRED)
find_package(Qt5WebKit REQUIRED)
find_package(Qt5Network REQUIRED)
find_package(Qt5Xml REQUIRED)
find_package(Qt5WebKitWidgets REQUIRED)
if(NOT TOKEN_AUTH_ONLY)
find_package(Qt5WebKitWidgets REQUIRED)
find_package(Qt5WebKit REQUIRED)
find_package(Qt5PrintSupport REQUIRED)
find_package(Qt5Quick REQUIRED)
find_package(Qt5Widgets REQUIRED)
endif()
if(APPLE)
find_package(Qt5MacExtras REQUIRED)
endif(APPLE)
@@ -37,23 +39,27 @@ if( Qt5Core_FOUND )
include_directories(${Qt5DBus_INCLUDES})
add_definitions(${Qt5DBus_DEFINITIONS})
endif (WITH_DBUS)
include_directories(${Qt5Widgets_INCLUDES})
add_definitions(${Qt5Widgets_DEFINITIONS})
include_directories(${Qt5Core_INCLUDES})
add_definitions(${Qt5Core_DEFINITIONS})
if (NOT WIN32) #implied on Win32
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif(NOT WIN32)
# set(CMAKE_CXX_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
if(APPLE)
if(APPLE AND NOT TOKEN_AUTH_ONLY)
include_directories(${Qt5MacExtras_INCLUDE_DIRS})
add_definitions(${Qt5MacExtras_DEFINITIONS})
set (QT_LIBRARIES ${QT_LIBRARIES} ${Qt5MacExtras_LIBRARIES})
endif(APPLE)
endif()
if(NOT BUILD_LIBRARIES_ONLY)
macro(qt_wrap_ui)
qt5_wrap_ui(${ARGN})
endmacro()
else()
# hack
SET(QT_UIC_EXECUTABLE "")
endif()
macro(qt_add_resources)
qt5_add_resources(${ARGN})

View File

@@ -44,11 +44,10 @@ if(HAVE_ICONV AND WITH_ICONV)
list(APPEND CSYNC_LINK_LIBRARIES ${ICONV_LIBRARIES})
endif()
set(BLACKLIST_ON_ERROR 0 CACHE BOOL
"If an errors occurs three times on the same file, do not attempt to process that file any further.")
if(BLACKLIST_ON_ERROR)
add_definitions(-DBLACKLIST_ON_ERROR)
# Specific option for builds tied to servers that do not support renaming extensions
set(NO_RENAME_EXTENSION 0 CACHE BOOL "Do not issue rename if the extension changes")
if(NO_RENAME_EXTENSION)
add_definitions(-DNO_RENAME_EXTENSION)
endif()
set(csync_SRCS
@@ -110,17 +109,29 @@ set_target_properties(
SOVERSION
${LIBRARY_SOVERSION}
)
INSTALL(
if(BUILD_OWNCLOUD_OSX_BUNDLE)
INSTALL(
TARGETS
${CSYNC_LIBRARY}
LIBRARY DESTINATION
${LIB_INSTALL_DIR}
ARCHIVE DESTINATION
${LIB_INSTALL_DIR}
RUNTIME DESTINATION
${BIN_INSTALL_DIR}
)
else()
INSTALL(
TARGETS
${CSYNC_LIBRARY}
LIBRARY DESTINATION
${LIB_INSTALL_DIR}
${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
ARCHIVE DESTINATION
${LIB_INSTALL_DIR}
${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
RUNTIME DESTINATION
${BIN_INSTALL_DIR}
)
${BIN_INSTALL_DIR}/${APPLICATION_EXECUTABLE}
)
endif()
# INSTALL(
# FILES

View File

@@ -453,8 +453,8 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
if( other_node ) {
csync_file_stat_t *other_stat = (csync_file_stat_t*)other_node->data;
trav.other.etag = other_stat->etag ? c_strdup(other_stat->etag) : NULL;
trav.other.file_id = c_strdup(other_stat->file_id);
trav.other.etag = other_stat->etag;
trav.other.file_id = other_stat->file_id;
trav.other.instruction = other_stat->instruction;
trav.other.modtime = other_stat->modtime;
trav.other.size = other_stat->size;
@@ -629,6 +629,8 @@ int csync_commit(CSYNC *ctx) {
_csync_clean_ctx(ctx);
ctx->remote.read_from_db = 0;
ctx->read_from_db_disabled = 0;
/* Create new trees */
rc = c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp);
@@ -923,3 +925,10 @@ int csync_set_module_property(CSYNC* ctx, const char* key, void* value)
return csync_vio_set_property(ctx, key, value);
}
int csync_set_read_from_db(CSYNC* ctx, int enabled)
{
ctx->read_from_db_disabled = !enabled;
return 0;
}

View File

@@ -102,7 +102,8 @@ enum csync_status_codes_e {
/* Codes for file individual status: */
CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK,
CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST,
CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS
CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS,
CYSNC_STATUS_FILE_LOCKED_OR_OPEN
};
typedef enum csync_status_codes_e CSYNC_STATUS;
@@ -130,10 +131,7 @@ enum csync_instructions_e {
CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */
CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */
CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080,
CSYNC_INSTRUCTION_ERROR = 0x00000100,
/* instructions for the propagator */
CSYNC_INSTRUCTION_DELETED = 0x00000200,
CSYNC_INSTRUCTION_UPDATED = 0x00000400
CSYNC_INSTRUCTION_ERROR = 0x00000100
};
enum csync_ftw_type_e {
@@ -591,6 +589,11 @@ void csync_resume(CSYNC *ctx);
*/
int csync_abort_requested(CSYNC *ctx);
/**
* Specify if it is allowed to read the remote tree from the DB (default to enabled)
*/
int csync_set_read_from_db(CSYNC* ctx, int enabled);
#ifdef __cplusplus
}
#endif

View File

@@ -144,6 +144,7 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
char *bname = NULL;
char *dname = NULL;
char *prev_dname = NULL;
char *conflict = NULL;
int rc = -1;
CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED;
CSYNC_EXCLUDE_TYPE type = CSYNC_NOT_EXCLUDED;
@@ -200,6 +201,19 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
goto out;
}
if (getenv("CSYNC_CONFLICT_FILE_USERNAME")) {
asprintf(&conflict, "*_conflict_%s-*", getenv("CSYNC_CONFLICT_FILE_USERNAME"));
rc = csync_fnmatch(conflict, path, 0);
if (rc == 0) {
match = CSYNC_FILE_SILENTLY_EXCLUDED;
SAFE_FREE(conflict);
SAFE_FREE(bname);
SAFE_FREE(dname);
goto out;
}
SAFE_FREE(conflict);
}
SAFE_FREE(bname);
SAFE_FREE(dname);

View File

@@ -161,6 +161,7 @@ struct csync_s {
int status;
volatile int abort;
void *rename_info;
int read_from_db_disabled;
};

View File

@@ -223,6 +223,16 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
/* file on current replica is changed or new */
case CSYNC_INSTRUCTION_EVAL:
case CSYNC_INSTRUCTION_NEW:
// This operation is usually a no-op and will by default return false
if (csync_file_locked_or_open(ctx->local.uri, cur->path)) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "[Reconciler] IGNORING file %s/%s since it is locked / open", ctx->local.uri, cur->path);
cur->instruction = CSYNC_INSTRUCTION_ERROR;
if (cur->error_status == CSYNC_STATUS_OK) // don't overwrite error
cur->error_status = CYSNC_STATUS_FILE_LOCKED_OR_OPEN;
break;
} else {
//CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "[Reconciler] not ignoring file %s/%s", ctx->local.uri, cur->path);
}
switch (other->instruction) {
/* file on other replica is changed or new */
case CSYNC_INSTRUCTION_NEW:
@@ -235,10 +245,11 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
}
if (is_equal_files) {
/* The files are considered equal. */
cur->instruction = CSYNC_INSTRUCTION_UPDATED; /* update the DB */
cur->instruction = CSYNC_INSTRUCTION_NONE;
other->instruction = CSYNC_INSTRUCTION_NONE;
if( !cur->etag && other->etag ) cur->etag = c_strdup(other->etag);
cur->should_update_etag = true; /* update DB */
} else if(ctx->current == REMOTE_REPLICA) {
cur->instruction = CSYNC_INSTRUCTION_CONFLICT;
other->instruction = CSYNC_INSTRUCTION_NONE;

View File

@@ -79,6 +79,26 @@ static uint64_t _hash_of_file(CSYNC *ctx, const char *file) {
return h;
}
#ifdef NO_RENAME_EXTENSION
/* Return true if the two path have the same extension. false otherwise. */
static bool _csync_sameextension(const char *p1, const char *p2) {
/* Find pointer to the extensions */
const char *e1 = strrchr(p1, '.');
const char *e2 = strrchr(p2, '.');
/* If the found extension contains a '/', it is because the . was in the folder name
* => no extensions */
if (e1 && strchr(e1, '/')) e1 = NULL;
if (e2 && strchr(e2, '/')) e2 = NULL;
/* If none have extension, it is the same extension */
if (!e1 && !e2)
return true;
/* c_streq takes care of the rest */
return c_streq(e1, e2);
}
#endif
static int _csync_detect_update(CSYNC *ctx, const char *file,
const csync_vio_file_stat_t *fs, const int type) {
@@ -235,12 +255,21 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
goto out;
}
if (type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA
&& c_streq(fs->file_id, tmp->file_id)) {
&& c_streq(fs->file_id, tmp->file_id) && !ctx->read_from_db_disabled) {
/* If both etag and file id are equal for a directory, read all contents from
* the database. */
* the database.
* The comparison of file id ensure that we fetch all the file id when upgrading from
* owncloud 5 to owncloud 6.
*/
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Reading from database: %s", path);
ctx->remote.read_from_db = true;
}
if (!c_streq(fs->file_id, tmp->file_id) && ctx->current == REMOTE_REPLICA) {
/* file id has changed. Which means we need to update the DB.
* (upgrade from owncloud 5 to owncloud 6 for instence) */
st->should_update_etag = true;
}
st->instruction = CSYNC_INSTRUCTION_NONE;
} else {
enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
@@ -259,8 +288,12 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
}
if (tmp && tmp->inode == fs->inode && tmp_vio_type == fs->type
&& (tmp->modtime == fs->mtime || fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY)) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "inodes: %" PRId64 " <-> %" PRId64, (uint64_t) tmp->inode, (uint64_t) fs->inode);
&& (tmp->modtime == fs->mtime || fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY)
#ifdef NO_RENAME_EXTENSION
&& _csync_sameextension(tmp->path, path)
#endif
) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
/* inode found so the file has been renamed */
st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {

View File

@@ -55,8 +55,6 @@ static const _instr_code_struct _instr[] =
{ "INSTRUCTION_SYNC", CSYNC_INSTRUCTION_SYNC },
{ "INSTRUCTION_STAT_ERR", CSYNC_INSTRUCTION_STAT_ERROR },
{ "INSTRUCTION_ERROR", CSYNC_INSTRUCTION_ERROR },
{ "INSTRUCTION_DELETED", CSYNC_INSTRUCTION_DELETED },
{ "INSTRUCTION_UPDATED", CSYNC_INSTRUCTION_UPDATED },
{ NULL, CSYNC_INSTRUCTION_ERROR }
};
@@ -182,3 +180,21 @@ csync_vio_file_stat_t *csync_vio_convert_file_stat(csync_file_stat_t *st) {
return vfs;
}
bool (*csync_file_locked_or_open_ext) (const char*) = 0; // filled in by library user
void set_csync_file_locked_or_open_ext(bool (*f) (const char*)) {
csync_file_locked_or_open_ext = f;
}
bool csync_file_locked_or_open( const char *dir, const char *fname) {
char *tmp_uri = NULL;
bool ret;
if (!csync_file_locked_or_open_ext) {
return false;
}
asprintf(&tmp_uri, "%s/%s", dir, fname);
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "csync_file_locked_or_open %s", tmp_uri);
ret = csync_file_locked_or_open_ext(tmp_uri);
SAFE_FREE(tmp_uri);
return ret;
}

View File

@@ -35,4 +35,5 @@ void csync_win32_set_file_hidden( const char *file, bool hidden );
/* Convert a csync_file_stat_t to csync_vio_file_stat_t */
csync_vio_file_stat_t *csync_vio_convert_file_stat(csync_file_stat_t *st);
bool csync_file_locked_or_open( const char *dir, const char *fname);
#endif /* _CSYNC_UTIL_H */

View File

@@ -233,8 +233,6 @@ static void check_csync_detect_update_db_none(void **state)
st = c_rbtree_node_data(csync->local.tree->root);
assert_int_equal(st->instruction, CSYNC_INSTRUCTION_NEW);
/* set the instruction to UPDATED that it gets written to the statedb */
st->instruction = CSYNC_INSTRUCTION_UPDATED;
/* create a statedb */
csync_set_status(csync, 0xFFFF);
@@ -262,9 +260,6 @@ static void check_csync_detect_update_db_eval(void **state)
st = c_rbtree_node_data(csync->local.tree->root);
assert_int_equal(st->instruction, CSYNC_INSTRUCTION_NEW);
/* set the instruction to UPDATED that it gets written to the statedb */
st->instruction = CSYNC_INSTRUCTION_UPDATED;
/* create a statedb */
csync_set_status(csync, 0xFFFF);
@@ -344,8 +339,6 @@ static void check_csync_detect_update_db_new(void **state)
st = c_rbtree_node_data(csync->local.tree->root);
assert_int_equal(st->instruction, CSYNC_INSTRUCTION_NEW);
/* set the instruction to UPDATED that it gets written to the statedb */
st->instruction = CSYNC_INSTRUCTION_UPDATED;
/* create a statedb */
csync_set_status(csync, 0xFFFF);

View File

@@ -56,13 +56,13 @@ assertLocalDirs( 'toremote1', localDir().'remoteToLocal1' );
# Check if the synced files from ownCloud have the same timestamp as the local ones.
print "\nNow assert remote 'toremote1' with local " . localDir() . " :\n";
assertLocalAndRemoteDir( 'remoteToLocal1', 0);
assertLocalAndRemoteDir( '', 0);
# remove a local file.
printInfo( "\nRemove a local file\n" );
unlink( localDir() . 'remoteToLocal1/kernelcrash.txt' );
unlink( localDir() . 'remoteToLocal1/rtl4/quitte.pdf' );
csync();
assertLocalAndRemoteDir( 'remoteToLocal1', 0);
assertLocalAndRemoteDir( '', 0);
# add local files to a new dir1
printInfo( "Add some more files to local:");
@@ -76,34 +76,46 @@ foreach my $file ( <./tolocal1/*> ) {
}
csync( );
print "\nAssert local and remote dirs.\n";
assertLocalAndRemoteDir( 'fromLocal1', 0);
assertLocalAndRemoteDir( '', 0);
# move a local file
printInfo( "Move a file locally." );
move( "$locDir/kramer.jpg", "$locDir/oldtimer.jpg" );
csync( );
assertLocalAndRemoteDir( 'fromLocal1', 0);
assertLocalAndRemoteDir( '', 0);
# move a local directory.
printInfo( "Move a local directory." );
move( localDir() . 'remoteToLocal1/rtl1', localDir(). 'remoteToLocal1/rtlX');
csync();
assertLocalAndRemoteDir( 'fromLocal1', 0);
assertLocalAndRemoteDir( '', 0);
# remove a local dir
printInfo( "Remove a local directory.");
localCleanup( 'remoteToLocal1/rtlX' );
csync();
assertLocalAndRemoteDir( 'fromLocal1', 0);
assertLocalAndRemoteDir( '', 0);
assert( ! -e localDir().'remoteToLocal1/rtlX' );
# create a false conflict, only the mtimes are changed, by content are equal.
printInfo( "Create a false conflict.");
my $srcFile = 'toremote1/kernelcrash.txt';
put_to_dir( $srcFile, 'remoteToLocal1' );
# create twos false conflict, only the mtimes are changed, by content are equal.
printInfo( "Create two false conflict.");
put_to_dir( 'toremote1/kernelcrash.txt', 'remoteToLocal1' );
put_to_dir( 'toremote1/kraft_logo.gif', 'remoteToLocal1' );
# don't wait so mtime are likely the same on the client and the server.
system( "touch " . localDir() . "remoteToLocal1/kraft_logo.gif" );
# wait two second so the mtime are different
system( "sleep 2 && touch " . localDir() . "remoteToLocal1/kernelcrash.txt" );
csync( );
assertLocalAndRemoteDir( 'fromLocal1', 0);
assertLocalAndRemoteDir( '', 0);
# The previous sync should have updated the etags, and this should NOT be a conflict
printInfo( "Update the file again");
system("echo more data >> " . localDir() . "remoteToLocal1/kernelcrash.txt");
system("echo corruption >> " . localDir() . "remoteToLocal1/kraft_logo.gif");
csync( );
assertLocalAndRemoteDir( '', 0);
# create a true conflict.
printInfo( "Create a conflict." );
@@ -111,13 +123,14 @@ system( "echo \"This is more stuff\" >> /tmp/kernelcrash.txt" );
put_to_dir( '/tmp/kernelcrash.txt', 'remoteToLocal1' );
system( "sleep 2 && touch " . localDir() . "remoteToLocal1/kernelcrash.txt" );
csync();
assertLocalAndRemoteDir( 'remoteToLocal1', 1);
assertLocalAndRemoteDir( '', 1);
my $localMD5 = md5OfFile( localDir().'remoteToLocal1/kernelcrash.txt' );
my $realMD5 = md5OfFile( '/tmp/kernelcrash.txt' );
print "MD5 compare $localMD5 <-> $realMD5\n";
assert( $localMD5 eq $realMD5 );
assert( glob(localDir().'remoteToLocal1/kernelcrash_conflict-*.txt' ) );
system("rm " . localDir().'remoteToLocal1/kernelcrash_conflict-*.txt' );
# prepare test for issue 1329, rtlX need to be modified
@@ -125,13 +138,13 @@ assert( glob(localDir().'remoteToLocal1/kernelcrash_conflict-*.txt' ) );
printInfo( "Add a local directory");
system("cp -r 'toremote1/rtl1/' '" . localDir(). "remoteToLocal1/rtlX'");
csync();
assertLocalAndRemoteDir( 'fromLocal1', 0);
assertLocalAndRemoteDir( '', 0);
# remove a local dir (still for issue 1329)
printInfo( "Remove that directory.");
localCleanup( 'remoteToLocal1/rtlX' );
csync();
assertLocalAndRemoteDir( 'fromLocal1', 0);
assertLocalAndRemoteDir( '', 0);
assert( ! -e localDir().'remoteToLocal1/rtlX' );
@@ -141,7 +154,7 @@ system("cp -r 'toremote1/rtl1/' '" . localDir(). "remoteToLocal1/rtlX'");
assert( -e localDir().'remoteToLocal1/rtlX' );
assert( -e localDir().'remoteToLocal1/rtlX/rtl11/file.txt' );
csync();
assertLocalAndRemoteDir( 'fromLocal1', 0);
assertLocalAndRemoteDir( '', 0);
assert( -e localDir().'remoteToLocal1/rtlX' );
assert( -e localDir().'remoteToLocal1/rtlX/rtl11/file.txt' );

View File

@@ -80,7 +80,6 @@ assert( $inode == $inode2, "Inode has changed!");
printInfo("Move a file into a sub directory.");
# now move the file into a sub directory
$inode = getInode('remoteToLocal1/kernel.txt');
moveRemoteFile( 'remoteToLocal1/kernel.txt', 'remoteToLocal1/rtl1/');
csync();
@@ -175,6 +174,24 @@ createLocalFile( localDir(). 'remoteToLocal1/rtl2/newRemoteDir/donat.txt', 8021
csync();
assertLocalAndRemoteDir( 'remoteToLocal1', 1);
printInfo("simulate a owncloud 5 update by removing all the fileid");
## simulate a owncloud 5 update by removing all the fileid
system( "sqlite3 " . localDir() . ".csync_journal.db \"UPDATE metadata SET fileid='';\"");
#refresh the ids
csync();
assertLocalAndRemoteDir( 'remoteToLocal1', 1);
printInfo("Move a file from the server");
$inode = getInode('remoteToLocal1/rtl2/kb1_local_gone.jpg');
moveRemoteFile( 'remoteToLocal1/rtl2/kb1_local_gone.jpg', 'remoteToLocal1/rtl2/kb1_local_gone2.jpg');
csync();
assertLocalAndRemoteDir( 'remoteToLocal1', 1);
$inode2 = getInode('remoteToLocal1/rtl2/kb1_local_gone2.jpg');
assert( $inode == $inode2, "Inode has changed 3!");
cleanup();
# --

View File

@@ -0,0 +1 @@
A nice document.

View File

@@ -0,0 +1,16 @@
freitag@zora:~>
Message from syslogd@zora at Sep 20 21:35:41 ...
kernel:[ 6702.458047] general protection fault: 0000 [#1] PREEMPT SMP
Message from syslogd@zora at Sep 20 21:35:41 ...
kernel:[ 6702.458060] last sysfs file: /sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:03/ATK0110:00/hwmon/hwmon0/temp1_label
Message from syslogd@zora at Sep 20 21:35:41 ...
kernel:[ 6702.458232] Stack:
Message from syslogd@zora at Sep 20 21:35:41 ...
kernel:[ 6702.458262] Call Trace:
Message from syslogd@zora at Sep 20 21:35:41 ...
kernel:[ 6702.458375] Code: 00 00 80 00 00 00 48 b9 00 00 00 00 80 ff ff ff 4e 8d 34 30 49 21 ce 48 8b 4c 24 38 49 8d 56 ff 48 3b 54 24 48 4c 0f 43 74 24 40 <48> 8b 11 48 85 d2 0f 84 d4 01 00 00 48 b9 fb 0f 00 00 00 c0 ff

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -1 +0,0 @@
some content.

View File

@@ -80,7 +80,7 @@ Adding a Folder
Adding a new sync is initiated by clicking ``Add Folder...`` in the ``Account``
settings.
..note: To add a folder, you must not already sync a folder that contains this
..note:: To add a folder, you must not already sync a folder that contains this
folder. By default, the wizard sets up the root folder of the ownCloud
server to sync all of your ownCloud account. In consequence, you will
first need to remove this folder prior to specifying new syncs.

View File

@@ -27,9 +27,9 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
)
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
if(SPARKLE_FOUND)
if(SPARKLE_FOUND AND NOT BUILD_LIBRARIES_ONLY)
list (APPEND OS_SPECIFIC_LINK_LIBRARIES ${SPARKLE_LIBRARY})
endif(SPARKLE_FOUND)
endif()
set(3rdparty_SRC
3rdparty/qtsingleapplication/qtsingleapplication.cpp
@@ -115,19 +115,19 @@ if(TOKEN_AUTH_ONLY)
${libsync_SRCS}
creds/tokencredentials.cpp
)
else()
set (libsync_SRCS
${libsync_SRCS}
creds/httpcredentials.cpp
creds/shibbolethcredentials.cpp
creds/shibboleth/shibbolethaccessmanager.cpp
creds/shibboleth/shibbolethcookiejar.cpp
creds/shibboleth/shibbolethwebview.cpp
creds/shibboleth/shibbolethrefresher.cpp
creds/shibboleth/shibbolethconfigfile.cpp
creds/shibboleth/authenticationdialog.cpp
creds/shibboleth/shibbolethuserjob.cpp
)
else()
set (libsync_SRCS
${libsync_SRCS}
creds/httpcredentials.cpp
creds/shibbolethcredentials.cpp
creds/shibboleth/shibbolethaccessmanager.cpp
creds/shibboleth/shibbolethcookiejar.cpp
creds/shibboleth/shibbolethwebview.cpp
creds/shibboleth/shibbolethrefresher.cpp
creds/shibboleth/shibbolethconfigfile.cpp
creds/shibboleth/authenticationdialog.cpp
creds/shibboleth/shibbolethuserjob.cpp
)
endif()
IF( NOT WIN32 AND NOT APPLE )
@@ -195,25 +195,31 @@ if(NEON_FOUND)
endif()
add_library(${synclib_NAME} SHARED ${libsync_SRCS} ${syncMoc})
qt5_use_modules(${synclib_NAME} Widgets Network Xml WebKitWidgets Sql)
if(TOKEN_AUTH_ONLY)
qt5_use_modules(${synclib_NAME} Network Xml Sql)
else()
qt5_use_modules(${synclib_NAME} Widgets Network Xml WebKitWidgets Sql)
endif()
set_target_properties( ${synclib_NAME} PROPERTIES
VERSION ${MIRALL_VERSION}
SOVERSION ${MIRALL_SOVERSION}
)
set_target_properties( ${synclib_NAME} PROPERTIES
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" )
target_link_libraries(${synclib_NAME} ${libsync_LINK_TARGETS} )
if(BUILD_LIBRARIES_ONLY)
add_library(${synclib_NAME}_static STATIC ${libsync_SRCS} ${syncMoc})
qt5_use_modules(${synclib_NAME}_static Widgets Network Xml WebKitWidgets Sql)
#add_library(${synclib_NAME}_static STATIC ${libsync_SRCS} ${syncMoc})
#qt5_use_modules(${synclib_NAME}_static Widgets Network Xml Sql)
set_target_properties( ${synclib_NAME}_static PROPERTIES
VERSION ${MIRALL_VERSION}
SOVERSION ${MIRALL_SOVERSION}
)
#set_target_properties( ${synclib_NAME}_static PROPERTIES
# VERSION ${MIRALL_VERSION}
# SOVERSION ${MIRALL_SOVERSION}
#)
target_link_libraries(${synclib_NAME}_static ${libsync_LINK_TARGETS} )
#target_link_libraries(${synclib_NAME}_static ${libsync_LINK_TARGETS} )
endif()
@@ -376,17 +382,17 @@ if (WITH_DBUS)
set(ADDITIONAL_APP_MODULES DBus)
endif(WITH_DBUS)
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY)
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
if(NOT WIN32 AND NOT BUILD_LIBRARIES_ONLY)
file( GLOB _icons "${theme_dir}/colored/${ICON_APP_NAME}-icon-*.png" )
foreach( _file ${_icons} )
string( REPLACE "${theme_dir}/colored/${ICON_APP_NAME}-icon-" "" _res ${_file} )
string( REPLACE ".png" "" _res ${_res} )
install( FILES ${_file} RENAME ${ICON_APP_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps )
endforeach( _file )
endif(NOT WIN32 AND NOT BUILD_LIBRARIES_ONLY)
if(NOT WIN32)
file( GLOB _icons "${theme_dir}/colored/${ICON_APP_NAME}-icon-*.png" )
foreach( _file ${_icons} )
string( REPLACE "${theme_dir}/colored/${ICON_APP_NAME}-icon-" "" _res ${_file} )
string( REPLACE ".png" "" _res ${_res} )
install( FILES ${_file} RENAME ${ICON_APP_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps )
endforeach( _file )
endif(NOT WIN32)
install(FILES ${mirall_I18N} DESTINATION share/${APPLICATION_EXECUTABLE}/i18n)
@@ -418,14 +424,17 @@ elseif(NOT BUILD_LIBRARIES_ONLY)
install(FILES ${qtkeychain_I18N} DESTINATION ${QM_DIR})
endif()
add_library(updater STATIC ${updater_SRCS} ${updaterMoc})
target_link_libraries(updater ${synclib_NAME})
qt5_use_modules(updater Widgets Network Xml)
if(NOT BUILD_LIBRARIES_ONLY)
add_library(updater STATIC ${updater_SRCS} ${updaterMoc})
target_link_libraries(updater ${synclib_NAME})
qt5_use_modules(updater Widgets Network Xml)
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}
)
set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" )
target_link_libraries( ${APPLICATION_EXECUTABLE} ${QT_LIBRARIES} )
target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} )
target_link_libraries( ${APPLICATION_EXECUTABLE} updater )
@@ -464,10 +473,14 @@ endif()
set(owncloudcmd_NAME ${APPLICATION_EXECUTABLE}cmd)
set(OWNCLOUDCMD_SRC owncloudcmd/simplesslerrorhandler.cpp owncloudcmd/owncloudcmd.cpp)
if(NOT BUILD_LIBRARIES_ONLY)
add_executable(${owncloudcmd_NAME} ${OWNCLOUDCMD_SRC})
qt5_use_modules(${owncloudcmd_NAME} Network Sql)
set_target_properties(${owncloudcmd_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} )
RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} )
set_target_properties(${owncloudcmd_NAME} PROPERTIES
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/${APPLICATION_EXECUTABLE}" )
target_link_libraries(${owncloudcmd_NAME} ${synclib_NAME})
endif()

View File

@@ -17,6 +17,8 @@
#include <QObject>
#include <csync.h>
#include "owncloudlib.h"
class QNetworkAccessManager;
class QNetworkReply;
@@ -24,7 +26,7 @@ namespace Mirall
{
class Account;
class AbstractCredentials : public QObject
class OWNCLOUDSYNC_EXPORT AbstractCredentials : public QObject
{
Q_OBJECT

View File

@@ -13,6 +13,7 @@
#include <QString>
#include "creds/credentialsfactory.h"
#ifdef TOKEN_AUTH_ONLY
#include "creds/tokencredentials.h"
#else

View File

@@ -14,16 +14,18 @@
#ifndef MIRALL_CREDS_CREDENTIALS_FACTORY_H
#define MIRALL_CREDS_CREDENTIALS_FACTORY_H
class AbstractCredentials;
#include "owncloudlib.h"
class QString;
namespace Mirall
{
class AbstractCredentials;
namespace CredentialsFactory
{
AbstractCredentials* create(const QString& type);
OWNCLOUDSYNC_EXPORT AbstractCredentials* create(const QString& type);
} // ns CredentialsFactory

View File

@@ -30,7 +30,7 @@ class Job;
namespace Mirall
{
class HttpCredentials : public AbstractCredentials
class OWNCLOUDSYNC_EXPORT HttpCredentials : public AbstractCredentials
{
Q_OBJECT

View File

@@ -35,7 +35,7 @@ void ShibbolethUserJob::start()
AbstractNetworkJob::start();
}
void ShibbolethUserJob::finished()
bool ShibbolethUserJob::finished()
{
bool success = false;
QVariantMap json = QtJson::parse(QString::fromUtf8(reply()->readAll()), success).toMap();
@@ -43,12 +43,13 @@ void ShibbolethUserJob::finished()
if (!success || json.isEmpty()) {
qDebug() << "cloud/user: invalid JSON!";
emit userFetched(QString());
return;
return true;
}
QString user = json.value("ocs").toMap().value("data").toMap().value("id").toString();
qDebug() << "cloud/user: " << json << "->" << user;
emit userFetched(user);
return true;
}

View File

@@ -36,7 +36,7 @@ signals:
void tryAgain();
private slots:
virtual void finished();
virtual bool finished();
};

View File

@@ -14,6 +14,7 @@
#ifndef MIRALL_WIZARD_SHIBBOLETH_WEB_VIEW_H
#define MIRALL_WIZARD_SHIBBOLETH_WEB_VIEW_H
#include "owncloudlib.h"
#include <QList>
#include <QPointer>
#include <QWebView>
@@ -27,7 +28,7 @@ namespace Mirall
class ShibbolethCookieJar;
class Account;
class ShibbolethWebView : public QWebView
class OWNCLOUDSYNC_EXPORT ShibbolethWebView : public QWebView
{
Q_OBJECT

View File

@@ -30,7 +30,7 @@ namespace Mirall
class ShibbolethWebView;
class ShibbolethCredentials : public AbstractCredentials
class OWNCLOUDSYNC_EXPORT ShibbolethCredentials : public AbstractCredentials
{
Q_OBJECT

View File

@@ -17,8 +17,6 @@
#include <QDebug>
#include <QNetworkReply>
#include <QSettings>
#include <QInputDialog>
#include "mirall/account.h"
#include "mirall/mirallaccessmanager.h"
@@ -70,6 +68,7 @@ int getauth(const char *prompt,
}
const char userC[] = "user";
const char authenticationFailedC[] = "owncloud-authentication-failed";
} // ns
@@ -174,22 +173,13 @@ bool TokenCredentials::stillValid(QNetworkReply *reply)
{
return ((reply->error() != QNetworkReply::AuthenticationRequiredError)
// returned if user or password is incorrect
&& (reply->error() != QNetworkReply::OperationCanceledError));
&& (reply->error() != QNetworkReply::OperationCanceledError
|| !reply->property(authenticationFailedC).toBool()));
}
QString TokenCredentials::queryPassword(bool *ok)
{
qDebug() << AccountManager::instance()->account()->state();
if (ok) {
QString str = QInputDialog::getText(0, tr("Enter Password"),
tr("Please enter %1 password for user '%2':")
.arg(Theme::instance()->appNameGUI(), _user),
QLineEdit::Password, QString(), ok);
qDebug() << AccountManager::instance()->account()->state();
return str;
} else {
return QString();
}
return QString();
}
void TokenCredentials::invalidateToken(Account *account)
@@ -221,6 +211,7 @@ void TokenCredentials::slotAuthentication(QNetworkReply* reply, QAuthenticator*
// instead of utf8 encoding. Instead, we send it manually. Thus, if we reach this signal,
// those credentials were invalid and we terminate.
qDebug() << "Stop request: Authentication failed for " << reply->url().toString();
reply->setProperty(authenticationFailedC, true);
reply->close();
}

View File

@@ -31,7 +31,7 @@ namespace Mirall
{
class TokenCredentialsAccessManager;
class TokenCredentials : public AbstractCredentials
class OWNCLOUDSYNC_EXPORT TokenCredentials : public AbstractCredentials
{
Q_OBJECT

View File

@@ -22,6 +22,7 @@
#include <QSslCertificate>
#include <QSslConfiguration>
#include <QSslError>
#include "utility.h"
class QSettings;
class QNetworkReply;
@@ -34,7 +35,7 @@ class AbstractCredentials;
class Account;
class QuotaInfo;
class AccountManager : public QObject {
class OWNCLOUDSYNC_EXPORT AccountManager : public QObject {
Q_OBJECT
public:
static AccountManager *instance();
@@ -63,7 +64,7 @@ public:
/**
* @brief This class represents an account on an ownCloud Server
*/
class Account : public QObject {
class OWNCLOUDSYNC_EXPORT Account : public QObject {
Q_OBJECT
public:
enum State { Disconnected = 0, /// no network connection

View File

@@ -241,6 +241,10 @@ void AccountSettings::slotButtonsSetEnabled()
void AccountSettings::setGeneralErrors( const QStringList& errors )
{
_generalErrors = errors;
if (_account) {
// this will update the message
slotAccountStateChanged(_account->state());
}
}
void AccountSettings::folderToModelItem( QStandardItem *item, Folder *f )
@@ -380,6 +384,7 @@ void AccountSettings::showConnectionLabel( const QString& message, const QString
if( _generalErrors.isEmpty() ) {
ui->connectLabel->setText( message );
ui->connectLabel->setToolTip(tooltip);
ui->connectLabel->setStyleSheet(QString());
} else {
const QString msg = _generalErrors.join(QLatin1String("\n"));
ui->connectLabel->setText( msg );

View File

@@ -139,6 +139,10 @@ Application::Application(int &argc, char **argv) :
this, SLOT(slotAccountChanged(Account*,Account*)));
// startup procedure.
connect(&_checkConnectionTimer, SIGNAL(timeout()), this, SLOT(slotCheckConnection()));
_checkConnectionTimer.setInterval(32 * 1000); // check for connection every 32 seconds.
_checkConnectionTimer.start();
// Also check immediatly
QTimer::singleShot( 0, this, SLOT( slotCheckConnection() ));
if( cfg.skipUpdateCheck() ) {
@@ -226,8 +230,9 @@ void Application::slotCheckConnection()
if (account->state() == Account::InvalidCredidential
|| account->state() == Account::SignedOut) {
//Do not try to connect if we are logged out
if (!_userTriggeredConnect)
if (!_userTriggeredConnect) {
return;
}
}
if (_conValidator)
@@ -269,6 +274,8 @@ void Application::slotToggleFolderman(int state)
folderMan->slotScheduleAllFolders();
break;
case Account::Disconnected:
_checkConnectionTimer.start();
// fall through
case Account::SignedOut:
case Account::InvalidCredidential:
folderMan->setSyncEnabled(false);
@@ -289,6 +296,7 @@ void Application::slotConnectionValidatorResult(ConnectionValidator::Status stat
folderMan->setSyncEnabled(true);
// queue up the sync for all folders.
folderMan->slotScheduleAllFolders();
_checkConnectionTimer.stop();
} else {
// if we have problems here, it's unlikely that syncing will work.
FolderMan::instance()->setSyncEnabled(false);
@@ -298,7 +306,6 @@ void Application::slotConnectionValidatorResult(ConnectionValidator::Status stat
if (_userTriggeredConnect) {
_userTriggeredConnect = false;
}
QTimer::singleShot(30*1000, this, SLOT(slotCheckConnection()));
}
_gui->startupConnected( (status == ConnectionValidator::Connected), startupFails);

View File

@@ -18,6 +18,7 @@
#include <QApplication>
#include <QPointer>
#include <QQueue>
#include <QTimer>
#include "qtsingleapplication.h"
@@ -103,6 +104,8 @@ private:
ClientProxy _proxy;
QTimer _checkConnectionTimer;
friend class ownCloudGui; // for _startupNetworkError
};

View File

@@ -18,12 +18,13 @@
#include <QNetworkProxy>
#include <csync.h>
#include "utility.h"
namespace Mirall {
class MirallConfigFile;
class ClientProxy : public QObject
class OWNCLOUDSYNC_EXPORT ClientProxy : public QObject
{
Q_OBJECT
public:

View File

@@ -14,6 +14,7 @@
#ifndef CONNECTIONVALIDATOR_H
#define CONNECTIONVALIDATOR_H
#include "owncloudlib.h"
#include <QObject>
#include <QStringList>
#include <QVariantMap>
@@ -23,7 +24,7 @@ namespace Mirall {
class Account;
class ConnectionValidator : public QObject
class OWNCLOUDSYNC_EXPORT ConnectionValidator : public QObject
{
Q_OBJECT
public:

View File

@@ -49,8 +49,11 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype);
#include <QTimer>
#include <QUrl>
#include <QDir>
#ifndef TOKEN_AUTH_ONLY
#include <QMessageBox>
#include <QPushButton>
#endif
namespace Mirall {
@@ -298,7 +301,8 @@ void Folder::bubbleUpSyncResult()
SyncRunFileLog syncFileLog;
syncFileLog.start(path(), _engine->stopWatch() );
syncFileLog.start(path(), _stopWatch );
_stopWatch.reset();
QElapsedTimer timer;
timer.start();
@@ -626,6 +630,7 @@ void Folder::slotSyncFinished()
qDebug() << "-> CSync Finished slot with error " << _csyncError << "warn count" << _syncResult.warnCount();
bubbleUpSyncResult();
_stopWatch = _engine->stopWatch();
_engine.reset(0);
// _watcher->setEventsEnabledDelayed(2000);
@@ -670,6 +675,7 @@ void Folder::slotTransmissionProgress(const Progress::Info &pi)
void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction direction, bool *cancel)
{
#ifndef TOKEN_AUTH_ONLY
QString msg = direction == SyncFileItem::Down ?
tr("This sync would remove all the files in the local sync folder '%1'.\n"
"If you or your administrator have reset your account on the server, choose "
@@ -690,6 +696,7 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction direction, bool *
if (*cancel) {
wipe();
}
#endif
}
SyncFileStatus Folder::fileStatus( const QString& fileName )

View File

@@ -21,6 +21,7 @@
#include "mirall/progressdispatcher.h"
#include "mirall/syncjournaldb.h"
#include "mirall/clientproxy.h"
#include "mirall/utility.h"
#include <csync.h>
@@ -59,7 +60,7 @@ typedef enum SyncFileStatus_s {
} SyncFileStatus;
class Folder : public QObject
class OWNCLOUDSYNC_EXPORT Folder : public QObject
{
Q_OBJECT
@@ -186,7 +187,6 @@ private slots:
private:
bool init();
void setIgnoredFiles();
void bubbleUpSyncResult();
@@ -217,6 +217,8 @@ private:
ClientProxy _clientProxy;
Utility::StopWatch _stopWatch;
CSYNC *_csync_ctx;
};

View File

@@ -27,8 +27,10 @@
#include <shlobj.h>
#endif
#include <QDesktopServices>
#ifndef TOKEN_AUTH_ONLY
#include <QMessageBox>
#endif
#include <QtCore>
namespace Mirall {
@@ -143,13 +145,13 @@ int FolderMan::setupFolders()
unloadAllFolders();
QDir dir( _folderConfigPath );
dir.setFilter(QDir::Files);
//We need to include hidden files just in case the alias starts with '.'
dir.setFilter(QDir::Files | QDir::Hidden);
QStringList list = dir.entryList();
foreach ( const QString& alias, list ) {
Folder *f = setupFolderFromConfigFile( alias );
if( f ) {
registerFolderMonitor(f);
slotScheduleSync(alias);
emit( folderSyncStateChange( f->alias() ) );
}
@@ -163,7 +165,8 @@ int FolderMan::setupFolders()
bool FolderMan::ensureJournalGone(const QString &localPath)
{
// FIXME move this to UI, not libowncloudsync
#ifndef TOKEN_AUTH_ONLY
// remove old .csync_journal file
QString stateDbFile = localPath+QLatin1String("/.csync_journal.db");
while (QFile::exists(stateDbFile) && !QFile::remove(stateDbFile)) {
@@ -177,6 +180,7 @@ bool FolderMan::ensureJournalGone(const QString &localPath)
return false;
}
}
#endif
return true;
}
@@ -307,6 +311,8 @@ Folder* FolderMan::setupFolderFromConfigFile(const QString &file) {
connect(folder, SIGNAL(syncFinished(SyncResult)), SLOT(slotFolderSyncFinished(SyncResult)));
_folderChangeSignalMapper->setMapping( folder, folder->alias() );
registerFolderMonitor(folder);
return folder;
}

View File

@@ -30,7 +30,7 @@ class SyncResult;
namespace Mirall {
class FolderMan : public QObject
class OWNCLOUDSYNC_EXPORT FolderMan : public QObject
{
Q_OBJECT
public:

View File

@@ -172,7 +172,7 @@ void FolderWatcherPrivate::slotReceivedNotification(int fd)
if (event->len > 0 && event->wd > -1) {
// qDebug() << Q_FUNC_INFO << event->name;
if (QByteArray(event->name).startsWith(".csync") ||
QByteArray(event->name) == ".owncloudsync.log") {
QByteArray(event->name).startsWith(".owncloudsync.log")) {
// qDebug() << "ignore journal";
} else {
const QString p = _watches[event->wd];

View File

@@ -22,6 +22,8 @@
#include <QTextStream>
#include <qmutex.h>
#include "utility.h"
namespace Mirall {
struct Log{
@@ -35,7 +37,7 @@ struct Log{
QString message;
};
class Logger : public QObject
class OWNCLOUDSYNC_EXPORT Logger : public QObject
{
Q_OBJECT
public:

View File

@@ -24,7 +24,7 @@ namespace Mirall
MirallAccessManager::MirallAccessManager(QObject* parent)
: QNetworkAccessManager (parent)
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && defined(Q_OS_MAC)
// FIXME Workaround http://stackoverflow.com/a/15707366/2941 https://bugreports.qt-project.org/browse/QTBUG-30434
QNetworkProxy proxy = this->proxy();
proxy.setHostName(" ");

View File

@@ -14,12 +14,13 @@
#ifndef MIRALL_ACCESS_MANAGER_H
#define MIRALL_ACCESS_MANAGER_H
#include "owncloudlib.h"
#include <QNetworkAccessManager>
namespace Mirall
{
class MirallAccessManager : public QNetworkAccessManager
class OWNCLOUDSYNC_EXPORT MirallAccessManager : public QNetworkAccessManager
{
Q_OBJECT

View File

@@ -22,7 +22,11 @@
#include "creds/abstractcredentials.h"
#include "creds/credentialsfactory.h"
#ifndef TOKEN_AUTH_ONLY
#include <QWidget>
#include <QHeaderView>
#endif
#include <QCoreApplication>
#include <QDir>
#include <QFile>
@@ -30,7 +34,6 @@
#include <QSettings>
#include <QDebug>
#include <QNetworkProxy>
#include <QHeaderView>
#define DEFAULT_REMOTE_POLL_INTERVAL 30000 // default remote poll time in milliseconds
#define DEFAULT_MAX_LOG_LINES 20000
@@ -109,20 +112,25 @@ void MirallConfigFile::setOptionalDesktopNotifications(bool show)
void MirallConfigFile::saveGeometry(QWidget *w)
{
#ifndef TOKEN_AUTH_ONLY
Q_ASSERT(!w->objectName().isNull());
QSettings settings(configFile(), QSettings::IniFormat);
settings.beginGroup(w->objectName());
settings.setValue(QLatin1String(geometryC), w->saveGeometry());
settings.sync();
#endif
}
void MirallConfigFile::restoreGeometry(QWidget *w)
{
#ifndef TOKEN_AUTH_ONLY
w->restoreGeometry(getValue(geometryC, w->objectName()).toByteArray());
#endif
}
void MirallConfigFile::saveGeometryHeader(QHeaderView *header)
{
#ifndef TOKEN_AUTH_ONLY
if(!header) return;
Q_ASSERT(!header->objectName().isNull());
@@ -130,16 +138,19 @@ void MirallConfigFile::saveGeometryHeader(QHeaderView *header)
settings.beginGroup(header->objectName());
settings.setValue(QLatin1String(geometryC), header->saveState());
settings.sync();
#endif
}
void MirallConfigFile::restoreGeometryHeader(QHeaderView *header)
{
#ifndef TOKEN_AUTH_ONLY
if(!header) return;
Q_ASSERT(!header->objectName().isNull());
QSettings settings(configFile(), QSettings::IniFormat);
settings.beginGroup(header->objectName());
header->restoreState(getValue(geometryC, header->objectName()).toByteArray());
#endif
}
QVariant MirallConfigFile::getPolicySetting(const QString &setting, const QVariant& defaultValue) const

View File

@@ -15,6 +15,7 @@
#ifndef MIRALLCONFIGFILE_H
#define MIRALLCONFIGFILE_H
#include "owncloudlib.h"
#include <QSharedPointer>
#include <QString>
#include <QVariant>
@@ -26,7 +27,7 @@ namespace Mirall {
class AbstractCredentials;
class MirallConfigFile
class OWNCLOUDSYNC_EXPORT MirallConfigFile
{
public:
MirallConfigFile();

View File

@@ -34,7 +34,6 @@
#include "creds/credentialsfactory.h"
#include "creds/abstractcredentials.h"
#include "creds/shibbolethcredentials.h"
Q_DECLARE_METATYPE(QTimer*)
@@ -148,7 +147,7 @@ void AbstractNetworkJob::slotFinished()
_responseTimestamp = QString::fromAscii(_reply->rawHeader("Date"));
_duration = _durationTimer.elapsed();
finished();
bool discard = finished();
AbstractCredentials *creds = _account->credentials();
if (!creds->stillValid(_reply) &&! _ignoreCredentialFailure
&& _account->state() != Account::InvalidCredidential) {
@@ -164,7 +163,9 @@ void AbstractNetworkJob::slotFinished()
creds->fetch(_account);
}
}
deleteLater();
if (discard) {
deleteLater();
}
}
quint64 AbstractNetworkJob::duration()
@@ -228,7 +229,7 @@ void RequestEtagJob::start()
AbstractNetworkJob::start();
}
void RequestEtagJob::finished()
bool RequestEtagJob::finished()
{
if (reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 207) {
// Parse DAV response
@@ -247,6 +248,7 @@ void RequestEtagJob::finished()
}
emit etagRetreived(etag);
}
return true;
}
/*********************************************************************************************/
@@ -265,9 +267,10 @@ void MkColJob::start()
AbstractNetworkJob::start();
}
void MkColJob::finished()
bool MkColJob::finished()
{
emit finished(reply()->error());
return true;
}
/*********************************************************************************************/
@@ -297,7 +300,7 @@ void LsColJob::start()
AbstractNetworkJob::start();
}
void LsColJob::finished()
bool LsColJob::finished()
{
if (reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 207) {
// Parse DAV response
@@ -323,13 +326,20 @@ void LsColJob::finished()
}
emit directoryListing(folders);
}
return true;
}
/*********************************************************************************************/
namespace {
const char statusphpC[] = "status.php";
const char owncloudDirC[] = "owncloud/";
}
CheckServerJob::CheckServerJob(Account *account, bool followRedirect, QObject *parent)
: AbstractNetworkJob(account, QLatin1String("status.php") , parent)
: AbstractNetworkJob(account, QLatin1String(statusphpC) , parent)
, _followRedirects(followRedirect)
, _subdirFallback(false)
, _redirectCount(0)
{
setIgnoreCredentialFailure(true);
@@ -364,7 +374,7 @@ bool CheckServerJob::installed(const QVariantMap &info)
return info.value(QLatin1String("installed")).toBool();
}
void CheckServerJob::finished()
bool CheckServerJob::finished()
{
account()->setSslConfiguration(reply()->sslConfiguration());
@@ -383,10 +393,20 @@ void CheckServerJob::finished()
resetTimeout();
setReply(getRequest(redirectUrl));
setupConnections(reply());
return;
return false;
}
}
// The serverInstalls to /owncloud. Let's try that if the file wasn't found
// at the original location
if ((reply()->error() == QNetworkReply::ContentNotFoundError) && (!_subdirFallback)) {
_subdirFallback = true;
setPath(QLatin1String(owncloudDirC)+QLatin1String(statusphpC));
start();
qDebug() << "Retrying with" << reply()->url();
return false;
}
bool success = false;
QVariantMap status = QtJson::parse(QString::fromUtf8(reply()->readAll()), success).toMap();
// empty or invalid response
@@ -401,7 +421,9 @@ void CheckServerJob::finished()
emit instanceFound(reply()->url(), status);
} else {
qDebug() << "No proper answer on " << requestedUrl;
emit instanceNotFound(reply());
}
return true;
}
/*********************************************************************************************/
@@ -451,7 +473,7 @@ QList<QByteArray> PropfindJob::properties() const
return _properties;
}
void PropfindJob::finished()
bool PropfindJob::finished()
{
int http_result_code = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@@ -486,6 +508,7 @@ void PropfindJob::finished()
qDebug() << "Quota request *not* successful, http result code is" << http_result_code
<< (http_result_code == 302 ? reply()->header(QNetworkRequest::LocationHeader).toString() : QLatin1String(""));
}
return true;
}
/*********************************************************************************************/
@@ -502,9 +525,10 @@ void EntityExistsJob::start()
AbstractNetworkJob::start();
}
void EntityExistsJob::finished()
bool EntityExistsJob::finished()
{
emit exists(reply());
return true;
}
/*********************************************************************************************/
@@ -535,7 +559,7 @@ void CheckQuotaJob::start()
AbstractNetworkJob::start();
}
void CheckQuotaJob::finished()
bool CheckQuotaJob::finished()
{
if (reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 207) {
// Parse DAV response
@@ -560,6 +584,7 @@ void CheckQuotaJob::finished()
qint64 total = quotaUsedBytes + quotaAvailableBytes;
emit quotaRetrieved(total, quotaUsedBytes);
}
return true;
}
NetworkJobTimeoutPauser::NetworkJobTimeoutPauser(QNetworkReply *reply)

View File

@@ -16,6 +16,7 @@
#ifndef NETWORKJOBS_H
#define NETWORKJOBS_H
#include "owncloudlib.h"
#include <QObject>
#include <QNetworkRequest>
#include <QNetworkReply>
@@ -46,7 +47,7 @@ private:
/**
* @brief The AbstractNetworkJob class
*/
class AbstractNetworkJob : public QObject {
class OWNCLOUDSYNC_EXPORT AbstractNetworkJob : public QObject {
Q_OBJECT
public:
explicit AbstractNetworkJob(Account *account, const QString &path, QObject* parent = 0);
@@ -87,7 +88,7 @@ protected:
QNetworkReply* headRequest(const QUrl &url);
int maxRedirects() const { return 10; }
virtual void finished() = 0;
virtual bool finished() = 0;
QString _responseTimestamp;
QElapsedTimer _durationTimer;
quint64 _duration;
@@ -108,7 +109,7 @@ private:
/**
* @brief The EntityExistsJob class
*/
class EntityExistsJob : public AbstractNetworkJob {
class OWNCLOUDSYNC_EXPORT EntityExistsJob : public AbstractNetworkJob {
Q_OBJECT
public:
explicit EntityExistsJob(Account *account, const QString &path, QObject* parent = 0);
@@ -118,13 +119,13 @@ signals:
void exists(QNetworkReply*);
private slots:
virtual void finished();
virtual bool finished();
};
/**
* @brief The LsColJob class
*/
class LsColJob : public AbstractNetworkJob {
class OWNCLOUDSYNC_EXPORT LsColJob : public AbstractNetworkJob {
Q_OBJECT
public:
explicit LsColJob(Account *account, const QString &path, QObject *parent = 0);
@@ -134,7 +135,7 @@ signals:
void directoryListing(const QStringList &items);
private slots:
virtual void finished();
virtual bool finished();
};
/**
@@ -152,7 +153,7 @@ signals:
void result(const QVariantMap &values);
private slots:
virtual void finished();
virtual bool finished();
private:
QList<QByteArray> _properties;
@@ -161,7 +162,7 @@ private:
/**
* @brief The MkColJob class
*/
class MkColJob : public AbstractNetworkJob {
class OWNCLOUDSYNC_EXPORT MkColJob : public AbstractNetworkJob {
Q_OBJECT
public:
explicit MkColJob(Account *account, const QString &path, QObject *parent = 0);
@@ -171,13 +172,13 @@ signals:
void finished(QNetworkReply::NetworkError);
private slots:
virtual void finished();
virtual bool finished();
};
/**
* @brief The CheckServerJob class
*/
class CheckServerJob : public AbstractNetworkJob {
class OWNCLOUDSYNC_EXPORT CheckServerJob : public AbstractNetworkJob {
Q_OBJECT
public:
explicit CheckServerJob(Account *account, bool followRedirect = false, QObject *parent = 0);
@@ -189,14 +190,16 @@ public:
signals:
void instanceFound(const QUrl&url, const QVariantMap &info);
void instanceNotFound(QNetworkReply *reply);
void timeout(const QUrl&url);
private slots:
virtual void finished();
virtual bool finished();
virtual void slotTimeout();
private:
bool _followRedirects;
bool _subdirFallback;
int _redirectCount;
};
@@ -214,7 +217,7 @@ signals:
void etagRetreived(const QString &etag);
private slots:
virtual void finished();
virtual bool finished();
};
/**
@@ -230,7 +233,8 @@ signals:
void quotaRetrieved(qint64 totalBytes, qint64 availableBytes);
private slots:
virtual void finished();
/** Return true if you want the job to be deleted after this slot has finished running. */
virtual bool finished();
};
} // namespace Mirall

View File

@@ -146,6 +146,7 @@ void ownCloudGui::slotOpenPath(const QString &path)
void ownCloudGui::slotAccountStateChanged()
{
setupContextMenu();
slotComputeOverallSyncStatus();
}
void ownCloudGui::startupConnected( bool connected, const QStringList& fails )
@@ -160,6 +161,8 @@ void ownCloudGui::startupConnected( bool connected, const QStringList& fails )
}
_startupFails = fails; // store that for the settings dialog once it appears.
if( !_settingsDialog.isNull() )
_settingsDialog->setGeneralErrors( _startupFails );
}
@@ -171,6 +174,11 @@ void ownCloudGui::slotComputeOverallSyncStatus()
_tray->setToolTip(tr("Please sign in"));
return;
}
if (a->state() == Account::Disconnected) {
_tray->setIcon(Theme::instance()->syncStateIcon( SyncResult::Unavailable, true));
_tray->setToolTip(tr("Disconnected from server"));
return;
}
}
// display the info of the least successful sync (eg. not just display the result of the latest sync
QString trayMessage;

20
src/mirall/owncloudlib.h Normal file
View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) by Olivier Goffart <ogoffart@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#pragma once
#ifdef owncloudsync_EXPORTS
#define OWNCLOUDSYNC_EXPORT Q_DECL_EXPORT
#else
#define OWNCLOUDSYNC_EXPORT Q_DECL_IMPORT
#endif

View File

@@ -45,6 +45,11 @@ void PropagateItemJob::done(SyncFileItem::Status status, const QString &errorStr
if( _item._httpErrorCode == 403 ||_item._httpErrorCode == 413 || _item._httpErrorCode == 415 ) {
qDebug() << "Fatal Error condition" << _item._httpErrorCode << ", forbid retry!";
retries = -1;
#ifdef OWNCLOUD_5XX_NO_BLACKLIST
} else if (_item._httpErrorCode / 100 == 5) {
// In this configuration, never blacklist error 5xx
qDebug() << "Do not blacklist error " << _item._httpErrorCode;
#endif
} else {
static QAtomicInt defaultRetriesCount(qgetenv("OWNCLOUD_BLACKLIST_COUNT").toInt());
if (defaultRetriesCount.fetchAndAddAcquire(0) <= 0) {
@@ -124,7 +129,7 @@ bool PropagateItemJob::checkForProblemsWithShared(int httpStatusCode, const QStr
_restoreJob.reset(newJob);
connect(_restoreJob.data(), SIGNAL(completed(SyncFileItem)),
this, SLOT(slotRestoreJobCompleted(SyncFileItem)));
_restoreJob->start();
QMetaObject::invokeMethod(newJob, "start");
}
return true;
}

View File

@@ -138,7 +138,7 @@ void OwncloudSetupWizard::slotDetermineAuthType(const QString &urlString)
CheckServerJob *job = new CheckServerJob(_ocWizard->account(), false, this);
job->setIgnoreCredentialFailure(true);
connect(job, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotOwnCloudFoundAuth(QUrl,QVariantMap)));
connect(job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotNoOwnCloudFoundAuth(QNetworkReply*)));
connect(job, SIGNAL(instanceNotFound(QNetworkReply*)), SLOT(slotNoOwnCloudFoundAuth(QNetworkReply*)));
connect(job, SIGNAL(timeout(const QUrl&)), SLOT(slotNoOwnCloudFoundAuthTimeout(const QUrl&)));
job->setTimeout(10*1000);
job->start();
@@ -152,7 +152,8 @@ void OwncloudSetupWizard::slotOwnCloudFoundAuth(const QUrl& url, const QVariantM
.arg(CheckServerJob::versionString(info))
.arg(CheckServerJob::version(info)));
if (url.path().endsWith("/status.php")) {
QString p = url.path();
if (p.endsWith("/status.php")) {
// We might be redirected, update the account
QUrl redirectedUrl = url;
redirectedUrl.setPath(url.path().left(url.path().length() - 11));
@@ -355,7 +356,7 @@ bool OwncloudSetupWizard::ensureStartFromScratch(const QString &localFolder) {
QMessageBox::StandardButton but;
but = QMessageBox::question( 0, tr("Folder rename failed"),
tr("Can't remove and back up the folder because the folder or a file in it is open in another program."
"Please close the folder or file and hit retry or cancel the setup."), QMessageBox::Retry | QMessageBox::Abort, QMessageBox::Retry);
" Please close the folder or file and hit retry or cancel the setup."), QMessageBox::Retry | QMessageBox::Abort, QMessageBox::Retry);
if( but == QMessageBox::Abort ) {
break;
}
@@ -446,7 +447,7 @@ void DetermineAuthTypeJob::start()
AbstractNetworkJob::start();
}
void DetermineAuthTypeJob::finished()
bool DetermineAuthTypeJob::finished()
{
QUrl redirection = reply()->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
qDebug() << Q_FUNC_INFO << redirection.toString();
@@ -472,6 +473,7 @@ void DetermineAuthTypeJob::finished()
emit authType(WizardCommon::HttpCreds);
}
}
return true;
}
ValidateDavAuthJob::ValidateDavAuthJob(Account *account, QObject *parent)
@@ -487,9 +489,10 @@ void ValidateDavAuthJob::start()
AbstractNetworkJob::start();
}
void ValidateDavAuthJob::finished()
bool ValidateDavAuthJob::finished()
{
emit authResult(reply());
return true;
}
} // ns Mirall

View File

@@ -39,7 +39,7 @@ public:
signals:
void authResult(QNetworkReply*);
private slots:
void finished();
bool finished();
};
class DetermineAuthTypeJob : public AbstractNetworkJob {
@@ -50,7 +50,7 @@ public:
signals:
void authType(WizardCommon::AuthType);
private slots:
void finished();
bool finished();
private:
int _redirects;
};

View File

@@ -16,10 +16,13 @@
#include <QString>
#include <QVariant>
#ifndef TOKEN_AUTH_ONLY
#include <QPixmap>
#include <QIcon>
#include <QStyle>
#include <QApplication>
#endif
#include <QCoreApplication>
#include <QDebug>
@@ -47,7 +50,7 @@ QString ownCloudTheme::about() const
const QString gitSha1(QLatin1String(GIT_SHA1));
devString = QCoreApplication::translate("ownCloudTheme::about()",
"<p><small>Built from Git revision <a href=\"%1\">%2</a>"
" on %3, %4 using Qt %5.</small><p>")
" on %3, %4 using Qt %5.</small></p>")
.arg(githubPrefix+gitSha1).arg(gitSha1.left(6))
.arg(__DATE__).arg(__TIME__)
.arg(QT_VERSION_STR);
@@ -66,6 +69,7 @@ QString ownCloudTheme::about() const
}
#ifndef TOKEN_AUTH_ONLY
QIcon ownCloudTheme::trayFolderIcon( const QString& ) const
{
QPixmap fallback = qApp->style()->standardPixmap(QStyle::SP_FileDialogNewFolder);
@@ -83,6 +87,8 @@ QIcon ownCloudTheme::applicationIcon( ) const
return themeIcon( QLatin1String("owncloud-icon") );
}
#endif
QVariant ownCloudTheme::customMedia(Theme::CustomMediaType type)
{
if (type == Theme::oCSetupTop) {
@@ -100,6 +106,7 @@ QString ownCloudTheme::helpUrl() const
return QString::fromLatin1("http://doc.owncloud.org/desktop/%1.%2/").arg(MIRALL_VERSION_MAJOR).arg(MIRALL_VERSION_MINOR);
}
#ifndef TOKEN_AUTH_ONLY
QColor ownCloudTheme::wizardHeaderBackgroundColor() const
{
return QColor("#1d2d42");
@@ -114,7 +121,7 @@ QPixmap ownCloudTheme::wizardHeaderLogo() const
{
return QPixmap(":/mirall/theme/colored/wizard_logo.png");
}
#endif
}

View File

@@ -25,21 +25,31 @@ ProgressDispatcher* ProgressDispatcher::_instance = 0;
QString Progress::asResultString( const SyncFileItem& item)
{
switch(item._instruction) {
case CSYNC_INSTRUCTION_CONFLICT:
case CSYNC_INSTRUCTION_SYNC:
case CSYNC_INSTRUCTION_NEW:
if (item._direction != SyncFileItem::Up)
return QCoreApplication::translate( "progress", "Downloaded");
else
return QCoreApplication::translate( "progress", "Uploaded");
case CSYNC_INSTRUCTION_REMOVE:
return QCoreApplication::translate( "progress", "Deleted");
case CSYNC_INSTRUCTION_EVAL_RENAME:
return QCoreApplication::translate( "progress", "Moved to %1").arg(item._renameTarget);
default:
// Should normaly not happen
return QCoreApplication::translate( "progress", "Unknown");
case CSYNC_INSTRUCTION_CONFLICT:
case CSYNC_INSTRUCTION_SYNC:
case CSYNC_INSTRUCTION_NEW:
if (item._direction != SyncFileItem::Up) {
return QCoreApplication::translate( "progress", "Downloaded");
} else {
return QCoreApplication::translate( "progress", "Uploaded");
}
case CSYNC_INSTRUCTION_REMOVE:
return QCoreApplication::translate( "progress", "Deleted");
case CSYNC_INSTRUCTION_EVAL_RENAME:
case CSYNC_INSTRUCTION_RENAME:
return QCoreApplication::translate( "progress", "Moved to %1").arg(item._renameTarget);
case CSYNC_INSTRUCTION_IGNORE:
return QCoreApplication::translate( "progress", "Ignored");
case CSYNC_INSTRUCTION_STAT_ERROR:
return QCoreApplication::translate( "progress", "Filesystem access error");
case CSYNC_INSTRUCTION_ERROR:
return QCoreApplication::translate( "progress", "Error");
case CSYNC_INSTRUCTION_NONE:
case CSYNC_INSTRUCTION_EVAL:
return QCoreApplication::translate( "progress", "Unknown");
}
return QCoreApplication::translate( "progress", "Unknown");
}
QString Progress::asActionString( const SyncFileItem &item )
@@ -55,11 +65,19 @@ QString Progress::asActionString( const SyncFileItem &item )
case CSYNC_INSTRUCTION_REMOVE:
return QCoreApplication::translate( "progress", "deleting");
case CSYNC_INSTRUCTION_EVAL_RENAME:
case CSYNC_INSTRUCTION_RENAME:
return QCoreApplication::translate( "progress", "moving");
default:
// Should normaly not happen
return QCoreApplication::translate( "progress", "processing");
case CSYNC_INSTRUCTION_IGNORE:
return QCoreApplication::translate( "progress", "ignoring");
case CSYNC_INSTRUCTION_STAT_ERROR:
return QCoreApplication::translate( "progress", "error");
case CSYNC_INSTRUCTION_ERROR:
return QCoreApplication::translate( "progress", "error");
case CSYNC_INSTRUCTION_NONE:
case CSYNC_INSTRUCTION_EVAL:
return QCoreApplication::translate( "progress", "unknown");
}
return QCoreApplication::translate( "progress", "unknown");
}
bool Progress::isWarningKind( SyncFileItem::Status kind)

View File

@@ -14,6 +14,7 @@
#ifndef PROGRESSDISPATCHER_H
#define PROGRESSDISPATCHER_H
#include "owncloudlib.h"
#include <QObject>
#include <QHash>
#include <QTime>
@@ -74,10 +75,10 @@ namespace Progress
}
};
QString asActionString( const SyncFileItem& item );
QString asResultString( const SyncFileItem& item );
OWNCLOUDSYNC_EXPORT QString asActionString( const SyncFileItem& item );
OWNCLOUDSYNC_EXPORT QString asResultString( const SyncFileItem& item );
bool isWarningKind( SyncFileItem::Status );
OWNCLOUDSYNC_EXPORT bool isWarningKind( SyncFileItem::Status );
}
@@ -90,7 +91,7 @@ namespace Progress
* or the overall sync progress.
*
*/
class ProgressDispatcher : public QObject
class OWNCLOUDSYNC_EXPORT ProgressDispatcher : public QObject
{
Q_OBJECT

View File

@@ -437,6 +437,8 @@ void PropagateDownloadFileLegacy::notify_status_cb(void* userdata, ne_session_st
}
}
extern QString makeConflictFileName(const QString &fn, const QDateTime &dt); // _qnam.cpp
void PropagateDownloadFileLegacy::start()
{
if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
@@ -564,15 +566,7 @@ void PropagateDownloadFileLegacy::start()
//In case of conflict, make a backup of the old file
if (isConflict) {
QFile f(fn);
QString conflictFileName(fn);
// Add _conflict-XXXX before the extention.
int dotLocation = conflictFileName.lastIndexOf('.');
// If no extention, add it at the end (take care of cases like foo/.hidden or foo.bar/file)
if (dotLocation <= conflictFileName.lastIndexOf('/') + 1) {
dotLocation = conflictFileName.size();
}
QString timeString = Utility::qDateTimeFromTime_t(_item._modtime).toString("yyyyMMdd-hhmmss");
conflictFileName.insert(dotLocation, "_conflict-" + timeString);
QString conflictFileName = makeConflictFileName(fn, Utility::qDateTimeFromTime_t(_item._modtime));
if (!f.rename(conflictFileName)) {
//If the rename fails, don't replace it.
done(SyncFileItem::NormalError, f.errorString());

View File

@@ -19,6 +19,7 @@
#include "syncjournalfilerecord.h"
#include "utility.h"
#include "filesystem.h"
#include "propagatorjobs.h"
#include <QNetworkAccessManager>
#include <QFileInfo>
#include <cmath>
@@ -287,8 +288,6 @@ void PropagateUploadFileQNAM::slotPutFinished()
return;
}
_propagator->_activeJobs--;
// the file id should only be empty for new files up- or downloaded
QByteArray fid = job->reply()->rawHeader("OC-FileID");
if( !fid.isEmpty() ) {
@@ -299,15 +298,30 @@ void PropagateUploadFileQNAM::slotPutFinished()
}
_item._etag = parseEtag(job->reply()->rawHeader("ETag"));
_item._responseTimeStamp = job->responseTimestamp();
if (job->reply()->rawHeader("X-OC-MTime") != "accepted") {
//FIXME
// updateMTimeAndETag(uri.data(), _item._modtime);
done(SyncFileItem::NormalError, tr("No X-OC-MTime extension, ownCloud 5 is required"));
// X-OC-MTime is supported since owncloud 5.0. But not when chunking.
// Normaly Owncloud 6 always put X-OC-MTime
qDebug() << "Server do not support X-OC-MTime";
PropagatorJob *newJob = new UpdateMTimeAndETagJob(_propagator, _item);
QObject::connect(newJob, SIGNAL(completed(SyncFileItem)), this, SLOT(finalize(SyncFileItem)));
QMetaObject::invokeMethod(newJob, "start");
return;
}
finalize(_item);
}
void PropagateUploadFileQNAM::finalize(const SyncFileItem &copy)
{
// Normally, copy == _item, but when it comes from the UpdateMTimeAndETagJob, we need to do
// some updates
_item._etag = copy._etag;
_item._fileId = copy._fileId;
_propagator->_activeJobs--;
_item._requestDuration = _duration.elapsed();
_item._responseTimeStamp = _job->responseTimestamp();
_propagator->_journal->setFileRecord(SyncJournalFileRecord(_item, _propagator->_localDir + _item._file));
// Remove from the progress database:
@@ -358,17 +372,25 @@ void GETFileJob::start() {
void GETFileJob::slotMetaDataChanged()
{
qDebug() << Q_FUNC_INFO << reply()->error() << reply()->errorString() << reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (reply()->error() != QNetworkReply::NoError ) {
// We will handle the error when the job is finished.
return;
}
QByteArray etag = parseEtag(reply()->rawHeader("Etag"));
if (etag.isEmpty()) {
qDebug() << Q_FUNC_INFO << "No E-Tag reply by server, considering it invalid";
_errorString = tr("No E-Tag received from server, check Proxy/Gateway");
_errorStatus = SyncFileItem::NormalError;
reply()->abort();
return;
} else if (!_expectedEtagForResume.isEmpty() && _expectedEtagForResume != etag) {
qDebug() << Q_FUNC_INFO << "We received a different E-Tag for resuming!"
<< _expectedEtagForResume << "vs" << etag;
_errorString = tr("We received a different E-Tag for resuming. Retrying next time.");
_errorStatus = SyncFileItem::NormalError;
reply()->abort();
return;
}
@@ -383,6 +405,7 @@ void GETFileJob::slotReadyRead()
qint64 r = reply()->read(buffer.data(), bufferSize);
if (r < 0) {
_errorString = reply()->errorString();
_errorStatus = SyncFileItem::NormalError;
qDebug() << "Error while reading from device: " << _errorString;
reply()->abort();
return;
@@ -391,6 +414,7 @@ void GETFileJob::slotReadyRead()
qint64 w = _device->write(buffer.constData(), r);
if (w != r) {
_errorString = _device->errorString();
_errorStatus = SyncFileItem::NormalError;
qDebug() << "Error while writing to file" << w << r << _errorString;
reply()->abort();
return;
@@ -497,7 +521,11 @@ void PropagateDownloadFileQNAM::slotGetFinished()
}
_item._httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
_propagator->_activeJobs--;
done(classifyError(err, _item._httpErrorCode), job->errorString());
SyncFileItem::Status status = job->errorStatus();
if (status == SyncFileItem::NoStatus) {
status = classifyError(err, _item._httpErrorCode);
}
done(status, job->errorString());
return;
}
@@ -510,6 +538,27 @@ void PropagateDownloadFileQNAM::slotGetFinished()
downloadFinished();
}
QString makeConflictFileName(const QString &fn, const QDateTime &dt)
{
QString conflictFileName(fn);
// Add _conflict-XXXX before the extention.
int dotLocation = conflictFileName.lastIndexOf('.');
// If no extention, add it at the end (take care of cases like foo/.hidden or foo.bar/file)
if (dotLocation <= conflictFileName.lastIndexOf('/') + 1) {
dotLocation = conflictFileName.size();
}
QString timeString = dt.toString("yyyyMMdd-hhmmss");
// Additional marker
QByteArray conflictFileUserName = qgetenv("CSYNC_CONFLICT_FILE_USERNAME");
if (conflictFileUserName.isEmpty())
conflictFileName.insert(dotLocation, "_conflict-" + timeString);
else
conflictFileName.insert(dotLocation, "_conflict_" + QString::fromUtf8(conflictFileUserName) + "-" + timeString);
return conflictFileName;
}
void PropagateDownloadFileQNAM::downloadFinished()
{
@@ -521,15 +570,7 @@ void PropagateDownloadFileQNAM::downloadFinished()
//In case of conflict, make a backup of the old file
if (isConflict) {
QFile f(fn);
QString conflictFileName(fn);
// Add _conflict-XXXX before the extention.
int dotLocation = conflictFileName.lastIndexOf('.');
// If no extention, add it at the end (take care of cases like foo/.hidden or foo.bar/file)
if (dotLocation <= conflictFileName.lastIndexOf('/') + 1) {
dotLocation = conflictFileName.size();
}
QString timeString = Utility::qDateTimeFromTime_t(_item._modtime).toString("yyyyMMdd-hhmmss");
conflictFileName.insert(dotLocation, "_conflict-" + timeString);
QString conflictFileName = makeConflictFileName(fn, Utility::qDateTimeFromTime_t(_item._modtime));
if (!f.rename(conflictFileName)) {
//If the rename fails, don't replace it.
done(SyncFileItem::NormalError, f.errorString());

View File

@@ -62,8 +62,9 @@ public:
virtual void start();
virtual void finished() {
virtual bool finished() {
emit finishedSignal();
return true;
}
signals:
@@ -90,7 +91,7 @@ private slots:
void slotUploadProgress(qint64,qint64);
void abort();
void startNextChunk();
void finalize(const Mirall::SyncFileItem&);
};
@@ -100,6 +101,7 @@ class GETFileJob : public AbstractNetworkJob {
QMap<QByteArray, QByteArray> _headers;
QString _errorString;
QByteArray _expectedEtagForResume;
SyncFileItem::Status _errorStatus;
public:
// DOES NOT take owncership of the device.
@@ -107,17 +109,21 @@ public:
const QMap<QByteArray, QByteArray> &headers, QByteArray expectedEtagForResume,
QObject* parent = 0)
: AbstractNetworkJob(account, path, parent),
_device(device), _headers(headers), _expectedEtagForResume(expectedEtagForResume) {}
_device(device), _headers(headers), _expectedEtagForResume(expectedEtagForResume),
_errorStatus(SyncFileItem::NoStatus) {}
virtual void start();
virtual void finished() {
virtual bool finished() {
emit finishedSignal();
return true;
}
QString errorString() {
return _errorString.isEmpty() ? reply()->errorString() : _errorString;
};
SyncFileItem::Status errorStatus() { return _errorStatus; }
signals:
void finishedSignal();
void downloadProgress(qint64,qint64);

View File

@@ -181,7 +181,6 @@ void PropagateLocalRename::start()
QFile::rename(_propagator->_localDir + _item._file, _propagator->_localDir + _item._renameTarget);
}
_item._instruction = CSYNC_INSTRUCTION_DELETED;
_propagator->_journal->deleteFileRecord(_item._originalFile);
// store the rename file name in the item.
@@ -323,5 +322,15 @@ bool PropagateNeonJob::updateErrorFromSession(int neon_code, ne_request* req, in
return false;
}
void UpdateMTimeAndETagJob::start()
{
QScopedPointer<char, QScopedPointerPodDeleter> uri(
ne_path_escape((_propagator->_remoteDir + _item._file).toUtf8()));
if (!updateMTimeAndETag(uri.data(), _item._modtime))
return;
done(SyncFileItem::Success);
}
}

View File

@@ -108,4 +108,13 @@ public:
};
// To support older owncloud in the
class UpdateMTimeAndETagJob : public PropagateNeonJob{
Q_OBJECT
public:
UpdateMTimeAndETagJob (OwncloudPropagator* propagator, const SyncFileItem& item) : PropagateNeonJob(propagator, item) {}
void start();
};
}

View File

@@ -69,8 +69,6 @@ void QuotaInfo::slotRequestFailed()
_lastQuotaTotalBytes = 0;
_lastQuotaUsedBytes = 0;
_jobRestartTimer->start(failIntervalT);
_jobRestartTimer->start(failIntervalT);
}
void QuotaInfo::slotCheckQuota()

View File

@@ -46,19 +46,12 @@ QString SslButton::protoToString(QSsl::SslProtocol proto)
}
}
static QString addCertDetailsField(const QString &key, const QString &value, bool tt = false)
static QString addCertDetailsField(const QString &key, const QString &value)
{
if (value.isEmpty())
return QString();
QString row = QString::fromLatin1("<tr><td style=\"vertical-align: top;\"><b>%1</b></td><td style=\"vertical-align: bottom;\">%2</td></tr>").arg(key);
if (tt) {
row = row.arg(QString::fromLatin1("<tt style=\"font-size: small\">%1</tt>").arg(value));
} else {
row = row.arg(value);
}
return row;
return QString::fromLatin1("<tr><td style=\"vertical-align: top;\"><b>%1</b></td><td style=\"vertical-align: bottom;\">%2</td></tr>").arg(key).arg(value);
}
@@ -80,8 +73,16 @@ QMenu* SslButton::buildCertMenu(QMenu *parent, const QSslCertificate& cert,
QString issuer = QStringList(cert.issuerInfo(QSslCertificate::CommonName)).join(QChar(';'));
if (issuer.isEmpty())
issuer = QStringList(cert.issuerInfo(QSslCertificate::OrganizationalUnitName)).join(QChar(';'));
QString md5 = Utility::formatFingerprint(cert.digest(QCryptographicHash::Md5).toHex());
QString sha1 = Utility::formatFingerprint(cert.digest(QCryptographicHash::Sha1).toHex());
QString sha1 = Utility::formatFingerprint(cert.digest(QCryptographicHash::Sha1).toHex(), false);
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QString md5 = Utility::formatFingerprint(cert.digest(QCryptographicHash::Md5).toHex(), false);
#else
QByteArray sha265hash = cert.digest(QCryptographicHash::Sha256).toHex();
QString sha256escaped =
Utility::escape(Utility::formatFingerprint(sha265hash.left(sha265hash.length()/2), false)) +
QLatin1String("<br/>") +
Utility::escape(Utility::formatFingerprint(sha265hash.mid(sha265hash.length()/2), false));
#endif
QString serial = QString::fromUtf8(cert.serialNumber(), true);
QString effectiveDate = cert.effectiveDate().date().toString();
QString expiryDate = cert.expiryDate().date().toString();
@@ -102,7 +103,7 @@ QMenu* SslButton::buildCertMenu(QMenu *parent, const QSslCertificate& cert,
stream << addCertDetailsField(tr("Organizational Unit (OU):"), Utility::escape(ou));
stream << addCertDetailsField(tr("State/Province:"), Utility::escape(state));
stream << addCertDetailsField(tr("Country:"), Utility::escape(country));
stream << addCertDetailsField(tr("Serial:"), Utility::escape(serial), true);
stream << addCertDetailsField(tr("Serial:"), Utility::escape(serial));
stream << QLatin1String("</table>");
stream << tr("<h3>Issuer</h3>");
@@ -116,8 +117,12 @@ QMenu* SslButton::buildCertMenu(QMenu *parent, const QSslCertificate& cert,
stream << tr("<h3>Fingerprints</h3>");
stream << QLatin1String("<table>");
stream << addCertDetailsField(tr("MD 5:"), Utility::escape(md5), true);
stream << addCertDetailsField(tr("SHA-1:"), Utility::escape(sha1), true);
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
stream << addCertDetailsField(tr("MD 5:"), Utility::escape(md5));
#else
stream << addCertDetailsField(tr("SHA-256:"), sha256escaped);
#endif
stream << addCertDetailsField(tr("SHA-1:"), Utility::escape(sha1));
stream << QLatin1String("</table>");
if (userApproved.contains(cert)) {

View File

@@ -39,7 +39,6 @@
#include <QStringList>
#include <QTextStream>
#include <QTime>
#include <QApplication>
#include <QUrl>
#include <QSslCertificate>
@@ -180,7 +179,7 @@ QString SyncEngine::csyncErrorToString(CSYNC_STATUS err)
break;
default:
errStr = tr("An internal error number %1 happend.").arg( (int) err );
errStr = tr("An internal error number %1 happened.").arg( (int) err );
}
return errStr;
@@ -280,6 +279,10 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
case CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS:
item._errorString = tr("File contains invalid characters that can not be synced cross platform.");
break;
case CYSNC_STATUS_FILE_LOCKED_OR_OPEN:
item._errorString = QLatin1String("File locked"); // don't translate, internal use!
break;
default:
Q_ASSERT("Non handled error-status");
/* No error string */
@@ -309,12 +312,12 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
int re = 0;
switch(file->instruction) {
case CSYNC_INSTRUCTION_UPDATED:
// We need to update the database.
_journal->setFileRecord(SyncJournalFileRecord(item, _localPath + item._file));
item._instruction = CSYNC_INSTRUCTION_NONE;
// fall trough
case CSYNC_INSTRUCTION_NONE:
if (file->should_update_etag && !item._isDirectory) {
// Update the database now already (new fileid or etag)
_journal->setFileRecord(SyncJournalFileRecord(item, _localPath + item._file));
item._should_update_etag = false;
}
if (item._isDirectory && remote) {
// Because we want still to update etags of directories
dir = SyncFileItem::None;
@@ -344,7 +347,6 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
case CSYNC_INSTRUCTION_NEW:
case CSYNC_INSTRUCTION_SYNC:
case CSYNC_INSTRUCTION_STAT_ERROR:
case CSYNC_INSTRUCTION_DELETED:
default:
dir = remote ? SyncFileItem::Down : SyncFileItem::Up;
break;
@@ -441,6 +443,7 @@ void SyncEngine::startSync()
// csync_update also opens the database.
int fileRecordCount = 0;
fileRecordCount = _journal->getFileRecordCount();
bool isUpdateFrom_1_5 = _journal->isUpdateFrom_1_5();
_journal->close();
if( fileRecordCount == -1 ) {
@@ -461,6 +464,12 @@ void SyncEngine::startSync()
} else {
qDebug() << "=====sync with existing DB";
}
if (fileRecordCount > 1 && isUpdateFrom_1_5) {
qDebug() << "detected update from 1.5";
// Disable the read from DB to be sure to re-read all the fileid and etags.
csync_set_read_from_db(_csync_ctx, false);
}
}
csync_set_module_property(_csync_ctx, "csync_context", _csync_ctx);
@@ -616,7 +625,7 @@ void SyncEngine::setNetworkLimits()
#endif
;
if( propDownloadLimit + propUploadLimit > 0 ) {
if( propDownloadLimit != 0 || propUploadLimit != 0 ) {
qDebug() << " N------N Network Limits (down/up) " << propDownloadLimit << propUploadLimit;
}
}

View File

@@ -39,12 +39,12 @@ class SyncJournalDb;
class OwncloudPropagator;
void csyncLogCatcher(int /*verbosity*/,
void OWNCLOUDSYNC_EXPORT csyncLogCatcher(int /*verbosity*/,
const char */*function*/,
const char *buffer,
void */*userdata*/);
class SyncEngine : public QObject
class OWNCLOUDSYNC_EXPORT SyncEngine : public QObject
{
Q_OBJECT
public:

View File

@@ -49,7 +49,8 @@ public:
FileIgnored ///< The file is in the ignored list
};
SyncFileItem() : _type(UnknownType), _should_update_etag(false), _blacklistedInDb(false),
SyncFileItem() : _type(UnknownType), _direction(None), _instruction(CSYNC_INSTRUCTION_NONE),
_should_update_etag(false), _blacklistedInDb(false),
_status(NoStatus), _httpErrorCode(0), _requestDuration(0) {}
friend bool operator==(const SyncFileItem& item1, const SyncFileItem& item2) {

View File

@@ -22,6 +22,7 @@
#include "syncjournaldb.h"
#include "syncjournalfilerecord.h"
#include "utility.h"
#include "version.h"
#include "../../csync/src/std/c_jhash.h"
@@ -30,7 +31,7 @@
namespace Mirall {
SyncJournalDb::SyncJournalDb(const QString& path, QObject *parent) :
QObject(parent), _transaction(0)
QObject(parent), _transaction(0), _possibleUpgradeFromMirall_1_5(false)
{
_dbFile = path;
@@ -192,6 +193,35 @@ bool SyncJournalDb::checkConnect()
return sqlFail("Create table blacklist", createQuery);
}
createQuery.prepare("CREATE TABLE IF NOT EXISTS version("
"major INTEGER(8),"
"minor INTEGER(8),"
"patch INTEGER(8),"
"custom VARCHAR(256)"
");");
if (!createQuery.exec()) {
return sqlFail("Create table blacklist", createQuery);
}
QSqlQuery versionQuery("SELECT major, minor FROM version;", _db);
if (!versionQuery.next()) {
// If there was no entry in the table, it means we are likely upgrading from 1.5
_possibleUpgradeFromMirall_1_5 = true;
} else {
// Delete the existing entry so we can replace it by the new one
createQuery.prepare("DELETE FROM version;");
if (!createQuery.exec()) {
return sqlFail("Remove version", createQuery);
}
}
createQuery.prepare("INSERT INTO version (major, minor, patch) VALUES ( ? , ? , ? );");
createQuery.bindValue(0, MIRALL_VERSION_MAJOR);
createQuery.bindValue(1, MIRALL_VERSION_MINOR);
createQuery.bindValue(2, MIRALL_VERSION_PATCH);
if (!createQuery.exec()) {
return sqlFail("Insert Version", createQuery);
}
commitInternal("checkConnect");
bool rc = updateDatabaseStructure();
@@ -260,6 +290,7 @@ void SyncJournalDb::close()
_deleteFileRecordPhash.reset(0);
_deleteFileRecordRecursively.reset(0);
_blacklistQuery.reset(0);
_possibleUpgradeFromMirall_1_5 = false;
_db.close();
_db = QSqlDatabase(); // avoid the warning QSqlDatabasePrivate::removeDatabase: connection [...] still in use
@@ -825,6 +856,13 @@ bool SyncJournalDb::isConnected()
return checkConnect();
}
bool SyncJournalDb::isUpdateFrom_1_5()
{
QMutexLocker lock(&_mutex);
checkConnect();
return _possibleUpgradeFromMirall_1_5;
}
} // namespace Mirall

View File

@@ -21,6 +21,8 @@
#include <QHash>
#include <QSqlQuery>
#include "utility.h"
namespace Mirall {
class SyncJournalFileRecord;
class SyncJournalBlacklistRecord;
@@ -30,7 +32,7 @@ class SyncJournalBlacklistRecord;
*
* This class is thread safe. All public function are locking the mutex.
*/
class SyncJournalDb : public QObject
class OWNCLOUDSYNC_EXPORT SyncJournalDb : public QObject
{
Q_OBJECT
public:
@@ -85,6 +87,12 @@ public:
*/
bool isConnected();
/**
* Tell the sync engine if we need to disable the fetch from db to be sure that the fileid
* are updated.
*/
bool isUpdateFrom_1_5();
@@ -106,6 +114,7 @@ private:
QString _dbFile;
QMutex _mutex; // Public functions are protected with the mutex.
int _transaction;
bool _possibleUpgradeFromMirall_1_5;
QScopedPointer<QSqlQuery> _getFileRecordQuery;
QScopedPointer<QSqlQuery> _setFileRecordQuery;
QScopedPointer<QSqlQuery> _getDownloadInfoQuery;

View File

@@ -19,12 +19,13 @@
#include <QHash>
#include <QDateTime>
#include "owncloudlib.h"
#include "mirall/syncfileitem.h"
namespace Mirall
{
class SyncResult
class OWNCLOUDSYNC_EXPORT SyncResult
{
public:
enum Status

View File

@@ -79,12 +79,6 @@ QString SyncRunFileLog::instructionToStr( csync_instructions_e inst )
case CSYNC_INSTRUCTION_ERROR:
re = "INST_ERROR";
break;
case CSYNC_INSTRUCTION_DELETED:
re = "INST_DELETED";
break;
case CSYNC_INSTRUCTION_UPDATED:
re = "INST_UPDATED";
break;
}
return re;

View File

@@ -17,7 +17,9 @@
#include "config.h"
#include <QtCore>
#ifndef TOKEN_AUTH_ONLY
#include <QtGui>
#endif
#include "mirall/owncloudtheme.h"
@@ -96,6 +98,8 @@ QString Theme::version() const
return QString::fromLocal8Bit( MIRALL_STRINGIFY( MIRALL_VERSION ));
}
#ifndef TOKEN_AUTH_ONLY
QIcon Theme::trayFolderIcon( const QString& backend ) const
{
Q_UNUSED(backend)
@@ -147,6 +151,7 @@ QIcon Theme::themeIcon( const QString& name, bool sysTray ) const
}
return icon;
}
#endif
// if this option return true, the client only supports one folder to sync.
// The Add-Button is removed accoringly.
@@ -207,10 +212,11 @@ QString Theme::about() const
"<p>Distributed by %4 and licensed under the GNU General Public License (GPL) Version 2.0.<br>"
"%5 and the %5 logo are registered trademarks of %4 in the<br>"
"United States, other countries, or both.</p>")
.arg(MIRALL_VERSION_STRING).arg("http://"MIRALL_STRINGIFY(APPLICATION_DOMAIN))
.arg(MIRALL_VERSION_MAJOR).arg("http://" MIRALL_STRINGIFY(APPLICATION_DOMAIN))
.arg(MIRALL_STRINGIFY(APPLICATION_DOMAIN)).arg(APPLICATION_VENDOR).arg(APPLICATION_NAME);
}
#ifndef TOKEN_AUTH_ONLY
QVariant Theme::customMedia( CustomMediaType type )
{
QVariant re;
@@ -305,6 +311,7 @@ QPixmap Theme::wizardHeaderBanner() const
pix.fill(wizardHeaderBackgroundColor());
return pix;
}
#endif
} // end namespace mirall

View File

@@ -28,7 +28,7 @@ namespace Mirall {
class SyncResult;
class Theme : public QObject
class OWNCLOUDSYNC_EXPORT Theme : public QObject
{
Q_OBJECT
public:
@@ -79,6 +79,7 @@ public:
*/
virtual QString configFileName() const = 0;
#ifndef TOKEN_AUTH_ONLY
/**
* the icon that is shown in the tray context menu left of the folder name
*/
@@ -91,6 +92,7 @@ public:
virtual QIcon folderDisabledIcon() const = 0;
virtual QIcon applicationIcon() const = 0;
#endif
virtual QString statusHeaderText( SyncResult::Status ) const;
virtual QString version() const;
@@ -130,6 +132,7 @@ public:
/** colored, white or black */
QString systrayIconFlavor(bool mono) const;
#ifndef TOKEN_AUTH_ONLY
/**
* Override to use a string or a custom image name.
* The default implementation will try to look up
@@ -154,6 +157,7 @@ public:
* @return banner for the setup wizard.
*/
virtual QPixmap wizardHeaderBanner() const;
#endif
/**
* About dialog contents

View File

@@ -22,16 +22,17 @@
#include <QDir>
#include <QFile>
#include <QUrl>
#ifndef TOKEN_AUTH_ONLY
#include <QWidget>
#include <QDebug>
#include <QDesktopServices>
#endif
#include <QDebug>
#include <QProcess>
#include <QThread>
#include <QDateTime>
#include <QSysInfo>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <QDesktopServices>
#include <QTextDocument>
#else
#include <QStandardPaths>
@@ -80,7 +81,7 @@ bool Utility::writeRandomFile( const QString& fname, int size )
}
QString Utility::formatFingerprint( const QByteArray& fmhash )
QString Utility::formatFingerprint( const QByteArray& fmhash, bool colonSeparated )
{
QByteArray hash;
int steps = fmhash.length()/2;
@@ -91,7 +92,9 @@ QString Utility::formatFingerprint( const QByteArray& fmhash )
}
QString fp = QString::fromLatin1( hash.trimmed() );
fp.replace(QChar(' '), QChar(':'));
if (colonSeparated) {
fp.replace(QChar(' '), QChar(':'));
}
return fp;
}
@@ -163,9 +166,11 @@ QByteArray Utility::userAgentString()
void Utility::raiseDialog( QWidget *raiseWidget )
{
#ifndef TOKEN_AUTH_ONLY
// viel hilft viel ;-)
if( raiseWidget ) {
#if defined(Q_OS_WIN) || defined (Q_OS_MAC)
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) && \
(defined(Q_OS_WIN) || defined (Q_OS_MAC))
Qt::WindowFlags eFlags = raiseWidget->windowFlags();
if (!(eFlags & Qt::WindowStaysOnTopHint)) {
eFlags |= Qt::WindowStaysOnTopHint;
@@ -179,6 +184,7 @@ void Utility::raiseDialog( QWidget *raiseWidget )
raiseWidget->raise();
raiseWidget->activateWindow();
}
#endif
}
bool Utility::hasLaunchOnStartup(const QString &appName)
@@ -257,10 +263,12 @@ QString Utility::escape(const QString &in)
QString Utility::dataLocation()
{
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// Qt 5's QStandardPaths::writableLocation gives us wrong results (without /data/),
// so we'll have to use the deprecated version for now
#ifndef TOKEN_AUTH_ONLY
return QDesktopServices::storageLocation(QDesktopServices::DataLocation);
#else
return QStandardPaths::writableLocation(QStandardPaths::DataLocation);
return QString();
#endif
}
@@ -435,7 +443,9 @@ void Utility::showInFileManager(const QString &localPath)
if (app.isEmpty() || args.isEmpty() || !canHandleFile) {
// fall back: open the default file manager, without ever selecting the file
#ifndef TOKEN_AUTH_ONLY
QDesktopServices::openUrl(QUrl::fromLocalFile(pathToOpen));
#endif
} else {
QProcess::startDetached(app, args);
}
@@ -504,6 +514,13 @@ void Utility::StopWatch::stop()
_timer.invalidate();
}
void Utility::StopWatch::reset()
{
_timer.invalidate();
_startTime.setMSecsSinceEpoch(0);
_lapTimes.clear();
}
quint64 Utility::StopWatch::addLapTime( const QString& lapName )
{
if( !_timer.isValid() ) {

View File

@@ -15,6 +15,7 @@
#ifndef UTILITY_H
#define UTILITY_H
#include "owncloudlib.h"
#include <QString>
#include <QByteArray>
#include <QDateTime>
@@ -27,20 +28,20 @@ namespace Mirall {
namespace Utility
{
void sleep(int sec);
void usleep(int usec);
QString formatFingerprint( const QByteArray& );
void setupFavLink( const QString &folder );
bool writeRandomFile( const QString& fname, int size = -1);
QString octetsToString( qint64 octets );
QString platform();
QByteArray userAgentString();
void raiseDialog(QWidget *);
bool hasLaunchOnStartup(const QString &appName);
void setLaunchOnStartup(const QString &appName, const QString& guiName, bool launch);
qint64 freeDiskSpace(const QString &path, bool *ok = 0);
QString toCSyncScheme(const QString &urlStr);
void showInFileManager(const QString &localPath);
OWNCLOUDSYNC_EXPORT void sleep(int sec);
OWNCLOUDSYNC_EXPORT void usleep(int usec);
OWNCLOUDSYNC_EXPORT QString formatFingerprint( const QByteArray&, bool colonSeparated = true );
OWNCLOUDSYNC_EXPORT void setupFavLink( const QString &folder );
OWNCLOUDSYNC_EXPORT bool writeRandomFile( const QString& fname, int size = -1);
OWNCLOUDSYNC_EXPORT QString octetsToString( qint64 octets );
OWNCLOUDSYNC_EXPORT QString platform();
OWNCLOUDSYNC_EXPORT QByteArray userAgentString();
OWNCLOUDSYNC_EXPORT void raiseDialog(QWidget *);
OWNCLOUDSYNC_EXPORT bool hasLaunchOnStartup(const QString &appName);
OWNCLOUDSYNC_EXPORT void setLaunchOnStartup(const QString &appName, const QString& guiName, bool launch);
OWNCLOUDSYNC_EXPORT qint64 freeDiskSpace(const QString &path, bool *ok = 0);
OWNCLOUDSYNC_EXPORT QString toCSyncScheme(const QString &urlStr);
OWNCLOUDSYNC_EXPORT void showInFileManager(const QString &localPath);
/** Like QLocale::toString(double, 'f', prec), but drops trailing zeros after the decimal point */
/**
@@ -51,22 +52,22 @@ namespace Utility
* @param unit an optional unit that is appended if present.
* @return the formatted string.
*/
QString compactFormatDouble(double value, int prec, const QString& unit = QString::null);
OWNCLOUDSYNC_EXPORT QString compactFormatDouble(double value, int prec, const QString& unit = QString::null);
// porting methods
QString escape(const QString&);
QString dataLocation();
OWNCLOUDSYNC_EXPORT QString escape(const QString&);
OWNCLOUDSYNC_EXPORT QString dataLocation();
// conversion function QDateTime <-> time_t (because the ones builtin work on only unsigned 32bit)
QDateTime qDateTimeFromTime_t(qint64 t);
qint64 qDateTimeToTime_t(const QDateTime &t);
OWNCLOUDSYNC_EXPORT QDateTime qDateTimeFromTime_t(qint64 t);
OWNCLOUDSYNC_EXPORT qint64 qDateTimeToTime_t(const QDateTime &t);
// convinience OS detection methods
bool isWindows();
bool isMac();
bool isUnix();
bool isLinux(); // use with care
OWNCLOUDSYNC_EXPORT bool isWindows();
OWNCLOUDSYNC_EXPORT bool isMac();
OWNCLOUDSYNC_EXPORT bool isUnix();
OWNCLOUDSYNC_EXPORT bool isLinux(); // use with care
class StopWatch {
private:
@@ -77,6 +78,7 @@ namespace Utility
void start();
void stop();
quint64 addLapTime( const QString& lapName );
void reset();
// out helpers, return the masured times.
QDateTime startTime() const;

View File

@@ -26,17 +26,30 @@ static void setupFavLink_private(const QString &folder) {
}
}
// returns the autostart directory the linux way
// and respects the XDG_CONFIG_HOME env variable
// can be replaces for qt5 with QStandardPaths
QString getUserAutostartDir_private()
{
QString config = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
if (config.isEmpty()) {
config = QDir::homePath()+QLatin1String("/.config");
}
config += QLatin1String("/autostart/");
return config;
}
bool hasLaunchOnStartup_private(const QString &appName)
{
QString userAutoStartPath = QDir::homePath()+QLatin1String("/.config/autostart/");
QString desktopFileLocation = userAutoStartPath+appName+QLatin1String(".desktop");
QString desktopFileLocation = getUserAutostartDir_private()+appName+QLatin1String(".desktop");
return QFile::exists(desktopFileLocation);
}
void setLaunchOnStartup_private(const QString &appName, const QString& guiName, bool enable)
{
QString userAutoStartPath = QDir::homePath()+QLatin1String("/.config/autostart/");
QString userAutoStartPath = getUserAutostartDir_private();
QString desktopFileLocation = userAutoStartPath+appName+QLatin1String(".desktop");
if (enable) {
if (!QDir().exists(userAutoStartPath) && !QDir().mkdir(userAutoStartPath)) {

View File

@@ -110,7 +110,7 @@ void parseOptions( const QStringList& app_args, CmdOptions *options )
options->target_url.replace(0, 4, "owncloud");
options->source_dir = args.takeLast();
if( !QFile::exists( options->source_dir )) {
std::cerr << "Source dir does not exists.";
std::cerr << "Source dir does not exists." << std::endl;
exit(1);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More