]> git.ipfire.org Git - thirdparty/git.git/blobdiff - archive-zip.c
Sync with maint
[thirdparty/git.git] / archive-zip.c
index 5a62351ab1a46f6a0827a7d41e794c00a4839edc..11f5b1974ba433fd77f9558528a053e4e2bb0a88 100644 (file)
@@ -24,6 +24,11 @@ static unsigned int max_creator_version;
 #define ZIP_STREAM     (1 <<  3)
 #define ZIP_UTF8       (1 << 11)
 
+enum zip_method {
+       ZIP_METHOD_STORE = 0,
+       ZIP_METHOD_DEFLATE = 8
+};
+
 struct zip_local_header {
        unsigned char magic[4];
        unsigned char version[2];
@@ -264,9 +269,10 @@ static int has_only_ascii(const char *s)
        }
 }
 
-static int entry_is_binary(const char *path, const void *buffer, size_t size)
+static int entry_is_binary(struct index_state *istate, const char *path,
+                          const void *buffer, size_t size)
 {
-       struct userdiff_driver *driver = userdiff_find_by_path(path);
+       struct userdiff_driver *driver = userdiff_find_by_path(istate, path);
        if (!driver)
                driver = userdiff_find_by_name("default");
        if (driver->binary != -1)
@@ -290,7 +296,7 @@ static int write_zip_entry(struct archiver_args *args,
        unsigned long attr2;
        unsigned long compressed_size;
        unsigned long crc;
-       int method;
+       enum zip_method method;
        unsigned char *out;
        void *deflated = NULL;
        void *buffer;
@@ -319,7 +325,7 @@ static int write_zip_entry(struct archiver_args *args,
        }
 
        if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
-               method = 0;
+               method = ZIP_METHOD_STORE;
                attr2 = 16;
                out = NULL;
                size = 0;
@@ -329,13 +335,13 @@ static int write_zip_entry(struct archiver_args *args,
                enum object_type type = oid_object_info(args->repo, oid,
                                                        &size);
 
-               method = 0;
+               method = ZIP_METHOD_STORE;
                attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) :
                        (mode & 0111) ? ((mode) << 16) : 0;
                if (S_ISLNK(mode) || (mode & 0111))
                        creator_version = 0x0317;
                if (S_ISREG(mode) && args->compression_level != 0 && size > 0)
-                       method = 8;
+                       method = ZIP_METHOD_DEFLATE;
 
                if (S_ISREG(mode) && type == OBJ_BLOB && !args->convert &&
                    size > big_file_threshold) {
@@ -352,11 +358,12 @@ static int write_zip_entry(struct archiver_args *args,
                                return error(_("cannot read %s"),
                                             oid_to_hex(oid));
                        crc = crc32(crc, buffer, size);
-                       is_binary = entry_is_binary(path_without_prefix,
+                       is_binary = entry_is_binary(args->repo->index,
+                                                   path_without_prefix,
                                                    buffer, size);
                        out = buffer;
                }
-               compressed_size = (method == 0) ? size : 0;
+               compressed_size = (method == ZIP_METHOD_STORE) ? size : 0;
        } else {
                return error(_("unsupported file mode: 0%o (SHA1: %s)"), mode,
                                oid_to_hex(oid));
@@ -365,13 +372,13 @@ static int write_zip_entry(struct archiver_args *args,
        if (creator_version > max_creator_version)
                max_creator_version = creator_version;
 
-       if (buffer && method == 8) {
+       if (buffer && method == ZIP_METHOD_DEFLATE) {
                out = deflated = zlib_deflate_raw(buffer, size,
                                                  args->compression_level,
                                                  &compressed_size);
                if (!out || compressed_size >= size) {
                        out = buffer;
-                       method = 0;
+                       method = ZIP_METHOD_STORE;
                        compressed_size = size;
                }
        }
@@ -418,7 +425,7 @@ static int write_zip_entry(struct archiver_args *args,
                zip_offset += ZIP64_EXTRA_SIZE;
        }
 
-       if (stream && method == 0) {
+       if (stream && method == ZIP_METHOD_STORE) {
                unsigned char buf[STREAM_BUFFER_SIZE];
                ssize_t readlen;
 
@@ -428,7 +435,8 @@ static int write_zip_entry(struct archiver_args *args,
                                break;
                        crc = crc32(crc, buf, readlen);
                        if (is_binary == -1)
-                               is_binary = entry_is_binary(path_without_prefix,
+                               is_binary = entry_is_binary(args->repo->index,
+                                                           path_without_prefix,
                                                            buf, readlen);
                        write_or_die(1, buf, readlen);
                }
@@ -440,7 +448,7 @@ static int write_zip_entry(struct archiver_args *args,
                zip_offset += compressed_size;
 
                write_zip_data_desc(size, compressed_size, crc);
-       } else if (stream && method == 8) {
+       } else if (stream && method == ZIP_METHOD_DEFLATE) {
                unsigned char buf[STREAM_BUFFER_SIZE];
                ssize_t readlen;
                git_zstream zstream;
@@ -460,7 +468,8 @@ static int write_zip_entry(struct archiver_args *args,
                                break;
                        crc = crc32(crc, buf, readlen);
                        if (is_binary == -1)
-                               is_binary = entry_is_binary(path_without_prefix,
+                               is_binary = entry_is_binary(args->repo->index,
+                                                           path_without_prefix,
                                                            buf, readlen);
 
                        zstream.next_in = buf;
@@ -573,7 +582,7 @@ static void write_zip64_trailer(void)
        write_or_die(1, &locator64, ZIP64_DIR_TRAILER_LOCATOR_SIZE);
 }
 
-static void write_zip_trailer(const unsigned char *sha1)
+static void write_zip_trailer(const struct object_id *oid)
 {
        struct zip_dir_trailer trailer;
        int clamped = 0;
@@ -586,31 +595,31 @@ static void write_zip_trailer(const unsigned char *sha1)
        copy_le16_clamp(trailer.entries, zip_dir_entries, &clamped);
        copy_le32(trailer.size, zip_dir.len);
        copy_le32_clamp(trailer.offset, zip_offset, &clamped);
-       copy_le16(trailer.comment_length, sha1 ? GIT_SHA1_HEXSZ : 0);
+       copy_le16(trailer.comment_length, oid ? the_hash_algo->hexsz : 0);
 
        write_or_die(1, zip_dir.buf, zip_dir.len);
        if (clamped)
                write_zip64_trailer();
        write_or_die(1, &trailer, ZIP_DIR_TRAILER_SIZE);
-       if (sha1)
-               write_or_die(1, sha1_to_hex(sha1), GIT_SHA1_HEXSZ);
+       if (oid)
+               write_or_die(1, oid_to_hex(oid), the_hash_algo->hexsz);
 }
 
 static void dos_time(timestamp_t *timestamp, int *dos_date, int *dos_time)
 {
        time_t time;
-       struct tm *t;
+       struct tm tm;
 
        if (date_overflows(*timestamp))
                die(_("timestamp too large for this system: %"PRItime),
                    *timestamp);
        time = (time_t)*timestamp;
-       t = localtime(&time);
+       localtime_r(&time, &tm);
        *timestamp = time;
 
-       *dos_date = t->tm_mday + (t->tm_mon + 1) * 32 +
-                   (t->tm_year + 1900 - 1980) * 512;
-       *dos_time = t->tm_sec / 2 + t->tm_min * 32 + t->tm_hour * 2048;
+       *dos_date = tm.tm_mday + (tm.tm_mon + 1) * 32 +
+                   (tm.tm_year + 1900 - 1980) * 512;
+       *dos_time = tm.tm_sec / 2 + tm.tm_min * 32 + tm.tm_hour * 2048;
 }
 
 static int archive_zip_config(const char *var, const char *value, void *data)
@@ -631,7 +640,7 @@ static int write_zip_archive(const struct archiver *ar,
 
        err = write_archive_entries(args, write_zip_entry);
        if (!err)
-               write_zip_trailer(args->commit_sha1);
+               write_zip_trailer(args->commit_oid);
 
        strbuf_release(&zip_dir);