summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-31 03:32:16 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-31 03:32:16 +0000
commitca0636d7f48754c9b15af88c1e971ce8d1bde1a8 (patch)
tree2c1336abcbaff41f1d8c52d4181b10800acd7065
parent3768653a2aed91290e05dd3fd42d5af2006c7ed4 (diff)
downloadtdeaddons-ca0636d7f48754c9b15af88c1e971ce8d1bde1a8.tar.gz
tdeaddons-ca0636d7f48754c9b15af88c1e971ce8d1bde1a8.zip
Added Unison support to remote sync plugin
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeaddons@1109340 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
-rw-r--r--konq-plugins/rsync/rsyncconfigdialog.cpp6
-rw-r--r--konq-plugins/rsync/rsyncplugin.cpp173
-rw-r--r--konq-plugins/rsync/rsyncplugin.h7
3 files changed, 171 insertions, 15 deletions
diff --git a/konq-plugins/rsync/rsyncconfigdialog.cpp b/konq-plugins/rsync/rsyncconfigdialog.cpp
index b28a02c..0549356 100644
--- a/konq-plugins/rsync/rsyncconfigdialog.cpp
+++ b/konq-plugins/rsync/rsyncconfigdialog.cpp
@@ -134,14 +134,14 @@ RsyncConfigDialog::RsyncConfigDialog(QWidget* parent, const char* name,
// Insert radiobuttons
rsync_rb1 = new QRadioButton(i18n("&Utilize rsync + ssh for upload to remote server\nExample: servername:/path/to/remote/folder"), layoutg);
rsync_rb2 = new QRadioButton(i18n("&Utilize rsync + ssh for download from remote server\nExample: servername:/path/to/remote/folder"), layoutg);
- //rsync_rb3 = new QRadioButton(i18n("&Utilize rsync + ssh for synchronization with remote server\nExample: servername:/path/to/remote/folder"), layoutg);
+ rsync_rb3 = new QRadioButton(i18n("&Utilize unison + ssh for bidirectional synchronization with remote server\nExample: ssh://servername//path/to/remote/folder"), layoutg);
if (syncmode == 1)
rsync_rb1->setChecked( TRUE );
else if (syncmode == 2)
rsync_rb2->setChecked( TRUE );
- //else if (syncmode == 3)
- // rsync_rb3->setChecked( TRUE );
+ else if (syncmode == 3)
+ rsync_rb3->setChecked( TRUE );
//(void)new QRadioButton( "R&adiobutton 2", layoutg );
//(void)new QRadioButton( "Ra&diobutton 3", layoutg );
diff --git a/konq-plugins/rsync/rsyncplugin.cpp b/konq-plugins/rsync/rsyncplugin.cpp
index ebf7dd7..bc16a5a 100644
--- a/konq-plugins/rsync/rsyncplugin.cpp
+++ b/konq-plugins/rsync/rsyncplugin.cpp
@@ -292,7 +292,7 @@ bool RsyncPlugin::syncUnidirectional(QString synccommand, QString syncflags, int
if (FD_ISSET(childFd,&rfds)) {
rc = read(childFd,buf+offset,32768-offset);
if (rc > 0) {
- int noff = establishConnection(buf,rc+offset);
+ int noff = establishConnectionRsync(buf,rc+offset);
if (noff < 0) return false;
if (noff > 0) memmove(buf,buf+offset+rc-noff,noff);
offset = noff;
@@ -312,11 +312,16 @@ bool RsyncPlugin::syncUnidirectional(QString synccommand, QString syncflags, int
/**
creates the bidirectional sync subprocess
*/
-bool RsyncPlugin::syncBidirectional(QString localfolder, QString remotepath) {
+bool RsyncPlugin::syncBidirectional(QString synccommand, QString syncflags, int parameter_order, QString localfolder, QString remotepath) {
int fd[2];
int rc, flags;
thisFn = QString::null;
+ // Check for and remove the trailing slash in localfolder
+ if (localfolder.endsWith("/")) {
+ localfolder.remove(localfolder.length()-1, 1);
+ }
+
rc = open_pty_pair(fd);
if (rc == -1) {
myDebug( << "socketpair failed, error: " << strerror(errno) << endl);
@@ -335,8 +340,8 @@ bool RsyncPlugin::syncBidirectional(QString localfolder, QString remotepath) {
// Create the rsync command to run
QString execstring;
// FIXME
- //execstring = synccommand + syncflags + localfolder + QString("/ ") + remotepath;
- exit -1;
+ execstring = synccommand + syncflags + localfolder + QString(" ") + remotepath;
+ printf("Will execute %s\n\r", execstring.ascii());
// taken from konsole, see TEPty.C for details
// note: if we're running on socket pairs,
@@ -426,7 +431,7 @@ bool RsyncPlugin::syncBidirectional(QString localfolder, QString remotepath) {
if (FD_ISSET(childFd,&rfds)) {
rc = read(childFd,buf+offset,32768-offset);
if (rc > 0) {
- int noff = establishConnection(buf,rc+offset);
+ int noff = establishConnectionUnison(buf,rc+offset, localfolder, remotepath);
if (noff < 0) return false;
if (noff > 0) memmove(buf,buf+offset+rc-noff,noff);
offset = noff;
@@ -463,7 +468,7 @@ void RsyncPlugin::writeChild(const char *buf, KIO::fileoffset_t len) {
/**
manages initial communication setup including password queries
*/
-int RsyncPlugin::establishConnection(char *buffer, KIO::fileoffset_t len) {
+int RsyncPlugin::establishConnectionRsync(char *buffer, KIO::fileoffset_t len) {
QString buf;
buf.setLatin1(buffer,len);
int pos;
@@ -569,6 +574,143 @@ int RsyncPlugin::establishConnection(char *buffer, KIO::fileoffset_t len) {
}
/**
+manages initial communication setup including password queries
+*/
+int RsyncPlugin::establishConnectionUnison(char *buffer, KIO::fileoffset_t len, QString localfolder, QString remotepath) {
+ QString buf;
+ buf.setLatin1(buffer,len);
+ int pos;
+ // Strip trailing whitespace
+ while (buf.length() && (buf[buf.length()-1] == ' '))
+ buf.truncate(buf.length()-1);
+
+ myDebug( << "establishing: got " << buf << endl);
+ while (childPid && (((pos = buf.find('\n')) >= 0) || buf.endsWith(":") || buf.endsWith("?") || buf.endsWith("]"))) {
+ if (m_progressDialogExists == true) {
+ qApp->processEvents();
+ }
+ pos++;
+ QString str = buf.left(pos);
+ buf = buf.mid(pos);
+ if (str == "\n")
+ continue;
+ //if (str.contains("rsync error:")) {
+ if (str.contains("rsync:") || str.contains("failed.") || (str.contains("Could not") && str.endsWith("."))) {
+ KMessageBox::error(NULL, str);
+ }
+ else if (!str.isEmpty()) {
+ thisFn += str;
+ if ((buf.endsWith(":") == false) && (buf.endsWith("?") == false)) {
+ // Display a nice little progress bar with text box
+ if (m_progressDialogExists == false) {
+ m_progressDialog = new KProgressBoxDialog(0, "rsyncProgress", i18n("Synchronizing Folder..."), i18n("Synchronizing Folder..."), true);
+ m_progressDialog->progressBar()->setFormat("%v / %m");
+ m_progressDialog->progressBar()->setTotalSteps(0);
+ m_progressDialog->setAutoClose(true);
+ connect (m_progressDialog, SIGNAL(cancelClicked()), SLOT(slotUnisonCancelled()));
+ m_progressDialog->show();
+ m_progressDialogExists = true;
+ }
+ }
+ }
+ else if (buf.endsWith(":")) {
+ if (!redirectUser.isEmpty() && connectionUser != redirectUser) {
+ // FIXME: Possibly do something here; is this the success response?
+ return -1;
+ } else if (!connectionPassword.isEmpty()) {
+ myDebug( << "sending cpass" << endl);
+ connectionAuth.password = connectionPassword+"\n";
+ connectionPassword = QString::null;
+ writeChild(connectionAuth.password.latin1(),connectionAuth.password.length());
+ } else {
+ myDebug( << "sending mpass" << endl);
+ connectionAuth.prompt = thisFn+buf;
+ connectionAuth.password = QString::null; // don't prefill
+ QCString thispass;
+ if (KPasswordDialog::getPassword (thispass, i18n("Remote authorization required") + QString("\n") + i18n("Please input") + QString(" ") + QString(buf), NULL) != 1) {
+ slotUnisonCancelled();
+ return -1;
+ }
+ else {
+ connectionAuth.password = QString(thispass);
+ }
+ connectionAuth.password += "\n";
+ myDebug( << "sending pass" << endl);
+ writeChild(connectionAuth.password.latin1(),connectionAuth.password.length());
+ }
+ thisFn = QString::null;
+ return 0;
+ }
+ else if (buf.endsWith("?") || buf.endsWith("? []")) {
+ buf.replace("[]", "");
+ if (buf.endsWith("? []")) {
+ int rc = KMessageBox::questionYesNo(NULL, buf);
+ if (rc == KMessageBox::Yes) {
+ writeChild("y\n",3);
+ } else {
+ writeChild("n\n",3);
+ }
+ }
+ else {
+ int rc = KMessageBox::questionYesNo(NULL, buf);
+ if (rc == KMessageBox::Yes) {
+ writeChild("yes\n",4);
+ } else {
+ writeChild("no\n",3);
+ }
+ }
+ thisFn = QString::null;
+ buf = "";
+ return 0;
+ }
+ else if (buf.endsWith("]")) {
+ if (m_progressDialogExists == true) {
+ m_progressDialog->textEdit()->append(buf);
+ m_progressDialog->textEdit()->scrollToBottom();
+ int currentPos;
+ currentPos = m_progressDialog->progressBar()->progress();
+ m_progressDialog->progressBar()->setProgress(++currentPos);
+ }
+ QString file_name;
+ file_name = buf;
+ file_name.replace("[]", "");
+ file_name.replace(QString("changed "), "");
+ //file_name = file_name.simplifyWhiteSpace();
+ KDialogBase *dialog= new KDialogBase(i18n("User Intervention Required"), KDialogBase::Yes | KDialogBase::No | KDialogBase::Cancel, KDialogBase::Yes, KDialogBase::Cancel, NULL, "warningYesNoCancel", true, true, i18n("Use &Local File"), i18n("Use &Remote File"), i18n("&Ignore"));
+ int rc = KMessageBox::createKMessageBox(dialog, QMessageBox::Warning, QString("<b>") + i18n("WARNING: Both the local and remote file have been modified") + QString("</b><p>") + i18n("Local") + QString(": ") + localfolder + QString("/") + file_name + QString("<br>") + i18n("Remote") + QString(": ") + remotepath + QString("/") + file_name + QString("<p>") + i18n("Please select the file to duplicate (the other will be overwritten)") + QString("<br>") + i18n("Or, select Ignore to skip synchronization of this file for now"), QStringList(), QString::null, NULL, 1);
+ if (rc == KDialogBase::Yes) {
+ writeChild(">\n",3);
+ }
+ else if (rc == KDialogBase::No) {
+ writeChild("<\n",3);
+ }
+ else {
+ writeChild("/\n",3);
+ }
+ return 0;
+ }
+
+ if (m_progressDialogExists == true) {
+ if (str.contains("exit()") && str.contains("ICE default IO")) {
+ if (m_progressDialogExists == true) {
+ m_progressDialog->progressBar()->setFormat("%v / %m");
+ m_progressDialog->progressBar()->setTotalSteps(2);
+ m_progressDialog->progressBar()->setValue(m_progressDialog->progressBar()->totalSteps());
+ }
+ }
+ else {
+ m_progressDialog->textEdit()->append(str);
+ m_progressDialog->textEdit()->scrollToBottom();
+ int currentPos;
+ currentPos = m_progressDialog->progressBar()->progress();
+ m_progressDialog->progressBar()->setProgress(++currentPos);
+ }
+ }
+ }
+ return buf.length();
+}
+
+/**
Forced close of the connection
This function gets called from the application side of the universe,
@@ -879,6 +1021,17 @@ void RsyncPlugin::slotRsyncCancelled()
m_pSyncNow->setEnabled (true);
}
+void RsyncPlugin::slotUnisonCancelled()
+{
+ shutdownConnection(true, true);
+ if (m_progressDialogExists == true) {
+ m_progressDialog->progressBar()->setFormat("%v / %m");
+ m_progressDialog->progressBar()->setTotalSteps(2);
+ m_progressDialog->progressBar()->setValue(m_progressDialog->progressBar()->totalSteps());
+ }
+ m_pSyncNow->setEnabled (true);
+}
+
void RsyncPlugin::slotSync()
{
if (!m_part)
@@ -899,10 +1052,10 @@ void RsyncPlugin::slotSync()
else if (syncmethod == "rsync_download") {
syncUnidirectional(QString("rsync"), QString(" -avtzAXE --delete --progress "), 1, url.directory(true, true) + QString("/") + url.fileName(true), findLocalFolderByName(url.directory(true, true) + QString("/") + url.fileName(true)));
}
-// else if (syncmethod == "rsync_bidirectional") {
-// syncint = 3;
-// }
-
+ else if (syncmethod == "rsync_bidirectional") {
+ syncBidirectional(QString("unison"), QString(" -ui text -auto "), 1, url.directory(true, true) + QString("/") + url.fileName(true), findLocalFolderByName(url.directory(true, true) + QString("/") + url.fileName(true)));
+ }
+
m_progressDialogExists = false;
m_pSyncNow->setEnabled (true);
}
diff --git a/konq-plugins/rsync/rsyncplugin.h b/konq-plugins/rsync/rsyncplugin.h
index 4deb2b3..86aa17f 100644
--- a/konq-plugins/rsync/rsyncplugin.h
+++ b/konq-plugins/rsync/rsyncplugin.h
@@ -65,11 +65,13 @@ protected:
int addLocalFolderByName(QString folderurl, QString remoteurl, QString syncmethod, QString excludelist);
QString findSyncMethodByName(QString folderurl);
/** manages initial communication setup including password queries */
- int establishConnection(char *buffer, KIO::fileoffset_t len);
+ int establishConnectionRsync(char *buffer, KIO::fileoffset_t len);
+ /** manages initial communication setup including password queries */
+ int establishConnectionUnison(char *buffer, KIO::fileoffset_t len, QString localfolder, QString remotepath);
/** creates the unidirectional sync subprocess */
bool syncUnidirectional(QString synccommand, QString syncflags, int parameter_order, QString localfolder, QString remotepath);
/** creates the bidirectional sync subprocess */
- bool syncBidirectional(QString localfolder, QString remotepath);
+ bool syncBidirectional(QString synccommand, QString syncflags, int parameter_order, QString localfolder, QString remotepath);
/** writes one chunk of data to stdin of child process */
void writeChild(const char *buf, KIO::fileoffset_t len);
/** AuthInfo object used for logging in */
@@ -89,6 +91,7 @@ private slots:
void slotSetupOK();
void slotSetupCancelled();
void slotRsyncCancelled();
+ void slotUnisonCancelled();
private:
KURL m_pURL;