-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)
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
/*
- $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
return afp_errno;
}
-#ifdef HAVE_SOLARIS_EAS
if (bitmap & kXAttrNoFollow)
oflag = O_NOFOLLOW;
-#endif
/* Skip Bitmap, ReqCount, StartIndex and maxreply*/
ibuf += 12;
bitmap = ntohs( bitmap );
ibuf += sizeof(bitmap);
-#ifdef HAVE_SOLARIS_EAS
if (bitmap & kXAttrNoFollow)
oflag = O_NOFOLLOW;
-#endif
/* Skip Offset and ReqCount */
ibuf += 16;
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];
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;
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];
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 )) ) {
/*
- $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
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 */
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 $
*/
#endif
#include <atalk/adouble.h>
+#include <atalk/util.h>
#include <atalk/logger.h>
/******** Solaris EA helper function prototypes ********/
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);
#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)
#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)
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)
#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);
#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)
#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);
#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)
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;
libvfs_la_SOURCES += acl.c
endif
-if USE_SOLARIS_EAS
libvfs_la_SOURCES += ea_solaris.c
-endif
/*
- $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;
}
*/
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;
}
/*
*/
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.
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;
}
/*
* Function: sol_set_ea
*
- * Purpose: set a Solaris native EA
+ * Purpose: set a native EA
*
* Arguments:
*
*
* 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;
}
/*
* Function: sol_remove_ea
*
- * Purpose: remove a Solaris native EA
+ * Purpose: remove a native EA
*
* Arguments:
*
*/
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;
}
/* vfs_remove */ remove_ea
};
-#ifdef HAVE_SOLARIS_EAS
static struct vfs_ops netatalk_ea_solaris = {
/* validupath: */ NULL,
/* rf_chown: */ NULL,
/* ea_set */ sol_set_ea,
/* ea_remove */ sol_remove_ea
};
-#endif
/*
* Tertiary VFS modules for ACLs
/* 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;