sha1_file.c 52.0 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
static size_t pack_mapped;
410
struct packed_git *packed_git;
411

412 413 414
void pack_report()
{
	fprintf(stderr,
415 416 417
		"pack_report: getpagesize()            = %10" SZ_FMT "\n"
		"pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n"
		"pack_report: core.packedGitLimit      = %10" SZ_FMT "\n",
418
		(size_t) getpagesize(),
419 420 421 422 423 424
		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"
425 426
		"pack_report: pack_mapped              = "
			"%10" SZ_FMT " / %10" SZ_FMT "\n",
427 428 429 430 431 432
		pack_used_ctr,
		pack_mmap_calls,
		pack_open_windows, peak_pack_open_windows,
		pack_mapped, peak_pack_mapped);
}

433 434 435
static int check_packed_git_idx(const char *path,
	unsigned long *idx_size_,
	void **idx_map_)
436 437
{
	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 451 452 453
	if (idx_size < 4 * 256 + 20 + 20) {
		close(fd);
		return error("index file %s is too small", path);
	}
454
	idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0);
455 456 457
	close(fd);

	index = idx_map;
458 459
	*idx_map_ = idx_map;
	*idx_size_ = idx_size;
460

461 462 463 464
	/* 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.
	 */
465 466
	if (index[0] == htonl(PACK_IDX_SIGNATURE)) {
		munmap(idx_map, idx_size);
467 468 469 470
		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 475
	nr = 0;
	for (i = 0; i < 256; i++) {
		unsigned int n = ntohl(index[i]);
476 477
		if (n < nr) {
			munmap(idx_map, idx_size);
478
			return error("non-monotonic index %s", path);
479
		}
480 481 482 483 484 485 486 487 488 489
		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
	 */
490 491
	if (idx_size != 4*256 + nr * 24 + 20 + 20) {
		munmap(idx_map, idx_size);
492
		return error("wrong index file size in %s", path);
493
	}
494 495 496 497

	return 0;
}

498 499 500 501
static void scan_windows(struct packed_git *p,
	struct packed_git **lru_p,
	struct pack_window **lru_w,
	struct pack_window **lru_l)
502
{
503 504 505 506 507 508 509 510
	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;
511 512
			}
		}
513
		w_l = w;
514
	}
515 516 517 518 519 520 521 522 523 524 525
}

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);
526 527 528 529 530 531 532
	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;
533
			if (!lru_p->windows && lru_p != current) {
534 535 536 537 538
				close(lru_p->pack_fd);
				lru_p->pack_fd = -1;
			}
		}
		free(lru_w);
539
		pack_open_windows--;
540 541 542
		return 1;
	}
	return 0;
543 544
}

545 546 547 548 549 550 551
void release_pack_memory(size_t need)
{
	size_t cur = pack_mapped;
	while (need >= (cur - pack_mapped) && unuse_one_window(NULL))
		; /* nothing */
}

552
void unuse_pack(struct pack_window **w_cursor)
553
{
554 555 556 557 558
	struct pack_window *w = *w_cursor;
	if (w) {
		w->inuse_cnt--;
		*w_cursor = NULL;
	}
559 560
}

561 562 563 564 565
/*
 * Do not call this directly as this leaks p->pack_fd on error return;
 * call open_packed_git() instead.
 */
static int open_packed_git_1(struct packed_git *p)
566
{
567 568 569 570
	struct stat st;
	struct pack_header hdr;
	unsigned char sha1[20];
	unsigned char *idx_sha1;
571
	long fd_flag;
572 573 574

	p->pack_fd = open(p->pack_name, O_RDONLY);
	if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
575
		return -1;
576 577

	/* If we created the struct before we had the pack we lack size. */
578 579
	if (!p->pack_size) {
		if (!S_ISREG(st.st_mode))
580
			return error("packfile %s not a regular file", p->pack_name);
581
		p->pack_size = st.st_size;
582
	} else if (p->pack_size != st.st_size)
583
		return error("packfile %s size changed", p->pack_name);
584

585 586 587 588 589
	/* 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)
590
		return error("cannot determine file descriptor flags");
591 592
	fd_flag |= FD_CLOEXEC;
	if (fcntl(p->pack_fd, F_SETFD, fd_flag) == -1)
593
		return error("cannot set FD_CLOEXEC");
594

595
	/* Verify we recognize this pack file format. */
596
	if (read_in_full(p->pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
597
		return error("file %s is far too short to be a packfile", p->pack_name);
598
	if (hdr.hdr_signature != htonl(PACK_SIGNATURE))
599
		return error("file %s is not a GIT packfile", p->pack_name);
600
	if (!pack_version_ok(hdr.hdr_version))
601
		return error("packfile %s is version %u and not supported"
602 603 604 605 606
			" (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))
607
		return error("packfile %s claims to have %u objects"
608 609 610 611
			" 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)
612
		return error("end of packfile %s is unavailable", p->pack_name);
613
	if (read_in_full(p->pack_fd, sha1, sizeof(sha1)) != sizeof(sha1))
614
		return error("packfile %s signature is unavailable", p->pack_name);
615 616
	idx_sha1 = ((unsigned char *)p->index_base) + p->index_size - 40;
	if (hashcmp(sha1, idx_sha1))
617 618
		return error("packfile %s does not match index", p->pack_name);
	return 0;
619 620
}

621 622 623 624 625 626 627 628 629 630 631
static int open_packed_git(struct packed_git *p)
{
	if (!open_packed_git_1(p))
		return 0;
	if (p->pack_fd != -1) {
		close(p->pack_fd);
		p->pack_fd = -1;
	}
	return -1;
}

632 633 634 635 636 637 638 639 640 641 642 643 644
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);
}

645 646 647 648
unsigned char* use_pack(struct packed_git *p,
		struct pack_window **w_cursor,
		unsigned long offset,
		unsigned int *left)
649
{
650
	struct pack_window *win = *w_cursor;
651

652 653
	if (p->pack_fd == -1 && open_packed_git(p))
		die("packfile %s cannot be accessed", p->pack_name);
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670

	/* 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) {
671
			size_t window_align = packed_git_window_size / 2;
672
			win = xcalloc(1, sizeof(*win));
673
			win->offset = (offset / window_align) * window_align;
674 675 676 677
			win->len = p->pack_size - win->offset;
			if (win->len > packed_git_window_size)
				win->len = packed_git_window_size;
			pack_mapped += win->len;
678 679
			while (packed_git_limit < pack_mapped
				&& unuse_one_window(p))
680
				; /* nothing */
681
			win->base = xmmap(NULL, win->len,
682 683 684
				PROT_READ, MAP_PRIVATE,
				p->pack_fd, win->offset);
			if (win->base == MAP_FAILED)
685 686 687
				die("packfile %s cannot be mapped: %s",
					p->pack_name,
					strerror(errno));
688 689 690 691 692 693
			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;
694 695 696
			win->next = p->windows;
			p->windows = win;
		}
697
	}
698 699 700 701 702
	if (win != *w_cursor) {
		win->last_used = pack_used_ctr++;
		win->inuse_cnt++;
		*w_cursor = win;
	}
703
	offset -= win->offset;
704 705 706
	if (left)
		*left = win->len - offset;
	return win->base + offset;
707 708
}

709
struct packed_git *add_packed_git(char *path, int path_len, int local)
710 711 712 713 714
{
	struct stat st;
	struct packed_git *p;
	unsigned long idx_size;
	void *idx_map;
715
	unsigned char sha1[20];
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734

	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;
735
	p->windows = NULL;
736
	p->pack_fd = -1;
737
	p->pack_local = local;
P
Pavel Roskin 已提交
738
	if ((path_len > 44) && !get_sha1_hex(path + path_len - 44, sha1))
739
		hashcpy(p->sha1, sha1);
740 741 742
	return p;
}

743
struct packed_git *parse_pack_index(unsigned char *sha1)
744 745 746 747 748
{
	char *path = sha1_pack_index_name(sha1);
	return parse_pack_index_file(sha1, path);
}

749
struct packed_git *parse_pack_index_file(const unsigned char *sha1, char *idx_path)
750 751 752 753
{
	struct packed_git *p;
	unsigned long idx_size;
	void *idx_map;
754
	char *path;
755

756
	if (check_packed_git_idx(idx_path, &idx_size, &idx_map))
757 758 759 760 761 762 763 764 765 766
		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;
767
	p->windows = NULL;
768
	p->pack_fd = -1;
769
	hashcpy(p->sha1, sha1);
770 771 772 773 774 775 776 777 778
	return p;
}

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

779
static void prepare_packed_git_one(char *objdir, int local)
780 781 782 783 784 785 786 787 788
{
	char path[PATH_MAX];
	int len;
	DIR *dir;
	struct dirent *de;

	sprintf(path, "%s/pack", objdir);
	len = strlen(path);
	dir = opendir(path);
789
	if (!dir) {
J
Junio C Hamano 已提交
790
		if (errno != ENOENT)
791
			error("unable to open object pack directory: %s: %s",
J
Junio C Hamano 已提交
792
			      path, strerror(errno));
793
		return;
794
	}
795 796 797 798 799
	path[len++] = '/';
	while ((de = readdir(dir)) != NULL) {
		int namelen = strlen(de->d_name);
		struct packed_git *p;

800
		if (!has_extension(de->d_name, ".idx"))
801 802
			continue;

803
		/* Don't reopen a pack we already have. */
804
		strcpy(path + len, de->d_name);
805 806 807 808 809 810
		for (p = packed_git; p; p = p->next) {
			if (!memcmp(path, p->pack_name, len + namelen - 4))
				break;
		}
		if (p)
			continue;
811 812 813
		/* See if it really is a valid .idx file with corresponding
		 * .pack file that we can map.
		 */
814
		p = add_packed_git(path, len + namelen, local);
815 816
		if (!p)
			continue;
817
		install_packed_git(p);
818
	}
819
	closedir(dir);
820 821
}

822
static int prepare_packed_git_run_once = 0;
823
void prepare_packed_git(void)
824
{
825
	struct alternate_object_database *alt;
826

827
	if (prepare_packed_git_run_once)
828
		return;
829
	prepare_packed_git_one(get_object_directory(), 1);
830
	prepare_alt_odb();
831
	for (alt = alt_odb_list; alt; alt = alt->next) {
832
		alt->name[-1] = 0;
833
		prepare_packed_git_one(alt->base, 0);
834
		alt->name[-1] = '/';
835
	}
836 837 838
	prepare_packed_git_run_once = 1;
}

839
void reprepare_packed_git(void)
840 841 842
{
	prepare_packed_git_run_once = 0;
	prepare_packed_git();
843 844
}

845
int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type)
846 847
{
	unsigned char real_sha1[20];
848
	hash_sha1_file(map, size, type, real_sha1);
849
	return hashcmp(sha1, real_sha1) ? -1 : 0;
850 851
}

852
void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
853 854 855
{
	struct stat st;
	void *map;
856
	int fd;
857 858 859 860 861
	char *filename = find_sha1_file(sha1, &st);

	if (!filename) {
		return NULL;
	}
862

863
	fd = open(filename, O_RDONLY | sha1_file_open_flag);
864
	if (fd < 0) {
865 866 867 868 869 870 871 872 873 874 875
		/* 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;
		}

876 877 878
		/* If it failed once, it will probably fail again.
		 * Stop using O_NOATIME
		 */
879
		sha1_file_open_flag = 0;
880
	}
881
	map = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
882 883 884 885 886
	close(fd);
	*size = st.st_size;
	return map;
}

887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
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;
}

903
unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep)
904
{
905
	unsigned shift;
906 907
	unsigned char c;
	unsigned long size;
908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933
	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 */
934
	};
935
	enum object_type type;
936

937 938 939 940 941
	/* Get the data stream */
	memset(stream, 0, sizeof(*stream));
	stream->next_in = map;
	stream->avail_in = mapsize;
	stream->next_out = buffer;
942 943
	stream->avail_out = bufsiz;

944
	if (legacy_loose_object(map)) {
945 946 947 948
		inflateInit(stream);
		return inflate(stream, 0);
	}

949 950
	used = unpack_object_header_gently(map, mapsize, &type, &size);
	if (!used || !valid_loose_object_type[type])
951
		return -1;
952 953
	map += used;
	mapsize -= used;
954 955 956 957

	/* Set up the stream for the rest.. */
	stream->next_in = map;
	stream->avail_in = mapsize;
958
	inflateInit(stream);
959 960

	/* And generate the fake traditional header */
961
	stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
962
					 typename(type), size);
963
	return 0;
964 965
}

L
Linus Torvalds 已提交
966
static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size)
967 968
{
	int bytes = strlen(buffer) + 1;
969
	unsigned char *buf = xmalloc(1+size);
970
	unsigned long n;
971

972 973 974 975 976
	n = stream->total_out - bytes;
	if (n > size)
		n = size;
	memcpy(buf, (char *) buffer + bytes, n);
	bytes = n;
977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992
	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.
 */
993
static int parse_sha1_header(const char *hdr, unsigned long *sizep)
994
{
995
	char type[10];
996 997 998 999 1000 1001
	int i;
	unsigned long size;

	/*
	 * The type can be at most ten bytes (including the 
	 * terminating '\0' that we add), and is followed by
1002
	 * a space.
1003
	 */
1004
	i = 0;
1005 1006 1007 1008
	for (;;) {
		char c = *hdr++;
		if (c == ' ')
			break;
1009 1010
		type[i++] = c;
		if (i >= sizeof(type))
1011 1012
			return -1;
	}
1013
	type[i] = 0;
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035

	/*
	 * 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
	 */
1036
	return *hdr ? -1 : type_from_string(type);
1037 1038
}

1039
void * unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size)
1040
{
1041
	int ret;
1042
	z_stream stream;
1043
	char hdr[8192];
1044

1045
	ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
1046
	if (ret < Z_OK || (*type = parse_sha1_header(hdr, size)) < 0)
1047 1048
		return NULL;

1049
	return unpack_sha1_rest(&stream, hdr, *size);
1050 1051
}

1052
static unsigned long get_delta_base(struct packed_git *p,
1053
				    struct pack_window **w_curs,
1054
				    unsigned long *curpos,
1055
				    enum object_type type,
1056
				    unsigned long delta_obj_offset)
1057
{
1058
	unsigned char *base_info = use_pack(p, w_curs, *curpos, NULL);
1059 1060
	unsigned long base_offset;

1061 1062 1063 1064 1065 1066
	/* 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.
	 */
1067
	if (type == OBJ_OFS_DELTA) {
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
		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");
1081
		*curpos += used;
1082
	} else if (type == OBJ_REF_DELTA) {
1083 1084 1085 1086 1087
		/* 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));
1088
		*curpos += 20;
1089 1090
	} else
		die("I am totally screwed");
1091
	return base_offset;
1092 1093
}

J
Junio C Hamano 已提交
1094
/* forward declaration for a mutually recursive function */
N
Nicolas Pitre 已提交
1095
static int packed_object_info(struct packed_git *p, unsigned long offset,
1096
			      unsigned long *sizep);
J
Junio C Hamano 已提交
1097

N
Nicolas Pitre 已提交
1098
static int packed_delta_info(struct packed_git *p,
1099
			     struct pack_window **w_curs,
1100
			     unsigned long curpos,
1101
			     enum object_type type,
1102
			     unsigned long obj_offset,
N
Nicolas Pitre 已提交
1103
			     unsigned long *sizep)
1104
{
N
Nicolas Pitre 已提交
1105
	unsigned long base_offset;
J
Junio C Hamano 已提交
1106

1107 1108
	base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset);
	type = packed_object_info(p, base_offset, NULL);
J
Junio C Hamano 已提交
1109

1110 1111 1112 1113 1114 1115 1116
	/* 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.
	 */
	if (sizep) {
		const unsigned char *data;
1117
		unsigned char delta_head[20], *in;
1118 1119 1120 1121 1122 1123 1124 1125
		z_stream stream;
		int st;

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

		inflateInit(&stream);
1126
		do {
1127
			in = use_pack(p, w_curs, curpos, &stream.avail_in);
1128 1129
			stream.next_in = in;
			st = inflate(&stream, Z_FINISH);
1130
			curpos += stream.next_in - in;
1131 1132
		} while ((st == Z_OK || st == Z_BUF_ERROR)
			&& stream.total_out < sizeof(delta_head));
1133 1134 1135 1136 1137 1138 1139 1140 1141
		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;
1142 1143 1144

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

1146
		/* Read the result size */
1147
		*sizep = get_delta_hdr_size(&data, delta_head+sizeof(delta_head));
1148
	}
1149 1150

	return type;
1151 1152
}

1153 1154 1155 1156
static int unpack_object_header(struct packed_git *p,
				struct pack_window **w_curs,
				unsigned long *curpos,
				unsigned long *sizep)
1157
{
1158 1159
	unsigned char *base;
	unsigned int left;
1160
	unsigned long used;
1161
	enum object_type type;
1162

1163 1164
	/* use_pack() assures us we have [base, base + 20) available
	 * as a range that we can look at at.  (Its actually the hash
P
Pavel Roskin 已提交
1165
	 * size that is assured.)  With our object header encoding
1166 1167 1168
	 * the maximum deflated object size is 2^137, which is just
	 * insane, so we know won't exceed what we have been given.
	 */
1169 1170
	base = use_pack(p, w_curs, *curpos, &left);
	used = unpack_object_header_gently(base, left, &type, sizep);
1171 1172
	if (!used)
		die("object offset outside of pack file");
1173
	*curpos += used;
1174

1175
	return type;
1176 1177
}

1178 1179 1180 1181 1182 1183
const char *packed_object_info_detail(struct packed_git *p,
				      unsigned long obj_offset,
				      unsigned long *size,
				      unsigned long *store_size,
				      unsigned int *delta_chain_length,
				      unsigned char *base_sha1)
1184
{
1185
	struct pack_window *w_curs = NULL;
1186
	unsigned long curpos, dummy;
N
Nicolas Pitre 已提交
1187
	unsigned char *next_sha1;
1188
	enum object_type type;
1189

N
Nicolas Pitre 已提交
1190
	*delta_chain_length = 0;
1191
	curpos = obj_offset;
1192
	type = unpack_object_header(p, &w_curs, &curpos, size);
N
Nicolas Pitre 已提交
1193 1194

	for (;;) {
1195
		switch (type) {
N
Nicolas Pitre 已提交
1196
		default:
1197
			die("pack %s contains unknown object type %d",
1198
			    p->pack_name, type);
N
Nicolas Pitre 已提交
1199 1200 1201 1202 1203
		case OBJ_COMMIT:
		case OBJ_TREE:
		case OBJ_BLOB:
		case OBJ_TAG:
			*store_size = 0; /* notyet */
1204
			unuse_pack(&w_curs);
1205
			return typename(type);
1206
		case OBJ_OFS_DELTA:
1207
			obj_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
1208
			if (*delta_chain_length == 0) {
1209
				/* TODO: find base_sha1 as pointed by curpos */
1210
				hashclr(base_sha1);
1211 1212 1213
			}
			break;
		case OBJ_REF_DELTA:
1214
			next_sha1 = use_pack(p, &w_curs, curpos, NULL);
N
Nicolas Pitre 已提交
1215 1216
			if (*delta_chain_length == 0)
				hashcpy(base_sha1, next_sha1);
1217
			obj_offset = find_pack_entry_one(next_sha1, p);
N
Nicolas Pitre 已提交
1218 1219 1220
			break;
		}
		(*delta_chain_length)++;
1221
		curpos = obj_offset;
1222
		type = unpack_object_header(p, &w_curs, &curpos, &dummy);
1223 1224 1225
	}
}

1226
static int packed_object_info(struct packed_git *p, unsigned long obj_offset,
1227
			      unsigned long *sizep)
1228
{
1229
	struct pack_window *w_curs = NULL;
1230
	unsigned long size, curpos = obj_offset;
1231
	enum object_type type;
1232

1233
	type = unpack_object_header(p, &w_curs, &curpos, &size);
1234

1235
	switch (type) {
1236 1237
	case OBJ_OFS_DELTA:
	case OBJ_REF_DELTA:
1238 1239
		type = packed_delta_info(p, &w_curs, curpos,
					 type, obj_offset, sizep);
1240
		break;
1241 1242 1243 1244
	case OBJ_COMMIT:
	case OBJ_TREE:
	case OBJ_BLOB:
	case OBJ_TAG:
1245 1246
		if (sizep)
			*sizep = size;
1247
		break;
1248
	default:
1249
		die("pack %s contains unknown object type %d",
1250
		    p->pack_name, type);
1251
	}
1252
	unuse_pack(&w_curs);
1253
	return type;
1254 1255
}

1256
static void *unpack_compressed_entry(struct packed_git *p,
1257
				    struct pack_window **w_curs,
1258
				    unsigned long curpos,
1259
				    unsigned long size)
1260 1261 1262
{
	int st;
	z_stream stream;
1263
	unsigned char *buffer, *in;
1264 1265 1266 1267 1268 1269 1270 1271

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

	inflateInit(&stream);
1272
	do {
1273
		in = use_pack(p, w_curs, curpos, &stream.avail_in);
1274 1275
		stream.next_in = in;
		st = inflate(&stream, Z_FINISH);
1276
		curpos += stream.next_in - in;
1277
	} while (st == Z_OK || st == Z_BUF_ERROR);
1278 1279 1280 1281 1282 1283 1284 1285 1286
	inflateEnd(&stream);
	if ((st != Z_STREAM_END) || stream.total_out != size) {
		free(buffer);
		return NULL;
	}

	return buffer;
}

1287
static void *unpack_delta_entry(struct packed_git *p,
1288
				struct pack_window **w_curs,
1289
				unsigned long curpos,
1290
				unsigned long delta_size,
1291
				unsigned long obj_offset,
1292
				enum object_type *type,
1293
				unsigned long *sizep)
1294
{
1295
	void *delta_data, *result, *base;
1296
	unsigned long base_size, base_offset;
N
Nicolas Pitre 已提交
1297

1298
	base_offset = get_delta_base(p, w_curs, &curpos, *type, obj_offset);
1299
	base = unpack_entry(p, base_offset, type, &base_size);
1300
	if (!base)
N
Nicolas Pitre 已提交
1301 1302
		die("failed to read delta base object at %lu from %s",
		    base_offset, p->pack_name);
1303

1304
	delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size);
1305 1306
	result = patch_delta(base, base_size,
			     delta_data, delta_size,
1307
			     sizep);
1308 1309 1310 1311 1312 1313 1314
	if (!result)
		die("failed to apply delta");
	free(delta_data);
	free(base);
	return result;
}

1315
void *unpack_entry(struct packed_git *p, unsigned long obj_offset,
1316
		   enum object_type *type, unsigned long *sizep)
1317
{
1318
	struct pack_window *w_curs = NULL;
1319 1320
	unsigned long curpos = obj_offset;
	void *data;
1321

1322 1323
	*type = unpack_object_header(p, &w_curs, &curpos, sizep);
	switch (*type) {
1324 1325
	case OBJ_OFS_DELTA:
	case OBJ_REF_DELTA:
1326 1327
		data = unpack_delta_entry(p, &w_curs, curpos, *sizep,
					  obj_offset, type, sizep);
1328
		break;
1329 1330 1331 1332
	case OBJ_COMMIT:
	case OBJ_TREE:
	case OBJ_BLOB:
	case OBJ_TAG:
1333
		data = unpack_compressed_entry(p, &w_curs, curpos, *sizep);
1334
		break;
1335
	default:
1336
		die("unknown object type %i in %s", *type, p->pack_name);
1337
	}
1338
	unuse_pack(&w_curs);
1339
	return data;
1340 1341
}

1342 1343
int num_packed_objects(const struct packed_git *p)
{
1344
	/* See check_packed_git_idx() */
1345 1346 1347 1348 1349 1350 1351 1352 1353
	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;
1354
	hashcpy(sha1, (unsigned char *) index + (24 * n) + 4);
1355 1356 1357
	return 0;
}

N
Nicolas Pitre 已提交
1358 1359
unsigned long find_pack_entry_one(const unsigned char *sha1,
				  struct packed_git *p)
1360
{
1361
	uint32_t *level1_ofs = p->index_base;
1362 1363 1364 1365 1366 1367
	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;
1368
		int cmp = hashcmp((unsigned char *)index + (24 * mi) + 4, sha1);
N
Nicolas Pitre 已提交
1369
		if (!cmp)
1370
			return ntohl(*((uint32_t *)((char *)index + (24 * mi))));
1371 1372 1373 1374 1375 1376 1377 1378
		if (cmp > 0)
			hi = mi;
		else
			lo = mi+1;
	} while (lo < hi);
	return 0;
}

1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396
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;
}

1397
static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed)
1398 1399
{
	struct packed_git *p;
N
Nicolas Pitre 已提交
1400 1401
	unsigned long offset;

1402 1403 1404
	prepare_packed_git();

	for (p = packed_git; p; p = p->next) {
1405 1406 1407
		if (ignore_packed) {
			const char **ig;
			for (ig = ignore_packed; *ig; ig++)
1408
				if (!matches_pack_name(p, *ig))
1409 1410 1411 1412
					break;
			if (*ig)
				continue;
		}
N
Nicolas Pitre 已提交
1413 1414
		offset = find_pack_entry_one(sha1, p);
		if (offset) {
1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426
			/*
			 * We are about to tell the caller where they can
			 * locate the requested object.  We better make
			 * sure the packfile is still here and can be
			 * accessed before supplying that answer, as
			 * it may have been deleted since the index
			 * was loaded!
			 */
			if (p->pack_fd == -1 && open_packed_git(p)) {
				error("packfile %s cannot be accessed", p->pack_name);
				continue;
			}
N
Nicolas Pitre 已提交
1427 1428 1429
			e->offset = offset;
			e->p = p;
			hashcpy(e->sha1, sha1);
1430
			return 1;
N
Nicolas Pitre 已提交
1431
		}
1432 1433 1434 1435
	}
	return 0;
}

1436 1437 1438 1439 1440 1441
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 已提交
1442
		if (find_pack_entry_one(sha1, p))
1443 1444 1445
			return p;
	}
	return NULL;
1446

1447 1448
}

1449
static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *sizep)
1450
{
1451
	int status;
1452 1453 1454
	unsigned long mapsize, size;
	void *map;
	z_stream stream;
N
Nicolas Pitre 已提交
1455
	char hdr[32];
1456

1457
	map = map_sha1_file(sha1, &mapsize);
1458 1459
	if (!map)
		return error("unable to find %s", sha1_to_hex(sha1));
1460 1461 1462
	if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0)
		status = error("unable to unpack %s header",
			       sha1_to_hex(sha1));
1463
	else if ((status = parse_sha1_header(hdr, &size)) < 0)
1464
		status = error("unable to parse %s header", sha1_to_hex(sha1));
1465 1466
	else if (sizep)
		*sizep = size;
1467 1468 1469 1470 1471
	inflateEnd(&stream);
	munmap(map, mapsize);
	return status;
}

1472
int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
1473 1474 1475 1476 1477 1478
{
	struct pack_entry e;

	if (!find_pack_entry(sha1, &e, NULL)) {
		reprepare_packed_git();
		if (!find_pack_entry(sha1, &e, NULL))
1479
			return sha1_loose_object_info(sha1, sizep);
1480
	}
1481
	return packed_object_info(e.p, e.offset, sizep);
1482 1483
}

1484 1485
static void *read_packed_sha1(const unsigned char *sha1,
			      enum object_type *type, unsigned long *size)
1486 1487 1488
{
	struct pack_entry e;

1489
	if (!find_pack_entry(sha1, &e, NULL))
1490
		return NULL;
1491 1492
	else
		return unpack_entry(e.p, e.offset, type, size);
1493 1494
}

1495 1496 1497 1498 1499 1500 1501 1502
/*
 * This is meant to hold a *small* number of objects that you would
 * want read_sha1_file() to be able to return, but yet you do not want
 * to write them into the object store (e.g. a browse-only
 * application).
 */
static struct cached_object {
	unsigned char sha1[20];
1503
	enum object_type type;
1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520
	void *buf;
	unsigned long size;
} *cached_objects;
static int cached_object_nr, cached_object_alloc;

static struct cached_object *find_cached_object(const unsigned char *sha1)
{
	int i;
	struct cached_object *co = cached_objects;

	for (i = 0; i < cached_object_nr; i++, co++) {
		if (!hashcmp(co->sha1, sha1))
			return co;
	}
	return NULL;
}

1521 1522
int pretend_sha1_file(void *buf, unsigned long len, enum object_type type,
		      unsigned char *sha1)
1523 1524 1525
{
	struct cached_object *co;

1526
	hash_sha1_file(buf, len, typename(type), sha1);
1527 1528 1529 1530 1531 1532 1533 1534 1535 1536
	if (has_sha1_file(sha1) || find_cached_object(sha1))
		return 0;
	if (cached_object_alloc <= cached_object_nr) {
		cached_object_alloc = alloc_nr(cached_object_alloc);
		cached_objects = xrealloc(cached_objects,
					  sizeof(*cached_objects) *
					  cached_object_alloc);
	}
	co = &cached_objects[cached_object_nr++];
	co->size = len;
1537
	co->type = type;
J
Junio C Hamano 已提交
1538 1539
	co->buf = xmalloc(len);
	memcpy(co->buf, buf, len);
1540 1541 1542 1543
	hashcpy(co->sha1, sha1);
	return 0;
}

1544 1545
void *read_sha1_file(const unsigned char *sha1, enum object_type *type,
		     unsigned long *size)
1546 1547 1548
{
	unsigned long mapsize;
	void *map, *buf;
1549 1550 1551 1552 1553 1554 1555
	struct cached_object *co;

	co = find_cached_object(sha1);
	if (co) {
		buf = xmalloc(co->size + 1);
		memcpy(buf, co->buf, co->size);
		((char*)buf)[co->size] = 0;
1556
		*type = co->type;
1557 1558 1559
		*size = co->size;
		return buf;
	}
1560

1561 1562 1563
	buf = read_packed_sha1(sha1, type, size);
	if (buf)
		return buf;
1564
	map = map_sha1_file(sha1, &mapsize);
1565 1566 1567 1568 1569
	if (map) {
		buf = unpack_sha1_file(map, mapsize, type, size);
		munmap(map, mapsize);
		return buf;
	}
1570
	reprepare_packed_git();
1571
	return read_packed_sha1(sha1, type, size);
1572 1573
}

1574
void *read_object_with_reference(const unsigned char *sha1,
1575
				 const char *required_type_name,
1576 1577
				 unsigned long *size,
				 unsigned char *actual_sha1_return)
1578
{
1579
	enum object_type type, required_type;
1580 1581
	void *buffer;
	unsigned long isize;
1582
	unsigned char actual_sha1[20];
1583

1584
	required_type = type_from_string(required_type_name);
1585
	hashcpy(actual_sha1, sha1);
1586 1587 1588
	while (1) {
		int ref_length = -1;
		const char *ref_type = NULL;
1589

1590
		buffer = read_sha1_file(actual_sha1, &type, &isize);
1591 1592
		if (!buffer)
			return NULL;
1593
		if (type == required_type) {
1594 1595
			*size = isize;
			if (actual_sha1_return)
1596
				hashcpy(actual_sha1_return, actual_sha1);
1597 1598 1599
			return buffer;
		}
		/* Handle references */
1600
		else if (type == OBJ_COMMIT)
1601
			ref_type = "tree ";
1602
		else if (type == OBJ_TAG)
1603 1604 1605 1606 1607 1608
			ref_type = "object ";
		else {
			free(buffer);
			return NULL;
		}
		ref_length = strlen(ref_type);
1609

1610
		if (memcmp(buffer, ref_type, ref_length) ||
1611
		    get_sha1_hex((char *) buffer + ref_length, actual_sha1)) {
1612 1613 1614
			free(buffer);
			return NULL;
		}
1615
		free(buffer);
1616 1617
		/* Now we have the ID of the referred-to object in
		 * actual_sha1.  Check again. */
1618 1619 1620
	}
}

R
Rene Scharfe 已提交
1621 1622
static void write_sha1_file_prepare(void *buf, unsigned long len,
                                    const char *type, unsigned char *sha1,
N
Nicolas Pitre 已提交
1623
                                    char *hdr, int *hdrlen)
1624 1625 1626 1627
{
	SHA_CTX c;

	/* Generate the header */
N
Nicolas Pitre 已提交
1628
	*hdrlen = sprintf(hdr, "%s %lu", type, len)+1;
1629 1630 1631 1632 1633 1634 1635 1636

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

1637 1638 1639 1640 1641 1642
/*
 * 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.
 */
1643
static int link_temp_to_file(const char *tmpfile, const char *filename)
1644 1645
{
	int ret;
S
Shawn Pearce 已提交
1646
	char *dir;
1647 1648 1649 1650 1651

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

	/*
S
Shawn Pearce 已提交
1652
	 * Try to mkdir the last path component if that failed.
1653 1654 1655 1656 1657 1658
	 *
	 * Re-try the "link()" regardless of whether the mkdir
	 * succeeds, since a race might mean that somebody
	 * else succeeded.
	 */
	ret = errno;
S
Shawn Pearce 已提交
1659 1660 1661
	dir = strrchr(filename, '/');
	if (dir) {
		*dir = 0;
1662
		if (!mkdir(filename, 0777) && adjust_shared_perm(filename)) {
1663
			*dir = '/';
S
Shawn Pearce 已提交
1664
			return -2;
1665
		}
S
Shawn Pearce 已提交
1666 1667 1668 1669
		*dir = '/';
		if (!link(tmpfile, filename))
			return 0;
		ret = errno;
1670 1671 1672 1673 1674 1675 1676
	}
	return ret;
}

/*
 * Move the just written object into its final resting place
 */
1677
int move_temp_to_file(const char *tmpfile, const char *filename)
1678 1679
{
	int ret = link_temp_to_file(tmpfile, filename);
1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693

	/*
	 * 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))
1694
			return 0;
1695
		ret = errno;
1696 1697 1698 1699
	}
	unlink(tmpfile);
	if (ret) {
		if (ret != EEXIST) {
1700
			return error("unable to write sha1 filename %s: %s\n", filename, strerror(ret));
1701 1702 1703 1704 1705 1706 1707
		}
		/* FIXME!!! Collision check here ? */
	}

	return 0;
}

L
Linus Torvalds 已提交
1708 1709
static int write_buffer(int fd, const void *buf, size_t len)
{
L
Linus Torvalds 已提交
1710
	if (write_in_full(fd, buf, len) < 0)
1711
		return error("file write error (%s)", strerror(errno));
L
Linus Torvalds 已提交
1712 1713 1714
	return 0;
}

1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734
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)
{
N
Nicolas Pitre 已提交
1735
	int obj_type, hdrlen;
1736 1737 1738 1739 1740 1741

	if (use_legacy_headers) {
		while (deflate(stream, 0) == Z_OK)
			/* nothing */;
		return;
	}
1742
	obj_type = type_from_string(type);
N
Nicolas Pitre 已提交
1743 1744 1745 1746
	hdrlen = write_binary_header(stream->next_out, obj_type, len);
	stream->total_out = hdrlen;
	stream->next_out += hdrlen;
	stream->avail_out -= hdrlen;
1747 1748
}

R
Rene Scharfe 已提交
1749 1750 1751
int hash_sha1_file(void *buf, unsigned long len, const char *type,
                   unsigned char *sha1)
{
N
Nicolas Pitre 已提交
1752
	char hdr[32];
R
Rene Scharfe 已提交
1753 1754 1755 1756 1757
	int hdrlen;
	write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
	return 0;
}

1758
int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
1759 1760
{
	int size;
1761
	unsigned char *compressed;
1762 1763
	z_stream stream;
	unsigned char sha1[20];
1764
	char *filename;
1765
	static char tmpfile[PATH_MAX];
N
Nicolas Pitre 已提交
1766
	char hdr[32];
1767
	int fd, hdrlen;
1768

1769 1770 1771
	/* Normally if we have it in the pack then we do not bother writing
	 * it out into .git/objects/??/?{38} file.
	 */
R
Rene Scharfe 已提交
1772 1773
	write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
	filename = sha1_file_name(sha1);
1774
	if (returnsha1)
1775
		hashcpy(returnsha1, sha1);
1776 1777
	if (has_sha1_file(sha1))
		return 0;
1778 1779
	fd = open(filename, O_RDONLY);
	if (fd >= 0) {
1780
		/*
1781 1782
		 * FIXME!!! We might do collision checking here, but we'd
		 * need to uncompress the old file and check it. Later.
1783
		 */
1784
		close(fd);
1785 1786 1787
		return 0;
	}

1788
	if (errno != ENOENT) {
1789
		return error("sha1 file %s: %s\n", filename, strerror(errno));
1790 1791 1792
	}

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

1794 1795
	fd = mkstemp(tmpfile);
	if (fd < 0) {
1796 1797 1798 1799
		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));
1800 1801
	}

1802 1803
	/* Set it up */
	memset(&stream, 0, sizeof(stream));
1804
	deflateInit(&stream, zlib_compression_level);
1805
	size = 8 + deflateBound(&stream, len+hdrlen);
1806
	compressed = xmalloc(size);
1807 1808 1809 1810

	/* Compress it */
	stream.next_out = compressed;
	stream.avail_out = size;
1811 1812

	/* First header.. */
N
Nicolas Pitre 已提交
1813
	stream.next_in = (unsigned char *)hdr;
1814
	stream.avail_in = hdrlen;
1815
	setup_object_header(&stream, type, len);
1816 1817 1818 1819

	/* Then the data itself.. */
	stream.next_in = buf;
	stream.avail_in = len;
1820 1821 1822 1823 1824
	while (deflate(&stream, Z_FINISH) == Z_OK)
		/* nothing */;
	deflateEnd(&stream);
	size = stream.total_out;

L
Linus Torvalds 已提交
1825 1826
	if (write_buffer(fd, compressed, size) < 0)
		die("unable to write sha1 file");
1827
	fchmod(fd, 0444);
1828
	close(fd);
1829
	free(compressed);
1830

1831
	return move_temp_to_file(tmpfile, filename);
1832
}
1833

L
Linus Torvalds 已提交
1834 1835 1836 1837 1838
/*
 * 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 已提交
1839
{
L
Linus Torvalds 已提交
1840
	size_t size;
D
Daniel Barkalow 已提交
1841
	z_stream stream;
L
Linus Torvalds 已提交
1842 1843
	unsigned char *unpacked;
	unsigned long len;
1844
	enum object_type type;
N
Nicolas Pitre 已提交
1845
	char hdr[32];
L
Linus Torvalds 已提交
1846 1847
	int hdrlen;
	void *buf;
1848

1849
	/* need to unpack and recompress it by itself */
1850
	unpacked = read_packed_sha1(sha1, &type, &len);
1851 1852
	if (!unpacked)
		error("cannot read sha1_file for %s", sha1_to_hex(sha1));
D
Daniel Barkalow 已提交
1853

1854
	hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1;
D
Daniel Barkalow 已提交
1855

L
Linus Torvalds 已提交
1856 1857
	/* Set it up */
	memset(&stream, 0, sizeof(stream));
1858
	deflateInit(&stream, zlib_compression_level);
L
Linus Torvalds 已提交
1859 1860
	size = deflateBound(&stream, len + hdrlen);
	buf = xmalloc(size);
D
Daniel Barkalow 已提交
1861

L
Linus Torvalds 已提交
1862 1863 1864
	/* Compress it */
	stream.next_out = buf;
	stream.avail_out = size;
D
Daniel Barkalow 已提交
1865

L
Linus Torvalds 已提交
1866 1867 1868 1869 1870
	/* First header.. */
	stream.next_in = (void *)hdr;
	stream.avail_in = hdrlen;
	while (deflate(&stream, 0) == Z_OK)
		/* nothing */;
1871

L
Linus Torvalds 已提交
1872 1873 1874 1875 1876 1877 1878
	/* Then the data itself.. */
	stream.next_in = unpacked;
	stream.avail_in = len;
	while (deflate(&stream, Z_FINISH) == Z_OK)
		/* nothing */;
	deflateEnd(&stream);
	free(unpacked);
1879

L
Linus Torvalds 已提交
1880 1881 1882 1883 1884 1885 1886 1887
	*objsize = stream.total_out;
	return buf;
}

int write_sha1_to_fd(int fd, const unsigned char *sha1)
{
	int retval;
	unsigned long objsize;
1888
	void *buf = map_sha1_file(sha1, &objsize);
L
Linus Torvalds 已提交
1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899

	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 已提交
1900 1901
}

1902 1903
int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
		       size_t bufsize, size_t *bufposn)
1904
{
1905
	char tmpfile[PATH_MAX];
1906 1907 1908
	int local;
	z_stream stream;
	unsigned char real_sha1[20];
1909
	unsigned char discard[4096];
1910 1911 1912
	int ret;
	SHA_CTX c;

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

1915
	local = mkstemp(tmpfile);
1916 1917 1918 1919 1920 1921
	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));
	}
1922 1923 1924 1925 1926 1927 1928 1929 1930

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

	inflateInit(&stream);

	SHA1_Init(&c);

	do {
		ssize_t size;
1931 1932
		if (*bufposn) {
			stream.avail_in = *bufposn;
P
Pavel Roskin 已提交
1933
			stream.next_in = (unsigned char *) buffer;
1934 1935 1936 1937 1938 1939 1940
			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 已提交
1941 1942
			if (write_buffer(local, buffer, *bufposn - stream.avail_in) < 0)
				die("unable to write sha1 file");
1943 1944 1945 1946 1947 1948
			memmove(buffer, buffer + *bufposn - stream.avail_in,
				stream.avail_in);
			*bufposn = stream.avail_in;
			if (ret != Z_OK)
				break;
		}
1949
		size = xread(fd, buffer + *bufposn, bufsize - *bufposn);
1950 1951
		if (size <= 0) {
			close(local);
1952
			unlink(tmpfile);
1953 1954 1955 1956 1957
			if (!size)
				return error("Connection closed?");
			perror("Reading from connection");
			return -1;
		}
1958 1959
		*bufposn += size;
	} while (1);
1960 1961 1962 1963 1964
	inflateEnd(&stream);

	close(local);
	SHA1_Final(real_sha1, &c);
	if (ret != Z_STREAM_END) {
1965
		unlink(tmpfile);
1966 1967
		return error("File %s corrupted", sha1_to_hex(sha1));
	}
1968
	if (hashcmp(sha1, real_sha1)) {
1969
		unlink(tmpfile);
1970
		return error("File %s has bad hash", sha1_to_hex(sha1));
1971
	}
1972 1973

	return move_temp_to_file(tmpfile, sha1_file_name(sha1));
1974 1975
}

1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991
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;
}

1992
int has_sha1_pack(const unsigned char *sha1, const char **ignore_packed)
1993 1994
{
	struct pack_entry e;
1995
	return find_pack_entry(sha1, &e, ignore_packed);
1996 1997
}

1998 1999 2000
int has_sha1_file(const unsigned char *sha1)
{
	struct stat st;
2001 2002
	struct pack_entry e;

2003
	if (find_pack_entry(sha1, &e, NULL))
2004
		return 1;
2005
	return find_sha1_file(sha1, &st) ? 1 : 0;
2006
}
J
Junio C Hamano 已提交
2007

2008 2009
/*
 * reads from fd as long as possible into a supplied buffer of size bytes.
2010
 * If necessary the buffer's size is increased using realloc()
2011 2012 2013 2014 2015 2016 2017
 *
 * 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)
2018
{
2019 2020 2021
	char* buf = *return_buf;
	unsigned long size = *return_size;
	int iret;
2022
	unsigned long off = 0;
2023

2024
	do {
2025
		iret = xread(fd, buf + off, size - off);
2026 2027 2028 2029
		if (iret > 0) {
			off += iret;
			if (off == size) {
				size *= 2;
J
Jonas Fonseca 已提交
2030
				buf = xrealloc(buf, size);
2031 2032 2033
			}
		}
	} while (iret > 0);
2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045

	*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 已提交
2046
	char *buf = xmalloc(size);
2047 2048 2049
	int ret;

	if (read_pipe(fd, &buf, &size)) {
2050 2051 2052
		free(buf);
		return -1;
	}
2053

2054
	if (!type)
2055
		type = blob_type;
2056
	if (write_object)
2057
		ret = write_sha1_file(buf, size, type, sha1);
R
Rene Scharfe 已提交
2058 2059
	else
		ret = hash_sha1_file(buf, size, type, sha1);
2060 2061 2062 2063
	free(buf);
	return ret;
}

2064
int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,
2065
	     enum object_type type, const char *path)
J
Junio C Hamano 已提交
2066 2067
{
	unsigned long size = st->st_size;
2068
	void *buf;
L
Linus Torvalds 已提交
2069
	int ret, re_allocated = 0;
J
Junio C Hamano 已提交
2070

2071
	buf = "";
J
Junio C Hamano 已提交
2072
	if (size)
2073
		buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
J
Junio C Hamano 已提交
2074 2075
	close(fd);

2076
	if (!type)
2077
		type = OBJ_BLOB;
L
Linus Torvalds 已提交
2078 2079 2080 2081

	/*
	 * Convert blobs to git internal format
	 */
2082
	if ((type == OBJ_BLOB) && S_ISREG(st->st_mode)) {
L
Linus Torvalds 已提交
2083 2084
		unsigned long nsize = size;
		char *nbuf = buf;
2085
		if (convert_to_git(path, &nbuf, &nsize)) {
L
Linus Torvalds 已提交
2086 2087 2088 2089 2090 2091 2092 2093
			if (size)
				munmap(buf, size);
			size = nsize;
			buf = nbuf;
			re_allocated = 1;
		}
	}

2094
	if (write_object)
2095
		ret = write_sha1_file(buf, size, typename(type), sha1);
R
Rene Scharfe 已提交
2096
	else
2097
		ret = hash_sha1_file(buf, size, typename(type), sha1);
L
Linus Torvalds 已提交
2098 2099 2100 2101
	if (re_allocated) {
		free(buf);
		return ret;
	}
2102 2103 2104
	if (size)
		munmap(buf, size);
	return ret;
J
Junio C Hamano 已提交
2105
}
2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117

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));
2118
		if (index_fd(sha1, fd, st, write_object, OBJ_BLOB, path) < 0)
2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129
			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 已提交
2130 2131 2132
		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))
2133 2134 2135 2136 2137 2138 2139 2140 2141
			return error("%s: failed to insert into database",
				     path);
		free(target);
		break;
	default:
		return error("%s: unsupported file type", path);
	}
	return 0;
}
2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162

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