svn commit: samba r24305 - in branches/SAMBA_3_2_0/source: . include lib

metze at samba.org metze at samba.org
Fri Aug 10 09:45:15 GMT 2007


Author: metze
Date: 2007-08-10 09:45:09 +0000 (Fri, 10 Aug 2007)
New Revision: 24305

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24305

Log:
merge from SAMBA_3_2:
patch from Bjoern JAcke <bj at SerNet.DE>:

attached patches add EA support for Solaris. If no one disagrees, can 
someone check this in please?

metze
Modified:
   branches/SAMBA_3_2_0/source/configure.in
   branches/SAMBA_3_2_0/source/include/includes.h
   branches/SAMBA_3_2_0/source/lib/system.c


Changeset:
Modified: branches/SAMBA_3_2_0/source/configure.in
===================================================================
--- branches/SAMBA_3_2_0/source/configure.in	2007-08-10 09:44:13 UTC (rev 24304)
+++ branches/SAMBA_3_2_0/source/configure.in	2007-08-10 09:45:09 UTC (rev 24305)
@@ -1664,6 +1664,14 @@
 esac
 
 ########################################################
+# Check if attropen() is present if this is Solaris
+case "$host_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, [

Modified: branches/SAMBA_3_2_0/source/include/includes.h
===================================================================
--- branches/SAMBA_3_2_0/source/include/includes.h	2007-08-10 09:44:13 UTC (rev 24304)
+++ branches/SAMBA_3_2_0/source/include/includes.h	2007-08-10 09:45:09 UTC (rev 24305)
@@ -224,6 +224,10 @@
 #include <sys/attributes.h>
 #endif
 
+#ifndef ENOATTR
+#define ENOATTR ENODATA
+#endif
+
 /* mutually exclusive (SuSE 8.2) */
 #if HAVE_ATTR_XATTR_H
 #include <attr/xattr.h>

Modified: branches/SAMBA_3_2_0/source/lib/system.c
===================================================================
--- branches/SAMBA_3_2_0/source/lib/system.c	2007-08-10 09:44:13 UTC (rev 24304)
+++ branches/SAMBA_3_2_0/source/lib/system.c	2007-08-10 09:45:09 UTC (rev 24305)
@@ -4,6 +4,7 @@
    Copyright (C) Andrew Tridgell 1992-1998
    Copyright (C) Jeremy Allison  1998-2005
    Copyright (C) Timur Bakeyev        2005
+   Copyright (C) Bjoern Jacke    2006-2007
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -1682,6 +1683,17 @@
 	SAFE_FREE(msgbuf);
 }
 
+/******** Solaris EA helper function prototypes ********/
+#ifdef HAVE_ATTROPEN
+#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
+int solaris_write_xattr(int attrfd, const char *value, size_t size);
+ssize_t solaris_read_xattr(int attrfd, void *value, size_t size);
+ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size);
+int solaris_unlinkat(int attrdirfd, const char *name);
+int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode);
+int solaris_openat(int fildes, const char *path, int oflag, mode_t mode);
+#endif
+
 /**************************************************************************
  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.
@@ -1730,6 +1742,14 @@
 	retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
 
 	return retval ? retval : valuelength;
+#elif defined(HAVE_ATTROPEN)
+	ssize_t ret = -1;
+	int attrfd = solaris_attropen(path, name, O_RDONLY, 0);
+	if (attrfd >= 0) {
+		ret = solaris_read_xattr(attrfd, value, size);
+		close(attrfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -1773,6 +1793,14 @@
 	retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
 
 	return retval ? retval : valuelength;
+#elif defined(HAVE_ATTROPEN)
+	ssize_t ret = -1;
+	int attrfd = solaris_attropen(path, name, O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
+	if (attrfd >= 0) {
+		ret = solaris_read_xattr(attrfd, value, size);
+		close(attrfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -1818,6 +1846,14 @@
 	retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
 
 	return retval ? retval : valuelength;
+#elif defined(HAVE_ATTROPEN)
+	ssize_t ret = -1;
+	int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0);
+	if (attrfd >= 0) {
+		ret = solaris_read_xattr(attrfd, value, size);
+		close(attrfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -2002,6 +2038,14 @@
 	return bsd_attr_list(0, arg, list, size);
 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
 	return irix_attr_list(path, 0, list, size, 0);
+#elif defined(HAVE_ATTROPEN)
+	ssize_t ret = -1;
+	int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0);
+	if (attrdirfd >= 0) {
+		ret = solaris_list_xattr(attrdirfd, list, size);
+		close(attrdirfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -2023,6 +2067,14 @@
 	return bsd_attr_list(1, arg, list, size);
 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
 	return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
+#elif defined(HAVE_ATTROPEN)
+	ssize_t ret = -1;
+	int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
+	if (attrdirfd >= 0) {
+		ret = solaris_list_xattr(attrdirfd, list, size);
+		close(attrdirfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -2046,6 +2098,14 @@
 	return bsd_attr_list(2, arg, list, size);
 #elif defined(HAVE_ATTR_LISTF)
 	return irix_attr_list(NULL, filedes, list, size, 0);
+#elif defined(HAVE_ATTROPEN)
+	ssize_t ret = -1;
+	int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
+	if (attrdirfd >= 0) {
+		ret = solaris_list_xattr(attrdirfd, list, size);
+		close(attrdirfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -2077,6 +2137,14 @@
 	if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
 	return attr_remove(path, attrname, flags);
+#elif defined(HAVE_ATTROPEN)
+	int ret = -1;
+	int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0);
+	if (attrdirfd >= 0) {
+		ret = solaris_unlinkat(attrdirfd, name);
+		close(attrdirfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -2106,6 +2174,14 @@
 	if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
 	return attr_remove(path, attrname, flags);
+#elif defined(HAVE_ATTROPEN)
+	int ret = -1;
+	int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
+	if (attrdirfd >= 0) {
+		ret = solaris_unlinkat(attrdirfd, name);
+		close(attrdirfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -2137,6 +2213,14 @@
 	if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
 	return attr_removef(filedes, attrname, flags);
+#elif defined(HAVE_ATTROPEN)
+	int ret = -1;
+	int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
+	if (attrdirfd >= 0) {
+		ret = solaris_unlinkat(attrdirfd, name);
+		close(attrdirfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -2195,6 +2279,17 @@
 	if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
 
 	return attr_set(path, attrname, (const char *)value, size, myflags);
+#elif defined(HAVE_ATTROPEN)
+	int ret = -1;
+	int myflags = O_RDWR;
+	if (flags & XATTR_CREATE) myflags |= O_EXCL;
+	if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
+	int attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
+	if (attrfd >= 0) {
+		ret = solaris_write_xattr(attrfd, value, size);
+		close(attrfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -2247,6 +2342,17 @@
 	if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
 
 	return attr_set(path, attrname, (const char *)value, size, myflags);
+#elif defined(HAVE_ATTROPEN)
+	int ret = -1;
+	int myflags = O_RDWR | AT_SYMLINK_NOFOLLOW;
+	if (flags & XATTR_CREATE) myflags |= O_EXCL;
+	if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
+	int attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
+	if (attrfd >= 0) {
+		ret = solaris_write_xattr(attrfd, value, size);
+		close(attrfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
@@ -2300,12 +2406,148 @@
 	if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
 
 	return attr_setf(filedes, attrname, (const char *)value, size, myflags);
+#elif defined(HAVE_ATTROPEN)
+	int ret = -1;
+	int myflags = O_RDWR | O_XATTR;
+	if (flags & XATTR_CREATE) myflags |= O_EXCL;
+	if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
+	int attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE);
+	if (attrfd >= 0) {
+		ret = solaris_write_xattr(attrfd, value, size);
+		close(attrfd);
+	}
+	return ret;
 #else
 	errno = ENOSYS;
 	return -1;
 #endif
 }
 
+/**************************************************************************
+ helper functions for Solaris' EA support
+****************************************************************************/
+#ifdef HAVE_ATTROPEN
+static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size)
+{
+	struct stat sbuf;
+
+	if (fstat(attrfd, &sbuf) == -1) {
+		errno = ENOATTR;
+		return -1;
+	}
+
+	/* This is to return the current size of the named extended attribute */
+	if (size == 0) {
+		return sbuf.st_size;
+	}
+
+	/* check size and read xattr */
+	if (sbuf.st_size > size) {
+		errno = ERANGE;
+		return -1;
+	}
+
+	return read(attrfd, value, sbuf.st_size);
+}
+
+static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size)
+{
+	ssize_t len = 0;
+	int stop = 0;
+	DIR *dirp;
+	struct dirent *de;
+	int newfd = dup(attrdirfd);
+	/* CAUTION: The originating file descriptor should not be
+	            used again following the call to fdopendir().
+	            For that reason we dup() the file descriptor
+		    here to make things more clear. */
+	dirp = fdopendir(newfd);
+
+	while ((de = readdir(dirp))) {
+		size_t listlen = strlen(de->d_name);
+		if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
+			/* we don't want "." and ".." here: */
+			DEBUG(10,("skipped EA %s\n",de->d_name));
+			continue;
+		}
+
+		if (size == 0) {
+			/* return the current size of the list of extended attribute names*/
+			len += listlen + 1;
+		} else {
+			/* check size and copy entrieѕ + nul into list. */
+			if ((len + listlen + 1) > size) {
+				errno = ERANGE;
+				len = -1;
+				break;
+			} else {
+				safe_strcpy(list + len, de->d_name, listlen);
+				pstrcpy(list + len, de->d_name);
+				len += listlen;
+				list[len] = '\0';
+				++len;
+			}
+		}
+	}
+
+	if (closedir(dirp) == -1) {
+		DEBUG(0,("closedir dirp failed: %s\n",strerror(errno)));
+		return -1;
+	}
+	return len;
+}
+
+static int solaris_unlinkat(int attrdirfd, const char *name)
+{
+	if (unlinkat(attrdirfd, name, 0) == -1) {
+		if (errno == ENOENT) {
+			errno = ENOATTR;
+		}
+		return -1;
+	}
+	return 0;
+}
+
+static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode)
+{
+	int filedes = attropen(path, attrpath, oflag, mode);
+	if (filedes == -1) {
+		DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path,attrpath,strerror(errno)));
+		if (errno == EINVAL) {
+			errno = ENOTSUP;
+		} else {
+			errno = ENOATTR;
+		}
+	}
+	return filedes;
+}
+
+static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode)
+{
+	int filedes = openat(fildes, path, oflag, mode);
+	if (filedes == -1) {
+		DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes,path,strerror(errno)));
+		if (errno == EINVAL) {
+			errno = ENOTSUP;
+		} else {
+			errno = ENOATTR;
+		}
+	}
+	return filedes;
+}
+
+static int solaris_write_xattr(int attrfd, const char *value, size_t size)
+{
+	if ((ftruncate(attrfd, 0) == 0) && (write(attrfd, value, size) == size)) {
+		return 0;
+	} else {
+		DEBUG(10,("solaris_write_xattr FAILED!\n"));
+		return -1;
+	}
+}
+#endif /*HAVE_ATTROPEN*/
+
+
 /****************************************************************************
  Return the major devicenumber for UNIX extensions.
 ****************************************************************************/



More information about the samba-cvs mailing list