Merge branch 'master' into pb/gitpm
[gitweb.git] / sha1_file.c
index 3db956dd5c96c6563a9505775570fbdfb4a8b720..ed52d71a1b01a20e61d736568983cb7a9c0d6b39 100644 (file)
@@ -126,16 +126,22 @@ static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
 char *sha1_file_name(const unsigned char *sha1)
 {
        static char *name, *base;
+       static const char *last_objdir;
+       const char *sha1_file_directory = get_object_directory();
 
-       if (!base) {
-               const char *sha1_file_directory = get_object_directory();
+       if (!last_objdir || strcmp(last_objdir, sha1_file_directory)) {
                int len = strlen(sha1_file_directory);
+               if (base)
+                       free(base);
                base = xmalloc(len + 60);
                memcpy(base, sha1_file_directory, len);
                memset(base+len, 0, 60);
                base[len] = '/';
                base[len+3] = '/';
                name = base + len + 1;
+               if (last_objdir)
+                       free((char *) last_objdir);
+               last_objdir = strdup(sha1_file_directory);
        }
        fill_sha1_path(name, sha1);
        return base;
@@ -145,14 +151,20 @@ char *sha1_pack_name(const unsigned char *sha1)
 {
        static const char hex[] = "0123456789abcdef";
        static char *name, *base, *buf;
+       static const char *last_objdir;
+       const char *sha1_file_directory = get_object_directory();
        int i;
 
-       if (!base) {
-               const char *sha1_file_directory = get_object_directory();
+       if (!last_objdir || strcmp(last_objdir, sha1_file_directory)) {
                int len = strlen(sha1_file_directory);
+               if (base)
+                       free(base);
                base = xmalloc(len + 60);
                sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.pack", sha1_file_directory);
                name = base + len + 11;
+               if (last_objdir)
+                       free((char *) last_objdir);
+               last_objdir = strdup(sha1_file_directory);
        }
 
        buf = name;
@@ -170,14 +182,20 @@ char *sha1_pack_index_name(const unsigned char *sha1)
 {
        static const char hex[] = "0123456789abcdef";
        static char *name, *base, *buf;
+       static const char *last_objdir;
+       const char *sha1_file_directory = get_object_directory();
        int i;
 
-       if (!base) {
-               const char *sha1_file_directory = get_object_directory();
+       if (!last_objdir || strcmp(last_objdir, sha1_file_directory)) {
                int len = strlen(sha1_file_directory);
+               if (base)
+                       free(base);
                base = xmalloc(len + 60);
                sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.idx", sha1_file_directory);
                name = base + len + 11;
+               if (last_objdir)
+                       free((char *) last_objdir);
+               last_objdir = strdup(sha1_file_directory);
        }
 
        buf = name;
@@ -646,8 +664,7 @@ int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long siz
        return memcmp(sha1, real_sha1, 20) ? -1 : 0;
 }
 
-static void *map_sha1_file_internal(const unsigned char *sha1,
-                                   unsigned long *size)
+void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
 {
        struct stat st;
        void *map;
@@ -684,10 +701,26 @@ static void *map_sha1_file_internal(const unsigned char *sha1,
        return map;
 }
 
+int legacy_loose_object(unsigned char *map)
+{
+       unsigned int word;
+
+       /*
+        * Is it a zlib-compressed buffer? If so, the first byte
+        * must be 0x78 (15-bit window size, deflated), and the
+        * first 16-bit word is evenly divisible by 31
+        */
+       word = (map[0] << 8) + map[1];
+       if (map[0] == 0x78 && !(word % 31))
+               return 1;
+       else
+               return 0;
+}
+
 static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
 {
        unsigned char c;
-       unsigned int word, bits;
+       unsigned int bits;
        unsigned long size;
        static const char *typename[8] = {
                NULL,   /* OBJ_EXT */
@@ -703,13 +736,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
        stream->next_out = buffer;
        stream->avail_out = bufsiz;
 
-       /*
-        * Is it a zlib-compressed buffer? If so, the first byte
-        * must be 0x78 (15-bit window size, deflated), and the
-        * first 16-bit word is evenly divisible by 31
-        */
-       word = (map[0] << 8) + map[1];
-       if (map[0] == 0x78 && !(word % 31)) {
+       if (legacy_loose_object(map)) {
                inflateInit(stream);
                return inflate(stream, 0);
        }
@@ -1246,7 +1273,7 @@ int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep
        z_stream stream;
        char hdr[128];
 
-       map = map_sha1_file_internal(sha1, &mapsize);
+       map = map_sha1_file(sha1, &mapsize);
        if (!map) {
                struct pack_entry e;
 
@@ -1291,7 +1318,7 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size
 
        if (find_pack_entry(sha1, &e))
                return read_packed_sha1(sha1, type, size);
-       map = map_sha1_file_internal(sha1, &mapsize);
+       map = map_sha1_file(sha1, &mapsize);
        if (map) {
                buf = unpack_sha1_file(map, mapsize, type, size);
                munmap(map, mapsize);
@@ -1629,7 +1656,7 @@ int write_sha1_to_fd(int fd, const unsigned char *sha1)
 {
        int retval;
        unsigned long objsize;
-       void *buf = map_sha1_file_internal(sha1, &objsize);
+       void *buf = map_sha1_file(sha1, &objsize);
 
        if (buf) {
                retval = write_buffer(fd, buf, objsize);