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