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