X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=sha1_file.c;h=8f577985afd89ef04a87b4373b5f1d4561600122;hb=aac17941320f7f73e5d411b152bfd041572e8a66;hp=ced079184702fad6f1e79a3b90aa4fc317aa0b88;hpb=ca4c7db9ef0e3ea95a768defeeaa7bea0f0b3dc6;p=git.git diff --git a/sha1_file.c b/sha1_file.c index ced079184..8f577985a 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -284,8 +284,9 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha unsigned char sha1[20]; SHA_CTX c; char *filename; + static char tmpfile[PATH_MAX]; char hdr[50]; - int fd, hdrlen; + int fd, hdrlen, ret; /* Generate the header */ hdrlen = sprintf(hdr, "%s %lu", type, len)+1; @@ -300,18 +301,28 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha memcpy(returnsha1, sha1, 20); filename = sha1_file_name(sha1); - fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666); - if (fd < 0) { - if (errno != EEXIST) - return -1; - + fd = open(filename, O_RDONLY); + if (fd >= 0) { /* - * We might do collision checking here, but we'd need to - * uncompress the old file and check it. Later. + * FIXME!!! We might do collision checking here, but we'd + * need to uncompress the old file and check it. Later. */ + close(fd); return 0; } + if (errno != ENOENT) { + fprintf(stderr, "sha1 file %s: %s", filename, strerror(errno)); + return -1; + } + + snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory()); + fd = mkstemp(tmpfile); + if (fd < 0) { + fprintf(stderr, "unable to create temporary sha1 filename %s: %s", tmpfile, strerror(errno)); + return -1; + } + /* Set it up */ memset(&stream, 0, sizeof(stream)); deflateInit(&stream, Z_BEST_COMPRESSION); @@ -338,54 +349,21 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha if (write(fd, compressed, size) != size) die("unable to write file"); + fchmod(fd, 0444); close(fd); - - return 0; -} - -static inline int collision_check(char *filename, void *buf, unsigned int size) -{ -#ifdef COLLISION_CHECK - void *map; - int fd = open(filename, O_RDONLY); - struct stat st; - int cmp; - /* Unreadable object, or object went away? Strange. */ - if (fd < 0) - return -1; - - if (fstat(fd, &st) < 0 || size != st.st_size) - return -1; - - map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); - close(fd); - if (map == MAP_FAILED) - return -1; - cmp = memcmp(buf, map, size); - munmap(map, size); - if (cmp) - return -1; -#endif - return 0; -} - -int write_sha1_buffer(const unsigned char *sha1, void *buf, unsigned int size) -{ - char *filename = sha1_file_name(sha1); - int fd; - - fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666); - if (fd < 0) { - if (errno != EEXIST) + ret = link(tmpfile, filename); + if (ret < 0) + ret = errno; + unlink(tmpfile); + if (ret) { + if (ret != EEXIST) { + fprintf(stderr, "unable to write sha1 filename %s: %s", filename, strerror(ret)); return -1; - if (collision_check(filename, buf, size)) - return error("SHA1 collision detected!" - " This is bad, bad, BAD!\a\n"); - return 0; + } + /* FIXME!!! Collision check here ? */ } - write(fd, buf, size); - close(fd); + return 0; } @@ -460,3 +438,22 @@ int has_sha1_file(const unsigned char *sha1) return 1; return 0; } + +int index_fd(unsigned char *sha1, int fd, struct stat *st) +{ + unsigned long size = st->st_size; + void *buf; + int ret; + + buf = ""; + if (size) + buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + close(fd); + if ((int)(long)buf == -1) + return -1; + + ret = write_sha1_file(buf, size, "blob", sha1); + if (size) + munmap(buf, size); + return ret; +}