SG_bool SG_context__has_err(const SG_context* pCtx) { SG_ASSERT( pCtx ); return ( SG_CONTEXT__HAS_ERR(pCtx) ); }
void SG_password__get( SG_context *pCtx, const char *szRepoSpec, const char *szUsername, SG_string **ppstrPassword) { SG_string* pstrTarget = NULL; SG_string* pstrPassword = NULL; LPWSTR pwszTarget = NULL; SG_byte* pbPassword = NULL; PCREDENTIAL pCred = NULL; BOOL result = FALSE; SG_NULLARGCHECK_RETURN(szRepoSpec); SG_NULLARGCHECK_RETURN(szUsername); SG_NULLARGCHECK_RETURN(ppstrPassword); _get_key(pCtx, szRepoSpec, szUsername, &pstrTarget); if (SG_CONTEXT__HAS_ERR(pCtx)) { SG_error err, err2; err2 = SG_context__get_err(pCtx, &err); if (SG_IS_ERROR(err2)) { SG_ERR_DISCARD; SG_ERR_THROW(err2); } if (err & __SG_ERR__GETLASTERROR__) SG_ERR_DISCARD; else SG_ERR_RETHROW; } if (pstrTarget) { SG_ERR_CHECK( SG_utf8__extern_to_os_buffer__wchar(pCtx, SG_string__sz(pstrTarget), &pwszTarget, NULL) ); result = CredReadW(pwszTarget, CRED_TYPE_GENERIC, 0, &pCred); if (!result) { DWORD err = GetLastError(); if (err != ERROR_NOT_FOUND && err != ERROR_NO_SUCH_LOGON_SESSION) SG_ERR_THROW2( SG_ERR_GETLASTERROR(GetLastError()), (pCtx, "%s", "unable to retrieve saved credentials") ); } else { SG_uint32 size = pCred->CredentialBlobSize+sizeof(wchar_t); SG_ERR_CHECK( SG_allocN(pCtx, pCred->CredentialBlobSize+sizeof(wchar_t), pbPassword) ); memcpy(pbPassword, pCred->CredentialBlob, size); SG_ERR_CHECK( SG_string__alloc(pCtx, &pstrPassword) ); SG_ERR_CHECK( SG_utf8__intern_from_os_buffer__wchar(pCtx, pstrPassword, (const LPWSTR)pbPassword) ); *ppstrPassword = pstrPassword; pstrPassword = NULL; } } /* fall through */ fail: SG_STRING_NULLFREE(pCtx, pstrTarget); SG_STRING_NULLFREE(pCtx, pstrPassword); SG_NULLFREE(pCtx, pwszTarget); SG_NULLFREE(pCtx, pbPassword); if (pCred) CredFree(pCred); }
void sg_vv2__history__repo2( SG_context * pCtx, SG_repo * pRepo, const SG_stringarray * psaArgs, // if present these must be full repo-paths const SG_rev_spec* pRevSpec, const SG_rev_spec* pRevSpec_single_revisions, const char* pszUser, const char* pszStamp, SG_uint32 nResultLimit, SG_bool bHideObjectMerges, SG_int64 nFromDate, SG_int64 nToDate, SG_bool bListAll, SG_bool bReassembleDag, SG_bool* pbHasResult, SG_history_result ** ppResult, SG_history_token ** ppHistoryToken) { SG_stringarray * pStringArrayChangesets_starting = NULL; SG_stringarray * pStringArrayChangesetsMissing = NULL; SG_stringarray * pStringArrayChangesets_single_revisions = NULL; SG_bool bRecommendDagWalk = SG_FALSE; SG_bool bLeaves = SG_FALSE; const char * pszCurrentDagnodeID = NULL; SG_stringarray * pStringArrayGIDs = NULL; SG_uint32 i = 0, nChangesetCount = 0; SG_uint32 count_args = 0; //Determine the starting changeset IDs. strBranch and bLeaves control this. //We do this step here, so that repo paths can be looked up before we call into history__core. SG_ERR_CHECK( sg_vv2__history__get_starting_changesets(pCtx, pRepo, pRevSpec, &pStringArrayChangesets_starting, &pStringArrayChangesetsMissing, &bRecommendDagWalk, &bLeaves) ); if (pStringArrayChangesetsMissing) { // See K2177, K1322, W0836, W8132. We requested specific starting // points and ran into some csets that were referenced (by --tag // or --branch) that are not present in the local repo. Try to // silently ignore them. SG_uint32 nrFound = 0; SG_ERR_CHECK( SG_stringarray__count(pCtx, pStringArrayChangesets_starting, &nrFound) ); if (nrFound > 0) { // Yes there were missing csets, but we still found some // of the referenced ones. Just ignore the missing ones. // This should behave just like we had the older tag/branch // dag prior to the push -r on the vc dag. } else { const char * psz_0; // TODO 2012/10/19 Do we want a different message if the number of missing is > 1 ? SG_ERR_CHECK( SG_stringarray__get_nth(pCtx, pStringArrayChangesetsMissing, 0, &psz_0) ); SG_ERR_THROW2( SG_ERR_CHANGESET_BLOB_NOT_FOUND, (pCtx, "%s", psz_0) ); } } if (bListAll) { // See W8493. If they gave us a --list-all along with a --rev or --tag, they // want to force us to show the full history rather than just the info for the // named cset. bRecommendDagWalk = SG_TRUE; } if (pRevSpec_single_revisions) { // We DO NOT pass a psaMissingHids here because we want // it to throw if the user names a missing cset. SG_ERR_CHECK( SG_rev_spec__get_all__repo__dedup(pCtx, pRepo, pRevSpec_single_revisions, SG_TRUE, &pStringArrayChangesets_single_revisions, NULL) ); } // TODO 2012/07/02 Is the following loop really what we want? // TODO As written, it will look at each changeset // TODO in the list and lookup each item's GID with // TODO it. If cset[k] does not have *ALL* of the // TODO items, we discard the array of GIDs already // TODO discovered and then try cset[k+1]. // TODO // TODO This seems wasteful and likely to fail in // TODO the presence of lots of adds and deletes. // TODO // TODO Seems like it would be better to start the // TODO result list outside of the loop and remove // TODO items from the search list as we find them // TODO as we iterate over the csets. This would // TODO let us stop as soon as we have them all and // TODO not require us to repeat the expensive mapping // TODO of repo-path to gid. // TODO // TODO Then again, I think the caller has limited us // TODO to only having *1* item in the set of files/folders, // TODO so this might not actually matter. if (psaArgs) SG_ERR_CHECK( SG_stringarray__count(pCtx, psaArgs, &count_args) ); if (count_args > 0) { SG_ERR_CHECK( SG_stringarray__count(pCtx, pStringArrayChangesets_starting, &nChangesetCount) ); //Look up the GIDs for all of the arguments. //Try every changeset, until we get one that has the GID in question. for (i = 0; i < nChangesetCount; i++) { SG_ERR_CHECK( SG_stringarray__get_nth(pCtx, pStringArrayChangesets_starting, i, &pszCurrentDagnodeID) ); //This might be used if you have --leaves, or if there are multiple parents //since they specified a changeset, we need to use the full repo path @/blah/blah to look up the objects sg_vv2__history__lookup_gids_by_repopaths(pCtx, pRepo, pszCurrentDagnodeID, psaArgs, &pStringArrayGIDs); if (SG_CONTEXT__HAS_ERR(pCtx)) { if (i == (nChangesetCount - 1) || ! SG_context__err_equals(pCtx, SG_ERR_NOT_FOUND) ) { SG_STRINGARRAY_NULLFREE(pCtx, pStringArrayGIDs); SG_ERR_RETHROW; } else { SG_STRINGARRAY_NULLFREE(pCtx, pStringArrayGIDs); SG_context__err_reset(pCtx); } } else break; } } //Call history core with the GIDs SG_ERR_CHECK( SG_history__run(pCtx, pRepo, pStringArrayGIDs, pStringArrayChangesets_starting, pStringArrayChangesets_single_revisions, pszUser, pszStamp, nResultLimit, bLeaves, bHideObjectMerges, nFromDate, nToDate, bRecommendDagWalk, bReassembleDag, pbHasResult, ppResult, ppHistoryToken) ); fail: SG_STRINGARRAY_NULLFREE(pCtx, pStringArrayGIDs); SG_STRINGARRAY_NULLFREE(pCtx, pStringArrayChangesets_starting); SG_STRINGARRAY_NULLFREE(pCtx, pStringArrayChangesetsMissing); SG_STRINGARRAY_NULLFREE(pCtx, pStringArrayChangesets_single_revisions); }