]> git.ipfire.org Git - thirdparty/git.git/blame - sha1_file.c
Merge branch 'fixes'
[thirdparty/git.git] / sha1_file.c
CommitLineData
0fcfd160
LT
1/*
2 * GIT - The information manager from hell
3 *
4 * Copyright (C) Linus Torvalds, 2005
5 *
6 * This handles basic git sha1 object files - packing, unpacking,
7 * creation etc.
8 */
1f688557
JH
9#include <sys/types.h>
10#include <dirent.h>
0fcfd160 11#include "cache.h"
1f688557 12#include "delta.h"
a733cb60 13#include "pack.h"
0fcfd160 14
144bde78
LT
15#ifndef O_NOATIME
16#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
17#define O_NOATIME 01000000
18#else
19#define O_NOATIME 0
20#endif
21#endif
22
88cd621d
JH
23const unsigned char null_sha1[20] = { 0, };
24
144bde78
LT
25static unsigned int sha1_file_open_flag = O_NOATIME;
26
0fcfd160
LT
27static unsigned hexval(char c)
28{
29 if (c >= '0' && c <= '9')
30 return c - '0';
31 if (c >= 'a' && c <= 'f')
32 return c - 'a' + 10;
33 if (c >= 'A' && c <= 'F')
34 return c - 'A' + 10;
35 return ~0;
36}
37
38int get_sha1_hex(const char *hex, unsigned char *sha1)
39{
40 int i;
41 for (i = 0; i < 20; i++) {
42 unsigned int val = (hexval(hex[0]) << 4) | hexval(hex[1]);
43 if (val & ~0xff)
44 return -1;
45 *sha1++ = val;
46 hex += 2;
47 }
48 return 0;
49}
50
b2cb9425
JH
51int safe_create_leading_directories(char *path)
52{
53 char *pos = path;
54
55 while (pos) {
56 pos = strchr(pos, '/');
57 if (!pos)
58 break;
59 *pos = 0;
60 if (mkdir(path, 0777) < 0)
61 if (errno != EEXIST) {
62 *pos = '/';
63 return -1;
64 }
65 *pos++ = '/';
66 }
67 return 0;
68}
723c31fe 69
0fcfd160
LT
70char * sha1_to_hex(const unsigned char *sha1)
71{
72 static char buffer[50];
73 static const char hex[] = "0123456789abcdef";
74 char *buf = buffer;
75 int i;
76
77 for (i = 0; i < 20; i++) {
78 unsigned int val = *sha1++;
79 *buf++ = hex[val >> 4];
80 *buf++ = hex[val & 0xf];
81 }
82 return buffer;
83}
84
ace1534d
JH
85static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
86{
87 int i;
88 for (i = 0; i < 20; i++) {
89 static char hex[] = "0123456789abcdef";
90 unsigned int val = sha1[i];
91 char *pos = pathbuf + i*2 + (i > 0);
92 *pos++ = hex[val >> 4];
93 *pos = hex[val & 0xf];
94 }
95}
96
0fcfd160
LT
97/*
98 * NOTE! This returns a statically allocated buffer, so you have to be
99 * careful about using it. Do a "strdup()" if you need to save the
100 * filename.
ace1534d
JH
101 *
102 * Also note that this returns the location for creating. Reading
103 * SHA1 file can happen from any alternate directory listed in the
d19938ab 104 * DB_ENVIRONMENT environment variable if it is not found in
ace1534d 105 * the primary object database.
0fcfd160
LT
106 */
107char *sha1_file_name(const unsigned char *sha1)
108{
0fcfd160
LT
109 static char *name, *base;
110
111 if (!base) {
d19938ab 112 const char *sha1_file_directory = get_object_directory();
0fcfd160 113 int len = strlen(sha1_file_directory);
812666c8 114 base = xmalloc(len + 60);
0fcfd160
LT
115 memcpy(base, sha1_file_directory, len);
116 memset(base+len, 0, 60);
117 base[len] = '/';
118 base[len+3] = '/';
119 name = base + len + 1;
120 }
ace1534d 121 fill_sha1_path(name, sha1);
0fcfd160
LT
122 return base;
123}
124
bf592c50
DB
125char *sha1_pack_name(const unsigned char *sha1)
126{
127 static const char hex[] = "0123456789abcdef";
128 static char *name, *base, *buf;
129 int i;
130
131 if (!base) {
132 const char *sha1_file_directory = get_object_directory();
133 int len = strlen(sha1_file_directory);
134 base = xmalloc(len + 60);
135 sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.pack", sha1_file_directory);
136 name = base + len + 11;
137 }
138
139 buf = name;
140
141 for (i = 0; i < 20; i++) {
142 unsigned int val = *sha1++;
143 *buf++ = hex[val >> 4];
144 *buf++ = hex[val & 0xf];
145 }
146
147 return base;
148}
149
150char *sha1_pack_index_name(const unsigned char *sha1)
151{
152 static const char hex[] = "0123456789abcdef";
153 static char *name, *base, *buf;
154 int i;
155
156 if (!base) {
157 const char *sha1_file_directory = get_object_directory();
158 int len = strlen(sha1_file_directory);
159 base = xmalloc(len + 60);
160 sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.idx", sha1_file_directory);
161 name = base + len + 11;
162 }
163
164 buf = name;
165
166 for (i = 0; i < 20; i++) {
167 unsigned int val = *sha1++;
168 *buf++ = hex[val >> 4];
169 *buf++ = hex[val & 0xf];
170 }
171
172 return base;
173}
174
d5a63b99
JH
175struct alternate_object_database *alt_odb_list;
176static struct alternate_object_database **alt_odb_tail;
ace1534d 177
ddd5d056
JH
178/*
179 * Prepare alternate object database registry.
d5a63b99
JH
180 *
181 * The variable alt_odb_list points at the list of struct
182 * alternate_object_database. The elements on this list come from
183 * non-empty elements from colon separated ALTERNATE_DB_ENVIRONMENT
184 * environment variable, and $GIT_OBJECT_DIRECTORY/info/alternates,
185 * whose contents is exactly in the same format as that environment
186 * variable. Its base points at a statically allocated buffer that
187 * contains "/the/directory/corresponding/to/.git/objects/...", while
188 * its name points just after the slash at the end of ".git/objects/"
189 * in the example above, and has enough space to hold 40-byte hex
190 * SHA1, an extra slash for the first level indirection, and the
191 * terminating NUL.
ddd5d056 192 */
ccfd3e99
JH
193static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
194 const char *relative_base)
ace1534d 195{
ace1534d 196 const char *cp, *last;
d5a63b99 197 struct alternate_object_database *ent;
ccfd3e99 198 int base_len = -1;
d5a63b99
JH
199
200 last = alt;
9577e7e3
JH
201 while (last < ep) {
202 cp = last;
203 if (cp < ep && *cp == '#') {
204 while (cp < ep && *cp != sep)
205 cp++;
206 last = cp + 1;
207 continue;
208 }
209 for ( ; cp < ep && *cp != sep; cp++)
d5a63b99
JH
210 ;
211 if (last != cp) {
212 /* 43 = 40-byte + 2 '/' + terminating NUL */
213 int pfxlen = cp - last;
214 int entlen = pfxlen + 43;
215
ccfd3e99
JH
216 if (*last != '/' && relative_base) {
217 /* Relative alt-odb */
218 if (base_len < 0)
219 base_len = strlen(relative_base) + 1;
220 entlen += base_len;
221 pfxlen += base_len;
222 }
d5a63b99
JH
223 ent = xmalloc(sizeof(*ent) + entlen);
224 *alt_odb_tail = ent;
225 alt_odb_tail = &(ent->next);
226 ent->next = NULL;
ccfd3e99
JH
227 if (*last != '/' && relative_base) {
228 memcpy(ent->base, relative_base, base_len - 1);
229 ent->base[base_len - 1] = '/';
230 memcpy(ent->base + base_len,
231 last, cp - last);
232 }
233 else
234 memcpy(ent->base, last, pfxlen);
d5a63b99
JH
235 ent->name = ent->base + pfxlen + 1;
236 ent->base[pfxlen] = ent->base[pfxlen + 3] = '/';
237 ent->base[entlen-1] = 0;
238 }
9577e7e3 239 while (cp < ep && *cp == sep)
d5a63b99
JH
240 cp++;
241 last = cp;
9577e7e3 242 }
d5a63b99
JH
243}
244
245void prepare_alt_odb(void)
246{
247 char path[PATH_MAX];
9577e7e3 248 char *map;
d5a63b99
JH
249 int fd;
250 struct stat st;
c7c81b3a
JR
251 char *alt;
252
a9ab586a 253 alt = getenv(ALTERNATE_DB_ENVIRONMENT);
c7c81b3a 254 if (!alt) alt = "";
ace1534d 255
d5a63b99
JH
256 if (alt_odb_tail)
257 return;
258 alt_odb_tail = &alt_odb_list;
ccfd3e99 259 link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL);
d5a63b99 260
ccfd3e99 261 sprintf(path, "%s/info/alternates", get_object_directory());
d5a63b99
JH
262 fd = open(path, O_RDONLY);
263 if (fd < 0)
264 return;
265 if (fstat(fd, &st) || (st.st_size == 0)) {
266 close(fd);
9a217f2a 267 return;
ace1534d 268 }
d5a63b99
JH
269 map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
270 close(fd);
271 if (map == MAP_FAILED)
272 return;
273
ccfd3e99
JH
274 link_alt_odb_entries(map, map + st.st_size, '\n',
275 get_object_directory());
d5a63b99 276 munmap(map, st.st_size);
ace1534d
JH
277}
278
279static char *find_sha1_file(const unsigned char *sha1, struct stat *st)
280{
ace1534d 281 char *name = sha1_file_name(sha1);
d5a63b99 282 struct alternate_object_database *alt;
ace1534d
JH
283
284 if (!stat(name, st))
285 return name;
9a217f2a 286 prepare_alt_odb();
d5a63b99
JH
287 for (alt = alt_odb_list; alt; alt = alt->next) {
288 name = alt->name;
ace1534d 289 fill_sha1_path(name, sha1);
d5a63b99
JH
290 if (!stat(alt->base, st))
291 return alt->base;
ace1534d
JH
292 }
293 return NULL;
294}
295
1f688557
JH
296#define PACK_MAX_SZ (1<<26)
297static int pack_used_ctr;
298static unsigned long pack_mapped;
9a217f2a 299struct packed_git *packed_git;
1f688557 300
1f688557
JH
301static int check_packed_git_idx(const char *path, unsigned long *idx_size_,
302 void **idx_map_)
303{
304 void *idx_map;
305 unsigned int *index;
306 unsigned long idx_size;
307 int nr, i;
308 int fd = open(path, O_RDONLY);
309 struct stat st;
310 if (fd < 0)
311 return -1;
312 if (fstat(fd, &st)) {
313 close(fd);
314 return -1;
315 }
316 idx_size = st.st_size;
317 idx_map = mmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0);
318 close(fd);
319 if (idx_map == MAP_FAILED)
320 return -1;
321
322 index = idx_map;
4d235c80
LT
323 *idx_map_ = idx_map;
324 *idx_size_ = idx_size;
1f688557
JH
325
326 /* check index map */
f9253394 327 if (idx_size < 4*256 + 20 + 20)
1f688557
JH
328 return error("index file too small");
329 nr = 0;
330 for (i = 0; i < 256; i++) {
331 unsigned int n = ntohl(index[i]);
332 if (n < nr)
333 return error("non-monotonic index");
334 nr = n;
335 }
336
337 /*
338 * Total size:
339 * - 256 index entries 4 bytes each
340 * - 24-byte entries * nr (20-byte sha1 + 4-byte offset)
341 * - 20-byte SHA1 of the packfile
342 * - 20-byte SHA1 file checksum
343 */
344 if (idx_size != 4*256 + nr * 24 + 20 + 20)
345 return error("wrong index file size");
346
1f688557
JH
347 return 0;
348}
349
f9253394 350static int unuse_one_packed_git(void)
1f688557 351{
f9253394
JH
352 struct packed_git *p, *lru = NULL;
353
354 for (p = packed_git; p; p = p->next) {
355 if (p->pack_use_cnt || !p->pack_base)
356 continue;
357 if (!lru || p->pack_last_used < lru->pack_last_used)
358 lru = p;
359 }
360 if (!lru)
361 return 0;
362 munmap(lru->pack_base, lru->pack_size);
363 lru->pack_base = NULL;
364 return 1;
365}
366
367void unuse_packed_git(struct packed_git *p)
368{
369 p->pack_use_cnt--;
1f688557
JH
370}
371
f9253394 372int use_packed_git(struct packed_git *p)
1f688557 373{
bf592c50
DB
374 if (!p->pack_size) {
375 struct stat st;
376 // We created the struct before we had the pack
377 stat(p->pack_name, &st);
378 if (!S_ISREG(st.st_mode))
379 die("packfile %s not a regular file", p->pack_name);
380 p->pack_size = st.st_size;
381 }
1f688557
JH
382 if (!p->pack_base) {
383 int fd;
384 struct stat st;
385 void *map;
386
387 pack_mapped += p->pack_size;
f9253394
JH
388 while (PACK_MAX_SZ < pack_mapped && unuse_one_packed_git())
389 ; /* nothing */
1f688557
JH
390 fd = open(p->pack_name, O_RDONLY);
391 if (fd < 0)
f9253394 392 die("packfile %s cannot be opened", p->pack_name);
1f688557
JH
393 if (fstat(fd, &st)) {
394 close(fd);
f9253394 395 die("packfile %s cannot be opened", p->pack_name);
1f688557
JH
396 }
397 if (st.st_size != p->pack_size)
f9253394 398 die("packfile %s size mismatch.", p->pack_name);
1f688557
JH
399 map = mmap(NULL, p->pack_size, PROT_READ, MAP_PRIVATE, fd, 0);
400 close(fd);
401 if (map == MAP_FAILED)
f9253394 402 die("packfile %s cannot be mapped.", p->pack_name);
1f688557 403 p->pack_base = map;
f9253394
JH
404
405 /* Check if the pack file matches with the index file.
406 * this is cheap.
407 */
408 if (memcmp((char*)(p->index_base) + p->index_size - 40,
bf592c50
DB
409 p->pack_base + p->pack_size - 20, 20)) {
410
f9253394 411 die("packfile %s does not match index.", p->pack_name);
bf592c50 412 }
1f688557
JH
413 }
414 p->pack_last_used = pack_used_ctr++;
f9253394 415 p->pack_use_cnt++;
1f688557
JH
416 return 0;
417}
418
f9253394 419struct packed_git *add_packed_git(char *path, int path_len)
1f688557
JH
420{
421 struct stat st;
422 struct packed_git *p;
423 unsigned long idx_size;
424 void *idx_map;
425
426 if (check_packed_git_idx(path, &idx_size, &idx_map))
427 return NULL;
428
429 /* do we have a corresponding .pack file? */
430 strcpy(path + path_len - 4, ".pack");
431 if (stat(path, &st) || !S_ISREG(st.st_mode)) {
432 munmap(idx_map, idx_size);
433 return NULL;
434 }
435 /* ok, it looks sane as far as we can check without
436 * actually mapping the pack file.
437 */
438 p = xmalloc(sizeof(*p) + path_len + 2);
439 strcpy(p->pack_name, path);
440 p->index_size = idx_size;
441 p->pack_size = st.st_size;
442 p->index_base = idx_map;
443 p->next = NULL;
d85a4fee 444 p->pack_base = NULL;
1f688557 445 p->pack_last_used = 0;
f9253394 446 p->pack_use_cnt = 0;
1f688557
JH
447 return p;
448}
449
bf592c50 450struct packed_git *parse_pack_index(unsigned char *sha1)
c508df5e
DB
451{
452 char *path = sha1_pack_index_name(sha1);
453 return parse_pack_index_file(sha1, path);
454}
455
2ab141a2 456struct packed_git *parse_pack_index_file(const unsigned char *sha1, char *idx_path)
bf592c50
DB
457{
458 struct packed_git *p;
459 unsigned long idx_size;
460 void *idx_map;
c508df5e 461 char *path;
bf592c50 462
c508df5e 463 if (check_packed_git_idx(idx_path, &idx_size, &idx_map))
bf592c50
DB
464 return NULL;
465
466 path = sha1_pack_name(sha1);
467
468 p = xmalloc(sizeof(*p) + strlen(path) + 2);
469 strcpy(p->pack_name, path);
470 p->index_size = idx_size;
471 p->pack_size = 0;
472 p->index_base = idx_map;
473 p->next = NULL;
474 p->pack_base = NULL;
475 p->pack_last_used = 0;
476 p->pack_use_cnt = 0;
477 memcpy(p->sha1, sha1, 20);
478 return p;
479}
480
481void install_packed_git(struct packed_git *pack)
482{
483 pack->next = packed_git;
484 packed_git = pack;
485}
486
1f688557
JH
487static void prepare_packed_git_one(char *objdir)
488{
489 char path[PATH_MAX];
490 int len;
491 DIR *dir;
492 struct dirent *de;
493
494 sprintf(path, "%s/pack", objdir);
495 len = strlen(path);
496 dir = opendir(path);
497 if (!dir)
498 return;
499 path[len++] = '/';
500 while ((de = readdir(dir)) != NULL) {
501 int namelen = strlen(de->d_name);
502 struct packed_git *p;
503
504 if (strcmp(de->d_name + namelen - 4, ".idx"))
505 continue;
506
507 /* we have .idx. Is it a file we can map? */
508 strcpy(path + len, de->d_name);
509 p = add_packed_git(path, len + namelen);
510 if (!p)
511 continue;
512 p->next = packed_git;
513 packed_git = p;
514 }
5b35bcd5 515 closedir(dir);
1f688557
JH
516}
517
9a217f2a 518void prepare_packed_git(void)
1f688557 519{
1f688557 520 static int run_once = 0;
d5a63b99 521 struct alternate_object_database *alt;
1f688557 522
d5a63b99 523 if (run_once)
1f688557 524 return;
1f688557 525 prepare_packed_git_one(get_object_directory());
9a217f2a 526 prepare_alt_odb();
d5a63b99
JH
527 for (alt = alt_odb_list; alt; alt = alt->next) {
528 alt->name[0] = 0;
529 prepare_packed_git_one(alt->base);
1f688557 530 }
d5a63b99 531 run_once = 1;
1f688557
JH
532}
533
5d6ccf5c 534int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type)
0fcfd160 535{
d98b46f8 536 char header[100];
0fcfd160
LT
537 unsigned char real_sha1[20];
538 SHA_CTX c;
539
540 SHA1_Init(&c);
d98b46f8 541 SHA1_Update(&c, header, 1+sprintf(header, "%s %lu", type, size));
0fcfd160
LT
542 SHA1_Update(&c, map, size);
543 SHA1_Final(real_sha1, &c);
544 return memcmp(sha1, real_sha1, 20) ? -1 : 0;
545}
546
1f688557 547static void *map_sha1_file_internal(const unsigned char *sha1,
d5f1befc 548 unsigned long *size)
0fcfd160 549{
0fcfd160
LT
550 struct stat st;
551 void *map;
144bde78 552 int fd;
ace1534d
JH
553 char *filename = find_sha1_file(sha1, &st);
554
555 if (!filename) {
ace1534d
JH
556 return NULL;
557 }
0fcfd160 558
144bde78 559 fd = open(filename, O_RDONLY | sha1_file_open_flag);
0fcfd160 560 if (fd < 0) {
144bde78
LT
561 /* See if it works without O_NOATIME */
562 switch (sha1_file_open_flag) {
563 default:
564 fd = open(filename, O_RDONLY);
565 if (fd >= 0)
566 break;
567 /* Fallthrough */
568 case 0:
144bde78
LT
569 return NULL;
570 }
571
1f688557
JH
572 /* If it failed once, it will probably fail again.
573 * Stop using O_NOATIME
574 */
144bde78 575 sha1_file_open_flag = 0;
0fcfd160 576 }
0fcfd160
LT
577 map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
578 close(fd);
e35f9824 579 if (map == MAP_FAILED)
0fcfd160
LT
580 return NULL;
581 *size = st.st_size;
582 return map;
583}
584
c4483576
LT
585int unpack_sha1_header(z_stream *stream, void *map, unsigned long mapsize, void *buffer, unsigned long size)
586{
587 /* Get the data stream */
588 memset(stream, 0, sizeof(*stream));
589 stream->next_in = map;
590 stream->avail_in = mapsize;
591 stream->next_out = buffer;
592 stream->avail_out = size;
593
594 inflateInit(stream);
595 return inflate(stream, 0);
596}
597
6da4016a 598static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size)
5180cacc
LT
599{
600 int bytes = strlen(buffer) + 1;
d565b341 601 unsigned char *buf = xmalloc(1+size);
5180cacc
LT
602
603 memcpy(buf, buffer + bytes, stream->total_out - bytes);
604 bytes = stream->total_out - bytes;
605 if (bytes < size) {
606 stream->next_out = buf + bytes;
607 stream->avail_out = size - bytes;
608 while (inflate(stream, Z_FINISH) == Z_OK)
609 /* nothing */;
610 }
611 buf[size] = 0;
612 inflateEnd(stream);
613 return buf;
614}
615
616/*
617 * We used to just use "sscanf()", but that's actually way
618 * too permissive for what we want to check. So do an anal
619 * object header parse by hand.
620 */
621int parse_sha1_header(char *hdr, char *type, unsigned long *sizep)
622{
623 int i;
624 unsigned long size;
625
626 /*
627 * The type can be at most ten bytes (including the
628 * terminating '\0' that we add), and is followed by
629 * a space.
630 */
631 i = 10;
632 for (;;) {
633 char c = *hdr++;
634 if (c == ' ')
635 break;
636 if (!--i)
637 return -1;
638 *type++ = c;
639 }
640 *type = 0;
641
642 /*
643 * The length must follow immediately, and be in canonical
644 * decimal format (ie "010" is not valid).
645 */
646 size = *hdr++ - '0';
647 if (size > 9)
648 return -1;
649 if (size) {
650 for (;;) {
651 unsigned long c = *hdr - '0';
652 if (c > 9)
653 break;
654 hdr++;
655 size = size * 10 + c;
656 }
657 }
658 *sizep = size;
659
660 /*
661 * The length must be followed by a zero byte
662 */
663 return *hdr ? -1 : 0;
664}
665
0fcfd160
LT
666void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size)
667{
5180cacc 668 int ret;
0fcfd160 669 z_stream stream;
5180cacc 670 char hdr[8192];
0fcfd160 671
5180cacc
LT
672 ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
673 if (ret < Z_OK || parse_sha1_header(hdr, type, size) < 0)
0fcfd160
LT
674 return NULL;
675
5180cacc 676 return unpack_sha1_rest(&stream, hdr, *size);
0fcfd160
LT
677}
678
f3bf9224
JH
679/* forward declaration for a mutually recursive function */
680static int packed_object_info(struct pack_entry *entry,
681 char *type, unsigned long *sizep);
682
5db47c2b
JH
683static int packed_delta_info(unsigned char *base_sha1,
684 unsigned long delta_size,
685 unsigned long left,
686 char *type,
f3bf9224
JH
687 unsigned long *sizep,
688 struct packed_git *p)
5db47c2b 689{
f3bf9224
JH
690 struct pack_entry base_ent;
691
5db47c2b
JH
692 if (left < 20)
693 die("truncated pack file");
5db47c2b 694
f3bf9224
JH
695 /* The base entry _must_ be in the same pack */
696 if (!find_pack_entry_one(base_sha1, &base_ent, p))
697 die("failed to find delta-pack base object %s",
698 sha1_to_hex(base_sha1));
699
c62266f3
JH
700 /* We choose to only get the type of the base object and
701 * ignore potentially corrupt pack file that expects the delta
702 * based on a base with a wrong size. This saves tons of
703 * inflate() calls.
704 */
5db47c2b 705
f3bf9224 706 if (packed_object_info(&base_ent, type, NULL))
c62266f3 707 die("cannot get info for delta-pack base");
5db47c2b 708
c62266f3
JH
709 if (sizep) {
710 const unsigned char *data;
711 unsigned char delta_head[64];
712 unsigned long result_size;
713 z_stream stream;
714 int st;
715
716 memset(&stream, 0, sizeof(stream));
717
718 data = stream.next_in = base_sha1 + 20;
719 stream.avail_in = left - 20;
720 stream.next_out = delta_head;
721 stream.avail_out = sizeof(delta_head);
722
723 inflateInit(&stream);
724 st = inflate(&stream, Z_FINISH);
725 inflateEnd(&stream);
726 if ((st != Z_STREAM_END) &&
727 stream.total_out != sizeof(delta_head))
728 die("delta data unpack-initial failed");
729
730 /* Examine the initial part of the delta to figure out
731 * the result size.
732 */
733 data = delta_head;
734 get_delta_hdr_size(&data); /* ignore base size */
5db47c2b 735
c62266f3
JH
736 /* Read the result size */
737 result_size = get_delta_hdr_size(&data);
738 *sizep = result_size;
739 }
5db47c2b
JH
740 return 0;
741}
742
a733cb60
LT
743static unsigned long unpack_object_header(struct packed_git *p, unsigned long offset,
744 enum object_type *type, unsigned long *sizep)
745{
01247d87 746 unsigned shift;
a733cb60
LT
747 unsigned char *pack, c;
748 unsigned long size;
749
750 if (offset >= p->pack_size)
751 die("object offset outside of pack file");
752
753 pack = p->pack_base + offset;
754 c = *pack++;
755 offset++;
756 *type = (c >> 4) & 7;
757 size = c & 15;
01247d87 758 shift = 4;
a733cb60
LT
759 while (c & 0x80) {
760 if (offset >= p->pack_size)
761 die("object offset outside of pack file");
762 c = *pack++;
763 offset++;
01247d87
LT
764 size += (c & 0x7f) << shift;
765 shift += 7;
a733cb60
LT
766 }
767 *sizep = size;
768 return offset;
769}
770
ad8c80a5
JH
771void packed_object_info_detail(struct pack_entry *e,
772 char *type,
773 unsigned long *size,
774 unsigned long *store_size,
775 int *delta_chain_length,
776 unsigned char *base_sha1)
777{
778 struct packed_git *p = e->p;
779 unsigned long offset, left;
780 unsigned char *pack;
781 enum object_type kind;
782
783 offset = unpack_object_header(p, e->offset, &kind, size);
784 pack = p->pack_base + offset;
785 left = p->pack_size - offset;
786 if (kind != OBJ_DELTA)
787 *delta_chain_length = 0;
788 else {
789 int chain_length = 0;
790 memcpy(base_sha1, pack, 20);
791 do {
792 struct pack_entry base_ent;
793 unsigned long junk;
794
795 find_pack_entry_one(pack, &base_ent, p);
796 offset = unpack_object_header(p, base_ent.offset,
797 &kind, &junk);
798 pack = p->pack_base + offset;
799 chain_length++;
800 } while (kind == OBJ_DELTA);
801 *delta_chain_length = chain_length;
802 }
803 switch (kind) {
804 case OBJ_COMMIT:
805 strcpy(type, "commit");
806 break;
807 case OBJ_TREE:
808 strcpy(type, "tree");
809 break;
810 case OBJ_BLOB:
811 strcpy(type, "blob");
812 break;
813 case OBJ_TAG:
814 strcpy(type, "tag");
815 break;
816 default:
264b16b6
JH
817 die("corrupted pack file %s containing object of kind %d",
818 p->pack_name, kind);
ad8c80a5
JH
819 }
820 *store_size = 0; /* notyet */
821}
822
1f688557
JH
823static int packed_object_info(struct pack_entry *entry,
824 char *type, unsigned long *sizep)
825{
826 struct packed_git *p = entry->p;
827 unsigned long offset, size, left;
828 unsigned char *pack;
a733cb60 829 enum object_type kind;
f9253394 830 int retval;
5db47c2b
JH
831
832 if (use_packed_git(p))
833 die("cannot map packed file");
834
a733cb60 835 offset = unpack_object_header(p, entry->offset, &kind, &size);
1f688557 836 pack = p->pack_base + offset;
a733cb60
LT
837 left = p->pack_size - offset;
838
839 switch (kind) {
840 case OBJ_DELTA:
f3bf9224 841 retval = packed_delta_info(pack, size, left, type, sizep, p);
f9253394
JH
842 unuse_packed_git(p);
843 return retval;
a733cb60 844 case OBJ_COMMIT:
1f688557
JH
845 strcpy(type, "commit");
846 break;
a733cb60 847 case OBJ_TREE:
1f688557
JH
848 strcpy(type, "tree");
849 break;
a733cb60 850 case OBJ_BLOB:
1f688557
JH
851 strcpy(type, "blob");
852 break;
a733cb60 853 case OBJ_TAG:
a69d0943
LT
854 strcpy(type, "tag");
855 break;
1f688557 856 default:
264b16b6
JH
857 die("corrupted pack file %s containing object of kind %d",
858 p->pack_name, kind);
1f688557 859 }
c62266f3
JH
860 if (sizep)
861 *sizep = size;
f9253394 862 unuse_packed_git(p);
1f688557
JH
863 return 0;
864}
865
866/* forward declaration for a mutually recursive function */
867static void *unpack_entry(struct pack_entry *, char *, unsigned long *);
868
869static void *unpack_delta_entry(unsigned char *base_sha1,
870 unsigned long delta_size,
871 unsigned long left,
872 char *type,
f3bf9224
JH
873 unsigned long *sizep,
874 struct packed_git *p)
1f688557 875{
f3bf9224 876 struct pack_entry base_ent;
1f688557
JH
877 void *data, *delta_data, *result, *base;
878 unsigned long data_size, result_size, base_size;
879 z_stream stream;
880 int st;
881
882 if (left < 20)
883 die("truncated pack file");
884 data = base_sha1 + 20;
885 data_size = left - 20;
886 delta_data = xmalloc(delta_size);
887
888 memset(&stream, 0, sizeof(stream));
889
890 stream.next_in = data;
891 stream.avail_in = data_size;
892 stream.next_out = delta_data;
893 stream.avail_out = delta_size;
894
895 inflateInit(&stream);
896 st = inflate(&stream, Z_FINISH);
897 inflateEnd(&stream);
898 if ((st != Z_STREAM_END) || stream.total_out != delta_size)
899 die("delta data unpack failed");
900
f3bf9224
JH
901 /* The base entry _must_ be in the same pack */
902 if (!find_pack_entry_one(base_sha1, &base_ent, p))
903 die("failed to find delta-pack base object %s",
904 sha1_to_hex(base_sha1));
905 base = unpack_entry_gently(&base_ent, type, &base_size);
1f688557
JH
906 if (!base)
907 die("failed to read delta-pack base object %s",
908 sha1_to_hex(base_sha1));
909 result = patch_delta(base, base_size,
910 delta_data, delta_size,
911 &result_size);
912 if (!result)
913 die("failed to apply delta");
914 free(delta_data);
915 free(base);
916 *sizep = result_size;
917 return result;
918}
919
920static void *unpack_non_delta_entry(unsigned char *data,
921 unsigned long size,
922 unsigned long left)
923{
924 int st;
925 z_stream stream;
4d235c80 926 unsigned char *buffer;
1f688557
JH
927
928 buffer = xmalloc(size + 1);
929 buffer[size] = 0;
930 memset(&stream, 0, sizeof(stream));
931 stream.next_in = data;
932 stream.avail_in = left;
933 stream.next_out = buffer;
934 stream.avail_out = size;
935
936 inflateInit(&stream);
937 st = inflate(&stream, Z_FINISH);
938 inflateEnd(&stream);
939 if ((st != Z_STREAM_END) || stream.total_out != size) {
940 free(buffer);
941 return NULL;
942 }
943
944 return buffer;
945}
946
947static void *unpack_entry(struct pack_entry *entry,
948 char *type, unsigned long *sizep)
949{
950 struct packed_git *p = entry->p;
f9253394 951 void *retval;
1f688557
JH
952
953 if (use_packed_git(p))
954 die("cannot map packed file");
f3bf9224
JH
955 retval = unpack_entry_gently(entry, type, sizep);
956 unuse_packed_git(p);
957 if (!retval)
264b16b6 958 die("corrupted pack file %s", p->pack_name);
f3bf9224
JH
959 return retval;
960}
961
962/* The caller is responsible for use_packed_git()/unuse_packed_git() pair */
963void *unpack_entry_gently(struct pack_entry *entry,
964 char *type, unsigned long *sizep)
965{
966 struct packed_git *p = entry->p;
967 unsigned long offset, size, left;
968 unsigned char *pack;
969 enum object_type kind;
970 void *retval;
1f688557 971
a733cb60 972 offset = unpack_object_header(p, entry->offset, &kind, &size);
1f688557 973 pack = p->pack_base + offset;
a733cb60
LT
974 left = p->pack_size - offset;
975 switch (kind) {
976 case OBJ_DELTA:
f3bf9224 977 retval = unpack_delta_entry(pack, size, left, type, sizep, p);
f9253394 978 return retval;
a733cb60 979 case OBJ_COMMIT:
1f688557
JH
980 strcpy(type, "commit");
981 break;
a733cb60 982 case OBJ_TREE:
1f688557
JH
983 strcpy(type, "tree");
984 break;
a733cb60 985 case OBJ_BLOB:
1f688557
JH
986 strcpy(type, "blob");
987 break;
a733cb60 988 case OBJ_TAG:
a69d0943
LT
989 strcpy(type, "tag");
990 break;
1f688557 991 default:
f3bf9224 992 return NULL;
1f688557
JH
993 }
994 *sizep = size;
f9253394 995 retval = unpack_non_delta_entry(pack, size, left);
f9253394 996 return retval;
1f688557
JH
997}
998
9a217f2a
JH
999int num_packed_objects(const struct packed_git *p)
1000{
f9253394 1001 /* See check_packed_git_idx() */
9a217f2a
JH
1002 return (p->index_size - 20 - 20 - 4*256) / 24;
1003}
1004
1005int nth_packed_object_sha1(const struct packed_git *p, int n,
1006 unsigned char* sha1)
1007{
1008 void *index = p->index_base + 256;
1009 if (n < 0 || num_packed_objects(p) <= n)
1010 return -1;
1011 memcpy(sha1, (index + 24 * n + 4), 20);
1012 return 0;
1013}
1014
f3bf9224
JH
1015int find_pack_entry_one(const unsigned char *sha1,
1016 struct pack_entry *e, struct packed_git *p)
1f688557 1017{
4d235c80 1018 unsigned int *level1_ofs = p->index_base;
1f688557
JH
1019 int hi = ntohl(level1_ofs[*sha1]);
1020 int lo = ((*sha1 == 0x0) ? 0 : ntohl(level1_ofs[*sha1 - 1]));
1021 void *index = p->index_base + 256;
1022
1023 do {
1024 int mi = (lo + hi) / 2;
1025 int cmp = memcmp(index + 24 * mi + 4, sha1, 20);
1026 if (!cmp) {
1027 e->offset = ntohl(*((int*)(index + 24 * mi)));
1028 memcpy(e->sha1, sha1, 20);
1029 e->p = p;
1030 return 1;
1031 }
1032 if (cmp > 0)
1033 hi = mi;
1034 else
1035 lo = mi+1;
1036 } while (lo < hi);
1037 return 0;
1038}
1039
1040static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
1041{
1042 struct packed_git *p;
1043 prepare_packed_git();
1044
1045 for (p = packed_git; p; p = p->next) {
f3bf9224 1046 if (find_pack_entry_one(sha1, e, p))
1f688557
JH
1047 return 1;
1048 }
1049 return 0;
1050}
1051
bf592c50
DB
1052struct packed_git *find_sha1_pack(const unsigned char *sha1,
1053 struct packed_git *packs)
1054{
1055 struct packed_git *p;
1056 struct pack_entry e;
1057
1058 for (p = packs; p; p = p->next) {
1059 if (find_pack_entry_one(sha1, &e, p))
1060 return p;
1061 }
1062 return NULL;
1063
1064}
1065
36e4d74a 1066int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep)
65c2e0c3 1067{
36e4d74a 1068 int status;
65c2e0c3
JH
1069 unsigned long mapsize, size;
1070 void *map;
1071 z_stream stream;
36e4d74a 1072 char hdr[128];
65c2e0c3 1073
d5f1befc 1074 map = map_sha1_file_internal(sha1, &mapsize);
1f688557
JH
1075 if (!map) {
1076 struct pack_entry e;
1077
1078 if (!find_pack_entry(sha1, &e))
1079 return error("unable to find %s", sha1_to_hex(sha1));
c62266f3 1080 return packed_object_info(&e, type, sizep);
1f688557 1081 }
36e4d74a
JH
1082 if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0)
1083 status = error("unable to unpack %s header",
1084 sha1_to_hex(sha1));
1085 if (parse_sha1_header(hdr, type, &size) < 0)
1086 status = error("unable to parse %s header", sha1_to_hex(sha1));
c4584ae3 1087 else {
65c2e0c3 1088 status = 0;
c62266f3
JH
1089 if (sizep)
1090 *sizep = size;
65c2e0c3 1091 }
65c2e0c3
JH
1092 inflateEnd(&stream);
1093 munmap(map, mapsize);
1094 return status;
1095}
1096
1f688557
JH
1097static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned long *size)
1098{
1099 struct pack_entry e;
1100
1101 if (!find_pack_entry(sha1, &e)) {
1102 error("cannot read sha1_file for %s", sha1_to_hex(sha1));
1103 return NULL;
1104 }
1105 return unpack_entry(&e, type, size);
1106}
1107
0fcfd160
LT
1108void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
1109{
1110 unsigned long mapsize;
1111 void *map, *buf;
ab90ea5d 1112 struct pack_entry e;
0fcfd160 1113
ab90ea5d
JH
1114 if (find_pack_entry(sha1, &e))
1115 return read_packed_sha1(sha1, type, size);
d5f1befc 1116 map = map_sha1_file_internal(sha1, &mapsize);
0fcfd160
LT
1117 if (map) {
1118 buf = unpack_sha1_file(map, mapsize, type, size);
1119 munmap(map, mapsize);
1120 return buf;
1121 }
ab90ea5d 1122 return NULL;
0fcfd160
LT
1123}
1124
40469ee9 1125void *read_object_with_reference(const unsigned char *sha1,
bf0f910d 1126 const char *required_type,
40469ee9
JH
1127 unsigned long *size,
1128 unsigned char *actual_sha1_return)
f4913f91
JH
1129{
1130 char type[20];
1131 void *buffer;
1132 unsigned long isize;
40469ee9 1133 unsigned char actual_sha1[20];
f4913f91 1134
40469ee9
JH
1135 memcpy(actual_sha1, sha1, 20);
1136 while (1) {
1137 int ref_length = -1;
1138 const char *ref_type = NULL;
f4913f91 1139
40469ee9
JH
1140 buffer = read_sha1_file(actual_sha1, type, &isize);
1141 if (!buffer)
1142 return NULL;
1143 if (!strcmp(type, required_type)) {
1144 *size = isize;
1145 if (actual_sha1_return)
1146 memcpy(actual_sha1_return, actual_sha1, 20);
1147 return buffer;
1148 }
1149 /* Handle references */
1150 else if (!strcmp(type, "commit"))
1151 ref_type = "tree ";
1152 else if (!strcmp(type, "tag"))
1153 ref_type = "object ";
1154 else {
1155 free(buffer);
1156 return NULL;
1157 }
1158 ref_length = strlen(ref_type);
f4913f91 1159
40469ee9
JH
1160 if (memcmp(buffer, ref_type, ref_length) ||
1161 get_sha1_hex(buffer + ref_length, actual_sha1)) {
1162 free(buffer);
1163 return NULL;
1164 }
1cf58e72 1165 free(buffer);
40469ee9
JH
1166 /* Now we have the ID of the referred-to object in
1167 * actual_sha1. Check again. */
f4913f91 1168 }
f4913f91
JH
1169}
1170
7672db20
BL
1171char *write_sha1_file_prepare(void *buf,
1172 unsigned long len,
1173 const char *type,
1174 unsigned char *sha1,
1175 unsigned char *hdr,
1176 int *hdrlen)
d410c0f5
JH
1177{
1178 SHA_CTX c;
1179
1180 /* Generate the header */
1181 *hdrlen = sprintf((char *)hdr, "%s %lu", type, len)+1;
1182
1183 /* Sha1.. */
1184 SHA1_Init(&c);
1185 SHA1_Update(&c, hdr, *hdrlen);
1186 SHA1_Update(&c, buf, len);
1187 SHA1_Final(sha1, &c);
1188
1189 return sha1_file_name(sha1);
1190}
1191
230f1322
LT
1192/*
1193 * Link the tempfile to the final place, possibly creating the
1194 * last directory level as you do so.
1195 *
1196 * Returns the errno on failure, 0 on success.
1197 */
1198static int link_temp_to_file(const char *tmpfile, char *filename)
1199{
1200 int ret;
1201
1202 if (!link(tmpfile, filename))
1203 return 0;
1204
1205 /*
1206 * Try to mkdir the last path component if that failed
1207 * with an ENOENT.
1208 *
1209 * Re-try the "link()" regardless of whether the mkdir
1210 * succeeds, since a race might mean that somebody
1211 * else succeeded.
1212 */
1213 ret = errno;
1214 if (ret == ENOENT) {
1215 char *dir = strrchr(filename, '/');
1216 if (dir) {
1217 *dir = 0;
1218 mkdir(filename, 0777);
1219 *dir = '/';
1220 if (!link(tmpfile, filename))
1221 return 0;
1222 ret = errno;
1223 }
1224 }
1225 return ret;
1226}
1227
1228/*
1229 * Move the just written object into its final resting place
1230 */
b721e01f 1231int move_temp_to_file(const char *tmpfile, char *filename)
230f1322
LT
1232{
1233 int ret = link_temp_to_file(tmpfile, filename);
1234 if (ret) {
1235 /*
1236 * Coda hack - coda doesn't like cross-directory links,
1237 * so we fall back to a rename, which will mean that it
1238 * won't be able to check collisions, but that's not a
1239 * big deal.
1240 *
1241 * When this succeeds, we just return 0. We have nothing
1242 * left to unlink.
1243 */
1244 if (ret == EXDEV && !rename(tmpfile, filename))
1245 return 0;
1246 }
1247 unlink(tmpfile);
1248 if (ret) {
1249 if (ret != EEXIST) {
1250 fprintf(stderr, "unable to write sha1 filename %s: %s", filename, strerror(ret));
1251 return -1;
1252 }
1253 /* FIXME!!! Collision check here ? */
1254 }
1255
1256 return 0;
1257}
1258
bf0f910d 1259int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
0fcfd160
LT
1260{
1261 int size;
bf0f910d 1262 unsigned char *compressed;
0fcfd160
LT
1263 z_stream stream;
1264 unsigned char sha1[20];
706bc531 1265 char *filename;
aac17941 1266 static char tmpfile[PATH_MAX];
bf0f910d 1267 unsigned char hdr[50];
230f1322 1268 int fd, hdrlen;
a44c9a5e 1269
d410c0f5
JH
1270 /* Normally if we have it in the pack then we do not bother writing
1271 * it out into .git/objects/??/?{38} file.
1272 */
1273 filename = write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
706bc531
LT
1274 if (returnsha1)
1275 memcpy(returnsha1, sha1, 20);
d410c0f5
JH
1276 if (has_sha1_file(sha1))
1277 return 0;
aac17941
LT
1278 fd = open(filename, O_RDONLY);
1279 if (fd >= 0) {
706bc531 1280 /*
aac17941
LT
1281 * FIXME!!! We might do collision checking here, but we'd
1282 * need to uncompress the old file and check it. Later.
706bc531 1283 */
aac17941 1284 close(fd);
706bc531
LT
1285 return 0;
1286 }
1287
aac17941
LT
1288 if (errno != ENOENT) {
1289 fprintf(stderr, "sha1 file %s: %s", filename, strerror(errno));
1290 return -1;
1291 }
1292
1293 snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory());
ace1534d 1294
aac17941
LT
1295 fd = mkstemp(tmpfile);
1296 if (fd < 0) {
1297 fprintf(stderr, "unable to create temporary sha1 filename %s: %s", tmpfile, strerror(errno));
1298 return -1;
1299 }
1300
0fcfd160
LT
1301 /* Set it up */
1302 memset(&stream, 0, sizeof(stream));
1303 deflateInit(&stream, Z_BEST_COMPRESSION);
a44c9a5e 1304 size = deflateBound(&stream, len+hdrlen);
812666c8 1305 compressed = xmalloc(size);
0fcfd160
LT
1306
1307 /* Compress it */
0fcfd160
LT
1308 stream.next_out = compressed;
1309 stream.avail_out = size;
a44c9a5e
LT
1310
1311 /* First header.. */
1312 stream.next_in = hdr;
1313 stream.avail_in = hdrlen;
1314 while (deflate(&stream, 0) == Z_OK)
6ffcee88 1315 /* nothing */;
a44c9a5e
LT
1316
1317 /* Then the data itself.. */
1318 stream.next_in = buf;
1319 stream.avail_in = len;
0fcfd160
LT
1320 while (deflate(&stream, Z_FINISH) == Z_OK)
1321 /* nothing */;
1322 deflateEnd(&stream);
1323 size = stream.total_out;
1324
706bc531
LT
1325 if (write(fd, compressed, size) != size)
1326 die("unable to write file");
aac17941 1327 fchmod(fd, 0444);
706bc531 1328 close(fd);
383f85b7 1329 free(compressed);
0fcfd160 1330
230f1322 1331 return move_temp_to_file(tmpfile, filename);
0fcfd160 1332}
8237b185 1333
a5eda52b
DB
1334int write_sha1_to_fd(int fd, const unsigned char *sha1)
1335{
1336 ssize_t size;
1337 unsigned long objsize;
1338 int posn = 0;
bfc66daf
SV
1339 void *map = map_sha1_file_internal(sha1, &objsize);
1340 void *buf = map;
1341 void *temp_obj = NULL;
a5eda52b 1342 z_stream stream;
bfc66daf 1343
a5eda52b
DB
1344 if (!buf) {
1345 unsigned char *unpacked;
1346 unsigned long len;
1347 char type[20];
1348 char hdr[50];
1349 int hdrlen;
1350 // need to unpack and recompress it by itself
1351 unpacked = read_packed_sha1(sha1, type, &len);
1352
1353 hdrlen = sprintf(hdr, "%s %lu", type, len) + 1;
1354
1355 /* Set it up */
1356 memset(&stream, 0, sizeof(stream));
1357 deflateInit(&stream, Z_BEST_COMPRESSION);
1358 size = deflateBound(&stream, len + hdrlen);
bfc66daf 1359 temp_obj = buf = xmalloc(size);
a5eda52b
DB
1360
1361 /* Compress it */
1362 stream.next_out = buf;
1363 stream.avail_out = size;
1364
1365 /* First header.. */
0ee19dce 1366 stream.next_in = (void *)hdr;
a5eda52b
DB
1367 stream.avail_in = hdrlen;
1368 while (deflate(&stream, 0) == Z_OK)
1369 /* nothing */;
1370
1371 /* Then the data itself.. */
1372 stream.next_in = unpacked;
1373 stream.avail_in = len;
1374 while (deflate(&stream, Z_FINISH) == Z_OK)
1375 /* nothing */;
1376 deflateEnd(&stream);
bfc66daf 1377 free(unpacked);
a5eda52b
DB
1378
1379 objsize = stream.total_out;
1380 }
1381
1382 do {
1383 size = write(fd, buf + posn, objsize - posn);
1384 if (size <= 0) {
1385 if (!size) {
1386 fprintf(stderr, "write closed");
1387 } else {
1388 perror("write ");
1389 }
1390 return -1;
1391 }
1392 posn += size;
1393 } while (posn < objsize);
bfc66daf
SV
1394
1395 if (map)
1396 munmap(map, objsize);
1397 if (temp_obj)
1398 free(temp_obj);
1399
a5eda52b
DB
1400 return 0;
1401}
1402
70b9829e
DB
1403int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
1404 size_t bufsize, size_t *bufposn)
8237b185 1405{
230f1322 1406 char tmpfile[PATH_MAX];
8237b185
DB
1407 int local;
1408 z_stream stream;
1409 unsigned char real_sha1[20];
bf0f910d 1410 unsigned char discard[4096];
8237b185
DB
1411 int ret;
1412 SHA_CTX c;
1413
230f1322 1414 snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory());
8237b185 1415
230f1322 1416 local = mkstemp(tmpfile);
8237b185 1417 if (local < 0)
230f1322 1418 return error("Couldn't open %s for %s\n", tmpfile, sha1_to_hex(sha1));
8237b185
DB
1419
1420 memset(&stream, 0, sizeof(stream));
1421
1422 inflateInit(&stream);
1423
1424 SHA1_Init(&c);
1425
1426 do {
1427 ssize_t size;
70b9829e
DB
1428 if (*bufposn) {
1429 stream.avail_in = *bufposn;
96ad15ae 1430 stream.next_in = (unsigned char *) buffer;
70b9829e
DB
1431 do {
1432 stream.next_out = discard;
1433 stream.avail_out = sizeof(discard);
1434 ret = inflate(&stream, Z_SYNC_FLUSH);
1435 SHA1_Update(&c, discard, sizeof(discard) -
1436 stream.avail_out);
1437 } while (stream.avail_in && ret == Z_OK);
1438 write(local, buffer, *bufposn - stream.avail_in);
1439 memmove(buffer, buffer + *bufposn - stream.avail_in,
1440 stream.avail_in);
1441 *bufposn = stream.avail_in;
1442 if (ret != Z_OK)
1443 break;
1444 }
1445 size = read(fd, buffer + *bufposn, bufsize - *bufposn);
8237b185
DB
1446 if (size <= 0) {
1447 close(local);
230f1322 1448 unlink(tmpfile);
8237b185
DB
1449 if (!size)
1450 return error("Connection closed?");
1451 perror("Reading from connection");
1452 return -1;
1453 }
70b9829e
DB
1454 *bufposn += size;
1455 } while (1);
8237b185
DB
1456 inflateEnd(&stream);
1457
1458 close(local);
1459 SHA1_Final(real_sha1, &c);
1460 if (ret != Z_STREAM_END) {
230f1322 1461 unlink(tmpfile);
8237b185
DB
1462 return error("File %s corrupted", sha1_to_hex(sha1));
1463 }
1464 if (memcmp(sha1, real_sha1, 20)) {
230f1322 1465 unlink(tmpfile);
8237b185
DB
1466 return error("File %s has bad hash\n", sha1_to_hex(sha1));
1467 }
230f1322
LT
1468
1469 return move_temp_to_file(tmpfile, sha1_file_name(sha1));
8237b185
DB
1470}
1471
bf592c50
DB
1472int has_pack_index(const unsigned char *sha1)
1473{
1474 struct stat st;
1475 if (stat(sha1_pack_index_name(sha1), &st))
1476 return 0;
1477 return 1;
1478}
1479
1480int has_pack_file(const unsigned char *sha1)
1481{
1482 struct stat st;
1483 if (stat(sha1_pack_name(sha1), &st))
1484 return 0;
1485 return 1;
1486}
1487
dade09c2
LT
1488int has_sha1_pack(const unsigned char *sha1)
1489{
1490 struct pack_entry e;
1491 return find_pack_entry(sha1, &e);
1492}
1493
8237b185
DB
1494int has_sha1_file(const unsigned char *sha1)
1495{
8237b185 1496 struct stat st;
1f688557
JH
1497 struct pack_entry e;
1498
ab90ea5d 1499 if (find_pack_entry(sha1, &e))
1f688557 1500 return 1;
ab90ea5d 1501 return find_sha1_file(sha1, &st) ? 1 : 0;
8237b185 1502}
74400e71 1503
7672db20 1504int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, const char *type)
74400e71 1505{
74400e71 1506 unsigned long size = st->st_size;
aac17941
LT
1507 void *buf;
1508 int ret;
7672db20
BL
1509 unsigned char hdr[50];
1510 int hdrlen;
74400e71 1511
aac17941 1512 buf = "";
74400e71 1513 if (size)
aac17941 1514 buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
74400e71 1515 close(fd);
e35f9824 1516 if (buf == MAP_FAILED)
74400e71
JH
1517 return -1;
1518
7672db20
BL
1519 if (!type)
1520 type = "blob";
1521 if (write_object)
1522 ret = write_sha1_file(buf, size, type, sha1);
1523 else {
1524 write_sha1_file_prepare(buf, size, type, sha1, hdr, &hdrlen);
1525 ret = 0;
1526 }
aac17941
LT
1527 if (size)
1528 munmap(buf, size);
1529 return ret;
74400e71 1530}
ec1fcc16
JH
1531
1532int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object)
1533{
1534 int fd;
1535 char *target;
1536
1537 switch (st->st_mode & S_IFMT) {
1538 case S_IFREG:
1539 fd = open(path, O_RDONLY);
1540 if (fd < 0)
1541 return error("open(\"%s\"): %s", path,
1542 strerror(errno));
1543 if (index_fd(sha1, fd, st, write_object, NULL) < 0)
1544 return error("%s: failed to insert into database",
1545 path);
1546 break;
1547 case S_IFLNK:
1548 target = xmalloc(st->st_size+1);
1549 if (readlink(path, target, st->st_size+1) != st->st_size) {
1550 char *errstr = strerror(errno);
1551 free(target);
1552 return error("readlink(\"%s\"): %s", path,
1553 errstr);
1554 }
1555 if (!write_object) {
1556 unsigned char hdr[50];
1557 int hdrlen;
1558 write_sha1_file_prepare(target, st->st_size, "blob",
1559 sha1, hdr, &hdrlen);
1560 } else if (write_sha1_file(target, st->st_size, "blob", sha1))
1561 return error("%s: failed to insert into database",
1562 path);
1563 free(target);
1564 break;
1565 default:
1566 return error("%s: unsupported file type", path);
1567 }
1568 return 0;
1569}