From: Frank Lahm Date: Sat, 23 Apr 2011 07:43:31 +0000 (+0200) Subject: Merge master X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=6d60f95c388da5f8f901d67e0018cf4896e6c6dc Merge master --- 6d60f95c388da5f8f901d67e0018cf4896e6c6dc diff --cc bin/Makefile.am index 1742ea6b,7c633f74..f5d1448a --- a/bin/Makefile.am +++ b/bin/Makefile.am @@@ -1,3 -1,11 +1,7 @@@ # Makefile.am for bin/ - SUBDIRS = ad afppasswd cnid megatron uniconv misc -SUBDIRS = adv1tov2 afppasswd cnid megatron uniconv misc - -if USE_APPLETALK -SUBDIRS += aecho getzones nbp pap psorder -endif ++SUBDIRS = afppasswd cnid megatron uniconv misc + + if HAVE_ATFUNCS + SUBDIRS += ad + endif diff --cc configure.in index 9da854d2,48449921..ea334e47 --- a/configure.in +++ b/configure.in @@@ -69,20 -61,32 +69,25 @@@ if test x"$libltdl_cv_need_uscore" = xy AC_DEFINE(DLSYM_PREPEND_UNDERSCORE, 1, [BSD compatibility macro]) fi -dnl Checks for library functions. -AC_TYPE_GETGROUPS -AC_PROG_GCC_TRADITIONAL -AC_FUNC_MEMCMP -AC_HEADER_MAJOR -AC_FUNC_MMAP -AC_TYPE_SIGNAL -AC_FUNC_UTIME_NULL -AC_FUNC_WAIT3 -AC_CHECK_FUNCS(getcwd gethostname gettimeofday getusershell mkdir rmdir select socket strdup strcasestr strstr strtoul strchr memcpy) -AC_CHECK_FUNCS(backtrace_symbols setlocale nl_langinfo strlcpy strlcat setlinebuf dirfd pselect access pread pwrite) -AC_CHECK_FUNCS(waitpid getcwd strdup strndup strnlen strtoul strerror chown fchown chmod fchmod chroot link mknod mknod64) +dnl Special hecks + ac_neta_haveatfuncs=yes + AC_CHECK_FUNCS(openat renameat fstatat unlinkat, , ac_neta_haveatfuncs=no) + if test x"$ac_neta_haveatfuncs" = x"yes" ; then + AC_DEFINE([_ATFILE_SOURCE], 1, AT file source) + AC_DEFINE([HAVE_ATFUNCS], 1, whether at funcs are available) + fi - AC_CHECK_MEMBERS(struct tm.tm_gmtoff,,, [#include ]) -AC_CHECK_FUNC(gethostbyname,,[AC_CHECK_LIB(nsl,gethostbyname)]) -AC_CHECK_FUNC(connect,,[AC_CHECK_LIB(socket,connect)]) -dnl search for necessary libs for libpthread stuff -AC_SEARCH_LIBS(pthread_sigmask, pthread,, - [AC_MSG_ERROR([cannot find pthread_sigmask in libc or libpthread])]) +dnl these tests have been comfirmed to be needed in 2011 - AC_CHECK_FUNC(renameat, AC_DEFINE([_ATFILE_SOURCE], 1, AT file source)) +AC_CHECK_FUNC(epoll_create, AC_DEFINE([HAVE_EPOLL], 1, Whether Linux epoll is available)) +AC_CHECK_FUNCS(backtrace_symbols dirfd getusershell pread pwrite pselect) +AC_CHECK_FUNCS(setlinebuf strlcat strlcpy strnlen) +AC_CHECK_FUNCS(mmap utime getpagesize) dnl needed by tbd + +dnl search for necessary libraries +AC_SEARCH_LIBS(gethostbyname, nsl) +AC_SEARCH_LIBS(connect, socket) +AC_SEARCH_LIBS(pthread_sigmask, pthread,,[AC_MSG_ERROR([missing pthread_sigmask])]) if test x"$ac_cv_search_pthread_sigmask" != x"none required" ; then PTHREAD_LIBS=$ac_cv_search_pthread_sigmask fi @@@ -326,6 -1261,8 +331,7 @@@ AM_CONDITIONAL(USE_GENTOO, test x$sysv_ AM_CONDITIONAL(USE_DEBIAN, test x$sysv_style = xdebian) AM_CONDITIONAL(USE_UNDEF, test x$sysv_style = x) AM_CONDITIONAL(USE_BDB, test x$bdb_required = xyes) -AM_CONDITIONAL(USE_APPLETALK, test x$netatalk_cv_ddp_enabled = xyes) + AM_CONDITIONAL(HAVE_ATFUNCS, test x"$ac_neta_haveatfuncs" = x"yes") dnl --------------------- generate files diff --cc etc/afpd/Makefile.am index a661a5e4,dd81a3f7..9b3fcae6 --- a/etc/afpd/Makefile.am +++ b/etc/afpd/Makefile.am @@@ -43,10 -44,9 +43,10 @@@ afpd_SOURCES = afpd_LDADD = \ $(top_builddir)/libatalk/cnid/libcnid.la \ $(top_builddir)/libatalk/libatalk.la \ - @LIBGCRYPT_LIBS@ @ZEROCONF_LIBS@ @QUOTA_LIBS@ @SLP_LIBS@ @WRAP_LIBS@ @LIBADD_DL@ @ACL_LIBS@ @PTHREAD_LIBS@ + $(top_builddir)/libevent/libevent.la \ - @QUOTA_LIBS@ @SLP_LIBS@ @WRAP_LIBS@ @LIBADD_DL@ @ACL_LIBS@ @ZEROCONF_LIBS@ @PTHREAD_LIBS@ ++ @LIBGCRYPT_LIBS@ @QUOTA_LIBS@ @SLP_LIBS@ @WRAP_LIBS@ @LIBADD_DL@ @ACL_LIBS@ @ZEROCONF_LIBS@ @PTHREAD_LIBS@ -afpd_LDFLAGS = -export-dynamic +afpd_LDFLAGS = -export-dynamic -static afpd_CFLAGS = \ -I$(top_srcdir)/include \ diff --cc etc/afpd/file.c index bd0e935c,f7df6049..0459656f --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@@ -718,9 -749,20 +722,20 @@@ int afp_createfile(AFPObj *obj, char *i } path = s_path->m_name; - ad_setname(adp, path); + ad_setname(&ad, path); + + struct stat st; + if (lstat(upath, &st) != 0) { + LOG(log_error, logtype_afpd, "afp_createfile(\"%s\"): stat: %s", + upath, strerror(errno)); + ad_close( adp, ADFLAGS_DF|ADFLAGS_HF); + return AFPERR_MISC; + } + + (void)get_id(vol, adp, &st, dir->d_did, upath, strlen(upath)); + - ad_flush( adp); - ad_close( adp, ADFLAGS_DF|ADFLAGS_HF ); + ad_flush(&ad); + ad_close(&ad, ADFLAGS_DF|ADFLAGS_HF ); createfile_done: curdir->offcnt++; diff --cc etc/afpd/globals.h index 3a9c229c,02dcf8b5..4d81463d --- a/etc/afpd/globals.h +++ b/etc/afpd/globals.h @@@ -50,9 -65,12 +56,11 @@@ struct afp_options int connections, transports, tickleval, timeout, server_notif, flags, dircachesize; int sleep; /* Maximum time allowed to sleep (in tickles) */ int disconnected; /* Maximum time in disconnected state (in tickles) */ + unsigned int tcp_sndbuf, tcp_rcvbuf; unsigned char passwdbits, passwdminlen, loginmaxfail; u_int32_t server_quantum; + int dsireadbuf; /* scale factor for sizefof(dsi->buffer) = server_quantum * dsireadbuf */ char hostname[MAXHOSTNAMELEN + 1], *server, *ipaddr, *port, *configfile; - struct at_addr ddpaddr; char *uampath, *fqdn; char *pidfile; char *sigconffile; diff --cc etc/afpd/volume.c index 2970bcc3,b73d13c2..60fc73e9 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@@ -28,8 -45,10 +28,10 @@@ #include #include #include +#include + #include + #include - #ifdef CNID_DB #include #endif /* CNID_DB*/ diff --cc etc/cnid_dbd/cmd_dbd_scanvol.c index f4122d84,daa13e41..8fb09624 --- a/etc/cnid_dbd/cmd_dbd_scanvol.c +++ b/etc/cnid_dbd/cmd_dbd_scanvol.c @@@ -677,13 -690,13 +690,13 @@@ static cnid_t check_cnid(const char *na ad_cnid = 0; if ( (myvolinfo->v_flags & AFPVOL_CACHE) && ADFILE_OK) { ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options); - if (ad_open_metadata( name, adflags, O_RDWR, &ad) != 0) { + if (ad_open(&ad, name, adflags, O_RDWR) != 0) { if (dbd_flags & DBD_FLAGS_CLEANUP) - return 0; + return CNID_INVALID; dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno)); - return 0; + return CNID_INVALID; } if (dbd_flags & DBD_FLAGS_FORCE) { @@@ -773,10 -791,10 +791,10 @@@ dbd_log(LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file", cwdbuf, name, ntohl(db_cnid)); ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options); - if (ad_open_metadata( name, adflags, O_RDWR, &ad) != 0) { + if (ad_open(&ad, name, adflags, O_RDWR) != 0) { dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno)); - return 0; + return CNID_INVALID; } ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp); ad_flush(&ad); @@@ -811,10 -831,10 +831,10 @@@ dbd_log(LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file", cwdbuf, name, ntohl(db_cnid)); ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options); - if (ad_open_metadata( name, adflags, O_RDWR, &ad) != 0) { + if (ad_open(&ad, name, adflags, O_RDWR) != 0) { dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno)); - return 0; + return CNID_INVALID; } ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp); ad_flush(&ad); diff --cc etc/cnid_dbd/db_param.h index d8f3c910,f3a4827a..fce1cb5a --- a/etc/cnid_dbd/db_param.h +++ b/etc/cnid_dbd/db_param.h @@@ -8,7 -8,18 +8,17 @@@ #define CNID_DBD_DB_PARAM_H 1 #include -#include + #define DEFAULT_LOGFILE_AUTOREMOVE 1 + #define DEFAULT_CACHESIZE (8 * 1024) /* KB, so 8 MB */ + #define DEFAULT_MAXLOCKS 5000 + #define DEFAULT_MAXLOCKOBJS 5000 + #define DEFAULT_FLUSH_FREQUENCY 1000 + #define DEFAULT_FLUSH_INTERVAL 1800 + #define DEFAULT_USOCK_FILE "usock" + #define DEFAULT_FD_TABLE_SIZE 512 + #define DEFAULT_IDLE_TIMEOUT (10 * 60) + struct db_param { char *dir; int logfile_autoremove; diff --cc include/atalk/util.h index 7b1b10fb,999f14da..1a428bda --- a/include/atalk/util.h +++ b/include/atalk/util.h @@@ -11,11 -11,16 +11,13 @@@ #ifndef _ATALK_UTIL_H #define _ATALK_UTIL_H 1 -#include #include -#ifdef HAVE_UNISTD_H +#include #include -#endif /* HAVE_UNISTD_H */ #include -#include + #include + #include /* exit error codes */ #define EXITERR_CLNT 1 /* client related error */ diff --cc libatalk/unicode/util_unistr.c index da61a437,070ca93b..5e4ae859 --- a/libatalk/unicode/util_unistr.c +++ b/libatalk/unicode/util_unistr.c @@@ -9,10 -9,10 +9,9 @@@ #include #include #include - -#include +#include #include - #include "ucs2_casetable.h" #include "precompose.h" #include "byteorder.h" diff --cc libatalk/util/Makefile.am index 957bf527,af5d3c9f..17ae747c --- a/libatalk/util/Makefile.am +++ b/libatalk/util/Makefile.am @@@ -1,13 -1,14 +1,13 @@@ # Makefile.am for libatalk/util/ -noinst_LTLIBRARIES = libutil.la +pkgconfdir = @PKGCONFDIR@ -AM_CFLAGS = -I$(top_srcdir)/sys +noinst_LTLIBRARIES = libutil.la libutil_la_SOURCES = \ - atalk_addr.c \ bprint.c \ + cnid.c \ fault.c \ - ftw.c \ getiface.c \ locking.c \ logger.c \ @@@ -17,8 -18,12 +17,12 @@@ server_ipc.c \ server_lock.c \ socket.c \ - strcasestr.c \ strdicasecmp.c \ - strlcpy.c \ - volinfo.c \ + volinfo.c \ unix.c - libutil_la_CFLAGS = -D_PATH_AFPDCONF=\"$(pkgconfdir)/afpd.conf\" ++libutil_la_CFLAGS = -D_PATH_AFPDCONF=\"$(pkgconfdir)/afpd.conf\" ++ + if HAVE_ATFUNCS + libutil_la_SOURCES += ftw.c + endif diff --cc libatalk/vfs/extattr.c index 0115c153,00000000..bdae873e mode 100644,000000..100644 --- a/libatalk/vfs/extattr.c +++ b/libatalk/vfs/extattr.c @@@ -1,874 -1,0 +1,876 @@@ +/* + Unix SMB/CIFS implementation. + Samba system utilities + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + sys_copyxattr modified from LGPL2.1 libattr copyright + Copyright (C) 2001-2002 Silicon Graphics, Inc. All Rights Reserved. + Copyright (C) 2001 Andreas Gruenbacher. + + Samba 3.0.28, modified for netatalk. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#if HAVE_ATTR_XATTR_H +#include +#elif HAVE_SYS_XATTR_H +#include +#endif + +#ifdef HAVE_SYS_EA_H +#include +#endif + +#ifdef HAVE_ATTROPEN + +#include +#endif + +#ifdef HAVE_SYS_EXTATTR_H +#include +#endif + +#include +#include +#include +#include +#include + +/******** Solaris EA helper function prototypes ********/ +#ifdef HAVE_ATTROPEN +#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP +static int solaris_write_xattr(int attrfd, const char *value, size_t size); +static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size); +static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size); +static int solaris_unlinkat(int attrdirfd, const char *name); +static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode); +static 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. +****************************************************************************/ +static char attr_name[256 +5] = "user."; + +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); +#else + int options = 0; + return getxattr(path, name, value, size, 0, options); +#endif +#elif defined(HAVE_GETEA) + return getea(path, name, value, size); +#elif defined(HAVE_EXTATTR_GET_FILE) + ssize_t retval; + /* + * The BSD implementation has a nasty habit of silently truncating + * the returned value to the size of the buffer, so we have to check + * that the buffer is large enough to fit the returned value. + */ + if((retval = extattr_get_file(path, EXTATTR_NAMESPACE_USER, uname, NULL, 0)) >= 0) { + if (size == 0) + /* size == 0 means only return size */ + return retval; + if (retval > size) { + errno = ERANGE; + return -1; + } + if ((retval = extattr_get_file(path, EXTATTR_NAMESPACE_USER, uname, value, size)) >= 0) + return retval; + } + + LOG(log_maxdebug, logtype_default, "sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno)); + return -1; +#elif defined(HAVE_ATTR_GET) + int retval, flags = 0; + int valuelength = (int)size; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + 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; +#endif +} + +ssize_t sys_fgetxattr (int filedes, const char *uname, void *value, size_t size) +{ + const char *name = prefix(uname); + +#if defined(HAVE_FGETXATTR) +#ifndef XATTR_ADD_OPT + return fgetxattr(filedes, name, value, size); +#else + int options = 0; + return fgetxattr(filedes, name, value, size, 0, options); +#endif +#elif defined(HAVE_FGETEA) + return fgetea(filedes, name, value, size); +#elif defined(HAVE_EXTATTR_GET_FD) + char *s; + ssize_t retval; + int attrnamespace = (strncmp(name, "system", 6) == 0) ? + EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER; + const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1; + + if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) { + if(retval > size) { + errno = ERANGE; + return -1; + } + if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0) + return retval; + } + + LOG(log_debug, logtype_default, "sys_fgetxattr: extattr_get_fd(): %s", + strerror(errno))); + return -1; +#elif defined(HAVE_ATTR_GETF) + int retval, flags = 0; + int valuelength = (int)size; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + 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; +#endif +} + +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) + int options = XATTR_NOFOLLOW; + return getxattr(path, name, value, size, 0, options); +#elif defined(HAVE_LGETEA) + return lgetea(path, name, value, size); +#elif defined(HAVE_EXTATTR_GET_LINK) + ssize_t retval; + if((retval=extattr_get_link(path, EXTATTR_NAMESPACE_USER, uname, NULL, 0)) >= 0) { + if(retval > size) { + errno = ERANGE; + return -1; + } + if((retval=extattr_get_link(path, EXTATTR_NAMESPACE_USER, uname, value, size)) >= 0) + return retval; + } + + LOG(log_maxdebug, logtype_default, "sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno)); + return -1; +#elif defined(HAVE_ATTR_GET) + int retval, flags = ATTR_DONTFOLLOW; + int valuelength = (int)size; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + 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; +#endif +} + +#if defined(HAVE_EXTATTR_LIST_FILE) + +#define EXTATTR_PREFIX(s) (s), (sizeof((s))-1) + +static struct { + int space; + const char *name; + size_t len; +} +extattr[] = { + { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("") }, + { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("") }, +}; + +typedef union { + const char *path; + int filedes; +} extattr_arg; + +static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size) +{ + ssize_t list_size; + int i, len; + + switch(type) { +#if defined(HAVE_EXTATTR_LIST_FILE) + case 0: + list_size = extattr_list_file(arg.path, EXTATTR_NAMESPACE_USER, list, size); + break; +#endif +#if defined(HAVE_EXTATTR_LIST_LINK) + case 1: + list_size = extattr_list_link(arg.path, EXTATTR_NAMESPACE_USER, list, size); + break; +#endif +#if defined(HAVE_EXTATTR_LIST_FD) + case 2: + list_size = extattr_list_fd(arg.filedes, EXTATTR_NAMESPACE_USER, list, size); + break; +#endif + default: + errno = ENOSYS; + return -1; + } + + /* Some error happend. Errno should be set by the previous call */ + if(list_size < 0) + return -1; + + /* No attributes */ + if(list_size == 0) + return 0; + + /* XXX: Call with an empty buffer may be used to calculate + necessary buffer size. Unfortunately, we can't say, how + many attributes were returned, so here is the potential + problem with the emulation. + */ + if(list == NULL) + return list_size; + + /* Buffer is too small to fit the results */ + if(list_size > size) { + errno = ERANGE; + return -1; + } + + /* Convert from pascal strings to C strings */ + len = list[0]; + memmove(list, list + 1, list_size); + + for(i = len; i < list_size; ) { + LOG(log_maxdebug, logtype_afpd, "len: %d, i: %d", len, i); + + len = list[i]; + list[i] = '\0'; + i += len + 1; + } + + return list_size; +} + +#endif + +#if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H) +static char attr_buffer[ATTR_MAX_VALUELEN]; + +static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags) +{ + int retval = 0, index; + attrlist_cursor_t *cursor = 0; + int total_size = 0; + attrlist_t * al = (attrlist_t *)attr_buffer; + attrlist_ent_t *ae; + size_t ent_size, left = size; + char *bp = list; + + while (True) { + if (filedes) + retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + else + retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + if (retval) break; + for (index = 0; index < al->al_count; index++) { + ae = ATTR_ENTRY(attr_buffer, index); + ent_size = strlen(ae->a_name) + sizeof("user."); + if (left >= ent_size) { + strncpy(bp, "user.", sizeof("user.")); + strncat(bp, ae->a_name, ent_size - sizeof("user.")); + bp += ent_size; + left -= ent_size; + } else if (size) { + errno = ERANGE; + retval = -1; + break; + } + total_size += ent_size; + } + if (al->al_more == 0) break; + } + if (retval == 0) { + flags |= ATTR_ROOT; + cursor = 0; + while (True) { + if (filedes) + retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + else + retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + if (retval) break; + for (index = 0; index < al->al_count; index++) { + ae = ATTR_ENTRY(attr_buffer, index); + ent_size = strlen(ae->a_name) + sizeof("system."); + if (left >= ent_size) { + strncpy(bp, "system.", sizeof("system.")); + strncat(bp, ae->a_name, ent_size - sizeof("system.")); + bp += ent_size; + left -= ent_size; + } else if (size) { + errno = ERANGE; + retval = -1; + break; + } + total_size += ent_size; + } + if (al->al_more == 0) break; + } + } + return (ssize_t)(retval ? retval : total_size); +} + +#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 + ret = listxattr(path, list, size); +#else + int options = 0; + 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) + extattr_arg arg; + arg.path = path; + 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; +#endif +} + +ssize_t sys_llistxattr (const char *path, char *list, size_t size) +{ +#if defined(HAVE_LLISTXATTR) + 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; + + 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) + extattr_arg arg; + arg.path = path; + 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; +#endif +} + +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); +#else + int options = 0; + return removexattr(path, name, options); +#endif +#elif defined(HAVE_REMOVEEA) + return removeea(path, name); +#elif defined(HAVE_EXTATTR_DELETE_FILE) + return extattr_delete_file(path, EXTATTR_NAMESPACE_USER, uname); +#elif defined(HAVE_ATTR_REMOVE) + int flags = 0; + char *attrname = strchr(name,'.') + 1; + + 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; +#endif +} + +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) + int options = XATTR_NOFOLLOW; + return removexattr(path, name, options); +#elif defined(HAVE_LREMOVEEA) + return lremoveea(path, name); +#elif defined(HAVE_EXTATTR_DELETE_LINK) + return extattr_delete_link(path, EXTATTR_NAMESPACE_USER, uname); +#elif defined(HAVE_ATTR_REMOVE) + int flags = ATTR_DONTFOLLOW; + char *attrname = strchr(name,'.') + 1; + + 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; +#endif +} + +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); +#else + int options = 0; + return setxattr(path, name, value, size, 0, options); +#endif +#elif defined(HAVE_SETEA) + return setea(path, name, value, size, flags); +#elif defined(HAVE_EXTATTR_SET_FILE) + int retval = 0; + if (flags) { + /* Check attribute existence */ + retval = extattr_get_file(path, EXTATTR_NAMESPACE_USER, uname, NULL, 0); + if (retval < 0) { + /* REPLACE attribute, that doesn't exist */ + if (flags & XATTR_REPLACE && errno == ENOATTR) { + errno = ENOATTR; + return -1; + } + /* Ignore other errors */ + } + else { + /* CREATE attribute, that already exists */ + if (flags & XATTR_CREATE) { + errno = EEXIST; + return -1; + } + } + } + retval = extattr_set_file(path, EXTATTR_NAMESPACE_USER, uname, value, size); + return (retval < 0) ? -1 : 0; +#elif defined(HAVE_ATTR_SET) + int myflags = 0; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; + if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; + 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; + int attrfd; + if (flags & XATTR_CREATE) myflags |= O_EXCL; + if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; + 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; +#endif +} + +int sys_fsetxattr (int filedes, const char *uname, const void *value, size_t size, int flags) +{ + const char *name = prefix(uname); + +#if defined(HAVE_FSETXATTR) +#ifndef XATTR_ADD_OPT + return fsetxattr(filedes, name, value, size, flags); +#else + int options = 0; + return fsetxattr(filedes, name, value, size, 0, options); +#endif +#elif defined(HAVE_FSETEA) + return fsetea(filedes, name, value, size, flags); +#elif defined(HAVE_EXTATTR_SET_FD) + char *s; + int retval = 0; + int attrnamespace = (strncmp(name, "system", 6) == 0) ? + EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER; + const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1; + if (flags) { + /* Check attribute existence */ + retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0); + if (retval < 0) { + /* REPLACE attribute, that doesn't exist */ + if (flags & XATTR_REPLACE && errno == ENOATTR) { + errno = ENOATTR; + return -1; + } + /* Ignore other errors */ + } + else { + log_error, logtype_default /* CREATE attribute, that already exists */ + if (flags & XATTR_CREATE) { + errno = EEXIST; + return -1; + } + } + } + retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size); + return (retval < 0) ? -1 : 0; +#elif defined(HAVE_ATTR_SETF) + int myflags = 0; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; + if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; + 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; + int attrfd; + if (flags & XATTR_CREATE) myflags |= O_EXCL; + if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; + 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 +} + +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) + int options = XATTR_NOFOLLOW; + return setxattr(path, name, value, size, 0, options); +#elif defined(LSETEA) + return lsetea(path, name, value, size, flags); +#elif defined(HAVE_EXTATTR_SET_LINK) + int retval = 0; + if (flags) { + /* Check attribute existence */ + retval = extattr_get_link(path, EXTATTR_NAMESPACE_USER, uname, NULL, 0); + if (retval < 0) { + /* REPLACE attribute, that doesn't exist */ + if (flags & XATTR_REPLACE && errno == ENOATTR) { + errno = ENOATTR; + return -1; + } + /* Ignore other errors */ + } + else { + /* CREATE attribute, that already exists */ + if (flags & XATTR_CREATE) { + errno = EEXIST; + return -1; + } + } + } + + retval = extattr_set_link(path, EXTATTR_NAMESPACE_USER, uname, value, size); + return (retval < 0) ? -1 : 0; +#elif defined(HAVE_ATTR_SET) + int myflags = ATTR_DONTFOLLOW; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; + if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; + 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; + int attrfd; + if (flags & XATTR_CREATE) myflags |= O_EXCL; + if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; + 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; +#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) { + 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) { + 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; + 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; + if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") || + !strcmp(de->d_name, "SUNWattr_ro") || !strcmp(de->d_name, "SUNWattr_rw")) + { + /* we don't want "." and ".." here: */ + LOG(log_maxdebug, logtype_default, "skipped EA %s\n",de->d_name); + continue; + } + + listlen = strlen(de->d_name); + if (size == 0) { + /* return the current size of the list of extended attribute names*/ + len += listlen + 1; + } else { + /* check size and copy entry + nul into list. */ + if ((len + listlen + 1) > size) { + errno = ERANGE; + len = -1; + break; + } else { + strcpy(list + len, de->d_name); + len += listlen; + list[len] = '\0'; + ++len; + } + } + } + + if (closedir(dirp) == -1) { - LOG(log_debug, logtype_default, "closedir dirp failed: %s\n",strerror(errno)); ++ LOG(log_error, logtype_default, "closedir dirp: %s",strerror(errno)); + return -1; + } + return len; +} + +static int solaris_unlinkat(int attrdirfd, const char *name) +{ + if (unlinkat(attrdirfd, name, 0) == -1) { + 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) { - LOG(log_maxdebug, logtype_default, "attropen FAILED: path: %s, name: %s, errno: %s", - path, attrpath, strerror(errno)); ++ if (errno != ENOENT) ++ LOG(log_error, logtype_default, "attropen(\"%s\", ea:'%s'): %s", ++ path, attrpath, strerror(errno)); + 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) { - LOG(log_maxdebug, logtype_default, "openat FAILED: fd: %d, path: %s, errno: %s", - filedes, path, strerror(errno)); ++ LOG(log_error, logtype_default, "openat(\"%s\"): %s", ++ path, strerror(errno)); + } + 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 { - LOG(log_maxdebug, logtype_default, "solaris_write_xattr FAILED!"); ++ LOG(log_error, logtype_default, "solaris_write_xattr: %s", ++ strerror(errno)); + return -1; + } +} + +#endif /*HAVE_ATTROPEN*/ + diff --cc man/man1/Makefile.am index ef56aadb,0154fc32..52564afb --- a/man/man1/Makefile.am +++ b/man/man1/Makefile.am @@@ -12,9 -12,8 +12,9 @@@ SUFFIXES= .tmpl -e s@:DEFAULT_CNID_SCHEME:@${DEFAULT_CNID_SCHEME}@ \ <$< >$@ - GENERATED_MANS = uniconv.1 asip-status.pl.1 - TEMPLATE_FILES = uniconv.1.tmpl asip-status.pl.1.tmpl + GENERATED_MANS = uniconv.1 asip-status.pl.1 afpldaptest.1 + TEMPLATE_FILES = uniconv.1.tmpl asip-status.pl.1.tmpl afpldaptest.1.tmpl + NONGENERATED_MANS = ad.1 \ afppasswd.1 \ apple_dump.1 \ diff --cc man/man5/Makefile.am index 84dd7b9c,a382039e..2f7ec5b6 --- a/man/man5/Makefile.am +++ b/man/man5/Makefile.am @@@ -23,8 -24,16 +24,9 @@@ TEMPLATE_FILES = AppleVolumes.default.5 afpd.conf.5.tmpl \ netatalk.conf.5.tmpl \ afp_ldap.conf.5.tmpl \ - afp_signature.conf.5.tmpl + afp_signature.conf.5.tmpl \ + afp_voluuid.conf.5.tmpl -ATALK_MANS = atalkd.conf.5.tmpl papd.conf.5.tmpl - -if USE_APPLETALK -GENERATED_MANS += atalkd.conf.5 papd.conf.5 -TEMPLATE_FILES += $(ATALK_MANS) -endif - NONGENERATED_MANS = AppleVolumes.5 AppleVolumes.system.5 man_MANS = $(GENERATED_MANS) $(NONGENERATED_MANS)