sha1_file.c 16.9 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*
 * GIT - The information manager from hell
 *
 * Copyright (C) Linus Torvalds, 2005
 *
 * This handles basic git sha1 object files - packing, unpacking,
 * creation etc.
 */
#include "cache.h"
N
Nicolas Pitre 已提交
10
#include "delta.h"
11

12 13 14 15 16 17 18 19 20 21
#ifndef O_NOATIME
#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
#define O_NOATIME 01000000
#else
#define O_NOATIME 0
#endif
#endif

static unsigned int sha1_file_open_flag = O_NOATIME;

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
static unsigned hexval(char c)
{
	if (c >= '0' && c <= '9')
		return c - '0';
	if (c >= 'a' && c <= 'f')
		return c - 'a' + 10;
	if (c >= 'A' && c <= 'F')
		return c - 'A' + 10;
	return ~0;
}

int get_sha1_hex(const char *hex, unsigned char *sha1)
{
	int i;
	for (i = 0; i < 20; i++) {
		unsigned int val = (hexval(hex[0]) << 4) | hexval(hex[1]);
		if (val & ~0xff)
			return -1;
		*sha1++ = val;
		hex += 2;
	}
	return 0;
}

L
Linus Torvalds 已提交
46
static int get_sha1_file(const char *path, unsigned char *result)
47 48 49 50 51 52 53 54 55 56 57 58 59 60
{
	char buffer[60];
	int fd = open(path, O_RDONLY);
	int len;

	if (fd < 0)
		return -1;
	len = read(fd, buffer, sizeof(buffer));
	close(fd);
	if (len < 40)
		return -1;
	return get_sha1_hex(buffer, result);
}

D
Daniel Barkalow 已提交
61
static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir;
62 63 64 65 66 67 68 69 70 71
static void setup_git_env(void)
{
	git_dir = gitenv(GIT_DIR_ENVIRONMENT);
	if (!git_dir)
		git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
	git_object_dir = gitenv(DB_ENVIRONMENT);
	if (!git_object_dir) {
		git_object_dir = xmalloc(strlen(git_dir) + 9);
		sprintf(git_object_dir, "%s/objects", git_dir);
	}
D
Daniel Barkalow 已提交
72 73
	git_refs_dir = xmalloc(strlen(git_dir) + 6);
	sprintf(git_refs_dir, "%s/refs", git_dir);
74 75 76 77 78 79 80 81 82 83 84 85 86 87
	git_index_file = gitenv(INDEX_ENVIRONMENT);
	if (!git_index_file) {
		git_index_file = xmalloc(strlen(git_dir) + 7);
		sprintf(git_index_file, "%s/index", git_dir);
	}
}

char *get_object_directory(void)
{
	if (!git_object_dir)
		setup_git_env();
	return git_object_dir;
}

D
Daniel Barkalow 已提交
88 89 90 91 92 93 94
char *get_refs_directory(void)
{
	if (!git_refs_dir)
		setup_git_env();
	return git_refs_dir;
}

95 96 97 98 99 100 101
char *get_index_file(void)
{
	if (!git_index_file)
		setup_git_env();
	return git_index_file;
}

102 103 104
int get_sha1(const char *str, unsigned char *sha1)
{
	static char pathname[PATH_MAX];
105 106 107 108 109 110 111 112 113
	static const char *prefix[] = {
		"",
		"refs",
		"refs/tags",
		"refs/heads",
		"refs/snap",
		NULL
	};
	const char **p;
114 115 116

	if (!get_sha1_hex(str, sha1))
		return 0;
117

118 119
	if (!git_dir)
		setup_git_env();
120
	for (p = prefix; *p; p++) {
121 122
		snprintf(pathname, sizeof(pathname), "%s/%s/%s",
			 git_dir, *p, str);
123 124 125 126
		if (!get_sha1_file(pathname, sha1))
			return 0;
	}

127 128 129
	return -1;
}

130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
char * sha1_to_hex(const unsigned char *sha1)
{
	static char buffer[50];
	static const char hex[] = "0123456789abcdef";
	char *buf = buffer;
	int i;

	for (i = 0; i < 20; i++) {
		unsigned int val = *sha1++;
		*buf++ = hex[val >> 4];
		*buf++ = hex[val & 0xf];
	}
	return buffer;
}

145 146 147 148 149 150 151 152 153 154 155 156
static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
{
	int i;
	for (i = 0; i < 20; i++) {
		static char hex[] = "0123456789abcdef";
		unsigned int val = sha1[i];
		char *pos = pathbuf + i*2 + (i > 0);
		*pos++ = hex[val >> 4];
		*pos = hex[val & 0xf];
	}
}

157 158 159 160
/*
 * NOTE! This returns a statically allocated buffer, so you have to be
 * careful about using it. Do a "strdup()" if you need to save the
 * filename.
161 162 163
 *
 * Also note that this returns the location for creating.  Reading
 * SHA1 file can happen from any alternate directory listed in the
J
Junio C Hamano 已提交
164
 * DB_ENVIRONMENT environment variable if it is not found in
165
 * the primary object database.
166 167 168 169 170 171
 */
char *sha1_file_name(const unsigned char *sha1)
{
	static char *name, *base;

	if (!base) {
J
Junio C Hamano 已提交
172
		const char *sha1_file_directory = get_object_directory();
173
		int len = strlen(sha1_file_directory);
174
		base = xmalloc(len + 60);
175 176 177 178 179 180
		memcpy(base, sha1_file_directory, len);
		memset(base+len, 0, 60);
		base[len] = '/';
		base[len+3] = '/';
		name = base + len + 1;
	}
181
	fill_sha1_path(name, sha1);
182 183 184
	return base;
}

J
Junio C Hamano 已提交
185
static struct alternate_object_database {
186 187 188 189
	char *base;
	char *name;
} *alt_odb;

J
Junio C Hamano 已提交
190 191 192 193 194
/*
 * Prepare alternate object database registry.
 * alt_odb points at an array of struct alternate_object_database.
 * This array is terminated with an element that has both its base
 * and name set to NULL.  alt_odb[n] comes from n'th non-empty
J
Junio C Hamano 已提交
195
 * element from colon separated ALTERNATE_DB_ENVIRONMENT environment
J
Junio C Hamano 已提交
196 197 198 199 200 201 202 203 204 205
 * variable, and its base points at a statically allocated buffer
 * that contains "/the/directory/corresponding/to/.git/objects/...",
 * while its name points just after the slash at the end of
 * ".git/objects/" in the example above, and has enough space to hold
 * 40-byte hex SHA1, an extra slash for the first level indirection,
 * and the terminating NUL.
 * This function allocates the alt_odb array and all the strings
 * pointed by base fields of the array elements with one xmalloc();
 * the string pool immediately follows the array.
 */
206 207 208 209
static void prepare_alt_odb(void)
{
	int pass, totlen, i;
	const char *cp, *last;
L
Linus Torvalds 已提交
210
	char *op = NULL;
J
Junio C Hamano 已提交
211
	const char *alt = gitenv(ALTERNATE_DB_ENVIRONMENT) ? : "";
212

J
Junio C Hamano 已提交
213 214 215 216 217 218
	/* The first pass counts how large an area to allocate to
	 * hold the entire alt_odb structure, including array of
	 * structs and path buffers for them.  The second pass fills
	 * the structure and prepares the path buffers for use by
	 * fill_sha1_path().
	 */
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
	for (totlen = pass = 0; pass < 2; pass++) {
		last = alt;
		i = 0;
		do {
			cp = strchr(last, ':') ? : last + strlen(last);
			if (last != cp) {
				/* 43 = 40-byte + 2 '/' + terminating NUL */
				int pfxlen = cp - last;
				int entlen = pfxlen + 43;
				if (pass == 0)
					totlen += entlen;
				else {
					alt_odb[i].base = op;
					alt_odb[i].name = op + pfxlen + 1;
					memcpy(op, last, pfxlen);
					op[pfxlen] = op[pfxlen + 3] = '/';
					op[entlen-1] = 0;
					op += entlen;
				}
				i++;
			}
			while (*cp && *cp == ':')
				cp++;
			last = cp;
		} while (*cp);
		if (pass)
			break;
J
Junio C Hamano 已提交
246
		alt_odb = xmalloc(sizeof(*alt_odb) * (i + 1) + totlen);
L
Linus Torvalds 已提交
247
		alt_odb[i].base = alt_odb[i].name = NULL;
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
		op = (char*)(&alt_odb[i+1]);
	}
}

static char *find_sha1_file(const unsigned char *sha1, struct stat *st)
{
	int i;
	char *name = sha1_file_name(sha1);

	if (!stat(name, st))
		return name;
	if (!alt_odb)
		prepare_alt_odb();
	for (i = 0; (name = alt_odb[i].name) != NULL; i++) {
		fill_sha1_path(name, sha1);
		if (!stat(alt_odb[i].base, st))
			return alt_odb[i].base;
	}
	return NULL;
}

269
int check_sha1_signature(unsigned char *sha1, void *map, unsigned long size, const char *type)
270
{
271
	char header[100];
272 273 274 275
	unsigned char real_sha1[20];
	SHA_CTX c;

	SHA1_Init(&c);
276
	SHA1_Update(&c, header, 1+sprintf(header, "%s %lu", type, size));
277 278 279 280 281 282 283 284 285
	SHA1_Update(&c, map, size);
	SHA1_Final(real_sha1, &c);
	return memcmp(sha1, real_sha1, 20) ? -1 : 0;
}

void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
{
	struct stat st;
	void *map;
286
	int fd;
287 288 289 290 291 292
	char *filename = find_sha1_file(sha1, &st);

	if (!filename) {
		error("cannot map sha1 file %s", sha1_to_hex(sha1));
		return NULL;
	}
293

294
	fd = open(filename, O_RDONLY | sha1_file_open_flag);
295
	if (fd < 0) {
296 297 298 299 300 301 302 303 304 305 306 307 308 309
		/* See if it works without O_NOATIME */
		switch (sha1_file_open_flag) {
		default:
			fd = open(filename, O_RDONLY);
			if (fd >= 0)
				break;
		/* Fallthrough */
		case 0:
			perror(filename);
			return NULL;
		}

		/* If it failed once, it will probably fail again. Stop using O_NOATIME */
		sha1_file_open_flag = 0;
310 311 312 313 314 315 316 317 318
	}
	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	close(fd);
	if (-1 == (int)(long)map)
		return NULL;
	*size = st.st_size;
	return map;
}

319 320 321 322 323 324 325 326 327 328 329 330 331
int unpack_sha1_header(z_stream *stream, void *map, unsigned long mapsize, void *buffer, unsigned long size)
{
	/* Get the data stream */
	memset(stream, 0, sizeof(*stream));
	stream->next_in = map;
	stream->avail_in = mapsize;
	stream->next_out = buffer;
	stream->avail_out = size;

	inflateInit(stream);
	return inflate(stream, 0);
}

332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size)
{
	int bytes = strlen(buffer) + 1;
	char *buf = xmalloc(1+size);

	memcpy(buf, buffer + bytes, stream->total_out - bytes);
	bytes = stream->total_out - bytes;
	if (bytes < size) {
		stream->next_out = buf + bytes;
		stream->avail_out = size - bytes;
		while (inflate(stream, Z_FINISH) == Z_OK)
			/* nothing */;
	}
	buf[size] = 0;
	inflateEnd(stream);
	return buf;
}

/*
 * We used to just use "sscanf()", but that's actually way
 * too permissive for what we want to check. So do an anal
 * object header parse by hand.
 */
int parse_sha1_header(char *hdr, char *type, unsigned long *sizep)
{
	int i;
	unsigned long size;

	/*
	 * The type can be at most ten bytes (including the 
	 * terminating '\0' that we add), and is followed by
	 * a space. 
	 */
	i = 10;
	for (;;) {
		char c = *hdr++;
		if (c == ' ')
			break;
		if (!--i)
			return -1;
		*type++ = c;
	}
	*type = 0;

	/*
	 * The length must follow immediately, and be in canonical
	 * decimal format (ie "010" is not valid).
	 */
	size = *hdr++ - '0';
	if (size > 9)
		return -1;
	if (size) {
		for (;;) {
			unsigned long c = *hdr - '0';
			if (c > 9)
				break;
			hdr++;
			size = size * 10 + c;
		}
	}
	*sizep = size;

	/*
	 * The length must be followed by a zero byte
	 */
	return *hdr ? -1 : 0;
}

400 401
void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size)
{
402
	int ret;
403
	z_stream stream;
404
	char hdr[8192];
405

406 407
	ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
	if (ret < Z_OK || parse_sha1_header(hdr, type, size) < 0)
408 409
		return NULL;

410
	return unpack_sha1_rest(&stream, hdr, *size);
411 412
}

413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
int sha1_delta_base(const unsigned char *sha1, unsigned char *base_sha1)
{
	int ret;
	unsigned long mapsize, size;
	void *map;
	z_stream stream;
	char hdr[64], type[20];
	void *delta_data_head;

	map = map_sha1_file(sha1, &mapsize);
	if (!map)
		return -1;
	ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
	if (ret < Z_OK || parse_sha1_header(hdr, type, &size) < 0) {
		ret = -1;
		goto out;
	}
	if (strcmp(type, "delta")) {
		ret = 0;
		goto out;
	}

	delta_data_head = hdr + strlen(hdr) + 1;
	ret = 1;
	memcpy(base_sha1, delta_data_head, 20);
 out:
	inflateEnd(&stream);
	munmap(map, mapsize);
	return ret;
}

444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
int sha1_file_size(const unsigned char *sha1, unsigned long *sizep)
{
	int ret, status;
	unsigned long mapsize, size;
	void *map;
	z_stream stream;
	char hdr[64], type[20];
	const unsigned char *data;
	unsigned char cmd;
	int i;

	map = map_sha1_file(sha1, &mapsize);
	if (!map)
		return -1;
	ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
	status = -1;
	if (ret < Z_OK || parse_sha1_header(hdr, type, &size) < 0)
		goto out;
	if (strcmp(type, "delta")) {
		*sizep = size;
		status = 0;
		goto out;
	}

	/* We are dealing with a delta object.  Inflated, the first
	 * 20 bytes hold the base object SHA1, and delta data follows
	 * immediately after it.
	 *
	 * The initial part of the delta starts at delta_data_head +
	 * 20.  Borrow code from patch-delta to read the result size.
	 */
	data = hdr + strlen(hdr) + 1 + 20;

	/* Skip over the source size; we are not interested in
	 * it and we cannot verify it because we do not want
	 * to read the base object.
	 */
	cmd = *data++;
	while (cmd) {
		if (cmd & 1)
			data++;
		cmd >>= 1;
	}
	/* Read the result size */
	size = i = 0;
	cmd = *data++;
	while (cmd) {
		if (cmd & 1)
			size |= *data++ << i;
		i += 8;
		cmd >>= 1;
	}
	*sizep = size;
	status = 0;
 out:
	inflateEnd(&stream);
	munmap(map, mapsize);
	return status;
}

504 505 506 507 508 509 510 511 512
void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
{
	unsigned long mapsize;
	void *map, *buf;

	map = map_sha1_file(sha1, &mapsize);
	if (map) {
		buf = unpack_sha1_file(map, mapsize, type, size);
		munmap(map, mapsize);
N
Nicolas Pitre 已提交
513 514 515 516 517 518 519 520 521 522 523 524 525
		if (buf && !strcmp(type, "delta")) {
			void *ref = NULL, *delta = buf;
			unsigned long ref_size, delta_size = *size;
			buf = NULL;
			if (delta_size > 20)
				ref = read_sha1_file(delta, type, &ref_size);
			if (ref)
				buf = patch_delta(ref, ref_size,
						  delta+20, delta_size-20, 
						  size);
			free(delta);
			free(ref);
		}
526 527 528 529 530
		return buf;
	}
	return NULL;
}

531
void *read_object_with_reference(const unsigned char *sha1,
532
				 const char *required_type,
533 534
				 unsigned long *size,
				 unsigned char *actual_sha1_return)
535 536 537 538
{
	char type[20];
	void *buffer;
	unsigned long isize;
539
	unsigned char actual_sha1[20];
540

541 542 543 544
	memcpy(actual_sha1, sha1, 20);
	while (1) {
		int ref_length = -1;
		const char *ref_type = NULL;
545

546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
		buffer = read_sha1_file(actual_sha1, type, &isize);
		if (!buffer)
			return NULL;
		if (!strcmp(type, required_type)) {
			*size = isize;
			if (actual_sha1_return)
				memcpy(actual_sha1_return, actual_sha1, 20);
			return buffer;
		}
		/* Handle references */
		else if (!strcmp(type, "commit"))
			ref_type = "tree ";
		else if (!strcmp(type, "tag"))
			ref_type = "object ";
		else {
			free(buffer);
			return NULL;
		}
		ref_length = strlen(ref_type);
565

566 567 568 569 570 571 572
		if (memcmp(buffer, ref_type, ref_length) ||
		    get_sha1_hex(buffer + ref_length, actual_sha1)) {
			free(buffer);
			return NULL;
		}
		/* Now we have the ID of the referred-to object in
		 * actual_sha1.  Check again. */
573 574 575
	}
}

576
int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
577 578
{
	int size;
579
	unsigned char *compressed;
580 581 582
	z_stream stream;
	unsigned char sha1[20];
	SHA_CTX c;
583
	char *filename;
584
	static char tmpfile[PATH_MAX];
585
	unsigned char hdr[50];
586
	int fd, hdrlen, ret;
587 588

	/* Generate the header */
589
	hdrlen = sprintf((char *)hdr, "%s %lu", type, len)+1;
590

591 592
	/* Sha1.. */
	SHA1_Init(&c);
593
	SHA1_Update(&c, hdr, hdrlen);
594 595 596
	SHA1_Update(&c, buf, len);
	SHA1_Final(sha1, &c);

597 598 599 600
	if (returnsha1)
		memcpy(returnsha1, sha1, 20);

	filename = sha1_file_name(sha1);
601 602
	fd = open(filename, O_RDONLY);
	if (fd >= 0) {
603
		/*
604 605
		 * FIXME!!! We might do collision checking here, but we'd
		 * need to uncompress the old file and check it. Later.
606
		 */
607
		close(fd);
608 609 610
		return 0;
	}

611 612 613 614 615 616
	if (errno != ENOENT) {
		fprintf(stderr, "sha1 file %s: %s", filename, strerror(errno));
		return -1;
	}

	snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory());
617

618 619 620 621 622 623
	fd = mkstemp(tmpfile);
	if (fd < 0) {
		fprintf(stderr, "unable to create temporary sha1 filename %s: %s", tmpfile, strerror(errno));
		return -1;
	}

624 625 626
	/* Set it up */
	memset(&stream, 0, sizeof(stream));
	deflateInit(&stream, Z_BEST_COMPRESSION);
627
	size = deflateBound(&stream, len+hdrlen);
628
	compressed = xmalloc(size);
629 630 631 632

	/* Compress it */
	stream.next_out = compressed;
	stream.avail_out = size;
633 634 635 636 637

	/* First header.. */
	stream.next_in = hdr;
	stream.avail_in = hdrlen;
	while (deflate(&stream, 0) == Z_OK)
638
		/* nothing */;
639 640 641 642

	/* Then the data itself.. */
	stream.next_in = buf;
	stream.avail_in = len;
643 644 645 646 647
	while (deflate(&stream, Z_FINISH) == Z_OK)
		/* nothing */;
	deflateEnd(&stream);
	size = stream.total_out;

648 649
	if (write(fd, compressed, size) != size)
		die("unable to write file");
650
	fchmod(fd, 0444);
651
	close(fd);
652
	free(compressed);
653

654
	ret = link(tmpfile, filename);
655
	if (ret < 0) {
656
		ret = errno;
657 658 659 660 661 662 663 664 665 666 667 668 669

		/*
		 * Coda hack - coda doesn't like cross-directory links,
		 * so we fall back to a rename, which will mean that it
		 * won't be able to check collisions, but that's not a
		 * big deal.
		 *
		 * When this succeeds, we just return 0. We have nothing
		 * left to unlink.
		 */
		if (ret == EXDEV && !rename(tmpfile, filename))
			return 0;
	}
670 671 672 673
	unlink(tmpfile);
	if (ret) {
		if (ret != EEXIST) {
			fprintf(stderr, "unable to write sha1 filename %s: %s", filename, strerror(ret));
674
			return -1;
675 676
		}
		/* FIXME!!! Collision check here ? */
677
	}
678

679 680
	return 0;
}
681 682 683 684 685 686 687 688

int write_sha1_from_fd(const unsigned char *sha1, int fd)
{
	char *filename = sha1_file_name(sha1);

	int local;
	z_stream stream;
	unsigned char real_sha1[20];
689 690
	unsigned char buf[4096];
	unsigned char discard[4096];
691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746
	int ret;
	SHA_CTX c;

	local = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);

	if (local < 0)
		return error("Couldn't open %s\n", filename);

	memset(&stream, 0, sizeof(stream));

	inflateInit(&stream);

	SHA1_Init(&c);

	do {
		ssize_t size;
		size = read(fd, buf, 4096);
		if (size <= 0) {
			close(local);
			unlink(filename);
			if (!size)
				return error("Connection closed?");
			perror("Reading from connection");
			return -1;
		}
		write(local, buf, size);
		stream.avail_in = size;
		stream.next_in = buf;
		do {
			stream.next_out = discard;
			stream.avail_out = sizeof(discard);
			ret = inflate(&stream, Z_SYNC_FLUSH);
			SHA1_Update(&c, discard, sizeof(discard) -
				    stream.avail_out);
		} while (stream.avail_in && ret == Z_OK);
		
	} while (ret == Z_OK);
	inflateEnd(&stream);

	close(local);
	SHA1_Final(real_sha1, &c);
	if (ret != Z_STREAM_END) {
		unlink(filename);
		return error("File %s corrupted", sha1_to_hex(sha1));
	}
	if (memcmp(sha1, real_sha1, 20)) {
		unlink(filename);
		return error("File %s has bad hash\n", sha1_to_hex(sha1));
	}
	
	return 0;
}

int has_sha1_file(const unsigned char *sha1)
{
	struct stat st;
747
	return !!find_sha1_file(sha1, &st);
748
}
J
Junio C Hamano 已提交
749 750 751 752

int index_fd(unsigned char *sha1, int fd, struct stat *st)
{
	unsigned long size = st->st_size;
753 754
	void *buf;
	int ret;
J
Junio C Hamano 已提交
755

756
	buf = "";
J
Junio C Hamano 已提交
757
	if (size)
758
		buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
J
Junio C Hamano 已提交
759
	close(fd);
760
	if ((int)(long)buf == -1)
J
Junio C Hamano 已提交
761 762
		return -1;

763 764 765 766
	ret = write_sha1_file(buf, size, "blob", sha1);
	if (size)
		munmap(buf, size);
	return ret;
J
Junio C Hamano 已提交
767
}