]> arthur.barton.de Git - netatalk.git/commitdiff
xattr, use them
authordidg <didg>
Fri, 13 Nov 2009 13:03:29 +0000 (13:03 +0000)
committerdidg <didg>
Fri, 13 Nov 2009 13:03:29 +0000 (13:03 +0000)
configure.in
etc/afpd/extattrs.c
include/atalk/ea.h
libatalk/adouble/ad_ea.c
libatalk/vfs/Makefile.am
libatalk/vfs/ea_solaris.c
libatalk/vfs/vfs.c

index b643b90b2ea02d60b35b93790b1059b2a0cc0a20..5e114e24da0b9e10912958c784b05ac0554ae376 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: configure.in,v 1.223 2009-10-25 09:47:03 didg Exp $
+dnl $Id: configure.in,v 1.224 2009-11-13 13:03:29 didg Exp $
 dnl configure.in for netatalk
 
 AC_INIT(etc/afpd/main.c)
@@ -1043,16 +1043,74 @@ AC_SUBST(LIBATALK_ACLS)
 
 dnl --------------------- check for Extended Attributes support
 neta_cv_eas="adouble"
-if test "x$this_os" = "xsolaris"; then
-       AC_CHECK_LIB(c,attropen, [
-            neta_cv_eas="$neta_cv_eas Solaris"
-            neta_cv_solaris_eas="yes"
-            AC_MSG_NOTICE([Enabling Solaris Extended Attributes support])
-            AC_DEFINE([HAVE_SOLARIS_EAS], 1, [Enable Extended Attributes])
-        ]
-    )
+neta_cv_eas="$neta_cv_eas Solaris"
+neta_cv_solaris_eas="yes"
+
+AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h sys/extattr.h sys/uio.h)
+AC_CHECK_HEADERS(sys/ea.h)
+
+case "$this_os" in
+  *osf*)
+       AC_SEARCH_LIBS(getproplist, [proplist])
+       AC_CHECK_FUNCS(getproplist fgetproplist setproplist fsetproplist)
+       AC_CHECK_FUNCS(delproplist fdelproplist add_proplist_entry get_proplist_entry)
+       AC_CHECK_FUNCS(sizeof_proplist_entry)
+  ;;
+  *)
+       AC_SEARCH_LIBS(getxattr, [attr])
+       AC_CHECK_FUNCS(getxattr lgetxattr fgetxattr listxattr llistxattr)
+       AC_CHECK_FUNCS(getea fgetea lgetea listea flistea llistea)
+       AC_CHECK_FUNCS(removeea fremoveea lremoveea setea fsetea lsetea)
+       AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr)
+       AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr)
+       AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove)
+       AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef)
+  ;;
+esac
+
+# Check if attropen() is present if this is Solaris
+case "$this_os" in
+  *solaris*)
+       AC_CHECK_FUNCS(attropen)
+  ;;
+esac
+
+# Do xattr functions take additional options like on Darwin?
+if test x"$ac_cv_func_getxattr" = x"yes" ; then
+       AC_CACHE_CHECK([whether xattr interface takes additional options], smb_attr_cv_xattr_add_opt, [
+               old_LIBS=$LIBS
+               LIBS="$LIBS $ACL_LIBS"
+               AC_TRY_COMPILE([
+                       #include <sys/types.h>
+                       #if HAVE_ATTR_XATTR_H
+                       #include <attr/xattr.h>
+                       #elif HAVE_SYS_XATTR_H
+                       #include <sys/xattr.h>
+                       #endif
+               ],[
+                       getxattr(0, 0, 0, 0, 0, 0);
+               ],
+               [smb_attr_cv_xattr_add_opt=yes],
+               [smb_attr_cv_xattr_add_opt=no;LIBS=$old_LIBS])
+       ])
+       if test x"$smb_attr_cv_xattr_add_opt" = x"yes"; then
+               AC_DEFINE(XATTR_ADD_OPT, 1, [xattr functions have additional options])
+       fi
 fi
 
+# Check if we have extattr
+case "$this_os" in
+  *freebsd4* | *dragonfly* )
+    AC_DEFINE(BROKEN_EXTATTR, 1, [Does extattr API work])
+    ;;
+  *)
+    AC_CHECK_FUNCS(extattr_delete_fd extattr_delete_file extattr_delete_link)
+    AC_CHECK_FUNCS(extattr_get_fd extattr_get_file extattr_get_link)
+    AC_CHECK_FUNCS(extattr_list_fd extattr_list_file extattr_list_link)
+    AC_CHECK_FUNCS(extattr_set_fd extattr_set_file extattr_set_link)
+    ;;
+esac
+
 dnl --------------------- Netatalk Webmin
 NETATALK_WEBMIN
 
index aa6077ef8f2232f2bfbbe838b7475be5470cd1ed..c96fa62c2092b762a39c045d802589817d16c19a 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  $Id: extattrs.c,v 1.22 2009-11-09 05:45:06 didg Exp $
+  $Id: extattrs.c,v 1.23 2009-11-13 13:03:29 didg Exp $
   Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
 
   This program is free software; you can redistribute it and/or modify
@@ -119,10 +119,8 @@ int afp_listextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf,
             return afp_errno;
         }
 
-#ifdef HAVE_SOLARIS_EAS
         if (bitmap & kXAttrNoFollow)
             oflag = O_NOFOLLOW;
-#endif
         /* Skip Bitmap, ReqCount, StartIndex and maxreply*/
         ibuf += 12;
 
@@ -286,10 +284,8 @@ int afp_getextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf,
     bitmap = ntohs( bitmap );
     ibuf += sizeof(bitmap);
 
-#ifdef HAVE_SOLARIS_EAS
     if (bitmap & kXAttrNoFollow)
         oflag = O_NOFOLLOW;
-#endif
 
     /* Skip Offset and ReqCount */
     ibuf += 16;
@@ -340,7 +336,7 @@ int afp_getextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf,
 
 int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
-    int                 oflag = O_CREAT | O_WRONLY, ret;
+    int                 oflag = 0, ret;
     uint16_t            vid, bitmap, attrnamelen;
     uint32_t            did, attrsize;
     char                attruname[256];
@@ -370,13 +366,11 @@ int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _
     bitmap = ntohs( bitmap );
     ibuf += sizeof(bitmap);
 
-#ifdef HAVE_SOLARIS_EAS
     if (bitmap & kXAttrNoFollow)
-        oflag |= AT_SYMLINK_NOFOLLOW;
-#endif
+        oflag |= O_NOFOLLOW;
 
     if (bitmap & kXAttrCreate)
-        oflag |= O_EXCL;
+        oflag |= O_CREAT;
     else if (bitmap & kXAttrReplace)
         oflag |= O_TRUNC;
 
@@ -422,7 +416,7 @@ int afp_setextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _
 
 int afp_remextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
-    int                 oflag = O_RDONLY, ret;
+    int                 oflag = 0, ret;
     uint16_t            vid, bitmap, attrnamelen;
     uint32_t            did;
     char                attruname[256];
@@ -451,10 +445,8 @@ int afp_remextattr(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _
     bitmap = ntohs( bitmap );
     ibuf += sizeof(bitmap);
 
-#ifdef HAVE_SOLARIS_EAS
     if (bitmap & kXAttrNoFollow)
-        oflag |= AT_SYMLINK_NOFOLLOW;
-#endif
+        oflag |= O_NOFOLLOW;
 
     /* get name */
     if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
index 53ace0e622a33a043917c056ff569b2c915e9cd7..8fff1e71975d847078f640f1f2171c709616156e 100644 (file)
@@ -1,5 +1,5 @@
 /*
-   $Id: ea.h,v 1.5 2009-10-20 08:38:41 franklahm Exp $
+   $Id: ea.h,v 1.6 2009-11-13 13:03:29 didg Exp $
    Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
 
    This program is free software; you can redistribute it and/or modify
@@ -131,12 +131,10 @@ extern int ea_chmod_file(VFS_FUNC_ARGS_SETFILEMODE);
 extern int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE);
 
 /* Solaris native EAs */
-#ifdef HAVE_SOLARIS_EAS
 extern int sol_get_easize(VFS_FUNC_ARGS_EA_GETSIZE);
 extern int sol_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT);
 extern int sol_list_eas(VFS_FUNC_ARGS_EA_LIST);
 extern int sol_set_ea(VFS_FUNC_ARGS_EA_SET);
 extern int sol_remove_ea(VFS_FUNC_ARGS_EA_REMOVE);
-#endif /* HAVE_SOLARIS_EAS */
 
 #endif /* ATALK_EA_H */
index ce852fcf4ba9de4aa8dc1560f8468d16f3743a1a..d641b3c34162afd124f87ccb6d4699a7e181dcc5 100644 (file)
@@ -21,7 +21,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    
    Samba 3.0.28, modified for netatalk.
-   $Id: ad_ea.c,v 1.3 2009-11-13 09:18:07 didg Exp $
+   $Id: ad_ea.c,v 1.4 2009-11-13 13:03:29 didg Exp $
    
 */
 
@@ -64,6 +64,7 @@
 #endif
 
 #include <atalk/adouble.h>
+#include <atalk/util.h>
 #include <atalk/logger.h>
 
 /******** Solaris EA helper function prototypes ********/
@@ -81,9 +82,22 @@ static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode);
  Wrappers for extented attribute calls. Based on the Linux package with
  support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
 ****************************************************************************/
+static char attr_name[256 +5] = "user.";
 
-ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
+static const char *prefix(const char *uname)
 {
+#if defined(HAVE_ATTROPEN)
+       return uname;
+#else
+       strlcpy(attr_name +5, uname, 256);
+       return attr_name;
+#endif
+}
+
+ssize_t sys_getxattr (const char *path, const char *uname, void *value, size_t size)
+{
+       const char *name = prefix(uname);
+
 #if defined(HAVE_GETXATTR)
 #ifndef XATTR_ADD_OPT
        return getxattr(path, name, value, size);
@@ -139,8 +153,10 @@ ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t si
 #endif
 }
 
-ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
+ssize_t sys_lgetxattr (const char *path, const char *uname, void *value, size_t size)
 {
+       const char *name = prefix(uname);
+
 #if defined(HAVE_LGETXATTR)
        return lgetxattr(path, name, value, size);
 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
@@ -351,15 +367,46 @@ static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t
 
 #endif
 
+#if defined(HAVE_LISTXATTR)
+static ssize_t remove_user(ssize_t ret, char *list, size_t size)
+{
+       size_t len;
+       char *ptr;
+       char *ptr1;
+       ssize_t ptrsize;
+       
+       if (ret <= 0 || size == 0)
+               return ret;
+       ptrsize = ret;
+       ptr = ptr1 = list;
+       while (ptrsize > 0) {
+               len = strlen(ptr1) +1;
+               ptrsize -= len;
+               if (strncmp(ptr1, "user.",5)) {
+                       ptr1 += len;
+                       continue;
+               }
+               memmove(ptr, ptr1 +5, len -5);
+               ptr += len -5;
+               ptr1 += len;
+       }
+       return ptr -list;
+}
+#endif
+
 ssize_t sys_listxattr (const char *path, char *list, size_t size)
 {
 #if defined(HAVE_LISTXATTR)
+       ssize_t ret;
+
 #ifndef XATTR_ADD_OPT
-       return listxattr(path, list, size);
+       ret = listxattr(path, list, size);
 #else
        int options = 0;
-       return listxattr(path, list, size, options);
+       ret = listxattr(path, list, size, options);
 #endif
+       return remove_user(ret, list, size);
+
 #elif defined(HAVE_LISTEA)
        return listea(path, list, size);
 #elif defined(HAVE_EXTATTR_LIST_FILE)
@@ -385,10 +432,17 @@ ssize_t sys_listxattr (const char *path, char *list, size_t size)
 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
 {
 #if defined(HAVE_LLISTXATTR)
-       return llistxattr(path, list, size);
+       ssize_t ret;
+
+       ret = llistxattr(path, list, size);
+       return remove_user(ret, list, size);
 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
+       ssize_t ret;
        int options = XATTR_NOFOLLOW;
-       return listxattr(path, list, size, options);
+
+       ret = listxattr(path, list, size, options);
+       return remove_user(ret, list, size);
+
 #elif defined(HAVE_LLISTEA)
        return llistea(path, list, size);
 #elif defined(HAVE_EXTATTR_LIST_LINK)
@@ -411,8 +465,9 @@ ssize_t sys_llistxattr (const char *path, char *list, size_t size)
 #endif
 }
 
-int sys_removexattr (const char *path, const char *name)
+int sys_removexattr (const char *path, const char *uname)
 {
+       const char *name = prefix(uname);
 #if defined(HAVE_REMOVEXATTR)
 #ifndef XATTR_ADD_OPT
        return removexattr(path, name);
@@ -450,8 +505,9 @@ int sys_removexattr (const char *path, const char *name)
 #endif
 }
 
-int sys_lremovexattr (const char *path, const char *name)
+int sys_lremovexattr (const char *path, const char *uname)
 {
+       const char *name = prefix(uname);
 #if defined(HAVE_LREMOVEXATTR)
        return lremovexattr(path, name);
 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
@@ -492,8 +548,9 @@ int sys_lremovexattr (const char *path, const char *name)
 #define XATTR_REPLACE 0x2       /* set value, fail if attr does not exist */
 #endif
 
-int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
+int sys_setxattr (const char *path, const char *uname, const void *value, size_t size, int flags)
 {
+       const char *name = prefix(uname);
 #if defined(HAVE_SETXATTR)
 #ifndef XATTR_ADD_OPT
        return setxattr(path, name, value, size, flags);
@@ -557,8 +614,9 @@ int sys_setxattr (const char *path, const char *name, const void *value, size_t
 #endif
 }
 
-int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
+int sys_lsetxattr (const char *path, const char *uname, const void *value, size_t size, int flags)
 {
+       const char *name = prefix(uname);
 #if defined(HAVE_LSETXATTR)
        return lsetxattr(path, name, value, size, flags);
 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
@@ -663,7 +721,9 @@ static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size)
 
        while ((de = readdir(dirp))) {
                size_t listlen;
-               if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
+               if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") ||
+                    !strcmp(dp->d_name, "SUNWattr_ro") || !strcmp(dp->d_name, "SUNWattr_rw")) 
+               {
                        /* we don't want "." and ".." here: */
                        LOG(log_maxdebug, logtype_default, "skipped EA %s\n",de->d_name);
                        continue;
index 45c48304eeefeff570b355b7484086f7fc2fc0e9..8793a81011b23825648aaf926754665287347fec 100644 (file)
@@ -8,6 +8,4 @@ if USE_NFSv4_ACLS
 libvfs_la_SOURCES += acl.c
 endif
 
-if USE_SOLARIS_EAS
 libvfs_la_SOURCES += ea_solaris.c
-endif
index dfd62816a4d413b8dff14f3808864d383c343bfa..6af89b8f90f6cf995666d41547fc7e8cdc9a3c50 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  $Id: ea_solaris.c,v 1.3 2009-10-29 13:06:19 franklahm Exp $
+  $Id: ea_solaris.c,v 1.4 2009-11-13 13:03:29 didg Exp $
   Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
 
   This program is free software; you can redistribute it and/or modify
 #include <fcntl.h>
 #include <dirent.h>
 
+#if HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#elif HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
+
+#ifdef HAVE_SYS_EA_H
+#include <sys/ea.h>
+#endif
+
+#ifdef HAVE_SYS_EXTATTR_H
+#include <sys/extattr.h>
+#endif
+
 #include <atalk/adouble.h>
 #include <atalk/ea.h>
 #include <atalk/afp.h>
  */
 int sol_get_easize(VFS_FUNC_ARGS_EA_GETSIZE)
 {
-    int                 ret, attrdirfd;
-    uint32_t            attrsize;
-    struct stat         st;
+    ssize_t   ret;
+    uint32_t  attrsize;
 
     LOG(log_debug7, logtype_afpd, "sol_getextattr_size(%s): attribute: \"%s\"", uname, attruname);
 
-    if ( -1 == (attrdirfd = attropen(uname, ".", O_RDONLY | oflag))) {
-        if (errno == ELOOP) {
-            /* its a symlink and client requested O_NOFOLLOW  */
-            LOG(log_debug, logtype_afpd, "sol_getextattr_size(%s): encountered symlink with kXAttrNoFollow", uname);
-
-            memset(rbuf, 0, 4);
-            *rbuflen += 4;
-
-            return AFP_OK;
-        }
-        LOG(log_error, logtype_afpd, "sol_getextattr_size: attropen error: %s", strerror(errno));
+    if ((oflag & O_NOFOLLOW) ) {
+        ret = sys_lgetxattr(uname, attruname, rbuf +4, 0);
+    }
+    else {
+        ret = sys_getxattr(uname, attruname,  rbuf +4, 0);
+    }
+    
+    if (ret == -1) switch(errno) {
+    case ELOOP:
+        /* its a symlink and client requested O_NOFOLLOW  */
+        LOG(log_debug, logtype_afpd, "sol_getextattr_size(%s): encountered symlink with kXAttrNoFollow", uname);
+
+        memset(rbuf, 0, 4);
+        *rbuflen += 4;
+
+        return AFP_OK;
+    default:
+        LOG(log_error, logtype_afpd, "sol_getextattr_size: error: %s", strerror(errno));
         return AFPERR_MISC;
     }
 
-    if ( -1 == (fstatat(attrdirfd, attruname, &st, 0))) {
-        LOG(log_error, logtype_afpd, "sol_getextattr_size: fstatat error: %s", strerror(errno));
-        ret = AFPERR_MISC;
-        goto exit;
-    }
-    attrsize = (st.st_size > MAX_EA_SIZE) ? MAX_EA_SIZE : st.st_size;
+    if (ret > MAX_EA_SIZE) 
+      ret = MAX_EA_SIZE;
 
     /* Start building reply packet */
-
-    LOG(log_debug7, logtype_afpd, "sol_getextattr_size(%s): attribute: \"%s\", size: %u", uname, attruname, attrsize);
+    LOG(log_debug7, logtype_afpd, "sol_getextattr_size(%s): attribute: \"%s\", size: %u", uname, attruname, ret);
 
     /* length of attribute data */
-    attrsize = htonl(attrsize);
+    attrsize = htonl((uint32_t)ret);
     memcpy(rbuf, &attrsize, 4);
     *rbuflen += 4;
 
     ret = AFP_OK;
-
-exit:
-    close(attrdirfd);
     return ret;
 }
 
@@ -132,69 +144,46 @@ exit:
  */
 int sol_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT)
 {
-    int                 ret, attrdirfd;
-    size_t              toread, okread = 0, len;
-    char                *datalength;
-    struct stat         st;
-
-    if ( -1 == (attrdirfd = attropen(uname, attruname, O_RDONLY | oflag))) {
-        if (errno == ELOOP) {
-            /* its a symlink and client requested O_NOFOLLOW  */
-            LOG(log_debug, logtype_afpd, "sol_getextattr_content(%s): encountered symlink with kXAttrNoFollow", uname);
-
-            memset(rbuf, 0, 4);
-            *rbuflen += 4;
-
-            return AFP_OK;
-        }
-        LOG(log_error, logtype_afpd, "sol_getextattr_content(%s): attropen error: %s", attruname, strerror(errno));
-        return AFPERR_MISC;
-    }
-
-    if ( -1 == (fstat(attrdirfd, &st))) {
-        LOG(log_error, logtype_afpd, "sol_getextattr_content(%s): fstatat error: %s", attruname,strerror(errno));
-        ret = AFPERR_MISC;
-        goto exit;
-    }
+    ssize_t   ret;
+    uint32_t  attrsize;
 
     /* Start building reply packet */
 
     maxreply -= MAX_REPLY_EXTRA_BYTES;
+
     if (maxreply > MAX_EA_SIZE)
         maxreply = MAX_EA_SIZE;
 
-    /* But never send more than the client requested */
-    toread = (maxreply < st.st_size) ? maxreply : st.st_size;
-
     LOG(log_debug7, logtype_afpd, "sol_getextattr_content(%s): attribute: \"%s\", size: %u", uname, attruname, maxreply);
 
-    /* remember where we must store length of attribute data in rbuf */
-    datalength = rbuf;
-    rbuf += 4;
-    *rbuflen += 4;
-
-    while (1) {
-        len = read(attrdirfd, rbuf, toread);
-        if (len == -1) {
-            LOG(log_error, logtype_afpd, "sol_getextattr_content(%s): read error: %s", attruname, strerror(errno));
-            ret = AFPERR_MISC;
-            goto exit;
-        }
-        okread += len;
-        rbuf += len;
-        *rbuflen += len;
-        if ((len == 0) || (okread == toread))
-            break;
+    if ((oflag & O_NOFOLLOW) ) {
+        ret = sys_lgetxattr(uname, attruname, rbuf +4, maxreply);
+    }
+    else {
+        ret = sys_getxattr(uname, attruname,  rbuf +4, maxreply);
+    }
+    
+    if (ret == -1) switch(errno) {
+    case ELOOP:
+        /* its a symlink and client requested O_NOFOLLOW  */
+        LOG(log_debug, logtype_afpd, "sol_getextattr_content(%s): encountered symlink with kXAttrNoFollow", uname);
+
+        memset(rbuf, 0, 4);
+        *rbuflen += 4;
+
+        return AFP_OK;
+    default:
+        LOG(log_error, logtype_afpd, "sol_getextattr_content(%s): error: %s", attruname, strerror(errno));
+        return AFPERR_MISC;
     }
 
-    okread = htonl((uint32_t)okread);
-    memcpy(datalength, &okread, 4);
+    /* remember where we must store length of attribute data in rbuf */
+    *rbuflen += 4 +ret;
 
-    ret = AFP_OK;
+    attrsize = htonl((uint32_t)ret);
+    memcpy(rbuf, &attrsize, 4);
 
-exit:
-    close(attrdirfd);
-    return ret;
+    return AFP_OK;
 }
 
 /*
@@ -219,48 +208,44 @@ exit:
  */
 int sol_list_eas(VFS_FUNC_ARGS_EA_LIST)
 {
-    int ret, attrbuflen = *buflen, len, attrdirfd = 0;
-    struct dirent *dp;
-    DIR *dirp = NULL;
+    ssize_t attrbuflen = *buflen;
+    int     ret, len, nlen;
+    char    *buf;
+    char    *ptr;
+        
+    buf = malloc(ATTRNAMEBUFSIZ);
+    if (!buf)
+        return AFPERR_MISC;
 
-    /* Now list file attribute dir */
-    if ( -1 == (attrdirfd = attropen( uname, ".", O_RDONLY | oflag))) {
-        if (errno == ELOOP) {
-            /* its a symlink and client requested O_NOFOLLOW */
-            ret = AFPERR_BADTYPE;
-            goto exit;
-        }
-        LOG(log_error, logtype_afpd, "sol_list_extattr(%s): error opening atttribute dir: %s", uname, strerror(errno));
-        ret = AFPERR_MISC;
-        goto exit;
+    if ((oflag & O_NOFOLLOW)) {
+        ret = sys_llistxattr(uname, buf, ATTRNAMEBUFSIZ);
     }
-
-    if (NULL == (dirp = fdopendir(attrdirfd))) {
-        LOG(log_error, logtype_afpd, "sol_list_extattr(%s): error opening atttribute dir: %s", uname, strerror(errno));
-        ret = AFPERR_MISC;
-        goto exit;
+    else {
+        ret = sys_listxattr(uname, buf, ATTRNAMEBUFSIZ);
     }
 
-    while ((dp = readdir(dirp)))  {
-        /* check if its "." or ".." */
-        if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..") == 0) ||
-            (strcmp(dp->d_name, "SUNWattr_ro") == 0) || (strcmp(dp->d_name, "SUNWattr_rw") == 0))
-            continue;
-
-        len = strlen(dp->d_name);
+    if (ret == -1) switch(errno) {
+        case ELOOP:
+            /* its a symlink and client requested O_NOFOLLOW */
+            ret = AFPERR_BADTYPE;
+        default:
+            LOG(log_error, logtype_afpd, "sol_list_extattr(%s): error opening atttribute dir: %s", uname, strerror(errno));
+            ret= AFPERR_MISC;
+    }
+    
+    ptr = buf;
+    while (ret > 0)  {
+        len = strlen(ptr);
 
         /* Convert name to CH_UTF8_MAC and directly store in in the reply buffer */
-        if ( 0 >= ( len = convert_string(vol->v_volcharset, CH_UTF8_MAC, dp->d_name, len, attrnamebuf + attrbuflen, 255)) ) {
+        if ( 0 >= ( nlen = convert_string(vol->v_volcharset, CH_UTF8_MAC, ptr, len, attrnamebuf + attrbuflen, 256)) ) {
             ret = AFPERR_MISC;
             goto exit;
         }
-        if (len == 255)
-            /* convert_string didn't 0-terminate */
-            attrnamebuf[attrbuflen + 255] = 0;
 
-        LOG(log_debug7, logtype_afpd, "sol_list_extattr(%s): attribute: %s", uname, dp->d_name);
+        LOG(log_debug7, logtype_afpd, "sol_list_extattr(%s): attribute: %s", uname, ptr);
 
-        attrbuflen += len + 1;
+        attrbuflen += nlen + 1;
         if (attrbuflen > (ATTRNAMEBUFSIZ - 256)) {
             /* Next EA name could overflow, so bail out with error.
                FIXME: evantually malloc/memcpy/realloc whatever.
@@ -269,17 +254,14 @@ int sol_list_eas(VFS_FUNC_ARGS_EA_LIST)
             ret = AFPERR_MISC;
             goto exit;
         }
+        ret -= len +1;
+        ptr += len +1;
     }
 
     ret = AFP_OK;
 
 exit:
-    if (dirp)
-        closedir(dirp);
-
-    if (attrdirfd > 0)
-        close(attrdirfd);
-
+    free(buf);
     *buflen = attrbuflen;
     return ret;
 }
@@ -287,7 +269,7 @@ exit:
 /*
  * Function: sol_set_ea
  *
- * Purpose: set a Solaris native EA
+ * Purpose: set a native EA
  *
  * Arguments:
  *
@@ -302,24 +284,32 @@ exit:
  *
  * Effects:
  *
- * Copies names of all EAs of uname as consecutive C strings into rbuf.
- * Increments *rbuflen accordingly.
  */
 int sol_set_ea(VFS_FUNC_ARGS_EA_SET)
 {
-    int attrdirfd;
-
-    if ( -1 == (attrdirfd = attropen(uname, attruname, oflag, 0666))) {
-        if (errno == ELOOP) {
-            /* its a symlink and client requested O_NOFOLLOW  */
-            LOG(log_debug, logtype_afpd, "afp_setextattr(%s): encountered symlink with kXAttrNoFollow", uname);
-            return AFP_OK;
-        }
-        LOG(log_error, logtype_afpd, "afp_setextattr(%s): attropen error: %s", uname, strerror(errno));
-        return AFPERR_MISC;
+    int attr_flag;
+    int ret;
+
+    attr_flag = 0;
+    if ((oflag & O_CREAT) ) 
+        attr_flag |= XATTR_CREATE;
+
+    else if ((oflag & O_TRUNC) ) 
+        attr_flag |= XATTR_REPLACE;
+    
+    if ((oflag & O_NOFOLLOW) ) {
+        ret = sys_lsetxattr(uname, attruname,  ibuf, attrsize,attr_flag);
+    }
+    else {
+        ret = sys_setxattr(uname, attruname,  ibuf, attrsize, attr_flag);
     }
 
-    if ((write(attrdirfd, ibuf, attrsize)) != attrsize) {
+    if (ret == -1) switch(errno) {
+    case ELOOP:
+        /* its a symlink and client requested O_NOFOLLOW  */
+        LOG(log_debug, logtype_afpd, "afp_setextattr(%s): encountered symlink with kXAttrNoFollow", uname);
+        return AFP_OK;
+    default:
         LOG(log_error, logtype_afpd, "afp_setextattr(%s): read error: %s", attruname, strerror(errno));
         return AFPERR_MISC;
     }
@@ -330,7 +320,7 @@ int sol_set_ea(VFS_FUNC_ARGS_EA_SET)
 /*
  * Function: sol_remove_ea
  *
- * Purpose: remove a Solaris native EA
+ * Purpose: remove a native EA
  *
  * Arguments:
  *
@@ -347,31 +337,26 @@ int sol_set_ea(VFS_FUNC_ARGS_EA_SET)
  */
 int sol_remove_ea(VFS_FUNC_ARGS_EA_REMOVE)
 {
-    int attrdirfd;
+    int ret;
 
-    if ( -1 == (attrdirfd = attropen(uname, ".", oflag))) {
-        switch (errno) {
-        case ELOOP:
-            /* its a symlink and client requested O_NOFOLLOW  */
-            LOG(log_debug, logtype_afpd, "afp_remextattr(%s): encountered symlink with kXAttrNoFollow", uname);
-            return AFP_OK;
-        case EACCES:
-            LOG(log_debug, logtype_afpd, "afp_remextattr(%s): unlinkat error: %s", uname, strerror(errno));
-            return AFPERR_ACCESS;
-        default:
-            LOG(log_error, logtype_afpd, "afp_remextattr(%s): attropen error: %s", uname, strerror(errno));
-            return AFPERR_MISC;
-        }
+    if ((oflag & O_NOFOLLOW) ) {
+        ret = sys_lremovexattr(uname, attruname);
+    }
+    else {
+        ret = sys_removexattr(uname, attruname);
     }
 
-    if ( -1 == (unlinkat(attrdirfd, attruname, 0)) ) {
-        if (errno == EACCES) {
-            LOG(log_debug, logtype_afpd, "afp_remextattr(%s): unlinkat error: %s", uname, strerror(errno));
-            return AFPERR_ACCESS;
-        }
-        LOG(log_error, logtype_afpd, "afp_remextattr(%s): unlinkat error: %s", uname, strerror(errno));
+    if (ret == -1) switch(errno) {
+    case ELOOP:
+        /* its a symlink and client requested O_NOFOLLOW  */
+        LOG(log_debug, logtype_afpd, "afp_remextattr(%s): encountered symlink with kXAttrNoFollow", uname);
+        return AFP_OK;
+    case EACCES:
+        LOG(log_debug, logtype_afpd, "afp_remextattr(%s): unlinkat error: %s", uname, strerror(errno));
+        return AFPERR_ACCESS;
+    default:
+        LOG(log_error, logtype_afpd, "afp_remextattr(%s): attropen error: %s", uname, strerror(errno));
         return AFPERR_MISC;
     }
-
     return AFP_OK;
 }
index a423bf63357eaa01ddeeccb5cd1d5b95c4b39dbe..d3cca207ff89d44f681a7a69b518b9a6c6f6050e 100644 (file)
@@ -925,7 +925,6 @@ static struct vfs_ops netatalk_ea_adouble = {
     /* vfs_remove         */ remove_ea
 };
 
-#ifdef HAVE_SOLARIS_EAS
 static struct vfs_ops netatalk_ea_solaris = {
     /* validupath:        */ NULL,
     /* rf_chown:          */ NULL,
@@ -946,7 +945,6 @@ static struct vfs_ops netatalk_ea_solaris = {
     /* ea_set             */ sol_set_ea,
     /* ea_remove          */ sol_remove_ea
 };
-#endif
 
 /* 
  * Tertiary VFS modules for ACLs
@@ -993,15 +991,9 @@ void initvol_vfs(struct vol *vol)
     /* Extended Attributes */
     if (vol->v_vfs_ea == AFPVOL_EA_SOLARIS) {
 
-#ifdef HAVE_SOLARIS_EAS
-        LOG(log_debug, logtype_afpd, "initvol_vfs: Enabling EA support with Solaris native EAs.");
+        LOG(log_debug, logtype_afpd, "initvol_vfs: Enabling EA support with native EAs.");
         vol->vfs_modules[1] = &netatalk_ea_solaris;
-#else
-        LOG(log_error, logtype_afpd, "initvol_vfs: Can't enable Solaris EA support.");
-        goto enable_adea;
-#endif
     } else {
-    enable_adea:
         /* default: AFPVOL_EA_AD */
         LOG(log_debug, logtype_afpd, "initvol_vfs: Enabling EA support with adouble files.");
         vol->vfs_modules[1] = &netatalk_ea_adouble;