]> arthur.barton.de Git - netatalk.git/commitdiff
Merge master
authorFrank Lahm <franklahm@googlemail.com>
Mon, 28 Nov 2011 15:31:58 +0000 (16:31 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Mon, 28 Nov 2011 15:31:58 +0000 (16:31 +0100)
98 files changed:
NEWS
bin/ad/ad.c
bin/ad/ad.h
bin/afppasswd/afppasswd.c
bin/megatron/megatron.c
bin/misc/logger_test.c
config/afpd.conf.tmpl
config/netatalk.conf
configure.ac [new file with mode: 0644]
configure.in [deleted file]
contrib/misc/Makefile.am [new file with mode: 0644]
contrib/misc/cnid.lua [new file with mode: 0644]
contrib/misc/make-casetable.pl [deleted file]
contrib/misc/make-precompose.h.pl [deleted file]
contrib/shell_utils/.gitignore
contrib/shell_utils/Makefile.am
contrib/shell_utils/afpd-mtab.pl.in [deleted file]
contrib/shell_utils/make-casetable.pl [new file with mode: 0755]
contrib/shell_utils/make-precompose.h.pl [new file with mode: 0755]
contrib/wireshark/cnid.lua [deleted file]
distrib/Makefile.am
distrib/initscripts/.gitignore
distrib/initscripts/rc.atalk.debian.tmpl
distrib/initscripts/rc.atalk.redhat-systemd.tmpl
distrib/initscripts/service.atalk.redhat-systemd.tmpl
distrib/systemd/Makefile.am [new file with mode: 0644]
distrib/systemd/README [new file with mode: 0644]
distrib/systemd/netatalk-afpd.service [new file with mode: 0644]
distrib/systemd/netatalk-cnid_metad.service [new file with mode: 0644]
etc/afpd/acls.c
etc/afpd/acls.h
etc/afpd/afp_dsi.c
etc/afpd/afp_options.c
etc/afpd/afs.c
etc/afpd/catsearch.c
etc/afpd/dircache.c
etc/afpd/directory.c
etc/afpd/fce_api.c
etc/afpd/fce_api_internal.h
etc/afpd/fce_util.c
etc/afpd/file.c
etc/afpd/fork.c
etc/afpd/main.c
etc/afpd/unix.c
etc/afpd/unix.h
etc/afpd/volume.c
etc/cnid_dbd/cmd_dbd_scanvol.c
etc/cnid_dbd/comm.c
etc/cnid_dbd/dbd_rebuild_add.c
etc/cnid_dbd/dbd_resolve.c
etc/uams/uams_dhx2_pam.c
etc/uams/uams_dhx2_passwd.c
etc/uams/uams_dhx_passwd.c
etc/uams/uams_passwd.c
etc/uams/uams_pgp.c
include/atalk/Makefile.am
include/atalk/acl.h
include/atalk/adouble.h
include/atalk/boolean.h [deleted file]
include/atalk/dsi.h
include/atalk/errchk.h
include/atalk/globals.h
include/atalk/ldapconfig.h
include/atalk/logger.h
include/atalk/paths.h
include/atalk/standards.h [new file with mode: 0644]
include/atalk/unix.h
include/atalk/util.h
include/atalk/volume.h
include/atalk/zip.h
libatalk/acl/unix.c
libatalk/adouble/ad_sendfile.c
libatalk/cnid/cnid.c
libatalk/dsi/dsi_cmdreply.c
libatalk/dsi/dsi_read.c
libatalk/dsi/dsi_stream.c
libatalk/unicode/precompose.h
libatalk/unicode/utf16_case.c
libatalk/unicode/utf16_casetable.h
libatalk/util/logger.c
libatalk/util/socket.c
libatalk/util/unix.c
libatalk/util/volinfo.c
libatalk/vfs/acl.c
libatalk/vfs/ea_ad.c
libatalk/vfs/unix.c
libatalk/vfs/vfs.c
macros/gssapi-check.m4
macros/iconv.m4
macros/netatalk.m4
macros/summary.m4
man/man1/ad.1
man/man1/apple_dump.1
man/man1/asip-status.pl.1.tmpl
man/man1/macusers.1 [new file with mode: 0644]
man/man1/megatron.1
man/man5/AppleVolumes.default.5.tmpl
man/man5/afpd.conf.5.tmpl

diff --git a/NEWS b/NEWS
index b6b387c42b6f7390b479dfcd7694e461df8671a0..a56a194658f5e0ef699b11a08ab78ea0283f7540 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,34 @@
+Changes in 2.2.2
+================
+
+* NEW: afpd: New option "adminauthuser". Specifying eg "-adminauthuser root"
+       whenever a normal user login fails, afpd tries to authenticate as
+       the specified adminauthuser. If this succeeds, a normal session is
+       created for the original connecting user. Said differently: if you
+       know the password of adminauthuser, you can authenticate as any other
+       user.
+* NEW: experimental systemd service files in distrib/systemd/
+* UPD: afpd: Enhanced POSIX ACL mapping semantics, from Laura Mueller
+* UPD: afpd: Reset options every time a :DEFAULT: line is found in a
+       AppleVolumes file
+* UPD: afpd: Convert passwords from legacy encoding (wire format) to host
+       encoding, NetAFP Bug ID #14
+* UPD: afpd: Don't set ATTRBIT_SHARED flag for directories
+* UPD: afpd: Use sendfile() on Solaris and FreeBSD for sending data
+* UPD: afpd: Faster volume used size calculation for "volsizelimit" option,
+       cf man AppleVolume.default for details
+* FIX: afpd: ACL access checking
+* FIX: afpd: Fix an error when duplicating files that lacked an AppleDouble
+       file which lead to a possible Finder crash
+* FIX: afpd: Read-only filesystems lead to afpd processes running as root
+* FIX: afpd: Fix for filesystem without NFSv4 ACL support on Solaris
+* FIX: afpd: Fix catsearch bug, NetAFP Bug ID #12
+* FIX: afpd: Fix dircache bug, NetAFP Bug ID #13
+* FIX: dbd: Better checking for duplicated or bogus CNIDs from AppleDouble
+       files
+* FIX: Fix compilation error when AppleTalk support is disabled
+* FIX: Portability fixes
+
 Changes in 2.2.1
 ================
 
@@ -34,6 +65,8 @@ Changes in 2.2.1
        if DARWIN_ACE_ADD_SUBDIRECTORY is set
 * FIX: afpd: afpd crashed when it failed to register with Avahi because eg
        user service registration is disabled in the Avahi config
+* FIX: dbd: function checking and removing malformed ad:ea header files failed
+       to chdir back to the original working directory
 * FIX: cnid_dbd: increase BerkeleyDB locks and lockobjs
 * FIX: cnid_dbd: implement -d option, deletes CNID db
 * FIX: dbd: better detection of local (or SMB/NFS) modifications on AFP volumes
index 71a0f7449d36927e43deb7a63bcfc4d4813c3445..38fd62bb3890099335d3780496af36a1eaaf8004 100644 (file)
 static void usage_main(void)
 {
     printf("Usage: ad ls|cp|rm|mv|find [file|dir, ...]\n");
+    printf("       ad -v|--version\n");
+}
+
+static void show_version(void)
+{
+    printf("ad (Netatalk %s)\n", VERSION);
 }
 
 int main(int argc, char **argv)
@@ -57,6 +63,14 @@ int main(int argc, char **argv)
         return ad_mv(argc, argv);
     else if (STRCMP(argv[1], ==, "find"))
         return ad_find(argc, argv);
+    else if (STRCMP(argv[1], ==, "-v")) {
+        show_version();
+        return 1;
+    }
+    else if  (STRCMP(argv[1], ==, "--version")) {
+        show_version();
+        return 1;
+    }
     else {
         usage_main();
         return 1;
index 360ac17369a0a4b8f7eadd79baa6850508038837..b0e8efba4a0d3aca3907eb31e23e525a4f315469 100644 (file)
@@ -1,5 +1,5 @@
 /* 
-   Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
+   Copyright (c) 2009,2011 Frank Lahm <franklahm@gmail.com>
    
    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
@@ -15,9 +15,7 @@
 #ifndef AD_H
 #define AD_H
 
-#if !defined(__FreeBSD__)
-# define _XOPEN_SOURCE 600
-#endif
+#include <atalk/standards.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
index c3e60fb5d8a5888c0a0a9c86d4d68cd78db88aff..f5778a53d03ba6b398ece79cb0d163ba44a7eb8e 100644 (file)
@@ -1,6 +1,4 @@
 /* 
- * $Id: afppasswd.c,v 1.19 2005-04-28 20:49:19 bfernhomberg Exp $
- *
  * Copyright 1999 (c) Adrian Sun (asun@u.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
  *
@@ -265,6 +263,7 @@ int main(int argc, char **argv)
   flags = ((uid = getuid()) == 0) ? OPT_ISROOT : 0;
 
   if (((flags & OPT_ISROOT) == 0) && (argc > 1)) {
+    fprintf(stderr, "afppasswd (Netatalk %s)\n", VERSION);
     fprintf(stderr, "Usage: afppasswd [-acfn] [-u minuid] [-p path] [username]\n");
     fprintf(stderr, "  -a        add a new user\n");
     fprintf(stderr, "  -c        create and initialize password file or specific user\n");
index f47a6dac7c8e9b681b57c01c22cf771e32ce5ebf..573a3dc88696c408e92a2173687cec417c978107 100644 (file)
@@ -1,7 +1,3 @@
-/*
- * $Id: megatron.c,v 1.14 2010-01-27 21:27:53 didg Exp $
- */
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
@@ -307,6 +303,14 @@ int main(int argc, char **argv)
 
     *newname = '\0';
     for ( c = 1 ; c < argc ; ++c ) {
+        if ( strcmp( argv [ c ], "--version" ) == 0 ) {
+           printf("%s (Netatalk %s megatron)\n", argv[0], VERSION);
+           return( -1 );
+       }
+        if ( strcmp( argv [ c ], "-v" ) == 0 ) {
+           printf("%s (Netatalk %s megatron)\n", argv[0], VERSION);
+           return( -1 );
+       }
         if ( strcmp( argv [ c ], "--header" ) == 0 ) {
            flags |= OPTION_HEADERONLY;
            continue;
@@ -335,4 +339,3 @@ int main(int argc, char **argv)
     }
     return( rv );
 }
-
index a968cce3ea802930b2b91e946f3af88eb191e348..b3ab7b53be6f2d70947c57d2691f34852bb6ffdf 100644 (file)
@@ -1,6 +1,6 @@
 #include <stdio.h>
+#include <stdbool.h>
 
-#include <atalk/boolean.h>
 #include <atalk/logger.h>
 
 int main(int argc, char *argv[])
index 7862d73310d8564314a3ad3203cb23ff94ae41a6..71f2d50b49280e6158c1344dcd1c654d7353bb87 100644 (file)
 #                         if you don't want the proxy server to act as
 #                         a ddp server as well, set -uamlist to an empty
 #                         string.
+#     -dsireadbuf [number]
+#                         Scale factor that determines the size of the
+#                         DSI/TCP readahead buffer, default is 12. This is
+#                         multiplies with the DSI server quantum (default
+#                         ~300k) to give the size of the buffer. Increasing
+#                         this value might increase throughput in fast local
+#                         networks for volume to volume copies.  Note: This
+#                         buffer is allocated per afpd child process, so
+#                         specifying large values will eat up large amount of
+#                         memory (buffer size * number of clients).
+#     -tcprcvbuf [number]
+#                         Try to set TCP receive buffer using setsockpt().
+#                         Often OSes impose restrictions on the applications
+#                         ability to set this value.
+#     -tcpsndbuf [number]
+#                         Try to set TCP send buffer using setsockpt().
+#                         Often OSes impose restrictions on the applications
+#                         ability to set this value.
 #     -slp                Register this server with the Service Location
 #                         Protocol (if SLP support was compiled in).
 #     -nozeroconf         Don't register this server with the Multicats
 #                         then tries to authenticate with the result
 #                         through the availabel and active UAM authentication
 #                         modules.
+#     -dircachesize entries
+#                         Maximum possible entries in the directory cache.
+#                         The cache stores directories and files. It is used
+#                         to cache the full path to directories and CNIDs
+#                         which considerably speeds up directory enumeration.
+#                         Default size is 8192, maximum size is 131072. Given
+#                         value is rounded up to nearest power of 2. Each
+#                         entry takes about 100 bytes, which is not much, but
+#                         remember that every afpd child process for every
+#                         connected user has its cache.
+#     -fcelistener host[:port]
+#                         Enables sending FCE events to the specified host,
+#                         default port is 12250 if not specified. Specifying
+#                         mutliple listeners is done by having this option
+#                         once for each of them.
+#     -fceevents fmod,fdel,ddel,fcre,dcre,tmsz
+#                         Speficies which FCE events are active, default is
+#                         fmod,fdel,ddel,fcre,dcre.
+#     -fcecoalesce all|delete|create
+#                         Coalesce FCE events.
+#     -fceholdfmod seconds
+#                         This determines the time delay in seconds which is
+#                         always waited if another file modification for the
+#                         same file is done by a client before sending an FCE
+#                         file modification event (fmod). For example saving
+#                         a file in Photoshop would generate multiple events
+#                         by itself because the application is opening,
+#                         modifying and closing a file mutliple times for
+#                         every "save". Defautl: 60 seconds.
+#     -keepsessions       Enable "Continuous AFP Service". This means the
+#                         ability to stop the master afpd process with a
+#                         SIGQUIT signal, possibly install an afpd update and
+#                         start the afpd process. Existing AFP sessions afpd
+#                         processes will remain unaffected. Technically they
+#                         will be notified of the master afpd shutdown, sleep
+#                         15-20 seconds and then try to reconnect their IPC
+#                         channel to the master afpd process. If this
+#                         reconnect fails, the sessions are in an undefined
+#                         state. Therefor it's absolutely critical to restart
+#                         the master process in time!
+#     -noacl2maccess      Don't map filesystem ACLs to effective permissions.
 #
 #   Codepage Options:
 #     -unixcodepage <CODEPAGE>  Specifies the servers unix codepage,
index b8c1e67b731325483351384e5f7a87c5c631efc9..cb873a3ee9f39a72a1442b95b055fed748187af1 100644 (file)
@@ -52,9 +52,10 @@ AFPD_RUN=yes
 
 #### Control whether the daemons are started in the background.
 #### If it is dissatisfied that legacy atalkd starts slowly, set "yes".
+#### In case using systemd/systemctl, this is not so significant.
 #ATALK_BGROUND=no
 
 #### Set the AppleTalk Zone name.
 #### NOTE: if your zone has spaces in it, you're better off specifying
-####       it in afpd.conf
+####       it in atalkd.conf
 #ATALK_ZONE=@zone
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..4a03c6d
--- /dev/null
@@ -0,0 +1,388 @@
+dnl configure.in for netatalk
+
+AC_INIT(etc/afpd/main.c)
+
+NETATALK_VERSION=`cat $srcdir/VERSION`
+AC_SUBST(NETATALK_VERSION)
+
+AC_CANONICAL_SYSTEM
+AM_INIT_AUTOMAKE(netatalk, ${NETATALK_VERSION})
+AM_CONFIG_HEADER(config.h)
+AM_MAINTAINER_MODE([enable])
+
+dnl Checks for programs.
+AC_PROG_AWK
+AC_PROG_CC
+AC_PROG_CC_C99
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_LIBTOOL_DLOPEN
+AC_PROG_LIBTOOL
+AC_PROG_PERL
+AC_PROG_GREP
+AC_PROG_PS
+AM_PROG_CC_C_O
+
+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
+])
+
+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 
+dnl --------------------------------------------------------------------------
+AC_LTDL_DLLIB
+AC_CHECK_FUNCS(dlopen dlsym dlclose)
+AC_LTDL_DLSYM_USCORE
+if test x"$libltdl_cv_need_uscore" = xyes; then
+    AC_DEFINE(DLSYM_PREPEND_UNDERSCORE, 1, [BSD compatibility macro])
+fi
+
+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>])
+
+dnl these tests have been comfirmed to be needed in 2011
+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_DEFINE(OPEN_NOFOLLOW_ERRNO, ELOOP, errno returned by open with O_NOFOLLOW)
+
+AC_CACHE_SAVE
+
+dnl --------------------------------------------------------------------------
+dnl 64bit platform check
+dnl --------------------------------------------------------------------------
+
+AC_MSG_CHECKING([whether to check for 64bit libraries])
+# Test if the compiler is in 64bit mode
+echo 'int i;' > conftest.$ac_ext
+atalk_cv_cc_64bit_output=no
+if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *"ELF 64"*)
+      atalk_cv_cc_64bit_output=yes
+      ;;
+    esac
+fi
+rm -rf conftest*
+
+case $host_cpu:$atalk_cv_cc_64bit_output in
+powerpc64:yes | s390x:yes | sparc*:yes | x86_64:yes | i386:yes)
+    case $target_os in
+    solaris2*)
+        AC_MSG_RESULT([yes])
+        atalk_libname="lib/64"
+        ;;
+    *bsd* | dragonfly*)
+        AC_MSG_RESULT([no])
+        atalk_libname="lib"
+        ;;
+    *)
+        AC_MSG_RESULT([yes])
+        atalk_libname="lib64"
+        ;;
+    esac
+    ;;
+*:*)
+    AC_MSG_RESULT([no])
+    atalk_libname="lib"
+    ;;
+esac
+
+dnl --------------------------------------------------------------------------
+dnl specific configuration comes in here:
+dnl --------------------------------------------------------------------------
+
+dnl Check for optional admin group support
+AC_NETATALK_ADMIN_GROUP
+
+dnl Check for optional AFS support
+AC_NETATALK_AFS_CHECK
+
+dnl --with-pkgconfdir check to change configuration directory location
+AC_NETATALK_CONFIG_DIRS
+
+dnl Check for optional cracklib support
+AC_NETATALK_CRACKLIB
+
+dnl Check whether to enable debug code
+AC_NETATALK_DEBUG
+
+dnl Check whethe to disable tickle SIGALARM stuff, which eases debugging
+AC_NETATALK_DEBUGGING
+
+dnl    Check for libiconv support
+AC_NETATALK_CHECK_ICONV
+
+dnl Check for CNID database backends
+AC_NETATALK_CNID([bdb_required=yes],[bdb_required=no])
+
+dnl Check for quota support
+AC_NETATALK_CHECK_QUOTA
+
+dnl Check for optional server location protocol support (used by MacOS X)
+AC_NETATALK_SRVLOC
+
+dnl Check for optional Zeroconf support
+AC_NETATALK_ZEROCONF
+
+dnl Check for optional TCP-wrappers support
+AC_NETATALK_TCP_WRAPPERS
+
+dnl Check for PAM libs
+AC_NETATALK_PATH_PAM
+
+dnl Check for optional shadow password support
+AC_NETATALK_SHADOW
+       
+dnl Check for optional valid-shell-check support
+AC_NETATALK_SHELL_CHECK
+
+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"])
+
+dnl Check for libgcrypt, if found enables DHX2 UAM
+AC_NETATALK_PATH_LIBGCRYPT([1:1.2.3])
+
+dnl Check for openssl, if found enables DHX UAM and Randnum UAM
+AC_NETATALK_PATH_SSL
+
+dnl Check for Berkeley DB library
+AC_NETATALK_PATH_BDB
+
+dnl Check for crypt
+AC_NETATALK_CRYPT
+
+dnl Check for building PGP UAM module
+AC_NETATALK_PGP_UAM
+
+dnl Check for building Kerberos V UAM module
+AC_NETATALK_KRB5_UAM
+
+dnl Check for overwrite the config files or not
+AC_NETATALK_OVERWRITE_CONFIG
+
+dnl Check for LDAP support, for client-side ACL visibility
+AC_NETATALK_LDAP
+
+dnl Check for ACL support
+AC_NETATALK_ACL
+
+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 Check if realpath() takes NULL
+AC_NETATALK_REALPATH
+
+dnl Check for sendfile()
+AC_NETATALK_SENDFILE
+
+dnl --------------------------------------------------------------------------
+dnl FHS stuff has to be done last because it overrides other defaults
+dnl --------------------------------------------------------------------------
+
+AC_MSG_CHECKING([whether to use Filesystem Hierarchy Standard (FHS) compatibility])
+AC_ARG_ENABLE(fhs,
+       [  --enable-fhs            use Filesystem Hierarchy Standard (FHS) compatibility],[
+       if test "$enableval" = "yes"; then
+               uams_path="${libdir}/netatalk"
+               sysconfdir="/etc"
+               PKGCONFDIR=${sysconfdir}/netatalk
+               SERVERTEXT="${PKGCONFDIR}/msg"
+               use_pam_so=yes
+               mandir="/usr/share/man"
+               AC_DEFINE(FHS_COMPATIBILITY, 1, [Define if you want compatibily with the FHS])
+               AC_MSG_RESULT([yes])
+       else
+               AC_MSG_RESULT([no])
+       fi
+       ],[
+               AC_MSG_RESULT([no])
+       ]
+)
+
+dnl --------------------------------------------------------------------------
+dnl post-FHS substitutions, etc
+dnl --------------------------------------------------------------------------
+
+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 -L\$(top_srcdir)/libevent"
+CFLAGS="-I\$(top_srcdir)/include -I\$(top_srcdir)/sys -I\$(top_srcdir)/libevent/include $CFLAGS"
+
+
+dnl --------------------------------------------------------------------------
+dnl Last minute substitutions
+dnl --------------------------------------------------------------------------
+
+AC_SUBST(LIBS)
+AC_SUBST(CFLAGS)
+
+AM_CONDITIONAL(SOLARIS_MODULE, test x$solaris_module = 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(HAVE_LDAP, test x"$with_ldap" = 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_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_NETBSD, test x$sysv_style = xnetbsd)
+AM_CONDITIONAL(USE_REDHAT_SYSV, test x$sysv_style = xredhat-sysv)
+AM_CONDITIONAL(USE_REDHAT_SYSTEMD, test x$sysv_style = xredhat-systemd)
+AM_CONDITIONAL(USE_SUSE, test x$sysv_style = xsuse)
+AM_CONDITIONAL(USE_SHADOWPW, test x$shadowpw = xyes)
+AM_CONDITIONAL(USE_TRU64, test x$sysv_style = xtru64)
+AM_CONDITIONAL(USE_SOLARIS, test x$sysv_style = xsolaris)
+AM_CONDITIONAL(USE_GENTOO, test x$sysv_style = xgentoo)
+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(HAVE_ATFUNCS, test x"$ac_neta_haveatfuncs" = x"yes")
+
+dnl --------------------- generate files
+
+AC_OUTPUT([Makefile
+       bin/Makefile
+       bin/ad/Makefile
+       bin/afppasswd/Makefile
+       bin/cnid/Makefile
+       bin/cnid/cnid2_create
+       bin/megatron/Makefile
+    bin/misc/Makefile
+       bin/uniconv/Makefile
+       config/Makefile
+       config/pam/Makefile
+       contrib/Makefile
+       contrib/macusers/Makefile
+       contrib/macusers/macusers
+       contrib/shell_utils/Makefile
+       contrib/shell_utils/apple_dump
+       contrib/shell_utils/asip-status.pl
+       distrib/Makefile
+       distrib/config/Makefile
+       distrib/config/netatalk-config
+       distrib/initscripts/Makefile
+       distrib/m4/Makefile
+       distrib/systemd/Makefile
+       doc/Makefile
+       etc/Makefile
+       etc/afpd/Makefile
+       etc/cnid_dbd/Makefile
+       etc/netalockd/Makefile
+       etc/uams/Makefile
+       include/Makefile
+       include/atalk/Makefile
+       libatalk/Makefile
+       libatalk/acl/Makefile
+       libatalk/adouble/Makefile
+       libatalk/bstring/Makefile
+       libatalk/cnid/Makefile
+       libatalk/cnid/cdb/Makefile
+       libatalk/cnid/last/Makefile
+       libatalk/cnid/dbd/Makefile
+       libatalk/cnid/tdb/Makefile
+       libatalk/compat/Makefile
+       libatalk/dsi/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/man5/Makefile
+       man/man8/Makefile
+       test/Makefile
+       test/afpd/Makefile
+       test/netalockd/Makefile
+       ],
+       [chmod a+x distrib/config/netatalk-config contrib/shell_utils/apple_*]
+)
+
+AC_NETATALK_LIBS_SUMMARY
+AC_NETATALK_CONFIG_SUMMARY
diff --git a/configure.in b/configure.in
deleted file mode 100644 (file)
index db254ab..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-dnl configure.in for netatalk
-
-AC_INIT(etc/afpd/main.c)
-
-NETATALK_VERSION=`cat $srcdir/VERSION`
-AC_SUBST(NETATALK_VERSION)
-
-AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE(netatalk, ${NETATALK_VERSION})
-AM_CONFIG_HEADER(config.h)
-AM_MAINTAINER_MODE([enable])
-
-dnl Checks for programs.
-AC_PROG_AWK
-AC_PROG_CC
-AC_PROG_CC_C99
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-AC_LIBTOOL_DLOPEN
-AC_PROG_LIBTOOL
-AC_PROG_PERL
-AC_PROG_GREP
-AC_PROG_PS
-AM_PROG_CC_C_O
-
-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
-])
-
-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 
-dnl --------------------------------------------------------------------------
-AC_LTDL_DLLIB
-AC_CHECK_FUNCS(dlopen dlsym dlclose)
-AC_LTDL_DLSYM_USCORE
-if test x"$libltdl_cv_need_uscore" = xyes; then
-    AC_DEFINE(DLSYM_PREPEND_UNDERSCORE, 1, [BSD compatibility macro])
-fi
-
-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>])
-
-dnl these tests have been comfirmed to be needed in 2011
-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)
-
-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 --------------------------------------------------------------------------
-
-AC_MSG_CHECKING([whether to check for 64bit libraries])
-# Test if the compiler is in 64bit mode
-echo 'int i;' > conftest.$ac_ext
-atalk_cv_cc_64bit_output=no
-if AC_TRY_EVAL(ac_compile); then
-    case `/usr/bin/file conftest.$ac_objext` in
-    *"ELF 64"*)
-      atalk_cv_cc_64bit_output=yes
-      ;;
-    esac
-fi
-rm -rf conftest*
-
-case $host_cpu:$atalk_cv_cc_64bit_output in
-powerpc64:yes | s390x:yes | sparc*:yes | x86_64:yes | i386:yes)
-    AC_MSG_RESULT([yes])
-    case $target_os in
-    solaris2*)
-        atalk_libname="lib/64"
-        ;;
-    *)
-        atalk_libname="lib64"
-        ;;
-    esac
-    ;;
-*:*)
-    AC_MSG_RESULT([no])
-    atalk_libname="lib"
-    ;;
-esac
-
-dnl --------------------------------------------------------------------------
-dnl specific configuration comes in here:
-dnl --------------------------------------------------------------------------
-
-dnl Check for optional admin group support
-AC_NETATALK_ADMIN_GROUP
-
-dnl Check for optional AFS support
-AC_NETATALK_AFS_CHECK
-
-dnl --with-pkgconfdir check to change configuration directory location
-AC_NETATALK_CONFIG_DIRS
-
-dnl Check for optional cracklib support
-AC_NETATALK_CRACKLIB
-
-dnl Check whether to enable debug code
-AC_NETATALK_DEBUG
-
-dnl Check whethe to disable tickle SIGALARM stuff, which eases debugging
-AC_NETATALK_DEBUGGING
-
-dnl    Check for libiconv support
-AC_NETATALK_CHECK_ICONV
-
-dnl Check for CNID database backends
-AC_NETATALK_CNID([bdb_required=yes],[bdb_required=no])
-
-dnl Check for quota support
-AC_NETATALK_CHECK_QUOTA
-
-dnl Check for optional server location protocol support (used by MacOS X)
-AC_NETATALK_SRVLOC
-
-dnl Check for optional Zeroconf support
-AC_NETATALK_ZEROCONF
-
-dnl Check for optional TCP-wrappers support
-AC_NETATALK_TCP_WRAPPERS
-
-dnl Check for PAM libs
-AC_NETATALK_PATH_PAM
-
-dnl Check for optional shadow password support
-AC_NETATALK_SHADOW
-       
-dnl Check for optional valid-shell-check support
-AC_NETATALK_SHELL_CHECK
-
-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"])
-
-dnl Check for libgcrypt, if found enables DHX2 UAM
-AC_NETATALK_PATH_LIBGCRYPT([1:1.2.3])
-
-dnl Check for openssl, if found enables DHX UAM and Randnum UAM
-AC_NETATALK_PATH_SSL
-
-dnl Check for Berkeley DB library
-AC_NETATALK_PATH_BDB
-
-dnl Check for crypt
-AC_NETATALK_CRYPT
-
-dnl Check for building PGP UAM module
-AC_NETATALK_PGP_UAM
-
-dnl Check for building Kerberos V UAM module
-AC_NETATALK_KRB5_UAM
-
-dnl Check for overwrite the config files or not
-AC_NETATALK_OVERWRITE_CONFIG
-
-dnl Check for LDAP support, for client-side ACL visibility
-AC_NETATALK_LDAP
-
-dnl Check for ACL support
-AC_NETATALK_ACL
-
-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 --------------------------------------------------------------------------
-
-AC_MSG_CHECKING([whether to use Filesystem Hierarchy Standard (FHS) compatibility])
-AC_ARG_ENABLE(fhs,
-       [  --enable-fhs            use Filesystem Hierarchy Standard (FHS) compatibility],[
-       if test "$enableval" = "yes"; then
-               uams_path="${libdir}/netatalk"
-               sysconfdir="/etc"
-               PKGCONFDIR=${sysconfdir}/netatalk
-               SERVERTEXT="${PKGCONFDIR}/msg"
-               use_pam_so=yes
-               mandir="/usr/share/man"
-               AC_DEFINE(FHS_COMPATIBILITY, 1, [Define if you want compatibily with the FHS])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-       ],[
-               AC_MSG_RESULT([no])
-       ]
-)
-
-dnl --------------------------------------------------------------------------
-dnl post-FHS substitutions, etc
-dnl --------------------------------------------------------------------------
-
-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 -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 Last minute substitutions
-dnl --------------------------------------------------------------------------
-
-AC_SUBST(LIBS)
-AC_SUBST(CFLAGS)
-
-AM_CONDITIONAL(SOLARIS_MODULE, test x$solaris_module = 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(HAVE_LDAP, test x"$with_ldap" = 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_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_NETBSD, test x$sysv_style = xnetbsd)
-AM_CONDITIONAL(USE_REDHAT_SYSV, test x$sysv_style = xredhat-sysv)
-AM_CONDITIONAL(USE_REDHAT_SYSTEMD, test x$sysv_style = xredhat-systemd)
-AM_CONDITIONAL(USE_SUSE, test x$sysv_style = xsuse)
-AM_CONDITIONAL(USE_SHADOWPW, test x$shadowpw = xyes)
-AM_CONDITIONAL(USE_TRU64, test x$sysv_style = xtru64)
-AM_CONDITIONAL(USE_SOLARIS, test x$sysv_style = xsolaris)
-AM_CONDITIONAL(USE_GENTOO, test x$sysv_style = xgentoo)
-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(HAVE_ATFUNCS, test x"$ac_neta_haveatfuncs" = x"yes")
-
-dnl --------------------- generate files
-
-AC_OUTPUT([Makefile
-       bin/Makefile
-       bin/ad/Makefile
-       bin/afppasswd/Makefile
-       bin/cnid/Makefile
-       bin/cnid/cnid2_create
-       bin/megatron/Makefile
-    bin/misc/Makefile
-       bin/uniconv/Makefile
-       config/Makefile
-    config/pam/Makefile
-       contrib/Makefile
-       contrib/macusers/Makefile
-       contrib/macusers/macusers
-       contrib/shell_utils/Makefile
-       contrib/shell_utils/afpd-mtab.pl
-    contrib/shell_utils/apple_dump
-       contrib/shell_utils/asip-status.pl
-       distrib/Makefile
-       distrib/config/Makefile
-       distrib/config/netatalk-config
-       distrib/initscripts/Makefile
-       distrib/m4/Makefile
-       doc/Makefile
-       etc/Makefile
-       etc/afpd/Makefile
-       etc/cnid_dbd/Makefile
-       etc/netalockd/Makefile
-       etc/uams/Makefile
-       include/Makefile
-       include/atalk/Makefile
-       libatalk/Makefile
-       libatalk/acl/Makefile
-       libatalk/adouble/Makefile
-       libatalk/bstring/Makefile
-       libatalk/cnid/Makefile
-       libatalk/cnid/cdb/Makefile
-       libatalk/cnid/last/Makefile
-       libatalk/cnid/dbd/Makefile
-       libatalk/cnid/tdb/Makefile
-       libatalk/compat/Makefile
-       libatalk/dsi/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/man5/Makefile
-       man/man8/Makefile
-       test/Makefile
-       test/afpd/Makefile
-       test/netalockd/Makefile
-       ],
-       [chmod a+x distrib/config/netatalk-config contrib/shell_utils/apple_*]
-)
-
-AC_NETATALK_LIBS_SUMMARY
-AC_NETATALK_CONFIG_SUMMARY
diff --git a/contrib/misc/Makefile.am b/contrib/misc/Makefile.am
new file mode 100644 (file)
index 0000000..d25d876
--- /dev/null
@@ -0,0 +1,3 @@
+# Makefile for contrib/misc/
+
+EXTRA_DIST = cnid.lua
diff --git a/contrib/misc/cnid.lua b/contrib/misc/cnid.lua
new file mode 100644 (file)
index 0000000..3b21723
--- /dev/null
@@ -0,0 +1,123 @@
+-- 
+-- Netatalk DBD protocol 
+-- wireshark -X lua_script:cnid.lua
+-- don't forget to comment out the line disable_lua = true; do return end;
+-- in /etc/wireshark/init.lua
+
+-- global environment
+local b = _G
+
+-- declare our protocol
+local dbd_proto = Proto("dbd","Netatalk Dbd Wire Protocol")
+
+local cmd = ProtoField.uint32("dbd.cmd", "Request") -- , base.HEX
+local len = ProtoField.uint32("dbd.name.len", "Name Length")
+local filename = ProtoField.string("dbd.name", "Name")
+local error = ProtoField.uint32("dbd.error", "Error code")
+local cnid = ProtoField.uint32("dbd.cnid", "Cnid")
+local did  = ProtoField.uint32("dbd.did", "Parent Directory Id")
+local dev  = ProtoField.uint64("dbd.dev", "Device number")
+local ino  = ProtoField.uint64("dbd.ino", "Inode number")
+local type = ProtoField.uint32("dbd.type", "File type")
+
+dbd_proto.fields = {cmd, error, cnid, did, dev, ino, type, filename, len}
+
+--- Request list
+local Cmd = { [3] = "add", 
+             [4] = "get", 
+             [5] = "resolve", 
+             [6] = "lookup", 
+             [7] = "update", 
+             [8] = "delete", 
+             [11] = "timestamp" 
+           }
+
+--- display a filename 
+local function fname(buffer, pinfo, tree, len, ofs)
+
+    pinfo.cols.info:append(" Name=" .. buffer(ofs +4, len):string())
+
+    local subtree = tree:add(buffer(ofs, len +4), buffer(ofs +4, len):string())
+    subtree:add(filename, buffer(ofs +4, len))
+
+    return subtree
+end
+
+-- create a function to dissect it
+function dbd_proto.dissector(buffer, pinfo, tree)
+
+
+    pinfo.cols.protocol = "DBD"
+
+    local subtree = tree:add(dbd_proto,buffer(),"Netatalk DBD Wire Protocol")
+
+    if pinfo.dst_port == 4700 then
+           pinfo.cols.info = "Query"
+           local val = buffer(0,4):uint()
+           local item = subtree:add(cmd, buffer(0,4))
+           if Cmd[val] then
+               item:append_text(" (" .. Cmd[val] .. ")")
+               pinfo.cols.info = Cmd[val]
+
+               local val = buffer(4,4):uint()
+               if val ~= 0 then
+                       pinfo.cols.info:append(" Cnid=" .. val)
+               end
+               subtree:add(cnid, buffer(4, 4))
+               subtree:add(dev, buffer(8, 8))
+               subtree:add(ino, buffer(16, 8))
+               subtree:add(type, buffer(24, 4))
+
+               local val = buffer(28,4):uint()
+               if val ~= 0 then
+                  pinfo.cols.info:append(" Did=" .. val)
+               end
+               subtree:add(did, buffer(28, 4))
+
+               local val = buffer(36,4):uint()
+               if val ~= 0 then
+                  item = fname(buffer, pinfo, subtree, val, 36)
+                  item:add(len, buffer(36, 4))
+                       
+               end
+           end
+    else
+           pinfo.cols.info = "Reply"
+
+           local rply = {}
+           
+           local val = buffer(0,4):uint()
+           rply.error = val
+           subtree:add(error, buffer(0,4))
+           if val ~= 0 then
+               pinfo.cols.info:append(" Error=" .. val)
+           end
+
+           val = buffer(4,4):uint()
+           rply.cnid = val
+           subtree:add(cnid, buffer(4,4))
+           if val ~= 0 then
+               pinfo.cols.info:append(" Cnid=" .. val)
+           end
+
+           val = buffer(8,4):uint()
+           rply.did = val
+           subtree:add(did, buffer(8,4))
+           if val ~= 0 then
+               pinfo.cols.info:append(" Did=" .. val)
+           end
+
+           val = buffer(16,4):uint()
+           rply.len = val
+           
+           if rply.error == 0 and rply.did ~= 0 then
+              subtree = fname(buffer, pinfo, subtree, val, 16)
+              subtree:add(len, buffer(16,4))
+           end
+    end
+end
+
+-- load the tcp.port table
+local tcp_table = DissectorTable.get("tcp.port")
+-- register our protocol 
+tcp_table:add(4700, dbd_proto)
diff --git a/contrib/misc/make-casetable.pl b/contrib/misc/make-casetable.pl
deleted file mode 100755 (executable)
index 9af15a9..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-#!/usr/bin/perl
-#
-# usage: make-casetable.pl <infile> <outfile1> <outfile2>
-#        make-casetable.pl UnicodeData.txt utf16_casetable.h utf16_case.c
-#
-# (c) 2011 by HAT <hat@fa2.so-net.ne.jp>
-#
-#  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.
-#
-
-# See
-# http://www.unicode.org/reports/tr44/
-# http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
-
-# One block has 64 chars.
-#
-# BMP
-# block    0 = dummy
-# block    1 = U+0000 - U+003F
-# block    2 = U+0040 - U+007F
-# .....
-# block 1024 = U+FFC0 - U+FFFF
-# block 1025 = dummy
-#
-# Surrogate Pair
-# block  1024 = dummy
-# block  1025 = U+010000 - U+01003F
-# block  1026 = U+010040 - U+01007F
-# .....
-# block 17408 = U+10FFC0 - U+10FFFF
-# block 17409 = dummy
-#
-# Dummy block is for edge detection.
-# If block include upper/lower chars, block_enable[]=1.
-
-use strict;
-use warnings;
-
-our $code0;
-our $Name1;
-our $General_Category2;
-our $Canonical_Combining_Class3;
-our $Bidi_Class4;
-our $Decomposition_Mapping5;
-our $Numeric_Value6;
-our $Numeric_Value7;
-our $Numeric_Value8;
-our $Bidi_Mirrored9;
-our $Unicode_1_Name10;
-our $ISO_Comment11;
-our $Simple_Uppercase_Mapping12;
-our $Simple_Lowercase_Mapping13;
-our $Simple_Titlecase_Mapping14;
-
-our $hex_code0;
-our $Mapping;
-our $hex_Mapping;
-
-our $char;
-our $sp;
-our $block;
-
-our @table;
-our @table_sp;
-
-our @block_enable;
-our @block_enable_sp;
-
-our $table_no;
-our $block_start;
-our $block_end;
-our $char_start;
-our $char_end;
-
-open(CHEADER, ">$ARGV[1]");
-open(CSOURCE, ">$ARGV[2]");
-
-printf (CHEADER "\/\*\n");
-printf (CHEADER "DO NOT EDIT BY HAND\!\!\!\n");
-printf (CHEADER "\n");
-printf (CHEADER "This file is generated by\n");
-printf (CHEADER " contrib/misc/make-casetable.pl %s %s %s\n", $ARGV[0], $ARGV[1], $ARGV[2]);
-printf (CHEADER "\n");
-printf (CHEADER "%s is got from\n", $ARGV[0]);
-printf (CHEADER "http\:\/\/www.unicode.org\/Public\/UNIDATA\/UnicodeData.txt\n");
-printf (CHEADER "\*\/\n");
-printf (CHEADER "\n");
-
-printf (CSOURCE "\/\*\n");
-printf (CSOURCE "DO NOT EDIT BY HAND\!\!\!\n");
-printf (CSOURCE "\n");
-printf (CSOURCE "This file is generated by\n");
-printf (CSOURCE " contrib/misc/make-casetable.pl %s %s %s\n", $ARGV[0], $ARGV[1], $ARGV[2]);
-printf (CSOURCE "\n");
-printf (CSOURCE "%s is got from\n", $ARGV[0]);
-printf (CSOURCE "http\:\/\/www.unicode.org\/Public\/UNIDATA\/UnicodeData.txt\n");
-printf (CSOURCE "\*\/\n");
-printf (CSOURCE "\n");
-printf (CSOURCE "\#include \<stdint.h\>\n");
-printf (CSOURCE "\#include \<atalk\/unicode.h\>\n");
-printf (CSOURCE "\#include \"%s\"\n", $ARGV[1]);
-printf (CSOURCE "\n");
-
-&make_array("upper");
-&make_array("lower");
-
-printf (CHEADER "\/\* EOF \*\/\n");
-printf (CSOURCE "\/\* EOF \*\/\n");
-
-close(CHEADER);
-close(CSOURCE);
-
-
-###########################################################################
-sub make_array{
-
-    # init table -----------------------------------------------------
-
-    for ($char = 0 ; $char <= 0xFFFF ; $char++) {
-        $table[$char][0] = $char;       # mapped char
-        $table[$char][1] = $char;       # orig char
-        $table[$char][2] = "";          # char name
-    }
-
-    for ($char = 0x10000 ; $char <= 0x10FFFF ; $char++) {
-        $sp = ((0xD800 - (0x10000 >> 10) + ($char >> 10)) << 16)
-            + (0xDC00 + ($char & 0x3FF));
-        $table_sp[$char][0] = $sp;      # mapped surrogate pair
-        $table_sp[$char][1] = $sp;      # orig surrogate pair
-        $table_sp[$char][2] = $char;    # mapped char
-        $table_sp[$char][3] = $char;    # orig char
-        $table_sp[$char][4] = "";       # char name
-    }
-
-    for ($block = 0 ; $block <= 1025 ; $block++) {
-        $block_enable[$block] = 0;
-    }
-
-    $block_enable[1] = 1;           # ASCII block is forcibly included
-    $block_enable[2] = 1;           # in the array for Speed-Up.
-
-    for ($block = 1024 ; $block <= 17409 ; $block++) {
-        $block_enable_sp[$block] = 0;
-    }
-
-    # write data to table --------------------------------------------
-
-    open(UNICODEDATA, "<$ARGV[0]");
-
-    while (<UNICODEDATA>) {
-        chop;
-        (
-            $code0,
-            $Name1,
-            $General_Category2,
-            $Canonical_Combining_Class3,
-            $Bidi_Class4,
-            $Decomposition_Mapping5,
-            $Numeric_Value6,
-            $Numeric_Value7,
-            $Numeric_Value8,
-            $Bidi_Mirrored9,
-            $Unicode_1_Name10,
-            $ISO_Comment11,
-            $Simple_Uppercase_Mapping12,
-            $Simple_Lowercase_Mapping13,
-            $Simple_Titlecase_Mapping14
-        ) = split(/\;/);
-
-        if ($_[0] eq "upper") {
-            $Mapping = $Simple_Uppercase_Mapping12;
-        } elsif ($_[0] eq "lower") {
-            $Mapping = $Simple_Lowercase_Mapping13;
-        } else {
-            exit(1);
-        }
-
-        next if ($Mapping eq "");
-
-        $hex_code0 = hex($code0);
-        $hex_Mapping = hex($Mapping);
-
-        if ($hex_code0 <= 0xFFFF) {
-            $table[$hex_code0][0] = $hex_Mapping;
-            #table[$hex_code0][1]   already set
-            $table[$hex_code0][2] = $Name1;
-            $block_enable[($hex_code0 / 64) +1] = 1;
-        } else {
-            $sp = ((0xD800 - (0x10000 >> 10) + ($hex_Mapping >> 10)) << 16)
-                + (0xDC00 + ($hex_Mapping & 0x3FF));
-            $table_sp[$hex_code0][0] = $sp;
-            #table_sp[$hex_code0][1]   already set
-            $table_sp[$hex_code0][2] = $hex_Mapping;
-            #table_sp[$hex_code0][3]   already set
-            $table_sp[$hex_code0][4] = $Name1;
-            $block_enable_sp[($hex_code0 / 64) +1] = 1;
-        }
-    }
-
-    close(UNICODEDATA);
-
-    # array for BMP --------------------------------------------------
-
-    printf(CSOURCE "\/*******************************************************************\n");
-    printf(CSOURCE " Convert a wide character to %s case.\n", $_[0]);
-    printf(CSOURCE "*******************************************************************\/\n");
-    printf(CSOURCE "ucs2\_t to%s\_w\(ucs2\_t val\)\n", $_[0]);
-    printf(CSOURCE "{\n");
-
-    $table_no = 1;
-
-    for ($block = 1 ; $block <= 1024 ; $block++) {
-
-        # rising edge detection
-        if ($block_enable[$block - 1] == 0 && $block_enable[$block] == 1) {
-            $block_start = $block;
-        }
-
-        # falling edge detection
-        if ($block_enable[$block] == 1 && $block_enable[$block + 1] == 0) {
-            $block_end = $block;
-
-            $char_start = ($block_start -1)* 64;
-            $char_end = ($block_end * 64) -1;
-
-            printf(CHEADER "static const uint16\_t %s\_table\_%d\[%d\] \= \{\n",
-                   $_[0], $table_no, $char_end - $char_start +1);
-
-            for ($char = $char_start ; $char <= $char_end ; $char++) {
-                printf(CHEADER "  0x%04X, /*U\+%04X*/ /*%s*/\n",
-                       $table[$char][0],
-                       $table[$char][1],
-                       $table[$char][2]
-                   );
-            }
-            printf(CHEADER "\}\;\n");
-            printf(CHEADER "\n");
-
-            if ($char_start == 0x0000) {
-                printf(CSOURCE "    if \( val \<\= 0x%04X)\n",
-                       $char_end);
-                printf(CSOURCE "        return %s\_table\_%d\[val]\;\n",
-                       $_[0], $table_no);
-            } else {
-                printf(CSOURCE "    if \( val \>\= 0x%04X \&\& val \<\= 0x%04X)\n",
-                       $char_start, $char_end);
-                printf(CSOURCE "        return %s\_table\_%d\[val-0x%04X\]\;\n",
-                       $_[0], $table_no, $char_start);
-            }
-            printf(CSOURCE "\n");
-
-            $table_no++;
-        }
-    }
-
-    printf(CSOURCE "\treturn \(val\)\;\n");
-    printf(CSOURCE "\}\n");
-    printf(CSOURCE "\n");
-
-    # array for Surrogate Pair ---------------------------------------
-
-    printf(CSOURCE "\/*******************************************************************\n");
-    printf(CSOURCE " Convert a surrogate pair to %s case.\n", $_[0]);
-    printf(CSOURCE "*******************************************************************\/\n");
-    printf(CSOURCE "uint32\_t to%s\_sp\(uint32\_t val\)\n", $_[0]);
-    printf(CSOURCE "{\n");
-
-    $table_no = 1;
-
-    for ($block = 1025 ; $block <= 17408 ; $block++) {
-
-        # rising edge detection
-        if ((($block_enable_sp[$block - 1] == 0) || ((($block - 1) & 0xF) == 0))
-                && ($block_enable_sp[$block] == 1)) {
-            $block_start = $block;
-        }
-
-        # falling edge detection
-        if (($block_enable_sp[$block] == 1) &&
-                ((($block - 1) & 0xF == 0xF) || ($block_enable_sp[$block + 1] == 0))) {
-            $block_end = $block;
-
-            $char_start = ($block_start -1)* 64;
-            $char_end = ($block_end * 64) -1;
-
-            printf(CHEADER "static const uint32\_t %s\_table\_sp\_%d\[%d\] \= \{\n",
-                   $_[0], $table_no, $char_end - $char_start +1);
-
-            for ($char = $char_start ; $char <= $char_end ; $char++) {
-                printf(CHEADER "  0x%08X, /*0x%08X*/ /*U\+%06X*/ /*U\+%06X*/ /*%s*/\n",
-                       $table_sp[$char][0],
-                       $table_sp[$char][1],
-                       $table_sp[$char][2],
-                       $table_sp[$char][3],
-                       $table_sp[$char][4]
-                   );
-            }
-            printf(CHEADER "\}\;\n");
-            printf(CHEADER "\n");
-
-            printf(CSOURCE "    if \( val \>\= 0x%08X \&\& val \<\= 0x%08X)\n",
-                   $table_sp[$char_start][1], $table_sp[$char_end][1]);
-            printf(CSOURCE "        return %s\_table\_sp\_%d\[val-0x%08X\]\;\n",
-                   $_[0], $table_no, $table_sp[$char_start][1]);
-            printf(CSOURCE "\n");
-
-            $table_no++;
-        }
-    }
-
-    printf(CSOURCE "\treturn \(val\)\;\n");
-    printf(CSOURCE "\}\n");
-    printf(CSOURCE "\n");
-}
-
-# EOF
diff --git a/contrib/misc/make-precompose.h.pl b/contrib/misc/make-precompose.h.pl
deleted file mode 100755 (executable)
index 11cb8d9..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-#!/usr/bin/perl
-#
-# usage: make-precompose.h.pl UnicodeData.txt > precompose.h
-#
-# (c) 2008-2011 by HAT <hat@fa2.so-net.ne.jp>
-#
-#  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.
-# 
-
-# See
-# http://www.unicode.org/Public/UNIDATA/UCD.html
-# http://www.unicode.org/reports/tr15/
-# http://www.unicode.org/Public/*/ucd/UnicodeData*.txt
-# http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
-
-
-# temp files for binary search (compose.TEMP, compose_sp.TEMP) -------------
-
-open(UNICODEDATA, "<$ARGV[0]");
-
-open(COMPOSE_TEMP, ">compose.TEMP");
-open(COMPOSE_SP_TEMP, ">compose_sp.TEMP");
-
-while (<UNICODEDATA>) {
-    chop;
-    (
-     $code0,
-     $Name1,
-     $General_Category2,
-     $Canonical_Combining_Class3,
-     $Bidi_Class4,
-     $Decomposition_Mapping5,
-     $Numeric_Value6,
-     $Numeric_Value7,
-     $Numeric_Value8,
-     $Bidi_Mirrored9,
-     $Unicode_1_Name10,
-     $ISO_Comment11,
-     $Simple_Uppercase_Mapping12,
-     $Simple_Lowercase_Mapping13,
-     $Simple_Titlecase_Mapping14
-    ) = split(/\;/);
-
-    if (($Decomposition_Mapping5 ne "") && ($Decomposition_Mapping5 !~ /\</) && ($Decomposition_Mapping5 =~ / /)) {
-       ($base, $comb) = split(/ /,$Decomposition_Mapping5);
-
-       $leftbracket  = "  { ";
-       $rightbracket =" },     ";
-
-       # AFP 3.x Spec
-       if ( ((0x2000  <= hex($code0)) && (hex($code0) <=  0x2FFF))
-            || ((0xFE30  <= hex($code0)) && (hex($code0) <=  0xFE4F))
-            || ((0x2F800 <= hex($code0)) && (hex($code0) <= 0x2FA1F))) {
-           $leftbracket  = "\/\*{ ";
-           $rightbracket =" },\*\/   ";
-       }
-
-       if (hex($code0) > 0xFFFF) {
-
-           $code0_sp_hi = 0xD800 - (0x10000 >> 10) + (hex($code0) >> 10);
-           $code0_sp_lo = 0xDC00 + (hex($code0) & 0x3FF);
-
-           $base_sp_hi = 0xD800 - (0x10000 >> 10) + (hex($base) >> 10);
-           $base_sp_lo = 0xDC00 + (hex($base) & 0x3FF);
-
-           $comb_sp_hi = 0xD800 - (0x10000 >> 10) + (hex($comb) >> 10);
-           $comb_sp_lo = 0xDC00 + (hex($comb) & 0x3FF);
-
-           printf(COMPOSE_SP_TEMP "%s0x%04X%04X, 0x%04X%04X, 0x%04X%04X%s\/\* %s \*\/\n",
-                  $leftbracket, $code0_sp_hi ,$code0_sp_lo, $base_sp_hi, $base_sp_lo, $comb_sp_hi, $comb_sp_lo, $rightbracket, $Name1);
-
-           $leftbracket  = "\/\*{ ";
-           $rightbracket =" },\*\/   ";
-       }
-
-       printf(COMPOSE_TEMP "%s0x%08X, 0x%08X, 0x%08X%s\/\* %s \*\/\n", $leftbracket, hex($code0), hex($base), hex($comb), $rightbracket, $Name1);
-
-    }
-}
-
-close(UNICODEDATA);
-
-close(COMPOSE_TEMP);
-close(COMPOSE_SP_TEMP);
-
-# macros for BMP (PRECOMP_COUNT, DECOMP_COUNT, MAXCOMBLEN) ----------------
-
-open(COMPOSE_TEMP, "<compose.TEMP");
-
-@comp_table = ();
-$comp_count = 0;
-
-while (<COMPOSE_TEMP>) {
-    if (m/^\/\*/) {
-       next;
-    }
-    $comp_table[$comp_count][0] = substr($_, 4, 10);
-    $comp_table[$comp_count][1] = substr($_, 16, 10);
-    $comp_count++;
-}
-
-$maxcomblen = 2;      # Hangul's maxcomblen is already 2. That is, VT.
-
-for ($i = 0 ; $i < $comp_count ; $i++) {
-    $base = $comp_table[$i][1];
-    $comblen = 1;
-    $j = 0;
-    while ($j < $comp_count) {
-       if ($base ne $comp_table[$j][0]) {
-           $j++;
-           next;
-       } else {
-           $comblen++;
-           $base =  $comp_table[$j][1];
-           $j = 0;
-       }
-    }
-    $maxcomblen = ($maxcomblen > $comblen) ? $maxcomblen : $comblen;
-}
-
-close(COMPOSE_TEMP);
-
-# macros for SP (PRECOMP_SP_COUNT,DECOMP_SP_COUNT, MAXCOMBSPLEN) -----------
-
-open(COMPOSE_SP_TEMP, "<compose_sp.TEMP");
-
-@comp_sp_table = ();
-$comp_sp_count = 0;
-
-while (<COMPOSE_SP_TEMP>) {
-    if (m/^\/\*/) {
-       next;
-    }
-    $comp_sp_table[$comp_sp_count][0] = substr($_, 4, 10);
-    $comp_sp_table[$comp_sp_count][1] = substr($_, 16, 10);
-    $comp_sp_count++;
-}
-
-$maxcombsplen = 2;     # one char have 2 codepoints, like a D8xx DCxx.
-
-for ($i = 0 ; $i < $comp_sp_count ; $i++) {
-    $base_sp = $comp_sp_table[$i][1];
-    $comblen = 2;
-    $j = 0;
-    while ($j < $comp_sp_count) {
-       if ($base_sp ne $comp_sp_table[$j][0]) {
-           $j++;
-           next;
-       } else {
-           $comblen += 2;
-           $base_sp =  $comp_sp_table[$j][1];
-           $j = 0;
-       }
-    }
-    $maxcombsplen = ($maxcombsplen > $comblen) ? $maxcombsplen : $comblen;
-}
-
-close(COMPOSE_SP_TEMP);
-
-# macro for buffer length (COMBBUFLEN) -------------------------------------
-
-$combbuflen = ($maxcomblen > $maxcombsplen) ? $maxcomblen : $maxcombsplen;
-
-# sort ---------------------------------------------------------------------
-
-system("sort -k 3 compose.TEMP \> precompose.SORT");
-system("sort -k 2 compose.TEMP \>  decompose.SORT");
-
-system("sort -k 3 compose_sp.TEMP \> precompose_sp.SORT");
-system("sort -k 2 compose_sp.TEMP \>  decompose_sp.SORT");
-
-# print  -------------------------------------------------------------------
-
-print ("\/\* DO NOT EDIT BY HAND\!\!\!                                           \*\/\n");
-print ("\/\* This file is generated by                                        \*\/\n");
-printf ("\/\*              contrib/misc/make-precompose.h.pl %s   \*\/\n", $ARGV[0]);
-print ("\n");
-printf ("\/\* %s is got from                                      \*\/\n", $ARGV[0]);
-print ("\/\* http\:\/\/www.unicode.org\/Public\/UNIDATA\/UnicodeData.txt            \*\/\n");
-print ("\n");
-
-print ("\#define SBASE 0xAC00\n");
-print ("\#define LBASE 0x1100\n");
-print ("\#define VBASE 0x1161\n");
-print ("\#define TBASE 0x11A7\n");
-print ("\#define LCOUNT 19\n");
-print ("\#define VCOUNT 21\n");
-print ("\#define TCOUNT 28\n");
-print ("\#define NCOUNT 588     \/\* (VCOUNT \* TCOUNT) \*\/\n");
-print ("\#define SCOUNT 11172   \/\* (LCOUNT \* NCOUNT) \*\/\n");
-print ("\n");
-
-printf ("\#define PRECOMP_COUNT %d\n", $comp_count);
-printf ("\#define DECOMP_COUNT %d\n", $comp_count);
-printf ("\#define MAXCOMBLEN %d\n", $maxcomblen);
-print ("\n");
-printf ("\#define PRECOMP_SP_COUNT %d\n", $comp_sp_count);
-printf ("\#define DECOMP_SP_COUNT %d\n", $comp_sp_count);
-printf ("\#define MAXCOMBSPLEN %d\n", $maxcombsplen);
-print ("\n");
-printf ("\#define COMBBUFLEN %d  \/\* max\(MAXCOMBLEN\,MAXCOMBSPLEN\) \*\/\n", $combbuflen);
-print ("\n");
-
-print ("static const struct \{\n");
-print ("  unsigned int replacement\;\n");
-print ("  unsigned int base\;\n");
-print ("  unsigned int comb\;\n");
-print ("\} precompositions\[\] \= \{\n");
-
-system("cat precompose.SORT");
-
-print ("\}\;\n");
-print ("\n");
-
-print ("static const struct \{\n");
-print ("  unsigned int replacement\;\n");
-print ("  unsigned int base\;\n");
-print ("  unsigned int comb\;\n");
-print ("\} decompositions\[\] \= \{\n");
-
-system("cat decompose.SORT");
-
-print ("\}\;\n");
-print ("\n");
-
-
-
-print ("static const struct \{\n");
-print ("  unsigned int replacement_sp\;\n");
-print ("  unsigned int base_sp\;\n");
-print ("  unsigned int comb_sp\;\n");
-print ("\} precompositions_sp\[\] \= \{\n");
-
-system("cat precompose_sp.SORT");
-
-print ("\}\;\n");
-print ("\n");
-
-print ("static const struct \{\n");
-print ("  unsigned int replacement_sp\;\n");
-print ("  unsigned int base_sp\;\n");
-print ("  unsigned int comb_sp\;\n");
-print ("\} decompositions_sp\[\] \= \{\n");
-
-system("cat decompose_sp.SORT");
-
-print ("\}\;\n");
-print ("\n");
-
-print ("\/\* EOF \*\/\n");
-
-# EOF
index 97941431cfb08e22c4630f89f31c94687c2428e0..c2af4d0e544e6c525088624bf689a6e12519089c 100644 (file)
@@ -1,6 +1,5 @@
 Makefile
 Makefile.in
-afpd-mtab.pl
 apple_cleanup
 apple_cp
 apple_mv
index c8cefe1e8ef8c8d0520b3c673e79474f43db1601..5e4aaa91abe17fedd8f559c67f94567a379e51de 100644 (file)
@@ -5,7 +5,6 @@ pkgconfdir = @PKGCONFDIR@
 GENERATED_FILES = lp2pap.sh
 TEMPLATE_FILES = lp2pap.sh.tmpl
 PERLSCRIPTS = \
-       afpd-mtab.pl \
        asip-status.pl \
        apple_dump
 
@@ -21,4 +20,4 @@ CLEANFILES = $(GENERATED_FILES)
 
 bin_SCRIPTS = $(PERLSCRIPTS) $(GENERATED_FILES)
 
-EXTRA_DIST = $(TEMPLATE_FILES)
+EXTRA_DIST = $(TEMPLATE_FILES) make-casetable.pl make-precompose.h.pl
diff --git a/contrib/shell_utils/afpd-mtab.pl.in b/contrib/shell_utils/afpd-mtab.pl.in
deleted file mode 100644 (file)
index 798af37..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#!@PERL@
-#
-# $Id: afpd-mtab.pl.in,v 1.1 2002-01-17 05:59:25 srittau Exp $
-#
-# Create an afpd.mtab on standard output from the mtab-format file on standard
-# input.
-#
-#      afpd-mtab.pl < /etc/mtab > /etc/afpd.mtab
-#
-#    Modification history:
-#
-# created.  -- rgr, 9-Apr-01.
-#
-
-print("# afpd.mtab, generated by afpd-mtab.pl on ",
-      `date`);
-while (<>) {
-    ($device, $mount_point, $fstype) = split;
-    next
-       if $device eq 'none' || $mount_point eq '/boot';
-    printf("%2d %-10s %s\n", ++$did_index, $device, $mount_point);
-}
diff --git a/contrib/shell_utils/make-casetable.pl b/contrib/shell_utils/make-casetable.pl
new file mode 100755 (executable)
index 0000000..4c71947
--- /dev/null
@@ -0,0 +1,324 @@
+#!/usr/bin/perl
+#
+# usage: make-casetable.pl <infile> <outfile1> <outfile2>
+#        make-casetable.pl UnicodeData.txt utf16_casetable.h utf16_case.c
+#
+# (c) 2011 by HAT <hat@fa2.so-net.ne.jp>
+#
+#  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.
+#
+
+# See
+# http://www.unicode.org/reports/tr44/
+# http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
+
+# One block has 64 chars.
+#
+# BMP
+# block    0 = dummy
+# block    1 = U+0000 - U+003F
+# block    2 = U+0040 - U+007F
+# .....
+# block 1024 = U+FFC0 - U+FFFF
+# block 1025 = dummy
+#
+# Surrogate Pair
+# block  1024 = dummy
+# block  1025 = U+010000 - U+01003F
+# block  1026 = U+010040 - U+01007F
+# .....
+# block 17408 = U+10FFC0 - U+10FFFF
+# block 17409 = dummy
+#
+# Dummy block is for edge detection.
+# If block include upper/lower chars, block_enable[]=1.
+
+use strict;
+use warnings;
+
+our $code0;
+our $Name1;
+our $General_Category2;
+our $Canonical_Combining_Class3;
+our $Bidi_Class4;
+our $Decomposition_Mapping5;
+our $Numeric_Value6;
+our $Numeric_Value7;
+our $Numeric_Value8;
+our $Bidi_Mirrored9;
+our $Unicode_1_Name10;
+our $ISO_Comment11;
+our $Simple_Uppercase_Mapping12;
+our $Simple_Lowercase_Mapping13;
+our $Simple_Titlecase_Mapping14;
+
+our $hex_code0;
+our $Mapping;
+our $hex_Mapping;
+
+our $char;
+our $sp;
+our $block;
+
+our @table;
+our @table_sp;
+
+our @block_enable;
+our @block_enable_sp;
+
+our $table_no;
+our $block_start;
+our $block_end;
+our $char_start;
+our $char_end;
+
+open(CHEADER, ">$ARGV[1]");
+open(CSOURCE, ">$ARGV[2]");
+
+printf (CHEADER "\/\*\n");
+printf (CHEADER "DO NOT EDIT BY HAND\!\!\!\n");
+printf (CHEADER "\n");
+printf (CHEADER "This file is generated by\n");
+printf (CHEADER " contrib/shell_utils/make-casetable.pl %s %s %s\n", $ARGV[0], $ARGV[1], $ARGV[2]);
+printf (CHEADER "\n");
+printf (CHEADER "%s is got from\n", $ARGV[0]);
+printf (CHEADER "http\:\/\/www.unicode.org\/Public\/UNIDATA\/UnicodeData.txt\n");
+printf (CHEADER "\*\/\n");
+printf (CHEADER "\n");
+
+printf (CSOURCE "\/\*\n");
+printf (CSOURCE "DO NOT EDIT BY HAND\!\!\!\n");
+printf (CSOURCE "\n");
+printf (CSOURCE "This file is generated by\n");
+printf (CSOURCE " contrib/shell_utils/make-casetable.pl %s %s %s\n", $ARGV[0], $ARGV[1], $ARGV[2]);
+printf (CSOURCE "\n");
+printf (CSOURCE "%s is got from\n", $ARGV[0]);
+printf (CSOURCE "http\:\/\/www.unicode.org\/Public\/UNIDATA\/UnicodeData.txt\n");
+printf (CSOURCE "\*\/\n");
+printf (CSOURCE "\n");
+printf (CSOURCE "\#include \<stdint.h\>\n");
+printf (CSOURCE "\#include \<atalk\/unicode.h\>\n");
+printf (CSOURCE "\#include \"%s\"\n", $ARGV[1]);
+printf (CSOURCE "\n");
+
+&make_array("upper");
+&make_array("lower");
+
+printf (CHEADER "\/\* EOF \*\/\n");
+printf (CSOURCE "\/\* EOF \*\/\n");
+
+close(CHEADER);
+close(CSOURCE);
+
+
+###########################################################################
+sub make_array{
+
+    # init table -----------------------------------------------------
+
+    for ($char = 0 ; $char <= 0xFFFF ; $char++) {
+        $table[$char][0] = $char;       # mapped char
+        $table[$char][1] = $char;       # orig char
+        $table[$char][2] = "";          # char name
+    }
+
+    for ($char = 0x10000 ; $char <= 0x10FFFF ; $char++) {
+        $sp = ((0xD800 - (0x10000 >> 10) + ($char >> 10)) << 16)
+            + (0xDC00 + ($char & 0x3FF));
+        $table_sp[$char][0] = $sp;      # mapped surrogate pair
+        $table_sp[$char][1] = $sp;      # orig surrogate pair
+        $table_sp[$char][2] = $char;    # mapped char
+        $table_sp[$char][3] = $char;    # orig char
+        $table_sp[$char][4] = "";       # char name
+    }
+
+    for ($block = 0 ; $block <= 1025 ; $block++) {
+        $block_enable[$block] = 0;
+    }
+
+    $block_enable[1] = 1;           # ASCII block is forcibly included
+    $block_enable[2] = 1;           # in the array for Speed-Up.
+
+    for ($block = 1024 ; $block <= 17409 ; $block++) {
+        $block_enable_sp[$block] = 0;
+    }
+
+    # write data to table --------------------------------------------
+
+    open(UNICODEDATA, "<$ARGV[0]");
+
+    while (<UNICODEDATA>) {
+        chop;
+        (
+            $code0,
+            $Name1,
+            $General_Category2,
+            $Canonical_Combining_Class3,
+            $Bidi_Class4,
+            $Decomposition_Mapping5,
+            $Numeric_Value6,
+            $Numeric_Value7,
+            $Numeric_Value8,
+            $Bidi_Mirrored9,
+            $Unicode_1_Name10,
+            $ISO_Comment11,
+            $Simple_Uppercase_Mapping12,
+            $Simple_Lowercase_Mapping13,
+            $Simple_Titlecase_Mapping14
+        ) = split(/\;/);
+
+        if ($_[0] eq "upper") {
+            $Mapping = $Simple_Uppercase_Mapping12;
+        } elsif ($_[0] eq "lower") {
+            $Mapping = $Simple_Lowercase_Mapping13;
+        } else {
+            exit(1);
+        }
+
+        next if ($Mapping eq "");
+
+        $hex_code0 = hex($code0);
+        $hex_Mapping = hex($Mapping);
+
+        if ($hex_code0 <= 0xFFFF) {
+            $table[$hex_code0][0] = $hex_Mapping;
+            #table[$hex_code0][1]   already set
+            $table[$hex_code0][2] = $Name1;
+            $block_enable[($hex_code0 / 64) +1] = 1;
+        } else {
+            $sp = ((0xD800 - (0x10000 >> 10) + ($hex_Mapping >> 10)) << 16)
+                + (0xDC00 + ($hex_Mapping & 0x3FF));
+            $table_sp[$hex_code0][0] = $sp;
+            #table_sp[$hex_code0][1]   already set
+            $table_sp[$hex_code0][2] = $hex_Mapping;
+            #table_sp[$hex_code0][3]   already set
+            $table_sp[$hex_code0][4] = $Name1;
+            $block_enable_sp[($hex_code0 / 64) +1] = 1;
+        }
+    }
+
+    close(UNICODEDATA);
+
+    # array for BMP --------------------------------------------------
+
+    printf(CSOURCE "\/*******************************************************************\n");
+    printf(CSOURCE " Convert a wide character to %s case.\n", $_[0]);
+    printf(CSOURCE "*******************************************************************\/\n");
+    printf(CSOURCE "ucs2\_t to%s\_w\(ucs2\_t val\)\n", $_[0]);
+    printf(CSOURCE "{\n");
+
+    $table_no = 1;
+
+    for ($block = 1 ; $block <= 1024 ; $block++) {
+
+        # rising edge detection
+        if ($block_enable[$block - 1] == 0 && $block_enable[$block] == 1) {
+            $block_start = $block;
+        }
+
+        # falling edge detection
+        if ($block_enable[$block] == 1 && $block_enable[$block + 1] == 0) {
+            $block_end = $block;
+
+            $char_start = ($block_start -1)* 64;
+            $char_end = ($block_end * 64) -1;
+
+            printf(CHEADER "static const u\_int16\_t %s\_table\_%d\[%d\] \= \{\n",
+                   $_[0], $table_no, $char_end - $char_start +1);
+
+            for ($char = $char_start ; $char <= $char_end ; $char++) {
+                printf(CHEADER "  0x%04X, /*U\+%04X*/ /*%s*/\n",
+                       $table[$char][0],
+                       $table[$char][1],
+                       $table[$char][2]
+                   );
+            }
+            printf(CHEADER "\}\;\n");
+            printf(CHEADER "\n");
+
+            if ($char_start == 0x0000) {
+                printf(CSOURCE "    if \( val \<\= 0x%04X)\n",
+                       $char_end);
+                printf(CSOURCE "        return %s\_table\_%d\[val]\;\n",
+                       $_[0], $table_no);
+            } else {
+                printf(CSOURCE "    if \( val \>\= 0x%04X \&\& val \<\= 0x%04X)\n",
+                       $char_start, $char_end);
+                printf(CSOURCE "        return %s\_table\_%d\[val-0x%04X\]\;\n",
+                       $_[0], $table_no, $char_start);
+            }
+            printf(CSOURCE "\n");
+
+            $table_no++;
+        }
+    }
+
+    printf(CSOURCE "\treturn \(val\)\;\n");
+    printf(CSOURCE "\}\n");
+    printf(CSOURCE "\n");
+
+    # array for Surrogate Pair ---------------------------------------
+
+    printf(CSOURCE "\/*******************************************************************\n");
+    printf(CSOURCE " Convert a surrogate pair to %s case.\n", $_[0]);
+    printf(CSOURCE "*******************************************************************\/\n");
+    printf(CSOURCE "uint32\_t to%s\_sp\(uint32\_t val\)\n", $_[0]);
+    printf(CSOURCE "{\n");
+
+    $table_no = 1;
+
+    for ($block = 1025 ; $block <= 17408 ; $block++) {
+
+        # rising edge detection
+        if ((($block_enable_sp[$block - 1] == 0) || ((($block - 1) & 0xF) == 0))
+                && ($block_enable_sp[$block] == 1)) {
+            $block_start = $block;
+        }
+
+        # falling edge detection
+        if (($block_enable_sp[$block] == 1) &&
+                ((($block - 1) & 0xF == 0xF) || ($block_enable_sp[$block + 1] == 0))) {
+            $block_end = $block;
+
+            $char_start = ($block_start -1)* 64;
+            $char_end = ($block_end * 64) -1;
+
+            printf(CHEADER "static const u\_int32\_t %s\_table\_sp\_%d\[%d\] \= \{\n",
+                   $_[0], $table_no, $char_end - $char_start +1);
+
+            for ($char = $char_start ; $char <= $char_end ; $char++) {
+                printf(CHEADER "  0x%08X, /*0x%08X*/ /*U\+%06X*/ /*U\+%06X*/ /*%s*/\n",
+                       $table_sp[$char][0],
+                       $table_sp[$char][1],
+                       $table_sp[$char][2],
+                       $table_sp[$char][3],
+                       $table_sp[$char][4]
+                   );
+            }
+            printf(CHEADER "\}\;\n");
+            printf(CHEADER "\n");
+
+            printf(CSOURCE "    if \( val \>\= 0x%08X \&\& val \<\= 0x%08X)\n",
+                   $table_sp[$char_start][1], $table_sp[$char_end][1]);
+            printf(CSOURCE "        return %s\_table\_sp\_%d\[val-0x%08X\]\;\n",
+                   $_[0], $table_no, $table_sp[$char_start][1]);
+            printf(CSOURCE "\n");
+
+            $table_no++;
+        }
+    }
+
+    printf(CSOURCE "\treturn \(val\)\;\n");
+    printf(CSOURCE "\}\n");
+    printf(CSOURCE "\n");
+}
+
+# EOF
diff --git a/contrib/shell_utils/make-precompose.h.pl b/contrib/shell_utils/make-precompose.h.pl
new file mode 100755 (executable)
index 0000000..ad42d9c
--- /dev/null
@@ -0,0 +1,260 @@
+#!/usr/bin/perl
+#
+# usage: make-precompose.h.pl UnicodeData.txt > precompose.h
+#
+# (c) 2008-2011 by HAT <hat@fa2.so-net.ne.jp>
+#
+#  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.
+# 
+
+# See
+# http://www.unicode.org/Public/UNIDATA/UCD.html
+# http://www.unicode.org/reports/tr15/
+# http://www.unicode.org/Public/*/ucd/UnicodeData*.txt
+# http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
+
+
+# temp files for binary search (compose.TEMP, compose_sp.TEMP) -------------
+
+open(UNICODEDATA, "<$ARGV[0]");
+
+open(COMPOSE_TEMP, ">compose.TEMP");
+open(COMPOSE_SP_TEMP, ">compose_sp.TEMP");
+
+while (<UNICODEDATA>) {
+    chop;
+    (
+     $code0,
+     $Name1,
+     $General_Category2,
+     $Canonical_Combining_Class3,
+     $Bidi_Class4,
+     $Decomposition_Mapping5,
+     $Numeric_Value6,
+     $Numeric_Value7,
+     $Numeric_Value8,
+     $Bidi_Mirrored9,
+     $Unicode_1_Name10,
+     $ISO_Comment11,
+     $Simple_Uppercase_Mapping12,
+     $Simple_Lowercase_Mapping13,
+     $Simple_Titlecase_Mapping14
+    ) = split(/\;/);
+
+    if (($Decomposition_Mapping5 ne "") && ($Decomposition_Mapping5 !~ /\</) && ($Decomposition_Mapping5 =~ / /)) {
+       ($base, $comb) = split(/ /,$Decomposition_Mapping5);
+
+       $leftbracket  = "  { ";
+       $rightbracket =" },     ";
+
+       # AFP 3.x Spec
+       if ( ((0x2000  <= hex($code0)) && (hex($code0) <=  0x2FFF))
+            || ((0xFE30  <= hex($code0)) && (hex($code0) <=  0xFE4F))
+            || ((0x2F800 <= hex($code0)) && (hex($code0) <= 0x2FA1F))) {
+           $leftbracket  = "\/\*{ ";
+           $rightbracket =" },\*\/   ";
+       }
+
+       if (hex($code0) > 0xFFFF) {
+
+           $code0_sp_hi = 0xD800 - (0x10000 >> 10) + (hex($code0) >> 10);
+           $code0_sp_lo = 0xDC00 + (hex($code0) & 0x3FF);
+
+           $base_sp_hi = 0xD800 - (0x10000 >> 10) + (hex($base) >> 10);
+           $base_sp_lo = 0xDC00 + (hex($base) & 0x3FF);
+
+           $comb_sp_hi = 0xD800 - (0x10000 >> 10) + (hex($comb) >> 10);
+           $comb_sp_lo = 0xDC00 + (hex($comb) & 0x3FF);
+
+           printf(COMPOSE_SP_TEMP "%s0x%04X%04X, 0x%04X%04X, 0x%04X%04X%s\/\* %s \*\/\n",
+                  $leftbracket, $code0_sp_hi ,$code0_sp_lo, $base_sp_hi, $base_sp_lo, $comb_sp_hi, $comb_sp_lo, $rightbracket, $Name1);
+
+           $leftbracket  = "\/\*{ ";
+           $rightbracket =" },\*\/   ";
+       }
+
+       printf(COMPOSE_TEMP "%s0x%08X, 0x%08X, 0x%08X%s\/\* %s \*\/\n", $leftbracket, hex($code0), hex($base), hex($comb), $rightbracket, $Name1);
+
+    }
+}
+
+close(UNICODEDATA);
+
+close(COMPOSE_TEMP);
+close(COMPOSE_SP_TEMP);
+
+# macros for BMP (PRECOMP_COUNT, DECOMP_COUNT, MAXCOMBLEN) ----------------
+
+open(COMPOSE_TEMP, "<compose.TEMP");
+
+@comp_table = ();
+$comp_count = 0;
+
+while (<COMPOSE_TEMP>) {
+    if (m/^\/\*/) {
+       next;
+    }
+    $comp_table[$comp_count][0] = substr($_, 4, 10);
+    $comp_table[$comp_count][1] = substr($_, 16, 10);
+    $comp_count++;
+}
+
+$maxcomblen = 2;      # Hangul's maxcomblen is already 2. That is, VT.
+
+for ($i = 0 ; $i < $comp_count ; $i++) {
+    $base = $comp_table[$i][1];
+    $comblen = 1;
+    $j = 0;
+    while ($j < $comp_count) {
+       if ($base ne $comp_table[$j][0]) {
+           $j++;
+           next;
+       } else {
+           $comblen++;
+           $base =  $comp_table[$j][1];
+           $j = 0;
+       }
+    }
+    $maxcomblen = ($maxcomblen > $comblen) ? $maxcomblen : $comblen;
+}
+
+close(COMPOSE_TEMP);
+
+# macros for SP (PRECOMP_SP_COUNT,DECOMP_SP_COUNT, MAXCOMBSPLEN) -----------
+
+open(COMPOSE_SP_TEMP, "<compose_sp.TEMP");
+
+@comp_sp_table = ();
+$comp_sp_count = 0;
+
+while (<COMPOSE_SP_TEMP>) {
+    if (m/^\/\*/) {
+       next;
+    }
+    $comp_sp_table[$comp_sp_count][0] = substr($_, 4, 10);
+    $comp_sp_table[$comp_sp_count][1] = substr($_, 16, 10);
+    $comp_sp_count++;
+}
+
+$maxcombsplen = 2;     # one char have 2 codepoints, like a D8xx DCxx.
+
+for ($i = 0 ; $i < $comp_sp_count ; $i++) {
+    $base_sp = $comp_sp_table[$i][1];
+    $comblen = 2;
+    $j = 0;
+    while ($j < $comp_sp_count) {
+       if ($base_sp ne $comp_sp_table[$j][0]) {
+           $j++;
+           next;
+       } else {
+           $comblen += 2;
+           $base_sp =  $comp_sp_table[$j][1];
+           $j = 0;
+       }
+    }
+    $maxcombsplen = ($maxcombsplen > $comblen) ? $maxcombsplen : $comblen;
+}
+
+close(COMPOSE_SP_TEMP);
+
+# macro for buffer length (COMBBUFLEN) -------------------------------------
+
+$combbuflen = ($maxcomblen > $maxcombsplen) ? $maxcomblen : $maxcombsplen;
+
+# sort ---------------------------------------------------------------------
+
+system("sort -k 3 compose.TEMP \> precompose.SORT");
+system("sort -k 2 compose.TEMP \>  decompose.SORT");
+
+system("sort -k 3 compose_sp.TEMP \> precompose_sp.SORT");
+system("sort -k 2 compose_sp.TEMP \>  decompose_sp.SORT");
+
+# print  -------------------------------------------------------------------
+
+print ("\/\* DO NOT EDIT BY HAND\!\!\!                                           \*\/\n");
+print ("\/\* This file is generated by                                        \*\/\n");
+printf ("\/\*       contrib/shell_utils/make-precompose.h.pl %s   \*\/\n", $ARGV[0]);
+print ("\n");
+printf ("\/\* %s is got from                                      \*\/\n", $ARGV[0]);
+print ("\/\* http\:\/\/www.unicode.org\/Public\/UNIDATA\/UnicodeData.txt            \*\/\n");
+print ("\n");
+
+print ("\#define SBASE 0xAC00\n");
+print ("\#define LBASE 0x1100\n");
+print ("\#define VBASE 0x1161\n");
+print ("\#define TBASE 0x11A7\n");
+print ("\#define LCOUNT 19\n");
+print ("\#define VCOUNT 21\n");
+print ("\#define TCOUNT 28\n");
+print ("\#define NCOUNT 588     \/\* (VCOUNT \* TCOUNT) \*\/\n");
+print ("\#define SCOUNT 11172   \/\* (LCOUNT \* NCOUNT) \*\/\n");
+print ("\n");
+
+printf ("\#define PRECOMP_COUNT %d\n", $comp_count);
+printf ("\#define DECOMP_COUNT %d\n", $comp_count);
+printf ("\#define MAXCOMBLEN %d\n", $maxcomblen);
+print ("\n");
+printf ("\#define PRECOMP_SP_COUNT %d\n", $comp_sp_count);
+printf ("\#define DECOMP_SP_COUNT %d\n", $comp_sp_count);
+printf ("\#define MAXCOMBSPLEN %d\n", $maxcombsplen);
+print ("\n");
+printf ("\#define COMBBUFLEN %d  \/\* max\(MAXCOMBLEN\,MAXCOMBSPLEN\) \*\/\n", $combbuflen);
+print ("\n");
+
+print ("static const struct \{\n");
+print ("  unsigned int replacement\;\n");
+print ("  unsigned int base\;\n");
+print ("  unsigned int comb\;\n");
+print ("\} precompositions\[\] \= \{\n");
+
+system("cat precompose.SORT");
+
+print ("\}\;\n");
+print ("\n");
+
+print ("static const struct \{\n");
+print ("  unsigned int replacement\;\n");
+print ("  unsigned int base\;\n");
+print ("  unsigned int comb\;\n");
+print ("\} decompositions\[\] \= \{\n");
+
+system("cat decompose.SORT");
+
+print ("\}\;\n");
+print ("\n");
+
+
+
+print ("static const struct \{\n");
+print ("  unsigned int replacement_sp\;\n");
+print ("  unsigned int base_sp\;\n");
+print ("  unsigned int comb_sp\;\n");
+print ("\} precompositions_sp\[\] \= \{\n");
+
+system("cat precompose_sp.SORT");
+
+print ("\}\;\n");
+print ("\n");
+
+print ("static const struct \{\n");
+print ("  unsigned int replacement_sp\;\n");
+print ("  unsigned int base_sp\;\n");
+print ("  unsigned int comb_sp\;\n");
+print ("\} decompositions_sp\[\] \= \{\n");
+
+system("cat decompose_sp.SORT");
+
+print ("\}\;\n");
+print ("\n");
+
+print ("\/\* EOF \*\/\n");
+
+# EOF
diff --git a/contrib/wireshark/cnid.lua b/contrib/wireshark/cnid.lua
deleted file mode 100644 (file)
index 3b21723..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
--- 
--- Netatalk DBD protocol 
--- wireshark -X lua_script:cnid.lua
--- don't forget to comment out the line disable_lua = true; do return end;
--- in /etc/wireshark/init.lua
-
--- global environment
-local b = _G
-
--- declare our protocol
-local dbd_proto = Proto("dbd","Netatalk Dbd Wire Protocol")
-
-local cmd = ProtoField.uint32("dbd.cmd", "Request") -- , base.HEX
-local len = ProtoField.uint32("dbd.name.len", "Name Length")
-local filename = ProtoField.string("dbd.name", "Name")
-local error = ProtoField.uint32("dbd.error", "Error code")
-local cnid = ProtoField.uint32("dbd.cnid", "Cnid")
-local did  = ProtoField.uint32("dbd.did", "Parent Directory Id")
-local dev  = ProtoField.uint64("dbd.dev", "Device number")
-local ino  = ProtoField.uint64("dbd.ino", "Inode number")
-local type = ProtoField.uint32("dbd.type", "File type")
-
-dbd_proto.fields = {cmd, error, cnid, did, dev, ino, type, filename, len}
-
---- Request list
-local Cmd = { [3] = "add", 
-             [4] = "get", 
-             [5] = "resolve", 
-             [6] = "lookup", 
-             [7] = "update", 
-             [8] = "delete", 
-             [11] = "timestamp" 
-           }
-
---- display a filename 
-local function fname(buffer, pinfo, tree, len, ofs)
-
-    pinfo.cols.info:append(" Name=" .. buffer(ofs +4, len):string())
-
-    local subtree = tree:add(buffer(ofs, len +4), buffer(ofs +4, len):string())
-    subtree:add(filename, buffer(ofs +4, len))
-
-    return subtree
-end
-
--- create a function to dissect it
-function dbd_proto.dissector(buffer, pinfo, tree)
-
-
-    pinfo.cols.protocol = "DBD"
-
-    local subtree = tree:add(dbd_proto,buffer(),"Netatalk DBD Wire Protocol")
-
-    if pinfo.dst_port == 4700 then
-           pinfo.cols.info = "Query"
-           local val = buffer(0,4):uint()
-           local item = subtree:add(cmd, buffer(0,4))
-           if Cmd[val] then
-               item:append_text(" (" .. Cmd[val] .. ")")
-               pinfo.cols.info = Cmd[val]
-
-               local val = buffer(4,4):uint()
-               if val ~= 0 then
-                       pinfo.cols.info:append(" Cnid=" .. val)
-               end
-               subtree:add(cnid, buffer(4, 4))
-               subtree:add(dev, buffer(8, 8))
-               subtree:add(ino, buffer(16, 8))
-               subtree:add(type, buffer(24, 4))
-
-               local val = buffer(28,4):uint()
-               if val ~= 0 then
-                  pinfo.cols.info:append(" Did=" .. val)
-               end
-               subtree:add(did, buffer(28, 4))
-
-               local val = buffer(36,4):uint()
-               if val ~= 0 then
-                  item = fname(buffer, pinfo, subtree, val, 36)
-                  item:add(len, buffer(36, 4))
-                       
-               end
-           end
-    else
-           pinfo.cols.info = "Reply"
-
-           local rply = {}
-           
-           local val = buffer(0,4):uint()
-           rply.error = val
-           subtree:add(error, buffer(0,4))
-           if val ~= 0 then
-               pinfo.cols.info:append(" Error=" .. val)
-           end
-
-           val = buffer(4,4):uint()
-           rply.cnid = val
-           subtree:add(cnid, buffer(4,4))
-           if val ~= 0 then
-               pinfo.cols.info:append(" Cnid=" .. val)
-           end
-
-           val = buffer(8,4):uint()
-           rply.did = val
-           subtree:add(did, buffer(8,4))
-           if val ~= 0 then
-               pinfo.cols.info:append(" Did=" .. val)
-           end
-
-           val = buffer(16,4):uint()
-           rply.len = val
-           
-           if rply.error == 0 and rply.did ~= 0 then
-              subtree = fname(buffer, pinfo, subtree, val, 16)
-              subtree:add(len, buffer(16,4))
-           end
-    end
-end
-
--- load the tcp.port table
-local tcp_table = DissectorTable.get("tcp.port")
--- register our protocol 
-tcp_table:add(4700, dbd_proto)
index 765af279125f6f94cce45f0276e614a7be1bbfe3..5d9bda826dc9e0427fa7fdf3efe9178d42ab885e 100644 (file)
@@ -1,3 +1,3 @@
 # Makefile.am for distrib/
 
-SUBDIRS = config initscripts m4
+SUBDIRS = config initscripts m4 systemd
index af1675fd9ea720b0329398be8250ad7a1b996121..150a119881a3e839df9631f4cb5f9366fd9bf92d 100644 (file)
@@ -9,5 +9,7 @@ rc.atalk.sysv
 service.atalk.redhat-systemd
 netatalk
 atalk
+netatalk.service
+netatalk.sh
 .gitignore
 *.o
index ac5d8da0ac6337ef81b0805a8cea0530ca3abd25..219f4ac944ae0255c75f4926ba5d749824c16dea 100644 (file)
@@ -4,7 +4,7 @@
 # Required-Start:    $remote_fs $syslog
 # Required-Stop:     $remote_fs $syslog
 # Default-Start:     2 3 4 5
-# Default-Stop:      1
+# Default-Stop:      0 1 6
 ### END INIT INFO
 #
 # netatalk      Netatalk :NETATALK_VERSION: initscript
index 58f197aed36f8a98949ab991df974e0105ca5e61..e0bd7fb1484d6855b27d9485a3c6fc641b504b7a 100644 (file)
@@ -2,6 +2,9 @@
 
 # Netatalk :NETATALK_VERSION: startup script for systemd.
 
+# The method of using this script is not suitable.
+# This script will be deleted in the future.
+
 ATALK_BIN=:BINDIR:
 ATALK_CONF_DIR=:ETCDIR:
 ATALK_SBIN=:SBINDIR:
index cd7a3dfcfb4e798a32d2e9bbb7f6a1a2918f5576..1af8576758b732d436ac2f4c4162005cec6de6ff 100644 (file)
@@ -1,5 +1,9 @@
 # This file is part of netatalk :NETATALK_VERSION:.
 
+# The method of using shell-script "netatalk.sh" is not suitable.
+# The future service files are due to start daemons directly.
+# See netatalk-xxx/distrib/systemd/ directory in tarball.
+
 [Unit]
 Description=File and Printer sharing for Macintosh clients
 After=syslog.target network.target
diff --git a/distrib/systemd/Makefile.am b/distrib/systemd/Makefile.am
new file mode 100644 (file)
index 0000000..ff8c5cd
--- /dev/null
@@ -0,0 +1,3 @@
+# Makefile for distrib/systemd/
+
+EXTRA_DIST = README netatalk-afpd.service netatalk-cnid_metad.service
diff --git a/distrib/systemd/README b/distrib/systemd/README
new file mode 100644 (file)
index 0000000..8d52e8d
--- /dev/null
@@ -0,0 +1,15 @@
+The service file of the current Netatalk is not appropriate because it use
+a shell-script "netatalk.sh".
+Two experimental files are for future netatalk.
+
+These files start daemons directly and do not read "netatalk.conf".
+Therefore, you need to edit files for setting options.
+
+ATALK_NAME:       set in afpd.conf instead
+AFPD_MAX_CLIENTS: set in netatalk-afpd.service by using -c
+AFPD_UAMLIST:     set in afpd.conf instead
+AFPD_GUEST:       set in afpd.conf instead
+CNID_CONFIG:      set in netatalk-cnid_metad.service by using -l and -f options
+
+There are no service files for atalkd, papd, timelord and a2boot
+because AppleTalk feature is due to be abolished in the future.
diff --git a/distrib/systemd/netatalk-afpd.service b/distrib/systemd/netatalk-afpd.service
new file mode 100644 (file)
index 0000000..7af238b
--- /dev/null
@@ -0,0 +1,16 @@
+# This is experimental service file.
+# See distrib/systemd/README
+
+[Unit]
+Description=Netatalk AFP fileserver for Macintosh clients
+After=syslog.target network.target slpd.service avahi-daemon.service netatalk-cnid_metad.service
+
+[Service]
+Type=forking
+GuessMainPID=no
+ExecStart=/usr/sbin/afpd -c 20
+Restart=always
+RestartSec=1
+
+[Install]
+WantedBy=multi-user.target
diff --git a/distrib/systemd/netatalk-cnid_metad.service b/distrib/systemd/netatalk-cnid_metad.service
new file mode 100644 (file)
index 0000000..6438229
--- /dev/null
@@ -0,0 +1,16 @@
+# This is experimental service file.
+# See distrib/systemd/README
+
+[Unit]
+Description=Netatalk CNID database daemon for afpd
+After=syslog.target network.target
+
+[Service]
+Type=forking
+GuessMainPID=no
+ExecStart=/usr/sbin/cnid_metad -l log_note
+Restart=always
+RestartSec=1
+
+[Install]
+WantedBy=multi-user.target
index fcc39995d952c9b684595ac6650c72a26a496442..40281bcc9b079260922af9db90b38a0c879f5069 100644 (file)
@@ -1,5 +1,6 @@
 /*
   Copyright (c) 2008, 2009, 2010 Frank Lahm <franklahm@gmail.com>
+  Copyright (c) 2011 Laura Mueller <laura-mueller@uni-duesseldorf.de>
 
   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
 #define MAP_MASK               31
 #define IS_DIR                 32
 
+/* bit flags for set_acl() and map_aces_darwin_to_posix() */
+#define HAS_DEFAULT_ACL 0x01
+#define HAS_EXT_DEFAULT_ACL 0x02
+
 /********************************************************
  * Solaris funcs
  ********************************************************/
@@ -397,79 +402,81 @@ static int posix_acl_rights(const char *path,
                             uint32_t *result)
 {
     EC_INIT;
-    int havemask = 0;
     int entry_id = ACL_FIRST_ENTRY;
-    uint32_t rights = 0, maskrights = 0;
+    uint32_t rights = 0; /* rights which do not depend on ACL_MASK */
+    uint32_t acl_rights = 0; /* rights which are subject to limitations imposed by ACL_MASK */
+    uint32_t mask_rights = 0xffffffff;
     uid_t *uid = NULL;
     gid_t *gid = NULL;
     acl_t acl = NULL;
     acl_entry_t e;
     acl_tag_t tag;
 
-    EC_NULL_LOG(acl = acl_get_file(path, ACL_TYPE_ACCESS));
-
-    /* itereate through all ACEs to get the mask */
-    while (!havemask && acl_get_entry(acl, entry_id, &e) == 1) {
-        entry_id = ACL_NEXT_ENTRY;
-        EC_ZERO_LOG(acl_get_tag_type(e, &tag));
-        switch (tag) {
-        case ACL_MASK:
-            maskrights = posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
-            LOG(log_maxdebug, logtype_afpd, "maskrights: 0x%08x", maskrights);
-            havemask = 1;
-            break;
-        default:
-            continue;
-        }
-    }
+    EC_NULL_LOGSTR(acl = acl_get_file(path, ACL_TYPE_ACCESS),
+                   "acl_get_file(\"%s\"): %s", fullpathname(path), strerror(errno));
 
-    /* itereate through all ACEs */
-    entry_id = ACL_FIRST_ENTRY;
+    /* Iterate through all ACEs. If we apply mask_rights later there is no need to iterate twice. */
     while (acl_get_entry(acl, entry_id, &e) == 1) {
         entry_id = ACL_NEXT_ENTRY;
         EC_ZERO_LOG(acl_get_tag_type(e, &tag));
+
         switch (tag) {
-        case ACL_USER:
-            EC_NULL_LOG(uid = (uid_t *)acl_get_qualifier(e));
-            if (*uid == uuid) {
-                LOG(log_maxdebug, logtype_afpd, "ACL_USER: %u", *uid);
-                rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
-            }
-            acl_free(uid);
-            uid = NULL;
-            break;
-        case ACL_USER_OBJ:
-            if (sb->st_uid == uuid) {
-                LOG(log_maxdebug, logtype_afpd, "ACL_USER_OBJ: %u", sb->st_uid);
-                rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
-            }
-            break;
-        case ACL_GROUP:
-            EC_NULL_LOG(gid = (gid_t *)acl_get_qualifier(e));
-            if (gmem(*gid)) {
-                LOG(log_maxdebug, logtype_afpd, "ACL_GROUP: %u", *gid);
-                rights |= (posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode)) & maskrights);
-            }
-            acl_free(gid);
-            gid = NULL;
-            break;
-        case ACL_GROUP_OBJ:
-            if (!(sb->st_uid == uuid) && gmem(sb->st_gid)) {
-                LOG(log_maxdebug, logtype_afpd, "ACL_GROUP_OBJ: %u", sb->st_gid);
-                rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));            
-            }
-            break;
-        case ACL_OTHER:
-            if (!(sb->st_uid == uuid) && !gmem(sb->st_gid)) {
-                LOG(log_maxdebug, logtype_afpd, "ACL_OTHER");
-                rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
-            }
-            break;
-        default:
-            continue;
+            case ACL_USER_OBJ:
+                if (sb->st_uid == uuid) {
+                    LOG(log_maxdebug, logtype_afpd, "ACL_USER_OBJ: %u", sb->st_uid);
+                    rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
+                }
+                break;
+
+            case ACL_USER:
+                EC_NULL_LOG(uid = (uid_t *)acl_get_qualifier(e));
+
+                if (*uid == uuid) {
+                    LOG(log_maxdebug, logtype_afpd, "ACL_USER: %u", *uid);
+                    acl_rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
+                }
+                acl_free(uid);
+                uid = NULL;
+                break;
+
+            case ACL_GROUP_OBJ:
+                if (!(sb->st_uid == uuid) && gmem(sb->st_gid)) {
+                    LOG(log_maxdebug, logtype_afpd, "ACL_GROUP_OBJ: %u", sb->st_gid);
+                    acl_rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
+                }
+                break;
+
+            case ACL_GROUP:
+                EC_NULL_LOG(gid = (gid_t *)acl_get_qualifier(e));
+
+                if (gmem(*gid)) {
+                    LOG(log_maxdebug, logtype_afpd, "ACL_GROUP: %u", *gid);
+                    acl_rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
+                }
+                acl_free(gid);
+                gid = NULL;
+                break;
+
+            case ACL_MASK:
+                mask_rights = posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
+                LOG(log_maxdebug, logtype_afpd, "maskrights: 0x%08x", mask_rights);
+                break;
+
+            case ACL_OTHER:
+                if (!(sb->st_uid == uuid) && !gmem(sb->st_gid)) {
+                    LOG(log_maxdebug, logtype_afpd, "ACL_OTHER");
+                    rights |= posix_permset_to_darwin_rights(e, S_ISDIR(sb->st_mode));
+                }
+                break;
+
+            default:
+                continue;
         }
     } /* while */
 
+    /* apply the mask and collect the rights */
+    rights |= (acl_rights & mask_rights);
+
     *result |= rights;
 
 EC_CLEANUP:
@@ -479,6 +486,143 @@ EC_CLEANUP:
     EC_EXIT;
 }
 
+/*!
+ * Helper function for posix_acls_to_uaperms() to convert Posix ACL permissions
+ * into access rights needed to fill ua_permissions of a FPUnixPrivs structure.
+ *
+ * @param entry     (r) Posix ACL entry
+ *
+ * @returns         access rights
+ */
+static u_char acl_permset_to_uarights(acl_entry_t entry) {
+    acl_permset_t permset;
+    u_char rights = 0;
+
+    if (acl_get_permset(entry, &permset) == -1)
+        return rights;
+
+#ifdef HAVE_ACL_GET_PERM_NP
+    if (acl_get_perm_np(permset, ACL_READ))
+#else
+    if (acl_get_perm(permset, ACL_READ))
+#endif
+        rights |= AR_UREAD;
+
+#ifdef HAVE_ACL_GET_PERM_NP
+    if (acl_get_perm_np(permset, ACL_WRITE))
+#else
+    if (acl_get_perm(permset, ACL_WRITE))
+#endif
+        rights |= AR_UWRITE;
+
+#ifdef HAVE_ACL_GET_PERM_NP
+    if (acl_get_perm_np(permset, ACL_EXECUTE))
+#else
+    if (acl_get_perm(permset, ACL_EXECUTE))
+#endif
+        rights |= AR_USEARCH;
+
+    return rights;
+}
+
+/*!
+ * Update FPUnixPrivs for a file-system object on a volume supporting ACLs
+ *
+ * Checks permissions granted by ACLS for a user to one fs-object and
+ * updates user and group permissions in given struct maccess. As OS X
+ * doesn't conform to Posix 1003.1e Draft 17 it expects proper group
+ * permissions in st_mode of struct stat even if the fs-object has an
+ * ACL_MASK entry, st_mode gets modified to properly reflect group
+ * permissions.
+ *
+ * @param path           (r) path to filesystem object
+ * @param sb             (rw) struct stat of path
+ * @param maccess        (rw) struct maccess of path
+ *
+ * @returns                  0 or -1 on error
+ */
+static int posix_acls_to_uaperms(const char *path, struct stat *sb, struct maccess *ma) {
+    EC_INIT;
+
+    int entry_id = ACL_FIRST_ENTRY;
+    acl_entry_t entry;
+    acl_tag_t tag;
+    acl_t acl = NULL;
+    uid_t *uid;
+    gid_t *gid;
+    uid_t whoami = geteuid();
+
+    u_char group_rights = 0x00;
+    u_char acl_rights = 0x00;
+    u_char mask = 0xff;
+
+    EC_NULL_LOG(acl = acl_get_file(path, ACL_TYPE_ACCESS));
+
+    /* iterate through all ACEs */
+    while (acl_get_entry(acl, entry_id, &entry) == 1) {
+        entry_id = ACL_NEXT_ENTRY;
+        EC_ZERO_LOG(acl_get_tag_type(entry, &tag));
+
+        switch (tag) {
+            case ACL_USER:
+                EC_NULL_LOG(uid = (uid_t *)acl_get_qualifier(entry));
+
+                if (*uid == uuid && !(whoami == sb->st_uid)) {
+                    LOG(log_maxdebug, logtype_afpd, "ACL_USER: %u", *uid);
+                    acl_rights |= acl_permset_to_uarights(entry);
+                }
+                acl_free(uid);
+                break;
+
+            case ACL_GROUP_OBJ:
+                group_rights = acl_permset_to_uarights(entry);
+                LOG(log_maxdebug, logtype_afpd, "ACL_GROUP_OBJ: %u", sb->st_gid);
+
+                if (gmem(sb->st_gid) && !(whoami == sb->st_uid))
+                    acl_rights |= group_rights;
+                break;
+
+            case ACL_GROUP:
+                EC_NULL_LOG(gid = (gid_t *)acl_get_qualifier(entry));
+
+                if (gmem(*gid) && !(whoami == sb->st_uid)) {
+                    LOG(log_maxdebug, logtype_afpd, "ACL_GROUP: %u", *gid);
+                    acl_rights |= acl_permset_to_uarights(entry);
+                }
+                acl_free(gid);
+                break;
+
+            case ACL_MASK:
+                mask = acl_permset_to_uarights(entry);
+                LOG(log_maxdebug, logtype_afpd, "ACL_MASK: 0x%02x", mask);
+                break;
+
+            default:
+                break;
+        }
+    }
+    /* apply the mask and adjust user and group permissions */
+    ma->ma_user |= (acl_rights & mask);
+    ma->ma_group = (group_rights & mask);
+
+    /* update st_mode to properly reflect group permissions */
+    sb->st_mode &= ~S_IRWXG;
+
+    if (ma->ma_group & AR_USEARCH)
+        sb->st_mode |= S_IXGRP;
+
+    if (ma->ma_group & AR_UWRITE)
+        sb->st_mode |= S_IWGRP;
+
+    if (ma->ma_group & AR_UREAD)
+        sb->st_mode |= S_IRGRP;
+
+EC_CLEANUP:
+    if (acl) acl_free(acl);
+
+    EC_EXIT;
+}
+
 /*!
  * Add entries of one acl to another acl
  *
@@ -523,7 +667,7 @@ static acl_perm_t map_darwin_right_to_posix_permset(uint32_t darwin_ace_rights,
     if (darwin_ace_rights & DARWIN_ACE_READ_DATA)
         perm |= ACL_READ;
 
-    if (darwin_ace_rights & (DARWIN_ACE_WRITE_DATA | (DARWIN_ACE_DELETE_CHILD & is_dir)))
+    if (darwin_ace_rights & (DARWIN_ACE_WRITE_DATA | (is_dir ? DARWIN_ACE_DELETE_CHILD : 0)))
         perm |= ACL_WRITE;
 
     if (darwin_ace_rights & DARWIN_ACE_EXECUTE)
@@ -583,7 +727,7 @@ static int posix_acl_add_perm(acl_t *aclp, acl_tag_t type, uid_t id, acl_perm_t
         EC_ZERO_LOG(acl_add_perm(permset, perm));
         EC_ZERO_LOG(acl_set_permset(e, permset));
     }
-    
+
 EC_CLEANUP:
     if (eid) acl_free(eid);
 
@@ -600,18 +744,23 @@ EC_CLEANUP:
  * - we throw away DARWIN_ACE_FLAGS_LIMIT_INHERIT (can't be mapped), thus the ACL will
  *   not be limited
  *
- * @param darwin_aces  (r)  pointer to darwin_aces buffer
- * @param def_aclp     (rw) directories: pointer to an initialized acl_t with the default acl
- *                          files: *def_aclp will be NULL
- * @param acc_aclp     (rw) pointer to an initialized acl_t with the access acl
- * @param ace_count    (r)  number of ACEs in darwin_aces buffer
+ * @param darwin_aces        (r)  pointer to darwin_aces buffer
+ * @param def_aclp           (rw) directories: pointer to an initialized acl_t with
+                                  the default acl files: *def_aclp will be NULL
+ * @param acc_aclp           (rw) pointer to an initialized acl_t with the access acl
+ * @param ace_count          (r)  number of ACEs in darwin_aces buffer
+ * @param default_acl_flags  (rw) flags to indicate if the object has a basic default
+ *                                acl or an extended default acl.
  *
- * @returns 0 on success storing the result in aclp, -1 on error.
+ * @returns 0 on success storing the result in aclp, -1 on error. default_acl_flags
+ * is set to HAS_DEFAULT_ACL|HAS_EXT_DEFAULT_ACL in case there is at least one
+ * extended default ace. Otherwise default_acl_flags is left unchanged.
  */
 static int map_aces_darwin_to_posix(const darwin_ace_t *darwin_aces,
                                     acl_t *def_aclp,
                                     acl_t *acc_aclp,
-                                    int ace_count)
+                                    int ace_count,
+                                    uint32_t *default_acl_flags)
 {
     EC_INIT;
     char *name = NULL;
@@ -667,7 +816,7 @@ static int map_aces_darwin_to_posix(const darwin_ace_t *darwin_aces,
             }
             /* add it as default ace */
             EC_ZERO_LOG(posix_acl_add_perm(def_aclp, tag, id, perm));
-
+            *default_acl_flags = (HAS_DEFAULT_ACL|HAS_EXT_DEFAULT_ACL);
 
             if (! (darwin_ace_flags & DARWIN_ACE_FLAGS_ONLY_INHERIT))
                 /* if it not a "inherit only" ace, it must be added as access aces too */
@@ -1099,44 +1248,77 @@ static int set_acl(const struct vol *vol,
                    uint32_t ace_count)
 {
     EC_INIT;
-    acl_t def_acl = NULL;
-    acl_t acc_acl = NULL;
+    struct stat st;
+    acl_t default_acl = NULL;
+    acl_t access_acl = NULL;
+    acl_entry_t entry;
+    acl_tag_t tag;
+    int entry_id = ACL_FIRST_ENTRY;
+    int has_def_acl = 0;
+    /* flags to indicate if the object has a minimal default acl and/or an extended
+     * default acl.
+     */
+    uint32_t default_acl_flags = 0;
 
     LOG(log_maxdebug, logtype_afpd, "set_acl: BEGIN");
 
-    struct stat st;
-    EC_ZERO_LOG_ERR(lstat(name, &st), AFPERR_NOOBJ);
+    EC_NULL_LOG_ERR(access_acl = acl_get_file(name, ACL_TYPE_ACCESS), AFPERR_MISC);
+
+    /* Iterate through acl and remove all extended acl entries. */
+    while (acl_get_entry(access_acl, entry_id, &entry) == 1) {
+        entry_id = ACL_NEXT_ENTRY;
+        EC_ZERO_LOG(acl_get_tag_type(entry, &tag));
+
+        if ((tag == ACL_USER) || (tag == ACL_GROUP) || (tag == ACL_MASK)) {
+            EC_ZERO_LOG_ERR(acl_delete_entry(access_acl, entry), AFPERR_MISC);
+        }
+    } /* while */
 
-    /* seed default ACL with access ACL */
-    if (S_ISDIR(st.st_mode))
-        EC_NULL_LOG_ERR(def_acl = acl_get_file(name, ACL_TYPE_ACCESS), AFPERR_MISC);
+   /* In case we are acting on a directory prepare a default acl. For files default_acl will be NULL.
+    * If the directory already has a default acl it will be preserved.
+    */
+   EC_ZERO_LOG_ERR(lstat(name, &st), AFPERR_NOOBJ);
 
-    /* for files def_acl will be NULL */
+   if (S_ISDIR(st.st_mode)) {
+       default_acl = acl_get_file(name, ACL_TYPE_DEFAULT);
 
-    /* create access acl from mode */
-    EC_NULL_LOG_ERR(acc_acl = acl_from_mode(st.st_mode), AFPERR_MISC);
+       if (default_acl) {
+           /* If default_acl is not empty then the dir has a default acl. */
+           if (acl_get_entry(default_acl, ACL_FIRST_ENTRY, &entry) == 1)
+               default_acl_flags = HAS_DEFAULT_ACL;
 
+           acl_free(default_acl);
+       }
+       default_acl = acl_dup(access_acl);
+    }
     /* adds the clients aces */
-    EC_ZERO_ERR(map_aces_darwin_to_posix(daces, &def_acl, &acc_acl, ace_count), AFPERR_MISC);
+    EC_ZERO_ERR(map_aces_darwin_to_posix(daces, &default_acl, &access_acl, ace_count, &default_acl_flags), AFPERR_MISC);
 
     /* calcuate ACL mask */
-    EC_ZERO_LOG_ERR(acl_calc_mask(&acc_acl), AFPERR_MISC);
+    EC_ZERO_LOG_ERR(acl_calc_mask(&access_acl), AFPERR_MISC);
 
     /* is it ok? */
-    EC_ZERO_LOG_ERR(acl_valid(acc_acl), AFPERR_MISC);
+    EC_ZERO_LOG_ERR(acl_valid(access_acl), AFPERR_MISC);
 
     /* set it */
-    EC_ZERO_LOG_ERR(acl_set_file(name, ACL_TYPE_ACCESS, acc_acl), AFPERR_MISC);
-    EC_ZERO_LOG_ERR(vol->vfs->vfs_acl(vol, name, ACL_TYPE_ACCESS, 0, acc_acl), AFPERR_MISC);
-
-    if (def_acl) {
-        EC_ZERO_LOG_ERR(acl_set_file(name, ACL_TYPE_DEFAULT, def_acl), AFPERR_MISC);
-        EC_ZERO_LOG_ERR(vol->vfs->vfs_acl(vol, name, ACL_TYPE_DEFAULT, 0, def_acl), AFPERR_MISC);
+    EC_ZERO_LOG_ERR(acl_set_file(name, ACL_TYPE_ACCESS, access_acl), AFPERR_MISC);
+    EC_ZERO_LOG_ERR(vol->vfs->vfs_acl(vol, name, ACL_TYPE_ACCESS, 0, access_acl), AFPERR_MISC);
+
+    if (default_acl) {
+        /* If the dir has an extended default acl it's ACL_MASK must be updated.*/
+        if (default_acl_flags & HAS_EXT_DEFAULT_ACL)
+            EC_ZERO_LOG_ERR(acl_calc_mask(&default_acl), AFPERR_MISC);
+
+        if (default_acl_flags) {
+            EC_ZERO_LOG_ERR(acl_valid(default_acl), AFPERR_MISC);
+            EC_ZERO_LOG_ERR(acl_set_file(name, ACL_TYPE_DEFAULT, default_acl), AFPERR_MISC);
+            EC_ZERO_LOG_ERR(vol->vfs->vfs_acl(vol, name, ACL_TYPE_DEFAULT, 0, default_acl), AFPERR_MISC);
+        }
     }
 
 EC_CLEANUP:
-    acl_free(acc_acl);
-    acl_free(def_acl);
+    if (access_acl) acl_free(access_acl);
+    if (default_acl) acl_free(default_acl);
 
     LOG(log_maxdebug, logtype_afpd, "set_acl: END");
     EC_EXIT;
@@ -1173,10 +1355,10 @@ static int check_acl_access(const struct vol *vol,
     LOG(log_maxdebug, logtype_afpd, "check_acl_access(dir: \"%s\", path: \"%s\", curdir: \"%s\", 0x%08x)",
         cfrombstr(dir->d_fullpath), path, getcwdpath(), requested_rights);
 
+    /* This check is not used anymore, as OS X Server seems to be ignoring too */
+#if 0
     /* Get uid or gid from UUID */
     EC_ZERO_ERR(getnamefromuuid(uuid, &username, &uuidtype), AFPERR_PARAM);
-    EC_ZERO_LOG_ERR(lstat(path, &st), AFPERR_PARAM);
-
     switch (uuidtype) {
     case UUID_USER:
         break;
@@ -1188,6 +1370,9 @@ static int check_acl_access(const struct vol *vol,
         EC_STATUS(AFPERR_MISC);
         goto EC_CLEANUP;
     }
+#endif
+
+    EC_ZERO_LOG_ERR(lstat(path, &st), AFPERR_PARAM);
 
     is_dir = !strcmp(path, ".");
 
@@ -1246,7 +1431,7 @@ static int check_acl_access(const struct vol *vol,
             if (allowed_rights & DARWIN_ACE_ADD_SUBDIRECTORY)
                 allowed_rights |= DARWIN_ACE_DELETE;
 
-            dir->d_rights_cache = allowed_rights;
+            curdir->d_rights_cache = allowed_rights;
         }
         LOG(log_debug, logtype_afpd, "allowed rights: 0x%08x", allowed_rights);
     }
@@ -1531,14 +1716,13 @@ int afp_setacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
  * This is the magic function that makes ACLs usable by calculating
  * the access granted by ACEs to the logged in user.
  */
-int acltoownermode(char *path, struct stat *st, struct maccess *ma)
+int acltoownermode(const struct vol *vol, char *path, struct stat *st, struct maccess *ma)
 {
     EC_INIT;
     uint32_t rights = 0;
 
     if ( ! (AFPobj->options.flags & OPTION_ACL2MACCESS)
-         || (current_vol == NULL)
-         || ! (current_vol->v_flags & AFPVOL_ACLS))
+         || ! (vol->v_flags & AFPVOL_ACLS))
          return 0;
 
     LOG(log_maxdebug, logtype_afpd, "acltoownermode(\"%s/%s\", 0x%02x)",
@@ -1546,10 +1730,6 @@ int acltoownermode(char *path, struct stat *st, struct maccess *ma)
 
 #ifdef HAVE_SOLARIS_ACLS
     EC_ZERO_LOG(solaris_acl_rights(path, st, &rights));
-#endif
-#ifdef HAVE_POSIX_ACLS
-    EC_ZERO_LOG(posix_acl_rights(path, st, &rights));
-#endif
 
     LOG(log_maxdebug, logtype_afpd, "rights: 0x%08x", rights);
 
@@ -1559,8 +1739,13 @@ int acltoownermode(char *path, struct stat *st, struct maccess *ma)
         ma->ma_user |= AR_UWRITE;
     if (rights & (DARWIN_ACE_EXECUTE | DARWIN_ACE_SEARCH))
         ma->ma_user |= AR_USEARCH;
+#endif
+
+#ifdef HAVE_POSIX_ACLS
+    EC_ZERO_LOG(posix_acls_to_uaperms(path, st, ma));
+#endif
 
-    LOG(log_maxdebug, logtype_afpd, "resulting user maccess: 0x%02x", ma->ma_user);
+    LOG(log_maxdebug, logtype_afpd, "resulting user maccess: 0x%02x group maccess: 0x%02x", ma->ma_user, ma->ma_group);
 
 EC_CLEANUP:
     EC_EXIT;
index c89fe9c8f3c5fe0ee8df275a5e9d8c8b3dd9d9f6..273a9f13e1cca3cdd31cfc659e1c4cafba6454ed 100644 (file)
@@ -113,6 +113,6 @@ int afp_setacl (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf,  size_t *rb
 extern int acl_ldap_readconfig(char *name);
 
 /* Misc funcs */
-extern int acltoownermode(char *path, struct stat *st, struct maccess *ma);
+extern int acltoownermode(const struct vol *vol, char *path, struct stat *st, struct maccess *ma);
 extern int check_vol_acl_support(const struct vol *vol);
 #endif
index 2fdeb9db32afc35fb68e73405bd4a1aa5542100c..51bd75b0b6055375c8b58266d2bed0205276ddc1 100644 (file)
@@ -479,7 +479,7 @@ void afp_over_dsi(AFPObj *obj)
             continue;
 
         /* Blocking read on the network socket */
-        cmd = dsi_receive(dsi);
+        cmd = dsi_stream_receive(dsi);
 
         if (cmd == 0) {
             /* cmd == 0 is the error condition */
@@ -588,7 +588,7 @@ void afp_over_dsi(AFPObj *obj)
 
             /* AFP replay cache */
             rc_idx = dsi->clientID % REPLAYCACHE_SIZE;
-            LOG(log_debug, logtype_afpd, "DSI request ID: %u", dsi->clientID);
+            LOG(log_debug, logtype_dsi, "DSI request ID: %u", dsi->clientID);
 
             if (replaycache[rc_idx].DSIreqID == dsi->clientID
                 && replaycache[rc_idx].AFPcommand == function) {
@@ -631,9 +631,7 @@ void afp_over_dsi(AFPObj *obj)
             if (dsi->flags & DSI_NOREPLY) {
                 dsi->flags &= ~DSI_NOREPLY;
                 break;
-            }
-
-            if (!dsi_cmdreply(dsi, err)) {
+            } else if (!dsi_cmdreply(dsi, err)) {
                 LOG(log_error, logtype_afpd, "dsi_cmdreply(%d): %s", dsi->socket, strerror(errno) );
                 if (dsi_disconnect(dsi) != 0)
                     afp_dsi_die(EXITERR_CLNT);
index e79fc4f227928209ed140a4613f3825944551680..4464434116eb695eada997272d92d1cffb207a5e 100644 (file)
@@ -142,6 +142,8 @@ void afp_options_free(struct afp_options *opt,
        free(opt->logconfig);
        if (opt->mimicmodel && (opt->mimicmodel != save->mimicmodel))
        free(opt->mimicmodel);
+       if (opt->adminauthuser && (opt->adminauthuser != save->adminauthuser))
+       free(opt->adminauthuser);
 }
 
 /* initialize options */
@@ -194,6 +196,7 @@ void afp_options_init(struct afp_options *options)
     options->dsireadbuf = 12;
        options->mimicmodel = NULL;
     options->fce_fmodwait = 60; /* put fmod events 60 seconds on hold */
+    options->adminauthuser = NULL;
 }
 
 /* parse an afpd.conf line. i'm doing it this way because it's
@@ -507,6 +510,9 @@ int afp_options_parseline(char *buf, struct afp_options *options)
     if ((c = getoption(buf, "-mimicmodel")) && (opt = strdup(c)))
        options->mimicmodel = opt;
 
+    if ((c = getoption(buf, "-adminauthuser")) && (opt = strdup(c)))
+       options->adminauthuser = opt;
+
     return 1;
 }
 
index 3b33c1ee3afabac3ca98d31131ed21282fa6acae..aebd1adbc52f00bacd1c022cdca3d8b23f5fa087 100644 (file)
@@ -129,7 +129,8 @@ int afp_getdiracl(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *r
     #undef accessmode
 #endif
 
-void afsmode( path, ma, dir, st )
+void afsmode( vol, path, ma, dir, st )
+const struct volume *vol;
 char           *path;
 struct maccess *ma;
 struct dir      *dir;
@@ -153,7 +154,7 @@ struct stat     *st;
         return;
     }
 
-    accessmode( path, ma, dir, st );
+    accessmode(vol, path, ma, dir, st );
 
     return;
 }
index 18fca228cf64e77e471ba212e8ce448faea533cf..1c913a0aab9de1fc008ea21b52cc789c724673e4 100644 (file)
@@ -504,7 +504,7 @@ static int catsearch(struct vol *vol,
 {
     static uint32_t cur_pos;    /* Saved position index (ID) - used to remember "position" across FPCatSearch calls */
     static DIR *dirpos;                 /* UNIX structure describing currently opened directory. */
-    struct dir *curdir;          /* struct dir of current directory */
+    struct dir *currentdir;      /* struct dir of current directory */
        int cidx, r;
        struct dirent *entry;
        int result = AFP_OK;
@@ -550,6 +550,8 @@ static int catsearch(struct vol *vol,
     start_time = time(NULL);
 
        while ((cidx = reducestack()) != -1) {
+        LOG(log_debug, logtype_afpd, "catsearch: dir: \"%s\"", dstack[cidx].path);
+
                error = lchdir(dstack[cidx].path);
 
                if (!error && dirpos == NULL)
@@ -576,10 +578,11 @@ static int catsearch(struct vol *vol,
                        goto catsearch_end;
                }
 
-        if ((curdir = dirlookup_bypath(vol, dstack[cidx].path)) == NULL) {
+        if ((currentdir = dirlookup_bypath(vol, dstack[cidx].path)) == NULL) {
             result = AFPERR_MISC;
             goto catsearch_end;
         }
+        LOG(log_debug, logtype_afpd, "catsearch: current struct dir: \"%s\"", cfrombstr(currentdir->d_fullpath));
                
                while ((entry = readdir(dirpos)) != NULL) {
                        (*pos)++;
@@ -587,6 +590,9 @@ static int catsearch(struct vol *vol,
                        if (!check_dirent(vol, entry->d_name))
                           continue;
 
+            LOG(log_debug, logtype_afpd, "catsearch(\"%s\"): dirent: \"%s\"",
+                cfrombstr(currentdir->d_fullpath), entry->d_name);
+
                        memset(&path, 0, sizeof(path));
                        path.u_name = entry->d_name;
                        if (of_stat(&path) != 0) {
@@ -611,13 +617,13 @@ static int catsearch(struct vol *vol,
                                */
                 int unlen = strlen(path.u_name);
                 path.d_dir = dircache_search_by_name(vol,
-                                                     curdir,
+                                                     currentdir,
                                                      path.u_name,
                                                      unlen);
                if (path.d_dir == NULL) {
                        /* path.m_name is set by adddir */
                    if ((path.d_dir = dir_add(vol,
-                                              curdir,
+                                              currentdir,
                                               &path,
                                               unlen)) == NULL) {
                                                result = AFPERR_MISC;
@@ -631,7 +637,7 @@ static int catsearch(struct vol *vol,
                                        goto catsearch_end;
                                } 
             } else {
-               path.d_dir = curdir;
+               path.d_dir = currentdir;
             }
 
                        ccr = crit_check(vol, &path);
index 3db94d192742973d1dcd92d411b431d9be61ac17..d3b8b6fc5fea30c64fefe9da4ec7d259fa9c15c4 100644 (file)
@@ -462,7 +462,7 @@ int dircache_add(const struct vol *vol,
         dircache_stat.expunged++;
     }
     key.d_vid = vol->v_vid;
-    key.d_pdid = dir->d_did;
+    key.d_pdid = dir->d_pdid;
     key.d_u_name = dir->d_u_name;
     if ((hn = hash_lookup(index_didname, &key))) {
         /* Found an entry with the same DID/name, delete it */
index a9e819e83a6b80065d317b81e6933c4b746f010a..dd9221034dbb5daf3e1cce0747ea2f92a4052516 100644 (file)
@@ -463,7 +463,15 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path)
     cnid = htonl(2);
     dir = vol->v_root;
 
+    LOG(log_debug, logtype_afpd, "dirlookup_bypath(\"%s\")", path);
+
+    if (strcmp(vol->v_path, path) == 0)
+        return dir;
+
     EC_NULL(rpath = rel_path_in_vol(path, vol->v_path)); /* 1. */
+
+    LOG(log_debug, logtype_afpd, "dirlookup_bypath: rpath: \"%s\"", cfrombstr(rpath));
+
     EC_NULL(statpath = bfromcstr(vol->v_path));          /* 2. */
 
     l = bsplit(rpath, '/');
@@ -471,6 +479,9 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path)
         did = cnid;
         EC_ZERO(bcatcstr(statpath, "/"));
         EC_ZERO(bconcat(statpath, l->entry[i]));
+
+        LOG(log_debug, logtype_afpd, "dirlookup_bypath: statpath: \"%s\"", cfrombstr(statpath));
+
         EC_ZERO_LOGSTR(lstat(cfrombstr(statpath), &st),
                        "lstat(rpath: %s, elem: %s): %s: %s",
                        cfrombstr(rpath), cfrombstr(l->entry[i]),
@@ -483,14 +494,14 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path)
                                            dir,
                                            cfrombstr(l->entry[i]),
                                            blength(l->entry[i]))) == NULL) {
+
             if ((cnid = cnid_add(vol->v_cdb,             /* 6. */
                                  &st,
                                  did,
                                  cfrombstr(l->entry[i]),
                                  blength(l->entry[i]),
-                                 0)) == CNID_INVALID) {
+                                 0)) == CNID_INVALID)
                 EC_FAIL;
-            }
 
             if ((dir = dirlookup(vol, cnid)) == NULL) /* 7. */
                 EC_FAIL;
@@ -504,6 +515,9 @@ EC_CLEANUP:
     if (ret != 0)
         return NULL;
 
+    LOG(log_debug, logtype_afpd, "dirlookup_bypath: result: \"%s\"",
+        cfrombstr(dir->d_fullpath));
+
     return dir;
 }
 
@@ -1410,7 +1424,7 @@ int check_access(char *path, int mode)
     if (!p)
         return -1;
 
-    accessmode(p, &ma, curdir, NULL);
+    accessmode(current_vol, p, &ma, curdir, NULL);
     if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE))
         return -1;
     if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD))
@@ -1424,7 +1438,7 @@ int file_access(struct path *path, int mode)
 {
     struct maccess ma;
 
-    accessmode(path->u_name, &ma, curdir, &path->st);
+    accessmode(current_vol, path->u_name, &ma, curdir, &path->st);
 
     LOG(log_debug, logtype_afpd, "file_access(\"%s\"): mapped user mode: 0x%02x",
         path->u_name, ma.ma_user);
@@ -1531,7 +1545,6 @@ int getdirparams(const struct vol *vol,
                 ashort = htons(ATTRBIT_INVISIBLE);
             } else
                 ashort = 0;
-            ashort |= htons(ATTRBIT_SHARED);
             memcpy( data, &ashort, sizeof( ashort ));
             data += sizeof( ashort );
             break;
@@ -1629,7 +1642,7 @@ int getdirparams(const struct vol *vol,
             break;
 
         case DIRPBIT_ACCESS :
-            accessmode( upath, &ma, dir , st);
+            accessmode(vol, upath, &ma, dir , st);
 
             *data++ = ma.ma_user;
             *data++ = ma.ma_world;
@@ -1664,6 +1677,9 @@ int getdirparams(const struct vol *vol,
             break;
 
         case DIRPBIT_UNIXPR :
+            /* accessmode may change st_mode with ACLs */
+            accessmode(vol, upath, &ma, dir, st);
+
             aint = htonl(st->st_uid);
             memcpy( data, &aint, sizeof( aint ));
             data += sizeof( aint );
@@ -1676,8 +1692,6 @@ int getdirparams(const struct vol *vol,
             memcpy( data, &aint, sizeof( aint ));
             data += sizeof( aint );
 
-            accessmode( upath, &ma, dir , st);
-
             *data++ = ma.ma_user;
             *data++ = ma.ma_world;
             *data++ = ma.ma_group;
@@ -2415,7 +2429,7 @@ int deletecurdir(struct vol *vol)
         dir_remove( vol, fdir );
     } else {
         LOG(log_error, logtype_afpd, "deletecurdir(\"%s\"): netatalk_rmdir_all_errors error",
-            curdir->d_fullpath);
+            cfrombstr(curdir->d_fullpath));
     }
 
 delete_done:
index fb7535b6c485e68b2dd8bfe269d2aabb8d89eca8..01b4d2ec130f8fcb72bd8e691e76dbb4eecd0770 100644 (file)
@@ -155,42 +155,44 @@ void fce_cleanup()
     udp_initialized = FCE_FALSE;
 }
 
-
 /*
  * Construct a UDP packet for our listeners and return packet size
  * */
 static ssize_t build_fce_packet( struct fce_packet *packet, char *path, int mode, uint32_t event_id )
 {
-    size_t pathlen;
+    size_t pathlen = 0;
     ssize_t data_len = 0;
+    uint64_t *t;
 
-    strncpy(packet->magic, FCE_PACKET_MAGIC, sizeof(packet->magic) );
+    /* Set content of packet */
+    memcpy(packet->magic, FCE_PACKET_MAGIC, sizeof(packet->magic) );
     packet->version = FCE_PACKET_VERSION;
     packet->mode = mode;
-    packet->event_id = event_id;
-
-    pathlen = strlen(path) + 1; /* include string terminator */
+   
+    packet->event_id = event_id; 
 
+    pathlen = strlen(path); /* exclude string terminator */
+    
     /* This should never happen, but before we bust this server, we send nonsense, fce listener has to cope */
     if (pathlen >= MAXPATHLEN)
         pathlen = MAXPATHLEN - 1;
 
-    /* This is the payload len. Means: the stream has len bytes more until packet is finished */
-    /* A server should read the first 16 byte, decode them and then fetch the rest */
-    data_len = FCE_PACKET_HEADER_SIZE + pathlen;
     packet->datalen = pathlen;
 
+    /* This is the payload len. Means: the packet has len bytes more until packet is finished */
+    data_len = FCE_PACKET_HEADER_SIZE + pathlen;
+
     switch (mode) {
     case FCE_TM_SIZE:
-        tm_used = hton64(tm_used);
-        memcpy(packet->data, &tm_used, sizeof(tm_used));
-        strncpy(packet->data + sizeof(tm_used), path, pathlen);
-
-        packet->datalen += sizeof(tm_used);
+        t = (uint64_t *)packet->data;
+        *t = hton64(tm_used);
+        memcpy(packet->data + sizeof(tm_used), path, pathlen);
+        
+        packet->datalen = pathlen + sizeof(tm_used);
         data_len += sizeof(tm_used);
         break;
     default:
-        strncpy(packet->data, path, pathlen);
+        memcpy(packet->data, path, pathlen);
         break;
     }
 
@@ -198,7 +200,10 @@ static ssize_t build_fce_packet( struct fce_packet *packet, char *path, int mode
     return data_len;
 }
 
-static int pack_fce_packet(struct fce_packet *packet, unsigned char *buf)
+/*
+ * Handle Endianess and write into buffer w/o padding
+ **/ 
+static void pack_fce_packet(struct fce_packet *packet, unsigned char *buf, int maxlen)
 {
     unsigned char *p = buf;
 
@@ -211,18 +216,17 @@ static int pack_fce_packet(struct fce_packet *packet, unsigned char *buf)
     *p = packet->mode;
     p++;
     
-    uint32_t id = htonl(packet->event_id);
-    memcpy(p, &id, sizeof(id));
+    uint32_t *id = (uint32_t*)p;
+    *id = htonl(packet->event_id);
     p += sizeof(packet->event_id);
 
-    uint16_t l = htons(packet->datalen);
-    memcpy(p, &l, sizeof(l));
-    p += sizeof(l);
+    uint16_t *l = ( uint16_t *)p;
+    *l = htons(packet->datalen);
+    p += sizeof(packet->datalen);
 
-    memcpy(p, &packet->data[0], packet->datalen);
-    p += packet->datalen;
-
-    return 0;
+    if (((p - buf) +  packet->datalen) < maxlen) {
+        memcpy(p, &packet->data[0], packet->datalen);
+    }
 }
 
 /*
@@ -250,7 +254,7 @@ static void send_fce_event( char *path, int mode )
 
     /* build our data packet */
     ssize_t data_len = build_fce_packet( &packet, path, mode, ++event_id );
-    pack_fce_packet(&packet, iobuf);
+    pack_fce_packet(&packet, iobuf, MAXIOBUF);
 
     for (int i = 0; i < udp_sockets; i++)
     {
@@ -281,7 +285,7 @@ static void send_fce_event( char *path, int mode )
 
             /* Okay, we have a running socket again, send server that we had a problem on our side*/
             data_len = build_fce_packet( &packet, "", FCE_CONN_BROKEN, 0 );
-            pack_fce_packet(&packet, iobuf);
+            pack_fce_packet(&packet, iobuf, MAXIOBUF);
 
             sendto(udp_entry->sock,
                    iobuf,
@@ -292,7 +296,7 @@ static void send_fce_event( char *path, int mode )
 
             /* Rebuild our original data packet */
             data_len = build_fce_packet( &packet, path, mode, event_id );
-            pack_fce_packet(&packet, iobuf);
+            pack_fce_packet(&packet, iobuf, MAXIOBUF);
         }
 
         sent_data = sendto(udp_entry->sock,
@@ -459,7 +463,7 @@ int fce_register_delete_file( struct path *path )
     if (!(fce_ev_enabled & (1 << FCE_FILE_DELETE)))
         return ret;
        
-    ret = register_fce( path->u_name, FALSE, FCE_FILE_DELETE );
+    ret = register_fce( path->u_name, false, FCE_FILE_DELETE );
 
     return ret;
 }
@@ -473,7 +477,7 @@ int fce_register_delete_dir( char *name )
     if (!(fce_ev_enabled & (1 << FCE_DIR_DELETE)))
         return ret;
        
-    ret = register_fce( name, TRUE, FCE_DIR_DELETE);
+    ret = register_fce( name, true, FCE_DIR_DELETE);
 
     return ret;
 }
@@ -488,7 +492,7 @@ int fce_register_new_dir( struct path *path )
     if (!(fce_ev_enabled & (1 << FCE_DIR_CREATE)))
         return ret;
 
-    ret = register_fce( path->u_name, TRUE, FCE_DIR_CREATE );
+    ret = register_fce( path->u_name, true, FCE_DIR_CREATE );
 
     return ret;
 }
@@ -504,7 +508,7 @@ int fce_register_new_file( struct path *path )
     if (!(fce_ev_enabled & (1 << FCE_FILE_CREATE)))
         return ret;
 
-    ret = register_fce( path->u_name, FALSE, FCE_FILE_CREATE );
+    ret = register_fce( path->u_name, false, FCE_FILE_CREATE );
 
     return ret;
 }
@@ -528,7 +532,7 @@ int fce_register_file_modification( struct ofork *ofork )
         return AFPERR_MISC;
     }
     
-    ret = register_fce( u_name, FALSE, FCE_FILE_MODIFY );
+    ret = register_fce( u_name, false, FCE_FILE_MODIFY );
     
     return ret;    
 }
@@ -544,7 +548,7 @@ int fce_register_tm_size(const char *vol, size_t used)
         return ret;
 
     tm_used = used;             /* oh what a hack */
-    ret = register_fce(vol, FALSE, FCE_TM_SIZE);
+    ret = register_fce(vol, false, FCE_TM_SIZE);
 
     return ret;
 }
index ff92fdc0187024cbed69307b81134c2466ab8340..9ed185e53457868b7107b42ee4322caebdcea198 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _FCE_API_INTERNAL_H
 #define        _FCE_API_INTERNAL_H
 
+#include <stdbool.h>
+
 #define FCE_MAX_UDP_SOCKS 5     /* Allow a maximum of udp listeners for file change events */
 #define FCE_SOCKET_RETRY_DELAY_S 600 /* Pause this time in s after socket was broken */
 #define FCE_PACKET_VERSION  1
@@ -43,7 +45,7 @@ struct fce_close_event {
 
 #define PACKET_HDR_LEN (sizeof(struct fce_packet) - FCE_MAX_PATH_LEN)
 
-int fce_handle_coalescation( char *path, int is_dir, int mode );
+bool fce_handle_coalescation( char *path, int is_dir, int mode );
 void fce_initialize_history();
 
 
index ad6026f79a9e5aabdeb6746380009250d5d3eb94..8523aa48683d0eef0b7121da6953da3c41828eb7 100644 (file)
 #endif /* HAVE_CONFIG_H */
 
 #include <stdio.h>
-
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <time.h>
-
-
+#include <stdbool.h>
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -96,7 +94,7 @@ void fce_initialize_history()
        }
 }
 
-int fce_handle_coalescation( char *path, int is_dir, int mode )
+bool fce_handle_coalescation( char *path, int is_dir, int mode )
 {
        /* These two are used to eval our next index in history */
        /* the history is unsorted, speed should not be a problem, length is 10 */
@@ -105,11 +103,11 @@ int fce_handle_coalescation( char *path, int is_dir, int mode )
        struct timeval tv;
 
        if (coalesce == 0)
-               return FALSE;
+               return false;
 
        /* After a file creation *ALWAYS* a file modification is produced */
        if ((mode == FCE_FILE_CREATE) && (coalesce & FCE_COALESCE_CREATE))
-        return TRUE;
+        return true;
 
        /* get timestamp */
        gettimeofday(&tv, 0);
@@ -140,7 +138,7 @@ int fce_handle_coalescation( char *path, int is_dir, int mode )
                if ((coalesce & FCE_COALESCE_CREATE) && (fh->mode == FCE_DIR_CREATE)) {
                        /* Parent dir ? */
                        if (!strncmp(fh->path, path, strlen(fh->path)))
-                               return TRUE;
+                               return true;
                }
 
                /* If we find a parent dir we should be DELETED we are done */
@@ -149,7 +147,7 @@ int fce_handle_coalescation( char *path, int is_dir, int mode )
             && (mode == FCE_FILE_DELETE || mode == FCE_DIR_DELETE)) {
                        /* Parent dir ? */
                        if (!strncmp(fh->path, path, strlen(fh->path)))
-                               return TRUE;
+                               return true;
                }
 
                /* Detect oldest entry for next new entry */
@@ -166,7 +164,7 @@ int fce_handle_coalescation( char *path, int is_dir, int mode )
        strncpy( fce_history_list[oldest_entry_idx].path, path, MAXPATHLEN);
 
        /* we have to handle this event */
-       return FALSE;
+       return false;
 }
 
 /*
index 779b93cabb6c91d854e81246f291b763405a47d1..4c954e4e80f8daccb64bac9731b975749d035a5a 100644 (file)
@@ -379,9 +379,9 @@ int getmetadata(struct vol *vol,
             /* FIXME do we want a visual clue if the file is read only
              */
             struct maccess     ma;
-            accessmode( ".", &ma, dir , NULL);
+            accessmode(vol, ".", &ma, dir , NULL);
             if ((ma.ma_user & AR_UWRITE)) {
-               accessmode( upath, &ma, dir , st);
+               accessmode(vol, upath, &ma, dir , st);
                if (!(ma.ma_user & AR_UWRITE)) {
                        ashort |= htons(ATTRBIT_NOWRITE);
                 }
@@ -548,7 +548,7 @@ int getmetadata(struct vol *vol,
             break;
         case FILPBIT_UNIXPR :
             /* accessmode may change st_mode with ACLs */
-            accessmode( upath, &ma, dir , st);
+            accessmode(vol, upath, &ma, dir , st);
 
             aint = htonl(st->st_uid);
             memcpy( data, &aint, sizeof( aint ));
@@ -1509,7 +1509,8 @@ int copyfile(const struct vol *s_vol,
     if (ad_reso_fileno(adp) == -1 || 0 == (err = copy_fork(ADEID_RFORK, &add, adp))){
         /* copy the data fork */
         if ((err = copy_fork(ADEID_DFORK, &add, adp)) == 0) {
-            err = d_vol->vfs->vfs_copyfile(d_vol, sfd, src, dst);
+            if (ad_meta_fileno(adp) != -1)
+                err = d_vol->vfs->vfs_copyfile(d_vol, sfd, src, dst);
         }
     }
 
index f2c42b4f10e8cb9436808630c97f40fd5a56eb1a..2887f93e332767983bd43a5e2f92cb9e9c62d325 100644 (file)
@@ -869,6 +869,9 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si
         goto afp_read_err;
     }
 
+    LOG(log_debug, logtype_afpd, "afp_read(name: \"%s\", offset: %jd, reqcount: %jd)",
+        of_name(ofork), (intmax_t)offset, (intmax_t)reqcount);
+
     savereqcount = reqcount;
     saveoff = offset;
     if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, savereqcount,ofork->of_refnum) < 0) {
@@ -876,11 +879,19 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si
         goto afp_read_err;
     }
 
+<<<<<<< HEAD
 #define min(a,b)    ((a)<(b)?(a):(b))
     *rbuflen = min( reqcount, *rbuflen );
+=======
+    *rbuflen = MIN(reqcount, *rbuflen);
+    LOG(log_debug, logtype_afpd, "afp_read(name: \"%s\", offset: %jd, reqcount: %jd): reading %jd bytes from file",
+        of_name(ofork), (intmax_t)offset, (intmax_t)reqcount, (intmax_t)*rbuflen);
+>>>>>>> netafp/master
     err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen, xlate);
     if (err < 0)
         goto afp_read_done;
+    LOG(log_debug, logtype_afpd, "afp_read(name: \"%s\", offset: %jd, reqcount: %jd): got %jd bytes from file",
+        of_name(ofork), (intmax_t)offset, (intmax_t)reqcount, (intmax_t)*rbuflen);
 
     /* dsi can stream requests. we can only do this if we're not checking
      * for an end-of-line character. oh well. */
@@ -913,6 +924,7 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si
             int fd;
 
             fd = ad_readfile_init(ofork->of_ad, eid, &offset, 0);
+
             if (dsi_stream_read_file(dsi, fd, offset, dsi->datasize) < 0) {
                 if (errno == EINVAL || errno == ENOSYS)
                     goto afp_read_loop;
@@ -1166,10 +1178,17 @@ static ssize_t write_file(struct ofork *ofork, int eid,
  * in reqcount et al. */
 static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen, int is64)
 {
+<<<<<<< HEAD
     struct ofork    *ofork;
     off_t               offset, saveoff, reqcount;
     int             endflag, eid, xlate = 0, err = AFP_OK;
     uint16_t       ofrefnum;
+=======
+    struct ofork       *ofork;
+    off_t           offset, saveoff, reqcount, oldsize, newsize;
+    int                        endflag, eid, xlate = 0, err = AFP_OK;
+    u_int16_t          ofrefnum;
+>>>>>>> netafp/master
     ssize_t             cc;
 
     /* figure out parameters */
@@ -1212,8 +1231,9 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s
         goto afp_write_err;
     }
 
+    oldsize = ad_size(ofork->of_ad, eid);
     if (endflag)
-        offset += ad_size(ofork->of_ad, eid);
+        offset += oldsize;
 
     /* handle bogus parameters */
     if (reqcount < 0 || offset < 0) {
@@ -1221,6 +1241,8 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s
         goto afp_write_err;
     }
 
+    newsize = ((offset + reqcount) > oldsize) ? (offset + reqcount) : oldsize;
+
     /* offset can overflow on 64-bit capable filesystems.
      * report disk full if that's going to happen. */
     if (sum_neg(is64, offset, reqcount)) {
@@ -1307,7 +1329,7 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s
     ofork->of_flags |= AFPFORK_MODIFIED;
 
     /* update write count */
-    ofork->of_vol->v_written += reqcount;
+    ofork->of_vol->v_appended += (newsize > oldsize) ? (newsize - oldsize) : 0;
 
     *rbuflen = set_off_t (offset, rbuf, is64);
     return( AFP_OK );
index e858146752f25aa95d8c555f34b8cb5db199a528..c056a737c0a9e64f8c89c5b1e68718c6d63943b4 100644 (file)
@@ -226,16 +226,16 @@ static int setlimits(void)
     struct rlimit rlim;
 
     if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
-        LOG(log_error, logtype_afpd, "setlimits: %s", strerror(errno));
-        exit(1);
+        LOG(log_warning, logtype_afpd, "setlimits: reading current limits failed: %s", strerror(errno));
+        return -1;
     }
     if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur < 65535) {
         rlim.rlim_cur = 65535;
         if (rlim.rlim_max != RLIM_INFINITY && rlim.rlim_max < 65535)
             rlim.rlim_max = 65535;
         if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
-            LOG(log_error, logtype_afpd, "setlimits: %s", strerror(errno));
-            exit(1);
+            LOG(log_warning, logtype_afpd, "setlimits: increasing limits failed: %s", strerror(errno));
+            return -1;
         }
     }
     return 0;
index e1358cc6100faa3f8ee8a2502b5bad2631194bd8..54914f1991779f3c392cd807457823ade7c09e4c 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <inttypes.h>
 #include <string.h>
 #include <errno.h>
 #include <limits.h>
@@ -35,7 +36,7 @@
  */
 int ustatfs_getvolspace(const struct vol *vol, VolSpace *bfree, VolSpace *btotal, uint32_t *bsize)
 {
-    VolSpace maxVolSpace = (~(VolSpace)0);
+    VolSpace maxVolSpace = UINT64_MAX;
 
 #ifdef ultrix
     struct fs_data     sfs;
@@ -43,7 +44,6 @@ int ustatfs_getvolspace(const struct vol *vol, VolSpace *bfree, VolSpace *btotal
     struct statfs      sfs;
 #endif /*ultrix*/
 
-
     if ( statfs( vol->v_path, &sfs ) < 0 ) {
         LOG(log_error, logtype_afpd, "ustatfs_getvolspace unable to stat %s", vol->v_path);
         return( AFPERR_PARAM );
@@ -152,7 +152,7 @@ mode_t mode;
  *
  * dir parameter is used by AFS
  */
-void accessmode(char *path, struct maccess *ma, struct dir *dir _U_, struct stat *st)
+void accessmode(const struct vol *vol, char *path, struct maccess *ma, struct dir *dir _U_, struct stat *st)
 {
     struct stat     sb;
 
@@ -164,7 +164,7 @@ void accessmode(char *path, struct maccess *ma, struct dir *dir _U_, struct stat
     }
     utommode( st, ma );
 #ifdef HAVE_ACLS
-    acltoownermode(path, st, ma);
+    acltoownermode(vol, path, st, ma);
 #endif
 }
 
@@ -266,17 +266,17 @@ int setdeskmode(const mode_t mode)
             }
 
             if (S_ISDIR(st.st_mode)) {
-                if ( chmod( modbuf,  (DIRBITS | mode) & ~default_options.umask ) < 0 && errno != EPERM ) {
+                if ( chmod_acl( modbuf,  (DIRBITS | mode) & ~default_options.umask ) < 0 && errno != EPERM ) {
                      LOG(log_error, logtype_afpd, "setdeskmode: chmod %s: %s",fullpathname(modbuf), strerror(errno) );
                 }
-            } else if ( chmod( modbuf,  mode & ~(default_options.umask | EXEC_MODE) ) < 0 && errno != EPERM ) {
+            } else if ( chmod_acl( modbuf,  mode & ~(default_options.umask | EXEC_MODE) ) < 0 && errno != EPERM ) {
                 LOG(log_error, logtype_afpd, "setdeskmode: chmod %s: %s",fullpathname(modbuf), strerror(errno) );
             }
 
         }
         closedir( sub );
         /* XXX: need to preserve special modes */
-        if ( chmod( deskp->d_name,  (DIRBITS | mode) & ~default_options.umask ) < 0 && errno != EPERM ) {
+        if ( chmod_acl( deskp->d_name,  (DIRBITS | mode) & ~default_options.umask ) < 0 && errno != EPERM ) {
             LOG(log_error, logtype_afpd, "setdeskmode: chmod %s: %s",fullpathname(deskp->d_name), strerror(errno) );
         }
     }
@@ -286,7 +286,7 @@ int setdeskmode(const mode_t mode)
         return -1;
     }
     /* XXX: need to preserve special modes */
-    if ( chmod( ".AppleDesktop",  (DIRBITS | mode) & ~default_options.umask ) < 0 && errno != EPERM ) {
+    if ( chmod_acl( ".AppleDesktop",  (DIRBITS | mode) & ~default_options.umask ) < 0 && errno != EPERM ) {
         LOG(log_error, logtype_afpd, "setdeskmode: chmod %s: %s", fullpathname(".AppleDesktop"),strerror(errno) );
     }
     return( 0 );
index dcf45c821537d79332523d2070a05c42f6b3dceb..417acb172e1561eff6abf9159a311fd9db4475a9 100644 (file)
@@ -221,7 +221,7 @@ extern int setdeskowner     (const uid_t, const gid_t);
 extern int setdirowner      (const struct vol *, const char *, const uid_t, const gid_t);
 extern int setfilunixmode   (const struct vol *, struct path*, const mode_t);
 extern int setfilowner      (const struct vol *, const uid_t, const gid_t, struct path*);
-extern void accessmode      (char *, struct maccess *, struct dir *, struct stat *);
+extern void accessmode      (const struct vol *, char *, struct maccess *, struct dir *, struct stat *);
 
 #ifdef AFS     
     #define accessmode afsmode
index b6707b313699ea77646019f1ec44c068a8234ea2..7437f58b6a6fad9a86b7d13bf4dd1cac89cb7446 100644 (file)
@@ -36,6 +36,7 @@
 #include <atalk/ftw.h>
 #include <atalk/globals.h>
 #include <atalk/fce_api.h>
+#include <atalk/errchk.h>
 
 #ifdef CNID_DB
 #include <atalk/cnid.h>
@@ -1102,6 +1103,7 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
     int         i;
     struct passwd   *pw;
     struct vol_option   save_options[VOLOPT_NUM];
+    struct vol_option   default_options[VOLOPT_NUM];
     struct vol_option   options[VOLOPT_NUM];
     struct stat         st;
 
@@ -1144,17 +1146,18 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
         break;
     }
 
-    memset(save_options, 0, sizeof(save_options));
+    memset(default_options, 0, sizeof(default_options));
 
     /* Enable some default options for all volumes */
-    save_options[VOLOPT_FLAGS].i_value |= AFPVOL_CACHE;
+    default_options[VOLOPT_FLAGS].i_value |= AFPVOL_CACHE;
 #ifdef HAVE_ACLS
-    save_options[VOLOPT_FLAGS].i_value |= AFPVOL_ACLS;
+    default_options[VOLOPT_FLAGS].i_value |= AFPVOL_ACLS;
 #endif
-    save_options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AUTO;
+    default_options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AUTO;
     LOG(log_maxdebug, logtype_afpd, "readvolfile: seeding default umask: %04o",
         obj->options.umask);
-    save_options[VOLOPT_UMASK].i_value = obj->options.umask;
+    default_options[VOLOPT_UMASK].i_value = obj->options.umask;
+    memcpy(save_options, default_options, sizeof(options));
 
     LOG(log_debug, logtype_afpd, "readvolfile: \"%s\"", path);
 
@@ -1169,12 +1172,14 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
         case ':':
             /* change the default options for this file */
             if (strncmp(path, VOLOPT_DEFAULT, VOLOPT_DEFAULT_LEN) == 0) {
+                volfree(default_options, save_options);
+                memcpy(default_options, save_options, sizeof(options));
                 *tmp = '\0';
                 for (i = 0; i < VOLOPT_NUM; i++) {
                     if (parseline( sizeof( path ) - VOLOPT_DEFAULT_LEN - 1,
                                    path + VOLOPT_DEFAULT_LEN) < 0)
                         break;
-                    volset(save_options, NULL, tmp, sizeof(tmp) - 1,
+                    volset(default_options, NULL, tmp, sizeof(tmp) - 1,
                            path + VOLOPT_DEFAULT_LEN);
                 }
             }
@@ -1213,7 +1218,7 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
              * able to specify things in any order, but i don't want to
              * re-write everything. */
 
-            memcpy(options, save_options, sizeof(options));
+            memcpy(options, default_options, sizeof(options));
             *volname = '\0';
 
             /* read in up to VOLOP_NUM possible options */
@@ -1221,7 +1226,7 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
                 if (parseline( sizeof( tmp ) - 1, tmp ) < 0)
                     break;
 
-                volset(options, save_options, volname, sizeof(volname) - 1, tmp);
+                volset(options, default_options, volname, sizeof(volname) - 1, tmp);
             }
 
             /* check allow/deny lists (if not afpd master loading volumes for Zeroconf reg.):
@@ -1252,7 +1257,7 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us
 
                 creatvol(obj, pwent, path, tmp, options, p2 != NULL);
             }
-            volfree(options, save_options);
+            volfree(options, default_options);
             break;
 
         case '.' :
@@ -1349,64 +1354,153 @@ static void volume_unlink(struct vol *volume)
         }
     }
 }
-
-static off_t getused_size; /* result of getused() */
-
 /*!
-  nftw callback for getused()
+ * Read band-size info from Info.plist XML file of an TM sparsebundle
+ *
+ * @param path   (r) path to Info.plist file
+ * @return           band-size in bytes, -1 on error
  */
-static int getused_stat(const char *path,
-                        const struct stat *statp,
-                        int tflag,
-                        struct FTW *ftw)
+static long long int get_tm_bandsize(const char *path)
 {
-    off_t low, high;
+    EC_INIT;
+    FILE *file = NULL;
+    char buf[512];
+    long long int bandsize = -1;
+
+    EC_NULL_LOGSTR( file = fopen(path, "r"),
+                    "get_tm_bandsize(\"%s\"): %s",
+                    path, strerror(errno) );
+
+    while (fgets(buf, sizeof(buf), file) != NULL) {
+        if (strstr(buf, "band-size") == NULL)
+            continue;
 
-    if (tflag == FTW_F || tflag == FTW_D) {
-        getused_size += statp->st_blocks * 512;
+        if (fscanf(file, " <integer>%lld</integer>", &bandsize) != 1) {
+            LOG(log_error, logtype_afpd, "get_tm_bandsize(\"%s\"): can't parse band-size", path);
+            EC_FAIL;
+        }
+        break;
     }
 
-    return 0;
+EC_CLEANUP:
+    if (file)
+        fclose(file);
+    LOG(log_debug, logtype_afpd, "get_tm_bandsize(\"%s\"): bandsize: %lld", path, bandsize);
+    return bandsize;
 }
 
-#define GETUSED_CACHETIME 5
 /*!
- * Calculate used size of a volume with nftw
+ * Return number on entries in a directory
  *
- * The result is cached, we're try to avoid frequently calling nftw()
+ * @param path   (r) path to dir
+ * @return           number of entries, -1 on error
+ */
+static long long int get_tm_bands(const char *path)
+{
+    EC_INIT;
+    long long int count = 0;
+    DIR *dir = NULL;
+    const struct dirent *entry;
+
+    EC_NULL( dir = opendir(path) );
+
+    while ((entry = readdir(dir)) != NULL)
+        count++;
+    count -= 2; /* All OSens I'm aware of return "." and "..", so just substract them, avoiding string comparison in loop */
+        
+EC_CLEANUP:
+    if (dir)
+        closedir(dir);
+    if (ret != 0)
+        return -1;
+    return count;
+}
+
+/*!
+ * Calculate used size of a TimeMachine volume
  *
- * 1) Call nftw an refresh if:
- * 1a) - we're called the first time 
- * 1b) - volume modification date is not yet set and the last time we've been called is
- *       longer then 30 sec ago
- * 1c) - the last volume modification is less then 30 sec old
+ * This assumes that the volume is used only for TimeMachine.
+ *
+ * 1) readdir(path of volume)
+ * 2) for every element that matches regex "\(.*\)\.sparsebundle$" :
+ * 3) parse "\1.sparsebundle/Info.plist" and read the band-size XML key integer value
+ * 4) readdir "\1.sparsebundle/bands/" counting files
+ * 5) calculate used size as: (file_count - 1) * band-size
+ *
+ * The result of the calculation is returned in "volume->v_tm_used".
+ * "volume->v_appended" gets reset to 0.
+ * "volume->v_tm_cachetime" is updated with the current time from time(NULL).
+ *
+ * "volume->v_tm_used" is cached for TM_USED_CACHETIME seconds and updated by
+ * "volume->v_appended". The latter is increased by X every time the client
+ * appends X bytes to a file (in fork.c).
  *
  * @param vol     (rw) volume to calculate
+ * @return             0 on success, -1 on error
  */
-static int getused(struct vol *vol)
+#define TM_USED_CACHETIME 60    /* cache for 60 seconds */
+static int get_tm_used(struct vol * restrict vol)
 {
-    static time_t vol_mtime = 0;
-    int ret = 0;
+    EC_INIT;
+    long long int bandsize;
+    VolSpace used = 0;
+    bstring infoplist = NULL;
+    bstring bandsdir = NULL;
+    DIR *dir = NULL;
+    const struct dirent *entry;
+    const char *p;
+    struct stat st;
+    long int links;
     time_t now = time(NULL);
 
-    if (!vol_mtime
-        || (!vol->v_mtime && ((vol_mtime + GETUSED_CACHETIME) < now))
-        || (vol->v_mtime && ((vol_mtime + GETUSED_CACHETIME) < vol->v_mtime))
-        ) {
-        vol_mtime = now;
-        getused_size = 0;
-        vol->v_written = 0;
-        ret = nftw(vol->v_path, getused_stat, NULL, 20, FTW_PHYS); /* 2 */
-        LOG(log_debug, logtype_afpd, "volparams: from nftw: %" PRIu64 " bytes",
-            getused_size);
-    } else {
-        getused_size += vol->v_written;
-        vol->v_written = 0;
-        LOG(log_debug, logtype_afpd, "volparams: cached used: %" PRIu64 " bytes",
-            getused_size);
+    if (vol->v_tm_cachetime
+        && ((vol->v_tm_cachetime + TM_USED_CACHETIME) >= now)) {
+        if (vol->v_tm_used == -1)
+            EC_FAIL;
+        vol->v_tm_used += vol->v_appended;
+        vol->v_appended = 0;
+        LOG(log_debug, logtype_afpd, "getused(\"%s\"): cached: %" PRIu64 " bytes",
+            vol->v_path, vol->v_tm_used);
+        return 0;
     }
 
-    return ret;
+    vol->v_tm_cachetime = now;
+
+    EC_NULL( dir = opendir(vol->v_path) );
+
+    while ((entry = readdir(dir)) != NULL) {
+        if (((p = strstr(entry->d_name, "sparsebundle")) != NULL)
+            && (strlen(entry->d_name) == (p + strlen("sparsebundle") - entry->d_name))) {
+
+            EC_NULL_LOG( infoplist = bformat("%s/%s/%s", vol->v_path, entry->d_name, "Info.plist") );
+            
+            if ((bandsize = get_tm_bandsize(cfrombstr(infoplist))) == -1)
+                continue;
+
+            EC_NULL_LOG( bandsdir = bformat("%s/%s/%s/", vol->v_path, entry->d_name, "bands") );
+
+            if ((links = get_tm_bands(cfrombstr(bandsdir))) == -1)
+                continue;
+
+            used += (links - 1) * bandsize;
+            LOG(log_debug, logtype_afpd, "getused(\"%s\"): bands: %" PRIu64 " bytes",
+                cfrombstr(bandsdir), used);
+        }
+    }
+
+    vol->v_tm_used = used;
+
+EC_CLEANUP:
+    if (infoplist)
+        bdestroy(infoplist);
+    if (bandsdir)
+        bdestroy(bandsdir);
+    if (dir)
+        closedir(dir);
+
+    LOG(log_debug, logtype_afpd, "getused(\"%s\"): %" PRIu64 " bytes", vol->v_path, vol->v_tm_used);
+
+    EC_EXIT;
 }
 
 static int getvolspace(struct vol *vol,
@@ -1439,13 +1533,12 @@ static int getvolspace(struct vol *vol,
         return( rc );
     }
 
-#define min(a,b)    ((a)<(b)?(a):(b))
 #ifndef NO_QUOTA_SUPPORT
     if ( spaceflag == AFPVOL_NONE || spaceflag == AFPVOL_UQUOTA ) {
         if ( uquota_getvolspace( vol, &qfree, &qtotal, *bsize ) == AFP_OK ) {
             vol->v_flags = ( ~AFPVOL_GVSMASK & vol->v_flags ) | AFPVOL_UQUOTA;
-            *xbfree = min(*xbfree, qfree);
-            *xbtotal = min( *xbtotal, qtotal);
+            *xbfree = MIN(*xbfree, qfree);
+            *xbtotal = MIN(*xbtotal, qtotal);
             goto getvolspace_done;
         }
     }
@@ -1454,18 +1547,19 @@ static int getvolspace(struct vol *vol,
 
 getvolspace_done:
     if (vol->v_limitsize) {
-        if (getused(vol) != 0)
+        if (get_tm_used(vol) != 0)
             return AFPERR_MISC;
-        LOG(log_debug, logtype_afpd, "volparams: used on volume: %" PRIu64 " bytes",
-            getused_size);
-        vol->v_tm_used = getused_size;
 
-        *xbtotal = min(*xbtotal, (vol->v_limitsize * 1024 * 1024));
-        *xbfree = min(*xbfree, *xbtotal < getused_size ? 0 : *xbtotal - getused_size);
+        *xbtotal = MIN(*xbtotal, (vol->v_limitsize * 1024 * 1024));
+        *xbfree = MIN(*xbfree, *xbtotal < vol->v_tm_used ? 0 : *xbtotal - vol->v_tm_used);
+
+        LOG(log_debug, logtype_afpd,
+            "volparams: total: %" PRIu64 ", used: %" PRIu64 ", free: %" PRIu64 " bytes",
+            *xbtotal, vol->v_tm_used, *xbfree);
     }
 
-    *bfree = min( *xbfree, maxsize);
-    *btotal = min( *xbtotal, maxsize);
+    *bfree = MIN(*xbfree, maxsize);
+    *btotal = MIN(*xbtotal, maxsize);
     return( AFP_OK );
 }
 
@@ -1480,7 +1574,7 @@ void vol_fce_tm_event(void)
         last = now;
         for ( ; vol; vol = vol->v_next ) {
             if (vol->v_flags & AFPVOL_TM)
-                (void)fce_register_tm_size(vol->v_path, vol->v_tm_used + vol->v_written);
+                (void)fce_register_tm_size(vol->v_path, vol->v_tm_used + vol->v_appended);
         }
     }
 }
@@ -1836,7 +1930,7 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
             if (!S_ISDIR(st.st_mode)) {
                 continue;       /* not a dir */
             }
-            accessmode(volume->v_path, &ma, NULL, &st);
+            accessmode(volume, volume->v_path, &ma, NULL, &st);
             if ((ma.ma_user & (AR_UREAD | AR_USEARCH)) != (AR_UREAD | AR_USEARCH)) {
                 continue;   /* no r-x access */
             }
index 7cf72871de3990e87b4e3c5f8e1b98b9c183d3d6..d661071d03b57c8e853e59cd431b2523f5474e69 100644 (file)
@@ -374,7 +374,7 @@ static void remove_eafiles(const char *name, struct ea *ea)
     if ((dp = opendir(".")) == NULL) {
         dbd_log(LOGSTD, "Couldn't open the directory '%s/%s': %s",
                 cwdbuf, ADv2_DIRNAME, strerror(errno));
-        return;
+        goto exit;
     }
 
     while ((ep = readdir(dp))) {
@@ -388,9 +388,14 @@ static void remove_eafiles(const char *name, struct ea *ea)
         } /* if */
     } /* while */
 
+exit:
     if (dp)
         closedir(dp);
-
+    if ((chdir("..")) != 0) {
+        dbd_log(LOGSTD, "Couldn't chdir to '%s': %s", cwdbuf, strerror(errno));
+        /* we can't proceed */
+        longjmp(jmp, 1); /* this jumps back to cmd_dbd_scanvol() */
+    }    
 }
 
 /*
@@ -750,24 +755,22 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi
         /* Everything is fine */
         return db_cnid;
     } else if (ad_cnid && db_cnid && (ad_cnid != db_cnid)) {
-        /* Mismatch ? Delete both from db and re-add data from file */
+        /* Mismatch, overwrite ad file with value from db */
         dbd_log( LOGSTD, "CNID mismatch for '%s/%s', db: %u, ad-file: %u", cwdbuf, name, ntohl(db_cnid), ntohl(ad_cnid));
         if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
-            rqst.cnid = db_cnid;
-            ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
-            if (dbif_txn_close(dbd, ret) != 0)
-                return CNID_INVALID;
-
-            rqst.cnid = ad_cnid;
-            ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
-            if (dbif_txn_close(dbd, ret) != 0)
-                return CNID_INVALID;
-
-            ret = dbd_rebuild_add(dbd, &rqst, &rply);
-            if (dbif_txn_close(dbd, ret) != 0)
+            dbd_log(LOGSTD, "Updating AppleDouble file for '%s/%s' with CNID: %u from database",
+                            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) {
+                dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s",
+                        cwdbuf, name, strerror(errno));
                 return CNID_INVALID;
+            }
+            ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp);
+            ad_flush(&ad);
+            ad_close_metadata(&ad);
         }
-        return ad_cnid;
+        return db_cnid;
     } else if (ad_cnid && (db_cnid == 0)) {
         /* in ad-file but not in db */
         if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
@@ -777,7 +780,7 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi
 
             rqst.cnid = ad_cnid;
             ret = dbd_resolve(dbd, &rqst, &rply);
-            if (ret == CNID_DBD_RES_OK) {
+            if (rply.result == CNID_DBD_RES_OK) {
                 /* Occupied! Choose another, update ad-file */
                 ret = dbd_add(dbd, &rqst, &rply, 1);
                 if (dbif_txn_close(dbd, ret) != 0)
index 4a109100a4264321ec4318dcd2e84141f96ceffe..23c6a58edaa18cfdeef1189759c047453ffd2416 100644 (file)
@@ -9,17 +9,7 @@
 #include "config.h"
 #endif
 
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-#ifndef _XOPEN_SOURCE
-# define _XOPEN_SOURCE 600
-#endif
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__
-#endif
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-#endif
+#include <atalk/standards.h>
 
 #include <stdio.h>
 #include <stdlib.h>
index fc8e32afb4224231c971bd9a3673ec094aacda87..562838b384a28dacc46873f8742a8296a6a2eba1 100644 (file)
@@ -48,6 +48,11 @@ int dbd_rebuild_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *
         return -1;
     }
 
+    LOG(log_debug, logtype_cnid,
+        "dbd_rebuild_add(CNID: %u, did: %u, name: \"%s\", dev/ino:0x%llx/0x%llx): success",
+        ntohl(rqst->cnid), ntohl(rqst->did), rqst->name,
+        (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
+
     key.data = ROOTINFO_KEY;
     key.size = ROOTINFO_KEYLEN;
 
index 49c69e9afb3d4f3728d4a95d5bcab54ea68048d0..bb3561caba7a1018605be36649d85b13abb8ab29 100644 (file)
@@ -54,8 +54,8 @@ int dbd_resolve(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply
     rply->namelen = data.size;
     rply->name = (char *)data.data;
 
-    LOG(log_debug, logtype_cnid, "dbd_resolve: Resolving CNID %u to did %u name %s",
-        ntohl(rqst->cnid), ntohl(rply->did), rply->name);
+    LOG(log_debug, logtype_cnid, "dbd_resolve(CNID: %u): did: %u, name: \"%s\"",
+        ntohl(rqst->cnid), ntohl(rply->did), rply->name + CNID_NAME_OFS);
 
     rply->result = CNID_DBD_RES_OK;
     return 1;
index f2976b45fb83d24af1edd6e32577a6bc876315dd..0f0c8a535329b579bac63659a88b41194f481b59 100644 (file)
@@ -529,16 +529,46 @@ exit:
     return ret;
 }
 
-static int logincont2(void *obj, struct passwd **uam_pwd,
+/**
+ * Try to authenticate via PAM as "adminauthuser"
+ **/
+static int loginasroot(const char *adminauthuser, const char **hostname, int status)
+{
+    int PAM_error;
+
+    if ((PAM_error = pam_end(pamh, status)) != PAM_SUCCESS)
+        goto exit;
+    pamh = NULL;
+
+    if ((PAM_error = pam_start("netatalk", adminauthuser, &PAM_conversation, &pamh)) != PAM_SUCCESS) {
+        LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", pam_strerror(pamh,PAM_error));
+        goto exit;
+    }
+
+    /* solaris craps out if PAM_TTY and PAM_RHOST aren't set. */
+    pam_set_item(pamh, PAM_TTY, "afpd");
+    pam_set_item(pamh, PAM_RHOST, *hostname);
+    if ((PAM_error = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
+        goto exit;
+
+    LOG(log_warning, logtype_uams, "DHX2: Authenticated as \"%s\"", adminauthuser);
+
+exit:
+    return PAM_error;
+}
+
+static int logincont2(void *obj_in, struct passwd **uam_pwd,
                       char *ibuf, size_t ibuflen,
                       char *rbuf _U_, size_t *rbuflen)
 {
-    int ret;
+    AFPObj *obj = obj_in;
+    int ret = AFPERR_MISC;
     int PAM_error;
     const char *hostname = NULL;
     gcry_mpi_t retServerNonce;
     gcry_cipher_hd_t ctx;
     gcry_error_t ctxerror;
+    char *utfpass = NULL;
 
     *rbuflen = 0;
 
@@ -594,27 +624,41 @@ static int logincont2(void *obj, struct passwd **uam_pwd,
 
     /* ---- Start authentication with PAM --- */
 
+    /* The password is in legacy Mac encoding, convert it to host encoding */
+    if (convert_string_allocate(CH_MAC, CH_UNIX, ibuf, -1, &utfpass) == (size_t)-1) {
+        LOG(log_error, logtype_uams, "DHX2: conversion error");
+        goto error_ctx;
+    }
+    PAM_password = utfpass;
+
+#ifdef DEBUG
+    LOG(log_maxdebug, logtype_default, "DHX2: password: %s", PAM_password);
+#endif
+
     /* Set these things up for the conv function */
-    PAM_password = ibuf;
 
     ret = AFPERR_NOTAUTH;
     PAM_error = pam_start("netatalk", PAM_username, &PAM_conversation, &pamh);
     if (PAM_error != PAM_SUCCESS) {
-        LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s",
-            pam_strerror(pamh,PAM_error));
+        LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", pam_strerror(pamh,PAM_error));
         goto error_ctx;
     }
 
     /* solaris craps out if PAM_TTY and PAM_RHOST aren't set. */
     pam_set_item(pamh, PAM_TTY, "afpd");
     pam_set_item(pamh, PAM_RHOST, hostname);
+
     PAM_error = pam_authenticate(pamh, 0);
     if (PAM_error != PAM_SUCCESS) {
         if (PAM_error == PAM_MAXTRIES)
             ret = AFPERR_PWDEXPR;
-        LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s",
-            pam_strerror(pamh, PAM_error));
-        goto error_ctx;
+        LOG(log_info, logtype_uams, "DHX2: PAM_Error: %s", pam_strerror(pamh, PAM_error));
+
+        if (!obj->options.adminauthuser)
+            goto error_ctx;
+        if (loginasroot(obj->options.adminauthuser, &hostname, PAM_error) != PAM_SUCCESS) {
+            goto error_ctx;
+        }
     }
 
     PAM_error = pam_acct_mgmt(pamh, 0);
@@ -627,8 +671,7 @@ static int logincont2(void *obj, struct passwd **uam_pwd,
         else if (PAM_error == PAM_AUTHTOKEN_REQD)
             ret = AFPERR_PWDCHNG;
 #endif
-        else
-            goto error_ctx;
+        goto error_ctx;
     }
 
 #ifndef PAM_CRED_ESTABLISH
@@ -649,15 +692,17 @@ static int logincont2(void *obj, struct passwd **uam_pwd,
     }
 
     memset(ibuf, 0, 256); /* zero out the password */
+    if (utfpass)
+        memset(utfpass, 0, strlen(utfpass));
     *uam_pwd = dhxpwd;
     LOG(log_info, logtype_uams, "DHX2: PAM Auth OK!");
-    if ( ret == AFPERR_PWDEXPR)
-        return ret;
+
     ret = AFP_OK;
 
 error_ctx:
     gcry_cipher_close(ctx);
 error_noctx:
+    if (utfpass) free(utfpass);
     free(K_MD5hash);
     K_MD5hash=NULL;
     gcry_mpi_release(serverNonce);
index c7ac24342aa80aaead5b50d8d80ae286cc5952d2..8d31b9f845b3502eb4935d38a0df5cf6635cfac2 100644 (file)
@@ -12,6 +12,8 @@
 
 #ifdef UAM_DHX2
 
+#include <atalk/standards.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index 8b772b6c449ef465f950f6a82ef9b330090d65c3..d390f76b4da29d556fb07bdf559849e3610e9362 100644 (file)
@@ -8,12 +8,7 @@
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
 
-#ifdef NETBSD
-#define _XOPEN_SOURCE 500 /* for crypt() */
-#endif
-#ifdef FREEBSD
-#define _XOPEN_SOURCE /* for crypt() */
-#endif
+#include <atalk/standards.h>
 
 #include <stdio.h>
 #include <stdlib.h>
index 72d024d2b521dc70b257f2f1e71c3e20d4e1e02a..6db3ce62028f0e3567e3b1cd96876b1067667a8b 100644 (file)
@@ -8,15 +8,9 @@
 #include <config.h>
 #endif /* HAVE_CONFIG_H */
 
-#include <sys/types.h>
-/* crypt needs _XOPEN_SOURCE (500) at least on BSD, but that breaks Solaris compile */
-#ifdef NETBSD
-#define _XOPEN_SOURCE 500 /* for crypt() */
-#endif
-#ifdef FREEBSD
-#define _XOPEN_SOURCE /* for crypt() */
-#endif
+#include <atalk/standards.h>
 
+#include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index 22aa8ae4d3edb60b64e63c20ad04c2aa0c5466d2..9b9c1d801dd57d53c543d8cdc1e11fb555f18f05 100644 (file)
@@ -12,8 +12,8 @@
 
 #ifdef UAM_PGP
 
-/* for crypt() */
-#define _XOPEN_SOURCE
+#include <atalk/standards.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index fb1d55dc16839a2025b6d8904cfa39e81dafb3ea..f4c2258df50027f6a51e35ba99af11a6b2e1e4fd 100644 (file)
@@ -43,7 +43,8 @@ noinst_HEADERS = \
        ldapconfig.h \
        list.h \
        globals.h \
-       fce_api.h
+       fce_api.h \
+       standards.h
 
 BUILT_SOURCES = lockrpc.gen.h
 EXTRADIST = lockrpc.gen.h
index 53d10b19aa011383c1d8f40788f4984332e70b18..95aa0753401bb3385013192c3ea620a1fdd327b1 100644 (file)
 
 #ifdef HAVE_SOLARIS_ACLS
 #include <sys/acl.h>
-#endif  /* HAVE_SOLARIS_ACLS */
 
-#ifdef HAVE_POSIX_ACLS
-#include <sys/types.h>
-#include <sys/acl.h>
-#endif /* HAVE_POSIX_ACLS */
+#define chmod_acl nfsv4_chmod
 
-#ifdef HAVE_SOLARIS_ACLS
-#define chmod nfsv4_chmod
 extern int get_nfsv4_acl(const char *name, ace_t **retAces);
 extern int strip_trivial_aces(ace_t **saces, int sacecount);
 extern int strip_nontrivial_aces(ace_t **saces, int sacecount);
 extern ace_t *concat_aces(ace_t *aces1, int ace1count, ace_t *aces2, int ace2count);
 extern int nfsv4_chmod(char *name, mode_t mode);
-#endif /* HAVE_SOLARIS_ACLS */
+
+#endif  /* HAVE_SOLARIS_ACLS */
+
+#ifdef HAVE_POSIX_ACLS
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/acl.h>
+
+#define chmod_acl posix_chmod
+#define fchmod_acl posix_fchmod
+
+extern int posix_chmod(const char *name, mode_t mode);
+extern int posix_fchmod(int fd, mode_t mode);
+
+#endif /* HAVE_POSIX_ACLS */
 
 extern int remove_acl_vfs(const char *name);
 
+#else /* HAVE_ACLS=no */
+
+#define chmod_acl chmod
+
 #endif /* HAVE_ACLS */
 
 #endif /* ATALK_ACL_H */
index 963417bd32b16ff6e4569c3c4b034dc693e21ba0..6913ddcdcfc22ce788b8aeacb8ae0d47d0a043d4 100644 (file)
@@ -33,6 +33,8 @@
 #include <config.h>
 #endif
 
+#include <atalk/standards.h>
+
 #include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
diff --git a/include/atalk/boolean.h b/include/atalk/boolean.h
deleted file mode 100644 (file)
index 2512052..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef _ATALK_BOOLEAN_H
-#define _ATALK_BOOLEAN_H 1
-
-/*
- * bool is a standard type in c++. In theory its one bit in size.
- *  In reality just use the quickest standard type.  
- */
-
-# ifndef __cplusplus
-#  ifndef bool
-typedef char bool;
-
-/*
- * bool, true and false
- *
- */
-
-#  endif   /* ndef bool */
-# endif   /* not C++ */
-# ifndef true
-#  define true    ((bool) 1)
-# endif
-# ifndef false
-#  define false   ((bool) 0)
-# endif
-typedef bool *BoolPtr;
-
-# ifndef TRUE
-#  define TRUE    1
-# endif   /* TRUE */
-
-# ifndef FALSE
-#  define FALSE   0
-# endif   /* FALSE */
-
-#endif
index 75e91b4f09e03c42d5dd0ee3ac16dd81e54d9ce4..de7464a593086d4670aff1965c6905ca3d2e5690 100644 (file)
@@ -185,7 +185,7 @@ extern void dsi_close (DSI *);
 extern ssize_t dsi_stream_write (DSI *, void *, const size_t, const int mode);
 extern size_t dsi_stream_read (DSI *, void *, const size_t);
 extern int dsi_stream_send (DSI *, void *, size_t);
-extern int dsi_stream_receive (DSI *, void *, const size_t, size_t *);
+extern int dsi_stream_receive (DSI *);
 extern int dsi_disconnect(DSI *dsi);
 
 #ifdef WITH_SENDFILE
@@ -210,6 +210,5 @@ extern void dsi_readdone (DSI *);
     (x)->header.dsi_len = htonl((x)->cmdlen); \
     dsi_stream_send((x), (x)->commands, (x)->cmdlen); \
 } while (0)
-#define dsi_receive(x)    (dsi_stream_receive((x), (x)->commands, \
-                                             DSI_CMDSIZ, &(x)->cmdlen))
+
 #endif /* atalk/dsi.h */
index 64a12764525282e0c19a4431e0ed362c413e683c..78e530a8e95227eac265a01e27dcdedbc7081216 100644 (file)
@@ -17,7 +17,7 @@
 
 #define EC_INIT int ret = 0
 #define EC_STATUS(a) ret = (a)
-#define EC_FAIL ret = -1; goto cleanup
+#define EC_FAIL do { ret = -1; goto cleanup; } while (0)
 #define EC_CLEANUP cleanup
 #define EC_EXIT return ret
 
index aa20d25e91bf6da857e40d3d104769854d874156..b65eeba1e069cd2743c2969ceec5bd5876a8e453 100644 (file)
@@ -90,6 +90,7 @@ struct afp_options {
     char *logconfig;
 
     char *mimicmodel;
+    char *adminauthuser;
 };
 
 #define AFPOBJ_TMPSIZ (MAXPATHLEN)
index 70f9f628c7c61c0c0fe7018b91bfceb884865f43..5a5b657061ff467c5a52c8b0d819927588460243 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef HAVE_ACLS
+#ifdef HAVE_LDAP
 
 #ifndef LDAPCONFIG_H
 #define LDAPCONFIG_H
@@ -39,4 +39,4 @@ extern int ldap_config_valid;
 
 #endif /* LDAPCONFIG_H */
 
-#endif /* HAVE_ACLS */
+#endif /* HAVE_LDAP */
index e91592bf68acd67bb30e20a1b02c240a298841c0..0c6e7d8536a85d2c3ee2ae219c44c2f8d909163e 100644 (file)
@@ -57,8 +57,7 @@
 
 #include <limits.h>
 #include <stdio.h>
-
-#include <atalk/boolean.h>
+#include <stdbool.h>
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
index 297a2ca12242b353eac744bd498fb57104b195ff..ff97357b372f10de5bf5e9600ac12e8d51e4d08a 100644 (file)
@@ -16,7 +16,7 @@
 
 /* lock file path. this should be re-organized a bit. */
 #if ! defined (_PATH_LOCKDIR)
-#  if defined (FHS_COMPATIBILITY) || defined (__NetBSD__)
+#  if defined (FHS_COMPATIBILITY) || defined (__NetBSD__) || defined (__OpenBSD__)
 #    define _PATH_LOCKDIR      "/var/run/"
 #  elif defined (BSD4_4)
 #    ifdef MACOSX_SERVER
@@ -51,7 +51,7 @@
  */
 #define _PATH_ATALKDEBUG       "/tmp/atalkd.debug"
 #define _PATH_ATALKDTMP                "atalkd.tmp"
-#if defined (FHS_COMPATIBILITY) || defined (__NetBSD__)
+#if defined (FHS_COMPATIBILITY) || defined (__NetBSD__) || defined (__OpenBSD__)
 #  define _PATH_ATALKDLOCK     ATALKPATHCAT(_PATH_LOCKDIR,"atalkd.pid")
 #else
 #  define _PATH_ATALKDLOCK     ATALKPATHCAT(_PATH_LOCKDIR,"atalkd")
@@ -61,7 +61,7 @@
  * psorder paths
  */
 #define _PATH_TMPPAGEORDER     "/tmp/psorderXXXXXX"
-#if defined (FHS_COMPATIBILITY) || defined (__NetBSD__)
+#if defined (FHS_COMPATIBILITY) || defined (__NetBSD__) || defined (__OpenBSD__)
 #  define _PATH_PAPDLOCK       ATALKPATHCAT(_PATH_LOCKDIR,"papd.pid")
 #else
 #  define _PATH_PAPDLOCK       ATALKPATHCAT(_PATH_LOCKDIR,"papd")
@@ -72,7 +72,7 @@
  */
 #define _PATH_AFPTKT           "/tmp/AFPtktXXXXXX"
 #define _PATH_AFP_IPC       ATALKPATHCAT(_PATH_LOCKDIR,"afpd_ipc")
-#if defined (FHS_COMPATIBILITY) || defined (__NetBSD__)
+#if defined (FHS_COMPATIBILITY) || defined (__NetBSD__) || defined (__OpenBSD__)
 #  define _PATH_AFPDLOCK       ATALKPATHCAT(_PATH_LOCKDIR,"afpd.pid")
 #else
 #  define _PATH_AFPDLOCK       ATALKPATHCAT(_PATH_LOCKDIR,"afpd")
@@ -81,7 +81,7 @@
 /*
  * cnid_metad paths
  */
-#if defined (FHS_COMPATIBILITY) || defined (__NetBSD__)
+#if defined (FHS_COMPATIBILITY) || defined (__NetBSD__) || defined (__OpenBSD__)
 #  define _PATH_CNID_METAD_LOCK        ATALKPATHCAT(_PATH_LOCKDIR,"cnid_metad.pid")
 #else
 #  define _PATH_CNID_METAD_LOCK        ATALKPATHCAT(_PATH_LOCKDIR,"cnid_metad")
diff --git a/include/atalk/standards.h b/include/atalk/standards.h
new file mode 100644 (file)
index 0000000..0393dd1
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+  Copyright (c) 2011, Frank Lahm
+
+  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.
+*/
+
+#ifndef ATALK_STANDARDS_H
+#define ATALK_STANDARDS_H 1
+
+#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
+# ifndef _XOPEN_SOURCE
+#  define _XOPEN_SOURCE 600
+# endif
+# ifndef __EXTENSIONS__
+#  define __EXTENSIONS__
+# endif
+# ifndef _GNU_SOURCE
+#  define _GNU_SOURCE
+# endif
+#endif
+
+#endif /* ATALK_STANDARDS_H */
index 06e3f49391dd7feea4e0998b805e9dcbfb4e9406..f6d191ca6000d21f1613cad1a3fd6afb47083786 100644 (file)
@@ -26,7 +26,6 @@
 /* vfs/unix.c */
 extern int netatalk_unlink(const char *name);
 extern int netatalk_unlinkat(int dirfd, const char *name);
-extern char *fullpathname(const char *);
 extern int statat(int dirfd, const char *path, struct stat *st);
 extern int lstatat(int dirfd, const char *path, struct stat *st);
 extern DIR *opendirat(int dirfd, const char *path);
index 1664c8c992fccd11c45a139e267e3308827a39e7..1febc062c0128fee626f5d64845b413effd0e2ab 100644 (file)
 #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))
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? a : b)
+#endif
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? a : b)
+#endif
 
 #if BYTE_ORDER == BIG_ENDIAN
 #define hton64(x)       (x)
@@ -171,6 +177,7 @@ extern int recv_fd(int fd, int nonblocking);
 
 extern const char *abspath(const char *name);
 extern const char *getcwdpath(void);
+extern const char *fullpathname(const char *);
 extern char *stripped_slashes_basename(char *p);
 extern int lchdir(const char *dir);
 extern void randombytes(void *buf, int n);
index 615ecd631428a6c535f1c0e858291fc46841e6df..82de0420c95260b87757a79566daa84ee7e7437a 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef ATALK_VOLUME_H
 #define ATALK_VOLUME_H 1
 
+#include <stdint.h>
+#include <sys/cdefs.h>
 #include <sys/types.h>
 
 #include <atalk/unicode.h>
@@ -61,8 +63,9 @@ struct vol {
     char            *v_gvs;
     void            *v_nfsclient;
     int             v_nfs;
-    uintmax_t       v_tm_used;  /* used bytes on a TM volume */
-    uintmax_t       v_written;  /* amount of data written in afp_write, reset every time a FCE_TM_SIZE event is sent */
+    VolSpace        v_tm_used;  /* used bytes on a TM volume */
+    time_t          v_tm_cachetime; /* time at which v_tm_used was calculated last */
+    VolSpace        v_appended; /* amount of data appended to files */
     
     /* only when opening/closing volumes or in error */
     int             v_casefold;
index 9079fc1ded403cf6fe9267f109f6cb56db247b77..42a7d648d032636c583cb2e1c055bbe2548cae62 100644 (file)
@@ -25,6 +25,8 @@
 #ifndef _ATALK_ZIP_H
 #define _ATALK_ZIP_H 1
 
+#ifndef NO_DDP
+
 #include <netatalk/endian.h>
 
 struct ziphdr {
@@ -55,4 +57,5 @@ struct zipreplent {
 #define ZIPGNI_INVALID 0x80
 #define ZIPGNI_ONEZONE 0x20
 
+#endif  /* NO_DDP */
 #endif
index 0ff0ea5b6c169597ef5208767231329d0d320354..9bad9c94ea277ec4d1a7be192ab539aa6c71977d 100644 (file)
@@ -1,5 +1,6 @@
 /*
   Copyright (c) 2010 Frank Lahm <franklahm@gmail.com>
+  Copyright (c) 2011 Laura Mueller <laura-mueller@uni-duesseldorf.de>
 
   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
@@ -16,7 +17,7 @@
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
 
-#ifdef HAVE_SOLARIS_ACLS
+#ifdef HAVE_ACLS
 
 #include <unistd.h>
 #include <sys/types.h>
@@ -33,6 +34,8 @@
 #include <atalk/util.h>
 #include <atalk/acl.h>
 
+#ifdef HAVE_SOLARIS_ACLS
+
 /* Get ACL. Allocates storage as needed. Caller must free.
  * Returns no of ACEs or -1 on error.  */
 int get_nfsv4_acl(const char *name, ace_t **retAces)
@@ -52,18 +55,18 @@ int get_nfsv4_acl(const char *name, ace_t **retAces)
         /* sorry, no ACLs for symlinks */
         return 0;
 
-    if ( ! ((S_ISREG(st.st_mode)) || (S_ISDIR(st.st_mode)))) {
-        LOG(log_warning, logtype_afpd, "get_nfsv4_acl(\"%s/%s\"): special", getcwdpath(), name);
+    if ( ! (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))) {
+        LOG(log_debug, logtype_afpd, "get_nfsv4_acl(\"%s/%s\"): special", getcwdpath(), name);
         return 0;
     }
 
     if ((ace_count = acl(name, ACE_GETACLCNT, 0, NULL)) == 0) {
-        LOG(log_warning, logtype_afpd, "get_nfsv4_acl(\"%s/%s\"): 0 ACEs", getcwdpath(), name);
+        LOG(log_debug, logtype_afpd, "get_nfsv4_acl(\"%s/%s\"): 0 ACEs", getcwdpath(), name);
         return 0;
     }
 
     if (ace_count == -1) {
-        LOG(log_error, logtype_afpd, "get_nfsv4_acl: acl('%s/%s', ACE_GETACLCNT): ace_count %i, error: %s",
+        LOG(log_debug, logtype_afpd, "get_nfsv4_acl: acl('%s/%s', ACE_GETACLCNT): ace_count %i, error: %s",
             getcwdpath(), name, ace_count, strerror(errno));
         return -1;
     }
@@ -202,10 +205,10 @@ int strip_nontrivial_aces(ace_t **saces, int sacecount)
  * Change mode of file preserving existing explicit ACEs
  *
  * nfsv4_chmod
- * (1) reads objects ACL (acl1)
+ * (1) reads objects ACL (acl1), may return 0 or -1 NFSv4 ACEs on eg UFS fs
  * (2) removes all trivial ACEs from the ACL by calling strip_trivial_aces(), possibly
  *     leaving 0 ACEs in the ACL if there were only trivial ACEs as mapped from the mode
- * (3) calls chmod() with mode
+ * (3) calls chmod() with mode, we're done if step (1) returned 0 for noaces
  * (4) reads the changed ACL (acl2) which
  *     a) might still contain explicit ACEs (up to onnv132)
  *     b) will have any explicit ACE removed (starting with onnv145/Openindiana)
@@ -222,14 +225,12 @@ int nfsv4_chmod(char *name, mode_t mode)
     LOG(log_debug, logtype_afpd, "nfsv4_chmod(\"%s/%s\", %04o)",
         getcwdpath(), name, mode);
 
-    if ((noaces = get_nfsv4_acl(name, &oacl)) == -1) /* (1) */
-        goto exit;
+    if ((noaces = get_nfsv4_acl(name, &oacl)) < 1) /* (1) */
+        return chmod(name, mode);
+
     if ((noaces = strip_trivial_aces(&oacl, noaces)) == -1) /* (2) */
         goto exit;
 
-#ifdef chmod
-#undef chmod
-#endif
     if (chmod(name, mode) != 0) /* (3) */
         goto exit;
 
@@ -258,3 +259,229 @@ exit:
 }
 
 #endif /* HAVE_SOLARIS_ACLS */
+
+#ifdef HAVE_POSIX_ACLS
+
+/* This is a workaround for chmod() on filestystems supporting Posix 1003.1e draft 17
+ * compliant ACLs. For objects with extented ACLs, eg objects with an ACL_MASK entry,
+ * chmod() manipulates ACL_MASK instead of ACL_GROUP_OBJ. As OS X isn't aware of
+ * this behavior calling FPSetFileDirParms may lead to unpredictable results. For
+ * more information see section 23.1.2 of Posix 1003.1e draft 17.
+ *
+ * posix_chmod() accepts the same arguments as chmod() and returns 0 in case of
+ * success or -1 in case something went wrong.
+ */
+
+#define SEARCH_GROUP_OBJ 0x01
+#define SEARCH_MASK 0x02
+
+int posix_chmod(const char *name, mode_t mode) {
+    int ret = 0;
+    int entry_id = ACL_FIRST_ENTRY;
+    acl_entry_t entry;
+    acl_entry_t group_entry;
+    acl_tag_t tag;
+    acl_t acl;
+    u_char not_found = (SEARCH_GROUP_OBJ|SEARCH_MASK); /* used as flags */
+
+    LOG(log_maxdebug, logtype_afpd, "posix_chmod: %s mode: 0x%08x", name, mode);
+
+    /* Call chmod() first because there might be some special bits to be set which
+     * aren't related to access control.
+     */
+    ret = chmod(name, mode);
+
+    if (ret)
+       goto done;
+
+    /* Check if the underlying filesystem supports ACLs. */
+    acl = acl_get_file(name, ACL_TYPE_ACCESS);
+
+    if (acl) {
+        /* There is no need to keep iterating once we have found ACL_GROUP_OBJ and ACL_MASK. */
+        while ((acl_get_entry(acl, entry_id, &entry) == 1) && not_found) {
+            entry_id = ACL_NEXT_ENTRY;
+
+            ret = acl_get_tag_type(entry, &tag);
+
+           if (ret) {
+                LOG(log_error, logtype_afpd, "posix_chmod: Failed to get tag type.");
+                goto cleanup;
+           }
+
+            switch (tag) {
+                case ACL_GROUP_OBJ:
+                    group_entry = entry;
+                    not_found &= ~SEARCH_GROUP_OBJ;
+                    break;
+
+                case ACL_MASK:
+                    not_found &= ~SEARCH_MASK;
+                    break;
+
+                default:
+                    break;
+            }
+        }
+        if (!not_found) {
+            /* The filesystem object has extented ACLs. We have to update ACL_GROUP_OBJ
+             * with the group permissions.
+             */
+           acl_permset_t permset;
+            acl_perm_t perm = 0;
+
+            ret = acl_get_permset(group_entry, &permset);
+
+            if (ret) {
+                LOG(log_error, logtype_afpd, "posix_chmod: Can't get permset.");
+                goto cleanup;
+            }
+            ret = acl_clear_perms(permset);
+
+            if (ret)
+                goto cleanup;
+
+            if (mode & S_IXGRP)
+                perm |= ACL_EXECUTE;
+
+            if (mode & S_IWGRP)
+                perm |= ACL_WRITE;
+
+            if (mode & S_IRGRP)
+                perm |= ACL_READ;
+
+            ret = acl_add_perm(permset, perm);
+
+            if (ret)
+                goto cleanup;
+
+            ret = acl_set_permset(group_entry, permset);
+
+            if (ret) {
+                LOG(log_error, logtype_afpd, "posix_chmod: Can't set permset.");
+                goto cleanup;
+            }
+            /* also update ACL_MASK */
+            ret = acl_calc_mask(&acl);
+
+           if (ret) {
+                LOG(log_error, logtype_afpd, "posix_chmod: acl_calc_mask failed.");
+               goto cleanup;
+            }
+           ret = acl_set_file(name, ACL_TYPE_ACCESS, acl);
+        }
+cleanup:
+        acl_free(acl);
+    }
+done:
+    LOG(log_maxdebug, logtype_afpd, "posix_chmod: %d", ret);
+    return ret;
+}
+
+/*
+ * posix_fchmod() accepts the same arguments as fchmod() and returns 0 in case of
+ * success or -1 in case something went wrong.
+ */
+int posix_fchmod(int fd, mode_t mode) {
+    int ret = 0;
+    int entry_id = ACL_FIRST_ENTRY;
+    acl_entry_t entry;
+    acl_entry_t group_entry;
+    acl_tag_t tag;
+    acl_t acl;
+    u_char not_found = (SEARCH_GROUP_OBJ|SEARCH_MASK); /* used as flags */
+
+    /* Call chmod() first because there might be some special bits to be set which
+     * aren't related to access control.
+     */
+    ret = fchmod(fd, mode);
+
+    if (ret)
+        goto done;
+
+    /* Check if the underlying filesystem supports ACLs. */
+    acl = acl_get_fd(fd);
+
+    if (acl) {
+        /* There is no need to keep iterating once we have found ACL_GROUP_OBJ and ACL_MASK. */
+        while ((acl_get_entry(acl, entry_id, &entry) == 1) && not_found) {
+            entry_id = ACL_NEXT_ENTRY;
+
+            ret = acl_get_tag_type(entry, &tag);
+
+            if (ret) {
+                LOG(log_error, logtype_afpd, "posix_fchmod: Failed to get tag type.");
+                goto cleanup;
+            }
+
+            switch (tag) {
+                case ACL_GROUP_OBJ:
+                    group_entry = entry;
+                    not_found &= ~SEARCH_GROUP_OBJ;
+                    break;
+
+                case ACL_MASK:
+                    not_found &= ~SEARCH_MASK;
+                    break;
+
+                default:
+                    break;
+            }
+        }
+        if (!not_found) {
+            /* The filesystem object has extented ACLs. We have to update ACL_GROUP_OBJ
+             * with the group permissions.
+             */
+            acl_permset_t permset;
+            acl_perm_t perm = 0;
+
+            ret = acl_get_permset(group_entry, &permset);
+
+            if (ret) {
+                LOG(log_error, logtype_afpd, "posix_fchmod: Can't get permset.");
+                goto cleanup;
+            }
+            ret = acl_clear_perms(permset);
+
+            if (ret)
+                goto cleanup;
+
+            if (mode & S_IXGRP)
+                perm |= ACL_EXECUTE;
+
+            if (mode & S_IWGRP)
+                perm |= ACL_WRITE;
+
+            if (mode & S_IRGRP)
+                perm |= ACL_READ;
+
+            ret = acl_add_perm(permset, perm);
+
+            if (ret)
+                goto cleanup;
+
+            ret = acl_set_permset(group_entry, permset);
+
+            if (ret) {
+                LOG(log_error, logtype_afpd, "posix_fchmod: Can't set permset.");
+                goto cleanup;
+            }
+            /* also update ACL_MASK */
+            ret = acl_calc_mask(&acl);
+
+            if (ret) {
+                LOG(log_error, logtype_afpd, "posix_fchmod: acl_calc_mask failed.");
+                goto cleanup;
+            }
+            ret = acl_set_fd(fd, acl);
+        }
+cleanup:
+        acl_free(acl);
+    }
+done:
+    return ret;
+}
+
+#endif /* HAVE_POSIX_ACLS */
+
+#endif /* HAVE_ACLS */
index 2a1f1426aa45b6a5aeb1aa13614c46b3be17e078..5452b271860174ddfe1cd03736c7636f83ba652c 100644 (file)
 
 #include "ad_lock.h"
 
-#if defined(LINUX_BROKEN_SENDFILE_API)
-
-extern int32_t sendfile (int fdout, int fdin, int32_t *offset, u_int32_t count);
+#if defined(SENDFILE_FLAVOR_LINUX)
+#include <sys/sendfile.h>
 
 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 {
-u_int32_t small_total;
-int32_t small_offset;
-int32_t nwritten;
-
-    /*
-     * Fix for broken Linux 2.4 systems with no working sendfile64().
-     * If the offset+count > 2 GB then pretend we don't have the
-     * system call sendfile at all. The upper layer catches this
-     * and uses a normal read. JRA.
-     */
-     if ((sizeof(off_t) >= 8) && (*offset + count > (off_t)0x7FFFFFFF)) {
-         errno = ENOSYS;
-         return -1;
-     }
-     small_offset = (int32_t)*offset;
-     small_total = (u_int32_t)count;
-     nwritten = sendfile(tofd, fromfd, &small_offset, small_total);
-     if (nwritten > = 0)
-         *offset += nwritten;
-     
-    return nwritten;
+    return sendfile(tofd, fromfd, offset, count);
 }
 
-#elif defined(SENDFILE_FLAVOR_LINUX)
+#elif defined(SENDFILE_FLAVOR_SOLARIS)
 #include <sys/sendfile.h>
 
 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
@@ -79,8 +57,6 @@ ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 }
 
 #elif defined(SENDFILE_FLAVOR_BSD )
-/* FIXME untested */
-#error sendfile semantic broken
 #include <sys/sendfile.h>
 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 {
index ab18f50c6baf4204aee05596a61916bf7f2428ea..0a977e6ae8a5f4f469b48b7b037e1811d370ba76 100644 (file)
@@ -217,7 +217,10 @@ void cnid_close(struct _cnid_db *db)
 cnid_t cnid_add(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, 
                 const char *name, const size_t len, cnid_t hint)
 {
-cnid_t ret;
+    cnid_t ret;
+
+    if (len == 0)
+        return CNID_INVALID;
 
     block_signal(cdb->flags);
     ret = valide(cdb->cnid_add(cdb, st, did, name, len, hint));
index 4d5a904d199003b8930f6b87e93641ee6907a13d..45798b09e6f026715fb0fc4a1cd9956f56b40bd9 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: dsi_cmdreply.c,v 1.5 2009-10-25 06:13:11 didg Exp $
- *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
  */
 #include <arpa/inet.h>
 
 #include <atalk/dsi.h>
+#include <atalk/logger.h>
+#include <netatalk/endian.h>
 
 /* this assumes that the reply follows right after the command, saving
  * on a couple assignments. specifically, command, requestID, and
  * reserved field are assumed to already be set. */ 
 int dsi_cmdreply(DSI *dsi, const int err)
 {
-int ret;
-  dsi->header.dsi_flags = DSIFL_REPLY;
-  /*dsi->header.dsi_command = DSIFUNC_CMD;*/
-  dsi->header.dsi_len = htonl(dsi->datalen);
-  dsi->header.dsi_code = htonl(err);
-
-  ret = dsi_stream_send(dsi, dsi->data, dsi->datalen);
-  return ret;
+    int ret;
+
+    LOG(log_debug, logtype_dsi, "dsi_cmdreply(DSI ID: %u, len: %jd): START",
+        dsi->clientID, (intmax_t)dsi->datalen);
+
+    dsi->header.dsi_flags = DSIFL_REPLY;
+    dsi->header.dsi_len = htonl(dsi->datalen);
+    dsi->header.dsi_code = htonl(err);
+
+    ret = dsi_stream_send(dsi, dsi->data, dsi->datalen);
+
+    LOG(log_debug, logtype_dsi, "dsi_cmdreply(DSI ID: %u, len: %jd): END",
+        dsi->clientID, (intmax_t)dsi->datalen);
+
+    return ret;
 }
index c723b3b43b878063c2ede7c1287cb8eea93589d9..75dfe9579d1c0923c3818a0b42255386f3e5fdd7 100644 (file)
 #include <sys/time.h>
 
 #include <atalk/dsi.h>
-
-#ifndef min
-#define min(a,b)   ((a) < (b) ? (a) : (b))
-#endif /* ! min */
+#include <atalk/util.h>
+#include <atalk/logger.h>
 
 /* streaming i/o for afp_read. this is all from the perspective of the
  * client. it basically does the reverse of dsi_write. on first entry,
  * buffer. it returns the amount of stuff still to be read
  * (constrained by the buffer size). */
 ssize_t dsi_readinit(DSI *dsi, void *buf, const size_t buflen,
-                   const size_t size, const int err)
+                     const size_t size, const int err)
 {
+    LOG(log_maxdebug, logtype_dsi, "dsi_readinit: sending %zd bytes from buffer, total size: %zd",
+        buflen, size);
 
-  dsi->flags |= DSI_NOREPLY; /* we will handle our own replies */
-  dsi->header.dsi_flags = DSIFL_REPLY;
-  /*dsi->header.dsi_command = DSIFUNC_CMD;*/
-  dsi->header.dsi_len = htonl(size);
-  dsi->header.dsi_code = htonl(err);
+    dsi->flags |= DSI_NOREPLY; /* we will handle our own replies */
+    dsi->header.dsi_flags = DSIFL_REPLY;
+    dsi->header.dsi_len = htonl(size);
+    dsi->header.dsi_code = htonl(err);
 
-  dsi->in_write++;
-  if (dsi_stream_send(dsi, buf, buflen)) {
-    dsi->datasize = size - buflen;
-    return min(dsi->datasize, buflen);
-  }
+    dsi->in_write++;
+    if (dsi_stream_send(dsi, buf, buflen)) {
+        dsi->datasize = size - buflen;
+        LOG(log_maxdebug, logtype_dsi, "dsi_readinit: remaining data for sendfile: %zd", dsi->datasize);
+        return MIN(dsi->datasize, buflen);
+    }
 
-  return -1; /* error */
+    return -1; /* error */
 }
 
 void dsi_readdone(DSI *dsi)
 {
-  dsi->in_write--;
+    dsi->in_write--;
 }
 
 /* send off the data */
 ssize_t dsi_read(DSI *dsi, void *buf, const size_t buflen)
 {
-  size_t len;
-  
-  len  = dsi_stream_write(dsi, buf, buflen, 0);
+    size_t len;
+
+    len  = dsi_stream_write(dsi, buf, buflen, 0);
 
-  if (len == buflen) {
-    dsi->datasize -= len;
-    return min(dsi->datasize, buflen);
-  }
+    if (len == buflen) {
+        dsi->datasize -= len;
+        return MIN(dsi->datasize, buflen);
+    }
 
-  return -1;
+    return -1;
 }
index 14a560815b6aa6050298e66af29db0076934613a..ef25275241e170c5563e730eba8260494cfa3d4e 100644 (file)
@@ -265,7 +265,7 @@ ssize_t dsi_stream_write(DSI *dsi, void *data, const size_t length, int mode)
   dsi->in_write++;
   written = 0;
 
-  LOG(log_maxdebug, logtype_dsi, "dsi_stream_write: sending %u bytes", length);
+  LOG(log_maxdebug, logtype_dsi, "dsi_stream_write(send: %zd bytes): START", length);
 
   if (dsi->flags & DSI_DISCONNECTED)
       return -1;
@@ -304,6 +304,7 @@ ssize_t dsi_stream_write(DSI *dsi, void *data, const size_t length, int mode)
   }
 
   dsi->write_count += written;
+  LOG(log_maxdebug, logtype_dsi, "dsi_stream_write(send: %zd bytes): END", length);
 
 exit:
   dsi->in_write--;
@@ -316,10 +317,12 @@ exit:
 #ifdef WITH_SENDFILE
 ssize_t dsi_stream_read_file(DSI *dsi, int fromfd, off_t offset, const size_t length)
 {
+  int ret = 0;
   size_t written;
   ssize_t len;
+  off_t pos = offset;
 
-  LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file: sending %u bytes", length);
+  LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file(send %zd bytes): START", length);
 
   if (dsi->flags & DSI_DISCONNECTED)
       return -1;
@@ -328,15 +331,24 @@ ssize_t dsi_stream_read_file(DSI *dsi, int fromfd, off_t offset, const size_t le
   written = 0;
 
   while (written < length) {
-    len = sys_sendfile(dsi->socket, fromfd, &offset, length - written);
+    len = sys_sendfile(dsi->socket, fromfd, &pos, length - written);
         
     if (len < 0) {
       if (errno == EINTR)
           continue;
-      if (errno == EINVAL || errno == ENOSYS)
-          return -1;
-          
+      if (errno == EINVAL || errno == ENOSYS) {
+          ret = -1;
+          goto exit;
+      }          
       if (errno == EAGAIN || errno == EWOULDBLOCK) {
+#ifdef SOLARIS
+          if (pos > offset) {
+              /* we actually have sent sth., adjust counters and keep trying */
+              len = pos - offset;
+              written += len;
+              offset = pos;
+          }
+#endif
           if (dsi_peek(dsi)) {
               /* can't go back to blocking mode, exit, the next read
                  will return with an error and afpd will die.
@@ -350,15 +362,20 @@ ssize_t dsi_stream_read_file(DSI *dsi, int fromfd, off_t offset, const size_t le
     }
     else if (!len) {
         /* afpd is going to exit */
-        errno = EIO;
-        return -1; /* I think we're at EOF here... */
+          ret = -1;
+          goto exit;
     }
     else 
         written += len;
   }
 
   dsi->write_count += written;
+
+exit:
   dsi->in_write--;
+  LOG(log_maxdebug, logtype_dsi, "dsi_stream_read_file: sent: %zd", written);
+  if (ret != 0)
+      return -1;
   return written;
 }
 #endif
@@ -422,8 +439,7 @@ int dsi_stream_send(DSI *dsi, void *buf, size_t length)
   size_t towrite;
   ssize_t len;
 
-  LOG(log_maxdebug, logtype_dsi, "dsi_stream_send: %u bytes",
-      length ? length : sizeof(block));
+  LOG(log_maxdebug, logtype_dsi, "dsi_stream_send(%u bytes): START", length);
 
   if (dsi->flags & DSI_DISCONNECTED)
       return 0;
@@ -438,6 +454,7 @@ int dsi_stream_send(DSI *dsi, void *buf, size_t length)
         sizeof(dsi->header.dsi_reserved));
 
   if (!length) { /* just write the header */
+      LOG(log_maxdebug, logtype_dsi, "dsi_stream_send(%u bytes): DSI header, no data", sizeof(block));
     length = (dsi_stream_write(dsi, block, sizeof(block), 0) == sizeof(block));
     return length; /* really 0 on failure, 1 on success */
   }
@@ -481,22 +498,26 @@ int dsi_stream_send(DSI *dsi, void *buf, size_t length)
           iov[1].iov_len -= len;
       }
   }
+
+  LOG(log_maxdebug, logtype_dsi, "dsi_stream_send(%u bytes): END", length);
   
   unblock_sig(dsi);
   return 1;
 }
 
 
-/* ---------------------------------------
- * read data. function on success. 0 on failure. data length gets
- * stored in length variable. this should really use size_t's, but
- * that would require changes elsewhere. */
-int dsi_stream_receive(DSI *dsi, void *buf, const size_t ilength,
-                      size_t *rlength)
+/*!
+ * Read DSI command and data
+ *
+ * @param  dsi   (rw) DSI handle
+ *
+ * @return    DSI function on success, 0 on failure
+ */
+int dsi_stream_receive(DSI *dsi)
 {
   char block[DSI_BLOCKSIZ];
 
-  LOG(log_maxdebug, logtype_dsi, "dsi_stream_receive: %u bytes", ilength);
+  LOG(log_maxdebug, logtype_dsi, "dsi_stream_receive: START");
 
   if (dsi->flags & DSI_DISCONNECTED)
       return 0;
@@ -507,26 +528,22 @@ int dsi_stream_receive(DSI *dsi, void *buf, const size_t ilength,
 
   dsi->header.dsi_flags = block[0];
   dsi->header.dsi_command = block[1];
-  /* FIXME, not the right place, 
-     but we get a server disconnect without reason in the log
-  */
-  if (!block[1]) {
-      LOG(log_error, logtype_dsi, "dsi_stream_receive: invalid packet, fatal");
+
+  if (dsi->header.dsi_command == 0)
       return 0;
-  }
 
-  memcpy(&dsi->header.dsi_requestID, block + 2, 
-        sizeof(dsi->header.dsi_requestID));
+  memcpy(&dsi->header.dsi_requestID, block + 2, sizeof(dsi->header.dsi_requestID));
   memcpy(&dsi->header.dsi_code, block + 4, sizeof(dsi->header.dsi_code));
   memcpy(&dsi->header.dsi_len, block + 8, sizeof(dsi->header.dsi_len));
-  memcpy(&dsi->header.dsi_reserved, block + 12,
-        sizeof(dsi->header.dsi_reserved));
+  memcpy(&dsi->header.dsi_reserved, block + 12, sizeof(dsi->header.dsi_reserved));
   dsi->clientID = ntohs(dsi->header.dsi_requestID);
   
   /* make sure we don't over-write our buffers. */
-  *rlength = min(ntohl(dsi->header.dsi_len), ilength);
-  if (dsi_stream_read(dsi, buf, *rlength) != *rlength
+  dsi->cmdlen = min(ntohl(dsi->header.dsi_len), DSI_CMDSIZ);
+  if (dsi_stream_read(dsi, dsi->commands, dsi->cmdlen) != dsi->cmdlen
     return 0;
 
+  LOG(log_debug, logtype_dsi, "dsi_stream_receive: DSI cmdlen: %zd", dsi->cmdlen);
+
   return block[1];
 }
index c925b00d74204a8792e911a43a30332134f17aca..5b47a78bf7ee990423b20502f18aa838ae4ea955 100644 (file)
@@ -1,6 +1,6 @@
 /* DO NOT EDIT BY HAND!!!                                           */
 /* This file is generated by                                        */
-/*              contrib/misc/make-precompose.h.pl UnicodeData.txt   */
+/*       contrib/shell_utils/make-precompose.h.pl UnicodeData.txt   */
 
 /* UnicodeData.txt is got from                                      */
 /* http://www.unicode.org/Public/UNIDATA/UnicodeData.txt            */
index dab888c280ca19fea8924700fab1b2cbddbd288b..3fc7ed36586081469f0423671d86b7d0ccc6cfea 100644 (file)
@@ -2,7 +2,7 @@
 DO NOT EDIT BY HAND!!!
 
 This file is generated by
- contrib/misc/make-casetable.pl UnicodeData.txt utf16_casetable.h utf16_case.c
+ contrib/shell_utils/make-casetable.pl UnicodeData.txt utf16_casetable.h utf16_case.c
 
 UnicodeData.txt is got from
 http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
index dab605f746f3d872a4312aaa466a094139414651..c0a268802e635417397e27e3f3ee882600238d49 100644 (file)
@@ -2,7 +2,7 @@
 DO NOT EDIT BY HAND!!!
 
 This file is generated by
- contrib/misc/make-casetable.pl UnicodeData.txt utf16_casetable.h utf16_case.c
+ contrib/shell_utils/make-casetable.pl UnicodeData.txt utf16_casetable.h utf16_case.c
 
 UnicodeData.txt is got from
 http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
index 9ce83c4dc4fac3606dfa744ee6234f62b1b51165..241b22df092285aff506350c137d6c2122df9385 100644 (file)
@@ -27,10 +27,9 @@ Netatalk 2001 (c)
 #include <time.h>
 #include <ctype.h>
 #include <errno.h>
+#include <stdbool.h>
 
-#include <atalk/boolean.h>
 #include <atalk/util.h>
-
 #include <atalk/logger.h>
 
 #define OPEN_LOGS_AS_UID 0
index c80a023d76225fddc6e69fbce5bfe803e1f57007..eda69c6c7e078c583e031add2aad2bd89d95d020 100644 (file)
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
 
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-# ifndef _XOPEN_SOURCE
-#  define _XOPEN_SOURCE 600
-# endif
-# ifndef __EXTENSIONS__
-#  define __EXTENSIONS__
-# endif
-# ifndef _GNU_SOURCE
-#  define _GNU_SOURCE
-# endif
-#endif
+#include <atalk/standards.h>
+
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <arpa/inet.h>
+#include <sys/uio.h>
 #include <netinet/in.h>
+#include <arpa/inet.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
index d202b99a31f9d1dc165c7836b8b43d3d0fcd6f4c..0ac210ec2c8d4e3e1d99ab16a33f7067cfabd24f 100644 (file)
@@ -112,28 +112,25 @@ const char *getcwdpath(void)
 }
 
 /*!
- * Make argument path absoulte
+ * @brief Request absolute path
  *
- * @returns pointer to path or pointer to error messages on error
+ * @returns Absolute filesystem path to object
  */
-const char *abspath(const char *name)
+const char *fullpathname(const char *name)
 {
-    static char buf[MAXPATHLEN + 1];
-    char *p;
-    int n;
+    static char wd[MAXPATHLEN + 1];
 
     if (name[0] == '/')
         return name;
 
-    if ((p = getcwd(buf, MAXPATHLEN)) == NULL)
-        return strerror(errno);
+    if (getcwd(wd , MAXPATHLEN)) {
+        strlcat(wd, "/", MAXPATHLEN);
+        strlcat(wd, name, MAXPATHLEN);
+    } else {
+        strlcpy(wd, name, MAXPATHLEN);
+    }
 
-    n = strlen(buf);
-    if (buf[n-1] != '/')
-        buf[n++] = '/';
-        
-    strlcpy(buf + n, name, MAXPATHLEN - n);
-    return buf;
+    return wd;
 }
 
 /*!
index 6e950924120995bd961a1e36002f0f8fbb368d40..52360b1ece0330089386c5383f9cc619c74403e3 100644 (file)
@@ -485,13 +485,19 @@ int savevolinfo(const struct vol *vol, const char *Cnid_srv, const char *Cnid_po
     }
 
     if ((fd = open(item, O_RDWR | O_CREAT , 0666)) <0 ) {
-        LOG(log_error, logtype_afpd,"Error opening %s: %s", item, strerror(errno));
+        LOG(log_debug, logtype_default,"Error opening %s: %s", item, strerror(errno));
+        if (process_uid) {
+            if (seteuid(process_uid) == -1) {
+                LOG(log_error, logtype_default, "can't seteuid back %s", strerror(errno));
+                exit(EXITERR_SYS);
+            }
+        }
         return (-1);
     }
 
     if (process_uid) {
         if (seteuid(process_uid) == -1) {
-            LOG(log_error, logtype_logger, "can't seteuid back %s", strerror(errno));
+            LOG(log_error, logtype_default, "can't seteuid back %s", strerror(errno));
             exit(EXITERR_SYS);
         }
     }
@@ -507,7 +513,7 @@ int savevolinfo(const struct vol *vol, const char *Cnid_srv, const char *Cnid_po
             /* ignore, other process already writing the file */
             return 0;
         } else {
-            LOG(log_error, logtype_cnid, "savevoloptions: cannot get lock: %s", strerror(errno));
+            LOG(log_error, logtype_default, "savevoloptions: cannot get lock: %s", strerror(errno));
             return (-1);
         }
     }
@@ -587,9 +593,9 @@ int savevolinfo(const struct vol *vol, const char *Cnid_srv, const char *Cnid_po
     strlcat(buf, item, sizeof(buf));
 
     if (strlen(buf) >= sizeof(buf)-1)
-        LOG(log_debug, logtype_afpd,"Error writing .volinfo file: buffer too small, %s", buf);
+        LOG(log_debug, logtype_default, "Error writing .volinfo file: buffer too small, %s", buf);
    if (write( fd, buf, strlen(buf)) < 0 || ftruncate(fd, strlen(buf)) < 0 ) {
-       LOG(log_debug, logtype_afpd,"Error writing .volinfo file: %s", strerror(errno));
+       LOG(log_debug, logtype_default, "Error writing .volinfo file: %s", strerror(errno));
    }
 
    lock.l_type = F_UNLCK;
index 1396ce34c809d98e5083f1b96ba16fe49180f266..c936f178d79bbd8bbbafc8c0269a07275ac550a7 100644 (file)
@@ -90,7 +90,7 @@ exit:
 
 #ifdef HAVE_POSIX_ACLS
 /*!
- * Remove any ACL_USER, ACL_GROUP or ACL_TYPE_DEFAULT ACEs from an object
+ * Remove any ACL_USER, ACL_GROUP, ACL_MASK or ACL_TYPE_DEFAULT ACEs from an object
  *
  * @param name  (r) filesystem object name
  *
@@ -116,14 +116,15 @@ int remove_acl_vfs(const char *name)
         acl = NULL;
     }
 
-    /* Now get ACL and remove ACL_USER or ACL_GROUP entries, then re-set the ACL again */
+    /* Now get ACL and remove ACL_MASK, ACL_USER or ACL_GROUP entries, then re-set
+     * the ACL again. acl_calc_mask() must not be called because there is no need
+     * for an ACL_MASK entry in a basic ACL. */
     EC_NULL_LOG_ERR(acl = acl_get_file(name, ACL_TYPE_ACCESS), AFPERR_MISC);
     for ( ; acl_get_entry(acl, entry_id, &e) == 1; entry_id = ACL_NEXT_ENTRY) {
         EC_ZERO_LOG_ERR(acl_get_tag_type(e, &tag), AFPERR_MISC);
-        if (tag == ACL_USER || tag == ACL_GROUP)
+        if (tag == ACL_USER || tag == ACL_GROUP || tag == ACL_MASK)
             EC_ZERO_LOG_ERR(acl_delete_entry(acl, e), AFPERR_MISC);
     }
-    EC_ZERO_LOG_ERR(acl_calc_mask(&acl), AFPERR_MISC);
     EC_ZERO_LOG_ERR(acl_valid(acl), AFPERR_MISC);
     EC_ZERO_LOG_ERR(acl_set_file(name, ACL_TYPE_ACCESS, acl), AFPERR_MISC);
 
index 7f9629b0053e19450c6d3e6a59edc10addc1373e..9f369ea4fb3506036ba204d10080a5d26a016474 100644 (file)
@@ -516,13 +516,15 @@ static int ea_delentry(struct ea * restrict ea, const char * restrict attruname)
     unsigned int count = 0;
 
     if (ea->ea_count == 0) {
-        LOG(log_error, logtype_afpd, "ea_delentry('%s'): illegal ea_count of 0 on deletion");
+        LOG(log_error, logtype_afpd, "ea_delentry('%s'): illegal ea_count of 0 on deletion",
+            attruname);
         return -1;
     }
 
     while (count < ea->ea_count) {
         /* search matching EA */
-        if (strcmp(attruname, (*ea->ea_entries)[count].ea_name) == 0) {
+        if ((*ea->ea_entries)[count].ea_name &&
+            strcmp(attruname, (*ea->ea_entries)[count].ea_name) == 0) {
             free((*ea->ea_entries)[count].ea_name);
             (*ea->ea_entries)[count].ea_name = NULL;
 
index 5e0588dfd171bf54e9b6b7410c292639aaeabb1b..14a0f1647dec29ad31974533de1561c8bc9242c7 100644 (file)
@@ -37,7 +37,7 @@ int stickydirmode(const char *name, const mode_t mode, const int dropbox, const
      *  Ignore EPERM errors:  We may be dealing with a directory that is
      *  group writable, in which case chmod will fail.
      */
-    if ( (chmod( name, (DIRBITS | mode) & ~v_umask ) < 0) && errno != EPERM &&
+    if ( (chmod_acl( name, (DIRBITS | mode) & ~v_umask ) < 0) && errno != EPERM &&
          !(errno == ENOENT && (dropbox & AFPVOL_NOADOUBLE)) )
     {
         LOG(log_error, logtype_afpd, "stickydirmode: chmod \"%s\": %s", fullpathname(name), strerror(errno) );
@@ -70,7 +70,7 @@ int setfilmode(const char * name, mode_t mode, struct stat *st, mode_t v_umask)
     
     mode |= st->st_mode & ~mask; /* keep other bits from previous mode */
 
-    if ( chmod( name,  mode & ~v_umask ) < 0 && errno != EPERM ) {
+    if ( chmod_acl( name,  mode & ~v_umask ) < 0 && errno != EPERM ) {
         return -1;
     }
     return 0;
@@ -146,21 +146,6 @@ int netatalk_unlink(const char *name)
     return AFP_OK;
 }
 
-char *fullpathname(const char *name)
-{
-    static char wd[ MAXPATHLEN + 1];
-
-    if ( getcwd( wd , MAXPATHLEN) ) {
-        strlcat(wd, "/", MAXPATHLEN);
-        strlcat(wd, name, MAXPATHLEN);
-    }
-    else {
-        strlcpy(wd, name, MAXPATHLEN);
-    }
-    return wd;
-}
-
-
 /**************************************************************************
  * *at semnatics support functions (like openat, renameat standard funcs)
  **************************************************************************/
@@ -185,13 +170,13 @@ int copy_file(int dirfd, const char *src, const char *dst, mode_t mode)
     sfd = open(src, O_RDONLY);
 #endif
     if (sfd < 0) {
-        LOG(log_error, logtype_afpd, "copy_file('%s'/'%s'): open '%s' error: %s",
+        LOG(log_info, logtype_afpd, "copy_file('%s'/'%s'): open '%s' error: %s",
             src, dst, src, strerror(errno));
         return -1;
     }
 
     if ((dfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, mode)) < 0) {
-        LOG(log_error, logtype_afpd, "copy_file('%s'/'%s'): open '%s' error: %s",
+        LOG(log_info, logtype_afpd, "copy_file('%s'/'%s'): open '%s' error: %s",
             src, dst, dst, strerror(errno));
         ret = -1;
         goto exit;
index 0eaacfaee8af8fc5f6babb34709d2e7f7c8022f9..b33138bc26ab22efe1fbd4d795b9a1b467f18c3c 100644 (file)
@@ -505,6 +505,33 @@ static int validupath_ea(VFS_FUNC_ARGS_VALIDUPATH)
 /* ----------------- */
 static int RF_chown_ea(VFS_FUNC_ARGS_CHOWN)
 {
+    mode_t file_mode = ad_hf_mode(mode);
+    mode_t dir_mode = file_mode;
+    struct set_mode param;
+
+    if ((dir_mode & (S_IRUSR | S_IWUSR )))
+        dir_mode |= S_IXUSR;
+    if ((dir_mode & (S_IRGRP | S_IWGRP )))
+        dir_mode |= S_IXGRP;
+    if ((dir_mode & (S_IROTH | S_IWOTH )))
+        dir_mode |= S_IXOTH;
+
+       /* change folder */
+       dir_mode |= DIRBITS;
+    if (dir_rx_set(dir_mode)) {
+        if (chmod_acl( name,  dir_mode ) < 0)
+            return -1;
+    }
+    param.st = st;
+    param.mode = file_mode;
+    if (for_each_adouble("setfilmode_ads", name, ads_setfilmode_loop, &param, 0, v_umask) < 0)
+        return -1;
+
+    if (!dir_rx_set(dir_mode)) {
+        if (chmod_acl( name,  dir_mode ) < 0)
+            return -1;
+    }
+
     return 0;
 }
 
index 547907c30a8bfe0a94181bd4f97d93918762a19a..f604c9d6e690f4b99866bffd204bd2209da7550b 100644 (file)
@@ -94,7 +94,7 @@ AC_DEFUN([NETATALK_GSSAPI_CHECK],
        CFLAGS="$CFLAGS $GSSAPI_CFLAGS"
        CPPFLAGS="$CPPFLAGS $GSSAPI_CPPFLAGS"
        LDFLAGS="$LDFLAGS $GSSAPI_LDFLAGS"
-       LIBS="$GSSAPI_LIBS"
+       LIBS="$LIBS $GSSAPI_LIBS"
 
 
        # check for gssapi headers
index 3ddd7a9dd5fd0f5069adcee03de762c35c57e95f..4805662d7e3933d04aa648c41cc0d322691e7a23 100644 (file)
@@ -3,6 +3,7 @@ AC_DEFUN([AC_NETATALK_CHECK_ICONV],
 
 dnl    #################################################
 dnl    # check for libiconv support
+       saved_CPPFLAGS="$CPPFLAGS"
         savedcflags="$CFLAGS"
         savedldflags="$LDFLAGS"
        ICONV_CFLAGS=""
index 94e65dd98eb8b7bb00dc0ae3367b576c5d137c43..512e479a7aae8cd5fd3a4b7f21774a4056f4e8fe 100644 (file)
@@ -199,6 +199,14 @@ case "$host_cpu" in
        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])
+        ;;
+     kfreebsd-gnu) AC_DEFINE(_GNU_SOURCE, 1, [Whether to use GNU libc extensions])
+        ;;
+esac
+
 dnl --------------------- operating system specific flags (port from sys/*)
 
 dnl ----- FreeBSD specific -----
@@ -206,7 +214,14 @@ 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 ----- GNU/kFreeBSD specific -----
+if test x"$this_os" = "xkfreebsd-gnu"; then 
+       AC_MSG_RESULT([ * GNU/kFreeBSD specific configuration])
+       AC_DEFINE(BSD4_4, 1, [BSD compatiblity macro])
+       AC_DEFINE(FREEBSD, 1, [Define if OS is FreeBSD])
     AC_DEFINE(OPEN_NOFOLLOW_ERRNO, EMLINK, errno returned by open with O_NOFOLLOW)
 fi
 
@@ -226,77 +241,9 @@ if test x"$this_os" = "xlinux"; then
        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
-
        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_QUOTA_SUPPORT, 1, [Define if Quota support should be disabled])
-       AC_DEFINE(MACOSX_SERVER, 1, [Define if compiling for MacOS X Server])
-    AC_DEFINE(NO_DDP, 1, [Define if DDP should be disabled])
-fi
-
 dnl ----- NetBSD specific -----
 if test x"$this_os" = "xnetbsd"; then 
        AC_MSG_RESULT([ * NetBSD specific configuration])
@@ -314,6 +261,7 @@ fi
 dnl ----- OpenBSD specific -----
 if test x"$this_os" = "xopenbsd"; then 
        AC_MSG_RESULT([ * OpenBSD specific configuration])
+    AC_DEFINE(BSD4_4, 1, [BSD compatiblity macro])
        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
@@ -793,3 +741,73 @@ AC_DEFUN([AC_NETATALK_SMB_SHAREMODES], [
 
     AM_CONDITIONAL(USE_SMB_SHAREMODES, test x"$neta_cv_have_smbshmd" = x"yes")
 ])
+
+dnl ------ Check for sendfile() --------
+AC_DEFUN([AC_NETATALK_SENDFILE], [
+netatalk_cv_search_sendfile=yes
+AC_ARG_ENABLE(sendfile,
+    [  --disable-sendfile       disable sendfile syscall],
+    [if test x"$enableval" = x"no"; then
+            netatalk_cv_search_sendfile=no
+        fi]
+)
+
+if test x"$netatalk_cv_search_sendfile" = x"yes"; then
+   case "$host_os" in
+   *linux*)
+        AC_DEFINE(SENDFILE_FLAVOR_LINUX,1,[Whether linux sendfile() API is available])
+        AC_CHECK_FUNC([sendfile], [netatalk_cv_HAVE_SENDFILE=yes])
+        ;;
+
+    *solaris*)
+        AC_DEFINE(SENDFILE_FLAVOR_SOLARIS, 1, [Solaris sendfile()])
+        AC_SEARCH_LIBS(sendfile, sendfile)
+        AC_CHECK_FUNC([sendfile], [netatalk_cv_HAVE_SENDFILE=yes])
+        ;;
+
+    *freebsd*)
+        AC_DEFINE(SENDFILE_FLAVOR_BSD, 1, [Define if the sendfile() function uses BSD semantics])
+        AC_CHECK_FUNC([sendfile], [netatalk_cv_HAVE_SENDFILE=yes])
+        ;;
+
+    *)
+        ;;
+
+    esac
+
+    if test x"$netatalk_cv_HAVE_SENDFILE" = x"yes"; then
+        AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() should be used])
+    fi
+fi
+])
+
+dnl --------------------- Check if realpath() takes NULL
+AC_DEFUN([AC_NETATALK_REALPATH], [
+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
+])
\ No newline at end of file
index 744c4f2b7f8e05aade37cece7e06728fbbd0a49d..8498c4246e171f9a71cd32dc1fc4eec37a06c451 100644 (file)
@@ -30,7 +30,7 @@ AC_DEFUN([AC_NETATALK_CONFIG_SUMMARY], [
                 AC_MSG_RESULT([         DHX2    ($uams_using_options)])
         fi
        if test "x$neta_cv_have_openssl" = "xyes"; then
-               AC_MSG_RESULT([         RANDNUM ($uams_using_options)])
+               AC_MSG_RESULT([         RANDNUM])
        fi
        if test x"$netatalk_cv_build_krb5_uam" = x"yes"; then
                AC_MSG_RESULT([         Kerberos V])
@@ -38,7 +38,7 @@ AC_DEFUN([AC_NETATALK_CONFIG_SUMMARY], [
        if test x"$compile_pgp" = x"yes"; then
                AC_MSG_RESULT([         PGP])
        fi
-       AC_MSG_RESULT([         passwd  ($uams_using_options)])
+       AC_MSG_RESULT([         clrtxt  ($uams_using_options)])
        AC_MSG_RESULT([         guest])
        AC_MSG_RESULT([    Options:])
        AC_MSG_RESULT([         SLP support:             $netatalk_cv_srvloc])
index b42b79b1a2b063b8b43350dac4daf1ba3de19225..7dc8014257d83f8ce21548f8f0bc012cdc4e131a 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: ad
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 30 Mar 2011
+.\"      Date: 02 Sep 2011
 .\"    Manual: Netatalk 2.2
 .\"    Source: Netatalk 2.2
 .\"  Language: English
 .\"
-.TH "AD" "1" "30 Mar 2011" "Netatalk 2.2" "Netatalk 2.2"
+.TH "AD" "1" "02 Sep 2011" "Netatalk 2.2" "Netatalk 2.2"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -23,6 +23,8 @@ ad \- Netatalk compatible UNIX file utility suite\&.
 .SH "SYNOPSIS"
 .HP \w'\fBad\fR\ 'u
 \fBad\fR {ls\ |\ cp\ |\ mv\ |\ rm} [\&.\&.\&.]
+.HP \w'\fBad\fR\ 'u
+\fBad\fR {\-v\ |\ \-\-version}
 .SH "DESCRIPTION"
 .PP
 \fBad\fR
@@ -49,8 +51,10 @@ Copy files and directories\&.
 Move files and directories\&.
 .HP \w'\fBad\ rm\fR\ 'u
 \fBad rm\fR [\-Rv] {file|directory}
+.HP \w'\fBad\ \-v|\-\-version\fR\ 'u
+\fBad \-v|\-\-version\fR
 .PP
-Remove files and directories\&.
+Show version\&.
 .SH "AD LS"
 .PP
 List files and directories\&. Options:
index 7df7c0998e78149223351b869f213a6948d94002..4bb8f4de5fe7894cc5862b3363df168ffa2c75a1 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: apple_dump
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 30 Mar 2011
+.\"      Date: 02 Sep 2011
 .\"    Manual: Netatalk 2.2
 .\"    Source: Netatalk 2.2
 .\"  Language: English
 .\"
-.TH "APPLE_DUMP" "1" "30 Mar 2011" "Netatalk 2.2" "Netatalk 2.2"
+.TH "APPLE_DUMP" "1" "02 Sep 2011" "Netatalk 2.2" "Netatalk 2.2"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -21,7 +21,7 @@
 .SH "NAME"
 apple_dump \- Dump AppleSingle/AppleDouble format file
 .SH "SYNOPSIS"
-.HP \w'\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\ 'u
+.HP \w'\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\ 'u
 \fBapple_dump\fR\fB\fR [\-a] \fIFILE\fR | \fIDIR\fR 
 .br
 \fBapple_dump\fR\fB\fR \-f \fIFILE\fR
@@ -29,6 +29,8 @@ apple_dump \- Dump AppleSingle/AppleDouble format file
 \fBapple_dump\fR\fB\fR \-d \fIFILE\fR
 .br
 \fBapple_dump\fR\fB\fR \-h | \-help | \-\-help 
+.br
+\fBapple_dump\fR\fB\fR \-v | \-version | \-\-version 
 .SH "DESCRIPTION"
 .PP
 \fBapple_dump\fR
@@ -67,6 +69,11 @@ Dump
 .RS 4
 Display the help and exit
 .RE
+.PP
+\fB\-v, \-version, \-\-version\fR
+.RS 4
+Show version and exit
+.RE
 .SH "NOTE"
 .PP
 There is no way to detect whether FinderInfo is FileInfo or DirInfo\&. By default, apple_dump examins whether file or directory, a parent directory is \&.AppleDouble, filename is \&._*, filename is \&.Parent, and so on\&.
index 2bf64bdc7ddb3bc111e5bd5f106e6e364e7524b3..2bf20b03405bb885b68dfc34a3c0324ec7ca7e4f 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: asip-status.pl
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 10 Mar 2011
+.\"      Date: 02 Sep 2011
 .\"    Manual: Netatalk 2.2
 .\"    Source: Netatalk 2.2
 .\"  Language: English
 .\"
-.TH "ASIP\-STATUS\&.PL" "1" "10 Mar 2011" "Netatalk 2.2" "Netatalk 2.2"
+.TH "ASIP\-STATUS\&.PL" "1" "02 Sep 2011" "Netatalk 2.2" "Netatalk 2.2"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -23,6 +23,10 @@ asip-status.pl \- Queries AFP servers for their capabilities
 .SH "SYNOPSIS"
 .HP \w'\fBasip\-status\&.pl\fR\fB\fR\ 'u
 \fBasip\-status\&.pl\fR\fB\fR [\-d] [\-i] [\-x] HOSTNAME[:PORT]
+
+.br
+.HP \w'\fBasip\-status\&.pl\fR\fB\fR\ 'u
+\fBasip\-status\&.pl\fR\fB\fR \-v | \-version | \-\-version 
 .SH "DESCRIPTION"
 .PP
 \fBasip\-status\&.pl\fR
@@ -45,6 +49,11 @@ Show icon if it exists\&.
 .RS 4
 Enable hex dump output\&.
 .RE
+.PP
+\fB\-v, \-version, \-\-version\fR
+.RS 4
+Show version\&.
+.RE
 .SH "EXAMPLES"
 .PP
 .if n \{\
diff --git a/man/man1/macusers.1 b/man/man1/macusers.1
new file mode 100644 (file)
index 0000000..6338c83
--- /dev/null
@@ -0,0 +1,45 @@
+'\" t
+.\"     Title: macusers
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\"      Date: 13 Oct 2011
+.\"    Manual: Netatalk 2.2
+.\"    Source: Netatalk 2.2
+.\"  Language: English
+.\"
+.TH "MACUSERS" "1" "13 Oct 2011" "Netatalk 2.2" "Netatalk 2.2"
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+macusers \- List the users connecting via AFP
+.SH "SYNOPSIS"
+.HP \w'\fBmacusers\fR\fB\fR\ 'u
+\fBmacusers\fR\fB\fR
+.HP \w'\fBmacusers\fR\fB\fR\ 'u
+\fBmacusers\fR\fB\fR \-v | \-version | \-\-version | \-h | \-help | \-\-help 
+.SH "DESCRIPTION"
+.PP
+\fBmacusers\fR
+list the users connecting via AFP\&.
+.SH "OPTIONS"
+.PP
+\fB\-v, \-version, \-\-version\fR
+.RS 4
+Show version and exit
+.RE
+.PP
+\fB\-h, \-help, \-\-help\fR
+.RS 4
+Display the help and exit
+.RE
+.SH "SEE ALSO"
+.PP
+\fBafpd\fR(8)
index 7b55c76fee304c12dbde5e500ef3ca3135eee5b1..15667962eaab307898a2b1983f6a95e878a45768 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: megatron
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 8 Jan 1992
+.\"      Date: 02 Sep 2011
 .\"    Manual: Netatalk 2.2
 .\"    Source: Netatalk 2.2
 .\"  Language: English
 .\"
-.TH "MEGATRON" "1" "8 Jan 1992" "Netatalk 2.2" "Netatalk 2.2"
+.TH "MEGATRON" "1" "02 Sep 2011" "Netatalk 2.2" "Netatalk 2.2"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -82,6 +82,12 @@ is `\fB\-\fR\', and if the conversion is from a BinHex or MacBinary file,
 will read from standard input\&.
 .PP
 The filename used to store any output file is the filename that is encoded in the source file\&. MacBinary files are created with a "\&.bin" extension\&. In the case of conflicts, the old file is overwritten!
+.SH "OPTIONS"
+.PP
+\fB\-v, \-\-version\fR
+.RS 4
+Show version\&.
+.RE
 .SH "SEE ALSO"
 .PP
 \fBafpd\fR(8)
index 716a7dc86e379df5154162b239e5e5adc338e9ce..6aabe036499e4fcdd05b3643acd7743de635f69d 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: AppleVolumes.default
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 30 Mar 2011
+.\"      Date: 13 Oct 2011
 .\"    Manual: Netatalk 2.2
 .\"    Source: Netatalk 2.2
 .\"  Language: English
 .\"
-.TH "APPLEVOLUMES\&.DEFAU" "5" "30 Mar 2011" "Netatalk 2.2" "Netatalk 2.2"
+.TH "APPLEVOLUMES\&.DEFAU" "5" "13 Oct 2011" "Netatalk 2.2" "Netatalk 2.2"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -139,6 +139,8 @@ be treated normally any longer\&. Its only aim was to temporarely share eg\&. FA
 volsizelimit:\fIsize in MiB\fR
 .RS 4
 Useful for TimeMachine: limits the reported volume size, thus preventing TM from using the whole real disk space for backup\&. Example: "volsizelimit:1000" would limit the reported disk space to 1 GB\&.
+\fBIMPORTANT: \fR
+This is an approximated calculation taking into accout the contents of TM sparsebundle images\&. Therefor you MUST NOT use this volume to store other content when using this option, because it would NOT be accounted\&. The calculation works by reading the band size from the Info\&.plist XML file of the sparsebundle, reading the bands/ directory counting the number of band files, and then multiplying one with the other\&.
 .RE
 .PP
 allow:\fI[users/groups]\fR
@@ -520,7 +522,7 @@ With OS X Apple introduced the AFP3 protocol\&. One of the most important change
 needs a way to preserve extended macintosh characters, or characters illegal in unix filenames, when saving files on a unix filesystem\&. Earlier versions used the the so called CAP encoding\&. An extended character (>0x7F) would be converted to a :xx sequence, e\&.g\&. the Apple Logo (MacRoman: 0XF0) was saved as
 :f0\&. Some special characters will be converted as to :xx notation as well\&. \'/\' will be encoded to
 :2f, if
-\fB\-usedots\fR
+\fBusedots\fR
 is not specified, a leading dot \'\&.\' will be encoded as
 :2e\&.
 .PP
index fbdd0f1f1cbcb7b7972cd6c01a007066702a5771..c6d02887ff27c15404fd820193ea8df77eb1170e 100644 (file)
@@ -131,6 +131,15 @@ These are required if the server supports the Kerberos 5 authentication UAM\&.
 .RS 4
 Use for eg\&. winbind authentication, prepends both strings before the username from login and then tries to authenticate with the result through the availabel and active UAM authentication modules\&.
 .RE
+.PP
+\-adminauthuser
+.RS 4
+Specifying eg
+\fB\-adminauthuser root\fR
+whenever a normal user login fails, afpd will try to authenticate as the specified
+\fBadminauthuser\fR\&. If this succeeds, a normal session is created for the original connecting user\&. Said differently: if you know the password of
+\fBadminauthuser\fR, you can authenticate as any other user\&.
+.RE
 .SH "CODEPAGE OPTIONS"
 .PP
 With OS X Apple introduced the AFP3 protocol\&. One of the big changes was, that AFP3 uses Unicode names encoded as Decomposed UTF\-8 (UTF8\-MAC)\&. Previous AFP/OS versions used codepages like MacRoman, MacCentralEurope, etc\&.