https://svn.collab.net/viewvc/svn?view=revision&revision=38004 https://svn.collab.net/viewvc/svn?view=revision&revision=38014 https://svn.collab.net/viewvc/svn?view=revision&revision=38028 https://svn.collab.net/viewvc/svn?view=revision&revision=38122 --- subversion/libsvn_auth_kwallet/kwallet.cpp +++ subversion/libsvn_auth_kwallet/kwallet.cpp @@ -22,6 +22,7 @@ /*** Includes. ***/ +#include #include #include @@ -30,6 +31,9 @@ #include "svn_auth.h" #include "svn_config.h" #include "svn_error.h" +#include "svn_io.h" +#include "svn_pools.h" +#include "svn_string.h" #include "svn_version.h" #include "private/svn_auth_private.h" @@ -38,13 +42,20 @@ #include #include +#include +#include #include +#include +#include #include #include #include #include #include +#include +#include +#include /*-----------------------------------------------------------------------*/ @@ -52,6 +63,28 @@ /*-----------------------------------------------------------------------*/ +#define INITIALIZE_APPLICATION \ + if (apr_hash_get(parameters, \ + "svn:auth:qapplication-safe", \ + APR_HASH_KEY_STRING)) \ + { \ + QApplication *app; \ + if (! qApp) \ + { \ + int argc = 1; \ + app = new QApplication(argc, (char *[1]) {(char *) "svn"}); \ + } \ + } \ + else \ + { \ + QCoreApplication *app; \ + if (! qApp) \ + { \ + int argc = 1; \ + app = new QCoreApplication(argc, (char *[1]) {(char *) "svn"}); \ + } \ + } + static const char * get_application_name(apr_hash_t *parameters, apr_pool_t *pool) @@ -69,8 +102,7 @@ const char *svn_application_name; if (svn_application_name_with_pid) { - long pid = getpid(); - svn_application_name = apr_psprintf(pool, "Subversion [%ld]", pid); + svn_application_name = apr_psprintf(pool, "Subversion [%ld]", long(getpid())); } else { @@ -102,9 +134,108 @@ } } +static pid_t +get_parent_pid(pid_t pid, + apr_pool_t *pool) +{ + pid_t parent_pid = 0; + +#ifdef __linux__ + svn_stream_t *stat_file_stream; + svn_string_t *stat_file_string; + const char *preceeding_space, *following_space, *parent_pid_string; + + const char *path = apr_psprintf(pool, "/proc/%ld/stat", long(pid)); + svn_error_t *err = svn_stream_open_readonly(&stat_file_stream, path, pool, pool); + if (err == SVN_NO_ERROR) + { + err = svn_string_from_stream(&stat_file_string, stat_file_stream, pool, pool); + if (err == SVN_NO_ERROR) + { + if ((preceeding_space = strchr(stat_file_string->data, ' '))) + { + if ((preceeding_space = strchr(preceeding_space + 1, ' '))) + { + if ((preceeding_space = strchr(preceeding_space + 1, ' '))) + { + if ((following_space = strchr(preceeding_space + 1, ' '))) + { + parent_pid_string = apr_pstrndup(pool, + preceeding_space + 1, + following_space - preceeding_space); + parent_pid = atol(parent_pid_string); + } + } + } + } + } + } + + if (err) + { + svn_error_clear(err); + } +#endif + + return parent_pid; +} + +static WId +get_wid(apr_hash_t *parameters, + apr_pool_t *pool) +{ + WId wid = 1; + + if (apr_hash_get(parameters, + "svn:auth:qapplication-safe", + APR_HASH_KEY_STRING)) + { + QMap process_info_list; + QList windows(KWindowSystem::windows()); + QList::const_iterator i; + for (i = windows.begin(); i != windows.end(); i++) + { + process_info_list[NETWinInfo(QX11Info::display(), + *i, + QX11Info::appRootWindow(), + NET::WMPid).pid()] = *i; + } + + apr_pool_t *iterpool = svn_pool_create(pool); + pid_t pid = getpid(); + while (pid != 0) + { + svn_pool_clear(iterpool); + if (process_info_list.contains(pid)) + { + wid = process_info_list[pid]; + break; + } + pid = get_parent_pid(pid, iterpool); + } + svn_pool_destroy(iterpool); + } + + if (wid == 1) + { + const char *wid_env_string = getenv("WINDOWID"); + if (wid_env_string) + { + long wid_env = atol(wid_env_string); + if (wid_env != 0) + { + wid = wid_env; + } + } + } + + return wid; +} + static KWallet::Wallet * get_wallet(QString wallet_name, - apr_hash_t *parameters) + apr_hash_t *parameters, + apr_pool_t *pool) { KWallet::Wallet *wallet = static_cast (apr_hash_get(parameters, @@ -115,7 +246,7 @@ APR_HASH_KEY_STRING)) { wallet = KWallet::Wallet::openWallet(wallet_name, - -1, + pool ? get_wid(parameters, pool) : 1, KWallet::Wallet::Synchronous); } if (wallet) @@ -141,7 +272,7 @@ apr_hash_t *parameters = static_cast (data); if (apr_hash_get(parameters, "kwallet-initialized", APR_HASH_KEY_STRING)) { - KWallet::Wallet *wallet = get_wallet(NULL, parameters); + KWallet::Wallet *wallet = get_wallet(NULL, parameters, NULL); delete wallet; apr_hash_set(parameters, "kwallet-initialized", @@ -172,12 +303,7 @@ return FALSE; } - QCoreApplication *app; - if (! qApp) - { - int argc = 1; - app = new QCoreApplication(argc, (char *[1]) {(char *) "svn"}); - } + INITIALIZE_APPLICATION KCmdLineArgs::init(1, (char *[1]) {(char *) "svn"}, @@ -195,7 +321,7 @@ QString::fromUtf8(username) + "@" + QString::fromUtf8(realmstring); if (! KWallet::Wallet::keyDoesNotExist(wallet_name, folder, key)) { - KWallet::Wallet *wallet = get_wallet(wallet_name, parameters); + KWallet::Wallet *wallet = get_wallet(wallet_name, parameters, pool); if (wallet) { apr_hash_set(parameters, @@ -242,12 +368,7 @@ return FALSE; } - QCoreApplication *app; - if (! qApp) - { - int argc = 1; - app = new QCoreApplication(argc, (char *[1]) {(char *) "svn"}); - } + INITIALIZE_APPLICATION KCmdLineArgs::init(1, (char *[1]) {(char *) "svn"}, @@ -262,7 +383,7 @@ QString q_password = QString::fromUtf8(password); QString wallet_name = get_wallet_name(parameters); QString folder = QString::fromUtf8("Subversion"); - KWallet::Wallet *wallet = get_wallet(wallet_name, parameters); + KWallet::Wallet *wallet = get_wallet(wallet_name, parameters, pool); if (wallet) { apr_hash_set(parameters, --- subversion/svn/main.c +++ subversion/svn/main.c @@ -2067,6 +2067,9 @@ pool))) svn_handle_error2(err, stderr, TRUE, "svn: "); + /* svn can safely create instance of QApplication class. */ + svn_auth_set_parameter(ab, "svn:auth:qapplication-safe", "1"); + ctx->auth_baton = ab; /* Set up conflict resolution callback. */ --- subversion/svnsync/main.c +++ subversion/svnsync/main.c @@ -1,6 +1,6 @@ /* * ==================================================================== - * Copyright (c) 2005-2008 CollabNet. All rights reserved. + * Copyright (c) 2005-2009 CollabNet. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -2362,7 +2362,15 @@ check_cancel, NULL, pool); if (! err) - err = (*subcommand->cmd_func)(os, &opt_baton, pool); + { + /* svnsync can safely create instance of QApplication class. */ + svn_auth_set_parameter(opt_baton.source_auth_baton, + "svn:auth:qapplication-safe", "1"); + svn_auth_set_parameter(opt_baton.sync_auth_baton, + "svn:auth:qapplication-safe", "1"); + + err = (*subcommand->cmd_func)(os, &opt_baton, pool); + } if (err) { /* For argument-related problems, suggest using the 'help'