From: "Erich E. Hoover" erich.e.hoover@gmail.com
--- configure.ac | 12 ++++++++++++ dlls/ntdll/unix/file.c | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac index 49d414e1d17..8b372f39dfa 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,7 @@ AC_ARG_WITH(unwind, AS_HELP_STRING([--without-unwind],[do not use the libunwi AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use the libusb library])) AC_ARG_WITH(v4l2, AS_HELP_STRING([--without-v4l2],[do not use v4l2 (video capture)])) AC_ARG_WITH(vulkan, AS_HELP_STRING([--without-vulkan],[do not use Vulkan])) +AC_ARG_WITH(xattr, AS_HELP_STRING([--without-xattr],[do not use xattr (security attributes support)])) AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]), [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi]) AC_ARG_WITH(xcursor, AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]), @@ -635,6 +636,17 @@ AC_CHECK_HEADERS([libprocstat.h],,, #include <sys/queue.h> #endif])
+if test "x$with_xattr" != "xno" +then + AC_CHECK_HEADERS(attr/xattr.h, [HAVE_XATTR=1]) +fi +if test "x$with_xattr" = "xyes" +then + WINE_ERROR_WITH(xattr,[test "x$HAVE_XATTR" = "x"],[xattr ${notice_platform}development files \ +not found. Wine will be built without extended attribute support, which probably isn't what you \ +want. You will need to install ${notice_platform}development packages of libattr at the very least.]) +fi + dnl **** Check for working dll ****
AC_SUBST(DLLFLAGS,"") diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index b31ce4fbb3d..86f7542479f 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -98,6 +98,9 @@ #ifdef HAVE_SYS_STATFS_H #include <sys/statfs.h> #endif +#ifdef HAVE_ATTR_XATTR_H +#include <attr/xattr.h> +#endif #include <time.h> #include <unistd.h>
@@ -355,6 +358,20 @@ NTSTATUS errno_to_status( int err ) } }
+#ifndef XATTR_USER_PREFIX +#define XATTR_USER_PREFIX "user." +#endif + +static int xattr_get( const char *path, const char *name, void *value, size_t size ) +{ +#if defined(HAVE_ATTR_XATTR_H) + return getxattr( path, name, value, size ); +#else + errno = ENOSYS; + return -1; +#endif +} + /* get space from the current directory data buffer, allocating a new one if necessary */ static void *get_dir_data_space( struct dir_data *data, unsigned int size ) { @@ -1436,6 +1453,22 @@ static BOOL append_entry( struct dir_data *data, const char *long_name, }
+/* Match the Samba conventions for storing DOS file attributes */ +#define SAMBA_XATTR_DOS_ATTRIB XATTR_USER_PREFIX "DOSATTRIB" +/* We are only interested in some attributes, the others have corresponding Unix attributes */ +#define XATTR_ATTRIBS_MASK (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM) + +/* decode the xattr-stored DOS attributes */ +static inline int get_file_xattr( char *hexattr, int attrlen ) +{ + if (attrlen > 2 && hexattr[0] == '0' && hexattr[1] == 'x') + { + hexattr[attrlen] = 0; + return strtol( hexattr+2, NULL, 16 ) & XATTR_ATTRIBS_MASK; + } + return 0; +} + /* fetch the attributes of a file */ static inline ULONG get_file_attributes( const struct stat *st ) { @@ -1479,7 +1512,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON static int get_file_info( const char *path, struct stat *st, ULONG *attr ) { char *parent_path; - int ret; + char hexattr[11]; + int len, ret;
*attr = 0; ret = lstat( path, st ); @@ -1505,6 +1539,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr ) free( parent_path ); } *attr |= get_file_attributes( st ); + len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 ); + if (len == -1) return ret; + *attr |= get_file_xattr( hexattr, len ); return ret; }