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