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