[PATCH] Additional functions for the objects database
authorDaniel Barkalow <barkalow@iabervon.org>
Sun, 24 Apr 2005 01:47:23 +0000 (18:47 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sun, 24 Apr 2005 01:47:23 +0000 (18:47 -0700)
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 <barkalow@iabervon.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
cache.h
sha1_file.c

diff --git a/cache.h b/cache.h
index bf30ac4..794d676 100644 (file)
--- 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! */
index 66308ed..97a515a 100644 (file)
@@ -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;
+}