sha1_file.con commit Allow removal of "path" when "path/file" exists. (4c5abf4)
   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 <stdarg.h>
  10#include <limits.h>
  11#include "cache.h"
  12
  13#ifndef O_NOATIME
  14#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
  15#define O_NOATIME 01000000
  16#else
  17#define O_NOATIME 0
  18#endif
  19#endif
  20
  21static unsigned int sha1_file_open_flag = O_NOATIME;
  22
  23static unsigned hexval(char c)
  24{
  25        if (c >= '0' && c <= '9')
  26                return c - '0';
  27        if (c >= 'a' && c <= 'f')
  28                return c - 'a' + 10;
  29        if (c >= 'A' && c <= 'F')
  30                return c - 'A' + 10;
  31        return ~0;
  32}
  33
  34int get_sha1_hex(const char *hex, unsigned char *sha1)
  35{
  36        int i;
  37        for (i = 0; i < 20; i++) {
  38                unsigned int val = (hexval(hex[0]) << 4) | hexval(hex[1]);
  39                if (val & ~0xff)
  40                        return -1;
  41                *sha1++ = val;
  42                hex += 2;
  43        }
  44        return 0;
  45}
  46
  47int get_sha1_file(const char *path, unsigned char *result)
  48{
  49        char buffer[60];
  50        int fd = open(path, O_RDONLY);
  51        int len;
  52
  53        if (fd < 0)
  54                return -1;
  55        len = read(fd, buffer, sizeof(buffer));
  56        close(fd);
  57        if (len < 40)
  58                return -1;
  59        return get_sha1_hex(buffer, result);
  60}
  61
  62int get_sha1(const char *str, unsigned char *sha1)
  63{
  64        static char pathname[PATH_MAX];
  65        static const char *prefix[] = {
  66                "",
  67                "refs",
  68                "refs/tags",
  69                "refs/heads",
  70                "refs/snap",
  71                NULL
  72        };
  73        const char *gitdir;
  74        const char **p;
  75
  76        if (!get_sha1_hex(str, sha1))
  77                return 0;
  78
  79        gitdir = ".git";
  80        for (p = prefix; *p; p++) {
  81                snprintf(pathname, sizeof(pathname), "%s/%s/%s", gitdir, *p, str);
  82                if (!get_sha1_file(pathname, sha1))
  83                        return 0;
  84        }
  85
  86        return -1;
  87}
  88
  89char * sha1_to_hex(const unsigned char *sha1)
  90{
  91        static char buffer[50];
  92        static const char hex[] = "0123456789abcdef";
  93        char *buf = buffer;
  94        int i;
  95
  96        for (i = 0; i < 20; i++) {
  97                unsigned int val = *sha1++;
  98                *buf++ = hex[val >> 4];
  99                *buf++ = hex[val & 0xf];
 100        }
 101        return buffer;
 102}
 103
 104static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
 105{
 106        int i;
 107        for (i = 0; i < 20; i++) {
 108                static char hex[] = "0123456789abcdef";
 109                unsigned int val = sha1[i];
 110                char *pos = pathbuf + i*2 + (i > 0);
 111                *pos++ = hex[val >> 4];
 112                *pos = hex[val & 0xf];
 113        }
 114}
 115
 116/*
 117 * NOTE! This returns a statically allocated buffer, so you have to be
 118 * careful about using it. Do a "strdup()" if you need to save the
 119 * filename.
 120 *
 121 * Also note that this returns the location for creating.  Reading
 122 * SHA1 file can happen from any alternate directory listed in the
 123 * SHA1_FILE_DIRECTORIES environment variable if it is not found in
 124 * the primary object database.
 125 */
 126char *sha1_file_name(const unsigned char *sha1)
 127{
 128        static char *name, *base;
 129
 130        if (!base) {
 131                char *sha1_file_directory = get_object_directory();
 132                int len = strlen(sha1_file_directory);
 133                base = xmalloc(len + 60);
 134                memcpy(base, sha1_file_directory, len);
 135                memset(base+len, 0, 60);
 136                base[len] = '/';
 137                base[len+3] = '/';
 138                name = base + len + 1;
 139        }
 140        fill_sha1_path(name, sha1);
 141        return base;
 142}
 143
 144static struct alternate_object_database
 145{
 146        char *base;
 147        char *name;
 148} *alt_odb;
 149
 150static void prepare_alt_odb(void)
 151{
 152        int pass, totlen, i;
 153        void *buf;
 154        const char *cp, *last;
 155        char *op = 0;
 156        const char *alt = getenv(ALTERNATE_DB_ENVIRONMENT) ? : "";
 157
 158        for (totlen = pass = 0; pass < 2; pass++) {
 159                last = alt;
 160                i = 0;
 161                do {
 162                        cp = strchr(last, ':') ? : last + strlen(last);
 163                        if (last != cp) {
 164                                /* 43 = 40-byte + 2 '/' + terminating NUL */
 165                                int pfxlen = cp - last;
 166                                int entlen = pfxlen + 43;
 167                                if (pass == 0)
 168                                        totlen += entlen;
 169                                else {
 170                                        alt_odb[i].base = op;
 171                                        alt_odb[i].name = op + pfxlen + 1;
 172                                        memcpy(op, last, pfxlen);
 173                                        op[pfxlen] = op[pfxlen + 3] = '/';
 174                                        op[entlen-1] = 0;
 175                                        op += entlen;
 176                                }
 177                                i++;
 178                        }
 179                        while (*cp && *cp == ':')
 180                                cp++;
 181                        last = cp;
 182                } while (*cp);
 183                if (pass)
 184                        break;
 185                alt_odb = buf = xmalloc(sizeof(*alt_odb) * (i + 1) + totlen);
 186                alt_odb[i].base = alt_odb[i].name = 0;
 187                op = (char*)(&alt_odb[i+1]);
 188        }
 189}
 190
 191static char *find_sha1_file(const unsigned char *sha1, struct stat *st)
 192{
 193        int i;
 194        char *name = sha1_file_name(sha1);
 195
 196        if (!stat(name, st))
 197                return name;
 198        if (!alt_odb)
 199                prepare_alt_odb();
 200        for (i = 0; (name = alt_odb[i].name) != NULL; i++) {
 201                fill_sha1_path(name, sha1);
 202                if (!stat(alt_odb[i].base, st))
 203                        return alt_odb[i].base;
 204        }
 205        return NULL;
 206}
 207
 208int check_sha1_signature(unsigned char *sha1, void *map, unsigned long size, const char *type)
 209{
 210        char header[100];
 211        unsigned char real_sha1[20];
 212        SHA_CTX c;
 213
 214        SHA1_Init(&c);
 215        SHA1_Update(&c, header, 1+sprintf(header, "%s %lu", type, size));
 216        SHA1_Update(&c, map, size);
 217        SHA1_Final(real_sha1, &c);
 218        return memcmp(sha1, real_sha1, 20) ? -1 : 0;
 219}
 220
 221void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
 222{
 223        struct stat st;
 224        void *map;
 225        int fd;
 226        char *filename = find_sha1_file(sha1, &st);
 227
 228        if (!filename) {
 229                error("cannot map sha1 file %s", sha1_to_hex(sha1));
 230                return NULL;
 231        }
 232
 233        fd = open(filename, O_RDONLY | sha1_file_open_flag);
 234        if (fd < 0) {
 235                /* See if it works without O_NOATIME */
 236                switch (sha1_file_open_flag) {
 237                default:
 238                        fd = open(filename, O_RDONLY);
 239                        if (fd >= 0)
 240                                break;
 241                /* Fallthrough */
 242                case 0:
 243                        perror(filename);
 244                        return NULL;
 245                }
 246
 247                /* If it failed once, it will probably fail again. Stop using O_NOATIME */
 248                sha1_file_open_flag = 0;
 249        }
 250        map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
 251        close(fd);
 252        if (-1 == (int)(long)map)
 253                return NULL;
 254        *size = st.st_size;
 255        return map;
 256}
 257
 258void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size)
 259{
 260        int ret, bytes;
 261        z_stream stream;
 262        char buffer[8192];
 263        char *buf;
 264
 265        /* Get the data stream */
 266        memset(&stream, 0, sizeof(stream));
 267        stream.next_in = map;
 268        stream.avail_in = mapsize;
 269        stream.next_out = buffer;
 270        stream.avail_out = sizeof(buffer);
 271
 272        inflateInit(&stream);
 273        ret = inflate(&stream, 0);
 274        if (ret < Z_OK)
 275                return NULL;
 276        if (sscanf(buffer, "%10s %lu", type, size) != 2)
 277                return NULL;
 278
 279        bytes = strlen(buffer) + 1;
 280        buf = xmalloc(*size);
 281
 282        memcpy(buf, buffer + bytes, stream.total_out - bytes);
 283        bytes = stream.total_out - bytes;
 284        if (bytes < *size && ret == Z_OK) {
 285                stream.next_out = buf + bytes;
 286                stream.avail_out = *size - bytes;
 287                while (inflate(&stream, Z_FINISH) == Z_OK)
 288                        /* nothing */;
 289        }
 290        inflateEnd(&stream);
 291        return buf;
 292}
 293
 294void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
 295{
 296        unsigned long mapsize;
 297        void *map, *buf;
 298
 299        map = map_sha1_file(sha1, &mapsize);
 300        if (map) {
 301                buf = unpack_sha1_file(map, mapsize, type, size);
 302                munmap(map, mapsize);
 303                return buf;
 304        }
 305        return NULL;
 306}
 307
 308void *read_object_with_reference(const unsigned char *sha1,
 309                                 const unsigned char *required_type,
 310                                 unsigned long *size,
 311                                 unsigned char *actual_sha1_return)
 312{
 313        char type[20];
 314        void *buffer;
 315        unsigned long isize;
 316        unsigned char actual_sha1[20];
 317
 318        memcpy(actual_sha1, sha1, 20);
 319        while (1) {
 320                int ref_length = -1;
 321                const char *ref_type = NULL;
 322
 323                buffer = read_sha1_file(actual_sha1, type, &isize);
 324                if (!buffer)
 325                        return NULL;
 326                if (!strcmp(type, required_type)) {
 327                        *size = isize;
 328                        if (actual_sha1_return)
 329                                memcpy(actual_sha1_return, actual_sha1, 20);
 330                        return buffer;
 331                }
 332                /* Handle references */
 333                else if (!strcmp(type, "commit"))
 334                        ref_type = "tree ";
 335                else if (!strcmp(type, "tag"))
 336                        ref_type = "object ";
 337                else {
 338                        free(buffer);
 339                        return NULL;
 340                }
 341                ref_length = strlen(ref_type);
 342
 343                if (memcmp(buffer, ref_type, ref_length) ||
 344                    get_sha1_hex(buffer + ref_length, actual_sha1)) {
 345                        free(buffer);
 346                        return NULL;
 347                }
 348                /* Now we have the ID of the referred-to object in
 349                 * actual_sha1.  Check again. */
 350        }
 351}
 352
 353int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned char *returnsha1)
 354{
 355        int size;
 356        char *compressed;
 357        z_stream stream;
 358        unsigned char sha1[20];
 359        SHA_CTX c;
 360        char *filename;
 361        static char tmpfile[PATH_MAX];
 362        char hdr[50];
 363        int fd, hdrlen, ret;
 364
 365        /* Generate the header */
 366        hdrlen = sprintf(hdr, "%s %lu", type, len)+1;
 367
 368        /* Sha1.. */
 369        SHA1_Init(&c);
 370        SHA1_Update(&c, hdr, hdrlen);
 371        SHA1_Update(&c, buf, len);
 372        SHA1_Final(sha1, &c);
 373
 374        if (returnsha1)
 375                memcpy(returnsha1, sha1, 20);
 376
 377        filename = sha1_file_name(sha1);
 378        fd = open(filename, O_RDONLY);
 379        if (fd >= 0) {
 380                /*
 381                 * FIXME!!! We might do collision checking here, but we'd
 382                 * need to uncompress the old file and check it. Later.
 383                 */
 384                close(fd);
 385                return 0;
 386        }
 387
 388        if (errno != ENOENT) {
 389                fprintf(stderr, "sha1 file %s: %s", filename, strerror(errno));
 390                return -1;
 391        }
 392
 393        snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory());
 394
 395        fd = mkstemp(tmpfile);
 396        if (fd < 0) {
 397                fprintf(stderr, "unable to create temporary sha1 filename %s: %s", tmpfile, strerror(errno));
 398                return -1;
 399        }
 400
 401        /* Set it up */
 402        memset(&stream, 0, sizeof(stream));
 403        deflateInit(&stream, Z_BEST_COMPRESSION);
 404        size = deflateBound(&stream, len+hdrlen);
 405        compressed = xmalloc(size);
 406
 407        /* Compress it */
 408        stream.next_out = compressed;
 409        stream.avail_out = size;
 410
 411        /* First header.. */
 412        stream.next_in = hdr;
 413        stream.avail_in = hdrlen;
 414        while (deflate(&stream, 0) == Z_OK)
 415                /* nothing */
 416
 417        /* Then the data itself.. */
 418        stream.next_in = buf;
 419        stream.avail_in = len;
 420        while (deflate(&stream, Z_FINISH) == Z_OK)
 421                /* nothing */;
 422        deflateEnd(&stream);
 423        size = stream.total_out;
 424
 425        if (write(fd, compressed, size) != size)
 426                die("unable to write file");
 427        fchmod(fd, 0444);
 428        close(fd);
 429        free(compressed);
 430
 431        ret = link(tmpfile, filename);
 432        if (ret < 0) {
 433                ret = errno;
 434
 435                /*
 436                 * Coda hack - coda doesn't like cross-directory links,
 437                 * so we fall back to a rename, which will mean that it
 438                 * won't be able to check collisions, but that's not a
 439                 * big deal.
 440                 *
 441                 * When this succeeds, we just return 0. We have nothing
 442                 * left to unlink.
 443                 */
 444                if (ret == EXDEV && !rename(tmpfile, filename))
 445                        return 0;
 446        }
 447        unlink(tmpfile);
 448        if (ret) {
 449                if (ret != EEXIST) {
 450                        fprintf(stderr, "unable to write sha1 filename %s: %s", filename, strerror(ret));
 451                        return -1;
 452                }
 453                /* FIXME!!! Collision check here ? */
 454        }
 455
 456        return 0;
 457}
 458
 459int write_sha1_from_fd(const unsigned char *sha1, int fd)
 460{
 461        char *filename = sha1_file_name(sha1);
 462
 463        int local;
 464        z_stream stream;
 465        unsigned char real_sha1[20];
 466        char buf[4096];
 467        char discard[4096];
 468        int ret;
 469        SHA_CTX c;
 470
 471        local = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
 472
 473        if (local < 0)
 474                return error("Couldn't open %s\n", filename);
 475
 476        memset(&stream, 0, sizeof(stream));
 477
 478        inflateInit(&stream);
 479
 480        SHA1_Init(&c);
 481
 482        do {
 483                ssize_t size;
 484                size = read(fd, buf, 4096);
 485                if (size <= 0) {
 486                        close(local);
 487                        unlink(filename);
 488                        if (!size)
 489                                return error("Connection closed?");
 490                        perror("Reading from connection");
 491                        return -1;
 492                }
 493                write(local, buf, size);
 494                stream.avail_in = size;
 495                stream.next_in = buf;
 496                do {
 497                        stream.next_out = discard;
 498                        stream.avail_out = sizeof(discard);
 499                        ret = inflate(&stream, Z_SYNC_FLUSH);
 500                        SHA1_Update(&c, discard, sizeof(discard) -
 501                                    stream.avail_out);
 502                } while (stream.avail_in && ret == Z_OK);
 503                
 504        } while (ret == Z_OK);
 505        inflateEnd(&stream);
 506
 507        close(local);
 508        SHA1_Final(real_sha1, &c);
 509        if (ret != Z_STREAM_END) {
 510                unlink(filename);
 511                return error("File %s corrupted", sha1_to_hex(sha1));
 512        }
 513        if (memcmp(sha1, real_sha1, 20)) {
 514                unlink(filename);
 515                return error("File %s has bad hash\n", sha1_to_hex(sha1));
 516        }
 517        
 518        return 0;
 519}
 520
 521int has_sha1_file(const unsigned char *sha1)
 522{
 523        struct stat st;
 524        return !!find_sha1_file(sha1, &st);
 525}
 526
 527int index_fd(unsigned char *sha1, int fd, struct stat *st)
 528{
 529        unsigned long size = st->st_size;
 530        void *buf;
 531        int ret;
 532
 533        buf = "";
 534        if (size)
 535                buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
 536        close(fd);
 537        if ((int)(long)buf == -1)
 538                return -1;
 539
 540        ret = write_sha1_file(buf, size, "blob", sha1);
 541        if (size)
 542                munmap(buf, size);
 543        return ret;
 544}