From: Tim Kientzle Date: Sat, 1 Aug 2009 05:30:24 +0000 (-0400) Subject: Conditionalize link, symlink, and lstat support. X-Git-Tag: v2.8.0~479 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b57c013d7b5a69071b98fc2f1e026bdc22fcb14;p=thirdparty%2Flibarchive.git Conditionalize link, symlink, and lstat support. SVN-Revision: 1304 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index c0c4c89f3..12ec0e8b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -287,10 +287,10 @@ CHECK_FUNCTION_EXISTS(SHA512_Init HAVE_SHA512) CHECK_FUNCS(chflags chown chroot) CHECK_FUNCS(fchdir fchflags fchmod fchown fcntl fork) CHECK_FUNCS(fstat ftruncate futimes geteuid getpid) -CHECK_FUNCS(lchflags lchmod lchown) +CHECK_FUNCS(lchflags lchmod lchown link lstat) CHECK_FUNCS(lutimes memmove memset mkdir mkfifo mknod) CHECK_FUNCS(nl_langinfo pipe poll readlink select setenv setlocale) -CHECK_FUNCS(strchr strdup strerror strrchr timegm) +CHECK_FUNCS(strchr strdup strerror strrchr symlink timegm) CHECK_FUNCS(tzset unsetenv utime utimes vfork) CHECK_FUNCS(wcrtomb wcscpy wcslen wctomb wmemcmp wmemcpy) diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in index b260b1cb5..b24016bfa 100644 --- a/build/cmake/config.h.in +++ b/build/cmake/config.h.in @@ -223,6 +223,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LIMITS_H 1 +/* Define to 1 if you have the link() function. */ +#cmakedefine HAVE_LINK 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LINUX_FS_H 1 @@ -241,6 +244,9 @@ /* Define to 1 if you have the `lsetxattr' function. */ #cmakedefine HAVE_LSETXATTR 1 +/* Define to 1 if you have the `lstat' function. */ +#cmakedefine HAVE_LSTAT 1 + /* Define to 1 if `lstat' has the bug that it succeeds when given the zero-length file name argument. */ #cmakedefine HAVE_LSTAT_EMPTY_STRING_BUG 1 @@ -426,6 +432,9 @@ /* Define to 1 if `st_umtime' is member of `struct stat'. */ #cmakedefine HAVE_STRUCT_STAT_ST_UMTIME 1 +/* Define to 1 if you have the symlink() function. */ +#cmakedefine HAVE_SYMLINK 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_ACL_H 1 diff --git a/configure.ac b/configure.ac index 3b72e3d15..756bcbc37 100644 --- a/configure.ac +++ b/configure.ac @@ -331,10 +331,10 @@ AC_FUNC_VPRINTF AC_CHECK_FUNCS([chflags chown chroot]) AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fork]) AC_CHECK_FUNCS([fstat ftruncate futimes geteuid getpid]) -AC_CHECK_FUNCS([lchflags lchmod lchown]) +AC_CHECK_FUNCS([lchflags lchmod lchown link]) AC_CHECK_FUNCS([lutimes memmove memset mkdir mkfifo mknod]) AC_CHECK_FUNCS([nl_langinfo pipe poll readlink select setenv setlocale]) -AC_CHECK_FUNCS([strchr strdup strerror strrchr timegm]) +AC_CHECK_FUNCS([strchr strdup strerror strrchr symlink timegm]) AC_CHECK_FUNCS([tzset unsetenv utime utimes vfork]) AC_CHECK_FUNCS([wcrtomb wcscpy wcslen wctomb wmemcmp wmemcpy]) # detects cygwin-1.7, as opposed to older versions diff --git a/libarchive/archive_write_disk.c b/libarchive/archive_write_disk.c index 97743de9e..99e15a108 100644 --- a/libarchive/archive_write_disk.c +++ b/libarchive/archive_write_disk.c @@ -1073,6 +1073,9 @@ create_filesystem_object(struct archive_write_disk *a) /* Since link(2) and symlink(2) don't handle modes, we're done here. */ linkname = archive_entry_hardlink(a->entry); if (linkname != NULL) { +#if !HAVE_LINK + return (EPERM); +#else r = link(linkname, a->name) ? errno : 0; /* * New cpio and pax formats allow hardlink entries @@ -1095,10 +1098,16 @@ create_filesystem_object(struct archive_write_disk *a) r = errno; } return (r); +#endif } linkname = archive_entry_symlink(a->entry); - if (linkname != NULL) + if (linkname != NULL) { +#if HAVE_SYMLINK return symlink(linkname, a->name) ? errno : 0; +#else + return (EPERM); +#endif + } /* * The remaining system calls all set permissions, so let's @@ -1398,9 +1407,15 @@ current_fixup(struct archive_write_disk *a, const char *pathname) * scan the path and both can be optimized by comparing against other * recent paths. */ +/* TODO: Extend this to support symlinks on Windows Vista and later. */ static int check_symlinks(struct archive_write_disk *a) { +#if !defined(HAVE_LSTAT) + /* Platform doesn't have lstat, so we can't look for symlinks. */ + (void)a; /* UNUSED */ + return (ARCHIVE_OK); +#else char *pn, *p; char c; int r; @@ -1481,6 +1496,7 @@ check_symlinks(struct archive_write_disk *a) /* We've checked and/or cleaned the whole path, so remember it. */ archive_strcpy(&a->path_safe, a->name); return (ARCHIVE_OK); +#endif } #if defined(_WIN32) || defined(__CYGWIN__) diff --git a/libarchive/config_freebsd.h b/libarchive/config_freebsd.h index 5272fcb39..f8224b322 100644 --- a/libarchive/config_freebsd.h +++ b/libarchive/config_freebsd.h @@ -73,6 +73,8 @@ #define HAVE_LCHMOD 1 #define HAVE_LCHOWN 1 #define HAVE_LIMITS_H 1 +#define HAVE_LINK 1 +#define HAVE_LSTAT 1 #define HAVE_LUTIMES 1 #define HAVE_MALLOC 1 #define HAVE_MD5 1 @@ -114,6 +116,7 @@ #define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1 #define HAVE_STRUCT_STAT_ST_FLAGS 1 #define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1 +#define HAVE_SYMLINK 1 #define HAVE_SYS_IOCTL_H 1 #define HAVE_SYS_SELECT_H 1 #define HAVE_SYS_STAT_H 1