コード例 #1
0
/**
 * Wrapper around SG_utf8__to_utf32 that allows empty strings.
 * I'm not sure why that function doesn't allow them, but I didn't want to change
 * something so low-level right now, so I'm wrapping it instead.  Will log something
 * to have it looked into later.
 */
static void _utf8_to_utf32(
    SG_context* pCtx,    //< [in] [out] Error and context info.
    const char* szUtf8,  //< [in] UTF8 string to convert, may be empty but not NULL.
    SG_int32**  ppUtf32, //< [out] Converted UTF32 string.
    SG_uint32*  pLength  //< [out] Length of converted UTF32 string, in characters.
)
{
    SG_int32* pUtf32  = NULL;
    SG_uint32 uLength = 0u;

    SG_NULLARGCHECK(szUtf8);
    SG_NULLARGCHECK(ppUtf32);

    if (szUtf8[0] == 0)
    {
        SG_alloc1(pCtx, pUtf32);
        pUtf32[0] = 0;
        uLength = 0u;
    }
    else
    {
        SG_ERR_CHECK(  SG_utf8__to_utf32__sz(pCtx, szUtf8, &pUtf32, &uLength)  );
    }

    *ppUtf32 = pUtf32;
    pUtf32 = NULL;
    if (pLength != NULL)
    {
        *pLength = uLength;
    }

fail:
    SG_NULLFREE(pCtx, pUtf32);
    return;
}
コード例 #2
0
/**
 * Wrapper around SG_utf8__from_utf32 that allows empty strings.
 * I'm not sure why that function doesn't allow them, but I didn't want to change
 * something so low-level right now, so I'm wrapping it instead.  Will log something
 * to have it looked into later.
 */
static void _utf32_to_utf8(
    SG_context* pCtx,   //< [in] [out] Error and context info.
    SG_int32*   pUtf32, //< [in] UTF32 string to convert, may be empty but not NULL.
    char**      ppUtf8, //< [in] Converted UTF8 string.
    SG_uint32*  pLength //< [out] Length of converted UTF32 string, in bytes.
)
{
    char*     szUtf8  = NULL;
    SG_uint32 uLength = 0u;

    SG_NULLARGCHECK(pUtf32);
    SG_NULLARGCHECK(ppUtf8);

    if (pUtf32[0] == 0)
    {
        SG_alloc1(pCtx, szUtf8);
        szUtf8[0] = 0;
        uLength = 1u;
    }
    else
    {
        SG_ERR_CHECK(  SG_utf8__from_utf32(pCtx, pUtf32, &szUtf8, &uLength)  );
    }

    *ppUtf8 = szUtf8;
    szUtf8 = NULL;
    if (pLength != NULL)
    {
        *pLength = uLength;
    }

fail:
    SG_NULLFREE(pCtx, szUtf8);
    return;
}
コード例 #3
0
void SG_mergereview__continue(SG_context * pCtx, SG_repo * pRepo, SG_varray * pContinuationToken, SG_bool singleMergeReview, SG_vhash * pMergeBaselines, SG_uint32 resultLimit, SG_varray ** ppResults, SG_uint32 * pCountResults, SG_varray ** ppContinuationToken)
{
	_tree_t tree;
	SG_uint16 firstVariantType;

	SG_zero(tree);

	SG_ASSERT(pCtx!=NULL);
	SG_NULLARGCHECK(pRepo);
	SG_NULLARGCHECK(pContinuationToken);
	if(resultLimit==0)
		resultLimit = SG_UINT32_MAX;
	SG_NULLARGCHECK(ppResults);

	SG_ERR_CHECK(  SG_varray__typeof(pCtx, pContinuationToken, 0, &firstVariantType)  );
	if(firstVariantType==SG_VARIANT_TYPE_SZ)
	{
		const char * szHead = NULL;
		SG_ERR_CHECK(  SG_varray__get__sz(pCtx, pContinuationToken, 0, &szHead)  );
		SG_ERR_CHECK(  _tree__init(pCtx, &tree, szHead, pRepo)  );
	}
	else
	{
		SG_ERR_CHECK(  _tree__init__continuation(pCtx, &tree, pContinuationToken, pRepo)  );
	}


	SG_ERR_CHECK(  _sg_mergereview(pCtx, &tree, singleMergeReview, SG_FALSE, pMergeBaselines, resultLimit, ppResults, pCountResults, ppContinuationToken)  );

	_tree__uninit(pCtx, &tree);

	return;
fail:
	_tree__uninit(pCtx, &tree);
}
コード例 #4
0
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);
}
コード例 #5
0
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_wc__status__find_status__single_item(SG_context * pCtx,
									  const SG_varray * pva_statuses,
									  const char * psz_repo_path, //This must be the repo path, exactly as it appears in the status results.
									  SG_vhash ** ppvh_status_result)
{
	SG_vhash * pvh_status = NULL;
	SG_uint32 nArraySize = 0;
	SG_uint32 index = 0;
	const char * psz_repo_path_to_check = NULL;
	SG_bool bFound = SG_FALSE;
	SG_NULLARGCHECK(pva_statuses);

	SG_ERR_CHECK(  SG_varray__count(pCtx, pva_statuses, &nArraySize)  );

	for (index = 0; index < nArraySize; index++)
	{
		SG_ERR_CHECK(  SG_varray__get__vhash(pCtx, pva_statuses, index, &pvh_status)  );
		SG_ERR_CHECK(  SG_vhash__get__sz(pCtx, pvh_status, "path", &psz_repo_path_to_check)  );
		if (SG_strcmp__null(psz_repo_path, psz_repo_path_to_check) == 0)
		{
			bFound = SG_TRUE;
			break;
		}
	}
	if (bFound)
		SG_RETURN_AND_NULL(pvh_status, ppvh_status_result);
fail:
	return;
}
コード例 #7
0
void SG_validate__sanitize__trim(
    SG_context* pCtx,
    const char* szValue,
    SG_uint32   uMin,
    SG_uint32   uMax,
    const char* szInvalids,
    SG_uint32   uFixFlags,
    const char* szReplace,
    const char* szAdd,
    SG_string** ppSanitized
)
{
    char* szTrimmed = NULL;

    SG_NULLARGCHECK(ppSanitized);

    // trim the value (will return NULL if the value is NULL or trims to nothing)
    SG_ERR_CHECK(  SG_sz__trim(pCtx, szValue, NULL, &szTrimmed)  );

    // sanitize the trimmed value
    if (szTrimmed == NULL)
    {
        SG_ERR_CHECK(  SG_validate__sanitize(pCtx, "", uMin, uMax, szInvalids, uFixFlags, szReplace, szAdd, ppSanitized)  );
    }
    else
    {
        SG_ERR_CHECK(  SG_validate__sanitize(pCtx, szTrimmed, uMin, uMax, szInvalids, uFixFlags, szReplace, szAdd, ppSanitized)  );
    }

fail:
    SG_NULLFREE(pCtx, szTrimmed);
    return;
}
コード例 #8
0
void sg_repo__bind_vtable(SG_context* pCtx, SG_repo * pRepo, const char * pszStorage)
{
    SG_uint32 count_vtables = 0;

	SG_NULLARGCHECK(pRepo);

	if (pRepo->p_vtable)			// can only be bound once
    {
		SG_ERR_THROW2(SG_ERR_INVALIDARG, (pCtx, "pRepo->p_vtable is already bound"));
    }

	if (pRepo->pvh_descriptor)
    {
		SG_ERR_THROW2(SG_ERR_INVALIDARG, (pCtx, "pRepo->pvh_descriptor is already bound"));
    }

    if (!g_prb_repo_vtables)
    {
		SG_ERR_THROW2(SG_ERR_UNKNOWN_STORAGE_IMPLEMENTATION, (pCtx, "There are no repo storage plugins installed"));
    }

    SG_ERR_CHECK(  SG_rbtree__count(pCtx, g_prb_repo_vtables, &count_vtables)  );

    if (0 == count_vtables)
    {
		SG_ERR_THROW2(SG_ERR_UNKNOWN_STORAGE_IMPLEMENTATION, (pCtx, "There are no repo storage plugins installed"));
    }

	if (!pszStorage || !*pszStorage)
    {
        if (1 == count_vtables)
        {
            SG_bool b = SG_FALSE;

            SG_ERR_CHECK(  SG_rbtree__iterator__first(pCtx, NULL, g_prb_repo_vtables, &b, NULL, (void**) &pRepo->p_vtable)  );
            SG_ASSERT(pRepo->p_vtable);
        }
        else
        {
            SG_ERR_THROW2(SG_ERR_UNKNOWN_STORAGE_IMPLEMENTATION, (pCtx, "Multiple repo storage plugins installed.  Must specify."));
        }
    }
    else
    {
        SG_bool b = SG_FALSE;

        SG_ERR_CHECK(  SG_rbtree__find(pCtx, g_prb_repo_vtables, pszStorage, &b, (void**) &pRepo->p_vtable)  );
        if (!b || !pRepo->p_vtable)
        {
            SG_ERR_THROW(SG_ERR_UNKNOWN_STORAGE_IMPLEMENTATION);
        }
    }

fail:
    ;
}
コード例 #9
0
void SG_mergereview(SG_context * pCtx, SG_repo * pRepo, const char * szHidHead, SG_bool singleMergeReview, SG_vhash * pMergeBaselines, SG_uint32 resultLimit, SG_varray ** ppResults, SG_uint32 * pCountResults, SG_varray ** ppContinuationToken)
{
	_tree_t tree;

	SG_ASSERT(pCtx!=NULL);
	SG_NULLARGCHECK(pRepo);
	SG_NONEMPTYCHECK(szHidHead);
	if(resultLimit==0)
		resultLimit = SG_UINT32_MAX;
	SG_NULLARGCHECK(ppResults);

	SG_ERR_CHECK(  _tree__init(pCtx, &tree, szHidHead, pRepo)  );

	SG_ERR_CHECK(  _sg_mergereview(pCtx, &tree, singleMergeReview, SG_TRUE, pMergeBaselines, resultLimit, ppResults, pCountResults, ppContinuationToken)  );

	_tree__uninit(pCtx, &tree);

	return;
fail:
	_tree__uninit(pCtx, &tree);
}
コード例 #10
0
ファイル: sg_diff_utils.c プロジェクト: avar/veracity
/**
 * Create a label for one side of a UNIFIED DIFF.  This will appear on one of
 * the header lines after the "+++ " or "--- ".  (We DO NOT create the "+++ "
 * portion.)
 *
 * Gnu-diff (when --label is not used) creates something like:
 *      +++ %s\t%s		with the file's relative pathname and date-time-modified.
 *
 *      --- d1/date2	1970-01-01 00:00:00.000000000 +0000
 *      +++ d2/date2	2009-04-30 13:10:57.000000000 +0000
 *
 * BZR's diff command creates something like:
 *
 *      --- d2/date2	2009-04-30 12:38:41 +0000
 *      +++ d2/date2	2009-04-30 13:10:57 +0000
 *
 * GIT's diff command creates something like:
 *
 *      --- a/eeeeee.txt
 *      +++ b/eeeeee.txt
 *
 * So, we can pretty much do whatever we want here.
 *
 * I'm going to try the following and see if we like it:
 * [] for a historical version, print:
 *      +++ %s\t%s    with the repo-path and the HID.
 *
 *    we don't have a valid date-stamp to print. (our caller might have
 *    the date-stamp on the changeset, but that doesn't have anything to
 *    to with the date on an indivdual file (the file might not have even
 *    been modified in that changeset).
 *
 *    the HID may be useful later.
 *
 * [] for a working-directory version, print:
 *      +++ %s\t%s    with the repo-path and the live date-time-stamp.
 *
 *    since the file is in the working-directory, the date stamp has
 *    some validity (it doesn't mean that they changed the file or reflect
 *    the last change (it could be date of the last get-latest for all we
 *    know)).
 *
 * [] just for sanity, we allow a repo-path only version:
 *      +++ %s
 *
 * In all cases we print the complete repo-path "@/a/b/c/foo.c".
 * The repo-path is as computed in SG_treediff2 and reflects all pathname
 * renames/moves.
 *
 * TODO do we care about feeding this output to PATCH and how it digests
 * pathnames and with the various -p0 -p1 ... arguments?
 *
 * We return a string that you must free.
 */
void SG_diff_utils__make_label(SG_context * pCtx,
							   const char * szRepoPath,
							   const char * szHid,
							   const char * szDate,
							   SG_string ** ppStringLabel)
{
	SG_string * pString = NULL;

	SG_NONEMPTYCHECK_RETURN(szRepoPath);

	if (szHid && szDate)			// allow zero or one, but not both
		SG_ERR_THROW_RETURN(  SG_ERR_INVALIDARG  );

	SG_NULLARGCHECK(ppStringLabel);

	SG_ERR_CHECK_RETURN(  SG_STRING__ALLOC(pCtx,&pString)  );

	//////////////////////////////////////////////////////////////////
	// WARNING: All of the input arguments are in our internal NFC UTF-8 format
	// WARNING: (as is everything).  SG_exec__() will convert whatever we construct
	// WARNING: here to an os-buffer (utf-8, locale, or wchar_t) before giving it
	// WARNING: to execvp() or CreateProcessW().
	// WARNING:
	// WARNING: I *think* this is what we want.
	// WARNING:
	// WARNING: We can't be sure how the child process will handle the label text
	// WARNING: when it prints it to its STDOUT.  This may cause some confusion.
	// WARNING: For example, NFC/NFD issues on MAC or some '?' characters getting
	// WARNING: printed by cygwin's version of gnu-diff and etc.
	// WARNING:
	// WARNING: I don't know if there are actually any issues here or not or if
	// WARNING: so whether they will cause a problem.
	//////////////////////////////////////////////////////////////////

	if (szHid)
		SG_ERR_CHECK(  SG_string__sprintf(pCtx,
										  pString,"%s\t%s",
										  szRepoPath,szHid)  );
	else if (szDate)
		SG_ERR_CHECK(  SG_string__sprintf(pCtx,
										  pString,"%s\t%s",
										  szRepoPath,szDate)  );
	else
		SG_ERR_CHECK(  SG_string__set__sz(pCtx,pString,szRepoPath)  );

	*ppStringLabel = pString;

	return;

fail:
	SG_STRING_NULLFREE(pCtx, pString);
}
コード例 #11
0
void SG_validate__check__trim(
    SG_context* pCtx,
    const char* szValue,
    SG_uint32   uMin,
    SG_uint32   uMax,
    const char* szInvalids,
    SG_bool     bControls,
    SG_uint32*  pResult,
    char**      ppTrimmed
)
{
    char* szTrimmed = NULL;

    SG_NULLARGCHECK(pResult);

    // trim the value (will return NULL if the value is NULL or trims to nothing)
    SG_ERR_CHECK(  SG_sz__trim(pCtx, szValue, NULL, &szTrimmed)  );

    // validate the trimmed value
    if (szTrimmed == NULL)
    {
        SG_ERR_CHECK(  SG_validate__check(pCtx, "", uMin, uMax, szInvalids, bControls, pResult)  );
    }
    else
    {
        SG_ERR_CHECK(  SG_validate__check(pCtx, szTrimmed, uMin, uMax, szInvalids, bControls, pResult)  );
    }

    // if it's valid and they want the trimmed value, return it
    if (*pResult == SG_VALIDATE__RESULT__VALID && ppTrimmed != NULL)
    {
        *ppTrimmed = szTrimmed;
        szTrimmed = NULL;
    }

fail:
    SG_NULLFREE(pCtx, szTrimmed);
    return;
}
static void make_request(
    SG_context* pCtx,
    const char* pszUrl,
    const char* psz_method,
    const char* psz_data,
    CFHTTPMessageRef* pp
)
{
    CFStringRef url = NULL;
    CFURLRef myURL = NULL;
    CFStringRef requestMethod = NULL;
    CFHTTPMessageRef myRequest = NULL;

    url = CFStringCreateWithCString(kCFAllocatorDefault, pszUrl,kCFStringEncodingUTF8);
    SG_NULLARGCHECK(url);

    myURL = CFURLCreateWithString(kCFAllocatorDefault, url, NULL);
    SG_NULLARGCHECK(myURL);

    requestMethod = CFStringCreateWithCString(kCFAllocatorDefault, psz_method,kCFStringEncodingUTF8);
    SG_NULLARGCHECK(requestMethod);

    myRequest = CFHTTPMessageCreateRequest(
                    kCFAllocatorDefault,
                    requestMethod,
                    myURL,
                    kCFHTTPVersion1_1
                );
    SG_NULLARGCHECK(myRequest);

    if (psz_data)
    {
        CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault, psz_data, kCFStringEncodingUTF8);
        CFDataRef bodyData = CFStringCreateExternalRepresentation(kCFAllocatorDefault, s, kCFStringEncodingUTF8, 0);
        CFRelease(s);
        CFHTTPMessageSetBody(myRequest, bodyData);
        CFRelease(bodyData);
    }

    *pp = myRequest;
    myRequest = NULL;

fail:
    if (myRequest)
    {
        CFRelease(myRequest);
        myRequest = NULL;
    }

    if (myURL)
    {
        CFRelease(myURL);
        myURL = NULL;
    }

    if (requestMethod)
    {
        CFRelease(requestMethod);
        requestMethod = NULL;
    }

    if (url)
    {
        CFRelease(url);
        url = NULL;
    }
}
コード例 #13
0
void SG_password__set(
	SG_context *pCtx,
	const char *szRepoSpec,
	SG_string *pUserName,
	SG_string *pPassword)
{
	const char *username, *password;
	SG_string *path = NULL;
	SG_string *server = NULL;
	SecProtocolType proto;
	SG_uint32 port;
	SG_bool isValid = SG_FALSE;

	OSStatus saveRes, findRes;
	SecKeychainItemRef item = NULL;

	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);

	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,
		NULL, NULL,
		&item);

	if (findRes == errSecSuccess)
	{
		saveRes = SecKeychainItemModifyAttributesAndData(item, NULL, SG_STRLEN(password), password);
	}
	else
	{
		saveRes = SecKeychainAddInternetPassword(
			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,
			SG_STRLEN(password), password,
			NULL);
	}

	if (saveRes != errSecSuccess)
		_SG_THROW_MAC_SEC_ERROR(saveRes);

fail:
	if (item)
		CFRelease(item);

	SG_STRING_NULLFREE(pCtx, path);
	SG_STRING_NULLFREE(pCtx, server);
}
コード例 #14
0
static void _sg_password__parse_url(
	SG_context *pCtx,
	const char *url,
	SG_bool *pIsValid,
	SG_string **ppProto,
	SG_string **ppServer,
	SG_string **ppPath,
	SG_uint32 *pPort
	)
{
	const char *slash, *colon, *ss;
	SG_string *server = NULL;
	SG_string *path = NULL;
	SG_string *proto = NULL;
	SG_NULLARGCHECK(url);

	*pIsValid = SG_FALSE;

	if (strncmp("http://", url, 7) == 0)
	{
		SG_ERR_CHECK(  SG_STRING__ALLOC__SZ(pCtx, &proto, "http")  );
		*pPort = 80;
		url += 7;
	}
	else if (strncmp("https://", url, 8) == 0)
	{
		SG_ERR_CHECK(  SG_STRING__ALLOC__SZ(pCtx, &proto, "https")  );
		*pPort = 443;
		url += 8;
	}
	else
		goto fail;

	slash = strchr(url, '/');

	if (! slash)
		goto fail;

	SG_ERR_CHECK(  SG_STRING__ALLOC__BUF_LEN(pCtx, &server, (const SG_byte *)url, (SG_uint32)(slash - url))  );

	ss = SG_string__sz(server);
	colon = strchr(ss, ':');
	if (colon)
	{
		SG_uint32 port = atoi(colon + 1);
		SG_uint32 plen = colon - ss;
		if (port == 0)
			goto fail;

		*pPort = port;

		SG_ERR_CHECK(  SG_string__remove(pCtx, server, plen, SG_STRLEN(ss) - plen)  );
	}

	SG_ERR_CHECK(  SG_STRING__ALLOC__SZ(pCtx, &path, "/")  );

	*ppPath = path;
	path = NULL;
	*ppServer = server;
	server = NULL;
	*ppProto = proto;
	proto = NULL;

	*pIsValid = SG_TRUE;

fail:
	SG_STRING_NULLFREE(pCtx, server);
	SG_STRING_NULLFREE(pCtx, path);
	SG_STRING_NULLFREE(pCtx, proto);
}
コード例 #15
0
void SG_password__get(
	SG_context *pCtx,
	const char *szRepoSpec,
	const char *username,
	SG_string **ppstrPassword)
{
	SG_string *password = NULL;
	SG_string *path = NULL;
	SG_string *server = NULL;
	SG_string *proto = NULL;
	SG_uint32 port;
	SG_bool isValid = SG_FALSE;
	GnomeKeyringResult saveRes = 0;
	GList *results = NULL;
	guint count = 0;

	SG_NULLARGCHECK(username);
	SG_NULLARGCHECK(ppstrPassword);
	SG_NULLARGCHECK(szRepoSpec);

	if (! SG_password__supported())
		goto fail;

	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_find_network_password_sync(
		username, NULL,
		SG_string__sz(server), SG_string__sz(path),
		SG_string__sz(proto), NULL, (guint32)port,
		&results);

	if ((saveRes != GNOME_KEYRING_RESULT_OK) && (saveRes != GNOME_KEYRING_RESULT_NO_MATCH) && (saveRes != GNOME_KEYRING_RESULT_CANCELLED))
		_SG_THROW_LINUX_SEC_ERROR(saveRes);

	if (results != NULL)
		count = g_list_length(results);

	if (count > 0)
	{
		const char *pw = "";
		GnomeKeyringNetworkPasswordData *entry = g_list_nth_data(results, 0);

		SG_ASSERT(entry != NULL);

		if (entry->password)
			pw = entry->password;

		SG_ERR_CHECK(  SG_string__alloc__sz(pCtx, &password, pw)  );
	}

	*ppstrPassword = password;
	password = NULL;

fail:
	SG_STRING_NULLFREE(pCtx, path);
	SG_STRING_NULLFREE(pCtx, server);
	SG_STRING_NULLFREE(pCtx, proto);
	SG_STRING_NULLFREE(pCtx, password);
	if (results)
		gnome_keyring_network_password_list_free(results);
}
コード例 #16
0
void SG_validate__sanitize(
    SG_context* pCtx,
    const char* szValue,
    SG_uint32   uMin,
    SG_uint32   uMax,
    const char* szInvalids,
    SG_uint32   uFixFlags,
    const char* szReplace,
    const char* szAdd,
    SG_string** ppSanitized
)
{
    SG_string* sSanitized = NULL;

    SG_NULLARGCHECK(ppSanitized);

    // treat NULL replacement string as empty
    if (szReplace == NULL)
    {
        szReplace = "";
    }

    // allocate our result string
    SG_ERR_CHECK(  SG_STRING__ALLOC__SZ(pCtx, &sSanitized, szValue)  );

    // if we need to sanitize bad characters, do that
    // Note: We do this first because sanitizing characters might change the
    //       length of the string and affect the min/max length check.
    if (uFixFlags & SG_VALIDATE__RESULT__INVALID_CHARACTER)
    {
        SG_ERR_CHECK(  _replace_chars_with_string(pCtx, sSanitized, szInvalids, szReplace)  );
    }
    if (uFixFlags & SG_VALIDATE__RESULT__CONTROL_CHARACTER)
    {
        SG_ERR_CHECK(  _replace_chars_with_string(pCtx, sSanitized, SG_VALIDATE__CHARS__CONTROL, szReplace)  );
    }

    // if we need to lengthen the string, do that
    // Note: We do this prior to checking the max length because we have more fine
    //       grained control over reducing length than we do over expanding it.  We
    //       can remove individual characters, but only add characters in blocks of
    //       strlen(szAdd).  If uMin and uMax are close to each other, then adding
    //       a single szAdd might take us over uMax.  If that happens, we want to
    //       be able to trim that back down to uMax afterward.
    if (uFixFlags & SG_VALIDATE__RESULT__TOO_SHORT)
    {
        SG_uint32 uSanitized = 0u;
        SG_uint32 uAdd       = 0u;

        SG_ARGCHECK(szAdd != NULL && SG_STRLEN(szAdd) > 0u, szAdd);

        // get the length of both strings
        SG_ERR_CHECK(  SG_utf8__length_in_characters__sz(pCtx, SG_string__sz(sSanitized), &uSanitized)  );
        SG_ERR_CHECK(  SG_utf8__length_in_characters__sz(pCtx, szAdd, &uAdd)  );

        // keep adding until the sanitized string is long enough
        while (uSanitized < uMin)
        {
            SG_ERR_CHECK(  SG_string__append__sz(pCtx, sSanitized, szAdd)  );
            uSanitized += uAdd;
        }
    }

    // if we need to shorten the string, do that
    if (uFixFlags & SG_VALIDATE__RESULT__TOO_LONG)
    {
        SG_ERR_CHECK(  _truncate_string(pCtx, sSanitized, uMax)  );
    }

    // return the sanitized result
    *ppSanitized = sSanitized;
    sSanitized = NULL;

fail:
    SG_STRING_NULLFREE(pCtx, sSanitized);
    return;
}
コード例 #17
0
void SG_validate__check(
    SG_context* pCtx,
    const char* szValue,
    SG_uint32   uMin,
    SG_uint32   uMax,
    const char* szInvalids,
    SG_bool     bControls,
    SG_uint32*  pResult
)
{
    SG_uint32 uResult = 0u;
    SG_uint32 uLength = 0u;

    SG_ARGCHECK(uMin <= uMax, uMin|uMax);
    SG_NULLARGCHECK(pResult);

    // treat NULL as an empty string
    if (szValue == NULL)
    {
        szValue = "";
    }

    // validate minimum length
    uLength = SG_STRLEN(szValue);
    if (uLength < uMin)
    {
        uResult |= SG_VALIDATE__RESULT__TOO_SHORT;
    }

    // validate maximum length
    if (uLength > uMax)
    {
        uResult |= SG_VALIDATE__RESULT__TOO_LONG;
    }

    // validate specified characters
    if (szInvalids != NULL)
    {
        SG_bool bShares = SG_FALSE;
        SG_ERR_CHECK(  SG_utf8__shares_characters(pCtx, szValue, szInvalids, &bShares)  );
        if (bShares != SG_FALSE)
        {
            uResult |= SG_VALIDATE__RESULT__INVALID_CHARACTER;
        }
    }

    // validate control characters
    if (bControls != SG_FALSE)
    {
        SG_bool bShares = SG_FALSE;
        SG_ERR_CHECK(  SG_utf8__shares_characters(pCtx, szValue, SG_VALIDATE__CHARS__CONTROL, &bShares)  );
        if (bShares != SG_FALSE)
        {
            uResult |= SG_VALIDATE__RESULT__CONTROL_CHARACTER;
        }
    }

    *pResult = uResult;

fail:
    return;
}
コード例 #18
0
/**
 * Finds any character from a given set within a string and replaces them with a
 * specified replacement string.
 */
static void _replace_chars_with_string(
    SG_context* pCtx,         //< [in] [out] Error and context info.
    SG_string*  sValue,       //< [in] [out] String to perform replacements in.
    const char* szChars,      //< [in] Set of characters to replace, as a string.
    //<      NULL is treated as an empty string.
    const char* szReplacement //< [in] String to use as a replacement for the characters.
    //<      This whole string is a replacement for each found character.
    //<      NULL is treated as an empty string.
)
{
    SG_int32* pValue32       = NULL;
    SG_uint32 uValue32       = 0u;
    SG_int32* pChars32       = NULL;
    SG_uint32 uChars32       = 0u;
    SG_int32* pReplacement32 = NULL;
    SG_uint32 uReplacement32 = 0u;
    SG_int32* pResult32      = NULL;
    SG_uint32 uResult32      = 0u;
    char*     szResult       = NULL;
    SG_uint32 uResult        = 0u;
    SG_uint32 uValueIndex    = 0u;

    SG_NULLARGCHECK(sValue);

    // treat NULLs as empty strings
    if (szChars == NULL)
    {
        szChars = "";
    }
    if (szReplacement == NULL)
    {
        szReplacement = "";
    }

    // convert everything to UTF32
    // I couldn't come up with a way to do this directly in UTF8 using the APIs
    // available in sg_utf8.
    SG_ERR_CHECK(  _utf8_to_utf32(pCtx, SG_string__sz(sValue), &pValue32, &uValue32)  );
    SG_ERR_CHECK(  _utf8_to_utf32(pCtx, szChars, &pChars32, &uChars32)  );
    SG_ERR_CHECK(  _utf8_to_utf32(pCtx, szReplacement, &pReplacement32, &uReplacement32)  );

    // allocate a result buffer
    if (uReplacement32 > 1u)
    {
        // largest possible size we could end up with is if we replace every single
        // character in the value with the replacement string
        SG_ERR_CHECK(  SG_allocN(pCtx, (uReplacement32 * uValue32) + 1u, pResult32)  );
    }
    else
    {
        // largest possible size we could end up with is if we do no replacements
        // at all and are left with exactly the input value
        SG_ERR_CHECK(  SG_allocN(pCtx, uValue32 + 1u, pResult32)  );
    }

    // run through each character in the value
    for (uValueIndex = 0u; uValueIndex < uValue32; ++uValueIndex)
    {
        SG_int32  iValueChar  = pValue32[uValueIndex];
        SG_bool   bReplace    = SG_FALSE;
        SG_uint32 uCharsIndex = 0u;

        // check if this character should be replaced
        for (uCharsIndex = 0u; uCharsIndex < uChars32; ++uCharsIndex)
        {
            if (iValueChar == pChars32[uCharsIndex])
            {
                bReplace = SG_TRUE;
                break;
            }
        }
        if (bReplace == SG_FALSE)
        {
            // append the character to the output
            pResult32[uResult32] = iValueChar;
            ++uResult32;
        }
        else
        {
            // append the replacement string to the output
            memcpy((void*)(pResult32 + uResult32), (void*)pReplacement32, uReplacement32 * sizeof(SG_int32));
            uResult32 += uReplacement32;
        }
    }

    // NULL-terminate the result and convert it back to UTF8
    pResult32[uResult32] = 0;
    SG_ERR_CHECK(  _utf32_to_utf8(pCtx, pResult32, &szResult, &uResult)  );

    // return the result by replacing the original value's contents
    SG_ERR_CHECK(  SG_string__adopt_buffer(pCtx, sValue, szResult, uResult)  );
    szResult = NULL;

fail:
    SG_NULLFREE(pCtx, pValue32);
    SG_NULLFREE(pCtx, pChars32);
    SG_NULLFREE(pCtx, pReplacement32);
    SG_NULLFREE(pCtx, pResult32);
    SG_NULLFREE(pCtx, szResult);
    return;
}
コード例 #19
0
void SG_dagquery__find_new_since_common(
	SG_context * pCtx,
	SG_repo * pRepo,
	SG_uint64 dagnum,
	const char * pszOldNodeHid,
	const char * pszNewNodeHid,
	SG_stringarray ** ppResults
	)
{
	_fnsc_work_queue_t workQueue = {NULL, 0, 0, 0, NULL};
	SG_uint32 i;
	SG_dagnode * pDagnode = NULL;
	SG_stringarray * pResults = NULL;
	
	SG_ASSERT(pCtx!=NULL);
	SG_NULLARGCHECK(pRepo);
	SG_NONEMPTYCHECK(pszOldNodeHid);
	SG_NONEMPTYCHECK(pszNewNodeHid);
	SG_NULLARGCHECK(ppResults);
	
	SG_ERR_CHECK(  SG_allocN(pCtx, _FNSC_WORK_QUEUE_INIT_LENGTH, workQueue.p)  );
	workQueue.allocatedLength = _FNSC_WORK_QUEUE_INIT_LENGTH;
	SG_ERR_CHECK(  SG_RBTREE__ALLOC(pCtx, &workQueue.pRevnoCache)  );
	
	SG_ERR_CHECK(  _fnsc_work_queue__insert(pCtx, &workQueue, pszOldNodeHid, dagnum, pRepo, _ANCESTOR_OF_OLD)  );
	SG_ERR_CHECK(  _fnsc_work_queue__insert(pCtx, &workQueue, pszNewNodeHid, dagnum, pRepo, _ANCESTOR_OF_NEW)  );
	
	SG_ERR_CHECK(  SG_STRINGARRAY__ALLOC(pCtx, &pResults, 32)  );
	while(workQueue.numAncestorsOfNewOnTheQueue > 0)
	{
		const char * pszHidRef = NULL;
		SG_byte isAncestorOf = 0;
		
		SG_ERR_CHECK(  _fnsc_work_queue__pop(pCtx, &workQueue, &pDagnode, &pszHidRef, &isAncestorOf)  );
		if (isAncestorOf==_ANCESTOR_OF_NEW)
			SG_ERR_CHECK(  SG_stringarray__add(pCtx, pResults, pszHidRef)  );
		
		{
			SG_uint32 count_parents = 0;
			const char** parents = NULL;
			SG_ERR_CHECK(  SG_dagnode__get_parents__ref(pCtx, pDagnode, &count_parents, &parents)  );
			for(i=0; i<count_parents; ++i)
				SG_ERR_CHECK(  _fnsc_work_queue__insert(pCtx, &workQueue, parents[i], dagnum, pRepo, isAncestorOf)  );
		}
		
		SG_DAGNODE_NULLFREE(pCtx, pDagnode);
	}
	
	for(i=0; i<workQueue.length; ++i)
		SG_DAGNODE_NULLFREE(pCtx, workQueue.p[i].pDagnode);
	SG_NULLFREE(pCtx, workQueue.p);
	SG_RBTREE_NULLFREE(pCtx, workQueue.pRevnoCache);
	
	*ppResults = pResults;

	return;
fail:
	for(i=0; i<workQueue.length; ++i)
		SG_DAGNODE_NULLFREE(pCtx, workQueue.p[i].pDagnode);
	SG_NULLFREE(pCtx, workQueue.p);
	SG_RBTREE_NULLFREE(pCtx, workQueue.pRevnoCache);

	SG_DAGNODE_NULLFREE(pCtx, pDagnode);

	SG_STRINGARRAY_NULLFREE(pCtx, pResults);
}
コード例 #20
0
void SG_dagquery__highest_revno_common_ancestor(
	SG_context * pCtx,
	SG_repo * pRepo,
	SG_uint64 dagnum,
	const SG_stringarray * pInputNodeHids,
	char ** ppOutputNodeHid
	)
{
	const char * const * paszInputNodeHids = NULL;
	SG_uint32 countInputNodes = 0;
	SG_repo_fetch_dagnodes_handle * pDagnodeFetcher = NULL;
	_hrca_work_queue_t workQueue = {NULL, 0, 0, NULL};
	SG_uint32 i;
	SG_dagnode * pDagnode = NULL;
	const char * pszHidRef = NULL;
	SG_bitvector * pIsAncestorOf = NULL;
	SG_uint32 countIsAncestorOf = 0;

	SG_ASSERT(pCtx!=NULL);
	SG_NULLARGCHECK(pRepo);
	SG_NULLARGCHECK(pInputNodeHids);
	SG_ERR_CHECK(  SG_stringarray__sz_array_and_count(pCtx, pInputNodeHids, &paszInputNodeHids, &countInputNodes)  );
	SG_ARGCHECK(countInputNodes>0, pInputNodeHids);
	SG_NULLARGCHECK(ppOutputNodeHid);

	SG_ERR_CHECK(  SG_repo__fetch_dagnodes__begin(pCtx, pRepo, dagnum, &pDagnodeFetcher)  );

	SG_ERR_CHECK(  SG_allocN(pCtx, _HRCA_WORK_QUEUE_INIT_LENGTH, workQueue.p)  );
	workQueue.allocatedLength = _HRCA_WORK_QUEUE_INIT_LENGTH;
	SG_ERR_CHECK(  SG_RBTREE__ALLOC(pCtx, &workQueue.pRevnoCache)  );

	SG_ERR_CHECK(  SG_BITVECTOR__ALLOC(pCtx, &pIsAncestorOf, countInputNodes)  );
	for(i=0; i<countInputNodes; ++i)
	{
		SG_ERR_CHECK(  SG_bitvector__zero(pCtx, pIsAncestorOf)  );
		SG_ERR_CHECK(  SG_bitvector__set_bit(pCtx, pIsAncestorOf, i, SG_TRUE)  );
		SG_ERR_CHECK(  _hrca_work_queue__insert(pCtx, &workQueue, paszInputNodeHids[i], pRepo, pDagnodeFetcher, pIsAncestorOf)  );
	}
	SG_BITVECTOR_NULLFREE(pCtx, pIsAncestorOf);

	SG_ERR_CHECK(  _hrca_work_queue__pop(pCtx, &workQueue, &pDagnode, &pszHidRef, &pIsAncestorOf)  );
	SG_ERR_CHECK(  SG_bitvector__count_set_bits(pCtx, pIsAncestorOf, &countIsAncestorOf)  );
	while(countIsAncestorOf < countInputNodes)
	{
		SG_uint32 count_parents = 0;
		const char** parents = NULL;
		SG_ERR_CHECK(  SG_dagnode__get_parents__ref(pCtx, pDagnode, &count_parents, &parents)  );
		for(i=0; i<count_parents; ++i)
			SG_ERR_CHECK(  _hrca_work_queue__insert(pCtx, &workQueue, parents[i], pRepo, pDagnodeFetcher, pIsAncestorOf)  );
		
		SG_DAGNODE_NULLFREE(pCtx, pDagnode);
		SG_BITVECTOR_NULLFREE(pCtx, pIsAncestorOf);

		SG_ERR_CHECK(  _hrca_work_queue__pop(pCtx, &workQueue, &pDagnode, &pszHidRef, &pIsAncestorOf)  );
		SG_ERR_CHECK(  SG_bitvector__count_set_bits(pCtx, pIsAncestorOf, &countIsAncestorOf)  );
	}

	SG_ERR_CHECK(  SG_strdup(pCtx, pszHidRef, ppOutputNodeHid)  );

	SG_DAGNODE_NULLFREE(pCtx, pDagnode);
	SG_BITVECTOR_NULLFREE(pCtx, pIsAncestorOf);

	for(i=0; i<workQueue.length; ++i)
	{
		SG_DAGNODE_NULLFREE(pCtx, workQueue.p[i].pDagnode);
		SG_BITVECTOR_NULLFREE(pCtx, workQueue.p[i].pIsAncestorOf);
	}
	SG_NULLFREE(pCtx, workQueue.p);
	SG_RBTREE_NULLFREE(pCtx, workQueue.pRevnoCache);

	SG_ERR_CHECK(  SG_repo__fetch_dagnodes__end(pCtx, pRepo, &pDagnodeFetcher)  );

	return;
fail:
	for(i=0; i<workQueue.length; ++i)
	{
		SG_DAGNODE_NULLFREE(pCtx, workQueue.p[i].pDagnode);
		SG_BITVECTOR_NULLFREE(pCtx, workQueue.p[i].pIsAncestorOf);
	}
	SG_NULLFREE(pCtx, workQueue.p);
	SG_RBTREE_NULLFREE(pCtx, workQueue.pRevnoCache);

	SG_DAGNODE_NULLFREE(pCtx, pDagnode);
	SG_BITVECTOR_NULLFREE(pCtx, pIsAncestorOf);

	if(pDagnodeFetcher!=NULL)
	{
		SG_ERR_IGNORE(  SG_repo__fetch_dagnodes__end(pCtx, pRepo, &pDagnodeFetcher)  );
	}
}