PERFORCE change 147243 for review
Anselm Strauss
strauss at FreeBSD.org
Tue Aug 12 16:15:55 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=147243
Change 147243 by strauss at strauss_marvelman on 2008/08/12 16:15:24
Added support for folders.
Affected files ...
.. //depot/projects/soc2008/strauss_libarchive/libarchive/archive_write_set_format_zip.c#32 edit
.. //depot/projects/soc2008/strauss_libarchive/libarchive/test/test_write_format_zip_no_compression.c#10 edit
Differences ...
==== //depot/projects/soc2008/strauss_libarchive/libarchive/archive_write_set_format_zip.c#32 (text+ko) ====
@@ -79,6 +79,8 @@
static int archive_write_zip_header(struct archive_write *, struct archive_entry *);
static void zip_encode(uint64_t, void *, size_t);
static unsigned int dos_time(const time_t);
+static size_t path_length(struct archive_entry *);
+static int write_path(struct archive_entry *, struct archive_write *);
struct zip_local_file_header {
char signature[4];
@@ -205,19 +207,19 @@
struct zip_extra_data e;
struct zip_data_descriptor *d;
struct zip_file_header_link *l;
- const char *path;
int ret;
int64_t size;
+ mode_t type;
- /* TODO: Also handle non-regular file entries. */
- if (archive_entry_filetype(entry) != AE_IFREG) {
- archive_set_error(&a->archive, EPERM, "Non-regular files are not yet supported.");
+ /* Entries other than a regular file or a folder are skipped. */
+ type = archive_entry_filetype(entry);
+ if ((type != AE_IFREG) & (type != AE_IFDIR)) {
+ archive_set_error(&a->archive, 0, "Filetype not supported");
return ARCHIVE_FAILED;
};
zip = a->format_data;
- d = &zip->data_descriptor;
- path = archive_entry_pathname(entry);
+ d = &zip->data_descriptor;
size = archive_entry_size(entry);
/* Append archive entry to the central directory data.
@@ -251,7 +253,7 @@
zip_encode(ZIP_VERSION_EXTRACT, &h.version, sizeof(h.version));
zip_encode(ZIP_FLAGS, &h.flags, sizeof(h.flags));
zip_encode(dos_time(archive_entry_mtime(entry)), &h.timedate, sizeof(h.timedate));
- zip_encode(strlen(path), &h.filename_length, sizeof(h.filename_length));
+ zip_encode(path_length(entry), &h.filename_length, sizeof(h.filename_length));
zip_encode(sizeof(e), &h.extra_length, sizeof(h.extra_length));
/* Formatting extra data. */
@@ -279,10 +281,10 @@
return (ARCHIVE_FATAL);
zip->written_bytes += sizeof(h);
- ret = (a->compressor.write)(a, path, strlen(path));
- if (ret != ARCHIVE_OK)
+ ret = write_path(entry, a);
+ if (ret <= ARCHIVE_OK)
return (ARCHIVE_FATAL);
- zip->written_bytes += strlen(path);
+ zip->written_bytes += ret;
ret = (a->compressor.write)(a, &e, sizeof(e));
if (ret != ARCHIVE_OK)
@@ -372,7 +374,7 @@
zip_encode(l->crc32, &h.crc32, sizeof(h.crc32));
zip_encode(size, &h.compressed_size, sizeof(h.compressed_size));
zip_encode(size, &h.uncompressed_size, sizeof(h.uncompressed_size));
- zip_encode(strlen(path), &h.filename_length, sizeof(h.filename_length));
+ zip_encode(path_length(l->entry), &h.filename_length, sizeof(h.filename_length));
h.extra_length[0] = l->extra_length[0];
h.extra_length[1] = l->extra_length[1];
zip_encode(l->offset, &h.offset, sizeof(h.offset));
@@ -382,10 +384,10 @@
return (ARCHIVE_FATAL);
zip->written_bytes += sizeof(h);
- ret = (a->compressor.write)(a, path, strlen(path));
- if (ret != ARCHIVE_OK)
+ ret = write_path(l->entry, a);
+ if (ret <= ARCHIVE_OK)
return (ARCHIVE_FATAL);
- zip->written_bytes += strlen(path);
+ zip->written_bytes += ret;
ret = (a->compressor.write)(a, &l->extra_data, sizeof(l->extra_data));
if (ret != ARCHIVE_OK)
@@ -467,3 +469,46 @@
return dos_time;
}
+
+static size_t
+path_length(struct archive_entry *entry)
+{
+ mode_t type;
+ const char *path;
+
+ type = archive_entry_filetype(entry);
+ path = archive_entry_pathname(entry);
+
+ if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
+ return strlen(path) + 1;
+ } else {
+ return strlen(path);
+ }
+}
+
+static int
+write_path(struct archive_entry *entry, struct archive_write *archive)
+{
+ int ret;
+ const char *path;
+ mode_t type;
+ size_t written_bytes;
+
+ path = archive_entry_pathname(entry);
+ type = archive_entry_filetype(entry);
+ written_bytes = 0;
+
+ ret = (archive->compressor.write)(archive, path, strlen(path));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ written_bytes += strlen(path);
+
+ if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
+ ret = (archive->compressor.write)(archive, "/", 1);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ written_bytes += 1;
+ }
+
+ return written_bytes;
+}
==== //depot/projects/soc2008/strauss_libarchive/libarchive/test/test_write_format_zip_no_compression.c#10 (text+ko) ====
@@ -40,8 +40,11 @@
const char *p, *q, *buffend;
size_t used;
int crc;
- const time_t t = time(NULL);
- struct tm *tm = localtime(&t);
+ time_t t;
+ struct tm *tm;
+
+ t = time(NULL);
+ tm = localtime(&t);
/* Create new ZIP archive in memory without padding. */
assert((a = archive_write_new()) != NULL);
@@ -56,7 +59,7 @@
/* Regular file */
assert((entry = archive_entry_new()) != NULL);
archive_entry_set_pathname(entry, "file");
- archive_entry_set_mode(entry, S_IFREG | 0664);
+ archive_entry_set_mode(entry, S_IFREG | 0644);
archive_entry_set_size(entry, 10);
archive_entry_set_uid(entry, 80);
archive_entry_set_gid(entry, 90);
@@ -69,7 +72,19 @@
assertEqualIntA(a, sizeof(data2), archive_write_data(a, data2, sizeof(data2)));
archive_entry_free(entry);
- /* TODO: Also test non-regular file and directory entries. */
+ /* Folder */
+ /*assert((entry = archive_entry_new()) != NULL);
+ archive_entry_set_pathname(entry, "folder");
+ archive_entry_set_mode(entry, S_IFDIR | 0755);
+ archive_entry_set_size(entry, 0);
+ archive_entry_set_uid(entry, 80);
+ archive_entry_set_gid(entry, 90);
+ archive_entry_set_dev(entry, 12);
+ archive_entry_set_ino(entry, 89);
+ archive_entry_set_nlink(entry, 1);
+ archive_entry_set_mtime(entry, t, 0);
+ assertEqualIntA(a, 0, archive_write_header(a, entry));
+ archive_entry_free(entry);*/
/* Close out the archive . */
assertA(0 == archive_write_close(a));
More information about the p4-projects
mailing list