sha1_file.c 49.7 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"
10
#include "delta.h"
11
#include "pack.h"
12 13 14 15
#include "blob.h"
#include "commit.h"
#include "tag.h"
#include "tree.h"
16

17 18 19 20 21 22 23 24
#ifndef O_NOATIME
#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
#define O_NOATIME 01000000
#else
#define O_NOATIME 0
#endif
#endif

25 26 27 28 29 30
#ifdef NO_C99_FORMAT
#define SZ_FMT "lu"
#else
#define SZ_FMT "zu"
#endif

31
const unsigned char null_sha1[20];
J
Junio C Hamano 已提交
32

33 34
static unsigned int sha1_file_open_flag = O_NOATIME;

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
signed char hexval_table[256] = {
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 00-07 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 08-0f */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 10-17 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 18-1f */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 20-27 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 28-2f */
	  0,  1,  2,  3,  4,  5,  6,  7,		/* 30-37 */
	  8,  9, -1, -1, -1, -1, -1, -1,		/* 38-3f */
	 -1, 10, 11, 12, 13, 14, 15, -1,		/* 40-47 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 48-4f */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 50-57 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 58-5f */
	 -1, 10, 11, 12, 13, 14, 15, -1,		/* 60-67 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 68-67 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 70-77 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 78-7f */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 80-87 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 88-8f */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 90-97 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* 98-9f */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* a0-a7 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* a8-af */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* b0-b7 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* b8-bf */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* c0-c7 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* c8-cf */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* d0-d7 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* d8-df */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* e0-e7 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* e8-ef */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* f0-f7 */
	 -1, -1, -1, -1, -1, -1, -1, -1,		/* f8-ff */
};
69 70 71 72 73 74 75 76 77 78 79 80 81 82

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

83 84 85
int safe_create_leading_directories(char *path)
{
	char *pos = path;
86 87
	struct stat st;

88 89
	if (*pos == '/')
		pos++;
90 91 92 93 94 95

	while (pos) {
		pos = strchr(pos, '/');
		if (!pos)
			break;
		*pos = 0;
96 97 98
		if (!stat(path, &st)) {
			/* path exists */
			if (!S_ISDIR(st.st_mode)) {
99
				*pos = '/';
100
				return -3;
101
			}
102
		}
103 104 105 106
		else if (mkdir(path, 0777)) {
			*pos = '/';
			return -1;
		}
107 108 109 110
		else if (adjust_shared_perm(path)) {
			*pos = '/';
			return -2;
		}
111 112 113 114
		*pos++ = '/';
	}
	return 0;
}
115

116 117
char * sha1_to_hex(const unsigned char *sha1)
{
L
Linus Torvalds 已提交
118 119
	static int bufno;
	static char hexbuffer[4][50];
120
	static const char hex[] = "0123456789abcdef";
L
Linus Torvalds 已提交
121
	char *buffer = hexbuffer[3 & ++bufno], *buf = buffer;
122 123 124 125 126 127 128
	int i;

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

131 132 133
	return buffer;
}

134 135 136 137 138 139 140 141 142 143 144 145
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];
	}
}

146 147
/*
 * NOTE! This returns a statically allocated buffer, so you have to be
148
 * careful about using it. Do a "xstrdup()" if you need to save the
149
 * filename.
150 151 152
 *
 * 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 已提交
153
 * DB_ENVIRONMENT environment variable if it is not found in
154
 * the primary object database.
155 156 157 158 159 160
 */
char *sha1_file_name(const unsigned char *sha1)
{
	static char *name, *base;

	if (!base) {
J
Junio C Hamano 已提交
161
		const char *sha1_file_directory = get_object_directory();
162
		int len = strlen(sha1_file_directory);
163
		base = xmalloc(len + 60);
164 165 166 167 168 169
		memcpy(base, sha1_file_directory, len);
		memset(base+len, 0, 60);
		base[len] = '/';
		base[len+3] = '/';
		name = base + len + 1;
	}
170
	fill_sha1_path(name, sha1);
171 172 173
	return base;
}

174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
char *sha1_pack_name(const unsigned char *sha1)
{
	static const char hex[] = "0123456789abcdef";
	static char *name, *base, *buf;
	int i;

	if (!base) {
		const char *sha1_file_directory = get_object_directory();
		int len = strlen(sha1_file_directory);
		base = xmalloc(len + 60);
		sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.pack", sha1_file_directory);
		name = base + len + 11;
	}

	buf = name;

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

char *sha1_pack_index_name(const unsigned char *sha1)
{
	static const char hex[] = "0123456789abcdef";
	static char *name, *base, *buf;
	int i;

	if (!base) {
		const char *sha1_file_directory = get_object_directory();
		int len = strlen(sha1_file_directory);
		base = xmalloc(len + 60);
		sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.idx", sha1_file_directory);
		name = base + len + 11;
	}

	buf = name;

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

224 225
struct alternate_object_database *alt_odb_list;
static struct alternate_object_database **alt_odb_tail;
226

M
Martin Waitz 已提交
227 228
static void read_info_alternates(const char * alternates, int depth);

J
Junio C Hamano 已提交
229 230
/*
 * Prepare alternate object database registry.
231 232 233 234 235
 *
 * The variable alt_odb_list points at the list of struct
 * alternate_object_database.  The elements on this list come from
 * non-empty elements from colon separated ALTERNATE_DB_ENVIRONMENT
 * environment variable, and $GIT_OBJECT_DIRECTORY/info/alternates,
236 237
 * whose contents is similar to that environment variable but can be
 * LF separated.  Its base points at a statically allocated buffer that
238 239 240 241 242
 * 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.
J
Junio C Hamano 已提交
243
 */
M
Martin Waitz 已提交
244
static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth)
245
{
M
Martin Waitz 已提交
246
	struct stat st;
247
	const char *objdir = get_object_directory();
M
Martin Waitz 已提交
248 249 250 251 252
	struct alternate_object_database *ent;
	struct alternate_object_database *alt;
	/* 43 = 40-byte + 2 '/' + terminating NUL */
	int pfxlen = len;
	int entlen = pfxlen + 43;
253
	int base_len = -1;
254

M
Martin Waitz 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
	if (*entry != '/' && relative_base) {
		/* Relative alt-odb */
		if (base_len < 0)
			base_len = strlen(relative_base) + 1;
		entlen += base_len;
		pfxlen += base_len;
	}
	ent = xmalloc(sizeof(*ent) + entlen);

	if (*entry != '/' && relative_base) {
		memcpy(ent->base, relative_base, base_len - 1);
		ent->base[base_len - 1] = '/';
		memcpy(ent->base + base_len, entry, len);
	}
	else
		memcpy(ent->base, entry, pfxlen);

	ent->name = ent->base + pfxlen + 1;
	ent->base[pfxlen + 3] = '/';
	ent->base[pfxlen] = ent->base[entlen-1] = 0;

	/* Detect cases where alternate disappeared */
	if (stat(ent->base, &st) || !S_ISDIR(st.st_mode)) {
		error("object directory %s does not exist; "
		      "check .git/objects/info/alternates.",
		      ent->base);
		free(ent);
		return -1;
	}

	/* Prevent the common mistake of listing the same
	 * thing twice, or object directory itself.
	 */
	for (alt = alt_odb_list; alt; alt = alt->next) {
		if (!memcmp(ent->base, alt->base, pfxlen)) {
			free(ent);
			return -1;
		}
	}
	if (!memcmp(ent->base, objdir, pfxlen)) {
		free(ent);
		return -1;
	}

	/* add the alternate entry */
	*alt_odb_tail = ent;
	alt_odb_tail = &(ent->next);
	ent->next = NULL;

	/* recursively add alternates */
	read_info_alternates(ent->base, depth + 1);

	ent->base[pfxlen] = '/';

	return 0;
}

static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
				 const char *relative_base, int depth)
{
	const char *cp, *last;

	if (depth > 5) {
		error("%s: ignoring alternate object stores, nesting too deep.",
				relative_base);
		return;
	}

323
	last = alt;
324 325 326 327 328 329 330 331
	while (last < ep) {
		cp = last;
		if (cp < ep && *cp == '#') {
			while (cp < ep && *cp != sep)
				cp++;
			last = cp + 1;
			continue;
		}
M
Martin Waitz 已提交
332 333
		while (cp < ep && *cp != sep)
			cp++;
334
		if (last != cp) {
M
Martin Waitz 已提交
335 336 337 338 339 340
			if ((*last != '/') && depth) {
				error("%s: ignoring relative alternate object store %s",
						relative_base, last);
			} else {
				link_alt_odb_entry(last, cp - last,
						relative_base, depth);
341
			}
342
		}
343
		while (cp < ep && *cp == sep)
344 345
			cp++;
		last = cp;
346
	}
347 348
}

M
Martin Waitz 已提交
349
static void read_info_alternates(const char * relative_base, int depth)
350
{
351
	char *map;
352
	struct stat st;
M
Martin Waitz 已提交
353 354
	char path[PATH_MAX];
	int fd;
355

M
Martin Waitz 已提交
356
	sprintf(path, "%s/info/alternates", relative_base);
357 358 359 360 361
	fd = open(path, O_RDONLY);
	if (fd < 0)
		return;
	if (fstat(fd, &st) || (st.st_size == 0)) {
		close(fd);
362
		return;
363
	}
364
	map = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
365 366
	close(fd);

M
Martin Waitz 已提交
367 368
	link_alt_odb_entries(map, map + st.st_size, '\n', relative_base, depth);

369
	munmap(map, st.st_size);
370 371
}

M
Martin Waitz 已提交
372 373
void prepare_alt_odb(void)
{
T
Timo Hirvonen 已提交
374
	const char *alt;
M
Martin Waitz 已提交
375 376 377 378 379 380 381 382 383 384 385 386

	alt = getenv(ALTERNATE_DB_ENVIRONMENT);
	if (!alt) alt = "";

	if (alt_odb_tail)
		return;
	alt_odb_tail = &alt_odb_list;
	link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL, 0);

	read_info_alternates(get_object_directory(), 0);
}

387 388 389
static char *find_sha1_file(const unsigned char *sha1, struct stat *st)
{
	char *name = sha1_file_name(sha1);
390
	struct alternate_object_database *alt;
391 392 393

	if (!stat(name, st))
		return name;
394
	prepare_alt_odb();
395 396
	for (alt = alt_odb_list; alt; alt = alt->next) {
		name = alt->name;
397
		fill_sha1_path(name, sha1);
398 399
		if (!stat(alt->base, st))
			return alt->base;
400 401 402 403
	}
	return NULL;
}

404
static unsigned int pack_used_ctr;
405 406 407 408
static unsigned int pack_mmap_calls;
static unsigned int peak_pack_open_windows;
static unsigned int pack_open_windows;
static size_t peak_pack_mapped;
409 410
static size_t pack_mapped;
static size_t page_size;
411
struct packed_git *packed_git;
412

413 414 415
void pack_report()
{
	fprintf(stderr,
416 417 418
		"pack_report: getpagesize()            = %10" SZ_FMT "\n"
		"pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n"
		"pack_report: core.packedGitLimit      = %10" SZ_FMT "\n",
419 420 421 422 423 424 425
		page_size,
		packed_git_window_size,
		packed_git_limit);
	fprintf(stderr,
		"pack_report: pack_used_ctr            = %10u\n"
		"pack_report: pack_mmap_calls          = %10u\n"
		"pack_report: pack_open_windows        = %10u / %10u\n"
426 427
		"pack_report: pack_mapped              = "
			"%10" SZ_FMT " / %10" SZ_FMT "\n",
428 429 430 431 432 433
		pack_used_ctr,
		pack_mmap_calls,
		pack_open_windows, peak_pack_open_windows,
		pack_mapped, peak_pack_mapped);
}

434 435 436 437
static int check_packed_git_idx(const char *path, unsigned long *idx_size_,
				void **idx_map_)
{
	void *idx_map;
438
	uint32_t *index;
439 440
	unsigned long idx_size;
	int nr, i;
441
	int fd = open(path, O_RDONLY);
442 443 444 445 446 447 448 449
	struct stat st;
	if (fd < 0)
		return -1;
	if (fstat(fd, &st)) {
		close(fd);
		return -1;
	}
	idx_size = st.st_size;
450
	idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0);
451 452 453
	close(fd);

	index = idx_map;
454 455
	*idx_map_ = idx_map;
	*idx_size_ = idx_size;
456 457

	/* check index map */
458
	if (idx_size < 4*256 + 20 + 20)
459 460 461 462 463 464 465 466 467 468 469 470
		return error("index file %s is too small", path);

	/* a future index format would start with this, as older git
	 * binaries would fail the non-monotonic index check below.
	 * give a nicer warning to the user if we can.
	 */
	if (index[0] == htonl(PACK_IDX_SIGNATURE))
		return error("index file %s is a newer version"
			" and is not supported by this binary"
			" (try upgrading GIT to a newer version)",
			path);

471 472 473 474
	nr = 0;
	for (i = 0; i < 256; i++) {
		unsigned int n = ntohl(index[i]);
		if (n < nr)
475
			return error("non-monotonic index %s", path);
476 477 478 479 480 481 482 483 484 485 486
		nr = n;
	}

	/*
	 * Total size:
	 *  - 256 index entries 4 bytes each
	 *  - 24-byte entries * nr (20-byte sha1 + 4-byte offset)
	 *  - 20-byte SHA1 of the packfile
	 *  - 20-byte SHA1 file checksum
	 */
	if (idx_size != 4*256 + nr * 24 + 20 + 20)
487
		return error("wrong index file size in %s", path);
488 489 490 491

	return 0;
}

492 493 494 495
static void scan_windows(struct packed_git *p,
	struct packed_git **lru_p,
	struct pack_window **lru_w,
	struct pack_window **lru_l)
496
{
497 498 499 500 501 502 503 504
	struct pack_window *w, *w_l;

	for (w_l = NULL, w = p->windows; w; w = w->next) {
		if (!w->inuse_cnt) {
			if (!*lru_w || w->last_used < (*lru_w)->last_used) {
				*lru_p = p;
				*lru_w = w;
				*lru_l = w_l;
505 506
			}
		}
507
		w_l = w;
508
	}
509 510 511 512 513 514 515 516 517 518 519
}

static int unuse_one_window(struct packed_git *current)
{
	struct packed_git *p, *lru_p = NULL;
	struct pack_window *lru_w = NULL, *lru_l = NULL;

	if (current)
		scan_windows(current, &lru_p, &lru_w, &lru_l);
	for (p = packed_git; p; p = p->next)
		scan_windows(p, &lru_p, &lru_w, &lru_l);
520 521 522 523 524 525 526
	if (lru_p) {
		munmap(lru_w->base, lru_w->len);
		pack_mapped -= lru_w->len;
		if (lru_l)
			lru_l->next = lru_w->next;
		else {
			lru_p->windows = lru_w->next;
527
			if (!lru_p->windows && lru_p != current) {
528 529 530 531 532
				close(lru_p->pack_fd);
				lru_p->pack_fd = -1;
			}
		}
		free(lru_w);
533
		pack_open_windows--;
534 535 536
		return 1;
	}
	return 0;
537 538
}

539 540 541 542 543 544 545
void release_pack_memory(size_t need)
{
	size_t cur = pack_mapped;
	while (need >= (cur - pack_mapped) && unuse_one_window(NULL))
		; /* nothing */
}

546
void unuse_pack(struct pack_window **w_cursor)
547
{
548 549 550 551 552
	struct pack_window *w = *w_cursor;
	if (w) {
		w->inuse_cnt--;
		*w_cursor = NULL;
	}
553 554
}

555
static void open_packed_git(struct packed_git *p)
556
{
557 558 559 560
	struct stat st;
	struct pack_header hdr;
	unsigned char sha1[20];
	unsigned char *idx_sha1;
561
	long fd_flag;
562 563 564 565 566 567

	p->pack_fd = open(p->pack_name, O_RDONLY);
	if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
		die("packfile %s cannot be opened", p->pack_name);

	/* If we created the struct before we had the pack we lack size. */
568 569 570 571
	if (!p->pack_size) {
		if (!S_ISREG(st.st_mode))
			die("packfile %s not a regular file", p->pack_name);
		p->pack_size = st.st_size;
572 573 574
	} else if (p->pack_size != st.st_size)
		die("packfile %s size changed", p->pack_name);

575 576 577 578 579 580 581 582 583 584
	/* We leave these file descriptors open with sliding mmap;
	 * there is no point keeping them open across exec(), though.
	 */
	fd_flag = fcntl(p->pack_fd, F_GETFD, 0);
	if (fd_flag < 0)
		die("cannot determine file descriptor flags");
	fd_flag |= FD_CLOEXEC;
	if (fcntl(p->pack_fd, F_SETFD, fd_flag) == -1)
		die("cannot set FD_CLOEXEC");

585
	/* Verify we recognize this pack file format. */
586 587
	if (read_in_full(p->pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
		die("file %s is far too short to be a packfile", p->pack_name);
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
	if (hdr.hdr_signature != htonl(PACK_SIGNATURE))
		die("file %s is not a GIT packfile", p->pack_name);
	if (!pack_version_ok(hdr.hdr_version))
		die("packfile %s is version %u and not supported"
			" (try upgrading GIT to a newer version)",
			p->pack_name, ntohl(hdr.hdr_version));

	/* Verify the pack matches its index. */
	if (num_packed_objects(p) != ntohl(hdr.hdr_entries))
		die("packfile %s claims to have %u objects"
			" while index size indicates %u objects",
			p->pack_name, ntohl(hdr.hdr_entries),
			num_packed_objects(p));
	if (lseek(p->pack_fd, p->pack_size - sizeof(sha1), SEEK_SET) == -1)
		die("end of packfile %s is unavailable", p->pack_name);
603 604
	if (read_in_full(p->pack_fd, sha1, sizeof(sha1)) != sizeof(sha1))
		die("packfile %s signature is unavailable", p->pack_name);
605 606 607 608 609
	idx_sha1 = ((unsigned char *)p->index_base) + p->index_size - 40;
	if (hashcmp(sha1, idx_sha1))
		die("packfile %s does not match index", p->pack_name);
}

610 611 612 613 614 615 616 617 618 619 620 621 622
static int in_window(struct pack_window *win, unsigned long offset)
{
	/* We must promise at least 20 bytes (one hash) after the
	 * offset is available from this window, otherwise the offset
	 * is not actually in this window and a different window (which
	 * has that one hash excess) must be used.  This is to support
	 * the object header and delta base parsing routines below.
	 */
	off_t win_off = win->offset;
	return win_off <= offset
		&& (offset + 20) <= (win_off + win->len);
}

623 624 625 626
unsigned char* use_pack(struct packed_git *p,
		struct pack_window **w_cursor,
		unsigned long offset,
		unsigned int *left)
627
{
628
	struct pack_window *win = *w_cursor;
629

630 631
	if (p->pack_fd == -1)
		open_packed_git(p);
632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656

	/* Since packfiles end in a hash of their content and its
	 * pointless to ask for an offset into the middle of that
	 * hash, and the in_window function above wouldn't match
	 * don't allow an offset too close to the end of the file.
	 */
	if (offset > (p->pack_size - 20))
		die("offset beyond end of packfile (truncated pack?)");

	if (!win || !in_window(win, offset)) {
		if (win)
			win->inuse_cnt--;
		for (win = p->windows; win; win = win->next) {
			if (in_window(win, offset))
				break;
		}
		if (!win) {
			if (!page_size)
				page_size = getpagesize();
			win = xcalloc(1, sizeof(*win));
			win->offset = (offset / page_size) * page_size;
			win->len = p->pack_size - win->offset;
			if (win->len > packed_git_window_size)
				win->len = packed_git_window_size;
			pack_mapped += win->len;
657 658
			while (packed_git_limit < pack_mapped
				&& unuse_one_window(p))
659
				; /* nothing */
660
			win->base = xmmap(NULL, win->len,
661 662 663
				PROT_READ, MAP_PRIVATE,
				p->pack_fd, win->offset);
			if (win->base == MAP_FAILED)
664 665 666
				die("packfile %s cannot be mapped: %s",
					p->pack_name,
					strerror(errno));
667 668 669 670 671 672
			pack_mmap_calls++;
			pack_open_windows++;
			if (pack_mapped > peak_pack_mapped)
				peak_pack_mapped = pack_mapped;
			if (pack_open_windows > peak_pack_open_windows)
				peak_pack_open_windows = pack_open_windows;
673 674 675
			win->next = p->windows;
			p->windows = win;
		}
676
	}
677 678 679 680 681
	if (win != *w_cursor) {
		win->last_used = pack_used_ctr++;
		win->inuse_cnt++;
		*w_cursor = win;
	}
682
	offset -= win->offset;
683 684 685
	if (left)
		*left = win->len - offset;
	return win->base + offset;
686 687
}

688
struct packed_git *add_packed_git(char *path, int path_len, int local)
689 690 691 692 693
{
	struct stat st;
	struct packed_git *p;
	unsigned long idx_size;
	void *idx_map;
694
	unsigned char sha1[20];
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713

	if (check_packed_git_idx(path, &idx_size, &idx_map))
		return NULL;

	/* do we have a corresponding .pack file? */
	strcpy(path + path_len - 4, ".pack");
	if (stat(path, &st) || !S_ISREG(st.st_mode)) {
		munmap(idx_map, idx_size);
		return NULL;
	}
	/* ok, it looks sane as far as we can check without
	 * actually mapping the pack file.
	 */
	p = xmalloc(sizeof(*p) + path_len + 2);
	strcpy(p->pack_name, path);
	p->index_size = idx_size;
	p->pack_size = st.st_size;
	p->index_base = idx_map;
	p->next = NULL;
714
	p->windows = NULL;
715
	p->pack_fd = -1;
716
	p->pack_local = local;
P
Pavel Roskin 已提交
717
	if ((path_len > 44) && !get_sha1_hex(path + path_len - 44, sha1))
718
		hashcpy(p->sha1, sha1);
719 720 721
	return p;
}

722
struct packed_git *parse_pack_index(unsigned char *sha1)
723 724 725 726 727
{
	char *path = sha1_pack_index_name(sha1);
	return parse_pack_index_file(sha1, path);
}

728
struct packed_git *parse_pack_index_file(const unsigned char *sha1, char *idx_path)
729 730 731 732
{
	struct packed_git *p;
	unsigned long idx_size;
	void *idx_map;
733
	char *path;
734

735
	if (check_packed_git_idx(idx_path, &idx_size, &idx_map))
736 737 738 739 740 741 742 743 744 745
		return NULL;

	path = sha1_pack_name(sha1);

	p = xmalloc(sizeof(*p) + strlen(path) + 2);
	strcpy(p->pack_name, path);
	p->index_size = idx_size;
	p->pack_size = 0;
	p->index_base = idx_map;
	p->next = NULL;
746
	p->windows = NULL;
747
	p->pack_fd = -1;
748
	hashcpy(p->sha1, sha1);
749 750 751 752 753 754 755 756 757
	return p;
}

void install_packed_git(struct packed_git *pack)
{
	pack->next = packed_git;
	packed_git = pack;
}

758
static void prepare_packed_git_one(char *objdir, int local)
759 760 761 762 763 764 765 766 767
{
	char path[PATH_MAX];
	int len;
	DIR *dir;
	struct dirent *de;

	sprintf(path, "%s/pack", objdir);
	len = strlen(path);
	dir = opendir(path);
768
	if (!dir) {
J
Junio C Hamano 已提交
769
		if (errno != ENOENT)
770
			error("unable to open object pack directory: %s: %s",
J
Junio C Hamano 已提交
771
			      path, strerror(errno));
772
		return;
773
	}
774 775 776 777 778
	path[len++] = '/';
	while ((de = readdir(dir)) != NULL) {
		int namelen = strlen(de->d_name);
		struct packed_git *p;

779
		if (!has_extension(de->d_name, ".idx"))
780 781 782 783
			continue;

		/* we have .idx.  Is it a file we can map? */
		strcpy(path + len, de->d_name);
784 785 786 787 788 789
		for (p = packed_git; p; p = p->next) {
			if (!memcmp(path, p->pack_name, len + namelen - 4))
				break;
		}
		if (p)
			continue;
790
		p = add_packed_git(path, len + namelen, local);
791 792
		if (!p)
			continue;
793
		install_packed_git(p);
794
	}
795
	closedir(dir);
796 797
}

798
static int prepare_packed_git_run_once = 0;
799
void prepare_packed_git(void)
800
{
801
	struct alternate_object_database *alt;
802

803
	if (prepare_packed_git_run_once)
804
		return;
805
	prepare_packed_git_one(get_object_directory(), 1);
806
	prepare_alt_odb();
807
	for (alt = alt_odb_list; alt; alt = alt->next) {
808
		alt->name[-1] = 0;
809
		prepare_packed_git_one(alt->base, 0);
810
		alt->name[-1] = '/';
811
	}
812 813 814
	prepare_packed_git_run_once = 1;
}

815
void reprepare_packed_git(void)
816 817 818
{
	prepare_packed_git_run_once = 0;
	prepare_packed_git();
819 820
}

821
int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type)
822 823
{
	unsigned char real_sha1[20];
824
	hash_sha1_file(map, size, type, real_sha1);
825
	return hashcmp(sha1, real_sha1) ? -1 : 0;
826 827
}

828
void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
829 830 831
{
	struct stat st;
	void *map;
832
	int fd;
833 834 835 836 837
	char *filename = find_sha1_file(sha1, &st);

	if (!filename) {
		return NULL;
	}
838

839
	fd = open(filename, O_RDONLY | sha1_file_open_flag);
840
	if (fd < 0) {
841 842 843 844 845 846 847 848 849 850 851
		/* 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:
			return NULL;
		}

852 853 854
		/* If it failed once, it will probably fail again.
		 * Stop using O_NOATIME
		 */
855
		sha1_file_open_flag = 0;
856
	}
857
	map = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
858 859 860 861 862
	close(fd);
	*size = st.st_size;
	return map;
}

863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
int legacy_loose_object(unsigned char *map)
{
	unsigned int word;

	/*
	 * Is it a zlib-compressed buffer? If so, the first byte
	 * must be 0x78 (15-bit window size, deflated), and the
	 * first 16-bit word is evenly divisible by 31
	 */
	word = (map[0] << 8) + map[1];
	if (map[0] == 0x78 && !(word % 31))
		return 1;
	else
		return 0;
}

879
unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep)
880
{
881
	unsigned shift;
882 883
	unsigned char c;
	unsigned long size;
884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
	unsigned long used = 0;

	c = buf[used++];
	*type = (c >> 4) & 7;
	size = c & 15;
	shift = 4;
	while (c & 0x80) {
		if (len <= used)
			return 0;
		if (sizeof(long) * 8 <= shift)
			return 0;
		c = buf[used++];
		size += (c & 0x7f) << shift;
		shift += 7;
	}
	*sizep = size;
	return used;
}

static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
{
	unsigned long size, used;
	static const char valid_loose_object_type[8] = {
		0, /* OBJ_EXT */
		1, 1, 1, 1, /* "commit", "tree", "blob", "tag" */
		0, /* "delta" and others are invalid in a loose object */
910
	};
911
	enum object_type type;
912

913 914 915 916 917
	/* Get the data stream */
	memset(stream, 0, sizeof(*stream));
	stream->next_in = map;
	stream->avail_in = mapsize;
	stream->next_out = buffer;
918 919
	stream->avail_out = bufsiz;

920
	if (legacy_loose_object(map)) {
921 922 923 924
		inflateInit(stream);
		return inflate(stream, 0);
	}

925 926
	used = unpack_object_header_gently(map, mapsize, &type, &size);
	if (!used || !valid_loose_object_type[type])
927
		return -1;
928 929
	map += used;
	mapsize -= used;
930 931 932 933

	/* Set up the stream for the rest.. */
	stream->next_in = map;
	stream->avail_in = mapsize;
934
	inflateInit(stream);
935 936

	/* And generate the fake traditional header */
937 938
	stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
					 type_names[type], size);
939
	return 0;
940 941
}

L
Linus Torvalds 已提交
942
static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size)
943 944
{
	int bytes = strlen(buffer) + 1;
945
	unsigned char *buf = xmalloc(1+size);
946
	unsigned long n;
947

948 949 950 951 952
	n = stream->total_out - bytes;
	if (n > size)
		n = size;
	memcpy(buf, (char *) buffer + bytes, n);
	bytes = n;
953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968
	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.
 */
969
static int parse_sha1_header(char *hdr, char *type, unsigned long *sizep)
970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
{
	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;
}

1014 1015
void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size)
{
1016
	int ret;
1017
	z_stream stream;
1018
	char hdr[8192];
1019

1020 1021
	ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
	if (ret < Z_OK || parse_sha1_header(hdr, type, size) < 0)
1022 1023
		return NULL;

1024
	return unpack_sha1_rest(&stream, hdr, *size);
1025 1026
}

1027
static unsigned long get_delta_base(struct packed_git *p,
1028
				    struct pack_window **w_curs,
1029 1030 1031 1032 1033
				    unsigned long offset,
				    enum object_type kind,
				    unsigned long delta_obj_offset,
				    unsigned long *base_obj_offset)
{
1034
	unsigned char *base_info = use_pack(p, w_curs, offset, NULL);
1035 1036
	unsigned long base_offset;

1037 1038 1039 1040 1041 1042
	/* use_pack() assured us we have [base_info, base_info + 20)
	 * as a range that we can look at without walking off the
	 * end of the mapped window.  Its actually the hash size
	 * that is assured.  An OFS_DELTA longer than the hash size
	 * is stupid, as then a REF_DELTA would be smaller to store.
	 */
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070
	if (kind == OBJ_OFS_DELTA) {
		unsigned used = 0;
		unsigned char c = base_info[used++];
		base_offset = c & 127;
		while (c & 128) {
			base_offset += 1;
			if (!base_offset || base_offset & ~(~0UL >> 7))
				die("offset value overflow for delta base object");
			c = base_info[used++];
			base_offset = (base_offset << 7) + (c & 127);
		}
		base_offset = delta_obj_offset - base_offset;
		if (base_offset >= delta_obj_offset)
			die("delta base offset out of bound");
		offset += used;
	} else if (kind == OBJ_REF_DELTA) {
		/* The base entry _must_ be in the same pack */
		base_offset = find_pack_entry_one(base_info, p);
		if (!base_offset)
			die("failed to find delta-pack base object %s",
				sha1_to_hex(base_info));
		offset += 20;
	} else
		die("I am totally screwed");
	*base_obj_offset = base_offset;
	return offset;
}

J
Junio C Hamano 已提交
1071
/* forward declaration for a mutually recursive function */
N
Nicolas Pitre 已提交
1072
static int packed_object_info(struct packed_git *p, unsigned long offset,
J
Junio C Hamano 已提交
1073 1074
			      char *type, unsigned long *sizep);

N
Nicolas Pitre 已提交
1075
static int packed_delta_info(struct packed_git *p,
1076
			     struct pack_window **w_curs,
N
Nicolas Pitre 已提交
1077
			     unsigned long offset,
1078 1079
			     enum object_type kind,
			     unsigned long obj_offset,
1080
			     char *type,
N
Nicolas Pitre 已提交
1081
			     unsigned long *sizep)
1082
{
N
Nicolas Pitre 已提交
1083
	unsigned long base_offset;
J
Junio C Hamano 已提交
1084

1085 1086
	offset = get_delta_base(p, w_curs, offset, kind,
		obj_offset, &base_offset);
J
Junio C Hamano 已提交
1087

1088 1089 1090 1091 1092
	/* We choose to only get the type of the base object and
	 * ignore potentially corrupt pack file that expects the delta
	 * based on a base with a wrong size.  This saves tons of
	 * inflate() calls.
	 */
N
Nicolas Pitre 已提交
1093
	if (packed_object_info(p, base_offset, type, NULL))
1094
		die("cannot get info for delta-pack base");
1095

1096 1097
	if (sizep) {
		const unsigned char *data;
1098
		unsigned char delta_head[20], *in;
1099 1100 1101 1102 1103 1104 1105 1106 1107
		unsigned long result_size;
		z_stream stream;
		int st;

		memset(&stream, 0, sizeof(stream));
		stream.next_out = delta_head;
		stream.avail_out = sizeof(delta_head);

		inflateInit(&stream);
1108 1109 1110 1111 1112 1113 1114
		do {
			in = use_pack(p, w_curs, offset, &stream.avail_in);
			stream.next_in = in;
			st = inflate(&stream, Z_FINISH);
			offset += stream.next_in - in;
		} while ((st == Z_OK || st == Z_BUF_ERROR)
			&& stream.total_out < sizeof(delta_head));
1115 1116 1117 1118 1119 1120 1121 1122 1123
		inflateEnd(&stream);
		if ((st != Z_STREAM_END) &&
		    stream.total_out != sizeof(delta_head))
			die("delta data unpack-initial failed");

		/* Examine the initial part of the delta to figure out
		 * the result size.
		 */
		data = delta_head;
1124 1125 1126

		/* ignore base size */
		get_delta_hdr_size(&data, delta_head+sizeof(delta_head));
1127

1128
		/* Read the result size */
1129
		result_size = get_delta_hdr_size(&data, delta_head+sizeof(delta_head));
1130 1131
		*sizep = result_size;
	}
1132 1133 1134
	return 0;
}

1135 1136 1137 1138 1139
static unsigned long unpack_object_header(struct packed_git *p,
		struct pack_window **w_curs,
		unsigned long offset,
		enum object_type *type,
		unsigned long *sizep)
1140
{
1141 1142
	unsigned char *base;
	unsigned int left;
1143
	unsigned long used;
1144

1145 1146 1147 1148 1149 1150
	/* use_pack() assures us we have [base, base + 20) available
	 * as a range that we can look at at.  (Its actually the hash
	 * size that is assurred.)  With our object header encoding
	 * the maximum deflated object size is 2^137, which is just
	 * insane, so we know won't exceed what we have been given.
	 */
1151 1152
	base = use_pack(p, w_curs, offset, &left);
	used = unpack_object_header_gently(base, left, type, sizep);
1153 1154 1155 1156
	if (!used)
		die("object offset outside of pack file");

	return offset + used;
1157 1158
}

N
Nicolas Pitre 已提交
1159 1160
void packed_object_info_detail(struct packed_git *p,
			       unsigned long offset,
1161 1162 1163
			       char *type,
			       unsigned long *size,
			       unsigned long *store_size,
J
Junio C Hamano 已提交
1164
			       unsigned int *delta_chain_length,
1165 1166
			       unsigned char *base_sha1)
{
1167
	struct pack_window *w_curs = NULL;
1168
	unsigned long obj_offset, val;
N
Nicolas Pitre 已提交
1169
	unsigned char *next_sha1;
1170 1171
	enum object_type kind;

N
Nicolas Pitre 已提交
1172
	*delta_chain_length = 0;
1173
	obj_offset = offset;
1174
	offset = unpack_object_header(p, &w_curs, offset, &kind, size);
N
Nicolas Pitre 已提交
1175 1176 1177 1178

	for (;;) {
		switch (kind) {
		default:
1179
			die("pack %s contains unknown object type %d",
N
Nicolas Pitre 已提交
1180 1181 1182 1183 1184 1185 1186
			    p->pack_name, kind);
		case OBJ_COMMIT:
		case OBJ_TREE:
		case OBJ_BLOB:
		case OBJ_TAG:
			strcpy(type, type_names[kind]);
			*store_size = 0; /* notyet */
1187
			unuse_pack(&w_curs);
N
Nicolas Pitre 已提交
1188
			return;
1189
		case OBJ_OFS_DELTA:
1190 1191
			get_delta_base(p, &w_curs, offset, kind,
				obj_offset, &offset);
1192 1193 1194 1195 1196
			if (*delta_chain_length == 0) {
				/* TODO: find base_sha1 as pointed by offset */
			}
			break;
		case OBJ_REF_DELTA:
1197
			next_sha1 = use_pack(p, &w_curs, offset, NULL);
N
Nicolas Pitre 已提交
1198 1199 1200 1201 1202
			if (*delta_chain_length == 0)
				hashcpy(base_sha1, next_sha1);
			offset = find_pack_entry_one(next_sha1, p);
			break;
		}
1203
		obj_offset = offset;
1204
		offset = unpack_object_header(p, &w_curs, offset, &kind, &val);
N
Nicolas Pitre 已提交
1205
		(*delta_chain_length)++;
1206 1207 1208
	}
}

N
Nicolas Pitre 已提交
1209
static int packed_object_info(struct packed_git *p, unsigned long offset,
1210 1211
			      char *type, unsigned long *sizep)
{
1212
	struct pack_window *w_curs = NULL;
1213
	unsigned long size, obj_offset = offset;
1214
	enum object_type kind;
1215
	int r;
1216

1217
	offset = unpack_object_header(p, &w_curs, offset, &kind, &size);
1218

1219
	switch (kind) {
1220 1221
	case OBJ_OFS_DELTA:
	case OBJ_REF_DELTA:
1222 1223 1224 1225
		r = packed_delta_info(p, &w_curs, offset, kind,
			obj_offset, type, sizep);
		unuse_pack(&w_curs);
		return r;
1226 1227 1228 1229
	case OBJ_COMMIT:
	case OBJ_TREE:
	case OBJ_BLOB:
	case OBJ_TAG:
1230
		strcpy(type, type_names[kind]);
1231
		unuse_pack(&w_curs);
1232
		break;
1233
	default:
1234
		die("pack %s contains unknown object type %d",
1235
		    p->pack_name, kind);
1236
	}
1237 1238
	if (sizep)
		*sizep = size;
1239 1240 1241
	return 0;
}

1242
static void *unpack_compressed_entry(struct packed_git *p,
1243
				    struct pack_window **w_curs,
1244 1245
				    unsigned long offset,
				    unsigned long size)
1246 1247 1248
{
	int st;
	z_stream stream;
1249
	unsigned char *buffer, *in;
1250 1251 1252 1253 1254 1255 1256 1257

	buffer = xmalloc(size + 1);
	buffer[size] = 0;
	memset(&stream, 0, sizeof(stream));
	stream.next_out = buffer;
	stream.avail_out = size;

	inflateInit(&stream);
1258 1259 1260 1261 1262 1263
	do {
		in = use_pack(p, w_curs, offset, &stream.avail_in);
		stream.next_in = in;
		st = inflate(&stream, Z_FINISH);
		offset += stream.next_in - in;
	} while (st == Z_OK || st == Z_BUF_ERROR);
1264 1265 1266 1267 1268 1269 1270 1271 1272
	inflateEnd(&stream);
	if ((st != Z_STREAM_END) || stream.total_out != size) {
		free(buffer);
		return NULL;
	}

	return buffer;
}

1273
static void *unpack_delta_entry(struct packed_git *p,
1274
				struct pack_window **w_curs,
1275
				unsigned long offset,
1276
				unsigned long delta_size,
1277 1278
				enum object_type kind,
				unsigned long obj_offset,
1279
				char *type,
1280
				unsigned long *sizep)
1281
{
1282
	void *delta_data, *result, *base;
N
Nicolas Pitre 已提交
1283 1284
	unsigned long result_size, base_size, base_offset;

1285 1286
	offset = get_delta_base(p, w_curs, offset, kind,
		obj_offset, &base_offset);
1287
	base = unpack_entry(p, base_offset, type, &base_size);
1288
	if (!base)
N
Nicolas Pitre 已提交
1289 1290
		die("failed to read delta base object at %lu from %s",
		    base_offset, p->pack_name);
1291

1292
	delta_data = unpack_compressed_entry(p, w_curs, offset, delta_size);
1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303
	result = patch_delta(base, base_size,
			     delta_data, delta_size,
			     &result_size);
	if (!result)
		die("failed to apply delta");
	free(delta_data);
	free(base);
	*sizep = result_size;
	return result;
}

1304
void *unpack_entry(struct packed_git *p, unsigned long offset,
1305 1306
			  char *type, unsigned long *sizep)
{
1307
	struct pack_window *w_curs = NULL;
1308 1309
	unsigned long size, obj_offset = offset;
	enum object_type kind;
1310
	void *retval;
1311

1312
	offset = unpack_object_header(p, &w_curs, offset, &kind, &size);
1313
	switch (kind) {
1314 1315
	case OBJ_OFS_DELTA:
	case OBJ_REF_DELTA:
1316 1317
		retval = unpack_delta_entry(p, &w_curs, offset, size,
			kind, obj_offset, type, sizep);
1318
		break;
1319 1320 1321 1322
	case OBJ_COMMIT:
	case OBJ_TREE:
	case OBJ_BLOB:
	case OBJ_TAG:
1323 1324
		strcpy(type, type_names[kind]);
		*sizep = size;
1325
		retval = unpack_compressed_entry(p, &w_curs, offset, size);
1326
		break;
1327
	default:
1328
		die("unknown object type %i in %s", kind, p->pack_name);
1329
	}
1330
	unuse_pack(&w_curs);
1331
	return retval;
1332 1333
}

1334 1335
int num_packed_objects(const struct packed_git *p)
{
1336
	/* See check_packed_git_idx() */
1337 1338 1339 1340 1341 1342 1343 1344 1345
	return (p->index_size - 20 - 20 - 4*256) / 24;
}

int nth_packed_object_sha1(const struct packed_git *p, int n,
			   unsigned char* sha1)
{
	void *index = p->index_base + 256;
	if (n < 0 || num_packed_objects(p) <= n)
		return -1;
1346
	hashcpy(sha1, (unsigned char *) index + (24 * n) + 4);
1347 1348 1349
	return 0;
}

N
Nicolas Pitre 已提交
1350 1351
unsigned long find_pack_entry_one(const unsigned char *sha1,
				  struct packed_git *p)
1352
{
1353
	uint32_t *level1_ofs = p->index_base;
1354 1355 1356 1357 1358 1359
	int hi = ntohl(level1_ofs[*sha1]);
	int lo = ((*sha1 == 0x0) ? 0 : ntohl(level1_ofs[*sha1 - 1]));
	void *index = p->index_base + 256;

	do {
		int mi = (lo + hi) / 2;
1360
		int cmp = hashcmp((unsigned char *)index + (24 * mi) + 4, sha1);
N
Nicolas Pitre 已提交
1361
		if (!cmp)
1362
			return ntohl(*((uint32_t *)((char *)index + (24 * mi))));
1363 1364 1365 1366 1367 1368 1369 1370
		if (cmp > 0)
			hi = mi;
		else
			lo = mi+1;
	} while (lo < hi);
	return 0;
}

1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388
static int matches_pack_name(struct packed_git *p, const char *ig)
{
	const char *last_c, *c;

	if (!strcmp(p->pack_name, ig))
		return 0;

	for (c = p->pack_name, last_c = c; *c;)
		if (*c == '/')
			last_c = ++c;
		else
			++c;
	if (!strcmp(last_c, ig))
		return 0;

	return 1;
}

1389
static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed)
1390 1391
{
	struct packed_git *p;
N
Nicolas Pitre 已提交
1392 1393
	unsigned long offset;

1394 1395 1396
	prepare_packed_git();

	for (p = packed_git; p; p = p->next) {
1397 1398 1399
		if (ignore_packed) {
			const char **ig;
			for (ig = ignore_packed; *ig; ig++)
1400
				if (!matches_pack_name(p, *ig))
1401 1402 1403 1404
					break;
			if (*ig)
				continue;
		}
N
Nicolas Pitre 已提交
1405 1406 1407 1408 1409
		offset = find_pack_entry_one(sha1, p);
		if (offset) {
			e->offset = offset;
			e->p = p;
			hashcpy(e->sha1, sha1);
1410
			return 1;
N
Nicolas Pitre 已提交
1411
		}
1412 1413 1414 1415
	}
	return 0;
}

1416 1417 1418 1419 1420 1421
struct packed_git *find_sha1_pack(const unsigned char *sha1, 
				  struct packed_git *packs)
{
	struct packed_git *p;

	for (p = packs; p; p = p->next) {
N
Nicolas Pitre 已提交
1422
		if (find_pack_entry_one(sha1, p))
1423 1424 1425 1426 1427 1428
			return p;
	}
	return NULL;
	
}

1429
static int sha1_loose_object_info(const unsigned char *sha1, char *type, unsigned long *sizep)
1430
{
1431
	int status;
1432 1433 1434
	unsigned long mapsize, size;
	void *map;
	z_stream stream;
1435
	char hdr[128];
1436

1437
	map = map_sha1_file(sha1, &mapsize);
1438 1439
	if (!map)
		return error("unable to find %s", sha1_to_hex(sha1));
1440 1441 1442 1443 1444
	if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0)
		status = error("unable to unpack %s header",
			       sha1_to_hex(sha1));
	if (parse_sha1_header(hdr, type, &size) < 0)
		status = error("unable to parse %s header", sha1_to_hex(sha1));
1445
	else {
1446
		status = 0;
1447 1448
		if (sizep)
			*sizep = size;
1449 1450 1451 1452 1453 1454
	}
	inflateEnd(&stream);
	munmap(map, mapsize);
	return status;
}

1455 1456 1457 1458 1459 1460 1461 1462 1463
int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep)
{
	struct pack_entry e;

	if (!find_pack_entry(sha1, &e, NULL)) {
		reprepare_packed_git();
		if (!find_pack_entry(sha1, &e, NULL))
			return sha1_loose_object_info(sha1, type, sizep);
	}
1464
	return packed_object_info(e.p, e.offset, type, sizep);
1465 1466
}

1467 1468 1469 1470
static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned long *size)
{
	struct pack_entry e;

1471
	if (!find_pack_entry(sha1, &e, NULL))
1472
		return NULL;
1473 1474
	else
		return unpack_entry(e.p, e.offset, type, size);
1475 1476
}

1477 1478 1479 1480 1481
void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
{
	unsigned long mapsize;
	void *map, *buf;

1482 1483 1484
	buf = read_packed_sha1(sha1, type, size);
	if (buf)
		return buf;
1485
	map = map_sha1_file(sha1, &mapsize);
1486 1487 1488 1489 1490
	if (map) {
		buf = unpack_sha1_file(map, mapsize, type, size);
		munmap(map, mapsize);
		return buf;
	}
1491
	reprepare_packed_git();
1492
	return read_packed_sha1(sha1, type, size);
1493 1494
}

1495
void *read_object_with_reference(const unsigned char *sha1,
1496
				 const char *required_type,
1497 1498
				 unsigned long *size,
				 unsigned char *actual_sha1_return)
1499 1500 1501 1502
{
	char type[20];
	void *buffer;
	unsigned long isize;
1503
	unsigned char actual_sha1[20];
1504

1505
	hashcpy(actual_sha1, sha1);
1506 1507 1508
	while (1) {
		int ref_length = -1;
		const char *ref_type = NULL;
1509

1510 1511 1512 1513 1514 1515
		buffer = read_sha1_file(actual_sha1, type, &isize);
		if (!buffer)
			return NULL;
		if (!strcmp(type, required_type)) {
			*size = isize;
			if (actual_sha1_return)
1516
				hashcpy(actual_sha1_return, actual_sha1);
1517 1518 1519
			return buffer;
		}
		/* Handle references */
1520
		else if (!strcmp(type, commit_type))
1521
			ref_type = "tree ";
1522
		else if (!strcmp(type, tag_type))
1523 1524 1525 1526 1527 1528
			ref_type = "object ";
		else {
			free(buffer);
			return NULL;
		}
		ref_length = strlen(ref_type);
1529

1530
		if (memcmp(buffer, ref_type, ref_length) ||
1531
		    get_sha1_hex((char *) buffer + ref_length, actual_sha1)) {
1532 1533 1534
			free(buffer);
			return NULL;
		}
1535
		free(buffer);
1536 1537
		/* Now we have the ID of the referred-to object in
		 * actual_sha1.  Check again. */
1538 1539 1540
	}
}

R
Rene Scharfe 已提交
1541 1542 1543
static void write_sha1_file_prepare(void *buf, unsigned long len,
                                    const char *type, unsigned char *sha1,
                                    unsigned char *hdr, int *hdrlen)
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556
{
	SHA_CTX c;

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

	/* Sha1.. */
	SHA1_Init(&c);
	SHA1_Update(&c, hdr, *hdrlen);
	SHA1_Update(&c, buf, len);
	SHA1_Final(sha1, &c);
}

1557 1558 1559 1560 1561 1562
/*
 * Link the tempfile to the final place, possibly creating the
 * last directory level as you do so.
 *
 * Returns the errno on failure, 0 on success.
 */
1563
static int link_temp_to_file(const char *tmpfile, const char *filename)
1564 1565
{
	int ret;
S
Shawn Pearce 已提交
1566
	char *dir;
1567 1568 1569 1570 1571

	if (!link(tmpfile, filename))
		return 0;

	/*
S
Shawn Pearce 已提交
1572
	 * Try to mkdir the last path component if that failed.
1573 1574 1575 1576 1577 1578
	 *
	 * Re-try the "link()" regardless of whether the mkdir
	 * succeeds, since a race might mean that somebody
	 * else succeeded.
	 */
	ret = errno;
S
Shawn Pearce 已提交
1579 1580 1581
	dir = strrchr(filename, '/');
	if (dir) {
		*dir = 0;
1582
		if (!mkdir(filename, 0777) && adjust_shared_perm(filename)) {
1583
			*dir = '/';
S
Shawn Pearce 已提交
1584
			return -2;
1585
		}
S
Shawn Pearce 已提交
1586 1587 1588 1589
		*dir = '/';
		if (!link(tmpfile, filename))
			return 0;
		ret = errno;
1590 1591 1592 1593 1594 1595 1596
	}
	return ret;
}

/*
 * Move the just written object into its final resting place
 */
1597
int move_temp_to_file(const char *tmpfile, const char *filename)
1598 1599
{
	int ret = link_temp_to_file(tmpfile, filename);
1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613

	/*
	 * 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.
	 *
	 * The same holds for FAT formatted media.
	 *
	 * When this succeeds, we just return 0. We have nothing
	 * left to unlink.
	 */
	if (ret && ret != EEXIST) {
		if (!rename(tmpfile, filename))
1614
			return 0;
1615
		ret = errno;
1616 1617 1618 1619
	}
	unlink(tmpfile);
	if (ret) {
		if (ret != EEXIST) {
1620
			return error("unable to write sha1 filename %s: %s\n", filename, strerror(ret));
1621 1622 1623 1624 1625 1626 1627
		}
		/* FIXME!!! Collision check here ? */
	}

	return 0;
}

L
Linus Torvalds 已提交
1628 1629
static int write_buffer(int fd, const void *buf, size_t len)
{
L
Linus Torvalds 已提交
1630
	if (write_in_full(fd, buf, len) < 0)
1631
		return error("file write error (%s)", strerror(errno));
L
Linus Torvalds 已提交
1632 1633 1634
	return 0;
}

1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677
static int write_binary_header(unsigned char *hdr, enum object_type type, unsigned long len)
{
	int hdr_len;
	unsigned char c;

	c = (type << 4) | (len & 15);
	len >>= 4;
	hdr_len = 1;
	while (len) {
		*hdr++ = c | 0x80;
		hdr_len++;
		c = (len & 0x7f);
		len >>= 7;
	}
	*hdr = c;
	return hdr_len;
}

static void setup_object_header(z_stream *stream, const char *type, unsigned long len)
{
	int obj_type, hdr;

	if (use_legacy_headers) {
		while (deflate(stream, 0) == Z_OK)
			/* nothing */;
		return;
	}
	if (!strcmp(type, blob_type))
		obj_type = OBJ_BLOB;
	else if (!strcmp(type, tree_type))
		obj_type = OBJ_TREE;
	else if (!strcmp(type, commit_type))
		obj_type = OBJ_COMMIT;
	else if (!strcmp(type, tag_type))
		obj_type = OBJ_TAG;
	else
		die("trying to generate bogus object of type '%s'", type);
	hdr = write_binary_header(stream->next_out, obj_type, len);
	stream->total_out = hdr;
	stream->next_out += hdr;
	stream->avail_out -= hdr;
}

R
Rene Scharfe 已提交
1678 1679 1680 1681 1682 1683 1684 1685 1686
int hash_sha1_file(void *buf, unsigned long len, const char *type,
                   unsigned char *sha1)
{
	unsigned char hdr[50];
	int hdrlen;
	write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
	return 0;
}

1687
int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
1688 1689
{
	int size;
1690
	unsigned char *compressed;
1691 1692
	z_stream stream;
	unsigned char sha1[20];
1693
	char *filename;
1694
	static char tmpfile[PATH_MAX];
1695
	unsigned char hdr[50];
1696
	int fd, hdrlen;
1697

1698 1699 1700
	/* Normally if we have it in the pack then we do not bother writing
	 * it out into .git/objects/??/?{38} file.
	 */
R
Rene Scharfe 已提交
1701 1702
	write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
	filename = sha1_file_name(sha1);
1703
	if (returnsha1)
1704
		hashcpy(returnsha1, sha1);
1705 1706
	if (has_sha1_file(sha1))
		return 0;
1707 1708
	fd = open(filename, O_RDONLY);
	if (fd >= 0) {
1709
		/*
1710 1711
		 * FIXME!!! We might do collision checking here, but we'd
		 * need to uncompress the old file and check it. Later.
1712
		 */
1713
		close(fd);
1714 1715 1716
		return 0;
	}

1717
	if (errno != ENOENT) {
1718
		return error("sha1 file %s: %s\n", filename, strerror(errno));
1719 1720 1721
	}

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

1723 1724
	fd = mkstemp(tmpfile);
	if (fd < 0) {
1725 1726 1727 1728
		if (errno == EPERM)
			return error("insufficient permission for adding an object to repository database %s\n", get_object_directory());
		else
			return error("unable to create temporary sha1 filename %s: %s\n", tmpfile, strerror(errno));
1729 1730
	}

1731 1732
	/* Set it up */
	memset(&stream, 0, sizeof(stream));
1733
	deflateInit(&stream, zlib_compression_level);
1734
	size = 8 + deflateBound(&stream, len+hdrlen);
1735
	compressed = xmalloc(size);
1736 1737 1738 1739

	/* Compress it */
	stream.next_out = compressed;
	stream.avail_out = size;
1740 1741 1742 1743

	/* First header.. */
	stream.next_in = hdr;
	stream.avail_in = hdrlen;
1744
	setup_object_header(&stream, type, len);
1745 1746 1747 1748

	/* Then the data itself.. */
	stream.next_in = buf;
	stream.avail_in = len;
1749 1750 1751 1752 1753
	while (deflate(&stream, Z_FINISH) == Z_OK)
		/* nothing */;
	deflateEnd(&stream);
	size = stream.total_out;

L
Linus Torvalds 已提交
1754 1755
	if (write_buffer(fd, compressed, size) < 0)
		die("unable to write sha1 file");
1756
	fchmod(fd, 0444);
1757
	close(fd);
1758
	free(compressed);
1759

1760
	return move_temp_to_file(tmpfile, filename);
1761
}
1762

L
Linus Torvalds 已提交
1763 1764 1765 1766 1767
/*
 * We need to unpack and recompress the object for writing
 * it out to a different file.
 */
static void *repack_object(const unsigned char *sha1, unsigned long *objsize)
D
Daniel Barkalow 已提交
1768
{
L
Linus Torvalds 已提交
1769
	size_t size;
D
Daniel Barkalow 已提交
1770
	z_stream stream;
L
Linus Torvalds 已提交
1771 1772 1773 1774 1775 1776
	unsigned char *unpacked;
	unsigned long len;
	char type[20];
	char hdr[50];
	int hdrlen;
	void *buf;
1777

1778
	/* need to unpack and recompress it by itself */
L
Linus Torvalds 已提交
1779
	unpacked = read_packed_sha1(sha1, type, &len);
1780 1781
	if (!unpacked)
		error("cannot read sha1_file for %s", sha1_to_hex(sha1));
D
Daniel Barkalow 已提交
1782

L
Linus Torvalds 已提交
1783
	hdrlen = sprintf(hdr, "%s %lu", type, len) + 1;
D
Daniel Barkalow 已提交
1784

L
Linus Torvalds 已提交
1785 1786
	/* Set it up */
	memset(&stream, 0, sizeof(stream));
1787
	deflateInit(&stream, zlib_compression_level);
L
Linus Torvalds 已提交
1788 1789
	size = deflateBound(&stream, len + hdrlen);
	buf = xmalloc(size);
D
Daniel Barkalow 已提交
1790

L
Linus Torvalds 已提交
1791 1792 1793
	/* Compress it */
	stream.next_out = buf;
	stream.avail_out = size;
D
Daniel Barkalow 已提交
1794

L
Linus Torvalds 已提交
1795 1796 1797 1798 1799
	/* First header.. */
	stream.next_in = (void *)hdr;
	stream.avail_in = hdrlen;
	while (deflate(&stream, 0) == Z_OK)
		/* nothing */;
1800

L
Linus Torvalds 已提交
1801 1802 1803 1804 1805 1806 1807
	/* Then the data itself.. */
	stream.next_in = unpacked;
	stream.avail_in = len;
	while (deflate(&stream, Z_FINISH) == Z_OK)
		/* nothing */;
	deflateEnd(&stream);
	free(unpacked);
1808

L
Linus Torvalds 已提交
1809 1810 1811 1812 1813 1814 1815 1816
	*objsize = stream.total_out;
	return buf;
}

int write_sha1_to_fd(int fd, const unsigned char *sha1)
{
	int retval;
	unsigned long objsize;
1817
	void *buf = map_sha1_file(sha1, &objsize);
L
Linus Torvalds 已提交
1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828

	if (buf) {
		retval = write_buffer(fd, buf, objsize);
		munmap(buf, objsize);
		return retval;
	}

	buf = repack_object(sha1, &objsize);
	retval = write_buffer(fd, buf, objsize);
	free(buf);
	return retval;
D
Daniel Barkalow 已提交
1829 1830
}

1831 1832
int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
		       size_t bufsize, size_t *bufposn)
1833
{
1834
	char tmpfile[PATH_MAX];
1835 1836 1837
	int local;
	z_stream stream;
	unsigned char real_sha1[20];
1838
	unsigned char discard[4096];
1839 1840 1841
	int ret;
	SHA_CTX c;

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

1844
	local = mkstemp(tmpfile);
1845 1846 1847 1848 1849 1850
	if (local < 0) {
		if (errno == EPERM)
			return error("insufficient permission for adding an object to repository database %s\n", get_object_directory());
		else
			return error("unable to create temporary sha1 filename %s: %s\n", tmpfile, strerror(errno));
	}
1851 1852 1853 1854 1855 1856 1857 1858 1859

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

	inflateInit(&stream);

	SHA1_Init(&c);

	do {
		ssize_t size;
1860 1861
		if (*bufposn) {
			stream.avail_in = *bufposn;
P
Pavel Roskin 已提交
1862
			stream.next_in = (unsigned char *) buffer;
1863 1864 1865 1866 1867 1868 1869
			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);
L
Linus Torvalds 已提交
1870 1871
			if (write_buffer(local, buffer, *bufposn - stream.avail_in) < 0)
				die("unable to write sha1 file");
1872 1873 1874 1875 1876 1877
			memmove(buffer, buffer + *bufposn - stream.avail_in,
				stream.avail_in);
			*bufposn = stream.avail_in;
			if (ret != Z_OK)
				break;
		}
1878
		size = xread(fd, buffer + *bufposn, bufsize - *bufposn);
1879 1880
		if (size <= 0) {
			close(local);
1881
			unlink(tmpfile);
1882 1883 1884 1885 1886
			if (!size)
				return error("Connection closed?");
			perror("Reading from connection");
			return -1;
		}
1887 1888
		*bufposn += size;
	} while (1);
1889 1890 1891 1892 1893
	inflateEnd(&stream);

	close(local);
	SHA1_Final(real_sha1, &c);
	if (ret != Z_STREAM_END) {
1894
		unlink(tmpfile);
1895 1896
		return error("File %s corrupted", sha1_to_hex(sha1));
	}
1897
	if (hashcmp(sha1, real_sha1)) {
1898
		unlink(tmpfile);
1899
		return error("File %s has bad hash", sha1_to_hex(sha1));
1900
	}
1901 1902

	return move_temp_to_file(tmpfile, sha1_file_name(sha1));
1903 1904
}

1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920
int has_pack_index(const unsigned char *sha1)
{
	struct stat st;
	if (stat(sha1_pack_index_name(sha1), &st))
		return 0;
	return 1;
}

int has_pack_file(const unsigned char *sha1)
{
	struct stat st;
	if (stat(sha1_pack_name(sha1), &st))
		return 0;
	return 1;
}

1921
int has_sha1_pack(const unsigned char *sha1, const char **ignore_packed)
1922 1923
{
	struct pack_entry e;
1924
	return find_pack_entry(sha1, &e, ignore_packed);
1925 1926
}

1927 1928 1929
int has_sha1_file(const unsigned char *sha1)
{
	struct stat st;
1930 1931
	struct pack_entry e;

1932
	if (find_pack_entry(sha1, &e, NULL))
1933
		return 1;
1934
	return find_sha1_file(sha1, &st) ? 1 : 0;
1935
}
J
Junio C Hamano 已提交
1936

1937 1938
/*
 * reads from fd as long as possible into a supplied buffer of size bytes.
1939
 * If necessary the buffer's size is increased using realloc()
1940 1941 1942 1943 1944 1945 1946
 *
 * returns 0 if anything went fine and -1 otherwise
 *
 * NOTE: both buf and size may change, but even when -1 is returned
 * you still have to free() it yourself.
 */
int read_pipe(int fd, char** return_buf, unsigned long* return_size)
1947
{
1948 1949 1950
	char* buf = *return_buf;
	unsigned long size = *return_size;
	int iret;
1951
	unsigned long off = 0;
1952

1953
	do {
1954
		iret = xread(fd, buf + off, size - off);
1955 1956 1957 1958
		if (iret > 0) {
			off += iret;
			if (off == size) {
				size *= 2;
J
Jonas Fonseca 已提交
1959
				buf = xrealloc(buf, size);
1960 1961 1962
			}
		}
	} while (iret > 0);
1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974

	*return_buf = buf;
	*return_size = off;

	if (iret < 0)
		return -1;
	return 0;
}

int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object)
{
	unsigned long size = 4096;
J
Jonas Fonseca 已提交
1975
	char *buf = xmalloc(size);
1976 1977 1978
	int ret;

	if (read_pipe(fd, &buf, &size)) {
1979 1980 1981
		free(buf);
		return -1;
	}
1982

1983
	if (!type)
1984
		type = blob_type;
1985
	if (write_object)
1986
		ret = write_sha1_file(buf, size, type, sha1);
R
Rene Scharfe 已提交
1987 1988
	else
		ret = hash_sha1_file(buf, size, type, sha1);
1989 1990 1991 1992
	free(buf);
	return ret;
}

1993
int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, const char *type)
J
Junio C Hamano 已提交
1994 1995
{
	unsigned long size = st->st_size;
1996 1997
	void *buf;
	int ret;
J
Junio C Hamano 已提交
1998

1999
	buf = "";
J
Junio C Hamano 已提交
2000
	if (size)
2001
		buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
J
Junio C Hamano 已提交
2002 2003
	close(fd);

2004
	if (!type)
2005
		type = blob_type;
2006 2007
	if (write_object)
		ret = write_sha1_file(buf, size, type, sha1);
R
Rene Scharfe 已提交
2008 2009
	else
		ret = hash_sha1_file(buf, size, type, sha1);
2010 2011 2012
	if (size)
		munmap(buf, size);
	return ret;
J
Junio C Hamano 已提交
2013
}
2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037

int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object)
{
	int fd;
	char *target;

	switch (st->st_mode & S_IFMT) {
	case S_IFREG:
		fd = open(path, O_RDONLY);
		if (fd < 0)
			return error("open(\"%s\"): %s", path,
				     strerror(errno));
		if (index_fd(sha1, fd, st, write_object, NULL) < 0)
			return error("%s: failed to insert into database",
				     path);
		break;
	case S_IFLNK:
		target = xmalloc(st->st_size+1);
		if (readlink(path, target, st->st_size+1) != st->st_size) {
			char *errstr = strerror(errno);
			free(target);
			return error("readlink(\"%s\"): %s", path,
			             errstr);
		}
R
Rene Scharfe 已提交
2038 2039 2040
		if (!write_object)
			hash_sha1_file(target, st->st_size, blob_type, sha1);
		else if (write_sha1_file(target, st->st_size, blob_type, sha1))
2041 2042 2043 2044 2045 2046 2047 2048 2049
			return error("%s: failed to insert into database",
				     path);
		free(target);
		break;
	default:
		return error("%s: unsupported file type", path);
	}
	return 0;
}
2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070

int read_pack_header(int fd, struct pack_header *header)
{
	char *c = (char*)header;
	ssize_t remaining = sizeof(struct pack_header);
	do {
		ssize_t r = xread(fd, c, remaining);
		if (r <= 0)
			/* "eof before pack header was fully read" */
			return PH_ERROR_EOF;
		remaining -= r;
		c += r;
	} while (remaining > 0);
	if (header->hdr_signature != htonl(PACK_SIGNATURE))
		/* "protocol error (pack signature mismatch detected)" */
		return PH_ERROR_PACK_SIGNATURE;
	if (!pack_version_ok(header->hdr_version))
		/* "protocol error (pack version unsupported)" */
		return PH_ERROR_PROTOCOL;
	return 0;
}