File indexing completed on 2024-05-05 05:44:48

0001 /***************************************************************************
0002  *   Copyright (C) 2005-2009 by Rajko Albrecht                             *
0003  *   ral@alwins-world.de                                                   *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0019  ***************************************************************************/
0020 #include "kiolistener.h"
0021 #include "helpers/kdesvn_debug.h"
0022 #include "kdesvndinterface.h"
0023 #include "kio_macros.h"
0024 #include "kiosvn.h"
0025 
0026 #include <klocalizedstring.h>
0027 
0028 namespace KIO
0029 {
0030 
0031 KioListener::KioListener(KIO::kio_svnProtocol *_par)
0032     : svn::ContextListener()
0033     , m_notifyCounter(0)
0034     , m_External(false)
0035     , m_HasChanges(false)
0036     , m_FirstTxDelta(false)
0037     , m_Canceld(false)
0038 {
0039     par = _par;
0040 }
0041 
0042 KioListener::~KioListener()
0043 {
0044 }
0045 
0046 /*!
0047     \fn KioListener::contextCancel()
0048  */
0049 bool KioListener::contextCancel()
0050 {
0051     return par->wasKilled() || m_Canceld;
0052 }
0053 
0054 /*!
0055     \fn KioListener::contextGetLogMessage (QString & msg)
0056  */
0057 bool KioListener::contextGetLogMessage(QString &msg, const svn::CommitItemList &_items)
0058 {
0059     Q_UNUSED(_items);
0060     CON_DBUS_VAL(false);
0061 
0062     QDBusReply<QStringList> res = kdesvndInterface.get_logmsg();
0063 
0064     if (!res.isValid()) {
0065         qWarning() << "Didn't get a valid reply!" << Qt::endl;
0066         return false;
0067     }
0068     QStringList lt = res.value();
0069 
0070     if (lt.count() != 1) {
0071         msg = i18n("Wrong or missing log (may cancel pressed).");
0072         qCDebug(KDESVN_LOG) << msg << Qt::endl;
0073         return false;
0074     }
0075     msg = lt[0];
0076 
0077     return true;
0078 }
0079 
0080 /*! the content of that method is taken from the notify in kio::svn in KDE SDK */
0081 /* this moment we don't use it full 'cause not all is made via KIO */
0082 void KioListener::contextNotify(const char *_path,
0083                                 svn_wc_notify_action_t action,
0084                                 svn_node_kind_t kind,
0085                                 const char *mime_type,
0086                                 svn_wc_notify_state_t content_state,
0087                                 svn_wc_notify_state_t prop_state,
0088                                 svn_revnum_t revision)
0089 {
0090     if (par->wasKilled()) {
0091         return;
0092     }
0093     if (par->checkKioCancel()) {
0094         m_Canceld = true;
0095     }
0096     QString userstring;
0097     const QString path(_path ? QString::fromUtf8(_path) : QString());
0098 
0099     switch (action) {
0100     case svn_wc_notify_add: {
0101         if (mime_type && (svn_mime_type_is_binary(mime_type))) {
0102             userstring = i18n("A (bin) %1", path);
0103         } else {
0104             userstring = i18n("A %1", path);
0105         }
0106         break;
0107     } break;
0108     case svn_wc_notify_copy: // copy
0109         break;
0110     case svn_wc_notify_delete: // delete
0111         m_HasChanges = true;
0112         userstring = i18n("D %1", path);
0113         break;
0114     case svn_wc_notify_restore: // restore
0115         userstring = i18n("Restored %1.", path);
0116         break;
0117     case svn_wc_notify_revert: // revert
0118         userstring = i18n("Reverted %1.", path);
0119         break;
0120     case svn_wc_notify_failed_revert: // failed revert
0121         userstring = i18n("Failed to revert %1.\nTry updating instead.", path);
0122         break;
0123     case svn_wc_notify_resolved: // resolved
0124         userstring = i18n("Resolved conflicted state of %1.", path);
0125         break;
0126     case svn_wc_notify_skip: // skip
0127         if (content_state == svn_wc_notify_state_missing) {
0128             userstring = i18n("Skipped missing target %1.", path);
0129         } else {
0130             userstring = i18n("Skipped %1.", path);
0131         }
0132         break;
0133     case svn_wc_notify_update_delete: // update_delete
0134         m_HasChanges = true;
0135         userstring = i18n("D %1", path);
0136         break;
0137     case svn_wc_notify_update_add: // update_add
0138         m_HasChanges = true;
0139         userstring = i18n("A %1", path);
0140         break;
0141     case svn_wc_notify_update_update: { // update_update
0142         /* If this is an inoperative dir change, do no notification.
0143            An inoperative dir change is when a directory gets closed
0144            without any props having been changed. */
0145         if (!((kind == svn_node_dir)
0146               && ((prop_state == svn_wc_notify_state_inapplicable) || (prop_state == svn_wc_notify_state_unknown)
0147                   || (prop_state == svn_wc_notify_state_unchanged)))) {
0148             m_HasChanges = true;
0149 
0150             if (kind == svn_node_file) {
0151                 if (content_state == svn_wc_notify_state_conflicted) {
0152                     userstring = QLatin1Char('C');
0153                 } else if (content_state == svn_wc_notify_state_merged) {
0154                     userstring = QLatin1Char('G');
0155                 } else if (content_state == svn_wc_notify_state_changed) {
0156                     userstring = QLatin1Char('U');
0157                 }
0158             }
0159 
0160             if (prop_state == svn_wc_notify_state_conflicted) {
0161                 userstring += QLatin1Char('C');
0162             } else if (prop_state == svn_wc_notify_state_merged) {
0163                 userstring += QLatin1Char('G');
0164             } else if (prop_state == svn_wc_notify_state_changed) {
0165                 userstring += QLatin1Char('U');
0166             } else {
0167                 userstring += QLatin1Char(' ');
0168             }
0169 
0170             if (!((content_state == svn_wc_notify_state_unchanged || content_state == svn_wc_notify_state_unknown)
0171                   && (prop_state == svn_wc_notify_state_unchanged || prop_state == svn_wc_notify_state_unknown))) {
0172                 userstring += QLatin1Char(' ') + path;
0173             }
0174         }
0175         break;
0176     }
0177     case svn_wc_notify_update_completed: { // update_completed
0178         if (!m_External) {
0179             if (SVN_IS_VALID_REVNUM(revision)) {
0180                 userstring = i18n("Finished at revision %1.", revision);
0181             } else {
0182                 userstring = i18n("Update finished.");
0183             }
0184         } else {
0185             if (SVN_IS_VALID_REVNUM(revision)) {
0186                 userstring = i18n("Finished external at revision %1.", revision);
0187             } else {
0188                 userstring = i18n("Finished external.");
0189             }
0190         }
0191     }
0192         if (m_External) {
0193             m_External = false;
0194         }
0195         break;
0196     case svn_wc_notify_update_external: // update_external
0197         m_External = true;
0198         userstring = i18n("Fetching external item into %1.", path);
0199         break;
0200     case svn_wc_notify_status_completed: // status_completed
0201         if (SVN_IS_VALID_REVNUM(revision)) {
0202             userstring = i18n("Status against revision: %1.", revision);
0203         }
0204         break;
0205     case svn_wc_notify_status_external: // status_external
0206         userstring = i18n("Performing status on external item at %1.", path);
0207         break;
0208     case svn_wc_notify_commit_modified: // commit_modified
0209         userstring = i18n("Sending %1.", path);
0210         break;
0211     case svn_wc_notify_commit_added: // commit_added
0212         if (mime_type && svn_mime_type_is_binary(mime_type)) {
0213             userstring = i18n("Adding (bin) %1.", path);
0214         } else {
0215             userstring = i18n("Adding %1.", path);
0216         }
0217         break;
0218     case svn_wc_notify_commit_deleted: // commit_deleted
0219         userstring = i18n("Deleting %1.", path);
0220         break;
0221     case svn_wc_notify_commit_replaced: // commit_replaced
0222         userstring = i18n("Replacing %1.", path);
0223         break;
0224     case svn_wc_notify_commit_postfix_txdelta: // commit_postfix_txdelta
0225         if (!m_FirstTxDelta) {
0226             m_FirstTxDelta = true;
0227             // check fullstops!
0228             userstring = i18n("Transmitting file data ");
0229         } else {
0230             userstring = QLatin1Char('.');
0231         }
0232         break;
0233     case svn_wc_notify_blame_revision: // blame_revision
0234         break;
0235     default:
0236         break;
0237     }
0238     const QString num(QString::number(counter()).rightJustified(10, QLatin1Char('0')));
0239     par->setMetaData(num + QStringLiteral("path"), path);
0240     par->setMetaData(num + QStringLiteral("action"), QString::number(action));
0241     par->setMetaData(num + QStringLiteral("kind"), QString::number(kind));
0242     par->setMetaData(num + QStringLiteral("mime_t"), QString::fromUtf8(mime_type));
0243     par->setMetaData(num + QStringLiteral("content"), QString::number(content_state));
0244     par->setMetaData(num + QStringLiteral("prop"), QString::number(prop_state));
0245     par->setMetaData(num + QStringLiteral("rev"), QString::number(revision));
0246     par->setMetaData(num + QStringLiteral("string"), userstring);
0247     incCounter();
0248 }
0249 
0250 void KioListener::contextNotify(const svn_wc_notify_t *action)
0251 {
0252     if (!action) {
0253         return;
0254     }
0255     //    if (action->action<svn_wc_notify_locked) {
0256     contextNotify(action->path, action->action, action->kind, action->mime_type, action->content_state, action->prop_state, action->revision);
0257     //        return;
0258     //    }
0259     //    QString aString = NotifyAction(action->action);
0260 }
0261 
0262 svn::ContextListener::SslServerTrustAnswer KioListener::contextSslServerTrustPrompt(const SslServerTrustData &data, apr_uint32_t &acceptedFailures)
0263 {
0264     Q_UNUSED(acceptedFailures);
0265     QDBusReply<int> res;
0266 
0267     CON_DBUS_VAL(DONT_ACCEPT);
0268     res = kdesvndInterface.get_sslaccept(data.hostname, data.fingerprint, data.validFrom, data.validUntil, data.issuerDName, data.realm);
0269 
0270     if (!res.isValid()) {
0271         qWarning() << "Unexpected reply type";
0272         return DONT_ACCEPT;
0273     }
0274 
0275     switch (res.value()) {
0276     case -1:
0277         return DONT_ACCEPT;
0278         break;
0279     case 1:
0280         return ACCEPT_PERMANENTLY;
0281         break;
0282     default:
0283     case 0:
0284         return ACCEPT_TEMPORARILY;
0285         break;
0286     }
0287     /* avoid compiler warnings */
0288     return ACCEPT_TEMPORARILY;
0289 }
0290 
0291 bool KioListener::contextLoadSslClientCertPw(QString &password, const QString &realm)
0292 {
0293     QDBusReply<QString> res;
0294 
0295     CON_DBUS_VAL(false);
0296     res = kdesvndInterface.load_sslclientcertpw(realm);
0297     if (!res.isValid()) {
0298         qWarning() << "Unexpected reply type";
0299         return false;
0300     }
0301     password = res.value();
0302     return true;
0303 }
0304 
0305 bool KioListener::contextSslClientCertPrompt(QString &certFile)
0306 {
0307     QDBusReply<QString> res;
0308 
0309     CON_DBUS_VAL(false);
0310     res = kdesvndInterface.get_sslclientcertfile();
0311     if (!res.isValid()) {
0312         qWarning() << "Unexpected reply type";
0313         return false;
0314     }
0315     certFile = res.value();
0316     if (certFile.isEmpty()) {
0317         return false;
0318     }
0319     return true;
0320 }
0321 
0322 bool KioListener::contextSslClientCertPwPrompt(QString &password, const QString &realm, bool &maySave)
0323 {
0324     Q_UNUSED(password);
0325     Q_UNUSED(realm);
0326     Q_UNUSED(maySave);
0327     return false;
0328 }
0329 
0330 bool KioListener::contextGetSavedLogin(const QString &realm, QString &username, QString &password)
0331 {
0332     QDBusReply<QStringList> res;
0333 
0334     CON_DBUS_VAL(false);
0335     res = kdesvndInterface.get_saved_login(realm, username);
0336     if (!res.isValid()) {
0337         qWarning() << "Unexpected reply type";
0338         return false;
0339     }
0340     QStringList lt = res.value();
0341     if (lt.count() != 2) {
0342         qCDebug(KDESVN_LOG) << "Wrong or missing auth list." << Qt::endl;
0343         return false;
0344     }
0345     username = lt[0];
0346     password = lt[1];
0347     return true;
0348 }
0349 
0350 bool KioListener::contextGetCachedLogin(const QString &realm, QString &username, QString &password)
0351 {
0352     Q_UNUSED(realm);
0353     Q_UNUSED(username);
0354     Q_UNUSED(password);
0355     return true;
0356 }
0357 
0358 bool KioListener::contextGetLogin(const QString &realm, QString &username, QString &password, bool &maySave)
0359 {
0360     QDBusReply<QStringList> res;
0361 
0362     CON_DBUS_VAL(false);
0363     res = kdesvndInterface.get_login(realm, username);
0364     if (!res.isValid()) {
0365         qWarning() << "Unexpected reply type";
0366         return false;
0367     }
0368     QStringList lt = res.value();
0369     if (lt.count() != 3) {
0370         qCDebug(KDESVN_LOG) << "Wrong or missing auth list (may cancel pressed)." << Qt::endl;
0371         return false;
0372     }
0373     username = lt[0];
0374     password = lt[1];
0375     maySave = lt[2] == QLatin1String("true");
0376     return true;
0377 }
0378 
0379 bool KioListener::contextAddListItem(svn::DirEntries *entries, const svn_dirent_t *dirent, const svn_lock_t *lock, const QString &path)
0380 {
0381     Q_UNUSED(entries);
0382     if (!dirent || path.isEmpty()) {
0383         // the path itself? is a problem within kio
0384         return false;
0385     }
0386     if (par) {
0387         if (par->checkKioCancel()) {
0388             m_Canceld = true;
0389         }
0390         par->listSendDirEntry(svn::DirEntry(path, dirent, lock));
0391         return true;
0392     }
0393     return false;
0394 }
0395 
0396 /*!
0397     \fn KioListener::contextProgress(long long int current, long long int max)
0398  */
0399 void KioListener::contextProgress(long long int cur, long long int max)
0400 {
0401     if (par) {
0402         if (par->checkKioCancel()) {
0403             m_Canceld = true;
0404         }
0405         par->contextProgress(cur, max);
0406     }
0407 }
0408 
0409 } // namespace KIO