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 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); }
/** * 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 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_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 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); }
/** * 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 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 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); }
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_vfile__end( SG_context* pCtx, SG_vfile** ppvf, const SG_vhash* pvh ) { SG_string* pstr = NULL; SG_vfile* pvf = NULL; SG_NULLARGCHECK_RETURN(ppvf); pvf = *ppvf; if (pvh) { SG_ARGCHECK_RETURN( !(pvf->mode & SG_FILE_RDONLY) , pvh ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr) ); SG_ERR_CHECK( SG_vhash__to_json(pCtx, pvh,pstr) ); SG_ERR_CHECK( SG_file__seek(pCtx, pvf->pFile, 0) ); SG_ERR_CHECK( SG_file__truncate(pCtx, pvf->pFile) ); #if TRACE_VFILE SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "VFileEnd: Writing %d bytes to file.\n", SG_string__length_in_bytes(pstr)) ); #endif SG_ERR_CHECK( SG_file__write(pCtx, pvf->pFile, SG_string__length_in_bytes(pstr), (const SG_byte *)SG_string__sz(pstr), NULL) ); SG_STRING_NULLFREE(pCtx, pstr); } else { if (!(pvf->mode & SG_FILE_RDONLY)) { SG_ERR_CHECK( SG_file__seek(pCtx, pvf->pFile, 0) ); SG_ERR_CHECK( SG_file__truncate(pCtx, pvf->pFile) ); #if TRACE_VFILE SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "VFileEnd: Truncating file.\n") ); #endif } } SG_FILE_NULLCLOSE(pCtx, pvf->pFile); SG_NULLFREE(pCtx, pvf); *ppvf = NULL; return; fail: SG_STRING_NULLFREE(pCtx, pstr); }
void SG_curl__free(SG_context* pCtx, SG_curl* pCurl) { _sg_curl* p = (_sg_curl*)pCurl; if (p) { SG_STRING_NULLFREE(pCtx, p->pstrErr); SG_STRING_NULLFREE(pCtx, p->pstrRawHeaders); curl_easy_cleanup(p->pCurl); SG_NULLFREE(pCtx, p); } }
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); }
void SG_getopt__free(SG_context * pCtx, SG_getopt * pGetopt) { if (!pGetopt) return; SG_STRING_NULLFREE(pCtx, pGetopt->pStringAppName); SG_STRING_NULLFREE(pCtx, pGetopt->pStringCommandName); if (pGetopt->paszArgs) { SG_ERR_CHECK_RETURN( SG_freeStringList(pCtx, (const char ***)&pGetopt->paszArgs, pGetopt->count_args) ); } SG_NULLFREE(pCtx, pGetopt); }
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_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_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 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); }
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__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_group__list( SG_context* pCtx, SG_repo* pRepo, SG_varray** ppva ) { SG_string* pstr_where = NULL; SG_stringarray* psa_results = NULL; char* psz_hid_cs_leaf = NULL; SG_vhash* pvh_group = NULL; SG_varray* pva_result = NULL; SG_stringarray* psa_fields = NULL; SG_ERR_CHECK( SG_zing__get_leaf__fail_if_needs_merge(pCtx, pRepo, SG_DAGNUM__USERS, &psz_hid_cs_leaf) ); SG_ERR_CHECK( SG_STRINGARRAY__ALLOC(pCtx, &psa_fields, 2) ); SG_ERR_CHECK( SG_stringarray__add(pCtx, psa_fields, "recid") ); SG_ERR_CHECK( SG_stringarray__add(pCtx, psa_fields, "name") ); SG_ERR_CHECK( SG_zing__query(pCtx, pRepo, SG_DAGNUM__USERS, psz_hid_cs_leaf, "group", NULL, "name #ASC", 0, 0, psa_fields, &pva_result) ); *ppva = pva_result; pva_result = NULL; fail: SG_VHASH_NULLFREE(pCtx, pvh_group); SG_NULLFREE(pCtx, psz_hid_cs_leaf); SG_VARRAY_NULLFREE(pCtx, pva_result); SG_STRINGARRAY_NULLFREE(pCtx, psa_results); SG_STRING_NULLFREE(pCtx, pstr_where); SG_STRINGARRAY_NULLFREE(pCtx, psa_fields); }
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); }
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_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); }
static void _get_sync_url(SG_context* pCtx, const char* pszBaseUrl, const char* pszUrlSuffix, const char* pszPushId, const char* pszQueryString, char** ppszUrl) { SG_string* pstrUrl = NULL; SG_ERR_CHECK( SG_STRING__ALLOC__RESERVE(pCtx, &pstrUrl, 1024) ); SG_ERR_CHECK( SG_string__append__sz(pCtx, pstrUrl, pszBaseUrl) ); if (pszUrlSuffix) SG_ERR_CHECK( SG_string__append__sz(pCtx, pstrUrl, pszUrlSuffix) ); if (pszPushId) { SG_ERR_CHECK( SG_string__append__sz(pCtx, pstrUrl, "/") ); SG_ERR_CHECK( SG_string__append__sz(pCtx, pstrUrl, pszPushId) ); } if (pszQueryString) { SG_ERR_CHECK( SG_string__append__sz(pCtx, pstrUrl, "?") ); SG_ERR_CHECK( SG_string__append__sz(pCtx, pstrUrl, pszQueryString) ); } SG_ERR_CHECK( SG_string__sizzle(pCtx, &pstrUrl, (SG_byte**)ppszUrl, NULL) ); return; fail: SG_STRING_NULLFREE(pCtx, pstrUrl); }
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); }
static void _get_host(SG_context* pCtx, const char* szRepoSpec, SG_string** ppstrHost) { LPWSTR pwszRepoSpec = NULL; SG_uint32 len = 0; URL_COMPONENTSW UrlComponents; SG_string* pstrHost = NULL; WCHAR buf[260]; SG_zero(UrlComponents); UrlComponents.dwStructSize = sizeof(URL_COMPONENTS); UrlComponents.dwHostNameLength = sizeof(buf); UrlComponents.lpszHostName = buf; SG_ERR_CHECK( SG_utf8__extern_to_os_buffer__wchar(pCtx, szRepoSpec, &pwszRepoSpec, &len) ); if ( !InternetCrackUrlW(pwszRepoSpec, len, ICU_DECODE, &UrlComponents) ) SG_ERR_THROW2( SG_ERR_GETLASTERROR(GetLastError()), (pCtx, "unable to parse host from URL") ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstrHost) ); SG_ERR_CHECK( SG_utf8__intern_from_os_buffer__wchar(pCtx, pstrHost, UrlComponents.lpszHostName) ); SG_RETURN_AND_NULL(pstrHost, ppstrHost); /* fall through */ fail: SG_NULLFREE(pCtx, pwszRepoSpec); SG_STRING_NULLFREE(pCtx, pstrHost); }
/** * Queue a request to resolve (or partially resolve) an issue. * We assume that the caller has already * queued any necessary WD operations * (such as moves/renamed) and now just * needs to mark the item resolved (or * partially resolved). * * Since an item may have multiple conflict * bits set, you can use this to mark the * specific choices made in the pvhSavedResolutions * and only mark it fully resolved when * everything has been chosen. * * We steal the optional/given pvhSavedResolutions. * */ void sg_wc_tx__queue__resolve_issue__sr(SG_context * pCtx, SG_wc_tx * pWcTx, sg_wc_liveview_item * pLVI, SG_wc_status_flags statusFlags_x_xr_xu, SG_vhash ** ppvhSavedResolutions) { SG_string * pStringResolveData = NULL; SG_NULLARGCHECK_RETURN( pWcTx ); SG_NULLARGCHECK_RETURN( pLVI ); // ppvhSavedResolutions is optional. if (ppvhSavedResolutions && *ppvhSavedResolutions) { SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pStringResolveData) ); SG_ERR_CHECK( SG_vhash__to_json(pCtx, (*ppvhSavedResolutions), pStringResolveData) ); } SG_ERR_CHECK( sg_wc_tx__journal__resolve_issue__sr(pCtx, pWcTx, pLVI->uiAliasGid, statusFlags_x_xr_xu, pStringResolveData) ); pLVI->statusFlags_x_xr_xu = statusFlags_x_xr_xu; SG_VHASH_NULLFREE(pCtx, pLVI->pvhSavedResolutions); if (ppvhSavedResolutions && *ppvhSavedResolutions) { pLVI->pvhSavedResolutions = *ppvhSavedResolutions; *ppvhSavedResolutions = NULL; } fail: SG_STRING_NULLFREE(pCtx, pStringResolveData); }
void SG_mrg_cset_entry_conflict__free(SG_context * pCtx, SG_mrg_cset_entry_conflict * pMrgCSetEntryConflict) { if (!pMrgCSetEntryConflict) return; SG_VECTOR_I64_NULLFREE(pCtx, pMrgCSetEntryConflict->pVec_MrgCSetEntryNeq_Changes); SG_VECTOR_NULLFREE(pCtx, pMrgCSetEntryConflict->pVec_MrgCSetEntry_Changes); // we do not own the pointers within SG_VECTOR_NULLFREE(pCtx, pMrgCSetEntryConflict->pVec_MrgCSet_Deletes); // we do not own the pointers within // for the collapsable rbUnique's we own the vectors in the rbtree-values, but not the pointers within the vector SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_AttrBits, (SG_free_callback *)SG_vector__free); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_Entryname, (SG_free_callback *)SG_vector__free); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_GidParent, (SG_free_callback *)SG_vector__free); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_Symlink_HidBlob, (SG_free_callback *)SG_vector__free); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_Submodule_HidBlob, (SG_free_callback *)SG_vector__free); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_File_HidBlob, (SG_free_callback *)SG_vector__free); SG_VECTOR_NULLFREE(pCtx, pMrgCSetEntryConflict->pVec_MrgCSetEntry_OtherDirsInCycle); // we do not own the pointers within SG_STRING_NULLFREE(pCtx, pMrgCSetEntryConflict->pStringPathCycleHint); SG_FILETOOL_NULLFREE(pCtx, pMrgCSetEntryConflict->pMergeTool); SG_PATHNAME_NULLFREE(pCtx, pMrgCSetEntryConflict->pPathTempDirForFile); SG_PATHNAME_NULLFREE(pCtx, pMrgCSetEntryConflict->pPathTempFile_Ancestor); SG_PATHNAME_NULLFREE(pCtx, pMrgCSetEntryConflict->pPathTempFile_Result); SG_PATHNAME_NULLFREE(pCtx, pMrgCSetEntryConflict->pPathTempFile_Baseline); SG_PATHNAME_NULLFREE(pCtx, pMrgCSetEntryConflict->pPathTempFile_Other); SG_NULLFREE(pCtx, pMrgCSetEntryConflict->pszHidDisposable); SG_NULLFREE(pCtx, pMrgCSetEntryConflict->pszHidGenerated); SG_NULLFREE(pCtx, pMrgCSetEntryConflict); }
/** * 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); }