Comparar commits

...

24 Commits

Autor SHA1 Mensagem Data
Daniel Molkentin 1c92d68fe1 Merge branch '1.6' of https://github.com/owncloud/mirall into 1.6 2014-12-02 15:14:04 +01:00
Olivier Goffart d983f45eab compile 2014-11-27 16:19:36 +01:00
Olivier Goffart 944de6a3d5 Shibboleth: Fix our implemtnation of CookieJar::deleteCookie
It was deleting too many cookies.
That function is virtual in Qt5 and is used when adding cookie.
But some Shibboleth have several cookies with the same name, and we need to keep them.

Our implementaiton was meant to delete all the shiboleth cookies when we want to log out

(cherry picked from commit 1f9d02e7fa)

Conflicts:
	src/mirall/cookiejar.h
2014-11-27 13:00:00 +01:00
Klaas Freitag ebb9cc786f tests: exit t5.pl if running against ownCloud 6
t5.pl checks the environment variable SERVER_VERSION and if that equals
"owncloud6" it bails out after a check of the sharing ocs api.

Conflicts:
	csync/tests/ownCloud/t5.pl
2014-11-21 17:10:34 +01:00
Klaas Freitag f01788ae78 tests: Never stumble over an already existing test share dir.
Conflicts:
	csync/tests/ownCloud/t5.pl
2014-11-21 17:10:34 +01:00
Klaas Freitag 4de09e85e3 Add call to removeRemoteDir 2014-11-21 17:10:34 +01:00
Klaas Freitag cc11833d8d tests: only do the sharing test with ownCloud6
set the environment variable SERVER_VERION=owncloud6 to have the full
test running. Fix required to make Jenkins go green.
2014-10-29 15:59:43 +01:00
Klaas Freitag c4a9e524e6 Set version to 1.6.4 final. 2014-10-22 11:33:26 +02:00
Daniel Molkentin 1ad23e6ab0 NSIS: Fix copying of qtbase translations 2014-10-17 16:44:16 +02:00
Daniel Molkentin f1dbba9e5a Second part of #1661
- QT_INSTALL_TRANSLATIONS was not defined in Qt5
- Some languages have been split up in multiple qm's. We only need qtbase for now
2014-10-15 17:10:41 +02:00
Daniel Molkentin 8d7408bb0c Correct lookup logic for Qt translations
Fixes #1661
2014-10-15 09:33:56 +02:00
Klaas Freitag 18f1b3c5ff Bumped version to 1.6.4 rc2 2014-10-10 11:53:13 +02:00
Daniel Molkentin 7dcbbb0046 Make sign_dmg.sh script fix frameworks correctly, resize disk image 2014-10-09 18:39:16 +02:00
Daniel Molkentin 0f58431746 Make sign_dmg.sh script fix frameworks correctly, resize disk image 2014-10-09 18:38:25 +02:00
Klaas Freitag cc8408be8f Bumped version to 1.6.4rc1 2014-10-09 15:03:27 +02:00
Klaas Freitag 4902271b19 Updated Changelog for 1.6.4 2014-10-09 15:02:40 +02:00
Christian Kamm b881b6db4e NetworkJobs: Propagator jobs keep others from expiring. #2155
In some owncloud server setups multiple concurrent connections for the
same session are not supported: owncloud/core#11153

This causes issues with multiple uploads and downloads. A usual symptom
is the quota job failing and the sync aborting.

This workaround lets activity on the propagator's GET and PUT jobs
reset the timeout of all network jobs. That way, queries like the quota
job would not time out while a large up/download is in progress.

(cherry picked from commit 2eec85a97c)
2014-10-09 11:29:12 +02:00
Christian Kamm 421177bfaf Download: Don't store message body if status != 2xx #2280
(cherry picked from commit 705cd571a5)
2014-10-09 11:23:39 +02:00
Christian Kamm 395ae1d4ed GET: Retry if bad range header used. #2280
* If a 416 is returned and we used a Range header, try again
  from scratch.
* The direct URL logic was also inconsistent for resumed downloads:
  it sent the Range header but didn't check the returned
  Content-Range header correctly. Now resuming is disabled for
  direct URL downloads.

(cherry picked from commit 48d3c75745)
2014-10-09 11:21:29 +02:00
Jürgen Weigert c0bb4cd938 Fixed https://github.com/owncloud/mirall/issues/1699
Added missing copyright headers.
2014-09-18 12:32:57 +02:00
Christian Kamm 06bcb8f3c8 Propagator: Use csync to get the modification time.
See owncloud/core#9781

(cherry picked from commit 2630a73a1c)

Conflict: Move modtime comparison from socketapi.cpp to folder.cpp.
2014-09-17 07:33:19 +02:00
Olivier Goffart 8711a3ea6c csync_vio_local on windows: fix overflow when computing the size of file > 4GiB
MAXDWORD is 0xFFFFFFFF, so if we add one, it overflows and is 0.
We need to cast it to 64 bits before
2014-09-10 12:12:07 +02:00
Daniel Molkentin 984be698b4 raiseDialog: Actually send the XEvent
Amendment to 25c274a0bd
2014-09-05 22:21:05 +02:00
Christian Kamm 4566ca3127 FolderMan: Fix startFromScratch logic. #1989 2014-09-05 10:13:00 +02:00
36 arquivos alterados com 307 adições e 90 exclusões
+13
Ver Arquivo
@@ -1,5 +1,18 @@
ChangeLog
=========
version 1.6.4 (release 2014-10-xx)
* Fix startup logic, fixes bug #1989
* Fix raise dialog on X11
* Win32: fix overflow when computing the size of file > 4GiB
* Use a fixed function to get files modification time, the
original one was broken for certain timezone issues, see
core bug #9781 for details
* Added some missing copyright headers
* Avoid data corruption due to wrong error handling, bug #2280
* Do improved request timeout handling to reduce the number of
timed out jobs, bug #2155
version 1.6.3 (release 2014-09-03)
* Fixed updater on OS X
* Fixed memory leak in SSL button that could lead to quick memory draining
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
set( MIRALL_VERSION_MAJOR 1 )
set( MIRALL_VERSION_MINOR 6 )
set( MIRALL_VERSION_PATCH 3 )
set( MIRALL_VERSION_PATCH 4 )
set( MIRALL_SOVERSION 0 )
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
+5
Ver Arquivo
@@ -23,6 +23,8 @@ fix_frameworks() {
mkdir -p "${FMWK_PATH}/Versions/${QT_FMWK_VERSION}/Resources/"
cp -avf "${QT_FMWK_PATH}/${FMWK}/Contents/Info.plist" "${FMWK_PATH}/Versions/${QT_FMWK_VERSION}/Resources"
(cd "${FMWK_PATH}" && ln -sf "Versions/${QT_FMWK_VERSION}/Resources" "Resources")
(cd "${FMWK_PATH}" && ln -sf "Versions/${QT_FMWK_VERSION}/${FMWK_NAME}")
(cd "${FMWK_PATH}/Versions" && ln -sf "${QT_FMWK_VERSION}" "Current")
perl -pi -e "s/${FMWK_NAME}_debug/${FMWK_NAME}/" "${FMWK_PATH}/Resources/Info.plist"
done
}
@@ -30,6 +32,9 @@ fix_frameworks() {
mount="/Volumes/$(basename "$src_dmg"|sed 's,-\([0-9]\)\(.*\),,')"
test -e "$tmp_dmg" && rm -rf "$tmp_dmg"
hdiutil convert "$src_dmg" -format UDRW -o "$tmp_dmg"
#signing adds data, add a bit of space
sectors=$(hdiutil resize -limits "$tmp_dmg" |grep -v cur|cut -f2)
hdiutil resize -sectors $(($sectors+(51200))) "$tmp_dmg"
hdiutil attach "$tmp_dmg"
pushd "$mount"
fix_frameworks "$mount"/*.app `qmake -query QT_INSTALL_LIBS` "$mount"/*.app/Contents/Frameworks
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# Always include srcdir and builddir in include path
# This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in
# about every subdir
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# define system dependent compiler flags
include(CheckCCompilerFlag)
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
if (UNIX)
# Suffix for Linux
SET(LIB_SUFFIX
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# Set system vars
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# This module defines
# INOTIFY_INCLUDE_DIR, where to find inotify.h, etc.
# INOTIFY_FOUND, If false, do not try to use inotify.
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# FIND_PACKAGE_VERSION_CHECK(NAME (DEFAULT_MSG|"Custom failure message"))
# This function is intended to be used in FindXXX.cmake modules files.
# It handles NAME_FIND_VERSION and NAME_VERSION variables in a Module.
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
find_program(PDFLATEX_EXECUTABLE NAMES pdflatex
HINTS
$ENV{PDFLATEX_DIR}
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# - Try to find QtKeychain
# Once done this will define
# QTKEYCHAIN_FOUND - System has QtKeychain
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# - Try to find QtKeychain
# Once done this will define
# QTKEYCHAIN_FOUND - System has QtKeychain
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
find_program(SPHINX_EXECUTABLE NAMES sphinx-build
HINTS
$ENV{SPHINX_DIR}
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# - macro_copy_file(_src _dst)
# Copies a file to ${_dst} only if ${_src} is different (newer) than ${_dst}
#
+1
Ver Arquivo
@@ -378,6 +378,7 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
; Make sure only to copy qt, not qt_help, etc
File "${MING_SHARE}\qt5\translations\qt_??.qm"
File "${MING_SHARE}\qt5\translations\qt_??_??.qm"
File "${MING_SHARE}\qt5\translations\qtbase_*.qm"
File "${MING_SHARE}\qt5\translations\qtkeychain_*.qm"
SetOutPath "$INSTDIR\platforms"
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
include (MacroOptionalFindPackage)
include (MacroLogFeature)
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# -helper macro to add a "doc" target with CMake build system.
# and configure doxy.config.in to doxy.config
#
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
if(CMAKE_COMPILER_IS_GNUCXX)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
+1 -1
Ver Arquivo
@@ -240,7 +240,7 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
/* printf("Index: %I64i\n", FileIndex.QuadPart); */
buf->inode = FileIndex.QuadPart;
buf->size = (fileInfo.nFileSizeHigh * (int64_t)(MAXDWORD+1)) + fileInfo.nFileSizeLow;
buf->size = (fileInfo.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + fileInfo.nFileSizeLow;
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
/* Get the file time with a win32 call rather than through stat. See
+28 -2
Ver Arquivo
@@ -61,7 +61,7 @@ our $infoCnt = 1;
our %config;
@ISA = qw(Exporter);
@EXPORT = qw( initTesting createRemoteDir createLocalDir cleanup csync
@EXPORT = qw( initTesting createRemoteDir removeRemoteDir createLocalDir cleanup csync
assertLocalDirs assertLocalAndRemoteDir glob_put put_to_dir
putToDirLWP localDir remoteDir localCleanup createLocalFile md5OfFile
remoteCleanup server initLocalDir initRemoteDir moveRemoteFile
@@ -181,6 +181,32 @@ sub initLocalDir
mkdir ($localDir, 0777 );
}
sub removeRemoteDir($;$)
{
my ($dir, $optionsRef) = @_;
my $url = testDirUrl() . $dir;
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $optionsRef->{user},
-pass=> $optionsRef->{passwd} );
if( $optionsRef->{url} ) {
$url = $optionsRef->{url} . $dir;
}
}
$d->open( $owncloud );
print $d->message . "\n";
my $re = $d->delete( $url );
if( $re == 0 ) {
print "Failed to remove directory <$url>:" . $d->message() ."\n";
}
return $re;
}
sub createRemoteDir(;$$)
{
my ($dir, $optionsRef) = @_;
@@ -201,7 +227,7 @@ sub createRemoteDir(;$$)
my $re = $d->mkcol( $url );
if( $re == 0 ) {
print "Failed to create directory <$url>: $d->message() \n";
print "Failed to create directory <$url>: " . $d->message() ."\n";
exit 1;
}
$d->open( $url );
+24 -14
Ver Arquivo
@@ -35,6 +35,13 @@ print "Hello, this is t5, a tester for syncing of files in Shares\n";
initTesting();
my $share_dir = "share_source";
my $sharee = { user => configValue('share_user'),
passwd => configValue('share_passwd'),
url => server() };
# first remove a possibly left over share dir.
printInfo( "Remove possibly left over share dir" );
removeRemoteDir( $share_dir, $sharee );
printInfo( "Create a share." );
my $shareId = createShare( $share_dir, 31 );
@@ -42,25 +49,28 @@ print "Created share with id <$shareId>\n";
assert( $shareId > 0 );
my $sharee = { user => configValue('share_user'),
passwd => configValue('share_passwd'),
url => server() };
if( $ENV{SERVER_VERSION} eq "owncloud7" ) {
print "This test does not make sense for ownCloud7, leaving for good!\n\n";
exit;
}
# put a couple of files into the shared directory in the sharer account
glob_put( 'sharing/*', $share_dir, $sharee);
# now user kf has a new directory in shared.
if( $ENV{SERVER_VERSION} eq "owncloud6" ) {
# now user kf has a new directory in shared.
# call csync, sync local t1 to remote t1
printInfo("Initial sync, sync stuff down.");
csync( server()."Shared" );
assertLocalAndRemoteDir( 'Shared', 0, server() );
# Local file to a read/write share should be synced up
printInfo("Put a file into the share.");
createLocalFile( localDir(). $share_dir . "/foobar.txt", 8094 );
csync( server()."Shared" );
assertLocalAndRemoteDir( 'Shared', 0, server() );
# call csync, sync local t1 to remote t1
printInfo("Initial sync, sync stuff down.");
csync( server()."Shared" );
assertLocalAndRemoteDir( 'Shared', 0, server() );
# Local file to a read/write share should be synced up
printInfo("Put a file into the share.");
createLocalFile( localDir(). $share_dir . "/foobar.txt", 8094 );
csync( server()."Shared" );
assertLocalAndRemoteDir( 'Shared', 0, server() );
}
printInfo("Remove a Share.");
removeShare($shareId, $share_dir);
+7 -1
Ver Arquivo
@@ -390,7 +390,6 @@ set(ownCloud ${ownCloud_old})
if (WITH_DBUS)
set(ADDITIONAL_APP_MODULES DBus)
endif(WITH_DBUS)
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY)
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
@@ -427,8 +426,15 @@ elseif(NOT BUILD_LIBRARIES_ONLY)
set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations)
install(FILES ${mirall_I18N} DESTINATION ${QM_DIR})
get_target_property(_qmake Qt5::qmake LOCATION)
execute_process(COMMAND ${_qmake} -query QT_INSTALL_TRANSLATIONS
OUTPUT_VARIABLE QT_TRANSLATIONS_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
file(GLOB qt_I18N ${QT_TRANSLATIONS_DIR}/qt_??.qm ${QT_TRANSLATIONS_DIR}/qt_??_??.qm)
install(FILES ${qt_I18N} DESTINATION ${QM_DIR})
file(GLOB qtbase_I18N ${QT_TRANSLATIONS_DIR}/qtbase_??.qm ${QT_TRANSLATIONS_DIR}/qt_??_??.qm)
install(FILES ${qtbase_I18N} DESTINATION ${QM_DIR})
file(GLOB qtkeychain_I18N ${QT_TRANSLATIONS_DIR}/qtkeychain*.qm)
install(FILES ${qtkeychain_I18N} DESTINATION ${QM_DIR})
endif()
+13 -1
Ver Arquivo
@@ -241,7 +241,19 @@ void ShibbolethCredentials::persist(Account* account)
void ShibbolethCredentials::invalidateToken(Account *account)
{
CookieJar *jar = static_cast<CookieJar*>(account->networkAccessManager()->cookieJar());
jar->deleteCookie(_shibCookie);
// Remove the _shibCookie
QList<QNetworkCookie> cookies = jar->allCookies();
for (QList<QNetworkCookie>::iterator it = cookies.begin(); it != cookies.end(); ) {
if (it->name() == _shibCookie.name()) {
it = cookies.erase(it);
} else {
++it;
}
}
jar->setAllCookies(cookies);
// Clear all other temporary cookies
jar->clearSessionCookies();
removeShibCookie(account);
_shibCookie = QNetworkCookie();
+2
Ver Arquivo
@@ -154,8 +154,10 @@ public:
QNetworkAccessManager* networkAccessManager();
QuotaInfo *quotaInfo();
signals:
void stateChanged(int state);
void propagatorNetworkActivity();
protected Q_SLOTS:
void slotHandleErrors(QNetworkReply*,QList<QSslError>);
+8 -5
Ver Arquivo
@@ -532,12 +532,15 @@ void Application::setupTranslations()
setProperty("ui_lang", lang);
const QString qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
const QString qtTrFile = QLatin1String("qt_") + lang;
if (qtTranslator->load(qtTrFile, qtTrPath)) {
qtTranslator->load(qtTrFile, trPath);
const QString qtBaseTrFile = QLatin1String("qtbase_") + lang;
if (!qtTranslator->load(qtTrFile, qtTrPath)) {
if (!qtTranslator->load(qtTrFile, trPath)) {
qtTranslator->load(qtBaseTrFile, trPath);
}
}
const QString qtkeychainFile = QLatin1String("qt_") + lang;
if (!qtkeychainTranslator->load(qtkeychainFile, qtTrPath)) {
qtkeychainTranslator->load(qtkeychainFile, trPath);
const QString qtkeychainTrFile = QLatin1String("qtkeychain_") + lang;
if (!qtkeychainTranslator->load(qtkeychainTrFile, qtTrPath)) {
qtkeychainTranslator->load(qtkeychainTrFile, trPath);
}
if (!translator->isEmpty())
installTranslator(translator);
-16
Ver Arquivo
@@ -91,27 +91,11 @@ QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl &url) const
return cookies;
}
bool CookieJar::deleteCookie(const QNetworkCookie &delCookie)
{
QList<QNetworkCookie> cookies = allCookies();
bool removeSucceeded = false;
foreach(const QNetworkCookie &cookie, cookies) {
// ### cookies are not identical in attriutes, why?
if (cookie.name() == delCookie.name()) {
cookies.removeOne(cookie);
removeSucceeded = true;
}
}
setAllCookies(cookies);
return removeSucceeded;
}
void CookieJar::clearSessionCookies()
{
setAllCookies(removeExpired(allCookies()));
}
void CookieJar::save()
{
QFile file;
+3 -1
Ver Arquivo
@@ -29,9 +29,11 @@ public:
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const;
virtual bool deleteCookie(const QNetworkCookie & cookie);
void clearSessionCookies();
using QNetworkCookieJar::setAllCookies;
using QNetworkCookieJar::allCookies;
signals:
void newCookiesForUrl(const QList<QNetworkCookie>& cookieList, const QUrl& url);
private:
+28 -1
Ver Arquivo
@@ -12,7 +12,10 @@
*/
#include "filesystem.h"
#include "utility.h"
#include <QFile>
#include <QFileInfo>
#include <QDebug>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
@@ -24,11 +27,16 @@
#include <winbase.h>
#endif
// We use some internals of csync:
extern "C" int c_utimes(const char *, const struct timeval *);
extern "C" void csync_win32_set_file_hidden( const char *file, bool h );
extern "C" {
#include "vio/csync_vio_handle.h"
#include "vio/csync_vio_file_stat.h"
#include "vio/csync_vio_local.h"
}
namespace Mirall {
bool FileSystem::fileEquals(const QString& fn1, const QString& fn2)
@@ -69,6 +77,25 @@ void FileSystem::setFileHidden(const QString& filename, bool hidden)
return csync_win32_set_file_hidden(filename.toUtf8().constData(), hidden);
}
time_t FileSystem::getModTime(const QString &filename)
{
csync_vio_file_stat_t* stat = csync_vio_file_stat_new();
qint64 result = -1;
if (csync_vio_local_stat(filename.toUtf8().data(), stat) != -1
&& (stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_MTIME))
{
result = stat->mtime;
}
else
{
qDebug() << "Could not get modification time for" << filename
<< "with csync, using QFileInfo";
result = Utility::qDateTimeToTime_t(QFileInfo(filename).lastModified());
}
csync_vio_file_stat_destroy(stat);
return result;
}
void FileSystem::setModTime(const QString& filename, time_t modTime)
{
struct timeval times[2];
+8
Ver Arquivo
@@ -30,6 +30,14 @@ bool fileEquals(const QString &fn1, const QString &fn2);
/** Mark the file as hidden (only has effects on windows) */
void setFileHidden(const QString& filename, bool hidden);
/** Get the mtime for a filepath.
*
* Use this over QFileInfo::lastModified() to avoid timezone related bugs. See
* owncloud/core#9781 for details.
*/
time_t getModTime(const QString &filename);
void setModTime(const QString &filename, time_t modTime);
/**
+4 -1
Ver Arquivo
@@ -27,6 +27,7 @@
#include "mirall/clientproxy.h"
#include "mirall/syncengine.h"
#include "mirall/syncrunfilelog.h"
#include "mirall/filesystem.h"
#include "creds/abstractcredentials.h"
@@ -776,7 +777,9 @@ SyncFileStatus Folder::fileStatus( const QString& fileName )
}
// file was locally modified.
if( stat == FILE_STATUS_NONE && fi.lastModified() != rec._modtime ) {
if( stat == FILE_STATUS_NONE &&
FileSystem::getModTime(fi.absoluteFilePath())
!= Utility::qDateTimeToTime_t(rec._modtime) ) {
stat = FILE_STATUS_EVAL;
}
+27 -13
Ver Arquivo
@@ -600,27 +600,41 @@ QString FolderMan::getBackupName( const QString& fullPathName ) const
bool FolderMan::startFromScratch( const QString& localFolder )
{
if( localFolder.isEmpty() ) return false;
if( localFolder.isEmpty() ) {
return false;
}
QFileInfo fi( localFolder );
if( fi.exists() && fi.isDir() ) {
QDir file = fi.dir();
QDir parentDir( fi.dir() );
QString folderName = fi.fileName();
// check if there are files in the directory.
if( file.count() == 0 ) {
// directory is existing, but its empty. Use it.
// Adjust for case where localFolder ends with a /
if ( fi.isDir() ) {
folderName = parentDir.dirName();
parentDir.cdUp();
}
if( fi.exists() ) {
// It exists, but is empty -> just reuse it.
if( fi.isDir() && fi.dir().count() == 0 ) {
qDebug() << "startFromScratch: Directory is empty!";
return true;
}
QString newName = getBackupName( fi.absoluteFilePath() );
if( file.rename( fi.absoluteFilePath(), newName )) {
if( file.mkdir( fi.absoluteFilePath() ) ) {
return true;
}
// Make a backup of the folder/file.
QString newName = getBackupName( parentDir.absoluteFilePath( folderName ) );
if( !parentDir.rename( fi.absoluteFilePath(), newName ) ) {
qDebug() << "startFromScratch: Could not rename" << fi.absoluteFilePath()
<< "to" << newName;
return false;
}
}
return false;
if( !parentDir.mkdir( fi.absoluteFilePath() ) ) {
qDebug() << "startFromScratch: Could not mkdir" << fi.absoluteFilePath();
return false;
}
return true;
}
void FolderMan::setDirtyProxy(bool value)
+16 -7
Ver Arquivo
@@ -50,6 +50,15 @@ AbstractNetworkJob::AbstractNetworkJob(Account *account, const QString &path, QO
_timer.setSingleShot(true);
_timer.setInterval(10*1000); // default to 10 seconds.
connect(&_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
connect(this, SIGNAL(networkActivity()), SLOT(resetTimeout()));
// Network activity on the propagator jobs (GET/PUT) keeps all requests alive.
// This is a workaround for OC instances which only support one
// parallel up and download
if (_account) {
connect(_account, SIGNAL(propagatorNetworkActivity()), SLOT(resetTimeout()));
}
}
void AbstractNetworkJob::setReply(QNetworkReply *reply)
@@ -80,11 +89,6 @@ void AbstractNetworkJob::setIgnoreCredentialFailure(bool ignore)
_ignoreCredentialFailure = ignore;
}
void AbstractNetworkJob::setAccount(Account *account)
{
_account = account;
}
void AbstractNetworkJob::setPath(const QString &path)
{
_path = path;
@@ -93,6 +97,8 @@ void AbstractNetworkJob::setPath(const QString &path)
void AbstractNetworkJob::setupConnections(QNetworkReply *reply)
{
connect(reply, SIGNAL(finished()), SLOT(slotFinished()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(networkActivity()));
connect(reply, SIGNAL(uploadProgress(qint64,qint64)), SIGNAL(networkActivity()));
}
QNetworkReply* AbstractNetworkJob::addTimer(QNetworkReply *reply)
@@ -179,8 +185,11 @@ QString AbstractNetworkJob::responseTimestamp()
return _responseTimestamp;
}
AbstractNetworkJob::~AbstractNetworkJob() {
_reply->deleteLater();
AbstractNetworkJob::~AbstractNetworkJob()
{
if (_reply) {
_reply->deleteLater();
}
}
void AbstractNetworkJob::start()
+2 -2
Ver Arquivo
@@ -55,15 +55,14 @@ public:
virtual void start();
void setAccount(Account *account);
Account* account() const { return _account; }
void setPath(const QString &path);
QString path() const { return _path; }
void setReply(QNetworkReply *reply);
QNetworkReply* reply() const { return _reply; }
void setIgnoreCredentialFailure(bool ignore);
bool ignoreCredentialFailure() const { return _ignoreCredentialFailure; }
@@ -75,6 +74,7 @@ public slots:
void resetTimeout();
signals:
void networkError(QNetworkReply *reply);
void networkActivity();
protected:
void setupConnections(QNetworkReply *reply);
QNetworkReply* davRequest(const QByteArray& verb, const QString &relPath,
+7
Ver Arquivo
@@ -559,6 +559,13 @@ void ownCloudGui::raiseDialog( QWidget *raiseWidget )
e.xclient.data.l[2] = 0;
e.xclient.data.l[3] = 0l;
e.xclient.data.l[4] = 0l;
Display *display = QX11Info::display();
XSendEvent(display,
RootWindow(display, DefaultScreen(display)),
False, // propagate
SubstructureRedirectMask|SubstructureNotifyMask,
&e);
#endif
}
+51 -24
Ver Arquivo
@@ -73,7 +73,7 @@ void PUTFileJob::start() {
}
connect(reply(), SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(uploadProgress(qint64,qint64)));
connect(reply(), SIGNAL(uploadProgress(qint64,qint64)), this, SLOT(resetTimeout()));
connect(this, SIGNAL(networkActivity()), account(), SIGNAL(propagatorNetworkActivity()));
AbstractNetworkJob::start();
}
@@ -302,8 +302,10 @@ void PropagateUploadFileQNAM::slotPutFinished()
return;
}
if (Utility::qDateTimeToTime_t(fi.lastModified()) != _item._modtime) {
qDebug() << "The local file has changed during upload:" << _item._modtime << "!=" << Utility::qDateTimeToTime_t(fi.lastModified()) << fi.lastModified();
const time_t new_mtime = FileSystem::getModTime(fi.absoluteFilePath());
if (new_mtime != _item._modtime) {
qDebug() << "The local file has changed during upload:" << _item._modtime << "!=" << new_mtime
<< ", QFileInfo: " << Utility::qDateTimeToTime_t(fi.lastModified()) << fi.lastModified();
_propagator->_activeJobs--;
done(SyncFileItem::SoftError, tr("Local file changed during sync."));
// FIXME: the legacy code was retrying for a few seconds.
@@ -395,6 +397,12 @@ void PropagateUploadFileQNAM::abort()
///////////////////////////////////////////////////////////////////////////////////////////////////
void GETFileJob::start() {
if (_resumeStart > 0) {
_headers["Range"] = "bytes=" + QByteArray::number(_resumeStart) +'-';
_headers["Accept-Ranges"] = "bytes";
qDebug() << "Retry with range " << _headers["Range"];
}
QNetworkRequest req;
for(QMap<QByteArray, QByteArray>::const_iterator it = _headers.begin(); it != _headers.end(); ++it) {
req.setRawHeader(it.key(), it.value());
@@ -411,15 +419,22 @@ void GETFileJob::start() {
connect(reply(), SIGNAL(metaDataChanged()), this, SLOT(slotMetaDataChanged()));
connect(reply(), SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
connect(reply(), SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(downloadProgress(qint64,qint64)));
connect(this, SIGNAL(networkActivity()), account(), SIGNAL(propagatorNetworkActivity()));
AbstractNetworkJob::start();
}
void GETFileJob::slotMetaDataChanged()
{
if (reply()->error() != QNetworkReply::NoError
|| reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() / 100 != 2) {
// We will handle the error when the job is finished.
int httpStatus = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// If the status code isn't 2xx, don't write the reply body to the file.
// For any error: handle it when the job is finished, not here.
if (httpStatus / 100 != 2) {
_device->close();
return;
}
if (reply()->error() != QNetworkReply::NoError) {
return;
}
@@ -484,16 +499,17 @@ void GETFileJob::slotReadyRead()
return;
}
qint64 w = _device->write(buffer.constData(), r);
if (w != r) {
_errorString = _device->errorString();
_errorStatus = SyncFileItem::NormalError;
qDebug() << "Error while writing to file" << w << r << _errorString;
reply()->abort();
return;
if (_device->isOpen()) {
qint64 w = _device->write(buffer.constData(), r);
if (w != r) {
_errorString = _device->errorString();
_errorStatus = SyncFileItem::NormalError;
qDebug() << "Error while writing to file" << w << r << _errorString;
reply()->abort();
return;
}
}
}
resetTimeout();
}
void PropagateDownloadFileQNAM::start()
@@ -558,17 +574,13 @@ void PropagateDownloadFileQNAM::start()
/* Allow compressed content by setting the header */
//headers["Accept-Encoding"] = "gzip";
if (_tmpFile.size() > 0) {
quint64 done = _tmpFile.size();
if (done == _item._size) {
_startSize = _tmpFile.size();
if (_startSize > 0) {
if (_startSize == _item._size) {
qDebug() << "File is already complete, no need to download";
downloadFinished();
return;
}
headers["Range"] = "bytes=" + QByteArray::number(done) +'-';
headers["Accept-Ranges"] = "bytes";
qDebug() << "Retry with range " << headers["Range"];
_startSize = done;
}
_job = new GETFileJob(AccountManager::instance()->account(),
@@ -595,18 +607,33 @@ void PropagateDownloadFileQNAM::slotGetFinished()
QNetworkReply::NetworkError err = job->reply()->error();
if (err != QNetworkReply::NoError) {
if (_tmpFile.size() == 0) {
// don't keep the temporary file if it is empty.
_item._httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// If we sent a 'Range' header and get 416 back, we want to retry
// without the header.
bool badRangeHeader = job->resumeStart() > 0 && _item._httpErrorCode == 416;
if (badRangeHeader) {
qDebug() << Q_FUNC_INFO << "server replied 416 to our range request, trying again without in next sync";
}
// Don't keep the temporary file if it is empty or we
// used a bad range header.
if (_tmpFile.size() == 0 || badRangeHeader) {
_tmpFile.close();
_tmpFile.remove();
_propagator->_journal->setDownloadInfo(_item._file, SyncJournalDb::DownloadInfo());
}
_item._httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
_propagator->_activeJobs--;
SyncFileItem::Status status = job->errorStatus();
if (status == SyncFileItem::NoStatus) {
status = classifyError(err, _item._httpErrorCode);
}
if (badRangeHeader) {
// Can't do this in classifyError() because 416 without a
// Range header should result in NormalError.
status = SyncFileItem::SoftError;
}
done(status, job->errorString());
return;
}
+2
Ver Arquivo
@@ -133,6 +133,8 @@ public:
SyncFileItem::Status errorStatus() { return _errorStatus; }
quint64 resumeStart() const { return _resumeStart; }
virtual void slotTimeout();