Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Aug 2008 16:15:54 GMT
From:      Anselm Strauss <strauss@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 147243 for review
Message-ID:  <200808121615.m7CGFskg041285@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=147243

Change 147243 by strauss@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));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808121615.m7CGFskg041285>