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