1 /***************************************************************************
2 * Copyright (C) 2005-2009 by Rajko Albrecht *
3 * ral@alwins-world.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
20 #include "kiolistener.h"
21 #include "kiosvn.h"
22 #include "kdesvndinterface.h"
23 #include "kio_macros.h"
24 #include "helpers/kdesvn_debug.h"
25
26 #include <klocalizedstring.h>
27
28 namespace KIO
29 {
30
KioListener(KIO::kio_svnProtocol * _par)31 KioListener::KioListener(KIO::kio_svnProtocol *_par)
32 : svn::ContextListener(), m_notifyCounter(0), m_External(false), m_HasChanges(false), m_FirstTxDelta(false), m_Canceld(false)
33 {
34 par = _par;
35 }
36
~KioListener()37 KioListener::~KioListener()
38 {
39 }
40
41 /*!
42 \fn KioListener::contextCancel()
43 */
contextCancel()44 bool KioListener::contextCancel()
45 {
46 return par->wasKilled() || m_Canceld;
47 }
48
49 /*!
50 \fn KioListener::contextGetLogMessage (QString & msg)
51 */
contextGetLogMessage(QString & msg,const svn::CommitItemList & _items)52 bool KioListener::contextGetLogMessage(QString &msg, const svn::CommitItemList &_items)
53 {
54 Q_UNUSED(_items);
55 CON_DBUS_VAL(false);
56
57 QDBusReply<QStringList> res = kdesvndInterface.get_logmsg();
58
59 if (!res.isValid()) {
60 qWarning() << "Didn't get a valid reply!" << endl;
61 return false;
62 }
63 QStringList lt = res.value();
64
65 if (lt.count() != 1) {
66 msg = i18n("Wrong or missing log (may cancel pressed).");
67 qCDebug(KDESVN_LOG) << msg << endl;
68 return false;
69 }
70 msg = lt[0];
71
72 return true;
73 }
74
75 /*! the content of that method is taken from the notify in kio::svn in KDE SDK */
76 /* this moment we don't use it full 'cause not all is made via KIO */
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)77 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)
78 {
79 if (par->wasKilled()) {
80 return;
81 }
82 if (par->checkKioCancel()) {
83 m_Canceld = true;
84 }
85 QString userstring;
86 const QString path(_path ? QString::fromUtf8(_path) : QString());
87
88 switch (action) {
89 case svn_wc_notify_add: {
90 if (mime_type && (svn_mime_type_is_binary(mime_type))) {
91 userstring = i18n("A (bin) %1", path);
92 } else {
93 userstring = i18n("A %1", path);
94 }
95 break;
96 }
97 break;
98 case svn_wc_notify_copy: //copy
99 break;
100 case svn_wc_notify_delete: //delete
101 m_HasChanges = true;
102 userstring = i18n("D %1", path);
103 break;
104 case svn_wc_notify_restore : //restore
105 userstring = i18n("Restored %1.", path);
106 break;
107 case svn_wc_notify_revert : //revert
108 userstring = i18n("Reverted %1.", path);
109 break;
110 case svn_wc_notify_failed_revert: //failed revert
111 userstring = i18n("Failed to revert %1.\nTry updating instead.", path);
112 break;
113 case svn_wc_notify_resolved: //resolved
114 userstring = i18n("Resolved conflicted state of %1.", path);
115 break;
116 case svn_wc_notify_skip: //skip
117 if (content_state == svn_wc_notify_state_missing) {
118 userstring = i18n("Skipped missing target %1.", path);
119 } else {
120 userstring = i18n("Skipped %1.", path);
121 }
122 break;
123 case svn_wc_notify_update_delete: //update_delete
124 m_HasChanges = true;
125 userstring = i18n("D %1", path);
126 break;
127 case svn_wc_notify_update_add: //update_add
128 m_HasChanges = true;
129 userstring = i18n("A %1", path);
130 break;
131 case svn_wc_notify_update_update: { //update_update
132 /* If this is an inoperative dir change, do no notification.
133 An inoperative dir change is when a directory gets closed
134 without any props having been changed. */
135 if (!((kind == svn_node_dir)
136 && ((prop_state == svn_wc_notify_state_inapplicable)
137 || (prop_state == svn_wc_notify_state_unknown)
138 || (prop_state == svn_wc_notify_state_unchanged)))) {
139 m_HasChanges = true;
140
141 if (kind == svn_node_file) {
142 if (content_state == svn_wc_notify_state_conflicted) {
143 userstring = QLatin1Char('C');
144 } else if (content_state == svn_wc_notify_state_merged) {
145 userstring = QLatin1Char('G');
146 } else if (content_state == svn_wc_notify_state_changed) {
147 userstring = QLatin1Char('U');
148 }
149 }
150
151 if (prop_state == svn_wc_notify_state_conflicted) {
152 userstring += QLatin1Char('C');
153 } else if (prop_state == svn_wc_notify_state_merged) {
154 userstring += QLatin1Char('G');
155 } else if (prop_state == svn_wc_notify_state_changed) {
156 userstring += QLatin1Char('U');
157 } else {
158 userstring += QLatin1Char(' ');
159 }
160
161 if (!((content_state == svn_wc_notify_state_unchanged
162 || content_state == svn_wc_notify_state_unknown)
163 && (prop_state == svn_wc_notify_state_unchanged
164 || prop_state == svn_wc_notify_state_unknown))) {
165 userstring += QLatin1Char(' ') + path;
166 }
167 }
168 break;
169 }
170 case svn_wc_notify_update_completed: { //update_completed
171 if (!m_External) {
172 if (SVN_IS_VALID_REVNUM(revision)) {
173 userstring = i18n("Finished at revision %1.", revision);
174 } else {
175 userstring = i18n("Update finished.");
176 }
177 } else {
178 if (SVN_IS_VALID_REVNUM(revision)) {
179 userstring = i18n("Finished external at revision %1.", revision);
180 } else {
181 userstring = i18n("Finished external.");
182 }
183 }
184 }
185 if (m_External) {
186 m_External = false;
187 }
188 break;
189 case svn_wc_notify_update_external: //update_external
190 m_External = true;
191 userstring = i18n("Fetching external item into %1.", path);
192 break;
193 case svn_wc_notify_status_completed: //status_completed
194 if (SVN_IS_VALID_REVNUM(revision)) {
195 userstring = i18n("Status against revision: %1.", revision);
196 }
197 break;
198 case svn_wc_notify_status_external: //status_external
199 userstring = i18n("Performing status on external item at %1.", path);
200 break;
201 case svn_wc_notify_commit_modified: //commit_modified
202 userstring = i18n("Sending %1.", path);
203 break;
204 case svn_wc_notify_commit_added: //commit_added
205 if (mime_type && svn_mime_type_is_binary(mime_type)) {
206 userstring = i18n("Adding (bin) %1.", path);
207 } else {
208 userstring = i18n("Adding %1.", path);
209 }
210 break;
211 case svn_wc_notify_commit_deleted: //commit_deleted
212 userstring = i18n("Deleting %1.", path);
213 break;
214 case svn_wc_notify_commit_replaced: //commit_replaced
215 userstring = i18n("Replacing %1.", path);
216 break;
217 case svn_wc_notify_commit_postfix_txdelta: //commit_postfix_txdelta
218 if (!m_FirstTxDelta) {
219 m_FirstTxDelta = true;
220 // check fullstops!
221 userstring = i18n("Transmitting file data ");
222 } else {
223 userstring = QLatin1Char('.');
224 }
225 break;
226 case svn_wc_notify_blame_revision: //blame_revision
227 break;
228 default:
229 break;
230 }
231 const QString num(QString::number(counter()).rightJustified(10, QLatin1Char('0')));
232 par->setMetaData(num + QStringLiteral("path"), path);
233 par->setMetaData(num + QStringLiteral("action"), QString::number(action));
234 par->setMetaData(num + QStringLiteral("kind"), QString::number(kind));
235 par->setMetaData(num + QStringLiteral("mime_t"), QString::fromUtf8(mime_type));
236 par->setMetaData(num + QStringLiteral("content"), QString::number(content_state));
237 par->setMetaData(num + QStringLiteral("prop"), QString::number(prop_state));
238 par->setMetaData(num + QStringLiteral("rev"), QString::number(revision));
239 par->setMetaData(num + QStringLiteral("string"), userstring);
240 incCounter();
241 }
242
contextNotify(const svn_wc_notify_t * action)243 void KioListener::contextNotify(const svn_wc_notify_t *action)
244 {
245 if (!action) {
246 return;
247 }
248 // if (action->action<svn_wc_notify_locked) {
249 contextNotify(action->path, action->action, action->kind, action->mime_type,
250 action->content_state, action->prop_state, action->revision);
251 // return;
252 // }
253 // QString aString = NotifyAction(action->action);
254 }
255
256 svn::ContextListener::SslServerTrustAnswer
contextSslServerTrustPrompt(const SslServerTrustData & data,apr_uint32_t & acceptedFailures)257 KioListener::contextSslServerTrustPrompt(const SslServerTrustData &data, apr_uint32_t &acceptedFailures)
258 {
259 Q_UNUSED(acceptedFailures);
260 QDBusReply<int> res;
261
262 CON_DBUS_VAL(DONT_ACCEPT);
263 res = kdesvndInterface.get_sslaccept(data.hostname,
264 data.fingerprint, data.validFrom, data.validUntil, data.issuerDName, data.realm);
265
266 if (!res.isValid()) {
267 qWarning() << "Unexpected reply type";
268 return DONT_ACCEPT;
269 }
270
271 switch (res.value()) {
272 case -1:
273 return DONT_ACCEPT;
274 break;
275 case 1:
276 return ACCEPT_PERMANENTLY;
277 break;
278 default:
279 case 0:
280 return ACCEPT_TEMPORARILY;
281 break;
282 }
283 /* avoid compiler warnings */
284 return ACCEPT_TEMPORARILY;
285 }
286
contextLoadSslClientCertPw(QString & password,const QString & realm)287 bool KioListener::contextLoadSslClientCertPw(QString &password, const QString &realm)
288 {
289 QDBusReply<QString> res;
290
291 CON_DBUS_VAL(false);
292 res = kdesvndInterface.load_sslclientcertpw(realm);
293 if (!res.isValid()) {
294 qWarning() << "Unexpected reply type";
295 return false;
296 }
297 password = res.value();
298 return true;
299 }
300
contextSslClientCertPrompt(QString & certFile)301 bool KioListener::contextSslClientCertPrompt(QString &certFile)
302 {
303 QDBusReply<QString> res;
304
305 CON_DBUS_VAL(false);
306 res = kdesvndInterface.get_sslclientcertfile();
307 if (!res.isValid()) {
308 qWarning() << "Unexpected reply type";
309 return false;
310 }
311 certFile = res.value();
312 if (certFile.isEmpty()) {
313 return false;
314 }
315 return true;
316 }
317
contextSslClientCertPwPrompt(QString & password,const QString & realm,bool & maySave)318 bool KioListener::contextSslClientCertPwPrompt(QString &password,
319 const QString &realm, bool &maySave)
320 {
321 Q_UNUSED(password);
322 Q_UNUSED(realm);
323 Q_UNUSED(maySave);
324 return false;
325 }
326
contextGetSavedLogin(const QString & realm,QString & username,QString & password)327 bool KioListener::contextGetSavedLogin(const QString &realm, QString &username, QString &password)
328 {
329 QDBusReply<QStringList> res;
330
331 CON_DBUS_VAL(false);
332 res = kdesvndInterface.get_saved_login(realm, username);
333 if (!res.isValid()) {
334 qWarning() << "Unexpected reply type";
335 return false;
336 }
337 QStringList lt = res.value();
338 if (lt.count() != 2) {
339 qCDebug(KDESVN_LOG) << "Wrong or missing auth list." << endl;
340 return false;
341 }
342 username = lt[0];
343 password = lt[1];
344 return true;
345 }
346
contextGetCachedLogin(const QString & realm,QString & username,QString & password)347 bool KioListener::contextGetCachedLogin(const QString &realm, QString &username, QString &password)
348 {
349 Q_UNUSED(realm);
350 Q_UNUSED(username);
351 Q_UNUSED(password);
352 return true;
353 }
354
contextGetLogin(const QString & realm,QString & username,QString & password,bool & maySave)355 bool KioListener::contextGetLogin(const QString &realm, QString &username, QString &password, bool &maySave)
356 {
357 QDBusReply<QStringList> res;
358
359 CON_DBUS_VAL(false);
360 res = kdesvndInterface.get_login(realm, username);
361 if (!res.isValid()) {
362 qWarning() << "Unexpected reply type";
363 return false;
364 }
365 QStringList lt = res.value();
366 if (lt.count() != 3) {
367 qCDebug(KDESVN_LOG) << "Wrong or missing auth list (may cancel pressed)." << endl;
368 return false;
369 }
370 username = lt[0];
371 password = lt[1];
372 maySave = lt[2] == QLatin1String("true");
373 return true;
374 }
375
contextAddListItem(svn::DirEntries * entries,const svn_dirent_t * dirent,const svn_lock_t * lock,const QString & path)376 bool KioListener::contextAddListItem(svn::DirEntries *entries, const svn_dirent_t *dirent, const svn_lock_t *lock, const QString &path)
377 {
378 Q_UNUSED(entries);
379 if (!dirent || path.isEmpty()) {
380 // the path itself? is a problem within kio
381 return false;
382 }
383 if (par) {
384 if (par->checkKioCancel()) {
385 m_Canceld = true;
386 }
387 par->listSendDirEntry(svn::DirEntry(path, dirent, lock));
388 return true;
389 }
390 return false;
391 }
392
393 /*!
394 \fn KioListener::contextProgress(long long int current, long long int max)
395 */
contextProgress(long long int cur,long long int max)396 void KioListener::contextProgress(long long int cur, long long int max)
397 {
398 if (par) {
399 if (par->checkKioCancel()) {
400 m_Canceld = true;
401 }
402 par->contextProgress(cur, max);
403 }
404 }
405
406 } // namespace KIO
407