GME  13
HiClient.cpp
Go to the documentation of this file.
00001 #include "../StdAfx.h"
00002 #include "HiClient.h"
00003 #include <fstream>
00004 #include "../ProgressWindow.h"
00005 
00006 #if(USESVN)
00007 #include "Pool.h"
00008 #include "svn_wc.h"
00009 #include "svn_dirent_uri.h"
00010 #include "svn_path.h"
00011 
00012 HiClient::HiClient( const std::string& p_userName, const std::string& p_passWord)
00013         : Client( p_userName, p_passWord)
00014         , CallLogger()
00015 {
00016 }
00017 
00018 HiClient::~HiClient(void)
00019 {
00020 }
00021 
00022 void HiClient::replaceUserName( const std::string& p_userName)
00023 {
00024         m_userName = p_userName;
00025 }
00026 
00027 bool HiClient::isItUs( const std::string& p_userName)
00028 {
00029         log( "isItUs", p_userName);
00030         return m_userName == p_userName;//strcmp( m_userName.c_str(), ( p_userName?p_userName:"")) == 0; // equal means yes
00031 }
00032 
00033 //bool HiClient::isLocked            ( const std::string& p_path)
00034 //{
00035 //      log( "isLocked", p_path);
00036 //      return isLockedByUser( p_path, std::string());
00037 //}
00038 //
00039 //bool HiClient::isLockedByUs        ( const std::string& p_path)
00040 //{
00041 //      bool lkd, l_us, l_else;
00042 //
00043 //      log( "isLockedByUs", p_path);
00044 //      lkd = isLockedByWhom( p_path, &l_us, &l_else);
00045 //
00046 //      return lkd && l_us;
00047 //}
00048 //
00049 bool HiClient::isLockedByOthers    ( const std::string& p_path)
00050 {
00051         bool lkd, l_us, l_else;
00052 
00053         log( "isLockedByOthers", p_path);
00054         lkd = isLockedByWhom( p_path, &l_us, &l_else);
00055 
00056         return lkd && l_else;
00057 }
00058 
00059 bool HiClient::isLockedByWhom      ( const std::string& p_path, bool * p_us, bool * p_else)
00060 {
00061         ASSERT( p_us);
00062         ASSERT( p_else);
00063 
00064         std::string    uname;
00065         bool           lockd = false;
00066 
00067         log( "isLockedByWhom", p_path);
00068         lockd = isLockedByUser( p_path, uname);
00069 
00070         *p_us   = isItUs( uname);
00071         *p_else = !*p_us;
00072 
00073         return lockd;
00074 }
00075 
00076 bool HiClient::isLockedByUser      ( const std::string& p_path, std::string& p_username)
00077 {
00078         Pool reqPool;
00079 
00080         bool res = false;
00081         ClientUtil::InfoHelp::InfoVec inf;
00082 
00083         log( "isLockedByUser", p_path + p_username);
00084         
00085         CString progressStr;
00086         progressStr.Format("Check lock status: %s", (LPCTSTR)p_path.c_str());
00087         UpdateProgress(progressStr);
00088 
00089         bool suc = info2Qck( p_path.c_str(), false, inf);
00090         ASSERT( suc);
00091         ASSERT( inf.size() == 1);
00092 
00093         for( ClientUtil::InfoHelp::InfoVecConIter it = inf.begin(), en = inf.end(); suc && it != en; ++it)
00094         {
00095 #if(USESERF)
00096                 if( it->m_info && it->m_info->lock && it->m_info->lock->token) // it seems that lock->token != 0 means for SERF the locked status
00097                 { // while for neon the lock != 0 means there is lock
00098                         // locked
00099                         res = true;
00100                         
00101                         // by whom
00102                         ASSERT( it->m_info->lock->owner);
00103                         if( it->m_info->lock->owner)
00104                                 p_username = it->m_info->lock->owner;
00105                         else
00106                                 p_username = "";
00107                 }
00108 #else // for all other cases: 'svn://', 'svn+ssh://' or 'https://' with USENEON (USENEON could be 1 or 0) this would work:
00109                 if( it->m_info && it->m_info->lock)
00110                 {
00111                         // locked
00112                         res = true;
00113                         
00114                         // by whom
00115                         ASSERT( it->m_info->lock->owner);
00116                         if( it->m_info->lock->owner)
00117                                 p_username = it->m_info->lock->owner;
00118                         else
00119                                 p_username = "";
00120                 }
00121 #endif
00122         }
00123 
00124         progressStr.Format("(%s) DONE.\r\n", (LPCTSTR)p_username.c_str());
00125         UpdateProgress(progressStr);
00126 
00127         return res;
00128 }
00129 
00130 bool HiClient::isVersioned         ( const std::string& p_path, bool p_isADir /*= false*/, bool p_suppressErrorMsg /*= false*/)
00131 {
00132         Pool reqPool;
00133 
00134         log( "isVersioned", p_path + (p_isADir?" dir ": " file "));
00135 
00136         CString progressStr;
00137         progressStr.Format("Check if versioned: %s", (LPCTSTR)p_path.c_str());
00138         UpdateProgress(progressStr);
00139 
00140         ClientUtil::InfoHelp::InfoVec inf;
00141         // PETER - SVNSPEEDHACK BEGIN
00142         // bool res = info2Qck( p_path.c_str(), false, inf, p_suppressErrorMsg);
00143         Revision rev( svn_path_is_url(p_path.c_str()) ? svn_opt_revision_head : svn_opt_revision_unspecified);
00144         bool res =  sub_info2( p_path.c_str(), rev, rev, false, inf, p_suppressErrorMsg);
00145         // FIXME: res is if an error occurred, not if p_path is under version control. Need to check inf!
00146         // This can lead to crashes
00147         // PETER - SVNSPEEDHACK BEGIN
00148 
00149         progressStr.Format("(%s) DONE.\r\n", res ? _T("yes") : _T("no"));
00150         UpdateProgress(progressStr);
00151 
00152         return res;
00153 }
00154 
00155 bool HiClient::info                ( const std::string& p_path, bool p_recursive, bool p_assembleInfoMessage, std::string& p_resultMsg, std::string& p_lastChangingAuthor, std::string& p_lockOwner)
00156 {
00157         Pool reqPool;
00158 
00159         bool rv = false;
00160         std::string msg;
00161         std::string aut;
00162         std::string own;
00163 
00164         log( "info", p_path);
00165 
00166         CString progressStr;
00167         progressStr.Format("Subversion info: %s", (LPCTSTR)p_path.c_str());
00168         UpdateProgress(progressStr);
00169 
00170         ClientUtil::InfoHelp::InfoVec inf;
00171         if( sub_info2( p_path.c_str(), Revision(), Revision(), p_recursive, inf, true)) // non-recursive info only
00172         {
00173                 rv = true;
00174 
00175                 if( 1)
00176                 {
00177                         msg = "After issuing 'svn info "; msg += ClientUtil::charstar2str( p_path.c_str(), "Url"); msg += "'";
00178                         for( ClientUtil::InfoHelp::InfoVecConIter it = inf.begin(), en = inf.end(); it != en; ++it)
00179                         {
00180                                 msg.append( "\nI know about: '");
00181                                 msg.append( ClientUtil::charstar2str( it->m_path, "Path"));
00182                                 msg.append( "' the following:");
00183                                 if( it->m_info)
00184                                 {
00185                                         if( !aut.empty()) aut.append( ", "); // if multiple entries in inf, then separate authors by ,
00186 
00187                                         msg.append( "\n\tLast Changed Author: "); 
00188                                         aut.append( ClientUtil::charstar2str( it->m_info->last_changed_author, "Author"));
00189                                         msg.append( ClientUtil::charstar2str( it->m_info->last_changed_author, "Author"));
00190 
00191                                         msg.append( "\n\tVersioned as (URL): "); 
00192                                         msg.append( ClientUtil::charstar2str( it->m_info->URL, "Url"));
00193 #if(USESERF)
00194                                         if( it->m_info->lock && it->m_info->lock->token)
00195                                         {
00196                                                 msg.append( "\n\tLocked by "); 
00197                                                 if( !own.empty()) own.append( ", "); // if multiple entries in inf, then separate owners by ,
00198 
00199                                                 own.append( ClientUtil::charstar2str( it->m_info->lock->owner, "LockOwner"));
00200                                                 msg.append( ClientUtil::charstar2str( it->m_info->lock->owner, "LockOwner"));
00201                                         }
00202                                         else
00203                                                 msg.append( "\n\tNot Locked");
00204 
00205 #else // for all other cases: 'svn://', 'svn+ssh://' or 'https://' with USENEON (USENEON could be 1 or 0) this would work:
00206 
00207                                         if( it->m_info->lock)
00208                                         {
00209                                                 msg.append( "\n\tLocked by "); 
00210                                                 if( !own.empty()) own.append( ", "); // if multiple entries in inf, then separate owners by ,
00211 
00212                                                 own.append( ClientUtil::charstar2str( it->m_info->lock->owner, "LockOwner"));
00213                                                 msg.append( ClientUtil::charstar2str( it->m_info->lock->owner, "LockOwner"));
00214                                         }
00215                                         else
00216                                                 msg.append( "\n\tNot Locked");
00217 #endif
00218                                 }
00219                                 else 
00220                                         msg.append( "No detailed info present for item");
00221                         }
00222                 }
00223         } 
00224         else 
00225         {
00226                 rv = false;
00227 
00228                 if( p_assembleInfoMessage)
00229                 {
00230                         msg.append( "svn info command failed");
00231                 }
00232         }
00233 
00234         if( p_assembleInfoMessage)
00235                 p_resultMsg = msg;
00236 
00237         p_lastChangingAuthor = aut;
00238         p_lockOwner          = own;
00239 
00240         progressStr.Format(" DONE.\r\n");
00241         UpdateProgress(progressStr);
00242 
00243         return rv;
00244 }
00245 
00246 bool HiClient::tryLock             ( const std::string& p_path)
00247 {
00248         log( "tryLock", p_path);
00249 
00250         bool res = false;
00251         if( isLockedByOthers( p_path)) return res;
00252 
00253         CString progressStr;
00254         progressStr.Format("Try to lock: %s", (LPCTSTR)p_path.c_str());
00255         UpdateProgress(progressStr);
00256 
00257         Pool reqPool;
00258 
00259         res = sub_lock(Targets(p_path.c_str(), reqPool.pool()), /*comment =*/ "nc" , /*force =*/ false );
00260 
00261         progressStr.Format("(%s) DONE.\r\n", res ? _T("succeeded") : _T("failed"));
00262         UpdateProgress(progressStr);
00263 
00264         return res;
00265 }
00266 
00267 bool HiClient::unLock              ( const std::string& p_path)
00268 {
00269         log( "unLock", p_path);
00270 
00271         CString progressStr;
00272         progressStr.Format("Unlock: %s", (LPCTSTR)p_path.c_str());
00273         UpdateProgress(progressStr);
00274 
00275         Pool reqPool;
00276 
00277         bool res = sub_unlock(Targets(p_path.c_str(), reqPool.pool()));
00278 
00279         progressStr.Format("(%s) DONE.\r\n", res ? _T("succeeded") : _T("failed"));
00280         UpdateProgress(progressStr);
00281 
00282         return res;
00283 }
00284 
00285 bool HiClient::unLock              ( const std::vector< std::string> & p_pathVec)
00286 {
00287         if( p_pathVec.size() == 0) return false;
00288         log( "unLockVec", p_pathVec.front());
00289 
00290         CString progressStr;
00291         progressStr.Format("Unlock: ");
00292 
00293         Pool reqPool;
00294         Targets tgts(p_pathVec.front().c_str(), reqPool.pool());
00295         std::vector< std::string>::const_iterator it = p_pathVec.begin();
00296         std::vector< std::string>::const_iterator en = p_pathVec.end();
00297         for( ++it; it != en; ++it) {      // safe to perform ++it in the initialize phase, since it's not empty
00298                 tgts.add( (*it).c_str());
00299                 progressStr.Append((*it).c_str());
00300                 progressStr.Append(", ");
00301         }
00302         UpdateProgress(progressStr);
00303 
00304         bool res = sub_unlock( tgts);
00305 
00306         progressStr.Format("(%s) DONE.\r\n", res ? _T("succeeded") : _T("failed"));
00307         UpdateProgress(progressStr);
00308 
00309         return res;
00310 }
00311 
00312 bool HiClient::lockableProp        ( const std::string& p_path)
00313 {
00314         log( "lockableProp", p_path);
00315 
00316         CString progressStr;
00317         progressStr.Format("Set lockable property: %s", (LPCTSTR)p_path.c_str());
00318         UpdateProgress(progressStr);
00319 
00320         Pool reqPool;
00321 
00322         bool res = sub_propertySet( p_path.c_str(), "svn:needs-lock", /*value =*/ "na", /*recurse =*/ false, /*force =*/ false );
00323 
00324         progressStr.Format("(%s) DONE.\r\n", res ? _T("succeeded") : _T("failed"));
00325         UpdateProgress(progressStr);
00326 
00327         return res;
00328 }
00329 
00330 bool HiClient::getLatest           ( const std::string& p_path)
00331 {
00332         log( "getLatest", p_path);
00333 
00334         CString progressStr;
00335         progressStr.Format("Get latest: %s", (LPCTSTR)p_path.c_str());
00336         UpdateProgress(progressStr);
00337 
00338         Pool reqPool;
00339 
00340         UPDATE_RES res;
00341         bool succ = sub_update(Targets(p_path.c_str(), reqPool.pool()), Revision(), /*recurse =*/ true, /*ignoreExt =*/ false, res);
00342 
00343         progressStr.Format("(%s) DONE.\r\n", succ ? _T("succeeded") : _T("failed"));
00344         UpdateProgress(progressStr);
00345 
00346         return succ;
00347 }
00348 
00349 bool HiClient::lightCheckOut( const std::string& p_path, const std::string& p_localDir)
00350 {
00351         log( "checkOut", p_path);
00352 
00353         CString progressStr;
00354         progressStr.Format("Checkout: %s", (LPCTSTR)p_path.c_str());
00355         UpdateProgress(progressStr);
00356 
00357         Pool reqPool;
00358 
00359         bool res =  0 < sub_checkout( p_path.c_str(), p_localDir.c_str(), Revision(), Revision(), /*recurse =*/ true, /*ignoreExt =*/ false);
00360 
00361         progressStr.Format("(%s) DONE.\r\n", res ? _T("succeeded") : _T("failed"));
00362         UpdateProgress(progressStr);
00363 
00364         return res;
00365 }
00366 
00367 bool HiClient::commitAll           ( const std::string& p_path, const std::string& p_comment, bool p_keepCheckedOut)
00368 {
00369         log( "commitAll", p_path);
00370 
00371         CString progressStr;
00372         progressStr.Format("Commit all: %s", (LPCTSTR)p_path.c_str());
00373         UpdateProgress(progressStr);
00374 
00375         Pool reqPool;
00376 
00377         Targets tgt(p_path.c_str(), reqPool.pool()); // commit might return -1 if there were no things to commit (diff was 0)
00378         bool res = 0 < sub_commit( tgt, p_comment.c_str(), /*recurse =*/ true, /*noUnlock =*/ p_keepCheckedOut);
00379 
00380         progressStr.Format("(%s) DONE.\r\n", res ? _T("succeeded") : _T("failed"));
00381         UpdateProgress(progressStr);
00382 
00383         return res;
00384 }
00385 
00386 bool HiClient::add                 ( const std::string& p_path, bool p_recursive)
00387 {
00388         log( "add", p_path);
00389 
00390         CString progressStr;
00391         progressStr.Format("Add: %s", (LPCTSTR)p_path.c_str());
00392         UpdateProgress(progressStr);
00393 
00394         Pool reqPool;
00395 
00396         bool res = 0 < sub_add( p_path.c_str(), p_recursive);
00397 
00398         progressStr.Format("(%s) DONE.\r\n", res ? _T("succeeded") : _T("failed"));
00399         UpdateProgress(progressStr);
00400 
00401         return res;
00402 }
00403 
00404 bool HiClient::mkDirOnServer       ( const std::string& p_path)
00405 {
00406         log( "mkDirOnServer", p_path);
00407 
00408         CString progressStr;
00409         progressStr.Format("Make repository dir: %s", (LPCTSTR)p_path.c_str());
00410         UpdateProgress(progressStr);
00411 
00412         Pool reqPool;
00413 
00414         bool res = 0 < sub_mkdir2(Targets(p_path.c_str(), reqPool.pool()), "nm");
00415 
00416         progressStr.Format("(%s) DONE.\r\n", res ? _T("succeeded") : _T("failed"));
00417         UpdateProgress(progressStr);
00418 
00419         return res;
00420 }
00421 
00422 bool HiClient::cleanup( const std::string& p_path)
00423 {
00424         log( "cleanup", p_path);
00425 
00426         CString progressStr;
00427         progressStr.Format("Cleanup: %s", (LPCTSTR)p_path.c_str());
00428         UpdateProgress(progressStr);
00429 
00430         Pool reqPool;
00431         
00432         bool res = sub_cleanup( p_path.c_str());
00433 
00434         progressStr.Format("(%s) DONE.\r\n", res ? _T("succeeded") : _T("failed"));
00435         UpdateProgress(progressStr);
00436 
00437         return res;
00438 }
00439 
00440 bool HiClient::resolve( const std::string& p_path, bool p_recursive)
00441 {
00442         log( "resolve", p_path);
00443 
00444         CString progressStr;
00445         progressStr.Format("Resolve: %s", (LPCTSTR)p_path.c_str());
00446         UpdateProgress(progressStr);
00447 
00448         Pool reqPool;
00449 
00450         bool res = sub_resolved( p_path.c_str(), p_recursive);
00451         
00452         progressStr.Format("(%s) DONE.\r\n", res ? _T("succeeded") : _T("failed"));
00453         UpdateProgress(progressStr);
00454 
00455         return res;
00456 }
00457 
00458 bool HiClient::status( const std::string& p_path, bool p_assembleStatusMsg, std::string& p_statMsg)
00459 {
00460         log( "status", p_path);
00461 
00462         CString progressStr;
00463         progressStr.Format("Status: %s", (LPCTSTR)p_path.c_str());
00464         UpdateProgress(progressStr);
00465 
00466         Pool reqPool;
00467 
00468         bool        rv = false;
00469         std::string msg;
00470 
00471         ClientUtil::StatusExtInfoVec vec;
00472         vec = sub_extended_status( p_path.c_str(), false /* on_server*/);
00473         if( !vec.empty())
00474         {
00475                 rv = true;
00476 
00477                 if( p_assembleStatusMsg)
00478                 {
00479                         msg = "Svn status " + p_path + " command resulted in:\n";
00480                         for( ClientUtil::StatusExtInfoVec::iterator it = vec.begin(); it != vec.end(); ++it)
00481                         {
00482                                 //const char *                   m_path;
00483                                 //svn_wc_status2_t *             m_status;
00484 
00485                                 if( !it->m_status)
00486                                         msg.append( "Null status");
00487                                 else
00488                                 {
00489                                         std::string st;
00490                                         switch( it->m_status->text_status) {
00491                                         //case items copied from enum svn_wc_status_kind, svn_wc.h
00492                                         case svn_wc_status_none:        st += "Not exists "; break; 
00493                                         case svn_wc_status_unversioned: st += "Unversioned"; break; 
00494                                         case svn_wc_status_normal:      st += "Normal     "; break; 
00495                                         case svn_wc_status_added:       st += "Added      "; break; 
00496                                         case svn_wc_status_missing:     st += "Missing    "; break; 
00497                                         case svn_wc_status_deleted:     st += "Deleted    "; break; 
00498                                         case svn_wc_status_replaced:    st += "Replaced   "; break; 
00499                                         case svn_wc_status_modified:    st += "Modified   "; break; 
00500                                         case svn_wc_status_merged:      st += "Merged     "; break; 
00501                                         case svn_wc_status_conflicted:  st += "Conflicted "; break; 
00502                                         case svn_wc_status_ignored:     st += "Ignored    "; break; 
00503                                         case svn_wc_status_obstructed:  st += "Obstructed "; break; 
00504                                         case svn_wc_status_external:    st += "External   "; break; 
00505                                         case svn_wc_status_incomplete:  st += "Incomplete "; break; 
00506                                         default:                        st += "Unknown    ";
00507                                         };
00508 
00509                                         msg.append( st);
00510                                 }
00511                                 msg.append( " ");
00512                                 msg.append( ClientUtil::charstar2str( it->m_path, "Path"));
00513                                 if( it->m_status && it->m_status->locked)
00514                                         msg.append( " locked");
00515                                 if( it->m_status && it->m_status->repos_lock)
00516                                         msg.append( std::string( " by ") + ClientUtil::charstar2str( it->m_status->repos_lock->owner, "Owner"));
00517                                 msg.append( "\n");
00518                         }
00519                         p_statMsg = msg;
00520                 }
00521         }
00522         else // vec.empty()
00523         {
00524                 if( p_assembleStatusMsg)
00525                         p_statMsg = "svn status command failed";
00526         }
00527 
00528         progressStr.Format("(%s) DONE.\r\n", (LPCTSTR)p_statMsg.c_str());
00529         UpdateProgress(progressStr);
00530 
00531         return rv;
00532 }
00533 
00534 
00535 bool HiClient::statusOnServer( const std::string& p_path, bool p_assembleStatusMsg, std::string& p_statMsg, bool* p_outOfDate, bool *p_repoEntryModified)
00536 {
00537         log( "statusOnServer", p_path);
00538 
00539         CString progressStr;
00540         progressStr.Format("Status on server: %s", (LPCTSTR)p_path.c_str());
00541         UpdateProgress(progressStr);
00542 
00543         Pool reqPool;
00544 
00545         bool        rv = false;
00546         std::string msg;
00547 
00548         ClientUtil::StatusExtInfoVec vec;
00549         vec = sub_extended_status( p_path.c_str(), true /* on_server*/);
00550         if( !vec.empty())
00551         {
00552                 rv = true;
00553 
00554                 msg = "Svn status " + p_path + " command resulted in:\n";
00555                 for( ClientUtil::StatusExtInfoVec::iterator it = vec.begin(); it != vec.end(); ++it)
00556                 {
00557                         //const char *                   m_path;
00558                         //svn_wc_status2_t *             m_status;
00559 
00560                         ASSERT( it->m_status);
00561                         if( it->m_status) 
00562                         {
00563 
00564                                 bool is_repos_text_status_modified = it->m_status->repos_text_status == svn_wc_status_modified;
00565                                 bool is_local_copy_out_of_date     = it->m_status->ood_last_cmt_rev != SVN_INVALID_REVNUM && it->m_status->entry->revision < it->m_status->ood_last_cmt_rev;
00566 
00567                                 if( p_outOfDate)               // valid ptr
00568                                         *p_outOfDate = is_local_copy_out_of_date;
00569                                 if( p_repoEntryModified)       // valid ptr
00570                                         *p_repoEntryModified = is_repos_text_status_modified;
00571 
00572                                 if( p_assembleStatusMsg)
00573                                 {
00574                                         if( 1)
00575                                         {
00576                                                 std::string st;
00577                                                 switch( it->m_status->text_status) {
00578                                                 //case items copied from enum svn_wc_status_kind, svn_wc.h
00579                                                 case svn_wc_status_none:        st += "Not exists "; break; 
00580                                                 case svn_wc_status_unversioned: st += "Unversioned"; break; 
00581                                                 case svn_wc_status_normal:      st += "Normal     "; break; 
00582                                                 case svn_wc_status_added:       st += "Added      "; break; 
00583                                                 case svn_wc_status_missing:     st += "Missing    "; break; 
00584                                                 case svn_wc_status_deleted:     st += "Deleted    "; break; 
00585                                                 case svn_wc_status_replaced:    st += "Replaced   "; break; 
00586                                                 case svn_wc_status_modified:    st += "Modified   "; break; 
00587                                                 case svn_wc_status_merged:      st += "Merged     "; break; 
00588                                                 case svn_wc_status_conflicted:  st += "Conflicted "; break; 
00589                                                 case svn_wc_status_ignored:     st += "Ignored    "; break; 
00590                                                 case svn_wc_status_obstructed:  st += "Obstructed "; break; 
00591                                                 case svn_wc_status_external:    st += "External   "; break; 
00592                                                 case svn_wc_status_incomplete:  st += "Incomplete "; break; 
00593                                                 default:                        st += "Unknown    ";
00594                                                 };
00595 
00596                                                 msg.append( st);
00597                                         }
00598 
00599                                         if( is_local_copy_out_of_date)
00600                                                 msg.append( " [Local copy out of date]");
00601 
00602                                         if( is_repos_text_status_modified)
00603                                                 msg.append( " [Server copy modified]");
00604 
00605                                         msg.append( " ");
00606                                         msg.append( ClientUtil::charstar2str( it->m_path, "Path"));
00607 
00608                                         if( it->m_status->locked)
00609                                                 msg.append( " locked");
00610                                         if( it->m_status->repos_lock)
00611                                                 msg.append( std::string( " by ") + ClientUtil::charstar2str( it->m_status->repos_lock->owner, "Owner"));
00612 
00613                                         msg.append( "\n");
00614                                 }
00615                         }
00616                         else
00617                                 msg.append( "Null status");
00618                 }
00619                 if( p_assembleStatusMsg)
00620                         p_statMsg = msg;
00621         }
00622         else // vec.empty()
00623         {
00624                 if( p_assembleStatusMsg)
00625                         p_statMsg = "svn status command failed";
00626         }
00627 
00628         progressStr.Format("(%s) DONE.\r\n", (LPCTSTR)p_statMsg.c_str());
00629         UpdateProgress(progressStr);
00630 
00631         return rv;
00632 }
00633 
00634 bool HiClient::speedLock( const std::vector< std::string> & pathVec, std::string &msg)
00635 {
00636         if( pathVec.size() == 0) return true;
00637         log( "speedLock", pathVec.front());
00638 
00639         CString progressStr("Speed lock: ");
00640 
00641         Pool reqPool;
00642 
00643         svn_error_t *err;
00644         apr_array_header_t* targets;
00645         
00646         targets = apr_array_make( reqPool.pool(), pathVec.size(), sizeof(const char *));
00647         for( std::vector< std::string>::size_type i = 0; i < pathVec.size(); ++i) {
00648                 const svn_wc_entry_t *entry;
00649                 const char *dirent;
00650                 const char *pathent;
00651                 svn_wc_adm_access_t *adm_access;
00652 
00653                 progressStr.Append(pathVec[i].c_str());
00654                 progressStr.Append(", ");
00655 
00656                 pathent = svn_dirent_internal_style(pathVec[i].c_str(), reqPool.pool());
00657                 dirent = svn_dirent_dirname( pathent, reqPool.pool());
00658                 err = svn_wc_adm_open( &adm_access, NULL, dirent, FALSE, FALSE, reqPool.pool());
00659                 if (err)
00660                 {
00661                         char errbuff[BUFSIZ];
00662                         const char* errbuff2 = svn_err_best_message(err, errbuff, BUFSIZ);
00663                         msg.append(errbuff2 ? errbuff2 : errbuff);
00664                         progressStr.Append(_T(" FAILED.\r\n"));
00665                         UpdateProgress(progressStr);
00666                         return false;
00667                 }
00668 
00669 
00670                 err = svn_wc_entry( &entry, pathent, adm_access, FALSE, reqPool.pool());
00671                 if (err)
00672                 {
00673                         char errbuff[BUFSIZ];
00674                         const char* errbuff2 = svn_err_best_message(err, errbuff, BUFSIZ);
00675                         msg.append(errbuff2 ? errbuff2 : errbuff);
00676                         progressStr.Append(_T(" FAILED.\r\n"));
00677                         UpdateProgress(progressStr);
00678                         return false;
00679                 }
00680 
00681                 err = svn_wc_adm_close( adm_access);
00682                 if (err)
00683                 {
00684                         char errbuff[BUFSIZ];
00685                         const char* errbuff2 = svn_err_best_message(err, errbuff, BUFSIZ);
00686                         msg.append(errbuff2 ? errbuff2 : errbuff);
00687                         progressStr.Append(_T(" FAILED.\r\n"));
00688                         UpdateProgress(progressStr);
00689                         return false;
00690                 }
00691 
00692                 if (entry && !entry->lock_token) {
00693                         const char ** ptr = (const char**)apr_array_push(targets);
00694                         *ptr = pathent;
00695                 }
00696         }
00697 
00698         svn_client_ctx_t *ctx = getContext(NULL, reqPool.pool());
00699         if(ctx == NULL)
00700         {
00701                 msg.append("Unable to create subversion client context");
00702                 progressStr.Append(_T(" FAILED.\r\n"));
00703                 UpdateProgress(progressStr);
00704                 return false;
00705         }
00706 
00707         m_notify2->m_msg.clear();
00708         m_notify2->m_OK = true;
00709 
00710         err = svn_client_lock(targets, "", FALSE, ctx, reqPool.pool());
00711   
00712         if (err)
00713     {
00714                 char errbuff[BUFSIZ];
00715                 const char* errbuff2 = svn_err_best_message(err, errbuff, BUFSIZ);
00716                 msg.append(errbuff2 ? errbuff2 : errbuff);
00717                 progressStr.Append(_T(" FAILED.\r\n"));
00718                 UpdateProgress(progressStr);
00719                 return false;
00720     }
00721 
00722         if (! m_notify2->m_OK ) {
00723                 msg.append(m_notify2->m_msg);
00724                 progressStr.Append(_T(" FAILED.\r\n"));
00725                 UpdateProgress(progressStr);
00726                 return false;
00727         }
00728         
00729         progressStr.Append(_T(" DONE.\r\n"));
00730         UpdateProgress(progressStr);
00731         return true;
00732 }
00733 
00734 //#if(0)
00735 //                      msg = "After issuing 'svn info "; msg += ClientUtil::charstar2str( p_path.c_str(), "Url"); msg += "'";
00736 //                      for( ClientUtil::InfoHelp::InfoVecConIter it = inf.begin(), en = inf.end(); it != en; ++it)
00737 //                      {
00738 //                              msg.append( "\nI know about: '");
00739 //                              msg.append( ClientUtil::charstar2str( it->m_path, "Path"));
00740 //                              msg.append( "' the following:");
00741 //                              if( it->m_info)
00742 //                              {
00743 //                                      if( !aut.empty()) aut.append( ", "); // if multiple entries in inf, then separate authors by ,
00744 //
00745 //                                      msg.append( "\n\tLast Changed Author: "); 
00746 //                                      aut.append( ClientUtil::charstar2str( it->m_info->last_changed_author, "Author"));
00747 //                                      msg.append( ClientUtil::charstar2str( it->m_info->last_changed_author, "Author"));
00748 //
00749 //                                      msg.append( "\n\tVersioned as (URL): "); 
00750 //                                      msg.append( ClientUtil::charstar2str( it->m_info->URL, "Url"));
00751 //                                      
00752 //                                      if( it->m_info->lock)
00753 //                                      {
00754 //                                              msg.append( "\n\tLocked by "); 
00755 //                                              if( !own.empty()) own.append( ", "); // if multiple entries in inf, then separate owners by ,
00756 //
00757 //                                              own.append( ClientUtil::charstar2str( it->m_info->lock->owner, "LockOwner"));
00758 //                                              msg.append( ClientUtil::charstar2str( it->m_info->lock->owner, "LockOwner"));
00759 //                                      }
00760 //                                      else
00761 //                                              msg.append( "\n\tNot Locked");
00762 //                              }
00763 //                              else 
00764 //                                      msg.append( "No detailed info present for item");
00765 //                      }
00766 //#endif
00767 
00768 #endif