Esempio n. 1
0
static void assert_config_entry_on_init_bytype(const char *config_key, int expected_value, bool is_bare)
{
	git_config *config;
	int current_value;
	git_buf repo_path = GIT_BUF_INIT;

	cl_set_cleanup(&cleanup_repository, "config_entry");

	cl_git_pass(git_buf_puts(&repo_path, "config_entry/test."));

	if (!is_bare)
		cl_git_pass(git_buf_puts(&repo_path, "non."));

	cl_git_pass(git_buf_puts(&repo_path, "bare.git"));

	cl_git_pass(git_repository_init(&_repo, git_buf_cstr(&repo_path), is_bare));

	git_buf_free(&repo_path);

	git_repository_config(&config, _repo);

	if (expected_value >= 0) {
		cl_git_pass(git_config_get_bool(&current_value, config, config_key));

		cl_assert_equal_i(expected_value, current_value);
	} else {
		int error = git_config_get_bool(&current_value, config, config_key);

		cl_assert_equal_i(expected_value, error);
	}

	git_config_free(config);
}
Esempio n. 2
0
static int buffer_want_with_caps(git_remote_head *head, git_transport_caps *caps, git_buf *buf)
{
	git_buf str = GIT_BUF_INIT;
	char oid[GIT_OID_HEXSZ +1] = {0};
	unsigned int len;

	if (caps->ofs_delta)
		git_buf_puts(&str, GIT_CAP_OFS_DELTA " ");

	if (caps->multi_ack)
		git_buf_puts(&str, GIT_CAP_MULTI_ACK " ");

	if (git_buf_oom(&str))
		return -1;

	len = (unsigned int)
		(strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
		 git_buf_len(&str) + 1 /* LF */);
	git_buf_grow(buf, git_buf_len(buf) + len);
	git_oid_fmt(oid, &head->oid);
	git_buf_printf(buf, "%04xwant %s %s\n", len, oid, git_buf_cstr(&str));
	git_buf_free(&str);

	return git_buf_oom(buf);
}
Esempio n. 3
0
static int gen_request(git_buf *buf, const char *path, const char *host, const char *op,
                       const char *service, ssize_t content_length, int ls)
{
	if (path == NULL) /* Is 'git fetch http://host.com/' valid? */
		path = "/";

	if (ls) {
		git_buf_printf(buf, "%s %s/info/refs?service=git-%s HTTP/1.1\r\n", op, path, service);
	} else {
		git_buf_printf(buf, "%s %s/git-%s HTTP/1.1\r\n", op, path, service);
	}
	git_buf_puts(buf, "User-Agent: git/1.0 (libgit2 " LIBGIT2_VERSION ")\r\n");
	git_buf_printf(buf, "Host: %s\r\n", host);
	if (content_length > 0) {
		git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", service);
		git_buf_printf(buf, "Content-Type: application/x-git-%s-request\r\n", service);
		git_buf_printf(buf, "Content-Length: %"PRIuZ "\r\n", content_length);
	} else {
		git_buf_puts(buf, "Accept: */*\r\n");
	}
	git_buf_puts(buf, "\r\n");

	if (git_buf_oom(buf))
		return -1;

	return 0;
}
Esempio n. 4
0
int git_reference_dwim(git_reference **out, git_repository *repo, const char *refname)
{
	int error = 0, i;
	bool fallbackmode = true, foundvalid = false;
	git_reference *ref;
	git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT;

	static const char* formatters[] = {
		"%s",
		GIT_REFS_DIR "%s",
		GIT_REFS_TAGS_DIR "%s",
		GIT_REFS_HEADS_DIR "%s",
		GIT_REFS_REMOTES_DIR "%s",
		GIT_REFS_REMOTES_DIR "%s/" GIT_HEAD_FILE,
		NULL
	};

	if (*refname)
		git_buf_puts(&name, refname);
	else {
		git_buf_puts(&name, GIT_HEAD_FILE);
		fallbackmode = false;
	}

	for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) {

		git_buf_clear(&refnamebuf);

		if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0)
			goto cleanup;

		if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) {
			error = GIT_EINVALIDSPEC;
			continue;
		}
		foundvalid = true;

		error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1);

		if (!error) {
			*out = ref;
			error = 0;
			goto cleanup;
		}

		if (error != GIT_ENOTFOUND)
			goto cleanup;
	}

cleanup:
	if (error && !foundvalid) {
		/* never found a valid reference name */
		giterr_set(GITERR_REFERENCE,
			"Could not use '%s' as valid reference name", git_buf_cstr(&name));
	}

	git_buf_free(&name);
	git_buf_free(&refnamebuf);
	return error;
}
Esempio n. 5
0
static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_buf *buf)
{
	git_buf str = GIT_BUF_INIT;
	char oid[GIT_OID_HEXSZ +1] = {0};
	unsigned int len;

	/* Prefer side-band-64k if the server supports both */
	if (caps->side_band) {
		if (caps->side_band_64k)
			git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K);
		else
			git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND);
	}
	if (caps->ofs_delta)
		git_buf_puts(&str, GIT_CAP_OFS_DELTA " ");

	if (caps->multi_ack)
		git_buf_puts(&str, GIT_CAP_MULTI_ACK " ");

	if (caps->include_tag)
		git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " ");

	if (git_buf_oom(&str))
		return -1;

	len = (unsigned int)
		(strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
		 git_buf_len(&str) + 1 /* LF */);
	git_buf_grow(buf, git_buf_len(buf) + len);
	git_oid_fmt(oid, &head->oid);
	git_buf_printf(buf, "%04xwant %s %s\n", len, oid, git_buf_cstr(&str));
	git_buf_free(&str);

	return git_buf_oom(buf);
}
Esempio n. 6
0
void verify_remote_refs(const git_remote_head *actual_refs[], size_t actual_refs_len, const expected_ref expected_refs[], size_t expected_refs_len)
{
	size_t i, j = 0;
	git_buf msg = GIT_BUF_INIT;
	const git_remote_head *actual;
	char *oid_str;
	bool master_present = false;

	/* We don't care whether "master" is present on the other end or not */
	for (i = 0; i < actual_refs_len; i++) {
		actual = actual_refs[i];
		if (!strcmp(actual->name, "refs/heads/master")) {
			master_present = true;
			break;
		}
	}

	if (expected_refs_len + (master_present ? 1 : 0) != actual_refs_len)
		goto failed;

	for (i = 0; i < actual_refs_len; i++) {
		actual = actual_refs[i];
		if (master_present && !strcmp(actual->name, "refs/heads/master"))
			continue;

		if (strcmp(expected_refs[j].name, actual->name) ||
			git_oid_cmp(expected_refs[j].oid, &actual->oid))
			goto failed;

		j++;
	}

	return;

failed:
	git_buf_puts(&msg, "Expected and actual refs differ:\nEXPECTED:\n");

	for(i = 0; i < expected_refs_len; i++) {
		cl_assert(oid_str = git_oid_allocfmt(expected_refs[i].oid));
		cl_git_pass(git_buf_printf(&msg, "%s = %s\n", expected_refs[i].name, oid_str));
		git__free(oid_str);
	}

	git_buf_puts(&msg, "\nACTUAL:\n");
	for (i = 0; i < actual_refs_len; i++) {
		actual = actual_refs[i];
		if (master_present && !strcmp(actual->name, "refs/heads/master"))
			continue;

		cl_assert(oid_str = git_oid_allocfmt(&actual->oid));
		cl_git_pass(git_buf_printf(&msg, "%s = %s\n", actual->name, oid_str));
		git__free(oid_str);
	}

	cl_fail(git_buf_cstr(&msg));

	git_buf_free(&msg);
}
Esempio n. 7
0
File: basic.c Progetto: 0CV0/libgit2
void test_buf_basic__resize(void)
{
	git_buf buf1 = GIT_BUF_INIT;
	git_buf_puts(&buf1, test_string);
	cl_assert(git_buf_oom(&buf1) == 0);
	cl_assert_equal_s(git_buf_cstr(&buf1), test_string);

	git_buf_puts(&buf1, test_string);
	cl_assert(strlen(git_buf_cstr(&buf1)) == strlen(test_string) * 2);
	git_buf_free(&buf1);
}
Esempio n. 8
0
static int negotiate_init_context(
    http_auth_negotiate_context *ctx,
    const gitno_connection_data *connection_data)
{
    OM_uint32 status_major, status_minor;
    gss_OID item, *oid;
    gss_OID_set mechanism_list;
    size_t i;

    /* Query supported mechanisms looking for SPNEGO) */
    if (GSS_ERROR(status_major =
                      gss_indicate_mechs(&status_minor, &mechanism_list))) {
        negotiate_err_set(status_major, status_minor,
                          "could not query mechanisms");
        return -1;
    }

    if (mechanism_list) {
        for (oid = negotiate_oids; *oid; oid++) {
            for (i = 0; i < mechanism_list->count; i++) {
                item = &mechanism_list->elements[i];

                if (item->length == (*oid)->length &&
                        memcmp(item->elements, (*oid)->elements, item->length) == 0) {
                    ctx->oid = *oid;
                    break;
                }

            }

            if (ctx->oid)
                break;
        }
    }

    gss_release_oid_set(&status_minor, &mechanism_list);

    if (!ctx->oid) {
        giterr_set(GITERR_NET, "Negotiate authentication is not supported");
        return -1;
    }

    git_buf_puts(&ctx->target, "HTTP@");
    git_buf_puts(&ctx->target, connection_data->host);

    if (git_buf_oom(&ctx->target))
        return -1;

    ctx->gss_context = GSS_C_NO_CONTEXT;
    ctx->configured = 1;

    return 0;
}
static int disambiguate_refname(git_reference **out, git_repository *repo, const char *refname)
{
	int error = 0, i;
	bool fallbackmode = true;
	git_reference *ref;
	git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT;

	static const char* formatters[] = {
		"%s",
		GIT_REFS_DIR "%s",
		GIT_REFS_TAGS_DIR "%s",
		GIT_REFS_HEADS_DIR "%s",
		GIT_REFS_REMOTES_DIR "%s",
		GIT_REFS_REMOTES_DIR "%s/" GIT_HEAD_FILE,
		NULL
	};

	if (*refname)
		git_buf_puts(&name, refname);
	else {
		git_buf_puts(&name, GIT_HEAD_FILE);
		fallbackmode = false;
	}

	for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) {

		git_buf_clear(&refnamebuf);

		if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0)
			goto cleanup;

		if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) {
			error = GIT_EINVALIDSPEC;
			continue;
		}

		error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1);

		if (!error) {
			*out = ref;
			error = 0;
			goto cleanup;
		}

		if (error != GIT_ENOTFOUND)
			goto cleanup;
	}

cleanup:
	git_buf_free(&name);
	git_buf_free(&refnamebuf);
	return error;
}
Esempio n. 10
0
static void do_verify_push_status(record_callbacks_data *data, const push_status expected[], const size_t expected_len)
{
	git_vector *actual = &data->statuses;
	push_status *iter;
	bool failed = false;
	size_t i;

	if (expected_len != actual->length)
		failed = true;
	else
		git_vector_foreach(actual, i, iter)
			if (strcmp(expected[i].ref, iter->ref) ||
				(expected[i].success != iter->success) ||
				(expected[i].msg && (!iter->msg || strcmp(expected[i].msg, iter->msg)))) {
				failed = true;
				break;
			}

	if (failed) {
		git_buf msg = GIT_BUF_INIT;

		git_buf_puts(&msg, "Expected and actual push statuses differ:\nEXPECTED:\n");

		for(i = 0; i < expected_len; i++) {
			git_buf_printf(&msg, "%s: %s\n",
				expected[i].ref,
				expected[i].success ? "success" : "failed");
		}

		git_buf_puts(&msg, "\nACTUAL:\n");

		git_vector_foreach(actual, i, iter) {
			if (iter->success)
				git_buf_printf(&msg, "%s: success\n", iter->ref);
			else
				git_buf_printf(&msg, "%s: failed with message: %s", iter->ref, iter->msg);
		}

		cl_fail(git_buf_cstr(&msg));

		git_buf_dispose(&msg);
	}

	git_vector_foreach(actual, i, iter) {
		push_status *s = (push_status *)iter;
		git__free(s->ref);
		git__free(s->msg);
		git__free(s);
	}
Esempio n. 11
0
static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_buf *buf)
{
	git_buf str = GIT_BUF_INIT;
	char oid[GIT_OID_HEXSZ +1] = {0};
	size_t len;

	/* Prefer multi_ack_detailed */
	if (caps->multi_ack_detailed)
		git_buf_puts(&str, GIT_CAP_MULTI_ACK_DETAILED " ");
	else if (caps->multi_ack)
		git_buf_puts(&str, GIT_CAP_MULTI_ACK " ");

	/* Prefer side-band-64k if the server supports both */
	if (caps->side_band_64k)
		git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K);
	else if (caps->side_band)
		git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND);

	if (caps->include_tag)
		git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " ");

	if (caps->thin_pack)
		git_buf_puts(&str, GIT_CAP_THIN_PACK " ");

	if (caps->ofs_delta)
		git_buf_puts(&str, GIT_CAP_OFS_DELTA " ");

	if (git_buf_oom(&str))
		return -1;

	len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
		 git_buf_len(&str) + 1 /* LF */;

	if (len > 0xffff) {
		giterr_set(GITERR_NET,
			"tried to produce packet with invalid length %" PRIuZ, len);
		return -1;
	}

	git_buf_grow_by(buf, len);
	git_oid_fmt(oid, &head->oid);
	git_buf_printf(buf,
		"%04xwant %s %s\n", (unsigned int)len, oid, git_buf_cstr(&str));
	git_buf_dispose(&str);

	GITERR_CHECK_ALLOC_BUF(buf);

	return 0;
}
Esempio n. 12
0
//no check is performed on ceiling_dirs length, so be sure it's long enough
static void append_ceiling_dir(git_buf *ceiling_dirs, const char *path)
{
	git_buf pretty_path = GIT_BUF_INIT;
	char ceiling_separator[2] = { GIT_PATH_LIST_SEPARATOR, '\0' };

	cl_git_pass(git_path_prettify_dir(&pretty_path, path, NULL));

	if (ceiling_dirs->size > 0)
		git_buf_puts(ceiling_dirs, ceiling_separator);

	git_buf_puts(ceiling_dirs, pretty_path.ptr);

	git_buf_free(&pretty_path);
	cl_assert(git_buf_oom(ceiling_dirs) == 0);
}
Esempio n. 13
0
static int disambiguate_refname(git_reference **out, git_repository *repo, const char *refname)
{
	int error, i;
	bool fallbackmode = true;
	git_reference *ref;
	git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT;

	static const char* formatters[] = {
		"%s",
		"refs/%s",
		"refs/tags/%s",
		"refs/heads/%s",
		"refs/remotes/%s",
		"refs/remotes/%s/HEAD",
		NULL
	};

	if (*refname)
		git_buf_puts(&name, refname);
	else {
		git_buf_puts(&name, GIT_HEAD_FILE);
		fallbackmode = false;
	}

	for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) {

		git_buf_clear(&refnamebuf);

		if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0)
			goto cleanup;

		error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1);

		if (!error) {
			*out = ref;
			error = 0;
			goto cleanup;
		}

		if (error != GIT_ENOTFOUND)
			goto cleanup;
	}

cleanup:
	git_buf_free(&name);
	git_buf_free(&refnamebuf);
	return error;
}
Esempio n. 14
0
static int refspec_transform(
	git_buf *out, const char *from, const char *to, const char *name)
{
	const char *from_star, *to_star;
	size_t replacement_len, star_offset;

	git_buf_sanitize(out);
	git_buf_clear(out);

	/*
	 * There are two parts to each side of a refspec, the bit
	 * before the star and the bit after it. The star can be in
	 * the middle of the pattern, so we need to look at each bit
	 * individually.
	 */
	from_star = strchr(from, '*');
	to_star = strchr(to, '*');

	assert(from_star && to_star);

	/* star offset, both in 'from' and in 'name' */
	star_offset = from_star - from;

	/* the first half is copied over */
	git_buf_put(out, to, to_star - to);

	/*
	 * Copy over the name, but exclude the trailing part in "from" starting
	 * after the glob
	 */
	replacement_len = strlen(name + star_offset) - strlen(from_star + 1);
	git_buf_put(out, name + star_offset, replacement_len);

	return git_buf_puts(out, to_star + 1);
}
Esempio n. 15
0
/* let's try some producer/consumer tests */
void test_core_buffer__4(void)
{
	git_buf buf = GIT_BUF_INIT;
	int i;

	for (i = 0; i < 10; ++i) {
		git_buf_puts(&buf, "1234"); /* add 4 */
		cl_assert(git_buf_oom(&buf) == 0);
		git_buf_consume(&buf, buf.ptr + 2); /* eat the first two */
		cl_assert(strlen(git_buf_cstr(&buf)) == (size_t)((i + 1) * 2));
	}
	/* we have appended 1234 10x and removed the first 20 letters */
	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));

	git_buf_consume(&buf, NULL);
	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));

	git_buf_consume(&buf, "invalid pointer");
	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));

	git_buf_consume(&buf, buf.ptr);
	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));

	git_buf_consume(&buf, buf.ptr + 1);
	cl_assert_equal_s("2341234123412341234", git_buf_cstr(&buf));

	git_buf_consume(&buf, buf.ptr + buf.size);
	cl_assert_equal_s("", git_buf_cstr(&buf));

	git_buf_free(&buf);
}
Esempio n. 16
0
/* test basic data concatenation */
void test_core_buffer__0(void)
{
	git_buf buf = GIT_BUF_INIT;

	cl_assert(buf.size == 0);

	git_buf_puts(&buf, test_string);
	cl_assert(git_buf_oom(&buf) == 0);
	cl_assert_equal_s(test_string, git_buf_cstr(&buf));

	git_buf_puts(&buf, test_string);
	cl_assert(git_buf_oom(&buf) == 0);
	cl_assert_equal_s(test_string_x2, git_buf_cstr(&buf));

	git_buf_free(&buf);
}
Esempio n. 17
0
File: stash.c Progetto: aep/libgit2
static int retrieve_base_commit_and_message(
	git_commit **b_commit,
	git_buf *stash_message,
	git_repository *repo)
{
	git_reference *head = NULL;
	int error;

	if ((error = retrieve_head(&head, repo)) < 0)
		return error;

	if (strcmp("HEAD", git_reference_name(head)) == 0)
		error = git_buf_puts(stash_message, "(no branch): ");
	else
		error = git_buf_printf(
			stash_message,
			"%s: ",
			git_reference_name(head) + strlen(GIT_REFS_HEADS_DIR));
	if (error < 0)
		goto cleanup;

	if ((error = git_commit_lookup(
			 b_commit, repo, git_reference_target(head))) < 0)
		goto cleanup;

	if ((error = append_commit_description(stash_message, *b_commit)) < 0)
		goto cleanup;

cleanup:
	git_reference_free(head);
	return error;
}
Esempio n. 18
0
File: stash.c Progetto: aep/libgit2
static int prepare_worktree_commit_message(
	git_buf* msg,
	const char *user_message)
{
	git_buf buf = GIT_BUF_INIT;
	int error;

	if ((error = git_buf_set(&buf, git_buf_cstr(msg), git_buf_len(msg))) < 0)
		return error;

	git_buf_clear(msg);

	if (!user_message)
		git_buf_printf(msg, "WIP on %s", git_buf_cstr(&buf));
	else {
		const char *colon;

		if ((colon = strchr(git_buf_cstr(&buf), ':')) == NULL)
			goto cleanup;

		git_buf_puts(msg, "On ");
		git_buf_put(msg, git_buf_cstr(&buf), colon - buf.ptr);
		git_buf_printf(msg, ": %s\n", user_message);
	}

	error = (git_buf_oom(msg) || git_buf_oom(&buf)) ? -1 : 0;

cleanup:
	git_buf_free(&buf);

	return error;
}
Esempio n. 19
0
static int write_tag_annotation(
    git_oid *oid,
    git_repository *repo,
    const char *tag_name,
    const git_object *target,
    const git_signature *tagger,
    const char *message)
{
    git_buf tag = GIT_BUF_INIT;
    git_odb *odb;

    git_oid__writebuf(&tag, "object ", git_object_id(target));
    git_buf_printf(&tag, "type %s\n", git_object_type2string(git_object_type(target)));
    git_buf_printf(&tag, "tag %s\n", tag_name);
    git_signature__writebuf(&tag, "tagger ", tagger);
    git_buf_putc(&tag, '\n');

    if (git_buf_puts(&tag, message) < 0)
        goto on_error;

    if (git_repository_odb__weakptr(&odb, repo) < 0)
        goto on_error;

    if (git_odb_write(oid, odb, tag.ptr, tag.size, GIT_OBJ_TAG) < 0)
        goto on_error;

    git_buf_free(&tag);
    return 0;

on_error:
    git_buf_free(&tag);
    giterr_set(GITERR_OBJECT, "Failed to create tag annotation.");
    return -1;
}
Esempio n. 20
0
static void create_paths(const char *root, int depth)
{
	git_buf fullpath = GIT_BUF_INIT;
	size_t root_len;
	int i;

	cl_git_pass(git_buf_puts(&fullpath, root));
	cl_git_pass(git_buf_putc(&fullpath, '/'));

	root_len = fullpath.size;

	for (i = 0; i < 8; i++) {
		bool file = (depth == 0 || (i % 2) == 0);
		git_buf_truncate(&fullpath, root_len);
		cl_git_pass(git_buf_printf(&fullpath, "item%d", i));

		if (file) {
			cl_git_rewritefile(fullpath.ptr, "This is a file!\n");
		} else {
			cl_must_pass(p_mkdir(fullpath.ptr, 0777));

			if (depth > 0)
				create_paths(fullpath.ptr, (depth - 1));
		}
	}

	git_buf_dispose(&fullpath);
}
Esempio n. 21
0
int git_futils_mktmp(git_buf *path_out, const char *filename, mode_t mode)
{
	int fd;
	mode_t mask;

	p_umask(mask = p_umask(0));

	git_buf_sets(path_out, filename);
	git_buf_puts(path_out, "_git2_XXXXXX");

	if (git_buf_oom(path_out))
		return -1;

	if ((fd = p_mkstemp(path_out->ptr)) < 0) {
		giterr_set(GITERR_OS,
			"Failed to create temporary file '%s'", path_out->ptr);
		return -1;
	}

	if (p_chmod(path_out->ptr, (mode & ~mask))) {
		giterr_set(GITERR_OS,
			"Failed to set permissions on file '%s'", path_out->ptr);
		return -1;
	}

	return fd;
}
Esempio n. 22
0
static int rebase_open_merge(git_rebase *rebase)
{
	git_buf state_path = GIT_BUF_INIT, buf = GIT_BUF_INIT, cmt = GIT_BUF_INIT;
	git_oid id;
	git_rebase_operation *operation;
	size_t i, msgnum = 0, end;
	int error;

	if ((error = git_buf_puts(&state_path, rebase->state_path)) < 0)
		goto done;

	/* Read 'msgnum' if it exists (otherwise, let msgnum = 0) */
	if ((error = rebase_readint(&msgnum, &buf, &state_path, MSGNUM_FILE)) < 0 &&
		error != GIT_ENOTFOUND)
		goto done;

	if (msgnum) {
		rebase->started = 1;
		rebase->current = msgnum - 1;
	}

	/* Read 'end' */
	if ((error = rebase_readint(&end, &buf, &state_path, END_FILE)) < 0)
		goto done;

	/* Read 'current' if it exists */
	if ((error = rebase_readoid(&id, &buf, &state_path, CURRENT_FILE)) < 0 &&
		error != GIT_ENOTFOUND)
		goto done;

	/* Read cmt.* */
	git_array_init_to_size(rebase->operations, end);
	GITERR_CHECK_ARRAY(rebase->operations);

	for (i = 0; i < end; i++) {
		git_buf_clear(&cmt);

		if ((error = git_buf_printf(&cmt, "cmt.%" PRIuZ, (i+1))) < 0 ||
			(error = rebase_readoid(&id, &buf, &state_path, cmt.ptr)) < 0)
			goto done;

		operation = rebase_operation_alloc(rebase, GIT_REBASE_OPERATION_PICK, &id, NULL);
		GITERR_CHECK_ALLOC(operation);
	}

	/* Read 'onto_name' */
	if ((error = rebase_readfile(&buf, &state_path, ONTO_NAME_FILE)) < 0)
		goto done;

	rebase->onto_name = git_buf_detach(&buf);

done:
	git_buf_free(&cmt);
	git_buf_free(&state_path);
	git_buf_free(&buf);

	return error;
}
Esempio n. 23
0
const char* cl_git_path_url(const char *path)
{
	static char url[4096];

	const char *in_buf;
	git_buf path_buf = GIT_BUF_INIT;
	git_buf url_buf = GIT_BUF_INIT;

	cl_git_pass(git_path_prettify_dir(&path_buf, path, NULL));
	cl_git_pass(git_buf_puts(&url_buf, "file://"));

#ifdef GIT_WIN32
	/*
	 * A FILE uri matches the following format: file://[host]/path
	 * where "host" can be empty and "path" is an absolute path to the resource.
	 *
	 * In this test, no hostname is used, but we have to ensure the leading triple slashes:
	 *
	 * *nix: file:///usr/home/...
	 * Windows: file:///C:/Users/...
	 */
	cl_git_pass(git_buf_putc(&url_buf, '/'));
#endif

	in_buf = git_buf_cstr(&path_buf);

	/*
	 * A very hacky Url encoding that only takes care of escaping the spaces
	 */
	while (*in_buf) {
		if (*in_buf == ' ')
			cl_git_pass(git_buf_puts(&url_buf, "%20"));
		else
			cl_git_pass(git_buf_putc(&url_buf, *in_buf));

		in_buf++;
	}

	cl_assert(url_buf.size < 4096);

	strncpy(url, git_buf_cstr(&url_buf), 4096);
	git_buf_free(&url_buf);
	git_buf_free(&path_buf);
	return url;
}
Esempio n. 24
0
static int gen_request(
	git_buf *buf,
	http_stream *s,
	size_t content_length)
{
	http_subtransport *t = OWNING_SUBTRANSPORT(s);
	const char *path = t->connection_data.path ? t->connection_data.path : "/";

	git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n", s->verb, path, s->service_url);

	git_buf_puts(buf, "User-Agent: git/1.0 (libgit2 " LIBGIT2_VERSION ")\r\n");
	git_buf_printf(buf, "Host: %s\r\n", t->connection_data.host);

	if (s->chunked || content_length > 0) {
		git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", s->service);
		git_buf_printf(buf, "Content-Type: application/x-git-%s-request\r\n", s->service);

		if (s->chunked)
			git_buf_puts(buf, "Transfer-Encoding: chunked\r\n");
		else
			git_buf_printf(buf, "Content-Length: %"PRIuZ "\r\n", content_length);
	} else
		git_buf_puts(buf, "Accept: */*\r\n");

	/* Apply credentials to the request */
	if (t->cred && t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT &&
		t->auth_mechanism == GIT_HTTP_AUTH_BASIC &&
		apply_basic_credential(buf, t->cred) < 0)
		return -1;

	/* Use url-parsed basic auth if username and password are both provided */
	if (!t->cred && t->connection_data.user && t->connection_data.pass) {
		if (!t->url_cred && git_cred_userpass_plaintext_new(&t->url_cred,
					t->connection_data.user, t->connection_data.pass) < 0)
			return -1;
		if (apply_basic_credential(buf, t->url_cred) < 0) return -1;
	}

	git_buf_puts(buf, "\r\n");

	if (git_buf_oom(buf))
		return -1;

	return 0;
}
Esempio n. 25
0
/**
 * Append to 'out' properly marking continuations when there's a newline in 'content'
 */
static void format_header_field(git_buf *out, const char *field, const char *content)
{
	const char *lf;

	assert(out && field && content);

	git_buf_puts(out, field);
	git_buf_putc(out, ' ');

	while ((lf = strchr(content, '\n')) != NULL) {
		git_buf_put(out, content, lf - content);
		git_buf_puts(out, "\n ");
		content = lf + 1;
	}

	git_buf_puts(out, content);
	git_buf_putc(out, '\n');
}
Esempio n. 26
0
static void expect_unquote_fail(const char *quoted)
{
	git_buf buf = GIT_BUF_INIT;

	cl_git_pass(git_buf_puts(&buf, quoted));
	cl_git_fail(git_buf_unquote(&buf));

	git_buf_dispose(&buf);
}
Esempio n. 27
0
int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name)
{
        git_buf_sanitize(out);

	if (!spec->pattern)
		return git_buf_puts(out, spec->src);

	return refspec_transform(out, spec->dst, spec->src, name);
}
static int remote_name(git_buf *buf, git_repository *repo, const char *canonical_branch_name)
{
	git_strarray remote_list = {0};
	size_t i;
	git_remote *remote;
	const git_refspec *fetchspec;
	int error = 0;
	char *remote_name = NULL;

	assert(buf && repo && canonical_branch_name);

	/* Verify that this is a remote branch */
	if (!git_reference__is_remote(canonical_branch_name)) {
		giterr_set(GITERR_INVALID, "Reference '%s' is not a remote branch.",
			canonical_branch_name);
		error = GIT_ERROR;
		goto cleanup;
	}

	/* Get the remotes */
	if ((error = git_remote_list(&remote_list, repo)) < 0)
		goto cleanup;

	/* Find matching remotes */
	for (i = 0; i < remote_list.count; i++) {
		if ((error = git_remote_load(&remote, repo, remote_list.strings[i])) < 0)
			continue;

		fetchspec = git_remote__matching_dst_refspec(remote, canonical_branch_name);
		if (fetchspec) {
			/* If we have not already set out yet, then set
			 * it to the matching remote name. Otherwise
			 * multiple remotes match this reference, and it
			 * is ambiguous. */
			if (!remote_name) {
				remote_name = remote_list.strings[i];
			} else {
				git_remote_free(remote);
				error = GIT_EAMBIGUOUS;
				goto cleanup;
			}
		}

		git_remote_free(remote);
	}

	if (remote_name) {
		git_buf_clear(buf);
		error = git_buf_puts(buf, remote_name);
	} else {
		error = GIT_ENOTFOUND;
	}

cleanup:
	git_strarray_free(&remote_list);
	return error;
}
Esempio n. 29
0
void giterr_set(int error_class, const char *string, ...)
{
	git_buf buf = GIT_BUF_INIT;
	va_list arglist;
#ifdef GIT_WIN32
	DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0;
#endif
	int error_code = (error_class == GITERR_OS) ? errno : 0;

	va_start(arglist, string);
	git_buf_vprintf(&buf, string, arglist);
	va_end(arglist);

	if (error_class == GITERR_OS) {
#ifdef GIT_WIN32
		if (win32_error_code) {
			char *lpMsgBuf;

			if (FormatMessageA(
					FORMAT_MESSAGE_ALLOCATE_BUFFER |
					FORMAT_MESSAGE_FROM_SYSTEM |
					FORMAT_MESSAGE_IGNORE_INSERTS,
					NULL, win32_error_code, 0, (LPSTR)&lpMsgBuf, 0, NULL)) {
				git_buf_PUTS(&buf, ": ");
				git_buf_puts(&buf, lpMsgBuf);
				LocalFree(lpMsgBuf);
			}

			SetLastError(0);
		}
		else
#endif
		if (error_code) {
			git_buf_PUTS(&buf, ": ");
			git_buf_puts(&buf, strerror(error_code));
		}

		if (error_code)
			errno = 0;
	}

	if (!git_buf_oom(&buf))
		set_error(error_class, git_buf_detach(&buf));
}
Esempio n. 30
0
static int apply_basic_credential(HINTERNET request, git_cred *cred)
{
	git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
	git_buf buf = GIT_BUF_INIT, raw = GIT_BUF_INIT;
	wchar_t *wide = NULL;
	int error = -1, wide_len = 0;

	git_buf_printf(&raw, "%s:%s", c->username, c->password);

	if (git_buf_oom(&raw) ||
		git_buf_puts(&buf, "Authorization: Basic ") < 0 ||
		git_buf_put_base64(&buf, git_buf_cstr(&raw), raw.size) < 0)
		goto on_error;

	wide_len = MultiByteToWideChar(CP_UTF8,	MB_ERR_INVALID_CHARS,
		git_buf_cstr(&buf),	-1, NULL, 0);

	if (!wide_len) {
		giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to measure string for wide conversion"));
		goto on_error;
	}

	wide = git__malloc(wide_len * sizeof(wchar_t));

	if (!wide)
		goto on_error;

	if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
		git_buf_cstr(&buf), -1, wide, wide_len)) {
		giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to convert string to wide form"));
		goto on_error;
	}

	if (!WinHttpAddRequestHeaders(request, wide, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
		giterr_set(GITERR_OS, QT_TRANSLATE_NOOP("libgit2", "Failed to add a header to the request"));
		goto on_error;
	}

	error = 0;

on_error:
	/* We were dealing with plaintext passwords, so clean up after ourselves a bit. */
	if (wide)
		memset(wide, 0x0, wide_len * sizeof(wchar_t));

	if (buf.size)
		memset(buf.ptr, 0x0, buf.size);

	if (raw.size)
		memset(raw.ptr, 0x0, raw.size);

	git__free(wide);
	git_buf_free(&buf);
	git_buf_free(&raw);
	return error;
}