From: Daniel Barkalow Date: Sun, 24 Apr 2005 01:47:23 +0000 (-0700) Subject: [PATCH] Additional functions for the objects database X-Git-Tag: v0.99~767 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=8237b1854c64492ab5772994b4ac4efd7f1c2fc0;p=git.git [PATCH] Additional functions for the objects database This adds two functions: one to check if an object is present in the local database, and one to add an object to the local database by reading it from a file descriptor and checking its hash. Signed-Off-By: Daniel Barkalow Signed-off-by: Linus Torvalds --- diff --git a/cache.h b/cache.h index bf30ac47..794d676a 100644 --- a/cache.h +++ b/cache.h @@ -122,11 +122,16 @@ extern void * map_sha1_file(const unsigned char *sha1, unsigned long *size); extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size); extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size); extern int write_sha1_file(char *buf, unsigned len, unsigned char *return_sha1); + extern int check_sha1_signature(unsigned char *sha1, void *buf, unsigned long size, const char *type); /* Read a tree into the cache */ extern int read_tree(void *buffer, unsigned long size, int stage); +extern int write_sha1_from_fd(const unsigned char *sha1, int fd); + +extern int has_sha1_file(const unsigned char *sha1); + /* Convert to/from hex/sha1 representation */ extern int get_sha1_hex(const char *hex, unsigned char *sha1); extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */ diff --git a/sha1_file.c b/sha1_file.c index 66308ede..97a515a0 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -328,3 +328,75 @@ int write_sha1_buffer(const unsigned char *sha1, void *buf, unsigned int size) close(fd); return 0; } + +int write_sha1_from_fd(const unsigned char *sha1, int fd) +{ + char *filename = sha1_file_name(sha1); + + int local; + z_stream stream; + unsigned char real_sha1[20]; + char buf[4096]; + char discard[4096]; + int ret; + SHA_CTX c; + + local = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666); + + if (local < 0) + return error("Couldn't open %s\n", filename); + + memset(&stream, 0, sizeof(stream)); + + inflateInit(&stream); + + SHA1_Init(&c); + + do { + ssize_t size; + size = read(fd, buf, 4096); + if (size <= 0) { + close(local); + unlink(filename); + if (!size) + return error("Connection closed?"); + perror("Reading from connection"); + return -1; + } + write(local, buf, size); + stream.avail_in = size; + stream.next_in = buf; + do { + stream.next_out = discard; + stream.avail_out = sizeof(discard); + ret = inflate(&stream, Z_SYNC_FLUSH); + SHA1_Update(&c, discard, sizeof(discard) - + stream.avail_out); + } while (stream.avail_in && ret == Z_OK); + + } while (ret == Z_OK); + inflateEnd(&stream); + + close(local); + SHA1_Final(real_sha1, &c); + if (ret != Z_STREAM_END) { + unlink(filename); + return error("File %s corrupted", sha1_to_hex(sha1)); + } + if (memcmp(sha1, real_sha1, 20)) { + unlink(filename); + return error("File %s has bad hash\n", sha1_to_hex(sha1)); + } + + return 0; +} + +int has_sha1_file(const unsigned char *sha1) +{ + char *filename = sha1_file_name(sha1); + struct stat st; + + if (!stat(filename, &st)) + return 1; + return 0; +}