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