File indexing completed on 2024-05-12 17:16:23
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 * 0006 * modify it under the terms of the GNU Lesser General Public * 0007 * License as published by the Free Software Foundation; either * 0008 * version 2.1 of the License, or (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 GNU * 0013 * Lesser General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU Lesser General Public * 0016 * License along with this program (in the file LGPL.txt); if not, * 0017 * write to the Free Software Foundation, Inc., 51 Franklin St, * 0018 * Fifth Floor, Boston, MA 02110-1301 USA * 0019 * * 0020 * This software consists of voluntary contributions made by many * 0021 * individuals. For exact contribution history, see the revision * 0022 * history and logs, available at http://kdesvn.alwins-world.de. * 0023 ***************************************************************************/ 0024 0025 0026 #include "contextdata.h" 0027 #include "context_listener.h" 0028 #include "conflictresult.h" 0029 #include "conflictdescription.h" 0030 0031 #include <svn_config.h> 0032 #include <svn_wc.h> 0033 #include <QCoreApplication> 0034 0035 namespace svn 0036 { 0037 0038 static inline char *toAprCharPtr(const QString &str, apr_pool_t *pool) 0039 { 0040 const QByteArray l = str.toUtf8(); 0041 return apr_pstrndup(pool, l.data(), l.size()); 0042 } 0043 0044 ContextData::ContextData(const QString &configDir_) 0045 : listener(nullptr), logIsSet(false), 0046 m_promptCounter(0), m_ConfigDir(configDir_) 0047 { 0048 const QByteArray cfgDirBa = m_ConfigDir.toUtf8(); 0049 const char *c_configDir = cfgDirBa.isEmpty() ? nullptr : cfgDirBa.constData(); 0050 0051 // make sure the configuration directory exists 0052 svn_config_ensure(c_configDir, pool); 0053 0054 // initialize authentication providers 0055 // * simple 0056 // * username 0057 // * simple pw cache of frontend app 0058 // * simple pw storage 0059 // * simple prompt 0060 // * ssl server trust file 0061 // * ssl server trust prompt 0062 // * ssl client cert pw file 0063 // * ssl client cert pw load 0064 // * ssl client cert pw prompt 0065 // * ssl client cert file 0066 // =================== 0067 // 11 providers (+1 for windowsvariant) 0068 0069 apr_array_header_t *providers = 0070 #if defined(WIN32) //krazy:exclude=cpp 0071 apr_array_make(pool, 12, sizeof(svn_auth_provider_object_t *)); 0072 #else 0073 apr_array_make(pool, 11, sizeof(svn_auth_provider_object_t *)); 0074 #endif 0075 svn_auth_provider_object_t *provider; 0076 0077 #if defined(WIN32) //krazy:exclude=cpp 0078 svn_auth_get_windows_simple_provider(&provider, pool); 0079 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; 0080 #endif 0081 0082 svn_auth_get_simple_provider2 0083 (&provider, maySavePlaintext, this, pool); 0084 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0085 0086 svn_auth_get_username_provider(&provider, pool); 0087 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0088 0089 svn_auth_get_simple_prompt_provider(&provider, onCachedPrompt, this, 0, pool); 0090 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0091 0092 svn_auth_get_simple_prompt_provider(&provider, onSavedPrompt, this, 0, pool); 0093 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0094 0095 /* not very nice. should be infinite... */ 0096 svn_auth_get_simple_prompt_provider(&provider, onSimplePrompt, this, 100000000, pool); 0097 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0098 0099 // add ssl providers 0100 0101 // file first then prompt providers 0102 svn_auth_get_ssl_server_trust_file_provider(&provider, pool); 0103 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0104 0105 svn_auth_get_ssl_client_cert_file_provider(&provider, pool); 0106 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0107 0108 svn_auth_get_ssl_client_cert_pw_file_provider2(&provider, maySavePlaintext, this, pool); 0109 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0110 0111 svn_auth_get_ssl_server_trust_prompt_provider(&provider, onSslServerTrustPrompt, this, pool); 0112 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0113 0114 // first try load from extra storage 0115 svn_auth_get_ssl_client_cert_pw_prompt_provider(&provider, onFirstSslClientCertPw, this, 0, pool); 0116 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0117 0118 // plugged in 3 as the retry limit - what is a good limit? 0119 svn_auth_get_ssl_client_cert_pw_prompt_provider(&provider, onSslClientCertPwPrompt, this, 3, pool); 0120 *(svn_auth_provider_object_t **)apr_array_push(providers) = provider; 0121 0122 svn_auth_baton_t *ab; 0123 svn_auth_open(&ab, providers, pool); 0124 0125 // todo svn 1.8: svn_client_create_context2 0126 // initialize ctx structure 0127 svn_client_create_context(&m_ctx, pool); 0128 0129 // get the config based on the configDir passed in 0130 svn_config_get_config(&(m_ctx->config), c_configDir, pool); 0131 0132 // tell the auth functions where the config is 0133 if (c_configDir) { 0134 svn_auth_set_parameter(ab, SVN_AUTH_PARAM_CONFIG_DIR, 0135 c_configDir); 0136 } 0137 0138 m_ctx->auth_baton = ab; 0139 m_ctx->notify_func = onNotify; 0140 m_ctx->notify_baton = this; 0141 m_ctx->cancel_func = onCancel; 0142 m_ctx->cancel_baton = this; 0143 m_ctx->notify_func2 = onNotify2; 0144 m_ctx->notify_baton2 = this; 0145 0146 m_ctx->log_msg_func = onLogMsg; 0147 m_ctx->log_msg_baton = this; 0148 // subversion 1.3 functions 0149 m_ctx->log_msg_func2 = onLogMsg2; 0150 m_ctx->log_msg_baton2 = this; 0151 0152 m_ctx->progress_func = onProgress; 0153 m_ctx->progress_baton = this; 0154 0155 m_ctx->log_msg_func3 = onLogMsg3; 0156 m_ctx->log_msg_baton3 = this; 0157 0158 m_ctx->conflict_func = onWcConflictResolver; 0159 m_ctx->conflict_baton = this; 0160 0161 m_ctx->conflict_func2 = onWcConflictResolver2; 0162 m_ctx->conflict_baton2 = this; 0163 0164 m_ctx->client_name = "SvnQt wrapper client"; 0165 initMimeTypes(); 0166 } 0167 0168 0169 ContextData::~ContextData() 0170 { 0171 } 0172 0173 0174 const QString &ContextData::getLogMessage() const 0175 { 0176 return logMessage; 0177 } 0178 0179 bool ContextData::retrieveLogMessage(QString &msg, const CommitItemList &_itemlist) 0180 { 0181 bool ok = false; 0182 if (listener) { 0183 ok = listener->contextGetLogMessage(logMessage, _itemlist); 0184 if (ok) { 0185 msg = logMessage; 0186 } else { 0187 logIsSet = false; 0188 } 0189 } 0190 return ok; 0191 } 0192 0193 void ContextData::notify(const char *path, 0194 svn_wc_notify_action_t action, 0195 svn_node_kind_t kind, 0196 const char *mime_type, 0197 svn_wc_notify_state_t content_state, 0198 svn_wc_notify_state_t prop_state, 0199 svn_revnum_t revision) 0200 { 0201 if (listener != nullptr) { 0202 listener->contextNotify(path, action, kind, mime_type, 0203 content_state, prop_state, revision); 0204 } 0205 } 0206 0207 void ContextData::notify(const svn_wc_notify_t *action) 0208 { 0209 if (listener != nullptr) { 0210 listener->contextNotify(action); 0211 } 0212 } 0213 0214 bool ContextData::cancel() 0215 { 0216 if (listener != nullptr) { 0217 return listener->contextCancel(); 0218 } else { 0219 // don't cancel if no listener 0220 return false; 0221 } 0222 } 0223 const QString &ContextData::getUsername() const 0224 { 0225 return username; 0226 } 0227 0228 const QString &ContextData::getPassword() const 0229 { 0230 return password; 0231 } 0232 0233 bool ContextData::retrieveLogin(const char *username_, 0234 const char *realm, 0235 bool &may_save) 0236 { 0237 bool ok; 0238 0239 if (listener == nullptr) { 0240 return false; 0241 } 0242 0243 username = QString::fromUtf8(username_); 0244 ok = listener->contextGetLogin(QString::fromUtf8(realm), username, password, may_save); 0245 0246 return ok; 0247 } 0248 0249 bool ContextData::retrieveSavedLogin(const char *username_, 0250 const char *realm, 0251 bool &may_save) 0252 { 0253 bool ok; 0254 may_save = false; 0255 0256 if (listener == nullptr) { 0257 return false; 0258 } 0259 0260 username = QString::fromUtf8(username_); 0261 ok = listener->contextGetSavedLogin(QString::fromUtf8(realm), username, password); 0262 return ok; 0263 } 0264 0265 bool ContextData::retrieveCachedLogin(const char *username_, 0266 const char *realm, 0267 bool &may_save) 0268 { 0269 bool ok; 0270 may_save = false; 0271 0272 if (listener == nullptr) { 0273 return false; 0274 } 0275 0276 username = QString::fromUtf8(username_); 0277 ok = listener->contextGetCachedLogin(QString::fromUtf8(realm), username, password); 0278 return ok; 0279 } 0280 0281 svn_client_ctx_t *ContextData::ctx() 0282 { 0283 return m_ctx; 0284 } 0285 0286 const QString &ContextData::configDir()const 0287 { 0288 return m_ConfigDir; 0289 } 0290 0291 svn_error_t * 0292 ContextData::getContextData(void *baton, ContextData **data) 0293 { 0294 if (baton == nullptr) 0295 return svn_error_create(SVN_ERR_CANCELLED, nullptr, 0296 QCoreApplication::translate("svnqt", "invalid baton").toUtf8()); 0297 0298 ContextData *data_ = static_cast <ContextData *>(baton); 0299 0300 if (data_->listener == nullptr) 0301 return svn_error_create(SVN_ERR_CANCELLED, nullptr, 0302 QCoreApplication::translate("svnqt", "invalid listener").toUtf8()); 0303 0304 *data = data_; 0305 return SVN_NO_ERROR; 0306 } 0307 0308 void ContextData::setAuthCache(bool value) 0309 { 0310 void *param = nullptr; 0311 if (!value) { 0312 param = (void *)"1"; 0313 } 0314 svn_auth_set_parameter(m_ctx->auth_baton, 0315 SVN_AUTH_PARAM_NO_AUTH_CACHE, param); 0316 } 0317 0318 void ContextData::setLogin(const QString &usr, const QString &pwd) 0319 { 0320 username = usr; 0321 password = pwd; 0322 svn_auth_baton_t *ab = m_ctx->auth_baton; 0323 svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_USERNAME, username.toUtf8()); 0324 svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD, password.toUtf8()); 0325 } 0326 0327 void ContextData::setLogMessage(const QString &msg) 0328 { 0329 logMessage = msg; 0330 if (msg.isNull()) { 0331 logIsSet = false; 0332 } else { 0333 logIsSet = true; 0334 } 0335 } 0336 0337 svn_error_t *ContextData::onLogMsg(const char **log_msg, 0338 const char **tmp_file, 0339 apr_array_header_t *commit_items, 0340 void *baton, 0341 apr_pool_t *pool) 0342 { 0343 ContextData *data = nullptr; 0344 SVN_ERR(getContextData(baton, &data)); 0345 0346 QString msg; 0347 if (data->logIsSet) { 0348 msg = data->getLogMessage(); 0349 } else { 0350 CommitItemList _items; 0351 _items.reserve(commit_items->nelts); 0352 for (int j = 0; j < commit_items->nelts; ++j) { 0353 svn_client_commit_item_t *item = ((svn_client_commit_item_t **)commit_items->elts)[j]; 0354 _items.push_back(CommitItem(item)); 0355 } 0356 if (!data->retrieveLogMessage(msg, _items)) { 0357 return data->generate_cancel_error(); 0358 } 0359 } 0360 0361 *log_msg = toAprCharPtr(msg, pool); 0362 *tmp_file = nullptr; 0363 return SVN_NO_ERROR; 0364 } 0365 0366 svn_error_t *ContextData::onLogMsg2(const char **log_msg, 0367 const char **tmp_file, 0368 const apr_array_header_t *commit_items, 0369 void *baton, 0370 apr_pool_t *pool) 0371 { 0372 ContextData *data = nullptr; 0373 SVN_ERR(getContextData(baton, &data)); 0374 0375 QString msg; 0376 if (data->logIsSet) { 0377 msg = data->getLogMessage(); 0378 } else { 0379 CommitItemList _items; 0380 _items.reserve(commit_items->nelts); 0381 for (int j = 0; j < commit_items->nelts; ++j) { 0382 svn_client_commit_item2_t *item = ((svn_client_commit_item2_t **)commit_items->elts)[j]; 0383 _items.push_back(CommitItem(item)); 0384 } 0385 0386 if (!data->retrieveLogMessage(msg, _items)) { 0387 return data->generate_cancel_error(); 0388 } 0389 } 0390 0391 *log_msg = toAprCharPtr(msg, pool); 0392 *tmp_file = nullptr; 0393 return SVN_NO_ERROR; 0394 } 0395 0396 svn_error_t *ContextData::onLogMsg3(const char **log_msg, 0397 const char **tmp_file, 0398 const apr_array_header_t *commit_items, 0399 void *baton, 0400 apr_pool_t *pool) 0401 { 0402 ContextData *data = nullptr; 0403 SVN_ERR(getContextData(baton, &data)); 0404 0405 QString msg; 0406 if (data->logIsSet) { 0407 msg = data->getLogMessage(); 0408 } else { 0409 CommitItemList _items; 0410 _items.reserve(commit_items->nelts); 0411 for (int j = 0; j < commit_items->nelts; ++j) { 0412 svn_client_commit_item3_t *item = ((svn_client_commit_item3_t **)commit_items->elts)[j]; 0413 _items.push_back(CommitItem(item)); 0414 } 0415 0416 if (!data->retrieveLogMessage(msg, _items)) { 0417 return data->generate_cancel_error(); 0418 } 0419 } 0420 0421 *log_msg = toAprCharPtr(msg, pool); 0422 *tmp_file = nullptr; 0423 return SVN_NO_ERROR; 0424 } 0425 0426 void ContextData::onNotify(void *baton, 0427 const char *path, 0428 svn_wc_notify_action_t action, 0429 svn_node_kind_t kind, 0430 const char *mime_type, 0431 svn_wc_notify_state_t content_state, 0432 svn_wc_notify_state_t prop_state, 0433 svn_revnum_t revision) 0434 { 0435 if (baton == nullptr) { 0436 return; 0437 } 0438 ContextData *data = static_cast <ContextData *>(baton); 0439 data->notify(path, action, kind, mime_type, content_state, 0440 prop_state, revision); 0441 } 0442 0443 void ContextData::onNotify2(void *baton, const svn_wc_notify_t *action, apr_pool_t */*tpool*/) 0444 { 0445 if (!baton) { 0446 return; 0447 } 0448 ContextData *data = static_cast <ContextData *>(baton); 0449 data->notify(action); 0450 } 0451 0452 svn_error_t *ContextData::onCancel(void *baton) 0453 { 0454 if (baton == nullptr) { 0455 return SVN_NO_ERROR; 0456 } 0457 ContextData *data = static_cast <ContextData *>(baton); 0458 if (data->cancel()) { 0459 return data->generate_cancel_error(); 0460 } else { 0461 return SVN_NO_ERROR; 0462 } 0463 } 0464 0465 svn_error_t *ContextData::onCachedPrompt(svn_auth_cred_simple_t **cred, 0466 void *baton, 0467 const char *realm, 0468 const char *username, 0469 svn_boolean_t _may_save, 0470 apr_pool_t *pool) 0471 { 0472 ContextData *data = nullptr; 0473 SVN_ERR(getContextData(baton, &data)); 0474 bool may_save = _may_save != 0; 0475 if (!data->retrieveCachedLogin(username, realm, may_save)) { 0476 return SVN_NO_ERROR; 0477 } 0478 svn_auth_cred_simple_t *lcred = (svn_auth_cred_simple_t *) 0479 apr_palloc(pool, sizeof(svn_auth_cred_simple_t)); 0480 lcred->password = toAprCharPtr(data->getPassword(), pool); 0481 lcred->username = toAprCharPtr(data->getUsername(), pool); 0482 0483 // tell svn if the credentials need to be saved 0484 lcred->may_save = may_save; 0485 *cred = lcred; 0486 0487 return SVN_NO_ERROR; 0488 } 0489 0490 svn_error_t *ContextData::onSavedPrompt(svn_auth_cred_simple_t **cred, 0491 void *baton, 0492 const char *realm, 0493 const char *username, 0494 svn_boolean_t _may_save, 0495 apr_pool_t *pool) 0496 { 0497 ContextData *data = nullptr; 0498 SVN_ERR(getContextData(baton, &data)); 0499 bool may_save = _may_save != 0; 0500 if (!data->retrieveSavedLogin(username, realm, may_save)) { 0501 return SVN_NO_ERROR; 0502 } 0503 svn_auth_cred_simple_t *lcred = (svn_auth_cred_simple_t *) 0504 apr_palloc(pool, sizeof(svn_auth_cred_simple_t)); 0505 lcred->password = toAprCharPtr(data->getPassword(), pool); 0506 lcred->username = toAprCharPtr(data->getUsername(), pool); 0507 0508 // tell svn if the credentials need to be saved 0509 lcred->may_save = may_save; 0510 *cred = lcred; 0511 0512 return SVN_NO_ERROR; 0513 } 0514 0515 svn_error_t *ContextData::onSimplePrompt(svn_auth_cred_simple_t **cred, 0516 void *baton, 0517 const char *realm, 0518 const char *username, 0519 svn_boolean_t _may_save, 0520 apr_pool_t *pool) 0521 { 0522 ContextData *data = nullptr; 0523 SVN_ERR(getContextData(baton, &data)); 0524 bool may_save = _may_save != 0; 0525 if (!data->retrieveLogin(username, realm, may_save)) { 0526 return data->generate_cancel_error(); 0527 } 0528 0529 svn_auth_cred_simple_t *lcred = (svn_auth_cred_simple_t *) 0530 apr_palloc(pool, sizeof(svn_auth_cred_simple_t)); 0531 lcred->password = toAprCharPtr(data->getPassword(), pool); 0532 lcred->username = toAprCharPtr(data->getUsername(), pool); 0533 0534 // tell svn if the credentials need to be saved 0535 lcred->may_save = may_save; 0536 *cred = lcred; 0537 0538 return SVN_NO_ERROR; 0539 } 0540 0541 svn_error_t *ContextData::onSslServerTrustPrompt(svn_auth_cred_ssl_server_trust_t **cred, 0542 void *baton, 0543 const char *realm, 0544 apr_uint32_t failures, 0545 const svn_auth_ssl_server_cert_info_t *info, 0546 svn_boolean_t may_save, 0547 apr_pool_t *pool) 0548 { 0549 ContextData *data = nullptr; 0550 SVN_ERR(getContextData(baton, &data)); 0551 0552 ContextListener::SslServerTrustData trustData(failures); 0553 if (realm != nullptr) { 0554 trustData.realm = QString::fromUtf8(realm); 0555 } 0556 trustData.hostname = QString::fromUtf8(info->hostname); 0557 trustData.fingerprint = QString::fromUtf8(info->fingerprint); 0558 trustData.validFrom = QString::fromUtf8(info->valid_from); 0559 trustData.validUntil = QString::fromUtf8(info->valid_until); 0560 trustData.issuerDName = QString::fromUtf8(info->issuer_dname); 0561 trustData.maySave = may_save != 0; 0562 0563 apr_uint32_t acceptedFailures = failures; 0564 ContextListener::SslServerTrustAnswer answer = 0565 data->listener->contextSslServerTrustPrompt( 0566 trustData, acceptedFailures); 0567 0568 if (answer == ContextListener::DONT_ACCEPT) { 0569 *cred = nullptr; 0570 } else { 0571 svn_auth_cred_ssl_server_trust_t *cred_ = 0572 (svn_auth_cred_ssl_server_trust_t *) 0573 apr_palloc(pool, sizeof(svn_auth_cred_ssl_server_trust_t)); 0574 0575 cred_->accepted_failures = failures; 0576 if (answer == ContextListener::ACCEPT_PERMANENTLY) { 0577 cred_->may_save = true; 0578 } else { 0579 cred_->may_save = false; 0580 } 0581 *cred = cred_; 0582 } 0583 0584 return SVN_NO_ERROR; 0585 } 0586 0587 svn_error_t *ContextData::onSslClientCertPrompt(svn_auth_cred_ssl_client_cert_t **cred, 0588 void *baton, 0589 apr_pool_t *pool) 0590 { 0591 ContextData *data = nullptr; 0592 SVN_ERR(getContextData(baton, &data)); 0593 0594 QString certFile; 0595 if (!data->listener->contextSslClientCertPrompt(certFile)) { 0596 return data->generate_cancel_error(); 0597 } 0598 0599 svn_auth_cred_ssl_client_cert_t *cred_ = 0600 (svn_auth_cred_ssl_client_cert_t *) 0601 apr_palloc(pool, sizeof(svn_auth_cred_ssl_client_cert_t)); 0602 0603 cred_->cert_file = toAprCharPtr(certFile, pool); 0604 0605 *cred = cred_; 0606 return SVN_NO_ERROR; 0607 } 0608 0609 svn_error_t *ContextData::onFirstSslClientCertPw( 0610 svn_auth_cred_ssl_client_cert_pw_t **cred, 0611 void *baton, 0612 const char *realm, 0613 svn_boolean_t maySave, 0614 apr_pool_t *pool) 0615 { 0616 ContextData *data = nullptr; 0617 SVN_ERR(getContextData(baton, &data)); 0618 0619 QString password; 0620 bool may_save = maySave != 0; 0621 if (!data->listener->contextLoadSslClientCertPw(password, QString::fromUtf8(realm))) { 0622 return SVN_NO_ERROR; 0623 } 0624 0625 svn_auth_cred_ssl_client_cert_pw_t *cred_ = 0626 (svn_auth_cred_ssl_client_cert_pw_t *) 0627 apr_palloc(pool, sizeof(svn_auth_cred_ssl_client_cert_pw_t)); 0628 0629 cred_->password = toAprCharPtr(password, pool); 0630 cred_->may_save = may_save; 0631 *cred = cred_; 0632 0633 return SVN_NO_ERROR; 0634 } 0635 0636 svn_error_t *ContextData::onSslClientCertPwPrompt( 0637 svn_auth_cred_ssl_client_cert_pw_t **cred, 0638 void *baton, 0639 const char *realm, 0640 svn_boolean_t maySave, 0641 apr_pool_t *pool) 0642 { 0643 ContextData *data = nullptr; 0644 SVN_ERR(getContextData(baton, &data)); 0645 0646 QString password; 0647 bool may_save = maySave != 0; 0648 if (!data->listener->contextSslClientCertPwPrompt(password, QString::fromUtf8(realm), may_save)) { 0649 return data->generate_cancel_error(); 0650 } 0651 0652 svn_auth_cred_ssl_client_cert_pw_t *cred_ = 0653 (svn_auth_cred_ssl_client_cert_pw_t *) 0654 apr_palloc(pool, sizeof(svn_auth_cred_ssl_client_cert_pw_t)); 0655 0656 cred_->password = toAprCharPtr(password, pool); 0657 cred_->may_save = may_save; 0658 *cred = cred_; 0659 0660 return SVN_NO_ERROR; 0661 } 0662 0663 void ContextData::setListener(ContextListener *_listener) 0664 { 0665 listener = _listener; 0666 } 0667 0668 ContextListener *ContextData::getListener() const 0669 { 0670 return listener; 0671 } 0672 0673 void ContextData::reset() 0674 { 0675 m_promptCounter = 0; 0676 logIsSet = false; 0677 } 0678 0679 svn_error_t *ContextData::generate_cancel_error() 0680 { 0681 return svn_error_create(SVN_ERR_CANCELLED, nullptr, QCoreApplication::translate("svnqt", "Cancelled by user.").toUtf8()); 0682 } 0683 0684 void ContextData::onProgress(apr_off_t progress, apr_off_t total, void *baton, apr_pool_t *) 0685 { 0686 ContextData *data = nullptr; 0687 if (getContextData(baton, &data) != SVN_NO_ERROR) { 0688 return; 0689 } 0690 data->getListener()->contextProgress(progress, total); 0691 } 0692 0693 void ContextData::initMimeTypes() 0694 { 0695 // code take from subversion 1.5 commandline client 0696 const char *mimetypes_file; 0697 svn_error_t *err = nullptr; 0698 svn_config_t *cfg = (svn_config_t *)apr_hash_get(m_ctx->config, SVN_CONFIG_CATEGORY_CONFIG, 0699 APR_HASH_KEY_STRING); 0700 0701 svn_config_get(cfg, &mimetypes_file, 0702 SVN_CONFIG_SECTION_MISCELLANY, 0703 SVN_CONFIG_OPTION_MIMETYPES_FILE, nullptr); 0704 if (mimetypes_file && *mimetypes_file) { 0705 if ((err = svn_io_parse_mimetypes_file(&(m_ctx->mimetypes_map), 0706 mimetypes_file, pool))) { 0707 svn_handle_error2(err, stderr, false, "svn: "); 0708 } 0709 } 0710 } 0711 0712 svn_error_t *ContextData::onWcConflictResolver(svn_wc_conflict_result_t **result, const svn_wc_conflict_description_t *description, void *baton, apr_pool_t *pool) 0713 { 0714 ContextData *data = nullptr; 0715 SVN_ERR(getContextData(baton, &data)); 0716 ConflictResult cresult; 0717 if (!data->getListener()->contextConflictResolve(cresult, ConflictDescription(description))) { 0718 return data->generate_cancel_error(); 0719 } 0720 cresult.assignResult(result, pool); 0721 return SVN_NO_ERROR; 0722 } 0723 0724 svn_error_t *ContextData::onWcConflictResolver2(svn_wc_conflict_result_t **result, 0725 const svn_wc_conflict_description2_t *description, 0726 void *baton, 0727 apr_pool_t *result_pool, 0728 apr_pool_t *) 0729 { 0730 ContextData *data = nullptr; 0731 SVN_ERR(getContextData(baton, &data)); 0732 ConflictResult cresult; 0733 if (!data->getListener()->contextConflictResolve(cresult, ConflictDescription(description))) { 0734 return data->generate_cancel_error(); 0735 } 0736 cresult.assignResult(result, result_pool); 0737 return SVN_NO_ERROR; 0738 } 0739 0740 svn_error_t *ContextData::maySavePlaintext(svn_boolean_t *may_save_plaintext, const char *realmstring, void *baton, apr_pool_t *pool) 0741 { 0742 Q_UNUSED(pool); 0743 ContextData *data = nullptr; 0744 SVN_ERR(getContextData(baton, &data)); 0745 data->getListener()->maySavePlaintext(may_save_plaintext, QString::fromUtf8(realmstring)); 0746 return SVN_NO_ERROR; 0747 } 0748 0749 bool ContextData::contextAddListItem(DirEntries *entries, const svn_dirent_t *dirent, const svn_lock_t *lock, const QString &path) 0750 { 0751 if (!getListener()) { 0752 if (!entries || !dirent) { 0753 return false; 0754 } 0755 entries->push_back(DirEntry(path, dirent, lock)); 0756 return true; 0757 } 0758 return getListener()->contextAddListItem(entries, dirent, lock, path); 0759 } 0760 0761 bool ContextListener::contextConflictResolve(ConflictResult &result, const ConflictDescription &description) 0762 { 0763 Q_UNUSED(description); 0764 result.setChoice(ConflictResult::ChoosePostpone); 0765 return true; 0766 } 0767 0768 bool ContextListener::contextAddListItem(DirEntries *entries, const svn_dirent_t *dirent, const svn_lock_t *lock, const QString &path) 0769 { 0770 if (!entries || !dirent) { 0771 return false; 0772 } 0773 entries->push_back(DirEntry(path, dirent, lock)); 0774 return true; 0775 } 0776 0777 void ContextListener::maySavePlaintext(svn_boolean_t *may_save_plaintext, const QString &realmstring) 0778 { 0779 Q_UNUSED(realmstring); 0780 if (may_save_plaintext) { 0781 *may_save_plaintext = true; 0782 } 0783 } 0784 0785 }