Example #1
0
static int handle_conflict(struct strbuf *out, struct rerere_io *io,
			   int marker_size, git_SHA_CTX *ctx)
{
	enum {
		RR_SIDE_1 = 0, RR_SIDE_2, RR_ORIGINAL
	} hunk = RR_SIDE_1;
	struct strbuf one = STRBUF_INIT, two = STRBUF_INIT;
	struct strbuf buf = STRBUF_INIT, conflict = STRBUF_INIT;
	int has_conflicts = -1;

	while (!io->getline(&buf, io)) {
		if (is_cmarker(buf.buf, '<', marker_size)) {
			if (handle_conflict(&conflict, io, marker_size, NULL) < 0)
				break;
			if (hunk == RR_SIDE_1)
				strbuf_addbuf(&one, &conflict);
			else
				strbuf_addbuf(&two, &conflict);
			strbuf_release(&conflict);
		} else if (is_cmarker(buf.buf, '|', marker_size)) {
			if (hunk != RR_SIDE_1)
				break;
			hunk = RR_ORIGINAL;
		} else if (is_cmarker(buf.buf, '=', marker_size)) {
			if (hunk != RR_SIDE_1 && hunk != RR_ORIGINAL)
				break;
			hunk = RR_SIDE_2;
		} else if (is_cmarker(buf.buf, '>', marker_size)) {
			if (hunk != RR_SIDE_2)
				break;
			if (strbuf_cmp(&one, &two) > 0)
				strbuf_swap(&one, &two);
			has_conflicts = 1;
			rerere_strbuf_putconflict(out, '<', marker_size);
			strbuf_addbuf(out, &one);
			rerere_strbuf_putconflict(out, '=', marker_size);
			strbuf_addbuf(out, &two);
			rerere_strbuf_putconflict(out, '>', marker_size);
			if (ctx) {
				git_SHA1_Update(ctx, one.buf ? one.buf : "",
					    one.len + 1);
				git_SHA1_Update(ctx, two.buf ? two.buf : "",
					    two.len + 1);
			}
			break;
		} else if (hunk == RR_SIDE_1)
			strbuf_addbuf(&one, &buf);
		else if (hunk == RR_ORIGINAL)
			; /* discard */
		else if (hunk == RR_SIDE_2)
			strbuf_addbuf(&two, &buf);
	}
	strbuf_release(&one);
	strbuf_release(&two);
	strbuf_release(&buf);

	return has_conflicts;
}
Example #2
0
File: gidit.c Project: zhaoz/gidit
/**
 * Given projdir and strbuf containing the pushobject, update with new
 * pushobject and update head file as well as projdir struct.
 * TODO verify pushobj with PGP key
 */
static int append_pushobj(struct projdir * pd, struct strbuf * pobj,
                          struct strbuf *sig)
{
    unsigned char sha1[20];
    char sha1_hex[41];
    FILE * pobj_fp;
    char * file_path;
    git_SHA_CTX c;

    git_SHA1_Init(&c);
    git_SHA1_Update(&c, pobj->buf, pobj->len);
    git_SHA1_Final(sha1, &c);

    file_path = (char*)malloc(strlen(pd->projdir) + 40 + 1);
    strcpy(sha1_hex, sha1_to_hex(sha1));
    sprintf(file_path, "%s/%s", pd->projdir, sha1_hex);

    if (access(file_path, F_OK) == 0)
        return error("Push object alread exists");

    pobj_fp = fopen(file_path, "w");
    fprintf(pobj_fp, "%s", pobj->buf);
    fprintf(pobj_fp, "%s", sig->buf);
    fprintf(pobj_fp, "%s PREV\n", pd->head);
    fclose(pobj_fp);

    update_proj_head(pd, sha1_hex);
    free(file_path);
    return 0;
}
Example #3
0
static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed)
{
	struct remote_lock *lock = (struct remote_lock *)ctx->userData;
	git_SHA_CTX sha_ctx;
	unsigned char lock_token_sha1[20];

	if (tag_closed && ctx->cdata) {
		if (!strcmp(ctx->name, DAV_ACTIVELOCK_OWNER)) {
			lock->owner = xstrdup(ctx->cdata);
		} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) {
			const char *arg;
			if (skip_prefix(ctx->cdata, "Second-", &arg))
				lock->timeout = strtol(arg, NULL, 10);
		} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
			lock->token = xstrdup(ctx->cdata);

			git_SHA1_Init(&sha_ctx);
			git_SHA1_Update(&sha_ctx, lock->token, strlen(lock->token));
			git_SHA1_Final(lock_token_sha1, &sha_ctx);

			lock->tmpfile_suffix[0] = '_';
			memcpy(lock->tmpfile_suffix + 1, sha1_to_hex(lock_token_sha1), 40);
		}
	}
}
Example #4
0
/* Discard current buffer used content. */
static void flush(void)
{
	if (input_offset) {
		if (output_fd >= 0)
			write_or_die(output_fd, input_buffer, input_offset);
		git_SHA1_Update(&input_ctx, input_buffer, input_offset);
		memmove(input_buffer, input_buffer + input_offset, input_len);
		input_offset = 0;
	}
}
Example #5
0
File: test-sha1.c Project: 0369/git
int main(int ac, char **av)
{
	git_SHA_CTX ctx;
	unsigned char sha1[20];
	unsigned bufsz = 8192;
	int binary = 0;
	char *buffer;

	if (ac == 2) {
		if (!strcmp(av[1], "-b"))
			binary = 1;
		else
			bufsz = strtoul(av[1], NULL, 10) * 1024 * 1024;
	}

	if (!bufsz)
		bufsz = 8192;

	while ((buffer = malloc(bufsz)) == NULL) {
		fprintf(stderr, "bufsz %u is too big, halving...\n", bufsz);
		bufsz /= 2;
		if (bufsz < 1024)
			die("OOPS");
	}

	git_SHA1_Init(&ctx);

	while (1) {
		ssize_t sz, this_sz;
		char *cp = buffer;
		unsigned room = bufsz;
		this_sz = 0;
		while (room) {
			sz = xread(0, cp, room);
			if (sz == 0)
				break;
			if (sz < 0)
				die_errno("test-sha1");
			this_sz += sz;
			cp += sz;
			room -= sz;
		}
		if (this_sz == 0)
			break;
		git_SHA1_Update(&ctx, buffer, this_sz);
	}
	git_SHA1_Final(sha1, &ctx);

	if (binary)
		fwrite(sha1, 1, 20, stdout);
	else
		puts(sha1_to_hex(sha1));
	exit(0);
}
Example #6
0
static void hmac_sha1(unsigned char *out,
		      const char *key_in, size_t key_len,
		      const char *text, size_t text_len)
{
	unsigned char key[HMAC_BLOCK_SIZE];
	unsigned char k_ipad[HMAC_BLOCK_SIZE];
	unsigned char k_opad[HMAC_BLOCK_SIZE];
	int i;
	git_SHA_CTX ctx;

	/* RFC 2104 2. (1) */
	memset(key, '\0', HMAC_BLOCK_SIZE);
	if (HMAC_BLOCK_SIZE < key_len) {
		git_SHA1_Init(&ctx);
		git_SHA1_Update(&ctx, key_in, key_len);
		git_SHA1_Final(key, &ctx);
	} else {
		memcpy(key, key_in, key_len);
	}

	/* RFC 2104 2. (2) & (5) */
	for (i = 0; i < sizeof(key); i++) {
		k_ipad[i] = key[i] ^ 0x36;
		k_opad[i] = key[i] ^ 0x5c;
	}

	/* RFC 2104 2. (3) & (4) */
	git_SHA1_Init(&ctx);
	git_SHA1_Update(&ctx, k_ipad, sizeof(k_ipad));
	git_SHA1_Update(&ctx, text, text_len);
	git_SHA1_Final(out, &ctx);

	/* RFC 2104 2. (6) & (7) */
	git_SHA1_Init(&ctx);
	git_SHA1_Update(&ctx, k_opad, sizeof(k_opad));
	git_SHA1_Update(&ctx, out, 20);
	git_SHA1_Final(out, &ctx);
}
Example #7
0
File: gidit.c Project: zhaoz/gidit
int gidit_store_bundle(FILE *fp, const char * basepath, unsigned int flags)
{
    char start_pobj_sha1[41];
    char end_pobj_sha1[41];
    unsigned char bundle_sha1[20];
    struct strbuf bundle = STRBUF_INIT;
    git_SHA_CTX c;
    FILE * out;

    if (!read_sha1(fp, start_pobj_sha1) || !read_sha1(fp, end_pobj_sha1))
        return error("protocol error: could not read sha1");

    if (!enter_bundle_dir(basepath, start_pobj_sha1, end_pobj_sha1))
        return error("Failed to enter gidit pushobj dir");


    // now we need to read in the bundle, and store it in it's own sha1

    strbuf_getline(&bundle, fp, EOF);
    if (bundle.len == 0)
        return error("Protocol error while reading bundle");

    git_SHA1_Init(&c);
    git_SHA1_Update(&c, bundle.buf, bundle.len);
    git_SHA1_Final(bundle_sha1, &c);

    out = fopen(sha1_to_hex(bundle_sha1), "w");

    if (!out)
        die("Error while writing bundle");

    if (fwrite(bundle.buf, bundle.len, 1, out) != 1)
        die("Error while writing to bundle");

    fclose(out);

    strbuf_release(&bundle);

    // create BUNDLE file pointing to sha1
    out = fopen("BUNDLES", "a");

    if (!out)
        die("Error while writing to BUNDLE");

    fprintf(out, "%s\n", sha1_to_hex(bundle_sha1));

    fclose(out);

    return 0;
}
Example #8
0
/*
 * Make sure at least "min" bytes are available in the buffer, and
 * return the pointer to the buffer.
 */
static void *fill(int min)
{
	if (min <= len)
		return buffer + offset;
	if (min > sizeof(buffer))
		die("cannot fill %d bytes", min);
	if (offset) {
		git_SHA1_Update(&ctx, buffer, offset);
		memmove(buffer, buffer + offset, len);
		offset = 0;
	}
	do {
		ssize_t ret = xread(0, buffer + len, sizeof(buffer) - len);
		if (ret <= 0) {
			if (!ret)
				die("early EOF");
			die_errno("read error on input");
		}
		len += ret;
	} while (len < min);
	return buffer;
}
Example #9
0
static int handle_path(unsigned char *sha1, struct rerere_io *io, int marker_size)
{
	git_SHA_CTX ctx;
	int hunk_no = 0;
	enum {
		RR_CONTEXT = 0, RR_SIDE_1, RR_SIDE_2, RR_ORIGINAL
	} hunk = RR_CONTEXT;
	struct strbuf one = STRBUF_INIT, two = STRBUF_INIT;
	struct strbuf buf = STRBUF_INIT;

	if (sha1)
		git_SHA1_Init(&ctx);

	while (!io->getline(&buf, io)) {
		if (is_cmarker(buf.buf, '<', marker_size, 1)) {
			if (hunk != RR_CONTEXT)
				goto bad;
			hunk = RR_SIDE_1;
		} else if (is_cmarker(buf.buf, '|', marker_size, 0)) {
			if (hunk != RR_SIDE_1)
				goto bad;
			hunk = RR_ORIGINAL;
		} else if (is_cmarker(buf.buf, '=', marker_size, 0)) {
			if (hunk != RR_SIDE_1 && hunk != RR_ORIGINAL)
				goto bad;
			hunk = RR_SIDE_2;
		} else if (is_cmarker(buf.buf, '>', marker_size, 1)) {
			if (hunk != RR_SIDE_2)
				goto bad;
			if (strbuf_cmp(&one, &two) > 0)
				strbuf_swap(&one, &two);
			hunk_no++;
			hunk = RR_CONTEXT;
			rerere_io_putconflict('<', marker_size, io);
			rerere_io_putmem(one.buf, one.len, io);
			rerere_io_putconflict('=', marker_size, io);
			rerere_io_putmem(two.buf, two.len, io);
			rerere_io_putconflict('>', marker_size, io);
			if (sha1) {
				git_SHA1_Update(&ctx, one.buf ? one.buf : "",
					    one.len + 1);
				git_SHA1_Update(&ctx, two.buf ? two.buf : "",
					    two.len + 1);
			}
			strbuf_reset(&one);
			strbuf_reset(&two);
		} else if (hunk == RR_SIDE_1)
			strbuf_addbuf(&one, &buf);
		else if (hunk == RR_ORIGINAL)
			; /* discard */
		else if (hunk == RR_SIDE_2)
			strbuf_addbuf(&two, &buf);
		else
			rerere_io_putstr(buf.buf, io);
		continue;
	bad:
		hunk = 99; /* force error exit */
		break;
	}
	strbuf_release(&one);
	strbuf_release(&two);
	strbuf_release(&buf);

	if (sha1)
		git_SHA1_Final(sha1, &ctx);
	if (hunk != RR_CONTEXT)
		return -1;
	return hunk_no;
}
Example #10
0
File: patch-id.c Project: avar/git
static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
			   struct strbuf *line_buf, int stable)
{
	int patchlen = 0, found_next = 0;
	int before = -1, after = -1;
	git_SHA_CTX ctx;

	git_SHA1_Init(&ctx);
	oidclr(result);

	while (strbuf_getwholeline(line_buf, stdin, '\n') != EOF) {
		char *line = line_buf->buf;
		const char *p = line;
		int len;

		if (!skip_prefix(line, "diff-tree ", &p) &&
		    !skip_prefix(line, "commit ", &p) &&
		    !skip_prefix(line, "From ", &p) &&
		    starts_with(line, "\\ ") && 12 < strlen(line))
			continue;

		if (!get_oid_hex(p, next_oid)) {
			found_next = 1;
			break;
		}

		/* Ignore commit comments */
		if (!patchlen && !starts_with(line, "diff "))
			continue;

		/* Parsing diff header?  */
		if (before == -1) {
			if (starts_with(line, "index "))
				continue;
			else if (starts_with(line, "--- "))
				before = after = 1;
			else if (!isalpha(line[0]))
				break;
		}

		/* Looking for a valid hunk header?  */
		if (before == 0 && after == 0) {
			if (starts_with(line, "@@ -")) {
				/* Parse next hunk, but ignore line numbers.  */
				scan_hunk_header(line, &before, &after);
				continue;
			}

			/* Split at the end of the patch.  */
			if (!starts_with(line, "diff "))
				break;

			/* Else we're parsing another header.  */
			if (stable)
				flush_one_hunk(result, &ctx);
			before = after = -1;
		}

		/* If we get here, we're inside a hunk.  */
		if (line[0] == '-' || line[0] == ' ')
			before--;
		if (line[0] == '+' || line[0] == ' ')
			after--;

		/* Compute the sha without whitespace */
		len = remove_space(line);
		patchlen += len;
		git_SHA1_Update(&ctx, line, len);
	}

	if (!found_next)
		oidclr(next_oid);

	flush_one_hunk(result, &ctx);

	return patchlen;
}
Example #11
0
File: rerere.c Project: emk/git
static int handle_file(const char *path,
	 unsigned char *sha1, const char *output)
{
	git_SHA_CTX ctx;
	char buf[1024];
	int hunk_no = 0;
	enum {
		RR_CONTEXT = 0, RR_SIDE_1, RR_SIDE_2, RR_ORIGINAL,
	} hunk = RR_CONTEXT;
	struct strbuf one = STRBUF_INIT, two = STRBUF_INIT;
	FILE *f = fopen(path, "r");
	FILE *out = NULL;
	int wrerror = 0;

	if (!f)
		return error("Could not open %s", path);

	if (output) {
		out = fopen(output, "w");
		if (!out) {
			fclose(f);
			return error("Could not write %s", output);
		}
	}

	if (sha1)
		git_SHA1_Init(&ctx);

	while (fgets(buf, sizeof(buf), f)) {
		if (!prefixcmp(buf, "<<<<<<< ")) {
			if (hunk != RR_CONTEXT)
				goto bad;
			hunk = RR_SIDE_1;
		} else if (!prefixcmp(buf, "|||||||") && isspace(buf[7])) {
			if (hunk != RR_SIDE_1)
				goto bad;
			hunk = RR_ORIGINAL;
		} else if (!prefixcmp(buf, "=======") && isspace(buf[7])) {
			if (hunk != RR_SIDE_1 && hunk != RR_ORIGINAL)
				goto bad;
			hunk = RR_SIDE_2;
		} else if (!prefixcmp(buf, ">>>>>>> ")) {
			if (hunk != RR_SIDE_2)
				goto bad;
			if (strbuf_cmp(&one, &two) > 0)
				strbuf_swap(&one, &two);
			hunk_no++;
			hunk = RR_CONTEXT;
			if (out) {
				ferr_puts("<<<<<<<\n", out, &wrerror);
				ferr_write(one.buf, one.len, out, &wrerror);
				ferr_puts("=======\n", out, &wrerror);
				ferr_write(two.buf, two.len, out, &wrerror);
				ferr_puts(">>>>>>>\n", out, &wrerror);
			}
			if (sha1) {
				git_SHA1_Update(&ctx, one.buf ? one.buf : "",
					    one.len + 1);
				git_SHA1_Update(&ctx, two.buf ? two.buf : "",
					    two.len + 1);
			}
			strbuf_reset(&one);
			strbuf_reset(&two);
		} else if (hunk == RR_SIDE_1)
			strbuf_addstr(&one, buf);
		else if (hunk == RR_ORIGINAL)
			; /* discard */
		else if (hunk == RR_SIDE_2)
			strbuf_addstr(&two, buf);
		else if (out)
			ferr_puts(buf, out, &wrerror);
		continue;
	bad:
		hunk = 99; /* force error exit */
		break;
	}
	strbuf_release(&one);
	strbuf_release(&two);

	fclose(f);
	if (wrerror)
		error("There were errors while writing %s (%s)",
		      path, strerror(wrerror));
	if (out && fclose(out))
		wrerror = error("Failed to flush %s: %s",
				path, strerror(errno));
	if (sha1)
		git_SHA1_Final(sha1, &ctx);
	if (hunk != RR_CONTEXT) {
		if (output)
			unlink(output);
		return error("Could not parse conflict hunks in %s", path);
	}
	if (wrerror)
		return -1;
	return hunk_no;
}
Example #12
0
static int get_one_patchid(unsigned char *next_sha1, git_SHA_CTX *ctx, struct strbuf *line_buf)
{
	int patchlen = 0, found_next = 0;
	int before = -1, after = -1;

	while (strbuf_getwholeline(line_buf, stdin, '\n') != EOF) {
		char *line = line_buf->buf;
		char *p = line;
		int len;

		if (!memcmp(line, "diff-tree ", 10))
			p += 10;
		else if (!memcmp(line, "commit ", 7))
			p += 7;
		else if (!memcmp(line, "From ", 5))
			p += 5;
		else if (!memcmp(line, "\\ ", 2) && 12 < strlen(line))
			continue;

		if (!get_sha1_hex(p, next_sha1)) {
			found_next = 1;
			break;
		}

		/* Ignore commit comments */
		if (!patchlen && memcmp(line, "diff ", 5))
			continue;

		/* Parsing diff header?  */
		if (before == -1) {
			if (!memcmp(line, "index ", 6))
				continue;
			else if (!memcmp(line, "--- ", 4))
				before = after = 1;
			else if (!isalpha(line[0]))
				break;
		}

		/* Looking for a valid hunk header?  */
		if (before == 0 && after == 0) {
			if (!memcmp(line, "@@ -", 4)) {
				/* Parse next hunk, but ignore line numbers.  */
				scan_hunk_header(line, &before, &after);
				continue;
			}

			/* Split at the end of the patch.  */
			if (memcmp(line, "diff ", 5))
				break;

			/* Else we're parsing another header.  */
			before = after = -1;
		}

		/* If we get here, we're inside a hunk.  */
		if (line[0] == '-' || line[0] == ' ')
			before--;
		if (line[0] == '+' || line[0] == ' ')
			after--;

		/* Compute the sha without whitespace */
		len = remove_space(line);
		patchlen += len;
		git_SHA1_Update(ctx, line, len);
	}

	if (!found_next)
		hashclr(next_sha1);

	return patchlen;
}
Example #13
0
static void ipc_do_configure_client(struct bind_msg *bmsg)
{
	int ret, i;
	char type[TYPNAMSIZ];
	size_t num = 0, orig;
	git_SHA_CTX sha;
	unsigned char hashout[20], hash[40];
	char hashopt[1024], str[64];

	for (i = 0; i < MAX_PROPS; ++i) {
		if (bmsg->props[i] != 0)
			num++;
	}

	bind_elems_in_stack(lower_fb_name, bmsg->name);

	init_reconfig(bmsg->name, "ch.ethz.csg.pf_lana",
		      lower_fb_name, "ch.ethz.csg.eth");

	setopt_of_elem_in_stack(bmsg->name, "iface=eth0", strlen("iface=eth0")); //XXX
	printd("%s bound to eth0!\n", bmsg->name);

	memset(hashopt, 0, sizeof(hashopt));

	git_SHA1_Init(&sha);
	git_SHA1_Update(&sha, "ch.ethz.csg.eth-ch.ethz.csg.pf_lana",
			strlen("ch.ethz.csg.eth-ch.ethz.csg.pf_lana"));
	git_SHA1_Final(hash, &sha);
	git_SHA1_Init(&sha);
	git_SHA1_Update(&sha, bmsg->app, strlen(bmsg->app));
	git_SHA1_Final(&hash[20], &sha);
	git_SHA1_Init(&sha);
	git_SHA1_Update(&sha, hash, sizeof(hash));
	git_SHA1_Final(hashout, &sha);

	snprintf(hashopt, sizeof(hashopt)-1, "%s=%s",
		 bin2hex_compat(hashout, 8, str, sizeof(str)),
		 bmsg->name);

	setopt_of_elem_in_stack(lower_fb_name, hashopt, strlen(hashopt));
	printd("%s set with opt: %s\n", lower_fb_name, hashopt);

	strlcpy(srv_name, bmsg->name, FBNAMSIZ);
	strlcpy(srv_app, bmsg->app, FBNAMSIZ);

	if (bmsg->flags == TYPE_SERVER) {
		reconfig_tell_app(bmsg->app);
		printd("Registered server %s for app %s\n", srv_name, srv_app);
		start_negotiation_server(bmsg->name);
		server = 1;
		return;
	}else if (bmsg->flags == TYPE_CLIENT) {
		orig = num;
		server = 0;
		while ((ret = find_type_by_properties(type, bmsg->props, &num)) >= -32) {
			char name[FBNAMSIZ];
			printd("Found match for %s: %s,%d (satisfied %zu of %zu)\n",
			       bmsg->name, type, ret, orig - num, orig);
			insert_and_bind_elem_to_vstack(type, name, sizeof(name));
			memset(type, 0, sizeof(type));
			memset(name, 0, sizeof(name));
		}
		if (num > 0) {
			printd("Cannot match requirements! Unable to connect socket!\n");
			//XXX cleanup!
			return;
		}
		printd("Initiate negotiation with server....\n");
		ret = init_negotiation(bmsg->name, bmsg->app);
		printd("client negotiation returned with %d!\n", ret);
		if (ret < 0) {
			printd("Remote end does not support stack config!\n");
			return;
		}
//		commit_vstack(bmsg->app);
	}

	printd("IPC Client %s up and running!\n", bmsg->name);
}
Example #14
0
/*
 * Read the contents from fd for size bytes, streaming it to the
 * packfile in state while updating the hash in ctx. Signal a failure
 * by returning a negative value when the resulting pack would exceed
 * the pack size limit and this is not the first object in the pack,
 * so that the caller can discard what we wrote from the current pack
 * by truncating it and opening a new one. The caller will then call
 * us again after rewinding the input fd.
 *
 * The already_hashed_to pointer is kept untouched by the caller to
 * make sure we do not hash the same byte when we are called
 * again. This way, the caller does not have to checkpoint its hash
 * status before calling us just in case we ask it to call us again
 * with a new pack.
 */
static int stream_to_pack(struct bulk_checkin_state *state,
			  git_SHA_CTX *ctx, off_t *already_hashed_to,
			  int fd, size_t size, enum object_type type,
			  const char *path, unsigned flags)
{
	git_zstream s;
	unsigned char obuf[16384];
	unsigned hdrlen;
	int status = Z_OK;
	int write_object = (flags & HASH_WRITE_OBJECT);
	off_t offset = 0;

	git_deflate_init(&s, pack_compression_level);

	hdrlen = encode_in_pack_object_header(obuf, sizeof(obuf), type, size);
	s.next_out = obuf + hdrlen;
	s.avail_out = sizeof(obuf) - hdrlen;

	while (status != Z_STREAM_END) {
		unsigned char ibuf[16384];

		if (size && !s.avail_in) {
			ssize_t rsize = size < sizeof(ibuf) ? size : sizeof(ibuf);
			if (read_in_full(fd, ibuf, rsize) != rsize)
				die("failed to read %d bytes from '%s'",
				    (int)rsize, path);
			offset += rsize;
			if (*already_hashed_to < offset) {
				size_t hsize = offset - *already_hashed_to;
				if (rsize < hsize)
					hsize = rsize;
				if (hsize)
					git_SHA1_Update(ctx, ibuf, hsize);
				*already_hashed_to = offset;
			}
			s.next_in = ibuf;
			s.avail_in = rsize;
			size -= rsize;
		}

		status = git_deflate(&s, size ? 0 : Z_FINISH);

		if (!s.avail_out || status == Z_STREAM_END) {
			if (write_object) {
				size_t written = s.next_out - obuf;

				/* would we bust the size limit? */
				if (state->nr_written &&
				    pack_size_limit_cfg &&
				    pack_size_limit_cfg < state->offset + written) {
					git_deflate_abort(&s);
					return -1;
				}

				sha1write(state->f, obuf, written);
				state->offset += written;
			}
			s.next_out = obuf;
			s.avail_out = sizeof(obuf);
		}

		switch (status) {
		case Z_OK:
		case Z_BUF_ERROR:
		case Z_STREAM_END:
			continue;
		default:
			die("unexpected deflate failure: %d", status);
		}
	}
	git_deflate_end(&s);
	return 0;
}
Example #15
0
static int deflate_to_pack(struct bulk_checkin_state *state,
			   unsigned char result_sha1[],
			   int fd, size_t size,
			   enum object_type type, const char *path,
			   unsigned flags)
{
	off_t seekback, already_hashed_to;
	git_SHA_CTX ctx;
	unsigned char obuf[16384];
	unsigned header_len;
	struct sha1file_checkpoint checkpoint;
	struct pack_idx_entry *idx = NULL;

	seekback = lseek(fd, 0, SEEK_CUR);
	if (seekback == (off_t) -1)
		return error("cannot find the current offset");

	header_len = xsnprintf((char *)obuf, sizeof(obuf), "%s %" PRIuMAX,
			       typename(type), (uintmax_t)size) + 1;
	git_SHA1_Init(&ctx);
	git_SHA1_Update(&ctx, obuf, header_len);

	/* Note: idx is non-NULL when we are writing */
	if ((flags & HASH_WRITE_OBJECT) != 0)
		idx = xcalloc(1, sizeof(*idx));

	already_hashed_to = 0;

	while (1) {
		prepare_to_stream(state, flags);
		if (idx) {
			sha1file_checkpoint(state->f, &checkpoint);
			idx->offset = state->offset;
			crc32_begin(state->f);
		}
		if (!stream_to_pack(state, &ctx, &already_hashed_to,
				    fd, size, type, path, flags))
			break;
		/*
		 * Writing this object to the current pack will make
		 * it too big; we need to truncate it, start a new
		 * pack, and write into it.
		 */
		if (!idx)
			die("BUG: should not happen");
		sha1file_truncate(state->f, &checkpoint);
		state->offset = checkpoint.offset;
		finish_bulk_checkin(state);
		if (lseek(fd, seekback, SEEK_SET) == (off_t) -1)
			return error("cannot seek back");
	}
	git_SHA1_Final(result_sha1, &ctx);
	if (!idx)
		return 0;

	idx->crc32 = crc32_end(state->f);
	if (already_written(state, result_sha1)) {
		sha1file_truncate(state->f, &checkpoint);
		state->offset = checkpoint.offset;
		free(idx);
	} else {
		hashcpy(idx->oid.hash, result_sha1);
		ALLOC_GROW(state->written,
			   state->nr_written + 1,
			   state->alloc_written);
		state->written[state->nr_written++] = idx;
	}
	return 0;
}
Example #16
0
File: gidit.c Project: zhaoz/gidit
/**
 * Initialize user directories, takes PGP
 */
int gidit_proj_init(FILE *fp, const char * basepath, unsigned int flags)
{
    FILE * pgp_fp;
    struct strbuf pgp_key = STRBUF_INIT;
    struct strbuf proj_name = STRBUF_INIT;
    unsigned char sha1[20];
    char pgp_sha1[41];
    git_SHA_CTX c;

    strbuf_getline(&proj_name, fp, '\n');

    if (proj_name.len == 0) {
        strbuf_release(&pgp_key);
        strbuf_release(&proj_name);
        return error("Error while reading project name\n");
    }

    strbuf_getline(&pgp_key, fp, EOF);

    if (pgp_key.len == 0) {
        strbuf_release(&pgp_key);
        strbuf_release(&proj_name);
        return error("Error while reading pgp_key");
    }

    // hash the pgp key
    git_SHA1_Init(&c);
    git_SHA1_Update(&c, pgp_key.buf, pgp_key.len);
    git_SHA1_Final(sha1, &c);


    // change dir to pushobjects dir
    if (chdir(basepath) || chdir(PUSHOBJ_DIR))
        return error("Error going to pushobjects directory\n");

    sprintf(pgp_sha1, "%s", sha1_to_hex(sha1));

    if (safe_create_dir(pgp_sha1))
        exit(1);

    chdir(pgp_sha1);

    // now ensure the project directories existence
    if (safe_create_dir(proj_name.buf))
        exit(1);

    // if pgp key file already exists, not need to resave
    if (access("PGP", F_OK)) {
        // save the PGP key in there
        pgp_fp = fopen("PGP", "w");

        if (!pgp_fp)
            die("Error while saving PGP key");

        fwrite(pgp_key.buf, pgp_key.len, 1, pgp_fp);

        fclose(pgp_fp);
    }
    strbuf_release(&pgp_key);
    strbuf_release(&proj_name);

    return 0;
}