diff options
author | Rene Scharfe <rene.scharfe@lsrfire.ath.cx> | 2006-10-07 01:47:35 +0200 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-10-07 23:16:54 -0700 |
commit | 62cdce17c57a28240048c5064fab57edae19657f (patch) | |
tree | 6cfdc218c3fdbccbb88e1f5ce31531aaa465071e /archive-zip.c | |
parent | cf72fb07b77c73b4777b6a2e0836e3029c5f0f3c (diff) | |
download | git-62cdce17c57a28240048c5064fab57edae19657f.tar.gz git-62cdce17c57a28240048c5064fab57edae19657f.tar.xz |
git-archive --format=zip: add symlink support
Add symlink support to ZIP file creation, and a few tests.
This implementation sets the "version made by" field
(creator_version) to Unix for symlinks, only; regular files and
directories are still marked as originating from FAT/VFAT/NTFS.
Also set "external file attributes" (attr2) to 0 for regular
files and 16 for directories (FAT attribute), and to the file
mode for symlinks.
We could always set the creator_version to Unix and include the
mode, but then Info-ZIP unzip would set the mode of the extracted
files to *exactly* the value stored in attr2. The FAT trick
makes it apply the umask instead. Note: FAT has no executable
bit, so this information is not stored in the ZIP file.
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'archive-zip.c')
-rw-r--r-- | archive-zip.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/archive-zip.c b/archive-zip.c index ae7462353..28e7352e9 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -145,6 +145,7 @@ static int write_zip_entry(const unsigned char *sha1, { struct zip_local_header header; struct zip_dir_header dirent; + unsigned long attr2; unsigned long compressed_size; unsigned long uncompressed_size; unsigned long crc; @@ -172,12 +173,16 @@ static int write_zip_entry(const unsigned char *sha1, if (S_ISDIR(mode)) { method = 0; + attr2 = 16; result = READ_TREE_RECURSIVE; out = NULL; uncompressed_size = 0; compressed_size = 0; - } else if (S_ISREG(mode)) { - method = zlib_compression_level == 0 ? 0 : 8; + } else if (S_ISREG(mode) || S_ISLNK(mode)) { + method = 0; + attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) : 0; + if (S_ISREG(mode) && zlib_compression_level != 0) + method = 8; result = 0; buffer = read_sha1_file(sha1, type, &size); if (!buffer) @@ -213,7 +218,7 @@ static int write_zip_entry(const unsigned char *sha1, } copy_le32(dirent.magic, 0x02014b50); - copy_le16(dirent.creator_version, 0); + copy_le16(dirent.creator_version, S_ISLNK(mode) ? 0x0317 : 0); copy_le16(dirent.version, 10); copy_le16(dirent.flags, 0); copy_le16(dirent.compression_method, method); @@ -227,7 +232,7 @@ static int write_zip_entry(const unsigned char *sha1, copy_le16(dirent.comment_length, 0); copy_le16(dirent.disk, 0); copy_le16(dirent.attr1, 0); - copy_le32(dirent.attr2, 0); + copy_le32(dirent.attr2, attr2); copy_le32(dirent.offset, zip_offset); memcpy(zip_dir + zip_dir_offset, &dirent, sizeof(struct zip_dir_header)); zip_dir_offset += sizeof(struct zip_dir_header); |