Comparar commits

..

2 Commits

Autor SHA1 Mensagem Data
Olivier Goffart 2039cfb56c PropagateDownload: disable fallback to owncloud if direct download fails 2015-09-18 15:15:07 +02:00
Christian Kamm 17b4c0e3bd Nicer fix for the security issue #3283.
(cherry picked from commit 89376e14d6)
2015-09-18 15:14:43 +02:00
161 arquivos alterados com 14459 adições e 23151 exclusões
+1 -1
Ver Arquivo
@@ -165,13 +165,13 @@ endif()
find_package(Sphinx)
find_package(PdfLatex)
find_package(SQLite3 3.8.0 REQUIRED)
# On some OS, we want to use our own, not the system sqlite
if (USE_OUR_OWN_SQLITE3)
include_directories(BEFORE ${SQLITE3_INCLUDE_DIR})
endif()
find_package(ZLIB)
configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+1 -84
Ver Arquivo
@@ -1,89 +1,6 @@
ChangeLog
=========
version 1.8.2 (release 2015-05-xx)
* Improve reporting of server error messages. (#3220)
* Discovery: Ignore folders with any 503. (#3113)
* Wizard: Show server error message if possible. (#3220)
* QNAM: Fix handling of mitm cert changes (#3283)
* Some more NSIS fixes, translations added
* Win32: Make Setup/Update Mutex theme-unique (#3272)
* HTTP: Add the branding name to the UserAgent string.
* ConnectonValidator: Always run with new credentials. (#3266)
* Recall Feature: Admins can trigger an upload of a file from
client to server again
* Propagator: Add 'Content-Length: 0' header to MKCOL request
* Switch on checksum verification through branding or config
* Add ability for checksum verification of up and download
* Fix opening external links for some labels (#3135)
* AccountState: Run only a single validator, allow error message
overriding (#3236 #3153)
* SyncJournalDB: Minor fixes and simplificatons
* SyncEngine: Force re-read of folder Etags for upgrades from
1.8.0 and 1.8.1
* Propagator: Limit length of temporary file name #2789
* ShareDialog: Password ui fixes. #3189
* Fix startup hang by removing QSettings lock file. (#3175)
* Wizard: Allow SSL cert dialog to show twice. (#3168)
* ProtocolWidget: Fix rename message. (#3210)
* Discovery: Test better, treat invalid hrefs as error (#3176)
* Propagator: Overwrite local data only if unchanged. (#3156)
* ShareDialog: Improve error reporting for share API fails
* OSX Updater: Only allow if in /Applications (#2931)
* Wizard: Fix lock icon (#1447)
* Fix compile with gcc 5
* Treat any 503 error as temporary (#3113)
* Work around for the Qt PUT corruption bug (#2425)
* OSX Shell integration: Optimizations
* Windows Shell integration: Optimizations
.. more than 250 commits since 1.8.1
version 1.8.1 (release 2015-05-07)
* Make "operation canceled" error a soft error
* Do not throw an error for files that are scheduled to be removed,
but can not be found on the server. #2919
* Windows: Reset QNAM to proper function after hibernation. #2899 #2895 #2973
* Fix argument verification of --confdir #2453
* Fix a crash when accessing a dangling UploadDevice pointer #2984
* Add-folder wizard: Make sure there is a scrollbar if folder names
are too long #2962
* Add-folder Wizard: Select the newly created folder
* Activity: Correctly restore column sizes #3005
* SSL Button: do not crash on empty certificate chain
* SSL Button: Make menu creation lazy #3007 #2990
* Lookup system proxy async to avoid hangs #2993 #2802
* ShareDialog: Some GUI refinements
* ShareDialog: On creation of a share always retrieve the share
This makes sure that if a default expiration date is set this is reflected
in the dialog. #2889
* ShareDialog: Only show share dialog if we are connected.
* HttpCreds: Fill pw dialog with previous password. #2848 #2879
* HttpCreds: Delete password from old location. #2186
* Do not store Session Cookies in the client cookie storage
* CookieJar: Don't accidentally overwrite cookies. #2808
* ProtocolWidget: Always add seconds to the DateTime locale. #2535
* Updater: Give context as to which app is about to be updated #3040
* Windows: Add version information for owncloud.exe. This should help us know
what version or build number a crash report was generated with.
* Fix a crash on shutdown in ~SocketApi #3057
* SyncEngine: Show more timing measurements #3064
* Discovery: Add warning if returned etag is 0
* Fix a crash caused by an invalid DiscoveryDirectoryResult::iterator #3051
* Sync: Fix sync of deletions during 503. #2894
* Handle redirect of auth request. #3082
* Discovery: Fix parsing of broken XML replies, which fixes local file disappearing #3102
* Migration: Silently restore files that were deleted locally by bug #3102
* Sort folder sizes SelectiveSyncTreeView numerically #3112
* Sync: PropagateDownload: Read the mtime from the file system after writing it #3103
* Sync: Propagate download: Fix restoring files for which the conflict file exists #3106
* Use identical User Agents and version for csync and the Qt parts
* Prevent another crash in ~SocketApi #3118
* Windows: Fix rename of finished file. #3073
* AccountWizard: Fix auth error handling. #3155
* Documentation fixes
* Infrastructure/build fixes
* Win32/OS X: Apply patch from OpenSSL to handle oudated intermediates gracefully #3087
version 1.8.0 (release 2015-03-17)
version 1.8.0 (release 2015-03-xx)
* Mac OS: HIDPI support
* Support Sharing from desktop: Added a share dialog that can be
opened by context menu in the file managers (Win, Mac, Nautilus)
+2 -2
Ver Arquivo
@@ -1,10 +1,10 @@
set( MIRALL_VERSION_MAJOR 1 )
set( MIRALL_VERSION_MINOR 8 )
set( MIRALL_VERSION_PATCH 2 )
set( MIRALL_VERSION_PATCH 0 )
set( MIRALL_SOVERSION 0 )
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
set( MIRALL_VERSION_SUFFIX "rc1") #e.g. beta1, beta2, rc1
set( MIRALL_VERSION_SUFFIX "") #e.g. beta1, beta2, rc1
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
if( NOT DEFINED MIRALL_VERSION_BUILD )
+1 -1
Ver Arquivo
@@ -50,7 +50,7 @@ if [ ! -z "$identity" ]; then
echo "Will try to sign the installer"
pushd $install_path
productsign --sign "$identity" "$installer_file" "$installer_file.new"
mv "$installer_file".new "$installer_file"
mv "$installer_file".new $installer_file
popd
else
echo "No certificate given, will not sign the pkg"
+2 -8
Ver Arquivo
@@ -260,18 +260,12 @@ def CopyFramework(path):
commands.append(args)
args = ['chmod', 'u+w', os.path.join(full_path, parts[-1])]
commands.append(args)
resources_dir = os.path.join(frameworks_dir, framework, "Resources")
args = ['mkdir', resources_dir]
commands.append(args)
args = ['chmod', 'u+w', resources_dir]
args = ['chmod', 'u+w', os.path.join(frameworks_dir, framework, "Resources")]
commands.append(args)
info_plist = os.path.join(os.path.split(path)[0], '..', '..', 'Contents', 'Info.plist')
if not os.path.exists(info_plist):
info_plist = os.path.join(os.path.split(path)[0], 'Resources', 'Info.plist')
if os.path.exists(info_plist):
args = ['cp', '-r', info_plist, resources_dir]
args = ['cp', '-r', info_plist, os.path.join(frameworks_dir, framework, "Resources")]
commands.append(args)
return os.path.join(full_path, parts[-1])
+2 -2
Ver Arquivo
@@ -1,4 +1,4 @@
#!/bin/sh -xe
#!/bin/sh -x
[ "$#" -lt 2 ] && echo "Usage: sign_app.sh <app> <identity>" && exit
@@ -7,6 +7,6 @@ identity="$2"
codesign -s "$identity" --force --verbose=4 --deep "$src_app"
# Verify the signature
# Just for our debug purposes:
spctl -a -t exec -vv $src_app
codesign -dv $src_app
+2 -7
Ver Arquivo
@@ -1,11 +1,6 @@
#!/bin/bash
if [ $# -lt 1 ]; then
echo "Usage: $(basename $0) directory_relative_to_home [uid]"
exit
fi
useradd user -u ${2:-1000}
useradd user
su - user << EOF
cd /home/user/$1
rm -rf build-win32
@@ -15,5 +10,5 @@ cd build-win32
cmake .. -DCMAKE_TOOLCHAIN_FILE=../admin/win/Toolchain-mingw32-openSUSE.cmake -DWITH_CRASHREPORTER=ON
make -j4
make package
ctest .
EOF
+24 -24
Ver Arquivo
@@ -10,25 +10,24 @@ minimum_perc = 5
# simple one-to-one language mappings
trans.ca = pofiles/ca.po
trans.el = pofiles/el.po
trans.es_AR = pofiles/es_AR.po
trans.es = pofiles/es.po
trans.eu = pofiles/eu.po
trans.fa = pofiles/fa.po
trans.fr = pofiles/fr.po
trans.gl = pofiles/gl.po
trans.it = pofiles/it.po
trans.nb_NO = pofiles/nb_NO.po
trans.nl = pofiles/nl.po
trans.pl = pofiles/pl.po
trans.pt_BR = pofiles/pt_BR.po
trans.ru = pofiles/ru.po
trans.el = pofiles/el.po
trans.es = pofiles/es.po
trans.es_AR = pofiles/es_AR.po
trans.eu = pofiles/eu.po
trans.fa = pofiles/fa.po
trans.fr = pofiles/fr.po
trans.gl = pofiles/gl.po
trans.it = pofiles/it.po
trans.nl = pofiles/nl.po
trans.pl = pofiles/pl.po
trans.pt_BR = pofiles/pt_BR.po
trans.ru = pofiles/ru.po
trans.sl = pofiles/sl.po
trans.sv = pofiles/sv.po
trans.tr = pofiles/tr.po
trans.uk = pofiles/uk.po
trans.zh_CN = pofiles/zh_CN.po
trans.zh_TW = pofiles/zh_TW.po
trans.uk = pofiles/uk.po
trans.zh_TW = pofiles/zh_TW.po
trans.zh_CN = pofiles/zh_CN.po
# special handling below
@@ -36,13 +35,14 @@ trans.zh_TW = pofiles/zh_TW.po
trans.de_DE = pofiles/de.po
# choose one of the given translations on transifex as default
trans.pt_PT = pofiles/pt.po
trans.pt_PT = pofiles/pt.po
# choose a special language as more generic default
trans.cs_CZ = pofiles/cs.po
trans.et_EE = pofiles/et.po
trans.fi_FI = pofiles/fi.po
trans.hu_HU = pofiles/hu.po
trans.ja_JP = pofiles/ja.po
trans.sk_SK = pofiles/sk.po
trans.th_TH = pofiles/th.po
trans.cs_CZ = pofiles/cs.po
trans.et_EE = pofiles/et.po
trans.fi_FI = pofiles/fi.po
trans.ja_JP = pofiles/ja.po
trans.hu_HU = pofiles/hu.po
trans.sk_SK = pofiles/sk.po
trans.th_TH = pofiles/th.po
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
# Auto-generated - do not modify
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Afficher les notes de version"
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Les processus ${APPLICATION_EXECUTABLE} en cours dexécution doivent être stoppés avant de poursuivre.$\nVoulez-vous que le programme dinstallation sen charge pour vous ?"
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Le(s) processus en cours dexécution ${APPLICATION_EXECUTABLE} doit (doivent) être stoppé(s) afin de poursuivre.$\nVoulez-vous que le programme dinstallation sen charge pour vous ?"
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Fermeture des processus ${APPLICATION_EXECUTABLE}."
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Le processus à stopper n'a pas été trouvé !"
StrCpy $PageReinstall_NEW_Field_1 "Une ancienne version de ${APPLICATION_NAME} est installée sur votre système. Il est recommandé de désinstaller cette version avant de continuer. Sélectionnez l'opération que vous voulez exécuter et cliquez sur Suivant pour continuer."
+2 -2
Ver Arquivo
@@ -39,8 +39,8 @@ StrCpy $UNINSTALL_ABORT "A desinstalaci
StrCpy $INIT_NO_QUICK_LAUNCH "Acceso de inicio rápido (n/d)"
StrCpy $INIT_NO_DESKTOP "Atallo no escritorio (sobrescribe o existente)"
StrCpy $UAC_ERROR_ELEVATE "Non foi posíbel elevalo, erro:"
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Este instalador require acceso de administrador, ténteo de novo"
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Este instalador require acceso de administrador, tenteo de novo"
StrCpy $INIT_INSTALLER_RUNNING "O instalador xa está en execución."
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Este desinstalador require acceso de administrador, ténteo de novo"
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Este desinstalador require acceso de administrador, tenteo de novo"
StrCpy $INIT_UNINSTALLER_RUNNING "O desinstalador xa está en execución."
StrCpy $SectionGroup_Shortcuts "Atallos"
-46
Ver Arquivo
@@ -1,46 +0,0 @@
# Auto-generated - do not modify
StrCpy $MUI_FINISHPAGE_SHOWREADME_TEXT_STRING "Vis versjonsmerknader"
StrCpy $ConfirmEndProcess_MESSAGEBOX_TEXT "Fant ${APPLICATION_EXECUTABLE}-prosess(er) som må stoppes.$\nVil du at installasjonsprogrammet skal stoppe dem for deg?"
StrCpy $ConfirmEndProcess_KILLING_PROCESSES_TEXT "Terminerer ${APPLICATION_EXECUTABLE}-prosesser."
StrCpy $ConfirmEndProcess_KILL_NOT_FOUND_TEXT "Fant ikke prosess som skulle termineres!"
StrCpy $PageReinstall_NEW_Field_1 "En eldre versjon av ${APPLICATION_NAME} er installert på systemet ditt. Det anbefales at du avnistallerer den versjonen før installering av ny versjon. Velg hva du vil gjøre og klikk Neste for å fortsette."
StrCpy $PageReinstall_NEW_Field_2 "Avinstaller før installering"
StrCpy $PageReinstall_NEW_Field_3 "Ikke avinstaller"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_TITLE "Allerede installert"
StrCpy $PageReinstall_NEW_MUI_HEADER_TEXT_SUBTITLE "Velg hvordan du vil installere ${APPLICATION_NAME}."
StrCpy $PageReinstall_OLD_Field_1 "En nyere versjon av ${APPLICATION_NAME} er allerede installert! Det anbefales ikke at du installerer en eldre versjon. Hvis du virkelig ønsker å installere denne eldre versjonen, er det bedre å avinstallere gjeldende versjon først. Velg hva du vil gjøre og klikk Neste for å fortsette."
StrCpy $PageReinstall_SAME_Field_1 "${APPLICATION_NAME} ${VERSION} er allerede installert.\nVelg hva du vil gjøre og klikk Neste for å fortsette."
StrCpy $PageReinstall_SAME_Field_2 "Legg til/installer komponenter på nytt"
StrCpy $PageReinstall_SAME_Field_3 "Avinstaller ${APPLICATION_NAME}"
StrCpy $UNINSTALLER_APPDATA_TITLE "Avinstaller ${APPLICATION_NAME}"
StrCpy $PageReinstall_SAME_MUI_HEADER_TEXT_SUBTITLE "Velg hva slags vedlikehold som skal utføres."
StrCpy $SEC_APPLICATION_DETAILS "Installerer ${APPLICATION_NAME} grunnleggende."
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integrering med Windows Utforsker"
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "Installerer integrering med Windows Utforsker"
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Snarvei i Start-menyen"
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "Legger til snarvei for ${APPLICATION_NAME} i Start-menyen."
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Snarvei på skrivebordet"
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "Oppretter snarveier på skrivebordet"
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Snarvei i Hurtigstart"
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_DetailPrint "Oppretter snarvei i Hurtigstart"
StrCpy $OPTION_SECTION_SC_APPLICATION_Desc "${APPLICATION_NAME} grunnleggende."
StrCpy $OPTION_SECTION_SC_START_MENU_Desc "${APPLICATION_NAME}-snarvei."
StrCpy $OPTION_SECTION_SC_DESKTOP_Desc "Skrivebordssnarvei for ${APPLICATION_NAME}."
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_Desc "Hurtigstart-snarvei for ${APPLICATION_NAME}."
StrCpy $UNINSTALLER_APPDATA_SUBTITLE "Fjern ${APPLICATION_NAME} sin datamappe fra datamaskinen."
StrCpy $UNINSTALLER_APPDATA_LABEL_1 "Ønsker du å slette ${APPLICATION_NAME} sin datamappe?"
StrCpy $UNINSTALLER_APPDATA_LABEL_2 "Ikke kryss av dersom du vil beholde datamappen for senere bruk. Kryss av for å slette mappen."
StrCpy $UNINSTALLER_APPDATA_CHECKBOX "Ja, slett denne datamappen."
StrCpy $UNINSTALLER_FILE_Detail "Skriver Avinstallasjonsprogram."
StrCpy $UNINSTALLER_REGISTRY_Detail "Skriver registernøkler for installasjonsprogrammet"
StrCpy $UNINSTALLER_FINISHED_Detail "Ferdig"
StrCpy $UNINSTALL_MESSAGEBOX "Det ser ikke ut som ${APPLICATION_NAME} er installert i mappe '$INSTDIR'.$\n$\nFortsett likevel (ikke anbefalt)?"
StrCpy $UNINSTALL_ABORT "Avinstallering avbrutt av bruker"
StrCpy $INIT_NO_QUICK_LAUNCH "Hurtigstart-snarvei (I/T)"
StrCpy $INIT_NO_DESKTOP "Snarvei på skrivebordet (skriver over eksisterende)"
StrCpy $UAC_ERROR_ELEVATE "Klarte ikke å heve tilgangsnivå. Feil: "
StrCpy $UAC_INSTALLER_REQUIRE_ADMIN "Dette installasjonsprogrammet krever administrasjonstilgang. Prøv igjen"
StrCpy $INIT_INSTALLER_RUNNING "Installasjonsprogrammet kjører allerede."
StrCpy $UAC_UNINSTALLER_REQUIRE_ADMIN "Avinstallasjonsprogrammet krever administrasjonstilgang. Prøv igjen"
StrCpy $INIT_UNINSTALLER_RUNNING "Avinstallasjonsprogrammet kjører allerede."
StrCpy $SectionGroup_Shortcuts "Snarveier"
+1 -1
Ver Arquivo
@@ -67,7 +67,7 @@ localeToName = {
"mg" : "Malagasy",
"ms" : "Malay",
"mn" : "Mongolian",
"nb_NO" : "Norwegian",
"nb" : "Norwegian",
"nn" : "NorwegianNynorsk",
"ps" : "Pashto",
"pl" : "Polish",
-1
Ver Arquivo
@@ -44,6 +44,5 @@ iconv -t CP1252 -o Finnish.nsh Finnish.nsh
iconv -t CP932 -o Japanese.nsh Japanese.nsh
iconv -t CP1250 -o Slovak.nsh Slovak.nsh
iconv -t CP1254 -o Turkish.nsh Turkish.nsh
iconv -t CP1252 -o Norwegian.nsh Norwegian.nsh
+1 -2
Ver Arquivo
@@ -8,14 +8,13 @@
!insertmacro MUI_LANGUAGE "Hungarian"
!insertmacro MUI_LANGUAGE "Ukrainian"
!insertmacro MUI_LANGUAGE "French"
!insertmacro MUI_LANGUAGE "Norwegian"
!insertmacro MUI_LANGUAGE "Catalan"
!insertmacro MUI_LANGUAGE "Russian"
!insertmacro MUI_LANGUAGE "Finnish"
!insertmacro MUI_LANGUAGE "Basque"
!insertmacro MUI_LANGUAGE "Greek"
!insertmacro MUI_LANGUAGE "SimpChinese"
!insertmacro MUI_LANGUAGE "PortugueseBR"
!insertmacro MUI_LANGUAGE "Catalan"
!insertmacro MUI_LANGUAGE "Italian"
!insertmacro MUI_LANGUAGE "Portuguese"
!insertmacro MUI_LANGUAGE "German"
+1 -1
Submodule binary updated: 8b72648a93...1fb9ddfa9a
+6 -10
Ver Arquivo
@@ -175,11 +175,10 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${VERSION}"
StrCmp $LANGUAGE ${LANG_ITALIAN} Italian 0
StrCmp $LANGUAGE ${LANG_ESTONIAN} Estonian 0
StrCmp $LANGUAGE ${LANG_GREEK} Greek 0
StrCmp $LANGUAGE ${LANG_BASQUE} Basque 0
StrCmp $LANGUAGE ${LANG_GALICIAN} Galician 0
StrCmp $LANGUAGE ${LANG_SLOVAC} Slovak 0
StrCmp $LANGUAGE ${LANG_TURKISH} Turkish 0
StrCmp $LANGUAGE ${LANG_NORWEGIAN} Norwegian 0
StrCmp $LANGUAGE ${LANG_GREEK} Basque 0
StrCmp $LANGUAGE ${LANG_GREEK} Galician 0
StrCmp $LANGUAGE ${LANG_GREEK} Slovak 0
StrCmp $LANGUAGE ${LANG_GREEK} Turkish 0
StrCmp $LANGUAGE ${LANG_PORTUGUESEBR} Brazilian EndLanguageCmp
German:
!include "${source_path}/admin/win/nsi/l10n\German.nsh"
@@ -222,9 +221,6 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${VERSION}"
Goto EndLanguageCmp
Brazilian:
!include "${source_path}/admin/win/nsi/l10n\PortugueseBR.nsh"
Goto EndLanguageCmp
Norwegian:
!include "${source_path}/admin/win/nsi/l10n\Norwegian.nsh"
EndLanguageCmp:
FunctionEnd
@@ -781,7 +777,7 @@ Function .onInit
goto UAC_Elevate
;Prevent multiple instances.
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${APPLICATION_SHORTNAME}Installer") i .r1 ?e'
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "owncloudInstaller") i .r1 ?e'
Pop $R0
StrCmp $R0 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION $INIT_INSTALLER_RUNNING
@@ -846,7 +842,7 @@ Function un.onInit
goto UAC_Elevate
;Prevent multiple instances.
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${APPLICATION_SHORTNAME}Uninstaller") i .r1 ?e'
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "owncloudUninstaller") i .r1 ?e'
Pop $R0
StrCmp $R0 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION $INIT_UNINSTALLER_RUNNING
-1
Ver Arquivo
@@ -17,7 +17,6 @@ if( Qt5Core_FOUND )
message(STATUS "Found Qt5 core, checking for further dependencies...")
find_package(Qt5Network REQUIRED)
find_package(Qt5Xml REQUIRED)
find_package(Qt5Concurrent REQUIRED)
if(NOT TOKEN_AUTH_ONLY)
find_package(Qt5WebKitWidgets REQUIRED)
find_package(Qt5WebKit REQUIRED)
-2
Ver Arquivo
@@ -19,8 +19,6 @@
#cmakedefine APPLICATION_EXECUTABLE "@APPLICATION_EXECUTABLE@"
#cmakedefine APPLICATION_UPDATE_URL "@APPLICATION_UPDATE_URL@"
#cmakedefine ZLIB_FOUND @ZLIB_FOUND@
#cmakedefine SYSCONFDIR "@SYSCONFDIR@"
#cmakedefine DATADIR "@DATADIR@"
+7 -1
Ver Arquivo
@@ -3,7 +3,13 @@
# global needed variables
set(APPLICATION_NAME "ocsync")
set(LIBRARY_VERSION ${MIRALL_VERSION})
set(APPLICATION_VERSION_MAJOR "0")
set(APPLICATION_VERSION_MINOR "91")
set(APPLICATION_VERSION_PATCH "5")
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
set(LIBRARY_VERSION "0.2.1")
set(LIBRARY_SOVERSION "0")
# add definitions
+8 -16
Ver Arquivo
@@ -386,20 +386,6 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
SAFE_FREE(renamed_path);
}
if (!other_node) {
/* Check the source path as well. */
int len;
uint64_t h = 0;
char *renamed_path = csync_rename_adjust_path_source(ctx, cur->path);
if (!c_streq(renamed_path, cur->path)) {
len = strlen( renamed_path );
h = c_jhash64((uint8_t *) renamed_path, len, 0);
other_node = c_rbtree_find(other_tree, &h);
}
SAFE_FREE(renamed_path);
}
if (obj == NULL || data == NULL) {
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
return -1;
@@ -590,8 +576,7 @@ int csync_commit(CSYNC *ctx) {
_csync_clean_ctx(ctx);
ctx->remote.read_from_db = 0;
ctx->read_remote_from_db = true;
ctx->db_is_empty = false;
ctx->read_from_db_disabled = 0;
/* Create new trees */
@@ -788,3 +773,10 @@ int csync_set_module_property(CSYNC* ctx, const char* key, void* value)
#endif
}
int csync_set_read_from_db(CSYNC* ctx, int enabled)
{
ctx->read_from_db_disabled = !enabled;
return 0;
}
+7
Ver Arquivo
@@ -40,6 +40,8 @@
#include <sys/types.h>
#include <config_csync.h>
#include "csync_version.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -548,6 +550,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);
char *csync_normalize_etag(const char *);
time_t oc_httpdate_parse( const char *date );
-1
Ver Arquivo
@@ -233,7 +233,6 @@ CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path
}
// check the strlen and ignore the file if its name is longer than 254 chars.
// whenever changing this also check createDownloadTmpFileName
if (strlen(bname) > 254) {
match = CSYNC_FILE_EXCLUDE_LONG_FILENAME;
SAFE_FREE(bname);
+1 -1
Ver Arquivo
@@ -61,7 +61,7 @@ enum csync_log_priority_e {
};
#define CSYNC_LOG(priority, ...) \
csync_log(priority, __func__, __VA_ARGS__)
csync_log(priority, __FUNCTION__, __VA_ARGS__)
void csync_log(int verbosity,
const char *function,
+2 -4
Ver Arquivo
@@ -26,8 +26,6 @@
#include "csync_private.h"
#include "csync_version.h"
/*
* helper method to build up a user text for SSL problems, called from the
@@ -439,8 +437,8 @@ int dav_connect(CSYNC *csyncCtx, const char *base_url) {
// Should never take more than some seconds, 30 is really a max.
ne_set_connect_timeout(ctx->dav_session.ctx, 30);
snprintf( uaBuf, sizeof(uaBuf), "Mozilla/5.0 (%s) mirall/%s (csyncoC)",
CSYNC_STRINGIFY( MIRALL_VERSION ), csync_owncloud_get_platform() );
snprintf( uaBuf, sizeof(uaBuf), "Mozilla/5.0 (%s) csyncoC/%s",
csync_owncloud_get_platform(), CSYNC_STRINGIFY( LIBCSYNC_VERSION ));
ne_set_useragent( ctx->dav_session.ctx, uaBuf);
ne_set_server_auth(ctx->dav_session.ctx, authentication_callback_by_neon, ctx);
+1 -11
Ver Arquivo
@@ -151,17 +151,7 @@ struct csync_s {
int status;
volatile int abort;
void *rename_info;
/**
* Specify if it is allowed to read the remote tree from the DB (default to enabled)
*/
bool read_remote_from_db;
/**
* If true, the DB is considered empty and all reads are skipped. (default is false)
* This is useful during the initial local discovery as it speeds it up significantly.
*/
bool db_is_empty;
int read_from_db_disabled;
struct csync_owncloud_ctx_s *owncloud_context;
+2 -2
Ver Arquivo
@@ -156,8 +156,8 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
}
if( tmp ) {
len = strlen( tmp->path );
if( len > 0 ) {
if( tmp->path ) {
len = strlen( tmp->path );
h = c_jhash64((uint8_t *) tmp->path, len, 0);
/* First, check that the file is NOT in our tree (another file with the same name was added) */
node = c_rbtree_find(ctx->current == REMOTE_REPLICA ? ctx->remote.tree : ctx->local.tree, &h);
-16
Ver Arquivo
@@ -43,7 +43,6 @@ struct csync_rename_s {
}
std::map<std::string, std::string> folder_renamed_to; // map from->to
std::map<std::string, std::string> folder_renamed_from; // map to->from
struct renameop {
csync_file_stat_t *st;
@@ -64,7 +63,6 @@ void csync_rename_destroy(CSYNC* ctx)
void csync_rename_record(CSYNC* ctx, const char* from, const char* to)
{
csync_rename_s::get(ctx)->folder_renamed_to[from] = to;
csync_rename_s::get(ctx)->folder_renamed_from[to] = from;
}
char* csync_rename_adjust_path(CSYNC* ctx, const char* path)
@@ -80,18 +78,4 @@ char* csync_rename_adjust_path(CSYNC* ctx, const char* path)
return c_strdup(path);
}
char* csync_rename_adjust_path_source(CSYNC* ctx, const char* path)
{
csync_rename_s* d = csync_rename_s::get(ctx);
for (std::string p = _parentDir(path); !p.empty(); p = _parentDir(p)) {
std::map< std::string, std::string >::iterator it = d->folder_renamed_from.find(p);
if (it != d->folder_renamed_from.end()) {
std::string rep = it->second + (path + p.length());
return c_strdup(rep.c_str());
}
}
return c_strdup(path);
}
}
-3
Ver Arquivo
@@ -26,10 +26,7 @@
extern "C" {
#endif
/* Return the final destination path of a given patch in case of renames */
char *csync_rename_adjust_path(CSYNC *ctx, const char *path);
/* Return the source of a given path in case of renames */
char *csync_rename_adjust_path_source(CSYNC *ctx, const char *path);
void csync_rename_destroy(CSYNC *ctx);
void csync_rename_record(CSYNC *ctx, const char *from, const char *to);
+4 -4
Ver Arquivo
@@ -298,7 +298,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx,
csync_file_stat_t *st = NULL;
int rc;
if( !ctx || ctx->db_is_empty ) {
if( !ctx ) {
return NULL;
}
@@ -341,7 +341,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx,
return 0;
}
if( !ctx || ctx->db_is_empty ) {
if( !ctx ) {
return NULL;
}
@@ -381,7 +381,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx,
return NULL;
}
if( !ctx || ctx->db_is_empty ) {
if( !ctx ) {
return NULL;
}
@@ -448,7 +448,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
return -1;
}
if( !ctx || ctx->db_is_empty ) {
if( !ctx ) {
return -1;
}
+2 -7
Ver Arquivo
@@ -306,7 +306,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|| !c_streq(fs->remotePerm, tmp->remotePerm)))
|| (ctx->current == LOCAL_REPLICA && fs->inode != tmp->inode);
if (type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA
&& !metadata_differ && ctx->read_remote_from_db) {
&& !metadata_differ && !ctx->read_from_db_disabled) {
/* If both etag and file id are equal for a directory, read all contents from
* the database.
* The metadata comparison ensure that we fetch all the file id or permission when
@@ -621,12 +621,7 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
if (asp < 0) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
}
}
// The server usually replies with the custom "503 Storage not available"
// if some path is temporarily unavailable. But in some cases a standard 503
// is returned too. Thus we can't distinguish the two and will treat any
// 503 as request to ignore the folder. See #3113 #2884.
else if(errno == ERRNO_STORAGE_UNAVAILABLE || errno == ERRNO_SERVICE_UNAVAILABLE) {
} else if(errno == ERRNO_STORAGE_UNAVAILABLE) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Storage was not available!");
if (ctx->current_fs) {
ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE;
+16 -1
Ver Arquivo
@@ -28,7 +28,22 @@ extern "C" {
#define CSYNC_STRINGIFY(s) CSYNC_TOSTRING(s)
#define CSYNC_TOSTRING(s) #s
#define MIRALL_VERSION @MIRALL_VERSION@
/* csync version macros */
#define CSYNC_VERSION_INT(a, b, c) ((a) << 16 | (b) << 8 | (c))
#define CSYNC_VERSION_DOT(a, b, c) a ##.## b ##.## c
#define CSYNC_VERSION(a, b, c) CSYNC_VERSION_DOT(a, b, c)
/* csync version */
#define LIBCSYNC_VERSION_MAJOR @APPLICATION_VERSION_MAJOR@
#define LIBCSYNC_VERSION_MINOR @APPLICATION_VERSION_MINOR@
#define LIBCSYNC_VERSION_MICRO @APPLICATION_VERSION_PATCH@
#define LIBCSYNC_VERSION_INT CSYNC_VERSION_INT(LIBCSYNC_VERSION_MAJOR, \
LIBCSYNC_VERSION_MINOR, \
LIBCSYNC_VERSION_MICRO)
#define LIBCSYNC_VERSION CSYNC_VERSION(LIBCSYNC_VERSION_MAJOR, \
LIBCSYNC_VERSION_MINOR, \
LIBCSYNC_VERSION_MICRO)
#ifdef __cplusplus
}
+1 -1
Ver Arquivo
@@ -42,7 +42,7 @@
#define DEBUG_HBF(...) { if(transfer->log_cb) { \
char buf[1024]; \
snprintf(buf, 1024, __VA_ARGS__); \
transfer->log_cb(__func__, buf, transfer->user_data); \
transfer->log_cb(__FUNCTION__, buf, transfer->user_data); \
} }
// #endif
+1 -5
Ver Arquivo
@@ -20,7 +20,6 @@
#include "c_lib.h"
#include "csync.h"
#include "csync_log.h"
csync_vio_file_stat_t *csync_vio_file_stat_new(void) {
csync_vio_file_stat_t *file_stat = (csync_vio_file_stat_t *) c_malloc(sizeof(csync_vio_file_stat_t));
@@ -31,9 +30,7 @@ csync_vio_file_stat_t *csync_vio_file_stat_new(void) {
csync_vio_file_stat_t* csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat) {
csync_vio_file_stat_t *file_stat_cpy = csync_vio_file_stat_new();
memcpy(file_stat_cpy, file_stat, sizeof(csync_vio_file_stat_t));
if (file_stat_cpy->fields & CSYNC_VIO_FILE_STAT_FIELDS_ETAG) {
file_stat_cpy->etag = c_strdup(file_stat_cpy->etag);
}
file_stat_cpy->etag = c_strdup(file_stat_cpy->etag);
if (file_stat_cpy->directDownloadCookies) {
file_stat_cpy->directDownloadCookies = c_strdup(file_stat_cpy->directDownloadCookies);
}
@@ -71,7 +68,6 @@ void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t *dst, const char* sr
void csync_vio_set_file_id( char* dst, const char *src ) {
if( src && dst ) {
if( strlen(src) > FILE_ID_BUF_SIZE ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Ignoring file_id because it is too long: %s", src);
strcpy(dst, "");
} else {
strcpy(dst, src);
+1 -1
Ver Arquivo
@@ -131,7 +131,7 @@ static void check_logging(void **state)
rc = csync_set_log_callback(check_log_callback);
assert_int_equal(rc, 0);
csync_log(1, __func__, "rc = %d", rc);
csync_log(1, __FUNCTION__, "rc = %d", rc);
rc = _tstat(path, &sb);
+4 -6
Ver Arquivo
@@ -124,8 +124,7 @@ sub initTesting(;$)
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0
}
my $ua = HTTP::DAV::UserAgent->new(keep_alive => 1 );
$d = HTTP::DAV->new(-useragent => $ua);
$d = HTTP::DAV->new();
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $user,
@@ -192,6 +191,7 @@ sub removeRemoteDir($;$)
my ($dir, $optionsRef) = @_;
my $url = testDirUrl() . $dir;
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $optionsRef->{user},
@@ -326,11 +326,11 @@ sub assertLocalDirs( $$ )
opendir(my $dh, $dir1 ) || die;
while(readdir $dh) {
assert( -e "$dir2/$_", " $dir2/$_ do not exist" );
assert( -e "$dir2/$_" );
next if( -d "$dir1/$_"); # don't compare directory sizes.
my $s1 = -s "$dir1/$_";
my $s2 = -s "$dir2/$_";
assert( $s1 == $s2, "$dir1/$_ <-> $dir2/$_ size not equal ($s1 != $s2)" );
assert( $s1 == $s2, "$dir1/$_ <-> $dir2/$_" );
}
closedir $dh;
}
@@ -524,9 +524,7 @@ sub put_to_dir( $$;$ )
my $filename = $file;
$filename =~ s/^.*\///;
$filename =~ s/#/%23/g; # poor man's URI encoder
my $puturl = $targetUrl . $dir. $filename;
print "put_to_dir puts to $puturl\n";
unless ($d->put( -local => $file, -url => $puturl )) {
print " ### FAILED to put a single file!\n";
-85
Ver Arquivo
@@ -1,85 +0,0 @@
#!/usr/bin/perl
#
# Test script for the ownCloud module of csync.
# This script requires a running ownCloud instance accessible via HTTP.
# It does quite some fancy tests and asserts the results.
#
# Copyright (C) by Olivier Goffart <ogoffart@woboq.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
use lib ".";
use File::Copy;
use ownCloud::Test;
use strict;
print "Hello, this is t_recall, a tester for the recall feature\n";
initTesting();
printInfo( "Syncing two files with the same name that differ with case" );
#create some files
my $tmpdir = "/tmp/t_recall/";
mkdir($tmpdir);
createLocalFile( $tmpdir . "file1.dat", 100 );
createLocalFile( $tmpdir . "file2.dat", 150 );
createLocalFile( $tmpdir . "file3.dat", 110 );
createLocalFile( $tmpdir . "file4.dat", 170 );
#put them in some directories
createRemoteDir( "dir" );
glob_put( "$tmpdir/*", "dir" );
csync();
assertLocalAndRemoteDir( '', 0);
printInfo( "Testing with a .sys.admin#recall#" );
system("echo 'dir/file2.dat' > ". $tmpdir . ".sys.admin\#recall\#");
system("echo 'dir/file3.dat' >> ". $tmpdir . ".sys.admin\#recall\#");
glob_put( "$tmpdir/.sys.admin\#recall\#", "" );
csync();
#test that the recall files have been created
assert( -e glob(localDir().'dir/file2_.sys.admin#recall#-*.dat' ) );
assert( -e glob(localDir().'dir/file3_.sys.admin#recall#-*.dat' ) );
#Remove the recall file
unlink(localDir() . ".sys.admin#recall#");
# 2 sync necessary for the recall to be uploaded
csync();
assertLocalAndRemoteDir( '', 0);
printInfo( "Testing with a dir/.sys.admin#recall#" );
system("echo 'file4.dat' > ". $tmpdir . ".sys.admin\#recall\#");
glob_put( "$tmpdir/.sys.admin\#recall\#", "dir" );
csync();
assert( -e glob(localDir().'dir/file4_.sys.admin#recall#-*.dat' ) );
cleanup();
system("rm -r " . $tmpdir);
-1
Ver Arquivo
@@ -1,4 +1,3 @@
==============
Advanced Usage
==============
+3 -3
Ver Arquivo
@@ -25,9 +25,9 @@ The process of synchronization keeps files in two separate repositories the
same. When synchronized:
- If a file is added to one repository it is copied to the other synchronized repository.
- When a file is changed in one repository, the change is propagated to any other
synchronized repository.
- If a file is deleted in one repository, it is deleted in any other.
- When a file is changed in one repository, the change is propagated to any
synchronized other repositories- If a file is deleted in one repository, it
is deleted in any other.
It is important to note that the ownCloud synchronization process does not use
a typical client/server system where the server is always master. This is a
+1 -9
Ver Arquivo
@@ -1,4 +1,3 @@
=====================
The Automatic Updater
=====================
@@ -10,15 +9,11 @@ users only need to use their normal package managers. However, on Linux systems
the Updater will check for updates and notify you when a new version is
available.
.. note:: Because of various technical issues, desktop sync clients older than
1.7 will not be allowed to connect and sync with the ownCloud 8.1 server. It is
highly recommended to keep your client updated.
Basic Workflow
--------------
The following sections describe how to use the Automatic Updater on different
operating systems.
operating systems:
Windows
^^^^^^^
@@ -31,9 +26,6 @@ If an update is available, and has been successfully downloaded, the ownCloud
client starts a silent update prior to its next launch and then restarts
itself. Should the silent update fail, the client offers a manual download.
When you upgrade from 1.7 you should restart Windows to ensure that all the new
features in 1.8 are enabled.
.. note:: Administrative privileges are required to perform the update.
Mac OS X
-3
Ver Arquivo
@@ -35,9 +35,6 @@ including:
and Nautilus on Linux.
* Faster uploads and downloads.
.. note:: When you upgrade from 1.7, restart Windows to ensure that all new
features are visible.
Installation
------------
-3
Ver Arquivo
@@ -11,6 +11,3 @@ Desktop Sync client enables you to:
Your files are always automatically synchronized between your ownCloud server
and local PC.
.. note:: Because of various technical issues, desktop sync clients older than
1.7 will not allowed to connect and sync with the ownCloud 8.1 server. It is
highly recommended to keep your client updated.
+8 -13
Ver Arquivo
@@ -1,28 +1,23 @@
You have the option of starting your ownCloud desktop client with the
``owncloud`` command. The following options are supported:
When invoking the client from the command line, the following options are supported:
``owncloud -h`` or ``owncloud --help``
``-h``, ``--help``
Displays all command options.
The other options are:
``--logwindow``
Opens a window displaying log output.
``--logfile`` `<filename>`
Write log output to the file specified. To write to stdout, specify `-`
as the filename.
Write log output to the file specified. To write to stdout, specify `-` as the filename.
``--logdir`` `<name>`
Writes each synchronization log output in a new file in the specified
directory.
Writes each synchronization log output in a new file in the specified directory.
``--logexpire`` `<hours>`
Removes logs older than the value specified (in hours). This command is
used with ``--logdir``.
Removes logs older than the value specified (in hours). This command is used with ``--logdir``.
``--logflush``
Clears (flushes) the log file after each write action.
``--confdir`` `<dirname>`
Uses the specified configuration directory.
Uses the specified configuration directory.
+38 -24
Ver Arquivo
@@ -1,14 +1,16 @@
The ownCloud Client packages contain a command line client, ``owncloudcmd``, that can
be used to synchronize ownCloud files to client machines.
The ownCloud Client packages contain a command line client that can be used to
synchronize ownCloud files to client machines. The command line client is
called ``owncloudcmd``.
``owncloudcmd`` performs a single *sync run* and then exits the synchronization
process. In this manner, ``owncloudcmd`` processes the differences between
client and server directories and propagates the files to bring both
repositories to the same state. Contrary to the GUI-based client,
``owncloudcmd`` does not repeat synchronizations on its own. It also does not
monitor for file system changes.
owncloudcmd performs a single *sync run* and then exits the synchronization
process. In this manner, owncloudcmd processes the differences between client
and server directories and propagates the files to bring both repositories to
the same state. Contrary to the GUI-based client, ``owncloudcmd`` does not
repeat
synchronizations on its own. It also does not monitor for file system changes.
To invoke ``owncloudcmd``, you must provide the local and the remote repository
To invoke ``owncloudcmd``, you must provide the local and the remote
repository
URL using the following command::
owncloudcmd [OPTIONS...] sourcedir owncloudurl
@@ -16,41 +18,45 @@ URL using the following command::
where ``sourcedir`` is the local directory and ``owncloudurl`` is
the server URL.
Other command line switches supported by ``owncloudcmd`` include the following:
.. note:: Prior to the 1.6 version of owncloudcmd, the tool only accepted
``owncloud://`` or ``ownclouds://`` in place of ``http://`` and ``https://`` as
a scheme. See ``Examples`` for details.
Other comand line switches supported by owncloudcmd include the following:
``--user``, ``-u`` ``[user]``
Specify the user's login name.
Use ``user`` as the login name.
``--password``, ``-p`` ``[password]``
Specify the user's password.
Use ``password`` as the password.
``-n``
Use ``netrc (5)`` for login.
Use ``netrc (5)`` for login.
``--non-interactive``
Do not prompt for questions.
Do not prompt for questions.
``--silent``, ``-s``
Inhibits verbose log output.
Inhibits verbose log output.
``--trust``
Trust any SSL certificate, including invalid ones.
Trust any SSL certificate, including invalid ones.
``--httpproxy http://[user@pass:]<server>:<port>``
Uses the specified ``server`` as the HTTP proxy.
``--unsyncedfolders [file]``
File containing list of folders to not sync
Credential Handling
~~~~~~~~~~~~~~~~~~~
By default, ``owncloudcmd`` reads the client configuration and uses the
credentials of the GUI synchronization client. If no client is configured, or if
you choose to use a different user to synchronize, you can specify the user
password setting with the usual URL pattern. For example::
credentials of the GUI synchronization client. If no client is configured, or if you choose
to use a different user to synchronize, you can specify the user password
setting with the usual URL pattern. For example::
$ owncloudcmd / https://carla:secret@server/owncloud/remote.php/webdav/
https://user:secret@192.168.178.2/remote.php/webdav
Example
~~~~~~~
To synchronize the ownCloud directory ``Music`` to the local directory
``media/music``, through a proxy listening on port ``8080``, and on a gateway
@@ -60,5 +66,13 @@ machine using IP address ``192.168.178.1``, the command line would be::
$HOME/media/music \
https://server/owncloud/remote.php/webdav/Music
``owncloudcmd`` will prompt for the user name and password, unless they have
``owncloudcmd`` will enquire user name and password, unless they have
been specified on the command line or ``-n`` has been passed.
Using the legacy scheme, the command line would be::
$ owncloudcmd --httpproxy http://192.168.178.1:8080 \
$HOME/media/music \
ownclouds://server/owncloud/remote.php/webdav/Music
+10 -14
Ver Arquivo
@@ -61,12 +61,12 @@ Other issues can affect synchronization of your ownCloud files:
ensure that the folder to which you are synchronizing is not shared with
other synchronization applications.
- Synchronizing the same directory with ownCloud and other synchronization
software such as Unison, rsync, Microsoft Windows Offline Folders, or other
cloud services such as DropBox or Microsoft SkyDrive is not supported and
should not be attempted. In the worst case, it is possible that synchronizing
folders or files using ownCloud and other synchronization software or
services can result in data loss.
- Synchronizing the same directory with ownCloud and other
synchronization software such as Unison, rsync, Microsoft Windows Offline
Folders, or other cloud services such as DropBox or Microsoft SkyDrive is not
supported and should not be attempted. In the worst case, it is possible that
synchronizing folders or files using ownCloud and other synchronization
software or services can result in data loss.
- If you find that only specific files are not synrchronized, the
synchronization protocol might be having an effect. Some files are
@@ -80,13 +80,9 @@ Other issues can affect synchronization of your ownCloud files:
.. note:: The data directory on the server is exclusive to ownCloud and must not be modified manually.
- If you are using a different file backend on the server, you can try to exclude a bug in the
If you are using a different file backend on the server, you can try to exclude a bug in the
backend by reverting to the built-in backend.
- If you are experiencing slow upload/download speed or similar performance issues
be aware that those could be caused by on-access virus scanning solutions, either
on the server (like the files_antivirus app) or the client.
Log Files
---------
@@ -129,9 +125,9 @@ mentioned above to save the log to a file.
.. note:: You can also open a log window for an already running session, by
restarting the client using the following command:
* Windows: ``C:\Program Files (x86)\ownCloud\owncloud.exe --logwindow``
* Mac OS X: ``/Applications/owncloud.app/Contents/MacOS/owncloud --logwindow``
* Linux: ``owncloud --logwindow``
* Windows: ``C:\Program Files (x86)\ownCloud\owncloud.exe --logwindow``
* Mac OS X: ``/Applications/owncloud.app/Contents/MacOS/owncloud --logwindow``
* Linux: ``owncloud --logwindow``
Saving Files Directly
~~~~~~~~~~~~~~~~~~~~~
@@ -17,7 +17,6 @@
@interface ContentManager : NSObject
{
NSMutableDictionary* _fileNamesCache;
NSMutableDictionary* _oldFileNamesCache;
BOOL _fileIconsEnabled;
BOOL _hasChangedContent;
@@ -36,9 +35,10 @@
- (void)enableFileIcons:(BOOL)enable;
- (NSNumber*)iconByPath:(NSString*)path isDirectory:(BOOL)isDir;
- (void)removeAllIcons;
- (void)removeIcons:(NSArray*)paths;
- (void)setIcons:(NSDictionary*)iconDictionary filterByFolder:(NSString*)filterFolder;
- (void)setResultForPath:(NSString*)path result:(NSString*)result;
- (void)clearFileNameCache;
- (void)clearFileNameCacheForPath:(NSString*)path;
- (void)reFetchFileNameCacheForPath:(NSString*)path;
- (void)repaintAllWindows;
@@ -30,7 +30,6 @@ static ContentManager* sharedInstance = nil;
if (self)
{
_fileNamesCache = [[NSMutableDictionary alloc] init];
_oldFileNamesCache = [[NSMutableDictionary alloc] init];
_fileIconsEnabled = TRUE;
_hasChangedContent = TRUE;
}
@@ -42,7 +41,6 @@ static ContentManager* sharedInstance = nil;
{
[self removeAllIcons];
[_fileNamesCache release];
[_oldFileNamesCache release];
sharedInstance = nil;
[super dealloc];
@@ -150,48 +148,84 @@ static ContentManager* sharedInstance = nil;
if( result == nil ) {
// start the async call
[[RequestManager sharedInstance] askForIcon:normalizedPath isDirectory:isDir];
NSNumber *askState = [[RequestManager sharedInstance] askForIcon:normalizedPath isDirectory:isDir];
[_fileNamesCache setObject:askState forKey:normalizedPath];
result = [NSNumber numberWithInt:0];
// Set 0 into the cache, meaning "don't have an icon, but already requested it"
[_fileNamesCache setObject:result forKey:normalizedPath];
} else if( [result intValue] == -1 ) {
// the socket call is underways.
result = [NSNumber numberWithInt:0];
} else {
// there is a proper icon index
}
if ([result intValue] == 0) {
// Show the old state while we wait for the new one
NSNumber* oldResult = [_oldFileNamesCache objectForKey:normalizedPath];
if (oldResult)
result = oldResult;
}
// NSLog(@"iconByPath return value %d", [result intValue]);
// NSLog(@"iconByPath return value %d", [result intValue]);
return result;
}
// Clears the entries from the hash to make it call again home to the desktop client.
- (void)clearFileNameCache
// called as a result of an UPDATE_VIEW message.
// it clears the entries from the hash to make it call again home to the desktop client.
- (void)clearFileNameCacheForPath:(NSString*)path
{
[_fileNamesCache release];
_fileNamesCache = [[NSMutableDictionary alloc] init];
[_oldFileNamesCache removeAllObjects];
//NSLog(@"%@", NSStringFromSelector(_cmd));
NSMutableArray *keysToDelete = [NSMutableArray array];
if( path != nil ) {
for (id p in [_fileNamesCache keyEnumerator]) {
//do stuff with obj
if ( [p hasPrefix:path] ) {
[keysToDelete addObject:p];
}
}
} else {
// clear the entire fileNameCache
[_fileNamesCache release];
_fileNamesCache = [[NSMutableDictionary alloc] init];
return;
}
if( [keysToDelete count] > 0 ) {
NSLog( @"Entries to delete: %lu", (unsigned long)[keysToDelete count]);
[_fileNamesCache removeObjectsForKeys:keysToDelete];
}
}
- (void)reFetchFileNameCacheForPath:(NSString*)path
{
//NSLog(@"%@", NSStringFromSelector(_cmd));
NSLog(@"%@", NSStringFromSelector(_cmd));
// We won't request the new state if if finds the path in _fileNamesCache
// Move all entries to _oldFileNamesCache so that the get re-requested, but
// still available while we refill the cache
[_oldFileNamesCache addEntriesFromDictionary:_fileNamesCache];
[_fileNamesCache removeAllObjects];
for (id p in [_fileNamesCache keyEnumerator]) {
if ( path && [p hasPrefix:path] ) {
[[RequestManager sharedInstance] askForIcon:p isDirectory:false]; // FIXME isDirectory parameter
//[_fileNamesCache setObject:askState forKey:p]; We don't do this since we want to keep the old icon meanwhile
//NSLog(@"%@ %@", NSStringFromSelector(_cmd), p);
}
}
[self repaintAllWindows];
// Ask for directory itself
if ([path hasSuffix:@"/"]) {
path = [path substringToIndex:path.length - 1];
}
[[RequestManager sharedInstance] askForIcon:path isDirectory:true];
//NSLog(@"%@ %@", NSStringFromSelector(_cmd), path);
}
- (void)removeAllIcons
{
[_fileNamesCache removeAllObjects];
[_oldFileNamesCache removeAllObjects];
[self repaintAllWindows];
}
- (void)removeIcons:(NSArray*)paths
{
for (NSString* path in paths)
{
NSString* normalizedPath = [path decomposedStringWithCanonicalMapping];
[_fileNamesCache removeObjectForKey:normalizedPath];
}
[self repaintAllWindows];
}
@@ -327,7 +361,6 @@ static ContentManager* sharedInstance = nil;
}
else
{
[_oldFileNamesCache removeObjectForKey:normalizedPath];
[_fileNamesCache setObject:iconId forKey:normalizedPath];
}
}
@@ -22,7 +22,6 @@
NSMutableArray* _requestQueue;
NSMutableDictionary* _registeredPathes;
NSMutableSet* _requestedPaths;
NSString *_shareMenuTitle;
@@ -35,7 +34,7 @@
- (BOOL)isRegisteredPath:(NSString*)path isDirectory:(BOOL)isDir;
- (void)askOnSocket:(NSString*)path query:(NSString*)verb;
- (void)askForIcon:(NSString*)path isDirectory:(BOOL)isDir;
- (NSNumber*)askForIcon:(NSString*)path isDirectory:(BOOL)isDir;
- (void)menuItemClicked:(NSDictionary*)actionDictionary;
- (void)start;
@@ -31,7 +31,6 @@ static RequestManager* sharedInstance = nil;
_isConnected = NO;
_registeredPathes = [[NSMutableDictionary alloc] init];
_requestedPaths = [[NSMutableSet alloc] init];
_shareMenuTitle = nil;
@@ -102,23 +101,28 @@ static RequestManager* sharedInstance = nil;
return registered;
}
- (void)askForIcon:(NSString*)path isDirectory:(BOOL)isDir
- (NSNumber*)askForIcon:(NSString*)path isDirectory:(BOOL)isDir
{
NSString *verb = @"RETRIEVE_FILE_STATUS";
NSNumber *res = [NSNumber numberWithInt:0];
if( [self isRegisteredPath:path isDirectory:isDir] ) {
[_requestedPaths addObject:path];
if( _isConnected ) {
if(isDir) {
verb = @"RETRIEVE_FOLDER_STATUS";
}
[self askOnSocket:path query:verb];
NSNumber *res_minus_one = [NSNumber numberWithInt:0];
return res_minus_one;
} else {
[_requestQueue addObject:path];
[self start]; // try again to connect
}
}
return res;
}
@@ -143,13 +147,9 @@ static RequestManager* sharedInstance = nil;
path, [chunks objectAtIndex:i+1] ];
}
}
// The client will broadcast all changes, do not fill the cache for paths that Finder didn't ask for.
if ([_requestedPaths containsObject:path]) {
[contentman setResultForPath:path result:[chunks objectAtIndex:1]];
}
[contentman setResultForPath:path result:[chunks objectAtIndex:1]];
} else if( [[chunks objectAtIndex:0] isEqualToString:@"UPDATE_VIEW"] ) {
NSString *path = [chunks objectAtIndex:1];
[_requestedPaths removeAllObjects];
[contentman reFetchFileNameCacheForPath:path];
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"REGISTER_PATH"] ) {
NSNumber *one = [NSNumber numberWithInt:1];
@@ -198,11 +198,10 @@ static RequestManager* sharedInstance = nil;
for( NSString *path in _requestQueue ) {
[self askOnSocket:path query:@"RETRIEVE_FILE_STATUS"];
}
[_requestQueue removeAllObjects];
}
ContentManager *contentman = [ContentManager sharedInstance];
[contentman clearFileNameCache];
[contentman clearFileNameCacheForPath:nil];
[contentman repaintAllWindows];
// Read for the UPDATE_VIEW requests
@@ -219,11 +218,10 @@ static RequestManager* sharedInstance = nil;
// clear the registered pathes.
[_registeredPathes release];
_registeredPathes = [[NSMutableDictionary alloc] init];
[_requestedPaths removeAllObjects];
// clear the caches in conent manager
ContentManager *contentman = [ContentManager sharedInstance];
[contentman clearFileNameCache];
[contentman clearFileNameCacheForPath:nil];
[contentman repaintAllWindows];
}
+3 -4
Ver Arquivo
@@ -1,6 +1,5 @@
#!/bin/sh
SELFPATH=`dirname $0`
# osascript $SELFPATH/unload.scpt
# osascript $HOME/owncloud.com/client/shell_integration/MacOSX/unload.scpt
sudo rm -rf /Library/ScriptingAdditions/SyncStateFinder.osax
# Klaas' machine
@@ -13,6 +12,6 @@ OSAXDIR=$HOME/Library/Developer/Xcode/DerivedData/OwnCloud-*/Build/Products/Debu
sudo killall Finder
sleep 1
osascript $SELFPATH/load.scpt
osascript $SELFPATH/check.scpt
osascript $HOME/owncloud.com/client/shell_integration/MacOSX/load.scpt
osascript $HOME/owncloud.com/client/shell_integration/MacOSX/check.scpt
@@ -98,8 +98,6 @@ void RemotePathChecker::workerThreadLoop()
++it;
}
}
// Assume that we won't need this at this point, UNREGISTER_PATH is rare
_oldCache.clear();
}
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH | SHCNF_FLUSHNOWAIT, responsePath.data(), NULL);
} else if (StringUtil::begins_with(response, wstring(L"STATUS:")) ||
@@ -117,16 +115,13 @@ void RemotePathChecker::workerThreadLoop()
auto responseStatus = response.substr(statusBegin+1, statusEnd - statusBegin-1);
auto responsePath = response.substr(statusEnd+1);
auto state = _StrToFileState(responseStatus);
bool wasAsked = asked.erase(responsePath) > 0;
auto erased = asked.erase(responsePath);
bool changed = false;
{ std::unique_lock<std::mutex> lock(_mutex);
bool wasCached = _cache.find(responsePath) != _cache.end();
if (wasAsked || wasCached) {
auto &it = _cache[responsePath];
changed = (it != state);
it = state;
}
auto &it = _cache[responsePath];
changed = (it != state);
it = state;
}
if (changed) {
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH | SHCNF_FLUSHNOWAIT, responsePath.data(), NULL);
@@ -134,25 +129,20 @@ void RemotePathChecker::workerThreadLoop()
}
else if (StringUtil::begins_with(response, wstring(L"UPDATE_VIEW"))) {
std::unique_lock<std::mutex> lock(_mutex);
// Keep the old states to continue having something to display while the new state is
// requested from the client, triggered by clearing _cache.
_oldCache.insert(_cache.cbegin(), _cache.cend());
// Swap to make a copy of the cache under the mutex and clear the one stored.
std::unordered_map<std::wstring, FileState> cache;
swap(cache, _cache);
auto cache = _cache; // Make a copy of the cache under the mutex
lock.unlock();
// Let explorer know about the invalidated cache entries, it will re-request the ones it needs.
for (auto it = cache.begin(); it != cache.end(); ++it) {
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH | SHCNF_FLUSHNOWAIT, it->first.data(), NULL);
}
}
// Request a status for all the items in the cache.
for (auto it = cache.begin(); it != cache.end(); ++it) {
if (!socket.SendMsg(wstring(L"RETRIEVE_FILE_STATUS:" + it->first + L'\n').data())) {
break;
}
}
}
}
if (socket.Event() == INVALID_HANDLE_VALUE) {
std::unique_lock<std::mutex> lock(_mutex);
_cache.clear();
_oldCache.clear();
_watchedDirectories.clear();
_connected = connected = false;
}
@@ -205,17 +195,11 @@ bool RemotePathChecker::IsMonitoredPath(const wchar_t* filePath, int* state)
return true;
}
// Re-request the status while we display what we have in _oldCache
_pending.push(filePath);
it = _oldCache.find(path);
bool foundInOldCache = it != _oldCache.end();
if (foundInOldCache)
*state = it->second;
lock.unlock();
SetEvent(_newQueries);
return foundInOldCache;
return false;
}
RemotePathChecker::FileState RemotePathChecker::_StrToFileState(const std::wstring &str)
@@ -52,7 +52,6 @@ private:
std::queue<std::wstring> _pending;
std::unordered_map<std::wstring, FileState> _cache;
std::unordered_map<std::wstring, FileState> _oldCache;
std::vector<std::wstring> _watchedDirectories;
bool _connected;
-1
Ver Arquivo
@@ -30,7 +30,6 @@
#include "qtlocalpeer.h"
#include <QCoreApplication>
#include <QDataStream>
#include <QTime>
#if defined(Q_OS_WIN)
+1 -6
Ver Arquivo
@@ -194,9 +194,6 @@ void parseOptions( const QStringList& app_args, CmdOptions *options )
if (options->target_url.startsWith("http"))
options->target_url.replace(0, 4, "owncloud");
options->source_dir = args.takeLast();
if (!options->source_dir.endsWith('/')) {
options->source_dir.append('/');
}
if( !QFile::exists( options->source_dir )) {
std::cerr << "Source dir '" << qPrintable(options->source_dir) << "' does not exist." << std::endl;
exit(1);
@@ -445,9 +442,7 @@ restart_sync:
if (!f.open(QFile::ReadOnly)) {
qCritical() << "Could not open file containing the list of unsynced folders: " << options.unsyncedfolders;
} else {
// filter out empty lines and comments
selectiveSyncList = QString::fromUtf8(f.readAll()).split('\n').filter(QRegExp("\\S+")).filter(QRegExp("^[^#]"));
selectiveSyncList = QString::fromUtf8(f.readAll()).split('\n');
for (int i = 0; i < selectiveSyncList.count(); ++i) {
if (!selectiveSyncList.at(i).endsWith(QLatin1Char('/'))) {
selectiveSyncList[i].append(QLatin1Char('/'));
-9
Ver Arquivo
@@ -154,19 +154,10 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
qt_add_translation(client_I18N ${TRANSLATIONS})
IF( WIN32 )
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in
${CMAKE_CURRENT_BINARY_DIR}/version.rc
@ONLY)
set(client_version ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
ENDIF()
set( final_src
${MIRALL_RC_SRC}
${client_SRCS}
${client_UI_SRCS}
${client_version}
${guiMoc}
${client_I18N}
${3rdparty_SRC}
+3
Ver Arquivo
@@ -28,6 +28,9 @@ public:
* @return the list of migrated folder definitions
*/
QStringList migrateFolderDefinitons();
signals:
public slots:
};
}
+3 -3
Ver Arquivo
@@ -234,7 +234,7 @@ void AccountSettings::slotAddFolder( Folder *folder )
if( ! folder || folder->alias().isEmpty() ) return;
QStandardItem *item = new QStandardItem();
folderToModelItem( item, folder, _accountState && _accountState->isConnectedOrTemporarilyUnavailable());
folderToModelItem( item, folder, _accountState && _accountState->isConnectedOrMaintenance());
_model->appendRow( item );
// in order to update the enabled state of the "Sync now" button
connect(folder, SIGNAL(syncStateChange()), this, SLOT(slotFolderSyncStateChange()), Qt::UniqueConnection);
@@ -537,7 +537,7 @@ void AccountSettings::slotUpdateFolderState( Folder *folder )
}
if( item ) {
folderToModelItem( item, folder, _accountState->isConnectedOrTemporarilyUnavailable() );
folderToModelItem( item, folder, _accountState->isConnectedOrMaintenance() );
} else {
// the dialog is not visible.
}
@@ -794,7 +794,7 @@ void AccountSettings::slotAccountStateChanged(int state)
foreach (Folder *folder, folderMan->map().values()) {
slotUpdateFolderState(folder);
}
if (state == AccountState::Connected || state == AccountState::ServiceUnavailable) {
if (state == AccountState::Connected || state == AccountState::ServerMaintenance) {
QString user;
if (AbstractCredentials *cred = account->credentials()) {
user = cred->user();
-3
Ver Arquivo
@@ -40,9 +40,6 @@
<property name="text">
<string>Connected with &lt;server&gt; as &lt;user&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
+10 -26
Ver Arquivo
@@ -43,9 +43,7 @@ void AccountStateManager::setAccountState(AccountState *accountState)
emit accountStateRemoved(_accountState);
}
_accountState = accountState;
if (accountState) {
emit accountStateAdded(accountState);
}
emit accountStateAdded(accountState);
}
void AccountStateManager::slotAccountAdded(AccountPtr account)
@@ -56,15 +54,13 @@ void AccountStateManager::slotAccountAdded(AccountPtr account)
AccountState::AccountState(AccountPtr account)
: QObject(account.data())
, _account(account)
, _quotaInfo(0)
, _quotaInfo(new QuotaInfo(this))
, _state(AccountState::Disconnected)
, _connectionStatus(ConnectionValidator::Undefined)
, _waitingForNewCredentials(false)
{
qRegisterMetaType<AccountState*>("AccountState*");
_quotaInfo = new QuotaInfo(this); // Need to be initialized when 'this' is fully initialized
connect(account.data(), SIGNAL(invalidCredentials()),
SLOT(slotInvalidCredentials()));
connect(account.data(), SIGNAL(credentialsFetched(AbstractCredentials*)),
@@ -114,10 +110,9 @@ void AccountState::setState(State state)
} else if (oldState == SignedOut && _state == Disconnected) {
checkConnectivity();
}
}
// might not have changed but the underlying _connectionErrors might have
emit stateChanged(_state);
emit stateChanged(_state);
}
}
QString AccountState::stateString(State state)
@@ -130,8 +125,8 @@ QString AccountState::stateString(State state)
return QLatin1String("Disconnected");
case Connected:
return QLatin1String("Connected");
case ServiceUnavailable:
return QLatin1String("ServiceUnavailable");
case ServerMaintenance:
return QLatin1String("ServerMaintenance");
case NetworkError:
return QLatin1String("NetworkError");
case ConfigurationError:
@@ -159,9 +154,9 @@ bool AccountState::isConnected() const
return _state == Connected;
}
bool AccountState::isConnectedOrTemporarilyUnavailable() const
bool AccountState::isConnectedOrMaintenance() const
{
return isConnected() || _state == ServiceUnavailable;
return isConnected() || _state == ServerMaintenance;
}
QuotaInfo *AccountState::quotaInfo()
@@ -175,12 +170,7 @@ void AccountState::checkConnectivity()
return;
}
if (_connectionValidator) {
qDebug() << "ConnectionValidator already running, ignoring";
return;
}
ConnectionValidator * conValidator = new ConnectionValidator(account());
_connectionValidator = conValidator;
connect(conValidator, SIGNAL(connectionResult(ConnectionValidator::Status,QStringList)),
SLOT(slotConnectionValidatorResult(ConnectionValidator::Status,QStringList)));
if (isConnected()) {
@@ -240,8 +230,8 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
case ConnectionValidator::UserCanceledCredentials:
setState(SignedOut);
break;
case ConnectionValidator::ServiceUnavailable:
setState(ServiceUnavailable);
case ConnectionValidator::ServerMaintenance:
setState(ServerMaintenance);
break;
case ConnectionValidator::Timeout:
setState(NetworkError);
@@ -269,12 +259,6 @@ void AccountState::slotCredentialsFetched(AbstractCredentials* credentials)
return;
}
// When new credentials become available we always want to restart the
// connection validation, even if it's currently running.
if (_connectionValidator) {
delete _connectionValidator;
}
checkConnectivity();
}
+4 -6
Ver Arquivo
@@ -16,7 +16,6 @@
#define ACCOUNTINFO_H
#include <QByteArray>
#include <QPointer>
#include "utility.h"
#include "connectionvalidator.h"
@@ -68,9 +67,9 @@ public:
/// The account is successfully talking to the server.
Connected,
/// There's a temporary problem with talking to the server,
/// don't bother the user too much and try again.
ServiceUnavailable,
/// The account is talking to the server, but the server is in
/// maintenance mode.
ServerMaintenance,
/// Could not communicate with the server for some reason.
/// We assume this may resolve itself over time and will try
@@ -101,7 +100,7 @@ public:
void setSignedOut(bool signedOut);
bool isConnected() const;
bool isConnectedOrTemporarilyUnavailable() const;
bool isConnectedOrMaintenance() const;
QuotaInfo *quotaInfo();
@@ -129,7 +128,6 @@ private:
ConnectionStatus _connectionStatus;
QStringList _connectionErrors;
bool _waitingForNewCredentials;
QPointer<ConnectionValidator> _connectionValidator;
};
}
+2 -12
Ver Arquivo
@@ -110,15 +110,6 @@ Application::Application(int &argc, char **argv) :
if (isRunning())
return;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) && QT_VERSION < QT_VERSION_CHECK(5, 4, 2)
// Workaround for QTBUG-44576: Make sure a stale QSettings lock file
// is deleted. (Introduced in Qt 5.4.0 and fixed in Qt 5.4.2)
{
QString lockFilePath = ConfigFile().configFile() + QLatin1String(".lock");
QLockFile(lockFilePath).removeStaleLockFile();
}
#endif
#if defined(WITH_CRASHREPORTER)
if (ConfigFile().crashReporter())
_crashHandler.reset(new CrashReporter::Handler( QDir::tempPath(), true, CRASHREPORTER_EXECUTABLE ));
@@ -189,8 +180,7 @@ Application::Application(int &argc, char **argv) :
Application::~Application()
{
// Remove the account from the account manager so it can be deleted.
AccountManager::instance()->setAccount(AccountPtr());
// qDebug() << "* OCC shutdown";
}
void Application::slotLogin()
@@ -279,7 +269,7 @@ void Application::slotAccountStateChanged(int state)
folderMan->setSyncEnabled(true);
folderMan->slotScheduleAllFolders();
break;
case AccountState::ServiceUnavailable:
case AccountState::ServerMaintenance:
case AccountState::SignedOut:
case AccountState::ConfigurationError:
case AccountState::NetworkError:
-1
Ver Arquivo
@@ -772,7 +772,6 @@ void Folder::startSync(const QStringList &pathList)
_timeSinceLastSyncStart.restart();
_syncResult.clearErrors();
_syncResult.setStatus( SyncResult::SyncPrepare );
_syncResult.setSyncFileItemVector(SyncFileItemVector());
emit syncStateChange();
qDebug() << "*** Start syncing - client version"
-7
Ver Arquivo
@@ -873,13 +873,6 @@ void FolderMan::setDirtyProxy(bool value)
foreach( Folder *f, _folderMap.values() ) {
if(f) {
f->setProxyDirty(value);
if (f->accountState() && f->accountState()->account()
&& f->accountState()->account()->networkAccessManager()) {
// Need to do this have us not use the old determined system proxy
f->accountState()->account()->networkAccessManager()->setProxy(
QNetworkProxy(QNetworkProxy::DefaultProxy));
}
}
}
}
-1
Ver Arquivo
@@ -32,7 +32,6 @@ class SelectiveSyncTreeView;
class ownCloudInfo;
class FormatWarningsWizardPage : public QWizardPage {
Q_OBJECT
protected:
QString formatWarnings(const QStringList &warnings) const;
};
+1
Ver Arquivo
@@ -43,6 +43,7 @@ IgnoreListEditor::IgnoreListEditor(QWidget *parent) :
connect(this, SIGNAL(accepted()), SLOT(slotUpdateLocalIgnoreList()));
ui->removePushButton->setEnabled(false);
connect(ui->listWidget, SIGNAL(itemSelectionChanged()), SLOT(slotItemSelectionChanged()));
connect(ui->listWidget, SIGNAL(itemActivated(QListWidgetItem*)), SLOT(slotItemChanged(QListWidgetItem*)));
connect(ui->removePushButton, SIGNAL(clicked()), SLOT(slotRemoveCurrentItem()));
connect(ui->addPushButton, SIGNAL(clicked()), SLOT(slotAddPattern()));
connect(ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), SLOT(slotEditPattern(QListWidgetItem*)));
+1 -1
Ver Arquivo
@@ -221,7 +221,7 @@ void ownCloudGui::slotComputeOverallSyncStatus()
_tray->setToolTip(tr("Please sign in"));
return;
}
if (!a->isConnectedOrTemporarilyUnavailable()) {
if (!a->isConnectedOrMaintenance()) {
_tray->setIcon(Theme::instance()->folderOfflineIcon(true));
_tray->setToolTip(tr("Disconnected from server"));
return;
+27 -74
Ver Arquivo
@@ -145,9 +145,6 @@ void OwncloudSetupWizard::slotDetermineAuthType(const QString &urlString)
}
AccountPtr account = _ocWizard->account();
account->setUrl(url);
// Reset the proxy which might had been determined previously in ConnectionValidator::checkServerAndAuth()
// when there was a previous account.
account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::DefaultProxy));
// Set fake credentials beforfe we check what credential it actually is.
account->setCredentials(CredentialsFactory::create("dummy"));
CheckServerJob *job = new CheckServerJob(_ocWizard->account(), this);
@@ -189,10 +186,6 @@ void OwncloudSetupWizard::slotNoOwnCloudFoundAuth(QNetworkReply *reply)
.arg(Theme::instance()->appNameGUI(),
reply->url().toString(),
reply->errorString()), checkDowngradeAdvised(reply));
// Allow the credentials dialog to pop up again for the same URL.
// Maybe the user just clicked 'Cancel' by accident or changed his mind.
_ocWizard->account()->resetSslCertErrorState();
}
void OwncloudSetupWizard::slotNoOwnCloudFoundAuthTimeout(const QUrl&url)
@@ -221,72 +214,11 @@ void OwncloudSetupWizard::testOwnCloudConnect()
auto *job = new PropfindJob(account, "/", this);
job->setIgnoreCredentialFailure(true);
job->setProperties(QList<QByteArray>() << "getlastmodified");
connect(job, SIGNAL(result(QVariantMap)), _ocWizard, SLOT(successfulStep()));
connect(job, SIGNAL(finishedWithError()), this, SLOT(slotAuthError()));
connect(job, SIGNAL(result(QVariantMap)), _ocWizard, SLOT(successfulStep()));
connect(job, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotConnectionCheck(QNetworkReply*)));
job->start();
}
void OwncloudSetupWizard::slotAuthError()
{
QString errorMsg;
PropfindJob* job = qobject_cast<PropfindJob*>(sender());
if (!job) {
qWarning() << "Can't check for authed redirects. This slot should be invoked from PropfindJob!";
return;
}
QNetworkReply* reply = job->reply();
// If there were redirects on the *authed* requests, also store
// the updated server URL, similar to redirects on status.php.
QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (!redirectUrl.isEmpty()) {
qDebug() << "authed request was redirected to" << redirectUrl.toString();
// strip the expected path
QString path = redirectUrl.path();
static QString expectedPath = "/" + _ocWizard->account()->davPath();
if (path.endsWith(expectedPath)) {
path.chop(expectedPath.size());
redirectUrl.setPath(path);
qDebug() << "setting account url to" << redirectUrl.toString();
_ocWizard->account()->setUrl(redirectUrl);
testOwnCloudConnect();
return;
}
errorMsg = tr("The authenticated request to the server was redirected to "
"'%1'. The URL is bad, the server is misconfigured.")
.arg(redirectUrl.toString());
// A 404 is actually a success: we were authorized to know that the folder does
// not exist. It will be created later...
} else if (reply->error() == QNetworkReply::ContentNotFoundError) {
_ocWizard->successfulStep();
return;
// Provide messages for other errors, such as invalid credentials.
} else if (reply->error() != QNetworkReply::NoError) {
if (!_ocWizard->account()->credentials()->stillValid(reply)) {
errorMsg = tr("Access forbidden by server. To verify that you have proper access, "
"<a href=\"%1\">click here</a> to access the service with your browser.")
.arg(_ocWizard->account()->url().toString());
} else {
errorMsg = errorMessage(reply->errorString(), reply->readAll());
}
// Something else went wrong, maybe the response was 200 but with invalid data.
} else {
errorMsg = tr("There was an invalid response to an authenticated webdav request");
}
_ocWizard->show();
if (_ocWizard->currentId() == WizardCommon::Page_ShibbolethCreds) {
_ocWizard->back();
}
_ocWizard->displayError(errorMsg, _ocWizard->currentId() == WizardCommon::Page_ServerSetup && checkDowngradeAdvised(reply));
}
bool OwncloudSetupWizard::checkDowngradeAdvised(QNetworkReply* reply)
{
if(reply->url().scheme() != QLatin1String("https")) {
@@ -310,6 +242,29 @@ bool OwncloudSetupWizard::checkDowngradeAdvised(QNetworkReply* reply)
return true;
}
void OwncloudSetupWizard::slotConnectionCheck(QNetworkReply* reply)
{
QString msg = reply->errorString();
switch (reply->error()) {
case QNetworkReply::NoError:
case QNetworkReply::ContentNotFoundError:
_ocWizard->successfulStep();
break;
default:
if (!_ocWizard->account()->credentials()->stillValid(reply)) {
msg = tr("Access forbidden by server. To verify that you have proper access, "
"<a href=\"%1\">click here</a> to access the service with your browser.")
.arg(_ocWizard->account()->url().toString());
}
_ocWizard->show();
if (_ocWizard->currentId() == WizardCommon::Page_ShibbolethCreds) {
_ocWizard->back();
}
_ocWizard->displayError(msg, _ocWizard->currentId() == WizardCommon::Page_ServerSetup && checkDowngradeAdvised(reply));
break;
}
}
void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFolder, const QString& remoteFolder)
{
qDebug() << "Setup local sync folder for new oC connection " << localFolder;
@@ -336,7 +291,7 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo
}
if (nextStep) {
EntityExistsJob *job = new EntityExistsJob(_ocWizard->account(), _ocWizard->account()->davPath() + remoteFolder, this);
connect(job, SIGNAL(exists(QNetworkReply*)), SLOT(slotRemoteFolderExists(QNetworkReply*)));
connect(job, SIGNAL(exists(QNetworkReply*)), SLOT(slotAuthCheckReply(QNetworkReply*)));
job->start();
} else {
finalizeSetup( false );
@@ -344,7 +299,7 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo
}
// ### TODO move into EntityExistsJob once we decide if/how to return gui strings from jobs
void OwncloudSetupWizard::slotRemoteFolderExists(QNetworkReply *reply)
void OwncloudSetupWizard::slotAuthCheckReply(QNetworkReply *reply)
{
bool ok = true;
QString error;
@@ -564,10 +519,8 @@ bool DetermineAuthTypeJob::finished()
} else if (redirection.toString().endsWith(account()->davPath())) {
// do a new run
_redirects++;
resetTimeout();
setReply(getRequest(redirection));
setupConnections(reply());
return false; // don't discard
} else {
QRegExp shibbolethyWords("SAML|wayf");
+2 -2
Ver Arquivo
@@ -62,10 +62,10 @@ private slots:
void slotNoOwnCloudFoundAuthTimeout(const QUrl&url);
void slotConnectToOCUrl(const QString&);
void slotAuthError();
void slotConnectionCheck(QNetworkReply*);
void slotCreateLocalAndRemoteFolders(const QString&, const QString&);
void slotRemoteFolderExists(QNetworkReply*);
void slotAuthCheckReply(QNetworkReply*);
void slotCreateRemoteFolderFinished(QNetworkReply::NetworkError);
void slotAssistantFinished( int );
void slotSkipFolderConfiguration();
+11 -6
Ver Arquivo
@@ -167,11 +167,16 @@ void ProtocolWidget::cleanIgnoreItems(const QString& folder)
QString ProtocolWidget::timeString(QDateTime dt, QLocale::FormatType format) const
{
const QLocale loc = QLocale::system();
QString dtFormat = loc.dateTimeFormat(format);
static const QRegExp re("(HH|H|hh|h):mm(?!:s)");
dtFormat.replace(re, "\\1:mm:ss");
return loc.toString(dt, dtFormat);
QLocale loc = QLocale::system();
QString timeStr;
if( format == QLocale::NarrowFormat ) {
timeStr = loc.toString(dt, QLocale::NarrowFormat);
} else {
timeStr = loc.toString(dt, format);
}
return timeStr;
}
void ProtocolWidget::slotOpenFile( QTreeWidgetItem *item, int )
@@ -206,7 +211,7 @@ QTreeWidgetItem* ProtocolWidget::createCompletedTreewidgetItem(const QString& fo
const QString longTimeStr = timeString(timestamp, QLocale::LongFormat);
columns << timeStr;
columns << fixupFilename(item._originalFile);
columns << fixupFilename(item._file);
columns << folder;
// If the error string is set, it's prefered because it is a useful user message.
+4 -27
Ver Arquivo
@@ -26,33 +26,10 @@
#include <QDebug>
#include <QSettings>
#include <QScopedValueRollback>
#include <QTreeWidgetItem>
#include <QLabel>
namespace OCC {
class SelectiveSyncTreeViewItem : public QTreeWidgetItem {
public:
SelectiveSyncTreeViewItem(int type = QTreeWidgetItem::Type)
: QTreeWidgetItem(type) { }
SelectiveSyncTreeViewItem(const QStringList &strings, int type = QTreeWidgetItem::Type)
: QTreeWidgetItem(strings, type) { }
SelectiveSyncTreeViewItem(QTreeWidget *view, int type = QTreeWidgetItem::Type)
: QTreeWidgetItem(view, type) { }
SelectiveSyncTreeViewItem(QTreeWidgetItem *parent, int type = QTreeWidgetItem::Type)
: QTreeWidgetItem(parent, type) { }
private:
bool operator<(const QTreeWidgetItem &other)const {
int column = treeWidget()->sortColumn();
if (column == 1) {
return data(1, Qt::UserRole).toLongLong() < other.data(1, Qt::UserRole).toLongLong();
}
return QTreeWidgetItem::operator <(other);
}
};
SelectiveSyncTreeView::SelectiveSyncTreeView(AccountPtr account, QWidget* parent)
: QTreeWidget(parent), _inserting(false), _account(account)
{
@@ -124,9 +101,9 @@ void SelectiveSyncTreeView::recursiveInsert(QTreeWidgetItem* parent, QStringList
parent->setToolTip(0, path);
parent->setData(0, Qt::UserRole, path);
} else {
SelectiveSyncTreeViewItem *item = static_cast<SelectiveSyncTreeViewItem*>(findFirstChild(parent, pathTrail.first()));
QTreeWidgetItem *item = findFirstChild(parent, pathTrail.first());
if (!item) {
item = new SelectiveSyncTreeViewItem(parent);
item = new QTreeWidgetItem(parent);
if (parent->checkState(0) == Qt::Checked
|| parent->checkState(0) == Qt::PartiallyChecked) {
item->setCheckState(0, Qt::Checked);
@@ -161,7 +138,7 @@ void SelectiveSyncTreeView::slotUpdateDirectories(const QStringList&list)
QScopedValueRollback<bool> isInserting(_inserting);
_inserting = true;
SelectiveSyncTreeViewItem *root = static_cast<SelectiveSyncTreeViewItem*>(topLevelItem(0));
QTreeWidgetItem *root = topLevelItem(0);
if (!root && list.size() <= 1) {
_loading->setText(tr("No subfolders currently on the server."));
@@ -172,7 +149,7 @@ void SelectiveSyncTreeView::slotUpdateDirectories(const QStringList&list)
}
if (!root) {
root = new SelectiveSyncTreeViewItem(this);
root = new QTreeWidgetItem(this);
root->setText(0, _rootName);
root->setIcon(0, Theme::instance()->applicationIcon());
root->setData(0, Qt::UserRole, QString());
+76 -114
Ver Arquivo
@@ -21,7 +21,6 @@
#include "folder.h"
#include "theme.h"
#include "syncresult.h"
#include "configfile.h"
#include "QProgressIndicator.h"
#include <QBuffer>
@@ -45,8 +44,6 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
_resharingAllowed(resharingAllowed)
{
setAttribute(Qt::WA_DeleteOnClose);
setObjectName("SharingDialog"); // required as group for saveGeometry call
_ui->setupUi(this);
_ui->pushButton_copy->setIcon(QIcon::fromTheme("edit-copy"));
_ui->pushButton_copy->setEnabled(false);
@@ -87,31 +84,24 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
QIcon icon = icon_provider.icon(f_info);
_ui->label_icon->setPixmap(icon.pixmap(40,40));
QFileInfo lPath(_localPath);
QString fileName = lPath.fileName();
_ui->label_name->setText(tr("%1").arg(fileName));
QFont f( _ui->label_name->font());
f.setPointSize( f.pointSize() * 1.4 );
_ui->label_name->setFont( f );
QString name;
if( f_info.isDir() ) {
name = tr("Share Directory");
} else {
name = tr("Share File");
}
_ui->groupBox->setTitle(name);
QString lPath(_localPath);
if( lPath.length() > 50) {
lPath = QLatin1String("...")+lPath.right(50);
}
_ui->label_name->setText(tr("Local path: %1").arg(lPath));
_ui->label_sharePath->setWordWrap(true);
QString ocDir(_sharePath);
ocDir.truncate(ocDir.length()-fileName.length());
if( ocDir == QLatin1String("/")) {
_ui->label_sharePath->setText(QString());
} else {
if( ocDir.startsWith(QLatin1Char('/')) ) {
ocDir = ocDir.mid(1, -1);
}
if( ocDir.endsWith(QLatin1Char('/')) ) {
ocDir.chop(1);
}
_ui->label_sharePath->setText(tr("Folder: %2").arg(ocDir));
}
_ui->label_sharePath->setText(tr("%1 path: %2").arg(Theme::instance()->appNameGUI()).arg(_sharePath));
this->setWindowTitle(tr("%1 Sharing").arg(Theme::instance()->appNameGUI()));
_ui->checkBox_password->setText(tr("P&assword protect"));
_ui->label_password->setText(tr("Set p&assword"));
// check if the file is already inside of a synced folder
if( sharePath.isEmpty() ) {
// The file is not yet in an ownCloud synced folder. We could automatically
@@ -138,21 +128,6 @@ ShareDialog::ShareDialog(AccountPtr account, const QString &sharePath, const QSt
_ui->errorLabel->hide();
}
void ShareDialog::done( int r ) {
ConfigFile cfg;
cfg.saveGeometry(this);
QDialog::done(r);
}
static int getJsonReturnCode(const QVariantMap &json, QString &message)
{
//TODO proper checking
int code = json.value("ocs").toMap().value("meta").toMap().value("statuscode").toInt();
message = json.value("ocs").toMap().value("meta").toMap().value("message").toString();
return code;
}
void ShareDialog::setExpireDate(const QDate &date)
{
if( _public_share_id == 0 ) {
@@ -171,14 +146,16 @@ void ShareDialog::setExpireDate(const QDate &date)
OcsShareJob *job = new OcsShareJob("PUT", url, _account, this);
job->setPostParams(postParams);
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotExpireSet(QVariantMap)));
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotExpireSet(QString)));
job->start();
}
void ShareDialog::slotExpireSet(const QVariantMap &reply)
void ShareDialog::slotExpireSet(const QString &reply)
{
QString message;
int code = getJsonReturnCode(reply, message);
int code = checkJsonReturnCode(reply, message);
qDebug() << Q_FUNC_INFO << "Status code: " << code;
if (code != 100) {
displayError(code);
}
@@ -241,15 +218,18 @@ void ShareDialog::setPassword(const QString &password)
}
OcsShareJob *job = new OcsShareJob(verb, url, _account, this);
job->setPostParams(requestParams);
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotPasswordSet(QVariantMap)));
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotPasswordSet(QString)));
job->start();
_passwordJobRunning = true;
}
void ShareDialog::slotPasswordSet(const QVariantMap &reply)
void ShareDialog::slotPasswordSet(const QString &reply)
{
QString message;
int code = getJsonReturnCode(reply, message);
int code = checkJsonReturnCode(reply, message);
qDebug() << Q_FUNC_INFO << "Status code: " << code;
if (code != 100) {
displayError(code);
}
@@ -271,20 +251,23 @@ void ShareDialog::getShares()
params.append(qMakePair(QString::fromLatin1("path"), _sharePath));
url.setQueryItems(params);
OcsShareJob *job = new OcsShareJob("GET", url, _account, this);
job->addPassStatusCode(404); // don't report error if share doesn't exist yet
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotSharesFetched(QVariantMap)));
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotSharesFetched(QString)));
job->start();
}
void ShareDialog::slotSharesFetched(const QVariantMap &reply)
void ShareDialog::slotSharesFetched(const QString &reply)
{
QString message;
int code = getJsonReturnCode(reply, message);
int code = checkJsonReturnCode(reply, message);
qDebug() << Q_FUNC_INFO << "Status code: " << code;
if (code != 100 && code != 404) {
displayError(code);
}
ShareDialog::_shares = reply.value("ocs").toMap().value("data").toList();
bool success = false;
QVariantMap json = QtJson::parse(reply, success).toMap();
ShareDialog::_shares = json.value("ocs").toMap().value("data").toList();
const QString versionString = AccountManager::instance()->account()->serverVersion();
Q_FOREACH(auto share, ShareDialog::_shares) {
@@ -292,7 +275,6 @@ void ShareDialog::slotSharesFetched(const QVariantMap &reply)
if (data.value("share_type").toInt() == SHARETYPE_PUBLIC) {
_public_share_id = data.value("id").toULongLong();
_ui->pushButton_copy->show();
_ui->widget_shareLink->show();
_ui->checkBox_shareLink->setChecked(true);
@@ -349,47 +331,28 @@ void ShareDialog::slotSharesFetched(const QVariantMap &reply)
}
}
void ShareDialog::resizeEvent(QResizeEvent *e)
{
QDialog::resizeEvent(e);
redrawElidedUrl();
}
void ShareDialog::redrawElidedUrl()
{
QString u;
if( !_shareUrl.isEmpty() ) {
QFontMetrics fm( _ui->_labelShareLink->font() );
int linkLengthPixel = _ui->_labelShareLink->width();
const QUrl realUrl(_shareUrl);
QString elidedUrl = fm.elidedText(_shareUrl, Qt::ElideRight, linkLengthPixel);
u = QString("<a href=\"%1\">%2</a>").arg(realUrl.toString(QUrl::None)).arg(elidedUrl);
}
_ui->_labelShareLink->setText(u);
}
void ShareDialog::setShareLink( const QString& url )
{
// FIXME: shorten the url for output.
const QUrl realUrl(url);
if( realUrl.isValid() ) {
const QString u = QString("<a href=\"%1\">%2</a>").arg(realUrl.toString(QUrl::None)).arg(url);
_ui->_labelShareLink->setText(u);
_shareUrl = url;
_ui->pushButton_copy->setEnabled(true);
} else {
_shareUrl.clear();
_ui->_labelShareLink->setText(QString::null);
}
redrawElidedUrl();
}
void ShareDialog::slotDeleteShareFetched(const QVariantMap &reply)
void ShareDialog::slotDeleteShareFetched(const QString &reply)
{
QString message;
int code = getJsonReturnCode(reply, message);
int code = checkJsonReturnCode(reply, message);
qDebug() << Q_FUNC_INFO << "Status code: " << code;
if (code != 100) {
displayError(code);
}
@@ -423,31 +386,29 @@ void ShareDialog::slotCheckBoxShareLinkClicked()
postParams.append(qMakePair(QString::fromLatin1("shareType"), QString::number(SHARETYPE_PUBLIC)));
OcsShareJob *job = new OcsShareJob("POST", url, _account, this);
job->setPostParams(postParams);
job->addPassStatusCode(403); // "password required" is not an error
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotCreateShareFetched(QVariantMap)));
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotCreateShareFetched(QString)));
job->start();
} else {
_pi_link->startAnimation();
QUrl url = Account::concatUrlPath(_account->url(), QString("ocs/v1.php/apps/files_sharing/api/v1/shares/%1").arg(_public_share_id));
OcsShareJob *job = new OcsShareJob("DELETE", url, _account, this);
connect(job, SIGNAL(jobFinished(QVariantMap)), this, SLOT(slotDeleteShareFetched(QVariantMap)));
connect(job, SIGNAL(jobFinished(QString)), this, SLOT(slotDeleteShareFetched(QString)));
job->start();
}
}
void ShareDialog::slotCreateShareFetched(const QVariantMap &reply)
void ShareDialog::slotCreateShareFetched(const QString &reply)
{
QString message;
int code = getJsonReturnCode(reply, message);
int code = checkJsonReturnCode(reply, message);
_pi_link->stopAnimation();
if (code == 403) {
// there needs to be a password
_ui->checkBox_password->setChecked(true);
_ui->checkBox_password->setEnabled(false);
_ui->checkBox_password->setText(tr("Public sh&aring requires a password"));
_ui->checkBox_password->setVisible(false);
_ui->label_password->setText(tr("Public sh&aring requires a password:"));
_ui->lineEdit_password->setFocus();
_ui->pushButton_copy->hide();
_ui->widget_shareLink->show();
slotCheckBoxPasswordClicked();
@@ -457,9 +418,16 @@ void ShareDialog::slotCreateShareFetched(const QVariantMap &reply)
return;
}
_public_share_id = reply.value("ocs").toMap().values("data")[0].toMap().value("id").toULongLong();
_ui->pushButton_copy->show();
getShares();
bool success;
QVariantMap json = QtJson::parse(reply, success).toMap();
_public_share_id = json.value("ocs").toMap().values("data")[0].toMap().value("id").toULongLong();
QString url = json.value("ocs").toMap().values("data")[0].toMap().value("url").toString();
setShareLink(url);
setShareCheckBoxTitle(true);
_ui->widget_shareLink->show();
}
void ShareDialog::slotCheckBoxPasswordClicked()
@@ -467,7 +435,7 @@ void ShareDialog::slotCheckBoxPasswordClicked()
if (_ui->checkBox_password->checkState() == Qt::Checked) {
_ui->lineEdit_password->show();
_ui->pushButton_setPassword->show();
_ui->lineEdit_password->setPlaceholderText(tr("Password"));
_ui->lineEdit_password->setPlaceholderText(tr("Choose a password for the public link"));
_ui->lineEdit_password->setFocus();
} else {
ShareDialog::setPassword(QString());
@@ -501,10 +469,26 @@ void ShareDialog::slotPushButtonCopyLinkPressed()
clipboard->setText(_shareUrl);
}
int ShareDialog::checkJsonReturnCode(const QString &reply, QString &message)
{
bool success;
QVariantMap json = QtJson::parse(reply, success).toMap();
if (!success) {
qDebug() << Q_FUNC_INFO << "Failed to parse reply";
}
//TODO proper checking
int code = json.value("ocs").toMap().value("meta").toMap().value("statuscode").toInt();
message = json.value("ocs").toMap().value("meta").toMap().value("message").toString();
return code;
}
void ShareDialog::setShareCheckBoxTitle(bool haveShares)
{
const QString noSharesTitle(tr("&Share link"));
const QString haveSharesTitle(tr("&Share link"));
const QString noSharesTitle(tr("Check to &share by public link"));
const QString haveSharesTitle(tr("&Shared by public link (uncheck to delete share)"));
if( haveShares ) {
_ui->checkBox_shareLink->setText( haveSharesTitle );
@@ -657,7 +641,6 @@ OcsShareJob::OcsShareJob(const QByteArray &verb, const QUrl &url, AccountPtr acc
_verb(verb),
_url(url)
{
_passStatusCodes.append(100);
setIgnoreCredentialFailure(true);
}
@@ -666,11 +649,6 @@ void OcsShareJob::setPostParams(const QList<QPair<QString, QString> >& postParam
_postParams = postParams;
}
void OcsShareJob::addPassStatusCode(int code)
{
_passStatusCodes.append(code);
}
void OcsShareJob::start()
{
QNetworkRequest req;
@@ -702,23 +680,7 @@ void OcsShareJob::start()
bool OcsShareJob::finished()
{
const QString replyData = reply()->readAll();
bool success;
QVariantMap json = QtJson::parse(replyData, success).toMap();
if (!success) {
qDebug() << "Could not parse reply to" << _verb << _url << _postParams
<< ":" << replyData;
}
QString message;
const int statusCode = getJsonReturnCode(json, message);
if (!_passStatusCodes.contains(statusCode)) {
qDebug() << "Reply to" << _verb << _url << _postParams
<< "has unexpected status code:" << statusCode << replyData;
}
emit jobFinished(json);
emit jobFinished(reply()->readAll());
return true;
}
+8 -12
Ver Arquivo
@@ -29,19 +29,17 @@ public:
explicit OcsShareJob(const QByteArray& verb, const QUrl& url, AccountPtr account, QObject* parent = 0);
void setPostParams(const QList<QPair<QString, QString> >& postParams);
void addPassStatusCode(int code);
public slots:
void start() Q_DECL_OVERRIDE;
signals:
void jobFinished(QVariantMap reply);
void jobFinished(QString reply);
private slots:
virtual bool finished() Q_DECL_OVERRIDE;
private:
QByteArray _verb;
QUrl _url;
QList<QPair<QString, QString> > _postParams;
QVector<int> _passStatusCodes;
};
@@ -51,6 +49,7 @@ class ShareDialog;
class AbstractCredentials;
class QuotaInfo;
class MirallAccessManager;
class SyncResult;
class ShareDialog : public QDialog
@@ -64,11 +63,11 @@ public:
void getShares();
private slots:
void slotSharesFetched(const QVariantMap &reply);
void slotCreateShareFetched(const QVariantMap &reply);
void slotDeleteShareFetched(const QVariantMap &reply);
void slotPasswordSet(const QVariantMap &reply);
void slotExpireSet(const QVariantMap &reply);
void slotSharesFetched(const QString &reply);
void slotCreateShareFetched(const QString &reply);
void slotDeleteShareFetched(const QString &reply);
void slotPasswordSet(const QString &reply);
void slotExpireSet(const QString &reply);
void slotCalendarClicked(const QDate &date);
void slotCheckBoxShareLinkClicked();
void slotCheckBoxPasswordClicked();
@@ -77,15 +76,11 @@ private slots:
void slotPasswordChanged(const QString& newText);
void slotPushButtonCopyLinkPressed();
void slotThumbnailFetched(const int &statusCode, const QByteArray &reply);
void done( int r );
private:
void setShareCheckBoxTitle(bool haveShares);
void displayError(int code);
void displayError(const QString& errMsg);
void setShareLink( const QString& url );
void resizeEvent(QResizeEvent *e);
void redrawElidedUrl();
Ui::ShareDialog *_ui;
AccountPtr _account;
@@ -103,6 +98,7 @@ private:
qulonglong _public_share_id;
void setPassword(const QString &password);
void setExpireDate(const QDate &date);
int checkJsonReturnCode(const QString &reply, QString &message);
QProgressIndicator *_pi_link;
QProgressIndicator *_pi_password;
+96 -121
Ver Arquivo
@@ -6,71 +6,23 @@
<rect>
<x>0</x>
<y>0</y>
<width>372</width>
<height>241</height>
<width>403</width>
<height>296</height>
</rect>
</property>
<property name="windowTitle">
<string>Share NewDocument.odt</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="label_icon">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_name">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>share label</string>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QProgressIndicator" name="pi_share" native="true"/>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_sharePath">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>ownCloud Path:</string>
</property>
</widget>
</item>
</layout>
<layout class="QGridLayout" name="gridLayout_4">
<item row="4" column="0">
<widget class="QLabel" name="errorLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_shareLink">
<property name="topMargin">
<number>10</number>
</property>
<item>
<widget class="QCheckBox" name="checkBox_shareLink">
<property name="text">
@@ -82,14 +34,8 @@
</item>
<item row="2" column="0" colspan="2">
<widget class="QWidget" name="widget_shareLink" native="true">
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>20</number>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -122,7 +68,7 @@
<item>
<widget class="QPushButton" name="pushButton_copy">
<property name="text">
<string>Copy &amp;link</string>
<string>Copy &amp;Link</string>
</property>
</widget>
</item>
@@ -133,36 +79,30 @@
<item>
<widget class="QCheckBox" name="checkBox_password">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Set password</string>
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<widget class="QLabel" name="label_password">
<property name="text">
<string>Set p&amp;assword</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
<property name="buddy">
<cstring>checkBox_password</cstring>
</property>
</spacer>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>20</number>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<item>
<widget class="QLineEdit" name="lineEdit_password">
<property name="echoMode">
@@ -172,24 +112,15 @@
</item>
<item>
<widget class="QPushButton" name="pushButton_setPassword">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Set &amp;password </string>
<string>Set &amp;Password</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="checkBox_expire">
<property name="text">
@@ -209,6 +140,80 @@
</layout>
</widget>
</item>
<item row="5" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Share Info</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="label_icon">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_name">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>share label</string>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QProgressIndicator" name="pi_share" native="true"/>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_sharePath">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>ownCloud Path:</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="3" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
@@ -222,37 +227,7 @@
</property>
</spacer>
</item>
<item row="4" column="0">
<widget class="QLabel" name="errorLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
<zorder>errorLabel</zorder>
<zorder>widget_shareLink</zorder>
<zorder>buttonBox</zorder>
<zorder>checkBox_password</zorder>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
+14 -22
Ver Arquivo
@@ -1,7 +1,6 @@
/*
* Copyright (C) by Dominik Schmidt <dev@dominik-schmidt.de>
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
* Copyright (C) by Roeland Jago Douma <roeland@famdouma.nl>
*
* 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
@@ -25,7 +24,6 @@
#include "syncfileitem.h"
#include "filesystem.h"
#include "version.h"
#include "accountstate.h"
#include <QDebug>
#include <QUrl>
@@ -138,9 +136,7 @@ SocketApi::~SocketApi()
{
DEBUG << "dtor";
_localServer.close();
// All remaining sockets will be destroyed with _localServer, their parent
Q_ASSERT(_listeners.isEmpty() || _listeners.first()->parent() == &_localServer);
_listeners.clear();
qDeleteAll(_listeners);
slotClearExcludesList();
}
@@ -167,7 +163,7 @@ void SocketApi::slotReadExcludes()
void SocketApi::slotNewConnection()
{
QLocalSocket* socket = _localServer.nextPendingConnection();
SocketType* socket = _localServer.nextPendingConnection();
if( ! socket ) {
return;
@@ -199,7 +195,7 @@ void SocketApi::onLostConnection()
{
DEBUG << "Lost connection " << sender();
QLocalSocket* socket = qobject_cast<QLocalSocket*>(sender());
SocketType* socket = qobject_cast<SocketType*>(sender());
_listeners.removeAll(socket);
socket->deleteLater();
}
@@ -207,7 +203,7 @@ void SocketApi::onLostConnection()
void SocketApi::slotReadSocket()
{
QLocalSocket* socket = qobject_cast<QLocalSocket*>(sender());
SocketType* socket = qobject_cast<SocketType*>(sender());
Q_ASSERT(socket);
while(socket->canReadLine()) {
@@ -215,12 +211,12 @@ void SocketApi::slotReadSocket()
QString command = line.split(":").first();
QString function = QString(QLatin1String("command_")).append(command);
QString functionWithArguments = function + QLatin1String("(QString,QLocalSocket*)");
QString functionWithArguments = function + QLatin1String("(QString,SocketType*)");
int indexOfMethod = this->metaObject()->indexOfMethod(functionWithArguments.toAscii());
QString argument = line.remove(0, command.length()+1).trimmed();
if(indexOfMethod != -1) {
QMetaObject::invokeMethod(this, function.toAscii(), Q_ARG(QString, argument), Q_ARG(QLocalSocket*, socket));
QMetaObject::invokeMethod(this, function.toAscii(), Q_ARG(QString, argument), Q_ARG(SocketType*, socket));
} else {
DEBUG << "The command is not supported by this version of the client:" << command << "with argument:" << argument;
}
@@ -232,7 +228,7 @@ void SocketApi::slotRegisterPath( const QString& alias )
Folder *f = FolderMan::instance()->folder(alias);
if (f) {
QString message = buildRegisterPathMessage(f->path());
foreach(QLocalSocket *socket, _listeners) {
foreach(SocketType *socket, _listeners) {
sendMessage(socket, message);
}
}
@@ -337,7 +333,7 @@ void SocketApi::slotSyncItemDiscovered(const QString &folder, const SyncFileItem
void SocketApi::sendMessage(QLocalSocket *socket, const QString& message, bool doWait)
void SocketApi::sendMessage(SocketType *socket, const QString& message, bool doWait)
{
DEBUG << "Sending message: " << message;
QString localMessage = message;
@@ -372,12 +368,12 @@ void SocketApi::broadcastMessage( const QString& verb, const QString& path, cons
// sendMessage already has a debug output
//DEBUG << "Broadcasting to" << _listeners.count() << "listeners: " << msg;
foreach(QLocalSocket *socket, _listeners) {
foreach(SocketType *socket, _listeners) {
sendMessage(socket, msg, doWait);
}
}
void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, QLocalSocket* socket)
void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, SocketType* socket)
{
// This command is the same as RETRIEVE_FILE_STATUS
@@ -385,7 +381,7 @@ void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, QLocalSo
command_RETRIEVE_FILE_STATUS(argument, socket);
}
void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QLocalSocket* socket)
void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, SocketType* socket)
{
if( !socket ) {
qDebug() << "No valid socket object.";
@@ -413,7 +409,7 @@ void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QLocalSock
sendMessage(socket, message);
}
void SocketApi::command_SHARE(const QString& localFile, QLocalSocket* socket)
void SocketApi::command_SHARE(const QString& localFile, SocketType* socket)
{
if (!socket) {
qDebug() << Q_FUNC_INFO << "No valid socket object.";
@@ -427,10 +423,6 @@ void SocketApi::command_SHARE(const QString& localFile, QLocalSocket* socket)
const QString message = QLatin1String("SHARE:NOP:")+QDir::toNativeSeparators(localFile);
// files that are not within a sync folder are not synced.
sendMessage(socket, message);
} else if (!shareFolder->accountState()->isConnected()) {
const QString message = QLatin1String("SHARE:NOTCONNECTED:")+QDir::toNativeSeparators(localFile);
// if the folder isn't connected, don't open the share dialog
sendMessage(socket, message);
} else {
const QString folderForPath = shareFolder->path();
const QString remotePath = shareFolder->remotePath() + localFile.right(localFile.count()-folderForPath.count()+1);
@@ -451,12 +443,12 @@ void SocketApi::command_SHARE(const QString& localFile, QLocalSocket* socket)
}
}
void SocketApi::command_VERSION(const QString&, QLocalSocket* socket)
void SocketApi::command_VERSION(const QString&, SocketType* socket)
{
sendMessage(socket, QLatin1String("VERSION:" MIRALL_VERSION_STRING ":" MIRALL_SOCKET_API_VERSION));
}
void SocketApi::command_SHARE_MENU_TITLE(const QString &, QLocalSocket* socket)
void SocketApi::command_SHARE_MENU_TITLE(const QString &, SocketType* socket)
{
sendMessage(socket, QLatin1String("SHARE_MENU_TITLE:") + tr("Share with %1", "parameter is ownCloud").arg(Theme::instance()->appNameGUI()));
}
+13 -7
Ver Arquivo
@@ -37,6 +37,8 @@ class QStringList;
namespace OCC {
typedef QLocalSocket SocketType;
class SyncFileStatus;
class Folder;
@@ -70,20 +72,24 @@ private:
SyncJournalFileRecord dbFileRecord_capi( Folder *folder, QString fileName );
SqlQuery *getSqlQuery( Folder *folder );
void sendMessage(QLocalSocket* socket, const QString& message, bool doWait = false);
void sendMessage(SocketType* socket, const QString& message, bool doWait = false);
void broadcastMessage(const QString& verb, const QString &path, const QString &status = QString::null, bool doWait = false);
Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString& argument, QLocalSocket* socket);
Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString& argument, QLocalSocket* socket);
Q_INVOKABLE void command_SHARE(const QString& localFile, QLocalSocket* socket);
Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString& argument, SocketType* socket);
Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString& argument, SocketType* socket);
Q_INVOKABLE void command_SHARE(const QString& localFile, SocketType* socket);
Q_INVOKABLE void command_VERSION(const QString& argument, QLocalSocket* socket);
Q_INVOKABLE void command_VERSION(const QString& argument, SocketType* socket);
Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString& argument, QLocalSocket* socket);
Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString& argument, SocketType* socket);
QString buildRegisterPathMessage(const QString& path);
QList<QLocalSocket*> _listeners;
#ifdef SOCKETAPI_TCP
QTcpServer _localServer;
#else
QLocalServer _localServer;
#endif
QList<SocketType*> _listeners;
c_strlist_t *_excludes;
QHash<Folder*, SqlQuery*> _dbQueries;
QHash<Folder*, SqlDatabase*> _openDbs;
+14 -28
Ver Arquivo
@@ -31,10 +31,6 @@ SslButton::SslButton(QWidget *parent) :
{
setPopupMode(QToolButton::InstantPopup);
setAutoRaise(true);
setMenu(new QMenu(this));
QObject::connect(menu(), SIGNAL(aboutToShow()),
this, SLOT(slotUpdateMenu()));
}
QString SslButton::protoToString(QSsl::SslProtocol proto)
@@ -182,31 +178,17 @@ void SslButton::updateAccountState(AccountState *accountState)
} else {
setVisible(true);
}
_accountState = accountState;
AccountPtr account = _accountState->account();
AccountPtr account = accountState->account();
if(QMenu *oldMenu = menu()) {
oldMenu->hide(); // Need to be hidden because the QToolButton would be left in invalid state if the menu is deleted while it is visible
setMenu(0);
oldMenu->deleteLater(); // setMenu do not delete the previous menu.
}
if (account->url().scheme() == QLatin1String("https")) {
QPixmap pm(Theme::hidpiFileName(":/client/resources/lock-https.png"));
setIcon(QIcon(pm));
setIcon(QIcon(QPixmap(Theme::hidpiFileName(":/client/resources/lock-https.png"))));
QSslCipher cipher = account->sslConfiguration().sessionCipher();
setToolTip(tr("This connection is encrypted using %1 bit %2.\n").arg(cipher.usedBits()).arg(cipher.name()));
} else {
setIcon(QIcon(QPixmap(Theme::hidpiFileName(":/client/resources/lock-http.png"))));
setToolTip(tr("This connection is NOT secure as it is not encrypted.\n"));
}
}
void SslButton::slotUpdateMenu() {
menu()->clear();
if (!_accountState) {
return;
}
AccountPtr account = _accountState->account();
if (account->url().scheme() == QLatin1String("https")) {
QMenu *menu = new QMenu(this);
QList<QSslCertificate> chain = account->sslConfiguration().peerCertificateChain();
if (chain.isEmpty()) {
@@ -214,7 +196,7 @@ void SslButton::slotUpdateMenu() {
return;
}
menu()->addAction(tr("Certificate information:"))->setEnabled(false);
menu->addAction(tr("Certificate information:"))->setEnabled(false);
QList<QSslCertificate> tmpChain;
foreach(QSslCertificate cert, chain) {
@@ -237,9 +219,13 @@ void SslButton::slotUpdateMenu() {
it.toBack();
int i = 0;
while (it.hasPrevious()) {
menu()->addMenu(buildCertMenu(menu(), it.previous(), account->approvedCerts(), i));
menu->addMenu(buildCertMenu(menu, it.previous(), account->approvedCerts(), i));
i++;
}
setMenu(menu);
} else {
setIcon(QIcon(QPixmap(Theme::hidpiFileName(":/client/resources/lock-http.png"))));
setToolTip(tr("This connection is NOT secure as it is not encrypted.\n"));
}
}
+1 -4
Ver Arquivo
@@ -24,6 +24,7 @@ class QSslConfiguration;
namespace OCC {
class Account;
class AccountState;
class SslButton : public QToolButton
@@ -34,13 +35,9 @@ public:
QString protoToString(QSsl::SslProtocol proto);
void updateAccountState(AccountState *accountState);
public slots:
void slotUpdateMenu();
private:
QMenu* buildCertMenu(QMenu *parent, const QSslCertificate& cert,
const QList<QSslCertificate>& userApproved, int pos);
QPointer<AccountState> _accountState;
};
} // namespace OCC
+3 -4
Ver Arquivo
@@ -52,10 +52,9 @@ bool OCUpdater::performUpdate()
QSettings settings(cfg.configFile(), QSettings::IniFormat);
QString updateFile = settings.value(updateAvailableC).toString();
if (!updateFile.isEmpty() && QFile(updateFile).exists()) {
const QString name = Theme::instance()->appNameGUI();
if (QMessageBox::information(0, tr("New %1 Update Ready").arg(name),
tr("A new update for %1 is about to be installed. The updater may ask\n"
"for additional privileges during the process.").arg(name), QMessageBox::Ok)) {
if (QMessageBox::information(0, tr("New Update Ready"),
tr("A new update is about to be installed. The updater may ask\n"
"for additional privileges during the process."), QMessageBox::Ok)) {
slotStartInstaller();
return true;
}
+2 -20
Ver Arquivo
@@ -111,33 +111,15 @@ SparkleUpdater::~SparkleUpdater()
delete d;
}
bool autoUpdaterAllowed()
{
// See https://github.com/owncloud/client/issues/2931
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *expectedPath = [NSString stringWithFormat:@"/Applications/%@", [bundlePath lastPathComponent]];
if ([expectedPath isEqualTo:bundlePath]) {
return true;
}
qWarning() << "ERROR: We are not in /Applications, won't check for update!";
return false;
}
void SparkleUpdater::checkForUpdate()
{
if (autoUpdaterAllowed()) {
[d->updater checkForUpdates: NSApp];
}
[d->updater checkForUpdates: NSApp];
}
void SparkleUpdater::backgroundCheckForUpdate()
{
qDebug() << Q_FUNC_INFO << "launching background check";
if (autoUpdaterAllowed()) {
[d->updater checkForUpdatesInBackground];
}
[d->updater checkForUpdatesInBackground];
}
} // namespace OCC
-25
Ver Arquivo
@@ -1,25 +0,0 @@
#include "winresrc.h"
#define VER_FILEVERSION @MIRALL_VERSION_MAJOR@,@MIRALL_VERSION_MINOR@,@MIRALL_VERSION_PATCH@,@MIRALL_VERSION_BUILD@
#define VER_FILEVERSION_STR "@MIRALL_VERSION_MAJOR@.@MIRALL_VERSION_MINOR@.@MIRALL_VERSION_PATCH@.@MIRALL_VERSION_BUILD@\0"
#define VER_PRODUCTVERSION @MIRALL_VERSION_MAJOR@,@MIRALL_VERSION_MINOR@,@MIRALL_VERSION_PATCH@,@MIRALL_VERSION_BUILD@
#define VER_PRODUCTVERSION_STR "@MIRALL_VERSION_MAJOR@.@MIRALL_VERSION_MINOR@.@MIRALL_VERSION_PATCH@.@MIRALL_VERSION_BUILD@\0"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1200
END
END
-3
Ver Arquivo
@@ -57,9 +57,6 @@
<property name="text">
<string>Error Label</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
+1 -2
Ver Arquivo
@@ -61,7 +61,6 @@ OwncloudSetupPage::OwncloudSetupPage(QWidget *parent)
setupCustomization();
slotUrlChanged(QLatin1String("")); // don't jitter UI
connect(_ui.leUrl, SIGNAL(textChanged(QString)), SLOT(slotUrlChanged(QString)));
connect(_ui.leUrl, SIGNAL(editingFinished()), SLOT(slotUrlEditFinished()));
@@ -116,7 +115,7 @@ void OwncloudSetupPage::slotUrlChanged(const QString& url)
_ui.leUrl->setText(newUrl);
}
if (!url.startsWith(QLatin1String("https://"))) {
if (url.startsWith(QLatin1String("http://"))) {
_ui.urlLabel->setPixmap(QPixmap(Theme::hidpiFileName(":/client/resources/lock-http.png")));
_ui.urlLabel->setToolTip(tr("This url is NOT secure as it is not encrypted.\n"
"It is not advisable to use it."));
+3 -8
Ver Arquivo
@@ -61,10 +61,10 @@ set(libsync_SRCS
theme.cpp
utility.cpp
ownsql.cpp
transmissionchecksumvalidator.cpp
creds/dummycredentials.cpp
creds/abstractcredentials.cpp
creds/credentialsfactory.cpp
creds/http/httpconfigfile.cpp
creds/credentialscommon.cpp
../3rdparty/qjson/json.cpp
../3rdparty/certificates/p12topem.cpp
@@ -142,11 +142,6 @@ if(NEON_FOUND)
endif()
endif()
if(ZLIB_FOUND)
list(APPEND libsync_LINK_TARGETS ${ZLIB_LIBRARIES})
include_directories(${ZLIB_INCLUDE_DIRS})
endif(ZLIB_FOUND)
add_library(${synclib_NAME} SHARED ${libsync_SRCS} ${syncMoc})
GENERATE_EXPORT_HEADER( ${synclib_NAME}
BASE_NAME ${synclib_NAME}
@@ -157,9 +152,9 @@ GENERATE_EXPORT_HEADER( ${synclib_NAME}
if(TOKEN_AUTH_ONLY)
qt5_use_modules(${synclib_NAME} Network Concurrent)
qt5_use_modules(${synclib_NAME} Network)
else()
qt5_use_modules(${synclib_NAME} Widgets Network WebKitWidgets Concurrent)
qt5_use_modules(${synclib_NAME} Widgets Network WebKitWidgets)
endif()
set_target_properties( ${synclib_NAME} PROPERTIES
+6 -27
Ver Arquivo
@@ -63,9 +63,7 @@ void AccountManager::setAccount(AccountPtr account)
emit accountRemoved(_account);
}
_account = account;
if (account) {
emit accountAdded(account);
}
emit accountAdded(account);
}
@@ -131,15 +129,6 @@ void Account::save()
if (!certs.isEmpty()) {
settings->setValue( QLatin1String(caCertsKeyC), certs );
}
// Save cookies.
if (_am) {
CookieJar* jar = qobject_cast<CookieJar*>(_am->cookieJar());
if (jar) {
qDebug() << "Saving cookies.";
jar->save();
}
}
}
AccountPtr Account::restore()
@@ -321,9 +310,7 @@ QNetworkReply *Account::getRequest(const QString &relPath)
QNetworkReply *Account::getRequest(const QUrl &url)
{
QNetworkRequest request(url);
#if QT_VERSION > QT_VERSION_CHECK(4, 8, 4)
request.setSslConfiguration(this->createSslConfig());
#endif
return _am->get(request);
}
@@ -335,9 +322,7 @@ QNetworkReply *Account::davRequest(const QByteArray &verb, const QString &relPat
QNetworkReply *Account::davRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
{
req.setUrl(url);
#if QT_VERSION > QT_VERSION_CHECK(4, 8, 4)
req.setSslConfiguration(this->createSslConfig());
#endif
return _am->sendCustomRequest(req, verb, data);
}
@@ -400,11 +385,6 @@ void Account::addApprovedCerts(const QList<QSslCertificate> certs)
_approvedCerts += certs;
}
void Account::resetSslCertErrorState()
{
_treatSslErrorsAsFailure = false;
}
void Account::setSslErrorHandler(AbstractSslErrorHandler *handler)
{
_sslErrorHandler.reset(handler);
@@ -500,14 +480,13 @@ void Account::slotHandleErrors(QNetworkReply *reply , QList<QSslError> errors)
addApprovedCerts(approvedCerts);
// all ssl certs are known and accepted. We can ignore the problems right away.
// qDebug() << out << "Certs are known and trusted! This is not an actual error.";
reply->ignoreSslErrors();
// Warning: Do *not* use ignoreSslErrors() (without args) here:
// it permanently ignores all SSL errors for this host, even
// certificate changes.
reply->ignoreSslErrors(errors);
} else {
_treatSslErrorsAsFailure = true;
// if during normal operation, a new certificate was MITM'ed, and the user does not
// ACK it, the running request must be aborted and the QNAM must be reset, to not
// treat the new cert as granted. See bug #3283
reply->abort();
resetNetworkAccessManager();
return;
}
}
+1 -5
Ver Arquivo
@@ -132,11 +132,6 @@ public:
void setApprovedCerts(const QList<QSslCertificate> certs);
void addApprovedCerts(const QList<QSslCertificate> certs);
// Usually when a user explicitly rejects a certificate we don't
// ask again. After this call, a dialog will again be shown when
// the next unknown certificate is encountered.
void resetSslCertErrorState();
// pluggable handler
void setSslErrorHandler(AbstractSslErrorHandler *handler);
@@ -191,6 +186,7 @@ private:
QNetworkAccessManager *_am;
AbstractCredentials* _credentials;
bool _treatSslErrorsAsFailure;
int _state;
static QString _configFileName;
QByteArray _pemCertificate;
QString _pemPrivateKey;
+31 -31
Ver Arquivo
@@ -90,7 +90,7 @@ BandwidthManager::~BandwidthManager()
void BandwidthManager::registerUploadDevice(UploadDevice *p)
{
//qDebug() << Q_FUNC_INFO << p;
qDebug() << Q_FUNC_INFO << p;
_absoluteUploadDeviceList.append(p);
_relativeUploadDeviceList.append(p);
QObject::connect(p, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterUploadDevice(QObject*)));
@@ -117,7 +117,7 @@ void BandwidthManager::unregisterUploadDevice(QObject *o)
void BandwidthManager::unregisterUploadDevice(UploadDevice* p)
{
//qDebug() << Q_FUNC_INFO << p;
qDebug() << Q_FUNC_INFO << p;
_absoluteUploadDeviceList.removeAll(p);
_relativeUploadDeviceList.removeAll(p);
if (p == _relativeLimitCurrentMeasuredDevice) {
@@ -128,7 +128,7 @@ void BandwidthManager::unregisterUploadDevice(UploadDevice* p)
void BandwidthManager::registerDownloadJob(GETFileJob* j)
{
//qDebug() << Q_FUNC_INFO << j;
qDebug() << Q_FUNC_INFO << j;
_downloadJobList.append(j);
QObject::connect(j, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterDownloadJob(QObject*)));
@@ -176,19 +176,19 @@ void BandwidthManager::relativeUploadMeasuringTimerExpired()
return;
}
// qDebug() << Q_FUNC_INFO << _relativeUploadDeviceList.count() << "Starting Delay";
qDebug() << Q_FUNC_INFO << _relativeUploadDeviceList.count() << "Starting Delay";
qint64 relativeLimitProgressMeasured = (_relativeLimitCurrentMeasuredDevice->_readWithProgress
+ _relativeLimitCurrentMeasuredDevice->_read) / 2;
qint64 relativeLimitProgressDifference = relativeLimitProgressMeasured - _relativeUploadLimitProgressAtMeasuringRestart;
// qDebug() << Q_FUNC_INFO << _relativeUploadLimitProgressAtMeasuringRestart
// << relativeLimitProgressMeasured << relativeLimitProgressDifference;
qDebug() << Q_FUNC_INFO << _relativeUploadLimitProgressAtMeasuringRestart
<< relativeLimitProgressMeasured << relativeLimitProgressDifference;
// qint64 speedkBPerSec = (relativeLimitProgressDifference / relativeLimitMeasuringTimerIntervalMsec*1000.0) / 1024.0;
// qDebug() << Q_FUNC_INFO << relativeLimitProgressDifference/1024 <<"kB =>" << speedkBPerSec << "kB/sec on full speed ("
// << _relativeLimitCurrentMeasuredDevice->_readWithProgress << _relativeLimitCurrentMeasuredDevice->_read
// << qAbs(_relativeLimitCurrentMeasuredDevice->_readWithProgress
// - _relativeLimitCurrentMeasuredDevice->_read) << ")";
qint64 speedkBPerSec = (relativeLimitProgressDifference / relativeLimitMeasuringTimerIntervalMsec*1000.0) / 1024.0;
qDebug() << Q_FUNC_INFO << relativeLimitProgressDifference/1024 <<"kB =>" << speedkBPerSec << "kB/sec on full speed ("
<< _relativeLimitCurrentMeasuredDevice->_readWithProgress << _relativeLimitCurrentMeasuredDevice->_read
<< qAbs(_relativeLimitCurrentMeasuredDevice->_readWithProgress
- _relativeLimitCurrentMeasuredDevice->_read) << ")";
qint64 uploadLimitPercent = -_currentUploadLimit;
// don't use too extreme values
@@ -197,9 +197,9 @@ void BandwidthManager::relativeUploadMeasuringTimerExpired()
qint64 wholeTimeMsec = (100.0 / uploadLimitPercent) * relativeLimitMeasuringTimerIntervalMsec;
qint64 waitTimeMsec = wholeTimeMsec - relativeLimitMeasuringTimerIntervalMsec;
qint64 realWaitTimeMsec = waitTimeMsec + wholeTimeMsec;
// qDebug() << Q_FUNC_INFO << waitTimeMsec << " - "<< realWaitTimeMsec <<
// " msec for " << uploadLimitPercent << "%";
// qDebug() << Q_FUNC_INFO << "XXXX" << uploadLimitPercent << relativeLimitMeasuringTimerIntervalMsec;
qDebug() << Q_FUNC_INFO << waitTimeMsec << " - "<< realWaitTimeMsec <<
" msec for " << uploadLimitPercent << "%";
qDebug() << Q_FUNC_INFO << "XXXX" << uploadLimitPercent << relativeLimitMeasuringTimerIntervalMsec;
// We want to wait twice as long since we want to give all
// devices the same quota we used now since we don't want
@@ -209,12 +209,12 @@ void BandwidthManager::relativeUploadMeasuringTimerExpired()
int deviceCount = _relativeUploadDeviceList.count();
qint64 quotaPerDevice = relativeLimitProgressDifference * (uploadLimitPercent / 100.0) / deviceCount + 1.0;
// qDebug() << Q_FUNC_INFO << "YYYY" << relativeLimitProgressDifference << uploadLimitPercent << deviceCount;
qDebug() << Q_FUNC_INFO << "YYYY" << relativeLimitProgressDifference << uploadLimitPercent << deviceCount;
Q_FOREACH(UploadDevice *ud, _relativeUploadDeviceList) {
ud->setBandwidthLimited(true);
ud->setChoked(false);
ud->giveBandwidthQuota(quotaPerDevice);
// qDebug() << Q_FUNC_INFO << "Gave" << quotaPerDevice/1024.0 << "kB to" << ud;
qDebug() << Q_FUNC_INFO << "Gave" << quotaPerDevice/1024.0 << "kB to" << ud;
}
_relativeLimitCurrentMeasuredDevice = 0;
}
@@ -232,7 +232,7 @@ void BandwidthManager::relativeUploadDelayTimerExpired()
return;
}
// qDebug() << Q_FUNC_INFO << _relativeUploadDeviceList.count() << "Starting measuring";
qDebug() << Q_FUNC_INFO << _relativeUploadDeviceList.count() << "Starting measuring";
// Take first device and then append it again (= we round robin all devices)
_relativeLimitCurrentMeasuredDevice = _relativeUploadDeviceList.takeFirst();
@@ -270,16 +270,16 @@ void BandwidthManager::relativeDownloadMeasuringTimerExpired()
return;
}
// qDebug() << Q_FUNC_INFO << _downloadJobList.count() << "Starting Delay";
qDebug() << Q_FUNC_INFO << _downloadJobList.count() << "Starting Delay";
qint64 relativeLimitProgressMeasured = _relativeLimitCurrentMeasuredJob->currentDownloadPosition();
qint64 relativeLimitProgressDifference = relativeLimitProgressMeasured - _relativeDownloadLimitProgressAtMeasuringRestart;
qDebug() << Q_FUNC_INFO << _relativeDownloadLimitProgressAtMeasuringRestart
<< relativeLimitProgressMeasured << relativeLimitProgressDifference;
// qint64 speedkBPerSec = (relativeLimitProgressDifference / relativeLimitMeasuringTimerIntervalMsec*1000.0) / 1024.0;
// qDebug() << Q_FUNC_INFO << relativeLimitProgressDifference/1024 <<"kB =>" << speedkBPerSec << "kB/sec on full speed ("
// << _relativeLimitCurrentMeasuredJob->currentDownloadPosition() ;
qint64 speedkBPerSec = (relativeLimitProgressDifference / relativeLimitMeasuringTimerIntervalMsec*1000.0) / 1024.0;
qDebug() << Q_FUNC_INFO << relativeLimitProgressDifference/1024 <<"kB =>" << speedkBPerSec << "kB/sec on full speed ("
<< _relativeLimitCurrentMeasuredJob->currentDownloadPosition() ;
qint64 downloadLimitPercent = -_currentDownloadLimit;
// don't use too extreme values
@@ -288,9 +288,9 @@ void BandwidthManager::relativeDownloadMeasuringTimerExpired()
qint64 wholeTimeMsec = (100.0 / downloadLimitPercent) * relativeLimitMeasuringTimerIntervalMsec;
qint64 waitTimeMsec = wholeTimeMsec - relativeLimitMeasuringTimerIntervalMsec;
qint64 realWaitTimeMsec = waitTimeMsec + wholeTimeMsec;
// qDebug() << Q_FUNC_INFO << waitTimeMsec << " - "<< realWaitTimeMsec <<
// " msec for " << downloadLimitPercent << "%";
// qDebug() << Q_FUNC_INFO << "XXXX" << downloadLimitPercent << relativeLimitMeasuringTimerIntervalMsec;
qDebug() << Q_FUNC_INFO << waitTimeMsec << " - "<< realWaitTimeMsec <<
" msec for " << downloadLimitPercent << "%";
qDebug() << Q_FUNC_INFO << "XXXX" << downloadLimitPercent << relativeLimitMeasuringTimerIntervalMsec;
// We want to wait twice as long since we want to give all
// devices the same quota we used now since we don't want
@@ -305,12 +305,12 @@ void BandwidthManager::relativeDownloadMeasuringTimerExpired()
// quota -= 20*1024;
// }
qint64 quotaPerJob = quota / jobCount + 1.0;
// qDebug() << Q_FUNC_INFO << "YYYY" << relativeLimitProgressDifference << downloadLimitPercent << jobCount;
qDebug() << Q_FUNC_INFO << "YYYY" << relativeLimitProgressDifference << downloadLimitPercent << jobCount;
Q_FOREACH(GETFileJob *gfj, _downloadJobList) {
gfj->setBandwidthLimited(true);
gfj->setChoked(false);
gfj->giveBandwidthQuota(quotaPerJob);
// qDebug() << Q_FUNC_INFO << "Gave" << quotaPerJob/1024.0 << "kB to" << gfj;
qDebug() << Q_FUNC_INFO << "Gave" << quotaPerJob/1024.0 << "kB to" << gfj;
}
_relativeLimitCurrentMeasuredDevice = 0;
}
@@ -329,7 +329,7 @@ void BandwidthManager::relativeDownloadDelayTimerExpired()
return;
}
// qDebug() << Q_FUNC_INFO << _downloadJobList.count() << "Starting measuring";
qDebug() << Q_FUNC_INFO << _downloadJobList.count() << "Starting measuring";
// Take first device and then append it again (= we round robin all devices)
_relativeLimitCurrentMeasuredJob = _downloadJobList.takeFirst();
@@ -393,18 +393,18 @@ void BandwidthManager::absoluteLimitTimerExpired()
{
if (usingAbsoluteUploadLimit() && _absoluteUploadDeviceList.count() > 0) {
qint64 quotaPerDevice = _currentUploadLimit / qMax(1, _absoluteUploadDeviceList.count());
// qDebug() << Q_FUNC_INFO << quotaPerDevice << _absoluteUploadDeviceList.count() << _currentUploadLimit;
qDebug() << Q_FUNC_INFO << quotaPerDevice << _absoluteUploadDeviceList.count() << _currentUploadLimit;
Q_FOREACH(UploadDevice *device, _absoluteUploadDeviceList) {
device->giveBandwidthQuota(quotaPerDevice);
// qDebug() << Q_FUNC_INFO << "Gave " << quotaPerDevice/1024.0 << " kB to" << device;
qDebug() << Q_FUNC_INFO << "Gave " << quotaPerDevice/1024.0 << " kB to" << device;
}
}
if (usingAbsoluteDownloadLimit() && _downloadJobList.count() > 0) {
qint64 quotaPerJob = _currentDownloadLimit / qMax(1, _downloadJobList.count());
// qDebug() << Q_FUNC_INFO << quotaPerJob << _downloadJobList.count() << _currentDownloadLimit;
qDebug() << Q_FUNC_INFO << quotaPerJob << _downloadJobList.count() << _currentDownloadLimit;
Q_FOREACH(GETFileJob *j, _downloadJobList) {
j->giveBandwidthQuota(quotaPerJob);
// qDebug() << Q_FUNC_INFO << "Gave " << quotaPerJob/1024.0 << " kB to" << j;
qDebug() << Q_FUNC_INFO << "Gave " << quotaPerJob/1024.0 << " kB to" << j;
}
}
}
+1 -55
Ver Arquivo
@@ -15,7 +15,6 @@
#include "configfile.h"
#include <QUrl>
#include <QThreadPool>
namespace OCC {
@@ -24,7 +23,7 @@ ClientProxy::ClientProxy(QObject *parent) :
{
}
static QNetworkProxy proxyFromConfig(const ConfigFile& cfg)
QNetworkProxy ClientProxy::proxyFromConfig(const ConfigFile& cfg)
{
QNetworkProxy proxy;
@@ -40,22 +39,6 @@ static QNetworkProxy proxyFromConfig(const ConfigFile& cfg)
return proxy;
}
bool ClientProxy::isUsingSystemDefault() {
OCC::ConfigFile cfg;
// if there is no config file, default to system proxy.
if( cfg.exists() ) {
return cfg.proxyType() == QNetworkProxy::DefaultProxy;
}
return false;
}
QString printQNetworkProxy(const QNetworkProxy &proxy)
{
return QString("%1://%2:%3").arg(proxy.type()).arg(proxy.hostName()).arg(proxy.port());
}
void ClientProxy::setupQtProxyFromConfig()
{
OCC::ConfigFile cfg;
@@ -70,23 +53,19 @@ void ClientProxy::setupQtProxyFromConfig()
switch(proxyType) {
case QNetworkProxy::NoProxy:
qDebug() << "Set proxy configuration to use NO proxy";
QNetworkProxyFactory::setUseSystemConfiguration(false);
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
break;
case QNetworkProxy::DefaultProxy:
qDebug() << "Set proxy configuration to use system configuration";
QNetworkProxyFactory::setUseSystemConfiguration(true);
break;
case QNetworkProxy::Socks5Proxy:
proxy.setType(QNetworkProxy::Socks5Proxy);
qDebug() << "Set proxy configuration to SOCKS5" << printQNetworkProxy(proxy);
QNetworkProxyFactory::setUseSystemConfiguration(false);
QNetworkProxy::setApplicationProxy(proxy);
break;
case QNetworkProxy::HttpProxy:
proxy.setType(QNetworkProxy::HttpProxy);
qDebug() << "Set proxy configuration to HTTP" << printQNetworkProxy(proxy);
QNetworkProxyFactory::setUseSystemConfiguration(false);
QNetworkProxy::setApplicationProxy(proxy);
break;
@@ -117,7 +96,6 @@ const char* ClientProxy::proxyTypeToCStr(QNetworkProxy::ProxyType type)
void ClientProxy::setCSyncProxy( const QUrl& url, CSYNC *csync_ctx )
{
#ifdef USE_NEON
/* Store proxy */
QList<QNetworkProxy> proxies = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(url));
// We set at least one in Application
@@ -140,39 +118,7 @@ void ClientProxy::setCSyncProxy( const QUrl& url, CSYNC *csync_ctx )
csync_set_module_property( csync_ctx, "proxy_port", &proxy_port );
csync_set_module_property( csync_ctx, "proxy_user", proxy.user().toUtf8().data());
csync_set_module_property( csync_ctx, "proxy_pwd", proxy.password().toUtf8().data());
#else
Q_UNUSED(url);
Q_UNUSED(csync_ctx);
#endif
}
void ClientProxy::lookupSystemProxyAsync(const QUrl &url, QObject *dst, const char *slot)
{
SystemProxyRunnable *runnable = new SystemProxyRunnable(url);
QObject::connect(runnable, SIGNAL(systemProxyLookedUp(QNetworkProxy)), dst, slot);
QThreadPool::globalInstance()->start(runnable); // takes ownership and deletes
}
SystemProxyRunnable::SystemProxyRunnable(const QUrl &url) : QObject(), QRunnable(), _url(url)
{
}
void SystemProxyRunnable::run()
{
qDebug() << Q_FUNC_INFO << "Starting system proxy lookup";
qRegisterMetaType<QNetworkProxy>("QNetworkProxy");
QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(QNetworkProxyQuery(_url));
if (proxies.isEmpty()) {
emit systemProxyLookedUp(QNetworkProxy(QNetworkProxy::NoProxy));
} else {
emit systemProxyLookedUp(proxies.first());
// FIXME Would we really ever return more?
}
}
}
+2 -18
Ver Arquivo
@@ -16,8 +16,6 @@
#include <QObject>
#include <QNetworkProxy>
#include <QRunnable>
#include <QUrl>
#include <csync.h>
#include "utility.h"
@@ -32,31 +30,17 @@ class OWNCLOUDSYNC_EXPORT ClientProxy : public QObject
public:
explicit ClientProxy(QObject *parent = 0);
static bool isUsingSystemDefault();
static void lookupSystemProxyAsync(const QUrl &url, QObject *dst, const char *slot);
signals:
public slots:
void setCSyncProxy( const QUrl& url, CSYNC *csync_ctx );
void setupQtProxyFromConfig();
private:
QNetworkProxy proxyFromConfig(const ConfigFile& cfg);
const char* proxyTypeToCStr(QNetworkProxy::ProxyType type);
};
class SystemProxyRunnable : public QObject, public QRunnable {
Q_OBJECT
public:
SystemProxyRunnable(const QUrl &url);
void run();
signals:
void systemProxyLookedUp(const QNetworkProxy &url);
private:
QUrl _url;
};
QString printQNetworkProxy(const QNetworkProxy &proxy);
}
#endif // CLIENTPROXY_H
+15 -16
Ver Arquivo
@@ -40,7 +40,7 @@
namespace OCC {
//static const char caCertsKeyC[] = "CaCertificates"; only used from account.cpp
static const char caCertsKeyC[] = "CaCertificates";
static const char remotePollIntervalC[] = "remotePollInterval";
static const char forceSyncIntervalC[] = "forceSyncInterval";
static const char monoIconsC[] = "monoIcons";
@@ -49,7 +49,6 @@ static const char optionalDesktopNoficationsC[] = "optionalDesktopNotifications"
static const char skipUpdateCheckC[] = "skipUpdateCheck";
static const char geometryC[] = "geometry";
static const char timeoutC[] = "timeout";
static const char transmissionChecksumC[] = "transmissionChecksum";
static const char proxyHostC[] = "Proxy/host";
static const char proxyTypeC[] = "Proxy/type";
@@ -119,20 +118,6 @@ int ConfigFile::timeout() const
return settings.value(QLatin1String(timeoutC), 300).toInt(); // default to 5 min
}
QString ConfigFile::transmissionChecksum() const
{
QSettings settings(configFile(), QSettings::IniFormat);
QString checksum = settings.value(QLatin1String(transmissionChecksumC), QString()).toString();
if( checksum.isEmpty() ) {
// if the config file setting is empty, maybe the Branding requires it.
checksum = Theme::instance()->transmissionChecksum();
}
return checksum;
}
void ConfigFile::setOptionalDesktopNotifications(bool show)
{
QSettings settings(configFile(), QSettings::IniFormat);
@@ -332,6 +317,20 @@ bool ConfigFile::dataExists(const QString& group, const QString& key) const
return settings.contains(key);
}
QByteArray ConfigFile::caCerts( )
{
QSettings settings(configFile(), QSettings::IniFormat);
return settings.value( QLatin1String(caCertsKeyC) ).toByteArray();
}
void ConfigFile::setCaCerts( const QByteArray & certs )
{
QSettings settings(configFile(), QSettings::IniFormat);
settings.setValue( QLatin1String(caCertsKeyC), certs );
settings.sync();
}
int ConfigFile::remotePollInterval( const QString& connection ) const
{
QString con( connection );
-6
Ver Arquivo
@@ -103,12 +103,6 @@ public:
int timeout() const;
// send a checksum as a header along with the transmission or not.
// possible values:
// empty: no checksum calculated or expected.
// or "Adler32", "MD5", "SHA1"
QString transmissionChecksum() const;
void saveGeometry(QWidget *w);
void restoreGeometry(QWidget *w);
+10 -41
Ver Arquivo
@@ -13,13 +13,11 @@
#include <QtCore>
#include <QNetworkReply>
#include <QNetworkProxyFactory>
#include "connectionvalidator.h"
#include "theme.h"
#include "account.h"
#include "networkjobs.h"
#include "clientproxy.h"
#include <creds/abstractcredentials.h>
namespace OCC {
@@ -48,8 +46,8 @@ QString ConnectionValidator::statusString( Status stat )
return QLatin1String("Status not found");
case UserCanceledCredentials:
return QLatin1String("User canceled credentials");
case ServiceUnavailable:
return QLatin1String("Service unavailable");
case ServerMaintenance:
return QLatin1String("Server in maintenance mode");
case Timeout:
return QLatin1String("Timeout");
}
@@ -63,38 +61,8 @@ void ConnectionValidator::checkServerAndAuth()
reportResult( NotConfigured );
return;
}
qDebug() << "Checking server and authentication";
_isCheckingServerAndAuth = true;
// Lookup system proxy in a thread https://github.com/owncloud/client/issues/2993
if (ClientProxy::isUsingSystemDefault()) {
qDebug() << "Trying to look up system proxy";
ClientProxy::lookupSystemProxyAsync(_account->url(),
this, SLOT(systemProxyLookupDone(QNetworkProxy)));
} else {
// We want to reset the QNAM proxy so that the global proxy settings are used (via ClientProxy settings)
_account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::DefaultProxy));
// use a queued invocation so we're as asynchronous as with the other code path
QMetaObject::invokeMethod(this, "slotCheckServerAndAuth", Qt::QueuedConnection);
}
}
void ConnectionValidator::systemProxyLookupDone(const QNetworkProxy &proxy) {
if (!_account) {
qDebug() << "Bailing out, Account had been deleted";
return;
}
qDebug() << Q_FUNC_INFO << "Setting QNAM proxy to be system proxy" << printQNetworkProxy(proxy);
_account->networkAccessManager()->setProxy(proxy);
slotCheckServerAndAuth();
}
// The actual check
void ConnectionValidator::slotCheckServerAndAuth()
{
CheckServerJob *checkJob = new CheckServerJob(_account, this);
checkJob->setIgnoreCredentialFailure(true);
connect(checkJob, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotStatusFound(QUrl,QVariantMap)));
@@ -130,16 +98,12 @@ void ConnectionValidator::slotStatusFound(const QUrl&url, const QVariantMap &inf
// Fetch them now! Once fetched, a new connectivity check will be
// initiated anyway.
creds->fetch();
// no result is reported
deleteLater();
}
}
// status.php could not be loaded (network or server issue!).
void ConnectionValidator::slotNoStatusFound(QNetworkReply *reply)
{
qDebug() << Q_FUNC_INFO << reply->error() << reply->errorString();
if( reply && ! _account->credentials()->stillValid(reply)) {
_errors.append(tr("Authentication error: Either username or password are wrong."));
} else {
@@ -187,13 +151,18 @@ void ConnectionValidator::slotAuthFailed(QNetworkReply *reply)
stat = CredentialsWrong;
} else if( reply->error() != QNetworkReply::NoError ) {
_errors << errorMessage(reply->errorString(), reply->readAll());
_errors << reply->errorString();
const int httpStatus =
reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if ( httpStatus == 503 ) {
_errors.clear();
stat = ServiceUnavailable;
// Is this a maintenance mode reply from the server
// or a regular 503 from somewhere else?
QByteArray body = reply->readAll();
if ( body.contains("Sabre\\DAV\\Exception\\ServiceUnavailable") ) {
_errors.clear();
stat = ServerMaintenance;
}
}
}
+1 -6
Ver Arquivo
@@ -36,8 +36,6 @@ namespace OCC {
*---> checkServerAndAuth (check status.php)
Will asynchronously check for system proxy (if using system proxy)
And then invoke slotCheckServerAndAuth
CheckServerJob
|
+-> slotNoStatusFound --> X
@@ -77,7 +75,7 @@ public:
CredentialsWrong,
StatusNotFound,
UserCanceledCredentials,
ServiceUnavailable,
ServerMaintenance,
// actually also used for other errors on the authed request
Timeout
};
@@ -87,7 +85,6 @@ public:
public slots:
/// Checks the server and the authentication.
void checkServerAndAuth();
void systemProxyLookupDone(const QNetworkProxy &proxy);
/// Checks authentication only.
void checkAuthentication();
@@ -96,8 +93,6 @@ signals:
void connectionResult( ConnectionValidator::Status status, QStringList errors );
protected slots:
void slotCheckServerAndAuth();
void slotStatusFound(const QUrl&url, const QVariantMap &info);
void slotNoStatusFound(QNetworkReply *reply);
void slotJobTimeout(const QUrl& url);
+1 -1
Ver Arquivo
@@ -19,7 +19,6 @@
#include <QFile>
#include <QDateTime>
#include <QNetworkCookie>
#include <QDataStream>
namespace OCC {
@@ -72,6 +71,7 @@ CookieJar::CookieJar(QObject *parent) :
CookieJar::~CookieJar()
{
save();
}
bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie>& cookieList, const QUrl& url)
+1 -2
Ver Arquivo
@@ -34,11 +34,10 @@ public:
using QNetworkCookieJar::setAllCookies;
using QNetworkCookieJar::allCookies;
void save();
signals:
void newCookiesForUrl(const QList<QNetworkCookie>& cookieList, const QUrl& url);
private:
void save();
void restore();
QList<QNetworkCookie> removeExpired(const QList<QNetworkCookie> &cookies);
QString storagePath() const;
+81
Ver Arquivo
@@ -0,0 +1,81 @@
/*
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.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.
*/
#include "creds/http/httpconfigfile.h"
namespace OCC
{
namespace
{
const char userC[] = "user";
const char passwdC[] = "passwd";
const char oldPasswdC[] = "password";
} // ns
QString HttpConfigFile::user() const
{
return retrieveData(QString(), QLatin1String(userC)).toString();
}
void HttpConfigFile::setUser(const QString& user)
{
storeData(QString(), QLatin1String(userC), QVariant(user));
}
QString HttpConfigFile::password() const
{
const QVariant passwd(retrieveData(QString(), QLatin1String(passwdC)));
if (passwd.isValid()) {
return QString::fromUtf8(QByteArray::fromBase64(passwd.toByteArray()));
}
return QString();
}
void HttpConfigFile::setPassword(const QString& password)
{
QByteArray pwdba = password.toUtf8();
storeData( QString(), QLatin1String(passwdC), QVariant(pwdba.toBase64()) );
removeOldPassword();
}
bool HttpConfigFile::passwordExists() const
{
return dataExists(QString(), QLatin1String(passwdC));
}
void HttpConfigFile::removePassword()
{
removeOldPassword();
removeData(QString(), QLatin1String(passwdC));
}
void HttpConfigFile::fixupOldPassword()
{
const QString old(QString::fromLatin1(oldPasswdC));
if (dataExists(QString(), old)) {
setPassword(retrieveData(QString(), old).toString());
}
}
void HttpConfigFile::removeOldPassword()
{
removeData(QString(), QLatin1String(oldPasswdC));
}
} // namespace OCC
+44
Ver Arquivo
@@ -0,0 +1,44 @@
/*
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.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.
*/
#ifndef MIRALL_CREDS_HTTP_CONFIG_FILE_H
#define MIRALL_CREDS_HTTP_CONFIG_FILE_H
#include "configfile.h"
namespace OCC
{
class HttpConfigFile : public ConfigFile
{
public:
QString user() const;
void setUser(const QString& user);
QString password() const;
void setPassword(const QString& password);
bool passwordExists() const;
void removePassword();
void fixupOldPassword();
QString certificatePath() const;
void setCertificatePath(const QString& cPath);
QString certificatePasswd() const;
void setCertificatePasswd(const QString& cPasswd);
private:
void removeOldPassword();
};
} // namespace OCC
#endif
+1 -12
Ver Arquivo
@@ -313,9 +313,6 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *job)
void HttpCredentials::invalidateToken()
{
if (! _password.isEmpty()) {
_previousPassword = _password;
}
_password = QString();
_ready = false;
@@ -336,14 +333,6 @@ void HttpCredentials::invalidateToken()
job->setKey(kck);
job->start();
// Also ensure the password is deleted from the deprecated place
// otherwise we'd possibly read and use it again and again.
DeletePasswordJob *job2 = new DeletePasswordJob(Theme::instance()->appName());
// no job2->setSettings() call here, to make it use the deprecated location.
job2->setInsecureFallback(true);
job2->setKey(kck);
job2->start();
_account->clearCookieJar();
}
@@ -398,7 +387,7 @@ QString HttpCredentialsGui::queryPassword(bool *ok)
QString str = QInputDialog::getText(0, tr("Enter Password"),
tr("Please enter %1 password for user '%2':")
.arg(Theme::instance()->appNameGUI(), _user),
QLineEdit::Password, _previousPassword, ok);
QLineEdit::Password, QString(), ok);
return str;
} else {
return QString();
-2
Ver Arquivo
@@ -64,7 +64,6 @@ private Q_SLOTS:
protected:
QString _user;
QString _password;
QString _previousPassword;
private:
QString _certificatePath;
@@ -75,7 +74,6 @@ private:
};
class OWNCLOUDSYNC_EXPORT HttpCredentialsGui : public HttpCredentials {
Q_OBJECT
public:
explicit HttpCredentialsGui() : HttpCredentials() {}
HttpCredentialsGui(const QString& user, const QString& password, const QString& certificatePath, const QString& certificatePasswd) : HttpCredentials(user, password, certificatePath, certificatePasswd) {}
+35 -24
Ver Arquivo
@@ -83,11 +83,21 @@ void DiscoveryJob::update_job_update_callback (bool local,
}
}
// Only use for error cases! It will always set an error errno
int get_errno_from_http_errcode( int err, const QString & reason ) {
int new_errno = EIO;
int new_errno = 0;
switch(err) {
case 200: /* OK */
case 201: /* Created */
case 202: /* Accepted */
case 203: /* Non-Authoritative Information */
case 204: /* No Content */
case 205: /* Reset Content */
case 207: /* Multi-Status */
case 304: /* Not Modified */
new_errno = 0;
break;
case 401: /* Unauthorized */
case 402: /* Payment Required */
case 407: /* Proxy Authentication Required */
@@ -258,11 +268,8 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file,QMap
}
FileStatPointer file_stat(propertyMapToFileStat(map));
csync_vio_file_stat_t *file_stat = propertyMapToFileStat(map);
file_stat->name = strdup(file.toUtf8());
if (!file_stat->etag || strlen(file_stat->etag) == 0) {
qDebug() << "WARNING: etag of" << file_stat->name << "is" << file_stat->etag << " This must not happen.";
}
//qDebug() << "!!!!" << file_stat << file_stat->name << file_stat->file_id << map.count();
_results.append(file_stat);
}
@@ -275,13 +282,6 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file,QMap
void DiscoverySingleDirectoryJob::lsJobFinishedWithoutErrorSlot()
{
if (!_ignoredFirst) {
// This is a sanity check, if we haven't _ignoredFirst then it means we never received any directoryListingIteratedSlot
// which means somehow the server XML was bogus
emit finishedWithError(ERRNO_WRONG_CONTENT, QLatin1String("Server error: PROPFIND reply is not XML formatted!"));
deleteLater();
return;
}
emit etagConcatenation(_etagConcatenation);
emit finishedWithResult(_results);
deleteLater();
@@ -293,7 +293,7 @@ void DiscoverySingleDirectoryJob::lsJobFinishedWithErrorSlot(QNetworkReply *r)
int httpCode = r->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString httpReason = r->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
QString msg = r->errorString();
int errnoCode = EIO; // Something went wrong
int errnoCode = 0;
qDebug() << Q_FUNC_INFO << r->errorString() << httpCode << r->error();
if (httpCode != 0 && httpCode != 207) {
errnoCode = get_errno_from_http_errcode(httpCode, httpReason);
@@ -302,11 +302,9 @@ void DiscoverySingleDirectoryJob::lsJobFinishedWithErrorSlot(QNetworkReply *r)
} else if (!contentType.contains("application/xml; charset=utf-8")) {
msg = QLatin1String("Server error: PROPFIND reply is not XML formatted!");
errnoCode = ERRNO_WRONG_CONTENT;
} else {
// Default keep at EIO, see above
}
emit finishedWithError(errnoCode == 0 ? EIO : errnoCode, msg);
emit finishedWithError(errnoCode, msg);
deleteLater();
}
@@ -318,6 +316,15 @@ void DiscoveryMainThread::setupHooks(DiscoveryJob *discoveryJob, const QString &
connect(discoveryJob, SIGNAL(doOpendirSignal(QString,DiscoveryDirectoryResult*)),
this, SLOT(doOpendirSlot(QString,DiscoveryDirectoryResult*)),
Qt::QueuedConnection);
connect(discoveryJob, SIGNAL(doClosedirSignal(QString)),
this, SLOT(doClosedirSlot(QString)),
Qt::QueuedConnection);
}
void DiscoveryMainThread::doClosedirSlot(QString path)
{
//qDebug() << Q_FUNC_INFO << "Invalidating" << path;
deleteCacheEntry(path);
}
// Coming from owncloud_opendir -> DiscoveryJob::vio_opendir_hook -> doOpendirSignal
@@ -342,8 +349,8 @@ void DiscoveryMainThread::doOpendirSlot(QString subPath, DiscoveryDirectoryResul
// Schedule the DiscoverySingleDirectoryJob
_singleDirJob = new DiscoverySingleDirectoryJob(_account, fullPath, this);
QObject::connect(_singleDirJob, SIGNAL(finishedWithResult(const QList<FileStatPointer> &)),
this, SLOT(singleDirectoryJobResultSlot(const QList<FileStatPointer> &)));
QObject::connect(_singleDirJob, SIGNAL(finishedWithResult(QLinkedList<csync_vio_file_stat_t *>)),
this, SLOT(singleDirectoryJobResultSlot(QLinkedList<csync_vio_file_stat_t*>)));
QObject::connect(_singleDirJob, SIGNAL(finishedWithError(int,QString)),
this, SLOT(singleDirectoryJobFinishedWithErrorSlot(int,QString)));
QObject::connect(_singleDirJob, SIGNAL(firstDirectoryPermissions(QString)),
@@ -354,7 +361,7 @@ void DiscoveryMainThread::doOpendirSlot(QString subPath, DiscoveryDirectoryResul
}
void DiscoveryMainThread::singleDirectoryJobResultSlot(const QList<FileStatPointer> & result)
void DiscoveryMainThread::singleDirectoryJobResultSlot(QLinkedList<csync_vio_file_stat_t *> result)
{
if (!_currentDiscoveryDirectoryResult) {
return; // possibly aborted
@@ -362,9 +369,11 @@ void DiscoveryMainThread::singleDirectoryJobResultSlot(const QList<FileStatPoint
qDebug() << Q_FUNC_INFO << "Have" << result.count() << "results for " << _currentDiscoveryDirectoryResult->path;
_directoryContents.insert(_currentDiscoveryDirectoryResult->path, result);
_currentDiscoveryDirectoryResult->list = result;
_currentDiscoveryDirectoryResult->code = 0;
_currentDiscoveryDirectoryResult->listIndex = 0;
_currentDiscoveryDirectoryResult->iterator = _currentDiscoveryDirectoryResult->list.begin();
_currentDiscoveryDirectoryResult = 0; // the sync thread owns it now
_discoveryJob->_vioMutex.lock();
@@ -402,7 +411,7 @@ void DiscoveryMainThread::abort() {
if (_singleDirJob) {
_singleDirJob->disconnect(SIGNAL(finishedWithError(int,QString)), this);
_singleDirJob->disconnect(SIGNAL(firstDirectoryPermissions(QString)), this);
_singleDirJob->disconnect(SIGNAL(finishedWithResult(const QList<FileStatPointer> &)), this);
_singleDirJob->disconnect(SIGNAL(finishedWithResult(QLinkedList<csync_vio_file_stat_t*>)), this);
_singleDirJob->abort();
}
if (_currentDiscoveryDirectoryResult) {
@@ -457,8 +466,9 @@ csync_vio_file_stat_t* DiscoveryJob::remote_vio_readdir_hook (csync_vio_handle_t
DiscoveryJob *discoveryJob = static_cast<DiscoveryJob*>(userdata);
if (discoveryJob) {
DiscoveryDirectoryResult *directoryResult = static_cast<DiscoveryDirectoryResult*>(dhandle);
if (directoryResult->listIndex < directoryResult->list.size()) {
csync_vio_file_stat_t *file_stat = directoryResult->list.at(directoryResult->listIndex++).data();
if (directoryResult->iterator != directoryResult->list.end()) {
csync_vio_file_stat_t *file_stat = *(directoryResult->iterator);
directoryResult->iterator++;
// Make a copy, csync_update will delete the copy
return csync_vio_file_stat_copy(file_stat);
}
@@ -474,6 +484,7 @@ void DiscoveryJob::remote_vio_closedir_hook (csync_vio_handle_t *dhandle, void
QString path = directoryResult->path;
qDebug() << Q_FUNC_INFO << discoveryJob << path;
delete directoryResult; // just deletes the struct and the iterator, the data itself is owned by the SyncEngine/DiscoveryMainThread
emit discoveryJob->doClosedirSignal(path);
}
}
+29 -29
Ver Arquivo
@@ -34,36 +34,12 @@ class Account;
* if the files are new, or changed.
*/
class FileStatPointer {
public:
FileStatPointer(csync_vio_file_stat_t *stat)
: _stat(stat)
{ }
FileStatPointer(const FileStatPointer &other)
: _stat(csync_vio_file_stat_copy(other._stat))
{ }
~FileStatPointer() {
csync_vio_file_stat_destroy(_stat);
}
FileStatPointer &operator=(const FileStatPointer &other) {
csync_vio_file_stat_destroy(_stat);
_stat = csync_vio_file_stat_copy(other._stat);
return *this;
}
inline csync_vio_file_stat_t *data() const { return _stat; }
inline csync_vio_file_stat_t *operator->() const { return _stat; }
private:
csync_vio_file_stat_t *_stat;
};
struct DiscoveryDirectoryResult {
QString path;
QString msg;
int code;
QList<FileStatPointer> list;
int listIndex;
DiscoveryDirectoryResult() : code(EIO), listIndex(0) { }
QLinkedList<csync_vio_file_stat_t*>::iterator iterator;
QLinkedList<csync_vio_file_stat_t *> list;
};
// Run in the main thread, reporting to the DiscoveryJobMainThread object
@@ -77,14 +53,14 @@ public:
signals:
void firstDirectoryPermissions(const QString &);
void etagConcatenation(const QString &);
void finishedWithResult(const QList<FileStatPointer> &);
void finishedWithResult(QLinkedList<csync_vio_file_stat_t*>);
void finishedWithError(int csyncErrnoCode, QString msg);
private slots:
void directoryListingIteratedSlot(QString,QMap<QString,QString>);
void lsJobFinishedWithoutErrorSlot();
void lsJobFinishedWithErrorSlot(QNetworkReply*);
private:
QList<FileStatPointer> _results;
QLinkedList<csync_vio_file_stat_t*> _results;
QString _subPath;
QString _etagConcatenation;
AccountPtr _account;
@@ -97,6 +73,11 @@ class DiscoveryJob;
class DiscoveryMainThread : public QObject {
Q_OBJECT
// For non-recursive and recursive
// If it is not in this map it needs to be requested
QMap<QString, QLinkedList<csync_vio_file_stat_t*> > _directoryContents;
QPointer<DiscoveryJob> _discoveryJob;
QPointer<DiscoverySingleDirectoryJob> _singleDirJob;
QString _pathPrefix;
@@ -106,6 +87,22 @@ class DiscoveryMainThread : public QObject {
public:
DiscoveryMainThread(AccountPtr account) : QObject(), _account(account), _currentDiscoveryDirectoryResult(0) {
}
void deleteCacheEntry(QString path) {
//qDebug() << path << _directoryContents.value(path).count();
foreach (csync_vio_file_stat_t* stat, _directoryContents.value(path)) {
csync_vio_file_stat_destroy(stat);
}
_directoryContents.remove(path);
}
~DiscoveryMainThread() {
// Delete the _contents_ of the list-map explicitly:
foreach (const QLinkedList<csync_vio_file_stat_t*> & list, _directoryContents) {
foreach (csync_vio_file_stat_t* stat, list) {
csync_vio_file_stat_destroy(stat);
}
}
}
void abort();
@@ -113,9 +110,10 @@ public:
public slots:
// From DiscoveryJob:
void doOpendirSlot(QString url, DiscoveryDirectoryResult* );
void doClosedirSlot(QString path);
// From Job:
void singleDirectoryJobResultSlot(const QList<FileStatPointer> &);
void singleDirectoryJobResultSlot(QLinkedList<csync_vio_file_stat_t*>);
void singleDirectoryJobFinishedWithErrorSlot(int csyncErrnoCode, QString msg);
void singleDirectoryJobFirstDirectoryPermissionsSlot(QString);
signals:
@@ -177,6 +175,8 @@ signals:
// After the discovery job has been woken up again (_vioWaitCondition)
void doOpendirSignal(QString url, DiscoveryDirectoryResult*);
// to tell the main thread to invalidate its directory data
void doClosedirSignal(QString path);
};
}
+1 -104
Ver Arquivo
@@ -16,13 +16,7 @@
#include "utility.h"
#include <QFile>
#include <QFileInfo>
#include <QCoreApplication>
#include <QDebug>
#include <QCryptographicHash>
#ifdef ZLIB_FOUND
#include <zlib.h>
#endif
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <qabstractfileengine.h>
@@ -161,50 +155,7 @@ bool FileSystem::rename(const QString &originFileName,
return success;
}
bool FileSystem::fileChanged(const QString& fileName,
qint64 previousSize,
time_t previousMtime)
{
return getSize(fileName) != previousSize
|| getModTime(fileName) != previousMtime;
}
bool FileSystem::verifyFileUnchanged(const QString& fileName,
qint64 previousSize,
time_t previousMtime)
{
const qint64 actualSize = getSize(fileName);
const time_t actualMtime = getModTime(fileName);
if (actualSize != previousSize || actualMtime != previousMtime) {
qDebug() << "File" << fileName << "has changed:"
<< "size: " << previousSize << "<->" << actualSize
<< ", mtime: " << previousMtime << "<->" << actualMtime;
return false;
}
return true;
}
bool FileSystem::renameReplace(const QString& originFileName,
const QString& destinationFileName,
qint64 destinationSize,
time_t destinationMtime,
QString* errorString)
{
if (fileExists(destinationFileName)
&& fileChanged(destinationFileName, destinationSize, destinationMtime)) {
if (errorString) {
*errorString = qApp->translate("FileSystem",
"The destination file has an unexpected size or modification time");
}
return false;
}
return uncheckedRenameReplace(originFileName, destinationFileName, errorString);
}
bool FileSystem::uncheckedRenameReplace(const QString& originFileName,
const QString& destinationFileName,
QString* errorString)
bool FileSystem::renameReplace(const QString& originFileName, const QString& destinationFileName, QString* errorString)
{
#ifndef Q_OS_WIN
bool success;
@@ -399,58 +350,4 @@ QString FileSystem::fileSystemForPath(const QString & path)
}
#endif
#define BUFSIZE 1024*1024*10
static QByteArray readToCrypto( const QString& filename, QCryptographicHash::Algorithm algo )
{
const qint64 bufSize = BUFSIZE;
QByteArray buf(bufSize,0);
QByteArray arr;
QCryptographicHash crypto( algo );
QFile file(filename);
if (file.open(QIODevice::ReadOnly)) {
qint64 size;
while (!file.atEnd()) {
size = file.read( buf.data(), bufSize );
if( size > 0 ) {
crypto.addData(buf.data(), size);
}
}
arr = crypto.result().toHex();
}
return arr;
}
QByteArray FileSystem::calcMd5( const QString& filename )
{
return readToCrypto( filename, QCryptographicHash::Md5 );
}
QByteArray FileSystem::calcSha1( const QString& filename )
{
return readToCrypto( filename, QCryptographicHash::Sha1 );
}
#ifdef ZLIB_FOUND
QByteArray FileSystem::calcAdler32( const QString& filename )
{
unsigned int adler = adler32(0L, Z_NULL, 0);
const qint64 bufSize = BUFSIZE;
QByteArray buf(bufSize, 0);
QFile file(filename);
if (file.open(QIODevice::ReadOnly)) {
qint64 size;
while (!file.atEnd()) {
size = file.read(buf.data(), bufSize);
if( size > 0 )
adler = adler32(adler, (const Bytef*) buf.data(), size);
}
}
return QByteArray::number( adler, 16 );
}
#endif
} // namespace OCC

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais