From: Michihiro NAKAJIMA Date: Fri, 11 Jun 2010 01:06:15 +0000 (-0400) Subject: Add archive_read_disk_current_filesystem_is_synthetic and X-Git-Tag: v3.0.0a~964 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3d450a7f4f6fc42e5c7fc8da53ebe4ed1d93f11;p=thirdparty%2Flibarchive.git Add archive_read_disk_current_filesystem_is_synthetic and archive_read_disk_current_filesystem_is_remote, which provide filesystem information. Currently those are supported on FreeBSD only. I will guradually support other platform. SVN-Revision: 2463 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index c1eba4d2b..6edd1b903 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,6 +242,7 @@ LA_CHECK_INCLUDE_FILE("sys/acl.h" HAVE_SYS_ACL_H) LA_CHECK_INCLUDE_FILE("sys/cdefs.h" HAVE_SYS_CDEFS_H) LA_CHECK_INCLUDE_FILE("sys/ioctl.h" HAVE_SYS_IOCTL_H) LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H) +LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H) LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H) LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H) LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H) @@ -491,6 +492,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID) CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R) CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R) CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID) +CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME) CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R) CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS) CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD) @@ -513,6 +515,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(select HAVE_SELECT) CHECK_FUNCTION_EXISTS_GLIBC(setenv HAVE_SETENV) CHECK_FUNCTION_EXISTS_GLIBC(setlocale HAVE_SETLOCALE) CHECK_FUNCTION_EXISTS_GLIBC(sigaction HAVE_SIGACTION) +CHECK_FUNCTION_EXISTS_GLIBC(statfs HAVE_STATFS) CHECK_FUNCTION_EXISTS_GLIBC(strchr HAVE_STRCHR) CHECK_FUNCTION_EXISTS_GLIBC(strdup HAVE_STRDUP) CHECK_FUNCTION_EXISTS_GLIBC(strerror HAVE_STRERROR) diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in index e6ea5176d..3f64b3a63 100644 --- a/build/cmake/config.h.in +++ b/build/cmake/config.h.in @@ -281,6 +281,9 @@ /* Define to 1 if you have the `getpid' function. */ #cmakedefine HAVE_GETPID 1 +/* Define to 1 if you have the `getvfsbyname' function. */ +#cmakedefine HAVE_GETVFSBYNAME 1 + /* Define to 1 if you have the `getxattr' function. */ #cmakedefine HAVE_GETXATTR 1 @@ -459,6 +462,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SIGNAL_H 1 +/* Define to 1 if you have the `statfs' function. */ +#cmakedefine HAVE_STATFS 1 + /* Define to 1 if `stat' has the bug that it succeeds when given the zero-length file name argument. */ #cmakedefine HAVE_STAT_EMPTY_STRING_BUG 1 @@ -551,6 +557,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_MKDEV_H 1 +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_MOUNT_H 1 + /* Define to 1 if you have the header file, and it defines `DIR'. */ #cmakedefine HAVE_SYS_NDIR_H 1 diff --git a/configure.ac b/configure.ac index 5b8b33d88..da462acdf 100644 --- a/configure.ac +++ b/configure.ac @@ -198,7 +198,8 @@ AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h]) AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h]) AC_CHECK_HEADERS([locale.h paths.h poll.h pwd.h regex.h signal.h stdarg.h]) AC_CHECK_HEADERS([stdint.h stdlib.h string.h]) -AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h sys/ioctl.h sys/mkdev.h]) +AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h sys/ioctl.h]) +AC_CHECK_HEADERS([sys/mkdev.h sys/mount.h]) AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/time.h sys/utime.h]) AC_CHECK_HEADERS([sys/utsname.h time.h unistd.h utime.h wchar.h wctype.h]) AC_CHECK_HEADERS([windows.h winioctl]) @@ -414,11 +415,11 @@ AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *]) AC_CHECK_FUNCS([chflags chown chroot ctime_r]) AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fork]) AC_CHECK_FUNCS([fstat ftruncate futimens futimes geteuid getpid]) -AC_CHECK_FUNCS([getgrnam_r getpwnam_r gmtime_r]) +AC_CHECK_FUNCS([getgrnam_r getpwnam_r getvfsbyname gmtime_r]) AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat]) AC_CHECK_FUNCS([lutimes mbrtowc memmove memset mkdir mkfifo mknod mkstemp]) AC_CHECK_FUNCS([nl_langinfo pipe poll readlink]) -AC_CHECK_FUNCS([select setenv setlocale sigaction]) +AC_CHECK_FUNCS([select setenv setlocale sigaction statfs]) AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm]) AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork]) AC_CHECK_FUNCS([wcrtomb wcscpy wcslen wctomb wmemcmp wmemcpy]) diff --git a/libarchive/archive.h b/libarchive/archive.h index 5edaf1d4a..e318d1d36 100644 --- a/libarchive/archive.h +++ b/libarchive/archive.h @@ -788,6 +788,8 @@ __LA_DECL int archive_read_disk_open(struct archive *, const char *); */ __LA_DECL int archive_read_disk_descend(struct archive *); __LA_DECL int archive_read_disk_current_filesystem(struct archive *); +__LA_DECL int archive_read_disk_current_filesystem_is_synthetic(struct archive *); +__LA_DECL int archive_read_disk_current_filesystem_is_remote(struct archive *); /* * Accessor functions to read/set various information in diff --git a/libarchive/archive_read_disk.c b/libarchive/archive_read_disk.c index 46bde2f5f..d34cb0b8f 100644 --- a/libarchive/archive_read_disk.c +++ b/libarchive/archive_read_disk.c @@ -31,6 +31,12 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk.c 189429 2009-03-06 04 #ifdef HAVE_SYS_STAT_H #include #endif +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif #ifdef HAVE_DIRECT_H #include #endif @@ -268,6 +274,8 @@ static int tree_current_is_physical_link(struct tree *); static int tree_current_is_dir(struct tree *); static int update_filesystem(struct archive_read_disk *a, const struct stat *st); +static int filesystem_information(struct archive_read_disk *, const char *, + struct filesystem *); static int _archive_read_free(struct archive *); static int _archive_read_close(struct archive *); @@ -809,7 +817,6 @@ update_filesystem(struct archive_read_disk *a, const struct stat *st) struct tree *t = a->tree; int i, fid; - /* Current filesystem is not changed. */ if (t->current_filesystem != NULL && t->current_filesystem->dev == st->st_dev) return (ARCHIVE_OK); @@ -843,11 +850,95 @@ update_filesystem(struct archive_read_disk *a, const struct stat *st) t->current_filesystem_id = fid; t->current_filesystem = &(t->filesystem_table[fid]); t->current_filesystem->dev = st->st_dev; - t->current_filesystem->synthetic = -1;/* Not yet supported. */ - t->current_filesystem->remote = -1;/* Not yet supported. */ + return (filesystem_information(a, tree_current_access_path(t), + t->current_filesystem)); +} + +/* + * Returns 1 if current filesystem is generated filesystem, 0 if it is not + * or -1 if it is unknown. + */ +int +archive_read_disk_current_filesystem_is_synthetic(struct archive *_a) +{ + struct archive_read_disk *a = (struct archive_read_disk *)_a; + + archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, + "archive_read_disk_current_filesystem"); + + return (a->tree->current_filesystem->synthetic); +} + +/* + * Returns 1 if current filesystem is remote filesystem, 0 if it is not + * or -1 if it is unknown. + */ +int +archive_read_disk_current_filesystem_is_remote(struct archive *_a) +{ + struct archive_read_disk *a = (struct archive_read_disk *)_a; + + archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, + "archive_read_disk_current_filesystem"); + + return (a->tree->current_filesystem->remote); +} + +#if defined(HAVE_GETVFSBYNAME) && defined(HAVE_STATFS) + +/* + * Get conditions of synthetic and remote on FreeBSD. + */ +static int +filesystem_information(struct archive_read_disk *a, const char *path, + struct filesystem *fs) +{ + struct statfs sfs; + struct xvfsconf vfc; + int r; + + fs->synthetic = -1; + fs->remote = -1; + r = statfs(path, &sfs); + if (r == -1) { + archive_set_error(&a->archive, errno, "statfs failed"); + return (ARCHIVE_FAILED); + } + if (sfs.f_flags & MNT_LOCAL) + fs->remote = 0; + else + fs->remote = 1; + r = getvfsbyname(sfs.f_fstypename, &vfc); + if (r == -1) { + archive_set_error(&a->archive, errno, "getvfsbyname failed"); + return (ARCHIVE_FAILED); + } + if (vfc.vfc_flags & VFCF_SYNTHETIC) + fs->synthetic = 1; + else + fs->synthetic = 0; return (ARCHIVE_OK); } +#else + +/* + * Generic + */ +static int +filesystem_information(struct archive_read_disk *a, const char *path, + struct filesystem *fs) +{ + (void)a; /* UNUSED */ + (void)path; /* UNUSED */ + fs->synthetic = -1;/* Not supported */ + fs->remote = -1;/* Not supported */ + return (ARCHIVE_OK); +} + +#endif + + /* * Add a directory path to the current stack. */