2012-02-15 12:30:37 +04:00
|
|
|
/*
|
|
|
|
* Copyright (C) by Duncan Mac-Vicar P. <duncan@kde.org>
|
|
|
|
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2012-05-21 18:48:49 +04:00
|
|
|
#include "mirall/csyncthread.h"
|
|
|
|
#include "mirall/mirallconfigfile.h"
|
2012-09-27 19:22:08 +04:00
|
|
|
#include "mirall/theme.h"
|
2012-12-05 19:45:28 +04:00
|
|
|
#include "mirall/logger.h"
|
2012-12-14 00:36:44 +04:00
|
|
|
#include "mirall/utility.h"
|
2012-05-21 18:48:49 +04:00
|
|
|
|
2012-12-06 19:24:53 +04:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
#include <windows.h>
|
|
|
|
#else
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
#include <QDebug>
|
2013-01-14 15:13:29 +04:00
|
|
|
#include <QSslSocket>
|
2012-02-15 12:30:37 +04:00
|
|
|
#include <QDir>
|
|
|
|
#include <QMutexLocker>
|
|
|
|
#include <QThread>
|
|
|
|
#include <QStringList>
|
|
|
|
#include <QTextStream>
|
2012-02-28 19:49:13 +04:00
|
|
|
#include <QTime>
|
2012-08-26 13:47:45 +04:00
|
|
|
#include <QApplication>
|
2012-12-11 15:49:48 +04:00
|
|
|
#include <QUrl>
|
2012-12-13 22:52:07 +04:00
|
|
|
#include <QSslCertificate>
|
2012-08-26 13:47:45 +04:00
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
namespace Mirall {
|
|
|
|
|
2012-03-13 20:37:43 +04:00
|
|
|
/* static variables to hold the credentials */
|
|
|
|
QString CSyncThread::_user;
|
|
|
|
QString CSyncThread::_passwd;
|
2012-10-09 04:34:22 +04:00
|
|
|
QNetworkProxy CSyncThread::_proxy;
|
2012-08-02 12:17:15 +04:00
|
|
|
|
2012-04-30 10:56:56 +04:00
|
|
|
QString CSyncThread::_csyncConfigDir; // to be able to remove the lock file.
|
|
|
|
|
2012-03-22 19:22:08 +04:00
|
|
|
QMutex CSyncThread::_mutex;
|
2012-03-21 21:03:49 +04:00
|
|
|
|
2012-12-04 20:24:46 +04:00
|
|
|
void csyncLogCatcher(CSYNC *ctx,
|
|
|
|
int verbosity,
|
|
|
|
const char *function,
|
|
|
|
const char *buffer,
|
|
|
|
void *userdata)
|
|
|
|
{
|
2012-12-07 12:03:24 +04:00
|
|
|
Logger::instance()->csyncLog( QString::fromUtf8(buffer) );
|
2012-12-04 20:24:46 +04:00
|
|
|
}
|
|
|
|
|
2012-12-06 20:34:12 +04:00
|
|
|
CSyncThread::CSyncThread(const QString &source, const QString &target)
|
2012-02-15 12:30:37 +04:00
|
|
|
: _source(source)
|
|
|
|
, _target(target)
|
2012-03-21 21:03:49 +04:00
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
{
|
2012-03-22 19:22:08 +04:00
|
|
|
_mutex.lock();
|
2012-08-17 19:13:17 +04:00
|
|
|
if( ! _source.endsWith(QLatin1Char('/'))) _source.append(QLatin1Char('/'));
|
2012-03-22 19:22:08 +04:00
|
|
|
_mutex.unlock();
|
2012-02-15 12:30:37 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
CSyncThread::~CSyncThread()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-12-20 23:51:22 +04:00
|
|
|
QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errString )
|
2012-12-20 19:45:56 +04:00
|
|
|
{
|
|
|
|
QString errStr;
|
|
|
|
|
|
|
|
switch( err ) {
|
|
|
|
case CSYNC_ERR_NONE:
|
|
|
|
errStr = tr("Success.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_LOG:
|
|
|
|
errStr = tr("CSync Logging setup failed.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_LOCK:
|
|
|
|
errStr = tr("CSync failed to create a lock file.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_STATEDB_LOAD:
|
|
|
|
errStr = tr("CSync failed to load the state db.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_MODULE:
|
|
|
|
errStr = tr("<p>The %1 plugin for csync could not be loaded.<br/>Please verify the installation!</p>").arg(Theme::instance()->appName());
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_TIMESKEW:
|
|
|
|
errStr = tr("The system time on this client is different than the system time on the server. "
|
|
|
|
"Please use a time synchronization service (NTP) on the server and client machines "
|
|
|
|
"so that the times remain the same.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_FILESYSTEM:
|
|
|
|
errStr = tr("CSync could not detect the filesystem type.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_TREE:
|
|
|
|
errStr = tr("CSync got an error while processing internal trees.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_MEM:
|
|
|
|
errStr = tr("CSync failed to reserve memory.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_PARAM:
|
|
|
|
errStr = tr("CSync fatal parameter error.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_UPDATE:
|
|
|
|
errStr = tr("CSync processing step update failed.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_RECONCILE:
|
|
|
|
errStr = tr("CSync processing step reconcile failed.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_PROPAGATE:
|
|
|
|
errStr = tr("CSync processing step propagate failed.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_ACCESS_FAILED:
|
|
|
|
errStr = tr("<p>The target directory %1 does not exist.</p><p>Please check the sync setup.</p>").arg(_target);
|
|
|
|
// this is critical. The database has to be removed.
|
|
|
|
emit wipeDb();
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_REMOTE_CREATE:
|
|
|
|
case CSYNC_ERR_REMOTE_STAT:
|
|
|
|
errStr = tr("A remote file can not be written. Please check the remote access.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_LOCAL_CREATE:
|
|
|
|
case CSYNC_ERR_LOCAL_STAT:
|
|
|
|
errStr = tr("The local filesystem can not be written. Please check permissions.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_PROXY:
|
|
|
|
errStr = tr("CSync failed to connect through a proxy.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_LOOKUP:
|
|
|
|
errStr = tr("CSync failed to lookup proxy or server.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_AUTH_SERVER:
|
|
|
|
errStr = tr("CSync failed to authenticate at the %1 server.").arg(Theme::instance()->appName());
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_AUTH_PROXY:
|
|
|
|
errStr = tr("CSync failed to authenticate at the proxy.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_CONNECT:
|
|
|
|
errStr = tr("CSync failed to connect to the network.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_TIMEOUT:
|
|
|
|
errStr = tr("A network connection timeout happend.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_HTTP:
|
|
|
|
errStr = tr("A HTTP transmission error happened.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_PERM:
|
|
|
|
errStr = tr("CSync failed due to not handled permission deniend.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_NOT_FOUND:
|
|
|
|
errStr = tr("CSync failed to find a specific file.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_EXISTS:
|
|
|
|
errStr = tr("CSync tried to create a directory that already exists.");
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_NOSPC:
|
|
|
|
errStr = tr("CSync: No space on %1 server available.").arg(Theme::instance()->appName());
|
|
|
|
break;
|
|
|
|
case CSYNC_ERR_UNSPEC:
|
|
|
|
errStr = tr("CSync unspecified error.");
|
|
|
|
|
|
|
|
default:
|
|
|
|
errStr = tr("An internal error number %1 happend.").arg( (int) err );
|
|
|
|
}
|
|
|
|
|
2012-12-20 23:51:22 +04:00
|
|
|
if( errString ) {
|
|
|
|
errStr += tr("<br/>Backend Message: ")+QString::fromUtf8(errString);
|
|
|
|
}
|
2012-12-20 19:45:56 +04:00
|
|
|
return errStr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-12-12 17:59:38 +04:00
|
|
|
const char* CSyncThread::proxyTypeToCStr(QNetworkProxy::ProxyType type)
|
2012-10-09 04:34:22 +04:00
|
|
|
{
|
|
|
|
switch (type) {
|
|
|
|
case QNetworkProxy::NoProxy:
|
2012-12-12 17:59:38 +04:00
|
|
|
return "NoProxy";
|
2012-10-09 04:34:22 +04:00
|
|
|
case QNetworkProxy::DefaultProxy:
|
2012-12-12 17:59:38 +04:00
|
|
|
return "DefaultProxy";
|
2012-10-09 04:34:22 +04:00
|
|
|
case QNetworkProxy::Socks5Proxy:
|
2012-12-12 17:59:38 +04:00
|
|
|
return "Socks5Proxy";
|
2013-01-14 15:12:53 +04:00
|
|
|
case QNetworkProxy::HttpProxy:
|
2012-12-12 17:59:38 +04:00
|
|
|
return "HttpProxy";
|
2013-01-14 15:12:53 +04:00
|
|
|
case QNetworkProxy::HttpCachingProxy:
|
2012-12-12 17:59:38 +04:00
|
|
|
return "HttpCachingProxy";
|
2013-01-14 15:12:53 +04:00
|
|
|
case QNetworkProxy::FtpCachingProxy:
|
2012-12-12 17:59:38 +04:00
|
|
|
return "FtpCachingProxy";
|
2012-10-09 04:34:22 +04:00
|
|
|
default:
|
2012-12-12 17:59:38 +04:00
|
|
|
return "NoProxy";
|
2012-10-09 04:34:22 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-15 23:41:52 +04:00
|
|
|
int CSyncThread::treewalkLocal( TREE_WALK_FILE* file, void *data )
|
|
|
|
{
|
|
|
|
return static_cast<CSyncThread*>(data)->treewalkFile( file, false );
|
|
|
|
}
|
|
|
|
|
|
|
|
int CSyncThread::treewalkRemote( TREE_WALK_FILE* file, void *data )
|
|
|
|
{
|
|
|
|
return static_cast<CSyncThread*>(data)->treewalkFile( file, true );
|
|
|
|
}
|
|
|
|
|
|
|
|
int CSyncThread::walkFinalize(TREE_WALK_FILE* file, void *data )
|
|
|
|
{
|
|
|
|
return static_cast<CSyncThread*>(data)->treewalkError( file);
|
|
|
|
}
|
|
|
|
|
|
|
|
int CSyncThread::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
|
|
|
{
|
|
|
|
if( ! file ) return -1;
|
|
|
|
SyncFileItem item;
|
|
|
|
item._file = QString::fromUtf8( file->path );
|
|
|
|
item._instruction = file->instruction;
|
|
|
|
item._dir = SyncFileItem::None;
|
|
|
|
|
|
|
|
SyncFileItem::Direction dir;
|
|
|
|
|
|
|
|
int re = 0;
|
|
|
|
|
|
|
|
switch(file->instruction) {
|
|
|
|
case CSYNC_INSTRUCTION_NONE:
|
|
|
|
// No need to do anything.
|
|
|
|
return re;
|
|
|
|
break;
|
|
|
|
case CSYNC_INSTRUCTION_RENAME:
|
|
|
|
dir = !remote ? SyncFileItem::Down : SyncFileItem::Up;
|
|
|
|
item._renameTarget = QString::fromUtf8( file->rename_path );
|
|
|
|
break;
|
|
|
|
case CSYNC_INSTRUCTION_REMOVE:
|
|
|
|
dir = !remote ? SyncFileItem::Down : SyncFileItem::Up;
|
|
|
|
break;
|
|
|
|
case CSYNC_INSTRUCTION_CONFLICT:
|
|
|
|
case CSYNC_INSTRUCTION_IGNORE:
|
|
|
|
case CSYNC_INSTRUCTION_ERROR:
|
|
|
|
dir = SyncFileItem::None;
|
|
|
|
break;
|
|
|
|
case CSYNC_INSTRUCTION_EVAL:
|
|
|
|
case CSYNC_INSTRUCTION_NEW:
|
|
|
|
case CSYNC_INSTRUCTION_SYNC:
|
|
|
|
case CSYNC_INSTRUCTION_STAT_ERROR:
|
|
|
|
case CSYNC_INSTRUCTION_DELETED:
|
|
|
|
case CSYNC_INSTRUCTION_UPDATED:
|
|
|
|
default:
|
|
|
|
dir = remote ? SyncFileItem::Down : SyncFileItem::Up;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
item._dir = dir;
|
|
|
|
_mutex.lock();
|
|
|
|
_syncedItems.append(item);
|
|
|
|
_mutex.unlock();
|
|
|
|
|
|
|
|
return re;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CSyncThread::treewalkError(TREE_WALK_FILE* file)
|
|
|
|
{
|
|
|
|
SyncFileItem item;
|
|
|
|
item._file= QString::fromUtf8(file->path);
|
|
|
|
int indx = _syncedItems.indexOf(item);
|
|
|
|
|
|
|
|
if ( indx == -1 )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if( item._instruction == CSYNC_INSTRUCTION_STAT_ERROR ||
|
|
|
|
item._instruction == CSYNC_INSTRUCTION_ERROR ) {
|
|
|
|
_mutex.lock();
|
|
|
|
_syncedItems[indx]._instruction = item._instruction;
|
|
|
|
_mutex.unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-26 13:47:45 +04:00
|
|
|
void CSyncThread::startSync()
|
2012-02-15 12:30:37 +04:00
|
|
|
{
|
2012-08-26 13:47:45 +04:00
|
|
|
qDebug() << "starting to sync " << qApp->thread() << QThread::currentThread();
|
2012-02-15 12:30:37 +04:00
|
|
|
CSYNC *csync;
|
2013-01-15 23:41:52 +04:00
|
|
|
bool doTreeWalk = true;
|
2012-03-22 19:22:08 +04:00
|
|
|
|
2012-10-29 13:30:25 +04:00
|
|
|
emit(started());
|
|
|
|
|
2012-03-21 21:03:49 +04:00
|
|
|
_mutex.lock();
|
2013-01-15 23:41:52 +04:00
|
|
|
_syncedItems.clear();
|
2012-08-30 19:50:42 +04:00
|
|
|
|
2012-03-22 19:22:08 +04:00
|
|
|
if( csync_create(&csync,
|
2012-06-13 19:34:20 +04:00
|
|
|
_source.toUtf8().data(),
|
|
|
|
_target.toUtf8().data()) < 0 ) {
|
2012-03-22 19:22:08 +04:00
|
|
|
emit csyncError( tr("CSync create failed.") );
|
|
|
|
}
|
2012-06-13 13:29:38 +04:00
|
|
|
_csyncConfigDir = QString::fromUtf8( csync_get_config_dir( csync ));
|
2012-03-21 21:03:49 +04:00
|
|
|
_mutex.unlock();
|
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
csync_enable_conflictcopys(csync);
|
|
|
|
|
2012-03-28 13:26:51 +04:00
|
|
|
MirallConfigFile cfg;
|
2012-03-28 14:23:34 +04:00
|
|
|
QString excludeList = cfg.excludeFile();
|
|
|
|
|
|
|
|
if( !excludeList.isEmpty() ) {
|
2012-12-20 19:48:32 +04:00
|
|
|
qDebug() << "==== added CSync exclude List: " << excludeList.toUtf8();
|
|
|
|
csync_add_exclude_list( csync, excludeList.toUtf8() );
|
2012-03-28 13:26:51 +04:00
|
|
|
}
|
|
|
|
|
2012-09-27 14:27:40 +04:00
|
|
|
csync_set_config_dir( csync, cfg.configPath().toUtf8() );
|
|
|
|
|
2012-02-28 19:49:13 +04:00
|
|
|
QTime t;
|
|
|
|
t.start();
|
|
|
|
|
2012-12-12 23:06:59 +04:00
|
|
|
csync_set_userdata(csync, this);
|
|
|
|
|
2012-12-11 15:49:48 +04:00
|
|
|
csync_set_log_callback( csync, csyncLogCatcher );
|
|
|
|
csync_set_auth_callback( csync, getauth );
|
2012-12-12 23:06:59 +04:00
|
|
|
csync_set_progress_callback( csync, progress );
|
2012-12-11 15:49:48 +04:00
|
|
|
|
2012-03-22 19:22:08 +04:00
|
|
|
if( csync_init(csync) < 0 ) {
|
2012-04-17 14:34:19 +04:00
|
|
|
CSYNC_ERROR_CODE err = csync_get_error( csync );
|
2012-12-20 23:51:22 +04:00
|
|
|
const char *errMsg = csync_get_error_string( csync );
|
|
|
|
QString errStr = csyncErrorToString(err, errMsg );
|
2012-12-20 19:45:56 +04:00
|
|
|
qDebug() << " #### ERROR csync_init: " << errStr;
|
2012-03-30 17:34:56 +04:00
|
|
|
emit csyncError(errStr);
|
2012-02-15 12:30:37 +04:00
|
|
|
goto cleanup;
|
2012-03-22 19:22:08 +04:00
|
|
|
}
|
2012-02-15 12:30:37 +04:00
|
|
|
|
2012-12-05 15:29:35 +04:00
|
|
|
// set module properties, mainly the proxy information.
|
|
|
|
// do not use QLatin1String here because that has to be real const char* for C.
|
2012-12-07 12:03:24 +04:00
|
|
|
csync_set_log_verbosity(csync, 11);
|
2012-12-06 20:56:46 +04:00
|
|
|
csync_set_module_property(csync, "csync_context", csync);
|
2012-12-12 17:59:38 +04:00
|
|
|
csync_set_module_property(csync, "proxy_type", (char*) proxyTypeToCStr(_proxy.type()) );
|
2012-12-20 19:48:32 +04:00
|
|
|
csync_set_module_property(csync, "proxy_host", _proxy.hostName().toUtf8().data() );
|
|
|
|
csync_set_module_property(csync, "proxy_user", _proxy.user().toUtf8().data() );
|
|
|
|
csync_set_module_property(csync, "proxy_pwd" , _proxy.password().toUtf8().data() );
|
2012-12-05 15:29:35 +04:00
|
|
|
|
2012-08-09 16:13:20 +04:00
|
|
|
qDebug() << "#### Update start #################################################### >>";
|
2012-03-22 19:22:08 +04:00
|
|
|
if( csync_update(csync) < 0 ) {
|
2012-08-09 16:13:20 +04:00
|
|
|
CSYNC_ERROR_CODE err = csync_get_error( csync );
|
2012-12-20 23:51:22 +04:00
|
|
|
const char *errMsg = csync_get_error_string( csync );
|
|
|
|
QString errStr = csyncErrorToString(err, errMsg);
|
2012-12-20 19:45:56 +04:00
|
|
|
qDebug() << " #### ERROR csync_update: " << errStr;
|
|
|
|
emit csyncError(errStr);
|
2012-02-15 12:30:37 +04:00
|
|
|
goto cleanup;
|
2012-03-22 19:22:08 +04:00
|
|
|
}
|
2012-08-09 16:13:20 +04:00
|
|
|
qDebug() << "<<#### Update end ###########################################################";
|
2012-02-15 12:30:37 +04:00
|
|
|
|
2013-01-15 23:41:52 +04:00
|
|
|
|
|
|
|
|
2012-12-06 20:34:12 +04:00
|
|
|
if( csync_reconcile(csync) < 0 ) {
|
2012-12-20 19:45:56 +04:00
|
|
|
CSYNC_ERROR_CODE err = csync_get_error( csync );
|
2012-12-20 23:51:22 +04:00
|
|
|
const char *errMsg = csync_get_error_string( csync );
|
|
|
|
QString errStr = csyncErrorToString(err, errMsg);
|
2012-12-20 19:45:56 +04:00
|
|
|
qDebug() << " #### ERROR csync_reconcile: " << errStr;
|
|
|
|
emit csyncError(errStr);
|
2012-03-22 19:22:08 +04:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2013-01-15 23:41:52 +04:00
|
|
|
|
|
|
|
if( csync_walk_local_tree(csync, &treewalkLocal, 0) < 0 ) {
|
|
|
|
qDebug() << "Error in local treewalk.";
|
|
|
|
doTreeWalk = false;
|
|
|
|
}
|
|
|
|
if( doTreeWalk && csync_walk_remote_tree(csync, &treewalkRemote, 0) < 0 ) {
|
|
|
|
qDebug() << "Error in remote treewalk.";
|
|
|
|
doTreeWalk = false;
|
|
|
|
}
|
|
|
|
|
2012-12-06 20:34:12 +04:00
|
|
|
if( csync_propagate(csync) < 0 ) {
|
2012-12-20 19:45:56 +04:00
|
|
|
CSYNC_ERROR_CODE err = csync_get_error( csync );
|
2012-12-20 23:51:22 +04:00
|
|
|
const char *errMsg = csync_get_error_string( csync );
|
|
|
|
QString errStr = csyncErrorToString(err, errMsg);
|
2012-12-20 19:45:56 +04:00
|
|
|
qDebug() << " #### ERROR csync_propagate: " << errStr;
|
|
|
|
emit csyncError(errStr);
|
2012-02-28 19:49:13 +04:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2013-01-15 23:41:52 +04:00
|
|
|
|
|
|
|
if( csync_walk_local_tree(csync, &walkFinalize, 0) < 0 ||
|
|
|
|
csync_walk_remote_tree( csync, &walkFinalize, 0 ) < 0 ) {
|
|
|
|
qDebug() << "Error in finalize treewalk.";
|
|
|
|
} else {
|
|
|
|
// emit the treewalk results.
|
|
|
|
emit treeWalkResult(_syncedItems);
|
|
|
|
}
|
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
cleanup:
|
|
|
|
csync_destroy(csync);
|
2012-08-02 12:17:15 +04:00
|
|
|
|
2012-02-28 19:49:13 +04:00
|
|
|
qDebug() << "CSync run took " << t.elapsed() << " Milliseconds";
|
2012-08-26 13:47:45 +04:00
|
|
|
emit(finished());
|
2012-02-28 19:49:13 +04:00
|
|
|
}
|
|
|
|
|
2012-10-09 04:34:22 +04:00
|
|
|
void CSyncThread::setConnectionDetails( const QString &user, const QString &passwd, const QNetworkProxy &proxy )
|
2012-03-13 20:37:43 +04:00
|
|
|
{
|
2012-03-22 19:22:08 +04:00
|
|
|
_mutex.lock();
|
2012-03-13 20:37:43 +04:00
|
|
|
_user = user;
|
|
|
|
_passwd = passwd;
|
2012-10-09 04:34:22 +04:00
|
|
|
_proxy = proxy;
|
2012-03-22 19:22:08 +04:00
|
|
|
_mutex.unlock();
|
2012-03-13 20:37:43 +04:00
|
|
|
}
|
|
|
|
|
2012-04-30 10:56:56 +04:00
|
|
|
QString CSyncThread::csyncConfigDir()
|
|
|
|
{
|
|
|
|
return _csyncConfigDir;
|
|
|
|
}
|
|
|
|
|
2012-03-13 20:37:43 +04:00
|
|
|
int CSyncThread::getauth(const char *prompt,
|
|
|
|
char *buf,
|
|
|
|
size_t len,
|
|
|
|
int echo,
|
|
|
|
int verify,
|
|
|
|
void *userdata
|
|
|
|
)
|
|
|
|
{
|
2012-06-05 20:37:48 +04:00
|
|
|
int re = 0;
|
|
|
|
|
2012-12-13 22:52:07 +04:00
|
|
|
QString qPrompt = QString::fromLatin1( prompt ).trimmed();
|
2012-03-13 20:37:43 +04:00
|
|
|
|
2012-08-17 19:13:17 +04:00
|
|
|
if( qPrompt == QLatin1String("Enter your username:") ) {
|
2012-03-26 16:38:48 +04:00
|
|
|
// qDebug() << "OOO Username requested!";
|
2012-12-13 22:52:07 +04:00
|
|
|
QMutexLocker locker( &_mutex );
|
2012-06-13 13:29:38 +04:00
|
|
|
qstrncpy( buf, _user.toUtf8().constData(), len );
|
2012-08-17 19:13:17 +04:00
|
|
|
} else if( qPrompt == QLatin1String("Enter your password:") ) {
|
2012-12-13 22:52:07 +04:00
|
|
|
QMutexLocker locker( &_mutex );
|
2012-03-26 16:38:48 +04:00
|
|
|
// qDebug() << "OOO Password requested!";
|
2012-06-13 13:29:38 +04:00
|
|
|
qstrncpy( buf, _passwd.toUtf8().constData(), len );
|
2012-03-13 20:37:43 +04:00
|
|
|
} else {
|
2012-04-12 13:37:48 +04:00
|
|
|
if( qPrompt.startsWith( QLatin1String("There are problems with the SSL certificate:"))) {
|
|
|
|
// SSL is requested. If the program came here, the SSL check was done by mirall
|
2013-01-14 15:13:29 +04:00
|
|
|
// It needs to be checked if the chain is still equal to the one which
|
|
|
|
// was verified by the user.
|
2012-12-13 22:52:07 +04:00
|
|
|
QRegExp regexp("fingerprint: ([\\w\\d:]+)");
|
|
|
|
bool certOk = false;
|
|
|
|
|
2012-12-19 21:05:58 +04:00
|
|
|
int pos = 0;
|
2012-12-13 22:52:07 +04:00
|
|
|
|
2013-01-14 15:13:29 +04:00
|
|
|
// IF we had a cert ack'ed by the user, it was added to the Qt default
|
|
|
|
// CA Cert list. So we get the list of certs to check against from
|
|
|
|
// Qt.
|
|
|
|
QList<QSslCertificate> certs = QSslSocket::defaultCaCertificates();
|
|
|
|
Utility util; // to format a Fingerprint.
|
2012-12-13 22:52:07 +04:00
|
|
|
|
2012-12-19 21:05:58 +04:00
|
|
|
while (!certOk && (pos = regexp.indexIn(qPrompt, 1+pos)) != -1) {
|
|
|
|
QString neon_fingerprint = regexp.cap(1);
|
2012-12-13 22:52:07 +04:00
|
|
|
|
2012-12-14 00:36:44 +04:00
|
|
|
foreach( const QSslCertificate& c, certs ) {
|
2012-12-19 21:05:58 +04:00
|
|
|
QString verified_shasum = util.formatFingerprint(c.digest(QCryptographicHash::Sha1).toHex());
|
|
|
|
qDebug() << "SSL Fingerprint from neon: " << neon_fingerprint << " compared to verified: " << verified_shasum;
|
|
|
|
if( verified_shasum == neon_fingerprint ) {
|
2012-12-13 22:52:07 +04:00
|
|
|
certOk = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// certOk = false; DEBUG setting, keep disabled!
|
2012-12-19 21:05:58 +04:00
|
|
|
if( !certOk ) { // Problem!
|
2012-12-13 22:52:07 +04:00
|
|
|
qstrcpy( buf, "no" );
|
|
|
|
re = -1;
|
2012-12-19 21:05:58 +04:00
|
|
|
} else {
|
|
|
|
qstrcpy( buf, "yes" ); // Certificate is fine!
|
2012-12-13 22:52:07 +04:00
|
|
|
}
|
2012-04-12 13:37:48 +04:00
|
|
|
} else {
|
|
|
|
qDebug() << "Unknown prompt: <" << prompt << ">";
|
2012-06-05 20:37:48 +04:00
|
|
|
re = -1;
|
2012-04-12 13:37:48 +04:00
|
|
|
}
|
2012-03-13 20:37:43 +04:00
|
|
|
}
|
2012-06-05 20:37:48 +04:00
|
|
|
return re;
|
2012-03-13 20:37:43 +04:00
|
|
|
}
|
|
|
|
|
2012-12-11 15:49:48 +04:00
|
|
|
|
|
|
|
void CSyncThread::progress(const char *remote_url, enum csync_notify_type_e kind,
|
|
|
|
long long o1, long long o2, void *userdata)
|
|
|
|
{
|
|
|
|
(void) o1; (void) o2;
|
|
|
|
if (kind == CSYNC_NOTIFY_FINISHED_DOWNLOAD) {
|
2012-12-12 23:06:59 +04:00
|
|
|
QString path = QUrl::fromEncoded(remote_url).toString();
|
2012-12-11 15:49:48 +04:00
|
|
|
CSyncThread *thread = static_cast<CSyncThread*>(userdata);
|
|
|
|
thread->fileReceived(path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-15 12:30:37 +04:00
|
|
|
}
|