예제 #1
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_expand_path_tokens(krb5_context context,
			 const char *path_in,
			 char **ppath_out)
{
    char *tok_begin, *tok_end, *append;
    const char *path_left;
    size_t len = 0;

    if (path_in == NULL || *path_in == '\0') {
        *ppath_out = strdup("");
        return 0;
    }

    *ppath_out = NULL;

    for (path_left = path_in; path_left && *path_left; ) {

	tok_begin = strstr(path_left, "%{");

	if (tok_begin && tok_begin != path_left) {

	    append = malloc((tok_begin - path_left) + 1);
	    if (append) {
		memcpy(append, path_left, tok_begin - path_left);
		append[tok_begin - path_left] = '\0';
	    }
	    path_left = tok_begin;

	} else if (tok_begin) {

	    tok_end = strchr(tok_begin, '}');
	    if (tok_end == NULL) {
		if (*ppath_out)
		    free(*ppath_out);
		*ppath_out = NULL;
		if (context)
		    krb5_set_error_message(context, EINVAL, "variable missing }");
		return EINVAL;
	    }

	    if (_expand_token(context, tok_begin, tok_end, &append)) {
		if (*ppath_out)
		    free(*ppath_out);
		*ppath_out = NULL;
		return EINVAL;
	    }

	    path_left = tok_end + 1;
	} else {

	    append = strdup(path_left);
	    path_left = NULL;

	}

	if (append == NULL) {

	    if (*ppath_out)
		free(*ppath_out);
	    *ppath_out = NULL;
	    if (context)
		krb5_set_error_message(context, ENOMEM, "malloc - out of memory");
	    return ENOMEM;

	}
	
	{
	    size_t append_len = strlen(append);
	    char * new_str = realloc(*ppath_out, len + append_len + 1);

	    if (new_str == NULL) {
		free(append);
		if (*ppath_out)
		    free(*ppath_out);
		*ppath_out = NULL;
		if (context)
		    krb5_set_error_message(context, ENOMEM, "malloc - out of memory");
		return ENOMEM;
	    }

	    *ppath_out = new_str;
	    memcpy(*ppath_out + len, append, append_len + 1);
	    len = len + append_len;
	    free(append);
	}
    }

#ifdef _WIN32
    /* Also deal with slashes */
    if (*ppath_out) {
	char * c;
	for (c = *ppath_out; *c; c++)
	    if (*c == '/')
		*c = '\\';
    }
#endif

    return 0;
}
예제 #2
0
/**
 * Internal function to expand tokens in paths.
 *
 * Inputs:
 *
 * @context   A krb5_context
 * @path_in   The path to expand tokens from
 * @token     Variable number of pairs of strings, the first of each
 *            being a token (e.g., "luser") and the second a string to
 *            replace it with.  The list is terminated by a NULL.
 * 
 * Outputs:
 *
 * @ppath_out Path with expanded tokens (caller must free() this)
 */
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_expand_path_tokensv(krb5_context context,
			  const char *path_in,
			  char **ppath_out, ...)
{
    char *tok_begin, *tok_end, *append;
    char **extra_tokens = NULL;
    const char *path_left;
    const char *s;
    size_t nextra_tokens = 0;
    size_t len = 0;
    va_list ap;

    if (path_in == NULL || *path_in == '\0') {
        *ppath_out = strdup("");
        return 0;
    }

    *ppath_out = NULL;

    va_start(ap, ppath_out);
    while ((s = va_arg(ap, const char *))) {
	nextra_tokens++;
	s = va_arg(ap, const char *);
    }
    va_end(ap);

    /* Get extra tokens */
    if (nextra_tokens) {
	size_t i;

	extra_tokens = calloc(nextra_tokens + 2, sizeof (*extra_tokens));
	if (extra_tokens == NULL)
	    return krb5_enomem(context);
	va_start(ap, ppath_out);
	for (i = 0; i < nextra_tokens; i++) {
	    s = va_arg(ap, const char *);
	    if (s == NULL)
		break;
	    extra_tokens[i] = strdup(s);
	    if (extra_tokens[i++] == NULL) {
		free_extra_tokens(extra_tokens);
		return krb5_enomem(context);
	    }
	    s = va_arg(ap, const char *);
	    if (s == NULL)
		break;
	    extra_tokens[i] = strdup(s);
	    if (extra_tokens[i] == NULL) {
		free_extra_tokens(extra_tokens);
		return krb5_enomem(context);
	    }
	}
	va_end(ap);
    }

    for (path_left = path_in; path_left && *path_left; ) {

	tok_begin = strstr(path_left, "%{");

	if (tok_begin && tok_begin != path_left) {

	    append = malloc((tok_begin - path_left) + 1);
	    if (append) {
		memcpy(append, path_left, tok_begin - path_left);
		append[tok_begin - path_left] = '\0';
	    }
	    path_left = tok_begin;

	} else if (tok_begin) {

	    tok_end = strchr(tok_begin, '}');
	    if (tok_end == NULL) {
		free_extra_tokens(extra_tokens);
		if (*ppath_out)
		    free(*ppath_out);
		*ppath_out = NULL;
		if (context)
		    krb5_set_error_message(context, EINVAL, "variable missing }");
		return EINVAL;
	    }

	    if (_expand_token(context, tok_begin, tok_end, extra_tokens,
			      &append)) {
		free_extra_tokens(extra_tokens);
		if (*ppath_out)
		    free(*ppath_out);
		*ppath_out = NULL;
		return EINVAL;
	    }

	    path_left = tok_end + 1;
	} else {

	    append = strdup(path_left);
	    path_left = NULL;

	}

	if (append == NULL) {

	    free_extra_tokens(extra_tokens);
	    if (*ppath_out)
		free(*ppath_out);
	    *ppath_out = NULL;
	    return krb5_enomem(context);

	}

	{
	    size_t append_len = strlen(append);
	    char * new_str = realloc(*ppath_out, len + append_len + 1);

	    if (new_str == NULL) {
		free_extra_tokens(extra_tokens);
		free(append);
		if (*ppath_out)
		    free(*ppath_out);
		*ppath_out = NULL;
		return krb5_enomem(context);
	    }

	    *ppath_out = new_str;
	    memcpy(*ppath_out + len, append, append_len + 1);
	    len = len + append_len;
	    free(append);
	}
    }

#ifdef _WIN32
    /* Also deal with slashes */
    if (*ppath_out) {
	char * c;
	for (c = *ppath_out; *c; c++)
	    if (*c == '/')
		*c = '\\';
    }
#endif

    free_extra_tokens(extra_tokens);
    return 0;
}