/** * Add the given "entryname" to the portability-collider and THROW * if there are any issues/problems. * * Since a PARTIAL COMMIT has the ability to include some changes * and not include other changes, we have to re-verify that the * set of items to be included in a TREENODE is well-defined. * * pszEntryname contains the item's entryname as we want it to * appear in the final TREENODE/TREENODEENTRY. * * pStringRepoPath contains the item's path for error messages. * the entryname in this path may be different from the given * entryname (such as when we want to test with the baseline * version of the entryname for a non-participating item, but * want to complain using the current pathname). * */ void sg_wc_tx__commit__queue__utils__check_port(SG_context * pCtx, SG_wc_port * pPort, const char * pszEntryname, SG_treenode_entry_type tneType, const SG_string * pStringRepoPath) { const SG_string * pStringItemLog = NULL; // we don't own this SG_wc_port_flags portFlags; SG_bool bIsDuplicate; SG_ERR_CHECK( SG_wc_port__add_item(pCtx, pPort, NULL, pszEntryname, tneType, &bIsDuplicate) ); if (bIsDuplicate) SG_ERR_THROW2( SG_ERR_PENDINGTREE_PARTIAL_CHANGE_COLLISION, (pCtx, "Partial commit would cause collision: '%s' (%s)", pszEntryname, SG_string__sz(pStringRepoPath)) ); SG_ERR_CHECK( SG_wc_port__get_item_result_flags(pCtx, pPort, pszEntryname, &portFlags, &pStringItemLog) ); if (portFlags) SG_ERR_THROW2( SG_ERR_WC_PORT_FLAGS, (pCtx, "Partial commit could (potentially) cause problems: '%s' (%s)\n%s", pszEntryname, SG_string__sz(pStringRepoPath), SG_string__sz(pStringItemLog)) ); // the item does not cause problems. fail: return; }
/** * Create a pathname in the per-file temp-dir for one * version of the file. * * We use the ancestor version of the entryname * to avoid issues with pending renames. * */ void _sg_mrg__create_pathname_for_conflict_file(SG_context * pCtx, SG_mrg * pMrg, SG_mrg_cset_entry_conflict * pMrgCSetEntryConflict, const char * pszPrefix, SG_pathname ** ppPathReturned) { SG_pathname * pPath = NULL; SG_string * pString = NULL; SG_ERR_CHECK( _sg_mrg__ensure_temp_dir_for_file_conflict(pCtx, pMrg, pMrgCSetEntryConflict) ); // create something like: "<sgtemp>/<gid7>_YYYYMMDD_<k>/<prefix>~<entryname>" SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pString) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pString, "%s~%s", pszPrefix, SG_string__sz(pMrgCSetEntryConflict->pMrgCSetEntry_Ancestor->pStringEntryname)) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPath, pMrgCSetEntryConflict->pPathTempDirForFile, SG_string__sz(pString)) ); SG_STRING_NULLFREE(pCtx, pString); *ppPathReturned = pPath; return; fail: SG_STRING_NULLFREE(pCtx, pString); SG_PATHNAME_NULLFREE(pCtx, pPath); }
void SG_getopt__print_option(SG_context* pCtx, SG_console_stream cs, SG_getopt_option* opt, const char * overrideDesc) { SG_string *opts; if (opt == NULL) { SG_ERR_IGNORE( SG_console(pCtx, cs, "?") ); return; } SG_ERR_CHECK( SG_string__alloc(pCtx, &opts) ); /* We have a valid option which may or may not have a "short name" (a single-character alias for the long option). */ if (opt->optch <= 255) SG_ERR_CHECK( SG_string__sprintf(pCtx, opts, "-%c [--%s]", opt->optch, opt->pStringName) ); else SG_ERR_CHECK( SG_string__sprintf(pCtx, opts, "--%s", opt->pStringName) ); if (opt->has_arg) SG_ERR_CHECK( SG_string__append__sz(pCtx, opts, " ARG") ); if (overrideDesc) SG_ERR_IGNORE( SG_console(pCtx, cs, "%-20s : %s\n", SG_string__sz(opts), overrideDesc) ); else SG_ERR_IGNORE( SG_console(pCtx, cs, "%-20s : %s\n", SG_string__sz(opts), opt->pStringDescription) ); fail: SG_STRING_NULLFREE(pCtx, opts); }
void SG_localsettings__varray__append(SG_context * pCtx, const char* psz_path, const char* pValue) { SG_jsondb* p = NULL; SG_string* pstr = NULL; SG_varray* pva = NULL; SG_string* pstr_path_found = NULL; SG_ASSERT(pCtx); SG_NONEMPTYCHECK_RETURN(psz_path); SG_ERR_CHECK( SG_closet__get_localsettings(pCtx, &p) ); SG_ERR_CHECK( SG_localsettings__get__varray(pCtx, psz_path, NULL, &pva, &pstr_path_found) ); if (!pstr_path_found) { // this came from factory defaults. SG_ERR_CHECK( SG_string__alloc(pCtx, &pstr_path_found) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path_found, "%s/%s", SG_LOCALSETTING__SCOPE__MACHINE, psz_path) ); SG_ERR_CHECK( SG_localsettings__update__varray(pCtx, SG_string__sz(pstr_path_found), pva) ); } SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr, "%s/#", SG_string__sz(pstr_path_found)) ); SG_ERR_CHECK( SG_jsondb__update__string__sz(pCtx, p, SG_string__sz(pstr), SG_TRUE, pValue) ); fail: SG_STRING_NULLFREE(pCtx, pstr); SG_JSONDB_NULLFREE(pCtx, p); SG_VARRAY_NULLFREE(pCtx, pva); SG_STRING_NULLFREE(pCtx, pstr_path_found); }
void SG_sync__remember_sync_target(SG_context* pCtx, const char * pszLocalRepoDescriptor, const char * pszSyncTarget) { SG_string * pString = NULL; SG_varray * pva_targets = NULL; SG_bool bFound = SG_FALSE; SG_uint32 nEntry = 0; //Save this destination to the local setting of previously used destinations. SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pString) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pString, "%s/%s/%s", SG_LOCALSETTING__SCOPE__INSTANCE, pszLocalRepoDescriptor, SG_LOCALSETTING__SYNC_TARGETS) ); SG_ERR_CHECK( SG_localsettings__get__varray(pCtx, SG_string__sz(pString), NULL, &pva_targets, NULL) ); if (pva_targets) SG_ERR_CHECK( SG_varray__find__sz(pCtx, pva_targets, pszSyncTarget, &bFound, &nEntry) ); else SG_VARRAY__ALLOC(pCtx, &pva_targets); if (!bFound) { SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_targets, pszSyncTarget) ); SG_ERR_CHECK( SG_localsettings__update__varray(pCtx, SG_string__sz(pString), pva_targets) ); } fail: SG_STRING_NULLFREE(pCtx, pString); SG_VARRAY_NULLFREE(pCtx, pva_targets); }
void sg_sync_client__http__get_dagnode_info( SG_context* pCtx, SG_sync_client* pSyncClient, SG_vhash* pvhRequest, SG_history_result** ppInfo) { SG_string* pstrRequest = NULL; char* pszUrl = NULL; SG_string* pstr = NULL; SG_NULLARGCHECK_RETURN(pSyncClient); SG_NULLARGCHECK_RETURN(pvhRequest); SG_NULLARGCHECK_RETURN(ppInfo); SG_ERR_CHECK( _get_sync_url(pCtx, pSyncClient->psz_remote_repo_spec, SYNC_URL_SUFFIX "/incoming" JSON_URL_SUFFIX, NULL, NULL, &pszUrl) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstrRequest) ); SG_ERR_CHECK( SG_vhash__to_json(pCtx, pvhRequest, pstrRequest) ); SG_ERR_CHECK( do_url(pCtx, pszUrl, "GET", SG_string__sz(pstrRequest), pSyncClient->psz_username, pSyncClient->psz_password, &pstr, NULL, SG_TRUE) ); SG_ERR_CHECK( SG_history_result__from_json(pCtx, SG_string__sz(pstr), ppInfo) ); /* fall through */ fail: SG_NULLFREE(pCtx, pszUrl); SG_STRING_NULLFREE(pCtx, pstrRequest); SG_STRING_NULLFREE(pCtx, pstr); }
void SG_password__get( SG_context *pCtx, const char *szRepoSpec, const char *username, SG_string **pPassword) { SG_byte *pwdata = NULL; SG_uint32 pwlen; SG_string *password = NULL; SG_string *path = NULL; SG_string *server = NULL; SecProtocolType proto; SG_uint32 port; SG_bool isValid = SG_FALSE; OSStatus findRes; SG_NULLARGCHECK_RETURN(pPassword); *pPassword = NULL; SG_NULLARGCHECK(username); SG_NULLARGCHECK(szRepoSpec); SG_ERR_CHECK( _sg_password__parse_url(pCtx, szRepoSpec, &isValid, &proto, &server, &path, &port) ); if (! isValid) SG_ERR_THROW(SG_ERR_NOTIMPLEMENTED); findRes = SecKeychainFindInternetPassword( NULL, SG_STRLEN( SG_string__sz(server) ), SG_string__sz(server), 0, NULL, SG_STRLEN(username), username, SG_STRLEN( SG_string__sz(path) ), SG_string__sz(path), port, proto, kSecAuthenticationTypeDefault, (UInt32 *)&pwlen, (void **)&pwdata, NULL); if (findRes == errSecItemNotFound || findRes == errSecInteractionNotAllowed) goto fail; else if (findRes != errSecSuccess) _SG_THROW_MAC_SEC_ERROR(findRes); SG_ERR_CHECK( SG_STRING__ALLOC__BUF_LEN(pCtx, &password, pwdata, pwlen) ); *pPassword = password; password = NULL; fail: if (pwdata) SecKeychainItemFreeContent(NULL, pwdata); SG_STRING_NULLFREE(pCtx, path); SG_STRING_NULLFREE(pCtx, server); SG_STRING_NULLFREE(pCtx, password); }
void SG_localsettings__varray__remove_first_match(SG_context * pCtx, const char* psz_path, const char* psz_val) { SG_jsondb* p = NULL; SG_string* pstr_path_element = NULL; SG_varray* pva = NULL; SG_uint32 ndx = 0; SG_uint32 count = 0; SG_uint32 i = 0; SG_bool b_found = SG_FALSE; SG_string* pstr_path_found = NULL; SG_ASSERT(pCtx); SG_NONEMPTYCHECK_RETURN(psz_path); SG_ERR_CHECK( SG_closet__get_localsettings(pCtx, &p) ); SG_ERR_CHECK( SG_localsettings__get__varray(pCtx, psz_path, NULL, &pva, &pstr_path_found) ); if (pva) { if (!pstr_path_found) { // this came from factory defaults. SG_ERR_CHECK( SG_string__alloc(pCtx, &pstr_path_found) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path_found, "%s/%s", SG_LOCALSETTING__SCOPE__MACHINE, psz_path) ); SG_ERR_CHECK( SG_localsettings__update__varray(pCtx, SG_string__sz(pstr_path_found), pva) ); } SG_ERR_CHECK( SG_varray__count(pCtx, pva, &count) ); for (i=0; i<count; i++) { const char* psz = NULL; SG_ERR_CHECK( SG_varray__get__sz(pCtx, pva, i, &psz) ); if (0 == strcmp(psz, psz_val)) { b_found = SG_TRUE; ndx = i; break; } } if (b_found) { SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr_path_element) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path_element, "%s/%d", SG_string__sz(pstr_path_found), ndx) ); SG_ERR_CHECK( SG_jsondb__remove(pCtx, p, SG_string__sz(pstr_path_element)) ); } } fail: SG_VARRAY_NULLFREE(pCtx, pva); SG_STRING_NULLFREE(pCtx, pstr_path_found); SG_STRING_NULLFREE(pCtx, pstr_path_element); SG_JSONDB_NULLFREE(pCtx, p); }
static void _default_replacer( SG_context * pCtx, const _request_headers *pRequestHeaders, SG_string *keyword, SG_string *replacement, SG_bool *needEncoding) { SG_string *pstrRepoDescriptorName = NULL; SG_repo *repo = NULL; SG_UNUSED(pRequestHeaders); if (seq(keyword, "WFREPO")) { SG_ERR_CHECK( _getDescriptorName(pCtx, pRequestHeaders, &pstrRepoDescriptorName) ); SG_ERR_CHECK( SG_string__set__string(pCtx, replacement, pstrRepoDescriptorName) ); } else if (seq(keyword, "USERNAME")) { SG_ERR_CHECK( _getDescriptorName(pCtx, pRequestHeaders, &pstrRepoDescriptorName) ); if (pstrRepoDescriptorName != NULL) { SG_ERR_CHECK( SG_repo__open_repo_instance(pCtx, SG_string__sz(pstrRepoDescriptorName), &repo) ); } SG_ERR_CHECK( _getUserId(pCtx, repo, replacement) ); } else if (seq(keyword, "EMAIL")) { SG_ERR_CHECK( _getDescriptorName(pCtx, pRequestHeaders, &pstrRepoDescriptorName) ); if (pstrRepoDescriptorName != NULL) { SG_ERR_CHECK( SG_repo__open_repo_instance(pCtx, SG_string__sz(pstrRepoDescriptorName), &repo) ); } SG_ERR_CHECK( _getUserEmail(pCtx, repo, replacement) ); } else if (seq(keyword, "USERSELECTION")) { SG_ERR_CHECK( _getDescriptorName(pCtx, pRequestHeaders, &pstrRepoDescriptorName) ); SG_ERR_CHECK( _fillInUserSelection(pCtx, pstrRepoDescriptorName, replacement) ); *needEncoding = SG_FALSE; } fail: SG_STRING_NULLFREE(pCtx, pstrRepoDescriptorName); SG_REPO_NULLFREE(pCtx, repo); }
void SG_dbrecord__save_to_repo(SG_context* pCtx, SG_dbrecord * pRecord, SG_repo * pRepo, SG_repo_tx_handle* pRepoTx, SG_uint64* iBlobFullLength) { SG_string * pString = NULL; char* pszHidComputed = NULL; SG_uint32 iLength = 0; SG_NULLARGCHECK_RETURN(pRepo); SG_NULLARGCHECK_RETURN(pRecord); // serialize the dbrecord into JSON string. SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pString) ); SG_ERR_CHECK( SG_dbrecord__to_json(pCtx, pRecord,pString) ); #if 0 printf("%s\n", SG_string__sz(pString)); // TODO remove this #endif // remember the length of the blob iLength = SG_string__length_in_bytes(pString); *iBlobFullLength = (SG_uint64) iLength; // create a blob in the repository using the JSON string. this computes the HID and returns it. SG_repo__store_blob_from_memory(pCtx, pRepo,pRepoTx, NULL, // TODO pass the record id into here SG_FALSE, (const SG_byte *)SG_string__sz(pString), iLength, &pszHidComputed); if (!SG_context__has_err(pCtx) || SG_context__err_equals(pCtx, SG_ERR_BLOBFILEALREADYEXISTS)) { // freeeze the dbrecord memory-object and effectively make it read-only // from this point forward. we give up our ownership of the HID. SG_ASSERT( pszHidComputed ); _sg_dbrecord__freeze(pCtx, pRecord, pszHidComputed); pszHidComputed = NULL; SG_STRING_NULLFREE(pCtx, pString); return; // return _OK or __BLOBFILEALREADYEXISTS } fail: SG_STRING_NULLFREE(pCtx, pString); SG_NULLFREE(pCtx, pszHidComputed); }
void SG_password__set( SG_context* pCtx, const char *szRepoSpec, SG_string *pUserName, SG_string *pPassword) { const char *username; const char *password; SG_string *path = NULL; SG_string *server = NULL; SG_string *proto = NULL; SG_uint32 port; SG_bool isValid = SG_FALSE; GnomeKeyringResult saveRes = 0; guint32 itemid = 0; if (! SG_password__supported()) goto fail; SG_NULLARGCHECK(pUserName); SG_NULLARGCHECK(pPassword); SG_NULLARGCHECK(szRepoSpec); username = SG_string__sz(pUserName); password = SG_string__sz(pPassword); SG_ERR_CHECK( _sg_password__parse_url(pCtx, szRepoSpec, &isValid, &proto, &server, &path, &port) ); if (! isValid) SG_ERR_THROW(SG_ERR_NOTIMPLEMENTED); saveRes = gnome_keyring_set_network_password_sync( NULL, username, NULL, SG_string__sz(server), SG_string__sz(path), SG_string__sz(proto), NULL, (guint32)port, password, &itemid); if ((saveRes != GNOME_KEYRING_RESULT_OK) && (saveRes != GNOME_KEYRING_RESULT_NO_MATCH) && (saveRes != GNOME_KEYRING_RESULT_CANCELLED)) _SG_THROW_LINUX_SEC_ERROR(saveRes); fail: SG_STRING_NULLFREE(pCtx, path); SG_STRING_NULLFREE(pCtx, server); SG_STRING_NULLFREE(pCtx, proto); }
void SG_workingdir__generate_and_create_temp_dir_for_purpose(SG_context * pCtx, const SG_pathname * pPathWorkingDirectoryTop, const char * pszPurpose, SG_pathname ** ppPathTempDir) { SG_pathname * pPathTempRoot = NULL; SG_pathname * pPath = NULL; SG_string * pString = NULL; SG_int64 iTimeUTC; SG_time tmLocal; SG_uint32 kAttempt = 0; SG_NONEMPTYCHECK_RETURN(pszPurpose); SG_NULLARGCHECK_RETURN(ppPathTempDir); // get path to "<wd-top>/.sgtemp". SG_ERR_CHECK( SG_workingdir__get_temp_path(pCtx,pPathWorkingDirectoryTop,&pPathTempRoot) ); SG_ERR_CHECK( SG_time__get_milliseconds_since_1970_utc(pCtx,&iTimeUTC) ); SG_ERR_CHECK( SG_time__decode__local(pCtx,iTimeUTC,&tmLocal) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx,&pString) ); while (1) { // build path "<wd-top>/.sgtemp/<purpose>_20091201_0". // where <purpose> is something like "revert" or "merge". SG_ERR_CHECK( SG_string__sprintf(pCtx,pString,"%s_%04d%02d%02d_%d", pszPurpose, tmLocal.year,tmLocal.month,tmLocal.mday, kAttempt++) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx,&pPath,pPathTempRoot,SG_string__sz(pString)) ); // try to create a NEW temp directory. if this path already exists on disk, // loop and try again. if we have a hard errors, just give up. SG_fsobj__mkdir_recursive__pathname(pCtx,pPath); if (SG_context__has_err(pCtx) == SG_FALSE) goto success; if (SG_context__err_equals(pCtx,SG_ERR_DIR_ALREADY_EXISTS) == SG_FALSE) SG_ERR_RETHROW; SG_context__err_reset(pCtx); SG_PATHNAME_NULLFREE(pCtx,pPath); } success: *ppPathTempDir = pPath; SG_STRING_NULLFREE(pCtx, pString); SG_PATHNAME_NULLFREE(pCtx, pPathTempRoot); return; fail: SG_STRING_NULLFREE(pCtx, pString); SG_PATHNAME_NULLFREE(pCtx, pPathTempRoot); SG_PATHNAME_NULLFREE(pCtx, pPath); }
/** * This is a special case of __get_original_content_hid() that * basically doest that and then fetches the blob and returns * the actual symlink target. * * This is a convenience for STATUS that can report 'target' * fields rather than (or in addition to) 'hid' for symlinks. * */ void sg_wc_liveview_item__get_original_symlink_target(SG_context * pCtx, sg_wc_liveview_item * pLVI, SG_wc_tx * pWcTx, SG_string ** ppStringTarget) { const char * pszHidContent; SG_string * pStringTarget = NULL; SG_byte* pBuffer = NULL; SG_uint64 uSize = 0u; if (pLVI->tneType != SG_TREENODEENTRY_TYPE_SYMLINK) SG_ERR_THROW2_RETURN( SG_ERR_INVALIDARG, (pCtx, "GetOriginalSymlinkTarget: '%s' is not a symlink.", SG_string__sz(pLVI->pStringEntryname)) ); SG_ERR_CHECK( sg_wc_liveview_item__get_original_content_hid(pCtx, pLVI, pWcTx, SG_FALSE, &pszHidContent) ); SG_ERR_CHECK( SG_repo__fetch_blob_into_memory(pCtx, pWcTx->pDb->pRepo, pszHidContent, &pBuffer, &uSize) ); SG_ERR_CHECK( SG_STRING__ALLOC__BUF_LEN(pCtx, &pStringTarget, pBuffer, (SG_uint32)uSize) ); *ppStringTarget = pStringTarget; pStringTarget = NULL; fail: SG_STRING_NULLFREE(pCtx, pStringTarget); SG_NULLFREE(pCtx, pBuffer); }
void u0026_jsonparser__test_jsonparser_vhash_2(SG_context * pCtx) { SG_string* pstr1 = NULL; SG_string* pstr2 = NULL; SG_vhash* pvh = NULL; VERIFY_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr1) ); VERIFY_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr2) ); VERIFY_ERR_CHECK( u0026_jsonparser__create_2(pCtx, pstr1) ); SG_VHASH__ALLOC__FROM_JSON__SZ(pCtx, &pvh, SG_string__sz(pstr1)); VERIFY_COND("from_json", !SG_context__has_err(pCtx)); VERIFY_COND("from_json", pvh); SG_context__err_reset(pCtx); SG_vhash__to_json(pCtx, pvh, pstr2); VERIFY_COND("from_json", !SG_context__has_err(pCtx)); // TODO do some checks fail: SG_STRING_NULLFREE(pCtx, pstr1); SG_STRING_NULLFREE(pCtx, pstr2); SG_VHASH_NULLFREE(pCtx, pvh); }
/** * The values for RENAME, MOVE, ATTRBITS, SYMLINKS, and SUBMODULES are collapsable. (see below) * In the corresponding rbUnique's we only need to remember the set of unique values for the * field. THESE ARE THE KEYS IN THE prbUnique. * * As a convenience, we associate a vector of entries with each key. These form a many-to-one * thing so that we can report all of the entries that have this value. * * TODO since we should only process a cset once, we should not get any * TODO duplicates in the vector, but it might be possible. i'm not going * TODO to worry about it now. if this becomes a problem, consider doing * TODO a unique-insert into the vector -or- making the vector a sub-rbtree. * */ static void _update_1_rbUnique(SG_context * pCtx, SG_rbtree * prbUnique, const char * pszKey, SG_mrg_cset_entry * pMrgCSetEntry_Leaf_k) { SG_vector * pVec_Allocated = NULL; SG_vector * pVec; SG_bool bFound; SG_ERR_CHECK( SG_rbtree__find(pCtx,prbUnique,pszKey,&bFound,(void **)&pVec) ); if (!bFound) { SG_ERR_CHECK( SG_VECTOR__ALLOC(pCtx,&pVec_Allocated,3) ); SG_ERR_CHECK( SG_rbtree__add__with_assoc(pCtx,prbUnique,pszKey,pVec_Allocated) ); pVec = pVec_Allocated; pVec_Allocated = NULL; // rbtree owns this now } SG_ERR_CHECK( SG_vector__append(pCtx,pVec,pMrgCSetEntry_Leaf_k,NULL) ); #if TRACE_WC_MERGE SG_ERR_IGNORE( SG_console(pCtx,SG_CS_STDERR,"_update_1_rbUnique: [%s][%s]\n", pszKey, SG_string__sz(pMrgCSetEntry_Leaf_k->pMrgCSet->pStringCSetLabel)) ); #endif return; fail: SG_VECTOR_NULLFREE(pCtx, pVec_Allocated); }
void SG_localsettings__descriptor__update__sz( SG_context * pCtx, const char * psz_descriptor_name, const char * psz_path, const char * pValue) { SG_jsondb* p = NULL; SG_string* pstr_path = NULL; SG_ASSERT(pCtx); SG_NONEMPTYCHECK_RETURN(psz_descriptor_name); SG_NONEMPTYCHECK_RETURN(psz_path); SG_ARGCHECK_RETURN('/' != psz_path[0], psz_path); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr_path) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s/%s/%s", SG_LOCALSETTING__SCOPE__INSTANCE, psz_descriptor_name, psz_path) ); SG_ERR_CHECK( SG_closet__get_localsettings(pCtx, &p) ); SG_ERR_CHECK( SG_jsondb__update__string__sz(pCtx, p, SG_string__sz(pstr_path), SG_TRUE, pValue) ); fail: SG_STRING_NULLFREE(pCtx, pstr_path); SG_JSONDB_NULLFREE(pCtx, p); }
void u0038_test_wdmapping(SG_context * pCtx) { SG_vhash* pvh = NULL; SG_pathname* pPath = NULL; SG_pathname* pMappedPath = NULL; SG_string* pstrRepoDescriptorName = NULL; char* pszidGid = NULL; VERIFY_ERR_CHECK_DISCARD( SG_PATHNAME__ALLOC(pCtx, &pPath) ); VERIFY_ERR_CHECK_DISCARD( SG_pathname__set__from_cwd(pCtx, pPath) ); VERIFY_ERR_CHECK_DISCARD( SG_VHASH__ALLOC(pCtx, &pvh) ); VERIFY_ERR_CHECK_DISCARD( SG_vhash__add__string__sz(pCtx, pvh, "hello", "world") ); VERIFY_ERR_CHECK_DISCARD( SG_vhash__add__string__sz(pCtx, pvh, "hola", "mundo") ); SG_ERR_IGNORE( SG_closet__descriptors__remove(pCtx, "r1") ); VERIFY_ERR_CHECK_DISCARD( SG_closet__descriptors__add(pCtx, "r1", pvh) ); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__set_mapping(pCtx, pPath, "r1", NULL) ); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__find_mapping(pCtx, pPath, &pMappedPath, &pstrRepoDescriptorName, &pszidGid) ); VERIFY_COND("ridesc match", (0 == strcmp("r1", SG_string__sz(pstrRepoDescriptorName)))); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "foo") ); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "bar") ); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "plok") ); SG_STRING_NULLFREE(pCtx, pstrRepoDescriptorName); SG_PATHNAME_NULLFREE(pCtx, pMappedPath); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__find_mapping(pCtx, pPath, &pMappedPath, &pstrRepoDescriptorName, &pszidGid) ); SG_STRING_NULLFREE(pCtx, pstrRepoDescriptorName); SG_PATHNAME_NULLFREE(pCtx, pMappedPath); SG_PATHNAME_NULLFREE(pCtx, pPath); SG_VHASH_NULLFREE(pCtx, pvh); }
void SG_localsettings__update__varray(SG_context * pCtx, const char * psz_path, const SG_varray * pValue) { SG_jsondb* p = NULL; SG_string* pstr_path = NULL; SG_ASSERT(pCtx); SG_NONEMPTYCHECK_RETURN(psz_path); SG_NULLARGCHECK_RETURN(pValue); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr_path) ); if ('/' == psz_path[0]) { SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s", psz_path) ); } else { SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s/%s", SG_LOCALSETTING__SCOPE__MACHINE, psz_path) ); } SG_ERR_CHECK( SG_closet__get_localsettings(pCtx, &p) ); SG_ERR_CHECK( SG_jsondb__update__varray(pCtx, p, SG_string__sz(pstr_path), SG_TRUE, pValue) ); fail: SG_JSONDB_NULLFREE(pCtx, p); SG_STRING_NULLFREE(pCtx, pstr_path); }
void sg_sync_client__http__push_commit( SG_context* pCtx, SG_sync_client * pSyncClient, SG_sync_client_push_handle* pPush, SG_vhash** ppResult) { char* pszUrl = NULL; sg_sync_client_http_push_handle* pMyPush = (sg_sync_client_http_push_handle*)pPush; SG_string* pstr = NULL; SG_NULLARGCHECK_RETURN(pSyncClient); SG_NULLARGCHECK_RETURN(pPush); SG_NULLARGCHECK_RETURN(ppResult); SG_ERR_CHECK( _get_sync_url(pCtx, pSyncClient->psz_remote_repo_spec, SYNC_URL_SUFFIX, pMyPush->pszPushId, NULL, &pszUrl) ); SG_ERR_CHECK( do_url( pCtx, pszUrl, "POST", NULL, pSyncClient->psz_username, pSyncClient->psz_password, &pstr, NULL, SG_TRUE) ); SG_ERR_CHECK( SG_vhash__alloc__from_json__sz(pCtx, ppResult, SG_string__sz(pstr)) ); /* fall through */ fail: SG_STRING_NULLFREE(pCtx, pstr); SG_NULLFREE(pCtx, pszUrl); }
void SG_password__forget_all(SG_context *pCtx) { SG_string* pstrFilter = NULL; WCHAR* pwszFilter = NULL; DWORD numCreds = 0; PCREDENTIAL* paCreds = NULL; SG_uint32 i; SG_ERR_CHECK( SG_STRING__ALLOC__SZ(pCtx, &pstrFilter, KEY_PREFIX) ); SG_ERR_CHECK( SG_string__append__sz(pCtx, pstrFilter, KEY_SEPARATOR) ); SG_ERR_CHECK( SG_string__append__sz(pCtx, pstrFilter, "*") ); SG_ERR_CHECK( SG_utf8__extern_to_os_buffer__wchar(pCtx, SG_string__sz(pstrFilter), &pwszFilter, NULL) ); if ( !CredEnumerateW( pwszFilter, 0, &numCreds, &paCreds) ) { DWORD err = GetLastError(); if ( ERROR_NOT_FOUND != err) SG_ERR_THROW2( SG_ERR_GETLASTERROR(err), (pCtx, "%s", "unable to enumerate saved credentials") ); } for (i = 0; i < numCreds; i++) { if ( !CredDeleteW( paCreds[i]->TargetName, CRED_TYPE_GENERIC, 0) ) SG_ERR_THROW2( SG_ERR_GETLASTERROR(GetLastError()), (pCtx, "%s", "unable to delete credential") ); } /* fall through */ fail: SG_NULLFREE(pCtx, pwszFilter); SG_STRING_NULLFREE(pCtx, pstrFilter); }
SG_error SG_context__err_to_console(SG_context* pCtx, SG_console_stream cs) { SG_error err; SG_string* pErrStr = NULL; SG_ASSERT( pCtx ); // SG_ASSERT( pCtx->level < SG_CONTEXT_MAX_ERROR_LEVELS ); if (pCtx->level > 0) // when in an error-on-error (level > 0), there is NO error string. return SG_ERR_OK; // so we don't need to do anything. // get the full error string about the error at the current level. err = SG_context__err_to_string(pCtx, &pErrStr); if (SG_IS_ERROR(err)) // an allocation/formatting error, just give up. return err; // write the error string/message to the console. we push a new level // so that any problems converting the message to the user's locale or // writing to the console device don't trash the current error context. // // ***DO NOT JUMP OUT OF THIS PUSH..POP BLOCK.*** SG_context__push_level(pCtx); { SG_console(pCtx, cs, SG_string__sz(pErrStr)); err = pCtx->errValues[pCtx->level]; // we return the error value of the conversion/writing. } SG_context__pop_level(pCtx); SG_STRING_NULLFREE(pCtx, pErrStr); return err; }
void SG_user__get_email_for_repo(SG_context * pCtx, SG_repo* pRepo, const char ** ppsz_email) { char * psz_admin_id = NULL; char * psz_userid = NULL; const char * psz_email_temp = NULL; SG_string * pstr_path = NULL; SG_vhash * pvh_userhash = NULL; if (pRepo) { SG_ERR_CHECK( SG_repo__get_admin_id(pCtx, pRepo, &psz_admin_id) ); // we store this userid under the admin scope of the repo we were given SG_ERR_CHECK( SG_string__alloc__format(pCtx, &pstr_path, "%s/%s/%s", SG_LOCALSETTING__SCOPE__ADMIN, psz_admin_id, SG_LOCALSETTING__USERID ) ); SG_ERR_CHECK( SG_localsettings__get__sz(pCtx, SG_string__sz(pstr_path), pRepo, &psz_userid, NULL) ); if (psz_userid == NULL || *psz_userid == 0) SG_ERR_THROW(SG_ERR_USER_NOT_FOUND); SG_ERR_CHECK( SG_user__lookup_by_userid(pCtx, pRepo, psz_userid, &pvh_userhash) ); SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh_userhash, "email", &psz_email_temp) ); SG_ERR_CHECK( SG_STRDUP(pCtx, psz_email_temp, (char**)ppsz_email) ); } fail: SG_VHASH_NULLFREE(pCtx, pvh_userhash); SG_NULLFREE(pCtx, psz_admin_id); SG_NULLFREE(pCtx, psz_userid); SG_STRING_NULLFREE(pCtx, pstr_path); }
static void do_one_template( SG_context* pCtx, SG_repo* pRepo, SG_uint32 iDagNum, SG_audit* pq, unsigned char* pjson ) { SG_vhash* pvh_template = NULL; SG_changeset* pcs = NULL; SG_dagnode* pdn = NULL; SG_zingtx* ptx = NULL; SG_string* pstr = NULL; // now the main dag SG_ERR_CHECK( SG_zing__begin_tx(pCtx, pRepo, iDagNum, pq->who_szUserId, NULL, &ptx) ); SG_ERR_CHECK( my_strip_comments(pCtx, (char*) pjson, &pstr) ); SG_ERR_CHECK( SG_vhash__alloc__from_json(pCtx, &pvh_template, SG_string__sz(pstr))); SG_ERR_CHECK( SG_zingtx__store_template(pCtx, ptx, &pvh_template) ); SG_ERR_CHECK( SG_zing__commit_tx(pCtx, pq->when_int64, &ptx, &pcs, &pdn, NULL) ); SG_STRING_NULLFREE(pCtx, pstr); SG_CHANGESET_NULLFREE(pCtx, pcs); SG_DAGNODE_NULLFREE(pCtx, pdn); // fall thru fail: SG_STRING_NULLFREE(pCtx, pstr); SG_CHANGESET_NULLFREE(pCtx, pcs); SG_DAGNODE_NULLFREE(pCtx, pdn); }
void u0025_jsonwriter__verify(SG_context * pCtx, SG_string* pstr) { const char *psz = SG_string__sz(pstr); SG_int32* putf32 = NULL; SG_uint32 len = 0; JSON_checker jc = new_JSON_checker(20); SG_uint32 i; int ok = 0; SG_utf8__to_utf32__sz(pCtx, psz, &putf32, &len); for (i=0; i<len; i++) { ok = JSON_checker_char(jc, putf32[i]); VERIFY_COND("JSON_checker_char", ok); if (!ok) { break; } } if (ok) { ok = JSON_checker_done(jc); VERIFY_COND("JSON_checker_done", ok); } SG_NULLFREE(pCtx, putf32); }
void SG_localsettings__reset(SG_context * pCtx, const char* psz_path) { SG_jsondb* p = NULL; SG_string* pstr_path = NULL; SG_ASSERT(pCtx); SG_NONEMPTYCHECK_RETURN(psz_path); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr_path) ); if ('/' == psz_path[0]) { SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s", psz_path) ); } else { SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s/%s", SG_LOCALSETTING__SCOPE__MACHINE, psz_path) ); } SG_ERR_CHECK( SG_closet__get_localsettings(pCtx, &p) ); SG_jsondb__remove(pCtx, p, SG_string__sz(pstr_path)); SG_ERR_CHECK_CURRENT_DISREGARD(SG_ERR_NOT_FOUND); fail: SG_JSONDB_NULLFREE(pCtx, p); SG_STRING_NULLFREE(pCtx, pstr_path); }
/** * Prompt user for what to do on an individual item. * */ static void _do_prompt(SG_context * pCtx, const char * pszPrompt, const char * pszChoices, char chDefault, char * pchChoice) { SG_string * pStringInput = NULL; while (1) { const char * pszInput; const char * p; SG_ERR_CHECK( SG_console(pCtx, SG_CS_STDOUT, "%s: ", pszPrompt) ); SG_ERR_CHECK( SG_console__readline_stdin(pCtx, &pStringInput) ); pszInput = SG_string__sz(pStringInput); while ((*pszInput==' ') || (*pszInput=='\t')) pszInput++; if ((*pszInput==0) || (*pszInput=='\r') || (*pszInput=='\n')) { *pchChoice = chDefault; break; } p = strchr(pszChoices, *pszInput); if (p) { *pchChoice = *p; break; } SG_STRING_NULLFREE(pCtx, pStringInput); } fail: SG_STRING_NULLFREE(pCtx, pStringInput); }
void u0038_test_wdmapping(SG_context * pCtx) { SG_vhash* pvh = NULL; SG_closet_descriptor_handle* ph = NULL; SG_pathname* pPath = NULL; SG_pathname* pMappedPath = NULL; SG_string* pstrRepoDescriptorName = NULL; char* pszidGid = NULL; char buf_tid[SG_TID_MAX_BUFFER_LENGTH]; VERIFY_ERR_CHECK_DISCARD( SG_tid__generate2__suffix(pCtx, buf_tid, sizeof(buf_tid), 32, "u0038") ); VERIFY_ERR_CHECK_DISCARD( SG_PATHNAME__ALLOC__SZ(pCtx, &pPath, buf_tid) ); VERIFY_ERR_CHECK_DISCARD( SG_fsobj__mkdir__pathname(pCtx, pPath) ); SG_ERR_IGNORE( SG_closet__descriptors__remove(pCtx, "r1") ); VERIFY_ERR_CHECK_DISCARD( SG_closet__descriptors__add_begin(pCtx, "r1", NULL, NULL, NULL, NULL, &pvh, &ph) ); VERIFY_ERR_CHECK_DISCARD( SG_closet__descriptors__add_commit(pCtx, &ph, pvh, SG_REPO_STATUS__NORMAL) ); SG_VHASH_NULLFREE(pCtx, pvh); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__set_mapping(pCtx, pPath, "r1", NULL) ); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__find_mapping(pCtx, pPath, &pMappedPath, &pstrRepoDescriptorName, &pszidGid) ); VERIFY_COND("ridesc match", (0 == strcmp("r1", SG_string__sz(pstrRepoDescriptorName)))); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "foo") ); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "bar") ); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "plok") ); SG_STRING_NULLFREE(pCtx, pstrRepoDescriptorName); SG_PATHNAME_NULLFREE(pCtx, pMappedPath); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__find_mapping(pCtx, pPath, &pMappedPath, &pstrRepoDescriptorName, &pszidGid) ); SG_STRING_NULLFREE(pCtx, pstrRepoDescriptorName); SG_PATHNAME_NULLFREE(pCtx, pMappedPath); SG_PATHNAME_NULLFREE(pCtx, pPath); }
/** * Convert relative path to absolute, but make * sure that normalization doesn't take it outside * of the working directory. * * This is just pathname/string parsing; we DO NOT * confirm that the path exists or could exist. * */ void sg_wc_db__path__relative_to_absolute(SG_context * pCtx, const sg_wc_db * pDb, const SG_string * pStringRelativePath, SG_pathname ** ppPathItem) { SG_pathname * pPathWDT = NULL; SG_pathname * pPath = NULL; SG_uint32 lenWDT; // choke if they give us a repo-path. SG_ARGCHECK_RETURN( (SG_string__sz(pStringRelativePath)[0] != '@'), pStringRelativePath ); // choke if this WC TX isn't cwd-based. SG_ERR_CHECK( _check_if_relative_paths_allowed(pCtx, pDb) ); // clone WDT so that we can force a trailing slash. SG_ERR_CHECK( SG_PATHNAME__ALLOC__COPY(pCtx, &pPathWDT, pDb->pPathWorkingDirectoryTop) ); SG_ERR_CHECK( SG_pathname__add_final_slash(pCtx, pPathWDT) ); lenWDT = SG_pathname__length_in_bytes(pPathWDT); // allocate and normalize a new path with the net // result rather than writing on the clone (so that // we can do the following prefix test safely). SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPath, pPathWDT, SG_string__sz(pStringRelativePath)) ); if (strncmp(SG_pathname__sz(pPath), SG_pathname__sz(pPathWDT), lenWDT) != 0) { SG_ERR_THROW2( SG_ERR_PATH_NOT_IN_WORKING_COPY, (pCtx, "The path '%s' is not inside the working copy rooted at '%s'.", SG_string__sz(pStringRelativePath), SG_pathname__sz(pDb->pPathWorkingDirectoryTop)) ); } SG_PATHNAME_NULLFREE(pCtx, pPathWDT); *ppPathItem = pPath; return; fail: SG_PATHNAME_NULLFREE(pCtx, pPathWDT); SG_PATHNAME_NULLFREE(pCtx, pPath); }
static void _resolve__fix__run_external_file_merge_1(SG_context * pCtx, struct _resolve_data * pData, _resolve__external_tool * pET, _resolve__step_pathnames * pStepPathnames, SG_string * pStrRepoPath, SG_bool * pbMergedText) { SG_exec_argvec * pArgVec = NULL; SG_exit_status exitStatus; SG_UNUSED( pData ); #if 0 && defined(DEBUG) SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, ("RESOLVE File Merge: %s\n" " Mine: %s\n" " Other: %s\n" " Ancestor: %s\n" " Result: %s\n"), SG_string__sz(pStrRepoPath), SG_pathname__sz(pStepPathnames->pPath_Mine), SG_pathname__sz(pStepPathnames->pPath_Other), SG_pathname__sz(pStepPathnames->pPath_Ancestor), SG_pathname__sz(pStepPathnames->pPath_Result)) ); #endif SG_ERR_CHECK( SG_exec_argvec__alloc(pCtx, &pArgVec) ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, "-r") ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, SG_pathname__sz(pStepPathnames->pPath_Result)) ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, "-t1") ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, "Mine") ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, "-t2") ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, SG_string__sz(pStrRepoPath)) ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, "-t3") ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, "Other") ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, SG_pathname__sz(pStepPathnames->pPath_Mine)) ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, SG_pathname__sz(pStepPathnames->pPath_Ancestor)) ); SG_ERR_CHECK( SG_exec_argvec__append__sz(pCtx, pArgVec, SG_pathname__sz(pStepPathnames->pPath_Other)) ); SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDOUT, "RESOLVE: Preparing to launch external merge tool: %s\n", pET->pszName) ); SG_ERR_CHECK( SG_exec__exec_sync__files(pCtx, pET->pszExe, pArgVec, NULL, NULL, NULL, &exitStatus) ); *pbMergedText = (exitStatus == 0); fail: SG_EXEC_ARGVEC_NULLFREE(pCtx, pArgVec); }
void SG_curl__throw_on_non200(SG_context* pCtx, SG_curl* pCurl) { SG_int32 httpResponseCode = 0; SG_vhash* pvhErr = NULL; _sg_curl* p = (_sg_curl*)pCurl; SG_NULLARGCHECK_RETURN(pCurl); SG_ERR_CHECK( SG_curl__getinfo__int32(pCtx, pCurl, CURLINFO_RESPONSE_CODE, &httpResponseCode) ); if (httpResponseCode != 200) { if ((httpResponseCode == 500 || httpResponseCode == 410) && p->pstrErr) { SG_bool bHas = SG_FALSE; const char* szMsg = NULL; SG_VHASH__ALLOC__FROM_JSON__SZ(pCtx, &pvhErr, SG_string__sz(p->pstrErr)); if (SG_context__err_equals(pCtx, SG_ERR_JSONPARSER_SYNTAX)) { // The server didn't return a JSON-formatted response. if (httpResponseCode == 500) SG_ERR_RESET_THROW2(SG_ERR_EXTENDED_HTTP_500, (pCtx, "%s", SG_string__sz(p->pstrErr))); else SG_ERR_THROW2(SG_ERR_SERVER_HTTP_ERROR, (pCtx, "%d", httpResponseCode)); } SG_ERR_CHECK_CURRENT; SG_ERR_CHECK( SG_vhash__has(pCtx, pvhErr, "msg", &bHas) ); if (bHas) SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvhErr, "msg", &szMsg) ); if (szMsg) SG_ERR_THROW2(SG_ERR_EXTENDED_HTTP_500, (pCtx, "%s", szMsg)); else SG_ERR_THROW2(SG_ERR_EXTENDED_HTTP_500, (pCtx, "%s", SG_string__sz(p->pstrErr))); } else if (httpResponseCode == 401) { SG_ERR_THROW(SG_ERR_AUTHORIZATION_REQUIRED); } else SG_ERR_THROW2(SG_ERR_SERVER_HTTP_ERROR, (pCtx, "%d", httpResponseCode)); } /* common cleanup */ fail: SG_VHASH_NULLFREE(pCtx, pvhErr); }