/* Entries other than a regular file or a folder are skipped. */
type = archive_entry_filetype(entry);
- if ((type != AE_IFREG) & (type != AE_IFDIR)) {
+ if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Filetype not supported");
return ARCHIVE_FAILED;
/* Initialize the CRC variable and potentially the local crc32(). */
l->crc32 = crc32(0, NULL, 0);
- l->compression = zip->compression;
- l->compressed_size = 0;
+ if (type == AE_IFLNK) {
+ const char *p = archive_entry_symlink(l->entry);
+ if (p != NULL)
+ size = strlen(p);
+ else
+ size = 0;
+ zip->remaining_data_bytes = 0;
+ archive_entry_set_size(l->entry, size);
+ l->compression = COMPRESSION_STORE;
+ l->compressed_size = size;
+ } else {
+ l->compression = zip->compression;
+ l->compressed_size = 0;
+ }
l->next = NULL;
if (zip->central_directory == NULL) {
zip->central_directory = l;
archive_le32enc(&h.signature, ZIP_SIGNATURE_LOCAL_FILE_HEADER);
archive_le16enc(&h.version, ZIP_VERSION_EXTRACT);
archive_le16enc(&h.flags, l->flags);
- archive_le16enc(&h.compression, zip->compression);
+ archive_le16enc(&h.compression, l->compression);
archive_le32enc(&h.timedate, dos_time(archive_entry_mtime(entry)));
archive_le16enc(&h.filename_length, (uint16_t)path_length(l->entry));
- switch (zip->compression) {
+ switch (l->compression) {
case COMPRESSION_STORE:
/* Setting compressed and uncompressed sizes even when
* specification says to set to zero when using data
return (ARCHIVE_FATAL);
zip->written_bytes += sizeof(e);
+ if (type == AE_IFLNK) {
+ const unsigned char *p;
+
+ p = (const unsigned char *)archive_entry_symlink(l->entry);
+ ret = __archive_write_output(a, p, size);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->written_bytes += size;
+ l->crc32 = crc32(l->crc32, p, size);
+ }
+
if (ret2 != ARCHIVE_OK)
return (ret2);
return (ARCHIVE_OK);
if (s == 0) return 0;
- switch (zip->compression) {
+ switch (l->compression) {
case COMPRESSION_STORE:
ret = __archive_write_output(a, buff, s);
if (ret != ARCHIVE_OK) return (ret);
size_t reminder;
#endif
- switch(zip->compression) {
+ switch(l->compression) {
case COMPRESSION_STORE:
break;
#if HAVE_ZLIB_H
archive_read_data(a, filedata, sizeof(filedata)));
assertEqualMem(filedata, "1234", 4);
+ /*
+ * Read the third file back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("symlink", archive_entry_pathname(ae));
+ if (expect_details) {
+ assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualString("file1", archive_entry_symlink(ae));
+ } else {
+ assertEqualInt(AE_IFREG | 0777, archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ }
+
/*
* Read the dir entry back.
*/
assertEqualInt(10, archive_entry_mtime_nsec(ae));
archive_entry_copy_pathname(ae, "file");
assertEqualString("file", archive_entry_pathname(ae));
- archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
archive_entry_set_size(ae, 8);
assertEqualInt(10, archive_entry_mtime_nsec(ae));
archive_entry_copy_pathname(ae, "file2");
assertEqualString("file2", archive_entry_pathname(ae));
- archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_mode(ae, AE_IFREG | 0755);
assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
archive_entry_set_size(ae, 4);
archive_entry_free(ae);
assertEqualInt(4, archive_write_data(a, "1234", 5));
+ /*
+ * Write symbolic like file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "symlink");
+ assertEqualString("symlink", archive_entry_pathname(ae));
+ archive_entry_copy_symlink(ae, "file1");
+ assertEqualString("file1", archive_entry_symlink(ae));
+ archive_entry_set_mode(ae, AE_IFLNK | 0755);
+ assertEqualInt((S_IFLNK | 0755), archive_entry_mode(ae));
+ archive_entry_set_size(ae, 4);
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+
/*
* Write a directory to it.
*/