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)
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)
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)
/* 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
/* Define to 1 if you have the <signal.h> 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
/* Define to 1 if you have the <sys/mkdev.h> header file. */
#cmakedefine HAVE_SYS_MKDEV_H 1
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#cmakedefine HAVE_SYS_MOUNT_H 1
+
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#cmakedefine HAVE_SYS_NDIR_H 1
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])
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])
*/
__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
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
#ifdef HAVE_DIRECT_H
#include <direct.h>
#endif
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 *);
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);
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.
*/