Module Name: src
Committed By: christos
Date: Thu Dec 3 20:00:12 UTC 2015
Modified Files:
src/usr.bin/unzip: unzip.c
Log Message:
PR/50496: Alex Kozlov: teach unzip to extract symlinks
Our libarchive does not handle symliks yet, but later versions do.
Set mode and times for symlinks. Finally handle hardlinks for
completion although they are not handled yet by librarchive.
To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/usr.bin/unzip/unzip.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/unzip/unzip.c
diff -u src/usr.bin/unzip/unzip.c:1.19 src/usr.bin/unzip/unzip.c:1.20
--- src/usr.bin/unzip/unzip.c:1.19 Tue Sep 6 14:43:41 2011
+++ src/usr.bin/unzip/unzip.c Thu Dec 3 15:00:12 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: unzip.c,v 1.19 2011/09/06 18:43:41 joerg Exp $ */
+/* $NetBSD: unzip.c,v 1.20 2015/12/03 20:00:12 christos Exp $ */
/*-
* Copyright (c) 2009, 2010 Joerg Sonnenberger <[email protected]>
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: unzip.c,v 1.19 2011/09/06 18:43:41 joerg Exp $");
+__RCSID("$NetBSD: unzip.c,v 1.20 2015/12/03 20:00:12 christos Exp $");
#include <sys/queue.h>
#include <sys/stat.h>
@@ -131,7 +131,6 @@ errorx(const char *fmt, ...)
exit(1);
}
-#if 0
/* non-fatal error message + errno */
__printflike(1, 2) static void
warning(const char *fmt, ...)
@@ -147,7 +146,7 @@ warning(const char *fmt, ...)
va_end(ap);
fprintf(stderr, ": %s\n", strerror(errno));
}
-#endif
+
/* non-fatal error message, no errno */
__printflike(1, 2) static void
warningx(const char *fmt, ...)
@@ -499,6 +498,7 @@ extract_file(struct archive *a, struct a
int cr, fd, text, warn, check;
ssize_t len;
unsigned char *p, *q, *end;
+ const char *linkname;
mode = archive_entry_mode(e) & 0777;
if (mode == 0)
@@ -531,6 +531,32 @@ recheck:
return;
}
+ /* process symlinks */
+ linkname = archive_entry_symlink(e);
+ if (linkname != NULL) {
+ if (symlink(linkname, *path) == -1)
+ error("symlink('%s', '%s')", linkname, *path);
+ info(" extracting: %s -> %s\n", *path, linkname);
+ if (lchmod(*path, mode) == -1)
+ warning("Cannot set mode for '%s'", *path);
+ tv[0].tv_sec = now;
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = mtime;
+ tv[1].tv_usec = 0;
+ if (lutimes(*path, tv) == -1)
+ warning("utimes('%s')", *path);
+ return;
+ }
+
+ /* process hardlinks */
+ linkname = archive_entry_hardlink(e);
+ if (linkname != NULL) {
+ if (link(linkname, *path) == -1)
+ error("link('%s', '%s')", linkname, *path);
+ info(" extracting: %s link to %s\n", *path, linkname);
+ return;
+ }
+
if ((fd = open(*path, O_RDWR|O_CREAT|O_TRUNC, mode)) < 0)
error("open('%s')", *path);
@@ -658,7 +684,7 @@ extract(struct archive *a, struct archiv
}
/* I don't think this can happen in a zipfile.. */
- if (!S_ISDIR(filetype) && !S_ISREG(filetype)) {
+ if (!S_ISDIR(filetype) && !S_ISREG(filetype) && !S_ISLNK(filetype)) {
warningx("skipping non-regular entry '%s'", pathname);
ac(archive_read_data_skip(a));
free(pathname);
@@ -714,7 +740,7 @@ extract_stdout(struct archive *a, struct
filetype = archive_entry_filetype(e);
/* I don't think this can happen in a zipfile.. */
- if (!S_ISDIR(filetype) && !S_ISREG(filetype)) {
+ if (!S_ISDIR(filetype) && !S_ISREG(filetype) && !S_ISLNK(filetype)) {
warningx("skipping non-regular entry '%s'", pathname);
ac(archive_read_data_skip(a));
free(pathname);