# 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
if (alarmed)
return -1;
+ /* This currently doesn't work with "." */
+ if (strcmp(path, ".") == 0) {
+ ERROR("\".\" not supported");
+ }
const char *dir = strrchr(path, '/');
if (dir == NULL)
dir = path;
break;
}
ad_init(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
- if (ad_open_metadata(to.p_path, ADFLAGS_DIR, O_RDWR | O_CREAT, &ad) != 0) {
+ if (ad_open(&ad, to.p_path, ADFLAGS_HF | ADFLAGS_DIR, O_RDWR | O_CREAT, 0666) != 0) {
ERROR("Error opening adouble for: %s", to.p_path);
}
ad_setid( &ad, st.st_dev, st.st_ino, did, pdid, dvolume.db_stamp);
break;
}
ad_init(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
- if (ad_open_metadata(to.p_path, 0, O_RDWR | O_CREAT, &ad) != 0) {
+ if (ad_open(&ad, to.p_path, ADFLAGS_HF, O_RDWR | O_CREAT) != 0) {
ERROR("Error opening adouble for: %s", to.p_path);
}
ad_setid( &ad, st.st_dev, st.st_ino, cnid, did, dvolume.db_stamp);
set_signal();
cnid_init();
if (openvol(argv[argc - 1], &dvolume) != 0) {
- SLOG("Error opening CNID database for %s: ", argv[argc - 1]);
+ SLOG("Error opening CNID database for source \"%s\": ", argv[argc - 1]);
return 1;
}
if (argc > 2)
usage_mv();
if (openvol(argv[0], &svolume) != 0) {
- SLOG("Error opening CNID database for %s: ", argv[0]);
+ SLOG("Error opening CNID database for destination \"%s\": ", argv[0]);
return 1;
}
rval = do_move(argv[0], argv[1]);
rval = 1;
} else {
memmove(endp, p, (size_t)len + 1);
- if (openvol(*argv, &svolume) != 0) {
- SLOG("Error opening CNID database for %s: ", argv[0]);
- rval = 1;
- goto exit;
- }
+ openvol(*argv, &svolume);
+
if (do_move(*argv, path))
rval = 1;
closevol(&svolume);
struct adouble ad;
ad_init(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
- if (ad_open_metadata(to, S_ISDIR(sb.st_mode) ? ADFLAGS_DIR : 0, O_RDWR, &ad) != 0) {
+ if (ad_open(&ad, to, S_ISDIR(sb.st_mode) ? (ADFLAGS_DIR | ADFLAGS_HF) : ADFLAGS_HF, O_RDWR) != 0) {
SLOG("Error opening adouble for: %s", to);
return 1;
}
#include <sys/param.h>
#include <pwd.h>
#include <dirent.h>
+#include <arpa/inet.h>
+
#include <atalk/afp.h>
#include <atalk/unicode.h>
#include <atalk/util.h>
#include <atalk/logger.h>
+#include <atalk/compat.h>
#include "atalk/cnid.h"
#ifndef MAXPATHLEN
{
DIR* startdir;
- if (NULL == (cdb = cnid_open (path, 0, cnid_type, 0, NULL, NULL)) ) {
+ if (NULL == (cdb = cnid_open (path, 0, cnid_type, 0, "localhost", "4700")) ) {
fprintf (stderr, "ERROR: cannot open CNID database in '%s'\n", path);
fprintf (stderr, "ERROR: check the logs for reasons, aborting\n");
return -1;
AC_PROG_PERL
AC_PROG_GREP
AC_PROG_PS
-
AM_PROG_CC_C_O
-dnl Checks for header files.
-AC_HEADER_DIRENT
-AC_HEADER_STDC
-AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(fcntl.h limits.h stdint.h strings.h time.h sys/param.h sys/fcntl.h sys/file.h sys/ioctl.h sys/time.h sys/mnttab.h sys/statvfs.h sys/stat.h sys/vfs.h mntent.h syslog.h unistd.h termios.h sys/termios.h netdb.h sgtty.h ufs/quota.h mount.h statfs.h sys/types.h dlfcn.h errno.h sys/errno.h sys/uio.h langinfo.h locale.h sys/filio.h)
-AC_CHECK_HEADER(sys/cdefs.h,,
- AC_MSG_RESULT([enabling generic cdefs.h from tree])
- CFLAGS="-I\$(top_srcdir)/sys/generic $CFLAGS"
-)
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_INLINE
+
+dnl Request SUSv3 standard interfaces plus anything else the platform may have
+CFLAGS="$CFLAGS -D_XOPEN_SOURCE=600 -D__EXTENSIONS__ -D_GNU_SOURCE"
+
+dnl Check if we can use attribute unused (gcc only) from ethereal
+AC_MSG_CHECKING(to see if we can add '__attribute__((unused))' to CFLAGS)
+if test x$GCC != x ; then
+ CFLAGS="-D_U_=\"__attribute__((unused))\" $CFLAGS"
+ AC_MSG_RESULT(yes)
+else
+ CFLAGS="-D_U_=\"\" $CFLAGS"
+ AC_MSG_RESULT(no)
+fi
+
+dnl Configure libevent
+AC_CONFIG_SUBDIRS([libevent])
+
+dnl Checks for header files, some checks are obsolete, unfortunately the code
+dnl uses the resulting macros, so the code has to cleaned up too before
+dnl we can remove the checks here.
+AC_CHECK_HEADERS(mntent.h unistd.h termios.h ufs/quota.h)
+AC_CHECK_HEADERS(netdb.h sgtty.h statfs.h dlfcn.h langinfo.h locale.h)
+AC_CHECK_HEADERS(sys/param.h sys/fcntl.h sys/termios.h)
+AC_CHECK_HEADERS(sys/mnttab.h sys/statvfs.h sys/stat.h sys/vfs.h)
+dnl Checks for header files, confirmed to be required as of 2011
+AC_CHECK_HEADERS(sys/epoll.h)
AC_CHECK_HEADERS([sys/mount.h], , ,
[#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
])
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_TYPE_UID_T
-AC_C_INLINE
-AC_TYPE_MODE_T
-AC_TYPE_OFF_T
-AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-AC_STRUCT_ST_RDEV
-AC_HEADER_TIME
-AC_STRUCT_TM
+AC_SYS_LARGEFILE([], AC_MSG_ERROR([AFP 3.x support requires Large File Support.]))
dnl --------------------------------------------------------------------------
dnl check if dlsym needs to add an underscore, uses libtool macros
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 <time.h>])
-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
AC_SUBST(PTHREAD_LIBS)
-AC_CACHE_SAVE
-dnl Checks for (v)snprintf
-NETATALK_SNPRINTF_CHECK
+dnl --------------------- Check if realpath() takes NULL
+AC_CACHE_CHECK([if the realpath function allows a NULL argument],
+ neta_cv_REALPATH_TAKES_NULL, [
+ AC_TRY_RUN([
+ #include <stdio.h>
+ #include <limits.h>
+ #include <signal.h>
+
+ void exit_on_core(int ignored) {
+ exit(1);
+ }
+
+ main() {
+ char *newpath;
+ signal(SIGSEGV, exit_on_core);
+ newpath = realpath("/tmp", NULL);
+ exit((newpath != NULL) ? 0 : 1);
+ }],
+ neta_cv_REALPATH_TAKES_NULL=yes,
+ neta_cv_REALPATH_TAKES_NULL=no,
+ neta_cv_REALPATH_TAKES_NULL=cross
+ )
+ ]
+)
+
+if test x"$neta_cv_REALPATH_TAKES_NULL" = x"yes"; then
+ AC_DEFINE(REALPATH_TAKES_NULL,1,[Whether the realpath function allows NULL])
+fi
+
+AC_CACHE_SAVE
dnl --------------------------------------------------------------------------
dnl 64bit platform check
dnl specific configuration comes in here:
dnl --------------------------------------------------------------------------
+dnl Check for optional admin group support
+AC_NETATALK_ADMIN_GROUP
-netatalk_cv_admin_group=yes
-AC_MSG_CHECKING([for administrative group support])
-AC_ARG_ENABLE(admin-group,
- [ --disable-admin-group disable admin group],[
- if test x"$enableval" = x"no"; then
- AC_DEFINE(ADMIN_GRP, 0, [Define if the admin group should be enabled])
- netatalk_cv_admin_group=no
- AC_MSG_RESULT([no])
- else
- AC_DEFINE(ADMIN_GRP, 1, [Define if the admin group should be enabled])
- AC_MSG_RESULT([yes])
- fi],[
- AC_DEFINE(ADMIN_GRP, 1, [Define if the admin group should be enabled])
- AC_MSG_RESULT([yes])
- ]
-)
+dnl Check for optional AFS support
+AC_NETATALK_AFS_CHECK
-NETATALK_AFS_CHECK
-
-NETATALK_CONFIG_DIRS
-
-netatalk_cv_with_cracklib=no
-AC_ARG_WITH(cracklib,
- [ --with-cracklib=DICT enable/set location of cracklib dictionary],[
- if test "x$withval" != "xno" ; then
- cracklib="$withval"
- AC_CHECK_LIB(crack, main, [
- AC_DEFINE(USE_CRACKLIB, 1, [Define if cracklib should be used])
- LIBS="$LIBS -lcrack"
- if test "$cracklib" = "yes"; then
- cracklib="/usr/$atalk_libname/cracklib_dict"
- fi
- AC_DEFINE_UNQUOTED(_PATH_CRACKLIB, "$cracklib",
- [path to cracklib dictionary])
- AC_MSG_RESULT([setting cracklib dictionary to $cracklib])
- netatalk_cv_with_cracklib=yes
- ],[
- AC_MSG_ERROR([cracklib not found!])
- ]
- )
- fi
- ]
-)
-AC_MSG_CHECKING([for cracklib support])
-AC_MSG_RESULT([$netatalk_cv_with_cracklib])
-
-netatalk_cv_ddp_enabled=no
-AC_MSG_CHECKING([whether to enable DDP])
-AC_ARG_ENABLE(ddp,
- [ --enable-ddp enable DDP (AppleTalk)],[
- if test "$enableval" = "yes"; then
- AC_MSG_RESULT([yes])
- netatalk_cv_ddp_enabled=yes
- else
- AC_MSG_RESULT([yes])
- AC_DEFINE(NO_DDP, 1, [Define if DDP should be disabled])
- fi
- ],[
- AC_MSG_RESULT([no])
- AC_DEFINE(NO_DDP, 1, [Define if DDP should be disabled])
- ]
-)
+dnl --with-pkgconfdir check to change configuration directory location
+AC_NETATALK_CONFIG_DIRS
-AC_MSG_CHECKING([whether to enable debug code])
-AC_ARG_ENABLE(debug1,
- [ --enable-debug1 enable debug code],[
- if test "$enableval" != "no"; then
- if test "$enableval" = "yes"; then
- AC_DEFINE(DEBUG1, 1, [Define if debugging information should be included])
- else
- AC_DEFINE_UNQUOTED(DEBUG1, $enableval, [Define if debugging information should be included])
- fi
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- ],[
- AC_MSG_RESULT([no])
- ]
-)
-
-AC_MSG_CHECKING([whether to enable verbose debug code])
-AC_ARG_ENABLE(debug,
- [ --enable-debug enable verbose debug code],[
- if test "$enableval" != "no"; then
- if test "$enableval" = "yes"; then
- AC_DEFINE(DEBUG, 1, [Define if verbose debugging information should be included])
- else
- AC_DEFINE_UNQUOTED(DEBUG, $enableval, [Define if verbose debugging information should be included])
- fi
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- AC_DEFINE(NDEBUG, 1, [Disable assertions])
- fi
- ],[
- AC_MSG_RESULT([no])
- AC_DEFINE(NDEBUG, 1, [Disable assertions])
- ]
-)
+dnl Check for optional cracklib support
+AC_NETATALK_CRACKLIB
-AC_MSG_CHECKING([whether to enable debugging with debuggers])
-AC_ARG_ENABLE(debugging,
- [ --enable-debugging disable SIGALRM timers and DSI tickles (eg for debugging with gdb/dbx/...)],[
- if test "$enableval" != "no"; then
- if test "$enableval" = "yes"; then
- AC_DEFINE(DEBUGGING, 1, [Define if you want to disable SIGALRM timers and DSI tickles])
- else
- AC_DEFINE_UNQUOTED(DEBUGGING, $enableval, [Define if you want to disable SIGALRM timers and DSI tickles])
- fi
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- ],[
- AC_MSG_RESULT([no])
- ]
-)
+dnl Check whether to enable debug code
+AC_NETATALK_DEBUG
-AC_SYS_LARGEFILE([], AC_MSG_ERROR([AFP 3.x support requires Large File Support.]))
-AC_CHECK_ICONV
-
-dnl ----------- A NOTE ABOUT DROPKLUDGE
-dnl The trouble with this fix is that if you know what the file is called, it
-dnl can be read from the Unix side. That's okay for most academic institutions
-dnl since the students don't have telnet access to the Mac servers. There is
-dnl currently no one working on further development/fixes of DROPKLUDGE.
-dnl -----------
-
-netatalk_cv_dropkludge=no
-AC_MSG_CHECKING([whether to enable experimental dropbox support])
-AC_ARG_ENABLE(dropkludge,
- [ --enable-dropkludge enable the experimental dropbox fix (INSECURE!) ],[
- if test "$enableval" = "yes"; then
- AC_DEFINE(DROPKLUDGE, 1, [Define if you want to use the experimental dropkludge support])
- AC_MSG_RESULT([yes])
- netatalk_cv_dropkludge=yes
- else
- AC_MSG_RESULT([no])
- fi
- ],[
- AC_MSG_RESULT([no])
- ]
-)
+dnl Check whethe to disable tickle SIGALARM stuff, which eases debugging
+AC_NETATALK_DEBUGGING
-netatalk_cv_force_uidgid=no
-AC_MSG_CHECKING([whether to enable forcing of uid/gid per volume])
-AC_ARG_ENABLE(force-uidgid,
- [ --enable-force-uidgid allow forcing of uid/gid per volume (BROKEN) ],[
- if test "$enableval" = "yes"; then
- AC_DEFINE(FORCE_UIDGID, 1, [Define if you want forcing of uid/gid per volume])
- AC_MSG_RESULT([enabling forcing of uid/gid per volume])
- AC_MSG_RESULT([yes])
- netatalk_cv_force_uidgid=yes
- else
- AC_MSG_RESULT([no])
- fi
- ],[
- AC_MSG_RESULT([no])
- ]
-)
+dnl Check for libiconv support
+AC_NETATALK_CHECK_ICONV
dnl Check for CNID database backends
-bdb_required=no
AC_NETATALK_CNID([bdb_required=yes],[bdb_required=no])
dnl Check for quota support
-AC_CHECK_QUOTA
+AC_NETATALK_CHECK_QUOTA
dnl Check for optional server location protocol support (used by MacOS X)
-NETATALK_SRVLOC
+AC_NETATALK_SRVLOC
dnl Check for optional Zeroconf support
-NETATALK_ZEROCONF
+AC_NETATALK_ZEROCONF
-dnl Check for PAM libs
-netatalk_cv_use_pam=no
-AC_PATH_PAM([
- use_pam_so=yes
- compile_pam=yes
- netatalk_cv_use_pam=yes
- AC_DEFINE(USE_PAM, 1, [Define to enable PAM support])
-])
+dnl Check for optional TCP-wrappers support
+AC_NETATALK_TCP_WRAPPERS
-netatalk_cv_use_shadowpw=no
-AC_ARG_WITH(shadow,
- [ --with-shadow enable shadow password support [[auto]]],
- [netatalk_cv_use_shadowpw="$withval"],
- [netatalk_cv_use_shadowpw=auto]
-)
-
-if test "x$netatalk_cv_use_shadowpw" != "xno"; then
- AC_CHECK_HEADER([shadow.h])
- if test x"$ac_cv_header_shadow_h" = x"yes"; then
- netatalk_cv_use_shadowpw=yes
- AC_DEFINE(SHADOWPW, 1, [Define if shadow passwords should be used])
- else
- if test "x$shadowpw" = "xyes"; then
- AC_MSG_ERROR([shadow support not available])
- else
- netatalk_cv_use_shadowpw=no
- fi
- fi
-fi
+dnl Check for PAM libs
+AC_NETATALK_PATH_PAM
-AC_MSG_CHECKING([whether shadow support should be enabled])
-if test "x$netatalk_cv_use_shadowpw" = "xyes"; then
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-
+dnl Check for optional shadow password support
+AC_NETATALK_SHADOW
-
-netatalk_cv_use_shellcheck=yes
-AC_MSG_CHECKING([whether checking for a valid shell should be enabled])
-AC_ARG_ENABLE(shell-check,
- [ --disable-shell-check disable checking for a valid shell],[
- if test "$enableval" = "no"; then
- AC_DEFINE(DISABLE_SHELLCHECK, 1, [Define if shell check should be disabled])
- AC_MSG_RESULT([no])
- netatalk_cv_use_shellcheck=no
- else
- AC_MSG_RESULT([yes])
- fi
- ],[
- AC_MSG_RESULT([yes])
- ]
-)
+dnl Check for optional valid-shell-check support
+AC_NETATALK_SHELL_CHECK
-NETATALK_TCP_WRAPPERS
-
-AC_MSG_CHECKING([whether system (fcntl) locking should be disabled])
-AC_ARG_ENABLE(locking,
- [ --disable-locking disable system locking],[
- if test "$enableval" = "no"; then
- AC_DEFINE(DISABLE_LOCKING, 1, [Define if system (fcntl) locking should be disabled])
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
-
- ],[
- AC_MSG_RESULT([no])
- ]
+dnl Check for optional Webmin
+AC_NETATALK_WEBMIN
-)
+dnl Check for optional sysv initscript install
+AC_NETATALK_SYSV_STYLE
+dnl Path where UAM modules shall be installed
+AC_ARG_WITH(uams-path, [ --with-uams-path=PATH path to UAMs [[PKGCONF/uams]]], [uams_path="$withval"], [uams_path="${PKGCONFDIR}/uams"])
-AC_ARG_ENABLE(redhat,
- [ --enable-redhat use redhat-style sysv configuration ],[
- if test "$enableval" = "yes"; then
- sysv_style=redhat
- fi
- AC_MSG_RESULT([enabling redhat-style sysv support])
- ]
-)
+dnl Check for libgcrypt, if found enables DHX2 UAM
+AC_NETATALK_PATH_LIBGCRYPT([1:1.2.3])
-AC_ARG_ENABLE(suse,
- [ --enable-suse use suse-style sysv configuration ],[
- if test "$enableval" = "yes"; then
- sysv_style=suse
- fi
- AC_MSG_RESULT([enabling suse-style sysv support])
- ]
-)
+dnl Check for openssl, if found enables DHX UAM and Randnum UAM
+AC_NETATALK_PATH_SSL
-AC_ARG_ENABLE(gentoo,
- [ --enable-gentoo use gentoo-style sysv configuration ],[
- if test "$enableval" = "yes"; then
- sysv_style=gentoo
- fi
- AC_MSG_RESULT([enabling gentoo-style sysv support])
- ]
-)
+dnl Check for Berkeley DB library
+AC_NETATALK_PATH_BDB
-AC_ARG_ENABLE(cobalt,
- [ --enable-cobalt use cobalt-style sysv configuration ],
- if test "$enableval" = "yes"; then
- sysv_style=cobalt
- fi
- AC_MSG_RESULT([enabling cobalt-style sysv support])
-)
+dnl Check for crypt
+AC_NETATALK_CRYPT
-AC_ARG_ENABLE(netbsd,
- [ --enable-netbsd use NetBSD-style rc.d configuration ],
- if test "x$enableval" = "xyes"; then
- sysv_style=netbsd
- fi
- AC_MSG_RESULT([enabling NetBSD-style rc.d support])
-)
+dnl Check for building PGP UAM module
+AC_NETATALK_PGP_UAM
-AC_ARG_ENABLE(debian,
- [ --enable-debian use debian-style sysv configuration ],[
- if test "$enableval" = "yes"; then
- sysv_style=debian
- fi
- AC_MSG_RESULT([enabling debian-style sysv support])
- ]
-)
+dnl Check for building Kerberos V UAM module
+AC_NETATALK_KRB5_UAM
-dnl ----- timelord compilation (disabled by default)
-AC_MSG_CHECKING([whether timelord should be compiled])
-compile_timelord=no
-AC_ARG_ENABLE(timelord,
- [ --enable-timelord enable compilation of timelord server],
- [compile_timelord="$enableval"],
- [compile_timelord="no"]
-)
-AC_MSG_RESULT([$compile_timelord])
-
-dnl ----- a2boot compilation (disabled by default)
-AC_MSG_CHECKING([whether a2boot should be compiled])
-compile_a2boot=no
-AC_ARG_ENABLE(a2boot,
- [ --enable-a2boot enable compilation of Apple2 boot server],
- [compile_a2boot="$enableval"],
- [compile_a2boot="no"]
-)
-AC_MSG_RESULT([$compile_a2boot])
+dnl Check for overwrite the config files or not
+AC_NETATALK_OVERWRITE_CONFIG
-AC_ARG_WITH(uams-path,
- [ --with-uams-path=PATH path to UAMs [[PKGCONF/uams]]],[
- uams_path="$withval"
- ],[
- uams_path="${PKGCONFDIR}/uams"
- ]
-)
+dnl Check for LDAP support, for client-side ACL visibility
+AC_NETATALK_LDAP
-NETATALK_AC_CUPS
+dnl Check for ACL support
+AC_NETATALK_ACL
-dnl check if we can use attribute unused (gcc only) from ethereal
-AC_MSG_CHECKING(to see if we can add '__attribute__((unused))' to CFLAGS)
-if test x$GCC != x ; then
- CFLAGS="-D_U_=\"__attribute__((unused))\" $CFLAGS"
- AC_MSG_RESULT(yes)
-else
- CFLAGS="-D_U_=\"\" $CFLAGS"
- AC_MSG_RESULT(no)
-fi
+dnl Check for Extended Attributes support
+AC_NETATALK_EXTENDED_ATTRIBUTES
+
+dnl Check for libsmbsharemodes from Samba for Samba/Netatalk access/deny/share modes interop
+AC_NETATALK_SMB_SHAREMODES
dnl --------------------------------------------------------------------------
dnl FHS stuff has to be done last because it overrides other defaults
dnl post-FHS substitutions, etc
dnl --------------------------------------------------------------------------
-dnl ***** UAMS_PATH
-dnl AC_DEFINE_UNQUOTED(UAMS_PATH, "${uams_path}",
-dnl [path to UAMs [default=PKGCONF/uams]])
UAMS_PATH="${uams_path}"
AC_SUBST(UAMS_PATH)
+
+dnl --------------------------------------------------------------------------
+dnl OS specific configuration comes in here:
+dnl --------------------------------------------------------------------------
+
+AC_NETATALK_OS_SPECIFIC
+
+
dnl --------------------------------------------------------------------------
dnl drop in includes for top level directory structures here...
dnl --------------------------------------------------------------------------
dnl Note: $(top_srcdir)/include should be added before all other includes
dnl so that includes from that directory a preferred to includes from
dnl /usr/include or similar places.
-LIBS="$LIBS -L\$(top_srcdir)/libatalk"
-CFLAGS="-I\$(top_srcdir)/include $CFLAGS -I\$(top_srcdir)/sys"
+LIBS="$LIBS -L\$(top_srcdir)/libatalk -L\$(top_srcdir)/libevent"
+CFLAGS="-I\$(top_srcdir)/include -I\$(top_srcdir)/sys -I\$(top_srcdir)/libevent/include $CFLAGS"
AC_DEFINE(OPEN_NOFOLLOW_ERRNO, ELOOP, errno returned by open with O_NOFOLLOW)
+
dnl --------------------------------------------------------------------------
-dnl specific configuration comes in here:
+dnl Last minute substitutions
dnl --------------------------------------------------------------------------
-
-dnl ac_cv_target_os is now host_os, ac_cv_target_cpu is now host_cpu
-
-dnl --------------------- determine operating system from "target"
-case "$host_os" in
- *aix*) this_os=aix ;;
- *freebsd*) this_os=freebsd ;;
- *hpux11*) this_os=hpux11 ;;
- *irix*) this_os=irix ;;
- *linux*) this_os=linux ;;
- *osx*) this_os=macosx ;;
- *darwin*) this_os=macosx ;;
- *netbsd*) this_os=netbsd ;;
- *openbsd*) this_os=openbsd ;;
- *osf*) this_os=tru64 ;;
- *solaris*) this_os=solaris ;;
-esac
-
-case "$host_cpu" in
- i386|i486|i586|i686|k7) this_cpu=x86 ;;
- alpha) this_cpu=alpha ;;
- mips) this_cpu=mips ;;
- powerpc|ppc) this_cpu=ppc ;;
-esac
-
-dnl --------------------- GNU source
-case "$this_os" in
- linux) AC_DEFINE(_GNU_SOURCE, 1, [Whether to use GNU libc extensions])
- ;;
-esac
-
-dnl --------------------- operating system specific flags (port from sys/*)
-
-dnl ----- AIX specific -----
-if test x"$this_os" = "xaix"; then
- AC_MSG_RESULT([ * AIX specific configuration])
- AC_DEFINE(NO_STRUCT_TM_GMTOFF, 1, [Define if the gmtoff member of struct tm is not available])
-
- dnl This is probably a lie; AIX 4.3 supports a 64-bit long
- dnl compilation environment. It's enough to get things defined
- dnl right in endian.h provided that long long is supported, though.
- AC_DEFINE(HAVE_32BIT_LONGS, 1, [Define if the data type long has 32 bit])
-fi
-
-dnl ----- FreeBSD specific -----
-if test x"$this_os" = "xfreebsd"; then
- AC_MSG_RESULT([ * FreeBSD specific configuration])
- AC_DEFINE(BSD4_4, 1, [BSD compatiblity macro])
- AC_DEFINE(FREEBSD, 1, [Define if OS is FreeBSD])
- AC_DEFINE(SENDFILE_FLAVOR_BSD, 1, [Define if the sendfile() function uses BSD semantics])
- AC_DEFINE(OPEN_NOFOLLOW_ERRNO, EMLINK, errno returned by open with O_NOFOLLOW)
-fi
-
-dnl ----- HP-UX 11 specific -----
-if test x"$this_os" = "xhpux11"; then
- AC_MSG_RESULT([ * HP-UX 11 specific configuration])
-
- AC_DEFINE(_ISOC9X_SOURCE, 1, [Compatibility macro])
- AC_DEFINE(NO_STRUCT_TM_GMTOFF, 1, [Define if the gmtoff member of struct tm is not available])
-fi
-
-dnl ----- IRIX specific -----
-if test x"$this_os" = "xirix"; then
- AC_MSG_RESULT([ * IRIX specific configuration])
-
- AC_DEFINE(NO_STRUCT_TM_GMTOFF, 1, [Define if the gmtoff member of struct tm is not available])
-fi
-
-dnl ----- Linux specific -----
-if test x"$this_os" = "xlinux"; then
- AC_MSG_RESULT([ * Linux specific configuration])
-
- dnl ----- kernel 2.6 changed struct at_addr to atalk_addr
- AC_MSG_CHECKING([for struct atalk_addr])
-dnl AC_COMPILE_IFELSE([
- AC_TRY_COMPILE([
-#include <sys/socket.h>
-#include <asm/types.h>
-#include <linux/atalk.h>
-
- struct atalk_addr foo;
-],
-[ ], [
- ac_have_atalk_addr=yes
- AC_MSG_RESULT([yes])
- ], [
- AC_MSG_RESULT([no])
- ])
-
-if test "x$ac_have_atalk_addr" = "xyes"; then
- AC_DEFINE(HAVE_ATALK_ADDR, 1, [set if struct at_addr is called atalk_addr])
-fi
-
- dnl ----- check if we need the quotactl wrapper
-# AC_CHECK_HEADERS(sys/quota.h linux/quota.h)
-# AC_CHECK_FUNC(quotactl,,
-# AC_DEFINE(NEED_QUOTACTL_WRAPPER, 1, [Define if the quotactl wrapper is needed])
-# AC_MSG_RESULT([enabling quotactl wrapper])
-# )
-
- # For quotas on Linux XFS filesystems
-
- # For linux > 2.5.56
- AC_CHECK_HEADERS(linux/dqblk_xfs.h,,
- [AC_CHECK_HEADERS(linux/xqm.h linux/xfs_fs.h)
- AC_CHECK_HEADERS(xfs/libxfs.h xfs/xqm.h xfs/xfs_fs.h)]
- )
-
-
- dnl ----- as far as I can tell, dbtob always does the wrong thing
- dnl ----- on every single version of linux I've ever played with.
- dnl ----- see etc/afpd/quota.c
- AC_DEFINE(HAVE_BROKEN_DBTOB, 1, [Define if dbtob is broken])
-
- netatalk_cv_linux_sendfile=yes
- AC_MSG_CHECKING([use sendfile syscall])
- AC_ARG_ENABLE(sendfile,
- [ --disable-sendfile disable linux sendfile syscall],[
- if test x"$enableval" = x"no"; then
- netatalk_cv_linux_sendfile=no
- AC_MSG_RESULT([no])
- else
- AC_MSG_RESULT([yes])
-
- fi
- ],[
- AC_MSG_RESULT([yes])
- ]
-
- )
-
- if test x"$netatalk_cv_linux_sendfile" = "xyes"; then
- AC_CACHE_CHECK([for linux sendfile support],netatalk_cv_HAVE_SENDFILE,[
- AC_TRY_LINK([#include <sys/sendfile.h>],
-[\
-int tofd, fromfd;
-off_t offset;
-size_t total;
-ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
-],
-netatalk_cv_HAVE_SENDFILE=yes,netatalk_cv_HAVE_SENDFILE=no)])
-
-# Try and cope with broken Linux sendfile....
- AC_CACHE_CHECK([for broken linux sendfile support],netatalk_cv_HAVE_BROKEN_LINUX_SENDFILE,[
- AC_TRY_LINK([\
-#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
-#undef _FILE_OFFSET_BITS
-#endif
-#include <sys/sendfile.h>],
-[\
-int tofd, fromfd;
-off_t offset;
-size_t total;
-ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
-],
-netatalk_cv_HAVE_BROKEN_LINUX_SENDFILE=yes,netatalk_cv_HAVE_BROKEN_LINUX_SENDFILE=no,netatalk_cv_HAVE_BROKEN_SENDFILE=cross)])
-
- if test x"$netatalk_cv_HAVE_SENDFILE" = x"yes"; then
- AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available])
- AC_DEFINE(SENDFILE_FLAVOR_LINUX,1,[Whether linux sendfile() API is available])
- AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() should be used])
- elif test x"$netatalk_cv_HAVE_BROKEN_LINUX_SENDFILE" = x"yes"; then
- AC_DEFINE(SENDFILE_FLAVOR_LINUX,1,[Whether linux sendfile() API is available])
- AC_DEFINE(LINUX_BROKEN_SENDFILE_API,1,[Whether (linux) sendfile() is broken])
- AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile should be used])
- else
- netatalk_cv_linux_sendfile=no
- AC_MSG_RESULT(no);
- fi
- fi
-
- dnl ----- Linux/alpha specific -----
- if test x"$this_cpu" = "xalpha"; then
- AC_MSG_RESULT([enabling gcc memcpy bug workaround])
- AC_DEFINE(HAVE_GCC_MEMCPY_BUG, 1, [Define if memcpy is buggy])
- fi
- need_dash_r=no
-
-
-fi
-
-dnl ----- Mac OSX specific -----
-if test x"$this_os" = "xmacosx"; then
- AC_MSG_RESULT([ * Mac OSX specific configuration])
- AC_DEFINE(BSD4_4, 1, [BSD compatiblity macro])
- AC_DEFINE(HAVE_2ARG_DBTOB, 1, [Define if dbtob takes two arguments])
- dnl AC_DEFINE(NO_DLFCN_H)
- AC_DEFINE(NO_DDP, 1, [Define if DDP should be disabled])
- AC_DEFINE(NO_QUOTA_SUPPORT, 1, [Define if Quota support should be disabled])
- AC_DEFINE(MACOSX_SERVER, 1, [Define if compiling for MacOS X Server])
-fi
-
-dnl ----- NetBSD specific -----
-if test x"$this_os" = "xnetbsd"; then
- AC_MSG_RESULT([ * NetBSD specific configuration])
- AC_DEFINE(BSD4_4, 1, [BSD compatiblity macro])
- AC_DEFINE(NETBSD, 1, [Define if OS is NetBSD])
- AC_DEFINE(OPEN_NOFOLLOW_ERRNO, EFTYPE, errno returned by open with O_NOFOLLOW)
-
- CFLAGS="-I\$(top_srcdir)/sys/netbsd $CFLAGS"
- need_dash_r=yes
-
- dnl ----- NetBSD does not have crypt.h, uses unistd.h -----
- AC_DEFINE(UAM_DHX, 1, [Define if the DHX UAM modules should be compiled])
-fi
-
-dnl ----- OpenBSD specific -----
-if test x"$this_os" = "xopenbsd"; then
- AC_MSG_RESULT([ * OpenBSD specific configuration])
- dnl ----- OpenBSD does not have crypt.h, uses unistd.h -----
- AC_DEFINE(UAM_DHX, 1, [Define if the DHX UAM modules should be compiled])
-fi
-
-dnl ----- Solaris specific -----
-if test x"$this_os" = "xsolaris"; then
- AC_MSG_RESULT([ * Solaris specific configuration])
- AC_DEFINE(__svr4__, 1, [Solaris compatibility macro])
- AC_DEFINE(_ISOC9X_SOURCE, 1, [Compatibility macro])
- AC_DEFINE(NO_STRUCT_TM_GMTOFF, 1, [Define if the gmtoff member of struct tm is not available])
- AC_DEFINE(SOLARIS, 1, [Solaris compatibility macro])
- CFLAGS="-I\$(top_srcdir)/sys/generic $CFLAGS"
- need_dash_r=yes
- sysv_style=solaris
-
- solaris_module=no
- AC_MSG_CHECKING([if we can build Solaris kernel module])
- if test -x /usr/ccs/bin/ld && test x"$netatalk_cv_ddp_enabled" = x"yes" ; then
- solaris_module=yes
- fi
- AC_MSG_RESULT([$solaris_module])
-
- COMPILE_64BIT_KMODULE=no
- KCFLAGS=""
- KLDFLAGS=""
- COMPILE_KERNEL_GCC=no
-
- if test "$solaris_module" = "yes"; then
- dnl Solaris kernel module stuff
- AC_MSG_CHECKING([if we have to build a 64bit kernel module])
-
- # check for isainfo, if not found it has to be a 32 bit kernel (<=2.6)
- if test -x /usr/bin/isainfo; then
- # check for 64 bit platform
- if isainfo -kv | grep '^64-bit'; then
- COMPILE_64BIT_KMODULE=yes
- fi
- fi
-
- AC_MSG_RESULT([$COMPILE_64BIT_KMODULE])
-
- if test "${GCC}" = yes; then
- COMPILE_KERNEL_GCC=yes
- if test "$COMPILE_64BIT_KMODULE" = yes; then
-
- AC_MSG_CHECKING([if we can build a 64bit kernel module])
-
- case `$CC --version 2>/dev/null` in
- [[12]].* | 3.0.*)
- COMPILE_64BIT_KMODULE=no
- COMPILE_KERNEL_GCC=no
- solaris_module=no;;
- *)
- # use for 64 bit
- KCFLAGS="-m64"
- #KLDFLAGS="-melf64_sparc"
- KLDFLAGS="-64";;
- esac
-
- AC_MSG_RESULT([$COMPILE_64BIT_KMODULE])
-
- else
- KCFLAGS=""
- KLDFLAGS=""
- fi
- KCFLAGS="$KCFLAGS -D_KERNEL -Wall -Wstrict-prototypes"
- else
- if test "$COMPILE_64BIT_KMODULE" = yes; then
- # use Sun CC (for a 64-bit kernel, uncomment " -xarch=v9 -xregs=no%appl ")
- KCFLAGS="-xarch=v9 -xregs=no%appl"
- KLDFLAGS="-64"
- else
- KCFLAGS=""
- KLDFLAGS=""
- fi
- KCFLAGS="-D_KERNEL $KCFLAGS -mno-app-regs -munaligned-doubles -fpcc-struct-return"
- fi
-
- AC_CACHE_CHECK([for timeout_id_t],netatalk_cv_HAVE_TIMEOUT_ID_T,[
- AC_TRY_LINK([\
-#include <sys/stream.h>
-#include <sys/ddi.h>],
-[\
-timeout_id_t dummy;
-],
-netatalk_cv_HAVE_TIMEOUT_ID_T=yes,netatalk_cv_HAVE_TIMEOUT_ID_T=no,netatalk_cv_HAVE_TIMEOUT_ID_T=cross)])
-
- AC_DEFINE(HAVE_TIMEOUT_ID_T, test x"$netatalk_cv_HAVE_TIMEOUT_ID" = x"yes", [define for timeout_id_t])
- fi
-
- AC_SUBST(COMPILE_KERNEL_GCC)
- AC_SUBST(COMPILE_64BIT_KMODULE)
- AC_SUBST(KCFLAGS)
- AC_SUBST(KLDFLAGS)
-fi
-
-dnl ----- Tru64 specific -----
-if test x"$this_os" = "xtru64"; then
- AC_MSG_RESULT([ * Tru64 specific configuration])
- AC_DEFINE(NO_DDP, 1, [Define if DDP should be disabled])
- AC_DEFINE(HAVE_64BIT_LONGS, 1, [Define if the data type long has 64 bit])
- dnl AC_DEFINE(USE_MOUNT_H)
- AC_DEFINE(USE_OLD_RQUOTA, 1, [Define to use old rquota])
- dnl AC_DEFINE(USE_UFS_QUOTA_H)
- AC_DEFINE(TRU64, 1, [Define on Tru64 platforms])
- AC_DEFINE(_OSF_SOURCE, 1, [Define if the *passwd UAMs should be used])
- AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Define for Berkeley DB 4])
- AC_CHECK_LIB(security,set_auth_parameters)
- CFLAGS="-I\$(top_srcdir)/sys/tru64 $CFLAGS"
- need_dash_r=no
- sysv_style=tru64
-fi
-
-dnl -- check for libgcrypt, if found enables DHX UAM
-AM_PATH_LIBGCRYPT([1:1.2.3],[neta_cv_compile_dhx2=yes
- neta_cv_have_libgcrypt=yes
- AC_MSG_NOTICE([Enabling DHX2 UAM])
- AC_DEFINE(HAVE_LIBGCRYPT, 1, [Define if the DHX2 modules should be built with libgcrypt])
- AC_DEFINE(UAM_DHX2, 1, [Define if the DHX2 UAM modules should be compiled])
- ])
-
-dnl -- look for openssl, if found enables DHX UAM and Randnum UAM
-AC_PATH_SSL
-
-dnl Check for Berkeley DB library
-if test "x$bdb_required" = "xyes"; then
- AC_PATH_BDB(, [
- AC_MSG_RESULT([])
- AC_MSG_RESULT([Make sure you have the required Berkeley DB libraries AND headers installed.])
- AC_MSG_RESULT([You can download the latest version from http://www.sleepycat.com.])
- AC_MSG_RESULT([If you have installed BDB in a non standard location use the])
- AC_MSG_RESULT([--with-bdb=/path/to/bdb configure option and make sure])
- AC_MSG_RESULT([your linker is configured to check for libraries there.])
- AC_MSG_ERROR([Berkeley DB library required but not found!])
- ])
-fi
-
-dnl -- check for crypt
-AC_CRYPT
-
-dnl --------------------- check for building PGP UAM module
-
-AC_MSG_CHECKING([whether the PGP UAM should be build])
-AC_ARG_ENABLE(pgp-uam,
- [ --enable-pgp-uam enable build of PGP UAM module],[
- if test "$enableval" = "yes"; then
- if test "x$neta_cv_have_openssl" = "xyes"; then
- AC_DEFINE(UAM_PGP, 1, [Define if the PGP UAM module should be compiled])
- compile_pgp=yes
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- fi
- ],[
- AC_MSG_RESULT([no])
- ]
-)
-
-dnl --------------------- check for building Kerberos v4 UAM module
-
-AC_MSG_CHECKING([whether the Kerberos IV UAM should be build])
-AC_ARG_ENABLE(krb4-uam,
- [ --enable-krb4-uam enable build of Kerberos v4 UAM module],[
- if test "$enableval" = "yes"; then
- AC_DEFINE(UAM_KRB4, 1, [Define if the Kerberos 4 UAM module should be compiled])
- compile_kerberos=yes
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- ],[
- AC_MSG_RESULT([no])
- ]
-)
-
-dnl --------------------- check for building Kerberos V UAM module
-
-netatalk_cv_build_krb5_uam=no
-AC_ARG_ENABLE(krbV-uam,
- [ --enable-krbV-uam enable build of Kerberos V UAM module],
- [
- if test x"$enableval" = x"yes"; then
- NETATALK_GSSAPI_CHECK([
- netatalk_cv_build_krb5_uam=yes
- ],[
- AC_MSG_ERROR([need GSSAPI to build Kerberos V UAM])
- ])
- fi
- ]
-
-)
-
-AC_MSG_CHECKING([whether Kerberos V UAM should be build])
-if test x"$netatalk_cv_build_krb5_uam" = x"yes"; then
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
-AM_CONDITIONAL(USE_GSSAPI, test x"$netatalk_cv_build_krb5_uam" = x"yes")
-
-dnl --------------------- overwrite the config files . . . or not.
-
-AC_MSG_CHECKING([whether configuration files should be overwritten])
-AC_ARG_ENABLE(overwrite,
- [ --enable-overwrite overwrite configuration files during installation],
- [OVERWRITE_CONFIG="${enable_overwrite}"],
- [OVERWRITE_CONFIG="no"]
-)
-AC_MSG_RESULT([$OVERWRITE_CONFIG])
-
-dnl --------------------- check for LDAP support, for client-side ACL visibility
-AC_MSG_CHECKING(for LDAP (necessary for client-side ACL visibility))
-AC_ARG_WITH(ldap,
- [AS_HELP_STRING([--with-ldap],
- [LDAP support (default=auto)])],
- [ case "$withval" in
- yes|no)
- with_ldap="$withval"
- ;;
- *)
- with_ldap=auto
- ;;
- esac ])
-AC_MSG_RESULT($with_ldap)
-
-if test x"$with_ldap" != x"no" ; then
- AC_CHECK_HEADER([ldap.h], with_ldap=yes,
- [ if test x"$with_ldap" = x"yes" ; then
- AC_MSG_ERROR([Missing LDAP headers])
- fi
- with_ldap=no
- ])
- AC_CHECK_LIB(ldap, ldap_init, with_ldap=yes,
- [ if test x"$with_ldap" = x"yes" ; then
- AC_MSG_ERROR([Missing LDAP library])
- fi
- with_ldap=no
- ])
-fi
-
-if test x"$with_ldap" = x"yes"; then
- AC_DEFINE(HAVE_LDAP,1,[Whether LDAP is available])
-fi
-
-dnl --------------------- check for ACL support
-AC_MSG_CHECKING(whether to support ACLs)
-AC_ARG_WITH(acls,
- [AS_HELP_STRING([--with-acls],
- [Include ACL support (default=auto)])],
- [ case "$withval" in
- yes|no)
- with_acl_support="$withval"
- ;;
- *)
- with_acl_support=auto
- ;;
- esac ],
- [with_acl_support=auto])
-AC_MSG_RESULT($with_acl_support)
-
-if test x"$with_acl_support" = x"no"; then
- AC_MSG_RESULT(Disabling ACL support)
- AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support should be built in])
-else
- with_acl_support=yes
-fi
-
-if test x"$with_acl_support" = x"yes" ; then
- AC_MSG_NOTICE(checking whether ACL support is available:)
- case "$host_os" in
- *sysv5*)
- AC_MSG_NOTICE(Using UnixWare ACLs)
- AC_DEFINE(HAVE_UNIXWARE_ACLS,1,[Whether UnixWare ACLs are available])
- ;;
- *solaris*)
- AC_MSG_NOTICE(Using solaris ACLs)
- AC_DEFINE(HAVE_SOLARIS_ACLS,1,[Whether solaris ACLs are available])
- ACL_LIBS="$ACL_LIBS -lsec"
- ;;
- *hpux*)
- AC_MSG_NOTICE(Using HPUX ACLs)
- AC_DEFINE(HAVE_HPUX_ACLS,1,[Whether HPUX ACLs are available])
- ;;
- *irix*)
- AC_MSG_NOTICE(Using IRIX ACLs)
- AC_DEFINE(HAVE_IRIX_ACLS,1,[Whether IRIX ACLs are available])
- ;;
- *aix*)
- AC_MSG_NOTICE(Using AIX ACLs)
- AC_DEFINE(HAVE_AIX_ACLS,1,[Whether AIX ACLs are available])
- ;;
- *osf*)
- AC_MSG_NOTICE(Using Tru64 ACLs)
- AC_DEFINE(HAVE_TRU64_ACLS,1,[Whether Tru64 ACLs are available])
- ACL_LIBS="$ACL_LIBS -lpacl"
- ;;
- *darwin*)
- AC_MSG_NOTICE(ACLs on Darwin currently not supported)
- AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support is available])
- ;;
- *)
- AC_CHECK_LIB(acl,acl_get_file,[ACL_LIBS="$ACL_LIBS -lacl"])
- case "$host_os" in
- *linux*)
- AC_CHECK_LIB(attr,getxattr,[ACL_LIBS="$ACL_LIBS -lattr"])
- ;;
- esac
- AC_CACHE_CHECK([for POSIX ACL support],netatalk_cv_HAVE_POSIX_ACLS,[
- acl_LIBS=$LIBS
- LIBS="$LIBS $ACL_LIBS"
- AC_TRY_LINK([
- #include <sys/types.h>
- #include <sys/acl.h>
- ],[
- acl_t acl;
- int entry_id;
- acl_entry_t *entry_p;
- return acl_get_entry(acl, entry_id, entry_p);
- ],
- [netatalk_cv_HAVE_POSIX_ACLS=yes],
- [netatalk_cv_HAVE_POSIX_ACLS=no
- with_acl_support=no])
- LIBS=$acl_LIBS
- ])
- if test x"$netatalk_cv_HAVE_POSIX_ACLS" = x"yes"; then
- AC_MSG_NOTICE(Using POSIX ACLs)
- AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether POSIX ACLs are available])
- AC_CACHE_CHECK([for acl_get_perm_np],netatalk_cv_HAVE_ACL_GET_PERM_NP,[
- acl_LIBS=$LIBS
- LIBS="$LIBS $ACL_LIBS"
- AC_TRY_LINK([
- #include <sys/types.h>
- #include <sys/acl.h>
- ],[
- acl_permset_t permset_d;
- acl_perm_t perm;
- return acl_get_perm_np(permset_d, perm);
- ],
- [samba_cv_HAVE_ACL_GET_PERM_NP=yes],
- [samba_cv_HAVE_ACL_GET_PERM_NP=no])
- LIBS=$acl_LIBS
- ])
- if test x"netatalk_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
- AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available])
- fi
- else
- AC_MSG_NOTICE(ACL support is not avaliable)
- AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support is available])
- fi
- ;;
- esac
-fi
-
-if test x"$with_acl_support" = x"yes" ; then
- AC_DEFINE(HAVE_ACLS,1,[Whether ACLs support is available])
- AC_SUBST(ACL_LIBS)
-fi
-
-dnl --------------------- check for Extended Attributes support
-neta_cv_eas="ad"
-neta_cv_eas_sys_found=no
-neta_cv_eas_sys_not_found=no
-
-AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h sys/extattr.h sys/uio.h sys/ea.h)
-
-case "$this_os" in
-
- *osf*)
- AC_SEARCH_LIBS(getproplist, [proplist])
- AC_CHECK_FUNCS([getproplist fgetproplist setproplist fsetproplist],
- [neta_cv_eas_sys_found=yes],
- [neta_cv_eas_sys_not_found=yes])
- AC_CHECK_FUNCS([delproplist fdelproplist add_proplist_entry get_proplist_entry],,
- [neta_cv_eas_sys_not_found=yes])
- AC_CHECK_FUNCS([sizeof_proplist_entry],,
- [neta_cv_eas_sys_not_found=yes])
- ;;
-
- *solaris*)
- AC_CHECK_FUNCS([attropen],
- [neta_cv_eas_sys_found=yes],
- [neta_cv_eas_sys_not_found=yes])
- ;;
-
- 'freebsd')
- AC_CHECK_FUNCS([extattr_delete_fd extattr_delete_file extattr_delete_link],
- [neta_cv_eas_sys_found=yes],
- [neta_cv_eas_sys_not_found=yes])
- AC_CHECK_FUNCS([extattr_get_fd extattr_get_file extattr_get_link],,
- [neta_cv_eas_sys_not_found=yes])
- AC_CHECK_FUNCS([extattr_list_fd extattr_list_file extattr_list_link],,
- [neta_cv_eas_sys_not_found=yes])
- AC_CHECK_FUNCS([extattr_set_fd extattr_set_file extattr_set_link],,
- [neta_cv_eas_sys_not_found=yes])
- ;;
-
- *freebsd4* | *dragonfly* )
- AC_DEFINE(BROKEN_EXTATTR, 1, [Does extattr API work])
- ;;
-
- *)
- AC_SEARCH_LIBS(getxattr, [attr])
-
- if test "x$neta_cv_eas_sys_found" != "xyes" ; then
- AC_CHECK_FUNCS([getxattr lgetxattr fgetxattr listxattr llistxattr],
- [neta_cv_eas_sys_found=yes],
- [neta_cv_eas_sys_not_found=yes])
- AC_CHECK_FUNCS([flistxattr removexattr lremovexattr fremovexattr],,
- [neta_cv_eas_sys_not_found=yes])
- AC_CHECK_FUNCS([setxattr lsetxattr fsetxattr],,
- [neta_cv_eas_sys_not_found=yes])
- fi
-
- if test "x$neta_cv_eas_sys_found" != "xyes" ; then
- AC_CHECK_FUNCS([getea fgetea lgetea listea flistea llistea],
- [neta_cv_eas_sys_found=yes],
- [neta_cv_eas_sys_not_found=yes])
- AC_CHECK_FUNCS([removeea fremoveea lremoveea setea fsetea lsetea],,
- [neta_cv_eas_sys_not_found=yes])
- fi
-
- if test "x$neta_cv_eas_sys_found" != "xyes" ; then
- AC_CHECK_FUNCS([attr_get attr_list attr_set attr_remove],,
- [neta_cv_eas_sys_not_found=yes])
- AC_CHECK_FUNCS([attr_getf attr_listf attr_setf attr_removef],,
- [neta_cv_eas_sys_not_found=yes])
- fi
- ;;
-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
-
-if test "x$neta_cv_eas_sys_found" = "xyes" ; then
- if test "x$neta_cv_eas_sys_not_found" != "xyes" ; then
- neta_cv_eas="$neta_cv_eas | sys"
- fi
-fi
-AC_DEFINE_UNQUOTED(EA_MODULES,["$neta_cv_eas"],[Available Extended Attributes modules])
-
-dnl --------------------- Check if realpath() takes NULL
-AC_CACHE_CHECK([if the realpath function allows a NULL argument],
- neta_cv_REALPATH_TAKES_NULL, [
- AC_TRY_RUN([
- #include <stdio.h>
- #include <limits.h>
- #include <signal.h>
-
- void exit_on_core(int ignored) {
- exit(1);
- }
-
- main() {
- char *newpath;
- signal(SIGSEGV, exit_on_core);
- newpath = realpath("/tmp", NULL);
- exit((newpath != NULL) ? 0 : 1);
- }],
- neta_cv_REALPATH_TAKES_NULL=yes,
- neta_cv_REALPATH_TAKES_NULL=no,
- neta_cv_REALPATH_TAKES_NULL=cross
- )
- ]
-)
-
-if test x"$neta_cv_REALPATH_TAKES_NULL" = x"yes"; then
- AC_DEFINE(REALPATH_TAKES_NULL,1,[Whether the realpath function allows NULL])
-fi
-
-dnl --------------------- Netatalk Webmin
-NETATALK_WEBMIN
-
-dnl --------------------- last minute substitutions
-
AC_SUBST(LIBS)
AC_SUBST(CFLAGS)
-AC_SUBST(OVERWRITE_CONFIG)
AM_CONDITIONAL(SOLARIS_MODULE, test x$solaris_module = xyes)
-AM_CONDITIONAL(COMPILE_TIMELORD, test x$compile_timelord = xyes)
-AM_CONDITIONAL(COMPILE_A2BOOT, test x$compile_a2boot = xyes)
AM_CONDITIONAL(HAVE_LIBGCRYPT, test x$neta_cv_have_libgcrypt = xyes)
AM_CONDITIONAL(HAVE_OPENSSL, test x$neta_cv_have_openssl = xyes)
AM_CONDITIONAL(HAVE_ACLS, test x"$with_acl_support" = x"yes")
AM_CONDITIONAL(USE_DHX, test x$neta_cv_compile_dhx = xyes)
AM_CONDITIONAL(USE_DHX2, test x$neta_cv_compile_dhx2 = xyes)
AM_CONDITIONAL(USE_RANDNUM, test x$neta_cv_have_openssl = xyes)
-AM_CONDITIONAL(USE_KERBEROS, test x$compile_kerberos = xyes)
AM_CONDITIONAL(USE_PAM_SO, test x$use_pam_so = xyes)
AM_CONDITIONAL(USE_PAM, test x$netatalk_cv_install_pam = xyes)
AM_CONDITIONAL(BUILD_PAM, test x$compile_pam = xyes)
AM_CONDITIONAL(USE_PGP, test x$compile_pgp = xyes)
AM_CONDITIONAL(DEFAULT_HOOK, test x$neta_cv_have_libgcrypt != xyes && test x$neta_cv_have_openssl != xyes)
-AM_CONDITIONAL(USE_COBALT, test x$sysv_style = xcobalt)
AM_CONDITIONAL(USE_NETBSD, test x$sysv_style = xnetbsd)
AM_CONDITIONAL(USE_REDHAT, test x$sysv_style = xredhat)
AM_CONDITIONAL(USE_SUSE, test x$sysv_style = xsuse)
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
AC_OUTPUT([Makefile
bin/Makefile
bin/ad/Makefile
- bin/adv1tov2/Makefile
- bin/aecho/Makefile
bin/afppasswd/Makefile
bin/cnid/Makefile
bin/cnid/cnid2_create
- bin/getzones/Makefile
bin/megatron/Makefile
bin/misc/Makefile
- bin/nbp/Makefile
- bin/pap/Makefile
- bin/psorder/Makefile
bin/uniconv/Makefile
config/Makefile
config/pam/Makefile
contrib/Makefile
contrib/macusers/Makefile
contrib/macusers/macusers
- contrib/printing/Makefile
contrib/shell_utils/Makefile
contrib/shell_utils/afpd-mtab.pl
contrib/shell_utils/apple_dump
contrib/shell_utils/asip-status.pl
- contrib/timelord/Makefile
- contrib/a2boot/Makefile
distrib/Makefile
distrib/config/Makefile
distrib/config/netatalk-config
doc/Makefile
etc/Makefile
etc/afpd/Makefile
- etc/atalkd/Makefile
etc/cnid_dbd/Makefile
+ etc/netalockd/Makefile
etc/uams/Makefile
- etc/uams/uams_krb4/Makefile
- etc/papd/Makefile
- etc/psf/Makefile
include/Makefile
include/atalk/Makefile
libatalk/Makefile
libatalk/acl/Makefile
libatalk/adouble/Makefile
- libatalk/asp/Makefile
- libatalk/atp/Makefile
libatalk/bstring/Makefile
libatalk/cnid/Makefile
libatalk/cnid/cdb/Makefile
libatalk/cnid/tdb/Makefile
libatalk/compat/Makefile
libatalk/dsi/Makefile
- libatalk/nbp/Makefile
- libatalk/netddp/Makefile
- libatalk/util/Makefile
+ libatalk/locking/Makefile
+ libatalk/rpc/Makefile
+ libatalk/talloc/Makefile
+ libatalk/tevent/Makefile
+ libatalk/tsocket/Makefile
libatalk/tdb/Makefile
libatalk/unicode/Makefile
libatalk/unicode/charsets/Makefile
+ libatalk/util/Makefile
libatalk/vfs/Makefile
macros/Makefile
man/Makefile
man/man1/Makefile
- man/man3/Makefile
- man/man4/Makefile
man/man5/Makefile
man/man8/Makefile
- sys/Makefile
- sys/generic/Makefile
- sys/generic/sys/Makefile
- sys/netatalk/Makefile
- sys/netbsd/Makefile
- sys/netbsd/netatalk/Makefile
- sys/solaris/Makefile
- sys/sunos/Makefile
- sys/ultrix/Makefile
test/Makefile
test/afpd/Makefile
+ test/netalockd/Makefile
],
[chmod a+x distrib/config/netatalk-config contrib/shell_utils/apple_*]
)
noinst_PROGRAMS = hash
afpd_SOURCES = \
- afp_asp.c \
afp_avahi.c \
afp_config.c \
afp_dsi.c \
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 \
#include <atalk/logger.h>
#include <atalk/util.h>
#include <atalk/dsi.h>
-#include <atalk/atp.h>
-#include <atalk/asp.h>
-#include <atalk/nbp.h>
#include <atalk/afp.h>
#include <atalk/compat.h>
#include <atalk/server_child.h>
}
switch (p->obj.proto) {
-#ifndef NO_DDP
- case AFPPROTO_ASP:
- free(p->obj.Obj);
- free(p->obj.Type);
- free(p->obj.Zone);
- atp_close(((ASP) p->obj.handle)->asp_atp);
- free(p->obj.handle);
- break;
-#endif /* no afp/asp */
case AFPPROTO_DSI:
close(p->fd);
free(p->obj.handle);
char *conv_name;
unsigned char *p;
unsigned int i = 0;
-#ifndef NO_DDP
- char *Obj, *Type = "", *Zone = "";
-#endif
/* Convert name to maccharset */
if ((size_t)-1 ==(convert_string_allocate( options->unixcharset, options->maccharset,
}
buf[i] = '\0';
-#ifndef NO_DDP
- /* Add ZONE, */
- if (nbp_name(options->server, &Obj, &Type, &Zone )) {
- LOG(log_error, logtype_afpd, "srvloc_encode: can't parse %s", options->server );
- }
- else {
- snprintf( buf+i, sizeof(buf)-i-1 ,"&ZONE=%s", Zone);
- }
-#endif
free (conv_name);
return buf;
#endif /* USE_SRVLOC */
}
-#ifndef NO_DDP
-static void asp_cleanup(const AFPConfig *config)
-{
- /* we need to stop tickle handler */
- asp_stop_tickle();
- nbp_unrgstr(config->obj.Obj, config->obj.Type, config->obj.Zone,
- &config->obj.options.ddpaddr);
-}
-
-/* these two are almost identical. it should be possible to collapse them
- * into one with minimal junk. */
-static int asp_start(AFPConfig *config, AFPConfig *configs,
- server_child *server_children)
-{
- ASP asp;
-
- if (!(asp = asp_getsession(config->obj.handle, server_children,
- config->obj.options.tickleval))) {
- LOG(log_error, logtype_afpd, "main: asp_getsession: %s", strerror(errno) );
- exit( EXITERR_CLNT );
- }
-
- if (asp->child) {
- configfree(configs, config); /* free a bunch of stuff */
- afp_over_asp(&config->obj);
- exit (0);
- }
-
- return 0;
-}
-#endif /* no afp/asp */
-
static afp_child_t *dsi_start(AFPConfig *config, AFPConfig *configs,
server_child *server_children)
{
return child;
}
-#ifndef NO_DDP
-static AFPConfig *ASPConfigInit(const struct afp_options *options,
- unsigned char *refcount)
-{
- AFPConfig *config;
- ATP atp;
- ASP asp;
- char *Obj, *Type = "AFPServer", *Zone = "*";
- char *convname = NULL;
-
- if ((config = (AFPConfig *) calloc(1, sizeof(AFPConfig))) == NULL)
- return NULL;
-
- if ((atp = atp_open(ATADDR_ANYPORT, &options->ddpaddr)) == NULL) {
- LOG(log_error, logtype_afpd, "main: atp_open: %s", strerror(errno) );
- free(config);
- return NULL;
- }
-
- if ((asp = asp_init( atp )) == NULL) {
- LOG(log_error, logtype_afpd, "main: asp_init: %s", strerror(errno) );
- atp_close(atp);
- free(config);
- return NULL;
- }
-
- /* register asp server */
- Obj = (char *) options->hostname;
- if (options->server && (size_t)-1 ==(convert_string_allocate( options->unixcharset, options->maccharset,
- options->server, strlen(options->server), &convname)) ) {
- if ((convname = strdup(options->server)) == NULL ) {
- LOG(log_error, logtype_afpd, "malloc: %s", strerror(errno) );
- goto serv_free_return;
- }
- }
-
- if (nbp_name(convname, &Obj, &Type, &Zone )) {
- LOG(log_error, logtype_afpd, "main: can't parse %s", options->server );
- goto serv_free_return;
- }
- if (convname)
- free (convname);
-
- /* dup Obj, Type and Zone as they get assigned to a single internal
- * buffer by nbp_name */
- if ((config->obj.Obj = strdup(Obj)) == NULL)
- goto serv_free_return;
-
- if ((config->obj.Type = strdup(Type)) == NULL) {
- free(config->obj.Obj);
- goto serv_free_return;
- }
-
- if ((config->obj.Zone = strdup(Zone)) == NULL) {
- free(config->obj.Obj);
- free(config->obj.Type);
- goto serv_free_return;
- }
-
- /* make sure we're not registered */
- nbp_unrgstr(Obj, Type, Zone, &options->ddpaddr);
- if (nbp_rgstr( atp_sockaddr( atp ), Obj, Type, Zone ) < 0 ) {
- LOG(log_error, logtype_afpd, "Can't register %s:%s@%s", Obj, Type, Zone );
- free(config->obj.Obj);
- free(config->obj.Type);
- free(config->obj.Zone);
- goto serv_free_return;
- }
-
- LOG(log_info, logtype_afpd, "%s:%s@%s started on %u.%u:%u (%s)", Obj, Type, Zone,
- ntohs( atp_sockaddr( atp )->sat_addr.s_net ),
- atp_sockaddr( atp )->sat_addr.s_node,
- atp_sockaddr( atp )->sat_port, VERSION );
-
- config->fd = atp_fileno(atp);
- config->obj.handle = asp;
- config->obj.config = config;
- config->obj.proto = AFPPROTO_ASP;
-
- memcpy(&config->obj.options, options, sizeof(struct afp_options));
- config->optcount = refcount;
- (*refcount)++;
-
- config->server_start = asp_start;
- config->server_cleanup = asp_cleanup;
-
- return config;
-
-serv_free_return:
- asp_close(asp);
- free(config);
- return NULL;
-}
-#endif /* no afp/asp */
-
-
static AFPConfig *DSIConfigInit(const struct afp_options *options,
unsigned char *refcount,
const dsi_proto protocol)
free(config);
return NULL;
}
+ dsi->dsireadbuf = options->dsireadbuf;
if (options->flags & OPTION_PROXY) {
LOG(log_note, logtype_afpd, "AFP/TCP proxy initialized for %s:%d (%s)",
static AFPConfig *AFPConfigInit(struct afp_options *options,
const struct afp_options *defoptions)
{
- AFPConfig *config = NULL, *next = NULL;
+ AFPConfig *next = NULL;
unsigned char *refcount;
if ((refcount = (unsigned char *)
return NULL;
}
-#ifndef NO_DDP
- /* handle asp transports */
- if ((options->transports & AFPTRANS_DDP) &&
- (config = ASPConfigInit(options, refcount)))
- config->defoptions = defoptions;
-#endif /* NO_DDP */
-
-
/* set signature */
set_signature(options);
* (next = DSIConfigInit(options, refcount, i)))
* next->defoptions = defoptions;
*/
- if ((options->transports & AFPTRANS_TCP) &&
- (((options->flags & OPTION_PROXY) == 0) ||
- ((options->flags & OPTION_PROXY) && config))
- && (next = DSIConfigInit(options, refcount, DSI_TCPIP)))
+ if ( (options->transports & AFPTRANS_TCP)
+ &&
+ ((options->flags & OPTION_PROXY) == 0)
+ &&
+ (next = DSIConfigInit(options, refcount, DSI_TCPIP)))
next->defoptions = defoptions;
/* load in all the authentication modules. we can load the same
/* this should be able to accept multiple dsi transports. i think
* the only thing that gets affected is the net addresses. */
- status_init(config, next, options);
-
- /* attach dsi config to tail of asp config */
- if (config) {
- config->next = next;
- return config;
- }
+ status_init(next, options);
return next;
}
first = AFPConfigInit(cmdline, cmdline);
/* Now register with zeroconf, we also need the volumes for that */
- load_volumes(&first->obj);
- zeroconf_register(first);
+ if (! (first->obj.options.flags & OPTION_NOZEROCONF)) {
+ load_volumes(&first->obj);
+ zeroconf_register(first);
+ }
return first;
}
#include <atalk/dsi.h>
#include <atalk/compat.h>
#include <atalk/util.h>
+#include <atalk/locking.h>
#include "globals.h"
#include "switch.h"
#include "fork.h"
#include "dircache.h"
-#ifdef FORCE_UIDGID
-#warning UIDGID
-#include "uid.h"
-#endif /* FORCE_UIDGID */
-
/*
* We generally pass this from afp_over_dsi to all afp_* funcs, so it should already be
* available everywhere. Unfortunately some funcs (eg acltoownermode) need acces to it
dsi_attention(AFPobj->handle, AFPATTN_SHUTDOWN);
afp_dsi_close(AFPobj);
- if (sig) /* if no signal, assume dieing because logins are disabled &
+ if (sig) /* if no signal, assume dieing because logins are disabled &
don't log it (maintenance mode)*/
LOG(log_info, logtype_afpd, "Connection terminated");
if (sig == SIGTERM || sig == SIGALRM) {
if (dsi->flags & DSI_SLEEPING) {
if (dsi->tickle > AFPobj->options.sleep) {
- LOG(log_error, logtype_afpd, "afp_alarm: sleep time ended");
+ LOG(log_note, logtype_afpd, "afp_alarm: sleep time ended");
afp_dsi_die(EXITERR_CLNT);
}
return;
if (dsi->flags & DSI_DISCONNECTED) {
if (dsi->tickle > AFPobj->options.disconnected) {
- LOG(log_error, logtype_afpd, "afp_alarm: no reconnect within 10 minutes, goodbye");
+ LOG(log_error, logtype_afpd, "afp_alarm: reconnect timer expired, goodbye");
afp_dsi_die(EXITERR_CLNT);
}
return;
}
if ((err = pollvoltime(AFPobj)) == 0)
+ LOG(log_debug, logtype_afpd, "afp_alarm: sending DSI tickle");
err = dsi_tickle(AFPobj->handle);
if (err <= 0) {
LOG(log_error, logtype_afpd, "afp_alarm: connection problem, entering disconnected state");
+ dsi->proto_close(dsi);
dsi->flags |= DSI_DISCONNECTED;
}
}
if (dircache_init(obj->options.dircachesize) != 0)
afp_dsi_die(EXITERR_SYS);
+ /* set TCP snd/rcv buf */
+ if (obj->options.tcp_rcvbuf) {
+ if (setsockopt(dsi->socket,
+ SOL_SOCKET,
+ SO_RCVBUF,
+ &obj->options.tcp_rcvbuf,
+ sizeof(obj->options.tcp_rcvbuf)) != 0) {
+ LOG(log_error, logtype_dsi, "afp_over_dsi: setsockopt(SO_RCVBUF): %s", strerror(errno));
+ }
+ }
+ if (obj->options.tcp_sndbuf) {
+ if (setsockopt(dsi->socket,
+ SOL_SOCKET,
+ SO_SNDBUF,
+ &obj->options.tcp_sndbuf,
+ sizeof(obj->options.tcp_sndbuf)) != 0) {
+ LOG(log_error, logtype_dsi, "afp_over_dsi: setsockopt(SO_SNDBUF): %s", strerror(errno));
+ }
+ }
+
/* get stuck here until the end */
while (1) {
if (sigsetjmp(recon_jmp, 1) != 0)
}
/* Some error on the client connection, enter disconnected state */
dsi->flags |= DSI_DISCONNECTED;
+
+ /* the client sometimes logs out (afp_logout) but doesn't close the DSI session */
+ if (dsi->flags & DSI_AFP_LOGGED_OUT) {
+ afp_dsi_close(obj);
+ exit(0);
+ }
+
pause(); /* gets interrupted by SIGALARM or SIGURG tickle */
continue; /* continue receiving until disconnect timer expires
* or a primary reconnect succeeds */
}
}
- if (cmd == DSIFUNC_TICKLE) {
- /* timer is not every 30 seconds anymore, so we don't get killed on the client side. */
- if ((dsi->flags & DSI_DIE))
- dsi_tickle(dsi);
- pending_request(dsi);
- continue;
- }
dsi->flags |= DSI_DATA;
+ dsi->tickle = 0;
+
switch(cmd) {
+
case DSIFUNC_CLOSE:
+ LOG(log_debug, logtype_afpd, "DSI: close session request");
afp_dsi_close(obj);
LOG(log_note, logtype_afpd, "done");
- return;
+ exit(0);
+
+ case DSIFUNC_TICKLE:
+ dsi->flags &= ~DSI_DATA; /* thats no data in the sense we use it in alarm_handler */
+ LOG(log_debug, logtype_afpd, "DSI: client tickle");
+ /* timer is not every 30 seconds anymore, so we don't get killed on the client side. */
+ if ((dsi->flags & DSI_DIE))
+ dsi_tickle(dsi);
break;
case DSIFUNC_CMD:
function = (u_char) dsi->commands[0];
/* AFP replay cache */
- rc_idx = REPLAYCACHE_SIZE % dsi->clientID;
+ rc_idx = dsi->clientID % REPLAYCACHE_SIZE;
LOG(log_debug, logtype_afpd, "DSI request ID: %u", dsi->clientID);
if (replaycache[rc_idx].DSIreqID == dsi->clientID
&& replaycache[rc_idx].AFPcommand == function) {
- LOG(log_debug, logtype_afpd, "AFP Replay Cache match: id: %u / cmd: %s",
+ LOG(log_note, logtype_afpd, "AFP Replay Cache match: id: %u / cmd: %s",
dsi->clientID, AfpNum2name(function));
err = replaycache[rc_idx].result;
/* AFP replay cache end */
dir_free_invalid_q();
-#ifdef FORCE_UIDGID
- /* bring everything back to old euid, egid */
- if (obj->force_uid)
- restore_uidgid ( &obj->uidgid );
-#endif /* FORCE_UIDGID */
dsi->flags &= ~DSI_RUNNING;
/* Add result to the AFP replay cache */
AfpNum2name(function), AfpErr2name(err));
dsi->flags &= ~DSI_RUNNING;
-#ifdef FORCE_UIDGID
- /* bring everything back to old euid, egid */
- if (obj->force_uid)
- restore_uidgid ( &obj->uidgid );
-#endif /* FORCE_UIDGID */
} else {
LOG(log_error, logtype_afpd, "(write) bad function %x", function);
dsi->datalen = 0;
options->dircachesize = DEFAULT_MAX_DIRCACHE_SIZE;
options->flags |= OPTION_ACL2MACCESS;
options->flags |= OPTION_UUID;
+ options->tcp_sndbuf = 0; /* 0 means don't change OS default */
+ options->tcp_rcvbuf = 0; /* 0 means don't change OS default */
+ options->dsireadbuf = 12;
}
/* parse an afpd.conf line. i'm doing it this way because it's
}
}
+ if ((c = getoption(buf, "-dsireadbuf"))) {
+ options->dsireadbuf = atoi(c);
+ if (options->dsireadbuf < 6)
+ options->dsireadbuf = 6;
+ }
+
if ((c = getoption(buf, "-server_quantum")))
options->server_quantum = strtoul(c, NULL, 0);
if ((c = getoption(buf, "-port")))
options->port = strdup(c);
- if ((c = getoption(buf, "-ddpaddr")))
- atalk_aton(c, &options->ddpaddr);
if ((c = getoption(buf, "-signature")) && (opt = strdup(c)))
options->signatureopt = opt;
if ((c = getoption(buf, "-dircachesize")))
options->dircachesize = atoi(c);
+ if ((c = getoption(buf, "-tcpsndbuf")))
+ options->tcp_sndbuf = atoi(c);
+
+ if ((c = getoption(buf, "-tcprcvbuf")))
+ options->tcp_rcvbuf = atoi(c);
+
return 1;
}
printf( " TCP/IP Support:\t" );
puts( "Yes" );
- printf( "DDP(AppleTalk) Support:\t" );
-#ifdef NO_DDP
- puts( "No" );
-#else
- puts( "Yes" );
-#endif
-
printf( " CNID backends:\t" );
#ifdef CNID_BACKEND_CDB
printf( "cdb ");
puts( "No" );
#endif
- printf( " Dropbox kludge:\t" );
-#ifdef DROPKLUDGE
- puts( "Yes" );
-#else
- puts( "No" );
-#endif
-
- printf( " Force volume uid/gid:\t" );
-#ifdef FORCE_UIDGID
- puts( "Yes" );
-#else
- puts( "No" );
-#endif
-
printf( " ACL support:\t" );
#ifdef HAVE_ACLS
puts( "Yes" );
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
-#include <netatalk/endian.h>
+#include <arpa/inet.h>
+
#include <atalk/afp.h>
#include <atalk/compat.h>
#include <atalk/util.h>
* These numbers are scattered throughout the code.
*/
static struct afp_versions afp_versions[] = {
-#ifndef NO_DDP
- { "AFPVersion 1.1", 11 },
- { "AFPVersion 2.0", 20 },
- { "AFPVersion 2.1", 21 },
-#endif /* ! NO_DDP */
{ "AFP2.2", 22 },
{ "AFPX03", 30 },
{ "AFP3.1", 31 },
static struct uam_obj *afp_uam = NULL;
-void status_versions( char *data, const ASP asp, const DSI *dsi)
+void status_versions( char *data, const DSI *dsi)
{
char *start = data;
u_int16_t status;
num = sizeof( afp_versions ) / sizeof( afp_versions[ 0 ] );
for ( i = 0; i < num; i++ ) {
-#ifndef NO_DDP
- if ( !asp && (afp_versions[ i ].av_number <= 21)) continue;
-#endif /* ! NO_DDP */
if ( !dsi && (afp_versions[ i ].av_number >= 22)) continue;
count++;
}
*data++ = count;
for ( i = 0; i < num; i++ ) {
-#ifndef NO_DDP
- if ( !asp && (afp_versions[ i ].av_number <= 21)) continue;
-#endif /* ! NO_DDP */
if ( !dsi && (afp_versions[ i ].av_number >= 22)) continue;
len = strlen( afp_versions[ i ].av_name );
*data++ = len;
LOG(log_note, logtype_afpd, "%s Login by %s",
afp_versions[afp_version_index].av_name, pwd->pw_name);
-#ifndef NO_DDP
- if (obj->proto == AFPPROTO_ASP) {
- ASP asp = obj->handle;
- int addr_net = ntohs( asp->asp_sat.sat_addr.s_net );
- int addr_node = asp->asp_sat.sat_addr.s_node;
-
- if (obj->options.authprintdir) {
- if(addr_net && addr_node) { /* Do we have a valid Appletalk address? */
- char nodename[256];
- FILE *fp;
- int mypid = getpid();
- struct stat stat_buf;
-
- sprintf(nodename, "%s/net%d.%dnode%d", obj->options.authprintdir,
- addr_net / 256, addr_net % 256, addr_node);
- LOG(log_info, logtype_afpd, "registering %s (uid %d) on %u.%u as %s",
- pwd->pw_name, pwd->pw_uid, addr_net, addr_node, nodename);
-
- if (stat(nodename, &stat_buf) == 0) { /* file exists */
- if (S_ISREG(stat_buf.st_mode)) { /* normal file */
- unlink(nodename);
- fp = fopen(nodename, "w");
- fprintf(fp, "%s:%d\n", pwd->pw_name, mypid);
- fclose(fp);
- chown( nodename, pwd->pw_uid, -1 );
- } else { /* somebody is messing with us */
- LOG(log_error, logtype_afpd, "print authfile %s is not a normal file, it will not be modified", nodename );
- }
- } else { /* file 'nodename' does not exist */
- fp = fopen(nodename, "w");
- fprintf(fp, "%s:%d\n", pwd->pw_name, mypid);
- fclose(fp);
- chown( nodename, pwd->pw_uid, -1 );
- }
- } /* if (addr_net && addr_node ) */
- } /* if (options->authprintdir) */
- } /* if (obj->proto == AFPPROTO_ASP) */
-#endif
-
if (initgroups( pwd->pw_name, pwd->pw_gid ) < 0) {
#ifdef RUN_AS_USER
LOG(log_info, logtype_afpd, "running with uid %d", geteuid());
obj->uid = geteuid();
obj->logout = logout;
-#ifdef FORCE_UIDGID
- obj->force_uid = 1;
- save_uidgid ( &obj->uidgid );
-#endif
-
return( AFP_OK );
}
/* ---------------------- */
- int afp_zzz(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
+ int afp_zzz(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
{
uint32_t data;
DSI *dsi = (DSI *)AFPobj->handle;
*rbuflen = 0;
+ ibuf += 2;
+ ibuflen -= 2;
if (ibuflen < 4)
return AFPERR_MISC;
if (data & AFPZZZ_EXT_WAKEUP) {
/* wakeup request from exetended sleep */
if (dsi->flags & DSI_EXTSLEEP) {
- LOG(log_debug, logtype_afpd, "afp_zzz: waking up from extended sleep");
+ LOG(log_note, logtype_afpd, "afp_zzz: waking up from extended sleep");
dsi->flags &= ~(DSI_SLEEPING | DSI_EXTSLEEP);
}
} else {
/* sleep request */
dsi->flags |= DSI_SLEEPING;
if (data & AFPZZZ_EXT_SLEEP) {
- LOG(log_debug, logtype_afpd, "afp_zzz: entering extended sleep");
+ LOG(log_note, logtype_afpd, "afp_zzz: entering extended sleep");
dsi->flags |= DSI_EXTSLEEP;
} else {
- LOG(log_debug, logtype_afpd, "afp_zzz: entering normal sleep");
+ LOG(log_note, logtype_afpd, "afp_zzz: entering normal sleep");
}
}
+
/*
* According to AFP 3.3 spec we should not return anything,
* but eg 10.5.8 server still returns the numbers of hours
}
- int afp_logout(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen _U_)
+ int afp_logout(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
{
+ DSI *dsi = (DSI *)(obj->handle);
+
LOG(log_note, logtype_afpd, "AFP logout by %s", obj->username);
+ of_close_all_forks();
close_all_vol();
- obj->exit(0);
+ dsi->flags = DSI_AFP_LOGGED_OUT;
+ *rbuflen = 0;
return AFP_OK;
}
#include <atalk/unix.h>
#include <atalk/bstrlib.h>
#include <atalk/bstradd.h>
+ #include <atalk/errchk.h>
#include "directory.h"
#include "dircache.h"
{
static char temp[ MAXPATHLEN + 1];
char *t;
- cnid_t fileid;
+ cnid_t fileid = 0;
if (afp_version >= 30) {
if (toUTF8) {
return param;
}
+ /*!
+ * Resolve struct dir for an absolute path
+ *
+ * Given a path like "/Volumes/volume/dir/subdir" in a volume "/Volumes/volume" return
+ * a pointer to struct dir of "subdir".
+ * 1. Remove volue path from absolute path
+ * 2. start path
+ * 3. loop through all elements of the remaining path from 1.
+ * 4. we only allow dirs
+ * 5. search dircache
+ * 6. if not found in the dircache query the CNID database for the DID
+ * 7. and use dirlookup to resolve the DID to a it's struct dir *
+ *
+ * @param vol (r) volume the path is in, must be known
+ * @param path (r) absoule path
+ *
+ * @returns pointer to struct dir or NULL on error
+ */
+ struct dir *dirlookup_bypath(const struct vol *vol, const char *path)
+ {
+ EC_INIT;
+
+ struct dir *dir = NULL;
+ cnid_t cnid, did;
+ bstring rpath = NULL;
+ bstring statpath = NULL;
+ struct bstrList *l = NULL;
+ struct stat st;
+
+ cnid = htonl(2);
+ dir = vol->v_root;
+
+ EC_NULL(rpath = rel_path_in_vol(path, vol->v_path)); /* 1. */
+ EC_NULL(statpath = bfromcstr(vol->v_path)); /* 2. */
+
+ l = bsplit(rpath, '/');
+ for (int i = 0; i < l->qty ; i++) { /* 3. */
+ did = cnid;
+ EC_ZERO(bconcat(statpath, l->entry[i]));
+ EC_ZERO_LOGSTR(lstat(cfrombstr(statpath), &st),
+ "lstat(rpath: %s, elem: %s): %s: %s",
+ cfrombstr(rpath), cfrombstr(l->entry[i]),
+ cfrombstr(statpath), strerror(errno));
+
+ if (!(S_ISDIR(st.st_mode))) /* 4. */
+ EC_FAIL;
+
+ if ((dir = dircache_search_by_name(vol, /* 5. */
+ dir,
+ cfrombstr(l->entry[i]),
+ blength(l->entry[i]),
+ st.st_ctime)) == NULL) {
+ if ((cnid = cnid_add(vol->v_cdb, /* 6. */
+ &st,
+ did,
+ cfrombstr(l->entry[i]),
+ blength(l->entry[i]),
+ 0)) == CNID_INVALID) {
+ EC_FAIL;
+ }
+
+ if ((dir = dirlookup(vol, cnid)) == NULL) /* 7. */
+ EC_FAIL;
+ }
+
+ EC_ZERO(bcatcstr(statpath, "/"));
+ }
+
+ EC_CLEANUP:
+ bdestroy(rpath);
+ bstrListDestroy(l);
+ bdestroy(statpath);
+ if (ret != 0)
+ return NULL;
+
+ return dir;
+ }
+
/*!
* @brief Resolve a DID
*
* @param did (r) DID to resolve
*
* @returns pointer to struct dir
- *
- * @note FIXME: OSX calls it with bogus id, ie file ID not folder ID,
- * and we are really bad in this case.
*/
struct dir *dirlookup(const struct vol *vol, cnid_t did)
{
int utf8;
int err = 0;
- LOG(log_debug, logtype_afpd, "dirlookup(did: %u) {start}", ntohl(did));
+ LOG(log_debug, logtype_afpd, "dirlookup(did: %u)", ntohl(did));
/* check for did 0, 1 and 2 */
if (did == 0 || vol == NULL) { /* 1 */
afp_errno = AFPERR_PARAM;
- return NULL;
+ ret = NULL;
+ goto exit;
} else if (did == DIRDID_ROOT_PARENT) {
rootParent.d_vid = vol->v_vid;
- return (&rootParent);
+ ret = &rootParent;
+ goto exit;
} else if (did == DIRDID_ROOT) {
- return vol->v_root;
+ ret = vol->v_root;
+ goto exit;
}
/* Search the cache */
if ((ret = dircache_search_by_did(vol, did)) != NULL) { /* 2a */
if (ret->d_fullpath == NULL) { /* 2b */
afp_errno = AFPERR_BADTYPE;
- return NULL;
+ ret = NULL;
+ goto exit;
}
if (lstat(cfrombstr(ret->d_fullpath), &st) != 0) {
LOG(log_debug, logtype_afpd, "dirlookup(did: %u) {lstat: %s}", ntohl(did), strerror(errno));
LOG(log_debug, logtype_afpd, "dirlookup(did: %u) {calling dir_remove()}", ntohl(did));
dir_remove(vol, ret);
afp_errno = AFPERR_NOOBJ;
- return NULL;
+ ret = NULL;
+ goto exit;
default:
- return ret;
+ ret = ret;
+ goto exit;
}
/* DEADC0DE */
- return NULL;
+ ret = NULL;
+ goto exit;
}
- return ret;
+ ret = ret;
+ goto exit;
}
utf8 = utf8_encoding();
/* Get it from the database */
cnid = did;
- if ( (upath = cnid_resolve(vol->v_cdb, &cnid, buffer, buflen)) == NULL
- || (upath = strdup(upath)) == NULL) { /* 3 */
+ if ((upath = cnid_resolve(vol->v_cdb, &cnid, buffer, buflen)) == NULL) {
+ afp_errno = AFPERR_NOOBJ;
+ err = 1;
+ goto exit;
+ }
+ if ((upath = strdup(upath)) == NULL) { /* 3 */
afp_errno = AFPERR_NOOBJ;
err = 1;
goto exit;
* - DIRDID_ROOT is hit
* - a cached entry is found
*/
+ LOG(log_debug, logtype_afpd, "dirlookup(did: %u) {recursion for did: %u}", ntohl(pdid));
if ((pdir = dirlookup(vol, pdid)) == NULL) {
err = 1;
goto exit;
}
/* Add it to the cache only if it's a dir */
- if (dircache_add(ret) != 0) { /* 7 */
+ if (dircache_add(vol, ret) != 0) { /* 7 */
err = 1;
goto exit;
}
- LOG(log_debug, logtype_afpd, "dirlookup(did: %u) {end: did:%u, path:'%s'}",
- ntohl(did), ntohl(pdid), cfrombstr(ret->d_fullpath));
-
exit:
if (upath) free(upath);
if (err) {
ret = NULL;
}
}
+ if (ret)
+ LOG(log_debug, logtype_afpd, "dirlookup(did: %u): pdid: %u, \"%s\"",
+ ntohl(ret->d_did), ntohl(ret->d_pdid), cfrombstr(ret->d_fullpath));
+
return ret;
}
/* get_id needs adp for reading CNID from adouble file */
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if ((ad_open_metadata(path->u_name, ADFLAGS_DIR, 0, &ad)) == 0) /* 1 */
+ if ((ad_open(&ad, path->u_name, ADFLAGS_HF | ADFLAGS_DIR)) == 0) /* 1 */
adp = &ad;
/* Get CNID */
/* Get macname from unixname */
if (path->m_name == NULL) {
if ((path->m_name = utompath(vol, path->u_name, id, utf8_encoding())) == NULL) {
+ LOG(log_error, logtype_afpd, "dir_add(\"%s\"): can't assign macname", path->u_name);
err = 2;
goto exit;
}
goto exit;
}
- if ((dircache_add(cdir)) != 0) { /* 4 */
+ if ((dircache_add(vol, cdir)) != 0) { /* 4 */
LOG(log_error, logtype_afpd, "dir_add: fatal dircache error: %s", cfrombstr(fullpath));
exit(EXITERR_SYS);
}
* @brief Remove a dir from a cache and queue it for freeing
*
* 1. Check if the dir is locked or has opened forks
- * 2. If it's a request to remove curdir, just chdir to volume root
- * 3. Remove it from the cache
- * 4. Queue it for removal
+ * 2. Remove it from the cache
+ * 3. Queue it for removal
+ * 4. If it's a request to remove curdir, mark curdir as invalid
* 5. Mark it as invalid
*
* @param (r) pointer to struct vol
if (dir->d_did == DIRDID_ROOT_PARENT || dir->d_did == DIRDID_ROOT)
return 0;
- if (dir->d_flags & DIRF_CACHELOCK) { /* 1 */
- LOG(log_warning, logtype_afpd, "dir_remove(did:%u,'%s'): dir is locked",
- ntohl(dir->d_did), cfrombstr(dir->d_u_name));
- return 0;
- }
-
- if (curdir == dir) { /* 2 */
- if (movecwd(vol, vol->v_root) < 0) {
- LOG(log_error, logtype_afpd, "dir_remove: can't chdir to : %s", vol->v_root);
- }
- }
-
LOG(log_debug, logtype_afpd, "dir_remove(did:%u,'%s'): {removing}",
ntohl(dir->d_did), cfrombstr(dir->d_u_name));
- dircache_remove(vol, dir, DIRCACHE | DIDNAME_INDEX | QUEUE_INDEX); /* 3 */
- enqueue(invalid_dircache_entries, dir); /* 4 */
+ dircache_remove(vol, dir, DIRCACHE | DIDNAME_INDEX | QUEUE_INDEX); /* 2 */
+ enqueue(invalid_dircache_entries, dir); /* 3 */
+
+ if (curdir == dir) /* 4 */
+ curdir = NULL;
+
dir->d_did = CNID_INVALID; /* 5 */
+
return 0;
}
+ #if 0 /* unused */
/*!
* @brief Modify a struct dir, adjust cache
*
dir->d_m_name_ucs2 = NULL;
/* Re-add it to the cache */
- if ((dircache_add(dir)) != 0) {
+ if ((dircache_add(vol, dir)) != 0) {
dircache_dump();
AFP_PANIC("dir_modify");
}
return ret;
}
+ #endif
/*!
* @brief Resolve a catalog node name path
/* 6*/
for ( p = path; *data != 0 && len > 0; len-- ) {
*p++ = *data++;
- if (p > &path[ MAXPATHLEN]) {
+ if (p > &path[UTF8FILELEN_EARLY]) { /* FIXME safeguard, limit of early Mac OS X */
afp_errno = AFPERR_PARAM;
return NULL;
}
AFP_ASSERT(vol);
AFP_ASSERT(dir);
- LOG(log_maxdebug, logtype_afpd, "movecwd(curdir:'%s', cwd:'%s')",
- cfrombstr(curdir->d_fullpath), getcwdpath());
+ LOG(log_maxdebug, logtype_afpd, "movecwd: from: curdir:\"%s\", cwd:\"%s\"",
+ curdir ? cfrombstr(curdir->d_fullpath) : "INVALID", getcwdpath());
- if ( dir == curdir)
- return( 0 );
if (dir->d_did == DIRDID_ROOT_PARENT) {
curdir = &rootParent;
return 0;
}
- LOG(log_debug, logtype_afpd, "movecwd(did:%u, '%s')",
+ LOG(log_debug, logtype_afpd, "movecwd(to: did: %u, \"%s\")",
ntohl(dir->d_did), cfrombstr(dir->d_fullpath));
if ((ret = lchdir(cfrombstr(dir->d_fullpath))) != 0 ) {
- LOG(log_debug, logtype_afpd, "movecwd('%s'): ret: %u, %s",
+ LOG(log_debug, logtype_afpd, "movecwd(\"%s\"): ret: %u, %s",
cfrombstr(dir->d_fullpath), ret, strerror(errno));
if (ret == 1) {
/* p is a symlink or getcwd failed */
struct maccess ma;
accessmode(path->u_name, &ma, curdir, &path->st);
- if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE))
+
+ LOG(log_debug, logtype_afpd, "file_access(\"%s\"): mapped user mode: 0x%02x",
+ path->u_name, ma.ma_user);
+
+ if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE)) {
+ LOG(log_debug, logtype_afpd, "file_access(\"%s\"): write access denied", path->u_name);
return -1;
- if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD))
+ }
+ if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD)) {
+ LOG(log_debug, logtype_afpd, "file_access(\"%s\"): read access denied", path->u_name);
return -1;
+ }
return 0;
}
(1 << DIRPBIT_FINFO)))) {
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if ( !ad_metadata( upath, ADFLAGS_CREATE|ADFLAGS_DIR, &ad) ) {
+ if ( !ad_metadata( upath, ADFLAGS_DIR, &ad) )
isad = 1;
- if (ad.ad_md->adf_flags & O_CREAT) {
- /* We just created it */
- ad_setname(&ad, s_path->m_name);
- ad_setid( &ad,
- s_path->st.st_dev,
- s_path->st.st_ino,
- dir->d_did,
- dir->d_pdid,
- vol->v_stamp);
- ad_flush( &ad);
- }
- }
}
pdid = dir->d_pdid;
}
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if (ad_open_metadata( upath, ADFLAGS_DIR, O_CREAT, &ad) < 0) {
+ if (ad_open(&ad, upath, ADFLAGS_HF | ADFLAGS_DIR, O_CREAT, 0777) != 0) {
/*
* Check to see what we're trying to set. If it's anything
* but ACCESS, UID, or GID, give an error. If it's any of those
* Check to see if a create was necessary. If it was, we'll want
* to set our name, etc.
*/
- if ( (ad_get_HF_flags( &ad ) & O_CREAT)) {
+ if ( (ad_get_MD_flags( &ad ) & O_CREAT)) {
ad_setname(&ad, cfrombstr(curdir->d_m_name));
}
}
}
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if (ad_open_metadata( ".", ADFLAGS_DIR, O_CREAT, &ad ) < 0) {
+ if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR, O_CREAT, 0777) < 0) {
if (vol_noadouble(vol))
goto createdir_done;
return( AFPERR_ACCESS );
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if (!ad_open_metadata( dst, ADFLAGS_DIR, 0, &ad)) {
+ if (ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_DIR) == 0) {
ad_setname(&ad, newname);
ad_flush( &ad);
ad_close_metadata( &ad);
{
struct dirent *de;
struct stat st;
- struct dir *fdir;
+ struct dir *fdir, *pdir;
DIR *dp;
struct adouble ad;
u_int16_t ashort;
int err;
- if ( dirlookup(vol, curdir->d_pdid) == NULL ) {
+ if ((pdir = dirlookup(vol, curdir->d_pdid)) == NULL) {
return( AFPERR_ACCESS );
}
}
err = vol->vfs->vfs_deletecurdir(vol);
if (err) {
+ LOG(log_error, logtype_afpd, "deletecurdir: error deleting .AppleDouble in \"%s\"",
+ curdir->d_fullpath);
return err;
}
/* bail if it's not a symlink */
if ((lstat(de->d_name, &st) == 0) && !S_ISLNK(st.st_mode)) {
+ LOG(log_error, logtype_afpd, "deletecurdir(\"%s\"): not empty",
+ curdir->d_fullpath);
closedir(dp);
return AFPERR_DIRNEMPT;
}
}
}
- if ( movecwd(vol, dirlookup(vol, curdir->d_pdid)) < 0 ) {
+ if (movecwd(vol, pdir) < 0) {
err = afp_errno;
goto delete_done;
}
+ LOG(log_debug, logtype_afpd, "deletecurdir: moved to \"%s\"",
+ cfrombstr(curdir->d_fullpath));
+
err = netatalk_rmdir_all_errors(-1, cfrombstr(fdir->d_u_name));
if ( err == AFP_OK || err == AFPERR_NOOBJ) {
cnid_delete(vol->v_cdb, fdir->d_did);
dir_remove( vol, fdir );
+ } else {
+ LOG(log_error, logtype_afpd, "deletecurdir(\"%s\"): netatalk_rmdir_all_errors error",
+ curdir->d_fullpath);
}
+
delete_done:
if (dp) {
/* inode is used as key for cnid.
#ifndef AFPD_DIRECTORY_H
#define AFPD_DIRECTORY_H 1
-#include <sys/cdefs.h>
#include <sys/types.h>
-/*#include <sys/stat.h>*/ /* including it here causes some confusion */
-#include <netatalk/endian.h>
+#include <arpa/inet.h>
#include <dirent.h>
/* sys/types.h usually snarfs in major/minor macros. if they don't
#define DIRF_OFFCNT (1<<4) /* offsprings count is valid */
#define DIRF_CNID (1<<5) /* renumerate id */
- #define DIRF_CACHELOCK (1<<6) /* lock in cache, don't remove in dircache_eviction, for catsearch */
#define AFPDIR_READ (1<<0)
const char *new_mname, const char *new_uname, bstring pdir_fullpath);
extern int dir_remove(const struct vol *vol, struct dir *dir);
extern struct dir *dirlookup (const struct vol *, cnid_t);
+ extern struct dir *dirlookup_bypath(const struct vol *vol, const char *path);
+
extern int movecwd (const struct vol *, struct dir *);
extern struct path *cname (struct vol *, struct dir *, char **);
#include <stdio.h>
#include <stdlib.h>
-/* STDC check */
-#if STDC_HEADERS
#include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
#include <utime.h>
#include <errno.h>
#include <sys/param.h>
else {
u_int16_t temp;
- if (aint > 255) /* FIXME safeguard, anyway if no ascii char it's game over*/
- aint = 255;
+ if (aint > UTF8FILELEN_EARLY) /* FIXME safeguard, anyway if no ascii char it's game over*/
+ aint = UTF8FILELEN_EARLY;
utf8 = vol->v_kTextEncoding;
memcpy(data, &utf8, sizeof(utf8));
struct stat *st;
struct maccess ma;
+ LOG(log_debug, logtype_afpd, "getmetadata(\"%s\")", path->u_name);
+
upath = path->u_name;
st = &path->st;
data = buf;
exit(EXITERR_SYS);
}
- if ((dircache_add(cachedfile)) != 0) {
+ if ((dircache_add(vol, cachedfile)) != 0) {
LOG(log_error, logtype_afpd, "getmetadata: fatal dircache error");
exit(EXITERR_SYS);
}
int opened = 0;
int rc;
+ LOG(log_debug, logtype_afpd, "getfilparams(\"%s\")", path->u_name);
+
opened = PARAM_NEED_ADP(bitmap);
adp = NULL;
if (opened) {
char *upath;
- int flags = (bitmap & (1 << FILPBIT_ATTR))?ADFLAGS_OPENFORKS:0;
+ int flags = (bitmap & (1 << FILPBIT_ATTR)) ? ADFLAGS_CHECK_OF : 0;
adp = of_ad(vol, path, &ad);
upath = path->u_name;
- if ( ad_metadata( upath, flags|ADFLAGS_CREATE, adp) < 0 ) {
+ if ( ad_metadata( upath, flags, adp) < 0 ) {
switch (errno) {
case EACCES:
LOG(log_error, logtype_afpd, "getfilparams(%s): %s: check resource fork permission?",
}
}
rc = getmetadata(vol, bitmap, path, dir, buf, buflen, adp);
- if ( adp ) {
- ad_close_metadata( adp);
- }
+ ad_close_metadata( adp);
return( rc );
}
/* ----------------------------- */
int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
{
- struct adouble ad, *adp;
+ struct adouble ad;
struct vol *vol;
struct dir *dir;
struct ofork *of = NULL;
memcpy(&vid, ibuf, sizeof( vid ));
ibuf += sizeof( vid );
- if (NULL == ( vol = getvolbyvid( vid )) ) {
+ if (NULL == ( vol = getvolbyvid( vid )) )
return( AFPERR_PARAM );
- }
if (vol->v_flags & AFPVOL_RO)
return AFPERR_VLOCK;
memcpy(&did, ibuf, sizeof( did));
ibuf += sizeof( did );
- if (NULL == ( dir = dirlookup( vol, did )) ) {
+ if (NULL == ( dir = dirlookup( vol, did )) )
return afp_errno;
- }
- if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
+ if (NULL == ( s_path = cname( vol, dir, &ibuf )) )
return get_afp_errno(AFPERR_PARAM);
- }
- if ( *s_path->m_name == '\0' ) {
+ if ( *s_path->m_name == '\0' )
return( AFPERR_BADTYPE );
- }
upath = s_path->u_name;
+ ad_init(&ad, vol->v_adouble, vol->v_ad_options);
/* if upath is deleted we already in trouble anyway */
if ((of = of_findname(s_path))) {
- adp = of->of_ad;
- } else {
- ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- adp = &ad;
- }
- if ( creatf) {
- /* on a hard create, fail if file exists and is open */
- if (of)
+ if (creatf)
return AFPERR_BUSY;
+ else
+ return AFPERR_EXIST;
+ }
+
+ if ( creatf)
openf = O_RDWR|O_CREAT|O_TRUNC;
- } else {
+ else
/* on a soft create, if the file is open then ad_open won't fail
- because open syscall is not called
- */
- if (of) {
- return AFPERR_EXIST;
- }
+ because open syscall is not called */
openf = O_RDWR|O_CREAT|O_EXCL;
- }
- if ( ad_open( upath, ADFLAGS_DF|ADFLAGS_HF|ADFLAGS_NOHF|ADFLAGS_CREATE,
- openf, 0666, adp) < 0 ) {
+ if ( ad_open(&ad, upath, ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF,
+ openf, 0666, openf, 0666) < 0 ) {
switch ( errno ) {
case EROFS:
return AFPERR_VLOCK;
return( AFPERR_PARAM );
}
}
- if ( ad_reso_fileno( adp ) == -1 ) { /* Hard META / HF */
+ if ( ad_meta_fileno( &ad ) == -1 ) { /* Hard META / HF */
/* on noadouble volumes, just creating the data fork is ok */
if (vol_noadouble(vol)) {
- ad_close( adp, ADFLAGS_DF );
+ ad_close( &ad, ADFLAGS_DF );
goto createfile_done;
}
/* FIXME with hard create on an existing file, we already
* corrupted the data file.
*/
netatalk_unlink( upath );
- ad_close( adp, ADFLAGS_DF );
+ ad_close( &ad, ADFLAGS_DF );
return AFPERR_ACCESS;
}
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++;
-#ifdef DROPKLUDGE
- if (vol->v_flags & AFPVOL_DROPBOX) {
- retvalue = matchfile2dirperms(upath, vol, did);
- }
-#endif /* DROPKLUDGE */
-
setvoltime(obj, vol );
return (retvalue);
/* second try with adouble open
*/
- if ( ad_open_metadata( upath, 0, O_CREAT, adp) < 0) {
+ if ( ad_open(adp, upath, ADFLAGS_HF, O_RDWR | O_CREAT, 0666) < 0) {
LOG(log_debug, logtype_afpd, "setfilparams: ad_open_metadata error");
/*
* For some things, we don't need an adouble header:
}
LOG(log_debug, logtype_afpd, "setfilparams: no adouble perms, but only FILPBIT_MDATE and/or FILPBIT_UNIXPR");
isad = 0;
- } else if ((ad_get_HF_flags( adp ) & O_CREAT) ) {
+ } else if ((ad_get_MD_flags( adp ) & O_CREAT) ) {
ad_setname(adp, path->m_name);
}
if (isad) {
ad_flush( adp);
ad_close_metadata( adp);
-
}
if (change_parent_mdate && gettimeofday(&tv, NULL) == 0) {
{
int rc;
+ LOG(log_debug, logtype_afpd,
+ "renamefile: src[%d, \"%s\"] -> dst[\"%s\"]", sdir_fd, src, dst);
+
if ( unix_rename( sdir_fd, src, -1, dst ) < 0 ) {
switch ( errno ) {
case ENOENT :
}
}
- /* don't care if we can't open the newly renamed ressource fork
- */
- if (!ad_open( dst, ADFLAGS_HF, O_RDWR, 0666, adp)) {
+ /* don't care if we can't open the newly renamed ressource fork */
+ if (ad_open(adp, dst, ADFLAGS_HF, O_RDWR) == 0) {
ad_setname(adp, newname);
ad_flush( adp );
ad_close( adp, ADFLAGS_HF );
adp = of_ad(s_vol, s_path, &ad);
- if (ad_open(s_path->u_name , ADFLAGS_DF |ADFLAGS_HF | ADFLAGS_NOHF, O_RDONLY, 0, adp) < 0) {
+ if (ad_open(adp, s_path->u_name, ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF, O_RDONLY, O_RDONLY) < 0) {
return AFPERR_DENYCONF;
}
- denyreadset = (getforkmode(adp, ADEID_DFORK, AD_FILELOCK_DENY_RD) != 0 ||
- getforkmode(adp, ADEID_RFORK, AD_FILELOCK_DENY_RD) != 0 );
+ denyreadset = (ad_testlock(adp, ADEID_DFORK, AD_FILELOCK_DENY_RD) != 0 ||
+ ad_testlock(adp, ADEID_RFORK, AD_FILELOCK_DENY_RD) != 0 );
if (denyreadset) {
retvalue = AFPERR_DENYCONF;
goto copy_exit;
}
-#ifdef FORCE_UIDGID
- /* FIXME svid != dvid && dvid's user can't read svid */
-#endif
if (NULL == ( d_vol = getvolbyvid( dvid )) ) {
retvalue = AFPERR_PARAM;
goto copy_exit;
}
curdir->offcnt++;
-#ifdef DROPKLUDGE
- if (vol->v_flags & AFPVOL_DROPBOX) {
- retvalue=matchfile2dirperms(upath, vol, ddid); /* FIXME sdir or ddid */
- }
-#endif /* DROPKLUDGE */
-
setvoltime(obj, d_vol );
copy_exit:
adflags |= ADFLAGS_HF;
}
- if (ad_openat(sfd, src, adflags | ADFLAGS_NOHF, O_RDONLY, 0, adp) < 0) {
+ if (ad_openat(adp, sfd, src, adflags | ADFLAGS_NOHF, O_RDONLY, O_RDONLY) < 0) {
ret_err = errno;
goto done;
}
}
ad_init(&add, d_vol->v_adouble, d_vol->v_ad_options);
- if (ad_open(dst , adflags, O_RDWR|O_CREAT|O_EXCL, st.st_mode, &add) < 0) {
+ if (ad_open(&add, dst, adflags, O_RDWR|O_CREAT|O_EXCL, st.st_mode, O_RDWR|O_CREAT|O_EXCL, st.st_mode) < 0) {
ret_err = errno;
ad_close( adp, adflags );
if (EEXIST != ret_err) {
* moreover sometimes deletefile is called with a no existent file and
* ad_open would create a 0 byte resource fork
*/
- if ( ad_metadataat(dirfd, file, ADFLAGS_OPENFORKS, &ad) == 0 ) {
+ if ( ad_metadataat(dirfd, file, ADFLAGS_CHECK_OF, &ad) == 0 ) {
if ((err = check_attrib(&ad))) {
ad_close_metadata(&ad);
return err;
/* try to open both forks at once */
adflags = ADFLAGS_DF;
- if ( ad_openat(dirfd, file, adflags |ADFLAGS_HF|ADFLAGS_NOHF, O_RDONLY, 0, &ad ) < 0 ) {
+ if ( ad_openat(&ad, dirfd, file, adflags |ADFLAGS_HF|ADFLAGS_NOHF, O_RDONLY, O_RDONLY) < 0 ) {
switch (errno) {
case ENOENT:
err = AFPERR_NOOBJ;
cnid_t did = param->did;
cnid_t aint;
- if ( lstat(de->d_name, &path.st)<0 )
+ if ( lstat(de->d_name, &path.st) < 0 )
return 0;
/* update or add to cnid */
aint = cnid_add(vol->v_cdb, &path.st, did, de->d_name, strlen(de->d_name), 0); /* ignore errors */
-#if AD_VERSION > AD_VERSION1
- if (aint != CNID_INVALID && !S_ISDIR(path.st.st_mode)) {
- struct adouble ad, *adp;
-
- path.st_errno = 0;
- path.st_valid = 1;
- path.u_name = de->d_name;
-
- adp = of_ad(vol, &path, &ad);
-
- if ( ad_open_metadata( de->d_name, 0, 0, adp ) < 0 ) {
- return 0;
- }
- if (ad_setid(adp, path.st.st_dev, path.st.st_ino, aint, did, vol->v_stamp)) {
- ad_flush(adp);
- }
- ad_close_metadata(adp);
- }
-#endif /* AD_VERSION > AD_VERSION1 */
-
return 0;
}
adp = (*of)->of_ad;
}
else {
- ret = ad_open( path->u_name, ADFLAGS_HF, O_RDONLY, 0, adp);
+ ret = ad_open(adp, path->u_name, ADFLAGS_HF, O_RDONLY);
/* META and HF */
if ( !ret && ad_reso_fileno(adp) != -1 && !(adp->ad_resource_fork.adf_flags & ( O_RDWR | O_WRONLY))) {
/* from AFP spec.
#include <stdio.h>
#include <stdlib.h>
-/* STDC check */
-#if STDC_HEADERS
#include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
#include <errno.h>
#include <sys/param.h>
#include "filedir.h"
#include "unix.h"
-#ifdef DROPKLUDGE
-int matchfile2dirperms(
-/* Since it's kinda' big; I decided against an
- inline function */
- char *upath,
- struct vol *vol,
- int did)
-/* The below code changes the way file ownership is determined in the name of
- fixing dropboxes. It has known security problem. See the netatalk FAQ for
- more information */
-{
- struct stat st, sb;
- struct dir *dir;
- char *adpath;
- uid_t uid;
- int ret = AFP_OK;
-#ifdef DEBUG
- LOG(log_debug9, logtype_afpd, "begin matchfile2dirperms:");
-#endif
-
- if (stat(upath, &st ) < 0) {
- LOG(log_error, logtype_afpd, "Could not stat %s: %s", upath, strerror(errno));
- return AFPERR_NOOBJ ;
- }
-
- adpath = vol->vfs->ad_path( upath, ADFLAGS_HF );
- /* FIXME dirsearch doesn't move cwd to did ! */
- if (( dir = dirlookup( vol, did )) == NULL ) {
- LOG(log_error, logtype_afpd, "matchfile2dirperms: Unable to get directory info.");
- ret = AFPERR_NOOBJ;
- }
- else if (stat(".", &sb) < 0) {
- LOG(log_error, logtype_afpd,
- "matchfile2dirperms: Error checking directory \"%s\": %s",
- dir->d_m_name, strerror(errno));
- ret = AFPERR_NOOBJ;
- }
- else {
- uid=geteuid();
- if ( uid != sb.st_uid )
- {
- seteuid(0);
- if (lchown(upath, sb.st_uid, sb.st_gid) < 0)
- {
- LOG(log_error, logtype_afpd,
- "matchfile2dirperms(%s): Error changing owner/gid: %s",
- upath, strerror(errno));
- ret = AFPERR_ACCESS;
- }
- else if ((!S_ISLNK(st->st_mode)) && (chmod(upath,(st.st_mode&~default_options.umask)| S_IRGRP| S_IROTH) < 0))
- {
- LOG(log_error, logtype_afpd,
- "matchfile2dirperms(%s): Error adding file read permissions: %s",
- upath, strerror(errno));
- ret = AFPERR_ACCESS;
- }
- else if (lchown(adpath, sb.st_uid, sb.st_gid) < 0)
- {
- LOG(log_error, logtype_afpd,
- "matchfile2dirperms(%s): Error changing AppleDouble owner/gid: %s",
- adpath, strerror(errno));
- ret = AFPERR_ACCESS;
- }
- else if (chmod(adpath, (st.st_mode&~default_options.umask)| S_IRGRP| S_IROTH) < 0)
- {
- LOG(log_error, logtype_afpd,
- "matchfile2dirperms(%s): Error adding AD file read permissions: %s",
- adpath, strerror(errno));
- ret = AFPERR_ACCESS;
- }
- seteuid(uid);
- }
- } /* end else if stat success */
-
-#ifdef DEBUG
- LOG(log_debug9, logtype_afpd, "end matchfile2dirperms:");
-#endif
- return ret;
-}
-#endif
-
int afp_getfildirparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
{
struct stat *st;
char *newname,
int isdir)
{
- char *p;
+ char *oldunixname = NULL;
char *upath;
int rc;
struct stat *st, nst;
cnid_t id;
int cwd_fd = -1;
+ LOG(log_debug, logtype_afpd,
+ "moveandrename: [\"%s\"/\"%s\"] -> \"%s\"",
+ cfrombstr(sdir->d_u_name), oldname, newname);
+
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
adp = &ad;
adflags = 0;
if (!isdir) {
- if ((p = mtoupath(vol, oldname, sdir->d_did, utf8_encoding())) == NULL)
+ if ((oldunixname = strdup(mtoupath(vol, oldname, sdir->d_did, utf8_encoding()))) == NULL)
return AFPERR_PARAM; /* can't convert */
+ id = cnid_get(vol->v_cdb, sdir->d_did, oldunixname, strlen(oldunixname));
- #ifndef HAVE_RENAMEAT
+ #ifndef HAVE_ATFUNCS
/* Need full path */
- id = cnid_get(vol->v_cdb, sdir->d_did, p, strlen(p));
- p = ctoupath( vol, sdir, oldname );
- if (!p)
+ free(oldunixname);
+ if ((oldunixname = strdup(ctoupath(vol, sdir, oldname))) == NULL)
return AFPERR_PARAM; /* pathname too long */
- #endif /* HAVE_RENAMEAT */
+ #endif /* HAVE_ATFUNCS */
path.st_valid = 0;
- path.u_name = p;
- #ifdef HAVE_RENAMEAT
+ path.u_name = oldunixname;
+
+ #ifdef HAVE_ATFUNCS
opened = of_findnameat(sdir_fd, &path);
#else
opened = of_findname(&path);
- #endif /* HAVE_RENAMEAT */
+ #endif /* HAVE_ATFUNCS */
+
if (opened) {
/* reuse struct adouble so it won't break locks */
adp = opened->of_ad;
}
} else {
id = sdir->d_did; /* we already have the CNID */
- p = ctoupath( vol, dirlookup(vol, sdir->d_pdid), oldname );
- if (!p) {
+ if ((oldunixname = strdup(ctoupath( vol, dirlookup(vol, sdir->d_pdid), oldname))) == NULL)
return AFPERR_PARAM;
- }
adflags = ADFLAGS_DIR;
}
/*
- * p now points to either
+ * oldunixname now points to either
* a) full pathname of the source fs object (if renameat is not available)
* b) the oldname (renameat is available)
* we are in the dest folder so we need to use
- * a) p for ad_open
+ * a) oldunixname for ad_open
* b) fchdir sdir_fd before eg ad_open or use *at functions where appropiate
*/
goto exit;
}
}
- if (!ad_metadata(p, adflags, adp)) {
+ if (!ad_metadata(oldunixname, adflags, adp)) {
u_int16_t bshort;
ad_getattr(adp, &bshort);
+
ad_close_metadata( adp);
if ((bshort & htons(ATTRBIT_NORENAME))) {
rc = AFPERR_OLOCK;
}
if (stat(upath, st) == 0 || caseenumerate(vol, &path, curdir) == 0) {
- if (!stat(p, &nst) && !(nst.st_dev == st->st_dev && nst.st_ino == st->st_ino) ) {
+ if (!stat(oldunixname, &nst) && !(nst.st_dev == st->st_dev && nst.st_ino == st->st_ino) ) {
/* not the same file */
rc = AFPERR_EXIST;
goto exit;
if (of_findname(&path)) {
rc = AFPERR_EXIST; /* was AFPERR_BUSY; */
} else {
- rc = renamefile(vol, sdir_fd, p, upath, newname, adp );
+ rc = renamefile(vol, sdir_fd, oldunixname, upath, newname, adp );
if (rc == AFP_OK)
of_rename(vol, opened, sdir, oldname, curdir, newname);
}
} else {
- rc = renamedir(vol, sdir_fd, p, upath, sdir, curdir, newname);
+ rc = renamedir(vol, sdir_fd, oldunixname, upath, sdir, curdir, newname);
}
if ( rc == AFP_OK && id ) {
/* renaming may have moved the file/dir across a filesystem */
(void)dir_remove(vol, cacheddir);
}
+ /* Fixup adouble info */
+ if (!ad_metadata(upath, adflags, adp)) {
+ ad_setid(adp, st->st_dev, st->st_ino, id, curdir->d_did, vol->v_stamp);
+ ad_flush(adp);
+ ad_close_metadata(adp);
+ }
+
/* fix up the catalog entry */
cnid_update(vol->v_cdb, id, st, curdir->d_did, upath, strlen(upath));
}
exit:
if (cwd_fd != -1)
close(cwd_fd);
+ if (oldunixname)
+ free(oldunixname);
return rc;
}
int plen;
u_int16_t vid;
int rc;
-#ifdef DROPKLUDGE
- int retvalue;
-#endif /* DROPKLUDGE */
int sdir_fd = -1;
memcpy(oldname, cfrombstr(sdir->d_m_name), blength(sdir->d_m_name) + 1);
}
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
if ((sdir_fd = open(".", O_RDONLY)) == -1)
return AFPERR_MISC;
#endif
}
curdir->offcnt++;
sdir->offcnt--;
-#ifdef DROPKLUDGE
- if (vol->v_flags & AFPVOL_DROPBOX) {
- /* FIXME did is not always the source id */
- if ((retvalue=matchfile2dirperms (upath, vol, did)) != AFP_OK) {
- rc = retvalue;
- goto exit;
- }
- }
- else
-#endif /* DROPKLUDGE */
- /* if unix priv don't try to match perm with dest folder */
- if (!isdir && !vol_unix_priv(vol)) {
- int admode = ad_mode("", 0777) | vol->v_fperm;
+ /* if unix priv don't try to match perm with dest folder */
+ if (!isdir && !vol_unix_priv(vol)) {
+ int admode = ad_mode("", 0777) | vol->v_fperm;
- setfilmode(upath, admode, NULL, vol->v_umask);
- vol->vfs->vfs_setfilmode(vol, upath, admode, NULL);
- }
+ setfilmode(upath, admode, NULL, vol->v_umask);
+ vol->vfs->vfs_setfilmode(vol, upath, admode, NULL);
+ }
setvoltime(obj, vol );
}
exit:
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
if (sdir_fd != -1)
close(sdir_fd);
#endif
#define AFPD_FORK_H 1
#include <stdio.h>
-#include <sys/cdefs.h>
+#include <arpa/inet.h>
-#include <netatalk/endian.h>
#include <atalk/adouble.h>
#include "volume.h"
#include "directory.h"
struct dir *, const char *,
struct dir *, const char *);
extern int of_flush (const struct vol *);
-extern void of_pforkdesc (FILE *);
extern int of_stat (struct path *);
extern int of_statdir (struct vol *vol, struct path *);
extern int of_closefork (struct ofork *ofork);
extern void of_closevol (const struct vol *vol);
+ extern void of_close_all_forks(void);
extern struct adouble *of_ad (const struct vol *, struct path *, struct adouble *);
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
extern struct ofork *of_findnameat(int dirfd, struct path *path);
extern int of_fstatat(int dirfd, struct path *path);
- #endif /* HAVE_RENAMEAT */
+ #endif /* HAVE_ATFUNCS */
/* in fork.c */
extern int flushfork (struct ofork *);
-extern int getforkmode (struct adouble *, int , int );
/* FP functions */
int afp_openfork (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen);
#define AFPD_GLOBALS_H 1
#include <sys/param.h>
-#include <sys/cdefs.h>
#ifdef ADMIN_GRP
#include <grp.h>
#include <atalk/unicode.h>
#include <atalk/uam.h>
- #define MACFILELEN 31
+ /* #define DOSFILELEN 12 */ /* Type1, DOS-compat*/
+ #define MACFILELEN 31 /* Type2, HFS-compat */
+ #define UTF8FILELEN_EARLY 255 /* Type3, early Mac OS X 10.0-10.4.? */
+ /* #define UTF8FILELEN_NAME_MAX 765 */ /* Type3, 10.4.?- , getconf NAME_MAX */
+ /* #define UTF8FILELEN_SPEC 0xFFFF */ /* Type3, spec on document */
+ /* #define HFSPLUSFILELEN 510 */ /* HFS+ spec, 510byte = 255codepoint */
+
#define MAXUSERLEN 256
#define OPTION_DEBUG (1 << 0)
#define OPTION_ACL2MACCESS (1 << 8)
#define OPTION_NOZEROCONF (1 << 9)
-#ifdef FORCE_UIDGID
-/* set up a structure for this */
-typedef struct uidgidset_t {
- uid_t uid;
- gid_t gid;
-} uidgidset;
-#endif /* FORCE_UIDGID */
-
/* a couple of these options could get stuck in unions to save
* space. */
struct afp_volume_name {
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;
struct session_info sinfo;
uid_t uid; /* client running user id */
int ipc_fd; /* anonymous PF_UNIX socket for IPC with afpd parent */
-#ifdef FORCE_UIDGID
- int force_uid;
- uidgidset uidgid;
-#endif
} AFPObj;
/* typedef for AFP functions handlers */
/* directory.c */
extern struct dir rootParent;
-#ifndef NO_DDP
-extern void afp_over_asp (AFPObj *);
-#endif /* NO_DDP */
extern void afp_over_dsi (AFPObj *);
#endif /* globals.h */
}
}
-#ifdef DEBUG1
-void of_pforkdesc( FILE *f)
-{
- int ofrefnum;
-
- if (!oforks)
- return;
-
- for ( ofrefnum = 0; ofrefnum < nforks; ofrefnum++ ) {
- if ( oforks[ ofrefnum ] != NULL ) {
- fprintf( f, "%hu <%s>\n", ofrefnum, of_name(oforks[ ofrefnum ]));
- }
- }
-}
-#endif
-
int of_flush(const struct vol *vol)
{
int refnum;
ad_open really does reinitialize the structure. */
ad_init(ad, vol->v_adouble, vol->v_ad_options);
- ad->ad_m_namelen = 255 +1;
+ ad->ad_m_namelen = UTF8FILELEN_EARLY +1;
/* here's the deal: we allocate enough for the standard mac file length.
* in the future, we'll reallocate in fairly large jumps in case
* of long unicode names */
return NULL;
}
strlcpy( ad->ad_m_name, path, ad->ad_m_namelen);
- } else {
- /* Increase the refcount on this struct adouble. This is
- decremented again in oforc_dealloc. */
- ad->ad_refcount++;
}
+ ad_ref(ad);
of->of_ad = ad;
of->of_vol = vol;
of->of_did = dir->d_did;
}
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
int of_fstatat(int dirfd, struct path *path)
{
int ret;
return ret;
}
- #endif /* HAVE_RENAMEAT */
+ #endif /* HAVE_ATFUNCS */
/* --------------------------
stat the current directory.
* @param dirfd (r) directory fd
* @param path (rw) pointer to struct path
*/
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
struct ofork *of_findnameat(int dirfd, struct path *path)
{
struct ofork *of;
of_unhash(of);
oforks[ of->of_refnum % nforks ] = NULL;
-
- /* decrease refcount */
- of->of_ad->ad_refcount--;
-
- if ( of->of_ad->ad_refcount <= 0) {
- free( of->of_ad->ad_m_name );
- free( of->of_ad);
- } else {/* someone's still using it. just free this user's locks */
- ad_unlock(of->of_ad, of->of_refnum);
- }
-
free( of );
}
int of_closefork(struct ofork *ofork)
{
struct timeval tv;
- int adflags, doflush = 0;
+ int doflush = 0;
int ret;
- adflags = 0;
- if ((ofork->of_flags & AFPFORK_DATA) && (ad_data_fileno( ofork->of_ad ) != -1)) {
- adflags |= ADFLAGS_DF;
- }
if ( (ofork->of_flags & AFPFORK_OPEN) && ad_reso_fileno( ofork->of_ad ) != -1 ) {
- adflags |= ADFLAGS_HF;
/*
* Only set the rfork's length if we're closing the rfork.
*/
}
}
ret = 0;
- if ( ad_close( ofork->of_ad, adflags ) < 0 ) {
- ret = -1;
+
+ ad_unlock(ofork->of_ad, ofork->of_refnum);
+
+ if (ad_unref(ofork->of_ad) == 0) {
+ if ( ad_close( ofork->of_ad, 0 ) < 0 ) {
+ ret = -1;
+ }
}
of_dealloc( ofork );
return;
}
+ /* ----------------------
+ close all forks for a volume
+ */
+ void of_close_all_forks(void)
+ {
+ int refnum;
+
+ if (!oforks)
+ return;
+
+ for ( refnum = 0; refnum < nforks; refnum++ ) {
+ if (oforks[ refnum ] != NULL) {
+ if (of_closefork( oforks[ refnum ]) < 0 ) {
+ LOG(log_error, logtype_afpd, "of_close_all_forks: %s", strerror(errno) );
+ }
+ }
+ }
+ return;
+ }
+
#endif /* BSD4_4 */
#endif
-#include <netatalk/at.h>
-#include <netatalk/endian.h>
+#include <arpa/inet.h>
+
#include <atalk/dsi.h>
-#include <atalk/atp.h>
-#include <atalk/asp.h>
-#include <atalk/nbp.h>
#include <atalk/unicode.h>
#include <atalk/util.h>
/* extract the obj part of the server */
Obj = (char *) server;
- nbp_name(server, &Obj, &Type, &Zone);
if ((size_t)-1 == (len = convert_string(
- options->unixcharset, options->maccharset,
- Obj, -1, buf, sizeof(buf))) ) {
- len = MIN(strlen(Obj), 31);
+ options->unixcharset, options->maccharset,
+ Obj, -1, buf, sizeof(buf))) ) {
+ len = MIN(strlen(Obj), 31);
*data++ = len;
memcpy( data, Obj, len );
- LOG ( log_error, logtype_afpd, "Could not set servername, using fallback");
+ LOG ( log_error, logtype_afpd, "Could not set servername, using fallback");
} else {
*data++ = len;
memcpy( data, buf, len );
}
static size_t status_netaddress(char *data, int *servoffset,
- const ASP asp, const DSI *dsi,
+ const DSI *dsi,
const struct afp_options *options)
{
char *begin;
/* number of addresses. this currently screws up if we have a dsi
connection, but we don't have the ip address. to get around this,
we turn off the status flag for tcp/ip. */
- *data++ = ((options->fqdn && dsi)? 1 : 0) + (dsi ? 1 : 0) + (asp ? 1 : 0) +
+ *data++ = ((options->fqdn && dsi)? 1 : 0) + (dsi ? 1 : 0) +
(((options->flags & OPTION_ANNOUNCESSH) && options->fqdn && dsi)? 1 : 0);
/* ip address */
}
}
-#ifndef NO_DDP
- if (asp) {
- const struct sockaddr_at *ddpaddr = atp_sockaddr(asp->asp_atp);
-
- /* ddp address */
- *data++ = 6;
- *data++ = 0x03; /* ddp address */
- memcpy(data, &ddpaddr->sat_addr.s_net, sizeof(ddpaddr->sat_addr.s_net));
- data += sizeof(ddpaddr->sat_addr.s_net);
- memcpy(data, &ddpaddr->sat_addr.s_node,
- sizeof(ddpaddr->sat_addr.s_node));
- data += sizeof(ddpaddr->sat_addr.s_node);
- memcpy(data, &ddpaddr->sat_port, sizeof(ddpaddr->sat_port));
- data += sizeof(ddpaddr->sat_port);
- }
-#endif /* ! NO_DDP */
-
/* calculate/store Directory Services Names offset */
offset = htons(data - begin);
*servoffset += sizeof(offset);
/* extract the obj part of the server */
Obj = (char *) (options->server ? options->server : options->hostname);
- nbp_name(options->server ? options->server : options->hostname, &Obj, &Type, &Zone);
-
if ((size_t) -1 == (len = convert_string (
- options->unixcharset, CH_UTF8_MAC,
- Obj, -1, data+sizeof(namelen), maxstatuslen-offset )) ) {
- LOG ( log_error, logtype_afpd, "Could not set utf8 servername");
+ options->unixcharset, CH_UTF8_MAC,
+ Obj, -1, data+sizeof(namelen), maxstatuslen-offset )) ) {
+ LOG ( log_error, logtype_afpd, "Could not set utf8 servername");
- /* set offset to 0 */
- memset(begin + *nameoffset, 0, sizeof(offset));
+ /* set offset to 0 */
+ memset(begin + *nameoffset, 0, sizeof(offset));
data = begin + offset;
- }
- else {
+ } else {
namelen = htons(len);
memcpy( data, &namelen, sizeof(namelen));
data += sizeof(namelen);
/* ---------------------
*/
-void status_init(AFPConfig *aspconfig, AFPConfig *dsiconfig,
+void status_init(AFPConfig *dsiconfig,
const struct afp_options *options)
{
- ASP asp;
DSI *dsi;
char *status = NULL;
size_t statuslen;
int c, sigoff, ipok;
- if (!(aspconfig || dsiconfig) || !options)
+ if (!dsiconfig || !options)
return;
-
- if (aspconfig) {
- status = aspconfig->status;
- maxstatuslen=sizeof(aspconfig->status);
- asp = aspconfig->obj.handle;
- } else
- asp = NULL;
ipok = 0;
if (dsiconfig) {
c = status_server(status, options->server ? options->server :
options->hostname, options);
status_machine(status);
- status_versions(status, asp, dsi);
+ status_versions(status, dsi);
status_uams(status, options->uamlist);
if (options->flags & OPTION_CUSTOMICON)
status_icon(status, icon, sizeof(icon), c);
sigoff = status_signature(status, &c, options);
/* c now contains the offset where the netaddress offset lives */
- status_netaddress(status, &c, asp, dsi, options);
+ status_netaddress(status, &c, dsi, options);
/* c now contains the offset where the Directory Names Count offset lives */
statuslen = status_directorynames(status, &c, dsi, options);
if ( statuslen < maxstatuslen)
statuslen = status_utf8servername(status, &c, dsi, options);
-#ifndef NO_DDP
- if (aspconfig) {
- if (dsiconfig) /* status is dsiconfig->status */
- memcpy(aspconfig->status, status, statuslen);
- asp_setstatus(asp, status, statuslen);
- aspconfig->signature = status + sigoff;
- aspconfig->statuslen = statuslen;
- }
-#endif /* ! NO_DDP */
-
if (dsiconfig) {
if ((options->flags & OPTION_CUSTOMICON) == 0) {
status_icon(status, apple_tcp_icon, sizeof(apple_tcp_icon), 0);
options->sigconffile, strerror(errno));
goto server_signature_random;
}
- } else { /* conf file don't exist */
+ } else { /* conf file don't exist */
if (( fd = creat(options->sigconffile, 0644 )) < 0 ) {
- LOG(log_error, logtype_atalkd, "Cannot create %s (%s). Using one-time signature.",
+ LOG(log_error, logtype_afpd, "ERROR: Cannot create %s (%s). Using one-time signature.",
options->sigconffile, strerror(errno));
goto server_signature_random;
}
if (( fp = fdopen( fd, "w" )) == NULL ) {
- LOG(log_error, logtype_atalkd, "Cannot fdopen %s (%s). Using one-time signature.",
+ LOG(log_error, logtype_afpd, "ERROR: Cannot fdopen %s (%s). Using one-time signature.",
options->sigconffile, strerror(errno));
close(fd);
goto server_signature_random;
#include <stdio.h>
#include <stdlib.h>
-
-/* STDC check */
-#ifdef STDC_HEADERS
#include <string.h>
-#else /* STDC_HEADERS */
-
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
-
#include <errno.h>
#include <limits.h>
#include <sys/param.h>
}
#ifdef accessmode
+
#undef accessmode
#endif
/*
/* --------------------- */
int setdirunixmode(const struct vol *vol, const char *name, mode_t mode)
{
-
- int dropbox = (vol->v_flags & AFPVOL_DROPBOX);
-
LOG(log_debug, logtype_afpd, "setdirunixmode('%s', mode:%04o) {v_dperm:%04o}",
fullpathname(name), mode, vol->v_dperm);
if (dir_rx_set(mode)) {
/* extending right? dir first then .AppleDouble in rf_setdirmode */
- if ( stickydirmode(name, DIRBITS | mode, dropbox, vol->v_umask) < 0 )
+ if ( stickydirmode(name, DIRBITS | mode, 0, vol->v_umask) < 0 )
return -1;
}
if (vol->vfs->vfs_setdirunixmode(vol, name, mode, NULL) < 0 && !vol_noadouble(vol)) {
return -1 ;
}
if (!dir_rx_set(mode)) {
- if ( stickydirmode(name, DIRBITS | mode, dropbox, vol->v_umask) < 0 )
+ if ( stickydirmode(name, DIRBITS | mode, 0, vol->v_umask) < 0 )
return -1;
}
return 0;
struct dirent *dirp;
DIR *dir;
mode_t hf_mode;
- int osx = vol->v_adouble == AD_VERSION2_OSX;
- int dropbox = (vol->v_flags & AFPVOL_DROPBOX);
mode |= vol->v_dperm;
hf_mode = ad_hf_mode(mode);
if (dir_rx_set(mode)) {
/* extending right? dir first */
- if ( stickydirmode(name, DIRBITS | mode, dropbox, vol->v_umask) < 0 )
+ if ( stickydirmode(name, DIRBITS | mode, 0, vol->v_umask) < 0 )
return -1;
}
for ( dirp = readdir( dir ); dirp != NULL; dirp = readdir( dir )) {
/* FIXME */
- if ( *dirp->d_name == '.' && (!osx || dirp->d_name[1] != '_')) {
+ if (*dirp->d_name == '.') {
continue;
}
if ( lstat( dirp->d_name, &st ) < 0 ) {
}
if (!S_ISDIR(st.st_mode)) {
- int setmode = (osx && *dirp->d_name == '.')?hf_mode:mode;
-
- if (setfilmode(dirp->d_name, setmode, &st, vol->v_umask) < 0) {
+ if (setfilmode(dirp->d_name, mode, &st, vol->v_umask) < 0) {
LOG(log_error, logtype_afpd, "setdirmode: chmod %s: %s",dirp->d_name, strerror(errno) );
return -1;
}
}
if (!dir_rx_set(mode)) {
- if ( stickydirmode(name, DIRBITS | mode, dropbox, vol->v_umask) < 0 )
+ if ( stickydirmode(name, DIRBITS | mode, 0, vol->v_umask) < 0 )
return -1;
}
return( 0 );
struct stat st;
struct dirent *dirp;
DIR *dir;
- int osx = vol->v_adouble == AD_VERSION2_OSX;
if (( dir = opendir( name )) == NULL ) {
return( -1 );
}
for ( dirp = readdir( dir ); dirp != NULL; dirp = readdir( dir )) {
- if ( *dirp->d_name == '.' && (!osx || dirp->d_name[1] != '_')) {
+ if ( *dirp->d_name == '.') {
continue;
}
if ( lstat( dirp->d_name, &st ) < 0 ) {
#include <grp.h>
#include <utime.h>
#include <errno.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-/* STDC check */
-#if STDC_HEADERS
#include <string.h>
-#else /* STDC_HEADERS */
-#ifndef HAVE_STRCHR
-#define strchr index
-#define strrchr index
-#endif /* HAVE_STRCHR */
-char *strchr (), *strrchr ();
-#ifndef HAVE_MEMCPY
-#define memcpy(d,s,n) bcopy ((s), (d), (n))
-#define memmove(d,s,n) bcopy ((s), (d), (n))
-#endif /* ! HAVE_MEMCPY */
-#endif /* STDC_HEADERS */
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#include <atalk/asp.h>
#include <atalk/dsi.h>
#include <atalk/adouble.h>
#include <atalk/afp.h>
#include <atalk/logger.h>
#include <atalk/vfs.h>
#include <atalk/uuid.h>
+#include <atalk/ea.h>
+ #include <atalk/bstrlib.h>
+ #include <atalk/bstradd.h>
-
#ifdef CNID_DB
#include <atalk/cnid.h>
#endif /* CNID_DB*/
#define VOLOPT_MACCHARSET 16
#define VOLOPT_CNIDSCHEME 17
#define VOLOPT_ADOUBLE 18 /* adouble version */
-
-#ifdef FORCE_UIDGID
-#warning UIDGID
-#include "uid.h"
-
-#define VOLOPT_FORCEUID 19 /* force uid for username x */
-#define VOLOPT_FORCEGID 20 /* force gid for group x */
-#endif /* FORCE_UIDGID */
-
+/* Usable slot: 19/20 */
#define VOLOPT_UMASK 21
#define VOLOPT_ALLOWED_HOSTS 22
#define VOLOPT_DENIED_HOSTS 23
static const _special_folder special_folders[] = {
{"Network Trash Folder", 1, 0777, 1},
- {"Temporary Items", 1, 0777, 1},
{".AppleDesktop", 1, 0777, 0},
-#if 0
- {"TheFindByContentFolder", 0, 0, 1},
- {"TheVolumeSettingsFolder", 0, 0, 1},
-#endif
{NULL, 0, 0, 0}};
/* Forward declarations */
static void deletevol(struct vol *vol);
static void volume_free(struct vol *vol);
static void check_ea_sys_support(struct vol *vol);
+ static char *get_vol_uuid(const AFPObj *obj, const char *volname);
+ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1,char *p2, int user, struct passwd *pwent);
static void volfree(struct vol_option *options, const struct vol_option *save)
{
} else if (is_var(p, "$c")) {
if (afpmaster && xlatevolname)
return NULL;
- if (obj->proto == AFPPROTO_ASP) {
- ASP asp = obj->handle;
-
- len = sprintf(dest, "%u.%u", ntohs(asp->asp_sat.sat_addr.s_net),
- asp->asp_sat.sat_addr.s_node);
- dest += len;
- destlen -= len;
-
- } else if (obj->proto == AFPPROTO_DSI) {
- DSI *dsi = obj->handle;
- len = sprintf(dest, "%s:%u",
- getip_string((struct sockaddr *)&dsi->client),
- getip_port((struct sockaddr *)&dsi->client));
- dest += len;
- destlen -= len;
- }
+ DSI *dsi = obj->handle;
+ len = sprintf(dest, "%s:%u",
+ getip_string((struct sockaddr *)&dsi->client),
+ getip_port((struct sockaddr *)&dsi->client));
+ dest += len;
+ destlen -= len;
} else if (is_var(p, "$d")) {
if (afpmaster && xlatevolname)
return NULL;
} else if (is_var(p, "$i")) {
if (afpmaster && xlatevolname)
return NULL;
- if (obj->proto == AFPPROTO_ASP) {
- ASP asp = obj->handle;
-
- len = sprintf(dest, "%u", ntohs(asp->asp_sat.sat_addr.s_net));
- dest += len;
- destlen -= len;
-
- } else if (obj->proto == AFPPROTO_DSI) {
- DSI *dsi = obj->handle;
- q = getip_string((struct sockaddr *)&dsi->client);
- }
+ DSI *dsi = obj->handle;
+ q = getip_string((struct sockaddr *)&dsi->client);
} else if (is_var(p, "$s")) {
if (obj->Obj)
q = obj->Obj;
else if (strcasecmp(val + 1, "xlateupper") == 0)
options[VOLOPT_CASEFOLD].i_value = AFPVOL_ULOWERMUPPER;
} else if (optionok(tmp, "adouble:", val)) {
- if (strcasecmp(val + 1, "v1") == 0)
- options[VOLOPT_ADOUBLE].i_value = AD_VERSION1;
-#if AD_VERSION == AD_VERSION2
- else if (strcasecmp(val + 1, "v2") == 0)
+ if (strcasecmp(val + 1, "v2") == 0)
options[VOLOPT_ADOUBLE].i_value = AD_VERSION2;
- else if (strcasecmp(val + 1, "osx") == 0)
- options[VOLOPT_ADOUBLE].i_value = AD_VERSION2_OSX;
- else if (strcasecmp(val + 1, "sfm") == 0)
- options[VOLOPT_ADOUBLE].i_value = AD_VERSION1_SFM;
-#endif
+ else if (strcasecmp(val + 1, "ea") == 0)
+ options[VOLOPT_ADOUBLE].i_value = AD_VERSION_EA;
} else if (optionok(tmp, "options:", val)) {
char *p;
options[VOLOPT_FLAGS].i_value |= AFPVOL_USEDOTS | AFPVOL_INV_DOTS;
else if (strcasecmp(p, "limitsize") == 0)
options[VOLOPT_FLAGS].i_value |= AFPVOL_LIMITSIZE;
- /* support for either "dropbox" or "dropkludge" */
- else if (strcasecmp(p, "dropbox") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_DROPBOX;
- else if (strcasecmp(p, "dropkludge") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_DROPBOX;
else if (strcasecmp(p, "nofileid") == 0)
options[VOLOPT_FLAGS].i_value |= AFPVOL_NOFILEID;
else if (strcasecmp(p, "nostat") == 0)
options[VOLOPT_DFLTPERM].i_value = (int)strtol(val+1, NULL, 8);
} else if (optionok(tmp, "password:", val)) {
setoption(options, save, VOLOPT_PASSWORD, val);
-
-#ifdef FORCE_UIDGID
-
- /* this code allows forced uid/gid per volume settings */
- } else if (optionok(tmp, "forceuid:", val)) {
- setoption(options, save, VOLOPT_FORCEUID, val);
- } else if (optionok(tmp, "forcegid:", val)) {
- setoption(options, save, VOLOPT_FORCEGID, val);
-
-#endif /* FORCE_UIDGID */
} else if (optionok(tmp, "root_preexec:", val)) {
setoption(options, save, VOLOPT_ROOTPREEXEC, val);
/* check duplicate */
for ( volume = Volumes; volume; volume = volume->v_next ) {
if (( strcasecmp_w( volume->v_u8mname, u8mtmpname ) == 0 ) || ( strcasecmp_w( volume->v_macname, mactmpname ) == 0 )){
+ LOG (log_error, logtype_afpd, "ERROR: Volume name is duplicated. Check AppleVolumes files.");
if (volume->v_deleted) {
volume->v_new = hide = 1;
}
if ((volume->v_flags & AFPVOL_EILSEQ))
volume->v_utom_flags |= CONV__EILSEQ;
-#ifdef FORCE_UIDGID
- if (options[VOLOPT_FORCEUID].c_value) {
- volume->v_forceuid = strdup(options[VOLOPT_FORCEUID].c_value);
- } else {
- volume->v_forceuid = NULL; /* set as null so as to return 0 later on */
- }
-
- if (options[VOLOPT_FORCEGID].c_value) {
- volume->v_forcegid = strdup(options[VOLOPT_FORCEGID].c_value);
- } else {
- volume->v_forcegid = NULL; /* set as null so as to return 0 later on */
- }
-#endif
if (!user) {
if (options[VOLOPT_PREEXEC].c_value)
volume->v_preexec = volxlate(obj, NULL, MAXPATHLEN, options[VOLOPT_PREEXEC].c_value, pwd, path, name);
/* get/store uuid from file */
if (volume->v_flags & AFPVOL_TM) {
- char *uuid = get_uuid(obj, volume->v_localname);
+ char *uuid = get_vol_uuid(obj, volume->v_localname);
if (!uuid) {
LOG(log_error, logtype_afpd, "Volume '%s': couldn't get UUID",
volume->v_localname);
* <extension> TYPE [CREATOR]
*
*/
- int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int user, struct passwd *pwent)
+ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int user, struct passwd *pwent)
{
FILE *fp;
char path[MAXPATHLEN + 1];
p1->mtime = st.st_mtime;
}
+ if ((read_lock(fd, 0, SEEK_SET, 0)) != 0) {
+ LOG(log_error, logtype_afpd, "readvolfile: can't lock volume file \"%s\"", path);
+ if ( fclose( fp ) != 0 ) {
+ LOG(log_error, logtype_afpd, "readvolfile: fclose: %s", strerror(errno) );
+ }
+ return -1;
+ }
+
memset(save_options, 0, sizeof(save_options));
/* Enable some default options for all volumes */
free(vol->v_cnidscheme);
free(vol->v_dbpath);
free(vol->v_gvs);
-#ifdef FORCE_UIDGID
- free(vol->v_forceuid);
- free(vol->v_forcegid);
-#endif /* FORCE_UIDGID */
if (vol->v_uuid)
free(vol->v_uuid);
}
getvolspace_done:
if (vol->v_limitsize) {
- /* FIXME: Free could be limit minus (total minus used), */
- /* which will confuse the client less ? */
- *xbfree = min(*xbfree, (vol->v_limitsize * 1024 * 1024));
+ bstring cmdstr;
+ if ((cmdstr = bformat("du -sh \"%s\" 2> /dev/null | cut -f1", vol->v_path)) == NULL)
+ return AFPERR_MISC;
+
+ FILE *cmd = popen(cfrombstr(cmdstr), "r");
+ bdestroy(cmdstr);
+ if (cmd == NULL)
+ return AFPERR_MISC;
+
+ char buf[100];
+ fgets(buf, 100, cmd);
+
+ if (pclose(cmd) == -1)
+ return AFPERR_MISC;
+
+ size_t multi = 0;
+ if (buf[strlen(buf) - 2] == 'G' || buf[strlen(buf) - 2] == 'g')
+ /* GB */
+ multi = 1024 * 1024 * 1024;
+ else if (buf[strlen(buf) - 2] == 'M' || buf[strlen(buf) - 2] == 'm')
+ /* MB */
+ multi = 1024 * 1024;
+ else if (buf[strlen(buf) - 2] == 'K' || buf[strlen(buf) - 2] == 'k')
+ /* MB */
+ multi = 1024;
+
+ char *p;
+ if (p = strchr(buf, ','))
+ /* ignore fraction */
+ *p = 0;
+ else
+ /* remove G|M|K char */
+ buf[strlen(buf) - 2] = 0;
+ /* now buf contains only digits */
+ long long used = atoll(buf) * multi;
+ LOG(log_debug, logtype_afpd, "volparams: used on volume: %llu bytes", used);
+
*xbtotal = min(*xbtotal, (vol->v_limitsize * 1024 * 1024));
+ *xbfree = min(*xbfree, *xbtotal < used ? 0 : *xbtotal - used);
}
*bfree = min( *xbfree, maxsize);
* .Parent file here if it doesn't exist. */
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if ( ad_open_metadata( vol->v_path, ADFLAGS_DIR, O_CREAT, &ad) < 0 ) {
+ if (ad_open(&ad, vol->v_path, ADFLAGS_HF | ADFLAGS_DIR, O_RDWR | O_CREAT, 0666) != 0 ) {
isad = 0;
vol->v_ctime = AD_DATE_FROM_UNIX(st->st_mtime);
#ifndef NO_LARGE_VOL_SUPPORT
case VOLPBIT_XBFREE :
xbfree = hton64( xbfree );
-#if defined(__GNUC__) && defined(HAVE_GCC_MEMCPY_BUG)
- bcopy(&xbfree, data, sizeof(xbfree));
-#else /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
memcpy(data, &xbfree, sizeof( xbfree ));
-#endif /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
data += sizeof( xbfree );
break;
case VOLPBIT_XBTOTAL :
xbtotal = hton64( xbtotal );
-#if defined(__GNUC__) && defined(HAVE_GCC_MEMCPY_BUG)
- bcopy(&xbtotal, data, sizeof(xbtotal));
-#else /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
memcpy(data, &xbtotal, sizeof( xbtotal ));
-#endif /* __GNUC__ && HAVE_GCC_MEMCPY_BUG */
data += sizeof( xbfree );
break;
#endif /* ! NO_LARGE_VOL_SUPPORT */
if (vol->v_vfs_ea == AFPVOL_EA_AUTO) {
if ((vol->v_flags & AFPVOL_RO) == AFPVOL_RO) {
- LOG(log_info, logtype_logger, "read-only volume '%s', can't test for EA support, disabling EAs", vol->v_localname);
+ LOG(log_info, logtype_afpd, "read-only volume '%s', can't test for EA support, disabling EAs", vol->v_localname);
vol->v_vfs_ea = AFPVOL_EA_NONE;
return;
}
process_uid = geteuid();
if (process_uid)
if (seteuid(0) == -1) {
- LOG(log_error, logtype_logger, "check_ea_sys_support: can't seteuid(0): %s", strerror(errno));
+ LOG(log_error, logtype_afpd, "check_ea_sys_support: can't seteuid(0): %s", strerror(errno));
exit(EXITERR_SYS);
}
if (process_uid) {
if (seteuid(process_uid) == -1) {
- LOG(log_error, logtype_logger, "can't seteuid back %s", strerror(errno));
+ LOG(log_error, logtype_afpd, "can't seteuid back %s", strerror(errno));
exit(EXITERR_SYS);
}
}
if (( volume->v_flags & AFPVOL_OPEN ) ) {
/* the volume is already open */
-#ifdef FORCE_UIDGID
- set_uidgid ( volume );
-#endif
return stat_vol(bitmap, volume, rbuf, rbuflen);
}
}
}
-#ifdef FORCE_UIDGID
- set_uidgid ( volume );
-#endif
-
if (volume->v_preexec) {
if ((ret = afprun(0, volume->v_preexec, NULL)) && volume->v_preexec_close) {
LOG(log_error, logtype_afpd, "afp_openvol(%s): preexec : %d", volume->v_path, ret );
* FIXME file size
*/
if (utf8_encoding()) {
- volume->max_filename = 255;
+ volume->max_filename = UTF8FILELEN_EARLY;
}
else {
volume->max_filename = MACFILELEN;
return( NULL );
}
-#ifdef FORCE_UIDGID
- set_uidgid ( vol );
-#endif /* FORCE_UIDGID */
-
current_vol = vol;
return( vol );
return AFPERR_BITMAP;
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if ( ad_open( vol->v_path, ADFLAGS_HF|ADFLAGS_DIR, O_RDWR,
- 0666, &ad) < 0 ) {
+ if ( ad_open(&ad, vol->v_path, ADFLAGS_HF|ADFLAGS_DIR, O_RDWR) < 0 ) {
if (errno == EROFS)
return AFPERR_VLOCK;
if ( !ret && folder->hide) {
/* Hide it */
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if (ad_open_metadata( p, ADFLAGS_DIR, O_CREAT, &ad) < 0) {
- free (p);
+ if (ad_open(&ad, p, ADFLAGS_HF | ADFLAGS_DIR, O_RDWR | O_CREAT, 0666) != 0) {
+ free(p);
free(q);
return (-1);
}
*
* Returns pointer to allocated storage on success, NULL on error.
*/
- char *get_uuid(const AFPObj *obj, const char *volname)
+ static char *get_vol_uuid(const AFPObj *obj, const char *volname)
{
char *volname_conf;
char buf[1024], uuid[UUID_PRINTABLE_STRING_LENGTH], *p;
if (stat(obj->options.uuidconf, &tmpstat)) { /* no file */
if (( fd = creat(obj->options.uuidconf, 0644 )) < 0 ) {
- LOG(log_error, logtype_atalkd, "ERROR: Cannot create %s (%s).",
+ LOG(log_error, logtype_afpd, "ERROR: Cannot create %s (%s).",
obj->options.uuidconf, strerror(errno));
return NULL;
}
if (( fp = fdopen( fd, "w" )) == NULL ) {
- LOG(log_error, logtype_atalkd, "ERROR: Cannot fdopen %s (%s).",
+ LOG(log_error, logtype_afpd, "ERROR: Cannot fdopen %s (%s).",
obj->options.uuidconf, strerror(errno));
close(fd);
return NULL;
fprintf(fp, "\"%s\"\t%36s\n", volname, cp);
fclose(fp);
- return strdup(uuid);
+ return strdup(cp);
}
#ifndef AFPD_VOLUME_H
#define AFPD_VOLUME_H 1
-#include <sys/cdefs.h>
#include <sys/types.h>
-#include <netatalk/endian.h>
+#include <arpa/inet.h>
#include <atalk/volume.h>
#include <atalk/cnid.h>
extern void setvoltime (AFPObj *, struct vol *);
extern int pollvoltime (AFPObj *);
extern void load_volumes (AFPObj *obj);
- extern int readvolfile(AFPObj *obj,
- struct afp_volume_name *p1,
- char *p2,
- int user,
- struct passwd *pwent);
extern const struct vol *getvolumes(void);
extern void unload_volumes_and_extmap(void);
- extern char *get_uuid(const AFPObj *obj, const char *volname);
/* FP functions */
int afp_openvol (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen);
#include <atalk/ea.h>
#include <atalk/util.h>
#include <atalk/acl.h>
+#include <atalk/compat.h>
#include "cmd_dbd.h"
#include "dbif.h"
*/
static int check_adfile(const char *fname, const struct stat *st)
{
- int ret, adflags;
+ int ret;
+ int adflags = ADFLAGS_HF;
struct adouble ad;
- char *adname;
+ const char *adname;
if (dbd_flags & DBD_FLAGS_CLEANUP)
return 0;
if (S_ISREG(st->st_mode))
- adflags = 0;
- else
- adflags = ADFLAGS_DIR;
+ adflags |= ADFLAGS_DIR;
adname = myvolinfo->ad_path(fname, adflags);
/* Create ad file */
ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options);
- if ((ret = ad_open_metadata( fname, adflags, O_CREAT, &ad)) != 0) {
+ if ((ret = ad_open(&ad, fname, adflags, O_CREAT | O_RDWR, 0666)) != 0) {
dbd_log( LOGSTD, "Error creating AppleDouble file '%s/%s': %s",
cwdbuf, adname, strerror(errno));
#endif
} else {
ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options);
- if (ad_open_metadata( fname, adflags, O_RDONLY, &ad) != 0) {
+ if (ad_open(&ad, fname, adflags, O_RDONLY) != 0) {
dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s'", cwdbuf, fname);
return -1;
}
/* Create ad dir and set name */
ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options);
- if (ad_open_metadata( ".", ADFLAGS_DIR, O_CREAT, &ad) != 0) {
+ if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR, O_CREAT | O_RDWR, 0777) != 0) {
dbd_log( LOGSTD, "Error creating AppleDouble dir in %s: %s", cwdbuf, strerror(errno));
return -1;
}
/*
Check CNID for a file/dir, both from db and from ad-file.
For detailed specs see intro.
+
+ @return Correct CNID of object or CNID_INVALID (ie 0) on error
*/
static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfile_ok, int adflags)
{
cnid_t db_cnid, ad_cnid;
struct adouble ad;
+ /* Force checkout every X items */
+ static int cnidcount = 0;
+ cnidcount++;
+ if (cnidcount > 10000) {
+ cnidcount = 0;
+ if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0) {
+ dbd_log(LOGSTD, "Error checkpointing!");
+ return CNID_INVALID;
+ }
+ }
+
/* Get CNID from ad-file if volume is using AFPVOL_CACHE */
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) {
/* Query the database */
ret = dbd_lookup(dbd, &rqst, &rply, (dbd_flags & DBD_FLAGS_SCAN) ? 1 : 0);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
if (rply.result == CNID_DBD_RES_OK) {
db_cnid = rply.cnid;
} else if (rply.result == CNID_DBD_RES_NOTFOUND) {
if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
rqst.cnid = db_cnid;
ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
rqst.cnid = ad_cnid;
ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
ret = dbd_rebuild_add(dbd, &rqst, &rply);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
}
return ad_cnid;
} else if (ad_cnid && (db_cnid == 0)) {
if (ret == CNID_DBD_RES_OK) {
/* Occupied! Choose another, update ad-file */
ret = dbd_add(dbd, &rqst, &rply, 1);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
db_cnid = rply.cnid;
dbd_log(LOGSTD, "New CNID for '%s/%s': %u", cwdbuf, name, ntohl(db_cnid));
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);
cwdbuf, name, ntohl(ad_cnid));
rqst.cnid = ad_cnid;
ret = dbd_rebuild_add(dbd, &rqst, &rply);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
}
return ad_cnid;
} else if ((db_cnid == 0) && (ad_cnid == 0)) {
if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
/* add to db */
ret = dbd_add(dbd, &rqst, &rply, 1);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
db_cnid = rply.cnid;
dbd_log(LOGSTD, "New CNID for '%s/%s': %u", cwdbuf, name, ntohl(db_cnid));
}
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);
return db_cnid;
}
- return 0;
+ return CNID_INVALID;
}
/*
continue;
}
+ /**************************************************************************
+ Statistics
+ **************************************************************************/
+ static unsigned long long statcount = 0;
+ static time_t t = 0;
+
+ if (t == 0)
+ t = time(NULL);
+
+ statcount++;
+ if ((statcount % 10000) == 0) {
+ if (dbd_flags & DBD_FLAGS_STATS)
+ dbd_log(LOGSTD, "Scanned: %10llu, time: %10llu s",
+ statcount, (unsigned long long)(time(NULL) - t));
+ }
+
/**************************************************************************
Tests
**************************************************************************/
cnid = check_cnid(ep->d_name, did, &st, adfile_ok, adflags);
/* Now add this object to our rebuild dbd */
- if (cnid) {
+ if (cnid && dbd_rebuild) {
+ static uint count = 0;
rqst.cnid = rply.cnid;
- dbd_rebuild_add(dbd_rebuild, &rqst, &rply);
+ ret = dbd_rebuild_add(dbd_rebuild, &rqst, &rply);
+ if (dbif_txn_close(dbd_rebuild, ret) != 0)
+ return -1;
if (rply.result != CNID_DBD_RES_OK) {
- dbd_log( LOGDEBUG, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db",
+ dbd_log( LOGSTD, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db",
cnid, cwdbuf, ep->d_name);
- longjmp(jmp, 1); /* this jumps back to cmd_dbd_scanvol() */
+ return -1;
+ }
+ count++;
+ if (count == 10000) {
+ if (dbif_txn_checkpoint(dbd_rebuild, 0, 0, 0) < 0) {
+ dbd_log(LOGSTD, "Error checkpointing!");
+ return -1;
+ }
+ count = 0;
}
}
}
close(cwd);
*(strrchr(cwdbuf, '/')) = 0;
if (ret < 0)
- continue;
+ return -1;
}
}
*/
static void delete_orphaned_cnids(DBD *dbd, DBD *dbd_rebuild, dbd_flags_t flags)
{
- int ret, deleted = 0;
+ int ret = 0, deleted = 0;
cnid_t dbd_cnid = 0, rebuild_cnid = 0;
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
if (alarmed)
longjmp(jmp, 1); /* this jumps back to cmd_dbd_scanvol() */
- if (deleted > 50) {
+ if (deleted > 1000) {
deleted = 0;
if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0) {
dbd_log(LOGSTD, "Error checkpointing!");
goto cleanup;
}
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return;
deleted++;
}
/* Check if we got a termination signal */
(void)dbif_txn_abort(dbd);
goto cleanup;
}
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return;
deleted++;
}
continue;
}
if (dbd_cnid > rebuild_cnid) {
+ dbif_idwalk(dbd, NULL, 1); /* Close cursor */
+ dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */
+ (void)dbif_txn_close(dbd, 2);
+ (void)dbif_txn_close(dbd_rebuild, 2);
dbd_log(LOGSTD, "Ghost CNID: %u. This is fatal! Dumping rebuild db:\n", rebuild_cnid);
dbif_dump(dbd_rebuild, 0);
dbd_log(LOGSTD, "Send this dump and a `dbd -d ...` dump to the Netatalk Dev team!");
- dbif_txn_close(dbd, ret);
- dbif_idwalk(dbd, NULL, 1); /* Close cursor */
- dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */
goto cleanup;
}
} /* while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) */
return;
}
+ static const char *get_tmpdb_path(void)
+ {
+ pid_t pid = getpid();
+ static char path[MAXPATHLEN];
+ snprintf(path, MAXPATHLEN, "/tmp/tmpdb-dbd.%u", pid);
+ if (mkdir(path, 0755) != 0)
+ return NULL;
+ return path;
+ }
+
/*
Main func called from cmd_dbd.c
*/
{
int ret = 0;
struct db_param db_param = { 0 };
+ const char *tmpdb_path = NULL;
/* Set cachesize for in-memory rebuild db */
- db_param.cachesize = 128 * 1024 * 1024; /* 128 MB */
+ db_param.cachesize = 64 * 1024; /* 64 MB */
+ db_param.maxlocks = DEFAULT_MAXLOCKS;
+ db_param.maxlockobjs = DEFAULT_MAXLOCKOBJS;
+ db_param.logfile_autoremove = 1;
/* Make it accessible for all funcs */
dbd = dbd_ref;
return -1;
}
- if (! nocniddb) {
- /* Get volume stamp */
- dbd_getstamp(dbd, &rqst, &rply);
- if (rply.result != CNID_DBD_RES_OK)
- goto exit_cleanup;
- memcpy(stamp, rply.name, CNID_DEV_LEN);
-
- /* open/create rebuild dbd, copy rootinfo key */
- if (NULL == (dbd_rebuild = dbif_init(NULL, NULL)))
- return -1;
- if (0 != (dbif_open(dbd_rebuild, &db_param, 0)))
- return -1;
- if (0 != (dbif_copy_rootinfokey(dbd, dbd_rebuild)))
- goto exit_cleanup;
+ /* Get volume stamp */
+ dbd_getstamp(dbd, &rqst, &rply);
+ if (rply.result != CNID_DBD_RES_OK) {
+ ret = -1;
+ goto exit;
}
+ memcpy(stamp, rply.name, CNID_DEV_LEN);
+
+ /* temporary rebuild db, used with -re rebuild to delete unused CNIDs, not used with -f */
+ if (! nocniddb && (flags & DBD_FLAGS_EXCL) && !(flags & DBD_FLAGS_FORCE)) {
+ tmpdb_path = get_tmpdb_path();
+ if (NULL == (dbd_rebuild = dbif_init(tmpdb_path, "cnid2.db"))) {
+ ret = -1;
+ goto exit;
+ }
- if (setjmp(jmp) != 0)
- goto exit_cleanup; /* Got signal, jump from dbd_readdir */
+ if (dbif_env_open(dbd_rebuild,
+ &db_param,
+ DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN) < 0) {
+ dbd_log(LOGSTD, "error opening tmp database!");
+ goto exit;
+ }
+
+ if (0 != (dbif_open(dbd_rebuild, NULL, 0))) {
+ ret = -1;
+ goto exit;
+ }
+
+ if (0 != (dbif_copy_rootinfokey(dbd, dbd_rebuild))) {
+ ret = -1;
+ goto exit;
+ }
+ }
+
+ if (setjmp(jmp) != 0) {
+ ret = 0; /* Got signal, jump from dbd_readdir */
+ goto exit;
+ }
/* scanvol */
- if ( (scanvol(vi, flags)) != 0)
- return -1;
+ if ( (scanvol(vi, flags)) != 0) {
+ ret = -1;
+ goto exit;
+ }
+ exit:
if (! nocniddb) {
- /* We can only do this in exclusive mode, otherwise we might delete CNIDs added from
- other clients in between our pass 1 and 2 */
- if (flags & DBD_FLAGS_EXCL)
+ if (dbif_txn_close(dbd, ret == 0 ? 1 : 0) != 0)
+ ret = -1;
+ if (dbd_rebuild)
+ if (dbif_txn_close(dbd_rebuild, ret == 0 ? 1 : 0) != 0)
+ ret = -1;
+ if ((ret == 0) && dbd_rebuild && (flags & DBD_FLAGS_EXCL) && !(flags & DBD_FLAGS_FORCE))
+ /* We can only do this in exclusive mode, otherwise we might delete CNIDs added from
+ other clients in between our pass 1 and 2 */
delete_orphaned_cnids(dbd, dbd_rebuild, flags);
}
- exit_cleanup:
- if (! nocniddb)
+ if (dbd_rebuild) {
+ dbd_log(LOGDEBUG, "Closing tmp db");
dbif_close(dbd_rebuild);
+
+ if (tmpdb_path) {
+ char cmd[8 + MAXPATHLEN];
+ snprintf(cmd, 8 + MAXPATHLEN, "rm -f %s/*", tmpdb_path);
+ dbd_log( LOGDEBUG, "Removing temp database '%s'", tmpdb_path);
+ system(cmd);
+ snprintf(cmd, 8 + MAXPATHLEN, "rmdir %s", tmpdb_path);
+ system(cmd);
+ }
+ }
return ret;
}
#include <sys/wait.h>
#include <sys/uio.h>
#include <sys/un.h>
-#define _XPG4_2 1
+// #define _XPG4_2 1
#include <sys/socket.h>
#include <stdio.h>
#include <time.h>
#include <atalk/cnid_dbd_private.h>
#include <atalk/paths.h>
#include <atalk/volinfo.h>
+#include <atalk/compat.h>
#include "usockfd.h"
/* Load .volinfo file */
if ((volinfo = allocvolinfo(volpath)) == NULL) {
- LOG(log_severe, logtype_cnid, "allocvolinfo: %s", strerror(errno));
+ LOG(log_severe, logtype_cnid, "allocvolinfo(\"%s\"): %s",
+ volpath, strerror(errno));
goto loop_end;
}
#include "config.h"
#endif
+ #ifndef _XOPEN_SOURCE
+ # define _XOPEN_SOURCE 600
+ #endif
+ #ifndef __EXTENSIONS__
+ # define __EXTENSIONS__
+ #endif
+ #ifndef _GNU_SOURCE
+ # define _GNU_SOURCE
+ #endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/uio.h>
- #define _XPG4_2 1
#include <sys/socket.h>
#include <sys/select.h>
#include <assert.h>
return -1;
}
- nametmp = rqst->name;
+ nametmp = (char *)rqst->name;
if ((b = readt(cur_fd, rqst, sizeof(struct cnid_dbd_rqst), 1, CNID_DBD_TIMEOUT))
!= sizeof(struct cnid_dbd_rqst)) {
if (b)
return 0;
}
rqst->name = nametmp;
- if (rqst->namelen && readt(cur_fd, rqst->name, rqst->namelen, 1, CNID_DBD_TIMEOUT)
+ if (rqst->namelen && readt(cur_fd, (char *)rqst->name, rqst->namelen, 1, CNID_DBD_TIMEOUT)
!= rqst->namelen) {
LOG(log_error, logtype_cnid, "error reading message name: %s", strerror(errno));
invalidate_fd(cur_fd);
}
/* We set this to make life easier for logging. None of the other stuff
needs zero terminated strings. */
- rqst->name[rqst->namelen] = '\0';
+ ((char *)(rqst->name))[rqst->namelen] = '\0';
LOG(log_maxdebug, logtype_cnid, "comm_rcv: got %u bytes", b + rqst->namelen);
#define CNID_DBD_DB_PARAM_H 1
#include <sys/param.h>
-#include <sys/cdefs.h>
+ #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;
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/cdefs.h>
#include <unistd.h>
+#include <arpa/inet.h>
#include <db.h>
return ret;
}
+ /*!
+ * Get lock on db lock file
+ *
+ * @args cmd (r) lock command:
+ * LOCK_FREE: close lockfd
+ * LOCK_UNLOCK: unlock lockm keep lockfd open
+ * LOCK_EXCL: F_WRLCK on lockfd
+ * LOCK_SHRD: F_RDLCK on lockfd
+ * @args dbpath (r) path to lockfile, only used on first call,
+ * later the stored fd is used
+ * @returns LOCK_FREE/LOCK_UNLOCK return 0 on success, -1 on error
+ * LOCK_EXCL/LOCK_SHRD return LOCK_EXCL or LOCK_SHRD respectively on
+ * success, 0 if the lock couldn't be acquired, -1 on other errors
+ */
+ int get_lock(int cmd, const char *dbpath)
+ {
+ static int lockfd = -1;
+ int ret;
+ char lockpath[PATH_MAX];
+ struct stat st;
+
+ switch (cmd) {
+ case LOCK_FREE:
+ if (lockfd == -1)
+ return -1;
+ close(lockfd);
+ lockfd = -1;
+ return 0;
+
+ case LOCK_UNLOCK:
+ if (lockfd == -1)
+ return -1;
+ return unlock(lockfd, 0, SEEK_SET, 0);
+
+ case LOCK_EXCL:
+ case LOCK_SHRD:
+ if (lockfd == -1) {
+ if ( (strlen(dbpath) + strlen(LOCKFILENAME+1)) > (PATH_MAX - 1) ) {
+ LOG(log_error, logtype_cnid, ".AppleDB pathname too long");
+ return -1;
+ }
+ strncpy(lockpath, dbpath, PATH_MAX - 1);
+ strcat(lockpath, "/");
+ strcat(lockpath, LOCKFILENAME);
+
+ if ((lockfd = open(lockpath, O_RDWR | O_CREAT, 0644)) < 0) {
+ LOG(log_error, logtype_cnid, "Error opening lockfile: %s", strerror(errno));
+ return -1;
+ }
+
+ if ((stat(dbpath, &st)) != 0) {
+ LOG(log_error, logtype_cnid, "Error statting lockfile: %s", strerror(errno));
+ return -1;
+ }
+
+ if ((chown(lockpath, st.st_uid, st.st_gid)) != 0) {
+ LOG(log_error, logtype_cnid, "Error inheriting lockfile permissions: %s",
+ strerror(errno));
+ return -1;
+ }
+ }
+
+ if (cmd == LOCK_EXCL)
+ ret = write_lock(lockfd, 0, SEEK_SET, 0);
+ else
+ ret = read_lock(lockfd, 0, SEEK_SET, 0);
+
+ if (ret != 0) {
+ if (cmd == LOCK_SHRD)
+ LOG(log_error, logtype_cnid, "Volume CNID db is locked, try again...");
+ return 0;
+ }
+
+ LOG(log_debug, logtype_cnid, "get_lock: got %s lock",
+ cmd == LOCK_EXCL ? "LOCK_EXCL" : "LOCK_SHRD");
+ return cmd;
+
+ default:
+ return -1;
+ } /* switch(cmd) */
+
+ /* deadc0de, never get here */
+ return -1;
+ }
+
/* --------------- */
DBD *dbif_init(const char *envhome, const char *filename)
{
return -1;
}
+ dbd->db_param = *dbp;
+
if ((dbif_openlog(dbd)) != 0)
return -1;
}
/*
- ret = 1 -> commit txn
- ret = 0 -> abort txn -> exit!
+ ret = 1 -> commit txn if db_param.txn_frequency
+ ret = 0 -> abort txn db_param.txn_frequency -> exit!
anything else -> exit!
+
+ @returns 0 on success (abort or commit), -1 on error
*/
- void dbif_txn_close(DBD *dbd, int ret)
+ int dbif_txn_close(DBD *dbd, int ret)
{
if (ret == 0) {
if (dbif_txn_abort(dbd) < 0) {
LOG( log_error, logtype_cnid, "Fatal error aborting transaction. Exiting!");
- exit(EXIT_FAILURE);
+ return -1;
}
} else if (ret == 1) {
ret = dbif_txn_commit(dbd);
if ( ret < 0) {
LOG( log_error, logtype_cnid, "Fatal error committing transaction. Exiting!");
- exit(EXIT_FAILURE);
+ return -1;
}
- } else
- exit(EXIT_FAILURE);
+ } else {
+ return -1;
+ }
+
+ return 0;
}
int dbif_txn_checkpoint(DBD *dbd, u_int32_t kbyte, u_int32_t min, u_int32_t flags)
#ifndef CNID_DBD_DBIF_H
#define CNID_DBD_DBIF_H 1
-#include <sys/cdefs.h>
#include <db.h>
#include <atalk/adouble.h>
#include "db_param.h"
#define DBIF_IDX_DIDNAME 2
#define DBIF_IDX_NAME 3
+ /* get_lock cmd and return value */
+ #define LOCKFILENAME "lock"
+ #define LOCK_FREE 0
+ #define LOCK_UNLOCK 1
+ #define LOCK_EXCL 2
+ #define LOCK_SHRD 3
+
/* Structures */
typedef struct {
char *name;
typedef struct {
DB_ENV *db_env;
+ struct db_param db_param;
DB_TXN *db_txn;
DBC *db_cur; /* for dbif_walk */
char *db_envhome;
} DBD;
/* Functions */
+ extern int get_lock(int cmd, const char *dbpath);
+
extern DBD *dbif_init(const char *envhome, const char *dbname);
extern int dbif_env_open(DBD *dbd, struct db_param *dbp, uint32_t dbenv_oflags);
extern int dbif_open(DBD *dbd, struct db_param *dbp, int reindex);
extern int dbif_txn_begin(DBD *);
extern int dbif_txn_commit(DBD *);
extern int dbif_txn_abort(DBD *);
- extern void dbif_txn_close(DBD *dbd, int ret); /* Switch between commit+abort */
+ extern int dbif_txn_close(DBD *dbd, int ret); /* Switch between commit+abort */
extern int dbif_txn_checkpoint(DBD *, u_int32_t, u_int32_t, u_int32_t);
extern int dbif_dump(DBD *dbd, int dumpindexes);
#include "config.h"
#endif /* HAVE_CONFIG_H */
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#ifdef HAVE_FCNTL_H
#include <fcntl.h>
-#endif /* HAVE_FCNTL_H */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
-#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
-#endif /* HAVE_SYS_TYPES_H */
#include <sys/param.h>
-#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
-#endif /* HAVE_SYS_STAT_H */
#include <time.h>
#include <sys/file.h>
+#include <arpa/inet.h>
-#include <netatalk/endian.h>
#include <atalk/cnid_dbd_private.h>
#include <atalk/logger.h>
#include <atalk/volinfo.h>
#include "dbd.h"
#include "comm.h"
- #define LOCKFILENAME "lock"
-
/*
Note: DB_INIT_LOCK is here so we can run the db_* utilities while netatalk is running.
It's a likey performance hit, but it might we worth it.
*/
- #define DBOPTIONS (DB_CREATE | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | DB_RECOVER)
+ #define DBOPTIONS (DB_CREATE | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN)
/* Global, needed by pack.c:idxname() */
struct volinfo volinfo;
static DBD *dbd;
static int exit_sig = 0;
+ static int db_locked;
static void sig_exit(int signo)
{
}
}
- /* ------------------------ */
- static int get_lock(void)
- {
- int lockfd;
- struct flock lock;
-
- if ((lockfd = open(LOCKFILENAME, O_RDWR | O_CREAT, 0644)) < 0) {
- LOG(log_error, logtype_cnid, "main: error opening lockfile: %s", strerror(errno));
- exit(1);
- }
-
- lock.l_start = 0;
- lock.l_whence = SEEK_SET;
- lock.l_len = 0;
- lock.l_type = F_WRLCK;
-
- if (fcntl(lockfd, F_SETLK, &lock) < 0) {
- if (errno == EACCES || errno == EAGAIN) {
- LOG(log_error, logtype_cnid, "get_lock: locked");
- exit(0);
- } else {
- LOG(log_error, logtype_cnid, "main: fcntl F_WRLCK lockfile: %s", strerror(errno));
- exit(1);
- }
- }
-
- return lockfd;
- }
/* ----------------------- */
static void set_signal(void)
}
}
- /* ----------------------- */
- static void free_lock(int lockfd)
- {
- struct flock lock;
-
- lock.l_start = 0;
- lock.l_whence = SEEK_SET;
- lock.l_len = 0;
- lock.l_type = F_UNLCK;
- fcntl(lockfd, F_SETLK, &lock);
- close(lockfd);
- }
-
/* ------------------------ */
int main(int argc, char *argv[])
{
struct db_param *dbp;
int err = 0;
- int lockfd, ctrlfd, clntfd;
+ int ctrlfd, clntfd;
char *logconfig;
set_processname("cnid_dbd");
switch_to_user(dbpath);
- /* Before we do anything else, check if there is an instance of cnid_dbd
- running already and silently exit if yes. */
- lockfd = get_lock();
+ /* Get db lock */
+ if ((db_locked = get_lock(LOCK_EXCL, dbpath)) == -1) {
+ LOG(log_error, logtype_cnid, "main: fatal db lock error");
+ exit(1);
+ }
+ if (db_locked != LOCK_EXCL) {
+ /* Couldn't get exclusive lock, try shared lock */
+ if ((db_locked = get_lock(LOCK_SHRD, NULL)) != LOCK_SHRD) {
+ LOG(log_error, logtype_cnid, "main: fatal db lock error");
+ exit(1);
+ }
+ }
set_signal();
if (NULL == (dbd = dbif_init(dbpath, "cnid2.db")))
exit(2);
- if (dbif_env_open(dbd, dbp, DBOPTIONS) < 0)
+ /* Only recover if we got the lock */
+ if (dbif_env_open(dbd,
+ dbp,
+ (db_locked == LOCK_EXCL) ? DBOPTIONS | DB_RECOVER : DBOPTIONS) < 0)
exit(2); /* FIXME: same exit code as failure for dbif_open() */
LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment");
}
LOG(log_debug, logtype_cnid, "Finished opening BerkeleyDB databases");
+ /* Downgrade db lock */
+ if (db_locked == LOCK_EXCL) {
+ if (get_lock(LOCK_UNLOCK, NULL) != 0) {
+ dbif_close(dbd);
+ exit(2);
+ }
+ if (get_lock(LOCK_SHRD, NULL) != LOCK_SHRD) {
+ dbif_close(dbd);
+ exit(2);
+ }
+ }
+
+
if (comm_init(dbp, ctrlfd, clntfd) < 0) {
dbif_close(dbd);
exit(3);
if (dbif_env_remove(dbpath) < 0)
err++;
- free_lock(lockfd);
-
if (err)
exit(4);
else if (exit_sig)
#ifndef _ATALK_DSI_H
#define _ATALK_DSI_H
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/time.h>
+#include <sys/socket.h>
#include <signal.h>
+#include <arpa/inet.h>
#include <netinet/in.h>
#include <atalk/afp.h>
#include <atalk/server_child.h>
-#include <netatalk/endian.h>
-
-#ifdef __OpenBSD__
-#include <sys/socket.h>
-#endif
/* What a DSI packet looks like:
0 32
#define DSI_CMDSIZ 8192
#define DSI_DATASIZ 8192
+
/* child and parent processes might interpret a couple of these
* differently. */
typedef struct DSI {
#endif
#ifdef USE_ZEROCONF
+ char *bonjourname; /* server name as UTF8 maxlen MAXINSTANCENAMELEN */
int zeroconf_registered;
#endif
- /* buffer for OSX deadlock */
+ /* DSI readahead buffer used for buffered reads in dsi_peek */
+ size_t dsireadbuf; /* size of the DSI readahead buffer used in dsi_peek() */
char *buffer;
char *start;
char *eof;
char *end;
- int maxsize;
-
} DSI;
/* DSI flags */
#define DSI_NOREPLY (1 << 6) /* in dsi_write we generate our own replies */
#define DSI_RECONSOCKET (1 << 7) /* we have a new socket from primary reconnect */
#define DSI_RECONINPROG (1 << 8) /* used in the new session in reconnect */
+ #define DSI_AFP_LOGGED_OUT (1 << 9) /* client called afp_logout, quit on next EOF from socket */
/* basic initialization: dsi_init.c */
extern DSI *dsi_init (const dsi_proto /*protocol*/,
#ifndef _ATALK_UNICODE_H
#define _ATALK_UNICODE_H 1
-#include <sys/cdefs.h>
-#include <netatalk/endian.h>
#include <errno.h>
#include <sys/param.h>
extern struct charset_functions *find_charset_functions (const char *);
extern int atalk_register_charset (struct charset_functions *);
+ /* from utf16_case.c */
+ extern ucs2_t toupper_w (ucs2_t);
+ extern u_int32_t toupper_sp (u_int32_t);
+ extern ucs2_t tolower_w (ucs2_t);
+ extern u_int32_t tolower_sp (u_int32_t);
+
/* from util_unistr.c */
- extern ucs2_t toupper_w (ucs2_t);
- extern ucs2_t tolower_w (ucs2_t);
extern int strupper_w (ucs2_t *);
extern int strlower_w (ucs2_t *);
extern int islower_w (ucs2_t);
#ifndef _ATALK_UTIL_H
#define _ATALK_UTIL_H 1
-#include <sys/cdefs.h>
#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
+#include <sys/socket.h>
#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
#include <poll.h>
-#include <netatalk/at.h>
+
#include <atalk/unicode.h>
+ #include <atalk/bstrlib.h>
/* exit error codes */
#define EXITERR_CLNT 1 /* client related error */
#define AFP_ASSERT(b)
#endif /* NDEBUG */
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
#define STRCMP(a,b,c) (strcmp(a,c) b 0)
+#define ZERO_STRUCT(a) memset(&(a), 0, sizeof(a))
+#define ZERO_STRUCTP(a) memset((a), 0, sizeof(a))
#ifdef WITH_SENDFILE
extern ssize_t sys_sendfile (int __out_fd, int __in_fd, off_t *__offset,size_t __count);
#define diatolower(x) _dialowermap[(unsigned char) (x)]
#define diatoupper(x) _diacasemap[(unsigned char) (x)]
-extern int atalk_aton (char *, struct at_addr *);
extern void bprint (char *, int);
extern int strdiacasecmp (const char *, const char *);
extern int strndiacasecmp (const char *, const char *, size_t);
extern void netatalk_panic(const char *why);
#define server_unlock(x) (unlink(x))
-/* strlcpy and strlcat are used by pam modules */
-#ifndef UAM_MODULE_EXPORT
-#define UAM_MODULE_EXPORT
-#endif
-
-#ifndef HAVE_STRLCPY
-UAM_MODULE_EXPORT size_t strlcpy (char *, const char *, size_t);
-#endif
-
-#ifndef HAVE_STRLCAT
-UAM_MODULE_EXPORT size_t strlcat (char *, const char *, size_t);
-#endif
-
#ifndef HAVE_DLFCN_H
extern void *mod_open (const char *);
extern void *mod_symbol (void *, const char *);
* unix.c
*****************************************************************/
+extern const char *abspath(const char *name);
extern const char *getcwdpath(void);
extern char *stripped_slashes_basename(char *p);
extern int lchdir(const char *dir);
extern void randombytes(void *buf, int n);
#endif /* _ATALK_UTIL_H */
+
+ /******************************************************************
+ * cnid.c
+ *****************************************************************/
+
+ extern bstring rel_path_in_vol(const char *path, const char *volpath);
/* sorry, no ACLs for symlinks */
return 0;
- if ( ! (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))) {
+ if ( ! ((S_ISREG(st.st_mode)) || (S_ISDIR(st.st_mode)))) {
LOG(log_warning, logtype_afpd, "get_nfsv4_acl(\"%s/%s\"): special", getcwdpath(), name);
return 0;
}
{
int ret = -1;
int noaces, nnaces;
- ace_t *oacl = NULL, *nacl = NULL, *cacl;
+ ace_t *oacl = NULL, *nacl = NULL, *cacl = NULL;
LOG(log_debug, logtype_afpd, "nfsv4_chmod(\"%s/%s\", %04o)",
getcwdpath(), name, mode);
#ifdef CNID_BACKEND_DBD
#include <stdlib.h>
-#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
-#endif /* HAVE_SYS_STAT_H */
-#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
-#endif /* HAVE_SYS_UIO_H */
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
#include <sys/time.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <errno.h>
#include <netdb.h>
#include <time.h>
+#include <arpa/inet.h>
-#include <netatalk/endian.h>
#include <atalk/logger.h>
#include <atalk/adouble.h>
#include <atalk/cnid.h>
}
if (setnonblock(sock, 1) != 0) {
- LOG(log_error, logtype_cnid, "getfd: setnonblock: %s", strerror(err));
+ LOG(log_error, logtype_cnid, "getfd: setnonblock: %s", strerror(errno));
close(sock);
sock = -1;
return -1;
vecs = 1;
if (rqst->namelen) {
- iov[1].iov_base = rqst->name;
+ iov[1].iov_base = (char *)rqst->name;
iov[1].iov_len = rqst->namelen;
towrite += rqst->namelen;
vecs++;
/* ---------------------- */
cnid_t cnid_dbd_add(struct _cnid_db *cdb, const struct stat *st,
- const cnid_t did, char *name, const size_t len,
- cnid_t hint)
+ cnid_t did, const char *name, size_t len, cnid_t hint)
{
CNID_private *db;
struct cnid_dbd_rqst rqst;
}
/* ---------------------- */
-cnid_t cnid_dbd_get(struct _cnid_db *cdb, const cnid_t did, char *name, const size_t len)
+cnid_t cnid_dbd_get(struct _cnid_db *cdb, cnid_t did, const char *name, size_t len)
{
CNID_private *db;
struct cnid_dbd_rqst rqst;
}
/* ---------------------- */
-cnid_t cnid_dbd_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
- char *name, const size_t len)
+cnid_t cnid_dbd_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did,
+ const char *name, size_t len)
{
CNID_private *db;
struct cnid_dbd_rqst rqst;
}
/* ---------------------- */
-int cnid_dbd_find(struct _cnid_db *cdb, char *name, size_t namelen, void *buffer, size_t buflen)
+int cnid_dbd_find(struct _cnid_db *cdb, const char *name, size_t namelen, void *buffer, size_t buflen)
{
CNID_private *db;
struct cnid_dbd_rqst rqst;
}
/* ---------------------- */
-int cnid_dbd_update(struct _cnid_db *cdb, const cnid_t id, const struct stat *st,
- const cnid_t did, char *name, const size_t len)
+int cnid_dbd_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
+ cnid_t did, const char *name, size_t len)
{
CNID_private *db;
struct cnid_dbd_rqst rqst;
/* ---------------------- */
cnid_t cnid_dbd_rebuild_add(struct _cnid_db *cdb, const struct stat *st,
- const cnid_t did, char *name, const size_t len,
- cnid_t hint)
+ cnid_t did, const char *name, size_t len, cnid_t hint)
{
CNID_private *db;
struct cnid_dbd_rqst rqst;
#include <stdio.h>
#include <stdlib.h>
+#include <arpa/inet.h>
+
#include <atalk/dsi.h>
-#include <netatalk/endian.h>
void dsi_close(DSI *dsi)
{
/* server generated. need to set all the fields. */
- if (!(dsi->flags & DSI_SLEEPING)) {
+ if (!(dsi->flags & DSI_SLEEPING) && !(dsi->flags & DSI_DISCONNECTED)) {
dsi->header.dsi_flags = DSIFL_REQUEST;
dsi->header.dsi_command = DSIFUNC_CLOSE;
dsi->header.dsi_requestID = htons(dsi_serverID(dsi));
#include <sys/types.h>
#include <sys/socket.h>
-/* POSIX.1 sys/wait.h check */
#include <sys/types.h>
-#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
-#endif /* HAVE_SYS_WAIT_H */
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
-#endif /* ! WEXITSTATUS */
-#ifndef WIFEXITED
-#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
-#endif /* ! WIFEXITED */
-
#include <sys/time.h>
#include <atalk/logger.h>
#include <atalk/util.h>
afp_child_t *child;
if (socketpair(PF_UNIX, SOCK_STREAM, 0, ipc_fds) < 0) {
- LOG(log_error, logtype_afpd, "dsi_getsess: %s", strerror(errno));
+ LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno));
exit( EXITERR_CLNT );
}
if (setnonblock(ipc_fds[0], 1) != 0 || setnonblock(ipc_fds[1], 1) != 0) {
- LOG(log_error, logtype_afpd, "dsi_getsess: setnonblock: %s", strerror(errno));
+ LOG(log_error, logtype_dsi, "dsi_getsess: setnonblock: %s", strerror(errno));
exit(EXITERR_CLNT);
}
/*
- * $Id: dsi_stream.c,v 1.20 2009-10-26 12:35:56 franklahm Exp $
- *
* Copyright (c) 1998 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
*
#include "config.h"
#endif /* HAVE_CONFIG_H */
- #define USE_WRITEV
-
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
-
- #ifdef USE_WRITEV
#include <sys/uio.h>
- #endif
#include <atalk/logger.h>
#include <atalk/dsi.h>
-#include <netatalk/endian.h>
#include <atalk/util.h>
#define min(a,b) ((a) < (b) ? (a) : (b))
#define MSG_DONTWAIT 0x40
#endif
- /* -------------------------
- * we don't use a circular buffer.
- */
- static void dsi_init_buffer(DSI *dsi)
- {
- if (!dsi->buffer) {
- /* XXX config options */
- dsi->maxsize = 6 * dsi->server_quantum;
- if (!dsi->maxsize)
- dsi->maxsize = 6 * DSI_SERVQUANT_DEF;
- dsi->buffer = malloc(dsi->maxsize);
- if (!dsi->buffer) {
- return;
- }
- dsi->start = dsi->buffer;
- dsi->eof = dsi->buffer;
- dsi->end = dsi->buffer + dsi->maxsize;
- }
- }
-
- /* ----------------------
- afpd is sleeping too much while trying to send something.
- May be there's no reader or the reader is also sleeping in write,
- look if there's some data for us to read, hopefully it will wake up
- the reader so we can write again.
- */
+ /*
+ * afpd is sleeping too much while trying to send something.
+ * May be there's no reader or the reader is also sleeping in write,
+ * look if there's some data for us to read, hopefully it will wake up
+ * the reader so we can write again.
+ *
+ * @returns 0 when is possible to send again, -1 on error
+ */
static int dsi_peek(DSI *dsi)
{
+ static int warned = 0;
fd_set readfds, writefds;
int len;
int maxfd;
int ret;
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_SET( dsi->socket, &readfds);
- FD_SET( dsi->socket, &writefds);
- maxfd = dsi->socket +1;
+ LOG(log_debug, logtype_dsi, "dsi_peek");
+
+ maxfd = dsi->socket + 1;
while (1) {
- FD_SET( dsi->socket, &readfds);
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+
+ if (dsi->eof < dsi->end) {
+ /* space in read buffer */
+ FD_SET( dsi->socket, &readfds);
+ } else {
+ if (!warned) {
+ warned = 1;
+ LOG(log_note, logtype_dsi, "dsi_peek: readahead buffer is full, possibly increase -dsireadbuf option");
+ LOG(log_note, logtype_dsi, "dsi_peek: dsireadbuf: %d, DSI quantum: %d, effective buffer size: %d",
+ dsi->dsireadbuf,
+ dsi->server_quantum ? dsi->server_quantum : DSI_SERVQUANT_DEF,
+ dsi->end - dsi->buffer);
+ }
+ }
+
FD_SET( dsi->socket, &writefds);
/* No timeout: if there's nothing to read nor nothing to write,
/* we might have been interrupted by out timer, so restart select */
continue;
/* give up */
+ LOG(log_error, logtype_dsi, "dsi_peek: unexpected select return: %d %s",
+ ret, ret < 0 ? strerror(errno) : "");
+ return -1;
+ }
+
+ if (FD_ISSET(dsi->socket, &writefds)) {
+ /* we can write again */
+ LOG(log_debug, logtype_dsi, "dsi_peek: can write again");
break;
}
/* Check if there's sth to read, hopefully reading that will unblock the client */
if (FD_ISSET(dsi->socket, &readfds)) {
- dsi_init_buffer(dsi);
- len = dsi->end - dsi->eof;
-
- if (len <= 0) {
- /* ouch, our buffer is full ! fall back to blocking IO
- * could block and disconnect but it's better than a cpu hog */
- break;
+ len = dsi->end - dsi->eof; /* it's ensured above that there's space */
+
+ if ((len = read(dsi->socket, dsi->eof, len)) <= 0) {
+ if (len == 0) {
+ LOG(log_error, logtype_dsi, "dsi_peek: EOF");
+ return -1;
+ }
+ LOG(log_error, logtype_dsi, "dsi_peek: read: %s", strerror(errno));
+ if (errno == EAGAIN)
+ continue;
+ return -1;
}
+ LOG(log_debug, logtype_dsi, "dsi_peek: read %d bytes", len);
- len = read(dsi->socket, dsi->eof, len);
- if (len <= 0)
- break;
dsi->eof += len;
}
-
- if (FD_ISSET(dsi->socket, &writefds))
- /* we can write again at last */
- break;
}
return 0;
LOG(log_maxdebug, logtype_dsi, "dsi_stream_write: sending %u bytes", length);
- /* non blocking mode */
- if (setnonblock(dsi->socket, 1) < 0) {
- LOG(log_error, logtype_dsi, "dsi_stream_write: setnonblock: %s", strerror(errno));
- return -1;
- }
-
while (written < length) {
len = send(dsi->socket, (u_int8_t *) data + written, length - written, flags);
if (len >= 0) {
continue;
if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ LOG(log_debug, logtype_dsi, "dsi_stream_write: send: %s", strerror(errno));
+
if (mode == DSI_NOWAIT && written == 0) {
/* DSI_NOWAIT is used by attention give up in this case. */
written = -1;
dsi->write_count += written;
exit:
- if (setnonblock(dsi->socket, 0) < 0) {
- LOG(log_error, logtype_dsi, "dsi_stream_write: setnonblock: %s", strerror(errno));
- written = -1;
- }
-
dsi->in_write--;
return written;
}
size_t written;
ssize_t len;
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file: sending %u bytes", length);
+
dsi->in_write++;
written = 0;
- /* non blocking mode */
- if (setnonblock(dsi->socket, 1) < 0) {
- LOG(log_error, logtype_dsi, "dsi_stream_read_file: setnonblock: %s", strerror(errno));
- return -1;
- }
-
while (written < length) {
len = sys_sendfile(dsi->socket, fromfd, &offset, length - written);
}
continue;
}
- LOG(log_error, logtype_dsi, "dsi_stream_write: %s", strerror(errno));
+ LOG(log_error, logtype_dsi, "dsi_stream_read_file: %s", strerror(errno));
break;
}
else if (!len) {
written += len;
}
- if (setnonblock(dsi->socket, 0) < 0) {
- LOG(log_error, logtype_dsi, "dsi_stream_read_file: setnonblock: %s", strerror(errno));
- return -1;
- }
-
dsi->write_count += written;
dsi->in_write--;
return written;
static size_t from_buf(DSI *dsi, u_int8_t *buf, size_t count)
{
size_t nbe = 0;
-
- if (dsi->start) {
- nbe = dsi->eof - dsi->start;
- if (nbe > 0) {
- nbe = min((size_t)nbe, count);
- memcpy(buf, dsi->start, nbe);
- dsi->start += nbe;
+ if (dsi->buffer == NULL)
+ /* afpd master has no DSI buffering */
+ return 0;
- if (dsi->eof == dsi->start)
- dsi->start = dsi->eof = dsi->buffer;
+ LOG(log_maxdebug, logtype_dsi, "from_buf: %u bytes", count);
+
+ nbe = dsi->eof - dsi->start;
- }
+ if (nbe > 0) {
+ nbe = min((size_t)nbe, count);
+ memcpy(buf, dsi->start, nbe);
+ dsi->start += nbe;
+
+ if (dsi->eof == dsi->start)
+ dsi->start = dsi->eof = dsi->buffer;
}
+
+ LOG(log_debug, logtype_dsi, "from_buf(read: %u, unread:%u , space left: %u): returning %u",
+ dsi->start - dsi->buffer, dsi->eof - dsi->start, dsi->end - dsi->eof, nbe);
+
return nbe;
}
*/
static ssize_t buf_read(DSI *dsi, u_int8_t *buf, size_t count)
{
- ssize_t nbe;
-
+ ssize_t len;
+
+ LOG(log_maxdebug, logtype_dsi, "buf_read(%u bytes)", count);
+
if (!count)
return 0;
- nbe = from_buf(dsi, buf, count); /* 1. */
- if (nbe)
- return nbe; /* 2. */
+ len = from_buf(dsi, buf, count); /* 1. */
+ if (len)
+ return len; /* 2. */
- return read(dsi->socket, buf, count); /* 3. */
+ len = readt(dsi->socket, buf, count, 0, 1); /* 3. */
+
+ LOG(log_maxdebug, logtype_dsi, "buf_read(%u bytes): got: %d", count, len);
+
+ return len;
}
/*
* Essentially a loop around buf_read() to ensure "length" bytes are read
* from dsi->buffer and/or the socket.
+ *
+ * @returns length on success, some value smaller then length indicates an error
*/
size_t dsi_stream_read(DSI *dsi, void *data, const size_t length)
{
size_t stored;
ssize_t len;
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_read(%u bytes)", length);
+
stored = 0;
while (stored < length) {
- len = buf_read(dsi, (u_int8_t *) data + stored, length - stored);
- if (len == -1 && errno == EINTR) {
- continue;
- } else if (len > 0) {
- stored += len;
- } else { /* eof or error */
- /* don't log EOF error if it's just after connect (OSX 10.3 probe) */
- if (len || stored || dsi->read_count) {
- if (! (dsi->flags & DSI_DISCONNECTED))
- LOG(log_error, logtype_dsi, "dsi_stream_read(fd: %i): len:%d, %s",
- dsi->socket, len, (len < 0) ? strerror(errno) : "unexpected EOF");
+ len = buf_read(dsi, (u_int8_t *) data + stored, length - stored);
+ if (len == -1 && (errno == EINTR || errno == EAGAIN)) {
+ LOG(log_debug, logtype_dsi, "dsi_stream_read: select read loop");
+ continue;
+ } else if (len > 0) {
+ stored += len;
+ } else { /* eof or error */
+ /* don't log EOF error if it's just after connect (OSX 10.3 probe) */
+ if (len || stored || dsi->read_count) {
+ if (! (dsi->flags & DSI_DISCONNECTED)) {
+ LOG(log_error, logtype_dsi, "dsi_stream_read: len:%d, %s",
+ len, (len < 0) ? strerror(errno) : "unexpected EOF");
+ }
+ return 0;
+ }
+ break;
}
- break;
- }
}
dsi->read_count += stored;
+
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_read(%u bytes): got: %u", length, stored);
return stored;
}
{
size_t len;
size_t buflen;
+
+ LOG(log_maxdebug, logtype_dsi, "dsi_buffered_stream_read: %u bytes", length);
- dsi_init_buffer(dsi);
len = from_buf(dsi, data, length); /* read from buffer dsi->buffer */
dsi->read_count += len;
if (len == length) { /* got enough bytes from there ? */
int dsi_stream_send(DSI *dsi, void *buf, size_t length)
{
char block[DSI_BLOCKSIZ];
- #ifdef USE_WRITEV
struct iovec iov[2];
size_t towrite;
ssize_t len;
- #endif /* USE_WRITEV */
+
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_send: %u bytes",
+ length ? length : sizeof(block));
block[0] = dsi->header.dsi_flags;
block[1] = dsi->header.dsi_command;
/* block signals */
block_sig(dsi);
- #ifdef USE_WRITEV
iov[0].iov_base = block;
iov[0].iov_len = sizeof(block);
iov[1].iov_base = buf;
towrite = sizeof(block) + length;
dsi->write_count += towrite;
while (towrite > 0) {
- if (((len = writev(dsi->socket, iov, 2)) == -1 && errno == EINTR) ||
- !len)
- continue;
+ if (((len = writev(dsi->socket, iov, 2)) == -1 && errno == EINTR) || (len == 0))
+ continue;
- if ((size_t)len == towrite) /* wrote everything out */
- break;
- else if (len < 0) { /* error */
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- if (!dsi_peek(dsi)) {
- continue;
+ if ((size_t)len == towrite) /* wrote everything out */
+ break;
+ else if (len < 0) { /* error */
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ if (!dsi_peek(dsi)) {
+ continue;
+ }
}
+ LOG(log_error, logtype_dsi, "dsi_stream_send: %s", strerror(errno));
+ unblock_sig(dsi);
+ return 0;
}
- LOG(log_error, logtype_dsi, "dsi_stream_send: %s", strerror(errno));
- unblock_sig(dsi);
- return 0;
- }
- towrite -= len;
- if (towrite > length) { /* skip part of header */
- iov[0].iov_base = (char *) iov[0].iov_base + len;
- iov[0].iov_len -= len;
- } else { /* skip to data */
- if (iov[0].iov_len) {
- len -= iov[0].iov_len;
- iov[0].iov_len = 0;
+ towrite -= len;
+ if (towrite > length) { /* skip part of header */
+ iov[0].iov_base = (char *) iov[0].iov_base + len;
+ iov[0].iov_len -= len;
+ } else { /* skip to data */
+ if (iov[0].iov_len) {
+ len -= iov[0].iov_len;
+ iov[0].iov_len = 0;
+ }
+ iov[1].iov_base = (char *) iov[1].iov_base + len;
+ iov[1].iov_len -= len;
}
- iov[1].iov_base = (char *) iov[1].iov_base + len;
- iov[1].iov_len -= len;
- }
}
- #else /* USE_WRITEV */
- /* write the header then data */
- if ((dsi_stream_write(dsi, block, sizeof(block), 1) != sizeof(block)) ||
- (dsi_stream_write(dsi, buf, length, 0) != length)) {
- unblock_sig(dsi);
- return 0;
- }
- #endif /* USE_WRITEV */
-
unblock_sig(dsi);
return 1;
}
{
char block[DSI_BLOCKSIZ];
+ LOG(log_maxdebug, logtype_dsi, "dsi_stream_receive: %u bytes", ilength);
+
/* read in the header */
if (dsi_buffered_stream_read(dsi, (u_int8_t *)block, sizeof(block)) != sizeof(block))
return 0;
#include <sys/stat.h>
#include <atalk/logger.h>
#include <errno.h>
-
-#include <netatalk/endian.h>
+#include <arpa/inet.h>
#include <atalk/unicode.h>
- #include "ucs2_casetable.h"
#include "precompose.h"
#include "byteorder.h"
- /*******************************************************************
- Convert a wide character to upper/lower case.
- ********************************************************************/
- ucs2_t toupper_w(ucs2_t val)
- {
- if ( val >= 0x0040 && val <= 0x007F)
- return upcase_table_1[val-0x0040];
- if ( val >= 0x00C0 && val <= 0x02BF)
- return upcase_table_2[val-0x00C0];
- if ( val >= 0x0380 && val <= 0x04FF)
- return upcase_table_3[val-0x0380];
- if ( val >= 0x0540 && val <= 0x05BF)
- return upcase_table_4[val-0x0540];
- if ( val >= 0x1E00 && val <= 0x1FFF)
- return upcase_table_5[val-0x1E00];
- if ( val >= 0x2140 && val <= 0x217F)
- return upcase_table_6[val-0x2140];
- if ( val >= 0x24C0 && val <= 0x24FF)
- return upcase_table_7[val-0x24C0];
- if ( val >= 0xFF40 && val <= 0xFF7F)
- return upcase_table_8[val-0xFF40];
-
- return (val);
- }
-
-
- ucs2_t tolower_w(ucs2_t val)
- {
- if ( val >= 0x0040 && val <= 0x007F)
- return lowcase_table_1[val-0x0040];
- if ( val >= 0x00C0 && val <= 0x023F)
- return lowcase_table_2[val-0x00C0];
- if ( val >= 0x0380 && val <= 0x057F)
- return lowcase_table_3[val-0x0380];
- if ( val >= 0x1E00 && val <= 0x1FFF)
- return lowcase_table_4[val-0x1E00];
- if ( val >= 0x2140 && val <= 0x217F)
- return lowcase_table_5[val-0x2140];
- if ( val >= 0x2480 && val <= 0x24FF)
- return lowcase_table_6[val-0x2480];
- if ( val >= 0xFF00 && val <= 0xFF3F)
- return lowcase_table_7[val-0xFF00];
-
- return (val);
- }
-
/*******************************************************************
Convert a string to lower case.
return True if any char is converted
# 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 \
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
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
#include <signal.h>
#include <errno.h>
-
-/* POSIX.1 sys/wait.h check */
#include <sys/types.h>
-#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
-#endif /* HAVE_SYS_WAIT_H */
#include <sys/time.h>
#include <atalk/logger.h>
"Session with different pid[%u]", child->pid);
}
} else {
- kill_child(child);
- LOG(log_note, logtype_default,
- "Terminated disconnected session[%u]", child->pid);
+ /* One client with multiple sessions */
+ LOG(log_debug, logtype_default,
+ "Found another session[%u] for client[%u]", child->pid, pid);
}
}
} else {
child->time = boottime;
if (child->clientid)
free(child->clientid);
- LOG(log_debug, logtype_default, "Setting client ID for %d", child->pid);
+ LOG(log_debug, logtype_default, "Setting client ID for %u", child->pid);
child->uid = uid;
child->valid = 1;
child->idlen = idlen;
/*
- $Id: ea_sys.c,v 1.8 2010-04-13 08:05:06 franklahm Exp $
Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
This program is free software; you can redistribute it and/or modify
#include <sys/stat.h>
#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 <arpa/inet.h>
#include <atalk/adouble.h>
#include <atalk/ea.h>
#include <atalk/unix.h>
#include <atalk/compat.h>
-#ifndef ENOATTR
-#define ENOATTR ENODATA
-#endif
-
-
/**********************************************************************************
* EA VFS funcs for storing EAs in nativa filesystem EAs
**********************************************************************************/
*
* Copies names of all EAs of uname as consecutive C strings into rbuf.
* Increments *rbuflen accordingly.
+ * We hide the adouble:ea extended attributes here, but we currently
+ * allow reading, writing and deleteting them.
*/
int sys_list_eas(VFS_FUNC_ARGS_EA_LIST)
{
ptr = buf;
while (ret > 0) {
len = strlen(ptr);
-
- /* Convert name to CH_UTF8_MAC and directly store in in the reply buffer */
- if ( 0 >= ( nlen = convert_string(vol->v_volcharset, CH_UTF8_MAC, ptr, len, attrnamebuf + attrbuflen, 256)) ) {
- ret = AFPERR_MISC;
- goto exit;
- }
-
- LOG(log_debug7, logtype_afpd, "sys_list_extattr(%s): attribute: %s", uname, ptr);
-
- attrbuflen += nlen + 1;
- if (attrbuflen > (ATTRNAMEBUFSIZ - 256)) {
- /* Next EA name could overflow, so bail out with error.
- FIXME: evantually malloc/memcpy/realloc whatever.
- Is it worth it ? */
- LOG(log_warning, logtype_afpd, "sys_list_extattr(%s): running out of buffer for EA names", uname);
- ret = AFPERR_MISC;
- goto exit;
+ if (NOT_NETATALK_EA(ptr)) {
+ /* Convert name to CH_UTF8_MAC and directly store in in the reply buffer */
+ if ( 0 >= ( nlen = convert_string(vol->v_volcharset, CH_UTF8_MAC, ptr, len, attrnamebuf + attrbuflen, 256)) ) {
+ ret = AFPERR_MISC;
+ goto exit;
+ }
+
+ LOG(log_debug7, logtype_afpd, "sys_list_extattr(%s): attribute: %s", uname, ptr);
+
+ attrbuflen += nlen + 1;
+ if (attrbuflen > (ATTRNAMEBUFSIZ - 256)) {
+ /* Next EA name could overflow, so bail out with error.
+ FIXME: evantually malloc/memcpy/realloc whatever.
+ Is it worth it ? */
+ LOG(log_warning, logtype_afpd, "sys_list_extattr(%s): running out of buffer for EA names", uname);
+ ret = AFPERR_MISC;
+ goto exit;
+ }
}
- ret -= len +1;
- ptr += len +1;
+ ret -= len + 1;
+ ptr += len + 1;
}
ret = AFP_OK;
switch(errno) {
case OPEN_NOFOLLOW_ERRNO:
/* its a symlink and client requested O_NOFOLLOW */
- LOG(log_debug, logtype_afpd, "sys_set_ea(%s/%s): encountered symlink with kXAttrNoFollow",
- uname, attruname);
+ LOG(log_debug, logtype_afpd, "sys_set_ea(\"%s/%s\", ea:'%s'): encountered symlink with kXAttrNoFollow",
+ getcwdpath(), uname, attruname);
return AFP_OK;
case EEXIST:
- LOG(log_debug, logtype_afpd, "sys_set_ea(%s/%s): EA already exists",
- uname, attruname);
+ LOG(log_debug, logtype_afpd, "sys_set_ea(\"%s/%s\", ea:'%s'): EA already exists",
+ getcwdpath(), uname, attruname);
return AFPERR_EXIST;
default:
- LOG(log_error, logtype_afpd, "sys_set_ea(%s/%s): error: %s", uname, attruname, strerror(errno));
+ LOG(log_error, logtype_afpd, "sys_set_ea(\"%s/%s\", ea:'%s', size: %u, flags: %s|%s|%s): %s",
+ getcwdpath(), uname, attruname, attrsize,
+ oflag & O_CREAT ? "XATTR_CREATE" : "-",
+ oflag & O_TRUNC ? "XATTR_REPLACE" : "-",
+ oflag & O_NOFOLLOW ? "O_NOFOLLOW" : "-",
+ strerror(errno));
return AFPERR_MISC;
}
}
--- /dev/null
- LOG(log_debug, logtype_default, "closedir dirp failed: %s\n",strerror(errno));
+/*
+ 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 <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <errno.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_ATTROPEN
+
+#include <dirent.h>
+#endif
+
+#ifdef HAVE_SYS_EXTATTR_H
+#include <sys/extattr.h>
+#endif
+
+#include <atalk/adouble.h>
+#include <atalk/util.h>
+#include <atalk/logger.h>
+#include <atalk/ea.h>
+#include <atalk/compat.h>
+
+/******** 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_maxdebug, logtype_default, "attropen FAILED: path: %s, name: %s, errno: %s",
- path, attrpath, 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, "openat FAILED: fd: %d, path: %s, errno: %s",
- filedes, path, 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, "solaris_write_xattr FAILED!");
++ 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_error, logtype_default, "solaris_write_xattr: %s",
++ strerror(errno));
+ return -1;
+ }
+}
+
+#endif /*HAVE_ATTROPEN*/
+
#include <atalk/logger.h>
#include <atalk/unix.h>
#include <atalk/acl.h>
+#include <atalk/compat.h>
/* -----------------------------
a dropbox is a folder where w is set but not r eg:
{
int retval = 0;
-#ifdef DROPKLUDGE
- /* Turn on the sticky bit if this is a drop box, also turn off the setgid bit */
- if ((dropbox & AFPVOL_DROPBOX)) {
- int uid;
-
- if ( ( (mode & S_IWOTH) && !(mode & S_IROTH)) ||
- ( (mode & S_IWGRP) && !(mode & S_IRGRP)) )
- {
- uid=geteuid();
- if ( seteuid(0) < 0) {
- LOG(log_error, logtype_afpd, "stickydirmode: unable to seteuid root: %s", strerror(errno));
- }
- if ( (retval=chmod( name, ( (DIRBITS | mode | S_ISVTX) & ~v_umask) )) < 0) {
- LOG(log_error, logtype_afpd, "stickydirmode: chmod \"%s\": %s", fullpathname(name), strerror(errno) );
- } else {
- LOG(log_debug, logtype_afpd, "stickydirmode: chmod \"%s\": %s", fullpathname(name), strerror(retval) );
- }
- seteuid(uid);
- return retval;
- }
- }
-#endif /* DROPKLUDGE */
-
/*
* Ignore EPERM errors: We may be dealing with a directory that is
* group writable, in which case chmod will fail.
/*
* @brief system rmdir with afp error code.
*
- * Supports *at semantics (cf openat) if HAVE_RENAMEAT. Pass dirfd=-1 to ignore this.
+ * Supports *at semantics (cf openat) if HAVE_ATFUNCS. Pass dirfd=-1 to ignore this.
*/
int netatalk_rmdir_all_errors(int dirfd, const char *name)
{
int err;
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
if (dirfd == -1)
- dirfd = ATFD_CWD;
+ dirfd = AT_FDCWD;
err = unlinkat(dirfd, name, AT_REMOVEDIR);
#else
err = rmdir(name);
/*
* @brief System rmdir with afp error code, but ENOENT is not an error.
*
- * Supports *at semantics (cf openat) if HAVE_RENAMEAT. Pass dirfd=-1 to ignore this.
+ * Supports *at semantics (cf openat) if HAVE_ATFUNCS. Pass dirfd=-1 to ignore this.
*/
int netatalk_rmdir(int dirfd, const char *name)
{
**************************************************************************/
/*
- * Supports *at semantics if HAVE_RENAMEAT, pass dirfd=-1 to ignore this
+ * Supports *at semantics if HAVE_ATFUNCS, pass dirfd=-1 to ignore this
*/
int copy_file(int dirfd, const char *src, const char *dst, mode_t mode)
{
size_t buflen;
char filebuf[8192];
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
if (dirfd == -1)
- dirfd = ATFD_CWD;
+ dirfd = AT_FDCWD;
sfd = openat(dirfd, src, O_RDONLY);
#else
sfd = open(src, O_RDONLY);
*/
int netatalk_unlinkat(int dirfd, const char *name)
{
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
if (dirfd == -1)
dirfd = AT_FDCWD;
/*
* @brief This is equivalent of unix rename()
*
- * unix_rename mulitplexes rename and renameat. If we dont HAVE_RENAMEAT, sfd and dfd
+ * unix_rename mulitplexes rename and renameat. If we dont HAVE_ATFUNCS, sfd and dfd
* are ignored.
*
- * @param sfd (r) if we HAVE_RENAMEAT, -1 gives AT_FDCWD
+ * @param sfd (r) if we HAVE_ATFUNCS, -1 gives AT_FDCWD
* @param oldpath (r) guess what
* @param dfd (r) same as sfd
* @param newpath (r) guess what
*/
int unix_rename(int sfd, const char *oldpath, int dfd, const char *newpath)
{
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
if (sfd == -1)
sfd = AT_FDCWD;
if (dfd == -1)
#else
if (rename(oldpath, newpath) < 0)
return -1;
- #endif /* HAVE_RENAMEAT */
+ #endif /* HAVE_ATFUNCS */
return 0;
}
/*
* @brief stat/fsstatat multiplexer
*
- * statat mulitplexes stat and fstatat. If we dont HAVE_RENAMEAT, dirfd is ignored.
+ * statat mulitplexes stat and fstatat. If we dont HAVE_ATFUNCS, dirfd is ignored.
*
- * @param dirfd (r) Only used if HAVE_RENAMEAT, ignored else, -1 gives AT_FDCWD
+ * @param dirfd (r) Only used if HAVE_ATFUNCS, ignored else, -1 gives AT_FDCWD
* @param path (r) pathname
* @param st (rw) pointer to struct stat
*/
int statat(int dirfd, const char *path, struct stat *st)
{
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
if (dirfd == -1)
dirfd = AT_FDCWD;
return (fstatat(dirfd, path, st, 0));
/*
* @brief lstat/fsstatat multiplexer
*
- * lstatat mulitplexes lstat and fstatat. If we dont HAVE_RENAMEAT, dirfd is ignored.
+ * lstatat mulitplexes lstat and fstatat. If we dont HAVE_ATFUNCS, dirfd is ignored.
*
- * @param dirfd (r) Only used if HAVE_RENAMEAT, ignored else, -1 gives AT_FDCWD
+ * @param dirfd (r) Only used if HAVE_ATFUNCS, ignored else, -1 gives AT_FDCWD
* @param path (r) pathname
* @param st (rw) pointer to struct stat
*/
int lstatat(int dirfd, const char *path, struct stat *st)
{
- #ifdef HAVE_RENAMEAT
+ #ifdef HAVE_ATFUNCS
if (dirfd == -1)
dirfd = AT_FDCWD;
return (fstatat(dirfd, path, st, AT_SYMLINK_NOFOLLOW));
-dnl $Id: db3-check.m4,v 1.23 2010-04-12 14:28:48 franklahm Exp $
dnl Autoconf macros to check for the Berkeley DB library
dnl -- check header for minimum version and return version in
])
dnl -- This is called from configure
-AC_DEFUN([AC_PATH_BDB],[
+AC_DEFUN([AC_NETATALK_PATH_BDB],[
+if test "x$bdb_required" = "xyes"; then
trybdbdir=""
dobdbsearch=yes
bdb_search_dirs="/usr/local /usr"
- search_subdirs="/ /db5 /db5.0 /db50 /db4.8 /db48 /db4.7 /db47 /db4.6 /db46 /db4"
+ search_subdirs="/ /db5 /db5.1 /db51 /db5.0 /db50 /db4.8 /db48 /db4.7 /db47 /db4.6 /db46 /db4"
bdbfound=no
savedcflags="$CFLAGS"
ifelse([$1], , :, [$1])
else
ifelse([$2], , :, [$2])
+ AC_MSG_ERROR([Berkeley DB library required but not found!])
fi
CFLAGS_REMOVE_USR_INCLUDE(BDB_CFLAGS)
AC_SUBST(BDB_LIBS)
AC_SUBST(BDB_BIN)
AC_SUBST(BDB_PATH)
+fi
])
-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 \
dbd.1 \
- hqx2bin.1 \
- macbinary.1 \
- megatron.1 \
- netatalk-config.1 \
- single2bin.1 \
- unbin.1 \
- unhex.1 \
- unsingle.1
-ATALK_MANS = aecho.1 \
- getzones.1 \
- nbp.1 \
- nbplkup.1 \
- nbprgstr.1 \
- nbpunrgstr.1 \
- pap.1 \
- papstatus.1 \
- psorder.1
-
-if USE_APPLETALK
-NONGENERATED_MANS += $(ATALK_MANS)
-endif
+ netatalk-config.1
man_MANS = $(GENERATED_MANS) $(NONGENERATED_MANS)
CLEANFILES = $(GENERATED_MANS)
afpd.conf.5 \
netatalk.conf.5 \
afp_ldap.conf.5 \
- afp_signature.conf.5
+ afp_signature.conf.5 \
+ afp_voluuid.conf.5
TEMPLATE_FILES = AppleVolumes.default.5.tmpl \
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)
CLEANFILES = $(GENERATED_MANS)
-EXTRA_DIST = $(TEMPLATE_FILES) $(NONGENERATED_MANS) $(ATALK_MANS)
+EXTRA_DIST = $(TEMPLATE_FILES) $(NONGENERATED_MANS)