-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

What are your thoughts on using Extended Attributes for items such as:
* Dos Attributes (like samba's "store dos attributes = yes")
* File Creation Times (like samba's proposed user.crtime)
* An option for alternate storage of NT ACLs (like samba's "vfs object =
acl-xattr")

Are Extended Attributes acceptable?
Or should they never touch the wine source?

Where would the portability functions for Extended Attributes on Linux,
Mac OS X, FreeBSD and Solaris belong?  I would think in libport.

Attached is a patch to add extended attribute portability functions for
fgetxattr, fsetxattr and fremovexattr to libport.

Please give me any comments on this patch, and the idea of using
extended attributes.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAksAm/4ACgkQTHDAI68NsumFzwCbBDcRbB8kFXroLeskA+hzgswu
i0UAn3NHbau8AjSgtoruggBH3py+orcZ
=tEvP
-----END PGP SIGNATURE-----
>From 2ef84c7f8c849db18ce15366e72c6787fa83597d Mon Sep 17 00:00:00 2001
From: Benjamin Peddell <klightsp...@netspace.net.au>
Date: Mon, 16 Nov 2009 01:23:28 +1000
Subject: [PATCH] Add Extended Attribute support to libport

---
 configure                |  178 ++++++++++++++++++++++++++++++++++++++++++++++
 configure.ac             |   45 ++++++++++++
 include/config.h.in      |   39 ++++++++++
 include/wine/port.h      |   36 +++++++++
 libs/port/Makefile.in    |    3 +
 libs/port/fgetxattr.c    |   96 +++++++++++++++++++++++++
 libs/port/fremovexattr.c |   75 +++++++++++++++++++
 libs/port/fsetxattr.c    |  102 ++++++++++++++++++++++++++
 8 files changed, 574 insertions(+), 0 deletions(-)
 create mode 100644 libs/port/fgetxattr.c
 create mode 100644 libs/port/fremovexattr.c
 create mode 100644 libs/port/fsetxattr.c

diff --git a/configure b/configure
index 15652b4..c9322b3 100755
--- a/configure
+++ b/configure
@@ -5747,6 +5747,7 @@ for ac_header in \
        sys/errno.h \
        sys/event.h \
        sys/exec_elf.h \
+       sys/extattr.h \
        sys/filio.h \
        sys/inotify.h \
        sys/ioctl.h \
@@ -5782,6 +5783,7 @@ for ac_header in \
        sys/utsname.h \
        sys/vm86.h \
        sys/wait.h \
+       sys/xattr.h \
        syscall.h \
        termios.h \
        unistd.h \
@@ -12084,6 +12086,9 @@ for ac_func in \
        chsize \
        dlopen \
        epoll_create \
+       extattr_delete_fd \
+       extattr_get_fd \
+       extattr_set_fd \
        ffs \
        finite \
        fnmatch \
@@ -12105,6 +12110,7 @@ for ac_func in \
        lstat \
        memmove \
        mmap \
+       openat \
        pclose \
        pipe2 \
        poll \
@@ -12137,6 +12143,7 @@ for ac_func in \
        tcgetattr \
        thr_kill2 \
        timegm \
+       unlinkat \
        usleep \
        vsnprintf \
        wait4 \
@@ -12262,6 +12269,81 @@ fi
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing 
fgetxattr" >&5
+$as_echo_n "checking for library containing fgetxattr... " >&6; }
+if test "${ac_cv_search_fgetxattr+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fgetxattr ();
+int
+main ()
+{
+return fgetxattr ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' attr; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_fgetxattr=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_fgetxattr+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_fgetxattr+set}" = set; then :
+
+else
+  ac_cv_search_fgetxattr=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fgetxattr" >&5
+$as_echo "$ac_cv_search_fgetxattr" >&6; }
+ac_res=$ac_cv_search_fgetxattr
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+for ac_func in \
+       fgetxattr \
+       fremovexattr \
+       fsetxattr \
+
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing 
gethostbyname" >&5
 $as_echo_n "checking for library containing gethostbyname... " >&6; }
 if test "${ac_cv_search_gethostbyname+set}" = set; then :
@@ -12616,6 +12698,102 @@ $as_echo "#define HAVE_ONE_ARG_MKDIR 1" >>confdefs.h
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fgetxattr takes six 
arguments" >&5
+$as_echo_n "checking whether fgetxattr takes six arguments... " >&6; }
+if test "${wine_cv_six_arg_fgetxattr+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/xattr.h>
+int
+main ()
+{
+fgetxattr(0, "foo", "foo", 3, 0, 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  wine_cv_six_arg_fgetxattr=yes
+else
+  wine_cv_six_arg_fgetxattr=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $wine_cv_six_arg_fgetxattr" 
>&5
+$as_echo "$wine_cv_six_arg_fgetxattr" >&6; }
+if test "$wine_cv_six_arg_fgetxattr" = "yes"
+then
+
+$as_echo "#define HAVE_SIX_ARG_FGETXATTR 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fsetxattr takes six 
arguments" >&5
+$as_echo_n "checking whether fsetxattr takes six arguments... " >&6; }
+if test "${wine_cv_six_arg_fsetxattr+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/xattr.h>
+int
+main ()
+{
+fsetxattr(0, "foo", "foo", 3, 0, 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  wine_cv_six_arg_fsetxattr=yes
+else
+  wine_cv_six_arg_fsetxattr=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $wine_cv_six_arg_fsetxattr" 
>&5
+$as_echo "$wine_cv_six_arg_fsetxattr" >&6; }
+if test "$wine_cv_six_arg_fsetxattr" = "yes"
+then
+
+$as_echo "#define HAVE_SIX_ARG_FSETXATTR 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fremovexattr takes 
three arguments" >&5
+$as_echo_n "checking whether fremovexattr takes three arguments... " >&6; }
+if test "${wine_cv_three_arg_fremovexattr+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/xattr.h>
+int
+main ()
+{
+fremovexattr("foo", "foo", 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  wine_cv_three_arg_fremovexattr=yes
+else
+  wine_cv_three_arg_fremovexattr=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: 
$wine_cv_three_arg_fremovexattr" >&5
+$as_echo "$wine_cv_three_arg_fremovexattr" >&6; }
+if test "$wine_cv_three_arg_fremovexattr" = "yes"
+then
+
+$as_echo "#define HAVE_THREE_ARG_FREMOVEXATTR 1" >>confdefs.h
+
+fi
+
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming 
const" >&5
 $as_echo_n "checking for an ANSI C-conforming const... " >&6; }
diff --git a/configure.ac b/configure.ac
index a5f1b8a..c0f5380 100644
--- a/configure.ac
+++ b/configure.ac
@@ -384,6 +384,7 @@ AC_CHECK_HEADERS(\
        sys/errno.h \
        sys/event.h \
        sys/exec_elf.h \
+       sys/extattr.h \
        sys/filio.h \
        sys/inotify.h \
        sys/ioctl.h \
@@ -419,6 +420,7 @@ AC_CHECK_HEADERS(\
        sys/utsname.h \
        sys/vm86.h \
        sys/wait.h \
+       sys/xattr.h \
        syscall.h \
        termios.h \
        unistd.h \
@@ -1684,6 +1686,9 @@ AC_CHECK_FUNCS(\
        chsize \
        dlopen \
        epoll_create \
+       extattr_delete_fd \
+       extattr_get_fd \
+       extattr_set_fd \
        ffs \
        finite \
        fnmatch \
@@ -1705,6 +1710,7 @@ AC_CHECK_FUNCS(\
        lstat \
        memmove \
        mmap \
+       openat \
        pclose \
        pipe2 \
        poll \
@@ -1737,6 +1743,7 @@ AC_CHECK_FUNCS(\
        tcgetattr \
        thr_kill2 \
        timegm \
+       unlinkat \
        usleep \
        vsnprintf \
        wait4 \
@@ -1757,6 +1764,16 @@ then
     AC_CHECK_LIB(poll,poll,[AC_DEFINE(HAVE_POLL,1) AC_SUBST(LIBPOLL,"-lpoll")])
 fi
 
+dnl Check for -lattr for the old attr package
+AC_SEARCH_LIBS(fgetxattr,attr)
+
+dnl Check for xattr functions which may rely on -lattr on Linux
+AC_CHECK_FUNCS(\
+       fgetxattr \
+       fremovexattr \
+       fsetxattr \
+)
+
 dnl Check for -lnsl for Solaris
 AC_SEARCH_LIBS(gethostbyname, nsl)
 
@@ -1816,6 +1833,34 @@ then
   AC_DEFINE(HAVE_ONE_ARG_MKDIR, 1, [Define if mkdir takes only one argument])
 fi
 
+dnl Check xattr functions
+AC_CACHE_CHECK([whether fgetxattr takes six arguments],
+       wine_cv_six_arg_fgetxattr,
+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include 
<sys/xattr.h>]],[[fgetxattr(0, "foo", "foo", 3, 0, 0);]])],
+                          
[wine_cv_six_arg_fgetxattr=yes],[wine_cv_six_arg_fgetxattr=no]))
+if test "$wine_cv_six_arg_fgetxattr" = "yes"
+then
+  AC_DEFINE(HAVE_SIX_ARG_FGETXATTR, 1, [Define if fgetxattr takes six 
arguments, as in Mac OS X])
+fi
+
+AC_CACHE_CHECK([whether fsetxattr takes six arguments],
+       wine_cv_six_arg_fsetxattr,
+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include 
<sys/xattr.h>]],[[fsetxattr(0, "foo", "foo", 3, 0, 0);]])],
+                          
[wine_cv_six_arg_fsetxattr=yes],[wine_cv_six_arg_fsetxattr=no]))
+if test "$wine_cv_six_arg_fsetxattr" = "yes"
+then
+  AC_DEFINE(HAVE_SIX_ARG_FSETXATTR, 1, [Define if fsetxattr takes six 
arguments, as in Mac OS X])
+fi
+
+AC_CACHE_CHECK([whether fremovexattr takes three arguments],
+       wine_cv_three_arg_fremovexattr,
+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include 
<sys/xattr.h>]],[[fremovexattr("foo", "foo", 0);]])],
+                          
[wine_cv_three_arg_fremovexattr=yes],[wine_cv_three_arg_fremovexattr=no]))
+if test "$wine_cv_three_arg_fremovexattr" = "yes"
+then
+  AC_DEFINE(HAVE_THREE_ARG_FREMOVEXATTR, 1, [Define if fremovexattr takes 
three arguments, as in Mac OS X])
+fi
+
 dnl **** Check for types ****
 
 AC_C_CONST
diff --git a/include/config.h.in b/include/config.h.in
index 16b2e90..1c6ec57 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -93,9 +93,21 @@
 /* Define if you have EsounD sound server */
 #undef HAVE_ESD
 
+/* Define to 1 if you have the `extattr_delete_fd' function. */
+#undef HAVE_EXTATTR_DELETE_FD
+
+/* Define to 1 if you have the `extattr_get_fd' function. */
+#undef HAVE_EXTATTR_GET_FD
+
+/* Define to 1 if you have the `extattr_set_fd' function. */
+#undef HAVE_EXTATTR_SET_FD
+
 /* Define to 1 if you have the `ffs' function. */
 #undef HAVE_FFS
 
+/* Define to 1 if you have the `fgetxattr' function. */
+#undef HAVE_FGETXATTR
+
 /* Define to 1 if you have the `finite' function. */
 #undef HAVE_FINITE
 
@@ -156,9 +168,15 @@
 /* Define to 1 if you have the <freetype/tttables.h> header file. */
 #undef HAVE_FREETYPE_TTTABLES_H
 
+/* Define to 1 if you have the `fremovexattr' function. */
+#undef HAVE_FREMOVEXATTR
+
 /* Define to 1 if the system has the type `fsblkcnt_t'. */
 #undef HAVE_FSBLKCNT_T
 
+/* Define to 1 if you have the `fsetxattr' function. */
+#undef HAVE_FSETXATTR
+
 /* Define to 1 if the system has the type `fsfilcnt_t'. */
 #undef HAVE_FSFILCNT_T
 
@@ -561,6 +579,9 @@
 /* Define to 1 if you have the <OpenAL/al.h> header file. */
 #undef HAVE_OPENAL_AL_H
 
+/* Define to 1 if you have the `openat' function. */
+#undef HAVE_OPENAT
+
 /* Define if OpenGL is present on the system */
 #undef HAVE_OPENGL
 
@@ -699,6 +720,12 @@
 /* Define to 1 if the system has the type `sigset_t'. */
 #undef HAVE_SIGSET_T
 
+/* Define if fgetxattr takes six arguments, as in Mac OS X */
+#undef HAVE_SIX_ARG_FGETXATTR
+
+/* Define if fsetxattr takes six arguments, as in Mac OS X */
+#undef HAVE_SIX_ARG_FSETXATTR
+
 /* Define to 1 if the system has the type `size_t'. */
 #undef HAVE_SIZE_T
 
@@ -855,6 +882,9 @@
 /* Define to 1 if you have the <sys/exec_elf.h> header file. */
 #undef HAVE_SYS_EXEC_ELF_H
 
+/* Define to 1 if you have the <sys/extattr.h> header file. */
+#undef HAVE_SYS_EXTATTR_H
+
 /* Define to 1 if you have the <sys/filio.h> header file. */
 #undef HAVE_SYS_FILIO_H
 
@@ -984,12 +1014,18 @@
 /* Define to 1 if you have the <sys/wait.h> header file. */
 #undef HAVE_SYS_WAIT_H
 
+/* Define to 1 if you have the <sys/xattr.h> header file. */
+#undef HAVE_SYS_XATTR_H
+
 /* Define to 1 if you have the `tcgetattr' function. */
 #undef HAVE_TCGETATTR
 
 /* Define to 1 if you have the <termios.h> header file. */
 #undef HAVE_TERMIOS_H
 
+/* Define if fremovexattr takes three arguments, as in Mac OS X */
+#undef HAVE_THREE_ARG_FREMOVEXATTR
+
 /* Define to 1 if you have the `thr_kill2' function. */
 #undef HAVE_THR_KILL2
 
@@ -1005,6 +1041,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the `unlinkat' function. */
+#undef HAVE_UNLINKAT
+
 /* Define to 1 if you have the `usleep' function. */
 #undef HAVE_USLEEP
 
diff --git a/include/wine/port.h b/include/wine/port.h
index 61c8399..6568dae 100644
--- a/include/wine/port.h
+++ b/include/wine/port.h
@@ -48,6 +48,9 @@
 # include <unistd.h>
 #endif
 
+#ifdef HAVE_SYS_XATTR_H
+# include <sys/xattr.h>
+#endif
 
 /****************************************************************
  * Type definitions
@@ -117,6 +120,18 @@ struct statvfs
 #define mkdir(path,mode) mkdir(path)
 #endif
 
+#ifdef HAVE_SIX_ARG_FGETXATTR
+#define fgetxattr(fd,name,val,size) fgetxattr(fd,name,val,size,0,0)
+#endif
+
+#ifdef HAVE_SIX_ARG_FSETXATTR
+#define fsetxattr(fd,name,val,size,opts) fsetxattr(fd,name,val,size,0,opts)
+#endif
+
+#ifdef HAVE_THREE_ARG_FREMOVEXATTR
+#define fremovexattr(fd,name) fremovexattr(fd,name,0)
+#endif
+
 #if !defined(HAVE_FTRUNCATE) && defined(HAVE_CHSIZE)
 #define ftruncate chsize
 #endif
@@ -328,6 +343,21 @@ int symlink(const char *from, const char *to);
 int usleep (unsigned int useconds);
 #endif /* !defined(HAVE_USLEEP) */
 
+#ifndef HAVE_FGETXATTR
+size_t fgetxattr (int fd, const char *name, void *value, size_t size);
+#endif /* !defined(HAVE_FGETXATTR) */
+
+#ifndef HAVE_FSETXATTR
+#define XATTR_CREATE 1
+#define XATTR_REPLACE 2
+size_t fsetxattr (int fd, const char *name, const void *value, size_t size, 
+                  int opts);
+#endif /* !defined(HAVE_FSETXATTR) */
+
+#ifndef HAVE_FREMOVEXATTR
+size_t fremovexattr (int fd, const char *name);
+#endif /* !defined(HAVE_FREMOVEXATTR) */
+
 #ifdef __i386__
 static inline void *memcpy_unaligned( void *dst, const void *src, size_t size )
 {
@@ -470,6 +500,12 @@ extern unsigned char interlocked_cmpxchg128( __int64 
*dest, __int64 xchg_high,
 #define strerror                __WINE_NOT_PORTABLE(strerror)
 #define strncasecmp             __WINE_NOT_PORTABLE(strncasecmp)
 #define usleep                  __WINE_NOT_PORTABLE(usleep)
+#undef fgetxattr
+#define fgetxattr              __WINE_NOT_PORTABLE(fgetxattr)
+#undef fsetxattr
+#define fsetxattr              __WINE_NOT_PORTABLE(fsetxattr)
+#undef fremovexattr
+#define fremovexattr           __WINE_NOT_PORTABLE(fremovexattr)
 
 #endif /* NO_LIBWINE_PORT */
 
diff --git a/libs/port/Makefile.in b/libs/port/Makefile.in
index c4c0127..e046562 100644
--- a/libs/port/Makefile.in
+++ b/libs/port/Makefile.in
@@ -8,6 +8,9 @@ MODULE    = libwine_port.a
 
 C_SRCS = \
        ffs.c \
+       fgetxattr.c \
+       fremovexattr.c \
+       fsetxattr.c \
        fstatvfs.c \
        futimes.c \
        getopt.c \
diff --git a/libs/port/fgetxattr.c b/libs/port/fgetxattr.c
new file mode 100644
index 0000000..196d11a
--- /dev/null
+++ b/libs/port/fgetxattr.c
@@ -0,0 +1,96 @@
+/*
+ * fgetxattr function
+ *
+ * Copyright 2009 Benjamin Peddell
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifndef HAVE_FGETXATTR
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_EXTATTR_H
+# include <sys/extattr.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <errno.h>
+
+size_t fgetxattr (int fd, const char *name, void *value, size_t size){
+/* Solaris openat(fd,path,O_XATTR) support */
+#ifdef defined(HAVE_OPENAT) && defined(O_XATTR)
+    int ret;
+    size_t attrsize = -1;
+    off_t pos;
+    struct stat statbuf;
+    int attrfd;
+    if (strchr(name, '/') != NULL){
+        errno = EINVAL;
+        return -1;
+    }
+    attrfd = openat(fd, name, O_XATTR | O_RDONLY);
+    if (attrfd >= 0){
+        ret = fstat(attrfd, &statbuf);
+        if (ret >= 0){
+            attrsize = (size_t)statbuf.st_size;
+            if (attrsize >= 0 && attrsize <= size){
+                pos = 0;
+                while (pos < attrsize){
+                    ret = read(attrfd, value + pos, attrsize - pos);
+                    if (ret > 0){
+                        pos += ret;
+                    } else {
+                        attrsize = pos;
+                    }
+                }
+            } else {
+                errno = ERANGE;
+            }
+        }
+        close(attrfd);
+    }
+    if (attrsize >= 0){
+        return attrsize;
+    } else {
+        return (size_t)ret;
+    }
+/* FreeBSD extattr_get_fd support */
+#elif defined(HAVE_EXTATTR_GET_FD)
+    int nameofs;
+    int namespace;
+    if (strncmp (name, "user.", 5) == 0){
+        namespace = EXTATTR_NAMESPACE_USER;
+        nameofs = 5;
+    } else if (strncmp (name, "system.", 7) == 0){
+        namespace = EXTATTR_NAMESPACE_SYSTEM;
+        nameofs = 7;
+    } else {
+        errno = ENOENT;
+        return -1;
+    }
+    return extattr_get_fd (fd, namespace, name + nameofs, value, size);
+#else
+    errno = ENOSYS;
+    return -1;
+#endif
+}
+
+#endif /* HAVE_FGETXATTR */
diff --git a/libs/port/fremovexattr.c b/libs/port/fremovexattr.c
new file mode 100644
index 0000000..b752fb8
--- /dev/null
+++ b/libs/port/fremovexattr.c
@@ -0,0 +1,75 @@
+/*
+ * fremovexattr function
+ *
+ * Copyright 2009 Benjamin Peddell
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifndef HAVE_FREMOVEXATTR
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_EXTATTR_H
+# include <sys/extattr.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <errno.h>
+
+size_t fremovexattr (int fd, const char *name){
+/* Solaris openat(fd,path,O_XATTR) support */
+#ifdef defined(HAVE_UNLINKAT) && defined(HAVE_OPENAT) && defined(O_XATTR)
+    int ret;
+    int attrfd;
+    if (strchr(name, '/') != NULL){
+        errno = EINVAL;
+        return -1;
+    }
+    attrfd = openat(fd, ".", O_RDONLY | O_XATTR);
+    if (attrfd >= 0){
+        ret = unlinkat(attrfd, name, 0);
+        close(attrfd);
+    } else {
+        ret = attrfd;
+    }
+    return ret;
+/* FreeBSD extattr_delete_fd support */
+#elif defined(HAVE_EXTATTR_SET_FD)
+    int nameofs;
+    int namespace;
+    if (strncmp (name, "user.", 5) == 0){
+        namespace = EXTATTR_NAMESPACE_USER;
+        nameofs = 5;
+    } else if (strncmp (name, "system.", 7) == 0){
+        namespace = EXTATTR_NAMESPACE_SYSTEM;
+        nameofs = 7;
+    } else {
+        errno = ENOENT;
+        return -1;
+    }
+    return extattr_delete_fd (fd, namespace, name + nameofs);
+#else
+    errno = ENOSYS;
+    return -1;
+#endif
+}
+
+#endif /* HAVE_FREMOVEXATTR */
diff --git a/libs/port/fsetxattr.c b/libs/port/fsetxattr.c
new file mode 100644
index 0000000..7640f81
--- /dev/null
+++ b/libs/port/fsetxattr.c
@@ -0,0 +1,102 @@
+/*
+ * fsetxattr function
+ *
+ * Copyright 2009 Benjamin Peddell
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifndef HAVE_FSETXATTR
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_EXTATTR_H
+# include <sys/extattr.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <errno.h>
+
+size_t fsetxattr (int fd, const char *name, const void *value, size_t size, 
+                  int opts){
+/* Solaris openat(fd,path,O_XATTR) support */
+#ifdef defined(HAVE_OPENAT) && defined(O_XATTR)
+    int ret;
+    size_t attrsize = -1;
+    off_t pos;
+    struct stat statbuf;
+    int attrfd;
+    int flags = O_XATTR | O_WRONLY | O_CREAT;
+    if (strchr(name, '/') != NULL){
+        errno = EINVAL;
+        return -1;
+    } else if (strncmp (name, "SUNW", 4) == 0){
+        errno = EINVAL;
+        return -1;
+    } else if (opts & XATTR_CREATE && opts & XATTR_REPLACE){
+        errno = EINVAL;
+        return -1;
+    } else if (opts & XATTR_CREATE){
+        flags |= O_EXCL;
+    } else if (opts & XATTR_REPLACE){
+        flags &= ~O_CREAT;
+    }
+    attrfd = openat(fd, name, flags, 0666);
+    if (attrfd >= 0){
+        pos = 0;
+        attrsize = size;
+        while (pos < attrsize){
+            ret = write(attrfd, value + pos, attrsize - pos);
+            if (ret > 0){
+                pos += ret;
+            } else {
+                attrsize = pos;
+            }
+        }
+        close(attrfd);
+    } else {
+        ret = attrfd;
+    }
+    if (attrsize >= 0){
+        return attrsize;
+    } else {
+        return (size_t)ret;
+    }
+/* FreeBSD extattr_set_fd support */
+#elif defined(HAVE_EXTATTR_SET_FD)
+    int nameofs;
+    int namespace;
+    if (strncmp (name, "user.", 5) == 0){
+        namespace = EXTATTR_NAMESPACE_USER;
+        nameofs = 5;
+    } else if (strncmp (name, "system.", 7) == 0){
+        namespace = EXTATTR_NAMESPACE_SYSTEM;
+        nameofs = 7;
+    } else {
+        errno = ENOENT;
+        return -1;
+    }
+    return extattr_set_fd (fd, namespace, name + nameofs, value, size);
+#else
+    errno = ENOSYS;
+    return -1;
+#endif
+}
+
+#endif /* HAVE_FSETXATTR */
-- 
1.6.4.4

<<attachment: klightspeed.vcf>>



Reply via email to