File indexing completed on 2024-05-12 17:16:00

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