]> arthur.barton.de Git - netatalk.git/commitdiff
Merge 3.0.2 release branch
authorFrank Lahm <franklahm@googlemail.com>
Mon, 21 Jan 2013 17:29:41 +0000 (18:29 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Mon, 21 Jan 2013 17:29:41 +0000 (18:29 +0100)
229 files changed:
NEWS
VERSION
bin/ad/ad.c
bin/ad/ad_cp.c
bin/ad/ad_mv.c
bin/ad/ad_set.c
bin/cnid/cnid2_create.in
bin/megatron/asingle.c
bin/megatron/asingle.h
bin/megatron/hqx.c
bin/megatron/hqx.h
bin/megatron/macbin.c
bin/megatron/macbin.h
bin/megatron/megatron.h
bin/megatron/nad.c
bin/megatron/nad.h
bin/megatron/updcrc.c
bin/megatron/updcrc.h
bin/misc/fce.c
bin/misc/logger_test.c
bin/misc/netacnv.c
config/Makefile.am
config/extmap.conf [new file with mode: 0644]
configure.ac
contrib/shell_utils/apple_dump.in
distrib/initscripts/Makefile.am
distrib/initscripts/service.systemd.tmpl
etc/afpd/Makefile.am
etc/afpd/acls.c
etc/afpd/afp_config.c
etc/afpd/afp_dsi.c
etc/afpd/afp_mdns.c
etc/afpd/afp_options.c
etc/afpd/afp_util.c
etc/afpd/afs.c
etc/afpd/appl.c
etc/afpd/catsearch.c
etc/afpd/desktop.c
etc/afpd/dircache.c
etc/afpd/directory.c
etc/afpd/directory.h
etc/afpd/enumerate.c
etc/afpd/extattrs.h
etc/afpd/fce_api.c
etc/afpd/fce_api_internal.h
etc/afpd/fce_util.c
etc/afpd/file.c
etc/afpd/file.h
etc/afpd/filedir.c
etc/afpd/fork.c
etc/afpd/fork.h
etc/afpd/gettok.c [deleted file]
etc/afpd/hash.c
etc/afpd/hash.h
etc/afpd/main.c
etc/afpd/mangle.h
etc/afpd/nfsquota.c
etc/afpd/ofork.c
etc/afpd/quota.c
etc/afpd/status.c
etc/afpd/switch.h
etc/afpd/uam.c
etc/afpd/uid.c
etc/afpd/uid.h
etc/afpd/unix.c
etc/afpd/unix.h
etc/afpd/volume.c
etc/afpd/volume.h
etc/cnid_dbd/cmd_dbd.c
etc/cnid_dbd/cmd_dbd.h
etc/cnid_dbd/cmd_dbd_scanvol.c
etc/cnid_dbd/cnid_metad.c
etc/cnid_dbd/db_param.c
etc/cnid_dbd/dbd.h
etc/cnid_dbd/dbd_add.c
etc/cnid_dbd/dbd_dbcheck.c
etc/cnid_dbd/dbd_delete.c
etc/cnid_dbd/dbd_get.c
etc/cnid_dbd/dbd_getstamp.c
etc/cnid_dbd/dbd_lookup.c
etc/cnid_dbd/dbd_rebuild_add.c
etc/cnid_dbd/dbd_resolve.c
etc/cnid_dbd/dbif.c
etc/cnid_dbd/dbif.h
etc/cnid_dbd/main.c
etc/cnid_dbd/usockfd.h
etc/netatalk/netatalk.c
etc/uams/uams_dhx2_pam.c
etc/uams/uams_dhx2_passwd.c
etc/uams/uams_dhx_pam.c
etc/uams/uams_gss.c
etc/uams/uams_guest.c
etc/uams/uams_pam.c
etc/uams/uams_pgp.c
etc/uams/uams_randnum.c
include/atalk/acl.h
include/atalk/adouble.h
include/atalk/cnid.h
include/atalk/cnid_dbd_private.h
include/atalk/dictionary.h
include/atalk/dsi.h
include/atalk/errchk.h
include/atalk/fce_api.h
include/atalk/globals.h
include/atalk/hash.h
include/atalk/iniparser.h
include/atalk/ldapconfig.h
include/atalk/logger.h
include/atalk/netatalk_conf.h
include/atalk/unicode.h
include/atalk/unix.h
include/atalk/util.h
include/atalk/volume.h
libatalk/Makefile.am
libatalk/acl/Makefile.am
libatalk/acl/cache.c
libatalk/acl/cache.h
libatalk/acl/ldap.c
libatalk/acl/ldap_config.c
libatalk/acl/uuid.c
libatalk/adouble/ad_attr.c
libatalk/adouble/ad_conv.c
libatalk/adouble/ad_flush.c
libatalk/adouble/ad_lock.c
libatalk/adouble/ad_open.c
libatalk/adouble/ad_read.c
libatalk/adouble/ad_size.c
libatalk/adouble/ad_write.c
libatalk/bstring/bstradd.c
libatalk/cnid/cdb/cnid_cdb_close.c
libatalk/cnid/cdb/cnid_cdb_delete.c
libatalk/cnid/cdb/cnid_cdb_meta.c
libatalk/cnid/cdb/cnid_cdb_meta.h
libatalk/cnid/cdb/cnid_cdb_nextid.c
libatalk/cnid/cdb/cnid_cdb_open.c
libatalk/cnid/cdb/cnid_cdb_rebuild_add.c
libatalk/cnid/cdb/cnid_cdb_resolve.c
libatalk/cnid/cnid.c
libatalk/cnid/cnid_init.c
libatalk/cnid/dbd/cnid_dbd.c
libatalk/cnid/dbd/cnid_dbd.h
libatalk/cnid/last/cnid_last.c
libatalk/cnid/tdb/cnid_tdb_add.c
libatalk/cnid/tdb/cnid_tdb_close.c
libatalk/cnid/tdb/cnid_tdb_delete.c
libatalk/cnid/tdb/cnid_tdb_get.c
libatalk/cnid/tdb/cnid_tdb_lookup.c
libatalk/cnid/tdb/cnid_tdb_nextid.c
libatalk/cnid/tdb/cnid_tdb_open.c
libatalk/cnid/tdb/cnid_tdb_resolve.c
libatalk/cnid/tdb/cnid_tdb_update.c
libatalk/compat/getusershell.c
libatalk/compat/mktemp.c
libatalk/compat/rquota_xdr.c
libatalk/dsi/dsi_attn.c
libatalk/dsi/dsi_close.c
libatalk/dsi/dsi_getsess.c
libatalk/dsi/dsi_getstat.c
libatalk/dsi/dsi_tcp.c
libatalk/dsi/dsi_tickle.c
libatalk/dsi/dsi_write.c
libatalk/iniparser/dictionary.c
libatalk/iniparser/iniparser.c
libatalk/libatalk-3.0.1dev.abi [new file with mode: 0644]
libatalk/libatalk-3.0.2.abi [new file with mode: 0644]
libatalk/tdb/io.c
libatalk/tdb/tdb_private.h
libatalk/unicode/charcnv.c
libatalk/unicode/charsets/mac_roman.h
libatalk/unicode/util_unistr.c
libatalk/util/Makefile.am
libatalk/util/ftw.c
libatalk/util/gettok.c [new file with mode: 0644]
libatalk/util/locking.c
libatalk/util/logger.c
libatalk/util/module.c
libatalk/util/netatalk_conf.c
libatalk/util/server_child.c
libatalk/util/server_ipc.c
libatalk/util/server_lock.c
libatalk/util/unix.c
libatalk/vfs/ea_ad.c
libatalk/vfs/ea_sys.c
libatalk/vfs/extattr.c
libatalk/vfs/unix.c
libatalk/vfs/vfs.c
macros/Makefile.am
macros/afs-check.m4
macros/ax_pthread.m4 [new file with mode: 0644]
macros/grep-check.m4
macros/netatalk.m4
macros/pam-check.m4
macros/perl-check.m4
macros/ps-check.m4
macros/quota-check.m4
macros/ssl-check.m4
macros/summary.m4
macros/tcp-wrappers.m4
man/man1/ad.1
man/man1/afpldaptest.1.tmpl
man/man1/afppasswd.1
man/man1/apple_dump.1
man/man1/asip-status.pl.1.tmpl
man/man1/dbd.1
man/man1/hqx2bin.1
man/man1/macbinary.1
man/man1/macusers.1
man/man1/megatron.1
man/man1/netatalk-config.1
man/man1/single2bin.1
man/man1/unbin.1
man/man1/unhex.1
man/man1/uniconv.1.tmpl
man/man1/unsingle.1
man/man5/Makefile.am
man/man5/afp.conf.5.tmpl
man/man5/afp_signature.conf.5.tmpl
man/man5/afp_voluuid.conf.5.tmpl
man/man5/extmap.conf.5.tmpl [new file with mode: 0644]
man/man8/afpd.8.tmpl
man/man8/cnid_dbd.8.tmpl
man/man8/cnid_metad.8.tmpl
man/man8/netatalk.8.tmpl
test/afpd/Makefile.am
test/afpd/afpfunc_helpers.c
test/afpd/afpfunc_helpers.h
test/afpd/subtests.h
test/afpd/test.c
test/afpd/test.h

diff --git a/NEWS b/NEWS
index 0c2f55807908b665b69b4f14f01b9497c4face06..154eccf2219f26fc167b7a16aa581679c9e319f2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,37 @@
+Changes in 3.0.2
+================
+* NEW: afpd: Put file extension type/creator mapping back in which had
+       been removed in 3.0.
+* NEW: afpd: new option 'ad domain'. From FR #66.
+* FIX: volumes and home share with symlinks in the path
+* FIX: Copying packages to a Netatalk share could fail, bug #469
+* FIX: Reloading volumes from config file was broken.  Fixes bug #474.
+* FIX: Fix _device-info service type registered with dns-sd API
+* FIX: Fix pathname bug for FCE modified event.
+* FIX: Remove length limitation of options like "valid users".
+       Fixes bug #473.
+* FIX: Dont copy our metadata EA in copyfile(). Fixes bug #452.
+* FIX: Fix an error where catalog search gave incomplete results.
+       Fixes bug #479.
+* REM: Remove TimeMachine volume used size FCE event.
+* UPD: Add quoting support to '[in]valid users' option. Fixes bug #472.
+* FIX: Install working PAM config on Solaris 11. Fixes bug #481.
+* FIX: Fix a race condition between dbd and the cnid_dbd daemon
+       which could result in users being disconnected from volumes
+       when dbd was scanning their volumes. Fixes bug #477.
+* FIX: Netatalk didn't start when the last line of the config file
+       afp.conf wasn't terminated by a newline. Fixes bug #476.
+* NEW: Add a new volumes option 'follow symlinks'. The default setting is
+       false, symlinks are not followed on the server. This is the same
+       behaviour as OS X's AFP server.
+       Setting the option to true causes afpd to follow symlinks on the
+       server. symlinks may point outside of the AFP volume, currently
+       afpd doesn't do any checks for "wide symlinks".
+* FIX: Automatic AppleDouble conversion to EAs failing for directories.
+       Fixes bug #486.
+* FIX: dbd failed to convert appledouble files of symlinks.
+       Fixes bug #490.
+
 Changes in 3.0.1
 ================
 * NEW: afpd: Optional "ldap uuid encoding = string | ms-guid" parameter to
diff --git a/VERSION b/VERSION
index 13d683ccbfeed4ecf19a8f76e016a4e0296ea4cf..d9c62ed923329477e5de742a0fdf392d55cdbce3 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.0.1
\ No newline at end of file
+3.0.2
\ No newline at end of file
index 7f5b3da6260e626ae210dfa71c82e13777a55240..3de3030b9a820bbde3c53caef74a27ac1b769482 100644 (file)
@@ -58,7 +58,7 @@ int main(int argc, char **argv)
 
     setuplog("default:note", "/dev/tty");
 
-    if (load_volumes(&obj, NULL) != 0)
+    if (load_volumes(&obj) != 0)
         return 1;
 
     if (STRCMP(argv[1], ==, "ls"))
index ef995ce8cf3f159c6346a5e32a4858e9cfad8948..239936dc06940cb788a62fd198e60f6c0051878b 100644 (file)
@@ -95,36 +95,14 @@ static volatile sig_atomic_t alarmed;
 static int badcp, rval;
 static int ftw_options = FTW_MOUNT | FTW_PHYS | FTW_ACTIONRETVAL;
 
-static char           *netatalk_dirs[] = {
-    ".AppleDouble",
-    ".AppleDB",
-    ".AppleDesktop",
-    NULL
-};
-
 /* Forward declarations */
 static int copy(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf);
 static int ftw_copy_file(const struct FTW *, const char *, const struct stat *, int);
 static int ftw_copy_link(const struct FTW *, const char *, const struct stat *, int);
 static int setfile(const struct stat *, int);
-static int preserve_dir_acls(const struct stat *, char *, char *);
+// static int preserve_dir_acls(const struct stat *, char *, char *);
 static int preserve_fd_acls(int, int);
 
-/*
-  Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop"
-  Returns pointer to name or NULL.
-*/
-static const char *check_netatalk_dirs(const char *name)
-{
-    int c;
-
-    for (c=0; netatalk_dirs[c]; c++) {
-        if ((strcmp(name, netatalk_dirs[c])) == 0)
-            return netatalk_dirs[c];
-    }
-    return NULL;
-}
-
 static void upfunc(void)
 {
     did = pdid;
@@ -953,9 +931,9 @@ static int preserve_fd_acls(int source_fd, int dest_fd)
     return (0);
 }
 
+#if 0
 static int preserve_dir_acls(const struct stat *fs, char *source_dir, char *dest_dir)
 {
-#if 0
     acl_t (*aclgetf)(const char *, acl_type_t);
     int (*aclsetf)(const char *, acl_type_t, acl_t);
     struct acl *aclp;
@@ -1037,6 +1015,6 @@ static int preserve_dir_acls(const struct stat *fs, char *source_dir, char *dest
         return (1);
     }
     acl_free(acl);
-#endif
     return (0);
 }
+#endif
index 7f592dd27e1aaf0623bb2a2e34038e13a6468b33..72698f73e9ad363e2ee5495d0596c77d19144fc2 100644 (file)
@@ -50,31 +50,9 @@ static int fflg, iflg, nflg, vflg;
 static afpvol_t svolume, dvolume;
 static cnid_t did, pdid;
 static volatile sig_atomic_t alarmed;
-static char           *netatalk_dirs[] = {
-    ".AppleDouble",
-    ".AppleDB",
-    ".AppleDesktop",
-    NULL
-};
 
 static int copy(const char *, const char *);
 static int do_move(const char *, const char *);
-static void preserve_fd_acls(int source_fd, int dest_fd, const char *source_path,
-                             const char *dest_path);
-/*
-  Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop"
-  Returns pointer to name or NULL.
-*/
-static const char *check_netatalk_dirs(const char *name)
-{
-    int c;
-
-    for (c=0; netatalk_dirs[c]; c++) {
-        if ((strcmp(name, netatalk_dirs[c])) == 0)
-            return netatalk_dirs[c];
-    }
-    return NULL;
-}
 
 /*
   SIGNAL handling:
@@ -242,7 +220,6 @@ int ad_mv(int argc, char *argv[], AFPObj *obj)
         }
     }
 
-exit:
     closevol(&dvolume);
     return rval;
 }
@@ -465,12 +442,3 @@ static int copy(const char *from, const char *to)
     }
     return 0;
 }
-
-static void
-preserve_fd_acls(int source_fd,
-                 int dest_fd,
-                 const char *source_path,
-                 const char *dest_path)
-{
-    ;
-}
index d41d5222040d8dce083e9e191d0a8807c71db990..af825093c1de8c2709955b4c9c57944db8124976 100644 (file)
@@ -140,7 +140,6 @@ static void change_label(char *path, afpvol_t *vol, const struct stat *st, struc
 
 static void change_attributes(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_attributes)
 {
-    char *FinderInfo;
     uint16_t AFPattributes;
 
     ad_getattr(ad, &AFPattributes);
@@ -256,7 +255,7 @@ static void change_flags(char *path, afpvol_t *vol, const struct stat *st, struc
 
 int ad_set(int argc, char **argv, AFPObj *obj)
 {
-    int c, firstarg;
+    int c;
     afpvol_t vol;
     struct stat st;
     int adflags = 0;
index e81ff1f3e320be0b965f29225b69b04fd4516967..c3e3ffd6c30a67e44a619c2d10ecf9529edc6ae5 100755 (executable)
@@ -3,7 +3,6 @@
 #
 # Upgrade version 1 CNID databases to version 2
 #
-# $Id: cnid2_create.in,v 1.2 2005-04-28 20:49:19 bfernhomberg Exp $
 #
 # Copyright (C) Joerg Lenneis 2003
 # All Rights Reserved.  See COPYING.
index 73e4ffaaff1022e6bc60a160ae2d550338b56d17..9ba3918b6a0a2dfa65b7d6de7b6e022003e74f50 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: asingle.c,v 1.14 2010-01-27 21:27:53 didg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
index c041ccaa99c9875844bdda6e98387563f4c0b9a4..769d58cd2ede563e086a409ce0ea999a2a88d432 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: asingle.h,v 1.4 2010-01-27 21:27:53 didg Exp $
  */
 
 #ifndef _ASINGLE_H
index da2f71cf58f04f7c25d6a0851fd8d8659ff78605..923ddbd1950131c30e98a87a5e078ff230639d7b 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: hqx.c,v 1.18 2010-01-27 21:27:53 didg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
index 38730d055ef4fbf96b4658279b35f04e8f65b6f8..b656f0b63e0c8f5ded4b9a9a0403c83f331a6f9d 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: hqx.h,v 1.3 2010-01-27 21:27:53 didg Exp $
  */
 
 #ifndef _HQX_H
index 51b7ac5f616ede35aeb604892e423e3bbf4a35e6..986aac9247c91f6e7cb210030facfa4d566ef01d 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: macbin.c,v 1.15 2010-01-27 21:27:53 didg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
index d216b1b9fcae4c5fa50c5f940007f42576218255..a1c5a3a1e83aac017b1e0cb904adb457293aba02 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: macbin.h,v 1.4 2010-01-27 21:27:53 didg Exp $
  */
 
 #ifndef _MACBIN_H
index c9aa8cee547ba75916a9b611e3fdb2c8aaa840d3..421a26afc31040c207c13f3d26137922e75dbdce 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: megatron.h,v 1.5 2009-10-14 01:38:28 didg Exp $
  */
 
 #ifndef _MEGATRON_H
index 9d0b64bf5627612a6bfeb1502d0512b6b8d27f1a..abe4541c71cc2f334fe38404ac308179e66610db 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: nad.c,v 1.18 2010-01-27 21:27:53 didg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
index 9fa8568442fc8a9680f353cf568d8aba3404df3c..f69e73231571d4b476e8cb69eeefe6416d8bfec6 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: nad.h,v 1.5 2010-01-27 21:27:53 didg Exp $
  */
 
 #ifndef _NAD_H
index d327571dc20d6cc41f9ca215082564403da036ae..ca199c8a8d26fe87c126bda0ab2eacd0d008150e 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: updcrc.c,v 1.5 2009-10-13 22:55:36 didg Exp $
  *
  * updcrc(3), crc(1) - calculate crc polynomials
  *
index 0b6039e5ff7ccf45e9763b515cde05b4b890efbf..75c38388bd7d5dcfc522e429e8afe050c230dd34 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: updcrc.h,v 1.1 2009-10-13 22:55:36 didg Exp $
  */
 
 #ifndef _UPDCRC_H
index d69699079ff99c63df589f5450fbddc226f3ee3f..23101bfbb34ed7a1622c488f82a1fa4e58278c88 100644 (file)
@@ -27,20 +27,9 @@ static char *fce_ev_names[] = {
     "FCE_FILE_DELETE",
     "FCE_DIR_DELETE",
     "FCE_FILE_CREATE",
-    "FCE_DIR_CREATE",
-    "FCE_TM_SIZE"
+    "FCE_DIR_CREATE"
 };
 
-// get sockaddr, IPv4 or IPv6:
-static void *get_in_addr(struct sockaddr *sa)
-{
-    if (sa->sa_family == AF_INET) {
-        return &(((struct sockaddr_in*)sa)->sin_addr);
-    }
-
-    return &(((struct sockaddr_in6*)sa)->sin6_addr);
-}
-
 static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet)
 {
     unsigned char *p = buf;
@@ -63,6 +52,7 @@ static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet)
     packet->datalen = ntohs(packet->datalen);
 
     memcpy(&packet->data[0], p, packet->datalen);
+    packet->data[packet->datalen] = 0; /* 0 terminate strings */
     p += packet->datalen;
 
     return 0;
@@ -77,8 +67,6 @@ int main(void)
     struct sockaddr_storage their_addr;
     char buf[MAXBUFLEN];
     socklen_t addr_len;
-    char s[INET6_ADDRSTRLEN];
-    uint64_t tmsize;
 
     memset(&hints, 0, sizeof hints);
     hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
@@ -129,18 +117,11 @@ int main(void)
             exit(1);
         }
 
-        unpack_fce_packet(buf, &packet);
+        unpack_fce_packet((unsigned char *)buf, &packet);
 
         if (memcmp(packet.magic, FCE_PACKET_MAGIC, sizeof(packet.magic)) == 0) {
 
             switch (packet.mode) {
-            case FCE_TM_SIZE:
-                memcpy(&tmsize, packet.data, sizeof(uint64_t));
-                tmsize = ntoh64(tmsize);
-                printf("ID: %" PRIu32 ", Event: %s, Volume: %s, TM used size: %" PRIu64 " \n",
-                       packet.event_id, fce_ev_names[packet.mode], packet.data + sizeof(uint64_t), tmsize);
-                break;
-
             case FCE_CONN_START:
                 printf("FCE Start\n");
                 break;
index 585c15839158a61534c96aafb62258908308d4ef..cf9321142371817b50d47adab5e42f0542e377a2 100644 (file)
@@ -1,3 +1,21 @@
+/*
+  Copyright (c) 2009 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
+  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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
 #include <stdio.h>
 #include <stdbool.h>
 
index e42c76b526b36013ace3c53f993ee2be8efb90f9..70c822d80419e97d342cc9ee6e0ae57719de8bf2 100644 (file)
@@ -21,7 +21,6 @@ struct flag_map {
 
 struct flag_map flag_map[] = {
     flag(CONV_ESCAPEHEX),
-    flag(CONV_ALLOW_COLON),
     flag(CONV_UNESCAPEHEX),    
     flag(CONV_ESCAPEDOTS),
     flag(CONV_IGNORE),
@@ -39,29 +38,32 @@ int main(int argc, char **argv)
 {
     int opt;
     uint16_t flags = 0;
-    char *string;
+    char *string, *macName = MACCHARSET;
     char *f = NULL, *t = NULL;
     charset_t from, to, mac;
 
-    while ((opt = getopt(argc, argv, ":o:f:t:")) != -1) {
+    while ((opt = getopt(argc, argv, "m:o:f:t:")) != -1) {
         switch(opt) {
+        case 'm':
+            macName = strdup(optarg);
+            break;
         case 'o':
             for (int i = 0; i < sizeof(flag_map)/sizeof(struct flag_map) - 1; i++)
                 if ((strcmp(flag_map[i].flagname, optarg)) == 0)
                     flags |= flag_map[i].flag;
             break;
         case 'f':
-            f = optarg;
+            f = strdup(optarg);
             break;
         case 't':
-            t = optarg;
+            t = strdup(optarg);
             break;
         }
     }
 
     if ((optind + 1) != argc) {
-        printf("Usage: test [-o <conversion option> [...]] [-f <from charset>] [-t <to charset>] <string>\n");
-        printf("Defaults: -f: UTF8-MAC , -t: UTF8 \n");
+        printf("Usage: test [-o <conversion option> [...]] [-f <from charset>] [-t <to charset>] [-m legacy Mac charset] <string>\n");
+        printf("Defaults: -f: UTF8-MAC, -t: UTF8, -m MAC_ROMAN\n");
         printf("Available conversion options:\n");
         for (int i = 0; i < (sizeof(flag_map)/sizeof(struct flag_map) - 1); i++) {
             printf("%s\n", flag_map[i].flagname);
@@ -70,6 +72,9 @@ int main(int argc, char **argv)
     }
     string = argv[optind];
 
+    set_charset_name(CH_UNIX, "UTF8");
+    set_charset_name(CH_MAC, macName);
+
     if ( (charset_t) -1 == (from = add_charset(f ? f : "UTF8-MAC")) ) {
         fprintf( stderr, "Setting codepage %s as from codepage failed\n", f ? f : "UTF8-MAC");
         return (-1);
@@ -80,7 +85,7 @@ int main(int argc, char **argv)
         return (-1);
     }
 
-    if ( (charset_t) -1 == (mac = add_charset(MACCHARSET)) ) {
+    if ( (charset_t) -1 == (mac = add_charset(macName)) ) {
         fprintf( stderr, "Setting codepage %s as Mac codepage failed\n", MACCHARSET);
         return (-1);
     }
index 4763046063a2ce5cd491e74dd8f0c46a831fa96c..57c85ff3a67250cbcd3ec769f42c3461b5a6766a 100644 (file)
@@ -6,11 +6,11 @@ SUFFIXES = .tmpl .
 TMPLFILES = afp.conf.tmpl
 GENFILES = afp.conf
 CLEANFILES = $(GENFILES)
-EXTRA_DIST = afp.conf.tmpl
+EXTRA_DIST = afp.conf.tmpl extmap.conf
 
 OVERWRITE_CONFIG = @OVERWRITE_CONFIG@
 
-CONFFILES = 
+CONFFILES = extmap.conf
 
 pkgconfdir = @PKGCONFDIR@
 #
diff --git a/config/extmap.conf b/config/extmap.conf
new file mode 100644 (file)
index 0000000..44ccec5
--- /dev/null
@@ -0,0 +1,308 @@
+# Netatalk file extension -> OS X type/creator mapping configuration file
+#
+# Delete a '#' character at the head of line to uncomment and enable a mapping
+#
+### Default translation:
+#.         "????"  "????"      Unix Binary                    Unix                      application/octet-stream
+#.         "BINA"  "UNIX"      Unix Binary                    Unix                      application/octet-stream
+#.         "TEXT"  "ttxt"      ASCII Text                     SimpleText                text/plain
+
+#.1st      "TEXT"  "ttxt"      Text Readme                    SimpleText                application/text
+#.669      "6669"  "SNPL"      669 MOD Music                  PlayerPro
+#.8med     "STrk"  "SCPL"      Amiga OctaMed music            SoundApp
+#.8svx     "8SVX"  "SCPL"      Amiga 8-bit sound              SoundApp
+#.a        "TEXT"  "ttxt"      Assembly Source                SimpleText
+#.aif      "AIFF"  "SCPL"      AIFF Sound                     SoundApp                  audio/x-aiff
+#.aifc     "AIFC"  "SCPL"      AIFF Sound Compressed          SoundApp                  audio/x-aiff
+#.aiff     "AIFF"  "SCPL"      AIFF Sound                     SoundApp                  audio/x-aiff
+#.al       "ALAW"  "SCPL"      ALAW Sound                     SoundApp
+#.ani      "ANIi"  "GKON"      Animated NeoChrome             GraphicConverter
+#.apd      "TEXT"  "ALD3"      Aldus Printer Description      Aldus PageMaker
+#.arc      "mArc"  "SITx"      PC ARChive                     StuffIt Expander
+#.arj      "BINA"  "DArj"      ARJ Archive                    DeArj
+#.arr      "ARR "  "GKON"      Amber ARR image                GraphicConverter
+#.art      "ART "  "GKON"      First Publisher                GraphicConverter
+#.asc      "TEXT"  "ttxt"      ASCII Text                     SimpleText                text/plain
+#.ascii    "TEXT"  "ttxt"      ASCII Text                     SimpleText                text/plain
+#.asf      "ASF_"  "Ms01"      Netshow Player                 Netshow Server            video/x-ms-asf
+#.asm      "TEXT"  "ttxt"      Assembly Source                SimpleText
+#.asx      "ASX_"  "Ms01"      Netshow Player                 Netshow Server            video/x-ms-asf
+#.au       "ULAW"  "TVOD"      Sun Sound                      QuickTime Player          audio/basic
+#.avi      "VfW "  "TVOD"      AVI Movie                      QuickTime Player          video/avi
+#.bar      "BARF"  "S691"      Unix BAR Archive               SunTar
+#.bas      "TEXT"  "ttxt"      BASIC Source                   SimpleText
+#.bat      "TEXT"  "ttxt"      MS-DOS Batch File              SimpleText
+#.bga      "BMPp"  "ogle"      OS/2 Bitmap                    PictureViewer
+#.bib      "TEXT"  "ttxt"      BibTex Bibliography            SimpleText
+#.bin      "SIT!"  "SITx"      MacBinary                      StuffIt Expander          application/macbinary
+#.binary   "BINA"  "hDmp"      Untyped Binary Data            HexEdit                   application/octet-stream
+#.bmp      "BMPp"  "ogle"      Windows Bitmap                 PictureViewer
+#.boo      "TEXT"  "ttxt"      BOO encoded                    SimpleText
+#.bst      "TEXT"  "ttxt"      BibTex Style                   SimpleText
+#.bw       "SGI "  "GKON"      SGI Image                      GraphicConverter
+#.c        "TEXT"  "CWIE"      C Source                       CodeWarrior
+#.cgm      "CGMm"  "GKON"      Computer Graphics Meta         GraphicConverter
+#.class    "Clss"  "CWIE"      Java Class File                CodeWarrior
+#.clp      "CLPp"  "GKON"      Windows Clipboard              GraphicConverter
+#.cmd      "TEXT"  "ttxt"      OS/2 Batch File                SimpleText
+#.com      "PCFA"  "SWIN"      MS-DOS Executable              SoftWindows
+#.cp       "TEXT"  "CWIE"      C++ Source                     CodeWarrior
+#.cpp      "TEXT"  "CWIE"      C++ Source                     CodeWarrior
+#.cpt      "PACT"  "SITx"      Compact Pro Archive            StuffIt Expander
+#.csv      "TEXT"  "XCEL"      Comma Separated Vars           Excel
+#.ct       "..CT"  "GKON"      Scitex-CT                      GraphicConverter
+#.cut      "Halo"  "GKON"      Dr Halo Image                  GraphicConverter
+#.cvs      "drw2"  "DAD2"      Canvas Drawing                 Canvas
+#.dbf      "COMP"  "FOX+"      DBase Document                 FoxBase+
+#.dcx      "DCXx"  "GKON"      Some PCX Images                GraphicConverter
+#.dif      "TEXT"  "XCEL"      Data Interchange Format        Excel
+#.diz      "TEXT"  "R*Ch"      BBS Descriptive Text           BBEdit
+#.dl       "DL  "  "AnVw"      DL Animation                   MacAnim Viewer
+#.dll      "PCFL"  "SWIN"      Windows DLL                    SoftWindows
+#.doc      "WDBN"  "MSWD"      Word Document                  Microsoft Word            application/msword
+#.dot      "sDBN"  "MSWD"      Word for Windows Template      Microsoft Word
+#.dvi      "ODVI"  "xdvi"      TeX DVI Document               xdvi                      application/x-dvi
+#.dwt      "TEXT"  "DmWr"      Dreamweaver Template           Dreamweaver
+#.dxf      "TEXT"  "SWVL"      AutoCAD 3D Data                Swivel Pro
+#.eps      "EPSF"  "vgrd"      Postscript                     LaserWriter 8             application/postscript
+#.epsf     "EPSF"  "vgrd"      Postscript                     LaserWriter 8             application/postscript
+#.etx      "TEXT"  "ezVu"      SEText                         Easy View                 text/x-setext
+#.evy      "EVYD"  "ENVY"      Envoy Document                 Envoy
+#.exe      "PCFA"  "SWIN"      MS-DOS Executable              SoftWindows
+#.faq      "TEXT"  "ttxt"      ASCII Text                     SimpleText                text/x-usenet-faq
+#.fit      "FITS"  "GKON"      Flexible Image Transport       GraphicConverter          image/x-fits
+#.fla      "SPA "  "MFL2"      Flash source                   Macromedia Flash
+#.flc      "FLI "  "TVOD"      FLIC Animation                 QuickTime Player
+#.fli      "FLI "  "TVOD"      FLI Animation                  QuickTime Player
+#.fm       "FMPR"  "FMPR"      FileMaker Pro Database         FileMaker Pro
+#.for      "TEXT"  "MPS "      Fortran Source                 MPW Shell
+#.fts      "FITS"  "GKON"      Flexible Image Transport       GraphicConverter
+#.gem      "GEM-"  "GKON"      GEM Metafile                   GraphicConverter
+#.gif      "GIFf"  "ogle"      GIF Picture                    PictureViewer             image/gif
+#.gl       "GL  "  "AnVw"      GL Animation                   MacAnim Viewer
+#.grp      "GRPp"  "GKON"      GRP Image                      GraphicConverter
+#.gz       "SIT!"  "SITx"      Gnu ZIP Archive                StuffIt Expander          application/x-gzip
+#.h        "TEXT"  "CWIE"      C Include File                 CodeWarrior
+#.hcom     "FSSD"  "SCPL"      SoundEdit Sound ex SOX         SoundApp
+#.hp       "TEXT"  "CWIE"      C Include File                 CodeWarrior
+#.hpgl     "HPGL"  "GKON"      HP GL/2                        GraphicConverter
+#.hpp      "TEXT"  "CWIE"      C Include File                 CodeWarrior
+#.hqx      "TEXT"  "SITx"      BinHex                         StuffIt Expander          application/mac-binhex40
+#.htm      "TEXT"  "MOSS"      HyperText                      Netscape Communicator     text/html
+#.html     "TEXT"  "MOSS"      HyperText                      Netscape Communicator     text/html
+#.i3       "TEXT"  "R*ch"      Modula 3 Interface             BBEdit
+#.ic1      "IMAG"  "GKON"      Atari Image                    GraphicConverter
+#.ic2      "IMAG"  "GKON"      Atari Image                    GraphicConverter
+#.ic3      "IMAG"  "GKON"      Atari Image                    GraphicConverter
+#.icn      "ICO "  "GKON"      Windows Icon                   GraphicConverter
+#.ico      "ICO "  "GKON"      Windows Icon                   GraphicConverter
+#.ief      "IEF "  "GKON"      IEF image                      GraphicConverter          image/ief
+#.iff      "ILBM"  "GKON"      Amiga IFF Image                GraphicConverter
+#.ilbm     "ILBM"  "GKON"      Amiga ILBM Image               GraphicConverter
+#.image    "dImg"  "ddsk"      Apple DiskCopy Image           Disk Copy
+#.img      "IMGg"  "GKON"      GEM bit image/XIMG             GraphicConverter
+#.ini      "TEXT"  "ttxt"      Windows INI File               SimpleText
+#.java     "TEXT"  "CWIE"      Java Source File               CodeWarrior
+#.jfif     "JPEG"  "ogle"      JFIF Image                     PictureViewer
+#.jpe      "JPEG"  "ogle"      JPEG Picture                   PictureViewer             image/jpeg
+#.jpeg     "JPEG"  "ogle"      JPEG Picture                   PictureViewer             image/jpeg
+#.jpg      "JPEG"  "ogle"      JPEG Picture                   PictureViewer             image/jpeg
+#.latex    "TEXT"  "OTEX"      Latex                          OzTex                     application/x-latex
+#.lbm      "ILBM"  "GKON"      Amiga IFF Image                GraphicConverter
+#.lha      "LHA "  "SITx"      LHArc Archive                  StuffIt Expander
+#.lzh      "LHA "  "SITx"      LHArc Archive                  StuffIt Expander
+#.m1a      "MPEG"  "TVOD"      MPEG-1 audiostream             MoviePlayer               audio/x-mpeg
+#.m1s      "MPEG"  "TVOD"      MPEG-1 systemstream            MoviePlayer
+#.m1v      "M1V "  "TVOD"      MPEG-1 IPB videostream         MoviePlayer               video/mpeg
+#.m2       "TEXT"  "R*ch"      Modula 2 Source                BBEdit
+#.m2v      "MPG2"  "MPG2"      MPEG-2 IPB videostream         MPEG2decoder
+#.m3       "TEXT"  "R*ch"      Modula 3 Source                BBEdit
+#.mac      "PICT"  "ogle"      PICT Picture                   PictureViewer             image/x-pict
+#.mak      "TEXT"  "R*ch"      Makefile                       BBEdit
+#.mcw      "WDBN"  "MSWD"      Mac Word Document              Microsoft Word
+#.me       "TEXT"  "ttxt"      Text Readme                    SimpleText
+#.med      "STrk"  "SCPL"      Amiga MED Sound                SoundApp
+#.mf       "TEXT"  "*MF*"      Metafont                       Metafont
+#.mid      "Midi"  "TVOD"      MIDI Music                     MoviePlayer
+#.midi     "Midi"  "TVOD"      MIDI Music                     MoviePlayer
+#.mif      "TEXT"  "Fram"      FrameMaker MIF                 FrameMaker                application/x-framemaker
+#.mime     "TEXT"  "SITx"      MIME Message                   StuffIt Expander          message/rfc822
+#.ml       "TEXT"  "R*ch"      ML Source                      BBEdit
+#.mod      "STrk"  "SCPL"      MOD Music                      SoundApp
+#.mol      "TEXT"  "RSML"      MDL Molfile                    RasMac
+#.moov     "MooV"  "TVOD"      QuickTime Movie                MoviePlayer               video/quicktime
+#.mov      "MooV"  "TVOD"      QuickTime Movie                MoviePlayer               video/quicktime
+#.mp2      "MPEG"  "TVOD"      MPEG-1 audiostream             MoviePlayer               audio/x-mpeg
+#.mp3      "MPG3"  "TVOD"      MPEG-3 audiostream             MoviePlayer               audio/x-mpeg
+#.mpa      "MPEG"  "TVOD"      MPEG-1 audiostream             MoviePlayer               audio/x-mpeg
+#.mpe      "MPEG"  "TVOD"      MPEG Movie of some sort        MoviePlayer               video/mpeg
+#.mpeg     "MPEG"  "TVOD"      MPEG Movie of some sort        MoviePlayer               video/mpeg
+#.mpg      "MPEG"  "TVOD"      MPEG Movie of some sort        MoviePlayer               video/mpeg
+#.msp      "MSPp"  "GKON"      Microsoft Paint                GraphicConverter
+#.mtm      "MTM "  "SNPL"      MultiMOD Music                 PlayerPro
+#.mw       "MW2D"  "MWII"      MacWrite Document              MacWrite II               application/macwriteii
+#.mwii     "MW2D"  "MWII"      MacWrite Document              MacWrite II               application/macwriteii
+#.neo      "NeoC"  "GKON"      Atari NeoChrome                GraphicConverter
+#.nfo      "TEXT"  "ttxt"      Info Text                      SimpleText                application/text
+#.nst      "STrk"  "SCPL"      MOD Music                      SoundApp
+#.obj      "PCFL"  "SWIN"      Object (DOS/Windows)           SoftWindows
+#.oda      "ODIF"  "ODA "      ODA Document                   MacODA XTND Translator    application/oda
+#.okt      "OKTA"  "SCPL"      Oktalyser MOD Music            SoundApp
+#.out      "BINA"  "hDmp"      Output File                    HexEdit
+#.ovl      "PCFL"  "SWIN"      Overlay (DOS/Windows)          SoftWindows
+#.p        "TEXT"  "CWIE"      Pascal Source                  CodeWarrior
+#.pac      "STAD"  "GKON"      Atari STAD Image               GraphicConverter
+#.pas      "TEXT"  "CWIE"      Pascal Source                  CodeWarrior
+#.pbm      "PPGM"  "GKON"      Portable Bitmap                GraphicConverter          image/x-portable-bitmap
+#.pc1      "Dega"  "GKON"      Atari Degas Image              GraphicConverter
+#.pc2      "Dega"  "GKON"      Atari Degas Image              GraphicConverter
+#.pc3      "Dega"  "GKON"      Atari Degas Image              GraphicConverter
+#.pcs      "PICS"  "GKON"      Animated PICTs                 GraphicConverter
+#.pct      "PICT"  "ogle"      PICT Picture                   PictureViewer             image/x-pict
+#.pcx      "PCXx"  "GKON"      PC PaintBrush                  GraphicConverter
+#.pdb      "TEXT"  "RSML"      Brookhaven PDB file            RasMac
+#.pdf      "PDF "  "CARO"      Portable Document Format       Acrobat Reader            application/pdf
+#.pdx      "TEXT"  "ALD5"      Printer Description            PageMaker
+#.pf       "CSIT"  "SITx"      Private File                   StuffIt Expander 
+#.pgm      "PPGM"  "GKON"      Portable Graymap               GraphicConverter          image/x-portable-graymap
+#.pi1      "Dega"  "GKON"      Atari Degas Image              GraphicConverter
+#.pi2      "Dega"  "GKON"      Atari Degas Image              GraphicConverter
+#.pi3      "Dega"  "GKON"      Atari Degas Image              GraphicConverter
+#.pic      "PICT"  "ogle"      PICT Picture                   PictureViewer             image/x-pict
+#.pict     "PICT"  "ogle"      PICT Picture                   PictureViewer             image/x-macpict
+#.pit      "PIT "  "SITx"      PackIt Archive                 StuffIt Expander
+#.pkg      "HBSF"  "SITx"      AppleLink Package              StuffIt Expander
+#.pl       "TEXT"  "McPL"      Perl Source                    MacPerl
+#.plt      "HPGL"  "GKON"      HP GL/2                        GraphicConverter
+#.pm       "PMpm"  "GKON"      Bitmap from xv                 GraphicConverter
+#.pm3      "ALB3"  "ALD3"      PageMaker 3 Document           PageMaker
+#.pm4      "ALB4"  "ALD4"      PageMaker 4 Document           PageMaker
+#.pm5      "ALB5"  "ALD5"      PageMaker 5 Document           PageMaker
+#.png      "PNG "  "ogle"      Portable Network Graphic       PictureViewer
+#.pntg     "PNTG"  "ogle"      Macintosh Painting             PictureViewer
+#.ppd      "TEXT"  "ALD5"      Printer Description            PageMaker
+#.ppm      "PPGM"  "GKON"      Portable Pixmap                GraphicConverter          image/x-portable-pixmap
+#.prn      "TEXT"  "R*ch"      Printer Output File            BBEdit
+#.ps       "TEXT"  "vgrd"      PostScript                     LaserWriter 8             application/postscript
+#.psd      "8BPS"  "8BIM"      PhotoShop Document             Photoshop
+#.pt4      "ALT4"  "ALD4"      PageMaker 4 Template           PageMaker
+#.pt5      "ALT5"  "ALD5"      PageMaker 5 Template           PageMaker
+#.pxr      "PXR "  "8BIM"      Pixar Image                    Photoshop
+#.qdv      "QDVf"  "GKON"      QDV image                      GraphicConverter
+#.qt       "MooV"  "TVOD"      QuickTime Movie                MoviePlayer               video/quicktime
+#.qxd      "XDOC"  "XPR3"      QuarkXpress Document           QuarkXpress
+#.qxt      "XTMP"  "XPR3"      QuarkXpress Template           QuarkXpress
+#.raw      "BINA"  "GKON"      Raw Image                      GraphicConverter
+#.readme   "TEXT"  "ttxt"      Text Readme                    SimpleText                application/text
+#.rgb      "SGI "  "GKON"      SGI Image                      GraphicConverter          image/x-rgb
+#.rgba     "SGI "  "GKON"      SGI Image                      GraphicConverter          image/x-rgb
+#.rib      "TEXT"  "RINI"      Renderman 3D Data              Renderman
+#.rif      "RIFF"  "GKON"      RIFF Graphic                   GraphicConverter
+#.rle      "RLE "  "GKON"      RLE image                      GraphicConverter
+#.rme      "TEXT"  "ttxt"      Text Readme                    SimpleText
+#.rpl      "FRL!"  "REP!"      Replica Document               Replica
+#.rsc      "rsrc"  "RSED"      Resource File                  ResEdit
+#.rsrc     "rsrc"  "RSED"      Resource File                  ResEdit
+#.rtf      "TEXT"  "MSWD"      Rich Text Format               Microsoft Word            application/rtf
+#.rtx      "TEXT"  "R*ch"      Rich Text                      BBEdit                    text/richtext
+#.s3m      "S3M "  "SNPL"      ScreamTracker 3 MOD            PlayerPro
+#.scc      "MSX "  "GKON"      MSX pitcure                    GraphicConverter
+#.scg      "RIX3"  "GKON"      ColoRIX                        GraphicConverter
+#.sci      "RIX3"  "GKON"      ColoRIX                        GraphicConverter
+#.scp      "RIX3"  "GKON"      ColoRIX                        GraphicConverter
+#.scr      "RIX3"  "GKON"      ColoRIX                        GraphicConverter
+#.scu      "RIX3"  "GKON"      ColoRIX                        GraphicConverter
+#.sea      "APPL"  "????"      Self-Extracting Archive        Self Extracting Archive
+#.sf       "IRCM"  "SDHK"      IRCAM Sound                    SoundHack
+#.sgi      ".SGI"  "ogle"      SGI Image                      PictureViewer
+#.sha      "TEXT"  "UnSh"      Unix Shell Archive             UnShar                    application/x-shar
+#.shar     "TEXT"  "UnSh"      Unix Shell Archive             UnShar                    application/x-shar
+#.shp      "SHPp"  "GKON"      Printmaster Icon Library       GraphicConverter
+#.sit      "SIT!"  "SITx"      StuffIt 1.5.1 Archive          StuffIt Expander          application/x-stuffit
+#.sithqx   "TEXT"  "SITx"      BinHexed StuffIt Archive       StuffIt Expander          application/mac-binhex40
+#.six      "SIXE"  "GKON"      SIXEL image                    GraphicConverter
+#.slk      "TEXT"  "XCEL"      SYLK Spreadsheet               Excel
+#.snd      "BINA"  "SCPL"      Sound of various types         SoundApp
+#.spc      "Spec"  "GKON"      Atari Spectrum 512             GraphicConverter
+#.sr       "SUNn"  "GKON"      Sun Raster Image               GraphicConverter
+#.sty      "TEXT"  "*TEX"      TeX Style                      Textures
+#.sun      "SUNn"  "GKON"      Sun Raster Image               GraphicConverter
+#.sup      "SCRN"  "GKON"      StartupScreen                  GraphicConverter
+#.svx      "8SVX"  "SCPL"      Amiga IFF Sound                SoundApp
+#.syk      "TEXT"  "XCEL"      SYLK Spreadsheet               Excel
+#.sylk     "TEXT"  "XCEL"      SYLK Spreadsheet               Excel
+#.tar      "TARF"  "SITx"      Unix Tape ARchive              StuffIt Expander          application/x-tar
+#.targa    "TPIC"  "GKON"      Truevision Image               GraphicConverter
+#.taz      "ZIVU"  "SITx"      Compressed Tape ARchive        StuffIt Expander          application/x-compress
+#.tex      "TEXT"  "OTEX"      TeX Document                   OzTeX                     application/x-tex
+#.texi     "TEXT"  "OTEX"      TeX Document                   OzTeX
+#.texinfo  "TEXT"  "OTEX"      TeX Document                   OzTeX                     application/x-texinfo
+#.text     "TEXT"  "ttxt"      ASCII Text                     SimpleText                text/plain
+#.tga      "TPIC"  "GKON"      Truevision Image               GraphicConverter
+#.tgz      "Gzip"  "SITx"      Gnu ZIPed Tape ARchive         StuffIt Expander          application/x-gzip
+#.tif      "TIFF"  "ogle"      TIFF Picture                   PictureViewer             image/tiff
+#.tiff     "TIFF"  "ogle"      TIFF Picture                   PictureViewer             image/tiff
+#.tny      "TINY"  "GKON"      Atari TINY Bitmap              GraphicConverter
+#.tsv      "TEXT"  "XCEL"      Tab Separated Values           Excel                     text/tab-separated-values
+#.tx8      "TEXT"  "ttxt"      8-bit ASCII Text               SimpleText
+#.txt      "TEXT"  "ttxt"      ASCII Text                     SimpleText                text/plain
+#.ul       "ULAW"  "TVOD"      Mu-Law Sound                   MoviePlayer               audio/basic
+#.url      "AURL"  "Arch"      URL Bookmark                   Anarchie                  message/external-body
+#.uu       "TEXT"  "SITx"      UUEncode                       StuffIt Expander
+#.uue      "TEXT"  "SITx"      UUEncode                       StuffIt Expander
+#.vff      "VFFf"  "GKON"      DESR VFF Greyscale Image       GraphicConverter
+#.vga      "BMPp"  "ogle"      OS/2 Bitmap                    PictureViewer
+#.voc      "VOC "  "SCPL"      VOC Sound                      SoundApp
+#.w51      ".WP5"  "WPC2"      WordPerfect PC 5.1 Doc         WordPerfect               application/wordperfect5.1
+#.wav      "WAVE"  "TVOD"      Windows WAV Sound              MoviePlayer               audio/x-wav
+#.wk1      "XLBN"  "XCEL"      Lotus Spreadsheet r2.1         Excel
+#.wks      "XLBN"  "XCEL"      Lotus Spreadsheet r1.x         Excel
+#.wmf      "WMF "  "GKON"      Windows Metafile               GraphicConverter
+#.wp       ".WP5"  "WPC2"      WordPerfect PC 5.1 Doc         WordPerfect               application/wordperfect5.1
+#.wp4      ".WP4"  "WPC2"      WordPerfect PC 4.2 Doc         WordPerfect
+#.wp5      ".WP5"  "WPC2"      WordPerfect PC 5.x Doc         WordPerfect               application/wordperfect5.1
+#.wp6      ".WP6"  "WPC2"      WordPerfect PC 6.x Doc         WordPerfect
+#.wpg      "WPGf"  "GKON"      WordPerfect Graphic            GraphicConverter
+#.wpm      "WPD1"  "WPC2"      WordPerfect Mac                WordPerfect
+#.wri      "WDBN"  "MSWD"      MS Write/Windows               Microsoft Word
+#.wve      "BINA"  "SCPL"      PSION sound                    SoundApp
+#.x10      "XWDd"  "GKON"      X-Windows Dump                 GraphicConverter          image/x-xwd
+#.x11      "XWDd"  "GKON"      X-Windows Dump                 GraphicConverter          image/x-xwd
+#.xbm      "XBM "  "GKON"      X-Windows Bitmap               GraphicConverter          image/x-xbm
+#.xl       "XLS "  "XCEL"      Excel Spreadsheet              Excel
+#.xlc      "XLC "  "XCEL"      Excel Chart                    Excel
+#.xlm      "XLM "  "XCEL"      Excel Macro                    Excel
+#.xls      "XLS "  "XCEL"      Excel Spreadsheet              Excel
+#.xlw      "XLW "  "XCEL"      Excel Workspace                Excel
+#.xm       "XM  "  "SNPL"      FastTracker MOD Music          PlayerPro
+#.xpm      "XPM "  "GKON"      X-Windows Pixmap               GraphicConverter          image/x-xpm
+#.xwd      "XWDd"  "GKON"      X-Windows Dump                 GraphicConverter          image/x-xwd
+#.Z        "ZIVU"  "SITx"      Unix Compress Archive          StuffIt Expander          application/x-compress
+#.zip      "ZIP "  "SITx"      PC ZIP Archive                 StuffIt Expander          application/zip
+#.zoo      "Zoo "  "Booz"      Zoo Archive                    MacBooz
+
+# I'd like to dedicate this as follows code to Miss.Tamaki Imazu
+#
+# Kazuhiko Okudaira the Nursery Teacher
+# kokudaira@hotmail.com
+
+#.bld  "BLD "  "GKON"  BLD                            GraphicConverter
+#.bum  ".bMp"  "GKON"  QuickTime Importer(QuickDraw)  GraphicConverter
+#.cel  "CEL "  "GKON"  KISS CEL                       GraphicConverter
+#.cur  "CUR "  "GKON"  Windows Cursor                 GraphicConverter
+#.cwj  "CWSS"  "cwkj"  ClarisWorks Document           ClarisWorks 4.0
+#.dat  "TCLl"  "GKON"  TCL image                      GraphicConverter
+#.hr   "TR80"  "GKON"  TSR-80 HR                      GraphicConverter
+#.iss  "ISS "  "GKON"  ISS                            GraphicConverter
+#.jif  "JIFf"  "GKON"  JIF99a                         GraphicConverter
+#.lwf  "lwfF"  "GKON"  LuraWave(LWF)                  GraphicConverter
+#.mbm  "MBM "  "GKON"  PSION 5(MBM)                   GraphicConverter
+#.ngg  "NGGC"  "GKON"  Mobile Phone(Nokia)Format      GraphicConverter
+#.nol  "NOL "  "GKON"  Mobile Phone(Nokia)Format      GraphicConverter
+#.pal  "8BCT"  "8BIM"  Color Table                    GraphicConverter
+#.pgc  "PGCF"  "GKON"  PGC/PGF  Atari Portfolio PCG   GraphicConverter
+#.pics "PICS"  "GKON"  PICS-PICT Sequence             GraphicConverter
+#.swf  "SWFL"  "SWF2"  Flash                          Macromedia Flash
+#.vpb  "VPB "  "GKON"  VPB QUANTEL                    GraphicConverter
+#.wbmp "WBMP"  "GKON"  WBMP                           GraphicConverter
+#.x-face  "TEXT"  "GKON"  X-Face                      GraphicConverter
index 49f70c603f2f4946763177f11df9aa772d559778..bfb578cae8108a7aa947a18cd395f2efad5384e1 100644 (file)
@@ -74,17 +74,13 @@ AC_CHECK_MEMBERS(struct tm.tm_gmtoff,,, [#include <time.h>])
 
 dnl these tests have been comfirmed to be needed in 2011
 AC_CHECK_FUNCS(backtrace_symbols dirfd getusershell pread pwrite pselect)
-AC_CHECK_FUNCS(setlinebuf strlcat strlcpy strnlen)
+AC_CHECK_FUNCS(setlinebuf strlcat strlcpy strnlen mempcpy)
 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)
+AX_PTHREAD(, [AC_MSG_ERROR([missing pthread_sigmask])])
 
 AC_DEFINE(OPEN_NOFOLLOW_ERRNO, ELOOP, errno returned by open with O_NOFOLLOW)
 
index 6054e0f8bb26bb5a71382a9f3736619e981ba0f1..30dbb425ba957317765dbfb3d152b862e184be22 100755 (executable)
@@ -50,6 +50,7 @@ use File::Basename;
 use File::Spec;
 use File::Temp qw /tempfile/;
 use bigint; # require perl >= 5.8
+use IPC::Open2 qw /open2/;
 
 # check command for extended attributes -----------------------------------
 
@@ -841,50 +842,46 @@ sub hexdump {
 sub checkea {
     my ($file) = @_;
 
-    $file =~ s/\\/\\\\/g;
-    $file =~ s/\"/\\\"/g;
-    $file =~ s/\$/\\\$/g;
-    $file =~ s/\`/\\\`/g;
     if ( $eacommand == 1 ) {
-        open(EALIST, "getfattr \"$file\" |");
+        open2(\*EALIST, \*EAIN, 'getfattr', $file) or die $@;
         while(<EALIST>) {
             if ( $_ eq "user.org.netatalk.Metadata\n" ) {
-                close (EALIST);
+                close (EALIST, EAIN);
                 return 1;
             }
         }
-        close (EALIST);
+        close (EALIST, EAIN);
         return 0;
     } elsif ( $eacommand == 2 ) {
-        open(EALIST, "attr -q -l \"$file\" |");
+        open2(\*EALIST, \*EAIN, 'attr', '-q', '-l', $file) or die $@;
         while(<EALIST>) {
             if ( $_ eq "org.netatalk.Metadata\n" ) {
-                close (EALIST);
+                close (EALIST, EAIN);
                 return 1;
             }
         }
-        close (EALIST);
+        close (EALIST, EAIN);
         return 0;
     } elsif ( $eacommand == 3 ) {
-        open(EALIST, "runat \"$file\" ls -1 |");
+        open2(\*EALIST, \*EAIN, 'runat', $file, 'ls', '-1') or die $@;
         while(<EALIST>) {
             if ( $_ eq "org.netatalk.Metadata\n" ) {
-                close (EALIST);
+                close (EALIST, EAIN);
                 return 1;
             }
         }
-        close (EALIST);
+        close (EALIST, EAIN);
         return 0;
     } elsif ( $eacommand == 4 ) {
-        open(EALIST, "lsextattr -q user \"$file\" |");
+        open2(\*EALIST, \*EAIN, 'lsextattr', '-q', 'user', $file) or die $@;
         while(<EALIST>) {
             $_ = "\t".$_;
             if ( $_ =~ /\torg\.netatalk\.Metadata[\n\t]/ ) {
-                close (EALIST);
+                close (EALIST, EAIN);
                 return 1;
             }
         }
-        close (EALIST);
+        close (EALIST, EAIN);
         return 0;
     } else {
         return 0;
@@ -893,25 +890,24 @@ sub checkea {
 
 sub eaopenfile {
     my ($file) = @_;
-
-    $file =~ s/\\/\\\\/g;
-    $file =~ s/\"/\\\"/g;
-    $file =~ s/\$/\\\$/g;
-    $file =~ s/\`/\\\`/g;
-    ($eatempfh, $eatempfile) = tempfile(UNLINK => 1);
+    my @eacommands = ();
 
     if ( $eacommand == 1 ) {
-        system("getfattr --only-values -n user.org.netatalk.Metadata \"$file\" > $eatempfile");
+        @eacommands = ('getfattr', '--only-values', '-n', 'user.org.netatalk.Metadata', $file);
     } elsif ( $eacommand == 2 ) {
-        system("attr -q -g org.netatalk.Metadata \"$file\" > $eatempfile");
+        @eacommands = ('attr', '-q', '-g', 'org.netatalk.Metadata', $file);
     } elsif ( $eacommand == 3 ) {
-        system("runat \"$file\" cat org.netatalk.Metadata > $eatempfile");
+        @eacommands = ('runat', $file, 'cat', 'org.netatalk.Metadata',);
     } elsif ( $eacommand == 4 ) {
-        system("getextattr -q user org.netatalk.Metadata \"$file\" > $eatempfile");
+        @eacommands = ('getextattr', '-q', 'user', 'org.netatalk.Metadata', $file);
     } else {
         return "";
     }
 
+    my ($eatempfh, $eatempfile) = tempfile(UNLINK => 1);
+    open2(my $ealist, my $eain, @eacommands) or die $@;
+    print $eatempfh $_ while(<$ealist>);
+    close($ealist, $eain);
     close($eatempfh);
     return $eatempfile;
 }
index 4b88ba9d39f6ac37bc4195ff89f0b9459fcb951a..5bdf95103016fb7796cfcdffc838bab4a56405ca 100644 (file)
@@ -39,6 +39,7 @@ TEMPLATES = \
 
 CLEANFILES = $(GENERATED_FILES) $(sysv_SCRIPTS) $(service_DATA) afpd cnid_metad
 EXTRA_DIST = $(TEMPLATES)
+noinst_DATA = $(GENERATED_FILES)
 
 # overwrite automake uninstall
 # not beautiful, but this way we can call the OS specific init script
index 2183f3036f1a4e5b0e054ec5d83d6bbdd9be233c..d21dde924f75c02d658b7d6b0d5bddf00886bfe4 100644 (file)
@@ -2,6 +2,8 @@
 
 [Unit]
 Description=Netatalk AFP fileserver for Macintosh clients
+Documentation=man:afp.conf(5) man:netatalk(8) man:afpd(8) man:cnid_metad(8) man:cnid_dbd(8)
+Documentation=http://netatalk.sourceforge.net/
 After=syslog.target network.target avahi-daemon.service
 
 [Service]
index 85b51dc86bdca8971ecb85ce94c66c1273c28e21..2404ad7dbf8fb5df1dd3b707ee7ebe76d9460ebb 100644 (file)
@@ -28,7 +28,6 @@ afpd_SOURCES = \
        file.c \
        filedir.c \
        fork.c \
-       gettok.c \
        hash.c \
        main.c \
        mangle.c \
@@ -50,7 +49,7 @@ afpd_LDADD =  \
 afpd_LDFLAGS = -export-dynamic
 
 afpd_CFLAGS = \
-       @ZEROCONF_CFLAGS@ @GSSAPI_CFLAGS@ @KRB5_CFLAGS@\
+       @ZEROCONF_CFLAGS@ @GSSAPI_CFLAGS@ @KRB5_CFLAGS@ @PTHREAD_CFLAGS@\
        -DAPPLCNAME \
        -DSERVERTEXT=\"$(SERVERTEXT)/\" \
        -D_PATH_AFPDPWFILE=\"$(pkgconfdir)/afppasswd\" \
index 305ef06fed6c65a7cf15e6dbe8e50f325f3f8736..55a1e3aea4262d53ee7dfbd62c1149f10af59f6c 100644 (file)
@@ -629,6 +629,7 @@ EC_CLEANUP:
     EC_EXIT;
 }
 
+#if 0
 /*!
  * Add entries of one acl to another acl
  *
@@ -651,6 +652,7 @@ static int acl_add_acl(acl_t *aclp, const acl_t acl)
 EC_CLEANUP:
     EC_EXIT;
 }
+#endif
 
 /*!
  * Map Darwin ACE rights to POSIX 1e perm
@@ -1261,7 +1263,6 @@ static int set_acl(const struct vol *vol,
     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.
      */
@@ -1355,7 +1356,6 @@ static int check_acl_access(const AFPObj *obj,
     int            ret;
     uint32_t       allowed_rights = 0;
     char           *username = NULL;
-    uuidtype_t     uuidtype;
     struct stat    st;
     bstring        parent = NULL;
     int            is_dir;
@@ -1380,7 +1380,7 @@ static int check_acl_access(const AFPObj *obj,
     }
 #endif
 
-    EC_ZERO_LOG_ERR(lstat(path, &st), AFPERR_PARAM);
+    EC_ZERO_LOG_ERR(ostat(path, &st, vol_syml_opt(vol)), AFPERR_PARAM);
 
     is_dir = !strcmp(path, ".");
 
@@ -1577,10 +1577,10 @@ int afp_getacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
         LOG(log_debug, logtype_afpd, "afp_getacl: client requested files owner user UUID");
         if (NULL == (pw = getpwuid(s_path->st.st_uid))) {
             LOG(log_debug, logtype_afpd, "afp_getacl: local uid: %u", s_path->st.st_uid);
-            localuuid_from_id(rbuf, UUID_USER, s_path->st.st_uid);
+            localuuid_from_id((unsigned char *)rbuf, UUID_USER, s_path->st.st_uid);
         } else {
             LOG(log_debug, logtype_afpd, "afp_getacl: got uid: %d, name: %s", s_path->st.st_uid, pw->pw_name);
-            if ((ret = getuuidfromname(pw->pw_name, UUID_USER, rbuf)) != 0)
+            if ((ret = getuuidfromname(pw->pw_name, UUID_USER, (unsigned char *)rbuf)) != 0)
                 return AFPERR_MISC;
         }
         rbuf += UUID_BINSIZE;
@@ -1592,10 +1592,10 @@ int afp_getacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
         LOG(log_debug, logtype_afpd, "afp_getacl: client requested files owner group UUID");
         if (NULL == (gr = getgrgid(s_path->st.st_gid))) {
             LOG(log_debug, logtype_afpd, "afp_getacl: local gid: %u", s_path->st.st_gid);
-            localuuid_from_id(rbuf, UUID_GROUP, s_path->st.st_gid);
+            localuuid_from_id((unsigned char *)rbuf, UUID_GROUP, s_path->st.st_gid);
         } else {
             LOG(log_debug, logtype_afpd, "afp_getacl: got gid: %d, name: %s", s_path->st.st_gid, gr->gr_name);
-            if ((ret = getuuidfromname(gr->gr_name, UUID_GROUP, rbuf)) != 0)
+            if ((ret = getuuidfromname(gr->gr_name, UUID_GROUP, (unsigned char *)rbuf)) != 0)
                 return AFPERR_MISC;
         }
         rbuf += UUID_BINSIZE;
@@ -1727,7 +1727,6 @@ int afp_setacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
 int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct stat *st, struct maccess *ma)
 {
     EC_INIT;
-    uint32_t rights = 0;
 
     if ( ! (obj->options.flags & OPTION_ACL2MACCESS)
          || ! (vol->v_flags & AFPVOL_ACLS))
@@ -1737,6 +1736,7 @@ int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct
         getcwdpath(), path, ma->ma_user);
 
 #ifdef HAVE_SOLARIS_ACLS
+    uint32_t rights = 0;
     EC_ZERO_LOG(solaris_acl_rights(obj, path, st, &rights));
 
     LOG(log_maxdebug, logtype_afpd, "rights: 0x%08x", rights);
index a61fe1022f551ccc84b9fef03c860cfe16c51a30..61bbf6844d1cffce461bc9d8e60fbc4029687d21 100644 (file)
 
 
 /*!
- * Free and cleanup all linked DSI objects from config
+ * Free and cleanup config and DSI
  *
- * Preserve object pointed to by "dsi".
- * "dsi" can be NULL in which case all DSI objects _and_ the options object are freed 
+ * "dsi" can be NULL in which case all DSI objects and the config object is freed,
+ * otherwise its an afpd session child and only any unneeded DSI objects are freed
  */
 void configfree(AFPObj *obj, DSI *dsi)
 {
     DSI *p, *q;
 
-    /* the master loaded the volumes for zeroconf, get rid of that */
+    if (!dsi) {
+        /* Master afpd reloading config */
+        auth_unload();
+        if (! (obj->options.flags & OPTION_NOZEROCONF)) {
+            zeroconf_deregister();
+        }
+    }
+
     unload_volumes(obj);
 
+    /* Master and child releasing unneeded DSI handles */
     for (p = obj->dsi; p; p = q) {
         q = p->next;
         if (p == dsi)
             continue;
-        close(p->socket);
+        dsi_free(p);
         free(p);
     }
+    obj->dsi = NULL;
 
+    /* afpd session child passes dsi handle to obj handle */
     if (dsi) {
         dsi->next = NULL;
         obj->dsi = dsi;
-    } else {
-        afp_options_free(&obj->options);
     }
 }
 
@@ -81,6 +89,9 @@ int configinit(AFPObj *obj)
 
     auth_load(obj->options.uampath, obj->options.uamlist);
     set_signature(&obj->options);
+#ifdef HAVE_LDAP
+    acl_ldap_freeconfig();
+#endif /* HAVE_LDAP */
 
     LOG(log_debug, logtype_afpd, "DSIConfigInit: hostname: %s, listen: %s, port: %s",
         obj->options.hostname,
@@ -122,7 +133,7 @@ int configinit(AFPObj *obj)
 
     /* Now register with zeroconf, we also need the volumes for that */
     if (! (obj->options.flags & OPTION_NOZEROCONF)) {
-        load_volumes(obj, NULL);
+        load_volumes(obj);
         zeroconf_register(obj);
     }
 
index 3e5cd47c3cbf4de4438bc6e3e0e2585a9be72417..8e1f90d290a08809451c121fc8cc206bfe0dcf8f 100644 (file)
@@ -143,8 +143,6 @@ static void afp_dsi_die(int sig)
 /* SIGQUIT handler */
 static void ipc_reconnect_handler(int sig _U_)
 {
-    DSI *dsi = (DSI *)AFPobj->dsi;
-
     if (reconnect_ipc(AFPobj) != 0) {
         LOG(log_error, logtype_afpd, "ipc_reconnect_handler: failed IPC reconnect");
         afp_dsi_close(AFPobj);
@@ -549,7 +547,7 @@ void afp_over_dsi(AFPObj *obj)
 
         if (reload_request) {
             reload_request = 0;
-            load_volumes(AFPobj, closevol);
+            load_volumes(AFPobj);
         }
 
         /* The first SIGINT enables debugging, the next restores the config */
@@ -626,7 +624,7 @@ void afp_over_dsi(AFPObj *obj)
                     LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function));
 
                     err = (*afp_switch[function])(obj,
-                                                  dsi->commands, dsi->cmdlen,
+                                                  (char *)dsi->commands, dsi->cmdlen,
                                                   (char *)&dsi->data, &dsi->datalen);
 
                     LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s",
@@ -667,7 +665,7 @@ void afp_over_dsi(AFPObj *obj)
                 LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function));
 
                 err = (*afp_switch[function])(obj,
-                                              dsi->commands, dsi->cmdlen,
+                                              (char *)dsi->commands, dsi->cmdlen,
                                               (char *)&dsi->data, &dsi->datalen);
 
                 LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s",
index e14791fee2dd93c4db6b8deef1c65f92ba168b77..3158ce7b7fee9ef3058563309151defdc211b53b 100644 (file)
@@ -50,15 +50,16 @@ static pthread_t       poller;
         free(str); free(key);                           \
     }
 
+static struct pollfd *fds;
 
 /*
  * This is the thread that polls the filehandles
  */
-void *polling_thread(void *arg) {
+static void *polling_thread(void *arg) {
     // First we loop through getting the filehandles and adding them to our poll, we
     // need to allocate our pollfd's
     DNSServiceErrorType error;
-    struct pollfd           *fds = calloc(svc_ref_count, sizeof(struct pollfd));
+    fds = calloc(svc_ref_count, sizeof(struct pollfd));
     assert(fds);
 
     for(int i=0; i < svc_ref_count; i++) {
@@ -78,28 +79,32 @@ void *polling_thread(void *arg) {
     return(NULL);
 }
 
-
 /*
  * This is the callback for the service register function ... actually there isn't a lot
  * we can do if we get problems, so we don't really need to do anything other than report
  * the issue.
  */
-void RegisterReply(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
-                   const char *name, const char *regtype, const char *domain, void *context) {
-
-    if(errorCode != kDNSServiceErr_NoError) {
+static void RegisterReply(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
+                          const char *name, const char *regtype, const char *domain, void *context)
+{
+    if (errorCode != kDNSServiceErr_NoError) {
         LOG(log_error, logtype_afpd, "Failed to register mDNS service: %s%s%s: code=%d",
             name, regtype, domain, errorCode);
     }
 }
 
-
 /*
  * This function unregisters anything we have already
  * registered and frees associated memory
  */
 static void unregister_stuff() {
-    pthread_kill(poller, SIGKILL);
+    pthread_cancel(poller);    
+
+    for (int i = 0; i < svc_ref_count; i++)
+        close(fds[i].fd);
+    free(fds);
+    fds = NULL;
+
     if(svc_refs) {
         for(int i=0; i < svc_ref_count; i++) {
             DNSServiceRefDeallocate(svc_refs[i]);
@@ -232,7 +237,7 @@ static void register_stuff(const AFPObj *obj) {
             LOG(log_info, logtype_afpd, "Registering server '%s' with model '%s'",
                 dsi->bonjourname, obj->options.mimicmodel);
             TXTRecordCreate(&txt_devinfo, 0, NULL);
-            TXTRecordPrintf(&txt_devinfo, "model=%s", obj->options.mimicmodel);
+            TXTRecordPrintf(&txt_devinfo, "model", obj->options.mimicmodel);
             error = DNSServiceRegister(&svc_refs[svc_ref_count++],
                                        0,               // no flags
                                        0,               // all network interfaces
@@ -240,7 +245,14 @@ static void register_stuff(const AFPObj *obj) {
                                        DEV_INFO_SERVICE_TYPE,
                                        "",            // default domains
                                        NULL,            // default host name
-                                       0,
+                                       /*
+                                        * We would probably use port 0 zero, but we can't, from man DNSServiceRegister:
+                                        *   "A value of 0 for a port is passed to register placeholder services.
+                                        *    Place holder services are not found  when browsing, but other
+                                        *    clients cannot register with the same name as the placeholder service."
+                                        * We therefor use port 9 which is used by the adisk service type.
+                                        */
+                                       htons(9),
                                        TXTRecordGetLength(&txt_devinfo),
                                        TXTRecordGetBytesPtr(&txt_devinfo),
                                        RegisterReply,           // callback
index 223f117881e20ca8b485290b4577ec6a999708d3..bac65d590e14ca122668a36b6c3dddb41d4075b2 100644 (file)
 
 #define LENGTH 512
 
-/* get rid of any allocated afp_option buffers. */
-void afp_options_free(struct afp_options *opt)
-{
-       if (opt->hostname)
-        free(opt->hostname);
-       if (opt->adminauthuser)
-        free(opt->adminauthuser);
-       if (opt->configfile)
-        free(opt->configfile);
-    if (opt->fqdn)
-        free(opt->fqdn);
-    if (opt->guest)
-        free(opt->guest);
-    if (opt->listen)
-        free(opt->listen);
-    if (opt->k5realm)
-        free(opt->k5realm);
-    if (opt->k5keytab)
-        free(opt->k5keytab);
-    if (opt->k5service)
-        free(opt->k5service);
-    if (opt->logconfig)
-        free(opt->logconfig);
-    if (opt->logfile)
-        free(opt->logfile);
-    if (opt->loginmesg)
-        free(opt->loginmesg);
-    if (opt->maccodepage)
-        free(opt->maccodepage);
-       if (opt->mimicmodel)
-        free(opt->mimicmodel);
-    if (opt->ntdomain)
-        free(opt->ntdomain);
-    if (opt->ntseparator)
-        free(opt->ntseparator);
-    if (opt->passwdfile)
-        free(opt->passwdfile);
-    if (opt->port)
-        free(opt->port);
-    if (opt->signatureopt)
-        free(opt->signatureopt);
-    if (opt->uamlist)
-        free(opt->uamlist);
-    if (opt->uampath)
-        free(opt->uampath);
-    if (opt->unixcodepage)
-        free(opt->unixcodepage);
-}
-
 /*
  * Show version information about afpd.
  * Used by "afp -v".
@@ -222,6 +173,7 @@ static void show_version_extended(void )
 static void show_paths( void )
 {
        printf( "              afp.conf:\t%s\n", _PATH_CONFDIR "afp.conf");
+       printf( "           extmap.conf:\t%s\n", _PATH_CONFDIR "extmap.conf");
        printf( "       state directory:\t%s\n", _PATH_STATEDIR);
        printf( "    afp_signature.conf:\t%s\n", _PATH_STATEDIR "afp_signature.conf");
        printf( "      afp_voluuid.conf:\t%s\n", _PATH_STATEDIR "afp_voluuid.conf");
index a8282c22b3fb38e57a4ddb94af1e529004a7022f..b7bc00f8f51709f1673410cecf773605ca3a5876 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: afp_util.c,v 1.10 2010-01-23 14:44:42 franklahm Exp $
  *
  * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
index f11d77eb22995a400ff43247cf7ddd4441babdbb..efe2ab6392f2fe1693b2d37ee0c9255fde06c099 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: afs.c,v 1.18 2009-10-15 10:43:13 didg Exp $
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
  */
index 3cba16e0c2ae7eab2fe07c28a4cbc6b11498ad85..04dd92d612b61cb2e2dae143a7f438ae13962d0c 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: appl.c,v 1.18.4.1 2010-02-01 10:56:08 franklahm Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
index 71843e2cd13237863791a396e9e389a8156dcf46..9ffea6e21415c3b0299efbdd6e6fdb863a95a974 100644 (file)
@@ -29,6 +29,9 @@
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
@@ -109,12 +112,8 @@ struct scrit {
  *
  */
 struct dsitem {
-//     struct dir *dir; /* Structure describing this directory */
-//  cnid_t did;      /* CNID of this directory           */
-       int pidx;        /* Parent's dsitem structure index. */
-       int checked;     /* Have we checked this directory ? */
-       int path_len;
-       char *path;      /* absolute UNIX path to this directory */
+    cnid_t ds_did;         /* CNID of this directory           */
+    int    ds_checked;     /* Have we checked this directory ? */
 };
  
 
@@ -131,7 +130,6 @@ static void clearstack(void)
        save_cidx = -1;
        while (dsidx > 0) {
                dsidx--;
-               free(dstack[dsidx].path);
        }
 }
 
@@ -139,7 +137,6 @@ static void clearstack(void)
 static int addstack(char *uname, struct dir *dir, int pidx)
 {
        struct dsitem *ds;
-       size_t         l, u;
     struct dsitem *tmpds = NULL;
 
        /* check if we have some space on stack... */
@@ -156,23 +153,8 @@ static int addstack(char *uname, struct dir *dir, int pidx)
 
        /* Put new element. Allocate and copy lname and path. */
        ds = dstack + dsidx++;
-//     ds->did = dir->d_did;
-       ds->pidx = pidx;
-       ds->checked = 0;
-       if (pidx >= 0) {
-           l = dstack[pidx].path_len;
-           u = strlen(uname) +1;
-           if (!(ds->path = malloc(l + u + 1) ))
-                       return -1;
-               memcpy(ds->path, dstack[pidx].path, l);
-               ds->path[l] = '/';
-               memcpy(&ds->path[l+1], uname, u);
-               ds->path_len = l +u;
-       }
-       else {
-           ds->path = strdup(uname);
-               ds->path_len = strlen(uname);
-       }
+       ds->ds_did = dir->d_did;
+       ds->ds_checked = 0;
        return 0;
 }
 
@@ -187,9 +169,9 @@ static int reducestack(void)
        }
 
        while (dsidx > 0) {
-               if (dstack[dsidx-1].checked) {
+               if (dstack[dsidx-1].ds_checked) {
                        dsidx--;
-                       free(dstack[dsidx].path);
+//                     free(dstack[dsidx].path);
                } else
                        return dsidx - 1;
        } 
@@ -211,7 +193,7 @@ static struct adouble *adl_lkup(struct vol *vol, struct path *path, struct adoub
            
        isdir  = S_ISDIR(path->st.st_mode);
 
-       if (!isdir && (of = of_findname(path))) {
+       if (!isdir && (of = of_findname(vol, path))) {
                adp = of->of_ad;
        } else {
                ad_init(&ad, vol);
@@ -521,7 +503,8 @@ static int catsearch(const AFPObj *obj,
     int num_rounds = NUM_ROUNDS;
     int cwd = -1;
     int error;
-        
+    int unlen;
+
        if (*pos != 0 && *pos != cur_pos) {
                result = AFPERR_CATCHNG;
                goto catsearch_end;
@@ -555,20 +538,24 @@ static int catsearch(const AFPObj *obj,
     start_time = time(NULL);
 
        while ((cidx = reducestack()) != -1) {
-        LOG(log_debug, logtype_afpd, "catsearch: dir: \"%s\"", dstack[cidx].path);
+        if ((currentdir = dirlookup(vol, dstack[cidx].ds_did)) == NULL) {
+            result = AFPERR_MISC;
+            goto catsearch_end;
+        }
+        LOG(log_debug, logtype_afpd, "catsearch: current struct dir: \"%s\"", cfrombstr(currentdir->d_fullpath));
 
-               error = lchdir(dstack[cidx].path);
+               error = movecwd(vol, currentdir);
 
                if (!error && dirpos == NULL)
                        dirpos = opendir(".");
 
                if (dirpos == NULL)
-                       dirpos = opendir(dstack[cidx].path);
+                       dirpos = opendir(cfrombstr(currentdir->d_fullpath));
 
                if (error || dirpos == NULL) {
                        switch (errno) {
                        case EACCES:
-                               dstack[cidx].checked = 1;
+                               dstack[cidx].ds_checked = 1;
                                continue;
                        case EMFILE:
                        case ENFILE:
@@ -583,11 +570,6 @@ static int catsearch(const AFPObj *obj,
                        goto catsearch_end;
                }
 
-        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)++;
@@ -600,7 +582,7 @@ static int catsearch(const AFPObj *obj,
 
                        memset(&path, 0, sizeof(path));
                        path.u_name = entry->d_name;
-                       if (of_stat(&path) != 0) {
+                       if (of_stat(vol, &path) != 0) {
                                switch (errno) {
                                case EACCES:
                                case ELOOP:
@@ -615,12 +597,13 @@ static int catsearch(const AFPObj *obj,
                                        goto catsearch_end;
                                } 
                        }
-                       if (S_ISDIR(path.st.st_mode)) {
+            switch (S_IFMT & path.st.st_mode) {
+            case S_IFDIR:
                                /* here we can short cut 
                                   ie if in the same loop the parent dir wasn't in the cache
                                   ALL dirsearch_byname will fail.
                                */
-                int unlen = strlen(path.u_name);
+                unlen = strlen(path.u_name);
                 path.d_dir = dircache_search_by_name(vol,
                                                      currentdir,
                                                      path.u_name,
@@ -641,8 +624,12 @@ static int catsearch(const AFPObj *obj,
                                        result = AFPERR_MISC;
                                        goto catsearch_end;
                                } 
-            } else {
+                break;
+            case S_IFREG:
                path.d_dir = currentdir;
+                break;
+            default:
+                continue;
             }
 
                        ccr = crit_check(vol, &path);
@@ -674,7 +661,7 @@ static int catsearch(const AFPObj *obj,
                } /* while ((entry=readdir(dirpos)) != NULL) */
                closedir(dirpos);
                dirpos = NULL;
-               dstack[cidx].checked = 1;
+               dstack[cidx].ds_checked = 1;
        } /* while (current_idx = reducestack()) != -1) */
 
        /* We have finished traversing our tree. Return EOF here. */
@@ -789,7 +776,7 @@ static int catsearch_db(const AFPObj *obj,
         path.u_name = name;
         path.m_name = utompath(vol, name, cnid, utf8_encoding(vol->v_obj));
 
-        if (of_stat(&path) != 0) {
+        if (of_stat(vol, &path) != 0) {
             switch (errno) {
             case EACCES:
             case ELOOP:
index c437b7e6b4adb92f2a2c03388b401b3ad2eb8082..9ba96bc595fd5562be47886acae0aba4238dccf2 100644 (file)
@@ -31,6 +31,7 @@
 #include <atalk/netatalk_conf.h>
 #include <atalk/unix.h>
 #include <atalk/bstrlib.h>
+#include <atalk/bstradd.h>
 #include <atalk/errchk.h>
 
 #include "volume.h"
@@ -61,7 +62,7 @@ int setdeskmode(const struct vol *vol, const mode_t mode)
     bstring dtpath = bfromcstr(vol->v_dbpath);
     bcatcstr(dtpath, "/" APPLEDESKTOP);
 
-    EC_NEG1( chdir(bdata(dtpath)) );
+    EC_NEG1( chdir(cfrombstr(dtpath)) );
 
     if (( desk = opendir( "." )) == NULL ) {
         if ( chdir( wd ) < 0 ) {
@@ -138,7 +139,7 @@ int setdeskowner(const struct vol *vol, uid_t uid, gid_t gid)
     bstring dtpath = bfromcstr(vol->v_dbpath);
     bcatcstr(dtpath, "/" APPLEDESKTOP);
 
-    EC_NEG1( chdir(bdata(dtpath)) );
+    EC_NEG1( chdir(cfrombstr(dtpath)) );
     
     if (( desk = opendir( "." )) == NULL ) {
         if ( chdir( wd ) < 0 ) {
@@ -182,7 +183,7 @@ int setdeskowner(const struct vol *vol, uid_t uid, gid_t gid)
         LOG(log_error, logtype_afpd, "setdeskowner: chdir %s: %s", wd, strerror(errno) );
         EC_FAIL;
     }
-    if (chown(bdata(dtpath), uid, gid ) < 0 && errno != EPERM ) {
+    if (chown(cfrombstr(dtpath), uid, gid ) < 0 && errno != EPERM ) {
         LOG(log_error, logtype_afpd, "setdeskowner: chown %s: %s", fullpathname(".AppleDouble"), strerror(errno) );
     }
 
@@ -203,11 +204,11 @@ static void create_appledesktop_folder(const struct vol * vol)
     dtpath = bfromcstr(vol->v_dbpath);
     bcatcstr(dtpath, "/" APPLEDESKTOP);
 
-    if (lstat(bdata(dtpath), &st) != 0) {
+    if (lstat(cfrombstr(dtpath), &st) != 0) {
 
         become_root();
 
-        if (lstat(bdata(olddtpath), &st) == 0) {
+        if (lstat(cfrombstr(olddtpath), &st) == 0) {
             cmd_argv[0] = "mv";
             cmd_argv[1] = bdata(olddtpath);
             cmd_argv[2] = bdata(dtpath);
@@ -215,10 +216,10 @@ static void create_appledesktop_folder(const struct vol * vol)
             if (run_cmd("mv", cmd_argv) != 0) {
                 LOG(log_error, logtype_afpd, "moving .AppleDesktop from \"%s\" to \"%s\" failed",
                     bdata(olddtpath), bdata(dtpath));
-                mkdir(bdata(dtpath), 0777);
+                mkdir(cfrombstr(dtpath), 0777);
             }
         } else {
-            mkdir(bdata(dtpath), 0777);
+            mkdir(cfrombstr(dtpath), 0777);
         }
 
         unbecome_root();
@@ -830,7 +831,7 @@ static int ad_addcomment(const AFPObj *obj, struct vol *vol, struct path *path,
     }
     
     isadir = path_isadir(path);
-    if (isadir || !(of = of_findname(path))) {
+    if (isadir || !(of = of_findname(vol, path))) {
         ad_init(&ad, vol);
         adp = &ad;
     } else
@@ -905,7 +906,7 @@ static int ad_getcomment(struct vol *vol, struct path *path, char *rbuf, size_t
 
     upath = path->u_name;
     isadir = path_isadir(path);
-    if (isadir || !(of = of_findname(path))) {
+    if (isadir || !(of = of_findname(vol, path))) {
         ad_init(&ad, vol);
         adp = &ad;
     } else
@@ -982,7 +983,7 @@ static int ad_rmvcomment(const AFPObj *obj, struct vol *vol, struct path *path)
     }
 
     isadir = path_isadir(path);
-    if (isadir || !(of = of_findname(path))) {
+    if (isadir || !(of = of_findname(vol, path))) {
         ad_init(&ad, vol);
         adp = &ad;
     } else
index 7cd08f6f4ec5182a356447306d5ddfa8baa4f173..37af45fa71ce9bf5fbc9d60e77da9033e4d464fa 100644 (file)
@@ -434,7 +434,6 @@ struct dir *dircache_search_by_name(const struct vol *vol,
 int dircache_add(const struct vol *vol,
                  struct dir *dir)
 {
-    struct dir *cdir = NULL;
     struct dir key;
     hnode_t *hn;
 
index ed40a26a7faf5e330ea8739386e33979e02de26f..9a4fc64e5d6704cc132f9e5125c97a0b71b7afbd 100644 (file)
@@ -134,7 +134,7 @@ static int netatalk_mkdir(const struct vol *vol, const char *name)
 }
 
 /* ------------------- */
-static int deletedir(int dirfd, char *dir)
+static int deletedir(const struct vol *vol, int dirfd, char *dir)
 {
     char path[MAXPATHLEN + 1];
     DIR *dp;
@@ -165,11 +165,11 @@ static int deletedir(int dirfd, char *dir)
             break;
         }
         strcpy(path + len, de->d_name);
-        if (lstatat(dirfd, path, &st)) {
+        if (ostatat(dirfd, path, &st, vol_syml_opt(vol))) {
             continue;
         }
         if (S_ISDIR(st.st_mode)) {
-            err = deletedir(dirfd, path);
+            err = deletedir(vol, dirfd, path);
         } else {
             err = netatalk_unlinkat(dirfd, path);
         }
@@ -185,7 +185,7 @@ static int deletedir(int dirfd, char *dir)
 }
 
 /* do a recursive copy. */
-static int copydir(const struct vol *vol, int dirfd, char *src, char *dst)
+static int copydir(struct vol *vol, struct dir *ddir, int dirfd, char *src, char *dst)
 {
     char spath[MAXPATHLEN + 1], dpath[MAXPATHLEN + 1];
     DIR *dp;
@@ -231,7 +231,7 @@ static int copydir(const struct vol *vol, int dirfd, char *src, char *dst)
         }
         strcpy(spath + slen, de->d_name);
 
-        if (lstatat(dirfd, spath, &st) == 0) {
+        if (ostatat(dirfd, spath, &st, vol_syml_opt(vol)) == 0) {
             if (strlen(de->d_name) > drem) {
                 err = AFPERR_PARAM;
                 break;
@@ -239,9 +239,9 @@ static int copydir(const struct vol *vol, int dirfd, char *src, char *dst)
             strcpy(dpath + dlen, de->d_name);
 
             if (S_ISDIR(st.st_mode)) {
-                if (AFP_OK != (err = copydir(vol, dirfd, spath, dpath)))
+                if (AFP_OK != (err = copydir(vol, ddir, dirfd, spath, dpath)))
                     goto copydir_done;
-            } else if (AFP_OK != (err = copyfile(vol, vol, dirfd, spath, dpath, NULL, NULL))) {
+            } else if (AFP_OK != (err = copyfile(vol, vol, ddir, dirfd, spath, dpath, NULL, NULL))) {
                 goto copydir_done;
 
             } else {
@@ -253,7 +253,7 @@ static int copydir(const struct vol *vol, int dirfd, char *src, char *dst)
     }
 
     /* keep the same time stamp. */
-    if (lstatat(dirfd, src, &st) == 0) {
+    if (ostatat(dirfd, src, &st, vol_syml_opt(vol)) == 0) {
         ut.actime = ut.modtime = st.st_mtime;
         utime(dst, &ut);
     }
@@ -643,7 +643,7 @@ struct dir *dirlookup(const struct vol *vol, cnid_t did)
     LOG(log_debug, logtype_afpd, "dirlookup(did: %u): stating \"%s\"",
         ntohl(did), cfrombstr(fullpath));
 
-    if (lstat(cfrombstr(fullpath), &st) != 0) { /* 5a */
+    if (ostat(cfrombstr(fullpath), &st, vol_syml_opt(vol)) != 0) { /* 5a */
         switch (errno) {
         case ENOENT:
             afp_errno = AFPERR_NOOBJ;
@@ -912,7 +912,7 @@ exit:
 void dir_free_invalid_q(void)
 {
     struct dir *dir;
-    while (dir = (struct dir *)dequeue(invalid_dircache_entries))
+    while ((dir = (struct dir *)dequeue(invalid_dircache_entries)))
         dir_free(dir);
 }
 
@@ -1181,7 +1181,7 @@ struct path *cname(struct vol *vol, struct dir *dir, char **cpath)
              *   and thus call continue which should terminate the while loop because
              *   len = 0. Ok?
              */
-            if (of_stat(&ret) != 0) { /* 9 */
+            if (of_stat(vol, &ret) != 0) { /* 9 */
                 /*
                  * ret.u_name doesn't exist, might be afp_createfile|dir
                  * that means it should have been the last part
@@ -1299,7 +1299,7 @@ int movecwd(const struct vol *vol, struct dir *dir)
     LOG(log_debug, logtype_afpd, "movecwd(to: did: %u, \"%s\")",
         ntohl(dir->d_did), cfrombstr(dir->d_fullpath));
 
-    if ((ret = lchdir(cfrombstr(dir->d_fullpath))) != 0 ) {
+    if ((ret = ochdir(cfrombstr(dir->d_fullpath), vol_syml_opt(vol))) != 0 ) {
         LOG(log_debug, logtype_afpd, "movecwd(\"%s\"): %s",
             cfrombstr(dir->d_fullpath), strerror(errno));
         if (ret == 1) {
@@ -2174,7 +2174,7 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_
         return err;
     }
 
-    if (of_stat(s_path) < 0) {
+    if (of_stat(vol, s_path) < 0) {
         return AFPERR_MISC;
     }
 
@@ -2195,12 +2195,11 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_
     ad_setname(&ad, s_path->m_name);
     ad_setid( &ad, s_path->st.st_dev, s_path->st.st_ino, dir->d_did, did, vol->v_stamp);
 
-    fce_register_new_dir(s_path);
+    fce_register(FCE_DIR_CREATE, bdata(curdir->d_fullpath), NULL, fce_dir);
 
     ad_flush(&ad);
     ad_close(&ad, ADFLAGS_HF);
 
-createdir_done:
     memcpy( rbuf, &dir->d_did, sizeof( uint32_t ));
     *rbuflen = sizeof( uint32_t );
     setvoltime(obj, vol );
@@ -2213,7 +2212,7 @@ createdir_done:
  * newparent curdir
  * dirfd     -1 means ignore dirfd (or use AT_FDCWD), otherwise src is relative to dirfd
  */
-int renamedir(const struct vol *vol,
+int renamedir(struct vol *vol,
               int dirfd,
               char *src,
               char *dst,
@@ -2239,11 +2238,11 @@ int renamedir(const struct vol *vol,
         case EXDEV:
             /* this needs to copy and delete. bleah. that means we have
              * to deal with entire directory hierarchies. */
-            if ((err = copydir(vol, dirfd, src, dst)) < 0) {
-                deletedir(-1, dst);
+            if ((err = copydir(vol, newparent, dirfd, src, dst)) < 0) {
+                deletedir(vol, -1, dst);
                 return err;
             }
-            if ((err = deletedir(dirfd, src)) < 0)
+            if ((err = deletedir(vol, dirfd, src)) < 0)
                 return err;
             break;
         default :
@@ -2308,7 +2307,7 @@ int deletecurdir(struct vol *vol)
             /* bail if it's not a symlink */
             if ((lstat(de->d_name, &st) == 0) && !S_ISLNK(st.st_mode)) {
                 LOG(log_error, logtype_afpd, "deletecurdir(\"%s\"): not empty",
-                    curdir->d_fullpath);
+                    bdata(curdir->d_fullpath));
                 closedir(dp);
                 return AFPERR_DIRNEMPT;
             }
@@ -2622,7 +2621,7 @@ int afp_opendir(AFPObj *obj _U_, char *ibuf, size_t ibuflen  _U_, char *rbuf, si
         return path_error(path, AFPERR_NOOBJ);
     }
 
-    if ( !path->st_valid && of_stat(path ) < 0 ) {
+    if ( !path->st_valid && of_stat(vol, path) < 0 ) {
         return( AFPERR_NOOBJ );
     }
     if ( path->st_errno ) {
index 7f3e8c56a1cd135c2405abb5fb3af61a700222dd..eb89c606afc41cce1994851265283bed05d27e9a 100644 (file)
@@ -115,7 +115,7 @@ extern int         getdirparams (const AFPObj *obj, const struct vol *, uint16_t
                                  struct dir *, char *, size_t *);
 
 extern int         setdirparams(struct vol *, struct path *, uint16_t, char *);
-extern int         renamedir(const struct vol *, int, char *, char *, struct dir *,
+extern int         renamedir(struct vol *, int, char *, char *, struct dir *,
                              struct dir *, char *);
 extern int         path_error(struct path *, int error);
 extern void        setdiroffcnt(struct dir *dir, struct stat *st,  uint32_t count);
index d469928c357b465a5781d2f5f51c9aad51fb8a2e..0c3c0576e5249f3b679bc4714f65c710847581a6 100644 (file)
@@ -284,7 +284,7 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,
     if ( sindex == 1 || curdir->d_did != sd.sd_did || vid != sd.sd_vid ) {
         sd.sd_last = sd.sd_buf;
         /* if dir was in the cache we don't have the inode */
-        if (( !o_path->st_valid && lstat( ".", &o_path->st ) < 0 ) ||
+        if (( !o_path->st_valid && ostat(".", &o_path->st, vol_syml_opt(vol)) < 0 ) ||
             (ret = for_each_dirent(vol, ".", enumerate_loop, (void *)&sd)) < 0) 
         {
             LOG(log_error, logtype_afpd, "enumerate: loop error: %s (%d)", strerror(errno), errno);
@@ -346,16 +346,10 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,
             sd.sd_last += len + 1;
             continue;
         }
-        memset(&s_path, 0, sizeof(s_path));
 
-        /* conversions on the fly */
-        const char *convname;
+        memset(&s_path, 0, sizeof(s_path));
         s_path.u_name = sd.sd_last;
-        if (ad_convert(sd.sd_last, &s_path.st, vol, &convname) == 0 && convname) {
-            s_path.u_name = (char *)convname;
-        }
-
-        if (of_stat( &s_path) < 0 ) {
+        if (of_stat(vol, &s_path) < 0 ) {
             /* so the next time it won't try to stat it again
              * another solution would be to invalidate the cache with 
              * sd.sd_did = 0 but if it's not ENOENT error it will start again
@@ -366,11 +360,17 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,
             continue;
         }
 
+        /* conversions on the fly */
+        const char *convname;
+        if (ad_convert(sd.sd_last, &s_path.st, vol, &convname) == 0 && convname) {
+            s_path.u_name = (char *)convname;
+        }
+
         /* Fixup CNID db if ad_convert resulted in a rename (then convname != NULL) */
         if (convname) {
             s_path.id = cnid_lookup(vol->v_cdb, &s_path.st, curdir->d_did, sd.sd_last, strlen(sd.sd_last));
             if (s_path.id != CNID_INVALID) {
-                if (cnid_update(vol->v_cdb, s_path.id, &s_path.st, curdir->d_did, convname, strlen(convname)) != 0)
+                if (cnid_update(vol->v_cdb, s_path.id, &s_path.st, curdir->d_did, (char *)convname, strlen(convname)) != 0)
                     LOG(log_error, logtype_afpd, "enumerate: error updating CNID of \"%s\"", fullpathname(convname));
             }
         }
index 64e8482d233ae4a20c5efe6a1b6ca92e1342c470..68e65905f97e46b65a899e7d66f6ae47271a24cf 100644 (file)
@@ -1,5 +1,4 @@
 /*
-   $Id: extattrs.h,v 1.3 2009-10-15 10:43:13 didg Exp $
    Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
 
    This program is free software; you can redistribute it and/or modify
index b40eafb988a7bf6681faf8fc8a60a2ebcafc40a3..49dd3cd7d4d5b367616213ca9975a803f42ab046 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2010 Mark Williams
+ * Copyright (c) 2012 Frank Lahm <franklahm@gmail.com>
  *
  * File change event API for netatalk
  *
 #include <stdlib.h>
 #include <errno.h>
 #include <time.h>
-
-
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#include <stdbool.h>
 
 #include <atalk/adouble.h>
 #include <atalk/vfs.h>
 // ONLY USED IN THIS FILE
 #include "fce_api_internal.h"
 
-#define FCE_TRUE 1
-#define FCE_FALSE 0
-
 /* We store our connection data here */
 static struct udp_entry udp_socket_list[FCE_MAX_UDP_SOCKS];
 static int udp_sockets = 0;
-static int udp_initialized = FCE_FALSE;
+static bool udp_initialized = false;
 static unsigned long fce_ev_enabled =
     (1 << FCE_FILE_MODIFY) |
     (1 << FCE_FILE_DELETE) |
@@ -70,9 +67,8 @@ static unsigned long fce_ev_enabled =
     (1 << FCE_FILE_CREATE) |
     (1 << FCE_DIR_CREATE);
 
-static uint64_t tm_used;          /* used for passing to event handler */
 #define MAXIOBUF 1024
-static char iobuf[MAXIOBUF];
+static unsigned char iobuf[MAXIOBUF];
 static const char *skip_files[] = 
 {
        ".DS_Store",
@@ -80,6 +76,15 @@ static const char *skip_files[] =
 };
 static struct fce_close_event last_close_event;
 
+static char *fce_event_names[] = {
+    "",
+    "FCE_FILE_MODIFY",
+    "FCE_FILE_DELETE",
+    "FCE_DIR_DELETE",
+    "FCE_FILE_CREATE",
+    "FCE_DIR_CREATE"
+};
+
 /*
  *
  * Initialize network structs for any listeners
@@ -91,7 +96,7 @@ void fce_init_udp()
     int rv;
     struct addrinfo hints, *servinfo, *p;
 
-    if (udp_initialized == FCE_TRUE)
+    if (udp_initialized == true)
         return;
 
     memset(&hints, 0, sizeof hints);
@@ -106,7 +111,7 @@ void fce_init_udp()
             close(udp_entry->sock);
 
         if ((rv = getaddrinfo(udp_entry->addr, udp_entry->port, &hints, &servinfo)) != 0) {
-            LOG(log_error, logtype_afpd, "fce_init_udp: getaddrinfo(%s:%s): %s",
+            LOG(log_error, logtype_fce, "fce_init_udp: getaddrinfo(%s:%s): %s",
                 udp_entry->addr, udp_entry->port, gai_strerror(rv));
             continue;
         }
@@ -114,7 +119,7 @@ void fce_init_udp()
         /* loop through all the results and make a socket */
         for (p = servinfo; p != NULL; p = p->ai_next) {
             if ((udp_entry->sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
-                LOG(log_error, logtype_afpd, "fce_init_udp: socket(%s:%s): %s",
+                LOG(log_error, logtype_fce, "fce_init_udp: socket(%s:%s): %s",
                     udp_entry->addr, udp_entry->port, strerror(errno));
                 continue;
             }
@@ -122,7 +127,7 @@ void fce_init_udp()
         }
 
         if (p == NULL) {
-            LOG(log_error, logtype_afpd, "fce_init_udp: no socket for %s:%s",
+            LOG(log_error, logtype_fce, "fce_init_udp: no socket for %s:%s",
                 udp_entry->addr, udp_entry->port);
         }
         udp_entry->addrinfo = *p;
@@ -131,12 +136,12 @@ void fce_init_udp()
         freeaddrinfo(servinfo);
     }
 
-    udp_initialized = FCE_TRUE;
+    udp_initialized = true;
 }
 
 void fce_cleanup()
 {
-    if (udp_initialized == FCE_FALSE )
+    if (udp_initialized == false )
         return;
 
     for (int i = 0; i < udp_sockets; i++)
@@ -150,22 +155,21 @@ void fce_cleanup()
             udp_entry->sock = -1;
         }
     }
-    udp_initialized = FCE_FALSE;
+    udp_initialized = 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 )
+static ssize_t build_fce_packet( struct fce_packet *packet, const char *path, int event, uint32_t event_id )
 {
     size_t pathlen = 0;
     ssize_t data_len = 0;
-    uint64_t *t;
 
     /* Set content of packet */
     memcpy(packet->magic, FCE_PACKET_MAGIC, sizeof(packet->magic) );
     packet->version = FCE_PACKET_VERSION;
-    packet->mode = mode;
+    packet->mode = event;
    
     packet->event_id = event_id; 
 
@@ -180,19 +184,7 @@ static ssize_t build_fce_packet( struct fce_packet *packet, char *path, int mode
     /* 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:
-        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:
-        memcpy(packet->data, path, pathlen);
-        break;
-    }
+    memcpy(packet->data, path, pathlen);
 
     /* return the packet len */
     return data_len;
@@ -231,27 +223,26 @@ static void pack_fce_packet(struct fce_packet *packet, unsigned char *buf, int m
  * Send the fce information to all (connected) listeners
  * We dont give return code because all errors are handled internally (I hope..)
  * */
-static void send_fce_event( char *path, int mode )
+static void send_fce_event(const char *path, int event)
 {    
-    static int first_event = FCE_TRUE;
+    static bool first_event = true;
 
     struct fce_packet packet;
-    void *data = &packet;
     static uint32_t event_id = 0; /* the unique packet couter to detect packet/data loss. Going from 0xFFFFFFFF to 0x0 is a valid increment */
     time_t now = time(NULL);
 
-    LOG(log_debug, logtype_afpd, "send_fce_event: start");
+    LOG(log_debug, logtype_fce, "send_fce_event: start");
 
     /* initialized ? */
-    if (first_event == FCE_TRUE) {
-        first_event = FCE_FALSE;
+    if (first_event == true) {
+        first_event = false;
         fce_init_udp();
         /* Notify listeners the we start from the beginning */
         send_fce_event( "", FCE_CONN_START );
     }
 
     /* build our data packet */
-    ssize_t data_len = build_fce_packet( &packet, path, mode, ++event_id );
+    ssize_t data_len = build_fce_packet( &packet, path, event, ++event_id );
     pack_fce_packet(&packet, iobuf, MAXIOBUF);
 
     for (int i = 0; i < udp_sockets; i++)
@@ -273,7 +264,7 @@ static void send_fce_event( char *path, int mode )
             
             if (udp_entry->sock == -1) {
                 /* failed again, so go to rest again */
-                LOG(log_error, logtype_afpd, "Cannot recreate socket for fce UDP connection: errno %d", errno  );
+                LOG(log_error, logtype_fce, "Cannot recreate socket for fce UDP connection: errno %d", errno  );
 
                 udp_entry->next_try_on_error = now + FCE_SOCKET_RETRY_DELAY_S;
                 continue;
@@ -293,7 +284,7 @@ static void send_fce_event( char *path, int mode )
                    udp_entry->addrinfo.ai_addrlen);
 
             /* Rebuild our original data packet */
-            data_len = build_fce_packet( &packet, path, mode, event_id );
+            data_len = build_fce_packet(&packet, path, event, event_id);
             pack_fce_packet(&packet, iobuf, MAXIOBUF);
         }
 
@@ -307,7 +298,7 @@ static void send_fce_event( char *path, int mode )
         /* Problems ? */
         if (sent_data != data_len) {
             /* Argh, socket broke, we close and retry later */
-            LOG(log_error, logtype_afpd, "send_fce_event: error sending packet to %s:%s, transfered %d of %d: %s",
+            LOG(log_error, logtype_fce, "send_fce_event: error sending packet to %s:%s, transfered %d of %d: %s",
                 udp_entry->addr, udp_entry->port, sent_data, data_len, strerror(errno));
 
             close( udp_entry->sock );
@@ -323,7 +314,7 @@ static int add_udp_socket(const char *target_ip, const char *target_port )
         target_port = FCE_DEFAULT_PORT_STRING;
 
     if (udp_sockets >= FCE_MAX_UDP_SOCKS) {
-        LOG(log_error, logtype_afpd, "Too many file change api UDP connections (max %d allowed)", FCE_MAX_UDP_SOCKS );
+        LOG(log_error, logtype_fce, "Too many file change api UDP connections (max %d allowed)", FCE_MAX_UDP_SOCKS );
         return AFPERR_PARAM;
     }
 
@@ -350,7 +341,7 @@ static void save_close_event(const char *path)
         send_fce_event(last_close_event.path, FCE_FILE_MODIFY);
     }
 
-    LOG(log_debug, logtype_afpd, "save_close_event: %s", path);
+    LOG(log_debug, logtype_fce, "save_close_event: %s", path);
 
     last_close_event.time = now;
     strncpy(last_close_event.path, path, MAXPATHLEN);
@@ -361,66 +352,55 @@ static void save_close_event(const char *path)
  * Dispatcher for all incoming file change events
  *
  * */
-static int register_fce(const char *u_name, int is_dir, int mode)
+int fce_register(fce_ev_t event, const char *path, const char *oldpath, fce_obj_t type)
 {
-    static int first_event = FCE_TRUE;
+    static bool first_event = true;
+    const char *bname;
+
+    if (!(fce_ev_enabled & (1 << event)))
+        return AFP_OK;
+
+    AFP_ASSERT(event >= FCE_FIRST_EVENT && event <= FCE_LAST_EVENT);
+
+    LOG(log_debug, logtype_fce, "register_fce(path: %s, type: %s, event: %s",
+        path , type == fce_dir ? "dir" : "file", fce_event_names[event]);
+
+    bname = basename_safe(path);
 
     if (udp_sockets == 0)
         /* No listeners configured */
         return AFP_OK;
 
-    if (u_name == NULL)
+    if (path == NULL)
         return AFPERR_PARAM;
 
        /* do some initialization on the fly the first time */
        if (first_event) {
                fce_initialize_history();
-        first_event = FCE_FALSE;
+        first_event = false;
        }
 
        /* handle files which should not cause events (.DS_Store atc. ) */
-       for (int i = 0; skip_files[i] != NULL; i++)
-       {
-               if (!strcmp( u_name, skip_files[i]))
+       for (int i = 0; skip_files[i] != NULL; i++) {
+               if (strcmp(bname, skip_files[i]) == 0)
                        return AFP_OK;
        }
 
-
-       char full_path_buffer[MAXPATHLEN + 1] = {""};
-       const char *cwd = getcwdpath();
-
-    if (mode == FCE_TM_SIZE) {
-        strlcpy(full_path_buffer, u_name, MAXPATHLEN);
-    } else if (!is_dir || mode == FCE_DIR_DELETE) {
-               if (strlen( cwd ) + strlen( u_name) + 1 >= MAXPATHLEN) {
-                       LOG(log_error, logtype_afpd, "FCE file name too long: %s/%s", cwd, u_name );
-                       return AFPERR_PARAM;
-               }
-               sprintf( full_path_buffer, "%s/%s", cwd, u_name );
-       } else {
-               if (strlen( cwd ) >= MAXPATHLEN) {
-                       LOG(log_error, logtype_afpd, "FCE directory name too long: %s", cwd);
-                       return AFPERR_PARAM;
-               }
-               strcpy( full_path_buffer, cwd);
-       }
-
        /* Can we ignore this event based on type or history? */
-       if (!(mode & FCE_TM_SIZE) && fce_handle_coalescation( full_path_buffer, is_dir, mode ))
-       {
-               LOG(log_debug9, logtype_afpd, "Coalesced fc event <%d> for <%s>", mode, full_path_buffer );
+       if (fce_handle_coalescation(event, path, type)) {
+               LOG(log_debug9, logtype_fce, "Coalesced fc event <%d> for <%s>", event, path);
                return AFP_OK;
        }
 
-       LOG(log_debug9, logtype_afpd, "Detected fc event <%d> for <%s>", mode, full_path_buffer );
-
-    if (mode & FCE_FILE_MODIFY) {
-        save_close_event(full_path_buffer);
-        return AFP_OK;
+    switch (event) {
+    case FCE_FILE_MODIFY:
+        save_close_event(path);
+        break;
+    default:
+        send_fce_event(path, event);
+        break;
     }
 
-    send_fce_event( full_path_buffer, mode );
-
     return AFP_OK;
 }
 
@@ -430,7 +410,7 @@ static void check_saved_close_events(int fmodwait)
 
     /* check if configured holdclose time has passed */
     if (last_close_event.time && ((last_close_event.time + fmodwait) < now)) {
-        LOG(log_debug, logtype_afpd, "check_saved_close_events: sending event: %s", last_close_event.path);
+        LOG(log_debug, logtype_fce, "check_saved_close_events: sending event: %s", last_close_event.path);
         /* yes, send event */
         send_fce_event(&last_close_event.path[0], FCE_FILE_MODIFY);
         last_close_event.path[0] = 0;
@@ -443,106 +423,11 @@ static void check_saved_close_events(int fmodwait)
 /*
  * API-Calls for file change api, called form outside (file.c directory.c ofork.c filedir.c)
  * */
-#ifndef FCE_TEST_MAIN
-
 void fce_pending_events(AFPObj *obj)
 {
-    vol_fce_tm_event();
     check_saved_close_events(obj->options.fce_fmodwait);
 }
 
-int fce_register_delete_file( struct path *path )
-{
-    int ret = AFP_OK;
-
-    if (path == NULL)
-        return AFPERR_PARAM;
-
-    if (!(fce_ev_enabled & (1 << FCE_FILE_DELETE)))
-        return ret;
-       
-    ret = register_fce( path->u_name, false, FCE_FILE_DELETE );
-
-    return ret;
-}
-int fce_register_delete_dir( char *name )
-{
-    int ret = AFP_OK;
-
-    if (name == NULL)
-        return AFPERR_PARAM;
-
-    if (!(fce_ev_enabled & (1 << FCE_DIR_DELETE)))
-        return ret;
-       
-    ret = register_fce( name, true, FCE_DIR_DELETE);
-
-    return ret;
-}
-
-int fce_register_new_dir( struct path *path )
-{
-    int ret = AFP_OK;
-
-    if (path == NULL)
-        return AFPERR_PARAM;
-
-    if (!(fce_ev_enabled & (1 << FCE_DIR_CREATE)))
-        return ret;
-
-    ret = register_fce( path->u_name, true, FCE_DIR_CREATE );
-
-    return ret;
-}
-
-
-int fce_register_new_file( struct path *path )
-{
-    int ret = AFP_OK;
-
-    if (path == NULL)
-        return AFPERR_PARAM;
-
-    if (!(fce_ev_enabled & (1 << FCE_FILE_CREATE)))
-        return ret;
-
-    ret = register_fce( path->u_name, false, FCE_FILE_CREATE );
-
-    return ret;
-}
-
-int fce_register_file_modification( struct ofork *ofork )
-{
-    int ret = AFP_OK;
-
-    if (ofork == NULL)
-        return AFPERR_PARAM;
-
-    if (!(fce_ev_enabled & (1 << FCE_FILE_MODIFY)))
-        return ret;
-
-    ret = register_fce(of_name(ofork), false, FCE_FILE_MODIFY );
-    
-    return ret;    
-}
-
-int fce_register_tm_size(const char *vol, size_t used)
-{
-    int ret = AFP_OK;
-
-    if (vol == NULL)
-        return AFPERR_PARAM;
-
-    if (!(fce_ev_enabled & (1 << FCE_TM_SIZE)))
-        return ret;
-
-    tm_used = used;             /* oh what a hack */
-    ret = register_fce(vol, false, FCE_TM_SIZE);
-
-    return ret;
-}
-#endif
-
 /*
  *
  * Extern connect to afpd parameter, can be called multiple times for multiple listeners (up to MAX_UDP_SOCKS times)
@@ -586,8 +471,6 @@ int fce_set_events(const char *events)
             fce_ev_enabled |= (1 << FCE_FILE_CREATE);
         } else if (strcmp(p, "dcre") == 0) {
             fce_ev_enabled |= (1 << FCE_DIR_CREATE);
-        } else if (strcmp(p, "tmsz") == 0) {
-            fce_ev_enabled |= (1 << FCE_TM_SIZE);
         }
     }
 
@@ -605,7 +488,7 @@ void shortsleep( unsigned int us )
 }
 int main( int argc, char*argv[] )
 {
-    int c,ret;
+    int c;
 
     char *port = FCE_DEFAULT_PORT_STRING;
     char *host = "localhost";
@@ -668,7 +551,7 @@ int main( int argc, char*argv[] )
         if (end_time && now >= end_time)
             break;
 
-        register_fce( path, 0, event_code );
+        fce_register(event_code, path, NULL, 0);
         ev_cnt++;
 
         
index 9ed185e53457868b7107b42ee4322caebdcea198..fb5e58e38971602b6de5317e41922e3db7d10461 100644 (file)
@@ -10,6 +10,8 @@
 
 #include <stdbool.h>
 
+#include <atalk/fce_api.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
@@ -20,8 +22,7 @@
 #define FCE_COALESCE_DELETE (1 << 1)
 #define FCE_COALESCE_ALL    (FCE_COALESCE_CREATE | FCE_COALESCE_DELETE)
 
-struct udp_entry
-{
+struct udp_entry {
     int sock;
     char *addr;
     char *port;
@@ -30,12 +31,11 @@ struct udp_entry
     time_t next_try_on_error;      /* In case of error set next timestamp to retry */
 };
 
-struct fce_history
-{
-    unsigned char mode;
-       int is_dir;
-       char path[MAXPATHLEN + 1];
-       struct timeval tv;
+struct fce_history {
+    fce_ev_t       fce_h_event;
+       fce_obj_t      fce_h_type;
+       char           fce_h_path[MAXPATHLEN + 1];
+       struct timeval fce_h_tv;
 };
 
 struct fce_close_event {
@@ -45,7 +45,7 @@ struct fce_close_event {
 
 #define PACKET_HDR_LEN (sizeof(struct fce_packet) - FCE_MAX_PATH_LEN)
 
-bool fce_handle_coalescation( char *path, int is_dir, int mode );
+bool fce_handle_coalescation(int event, const char *path, fce_obj_t type);
 void fce_initialize_history();
 
 
index 07b59d73621555cf917eebbc4028ac347860cc37..69f6ea0dabfb9987c767eb6b8ff521bcdc3c1c9e 100644 (file)
@@ -54,9 +54,6 @@
 // ONLY USED IN THIS FILE
 #include "fce_api_internal.h"
 
-#define FCE_TRUE 1
-#define FCE_FALSE 0
-
 /* We store our connection data here */
 static uint32_t coalesce = 0;
 static struct fce_history fce_history_list[FCE_HISTORY_LEN];
@@ -92,7 +89,7 @@ void fce_initialize_history()
        }
 }
 
-bool fce_handle_coalescation( char *path, int is_dir, int mode )
+bool fce_handle_coalescation(int event, const char *path, fce_obj_t type)
 {
        /* These two are used to eval our next index in history */
        /* the history is unsorted, speed should not be a problem, length is 10 */
@@ -104,7 +101,7 @@ bool fce_handle_coalescation( char *path, int is_dir, int mode )
                return false;
 
        /* After a file creation *ALWAYS* a file modification is produced */
-       if ((mode == FCE_FILE_CREATE) && (coalesce & FCE_COALESCE_CREATE))
+       if ((event == FCE_FILE_CREATE) && (coalesce & FCE_COALESCE_CREATE))
         return true;
 
        /* get timestamp */
@@ -115,7 +112,7 @@ bool fce_handle_coalescation( char *path, int is_dir, int mode )
                struct fce_history *fh = &fce_history_list[i];
 
                /* Not inited ? */
-               if (fh->tv.tv_sec == 0) {
+               if (fh->fce_h_tv.tv_sec == 0) {
                        /* we can use it for new elements */
                        oldest_entry = 0;
                        oldest_entry_idx = i;
@@ -123,9 +120,9 @@ bool fce_handle_coalescation( char *path, int is_dir, int mode )
                }
 
                /* Too old ? */
-               if (get_ms_difftime( &fh->tv, &tv ) > MAX_COALESCE_TIME_MS) {
+               if (get_ms_difftime(&fh->fce_h_tv, &tv ) > MAX_COALESCE_TIME_MS) {
                        /* Invalidate entry */
-                       fh->tv.tv_sec = 0;
+                       fh->fce_h_tv.tv_sec = 0;
                        oldest_entry = 0;
                        oldest_entry_idx = i;                   
                        continue;
@@ -133,33 +130,33 @@ bool fce_handle_coalescation( char *path, int is_dir, int mode )
 
 
                /* If we find a parent dir wich was created we are done */
-               if ((coalesce & FCE_COALESCE_CREATE) && (fh->mode == FCE_DIR_CREATE)) {
+               if ((coalesce & FCE_COALESCE_CREATE) && (fh->fce_h_event == FCE_DIR_CREATE)) {
                        /* Parent dir ? */
-                       if (!strncmp(fh->path, path, strlen(fh->path)))
+                       if (!strncmp(fh->fce_h_path, path, strlen(fh->fce_h_path)))
                                return true;
                }
 
                /* If we find a parent dir we should be DELETED we are done */
                if ((coalesce & FCE_COALESCE_DELETE)
-            && fh->is_dir
-            && (mode == FCE_FILE_DELETE || mode == FCE_DIR_DELETE)) {
+            && fh->fce_h_type
+            && (event == FCE_FILE_DELETE || event == FCE_DIR_DELETE)) {
                        /* Parent dir ? */
-                       if (!strncmp(fh->path, path, strlen(fh->path)))
+                       if (!strncmp(fh->fce_h_path, path, strlen(fh->fce_h_path)))
                                return true;
                }
 
                /* Detect oldest entry for next new entry */
-               if (oldest_entry_idx == -1 || fh->tv.tv_sec < oldest_entry) {
-                       oldest_entry = fh->tv.tv_sec;
+               if (oldest_entry_idx == -1 || fh->fce_h_tv.tv_sec < oldest_entry) {
+                       oldest_entry = fh->fce_h_tv.tv_sec;
                        oldest_entry_idx = i;
                }
        }
 
        /* We have a new entry for the history, register it */
-       fce_history_list[oldest_entry_idx].tv = tv;
-       fce_history_list[oldest_entry_idx].mode = mode;
-       fce_history_list[oldest_entry_idx].is_dir = is_dir;
-       strncpy( fce_history_list[oldest_entry_idx].path, path, MAXPATHLEN);
+       fce_history_list[oldest_entry_idx].fce_h_tv = tv;
+       fce_history_list[oldest_entry_idx].fce_h_event = event;
+       fce_history_list[oldest_entry_idx].fce_h_type = type;
+       strncpy(fce_history_list[oldest_entry_idx].fce_h_path, path, MAXPATHLEN);
 
        /* we have to handle this event */
        return false;
index 8cd5f456947333a38372e90487aa78c7819eae70..153f1325a2641bd021ace0401285f49966f3b112 100644 (file)
@@ -77,6 +77,7 @@ static int default_type(void *finder)
 /* FIXME path : unix or mac name ? (for now it's unix name ) */
 void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *adp, void *data, int islink)
 {
+    struct extmap       *em;
     void                *ad_finder = NULL;
     int                 chk_ext = 0;
 
@@ -85,9 +86,13 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a
 
     if (ad_finder) {
         memcpy(data, ad_finder, ADEDLEN_FINDERI);
+        /* default type ? */
+        if (default_type(ad_finder)) 
+            chk_ext = 1;
     }
     else {
         memcpy(data, ufinderi, ADEDLEN_FINDERI);
+        chk_ext = 1;
         if (vol_inv_dots(vol) && *upath == '.') { /* make it invisible */
             uint16_t ashort;
             
@@ -96,7 +101,7 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a
         }
     }
 
-    if (islink){
+    if (islink && !vol_syml_opt(vol)) {
         uint16_t linkflag;
         memcpy(&linkflag, (char *)data + FINDERINFO_FRFLAGOFF, 2);
         linkflag |= htons(FINDERINFO_ISALIAS);
@@ -105,6 +110,12 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a
         memcpy((char *)data + FINDERINFO_FRCREATOFF,"rhap",4); 
     }
 
+    /** Only enter if no appledouble information and no finder information found. */
+    if (chk_ext && (em = getextmap( upath ))) {
+        memcpy(data, em->em_type, sizeof( em->em_type ));
+        memcpy((char *)data + 4, em->em_creator, sizeof(em->em_creator));
+    }
+
     return data;
 }
 
@@ -594,7 +605,7 @@ int getfilparams(const AFPObj *obj, struct vol *vol, uint16_t bitmap, struct pat
     struct adouble     ad, *adp;
     int                 opened = 0;
     int rc;    
-    int flags;
+    int flags; /* uninitialized ok */
 
     LOG(log_debug, logtype_afpd, "getfilparams(\"%s\")", path->u_name);
 
@@ -630,7 +641,9 @@ int getfilparams(const AFPObj *obj, struct vol *vol, uint16_t bitmap, struct pat
         }
     }
     rc = getmetadata(obj, vol, bitmap, path, dir, buf, buflen, adp);
-    ad_close(adp, ADFLAGS_HF | flags);
+
+    if (opened)
+        ad_close(adp, ADFLAGS_HF | flags);
 
     return( rc );
 }
@@ -675,7 +688,7 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_,
     ad_init(&ad, vol);
     
     /* if upath is deleted we already in trouble anyway */
-    if ((of = of_findname(s_path))) {
+    if ((of = of_findname(vol, s_path))) {
         if (creatf)
             return AFPERR_BUSY;
         else
@@ -737,9 +750,8 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_,
 createfile_iderr:
     ad_flush(&ad);
     ad_close(&ad, ADFLAGS_DF|ADFLAGS_HF );
-    fce_register_new_file(s_path);
+    fce_register(FCE_FILE_CREATE, fullpathname(upath), NULL, fce_file);
 
-createfile_done:
     curdir->d_offcnt++;
 
     setvoltime(obj, vol );
@@ -828,7 +840,10 @@ int setfilparams(const AFPObj *obj, struct vol *vol,
     uint16_t           bitmap = f_bitmap;
     uint32_t           cdate,bdate;
     u_char              finder_buf[32];
-    int symlinked = 0;
+    int symlinked = S_ISLNK(path->st.st_mode);
+    int fp;
+    ssize_t len;
+    char symbuf[MAXPATHLEN+1];
 
 #ifdef DEBUG
     LOG(log_debug9, logtype_afpd, "begin setfilparams:");
@@ -870,29 +885,33 @@ int setfilparams(const AFPObj *obj, struct vol *vol,
             break;
         case FILPBIT_FINFO :
             change_mdate = 1;
-            memcpy(finder_buf, buf, 32 );
-            if (memcmp(buf, "slnkrhap", 8) == 0 && !S_ISLNK(path->st.st_mode)) {
-                int fp;
-                ssize_t len;
-                int erc=1;
-                char buf[PATH_MAX+1];
-                if ((fp = open(path->u_name, O_RDONLY)) >= 0) {
-                    if ((len = read(fp, buf, PATH_MAX+1))) {
-                        if (unlink(path->u_name) == 0) {
-                            buf[len] = 0;
-                            erc = symlink(buf, path->u_name);
-                            if (!erc)
-                                of_stat(path);
-                        }
-                    }
-                    close(fp);
+            if (memcmp(buf,"slnkrhap",8) == 0
+                && !(S_ISLNK(path->st.st_mode))
+                && !(vol->v_flags & AFPVOL_FOLLOWSYM)) {
+                /* request to turn this into a symlink */
+                if ((fp = open(path->u_name, O_RDONLY)) == -1) {
+                    err = AFPERR_MISC;
+                    goto setfilparam_done;
+                }
+                len = read(fp, symbuf, MAXPATHLEN);
+                close(fp);
+                if (!(len > 0)) {
+                    err = AFPERR_MISC;
+                    goto setfilparam_done;
                 }
-                if (erc != 0) {
-                    err=AFPERR_BITMAP;
+                if (unlink(path->u_name) != 0) {
+                    err = AFPERR_MISC;
                     goto setfilparam_done;
                 }
+                symbuf[len] = 0;
+                if (symlink(symbuf, path->u_name) != 0) {
+                    err = AFPERR_MISC;
+                    goto setfilparam_done;
+                }
+                of_stat(vol, path);
                 symlinked = 1;
             }
+            memcpy(finder_buf, buf, 32 );
             buf += 32;
             break;
         case FILPBIT_UNIXPR :
@@ -970,6 +989,12 @@ int setfilparams(const AFPObj *obj, struct vol *vol,
         isad = 0;
     } else if ((ad_get_MD_flags( adp ) & O_CREAT) ) {
         ad_setname(adp, path->m_name);
+        cnid_t id;
+        if ((id = get_id(vol, adp, &path->st, curdir->d_did, upath, strlen(upath))) == CNID_INVALID) {
+            LOG(log_error, logtype_afpd, "afp_createfile(\"%s\"): CNID error", upath);
+            return AFPERR_MISC;
+        }
+        (void)ad_setid(adp, path->st.st_dev, path->st.st_ino, id, curdir->d_did, vol->v_stamp);
     }
     
     bit = 0;
@@ -1002,6 +1027,17 @@ int setfilparams(const AFPObj *obj, struct vol *vol,
             ad_setdate(adp, AD_DATE_BACKUP, bdate);
             break;
         case FILPBIT_FINFO :
+            if (default_type( ad_entry( adp, ADEID_FINDERI ))
+                    && ( 
+                     ((em = getextmap( path->m_name )) &&
+                      !memcmp(finder_buf, em->em_type, sizeof( em->em_type )) &&
+                      !memcmp(finder_buf + 4, em->em_creator,sizeof( em->em_creator)))
+                     || ((em = getdefextmap()) &&
+                      !memcmp(finder_buf, em->em_type, sizeof( em->em_type )) &&
+                      !memcmp(finder_buf + 4, em->em_creator,sizeof( em->em_creator)))
+            )) {
+                memcpy(finder_buf, ufinderi, 8 );
+            }
             memcpy(ad_entry( adp, ADEID_FINDERI ), finder_buf, 32 );
             break;
         case FILPBIT_UNIXPR :
@@ -1064,7 +1100,7 @@ setfilparam_done:
  * adp         adouble struct of src file, if open, or & zeroed one
  *
  */
-int renamefile(const struct vol *vol, int sdir_fd, char *src, char *dst, char *newname, struct adouble *adp)
+int renamefile(struct vol *vol, struct dir *ddir, int sdir_fd, char *src, char *dst, char *newname, struct adouble *adp)
 {
     int                rc;
 
@@ -1089,7 +1125,7 @@ int renamefile(const struct vol *vol, int sdir_fd, char *src, char *dst, char *n
                /* FIXME  warning in syslog so admin'd know there's a conflict ?*/
                return AFPERR_OLOCK; /* little lie */
            }
-            if (AFP_OK != ( rc = copyfile(vol, vol, sdir_fd, src, dst, newname, NULL )) ) {
+            if (AFP_OK != ( rc = copyfile(vol, vol, ddir, sdir_fd, src, dst, newname, NULL )) ) {
                 /* on error copyfile delete dest */
                 return( rc );
             }
@@ -1323,7 +1359,7 @@ int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, si
         goto copy_exit;
     }
 
-    if ( (err = copyfile(s_vol, d_vol, -1, p, upath , newname, adp)) < 0 ) {
+    if ( (err = copyfile(s_vol, d_vol, curdir, -1, p, upath , newname, adp)) < 0 ) {
         retvalue = err;
         goto copy_exit;
     }
@@ -1341,8 +1377,9 @@ copy_exit:
  * because we are doing it elsewhere.
  * currently if newname is NULL then adp is NULL. 
  */
-int copyfile(const struct vol *s_vol,
-             const struct vol *d_vol, 
+int copyfile(struct vol *s_vol,
+             struct vol *d_vol, 
+             struct dir *d_dir, 
              int sfd,
              char *src,
              char *dst,
@@ -1364,13 +1401,17 @@ int copyfile(const struct vol *s_vol,
         adp = &ads;
     }
 
-    adflags = ADFLAGS_DF | ADFLAGS_RF | ADFLAGS_NORF;
+    adflags = ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF | ADFLAGS_RF | ADFLAGS_NORF;
 
     if (ad_openat(adp, sfd, src, adflags | ADFLAGS_RDONLY) < 0) {
         ret_err = errno;
         goto done;
     }
 
+    if (!AD_META_OPEN(adp))
+        /* no resource fork, don't create one for dst file */
+        adflags &= ~ADFLAGS_HF;
+
     if (!AD_RSRC_OPEN(adp))
         /* no resource fork, don't create one for dst file */
         adflags &= ~ADFLAGS_RF;
@@ -1403,12 +1444,25 @@ int copyfile(const struct vol *s_vol,
     if (err < 0)
        ret_err = errno;
 
-    if (!ret_err && newname && (adflags & ADFLAGS_HF)) {
-        /* set the new name in the resource fork */
-        ad_copy_header(&add, adp);
-        ad_setname(&add, newname);
-        ad_flush( &add );
+    if (AD_META_OPEN(&add)) {
+        if (AD_META_OPEN(adp))
+            ad_copy_header(&add, adp);
+        ad_setname(&add, dst);
+        cnid_t id;
+        struct stat stdest;
+        if (fstat(ad_meta_fileno(&add), &stdest) != 0) {
+            ret_err = errno;
+            goto error;
+        }
+        if ((id = get_id(d_vol, &add, &stdest, d_dir->d_did, dst, strlen(dst))) == CNID_INVALID) {
+            ret_err = EINVAL;
+            goto error;
+        }
+        (void)ad_setid(&add, stdest.st_dev, stdest.st_ino, id, d_dir->d_did, d_vol->v_stamp);
+        ad_flush(&add);
     }
+
+error:
     ad_close( adp, adflags );
 
     if (ad_close( &add, adflags ) <0) {
@@ -1650,7 +1704,7 @@ static int reenumerate_loop(struct dirent *de, char *mname _U_, void *data)
     cnid_t        did  = param->did;
     cnid_t       aint;
     
-    if ( lstat(de->d_name, &path.st) < 0 )
+    if (ostat(de->d_name, &path.st, vol_syml_opt(vol)) < 0)
         return 0;
     
     /* update or add to cnid */
@@ -1675,7 +1729,7 @@ reenumerate_id(struct vol *vol, char *name, struct dir *dir)
     }
     
     /* FIXME use of_statdir ? */
-    if (lstat(name, &st)) {
+    if (ostat(name, &st, vol_syml_opt(vol))) {
        return -1;
     }
 
@@ -1754,7 +1808,7 @@ retry:
 
     memset(&path, 0, sizeof(path));
     path.u_name = upath;
-    if ( of_stat(&path) < 0 ) {
+    if (of_stat(vol, &path) < 0 ) {
 #ifdef ESTALE
         /* with nfs and our working directory is deleted */
        if (errno == ESTALE) {
@@ -1849,7 +1903,7 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
     }
 
     err = AFP_OK;
-    if ((movecwd(vol, dir) < 0) || (lstat(upath, &st) < 0)) {
+    if ((movecwd(vol, dir) < 0) || (ostat(upath, &st, vol_syml_opt(vol)) < 0)) {
         switch (errno) {
         case EACCES:
         case EPERM:
@@ -1912,7 +1966,7 @@ static struct adouble *find_adouble(const AFPObj *obj, struct vol *vol, struct p
         return NULL;
     }
     
-    if ((*of = of_findname(path))) {
+    if ((*of = of_findname(vol, path))) {
         /* reuse struct adouble so it won't break locks */
         adp = (*of)->of_ad;
     }
@@ -2057,11 +2111,13 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
      * NOTE: the temp file will be in the dest file's directory. it
      * will also be inaccessible from AFP. */
     memcpy(temp, APPLETEMP, sizeof(APPLETEMP));
-    if (!mktemp(temp)) {
+    int fd;
+    if ((fd = mkstemp(temp)) == -1) {
         err = AFPERR_MISC;
         goto err_exchangefile;
     }
-    
+    close(fd);
+
     if (crossdev) {
         /* FIXME we need to close fork for copy, both s_of and d_of are null */
        ad_close(adsp, ADFLAGS_HF);
@@ -2069,17 +2125,17 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
     }
 
     /* now, quickly rename the file. we error if we can't. */
-    if ((err = renamefile(vol, -1, p, temp, temp, adsp)) != AFP_OK)
+    if ((err = renamefile(vol, curdir, -1, p, temp, temp, adsp)) != AFP_OK)
         goto err_exchangefile;
     of_rename(vol, s_of, sdir, spath, curdir, temp);
 
     /* rename destination to source */
-    if ((err = renamefile(vol, -1, upath, p, spath, addp)) != AFP_OK)
+    if ((err = renamefile(vol, curdir, -1, upath, p, spath, addp)) != AFP_OK)
         goto err_src_to_tmp;
     of_rename(vol, d_of, curdir, path->m_name, sdir, spath);
 
     /* rename temp to destination */
-    if ((err = renamefile(vol, -1, temp, upath, path->m_name, adsp)) != AFP_OK)
+    if ((err = renamefile(vol, curdir, -1, temp, upath, path->m_name, adsp)) != AFP_OK)
         goto err_dest_to_src;
     of_rename(vol, s_of, curdir, temp, curdir, path->m_name);
 
@@ -2091,10 +2147,10 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
     if (did)
         cnid_delete(vol->v_cdb, did);
 
-    if ((did && ( (crossdev && lstat( upath, &srcst) < 0) || 
+    if ((did && ( (crossdev && ostat(upath, &srcst, vol_syml_opt(vol)) < 0) || 
                 cnid_update(vol->v_cdb, did, &srcst, curdir->d_did,upath, dlen) < 0))
        ||
-       (sid && ( (crossdev && lstat(p, &destst) < 0) ||
+        (sid && ( (crossdev && ostat(p, &destst, vol_syml_opt(vol)) < 0) ||
                 cnid_update(vol->v_cdb, sid, &destst, sdir->d_did,supath, slen) < 0))
     ) {
         switch (errno) {
@@ -2154,17 +2210,17 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
      * properly. */
 err_temp_to_dest:
     /* rename dest to temp */
-    renamefile(vol, -1, upath, temp, temp, adsp);
+    renamefile(vol, curdir, -1, upath, temp, temp, adsp);
     of_rename(vol, s_of, curdir, upath, curdir, temp);
 
 err_dest_to_src:
     /* rename source back to dest */
-    renamefile(vol, -1, p, upath, path->m_name, addp);
+    renamefile(vol, curdir, -1, p, upath, path->m_name, addp);
     of_rename(vol, d_of, sdir, spath, curdir, path->m_name);
 
 err_src_to_tmp:
     /* rename temp back to source */
-    renamefile(vol, -1, temp, p, spath, adsp);
+    renamefile(vol, curdir, -1, temp, p, spath, adsp);
     of_rename(vol, s_of, curdir, temp, sdir, spath);
 
 err_exchangefile:
index aa9f3b4449a8ea386adf328e8b3f97d39cf759b6..1d0ff45ea16b4f3aeaf234b10d5f0c667179e1b6 100644 (file)
@@ -51,12 +51,6 @@ extern const u_char  ufinderi[];
 #define FILPBIT_EXTRFLEN 14
 #define FILPBIT_UNIXPR   15
 
-struct extmap {
-    char               *em_ext;
-    char               em_creator[ 4 ];
-    char               em_type[ 4 ];
-};
-
 #define kTextEncodingUTF8 0x08000103
 
 typedef enum {
@@ -111,8 +105,8 @@ extern struct extmap        *getdefextmap (void);
 extern int getfilparams (const AFPObj *obj, struct vol *, uint16_t, struct path *,
                          struct dir *, char *buf, size_t *, int);
 extern int setfilparams (const AFPObj *obj, struct vol *, struct path *, uint16_t, char *);
-extern int renamefile   (const struct vol *, int, char *, char *, char *, struct adouble *);
-extern int copyfile     (const struct vol *, const struct vol *, int, char *, char *, char *, struct adouble *);
+extern int renamefile   (struct vol *, struct dir *, int, char *, char *, char *, struct adouble *);
+extern int copyfile     (struct vol *, struct vol *, struct dir *, int, char *, char *, char *, struct adouble *);
 extern int deletefile   (const struct vol *, int, char *, int);
 
 extern int getmetadata  (const AFPObj *obj, struct vol *vol, uint16_t bitmap, struct path *path, 
index 56cbaccffff2d32d59697fb6acad396589284bca..543db0dc0ecdb6710cf30c182234f6942ef50553 100644 (file)
@@ -218,7 +218,7 @@ int check_name(const struct vol *vol, char *name)
     move and rename sdir:oldname to curdir:newname in volume vol
     special care is needed for lock   
 */
-static int moveandrename(const struct vol *vol,
+static int moveandrename(struct vol *vol,
                          struct dir *sdir,
                          int sdir_fd,
                          char *oldname,
@@ -346,10 +346,10 @@ static int moveandrename(const struct vol *vol,
     if ( !isdir ) {
         path.st_valid = 1;
         path.st_errno = errno;
-        if (of_findname(&path)) {
+        if (of_findname(vol, &path)) {
             rc = AFPERR_EXIST; /* was AFPERR_BUSY; */
         } else {
-            rc = renamefile(vol, sdir_fd, oldunixname, upath, newname, adp );
+            rc = renamefile(vol, curdir, sdir_fd, oldunixname, upath, newname, adp );
             if (rc == AFP_OK)
                 of_rename(vol, opened, sdir, oldname, curdir, newname);
         }
@@ -525,7 +525,7 @@ int afp_delete(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
                 delcnid = cnid_get(vol->v_cdb, curdir->d_did, upath, strlen(upath));
             if (delcnid != CNID_INVALID)
                 cnid_delete(vol->v_cdb, delcnid);
-            fce_register_delete_dir(upath);
+            fce_register(FCE_DIR_DELETE, fullpathname(upath), NULL, fce_dir);
         } else {
             /* we have to cache this, the structs are lost in deletcurdir*/
             /* but we need the positive returncode to send our event */
@@ -533,10 +533,10 @@ int afp_delete(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
             if ((dname = bstrcpy(curdir->d_u_name)) == NULL)
                 return AFPERR_MISC;
             if ((rc = deletecurdir(vol)) == AFP_OK)
-                fce_register_delete_dir(cfrombstr(dname));
+                fce_register(FCE_DIR_DELETE, fullpathname(cfrombstr(dname)), NULL, fce_dir);
             bdestroy(dname);
         }
-    } else if (of_findname(s_path)) {
+    } else if (of_findname(vol, s_path)) {
         rc = AFPERR_BUSY;
     } else {
         /* it's a file st_valid should always be true
@@ -547,7 +547,7 @@ int afp_delete(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
             rc = AFPERR_NOOBJ;
         } else {
             if ((rc = deletefile(vol, -1, upath, 1)) == AFP_OK) {
-                               fce_register_delete_file( s_path );
+                               fce_register(FCE_FILE_DELETE, fullpathname(upath), NULL, fce_file);
                 if (vol->v_tm_used < s_path->st.st_size)
                     vol->v_tm_used = 0;
                 else 
@@ -703,8 +703,8 @@ int afp_moveandrename(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U
         if (!isdir && !vol_unix_priv(vol)) {
             int  admode = ad_mode("", 0777) | vol->v_fperm;
 
-            setfilmode(upath, admode, NULL, vol->v_umask);
-            vol->vfs->vfs_setfilmode(vol, upath, admode, NULL);
+            setfilmode(vol, upath, admode, path->st_valid ? &path->st : NULL);
+            vol->vfs->vfs_setfilmode(vol, upath, admode, path->st_valid ? &path->st : NULL);
         }
         setvoltime(obj, vol );
     }
index 9c3ed7d2f1be64ce11c14b5814850195ca6c7742..2d59b5da0450e22d5b9f8b21ae3562d3beab6d3c 100644 (file)
@@ -22,6 +22,7 @@
 #include <atalk/logger.h>
 #include <atalk/util.h>
 #include <atalk/cnid.h>
+#include <atalk/bstrlib.h>
 #include <atalk/bstradd.h>
 #include <atalk/globals.h>
 #include <atalk/netatalk_conf.h>
@@ -250,7 +251,6 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
     struct stat     *st;
     uint16_t        bshort;
     struct path     *s_path;
-    struct stat xxx;
 
     ibuf++;
     fork = *ibuf++;
@@ -316,7 +316,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
         }
     }
 
-    if ((opened = of_findname(s_path))) {
+    if ((opened = of_findname(vol, s_path))) {
         adsame = opened->of_ad;
     }
 
@@ -733,8 +733,6 @@ int afp_bytelock_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t
 static int read_file(const struct ofork *ofork, int eid, off_t offset, char *rbuf, size_t *rbuflen)
 {
     ssize_t cc;
-    int eof = 0;
-    char *p, *q;
 
     cc = ad_read(ofork->of_ad, eid, offset, rbuf, *rbuflen);
     if ( cc < 0 ) {
@@ -1051,7 +1049,6 @@ static ssize_t write_file(struct ofork *ofork, int eid,
                           off_t offset, char *rbuf,
                           size_t rbuflen)
 {
-    char *p, *q;
     ssize_t cc;
 
     LOG(log_debug, logtype_afpd, "write_file(off: %ju, size: %zu)",
@@ -1090,7 +1087,7 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s
     uint16_t        ofrefnum;
     ssize_t         cc;
     DSI             *dsi = obj->dsi;
-    char            *rcvbuf = dsi->commands;
+    char            *rcvbuf = (char *)dsi->commands;
     size_t          rcvbuflen = dsi->server_quantum;
 
     /* figure out parameters */
index d7120e4778b163927bd17b31c2f5ffd4872aa3a9..5b63601f992fe139e2b67bf4d724199a6c873c52 100644 (file)
@@ -59,13 +59,13 @@ extern struct ofork *of_alloc    (struct vol *, struct dir *,
                                                       struct stat *);
 extern void         of_dealloc   (struct ofork *);
 extern struct ofork *of_find     (const uint16_t);
-extern struct ofork *of_findname (struct path *);
+extern struct ofork *of_findname (const struct vol *vol, struct path *);
 extern int          of_rename    (const struct vol *,
                                           struct ofork *,
                                           struct dir *, const char *,
                                           struct dir *, const char *);
 extern int          of_flush     (const struct vol *);
-extern int          of_stat      (struct path *);
+extern int          of_stat      (const struct vol *vol, struct path *);
 extern int          of_statdir   (struct vol *vol, struct path *);
 extern int          of_closefork (const AFPObj *obj, struct ofork *ofork);
 extern void         of_closevol  (const AFPObj *obj, const struct vol *vol);
diff --git a/etc/afpd/gettok.c b/etc/afpd/gettok.c
deleted file mode 100644 (file)
index fd48db6..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * $Id: gettok.c,v 1.6 2009-10-13 22:55:37 didg Exp $
- *
- * Copyright (c) 1990,1994 Regents of The University of Michigan.
- * All Rights Reserved.  See COPYRIGHT.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include <sys/param.h>
-#include <string.h>
-#include <ctype.h>
-#include <pwd.h>
-
-#include <atalk/globals.h>
-
-static char    *l_curr;
-static char    *l_end;
-
-void initline( int len, char *line)
-{
-    l_curr = line;
-    l_end = line + len;
-}
-
-#define ST_QUOTE       0
-#define ST_WORD                1
-#define ST_BEGIN       2
-
-int
-parseline(int len, char *token)
-{
-    char       *p, *e;
-    int                state;
-
-    state = ST_BEGIN;
-    p = token;
-    e = token + len;
-
-    for (;;) {
-        if ( l_curr > l_end ) {                        /* end of line */
-            *token = '\0';
-            return( -1 );
-        }
-
-        switch ( *l_curr ) {
-        case '"' :
-            if ( state == ST_QUOTE ) {
-                state = ST_WORD;
-            } else {
-                state = ST_QUOTE;
-            }
-            break;
-
-        case '\0' :
-        case '\t' :
-        case '\n' :
-        case ' ' :
-            if ( state == ST_WORD ) {
-                *p = '\0';
-                return( p - token );
-            }
-            if ( state != ST_QUOTE ) {
-                break;
-            }
-            /* FALL THROUGH */
-
-        default :
-            if ( state == ST_BEGIN ) {
-                state = ST_WORD;
-            }
-            if ( p > e ) {                     /* end of token */
-                *token = '\0';
-                return( -1 );
-            }
-            *p++ = *l_curr;
-            break;
-        }
-
-        l_curr++;
-    }
-}
-
-#ifdef notdef
-void parseline(char *token, char *user)
-{
-    char               *p = pos, *t = token, *u, *q, buf[ MAXPATHLEN ];
-    struct passwd      *pwent;
-    int                        quoted = 0;
-
-    while ( isspace( *p )) {
-        p++;
-    }
-
-    /*
-     * If we've reached the end of the line, or a comment,
-     * don't return any more tokens.
-     */
-    if ( *p == '\0' || *p == '#' ) {
-        *token = '\0';
-        return;
-    }
-
-    if ( *p == '"' ) {
-        p++;
-        quoted = 1;
-    }
-    while ( *p != '\0' && ( quoted || !isspace( *p ))) {
-        if ( *p == '"' ) {
-            if ( quoted ) {
-                *t = '\0';
-                break;
-            }
-            quoted = 1;
-            p++;
-        } else {
-            *t++ = *p++;
-        }
-    }
-    pos = p;
-    *t = '\0';
-
-    /*
-     * We got to the end of the line without closing an open quote
-     */
-    if ( *p == '\0' && quoted ) {
-        *token = '\0';
-        return;
-    }
-
-    t = token;
-    if ( *t == '~' ) {
-        t++;
-        if ( *t == '\0' || *t == '/' ) {
-            u = user;
-            if ( *t == '/' ) {
-                t++;
-            }
-        } else {
-            u = t;
-            if (( q = strchr( t, '/' )) == NULL ) {
-                t = "";
-            } else {
-                *q = '\0';
-                t = q + 1;
-            }
-        }
-        if ( u == NULL || ( pwent = getpwnam( u )) == NULL ) {
-            *token = '\0';
-            return;
-        }
-        strcpy( buf, pwent->pw_dir );
-        if ( *t != '\0' ) {
-            strcat( buf, "/" );
-            strcat( buf, t );
-        }
-        strcpy( token, buf );
-    }
-    return;
-}
-#endif /* notdef */
index b7471ccb19ec821b7b7a6559272b02ec6736c985..4861e8112589a7ffb8af67cd4ede9ad741067fb2 100644 (file)
@@ -14,7 +14,6 @@
  * into proprietary software; there is no requirement for such software to
  * contain a copyright notice related to this source.
  *
- * $Id: hash.c,v 1.4 2009-11-19 10:37:43 franklahm Exp $
  * $Name:  $
  */
 #define NDEBUG
@@ -26,7 +25,6 @@
 #include "hash.h"
 
 #ifdef KAZLIB_RCSID
-static const char rcsid[] = "$Id: hash.c,v 1.4 2009-11-19 10:37:43 franklahm Exp $";
 #endif
 
 #define INIT_BITS   6
@@ -58,7 +56,6 @@ static const char rcsid[] = "$Id: hash.c,v 1.4 2009-11-19 10:37:43 franklahm Exp
 static hnode_t *hnode_alloc(void *context);
 static void hnode_free(hnode_t *node, void *context);
 static hash_val_t hash_fun_default(const void *key);
-static hash_val_t hash_fun2(const void *key);
 static int hash_comp_default(const void *key1, const void *key2);
 
 int hash_val_t_bit;
@@ -850,6 +847,13 @@ static hash_val_t hash_fun_default(const void *key)
                       +(uint32_t)(((const uint8_t *)(d))[0]) )
 #endif
 
+static int hash_comp_default(const void *key1, const void *key2)
+{
+    return strcmp(key1, key2);
+}
+
+#ifdef KAZLIB_TEST_MAIN
+
 static hash_val_t hash_fun2(const void *key)
 {
     int len, rem;
@@ -897,13 +901,6 @@ static hash_val_t hash_fun2(const void *key)
     return hash;
 }
 
-static int hash_comp_default(const void *key1, const void *key2)
-{
-    return strcmp(key1, key2);
-}
-
-#ifdef KAZLIB_TEST_MAIN
-
 #include <stdio.h>
 #include <ctype.h>
 #include <stdarg.h>
index dcac14b6bd40a7f4ae8ada703b2244721d5d5261..886344eb13e3453f26f28b23f48856b2c650e8a4 100644 (file)
@@ -14,7 +14,6 @@
  * into proprietary software; there is no requirement for such software to
  * contain a copyright notice related to this source.
  *
- * $Id: hash.h,v 1.2 2009-10-02 09:32:40 franklahm Exp $
  * $Name:  $
  */
 
index e89d0a2e9e58d6aacf2e2cc5af061a56959bb5dc..0e0a858e84ce51b9b6bad2ee2f4118e10e837232 100644 (file)
@@ -210,8 +210,6 @@ static int setlimits(void)
 
 int main(int ac, char **av)
 {
-    fd_set              rfds;
-    void                *ipc;
     struct sigaction   sv;
     sigset_t            sigs;
     int                 ret;
@@ -253,6 +251,13 @@ int main(int ac, char **av)
         afp_exit(EXITERR_SYS);
     }
 #endif
+
+    sv.sa_handler = SIG_IGN;
+    sigemptyset( &sv.sa_mask );
+    if (sigaction(SIGPIPE, &sv, NULL ) < 0 ) {
+        LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
+        afp_exit(EXITERR_SYS);
+    }
     
     sv.sa_handler = afp_goaway; /* handler for all sigs */
 
@@ -382,12 +387,17 @@ int main(int ac, char **av)
 
         if (reloadconfig) {
             nologin++;
-            auth_unload();
+
             fd_reset_listening_sockets(&obj);
 
             LOG(log_info, logtype_afpd, "re-reading configuration file");
 
             configfree(&obj, NULL);
+            afp_config_free(&obj);
+
+            if (afp_config_parse(&obj, "afpd") != 0)
+                afp_exit(EXITERR_CONF);
+
             if (configinit(&obj) != 0) {
                 LOG(log_error, logtype_afpd, "config re-read: no servers configured");
                 afp_exit(EXITERR_CONF);
@@ -416,7 +426,7 @@ int main(int ac, char **av)
                 switch (polldata[i].fdtype) {
 
                 case LISTEN_FD:
-                    if (child = dsi_start(&obj, (DSI *)polldata[i].data, server_children)) {
+                    if ((child = dsi_start(&obj, (DSI *)polldata[i].data, server_children))) {
                         /* Add IPC fd to select fd set */
                         fdset_add_fd(obj.options.connections + AFP_LISTENERS + FDSET_SAFETY,
                                      &fdset,
index dce7e61681ac8e646ad4ed5ef810d39dacade824..18d6fcd91a227526a728f4b2bec9d6a83d7b4142 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: mangle.h,v 1.7 2009-10-13 22:55:37 didg Exp $
  *
  */
 
index b250c16633991d0a6a36a365f1cd48c585220bdb..50440ab42b6d2f38677dad27c86a88ae8299b218 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: nfsquota.c,v 1.13 2009-10-13 22:55:37 didg Exp $
  *
  * parts of this are lifted from the bsd quota program and are
  * therefore under the following copyright:
index 3d690079ba84f7136575afa593e79ad2a3c6425a..cf77d4906ad6edaf0a8dc82c40ba6f75f378be0d 100644 (file)
@@ -228,14 +228,14 @@ struct ofork *of_find(const uint16_t ofrefnum )
 }
 
 /* -------------------------- */
-int of_stat(struct path *path)
+int of_stat(const struct vol *vol, struct path *path)
 {
     int ret;
 
     path->st_errno = 0;
     path->st_valid = 1;
 
-    if ((ret = lstat(path->u_name, &path->st)) < 0) {
+    if ((ret = ostat(path->u_name, &path->st, vol_syml_opt(vol))) < 0) {
         LOG(log_debug, logtype_afpd, "of_stat('%s/%s': %s)",
             cfrombstr(curdir->d_fullpath), path->u_name, strerror(errno));
        path->st_errno = errno;
@@ -274,7 +274,7 @@ int of_statdir(struct vol *vol, struct path *path)
 
     if (*path->m_name) {
         /* not curdir */
-        return of_stat (path);
+        return of_stat(vol, path);
     }
     path->st_errno = 0;
     path->st_valid = 1;
@@ -286,7 +286,7 @@ int of_statdir(struct vol *vol, struct path *path)
 
     LOG(log_debug, logtype_afpd, "of_statdir: stating: '%s'", pathname);
 
-    if (!(ret = lstat(pathname, &path->st)))
+    if (!(ret = ostat(pathname, &path->st, vol_syml_opt(vol))))
         return 0;
 
     path->st_errno = errno;
@@ -297,7 +297,7 @@ int of_statdir(struct vol *vol, struct path *path)
            return -1;
        path->st_errno = 0;
 
-       if ((ret = lstat(cfrombstr(path->d_dir->d_u_name), &path->st)) < 0) 
+       if ((ret = ostat(cfrombstr(path->d_dir->d_u_name), &path->st, vol_syml_opt(vol))) < 0) 
            path->st_errno = errno;
     }
 
@@ -305,13 +305,13 @@ int of_statdir(struct vol *vol, struct path *path)
 }
 
 /* -------------------------- */
-struct ofork *of_findname(struct path *path)
+struct ofork *of_findname(const struct vol *vol, struct path *path)
 {
     struct ofork *of;
     struct file_key key;
 
     if (!path->st_valid) {
-        of_stat(path);
+        of_stat(vol, path);
     }
 
     if (path->st_errno)
@@ -407,7 +407,10 @@ int of_closefork(const AFPObj *obj, struct ofork *ofork)
 
     /* Somone has used write_fork, we assume file was changed, register it to file change event api */
     if (ofork->of_flags & AFPFORK_MODIFIED) {
-        fce_register_file_modification(ofork);
+        struct dir *dir =  dirlookup(ofork->of_vol, ofork->of_did);
+        bstring forkpath = bformat("%s/%s", bdata(dir->d_fullpath), of_name(ofork));
+        fce_register(FCE_FILE_MODIFY, bdata(forkpath), NULL, fce_file);
+        bdestroy(forkpath);
     }
 
     ad_unlock(ofork->of_ad, ofork->of_refnum, ofork->of_flags & AFPFORK_ERROR ? 0 : 1);
@@ -441,7 +444,7 @@ struct adouble *of_ad(const struct vol *vol, struct path *path, struct adouble *
     struct ofork        *of;
     struct adouble      *adp;
 
-    if ((of = of_findname(path))) {
+    if ((of = of_findname(vol, path))) {
         adp = of->of_ad;
     } else {
         ad_init(ad, vol);
index 6903a21610ab421bbd3560569ae0e3cb30131d45..614a7f95e74956a6d5881b4b35b0915cf20c3fe4 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: quota.c,v 1.35 2010-04-03 07:11:35 franklahm Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -26,6 +25,7 @@
 #include <atalk/afp.h>
 #include <atalk/compat.h>
 #include <atalk/unix.h>
+#include <atalk/util.h>
 
 #include "auth.h"
 #include "volume.h"
@@ -370,7 +370,7 @@ mountp( char *file, int *nfs)
     dev_t                      devno;
     static struct mnttab       mnt;
 
-    if ( lstat( file, &sb ) < 0 ) {
+    if (stat(file, &sb) < 0) {
         return( NULL );
     }
     devno = sb.st_dev;
@@ -381,14 +381,14 @@ mountp( char *file, int *nfs)
 
     while ( getmntent( mtab, &mnt ) == 0 ) {
         /* local fs */
-        if ( (lstat( mnt.mnt_special, &sb ) == 0) && (devno == sb.st_rdev)) {
+        if ( (stat( mnt.mnt_special, &sb ) == 0) && (devno == sb.st_rdev)) {
             fclose( mtab );
             return mnt.mnt_mountp;
         }
 
         /* check for nfs. we probably should use
          * strcmp(mnt.mnt_fstype, MNTTYPE_NFS), but that's not as fast. */
-        if ((lstat(mnt.mnt_mountp, &sb) == 0) && (devno == sb.st_dev) &&
+        if ((stat(mnt.mnt_mountp, &sb) == 0) && (devno == sb.st_dev) &&
                 strchr(mnt.mnt_special, ':')) {
             *nfs = 1;
             fclose( mtab );
@@ -458,7 +458,7 @@ special(char *file, int *nfs)
     struct mntent      *mnt;
     int                found=0;
 
-    if ( lstat( file, &sb ) < 0 ) {
+    if (stat(file, &sb) < 0 ) {
         return( NULL );
     }
     devno = sb.st_dev;
@@ -469,14 +469,14 @@ special(char *file, int *nfs)
 
     while (( mnt = getmntent( mtab )) != NULL ) {
         /* check for local fs */
-        if ( (lstat( mnt->mnt_fsname, &sb ) == 0) && devno == sb.st_rdev) {
+        if ( (stat( mnt->mnt_fsname, &sb ) == 0) && devno == sb.st_rdev) {
            found = 1;
            break;
         }
 
         /* check for an nfs mount entry. the alternative is to use
         * strcmp(mnt->mnt_type, MNTTYPE_NFS) instead of the strchr. */
-        if ((lstat(mnt->mnt_dir, &sb) == 0) && (devno == sb.st_dev) &&
+        if ((stat(mnt->mnt_dir, &sb) == 0) && (devno == sb.st_dev) &&
                 strchr(mnt->mnt_fsname, ':')) {
             *nfs = 1;
            found = 1;
index f42bf5ec0ef97d657caca080f4a095b36f3db6b4..35e088499db21c56483139df30e3c7b3d5c7f9de 100644 (file)
@@ -95,7 +95,7 @@ static void status_flags(char *data,
 static int status_server(char *data, const char *server, const struct afp_options *options)
 {
     char                *start = data;
-    char                *Obj, *Type, *Zone;
+    char                *Obj;
     char               buf[32];
     uint16_t           status;
     size_t             len;
@@ -364,7 +364,6 @@ static size_t status_directorynames(char *data,
     data += offset;
 
     char *DirectoryNamesCount = data++;
-    char *DirectoryNames = data;
     size_t size = sizeof(uint8_t);
     *DirectoryNamesCount = 0;
 
@@ -441,8 +440,11 @@ static size_t status_directorynames(char *data,
     }
 
     krb5_unparse_name(context, entry.principal, &principal);
+#ifdef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS
+    krb5_free_keytab_entry_contents(context, &entry);
+#elif defined(HAVE_KRB5_KT_FREE_ENTRY)
     krb5_kt_free_entry(context, &entry);
-
+#endif
     append_directoryname(&data,
                          offset,
                          &size,
@@ -501,7 +503,7 @@ static size_t status_utf8servername(char *data, int *nameoffset,
     uint16_t namelen;
     size_t len;
     char *begin = data;
-    uint16_t offset, status;
+    uint16_t offset;
 
     memcpy(&offset, data + *nameoffset, sizeof(offset));
     offset = ntohs(offset);
@@ -645,7 +647,7 @@ void set_signature(struct afp_options *options) {
     char *servername_conf;
     int header = 0;
     char buf[1024], *p;
-    FILE *fp = NULL, *randomp;
+    FILE *fp = NULL;
     size_t len;
     char *server_tmp;
     
index 2f94ac8885d76dd18c5b3cf6d3d9d2040681fccb..1cc50d01bf038a4f017c530dcf5b7b001d2d5e9f 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: switch.h,v 1.4 2009-10-15 10:43:13 didg Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
index d99d381edd38cc4408a5076039ef47f53d4e7899..208c9ff234313dd8194a7ac9e488b609b6f9ef99 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: uam.c,v 1.35 2009-11-08 01:15:31 didg Exp $
  *
  * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved.  See COPYRIGHT.
@@ -31,6 +30,7 @@
 #include <atalk/util.h>
 #include <atalk/globals.h>
 #include <atalk/volume.h>
+#include <atalk/bstrlib.h>
 
 #include "afp_config.h"
 #include "auth.h"
@@ -209,25 +209,24 @@ struct passwd *uam_getname(void *private, char *name, const int len)
         return pwent;
         
     /* if we have a NT domain name try with it */
-    if (obj->options.ntdomain && obj->options.ntseparator) {
+    if (obj->options.addomain || (obj->options.ntdomain && obj->options.ntseparator)) {
         /* FIXME What about charset ? */
-        size_t ulen = strlen(obj->options.ntdomain) + strlen(obj->options.ntseparator) + strlen(name);
-        if ((p = malloc(ulen +1))) {
-            strcpy(p, obj->options.ntdomain);
-            strcat(p, obj->options.ntseparator);
-            strcat(p, name);
-            pwent = getpwnam(p);
-            free(p);
-            if (pwent) {
-                int len = strlen(pwent->pw_name);              
-                if (len < MAXUSERLEN) {
-                    strncpy(name,pwent->pw_name, MAXUSERLEN);  
-                }else{
-                    LOG(log_error, logtype_uams, "MAJOR:The name %s is longer than %d",pwent->pw_name,MAXUSERLEN);
-                }
-
-                return pwent;
+        bstring princ;
+        if (obj->options.addomain)
+            princ = bformat("%s@%s", name, obj->options.addomain);
+        else
+            princ = bformat("%s%s%s", obj->options.ntdomain, obj->options.ntseparator, name);
+        pwent = getpwnam(bdata(princ));
+        bdestroy(princ);
+
+        if (pwent) {
+            int len = strlen(pwent->pw_name);              
+            if (len < MAXUSERLEN) {
+                strncpy(name,pwent->pw_name, MAXUSERLEN);  
+            } else {
+                LOG(log_error, logtype_uams, "The name '%s' is longer than %d", pwent->pw_name, MAXUSERLEN);
             }
+            return pwent;
         }
     }
 #ifndef NO_REAL_USER_NAME
index e26e6d1f1b50f702da0fb3ea0d9786937b275e99..a3e4d59704592e9626734bdde323a992953241b1 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: uid.c,v 1.14 2005-04-28 20:49:45 bfernhomberg Exp $
  * code: jeff@univrel.pr.uconn.edu
  *
  * These functions are abstracted here, so that all calls for resolving
index 647cbd8d164a76182953c420c3650ae773f2a2a2..87745147fc3c0a4bea82ba5652acf4bfbdca107c 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: uid.h,v 1.6 2002-08-30 19:32:41 didg Exp $
  * code: jeff@univrel.pr.uconn.edu
  */
 
index 16562f3b757b1d0912d09e221a2d52b5144aee33..7c90462874cd0cceec47f3c9836f42319e6a1937 100644 (file)
@@ -158,7 +158,7 @@ void accessmode(const AFPObj *obj, const struct vol *vol, char *path, struct mac
 
     ma->ma_user = ma->ma_owner = ma->ma_world = ma->ma_group = 0;
     if (!st) {
-        if (lstat(path, &sb) != 0)
+        if (ostat(path, &sb, vol_syml_opt(vol)) != 0)
             return;
         st = &sb;
     }
@@ -207,7 +207,7 @@ mode_t mtoumode(struct maccess *ma)
 int setfilunixmode (const struct vol *vol, struct path* path, mode_t mode)
 {
     if (!path->st_valid) {
-        of_stat(path);
+        of_stat(vol, path);
     }
 
     if (path->st_errno) {
@@ -216,7 +216,7 @@ int setfilunixmode (const struct vol *vol, struct path* path, mode_t mode)
         
     mode |= vol->v_fperm;
 
-    if (setfilmode( path->u_name, mode, &path->st, vol->v_umask) < 0)
+    if (setfilmode(vol, path->u_name, mode, &path->st) < 0)
         return -1;
     /* we need to set write perm if read set for resource fork */
     return vol->vfs->vfs_setfilmode(vol, path->u_name, mode, &path->st);
@@ -224,7 +224,7 @@ int setfilunixmode (const struct vol *vol, struct path* path, mode_t mode)
 
 
 /* --------------------- */
-int setdirunixmode(const struct vol *vol, const char *name, mode_t mode)
+int setdirunixmode(const struct vol *vol, char *name, mode_t mode)
 {
     LOG(log_debug, logtype_afpd, "setdirunixmode('%s', mode:%04o) {v_dperm:%04o}",
         fullpathname(name), mode, vol->v_dperm);
@@ -249,7 +249,7 @@ int setdirunixmode(const struct vol *vol, const char *name, mode_t mode)
 /* ----------------------------- */
 int setfilowner(const struct vol *vol, const uid_t uid, const gid_t gid, struct path* path)
 {
-    if (lchown(path->u_name, uid, gid) < 0 && errno != EPERM) {
+    if (ochown( path->u_name, uid, gid, vol_syml_opt(vol)) < 0 && errno != EPERM ) {
         LOG(log_debug, logtype_afpd, "setfilowner: chown %d/%d %s: %s",
             uid, gid, path->u_name, strerror(errno));
         return -1;
@@ -271,7 +271,7 @@ int setfilowner(const struct vol *vol, const uid_t uid, const gid_t gid, struct
  * co-opting some bits. */
 int setdirowner(const struct vol *vol, const char *name, const uid_t uid, const gid_t gid)
 {
-    if (lchown(name, uid, gid ) < 0 && errno != EPERM ) {
+    if (ochown(name, uid, gid, vol_syml_opt(vol)) < 0 && errno != EPERM ) {
         LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s",
             uid, gid, fullpathname(name), strerror(errno) );
     }
@@ -281,4 +281,3 @@ int setdirowner(const struct vol *vol, const char *name, const uid_t uid, const
 
     return( 0 );
 }
-
index 73a515b2dcf357496ffec0ae57aa67ca11f13422..3b3c281b528c57dd4c035243796340823c35ec8f 100644 (file)
@@ -213,7 +213,7 @@ extern int uquota_getvolspace (const AFPObj *obj, struct vol *, VolSpace *, VolS
 
 extern struct afp_options default_options;
 
-extern int setdirunixmode   (const struct vol *, const char *, mode_t);
+extern int setdirunixmode   (const struct vol *, char *, mode_t);
 extern int setdirmode       (const struct vol *, const char *, mode_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);
index 3b02b2390a467dd81de3319fa757ceb709434844..844444ba77498aa020875cd8c98413a78bcff5fe 100644 (file)
@@ -152,7 +152,6 @@ static int get_tm_used(struct vol * restrict vol)
     DIR *dir = NULL;
     const struct dirent *entry;
     const char *p;
-    struct stat st;
     long int links;
     time_t now = time(NULL);
 
@@ -212,7 +211,6 @@ static int getvolspace(const AFPObj *obj, struct vol *vol,
 {
     int         spaceflag, rc;
     uint32_t   maxsize;
-    VolSpace    used;
 #ifndef NO_QUOTA_SUPPORT
     VolSpace    qfree, qtotal;
 #endif
@@ -264,22 +262,6 @@ getvolspace_done:
     return( AFP_OK );
 }
 
-#define FCE_TM_DELTA 10  /* send notification every 10 seconds */
-void vol_fce_tm_event(void)
-{
-    static time_t last;
-    time_t now = time(NULL);
-    struct vol  *vol = getvolumes();
-
-    if ((last + FCE_TM_DELTA) < now) {
-        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_appended);
-        }
-    }
-}
-
 /* -----------------------
  * set volume creation date
  * avoid duplicate, well at least it tries
@@ -543,7 +525,7 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
     int         vcnt;
     size_t      len;
 
-    load_volumes(obj, closevol);
+    load_volumes(obj);
 
     data = rbuf + 5;
     for ( vcnt = 0, volume = getvolumes(); volume; volume = volume->v_next ) {
@@ -679,14 +661,12 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
 {
     struct stat st;
     char    *volname;
-    char        *p;
 
     struct vol  *volume;
     struct dir  *dir;
     int     len, ret;
     size_t  namelen;
     uint16_t   bitmap;
-    char        path[ MAXPATHLEN + 1];
     char        *vol_uname;
     char        *vol_mname;
     char        *volname_tmp;
@@ -721,7 +701,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
     if ((len + 1) & 1) /* pad to an even boundary */
         ibuf++;
 
-    load_volumes(obj, closevol);
+    load_volumes(obj);
 
     for ( volume = getvolumes(); volume; volume = volume->v_next ) {
         if ( strcasecmp_w( (ucs2_t*) volname, volume->v_name ) == 0 ) {
@@ -765,33 +745,6 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
         return AFPERR_PARAM;
     }
 
-    if ( NULL == getcwd(path, MAXPATHLEN)) {
-        /* shouldn't be fatal but it will fail later */
-        LOG(log_error, logtype_afpd, "afp_openvol(%s): volume pathlen too long", volume->v_path);
-        return AFPERR_MISC;
-    }
-
-    /* Normalize volume path */
-#ifdef REALPATH_TAKES_NULL
-    if ((volume->v_path = realpath(path, NULL)) == NULL)
-        return AFPERR_MISC;
-#else
-    if ((volume->v_path = malloc(MAXPATHLEN+1)) == NULL)
-        return AFPERR_MISC;
-    if (realpath(path, volume->v_path) == NULL) {
-        free(volume->v_path);
-        return AFPERR_MISC;
-    }
-    /* Safe some memory */
-    char *tmp;
-    if ((tmp = strdup(volume->v_path)) == NULL) {
-        free(volume->v_path);
-        return AFPERR_MISC;
-    }
-    free(volume->v_path);
-    volume->v_path = tmp;
-#endif
-
     if (volume_codepage(obj, volume) < 0) {
         ret = AFPERR_MISC;
         goto openvol_err;
@@ -820,9 +773,9 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
         goto openvol_err;
     }
 
-    if ((vol_uname = strrchr(path, '/')) == NULL)
-        vol_uname = path;
-    else if (*(vol_uname + 1) != '\0')
+    if ((vol_uname = strrchr(volume->v_path, '/')) == NULL)
+        vol_uname = volume->v_path;
+    else if (vol_uname[1] != '\0')
         vol_uname++;
 
     if ((dir = dir_new(vol_mname,
index 3bca88214bfee50687bc7dc052d5e70a9bb8c948..a8bd2b8bad453a6b51de78a8f90dad5ee8026257 100644 (file)
@@ -19,7 +19,6 @@ extern int              ustatfs_getvolspace (const struct vol *,
                                              uint32_t *);
 extern void             setvoltime (AFPObj *, struct vol *);
 extern int              pollvoltime (AFPObj *);
-extern void             vol_fce_tm_event(void);
 
 /* FP functions */
 int afp_openvol      (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf,  size_t *rbuflen);
index 8f8b734216fb2a9413d1ffde668d2ff5fb40b5f1..31d74e6c8b06724e6e1e1102393fa66cd1d18a69 100644 (file)
 #include <errno.h>
 
 #include <atalk/logger.h>
-#include <atalk/cnid_dbd_private.h>
 #include <atalk/globals.h>
 #include <atalk/netatalk_conf.h>
 #include <atalk/util.h>
+#include <atalk/errchk.h>
 
 #include "cmd_dbd.h"
-#include "dbd.h"
-#include "dbif.h"
-#include "db_param.h"
-#include "pack.h"
 
-#define DBOPTIONS (DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN)
+enum dbd_cmd {dbd_scan, dbd_rebuild};
 
-int nocniddb = 0;               /* Dont open CNID database, only scan filesystem */
+/* Global variables */
 volatile sig_atomic_t alarmed;  /* flags for signals */
-int db_locked;                  /* have we got the fcntl lock on lockfile ? */
-
-static DBD *dbd;
-static int verbose;             /* Logging flag */
-static int exclusive;           /* Exclusive volume access */
-static struct db_param db_param = {
-    NULL,                       /* Volume dirpath */
-    1,                          /* bdb logfile autoremove */
-    64 * 1024,                  /* bdb cachesize (64 MB) */
-    DEFAULT_MAXLOCKS,           /* maxlocks */
-    DEFAULT_MAXLOCKOBJS,        /* maxlockobjs */
-    0,                          /* flush_interval */
-    0,                          /* flush_frequency */
-    0,                          /* usock_file */
-    -1,                         /* fd_table_size */
-    -1,                         /* idle_timeout */
-    -1                          /* max_vols */
-};
-static char dbpath[MAXPATHLEN+1];   /* Path to the dbd database */
 
-/* 
-   Provide some logging
- */
-void dbd_log(enum logtype lt, char *fmt, ...)
-{
-    int len;
-    static char logbuffer[1024];
-    va_list args;
+/* Local variables */
+static dbd_flags_t flags;
 
-    if ( (lt == LOGSTD) || (verbose == 1)) {
-        va_start(args, fmt);
-        len = vsnprintf(logbuffer, 1023, fmt, args);
-        va_end(args);
-        logbuffer[1023] = 0;
+/***************************************************************************
+ * Local functions
+ ***************************************************************************/
 
-        printf("%s\n", logbuffer);
-    }
-}
-
-/* 
-   SIGNAL handling:
-   catch SIGINT and SIGTERM which cause clean exit. Ignore anything else.
+/*
+ * SIGNAL handling:
+ * catch SIGINT and SIGTERM which cause clean exit. Ignore anything else.
  */
-
 static void sig_handler(int signo)
 {
     alarmed = 1;
@@ -128,99 +92,79 @@ static void set_signal(void)
 
 static void usage (void)
 {
-    printf("dbd (Netatalk %s)\n"
-           "Usage: dbd [-CeFtvx] -d [-i] | -s [-c|-n]| -r [-c|-f] | -u <path to netatalk volume>\n"
-           "dbd can dump, scan, reindex and rebuild Netatalk dbd CNID databases.\n"
-           "dbd must be run with appropiate permissions i.e. as root.\n\n"
-           "Main commands are:\n"
-           "   -d Dump CNID database\n"
-           "      Option: -i dump indexes too\n\n"
-           "   -s Scan volume:\n"
-           "      Options: -c Don't check .AppleDouble stuff, only ckeck orphaned.\n"
-           "               -n Don't open CNID database, skip CNID checks.\n\n"
-           "   -r Rebuild volume:\n"
-           "      Options: -c Don't create .AppleDouble stuff, only cleanup orphaned.\n"
-           "               -f wipe database and rebuild from IDs stored in AppleDouble\n"
-           "                  metadata file or EA. Implies -e.\n\n"
-           "   -u Upgrade:\n"
-           "      Opens the database which triggers any necessary upgrades,\n"
-           "      then closes and exits.\n\n"
-           "General options:\n"
-           "   -C convert from adouble:v2 to adouble:ea (use with -r)\n"
+    printf("Usage: dbd [-cfFstvV] <path to netatalk volume>\n\n"
+           "dbd scans all file and directories of AFP volumes, updating the\n"
+           "CNID database of the volume. dbd must be run with appropiate\n"
+           "permissions i.e. as root.\n\n"
+           "Options:\n"
+           "   -s scan volume: treat the volume as read only and don't\n"
+           "      perform any filesystem modifications\n"
+           "   -c convert from adouble:v2 to adouble:ea\n"
            "   -F location of the afp.conf config file\n"
-           "   -e only work on inactive volumes and lock them (exclusive)\n"
-           "   -x rebuild indexes (just for completeness, mostly useless!)\n"
+           "   -f delete and recreate CNID database\n"
            "   -t show statistics while running\n"
-           "   -v verbose\n\n"
-           , VERSION
+           "   -v verbose\n"
+           "   -V show version info\n\n"
         );
 }
 
-int main(int argc, char **argv)
+/***************************************************************************
+ * Global functions
+ ***************************************************************************/
+
+void dbd_log(enum logtype lt, char *fmt, ...)
 {
-    int c, lockfd, ret = -1;
-    int dump=0, scan=0, rebuild=0, prep_upgrade=0, rebuildindexes=0, dumpindexes=0, force=0;
-    dbd_flags_t flags = 0;
-    char *volpath;
-    int cdir;
-    AFPObj obj = { 0 };
-    struct vol *vol;
+    int len;
+    static char logbuffer[1024];
+    va_list args;
 
-    if (geteuid() != 0) {
-        usage();
-        exit(EXIT_FAILURE);
+    if ( (lt == LOGSTD) || (flags & DBD_FLAGS_VERBOSE)) {
+        va_start(args, fmt);
+        len = vsnprintf(logbuffer, 1023, fmt, args);
+        va_end(args);
+        logbuffer[1023] = 0;
+
+        printf("%s\n", logbuffer);
     }
-    /* Inhereting perms in ad_mkdir etc requires this */
-    ad_setfuid(0);
+}
 
-    while ((c = getopt(argc, argv, ":cCdefFinrstuvx")) != -1) {
+int main(int argc, char **argv)
+{
+    EC_INIT;
+    int dbd_cmd = dbd_rebuild;
+    int cdir = -1;
+    AFPObj obj = { 0 };
+    struct vol *vol = NULL;
+    const char *volpath = NULL;
+
+    int c;
+    while ((c = getopt(argc, argv, ":cfF:rstvV")) != -1) {
         switch(c) {
         case 'c':
-            flags |= DBD_FLAGS_CLEANUP;
-            break;
-        case 'C':
             flags |= DBD_FLAGS_V2TOEA;
             break;
-        case 'd':
-            dump = 1;
+        case 'f':
+            flags |= DBD_FLAGS_FORCE;
+            break;
+        case 'F':
+            obj.cmdlineconfigfile = strdup(optarg);
             break;
-        case 'i':
-            dumpindexes = 1;
+        case 'r':
+            /* the default */
             break;
         case 's':
-            scan = 1;
+            dbd_cmd = dbd_scan;
             flags |= DBD_FLAGS_SCAN;
             break;
-        case 'n':
-            nocniddb = 1; /* FIXME: this could/should be a flag too for consistency */
-            break;
-        case 'r':
-            rebuild = 1;
-            break;
         case 't':
             flags |= DBD_FLAGS_STATS;
             break;
-        case 'u':
-            prep_upgrade = 1;
-            break;
         case 'v':
-            verbose = 1;
-            break;
-        case 'e':
-            exclusive = 1;
-            flags |= DBD_FLAGS_EXCL;
-            break;
-        case 'x':
-            rebuildindexes = 1;
-            break;
-        case 'f':
-            force = 1;
-            exclusive = 1;
-            flags |= DBD_FLAGS_FORCE | DBD_FLAGS_EXCL;
-            break;
-        case 'F':
-            obj.cmdlineconfigfile = strdup(optarg);
+            flags |= DBD_FLAGS_VERBOSE;
             break;
+        case 'V':
+            printf("dbd %s\n", VERSION);
+            exit(0);
         case ':':
         case '?':
             usage();
@@ -229,16 +173,18 @@ int main(int argc, char **argv)
         }
     }
 
-    if ((dump + scan + rebuild + prep_upgrade) != 1) {
+    if ( (optind + 1) != argc ) {
         usage();
         exit(EXIT_FAILURE);
     }
+    volpath = argv[optind];
 
-    if ( (optind + 1) != argc ) {
+    if (geteuid() != 0) {
         usage();
         exit(EXIT_FAILURE);
     }
-    volpath = argv[optind];
+    /* Inhereting perms in ad_mkdir etc requires this */
+    ad_setfuid(0);
 
     setvbuf(stdout, (char *) NULL, _IONBF, 0);
 
@@ -257,13 +203,16 @@ int main(int argc, char **argv)
         exit(EXIT_FAILURE);
     }
 
+    /* Initialize CNID subsystem */
+    cnid_init();
+
     /* Setup logging. Should be portable among *NIXes */
-    if (!verbose)
-        setuplog("default:info", "/dev/tty");
+    if (flags & DBD_FLAGS_VERBOSE)
+        setuplog("default:note, cnid:debug", "/dev/tty");
     else
-        setuplog("default:debug", "/dev/tty");
+        setuplog("default:note", "/dev/tty");
 
-    if (load_volumes(&obj, NULL) != 0) {
+    if (load_volumes(&obj) != 0) {
         dbd_log( LOGSTD, "Couldn't load volumes");
         exit(EXIT_FAILURE);
     }
@@ -278,7 +227,20 @@ int main(int argc, char **argv)
         exit(EXIT_FAILURE);
     }
 
-    pack_setvol(vol);
+    /* open volume */
+    if (STRCMP(vol->v_cnidscheme, != , "dbd")) {
+        dbd_log(LOGSTD, "\"%s\" isn't a \"dbd\" CNID volume", vol->v_path);
+        exit(EXIT_FAILURE);
+    }
+    if ((vol->v_cdb = cnid_open(vol->v_path,
+                                0000,
+                                "dbd",
+                                vol->v_flags & AFPVOL_NODEV ? CNID_FLAG_NODEV : 0,
+                                vol->v_cnidserver,
+                                vol->v_cnidport)) == NULL) {
+        dbd_log(LOGSTD, "Cant initialize CNID database connection for %s", vol->v_path);
+        exit(EXIT_FAILURE);
+    }
 
     if (vol->v_adouble == AD_VERSION_EA)
         dbd_log( LOGDEBUG, "adouble:ea volume");
@@ -301,145 +263,28 @@ int main(int argc, char **argv)
         exit(EXIT_FAILURE);        
     }
 
-    /* Enuser dbpath is there, create if necessary */
-    struct stat st;
-    if (stat(vol->v_dbpath, &st) != 0) {
-        if (errno != ENOENT) {
-            dbd_log( LOGSTD, "Can't stat dbpath \"%s\": %s", vol->v_dbpath, strerror(errno));
-            exit(EXIT_FAILURE);        
-        }
-        if ((mkdir(vol->v_dbpath, 0755)) != 0) {
-            dbd_log( LOGSTD, "Can't create dbpath \"%s\": %s", vol->v_dbpath, strerror(errno));
-            exit(EXIT_FAILURE);
-        }        
-    }
-
-    /* Put "/.AppleDB" at end of volpath, get path from volinfo file */
-    if ( (strlen(vol->v_dbpath) + strlen("/.AppleDB")) > MAXPATHLEN ) {
-        dbd_log( LOGSTD, "Volume pathname too long");
-        exit(EXIT_FAILURE);        
-    }
-    strncpy(dbpath, vol->v_dbpath, MAXPATHLEN - strlen("/.AppleDB"));
-    strcat(dbpath, "/.AppleDB");
-
-    /* Check or create dbpath */
-    int dbdirfd = open(dbpath, O_RDONLY);
-    if (dbdirfd == -1 && errno == ENOENT) {
-        if (errno == ENOENT) {
-            if ((mkdir(dbpath, 0755)) != 0) {
-                dbd_log( LOGSTD, "Can't create .AppleDB for \"%s\": %s", dbpath, strerror(errno));
-                exit(EXIT_FAILURE);
-            }
-        } else {
-            dbd_log( LOGSTD, "Somethings wrong with .AppleDB for \"%s\", giving up: %s", dbpath, strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-    } else {
-        close(dbdirfd);
-    }
-
-    /* Get db lock */
-    if ((db_locked = get_lock(LOCK_EXCL, dbpath)) == -1)
-        goto exit_noenv;
-    if (db_locked != LOCK_EXCL) {
-        dbd_log(LOGDEBUG, "Database is in use, acquiring shared lock");
-        /* Couldn't get exclusive lock, try shared lock if -e wasn't requested */
-        if (exclusive) {
-            dbd_log(LOGSTD, "Database is in use and exlusive was requested");
-            goto exit_noenv;
+    if (flags & DBD_FLAGS_FORCE) {
+        if (cnid_wipe(vol->v_cdb) != 0) {
+            dbd_log( LOGSTD, "Failed to wipe CNID db");
+            EC_FAIL;
         }
-        if ((db_locked = get_lock(LOCK_SHRD, NULL)) != LOCK_SHRD)
-            goto exit_noenv;
-    }
-
-    /* Check if -f is requested and wipe db if yes */
-    if ((flags & DBD_FLAGS_FORCE) && rebuild) {
-        char cmd[8 + MAXPATHLEN];
-        if ((db_locked = get_lock(LOCK_FREE, NULL)) != 0)
-            goto exit_noenv;
-
-        snprintf(cmd, 8 + MAXPATHLEN, "rm -rf \"%s\"", dbpath);
-        dbd_log( LOGDEBUG, "Removing old database of volume: '%s'", volpath);
-        system(cmd);
-        if ((mkdir(dbpath, 0755)) != 0) {
-            dbd_log( LOGSTD, "Can't create dbpath \"%s\": %s", dbpath, strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-        dbd_log( LOGDEBUG, "Removed old database.");
-        if ((db_locked = get_lock(LOCK_EXCL, dbpath)) == -1)
-            goto exit_noenv;
-    }
-
-    /* 
-       Lets start with the BerkeleyDB stuff
-    */
-    if ( ! nocniddb) {
-        if ((dbd = dbif_init(dbpath, "cnid2.db")) == NULL)
-            goto exit_noenv;
-        
-        if (dbif_env_open(dbd,
-                          &db_param,
-                          (db_locked == LOCK_EXCL) ? (DBOPTIONS | DB_RECOVER) : DBOPTIONS) < 0) {
-            dbd_log( LOGSTD, "error opening database!");
-            goto exit_noenv;
-        }
-
-        if (db_locked == LOCK_EXCL)
-            dbd_log( LOGDEBUG, "Finished recovery.");
-
-        if (dbif_open(dbd, NULL, rebuildindexes) < 0) {
-            dbif_close(dbd);
-            goto exit_failure;
-        }
-
-        /* Prepare upgrade ? We're done */
-        if (prep_upgrade) {
-            (void)dbif_txn_close(dbd, 1);
-            goto cleanup;
-        }
-    }
-
-    /* Downgrade db lock if not running exclusive */
-    if (!exclusive && (db_locked == LOCK_EXCL)) {
-        if (get_lock(LOCK_UNLOCK, NULL) != 0)
-            goto exit_failure;
-        if (get_lock(LOCK_SHRD, NULL) != LOCK_SHRD)
-            goto exit_failure;
     }
 
     /* Now execute given command scan|rebuild|dump */
-    if (dump && ! nocniddb) {
-        if (dbif_dump(dbd, dumpindexes) < 0) {
-            dbd_log( LOGSTD, "Error dumping database");
-        }
-    } else if ((rebuild && ! nocniddb) || scan) {
-        if (cmd_dbd_scanvol(dbd, vol, flags) < 0) {
+    switch (dbd_cmd) {
+    case dbd_scan:
+    case dbd_rebuild:
+        if (cmd_dbd_scanvol(vol, flags) < 0) {
             dbd_log( LOGSTD, "Error repairing database.");
         }
+        break;
     }
 
-cleanup:
-    /* Cleanup */
-    dbd_log(LOGDEBUG, "Closing db");
-    if (! nocniddb) {
-        if (dbif_close(dbd) < 0) {
-            dbd_log( LOGSTD, "Error closing database");
-            goto exit_failure;
-        }
-    }
-
-exit_success:
-    ret = 0;
-
-exit_failure:
-    if (dbif_env_remove(dbpath) < 0) {
-        dbd_log( LOGSTD, "Error removing BerkeleyDB database environment");
-        ret++;
-    }
-    get_lock(0, NULL);
+EC_CLEANUP:
+    if (vol)
+        cnid_close(vol->v_cdb);
 
-exit_noenv:    
-    if ((fchdir(cdir)) < 0)
+    if (cdir != -1 && (fchdir(cdir) < 0))
         dbd_log(LOGSTD, "fchdir: %s", strerror(errno));
 
     if (ret == 0)
index efec636b482e464f40a1bda7ebc469dd420acb70..9fcb3f4edbef4178feb1004a7864bab7cfd520c4 100644 (file)
@@ -12,29 +12,18 @@ typedef unsigned int dbd_flags_t;
 
 #define DBD_FLAGS_SCAN     (1 << 0)
 #define DBD_FLAGS_FORCE    (1 << 1)
-#define DBD_FLAGS_EXCL     (1 << 2)
-#define DBD_FLAGS_CLEANUP  (1 << 3) /* Dont create AD stuff, but cleanup orphaned */
-#define DBD_FLAGS_STATS    (1 << 4)
-#define DBD_FLAGS_V2TOEA   (1 << 5) /* Convert adouble:v2 to adouble:ea */
+#define DBD_FLAGS_STATS    (1 << 2)
+#define DBD_FLAGS_V2TOEA   (1 << 3) /* Convert adouble:v2 to adouble:ea */
+#define DBD_FLAGS_VERBOSE  (1 << 4)
 
 #define ADv2_DIRNAME ".AppleDouble"
 
 #define DIR_DOT_OR_DOTDOT(a) \
         ((strcmp(a, ".") == 0) || (strcmp(a, "..") == 0))
 
-#define STRCMP(a,b,c) \
-        (strcmp(a,c) b 0)
-
-extern int nocniddb; /* Dont open CNID database, only scan filesystem */
-extern int db_locked; /* have we got the fcntl lock on lockfd ? */
 extern volatile sig_atomic_t alarmed;
 
 extern void dbd_log(enum logtype lt, char *fmt, ...);
-extern int cmd_dbd_scanvol(DBD *dbd, struct vol *vol, dbd_flags_t flags);
+extern int cmd_dbd_scanvol(struct vol *vol, dbd_flags_t flags);
 
-/*
-  Functions for querying the database which couldn't be reused from the existing
-  funcs pool of dbd_* for one reason or another
-*/
-extern int cmd_dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply);
 #endif /* CMD_DBD_H */
index dcbd4c74779161acb4be4f3b3feda12bc6bec771..b9fbf3e88ac4d63bea0766caa4fef714b522ffee 100644 (file)
 #include <atalk/adouble.h>
 #include <atalk/unicode.h>
 #include <atalk/netatalk_conf.h>
-#include <atalk/cnid_dbd_private.h>
 #include <atalk/volume.h>
 #include <atalk/ea.h>
 #include <atalk/util.h>
 #include <atalk/acl.h>
 #include <atalk/compat.h>
+#include <atalk/cnid.h>
+#include <atalk/errchk.h>
 
 #include "cmd_dbd.h"
 #include "dbif.h"
 #define ADFILE_OK (adfile_ok == 0)
 
 
-static struct vol     *myvol;
 static char           cwdbuf[MAXPATHLEN+1];
-static DBD            *dbd;
-static DBD            *dbd_rebuild;
+static struct vol     *vol;
 static dbd_flags_t    dbd_flags;
 static char           stamp[CNID_DEV_LEN];
 static char           *netatalk_dirs[] = {
@@ -83,74 +82,28 @@ static char *utompath(char *upath)
     u = upath;
     outlen = strlen(upath);
 
-    if ((myvol->v_casefold & AFPVOL_UTOMUPPER))
+    if ((vol->v_casefold & AFPVOL_UTOMUPPER))
         flags |= CONV_TOUPPER;
-    else if ((myvol->v_casefold & AFPVOL_UTOMLOWER))
+    else if ((vol->v_casefold & AFPVOL_UTOMLOWER))
         flags |= CONV_TOLOWER;
 
-    if ((myvol->v_flags & AFPVOL_EILSEQ)) {
+    if ((vol->v_flags & AFPVOL_EILSEQ)) {
         flags |= CONV__EILSEQ;
     }
 
     /* convert charsets */
-    if ((size_t)-1 == ( outlen = convert_charset(myvol->v_volcharset,
+    if ((size_t)-1 == ( outlen = convert_charset(vol->v_volcharset,
                                                  CH_UTF8_MAC,
-                                                 myvol->v_maccharset,
+                                                 vol->v_maccharset,
                                                  u, outlen, mpath, MAXPATHLEN, &flags)) ) {
         dbd_log( LOGSTD, "Conversion from %s to %s for %s failed.",
-                 myvol->v_volcodepage, myvol->v_maccodepage, u);
+                 vol->v_volcodepage, vol->v_maccodepage, u);
         return NULL;
     }
 
     return(m);
 }
 
-/*
-  Taken form afpd/desktop.c
-*/
-static char *mtoupath(char *mpath)
-{
-    static char  upath[ MAXPATHLEN + 2]; /* for convert_charset dest_len parameter +2 */
-    char    *m, *u;
-    size_t       inplen;
-    size_t       outlen;
-    u_int16_t    flags = 0;
-
-    if (!mpath)
-        return NULL;
-
-    if ( *mpath == '\0' ) {
-        return( "." );
-    }
-
-    /* set conversion flags */
-    if ((myvol->v_casefold & AFPVOL_MTOUUPPER))
-        flags |= CONV_TOUPPER;
-    else if ((myvol->v_casefold & AFPVOL_MTOULOWER))
-        flags |= CONV_TOLOWER;
-
-    if ((myvol->v_flags & AFPVOL_EILSEQ)) {
-        flags |= CONV__EILSEQ;
-    }
-
-    m = mpath;
-    u = upath;
-
-    inplen = strlen(m);
-    outlen = MAXPATHLEN;
-
-    if ((size_t)-1 == (outlen = convert_charset(CH_UTF8_MAC,
-                                                myvol->v_volcharset,
-                                                myvol->v_maccharset,
-                                                m, inplen, u, outlen, &flags)) ) {
-        dbd_log( LOGSTD, "conversion from UTF8-MAC to %s for %s failed.",
-                 myvol->v_volcodepage, mpath);
-        return NULL;
-    }
-
-    return( upath );
-}
-
 /*
   Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop"
   Returns pointer to name or NULL.
@@ -186,46 +139,15 @@ static const char *check_special_dirs(const char *name)
  */
 static int update_cnid(cnid_t did, const struct stat *sp, const char *oldname, const char *newname)
 {
-    int ret;
     cnid_t id;
 
-    /* Prepare request data */
-    memset(&rqst, 0, sizeof(struct cnid_dbd_rqst));
-    memset(&rply, 0, sizeof(struct cnid_dbd_rply));
-    rqst.did = did;
-    rqst.cnid = 0;
-    if ( ! (myvol->v_flags & AFPVOL_NODEV))
-        rqst.dev = sp->st_dev;
-    rqst.ino = sp->st_ino;
-    rqst.type = S_ISDIR(sp->st_mode) ? 1 : 0;
-    rqst.name = (char *)oldname;
-    rqst.namelen = strlen(oldname);
-
     /* Query the database */
-    ret = dbd_lookup(dbd, &rqst, &rply, (dbd_flags & DBD_FLAGS_SCAN) ? 1 : 0);
-    if (dbif_txn_close(dbd, ret) != 0)
-        return -1;
-    if (rply.result != CNID_DBD_RES_OK)
+    if ((id = cnid_lookup(vol->v_cdb, sp, did, (char *)oldname, strlen(oldname))) == CNID_INVALID)
+        /* not in db, no need to update */
         return 0;
-    id = rply.cnid;
-
-    /* Prepare request data */
-    memset(&rqst, 0, sizeof(struct cnid_dbd_rqst));
-    memset(&rply, 0, sizeof(struct cnid_dbd_rply));
-    rqst.did = did;
-    rqst.cnid = id;
-    if ( ! (myvol->v_flags & AFPVOL_NODEV))
-        rqst.dev = sp->st_dev;
-    rqst.ino = sp->st_ino;
-    rqst.type = S_ISDIR(sp->st_mode) ? 1 : 0;
-    rqst.name = (char *)newname;
-    rqst.namelen = strlen(newname);
 
     /* Update the database */
-    ret = dbd_update(dbd, &rqst, &rply);
-    if (dbif_txn_close(dbd, ret) != 0)
-        return -1;
-    if (rply.result != CNID_DBD_RES_OK)
+    if (cnid_update(vol->v_cdb, id, sp, did, (char *)newname, strlen(newname)) < 0)
         return -1;
 
     return 0;
@@ -243,10 +165,10 @@ static int check_adfile(const char *fname, const struct stat *st, const char **n
 
     *newname = NULL;
 
-    if (myvol->v_adouble == AD_VERSION_EA) {
+    if (vol->v_adouble == AD_VERSION_EA) {
         if (!(dbd_flags & DBD_FLAGS_V2TOEA))
             return 0;
-        if (ad_convert(fname, st, myvol, newname) != 0) {
+        if (ad_convert(fname, st, vol, newname) != 0) {
             switch (errno) {
             case ENOENT:
                 break;
@@ -258,13 +180,10 @@ static int check_adfile(const char *fname, const struct stat *st, const char **n
         return 0;
     }
     
-    if (dbd_flags & DBD_FLAGS_CLEANUP)
-        return 0;
-
     if (S_ISDIR(st->st_mode))
         adflags |= ADFLAGS_DIR;
 
-    adname = myvol->ad_path(fname, adflags);
+    adname = vol->ad_path(fname, adflags);
 
     if ((ret = access( adname, F_OK)) != 0) {
         if (errno != ENOENT) {
@@ -280,7 +199,7 @@ static int check_adfile(const char *fname, const struct stat *st, const char **n
             return -1;
 
         /* Create ad file */
-        ad_init(&ad, myvol);
+        ad_init(&ad, vol);
 
         if ((ret = ad_open(&ad, fname, adflags | ADFLAGS_CREATE | ADFLAGS_RDWR, 0666)) != 0) {
             dbd_log( LOGSTD, "Error creating AppleDouble file '%s/%s': %s",
@@ -300,7 +219,7 @@ static int check_adfile(const char *fname, const struct stat *st, const char **n
         chmod(adname, st->st_mode);
 #endif
     } else {
-        ad_init(&ad, myvol);
+        ad_init(&ad, vol);
         if (ad_open(&ad, fname, adflags | ADFLAGS_RDONLY) != 0) {
             dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s'", cwdbuf, fname);
             return -1;
@@ -369,7 +288,7 @@ static int check_eafiles(const char *fname)
     struct stat st;
     char *eaname;
 
-    if ((ret = ea_open(myvol, fname, EA_RDWR, &ea)) != 0) {
+    if ((ret = ea_open(vol, fname, EA_RDWR, &ea)) != 0) {
         if (errno == ENOENT)
             return 0;
         dbd_log(LOGSTD, "Error calling ea_open for file: %s/%s, removing EA files", cwdbuf, fname);
@@ -422,10 +341,7 @@ static int check_addir(int volroot)
     struct adouble ad;
     char *mname = NULL;
 
-    if (dbd_flags & DBD_FLAGS_CLEANUP)
-        return 0;
-
-    if (myvol->v_adouble == AD_VERSION_EA)
+    if (vol->v_adouble == AD_VERSION_EA)
         return 0;
 
     /* Check for ad-dir */
@@ -438,10 +354,10 @@ static int check_addir(int volroot)
     }
 
     /* Check for ".Parent" */
-    if ( (adpar_ok = access(myvol->ad_path(".", ADFLAGS_DIR), F_OK)) != 0) {
+    if ( (adpar_ok = access(vol->ad_path(".", ADFLAGS_DIR), F_OK)) != 0) {
         if (errno != ENOENT) {
             dbd_log(LOGSTD, "Access error on '%s/%s': %s",
-                    cwdbuf, myvol->ad_path(".", ADFLAGS_DIR), strerror(errno));
+                    cwdbuf, vol->ad_path(".", ADFLAGS_DIR), strerror(errno));
             return -1;
         }
         dbd_log(LOGSTD, "Missing .AppleDouble/.Parent for '%s'", cwdbuf);
@@ -460,7 +376,7 @@ static int check_addir(int volroot)
         }
 
         /* Create ad dir and set name */
-        ad_init(&ad, myvol);
+        ad_init(&ad, vol);
 
         if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_CREATE | ADFLAGS_RDWR, 0777) != 0) {
             dbd_log( LOGSTD, "Error creating AppleDouble dir in %s: %s", cwdbuf, strerror(errno));
@@ -481,7 +397,7 @@ static int check_addir(int volroot)
             return -1;
         }
         chown(ADv2_DIRNAME, st.st_uid, st.st_gid);
-        chown(myvol->ad_path(".", ADFLAGS_DIR), st.st_uid, st.st_gid);
+        chown(vol->ad_path(".", ADFLAGS_DIR), st.st_uid, st.st_gid);
     }
 
     return 0;
@@ -500,7 +416,7 @@ static int check_eafile_in_adouble(const char *name)
     char *namep, *namedup = NULL;
 
     /* Check if this is an AFPVOL_EA_AD vol */
-    if (myvol->v_vfs_ea == AFPVOL_EA_AD) {
+    if (vol->v_vfs_ea == AFPVOL_EA_AD) {
         /* Does the filename contain "::EA" ? */
         namedup = strdup(name);
         if ((namep = strstr(namedup, "::EA")) == NULL) {
@@ -559,7 +475,7 @@ static int read_addir(void)
     struct stat st;
 
     if ((chdir(ADv2_DIRNAME)) != 0) {
-        if (myvol->v_adouble == AD_VERSION_EA) {
+        if (vol->v_adouble == AD_VERSION_EA) {
             return 0;
         }
         dbd_log(LOGSTD, "Couldn't chdir to '%s/%s': %s",
@@ -643,49 +559,27 @@ static int read_addir(void)
 */
 static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfile_ok)
 {
-    int ret, adflags = ADFLAGS_HF;
+    int adflags = ADFLAGS_HF;
     cnid_t db_cnid, ad_cnid;
     struct adouble ad;
 
     adflags = ADFLAGS_HF | (S_ISDIR(st->st_mode) ? ADFLAGS_DIR : 0);
 
-    /* Force checkout every X items */
-    static int cnidcount = 0;
-    cnidcount++;
-    if (cnidcount > 10000) {
-        cnidcount = 0;
-        if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0) {
-            dbd_log(LOGSTD, "Error checkpointing!");
-            return CNID_INVALID;
-        }
-    }
-
     /* Get CNID from ad-file */
-    ad_cnid = 0;
+    ad_cnid = CNID_INVALID;
     if (ADFILE_OK) {
-        ad_init(&ad, myvol);
+        ad_init(&ad, vol);
         if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) {
             
-            if (dbd_flags & DBD_FLAGS_CLEANUP)
-                return CNID_INVALID;
-
-            if (myvol->v_adouble != AD_VERSION_EA) {
+            if (vol->v_adouble != AD_VERSION_EA) {
                 dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno));
                 return CNID_INVALID;
             }
             dbd_log( LOGDEBUG, "File without meta EA: \"%s/%s\"", cwdbuf, name);
             adfile_ok = 1;
         } else {
-
-            if (dbd_flags & DBD_FLAGS_FORCE) {
-                ad_cnid = ad_forcegetid(&ad);
-                /* This ensures the changed stamp is written */
-                ad_setid( &ad, st->st_dev, st->st_ino, ad_cnid, did, stamp);
-                ad_flush(&ad);
-            } else
-                ad_cnid = ad_getid(&ad, st->st_dev, st->st_ino, 0, stamp);
-
-            if (ad_cnid == 0)
+            ad_cnid = ad_getid(&ad, st->st_dev, st->st_ino, 0, stamp);
+            if (ad_cnid == CNID_INVALID)
                 dbd_log( LOGSTD, "Bad CNID in adouble file of '%s/%s'", cwdbuf, name);
             else
                 dbd_log( LOGDEBUG, "CNID from .AppleDouble file for '%s/%s': %u", cwdbuf, name, ntohl(ad_cnid));
@@ -694,128 +588,26 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi
     }
 
     /* Get CNID from database */
-
-    /* Prepare request data */
-    memset(&rqst, 0, sizeof(struct cnid_dbd_rqst));
-    memset(&rply, 0, sizeof(struct cnid_dbd_rply));
-    rqst.did = did;
-    rqst.cnid = ad_cnid;
-    if ( ! (myvol->v_flags & AFPVOL_NODEV))
-        rqst.dev = st->st_dev;
-    rqst.ino = st->st_ino;
-    rqst.type = S_ISDIR(st->st_mode)?1:0;
-    rqst.name = (char *)name;
-    rqst.namelen = strlen(name);
-
-    /* Query the database */
-    ret = dbd_lookup(dbd, &rqst, &rply, (dbd_flags & DBD_FLAGS_SCAN) ? 1 : 0);
-    if (dbif_txn_close(dbd, ret) != 0)
+    if ((db_cnid = cnid_add(vol->v_cdb, st, did, (char *)name, strlen(name), ad_cnid)) == CNID_INVALID)
         return CNID_INVALID;
-    if (rply.result == CNID_DBD_RES_OK) {
-        db_cnid = rply.cnid;
-    } else if (rply.result == CNID_DBD_RES_NOTFOUND) {
-        if ( ! (dbd_flags & DBD_FLAGS_FORCE))
-            dbd_log( LOGSTD, "No CNID for '%s/%s' in database", cwdbuf, name);
-        db_cnid = 0;
-    } else {
-        dbd_log( LOGSTD, "Fatal error resolving '%s/%s'", cwdbuf, name);
-        db_cnid = 0;
-    }
 
-    /* Compare results from both CNID searches */
-    if (ad_cnid && db_cnid && (ad_cnid == db_cnid)) {
-        /* Everything is fine */
-        return db_cnid;
-    } else if (ad_cnid && db_cnid && (ad_cnid != db_cnid)) {
+    /* Compare CNID from db and adouble file */
+    if (ad_cnid != db_cnid && adfile_ok == 0) {
         /* 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)) {
-            dbd_log(LOGSTD, "Updating AppleDouble file for '%s/%s' with CNID: %u from database",
-                            cwdbuf, name, ntohl(db_cnid));
-            ad_init(&ad, myvol);
-            if (ad_open(&ad, name, adflags | ADFLAGS_HF | ADFLAGS_RDWR) != 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(&ad, ADFLAGS_HF);
-        }
-        return db_cnid;
-    } else if (ad_cnid && (db_cnid == 0)) {
-        /* in ad-file but not in db */
-        if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
-            /* Ensure the cnid from the ad-file is not already occupied by another file */
-            dbd_log(LOGDEBUG, "Checking whether CNID %u from ad-file is occupied",
-                    ntohl(ad_cnid));
-
-            rqst.cnid = ad_cnid;
-            ret = dbd_resolve(dbd, &rqst, &rply);
-            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)
-                    return CNID_INVALID;
-                db_cnid = rply.cnid;
-                dbd_log(LOGSTD, "New CNID for '%s/%s': %u", cwdbuf, name, ntohl(db_cnid));
-
-                if (ADFILE_OK && ( ! (dbd_flags & DBD_FLAGS_SCAN))) {
-                    dbd_log(LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file",
-                            cwdbuf, name, ntohl(db_cnid));
-                    ad_init(&ad, myvol);
-                    if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 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(&ad, ADFLAGS_HF);
-                }
-                return db_cnid;
-            }
-
-            dbd_log(LOGDEBUG, "CNID rebuild add '%s/%s' with CNID from ad-file %u",
-                    cwdbuf, name, ntohl(ad_cnid));
-            rqst.cnid = ad_cnid;
-            ret = dbd_rebuild_add(dbd, &rqst, &rply);
-            if (dbif_txn_close(dbd, ret) != 0)
-                return CNID_INVALID;
-        }
-        return ad_cnid;
-    } else if ((db_cnid == 0) && (ad_cnid == 0)) {
-        /* No CNID at all, we clearly have to allocate a fresh one... */
-        /* Note: the next test will use this new CNID too! */
-        if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
-            /* add to db */
-            ret = dbd_add(dbd, &rqst, &rply, 1);
-            if (dbif_txn_close(dbd, ret) != 0)
-                return CNID_INVALID;
-            db_cnid = rply.cnid;
-            dbd_log(LOGSTD, "New CNID for '%s/%s': %u", cwdbuf, name, ntohl(db_cnid));
-        }
-    }
-
-    if ((ad_cnid == 0) && db_cnid) {
-        /* in db but zeroID in ad-file, write it to ad-file */
-        if (ADFILE_OK && ! (dbd_flags & DBD_FLAGS_SCAN)) {            
-            dbd_log(LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file",
-                    cwdbuf, name, ntohl(db_cnid));
-            ad_init(&ad, myvol);
-            if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 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(&ad, ADFLAGS_HF);
+        dbd_log(LOGSTD, "CNID mismatch for '%s/%s', CNID db: %u, ad-file: %u",
+                cwdbuf, name, ntohl(db_cnid), ntohl(ad_cnid));
+        ad_init(&ad, vol);
+        if (ad_open(&ad, name, adflags | ADFLAGS_HF | ADFLAGS_RDWR) != 0) {
+            dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s",
+                    cwdbuf, name, strerror(errno));
+            return CNID_INVALID;
         }
-        return db_cnid;
+        ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp);
+        ad_flush(&ad);
+        ad_close(&ad, ADFLAGS_HF);
     }
 
-    return CNID_INVALID;
+    return db_cnid;
 }
 
 /*
@@ -826,7 +618,7 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi
 */
 static int dbd_readdir(int volroot, cnid_t did)
 {
-    int cwd, ret = 0, adfile_ok, addir_ok, encoding_ok;
+    int cwd, ret = 0, adfile_ok, addir_ok;
     cnid_t cnid = 0;
     const char *name;
     DIR *dp;
@@ -879,7 +671,7 @@ static int dbd_readdir(int volroot, cnid_t did)
         if (STRCMP(ep->d_name, == , ADv2_DIRNAME))
             continue;
 
-        if (!myvol->vfs->vfs_validupath(myvol, ep->d_name)) {
+        if (!vol->vfs->vfs_validupath(vol, ep->d_name)) {
             dbd_log(LOGDEBUG, "Ignoring \"%s\"", ep->d_name);
             continue;
         }
@@ -893,10 +685,8 @@ static int dbd_readdir(int volroot, cnid_t did)
         switch (st.st_mode & S_IFMT) {
         case S_IFREG:
         case S_IFDIR:
-            break;
         case S_IFLNK:
-            dbd_log(LOGDEBUG, "Ignoring symlink %s/%s", cwdbuf, ep->d_name);
-            continue;
+            break;
         default:
             dbd_log(LOGSTD, "Bad filetype: %s/%s", cwdbuf, ep->d_name);
             if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
@@ -933,47 +723,25 @@ static int dbd_readdir(int volroot, cnid_t did)
         if (ADDIR_OK)
             adfile_ok = check_adfile(ep->d_name, &st, &name);
 
-        if (name == NULL) {
-            name = ep->d_name;
-        } else {
-            update_cnid(did, &st, ep->d_name, name);
-        }
+        if (!S_ISLNK(st.st_mode)) {
+            if (name == NULL) {
+                name = ep->d_name;
+            } else {
+                update_cnid(did, &st, ep->d_name, name);
+            }
 
-        if ( ! nocniddb) {
             /* Check CNIDs */
             cnid = check_cnid(name, did, &st, adfile_ok);
 
-            /* Now add this object to our rebuild dbd */
-            if (cnid && dbd_rebuild) {
-                static uint count = 0;
-                rqst.cnid = rply.cnid;
-                ret = dbd_rebuild_add(dbd_rebuild, &rqst, &rply);
-                if (dbif_txn_close(dbd_rebuild, ret) != 0)
-                    return -1;
-                if (rply.result != CNID_DBD_RES_OK) {
-                    dbd_log( LOGSTD, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db",
-                             cnid, cwdbuf, name);
-                    return -1;
-                }
-                count++;
-                if (count == 10000) {
-                    if (dbif_txn_checkpoint(dbd_rebuild, 0, 0, 0) < 0) {
-                        dbd_log(LOGSTD, "Error checkpointing!");
-                        return -1;
-                    }
-                    count = 0;
-                }
-            }
+            /* Check EA files */
+            if (vol->v_vfs_ea == AFPVOL_EA_AD)
+                check_eafiles(name);
         }
 
-        /* Check EA files */
-        if (myvol->v_vfs_ea == AFPVOL_EA_AD)
-            check_eafiles(name);
-
         /**************************************************************************
           Recursion
         **************************************************************************/
-        if (S_ISDIR(st.st_mode) && (cnid || nocniddb)) { /* If we have no cnid for it we cant recur */
+        if (S_ISDIR(st.st_mode) && cnid) { /* If we have no cnid for it we cant enter recursion */
             strcat(cwdbuf, "/");
             strcat(cwdbuf, name);
             dbd_log( LOGDEBUG, "Entering directory: %s", cwdbuf);
@@ -1000,7 +768,7 @@ static int dbd_readdir(int volroot, cnid_t did)
     /*
       Use results of previous checks
     */
-    if ((myvol->v_adouble == AD_VERSION_EA) && (dbd_flags & DBD_FLAGS_V2TOEA)) {
+    if ((vol->v_adouble == AD_VERSION_EA) && (dbd_flags & DBD_FLAGS_V2TOEA)) {
         if (rmdir(ADv2_DIRNAME) != 0) {
             switch (errno) {
             case ENOENT:
@@ -1015,246 +783,57 @@ static int dbd_readdir(int volroot, cnid_t did)
     return ret;
 }
 
-static int scanvol(struct vol *vol, dbd_flags_t flags)
+/*
+  Main func called from cmd_dbd.c
+*/
+int cmd_dbd_scanvol(struct vol *vol_in, dbd_flags_t flags)
 {
+    EC_INIT;
     struct stat st;
 
-    /* Make this stuff accessible from all funcs easily */
-    myvol = vol;
-    dbd_flags = flags;
-
     /* Run with umask 0 */
     umask(0);
 
-    strcpy(cwdbuf, myvol->v_path);
-    chdir(myvol->v_path);
+    /* Make vol accessible for all funcs */
+    vol = vol_in;
+    dbd_flags = flags;
 
-    if ((myvol->v_adouble == AD_VERSION_EA) && (dbd_flags & DBD_FLAGS_V2TOEA)) {
+    /* We only support unicode volumes ! */
+    if (vol->v_volcharset != CH_UTF8) {
+        dbd_log(LOGSTD, "Not a Unicode volume: %s, %u != %u", vol->v_volcodepage, vol->v_volcharset, CH_UTF8);
+        EC_FAIL;
+    }
+
+    /*
+     * Get CNID database stamp, cnid_getstamp() passes the buffer,
+     * then cnid_resolve() actually gets the value from the db
+     */
+    cnid_getstamp(vol->v_cdb, stamp, sizeof(stamp));
+
+    if (setjmp(jmp) != 0) {
+        EC_EXIT_STATUS(0); /* Got signal, jump from dbd_readdir */
+    }
+
+    strcpy(cwdbuf, vol->v_path);
+    chdir(vol->v_path);
+
+    if ((vol->v_adouble == AD_VERSION_EA) && (dbd_flags & DBD_FLAGS_V2TOEA)) {
         if (lstat(".", &st) != 0)
-            return -1;
+            EC_FAIL;
         if (ad_convert(".", &st, vol, NULL) != 0) {
             switch (errno) {
             case ENOENT:
                 break;
             default:
-                dbd_log(LOGSTD, "Conversion error for \"%s\": %s", myvol->v_path, strerror(errno));
+                dbd_log(LOGSTD, "Conversion error for \"%s\": %s", vol->v_path, strerror(errno));
                 break;
             }
         }
     }
 
     /* Start recursion */
-    if (dbd_readdir(1, htonl(2)) < 0)  /* 2 = volumeroot CNID */
-        return -1;
-
-    return 0;
-}
-
-/*
-  Remove all CNIDs from dbd that are not in dbd_rebuild
-*/
-static void delete_orphaned_cnids(DBD *dbd, DBD *dbd_rebuild, dbd_flags_t flags)
-{
-    int ret = 0, deleted = 0;
-    cnid_t dbd_cnid = 0, rebuild_cnid = 0;
-    struct cnid_dbd_rqst rqst;
-    struct cnid_dbd_rply rply;
-
-    /* jump over rootinfo key */
-    if ( dbif_idwalk(dbd, &dbd_cnid, 0) != 1)
-        return;
-    if ( dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0) != 1)
-        return;
-
-    /* Get first id from dbd_rebuild */
-    if ((dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0)) == -1)
-        return;
-
-    /* Start main loop through dbd: get CNID from dbd */
-    while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) {
-        /* Check if we got a termination signal */
-        if (alarmed)
-            longjmp(jmp, 1); /* this jumps back to cmd_dbd_scanvol() */
-
-        if (deleted > 1000) {
-            deleted = 0;
-            if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0) {
-                dbd_log(LOGSTD, "Error checkpointing!");
-                goto cleanup;
-            }
-        }
-
-        /* This should be the normal case: CNID is in both dbs */
-        if (dbd_cnid == rebuild_cnid) {
-            /* Get next CNID from rebuild db */
-            if ((ret = dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0)) == -1) {
-                /* Some error */
-                goto cleanup;
-            } else if (ret == 0) {
-                /* end of rebuild_cnid, delete all remaining CNIDs from dbd */
-                while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) {
-                    dbd_log(LOGSTD, "Orphaned CNID in database: %u", dbd_cnid);
-                    if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
-                        rqst.cnid = htonl(dbd_cnid);
-                        if ((ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID)) == -1) {
-                            dbd_log(LOGSTD, "Error deleting CNID %u", dbd_cnid);
-                            (void)dbif_txn_abort(dbd);
-                            goto cleanup;
-                        }
-                        
-                        if (dbif_txn_close(dbd, ret) != 0)
-                            return;
-                        deleted++;
-                    }
-                    /* Check if we got a termination signal */
-                    if (alarmed)
-                        longjmp(jmp, 1); /* this jumps back to cmd_dbd_scanvol() */
-                }
-                return;
-            } else
-                /* Normal case (ret=1): continue while loop */
-                continue;
-        }
-
-        if (dbd_cnid < rebuild_cnid) {
-            /* CNID is orphaned -> delete */
-            dbd_log(LOGSTD, "One orphaned CNID in database: %u.", dbd_cnid);
-            if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
-                rqst.cnid = htonl(dbd_cnid);
-                if ((ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID)) == -1) {
-                    dbd_log(LOGSTD, "Error deleting CNID %u", dbd_cnid);
-                    (void)dbif_txn_abort(dbd);
-                    goto cleanup;
-                }
-                if (dbif_txn_close(dbd, ret) != 0)
-                    return;
-                deleted++;
-            }
-            continue;
-        }
-
-        if (dbd_cnid > rebuild_cnid) {
-            dbif_idwalk(dbd, NULL, 1); /* Close cursor */
-            dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */
-            (void)dbif_txn_close(dbd, 2);
-            (void)dbif_txn_close(dbd_rebuild, 2);                
-            dbd_log(LOGSTD, "Ghost CNID: %u. This is fatal! Dumping rebuild db:\n", rebuild_cnid);
-            dbif_dump(dbd_rebuild, 0);
-            dbd_log(LOGSTD, "Send this dump and a `dbd -d ...` dump to the Netatalk Dev team!");
-            goto cleanup;
-        }
-    } /* while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) */
-
-cleanup:
-    dbif_idwalk(dbd, NULL, 1); /* Close cursor */
-    dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */
-    return;
-}
-
-static const char *get_tmpdb_path(void)
-{
-    pid_t pid = getpid();
-    static char path[MAXPATHLEN];
-    snprintf(path, MAXPATHLEN, "/tmp/tmpdb-dbd.%u", pid);
-    if (mkdir(path, 0755) != 0)
-        return NULL;
-    return path;
-}
-
-/*
-  Main func called from cmd_dbd.c
-*/
-int cmd_dbd_scanvol(DBD *dbd_ref, struct vol *vol, dbd_flags_t flags)
-{
-    int ret = 0;
-    struct db_param db_param = { 0 };
-    const char *tmpdb_path = NULL;
-
-    /* Set cachesize for in-memory rebuild db */
-    db_param.cachesize = 64 * 1024;         /* 64 MB */
-    db_param.maxlocks = DEFAULT_MAXLOCKS;
-    db_param.maxlockobjs = DEFAULT_MAXLOCKOBJS;
-    db_param.logfile_autoremove = 1;
-
-    /* Make it accessible for all funcs */
-    dbd = dbd_ref;
-
-    /* We only support unicode volumes ! */
-    if (vol->v_volcharset != CH_UTF8) {
-        dbd_log( LOGSTD, "Not a Unicode volume: %s, %u != %u", vol->v_volcodepage, vol->v_volcharset, CH_UTF8);
-        return -1;
-    }
-
-    /* Get volume stamp */
-    dbd_getstamp(dbd, &rqst, &rply);
-    if (rply.result != CNID_DBD_RES_OK) {
-        ret = -1;
-        goto exit;
-    }
-    memcpy(stamp, rply.name, CNID_DEV_LEN);
-
-    /* temporary rebuild db, used with -re rebuild to delete unused CNIDs, not used with -f */
-    if (! nocniddb && (flags & DBD_FLAGS_EXCL) && !(flags & DBD_FLAGS_FORCE)) {
-        tmpdb_path = get_tmpdb_path();
-        if (NULL == (dbd_rebuild = dbif_init(tmpdb_path, "cnid2.db"))) {
-            ret = -1;
-            goto exit;
-        }
-
-        if (dbif_env_open(dbd_rebuild,
-                          &db_param,
-                          DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN) < 0) {
-            dbd_log(LOGSTD, "error opening tmp database!");
-            goto exit;
-        }
+    EC_NEG1( dbd_readdir(1, htonl(2)) );  /* 2 = volumeroot CNID */
 
-        if (0 != (dbif_open(dbd_rebuild, NULL, 0))) {
-            ret = -1;
-            goto exit;
-        }
-
-        if (0 != (dbif_copy_rootinfokey(dbd, dbd_rebuild))) {
-            ret = -1;
-            goto exit;
-        }
-    }
-
-    if (setjmp(jmp) != 0) {
-        ret = 0;                /* Got signal, jump from dbd_readdir */
-        goto exit;
-    }
-
-    /* scanvol */
-    if ((scanvol(vol, flags)) != 0) {
-        ret = -1;
-        goto exit;
-    }
-
-exit:
-    if (! nocniddb) {
-        if (dbif_txn_close(dbd, ret == 0 ? 1 : 0) != 0)
-            ret = -1;
-        if (dbd_rebuild)
-            if (dbif_txn_close(dbd_rebuild, ret == 0 ? 1 : 0) != 0)
-                ret = -1;
-        if ((ret == 0) && dbd_rebuild && (flags & DBD_FLAGS_EXCL) && !(flags & DBD_FLAGS_FORCE))
-            /* We can only do this in exclusive mode, otherwise we might delete CNIDs added from
-               other clients in between our pass 1 and 2 */
-            delete_orphaned_cnids(dbd, dbd_rebuild, flags);
-    }
-
-    if (dbd_rebuild) {
-        dbd_log(LOGDEBUG, "Closing tmp db");
-        dbif_close(dbd_rebuild);
-
-        if (tmpdb_path) {
-            char cmd[8 + MAXPATHLEN];
-            snprintf(cmd, 8 + MAXPATHLEN, "rm -f %s/*", tmpdb_path);
-            dbd_log( LOGDEBUG, "Removing temp database '%s'", tmpdb_path);
-            system(cmd);
-            snprintf(cmd, 8 + MAXPATHLEN, "rmdir %s", tmpdb_path);
-            system(cmd);
-        }        
-    }
-    return ret;
+EC_CLEANUP:
+    EC_EXIT;
 }
index dcf7d5faaa78b89fb68f866a979d3f5c55d7b4af..18e063da638180339b4c5f9dec0fd75b8cf7a926 100644 (file)
@@ -92,6 +92,7 @@
 #include <atalk/compat.h>
 #include <atalk/errchk.h>
 #include <atalk/bstrlib.h>
+#include <atalk/bstradd.h>
 #include <atalk/netatalk_conf.h>
 #include <atalk/volume.h>
 
@@ -286,7 +287,6 @@ static int maybe_start_dbd(const AFPObj *obj, char *dbdpn, const char *volpath)
 static int set_dbdir(const char *dbdir, const char *vpath)
 {
     EC_INIT;
-    int status;
     struct stat st;
     bstring oldpath, newpath;
     char *cmd_argv[4];
@@ -301,7 +301,7 @@ static int set_dbdir(const char *dbdir, const char *vpath)
         EC_FAIL;
     }
 
-    if (lstat(bdata(oldpath), &st) == 0 && lstat(bdata(newpath), &st) != 0 && errno == ENOENT) {
+    if (lstat(cfrombstr(oldpath), &st) == 0 && lstat(cfrombstr(newpath), &st) != 0 && errno == ENOENT) {
         /* There's an .AppleDB in the volume root, we move it */
         cmd_argv[0] = "mv";
         cmd_argv[1] = bdata(oldpath);
@@ -315,7 +315,7 @@ static int set_dbdir(const char *dbdir, const char *vpath)
 
     }
 
-    if (lstat(bdata(newpath), &st) < 0 && mkdir(bdata(newpath), 0755 ) < 0) {
+    if (lstat(cfrombstr(newpath), &st) < 0 && mkdir(cfrombstr(newpath), 0755 ) < 0) {
         LOG(log_error, logtype_cnid, "set_dbdir: mkdir failed for %s", bdata(newpath));
         EC_FAIL;
     }
@@ -326,44 +326,6 @@ EC_CLEANUP:
     EC_EXIT;
 }
 
-/* ------------------ */
-static uid_t user_to_uid (char *username)
-{
-    struct passwd *this_passwd;
-
-    /* check for anything */
-    if ( !username || strlen ( username ) < 1 ) return 0;
-
-    /* grab the /etc/passwd record relating to username */
-    this_passwd = getpwnam ( username );
-
-    /* return false if there is no structure returned */
-    if (this_passwd == NULL) return 0;
-
-    /* return proper uid */
-    return this_passwd->pw_uid;
-
-}
-
-/* ------------------ */
-static gid_t group_to_gid ( char *group)
-{
-    struct group *this_group;
-
-    /* check for anything */
-    if ( !group || strlen ( group ) < 1 ) return 0;
-
-    /* grab the /etc/groups record relating to group */
-    this_group = getgrnam ( group );
-
-    /* return false if there is no structure returned */
-    if (this_group == NULL) return 0;
-
-    /* return proper gid */
-    return this_group->gr_gid;
-
-}
-
 /* ------------------ */
 static void catch_child(int sig _U_) 
 {
@@ -471,7 +433,6 @@ int main(int argc, char *argv[])
     int    cc;
     uid_t  uid = 0;
     gid_t  gid = 0;
-    int    err = 0;
     int    debug = 0;
     int    ret;
     sigset_t set;
@@ -502,13 +463,13 @@ int main(int argc, char *argv[])
     if (afp_config_parse(&obj, "cnid_metad") != 0)
         daemon_exit(1);
 
-    if (load_volumes(&obj, NULL) != 0)
+    if (load_volumes(&obj) != 0)
         daemon_exit(1);
 
     (void)setlimits();
 
     host = iniparser_getstrdup(obj.iniconfig, INISEC_GLOBAL, "cnid listen", "localhost:4700");
-    if (port = strrchr(host, ':'))
+    if ((port = strrchr(host, ':')))
         *port++ = 0;
     else
         port = DEFAULTPORT;
@@ -604,7 +565,7 @@ int main(int argc, char *argv[])
 
         LOG(log_debug, logtype_cnid, "main: request for volume: %s", volpath);
 
-        if (load_volumes(&obj, NULL) != 0) {
+        if (load_volumes(&obj) != 0) {
             LOG(log_severe, logtype_cnid, "main: error reloading config");
             goto loop_end;
         }
index c89f8e5cec00890c2d9b4a3e8410241cc7b684a7..3c8c102fc17cd39a16f9d09c89068b476833d9bd 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: db_param.c,v 1.9 2009-11-23 19:04:14 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * Copyright (c) Frank Lahm 2009
index bfa60954037c19bbfca7d998ab34d9725f50792a..7b8da1cadab6fceb87952aa06613ec8848e74437 100644 (file)
@@ -14,8 +14,8 @@
 extern int add_cnid(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply);
 extern int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply);
 
-extern int dbd_add(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *, int nolookup);
-extern int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *, int roflag);
+extern int dbd_add(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *);
+extern int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *);
 extern int dbd_get(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *);
 extern int dbd_resolve(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *);
 extern int dbd_update(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *);
index 36c0856867b5e4c703926f34c4ac6de405ba3d94..db9c6cc29d23f5c3ba023032e97cd7e325b8ea54 100644 (file)
@@ -74,7 +74,7 @@ int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply)
 {
     static cnid_t id;
     static char buf[ROOTINFO_DATALEN];
-    DBT rootinfo_key, rootinfo_data;
+    DBT rootinfo_key, rootinfo_data, key, data;
     int rc;
     cnid_t hint;
 
@@ -83,47 +83,63 @@ int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply)
     rootinfo_key.data = ROOTINFO_KEY;
     rootinfo_key.size = ROOTINFO_KEYLEN;
 
+    memset(&key, 0, sizeof(key));
+    memset(&data, 0, sizeof(data));
+
     if (id == 0) {
-        if ((rc = dbif_get(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0)) < 0) {
+        if ((rc = dbif_get(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0)) != 1) {
             rply->result = CNID_DBD_RES_ERR_DB;
             return -1;
         }
-        if (rc == 0) {
-            /* no rootinfo key yet */
-            memcpy(buf, ROOTINFO_DATA, ROOTINFO_DATALEN);
+        memcpy(buf, (char *)rootinfo_data.data, ROOTINFO_DATALEN);
+        memcpy(&hint, buf + CNID_TYPE_OFS, sizeof(hint));
+        id = ntohl(hint);
+        if (id < CNID_START - 1)
             id = CNID_START - 1;
-        } else {
-            memcpy(buf, (char *)rootinfo_data.data, ROOTINFO_DATALEN);
-            memcpy(&hint, buf + CNID_TYPE_OFS, sizeof(hint));
-            id = ntohl(hint);
-            if (id < CNID_START - 1)
-                id = CNID_START - 1;
-        }
     }
 
-    /* If we've hit the max CNID allowed, we return an error. CNID
-     * needs to be recycled before proceding. */
-    if (++id == CNID_INVALID) {
-        rply->result = CNID_DBD_RES_ERR_MAX;
-        return -1;
+    cnid_t trycnid, tmp;
+
+    while (true) {
+        if (rply->cnid != CNID_INVALID) {
+            trycnid = ntohl(rply->cnid);
+            rply->cnid = CNID_INVALID;
+        } else {
+            if (++id == CNID_INVALID)
+                id = CNID_START;
+            trycnid = id;
+        }
+        tmp = htonl(trycnid);
+        key.data = &tmp;
+        key.size = sizeof(cnid_t);
+        rc = dbif_get(dbd, DBIF_CNID, &key, &data, 0);
+        if (rc == 0) {
+            break;
+        } else if (rc == -1) {
+            rply->result = CNID_DBD_RES_ERR_DB;
+            return -1;
+        }
     }
 
-    rootinfo_data.data = buf;
-    rootinfo_data.size = ROOTINFO_DATALEN;
-    hint = htonl(id);
-    memcpy(buf + CNID_TYPE_OFS, &hint, sizeof(hint));
+    if (trycnid == id) {
+        rootinfo_data.data = buf;
+        rootinfo_data.size = ROOTINFO_DATALEN;
+        hint = htonl(id);
+        memcpy(buf + CNID_TYPE_OFS, &hint, sizeof(hint));
 
-    if (dbif_put(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0) < 0) {
-        rply->result = CNID_DBD_RES_ERR_DB;
-        return -1;
+        if (dbif_put(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0) < 0) {
+            rply->result = CNID_DBD_RES_ERR_DB;
+            return -1;
+        }
     }
-    rply->cnid = hint;
+
+    rply->cnid = htonl(trycnid);
     return 0;
 }
 
 /* ------------------------ */
 /* We need a nolookup version for `dbd` */
-int dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, int nolookup)
+int dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
 {
     rply->namelen = 0;
 
@@ -131,24 +147,25 @@ int dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, in
         ntohl(rqst->did), rqst->name, (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
 
     /* See if we have an entry already and return it if yes */
-    if (! nolookup) {
-        if (dbd_lookup(dbd, rqst, rply, 0) < 0) {
-            LOG(log_debug, logtype_cnid, "dbd_add(did:%u, '%s', dev/ino:0x%llx/0x%llx): error in dbd_lookup",
-                ntohl(rqst->did), rqst->name, (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
-            return -1;
-        }
+    if (dbd_lookup(dbd, rqst, rply) < 0) {
+        LOG(log_debug, logtype_cnid, "dbd_add(did:%u, '%s', dev/ino:0x%llx/0x%llx): error in dbd_lookup",
+            ntohl(rqst->did), rqst->name, (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
+        return -1;
+    }
 
-        if (rply->result == CNID_DBD_RES_OK) {
-            /* Found it. rply->cnid is the correct CNID now. */
-            LOG(log_debug, logtype_cnid, "dbd_add: dbd_lookup success --> CNID: %u", ntohl(rply->cnid));
-            return 1;
-        }
+    if (rply->result == CNID_DBD_RES_OK) {
+        /* Found it. rply->cnid is the correct CNID now. */
+        LOG(log_debug, logtype_cnid, "dbd_add: dbd_lookup success --> CNID: %u", ntohl(rply->cnid));
+        return 1;
     }
 
     LOG(log_debug, logtype_cnid, "dbd_add(did:%u, '%s', dev/ino:0x%llx/0x%llx): {adding to database ...}",
         ntohl(rqst->did), rqst->name, (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
 
-
+    if (rqst->cnid) {
+        /* rqst->cnid is the cnid "hint"/backup from the adouble file */
+        rply->cnid = rqst->cnid;
+    }
     if (get_cnid(dbd, rply) < 0) {
         if (rply->result == CNID_DBD_RES_ERR_MAX) {
             LOG(log_error, logtype_cnid, "dbd_add: FATAL: CNID database has reached its limit.");
index e621704f9339305aeac21c9e1e35555c65bdcb30..98ce2210644a1c9df415789f8d82d334cd6ed3d1 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dbd_dbcheck.c,v 1.4 2009-05-06 11:54:24 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYING.
index a4a3ca63e29a8c58aad3b15a1ace3e66a2793701..f34a9d500621ac9d967aab7200f111bc5d512bae 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dbd_delete.c,v 1.5 2009-07-12 09:21:34 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYING.
index 0ef71b19670c8c734ec34d3f825604559a41e682..c1c7bb8cc44f28e100f1540f2ff110f29ec7f872 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dbd_get.c,v 1.4 2009-05-06 11:54:24 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYING.
index 197a6db12087eb2f35e052ba5b0c29f30e34d398..ffba39721b620589d82b318baa3156070a7deeef 100644 (file)
@@ -1,6 +1,5 @@
 
 /*
- * $Id: dbd_getstamp.c,v 1.4 2009-05-06 11:54:24 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYING.
index 6169738b5f66e3230bb55fbb246eb38b08259d0f..f77b9fc2cb5f95a3abea20009fee1d980a7296ed 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dbd_lookup.c,v 1.18 2010-01-19 14:57:11 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * Copyright (C) Frank Lahm 2009
@@ -120,6 +119,7 @@ to be safe we must assign new CNIDs to both files.
 
 #include <atalk/logger.h>
 #include <atalk/cnid_dbd_private.h>
+#include <atalk/cnid.h>
 
 #include "pack.h"
 #include "dbif.h"
@@ -130,7 +130,7 @@ to be safe we must assign new CNIDs to both files.
  *  up the database if there's a problem.
  */
 
-int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, int roflag)
+int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
 {
     unsigned char *buf;
     DBT key, devdata, diddata;
@@ -211,16 +211,14 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply,
             LOG(log_debug, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): type mismatch for devino", 
                 rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
 
-            if (! roflag) {
-                rqst->cnid = id_devino;
-                rc = dbd_delete(dbd, rqst, rply, DBIF_CNID);
-                rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DEVINO);
-                rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DIDNAME);
-                if (rc < 0) {
-                    LOG(log_error, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): error deleting type mismatch for devino", 
-                        rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
-                    return -1;
-                }
+            rqst->cnid = id_devino;
+            rc = dbd_delete(dbd, rqst, rply, DBIF_CNID);
+            rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DEVINO);
+            rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DIDNAME);
+            if (rc < 0) {
+                LOG(log_error, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): error deleting type mismatch for devino", 
+                    rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
+                return -1;
             }
         }
 
@@ -230,16 +228,14 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply,
             LOG(log_debug, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): type mismatch for didname", 
                 rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
 
-            if (! roflag) {
-                rqst->cnid = id_didname;
-                rc = dbd_delete(dbd, rqst, rply, DBIF_CNID);
-                rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DEVINO);
-                rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DIDNAME);
-                if (rc < 0) {
-                    LOG(log_error, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): error deleting type mismatch for didname", 
-                        rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
-                    return -1;
-                }
+            rqst->cnid = id_didname;
+            rc = dbd_delete(dbd, rqst, rply, DBIF_CNID);
+            rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DEVINO);
+            rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DIDNAME);
+            if (rc < 0) {
+                LOG(log_error, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): error deleting type mismatch for didname", 
+                    rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
+                return -1;
             }
         }
 
@@ -262,15 +258,14 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply,
             ntohl(rqst->did), rqst->name, ntohl(id_didname),
             (unsigned long long)rqst->dev, (unsigned long long)rqst->ino, ntohl(id_devino));
 
-        if (! roflag) {
-            rqst->cnid = id_devino;
-            if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0)
-                return -1;
+        rqst->cnid = id_devino;
+        if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0)
+            return -1;
+
+        rqst->cnid = id_didname;
+        if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0)
+            return -1;
 
-            rqst->cnid = id_didname;
-            if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0)
-                return -1;
-        }
         rply->result = CNID_DBD_RES_NOTFOUND;
         return 1;
     }
@@ -282,12 +277,11 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply,
             LOG(log_debug, logtype_cnid, "dbd_lookup: server side mv (with resource fork)");
             update = 1;
         } else {
-            if ( ! roflag) {
-                rqst->cnid = id_devino;
-                if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0)
-                    return -1;
-            }
+            rqst->cnid = id_devino;
+            if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0)
+                return -1;
             rply->result = CNID_DBD_RES_NOTFOUND;
+            rqst->cnid = CNID_INVALID; /* invalidate CNID hint */
             return 1;
         }
     }
@@ -295,17 +289,16 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply,
     if ( ! devino) {
         LOG(log_debug, logtype_cnid, "dbd_lookup(DID:%u/'%s',0x%llx/0x%llx): CNID resolve problem: changed dev/ino",
             ntohl(rqst->did), rqst->name, (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
-        if ( ! roflag) {
-            rqst->cnid = id_didname;
-            if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0)
-                return -1;
-        }
+        rqst->cnid = id_didname;
+        if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0)
+            return -1;
         rply->result = CNID_DBD_RES_NOTFOUND;
+        rqst->cnid = CNID_INVALID; /* invalidate CNID hint */
         return 1;
     }
 
     /* This is also a catch all if we've forgot to catch some possibility with the preceding ifs*/
-    if (!update || roflag) {
+    if (!update) {
         rply->result = CNID_DBD_RES_NOTFOUND;
         return 1;
     }
index 562838b384a28dacc46873f8742a8296a6a2eba1..f1bf7aca30fb219b4a9cb68d63c41c163d0e2a19 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dbd_rebuild_add.c,v 1.4 2009-12-23 10:18:48 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2005
  * All Rights Reserved.  See COPYING.
index bb3561caba7a1018605be36649d85b13abb8ab29..53407757969b008256b7de3344250c53814f3d21 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dbd_resolve.c,v 1.4 2009-05-06 11:54:24 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYING.
index b21f259b860f40e12c71167d27c4695a9bc1bda9..3dae61cdad2f6ba5561f14708d4c37f39dc5f27c 100644 (file)
@@ -22,6 +22,7 @@
 #include <atalk/logger.h>
 #include <atalk/util.h>
 #include <atalk/errchk.h>
+#include <atalk/cnid.h>
 
 #include "db_param.h"
 #include "dbif.h"
@@ -88,13 +89,11 @@ EC_CLEANUP:
 static int dbif_init_rootinfo(DBD *dbd, int version)
 {
     DBT key, data;
-    uint32_t v;
+    uint32_t uint32;
     char buf[ROOTINFO_DATALEN];
 
     LOG(log_debug, logtype_cnid, "Setting CNID database version to %u", version);
 
-    v = version;
-    v = htonl(v);
 
     memset(&key, 0, sizeof(key));
     memset(&data, 0, sizeof(data));
@@ -104,7 +103,13 @@ static int dbif_init_rootinfo(DBD *dbd, int version)
     data.size = ROOTINFO_DATALEN;
 
     memcpy(buf, ROOTINFO_DATA, ROOTINFO_DATALEN);
-    memcpy(buf + CNID_DID_OFS, &v, sizeof(v));
+
+    uint32 = htonl(CNID_START - 1);
+    memcpy(buf + CNID_TYPE_OFS, &uint32, sizeof(uint32));
+
+    uint32 = htonl(version);
+    memcpy(buf + CNID_DID_OFS, &uint32, sizeof(uint32));
+
     if (dbif_stamp(dbd, buf + CNID_DEV_OFS, CNID_DEV_LEN) < 0)
         return -1;
 
@@ -326,97 +331,6 @@ exit:
     return ret;
 }
 
-/*!
- * Get lock on db lock file
- *
- * @args cmd       (r) lock command:
- *                     LOCK_FREE:   close lockfd
- *                     LOCK_UNLOCK: unlock lockm keep lockfd open
- *                     LOCK_EXCL:   F_WRLCK on lockfd
- *                     LOCK_SHRD:   F_RDLCK on lockfd
- * @args dbpath    (r) path to lockfile, only used on first call,
- *                     later the stored fd is used
- * @returns            LOCK_FREE/LOCK_UNLOCK return 0 on success, -1 on error
- *                     LOCK_EXCL/LOCK_SHRD return LOCK_EXCL or LOCK_SHRD respectively on
- *                     success, 0 if the lock couldn't be acquired, -1 on other errors
- */
-int get_lock(int cmd, const char *dbpath)
-{
-    static int lockfd = -1;
-    int ret;
-    char lockpath[PATH_MAX];
-    struct stat st;
-
-    LOG(log_debug, logtype_cnid, "get_lock(%s, \"%s\")",
-        cmd == LOCK_EXCL ? "LOCK_EXCL" :
-        cmd == LOCK_SHRD ? "LOCK_SHRD" :
-        cmd == LOCK_FREE ? "LOCK_FREE" :
-        cmd == LOCK_UNLOCK ? "LOCK_UNLOCK" : "UNKNOWN" , dbpath ? dbpath : "");
-
-    switch (cmd) {
-    case LOCK_FREE:
-        if (lockfd == -1)
-            return -1;
-        close(lockfd);
-        lockfd = -1;
-        return 0;
-
-    case LOCK_UNLOCK:
-        if (lockfd == -1)
-            return -1;
-        return unlock(lockfd, 0, SEEK_SET, 0);
-
-    case LOCK_EXCL:
-    case LOCK_SHRD:
-        if (lockfd == -1) {
-            if ( (strlen(dbpath) + strlen(LOCKFILENAME+1)) > (PATH_MAX - 1) ) {
-                LOG(log_error, logtype_cnid, ".AppleDB pathname too long");
-                return -1;
-            }
-            strncpy(lockpath, dbpath, PATH_MAX - 1);
-            strcat(lockpath, "/");
-            strcat(lockpath, LOCKFILENAME);
-
-            if ((lockfd = open(lockpath, O_RDWR | O_CREAT, 0644)) < 0) {
-                LOG(log_error, logtype_cnid, "Error opening lockfile: %s", strerror(errno));
-                return -1;
-            }
-
-            if ((stat(dbpath, &st)) != 0) {
-                LOG(log_error, logtype_cnid, "Error statting lockfile: %s", strerror(errno));
-                return -1;
-            }
-
-            if ((chown(lockpath, st.st_uid, st.st_gid)) != 0) {
-                LOG(log_error, logtype_cnid, "Error inheriting lockfile permissions: %s",
-                         strerror(errno));
-                return -1;
-            }
-        }
-    
-        if (cmd == LOCK_EXCL)
-            ret = write_lock(lockfd, 0, SEEK_SET, 0);
-        else
-            ret = read_lock(lockfd, 0, SEEK_SET, 0);
-
-        if (ret != 0) {
-            if (cmd == LOCK_SHRD)
-                LOG(log_error, logtype_cnid, "Volume CNID db is locked, try again...");
-            return 0; 
-        }
-
-        LOG(log_debug, logtype_cnid, "get_lock: got %s lock",
-            cmd == LOCK_EXCL ? "LOCK_EXCL" : "LOCK_SHRD");    
-        return cmd;
-
-    default:
-        return -1;
-    } /* switch(cmd) */
-
-    /* deadc0de, never get here */
-    return -1;
-}
-
 /* --------------- */
 DBD *dbif_init(const char *envhome, const char *filename)
 {
@@ -813,11 +727,6 @@ int dbif_env_remove(const char *path)
 
     LOG(log_debug, logtype_cnid, "Trying to remove BerkeleyDB environment");
 
-    if (get_lock(LOCK_EXCL, path) != LOCK_EXCL) {
-        LOG(log_debug, logtype_cnid, "CNID db \"%s\" in use, not removing BerkeleyDB environment", path);
-        return 0;
-    }
-    
     if (NULL == (dbd = dbif_init(path, "cnid2.db")))
         return -1;
 
index 8c71de36b96221f598f64f4943b0878e7906f444..a6c88a98068ad30f9535e03d6cb694c12e17e7dd 100644 (file)
@@ -64,7 +64,6 @@
 #define DBIF_IDX_DIDNAME   2
 #define DBIF_IDX_NAME      3
 
-/* get_lock cmd and return value */
 #define LOCKFILENAME  "lock"
 #define LOCK_FREE          0
 #define LOCK_UNLOCK        1
@@ -91,9 +90,6 @@ typedef struct {
     db_table db_table[DBIF_DB_CNT];
 } DBD;
 
-/* Functions */
-extern int get_lock(int cmd, const char *dbpath);
-
 extern DBD *dbif_init(const char *envhome, const char *dbname);
 extern int dbif_env_open(DBD *dbd, struct db_param *dbp, uint32_t dbenv_oflags);
 extern int dbif_open(DBD *dbd, struct db_param *dbp, int reindex);
index 8ed0e5ff2bcd37796511c3094689ce3b7dfb6da8..767e1e3c95dea4214aa8afbb81ca414b30e9ef5f 100644 (file)
@@ -26,7 +26,9 @@
 #include <atalk/logger.h>
 #include <atalk/errchk.h>
 #include <atalk/bstrlib.h>
+#include <atalk/bstradd.h>
 #include <atalk/netatalk_conf.h>
+#include <atalk/util.h>
 
 #include "db_param.h"
 #include "dbif.h"
@@ -43,6 +45,9 @@
 static DBD *dbd;
 static int exit_sig = 0;
 static int db_locked;
+static bstring dbpath;
+static struct db_param *dbp;
+static struct vol *vol;
 
 static void sig_exit(int signo)
 {
@@ -77,9 +82,203 @@ static void block_sigs_onoff(int block)
   of the cnid_dbd_rply structure contains further details.
 
 */
-#ifndef min
-#define min(a,b)        ((a)<(b)?(a):(b))
-#endif
+
+/*!
+ * Get lock on db lock file
+ *
+ * @args cmd       (r) lock command:
+ *                     LOCK_FREE:   close lockfd
+ *                     LOCK_UNLOCK: unlock lockm keep lockfd open
+ *                     LOCK_EXCL:   F_WRLCK on lockfd
+ *                     LOCK_SHRD:   F_RDLCK on lockfd
+ * @args dbpath    (r) path to lockfile, only used on first call,
+ *                     later the stored fd is used
+ * @returns            LOCK_FREE/LOCK_UNLOCK return 0 on success, -1 on error
+ *                     LOCK_EXCL/LOCK_SHRD return LOCK_EXCL or LOCK_SHRD respectively on
+ *                     success, 0 if the lock couldn't be acquired, -1 on other errors
+ */
+static int get_lock(int cmd, const char *dbpath)
+{
+    static int lockfd = -1;
+    int ret;
+    char lockpath[PATH_MAX];
+    struct stat st;
+
+    LOG(log_debug, logtype_cnid, "get_lock(%s, \"%s\")",
+        cmd == LOCK_EXCL ? "LOCK_EXCL" :
+        cmd == LOCK_SHRD ? "LOCK_SHRD" :
+        cmd == LOCK_FREE ? "LOCK_FREE" :
+        cmd == LOCK_UNLOCK ? "LOCK_UNLOCK" : "UNKNOWN",
+        dbpath ? dbpath : "");
+
+    switch (cmd) {
+    case LOCK_FREE:
+        if (lockfd == -1)
+            return -1;
+        close(lockfd);
+        lockfd = -1;
+        return 0;
+
+    case LOCK_UNLOCK:
+        if (lockfd == -1)
+            return -1;
+        return unlock(lockfd, 0, SEEK_SET, 0);
+
+    case LOCK_EXCL:
+    case LOCK_SHRD:
+        if (lockfd == -1) {
+            if ( (strlen(dbpath) + strlen(LOCKFILENAME+1)) > (PATH_MAX - 1) ) {
+                LOG(log_error, logtype_cnid, ".AppleDB pathname too long");
+                return -1;
+            }
+            strncpy(lockpath, dbpath, PATH_MAX - 1);
+            strcat(lockpath, "/");
+            strcat(lockpath, LOCKFILENAME);
+
+            if ((lockfd = open(lockpath, O_RDWR | O_CREAT, 0644)) < 0) {
+                LOG(log_error, logtype_cnid, "Error opening lockfile: %s", strerror(errno));
+                return -1;
+            }
+
+            if ((stat(dbpath, &st)) != 0) {
+                LOG(log_error, logtype_cnid, "Error statting lockfile: %s", strerror(errno));
+                return -1;
+            }
+
+            if ((chown(lockpath, st.st_uid, st.st_gid)) != 0) {
+                LOG(log_error, logtype_cnid, "Error inheriting lockfile permissions: %s",
+                         strerror(errno));
+                return -1;
+            }
+        }
+    
+        if (cmd == LOCK_EXCL)
+            ret = write_lock(lockfd, 0, SEEK_SET, 0);
+        else
+            ret = read_lock(lockfd, 0, SEEK_SET, 0);
+
+        if (ret != 0) {
+            if (cmd == LOCK_SHRD)
+                LOG(log_error, logtype_cnid, "Volume CNID db is locked, try again...");
+            return 0; 
+        }
+
+        LOG(log_debug, logtype_cnid, "get_lock: got %s lock",
+            cmd == LOCK_EXCL ? "LOCK_EXCL" : "LOCK_SHRD");    
+        return cmd;
+
+    default:
+        return -1;
+    } /* switch(cmd) */
+
+    /* deadc0de, never get here */
+    return -1;
+}
+
+static int open_db(void)
+{
+    EC_INIT;
+
+    /* Get db lock */
+    if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) {
+        LOG(log_error, logtype_cnid, "main: fatal db lock error");
+        EC_FAIL;
+    }
+
+    if (NULL == (dbd = dbif_init(bdata(dbpath), "cnid2.db")))
+        EC_FAIL;
+
+    /* Only recover if we got the lock */
+    if (dbif_env_open(dbd, dbp, DBOPTIONS | DB_RECOVER) < 0)
+        EC_FAIL;
+
+    LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment");
+
+    if (dbif_open(dbd, dbp, 0) < 0)
+        EC_FAIL;
+
+    LOG(log_debug, logtype_cnid, "Finished opening BerkeleyDB databases");
+
+EC_CLEANUP:
+    if (ret != 0) {
+        if (dbd) {
+            (void)dbif_close(dbd);
+            dbd = NULL;
+        }
+    }
+
+    EC_EXIT;
+}
+
+static int delete_db(void)
+{
+    EC_INIT;
+    int cwd = -1;
+
+    EC_ZERO( get_lock(LOCK_FREE, bdata(dbpath)) );
+    EC_NEG1( cwd = open(".", O_RDONLY) );
+    chdir(cfrombstr(dbpath));
+    system("rm -f cnid2.db lock log.* __db.*");
+
+    if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) {
+        LOG(log_error, logtype_cnid, "main: fatal db lock error");
+        EC_FAIL;
+    }
+
+    LOG(log_warning, logtype_cnid, "Recreated CNID BerkeleyDB databases of volume \"%s\"", vol->v_localname);
+
+EC_CLEANUP:
+    if (cwd != -1)
+        fchdir(cwd);
+    EC_EXIT;
+}
+
+
+/**
+ * Close dbd if open, delete it, reopen
+ *
+ * Also tries to copy the rootinfo key, that would allow for keeping the db stamp
+ * and last used CNID
+ **/
+static int reinit_db(void)
+{
+    EC_INIT;
+    DBT key, data;
+    bool copyRootInfo = false;
+
+    if (dbd) {
+        memset(&key, 0, sizeof(key));
+        memset(&data, 0, sizeof(data));
+
+        key.data = ROOTINFO_KEY;
+        key.size = ROOTINFO_KEYLEN;
+
+        if (dbif_get(dbd, DBIF_CNID, &key, &data, 0) <= 0) {
+            LOG(log_error, logtype_cnid, "dbif_copy_rootinfokey: Error getting rootinfo record");
+            copyRootInfo = false;
+        } else {
+            copyRootInfo = true;
+        }
+        (void)dbif_close(dbd);
+    }
+
+    EC_ZERO_LOG( delete_db() );
+    EC_ZERO_LOG( open_db() );
+
+    if (copyRootInfo == true) {
+        memset(&key, 0, sizeof(key));
+        key.data = ROOTINFO_KEY;
+        key.size = ROOTINFO_KEYLEN;
+
+        if (dbif_put(dbd, DBIF_CNID, &key, &data, 0) != 0) {
+            LOG(log_error, logtype_cnid, "dbif_copy_rootinfokey: Error writing rootinfo key");
+            EC_FAIL;
+        }
+    }
+
+EC_CLEANUP:
+    EC_EXIT;
+}
 
 static int loop(struct db_param *dbp)
 {
@@ -110,7 +309,7 @@ static int loop(struct db_param *dbp)
         dbp->flush_interval, timebuf);
 
     while (1) {
-        timeout = min(time_next_flush, time_last_rqst +dbp->idle_timeout);
+        timeout = MIN(time_next_flush, time_last_rqst + dbp->idle_timeout);
         if (timeout > now)
             timeout -= now;
         else
@@ -145,7 +344,7 @@ static int loop(struct db_param *dbp)
                 ret = 1;
                 break;
             case CNID_DBD_OP_ADD:
-                ret = dbd_add(dbd, &rqst, &rply, 0);
+                ret = dbd_add(dbd, &rqst, &rply);
                 break;
             case CNID_DBD_OP_GET:
                 ret = dbd_get(dbd, &rqst, &rply);
@@ -154,7 +353,7 @@ static int loop(struct db_param *dbp)
                 ret = dbd_resolve(dbd, &rqst, &rply);
                 break;
             case CNID_DBD_OP_LOOKUP:
-                ret = dbd_lookup(dbd, &rqst, &rply, 0);
+                ret = dbd_lookup(dbd, &rqst, &rply);
                 break;
             case CNID_DBD_OP_UPDATE:
                 ret = dbd_update(dbd, &rqst, &rply);
@@ -171,6 +370,9 @@ static int loop(struct db_param *dbp)
             case CNID_DBD_OP_SEARCH:
                 ret = dbd_search(dbd, &rqst, &rply);
                 break;
+            case CNID_DBD_OP_WIPE:
+                ret = reinit_db();
+                break;
             default:
                 LOG(log_error, logtype_cnid, "loop: unknown op %d", rqst.op);
                 ret = -1;
@@ -274,18 +476,15 @@ static void set_signal(void)
 int main(int argc, char *argv[])
 {
     EC_INIT;
-    struct db_param *dbp;
     int delete_bdb = 0;
     int ctrlfd = -1, clntfd = -1;
-    char *logconfig;
     AFPObj obj = { 0 };
-    struct vol *vol;
     char *volpath = NULL;
-    bstring dbpath;
 
     while (( ret = getopt( argc, argv, "dF:l:p:t:vV")) != -1 ) {
         switch (ret) {
         case 'd':
+            /* this is now just ignored, as we do it automatically anyway */
             delete_bdb = 1;
             break;
         case 'F':
@@ -314,7 +513,7 @@ int main(int argc, char *argv[])
 
     EC_ZERO( afp_config_parse(&obj, "cnid_dbd") );
 
-    EC_ZERO( load_volumes(&obj, NULL) );
+    EC_ZERO( load_volumes(&obj) );
     EC_NULL( vol = getvolbypath(&obj, volpath) );
     EC_ZERO( load_charset(vol) );
     pack_setvol(vol);
@@ -326,29 +525,6 @@ int main(int argc, char *argv[])
 
     switch_to_user(bdata(dbpath));
 
-    /* Get db lock */
-    if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) == -1) {
-        LOG(log_error, logtype_cnid, "main: fatal db lock error");
-        EC_FAIL;
-    }
-    if (db_locked != LOCK_EXCL) {
-        /* Couldn't get exclusive lock, try shared lock  */
-        if ((db_locked = get_lock(LOCK_SHRD, NULL)) != LOCK_SHRD) {
-            LOG(log_error, logtype_cnid, "main: fatal db lock error");
-            EC_FAIL;
-        }
-    }
-
-    if (delete_bdb && (db_locked == LOCK_EXCL)) {
-        LOG(log_warning, logtype_cnid, "main: too many CNID db opening attempts, wiping the slate clean");
-        chdir(bdata(dbpath));
-        system("rm -f cnid2.db lock log.* __db.*");
-        if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) {
-            LOG(log_error, logtype_cnid, "main: fatal db lock error");
-            EC_FAIL;
-        }
-    }
-
     set_signal();
 
     /* SIGINT and SIGTERM are always off, unless we are in pselect */
@@ -358,37 +534,11 @@ int main(int argc, char *argv[])
         EC_FAIL;
     LOG(log_maxdebug, logtype_cnid, "Finished parsing db_param config file");
 
-    if (NULL == (dbd = dbif_init(bdata(dbpath), "cnid2.db")))
-        EC_FAIL;
-
-    /* Only recover if we got the lock */
-    if (dbif_env_open(dbd,
-                      dbp,
-                      (db_locked == LOCK_EXCL) ? DBOPTIONS | DB_RECOVER : DBOPTIONS) < 0)
-        EC_FAIL;
-    LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment");
-
-    if (dbif_open(dbd, dbp, 0) < 0) {
-        ret = -1;
-        goto close_db;
-    }
-
-    LOG(log_debug, logtype_cnid, "Finished opening BerkeleyDB databases");
-
-    /* Downgrade db lock  */
-    if (db_locked == LOCK_EXCL) {
-        if (get_lock(LOCK_UNLOCK, NULL) != 0) {
-            ret = -1;
-            goto close_db;
-        }
-
-        if (get_lock(LOCK_SHRD, NULL) != LOCK_SHRD) {
-            ret = -1;
-            goto close_db;
-        }
+    if (open_db() != 0) {
+        LOG(log_error, logtype_cnid, "Failed to open CNID database for volume \"%s\"", vol->v_localname);
+        EC_ZERO_LOG( reinit_db() );
     }
 
-
     if (comm_init(dbp, ctrlfd, clntfd) < 0) {
         ret = -1;
         goto close_db;
index ee4d4327a77100bc247b7b28f7848266542c3338..27bde63c31b6a6d665d87f264c85de059b53a96d 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: usockfd.h,v 1.5 2009-11-05 14:38:07 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYING.
index b35d264c81819787dbd2197d7f5de21bb640926a..9ac72c5ad5d4cc8ebc5530f3f090d1305fd24c11 100644 (file)
@@ -1,8 +1,16 @@
-/*
- * Copyright (c) 1990,1993 Regents of The University of Michigan.
- * All Rights Reserved.  See COPYRIGHT.
- */
-
+/* 
+   Copyright (c) 2012 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
+   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.
+*/
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
@@ -44,7 +52,6 @@ static void kill_childs(int sig, ...);
 
 /* static variables */
 static AFPObj obj;
-static sig_atomic_t got_chldsig;
 static pid_t afpd_pid = -1,  cnid_metad_pid = -1;
 static uint afpd_restarts, cnid_metad_restarts;
 static struct event_base *base;
@@ -116,10 +123,17 @@ static void sigquit_cb(evutil_socket_t fd, short what, void *arg)
     kill_childs(SIGQUIT, &afpd_pid, &cnid_metad_pid, NULL);
 }
 
+/* SIGQUIT callback */
+static void sighup_cb(evutil_socket_t fd, short what, void *arg)
+{
+    LOG(log_note, logtype_afpd, "Received SIGHUP, sending all processes signal to reload config");
+    kill_childs(SIGHUP, &afpd_pid, &cnid_metad_pid, NULL);
+}
+
 /* SIGCHLD callback */
 static void sigchld_cb(evutil_socket_t fd, short what, void *arg)
 {
-    int status, i;
+    int status;
     pid_t pid;
 
     LOG(log_debug, logtype_afpd, "Got SIGCHLD event");
@@ -139,7 +153,7 @@ static void sigchld_cb(evutil_socket_t fd, short what, void *arg)
 
         if (pid == afpd_pid)
             afpd_pid = -1;
-        else if (pid = cnid_metad_pid)
+        else if (pid == cnid_metad_pid)
             cnid_metad_pid = -1;
         else
             LOG(log_error, logtype_afpd, "Bad pid: %d", pid);
@@ -152,8 +166,6 @@ static void sigchld_cb(evutil_socket_t fd, short what, void *arg)
 /* timer callback */
 static void timer_cb(evutil_socket_t fd, short what, void *arg)
 {
-    static int i = 0;
-
     if (in_shutdown)
         return;
 
@@ -237,7 +249,6 @@ static void usage(void)
 
 int main(int argc, char **argv)
 {
-    const char *configfile = NULL;
     int c, ret, debug = 0;
     sigset_t blocksigs;
     struct timeval tv;
@@ -296,6 +307,7 @@ int main(int argc, char **argv)
 
     sigterm_ev = event_new(base, SIGTERM, EV_SIGNAL, sigterm_cb, NULL);
     sigquit_ev = event_new(base, SIGQUIT, EV_SIGNAL | EV_PERSIST, sigquit_cb, NULL);
+    sigquit_ev = event_new(base, SIGHUP,  EV_SIGNAL | EV_PERSIST, sighup_cb, NULL);
     sigchld_ev = event_new(base, SIGCHLD, EV_SIGNAL | EV_PERSIST, sigchld_cb, NULL);
     timer_ev = event_new(base, -1, EV_PERSIST, timer_cb, NULL);
 
@@ -311,6 +323,7 @@ int main(int argc, char **argv)
     sigdelset(&blocksigs, SIGTERM);
     sigdelset(&blocksigs, SIGQUIT);
     sigdelset(&blocksigs, SIGCHLD);
+    sigdelset(&blocksigs, SIGHUP);
     sigprocmask(SIG_SETMASK, &blocksigs, NULL);
 
     /* run the event loop */
index d033d96b12c76e322a8fd143b90e283ff8847738..76e9143f6a97bd20e6cab84f8027cff6e44a64ce 100644 (file)
@@ -136,7 +136,11 @@ error:
  * echo off means password.
  */
 static int PAM_conv (int num_msg,
+#ifdef LINUX
                      const struct pam_message **msg,
+#else
+                     struct pam_message **msg,
+#endif
                      struct pam_response **resp,
                      void *appdata_ptr _U_) {
     int count = 0;
@@ -927,9 +931,6 @@ static int uam_setup(const char *path)
     if (uam_register(UAM_SERVER_CHANGEPW, path, "DHX2", dhx2_changepw) < 0)
         return -1;
 
-    p = gcry_mpi_new(0);
-    g = gcry_mpi_new(0);
-
     LOG(log_debug, logtype_uams, "DHX2: generating mersenne primes");
     /* Generate p and g for DH */
     if (dh_params_generate(PRIMEBITS) != 0) {
@@ -945,6 +946,8 @@ static void uam_cleanup(void)
     uam_unregister(UAM_SERVER_LOGIN, "DHX2");
     uam_unregister(UAM_SERVER_CHANGEPW, "DHX2");
 
+    LOG(log_debug, logtype_uams, "DHX2: uam_cleanup");
+
     gcry_mpi_release(p);
     gcry_mpi_release(g);
 }
index c4a322ad48220ca899783ce5d0a83c17b4a4650c..a2737d0f920f90b746df9efc8c0495409a7cba7e 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: uams_dhx2_passwd.c,v 1.8 2010-03-30 10:25:49 franklahm Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
index 4c7d87c0cbf03fc4e592134ea52046ba382b994b..bc19c7851b294f7eb151f1a384db4c23e23465e5 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: uams_dhx_pam.c,v 1.33 2010-03-30 10:25:49 franklahm Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) 
@@ -80,7 +79,11 @@ static char *PAM_password;
  * echo off means password.
  */
 static int PAM_conv (int num_msg,
+#ifdef LINUX
                      const struct pam_message **msg,
+#else
+                     struct pam_message **msg,
+#endif
                      struct pam_response **resp,
                      void *appdata_ptr _U_) {
   int count = 0;
@@ -193,7 +196,7 @@ static int dhx_setup(void *obj, char *ibuf, size_t ibuflen _U_,
     DH *dh;
 
     /* get the client's public key */
-    if (!(bn = BN_bin2bn(ibuf, KEYSIZE, NULL))) {
+    if (!(bn = BN_bin2bn((unsigned char *)ibuf, KEYSIZE, NULL))) {
     /* Log Entry */
            LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM No Public Key -- %s",
                  strerror(errno));
@@ -255,10 +258,10 @@ static int dhx_setup(void *obj, char *ibuf, size_t ibuflen _U_,
     }
 
     /* figure out the key. store the key in rbuf for now. */
-    i = DH_compute_key(rbuf, bn, dh);
+    i = DH_compute_key((unsigned char *)rbuf, bn, dh);
     
     /* set the key */
-    CAST_set_key(&castkey, i, rbuf);
+    CAST_set_key(&castkey, i, (unsigned char *)rbuf);
     
     /* session id. it's just a hashed version of the object pointer. */
     sessid = dhxhash(obj);
@@ -267,7 +270,7 @@ static int dhx_setup(void *obj, char *ibuf, size_t ibuflen _U_,
     *rbuflen += sizeof(sessid);
     
     /* public key */
-    BN_bn2bin(dh->pub_key, rbuf); 
+    BN_bn2bin(dh->pub_key, (unsigned char *)rbuf); 
     rbuf += KEYSIZE;
     *rbuflen += KEYSIZE;
 
@@ -301,7 +304,7 @@ static int dhx_setup(void *obj, char *ibuf, size_t ibuflen _U_,
 #endif /* 0 */
 
     /* encrypt using cast */
-    CAST_cbc_encrypt(rbuf, rbuf, CRYPTBUFLEN, &castkey, msg2_iv, 
+    CAST_cbc_encrypt((unsigned char *)rbuf, (unsigned char *)rbuf, CRYPTBUFLEN, &castkey, msg2_iv, 
                     CAST_ENCRYPT);
     *rbuflen += CRYPTBUFLEN;
     BN_free(bn);
@@ -436,13 +439,13 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd,
        hostname = NULL;
        }
 
-    CAST_cbc_encrypt(ibuf, rbuf, CRYPT2BUFLEN, &castkey,
+    CAST_cbc_encrypt((unsigned char *)ibuf, (unsigned char *)rbuf, CRYPT2BUFLEN, &castkey,
                     msg3_iv, CAST_DECRYPT);
     memset(&castkey, 0, sizeof(castkey));
 
     /* check to make sure that the random number is the same. we
      * get sent back an incremented random number. */
-    if (!(bn1 = BN_bin2bn(rbuf, KEYSIZE, NULL)))
+    if (!(bn1 = BN_bin2bn((unsigned char *)rbuf, KEYSIZE, NULL)))
       return AFPERR_PARAM;
 
     if (!(bn2 = BN_bin2bn(randbuf, sizeof(randbuf), NULL))) {
@@ -613,13 +616,13 @@ static int pam_changepw(void *obj, char *username,
     }
 
     /* grab the client's nonce, old password, and new password. */
-    CAST_cbc_encrypt(ibuf, ibuf, CHANGEPWBUFLEN, &castkey,
+    CAST_cbc_encrypt((unsigned char *)ibuf, (unsigned char *)ibuf, CHANGEPWBUFLEN, &castkey,
                     msg3_iv, CAST_DECRYPT);
     memset(&castkey, 0, sizeof(castkey));
 
     /* check to make sure that the random number is the same. we
      * get sent back an incremented random number. */
-    if (!(bn1 = BN_bin2bn(ibuf, KEYSIZE, NULL))) {
+    if (!(bn1 = BN_bin2bn((unsigned char *)ibuf, KEYSIZE, NULL))) {
     /* Log Entry */
            LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Random Number Not the same or not incremented-- %s",
                  strerror(errno));
index f8cfc1af1434c0ad7384456e9340fe5fdd38d379..29ea36c04842ebf85c8aeb87195ad407eb54b952 100644 (file)
@@ -318,8 +318,6 @@ static int do_gss_auth(void *obj,
 
 cleanup_client_name:
     gss_release_name(&status, &client_name);
-
-cleanup_context:
     gss_release_buffer(&status, &authenticator_buff);
     gss_delete_sec_context(&status, &context, NULL);
 
index 00f90ece0972ee01670d5cc1eee55879d6795b35..82ee43ef5d552dc3fe7fc78441942c125a368bd0 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: uams_guest.c,v 1.18 2009-11-08 01:07:17 didg Exp $
  *
  * (c) 2001 (see COPYING)
  */
index 6f15ac0a30c660bbdec3939e66b0059e06643f5f..b490c2ee20aaf81cd5d5f61888a49a03680e4cc2 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: uams_pam.c,v 1.24 2010-03-30 10:25:49 franklahm Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) 
@@ -54,7 +53,11 @@ extern UAM_MODULE_EXPORT void append(struct papfile *, const char *, int);
  * echo off means password.
  */
 static int PAM_conv (int num_msg,
+#ifdef LINUX
                      const struct pam_message **msg,
+#else
+                     struct pam_message **msg,
+#endif
                      struct pam_response **resp,
                      void *appdata_ptr _U_) 
 {
index 9b9c1d801dd57d53c543d8cdc1e11fb555f18f05..6a2994401c493d5cadd33a5f86161904d17f644c 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: uams_pgp.c,v 1.12 2009-10-15 11:39:48 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) 
index 301fdd0ff4cb69d48fe7e1f81d7572a954c7dfea..22687fcc8921cf74304f23791390580c326b8b2e 100644 (file)
@@ -1,5 +1,4 @@
 /* 
- * $Id: uams_randnum.c,v 1.21 2010-03-30 10:25:49 franklahm Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) 
index 95aa0753401bb3385013192c3ea620a1fdd327b1..d30a25c1d72168123f40ed4e92963c97a2acded0 100644 (file)
@@ -21,6 +21,8 @@
 
 #ifdef HAVE_ACLS
 
+#define O_NETATALK_ACL (O_NOFOLLOW << 1)
+
 #ifdef HAVE_SOLARIS_ACLS
 #include <sys/acl.h>
 
@@ -51,6 +53,7 @@ extern int remove_acl_vfs(const char *name);
 
 #else /* HAVE_ACLS=no */
 
+#define O_NETATALK_ACL 0
 #define chmod_acl chmod
 
 #endif /* HAVE_ACLS */
index 384486ea4633d8c14085af8fb998e7853e789e3f..6e76e51b842fba92ceb35b224893a6b67e5277b8 100644 (file)
@@ -247,6 +247,7 @@ struct adouble {
 #define ADVOL_NODEV      (1 << 0)
 #define ADVOL_UNIXPRIV   (1 << 2) /* adouble unix priv */
 #define ADVOL_INVDOTS    (1 << 3) /* dot files (.DS_Store) are invisible) */
+#define ADVOL_FOLLO_SYML (1 << 4)
 
 /* lock flags */
 #define ADLOCK_CLR      (0)
@@ -369,6 +370,8 @@ struct adouble {
 #define ad_ref(ad)   (ad)->ad_refcount++
 #define ad_unref(ad) --((ad)->ad_refcount)
 
+#define ad_get_syml_opt(ad) (((ad)->ad_options & ADVOL_FOLLO_SYML) ? 0 : O_NOFOLLOW)
+
 /* ad_flush.c */
 extern int ad_rebuild_adouble_header_v2(struct adouble *);
 extern int ad_rebuild_adouble_header_ea(struct adouble *);
index 2d3aa062b8b601c4ac016e4aa59d5d672e8e05c6..ba0b62fad3d0d1e4149d5aeae63565e1b748e3f8 100644 (file)
@@ -69,6 +69,7 @@ struct _cnid_db {
                                 const char *, size_t, cnid_t);
     int    (*cnid_find)        (struct _cnid_db *cdb, const char *name, size_t namelen,
                                 void *buffer, size_t buflen);
+    int    (*cnid_wipe)        (struct _cnid_db *cdb);
 };
 typedef struct _cnid_db cnid_db;
 
@@ -123,6 +124,7 @@ cnid_t cnid_rebuild_add(struct _cnid_db *cdb, const struct stat *st, const cnid_
                         char *name, const size_t len, cnid_t hint);
 int    cnid_find       (struct _cnid_db *cdb, const char *name, size_t namelen,
                         void *buffer, size_t buflen);
+int    cnid_wipe       (struct _cnid_db *cdb);
 void   cnid_close      (struct _cnid_db *db);
 
 #endif
index d7484e42088d7c69ab71326f96d71c1d093bea86..b61f7a8ce6e3d1d65275c4c01537ac967c6a3894 100644 (file)
@@ -25,6 +25,7 @@
 #define CNID_DBD_OP_GETSTAMP    0x0b
 #define CNID_DBD_OP_REBUILD_ADD 0x0c
 #define CNID_DBD_OP_SEARCH      0x0d
+#define CNID_DBD_OP_WIPE        0x0e
 
 #define CNID_DBD_RES_OK            0x00
 #define CNID_DBD_RES_NOTFOUND      0x01
index 7a910524699446d41745e4b5b6fb52aa0503e723..b28d736e09855bed7cfee85c8d1d464bb8434c97 100644 (file)
@@ -4,7 +4,6 @@
    @file    dictionary.h
    @author  N. Devillard
    @date    Sep 2007
-   @version $Revision: 1.12 $
    @brief   Implements a dictionary for string variables.
 
    This module implements a simple dictionary object, i.e. a list
 /*--------------------------------------------------------------------------*/
 
 /*
-       $Id: dictionary.h,v 1.12 2007-11-23 21:37:00 ndevilla Exp $
        $Author: ndevilla $
        $Date: 2007-11-23 21:37:00 $
-       $Revision: 1.12 $
 */
 
 #ifndef _DICTIONARY_H_
index 0e776c31cca07667a43926f5ad96d493163a25ba..00c80d423e80c1f345bbfca261ecdfe9b0a6d725 100644 (file)
@@ -162,6 +162,7 @@ typedef struct DSI {
 extern DSI *dsi_init(AFPObj *obj, const char *hostname, const char *address, const char *port);
 extern void dsi_setstatus (DSI *, char *, const size_t);
 extern int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address, const char *port);
+extern void dsi_free(DSI *dsi);
 
 /* in dsi_getsess.c */
 extern int dsi_getsession (DSI *, server_child *, const int, afp_child_t **);
index 094065b9d5a7d6a799680eba3f2eac91c197e65a..ccc66eb6f4ac1a9ae7ff52a57c3291d219e3ed02 100644 (file)
@@ -17,6 +17,7 @@
 
 #define EC_INIT int ret = 0
 #define EC_STATUS(a) ret = (a)
+#define EC_EXIT_STATUS(a) do { ret = (a); goto cleanup; } while (0)
 #define EC_FAIL do { ret = -1; goto cleanup; } while (0)
 #define EC_FAIL_LOG(a, ...)                     \
     do {               \
index aebb56adffcdafdb9463b712afa9fe91685186e0..d11a2d4927a4752da0593fb3e54c2acc976cf57e 100755 (executable)
 #define FCE_DIR_DELETE      3
 #define FCE_FILE_CREATE     4
 #define FCE_DIR_CREATE      5
-#define FCE_TM_SIZE         6
 #define FCE_CONN_START     42
 #define FCE_CONN_BROKEN    99
 
+#define FCE_FIRST_EVENT     FCE_FILE_MODIFY /* keep in sync with last file event above */
+#define FCE_LAST_EVENT      FCE_DIR_CREATE  /* keep in sync with last file event above */
 
 /* fce_packet.fce_magic */
 #define FCE_PACKET_MAGIC  "at_fcapi"
@@ -31,6 +32,7 @@
  * Format is network byte order.
  */
 #define FCE_PACKET_HEADER_SIZE 8+1+1+4+2
+
 struct fce_packet
 {
     char magic[8];
@@ -41,21 +43,17 @@ struct fce_packet
     char data[MAXPATHLEN];
 };
 
+typedef uint32_t fce_ev_t;
+typedef enum { fce_file, fce_dir } fce_obj_t;
+
 struct path;
 struct ofork;
 
 void fce_pending_events(AFPObj *obj);
-
-int fce_register_delete_file( struct path *path );
-int fce_register_delete_dir( char *name );
-int fce_register_new_dir( struct path *path );
-int fce_register_new_file( struct path *path );
-int fce_register_file_modification( struct ofork *ofork );
-int fce_register_tm_size(const char *vol, size_t used);
-
+int fce_register(fce_ev_t event, const char *path, const char *oldpath, fce_obj_t type);
 int fce_add_udp_socket(const char *target );  // IP or IP:Port
 int fce_set_coalesce(const char *coalesce_opt ); // all|delete|create
-int fce_set_events(const char *events);     /* fmod,fdel,ddel,fcre,dcre,tmsz (default is all except tmsz) */
+int fce_set_events(const char *events);     /* fmod,fdel,ddel,fcre,dcre */
 
 #define FCE_DEFAULT_PORT 12250
 #define FCE_DEFAULT_PORT_STRING "12250"
index b8412d15d7c7b300f8b90b3c94a58ddeb96e374b..75d4041b7c6089afe325522478e518a7408c699c 100644 (file)
@@ -86,7 +86,7 @@ struct afp_options {
     char *uampath, *fqdn;
     char *sigconffile;
     char *uuidconf;
-    char *guest, *loginmesg, *keyfile, *passwdfile;
+    char *guest, *loginmesg, *keyfile, *passwdfile, *extmapfile;
     char *uamlist;
     char *signatureopt;
     unsigned char signature[16];
@@ -98,7 +98,7 @@ struct afp_options {
     gid_t admingid;
     int    volnamelen;
     /* default value for winbind authentication */
-    char *ntdomain, *ntseparator;
+    char *ntdomain, *ntseparator, *addomain;
     char *logconfig;
     char *logfile;
     char *mimicmodel;
@@ -147,14 +147,9 @@ extern const char         *Cnid_port;
 extern int  get_afp_errno   (const int param);
 extern void afp_options_init (struct afp_options *);
 extern void afp_options_parse_cmdline(AFPObj *obj, int ac, char **av);
-extern void afp_options_free(struct afp_options *);
 extern void setmessage (const char *);
 extern void readmessage (AFPObj *);
 
-/* gettok.c */
-extern void initline   (int, char *);
-extern int  parseline  (int, char *);
-
 /* afp_util.c */
 extern const char *AfpNum2name (int );
 extern const char *AfpErr2name(int err);
index 14cddf669d671287020c6d24585106907789bbdd..0a75e4f64f9ccd5f3265769d4dc30f13c660ec91 100644 (file)
@@ -14,7 +14,6 @@
  * into proprietary software; there is no requirement for such software to
  * contain a copyright notice related to this source.
  *
- * $Id: hash.h,v 1.2 2009-11-19 10:37:44 franklahm Exp $
  * $Name:  $
  */
 
index 0eefa4cb3aa64c8603d985d60741d7ff09ffe0a4..8f94c5ca4a11f677c135a12794cbbff9be2114b4 100644 (file)
@@ -10,8 +10,6 @@
 /*--------------------------------------------------------------------------*/
 
 /*
-       $Id: iniparser.h,v 1.26 2011-03-02 20:15:13 ndevilla Exp $
-       $Revision: 1.26 $
 */
 
 #ifndef _INIPARSER_H_
index 16e5484f6dd24822874f465a221918bac251ab9d..adc2a99d441ad31414b6ea392800db191a790c50 100644 (file)
@@ -7,6 +7,7 @@
 
 /* One function does the whole job */
 extern int acl_ldap_readconfig(dictionary *iniconfig);
+extern void acl_ldap_freeconfig(void);
 
 /* These are the prefvalues */
 extern char *ldap_server;
@@ -33,6 +34,7 @@ struct ldap_pref {
     int strorint;     /* string to just store in char * or convert to int ? */
     int intfromarray; /* convert to int, but use string to int mapping array pref_array[] */
     int valid;        /* -1 = mandatory, 0 = omittable/valid */
+    int valid_save;   /* copy of 'valid', used when resettting config */
 };
 
 struct pref_array {
index cf67bcad6f5260d8b1e0d42b3812e77a9b492521..1847c0d50b8ee746e583b749b3e8ec02e683f5f8 100644 (file)
@@ -90,9 +90,9 @@ enum logtypes {
   logtype_cnid,
   logtype_afpd,
   logtype_dsi,
-  logtype_atalkd,
-  logtype_papd,
   logtype_uams,
+  logtype_fce,
+  logtype_ad,
   logtype_end_of_list_marker  /* don't put any logtypes after this */
 };
 
index 33459b3188b70a4c1e3732bcc5a2b808e9000d77..858b4f1cd17a1107dbd017023c9c8ef77b2f7f28 100644 (file)
@@ -21,9 +21,9 @@
 #include <atalk/volume.h>
 
 extern int        afp_config_parse(AFPObj *obj, char *processname);
-
+extern void       afp_config_free(AFPObj *obj);
 extern int        load_charset(struct vol *vol);
-extern int        load_volumes(AFPObj *obj, void (*delvol_fn)(const AFPObj *obj, struct vol *));
+extern int        load_volumes(AFPObj *obj);
 extern void       unload_volumes(AFPObj *obj);
 extern struct vol *getvolumes(void);
 extern struct vol *getvolbyvid(const uint16_t);
@@ -31,4 +31,9 @@ extern struct vol *getvolbypath(AFPObj *obj, const char *path);
 extern struct vol *getvolbyname(const char *name);
 extern void       volume_free(struct vol *vol);
 extern void       volume_unlink(struct vol *volume);
+
+/* Extension type/creator mapping */
+struct extmap *getdefextmap(void);
+struct extmap *getextmap(const char *path);
+
 #endif
index 0bb43b52de51419d59c73c93ed527722793e6d15..75a970b631efa16167194b0108cb33cb5ca05f63 100644 (file)
@@ -56,8 +56,6 @@ typedef struct {
 #define CONV_DECOMPOSE      (1<<7) /* precompose */
 #define CONV_FORCE          (1<<8) /* force convertion */
 #define CONV__EILSEQ        (1<<9) /* ignore EILSEQ, replace with IGNORE_CHAR (try USC2) */
-#define CONV_ALLOW_COLON   (1<<10) /* Allow ':' in name. Needed for Extended Attributes */
-#define CONV_ALLOW_SLASH   (1<<11) /* Allow '/' in name. Needed for volume name */
 
 /* conversion return flags */
 #define CONV_REQMANGLE  (1<<14) /* mangling of returned name is required */
@@ -125,6 +123,7 @@ extern size_t   utf8_strlen_validate ( char *);
 
 /* from charcnv.c */
 extern int      set_charset_name(charset_t, const char *);
+extern void     free_charset_names(void);
 extern void     init_iconv (void);
 extern size_t   convert_string (charset_t, charset_t, void const *, size_t, void *, size_t);
 extern size_t   convert_string_allocate (charset_t, charset_t, void const *, size_t, char **);
index 01997e9400f8b74d5e4c77a6a45c4f036029d4b0..d3378ccb2134640b629f50d1bbde5ab974650b6f 100644 (file)
 #define NETATALK_DIOSZ_STACK 65536
 #define NETATALK_DIOSZ_HEAP  (1024*1024)
 
+struct vol;
+
 /* vfs/unix.c */
 extern int netatalk_unlink(const char *name);
 extern int netatalk_unlinkat(int dirfd, const char *name);
 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);
 
 /* rmdir ENOENT not an error */
 extern int netatalk_rmdir(int dirfd, const char *name);
 extern int netatalk_rmdir_all_errors(int dirfd, const char *name);
 
-extern int setfilmode(const char *, mode_t, struct stat *, mode_t);
+extern int setfilmode(const struct vol *vol, const char *name, mode_t mode, struct stat *st);
 extern int dir_rx_set(mode_t mode);
 extern int unix_rename(int sfd, const char *oldpath, int dfd, const char *newpath);
 extern int copy_file(int sfd, const char *src, const char *dst, mode_t mode);
index c5b23ee6f9eaeca3687c0a884d6b5a0c5c614c63..08c373948a3f7a9a7e77e53fcf26fe0d1d4d1f47 100644 (file)
@@ -15,6 +15,7 @@
 #include <sys/socket.h>
 #include <unistd.h>
 #include <poll.h>
+#include <sys/stat.h>
 
 #include <atalk/unicode.h>
 #include <atalk/bstrlib.h>
@@ -178,10 +179,18 @@ extern int recv_fd(int fd, int nonblocking);
 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);
 extern int daemonize(int nochdir, int noclose);
 extern int run_cmd(const char *cmd, char **cmd_argv);
+extern char *realpath_safe(const char *path);
+extern const char *basename_safe(const char *path);
+extern char *strtok_quote (char *s, const char *delim);
+
+extern int ochdir(const char *dir, int options);
+extern int ostat(const char *path, struct stat *buf, int options);
+extern int ostatat(int dirfd, const char *path, struct stat *st, int options);
+extern int ochown(const char *path, uid_t owner, gid_t group, int options);
+extern int ochmod(char *path, mode_t mode, const struct stat *st, int options);
 
 /******************************************************************
  * cnid.c
@@ -189,4 +198,11 @@ extern int run_cmd(const char *cmd, char **cmd_argv);
 
 extern bstring rel_path_in_vol(const char *path, const char *volpath);
 
+/******************************************************************
+ * cnid.c
+ *****************************************************************/
+
+extern void initline   (int, char *);
+extern int  parseline  (int, char *);
+
 #endif  /* _ATALK_UTIL_H */
index 116a4ceca336e947c6ea9e21038ab267ddbb7249..b185f994c1e2a0f7b0175a1e28c32735a7e6fb70 100644 (file)
 
 typedef uint64_t VolSpace;
 
+/* This should belong in a file.h */
+struct extmap {
+    char               *em_ext;
+    char               em_creator[4];
+    char               em_type[4];
+};
+
 struct vol {
     struct vol      *v_next;
     AFPObj          *v_obj;
@@ -125,6 +132,7 @@ struct vol {
 #define AFPVOL_ACLS      (1 << 24)   /* Volume supports ACLS */
 #define AFPVOL_SEARCHDB  (1 << 25)   /* Use fast CNID db search instead of filesystem */
 #define AFPVOL_NONETIDS  (1 << 26)   /* signal the client it shall do privelege mapping */
+#define AFPVOL_FOLLOWSYM (1 << 27)   /* follow symlinks on the server, default is not to */
 
 /* Extended Attributes vfs indirection  */
 #define AFPVOL_EA_NONE           0   /* No EAs */
@@ -183,6 +191,6 @@ struct vol {
 #define vol_nodev(vol) (((vol)->v_flags & AFPVOL_NODEV) ? 1 : 0)
 #define vol_unix_priv(vol) ((vol)->v_obj->afp_version >= 30 && ((vol)->v_flags & AFPVOL_UNIX_PRIV))
 #define vol_inv_dots(vol) (((vol)->v_flags & AFPVOL_INV_DOTS) ? 1 : 0)
-
+#define vol_syml_opt(vol) (((vol)->v_flags & AFPVOL_FOLLOWSYM) ? 0 : O_NOFOLLOW)
 
 #endif
index ed597dcb5f0a608c389079722dd38bff5118cc8d..732aeea89267b8706bc8175d5066837068c07de8 100644 (file)
@@ -18,7 +18,7 @@
 #        current+1:0:0
 #
 
-VERSION_INFO = 2:0:0
+VERSION_INFO = 3:0:0
 
 # History:          VERSION_INFO
 #
@@ -29,6 +29,7 @@ VERSION_INFO = 2:0:0
 #   3.0.0-beta2     1:0:0
 #   3.0             1:0:0
 #   3.0.1           2:0:0
+#   3.0.2           3:0:0
 
 SUBDIRS = acl adouble bstring compat cnid dsi iniparser tdb util unicode vfs
 
@@ -36,8 +37,11 @@ lib_LTLIBRARIES = libatalk.la
 
 libatalk_la_SOURCES = dummy.c
 
+libatalk_la_CFLAGS = \
+       @PTHREAD_CFLAGS@
+
 libatalk_la_LIBADD  = \
-       @WRAP_LIBS@ @ACL_LIBS@ \
+       @WRAP_LIBS@ @ACL_LIBS@ @PTHREAD_LIBS@ \
        acl/libacl.la \
        adouble/libadouble.la   \
        bstring/libbstring.la \
@@ -88,5 +92,6 @@ endif
 EXTRA_DIST = \
        libatalk-3.0beta1.abi \
        libatalk-3.0beta2.abi \
+       libatalk-3.0.abi \
        libatalk-3.0.1.abi \
-       libatalk-3.0.abi
+       libatalk-3.0.2.abi
index 0e75ee9ee420ff98c151043d533ab13c2f1150be..1013f46c15ddd55a22f8f5da570235e507a2e5be 100644 (file)
@@ -6,7 +6,7 @@ noinst_LTLIBRARIES = libacl.la
 libacl_la_SOURCES = cache.c unix.c uuid.c
 libacl_la_CFLAGS =
 libacl_la_LDFLAGS =
-libacl_la_LIBADD  =
+libacl_la_LIBADD  = @ACL_LIBS@
 
 if HAVE_LDAP
 libacl_la_SOURCES += ldap.c ldap_config.c
index bc9806d9d323f1e58af3c44e0c94c79b62ad1037..15eea478d099e1b361c69c89a37fefa30a2125cc 100644 (file)
@@ -46,7 +46,6 @@ static cacheduser_t *uuidcache[256];   /* indexed by hash of uuid */
 
 void uuidcache_dump(void) {
     int i;
-    int ret = 0;
     cacheduser_t *entry;
     char timestr[200];
     struct tm *tmp = NULL;
@@ -301,7 +300,6 @@ int add_cachebyuuid( uuidp_t inuuid, const char *inname, uuidtype_t type, const
     char *name = NULL;
     unsigned char *uuid = NULL;
     cacheduser_t *cacheduser = NULL;
-    cacheduser_t *entry;
     unsigned char hash;
 
     /* allocate mem and copy values */
index 11731a26c69d5bdeb683be1667a8c2c6bd351e03..8e33004a9e9a644778b776c612159f2adcc7ca32 100644 (file)
@@ -1,5 +1,4 @@
 /*
-   $Id: cache.h,v 1.1 2009-02-02 11:55:01 franklahm Exp $
    Copyright (c) 2008,2009 Frank Lahm <franklahm@gmail.com>
 
    This program is free software; you can redistribute it and/or modify
index 8743bafeabcd90b7f0e16afd6fa79bf3738b332a..f04c5aef1ed106df95247757e97581c08ff86ef5 100644 (file)
@@ -23,6 +23,7 @@
 #include <sys/time.h>
 #include <string.h>
 #include <errno.h>
+#include <ctype.h>
 #define LDAP_DEPRECATED 1
 #include <ldap.h>
 
@@ -56,21 +57,22 @@ char *ldap_uid_attr;
 int  ldap_uuid_encoding;
 
 struct ldap_pref ldap_prefs[] = {
-    {&ldap_server,     "ldap server",      0, 0, -1},
-    {&ldap_auth_method,"ldap auth method", 1, 1, -1},
-    {&ldap_auth_dn,    "ldap auth dn",     0, 0,  0},
-    {&ldap_auth_pw,    "ldap auth pw",     0, 0,  0},
-    {&ldap_userbase,   "ldap userbase",    0, 0, -1},
-    {&ldap_userscope,  "ldap userscope",   1 ,1, -1},
-    {&ldap_groupbase,  "ldap groupbase",   0, 0, -1},
-    {&ldap_groupscope, "ldap groupscope",  1 ,1, -1},
-    {&ldap_uuid_attr,  "ldap uuid attr",   0, 0, -1},
-    {&ldap_uuid_string,"ldap uuid string", 0, 0,  0},
-    {&ldap_name_attr,  "ldap name attr",   0, 0, -1},
-    {&ldap_group_attr, "ldap group attr",  0, 0, -1},
-    {&ldap_uid_attr,   "ldap uid attr",    0, 0,  0},
-    {&ldap_uuid_encoding,"ldap uuid encoding", 1, 1,  0},
-    {NULL,             NULL,               0, 0, -1}
+    /* pointer to pref,    prefname,              strorint, intfromarray, valid, valid_save */
+    {&ldap_server,         "ldap server",         0, 0, -1, -1},
+    {&ldap_auth_method,    "ldap auth method",    1, 1, -1, -1},
+    {&ldap_auth_dn,        "ldap auth dn",        0, 0,  0,  0},
+    {&ldap_auth_pw,        "ldap auth pw",        0, 0,  0,  0},
+    {&ldap_userbase,       "ldap userbase",       0, 0, -1, -1},
+    {&ldap_userscope,      "ldap userscope",      1 ,1, -1, -1},
+    {&ldap_groupbase,      "ldap groupbase",      0, 0, -1, -1},
+    {&ldap_groupscope,     "ldap groupscope",     1 ,1, -1, -1},
+    {&ldap_uuid_attr,      "ldap uuid attr",      0, 0, -1, -1},
+    {&ldap_uuid_string,    "ldap uuid string",    0, 0,  0,  0},
+    {&ldap_name_attr,      "ldap name attr",      0, 0, -1, -1},
+    {&ldap_group_attr,     "ldap group attr",     0, 0, -1, -1},
+    {&ldap_uid_attr,       "ldap uid attr",       0, 0,  0,  0},
+    {&ldap_uuid_encoding,  "ldap uuid encoding",  1, 1,  0,  0},
+    {NULL,                 NULL,                  0, 0,  0,  0}
 };
 
 struct pref_array prefs_array[] = {
@@ -345,7 +347,7 @@ int ldap_getnamefromuuid( const char *uuidstr, char **name, uuidtype_t *type) {
         int i = 0;
         int s = 0;
         char c;
-        while(c = uuidstr[i]) {
+        while ((c = uuidstr[i])) {
             if((c >='a' && c <= 'f')
                 || (c >= 'A' && c <= 'F')
                 || (c >= '0' && c <= '9')) {
index bd9d414b85758ce8439863100e9752f33b0785af..26a63fa9c76dab72f94af1fb812943d50f2ba804 100644 (file)
 #include <atalk/logger.h>
 #include <atalk/iniparser.h>
 
+void acl_ldap_freeconfig(void)
+{
+    for (int i = 0; ldap_prefs[i].name != NULL; i++) {
+        if (ldap_prefs[i].intfromarray == 0 && ldap_prefs[i].strorint == 0) {
+            free(*((char **)(ldap_prefs[i].pref)));
+            *((char **)(ldap_prefs[i].pref)) = NULL;
+        }
+        ldap_prefs[i].valid = ldap_prefs[i].valid_save;
+    }
+}
+
 int acl_ldap_readconfig(dictionary *iniconfig)
 {
     int i, j;
index b71c13e689cd3cab889cbb6a24dfb7bbf1c45417..c1bc065f8bfab27d316a2db2b5e150a3bd6553a4 100644 (file)
@@ -209,7 +209,6 @@ int getuuidfromname( const char *name, uuidtype_t type, unsigned char *uuid) {
         add_cachebyname(name, uuid, mytype, 0);
     }
 
-cleanup:
 #ifdef HAVE_LDAP
     if (uuid_string) free(uuid_string);
 #endif
index e5fe323fd7814249cf21b412695a85f02739f3ae..43d798bb647f7e0f6921a22ec33652b822bc204b 100644 (file)
@@ -117,25 +117,22 @@ int ad_setid (struct adouble *adp, const dev_t dev, const ino_t ino , const uint
 }
 
 /* ----------------------------- */
-uint32_t ad_getid (struct adouble *adp, const dev_t st_dev, const ino_t st_ino , const cnid_t did, const void *stamp)
+uint32_t ad_getid (struct adouble *adp, const dev_t st_dev, const ino_t st_ino , const cnid_t did, const void *stamp _U_)
 {
     uint32_t aint = 0;
     dev_t  dev;
     ino_t  ino;
     cnid_t a_did;
-    char   temp[ADEDLEN_PRIVSYN];
 
     if (adp) {
         if (sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)) {
             memcpy(&dev, ad_entry(adp, ADEID_PRIVDEV), sizeof(dev_t));
             memcpy(&ino, ad_entry(adp, ADEID_PRIVINO), sizeof(ino_t));
-            memcpy(temp, ad_entry(adp, ADEID_PRIVSYN), sizeof(temp));
             memcpy(&a_did, ad_entry(adp, ADEID_DID), sizeof(cnid_t));
 
             if (((adp->ad_options & ADVOL_NODEV) || (dev == st_dev))
                 && ino == st_ino
-                && (!did || a_did == did)
-                && (memcmp(stamp, temp, sizeof(temp)) == 0) ) {
+                && (!did || a_did == did) ) {
                 memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint));
                 if (adp->ad_vers == AD_VERSION2)
                     return aint;
index eaac8db97032eab7aead8b644de35657854ea9f3..a9fae763affc2874f5e52d11e956f665cd6b13d6 100644 (file)
@@ -57,15 +57,22 @@ static int ad_conv_v22ea_hf(const char *path, const struct stat *sp, const struc
     EC_INIT;
     struct adouble adv2;
     struct adouble adea;
-    const char *adpath;
     int adflags;
     uint32_t ctime, mtime, afpinfo = 0;
     char *emptyad;
 
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): BEGIN", fullpathname(path));
+    LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): BEGIN", fullpathname(path));
+
+    switch (S_IFMT & sp->st_mode) {
+    case S_IFREG:
+        break;
+    default:
+        return 0;
+    }
 
     ad_init(&adea, vol);
     ad_init_old(&adv2, AD_VERSION2, adea.ad_options);
+
     adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0;
 
     /* Open and lock adouble:v2 file */
@@ -97,12 +104,12 @@ static int ad_conv_v22ea_hf(const char *path, const struct stat *sp, const struc
             goto copy;
     }
 
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): default adouble", fullpathname(path), ret);
+    LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): default adouble", fullpathname(path), ret);
     goto EC_CLEANUP;
 
 copy:
     /* Create a adouble:ea meta EA */
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): copying adouble", fullpathname(path), ret);
+    LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): copying adouble", fullpathname(path), ret);
     EC_ZERO_LOGSTR( ad_open(&adea, path, adflags | ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE),
                     "ad_conv_v22ea_hf(\"%s\"): error creating metadata EA: %s",
                     fullpathname(path), strerror(errno));
@@ -112,7 +119,7 @@ copy:
 EC_CLEANUP:
     EC_ZERO_LOG( ad_close(&adv2, ADFLAGS_HF | ADFLAGS_SETSHRMD) );
     EC_ZERO_LOG( ad_close(&adea, ADFLAGS_HF | ADFLAGS_SETSHRMD) );
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): END: %d", fullpathname(path), ret);
+    LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): END: %d", fullpathname(path), ret);
     EC_EXIT;
 }
 
@@ -122,7 +129,14 @@ static int ad_conv_v22ea_rf(const char *path, const struct stat *sp, const struc
     struct adouble adv2;
     struct adouble adea;
 
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_rf(\"%s\"): BEGIN", fullpathname(path));
+    LOG(log_debug, logtype_ad,"ad_conv_v22ea_rf(\"%s\"): BEGIN", fullpathname(path));
+
+    switch (S_IFMT & sp->st_mode) {
+    case S_IFREG:
+        break;
+    default:
+        return 0;
+    }
 
     if (S_ISDIR(sp->st_mode))
         return 0;
@@ -147,7 +161,7 @@ static int ad_conv_v22ea_rf(const char *path, const struct stat *sp, const struc
 EC_CLEANUP:
     EC_ZERO_LOG( ad_close(&adv2, ADFLAGS_HF | ADFLAGS_RF) );
     EC_ZERO_LOG( ad_close(&adea, ADFLAGS_HF | ADFLAGS_RF) );
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_rf(\"%s\"): END: %d", fullpathname(path), ret);
+    LOG(log_debug, logtype_ad,"ad_conv_v22ea_rf(\"%s\"): END: %d", fullpathname(path), ret);
     EC_EXIT;
 }
 
@@ -159,11 +173,14 @@ static int ad_conv_v22ea(const char *path, const struct stat *sp, const struct v
 
     become_root();
 
-    EC_ZERO( ad_conv_v22ea_hf(path, sp, vol) );
-    EC_ZERO( ad_conv_v22ea_rf(path, sp, vol) );
+    if (ad_conv_v22ea_hf(path, sp, vol) != 0)
+        goto delete;
+    if (ad_conv_v22ea_rf(path, sp, vol) != 0)
+        goto delete;
 
+delete:
     EC_NULL( adpath = ad_path(path, adflags) );
-    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): deleting adouble:v2 file: \"%s\"",
+    LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): deleting adouble:v2 file: \"%s\"",
         path, fullpathname(adpath));
 
     unlink(adpath);
@@ -184,11 +201,11 @@ static int ad_conv_dehex(const char *path, const struct stat *sp, const struct v
 {
     EC_INIT;
     static char buf[MAXPATHLEN];
-    const char *adpath, *p;
+    const char *p;
     int adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0;
     bstring newpath = NULL;
 
-    LOG(log_debug, logtype_default,"ad_conv_dehex(\"%s\"): BEGIN", fullpathname(path));
+    LOG(log_debug, logtype_ad,"ad_conv_dehex(\"%s\"): BEGIN", fullpathname(path));
 
     *newpathp = NULL;
 
@@ -231,7 +248,7 @@ int ad_convert(const char *path, const struct stat *sp, const struct vol *vol, c
     EC_INIT;
     const char *p;
 
-    LOG(log_debug, logtype_default,"ad_convert(\"%s\"): BEGIN", fullpathname(path));
+    LOG(log_debug, logtype_ad,"ad_convert(\"%s\"): BEGIN", fullpathname(path));
 
     if (newpath)
         *newpath = NULL;
@@ -246,7 +263,7 @@ int ad_convert(const char *path, const struct stat *sp, const struct vol *vol, c
     }
 
 EC_CLEANUP:
-    LOG(log_debug, logtype_default,"ad_convert(\"%s\"): END: %d", fullpathname(path), ret);
+    LOG(log_debug, logtype_ad,"ad_convert(\"%s\"): END: %d", fullpathname(path), ret);
     EC_EXIT;
 }
 
index a637b27f2ebeb108db55d5eeeb9674684e43beb2..50fd8baef2a2acc7297d0dbb5178490cc456532f 100644 (file)
@@ -59,9 +59,8 @@ int ad_rebuild_adouble_header_v2(struct adouble *ad)
     uint32_t       temp;
     uint16_t       nent;
     char        *buf, *nentp;
-    int             len;
 
-    LOG(log_debug, logtype_default, "ad_rebuild_adouble_header_v2");
+    LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_v2");
 
     buf = ad->ad_data;
 
@@ -105,9 +104,8 @@ int ad_rebuild_adouble_header_ea(struct adouble *ad)
     uint32_t       temp;
     uint16_t       nent;
     char        *buf, *nentp;
-    int             len;
 
-    LOG(log_debug, logtype_default, "ad_rebuild_adouble_header_ea");
+    LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_ea");
 
     buf = ad->ad_data;
 
@@ -153,9 +151,8 @@ static int ad_rebuild_adouble_header_osx(struct adouble *ad, char *adbuf)
     uint32_t       temp;
     uint16_t       nent;
     char           *buf;
-    int            len;
 
-    LOG(log_debug, logtype_default, "ad_rebuild_adouble_header_osx");
+    LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_osx");
 
     buf = &adbuf[0];
 
@@ -167,7 +164,7 @@ static int ad_rebuild_adouble_header_osx(struct adouble *ad, char *adbuf)
     memcpy(buf, &temp, sizeof( temp ));
     buf += sizeof( temp );
 
-    memset(buf, 0, sizeof(ad->ad_filler));
+    memcpy(buf, "Netatalk        ", 16);
     buf += sizeof( ad->ad_filler );
 
     nent = htons(ADEID_NUM_OSX);
@@ -237,8 +234,8 @@ int ad_copy_header(struct adouble *add, struct adouble *ads)
     }
     add->ad_rlen = ads->ad_rlen;
 
-    if ((ads->ad_vers == AD_VERSION2) && (add->ad_vers = AD_VERSION_EA)
-        || (ads->ad_vers == AD_VERSION_EA) && (add->ad_vers = AD_VERSION2)) {
+    if (((ads->ad_vers == AD_VERSION2) && (add->ad_vers == AD_VERSION_EA))
+        || ((ads->ad_vers == AD_VERSION_EA) && (add->ad_vers == AD_VERSION2))) {
         cnid_t id;
         memcpy(&id, ad_entry(add, ADEID_PRIVID), sizeof(cnid_t));
         id = htonl(id);
@@ -253,7 +250,7 @@ static int ad_flush_hf(struct adouble *ad)
     int len;
     int cwd = -1;
 
-    LOG(log_debug, logtype_default, "ad_flush_hf(%s)", adflags2logstr(ad->ad_adflags));
+    LOG(log_debug, logtype_ad, "ad_flush_hf(%s)", adflags2logstr(ad->ad_adflags));
 
     struct ad_fd *adf;
 
@@ -265,7 +262,7 @@ static int ad_flush_hf(struct adouble *ad)
         adf = &ad->ad_data_fork;
         break;
     default:
-        LOG(log_error, logtype_afpd, "ad_flush: unexpected adouble version");
+        LOG(log_error, logtype_ad, "ad_flush: unexpected adouble version");
         return -1;
     }
 
@@ -292,7 +289,8 @@ static int ad_flush_hf(struct adouble *ad)
                 if (ad->ad_adflags & ADFLAGS_DIR) {
                     EC_NEG1_LOG( cwd = open(".", O_RDONLY) );
                     EC_NEG1_LOG( fchdir(ad_data_fileno(ad)) );
-                    EC_ZERO_LOG( sys_lsetxattr(".", AD_EA_META, ad->ad_data, AD_DATASZ_EA, 0) );
+                    EC_ZERO_LOGSTR( sys_lsetxattr(".", AD_EA_META, ad->ad_data, AD_DATASZ_EA, 0),
+                                    "sys_lsetxattr(\"%s\"): %s", fullpathname(".") ,strerror(errno));
                     EC_NEG1_LOG( fchdir(cwd) );
                     EC_NEG1_LOG( close(cwd) );
                     cwd = -1;
@@ -302,7 +300,7 @@ static int ad_flush_hf(struct adouble *ad)
             }
             break;
         default:
-            LOG(log_error, logtype_afpd, "ad_flush: unexpected adouble version");
+            LOG(log_error, logtype_ad, "ad_flush: unexpected adouble version");
             return -1;
         }
     }
@@ -329,7 +327,7 @@ static int ad_flush_rf(struct adouble *ad)
     if (ad->ad_vers != AD_VERSION_EA)
         return 0;
 
-    LOG(log_debug, logtype_default, "ad_flush_rf(%s)", adflags2logstr(ad->ad_adflags));
+    LOG(log_debug, logtype_ad, "ad_flush_rf(%s)", adflags2logstr(ad->ad_adflags));
 
     if ((ad->ad_rfp->adf_flags & O_RDWR)) {
         if (ad_getentryoff(ad, ADEID_RFORK)) {
@@ -353,7 +351,7 @@ int ad_flush(struct adouble *ad)
 {
     EC_INIT;
 
-    LOG(log_debug, logtype_default, "ad_flush(%s)", adflags2logstr(ad->ad_adflags));
+    LOG(log_debug, logtype_ad, "ad_flush(%s)", adflags2logstr(ad->ad_adflags));
 
     if (AD_META_OPEN(ad)) {
         EC_ZERO( ad_flush_hf(ad) );
@@ -393,7 +391,7 @@ int ad_close(struct adouble *ad, int adflags)
         return err;
 
 
-    LOG(log_debug, logtype_default,
+    LOG(log_debug, logtype_ad,
         "ad_close(%s): BEGIN: {d: %d, m: %d, r: %d} "
         "[dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
         adflags2logstr(adflags),
@@ -412,11 +410,11 @@ int ad_close(struct adouble *ad, int adflags)
 
     if ((adflags & ADFLAGS_DF) && (ad_data_fileno(ad) >= 0 || ad_data_fileno(ad) == AD_SYMLINK)) {        
         if (ad->ad_data_refcount)
-            ad->ad_data_refcount--;
+            if (--ad->ad_data_refcount == 0)
+                adf_lock_free(&ad->ad_data_fork);                
         if (--ad->ad_data_fork.adf_refcount == 0) {
             if (ad_data_closefd(ad) < 0)
                 err = -1;
-            adf_lock_free(&ad->ad_data_fork);
         }
     }
 
@@ -427,14 +425,13 @@ int ad_close(struct adouble *ad, int adflags)
             if (close( ad_meta_fileno(ad)) < 0)
                 err = -1;
             ad_meta_fileno(ad) = -1;
-            if (ad->ad_vers == AD_VERSION2)
-                adf_lock_free(ad->ad_mdp);
         }
     }
 
     if (adflags & ADFLAGS_RF) {
         if (ad->ad_reso_refcount)
-            ad->ad_reso_refcount--;
+            if (--ad->ad_reso_refcount == 0)
+                adf_lock_free(ad->ad_rfp);
         if (ad->ad_vers == AD_VERSION_EA) {
             if ((ad_reso_fileno(ad) != -1)
                 && !(--ad->ad_rfp->adf_refcount)) {
@@ -442,12 +439,11 @@ int ad_close(struct adouble *ad, int adflags)
                     err = -1;
                 ad->ad_rlen = 0;
                 ad_reso_fileno(ad) = -1;
-                adf_lock_free(ad->ad_rfp);
             }
         }
     }
 
-    LOG(log_debug, logtype_default,
+    LOG(log_debug, logtype_ad,
         "ad_close(%s): END: %d {d: %d, m: %d, r: %d} "
         "[dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
         adflags2logstr(adflags), err,
index 92f0ab89224501331c5a010dd323196ced0258b3..173adc4c1f113f22b9bdeeee05d000f993b4cdee 100644 (file)
@@ -64,7 +64,7 @@ static int set_lock(int fd, int cmd,  struct flock *lock)
 {
     EC_INIT;
 
-    LOG(log_debug, logtype_default, "set_lock(fd: %d, %s, %s, off: %jd (%s), len: %jd): BEGIN",
+    LOG(log_debug, logtype_ad, "set_lock(fd: %d, %s, %s, off: %jd (%s), len: %jd): BEGIN",
         fd, cmd == F_SETLK ? "F_SETLK" : "F_GETLK",
         lock->l_type == F_RDLCK ? "F_RDLCK" : lock->l_type == F_WRLCK ? "F_WRLCK" : "F_UNLCK",
         (intmax_t)lock->l_start,
@@ -361,7 +361,7 @@ int ad_lock(struct adouble *ad, uint32_t eid, int locktype, off_t off, off_t len
     int type;  
     int ret = 0, fcntl_lock_err = 0;
 
-    LOG(log_debug, logtype_default, "ad_lock(%s, %s, off: %jd (%s), len: %jd): BEGIN",
+    LOG(log_debug, logtype_ad, "ad_lock(%s, %s, off: %jd (%s), len: %jd): BEGIN",
         eid == ADEID_DFORK ? "data" : "reso",
         locktypetostr(locktype),
         (intmax_t)off,
@@ -496,7 +496,7 @@ exit:
             set_lock(adf->adf_fd, F_SETLK, &lock);
         }
     }
-    LOG(log_debug, logtype_default, "ad_lock: END: %d", ret);
+    LOG(log_debug, logtype_ad, "ad_lock: END: %d", ret);
     return ret;
 }
 
@@ -507,7 +507,7 @@ int ad_tmplock(struct adouble *ad, uint32_t eid, int locktype, off_t off, off_t
     int err;
     int type;  
 
-    LOG(log_debug, logtype_default, "ad_tmplock(%s, %s, off: %jd (%s), len: %jd): BEGIN",
+    LOG(log_debug, logtype_ad, "ad_tmplock(%s, %s, off: %jd (%s), len: %jd): BEGIN",
         eid == ADEID_DFORK ? "data" : "reso",
         locktypetostr(locktype),
         (intmax_t)off,
@@ -564,14 +564,14 @@ int ad_tmplock(struct adouble *ad, uint32_t eid, int locktype, off_t off, off_t
         adf_relockrange(adf, adf->adf_fd, lock.l_start, len);
 
 exit:
-    LOG(log_debug, logtype_default, "ad_tmplock: END: %d", err);
+    LOG(log_debug, logtype_ad, "ad_tmplock: END: %d", err);
     return err;
 }
 
 /* --------------------- */
 void ad_unlock(struct adouble *ad, const int fork, int unlckbrl)
 {
-    LOG(log_debug, logtype_default, "ad_unlock(unlckbrl: %d): BEGIN", unlckbrl);
+    LOG(log_debug, logtype_ad, "ad_unlock(unlckbrl: %d): BEGIN", unlckbrl);
 
     if (ad_data_fileno(ad) != -1) {
         adf_unlock(ad, &ad->ad_data_fork, fork, unlckbrl);
@@ -580,7 +580,7 @@ void ad_unlock(struct adouble *ad, const int fork, int unlckbrl)
         adf_unlock(ad, &ad->ad_resource_fork, fork, unlckbrl);
     }
 
-    LOG(log_debug, logtype_default, "ad_unlock: END");
+    LOG(log_debug, logtype_ad, "ad_unlock: END");
 }
 
 /*!
@@ -598,7 +598,7 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off)
     int ret = 0;
     off_t lock_offset;
 
-    LOG(log_debug, logtype_default, "ad_testlock(%s, off: %jd (%s): BEGIN",
+    LOG(log_debug, logtype_ad, "ad_testlock(%s, off: %jd (%s): BEGIN",
         eid == ADEID_DFORK ? "data" : "reso",
         (intmax_t)off,
         shmdstrfromoff(off));
@@ -611,7 +611,7 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off)
 
     ret = testlock(&ad->ad_data_fork, lock_offset, 1);
 
-    LOG(log_debug, logtype_default, "ad_testlock: END: %d", ret);
+    LOG(log_debug, logtype_ad, "ad_testlock: END: %d", ret);
     return ret;
 }
 
@@ -630,7 +630,6 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off)
 uint16_t ad_openforks(struct adouble *ad, uint16_t attrbits)
 {
     uint16_t ret = 0;
-    struct ad_fd *adf;
     off_t off;
     off_t len;
 
index 3e06e93fb6cfe7e715ac0de66be0d58cf0ae72a7..5205b9e234020d62b82e26d0a4e799b7994ca72e 100644 (file)
@@ -108,7 +108,9 @@ static int ad_mkrf(const char *path);
 static int ad_header_read(const char *path, struct adouble *ad, const struct stat *hst);
 static int ad_header_upgrade(struct adouble *ad, const char *name);
 
+#ifdef HAVE_EAFD
 static int ad_mkrf_ea(const char *path);
+#endif
 static int ad_header_read_ea(const char *path, struct adouble *ad, const struct stat *hst);
 static int ad_header_upgrade_ea(struct adouble *ad, const char *name);
 static int ad_reso_size(const char *path, int adflags, struct adouble *ad);
@@ -316,10 +318,10 @@ static int new_ad_header(struct adouble *ad, const char *path, struct stat *stp,
     uint16_t            ashort;
     struct stat         st;
 
-    LOG(log_debug, logtype_default, "new_ad_header(\"%s\")", path);
+    LOG(log_debug, logtype_ad, "new_ad_header(\"%s\")", path);
 
     if (ad->ad_magic == AD_MAGIC) {
-        LOG(log_debug, logtype_default, "new_ad_header(\"%s\"): already initialized", path);
+        LOG(log_debug, logtype_ad, "new_ad_header(\"%s\"): already initialized", path);
         return 0;
     }
 
@@ -409,7 +411,7 @@ static void parse_entries(struct adouble *ad, char *buf, uint16_t nentries)
             ad->ad_eid[ eid ].ade_len = len;
         } else if (!warning) {
             warning = 1;
-            LOG(log_warning, logtype_default, "parse_entries: bogus eid: %d", eid);
+            LOG(log_warning, logtype_ad, "parse_entries: bogus eid: %d", eid);
         }
     }
 }
@@ -444,7 +446,7 @@ static int ad_header_read(const char *path _U_, struct adouble *ad, const struct
     ad->ad_version = ntohl( ad->ad_version );
 
     if ((ad->ad_magic != AD_MAGIC) || (ad->ad_version != AD_VERSION2)) {
-        LOG(log_error, logtype_default, "ad_open: can't parse AppleDouble header.");
+        LOG(log_error, logtype_ad, "ad_open: can't parse AppleDouble header.");
         errno = EIO;
         return -1;
     }
@@ -461,7 +463,7 @@ static int ad_header_read(const char *path _U_, struct adouble *ad, const struct
 
     buf += AD_HEADER_LEN;
     if (len > header_len - AD_HEADER_LEN) {
-        LOG(log_error, logtype_default, "ad_header_read: can't read entry info.");
+        LOG(log_error, logtype_ad, "ad_header_read: can't read entry info.");
         errno = EIO;
         return -1;
     }
@@ -473,13 +475,13 @@ static int ad_header_read(const char *path _U_, struct adouble *ad, const struct
     if (!ad_getentryoff(ad, ADEID_RFORK)
         || (ad_getentryoff(ad, ADEID_RFORK) > sizeof(ad->ad_data))
         ) {
-        LOG(log_error, logtype_default, "ad_header_read: problem with rfork entry offset.");
+        LOG(log_error, logtype_ad, "ad_header_read: problem with rfork entry offset.");
         errno = EIO;
         return -1;
     }
 
     if (ad_getentryoff(ad, ADEID_RFORK) > header_len) {
-        LOG(log_error, logtype_default, "ad_header_read: can't read in entries.");
+        LOG(log_error, logtype_ad, "ad_header_read: can't read in entries.");
         errno = EIO;
         return -1;
     }
@@ -505,7 +507,7 @@ int ad_valid_header_osx(const char *path)
     char                *buf = &adosx.ad_data[0];
     ssize_t             header_len;
 
-    LOG(log_debug, logtype_afpd, "ad_valid_header_osx(\"%s\"): BEGIN", fullpathname(path));
+    LOG(log_debug, logtype_ad, "ad_valid_header_osx(\"%s\"): BEGIN", fullpathname(path));
 
     EC_NEG1( fd = open(path, O_RDONLY) );
 
@@ -521,12 +523,20 @@ int ad_valid_header_osx(const char *path)
     adosx.ad_version = ntohl(adosx.ad_version);
 
     if ((adosx.ad_magic != AD_MAGIC) || (adosx.ad_version != AD_VERSION2)) {
-        LOG(log_error, logtype_afpd, "ad_valid_header_osx: not an adouble:ox file");
+        LOG(log_warning, logtype_ad, "ad_valid_header_osx: not an adouble:osx file");
         EC_FAIL;
     }
 
+    if (strncmp(buf + ADEDOFF_FILLER, "Mac OS X", strlen("Mac OS X")) == 0)
+        /*
+         * It's a split fork created by OS X, it's not our "own" ._ file
+         * and thus not a valid header in this context.
+         * We allow enumeration and access.
+         */
+        EC_FAIL;
+
 EC_CLEANUP:
-    LOG(log_debug, logtype_afpd, "ad_valid_header_osx(\"%s\"): END: %d", fullpathname(path), ret);
+    LOG(log_debug, logtype_ad, "ad_valid_header_osx(\"%s\"): END: %d", fullpathname(path), ret);
     if (fd != -1)
         close(fd);
     if (ret != 0)
@@ -561,7 +571,7 @@ static int ad_header_read_osx(const char *path _U_, struct adouble *ad, const st
     adosx.ad_version = ntohl(adosx.ad_version);
 
     if ((adosx.ad_magic != AD_MAGIC) || (adosx.ad_version != AD_VERSION2)) {
-        LOG(log_error, logtype_afpd, "ad_header_read_osx: can't parse AppleDouble header");
+        LOG(log_error, logtype_ad, "ad_header_read_osx: can't parse AppleDouble header");
         errno = EIO;
         return -1;
     }
@@ -575,7 +585,7 @@ static int ad_header_read_osx(const char *path _U_, struct adouble *ad, const st
 
     buf += AD_HEADER_LEN;
     if (len > header_len - AD_HEADER_LEN) {
-        LOG(log_error, logtype_afpd, "ad_header_read_osx: can't read entry info.");
+        LOG(log_error, logtype_ad, "ad_header_read_osx: can't read entry info.");
         errno = EIO;
         return -1;
     }
@@ -587,7 +597,7 @@ static int ad_header_read_osx(const char *path _U_, struct adouble *ad, const st
         || ad_getentryoff(&adosx, ADEID_RFORK) > sizeof(ad->ad_data)
         || ad_getentryoff(&adosx, ADEID_RFORK) > header_len
         ) {
-        LOG(log_error, logtype_afpd, "ad_header_read_osx: problem with rfork entry offset.");
+        LOG(log_error, logtype_ad, "ad_header_read_osx: problem with rfork entry offset.");
         errno = EIO;
         return -1;
     }
@@ -616,12 +626,12 @@ static int ad_header_read_ea(const char *path, struct adouble *ad, const struct
     else
         header_len = sys_lgetxattr(path, AD_EA_META, ad->ad_data, AD_DATASZ_EA);
      if (header_len < 1) {
-        LOG(log_debug, logtype_default, "ad_header_read_ea: %s", strerror(errno));
+        LOG(log_debug, logtype_ad, "ad_header_read_ea: %s", strerror(errno));
         return -1;
     }
 
     if (header_len < AD_HEADER_LEN) {
-        LOG(log_error, logtype_default, "ad_header_read_ea: bogus AppleDouble header.");
+        LOG(log_error, logtype_ad, "ad_header_read_ea: bogus AppleDouble header.");
         errno = EIO;
         return -1;
     }
@@ -633,7 +643,7 @@ static int ad_header_read_ea(const char *path, struct adouble *ad, const struct
     ad->ad_version = ntohl( ad->ad_version );
 
     if ((ad->ad_magic != AD_MAGIC) || (ad->ad_version != AD_VERSION2)) {
-        LOG(log_error, logtype_default, "ad_header_read_ea: wrong magic or version");
+        LOG(log_error, logtype_ad, "ad_header_read_ea: wrong magic or version");
         errno = EIO;
         return -1;
     }
@@ -646,7 +656,7 @@ static int ad_header_read_ea(const char *path, struct adouble *ad, const struct
     if (len + AD_HEADER_LEN > sizeof(ad->ad_data))
         len = sizeof(ad->ad_data) - AD_HEADER_LEN;
     if (len > header_len - AD_HEADER_LEN) {
-        LOG(log_error, logtype_default, "ad_header_read_ea: can't read entry info.");
+        LOG(log_error, logtype_ad, "ad_header_read_ea: can't read entry info.");
         errno = EIO;
         return -1;
     }
@@ -683,11 +693,13 @@ static int ad_mkrf(const char *path)
     return 0;
 }
 
+#ifdef HAVE_EAFD
 static int ad_mkrf_ea(const char *path _U_)
 {
     AFP_PANIC("ad_mkrf_ea: dont use");
     return 0;
 }
+#endif
 
 static int ad_mkrf_osx(const char *path _U_)
 {
@@ -800,6 +812,9 @@ static int ad2openflags(const struct adouble *ad, int adfile, int adflags)
     if (adflags & ADFLAGS_TRUNC)
         oflags |= O_TRUNC;
 
+    if (!(ad->ad_options & ADVOL_FOLLO_SYML))
+        oflags |= O_NOFOLLOW;
+
     return oflags;
 }
 
@@ -812,7 +827,7 @@ static int ad_open_df(const char *path, int adflags, mode_t mode, struct adouble
     int         st_invalid = -1;
     ssize_t     lsz;
 
-    LOG(log_debug, logtype_default,
+    LOG(log_debug, logtype_ad,
         "ad_open_df(\"%s\", %s): BEGIN [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
         fullpathname(path), adflags2logstr(adflags),
         ad_data_fileno(ad), ad->ad_data_fork.adf_refcount,
@@ -833,7 +848,7 @@ static int ad_open_df(const char *path, int adflags, mode_t mode, struct adouble
         goto EC_CLEANUP;
     }
 
-    oflags = O_NOFOLLOW | ad2openflags(ad, ADFLAGS_DF, adflags);
+    oflags = ad2openflags(ad, ADFLAGS_DF, adflags);
 
     admode = mode;
     if ((adflags & ADFLAGS_CREATE)) {
@@ -878,7 +893,7 @@ static int ad_open_df(const char *path, int adflags, mode_t mode, struct adouble
     ad->ad_data_fork.adf_refcount++;
 
 EC_CLEANUP:
-    LOG(log_debug, logtype_default,
+    LOG(log_debug, logtype_ad,
         "ad_open_df(\"%s\", %s): END: %d [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
         fullpathname(path), adflags2logstr(adflags), ret,
         ad_data_fileno(ad), ad->ad_data_fork.adf_refcount,
@@ -898,7 +913,7 @@ static int ad_open_hf_v2(const char *path, int adflags, mode_t mode, struct adou
     mode_t      admode;
     int         st_invalid = -1;
 
-    LOG(log_debug, logtype_default,
+    LOG(log_debug, logtype_ad,
         "ad_open_hf_v2(\"%s\", %s): BEGIN [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
         fullpathname(path), adflags2logstr(adflags),
         ad_data_fileno(ad), ad->ad_data_fork.adf_refcount,
@@ -921,8 +936,8 @@ static int ad_open_hf_v2(const char *path, int adflags, mode_t mode, struct adou
     }
 
     ad_p = ad->ad_ops->ad_path(path, adflags);
-    oflags = O_NOFOLLOW | ad2openflags(ad, ADFLAGS_HF, adflags);
-    LOG(log_debug, logtype_default,"ad_open_hf_v2(\"%s\"): open flags: %s",
+    oflags = ad2openflags(ad, ADFLAGS_HF, adflags);
+    LOG(log_debug, logtype_ad,"ad_open_hf_v2(\"%s\"): open flags: %s",
         fullpathname(path), openflags2logstr(oflags));
     nocreatflags = oflags & ~(O_CREAT | O_EXCL);
 
@@ -949,7 +964,7 @@ static int ad_open_hf_v2(const char *path, int adflags, mode_t mode, struct adou
             /*
              * We're expecting to create a new adouble header file here
              */
-            LOG(log_debug, logtype_default, "ad_open(\"%s\"): creating adouble file",
+            LOG(log_debug, logtype_ad, "ad_open(\"%s\"): creating adouble file",
                 fullpathname(path));
             admode = mode;
             errno = 0;
@@ -1010,7 +1025,7 @@ EC_CLEANUP:
         ad_meta_fileno(ad) = -1;
         ad->ad_mdp->adf_refcount = 0;
     }
-    LOG(log_debug, logtype_default,
+    LOG(log_debug, logtype_ad,
         "ad_open_hf_v2(\"%s\", %s): END: %d [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
         fullpathname(path), adflags2logstr(adflags), ret,
         ad_data_fileno(ad), ad->ad_data_fork.adf_refcount,
@@ -1022,18 +1037,17 @@ EC_CLEANUP:
 static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble *ad)
 {
     EC_INIT;
-    ssize_t rforklen;
     int oflags;
     int opened = 0;
 
-    LOG(log_debug, logtype_default,
+    LOG(log_debug, logtype_ad,
         "ad_open_hf_ea(\"%s\", %s): BEGIN [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
         fullpathname(path), adflags2logstr(adflags),
         ad_data_fileno(ad), ad->ad_data_fork.adf_refcount,
         ad_meta_fileno(ad), ad->ad_mdp->adf_refcount,
         ad_reso_fileno(ad), ad->ad_rfp->adf_refcount);
 
-    oflags = O_NOFOLLOW | (ad2openflags(ad, ADFLAGS_DF, adflags) & ~(O_CREAT | O_TRUNC));
+    oflags = ad2openflags(ad, ADFLAGS_DF, adflags) & ~(O_CREAT | O_TRUNC);
 
     if (ad_meta_fileno(ad) == AD_SYMLINK)
         goto EC_CLEANUP;
@@ -1043,7 +1057,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble
         if ((oflags & O_RDWR) &&
             /* and it was already denied: */
             (ad->ad_mdp->adf_flags & O_RDONLY)) {
-            LOG(log_error, logtype_default, "ad_open_hf_ea(%s): rw request for ro file: %s",
+            LOG(log_error, logtype_ad, "ad_open_hf_ea(%s): rw request for ro file: %s",
                 fullpathname(path), strerror(errno));
             errno = EACCES;
             EC_FAIL;
@@ -1056,7 +1070,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble
             if (adflags & ADFLAGS_DIR)
                 /* For directories we open the directory RDONYL so we can later fchdir()  */
                 oflags = (oflags & ~O_RDWR) | O_RDONLY;
-            LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): opening base file for meta adouble EA", path);
+            LOG(log_debug, logtype_ad, "ad_open_hf_ea(\"%s\"): opening base file for meta adouble EA", path);
             EC_NEG1(ad_meta_fileno(ad) = open(path, oflags));
             opened = 1;
             ad->ad_mdp->adf_flags = oflags;
@@ -1066,16 +1080,16 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble
     /* Read the adouble header in and parse it.*/
     if (ad->ad_ops->ad_header_read(path, ad, NULL) != 0) {
         if (!(adflags & ADFLAGS_CREATE)) {
-            LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): can't read metadata EA", path);
+            LOG(log_debug, logtype_ad, "ad_open_hf_ea(\"%s\"): can't read metadata EA", path);
             errno = ENOENT;
             EC_FAIL;
         }
 
-        LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): creating metadata EA", path);
+        LOG(log_debug, logtype_ad, "ad_open_hf_ea(\"%s\"): creating metadata EA", path);
 
         /* It doesnt exist, EPERM or another error */
         if (!(errno == ENOATTR || errno == ENOENT)) {
-            LOG(log_error, logtype_default, "ad_open_hf_ea: unexpected: %s", strerror(errno));
+            LOG(log_error, logtype_ad, "ad_open_hf_ea: unexpected: %s", strerror(errno));
             EC_FAIL;
         }
 
@@ -1083,7 +1097,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble
         EC_NEG1_LOG(new_ad_header(ad, path, NULL, adflags));
         ad->ad_mdp->adf_flags |= O_CREAT; /* mark as just created */
         ad_flush(ad);
-        LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): created metadata EA", path);
+        LOG(log_debug, logtype_ad, "ad_open_hf_ea(\"%s\"): created metadata EA", path);
     }
 
     if (ad_meta_fileno(ad) != -1)
@@ -1096,7 +1110,7 @@ EC_CLEANUP:
         ad_meta_fileno(ad) = -1;
         ad->ad_mdp->adf_refcount = 0;
     }
-    LOG(log_debug, logtype_default,
+    LOG(log_debug, logtype_ad,
         "ad_open_hf_ea(\"%s\", %s): END: %d [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
         fullpathname(path), adflags2logstr(adflags), ret,
         ad_data_fileno(ad), ad->ad_data_fork.adf_refcount,
@@ -1125,7 +1139,9 @@ static int ad_open_hf(const char *path, int adflags, int mode, struct adouble *a
         break;
     }
 
-    if (ret != 0)
+    if (ret == 0)
+        ad->ad_meta_refcount++;
+    else
         ret = ad_error(ad, adflags);
 
     return ret;
@@ -1144,7 +1160,7 @@ static int ad_reso_size(const char *path, int adflags, struct adouble *ad)
         goto EC_CLEANUP;
     }
 
-    LOG(log_debug, logtype_default, "ad_reso_size(\"%s\"): BEGIN", path);
+    LOG(log_debug, logtype_ad, "ad_reso_size(\"%s\"): BEGIN", path);
 
 #ifdef HAVE_EAFD
     ssize_t easz;
@@ -1168,7 +1184,7 @@ static int ad_reso_size(const char *path, int adflags, struct adouble *ad)
         ad->ad_rlen = 0;
 #endif
 
-    LOG(log_debug, logtype_default, "ad_reso_size(\"%s\"): size: %zd", path, ad->ad_rlen);
+    LOG(log_debug, logtype_ad, "ad_reso_size(\"%s\"): size: %zd", path, ad->ad_rlen);
 
 EC_CLEANUP:
     if (ret != 0)
@@ -1178,13 +1194,23 @@ EC_CLEANUP:
 
 static int ad_open_rf_v2(const char *path, int adflags, int mode, struct adouble *ad)
 {
+    EC_INIT;
+
     /*
      * ad_open_hf_v2() does the work, but if it failed and adflags are ADFLAGS_NOHF | ADFLAGS_RF
      * ad_open_hf_v2() didn't give an error, but we're supposed to return a reso fork fd
      */
-    if (!AD_RSRC_OPEN(ad) && !(adflags & ADFLAGS_NORF))
-        return -1;
-    return 0;
+
+    LOG(log_debug, logtype_ad, "ad_open_rf_v2(\"%s\"): BEGIN", fullpathname(path));
+
+    if (!AD_META_OPEN(ad) && !(adflags & ADFLAGS_NORF))
+        EC_FAIL;
+    if (AD_META_OPEN(ad))
+        ad->ad_reso_refcount++;
+
+EC_CLEANUP:
+    LOG(log_debug, logtype_ad, "ad_open_rf_v2(\"%s\"): END: %d", fullpathname(path), ret);
+    EC_EXIT;
 }
 
 static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble *ad)
@@ -1193,15 +1219,14 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble
     int oflags;
     int opened = 0;
     int closeflags = adflags & (ADFLAGS_DF | ADFLAGS_HF);
-    ssize_t rlen;
 #ifndef HAVE_EAFD
     const char *rfpath;
     struct stat st;
 #endif
 
-    LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): BEGIN", fullpathname(path));
+    LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): BEGIN", fullpathname(path));
 
-    oflags = O_NOFOLLOW | (ad2openflags(ad, ADFLAGS_RF, adflags) & ~O_CREAT);
+    oflags = ad2openflags(ad, ADFLAGS_RF, adflags) & ~O_CREAT;
 
     if (ad_reso_fileno(ad) != -1) {
         /* the file is already open, but we want write access: */
@@ -1235,27 +1260,28 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble
             EC_FAIL;
         oflags |= O_CREAT;
         EC_NEG1_LOG( ad_reso_fileno(ad) = open(rfpath, oflags, mode) );
-        LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): created adouble rfork: \"%s\"",
+        LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): created adouble rfork: \"%s\"",
             path, rfpath);
     }
 #endif
     opened = 1;
     ad->ad_rfp->adf_refcount = 1;
     ad->ad_rfp->adf_flags = oflags;
+    ad->ad_reso_refcount++;
 
 #ifndef HAVE_EAFD
     EC_ZERO_LOG( fstat(ad_reso_fileno(ad), &st) );
     if (ad->ad_rfp->adf_flags & O_CREAT) {
         /* This is a new adouble header file, create it */
-        LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): created adouble rfork, initializing: \"%s\"",
+        LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): created adouble rfork, initializing: \"%s\"",
             path, rfpath);
         EC_NEG1_LOG( new_ad_header(ad, path, NULL, adflags) );
-        LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): created adouble rfork, flushing: \"%s\"",
+        LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): created adouble rfork, flushing: \"%s\"",
             path, rfpath);
         ad_flush(ad);
     } else {
         /* Read the adouble header */
-        LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): reading adouble rfork: \"%s\"",
+        LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): reading adouble rfork: \"%s\"",
             path, rfpath);
         EC_NEG1_LOG( ad_header_read_osx(NULL, ad, &st) );
     }
@@ -1268,6 +1294,7 @@ EC_CLEANUP:
         if (opened && (ad_reso_fileno(ad) != -1)) {
             close(ad_reso_fileno(ad));
             ad_reso_fileno(ad) = -1;
+            ad->ad_reso_refcount--;
             ad->ad_rfp->adf_refcount = 0;
         }
         if (adflags & ADFLAGS_NORF) {
@@ -1280,7 +1307,7 @@ EC_CLEANUP:
         ad->ad_rlen = 0;
     }
 
-    LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): END: %d", fullpathname(path), ret);
+    LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): END: %d", fullpathname(path), ret);
 
     EC_EXIT;
 }
@@ -1478,7 +1505,7 @@ int ad_stat(const char *path, struct stat *stbuf)
     p = ad_dir(path);
     if (!p)
         return -1;
-    return lstat( p, stbuf );
+    return stat( p, stbuf );
 }
 
 /* ----------------
@@ -1500,7 +1527,7 @@ int ad_mkdir( const char *path, mode_t mode)
     int st_invalid;
     struct stat stbuf;
 
-    LOG(log_debug, logtype_default, "ad_mkdir(\"%s\", %04o) {cwd: \"%s\"}",
+    LOG(log_debug, logtype_ad, "ad_mkdir(\"%s\", %04o) {cwd: \"%s\"}",
         path, mode, getcwdpath());
 
     st_invalid = ad_mode_st(path, &mode, &stbuf);
@@ -1603,7 +1630,7 @@ int ad_open(struct adouble *ad, const char *path, int adflags, ...)
     va_list args;
     mode_t mode = 0;
 
-    LOG(log_debug, logtype_default,
+    LOG(log_debug, logtype_ad,
         "ad_open(\"%s\", %s): BEGIN {d: %d, m: %d, r: %d}"
         "[dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
         fullpathname(path), adflags2logstr(adflags),
@@ -1650,17 +1677,13 @@ int ad_open(struct adouble *ad, const char *path, int adflags, ...)
     }
 
     if (adflags & ADFLAGS_HF) {
-        ad->ad_meta_refcount++;
         if (ad_open_hf(path, adflags, mode, ad) != 0) {
-            ad->ad_meta_refcount--;
             EC_FAIL;
         }
     }
 
     if (adflags & ADFLAGS_RF) {
-        ad->ad_reso_refcount++;
         if (ad_open_rf(path, adflags, mode, ad) != 0) {
-            ad->ad_reso_refcount--;
             EC_FAIL;
         }
     }
@@ -1670,7 +1693,7 @@ int ad_open(struct adouble *ad, const char *path, int adflags, ...)
     }
 
 EC_CLEANUP:
-    LOG(log_debug, logtype_default,
+    LOG(log_debug, logtype_ad,
         "ad_open(\"%s\"): END: %d {d: %d, m: %d, r: %d}"
         "[dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
         fullpathname(path), ret,
@@ -1734,7 +1757,7 @@ int ad_metadataat(int dirfd, const char *name, int flags, struct adouble *adp)
     if (dirfd != -1) {
 
         if (fchdir(cwdfd) != 0) {
-            LOG(log_error, logtype_afpd, "ad_openat: cant chdir back, exiting");
+            LOG(log_error, logtype_ad, "ad_openat: cant chdir back, exiting");
             exit(EXITERR_SYS);
         }
     }
index ed7c0cb4da2b182b93a7c203e615403751682bb0..852a6e963b94f964e3b47d1ea8b67df6cac0717e 100644 (file)
@@ -62,7 +62,6 @@ ssize_t adf_pread(struct ad_fd *ad_fd, void *buf, size_t count, off_t offset)
 ssize_t ad_read( struct adouble *ad, const uint32_t eid, off_t off, char *buf, const size_t buflen)
 {
     ssize_t     cc;
-    ssize_t     rlen;
     off_t r_off = 0;
 
     /* We're either reading the data fork (and thus the data file)
index 337ff6ed3d5f07075ff286dfa58964488c9158f4..6b4ed96d40a9fd09a8173becbce1d28dca3d43f6 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: ad_size.c,v 1.8 2010-02-26 14:13:16 didg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
index bfed9b400f27f8fd577310bc4052a76e2e6a5017..a807c1de748e7ae0da06f93f9643654cee0dbbac 100644 (file)
@@ -52,7 +52,6 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha
     EC_INIT;
     struct stat                st;
     ssize_t            cc;
-    size_t roundup;
     off_t    r_off;
 
     if (ad_data_fileno(ad) == AD_SYMLINK) {
@@ -60,7 +59,7 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha
         return -1;
     }
 
-    LOG(log_debug, logtype_default, "ad_write: off: %ju, size: %zu, eabuflen: %zu",
+    LOG(log_debug, logtype_ad, "ad_write: off: %ju, size: %zu, eabuflen: %zu",
         (uintmax_t)off, buflen, ad->ad_rlen);
     
     if ( eid == ADEID_DFORK ) {
@@ -94,7 +93,6 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha
         return -1; /* we don't know how to write if it's not a ressource or data fork */
     }
 
-EC_CLEANUP:
     if (ret != 0)
         return ret;
     return( cc );
@@ -174,7 +172,7 @@ EC_CLEANUP:
     if (ret == 0)
         ad->ad_rlen = size;    
     else
-        LOG(log_error, logtype_default, "ad_rtruncate(\"%s\"): %s",
+        LOG(log_error, logtype_ad, "ad_rtruncate(\"%s\"): %s",
             fullpathname(ad->ad_name), strerror(errno));
     EC_EXIT;
 }
@@ -182,7 +180,7 @@ EC_CLEANUP:
 int ad_dtruncate(struct adouble *ad, const off_t size)
 {
     if (sys_ftruncate(ad_data_fileno(ad), size) < 0) {
-        LOG(log_error, logtype_default, "sys_ftruncate(fd: %d): %s",
+        LOG(log_error, logtype_ad, "sys_ftruncate(fd: %d): %s",
             ad_data_fileno(ad), strerror(errno));
         return -1;
     }
index 7b59b2e8ee67a9340da551ad81a164a1df544e27..98e1a1553864bf2fc820d080b99ae56ab01b295b 100644 (file)
@@ -1,5 +1,4 @@
 /*
-  $Id: bstradd.c,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $
   Copyright (c) 2010 Frank Lahm <franklahm@gmail.com>
 
   This program is free software; you can redistribute it and/or modify
@@ -77,7 +76,6 @@
  */
 bstring brefcstr (char *str) {
     bstring b;
-    int i;
     size_t j;
 
        if (str == NULL)
@@ -90,7 +88,7 @@ bstring brefcstr (char *str) {
 
        b->slen = (int) j;
     b->mlen = -1;
-    b->data = str;
+    b->data = (unsigned char *)str;
 
        return b;
 }
index 92f8ce6846c65ff9448e482623d6732fffc18eb0..d34a418b7e3cef4b623912d2008a4f54cec5a04e 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_cdb_close.c,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
index 1d14640af1fb68c77b2e9903a07385a36e47b619..ace358aa8b617b79a1f01fa0f4d8274b7c8e9822 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_cdb_delete.c,v 1.4 2009-10-29 13:38:16 didg Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
index 9184264ae8ec40f420d7847328fac9050496cb30..f88a9e29c0e103416b9f7f96c21f5bdd70b9447e 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_cdb_meta.c,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
index cf9d905a614cf9bb65293b363084ab6ec14c10cd..e8a4bdd050b2abe559e816d8928d21fa7a2e25f1 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_cdb_meta.h,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $
  */
 
 #define CNID_META_CNID_LEN      4
index 60141c3bea5f7de7c1e688de9a983f00f21ab3b5..ba14bd8e46fa3d6a28f043d016477ba21307ae06 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_cdb_nextid.c,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
index 056420dad099f1123a6e514f98630055d285fa3a..757d1b0da1e2c3c351ef618679e5ab37b2c64b48 100644 (file)
@@ -144,7 +144,7 @@ static struct _cnid_db *cnid_cdb_new(const char *volpath)
     cdb->cnid_close = cnid_cdb_close;
     cdb->cnid_getstamp = cnid_cdb_getstamp;
     cdb->cnid_rebuild_add = cnid_cdb_rebuild_add;
-
+    cdb->cnid_wipe = NULL;
     return cdb;
 }
 
index be2db1023692be7e7d966b76e23d1773b37ee1a0..4620782e14057f4ce5cf29d7976ad7e6d3c9b885 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_cdb_rebuild_add.c,v 1.6 2009-11-20 17:22:11 didg Exp $
  *
  * All Rights Reserved. See COPYRIGHT.
  *
index 6c16ce7ec6a12b6341d5758075ba1325b7f09945..63ed9f8a1c14b51c9de5837ef32e91ab2713d558 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_cdb_resolve.c,v 1.5 2009-10-29 13:38:16 didg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
index 0a977e6ae8a5f4f469b48b7b037e1811d370ba76..7cf3af1618d19a6de2e0cecada09936aeab90508 100644 (file)
@@ -338,3 +338,15 @@ cnid_t ret;
     unblock_signal(cdb->flags);
     return ret;
 }
+
+/* --------------- */
+int cnid_wipe(struct _cnid_db *cdb)
+{
+    int ret = 0;
+
+    block_signal(cdb->flags);
+    if (cdb->cnid_wipe)
+        ret = cdb->cnid_wipe(cdb);
+    unblock_signal(cdb->flags);
+    return ret;
+}
index 7cc108d3bcf5013dc6724ff96316034b36aad4c8..75fc5db380f94f7a400a070b8eecde3c4abbdf52 100644 (file)
@@ -1,6 +1,5 @@
 
 /* 
- * $Id: cnid_init.c,v 1.3 2009-10-13 22:55:37 didg Exp $
  *
  * Copyright (c) 2003 the Netatalk Team
  * Copyright (c) 2003 Rafal Lewczuk <rlewczuk@pronet.pl>
index 32be8f475408fc644d21d010dc9e76091678d9e4..3f0278ae46aa9678e320e232580c52e53ea38535 100644 (file)
@@ -356,47 +356,18 @@ static int transmit(CNID_private *db, struct cnid_dbd_rqst *rqst, struct cnid_db
     time_t orig, t;
     int clean = 1; /* no errors so far - to prevent sleep on first try */
 
-    if (db->changed) {
-        /* volume and db don't have the same timestamp
-         */
-        return -1;
-    }
     while (1) {
         if (db->fd == -1) {
-            struct cnid_dbd_rqst rqst_stamp;
-            struct cnid_dbd_rply rply_stamp;
-            char  stamp[ADEDLEN_PRIVSYN];
-
             LOG(log_maxdebug, logtype_cnid, "transmit: connecting to cnid_dbd ...");
             if ((db->fd = init_tsock(db)) < 0) {
                 goto transmit_fail;
             }
-            dbd_initstamp(&rqst_stamp);
-            memset(stamp, 0, ADEDLEN_PRIVSYN);
-            rply_stamp.name = stamp;
-            rply_stamp.namelen = ADEDLEN_PRIVSYN;
-
-            if (dbd_rpc(db, &rqst_stamp, &rply_stamp) < 0)
-                goto transmit_fail;
-            if (dbd_reply_stamp(&rply_stamp ) < 0)
-                goto transmit_fail;
-
             if (db->notfirst) {
-                LOG(log_debug7, logtype_cnid, "transmit: reconnected to cnid_dbd, comparing database stamps...");
-                if (memcmp(stamp, db->stamp, ADEDLEN_PRIVSYN)) {
-                    LOG(log_error, logtype_cnid, "transmit: ... not the same db!");
-                    db->changed = 1;
-                    return -1;
-                }
-                LOG(log_debug7, logtype_cnid, "transmit: ... OK.");
+                LOG(log_debug7, logtype_cnid, "transmit: reconnected to cnid_dbd");
             } else { /* db->notfirst == 0 */
                 db->notfirst = 1;
-                if (db->client_stamp)
-                    memcpy(db->client_stamp, stamp, ADEDLEN_PRIVSYN);
-                memcpy(db->stamp, stamp, ADEDLEN_PRIVSYN);
             }
-            LOG(log_debug, logtype_cnid, "transmit: attached to '%s', stamp: '%08lx'.",
-                db->db_dir, *(uint64_t *)stamp);
+            LOG(log_debug, logtype_cnid, "transmit: attached to '%s'", db->db_dir);
         }
         if (!dbd_rpc(db, rqst, rply)) {
             LOG(log_maxdebug, logtype_cnid, "transmit: {done}");
@@ -456,7 +427,7 @@ static struct _cnid_db *cnid_dbd_new(const char *volpath)
     cdb->cnid_update = cnid_dbd_update;
     cdb->cnid_rebuild_add = cnid_dbd_rebuild_add;
     cdb->cnid_close = cnid_dbd_close;
-
+    cdb->cnid_wipe = cnid_dbd_wipe;
     return cdb;
 }
 
@@ -531,6 +502,32 @@ void cnid_dbd_close(struct _cnid_db *cdb)
     return;
 }
 
+/**
+ * Get the db stamp
+ **/
+static int cnid_dbd_stamp(CNID_private *db)
+{
+    struct cnid_dbd_rqst rqst_stamp;
+    struct cnid_dbd_rply rply_stamp;
+    char  stamp[ADEDLEN_PRIVSYN];
+
+    dbd_initstamp(&rqst_stamp);
+    memset(stamp, 0, ADEDLEN_PRIVSYN);
+    rply_stamp.name = stamp;
+    rply_stamp.namelen = ADEDLEN_PRIVSYN;
+
+    if (transmit(db, &rqst_stamp, &rply_stamp) < 0)
+        return -1;
+    if (dbd_reply_stamp(&rply_stamp ) < 0)
+        return -1;
+
+    if (db->client_stamp)
+        memcpy(db->client_stamp, stamp, ADEDLEN_PRIVSYN);
+    memcpy(db->stamp, stamp, ADEDLEN_PRIVSYN);
+
+    return 0;
+}
+
 /* ---------------------- */
 cnid_t cnid_dbd_add(struct _cnid_db *cdb, const struct stat *st,
                     cnid_t did, const char *name, size_t len, cnid_t hint)
@@ -566,8 +563,8 @@ cnid_t cnid_dbd_add(struct _cnid_db *cdb, const struct stat *st,
     rqst.name = name;
     rqst.namelen = len;
 
-    LOG(log_debug, logtype_cnid, "cnid_dbd_add: CNID: %u, name: '%s', inode: 0x%llx, type: %d (0=file, 1=dir)",
-        ntohl(did), name, (long long)st->st_ino, rqst.type);
+    LOG(log_debug, logtype_cnid, "cnid_dbd_add: CNID: %u, name: '%s', dev: 0x%llx, inode: 0x%llx, type: %s",
+        ntohl(did), name, (long long)rqst.dev, (long long)st->st_ino, rqst.type ? "dir" : "file");
 
     rply.namelen = 0;
     if (transmit(db, &rqst, &rply) < 0) {
@@ -706,7 +703,9 @@ char *cnid_dbd_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t le
     return name;
 }
 
-/* ---------------------- */
+/**
+ * Caller passes buffer where we will store the db stamp
+ **/
 int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, const size_t len)
 {
     CNID_private *db;
@@ -718,8 +717,8 @@ int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, const size_t len)
     }
     db->client_stamp = buffer;
     db->stamp_size = len;
-    memset(buffer,0, len);
-    return 0;
+
+    return cnid_dbd_stamp(db);
 }
 
 /* ---------------------- */
@@ -994,6 +993,39 @@ int cnid_dbd_delete(struct _cnid_db *cdb, const cnid_t id)
     }
 }
 
+int cnid_dbd_wipe(struct _cnid_db *cdb)
+{
+    CNID_private *db;
+    struct cnid_dbd_rqst rqst;
+    struct cnid_dbd_rply rply;
+
+    if (!cdb || !(db = cdb->_private)) {
+        LOG(log_error, logtype_cnid, "cnid_wipe: Parameter error");
+        errno = CNID_ERR_PARAM;
+        return -1;
+    }
+
+    LOG(log_debug, logtype_cnid, "cnid_dbd_wipe");
+
+    RQST_RESET(&rqst);
+    rqst.op = CNID_DBD_OP_WIPE;
+    rqst.cnid = 0;
+
+    rply.namelen = 0;
+    if (transmit(db, &rqst, &rply) < 0) {
+        errno = CNID_ERR_DB;
+        return -1;
+    }
+
+    if (rply.result != CNID_DBD_RES_OK) {
+        errno = CNID_ERR_DB;
+        return -1;
+    }
+    LOG(log_debug, logtype_cnid, "cnid_dbd_wipe: ok");
+
+    return cnid_dbd_stamp(db);
+}
+
 
 struct _cnid_module cnid_dbd_module = {
     "dbd",
index fdba4c042a62591e3e771ed449ad7de6588986ca..69ff5a64fb252a0e8424a76ebb9e688eded6174b 100644 (file)
@@ -32,7 +32,7 @@ extern int    cnid_dbd_update     (struct _cnid_db *, cnid_t, const struct stat
 extern int    cnid_dbd_delete     (struct _cnid_db *, const cnid_t);
 extern cnid_t cnid_dbd_rebuild_add(struct _cnid_db *, const struct stat *,
                                    cnid_t, const char *, size_t, cnid_t);
-
+extern int    cnid_dbd_wipe       (struct _cnid_db *cdb);
 /* FIXME: These functions could be static in cnid_dbd.c */
 
 #endif /* include/atalk/cnid_dbd.h */
index 5903d03fe449da281238818e9501c57e812cf9f1..cc2ae1c7d19e79ec3ef8ae13c14936bc491908b7 100644 (file)
@@ -1,6 +1,5 @@
 
 /*
- * $Id: cnid_last.c,v 1.5 2010-03-31 09:47:32 franklahm Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
@@ -139,7 +138,8 @@ static struct _cnid_db *cnid_last_new(const char *volpath)
     cdb->cnid_resolve = cnid_last_resolve;
     cdb->cnid_update = cnid_last_update;
     cdb->cnid_close = cnid_last_close;
-    
+    cdb->cnid_wipe = NULL;
+
     return cdb;
 }
 
index fcb43fa2f6488d5d725a79ee43cec230571e96a3..3203eda94a9f80de30e180f44bd3744755d65b92 100644 (file)
@@ -93,7 +93,7 @@ static int add_cnid (struct _cnid_tdb_private *db, TDB_DATA *key, TDB_DATA *data
     }
 
     /* did/name database */
-    altkey.dptr = (char *) data->dptr +CNID_DID_OFS;
+    altkey.dptr = data->dptr +CNID_DID_OFS;
     altkey.dsize = data->dsize -CNID_DID_OFS;
     if (tdb_store(db->tdb_didname, altkey, altdata, TDB_REPLACE)) {
         goto abort;
@@ -112,7 +112,7 @@ static cnid_t get_cnid(struct _cnid_tdb_private *db)
     
     memset(&rootinfo_key, 0, sizeof(rootinfo_key));
     memset(&data, 0, sizeof(data));
-    rootinfo_key.dptr = ROOTINFO_KEY;
+    rootinfo_key.dptr = (unsigned char *)ROOTINFO_KEY;
     rootinfo_key.dsize = ROOTINFO_KEYLEN;
     
     tdb_chainlock(db->tdb_didname, rootinfo_key);  
@@ -136,7 +136,7 @@ static cnid_t get_cnid(struct _cnid_tdb_private *db)
     }
     
     memset(&data, 0, sizeof(data));
-    data.dptr = (char *)&hint;
+    data.dptr = (unsigned char *)&hint;
     data.dsize = sizeof(hint);
     if (tdb_store(db->tdb_didname, rootinfo_key, data, TDB_REPLACE)) {
         goto cleanup;
@@ -181,7 +181,7 @@ cnid_t cnid_tdb_add(struct _cnid_db *cdb, const struct stat *st,
     memset(&key, 0, sizeof(key));
     memset(&data, 0, sizeof(data));
 
-    key.dptr = (char *)&hint;
+    key.dptr = (unsigned char *)&hint;
     key.dsize = sizeof(cnid_t);
     if ((data.dptr = make_tdb_data(cdb->flags, lstp, did, name, len)) == NULL) {
         LOG(log_error, logtype_default, "tdb_add: Path name is too long");
index cbe89a6e8a8dcd415b3f63fafb198c808057c419..c500181611549fb49deeddfabe646c30ec6aa6c8 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_tdb_close.c,v 1.3 2009-11-21 13:38:11 didg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
index aa801e584ac29c43a16be416e2a881771fb52d2b..a16a99519327bcab826589b3995524b44a67b2d0 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_tdb_delete.c,v 1.4 2009-11-20 19:25:05 didg Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
@@ -26,7 +25,7 @@ int cnid_tdb_delete(struct _cnid_db *cdb, const cnid_t id)
     memset(&key, 0, sizeof(key));
     memset(&data, 0, sizeof(data));
 
-    key.dptr  = (char *)&id;
+    key.dptr  = (unsigned char *)&id;
     key.dsize = sizeof(cnid_t);
     data = tdb_fetch(db->tdb_cnid, key);
     if (!data.dptr)
@@ -40,7 +39,7 @@ int cnid_tdb_delete(struct _cnid_db *cdb, const cnid_t id)
     key.dsize = CNID_DEVINO_LEN;
     tdb_delete(db->tdb_devino, key); 
 
-    key.dptr = (char *)data.dptr +CNID_DID_OFS;
+    key.dptr = data.dptr +CNID_DID_OFS;
     key.dsize = data.dsize -CNID_DID_OFS;
     tdb_delete(db->tdb_didname, key); 
 
index 8321d04e868eb20469c061bd08c0057c7dacc7ae..4e7f638dd18debb62470bc4f19b7bcb58be589e7 100644 (file)
@@ -26,7 +26,7 @@ cnid_t cnid_tdb_get(struct _cnid_db *cdb, cnid_t did, const char *name, size_t l
     buf += sizeof(did);
     memcpy(buf, name, len);
     *(buf + len) = '\0'; /* Make it a C-string. */
-    key.dptr = start;
+    key.dptr = (unsigned char *)start;
     key.dsize = CNID_DID_LEN + len + 1;
     data = tdb_fetch(db->tdb_didname, key);
     if (!data.dptr)
index f095cd54b9c989e186e66360177b0c4bc4f8110a..c95631afee52574c292cb0534b85b6a407cc6e0f 100644 (file)
@@ -25,7 +25,7 @@ cnid_t cnid_tdb_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did,
         return 0;
     }
 
-    if ((buf = make_tdb_data(cdb->flags, st, did, name, len)) == NULL) {
+    if ((buf = (char *)make_tdb_data(cdb->flags, st, did, name, len)) == NULL) {
         LOG(log_error, logtype_default, "tdb_lookup: Pathname is too long");
         return 0;
     }
@@ -42,7 +42,7 @@ cnid_t cnid_tdb_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did,
     memcpy(dev, buf + CNID_DEV_OFS, CNID_DEV_LEN);
     memcpy(ino, buf + CNID_INO_OFS, CNID_INO_LEN);
 
-    key.dptr = buf +CNID_DEVINO_OFS;
+    key.dptr = (unsigned char *)buf + CNID_DEVINO_OFS;
     key.dsize  = CNID_DEVINO_LEN;
     cniddata = tdb_fetch(db->tdb_devino, key);
     if (!cniddata.dptr) {
@@ -66,7 +66,7 @@ cnid_t cnid_tdb_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did,
     }
 
     /* did/name now */
-    key.dptr = buf + CNID_DID_OFS;
+    key.dptr = (unsigned char *)buf + CNID_DID_OFS;
     key.dsize = CNID_DID_LEN + len + 1;
     cniddata = tdb_fetch(db->tdb_didname, key);
     if (!cniddata.dptr) {
index 8aefa42b2278c6f34696d095451ff7e375a2b62e..8e7b12616f0a9f3020e03f743bef034fdd6ce543 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_tdb_nextid.c,v 1.2 2005-04-28 20:50:02 bfernhomberg Exp $
  */
 
 #ifdef HAVE_CONFIG_H
index d02ef0bcc054caa1da65ab3ccfa5f6c5885a8b5a..0aee5b4df5469ddbb3282c8d23d67f35f3bb3837 100644 (file)
@@ -56,7 +56,8 @@ static struct _cnid_db *cnid_tdb_new(const char *volpath)
     cdb->cnid_resolve = cnid_tdb_resolve;
     cdb->cnid_update = cnid_tdb_update;
     cdb->cnid_close = cnid_tdb_close;
-    
+    cdb->cnid_wipe = NULL;
+
     return cdb;
 }
 
@@ -124,14 +125,14 @@ struct _cnid_db *cnid_tdb_open(struct cnid_open_args *args)
      * to change the format in any way. */
     memset(&key, 0, sizeof(key));
     memset(&data, 0, sizeof(data));
-    key.dptr = DBVERSION_KEY;
+    key.dptr = (unsigned char *)DBVERSION_KEY;
     key.dsize = DBVERSION_KEYLEN;
 
     data = tdb_fetch(db->tdb_didname, key);
     if (!data.dptr) {
         uint32_t version = htonl(DBVERSION);
 
-        data.dptr = (char *)&version;
+        data.dptr = (unsigned char *)&version;
         data.dsize = sizeof(version);
         if (tdb_store(db->tdb_didname, key, data, TDB_REPLACE)) {
             LOG(log_error, logtype_default, "tdb_open: Error putting new version");
index 5e8312222ca377b7e8e25bcf27d53b9017e6afb3..851f9e55e7be86811bb4106018411f0cc98b5a30 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: cnid_tdb_resolve.c,v 1.4 2009-11-22 14:14:05 franklahm Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -19,7 +18,7 @@ char *cnid_tdb_resolve(struct _cnid_db *cdb, cnid_t * id, void *buffer, size_t l
     if (!cdb || !(db = cdb->_private) || !id || !(*id)) {
         return NULL;
     }
-    key.dptr  = (char *)id;
+    key.dptr  = (unsigned char *)id;
     key.dsize = sizeof(cnid_t);
     data = tdb_fetch(db->tdb_cnid, key);
     if (data.dptr) 
index d367334e06126c8f903fe8bea20d1a0d7efea0b1..6d23b109f528ab71aad7de553339d534fd85431e 100644 (file)
@@ -38,7 +38,7 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
         free(altdata.dptr);
 
         if (data.dptr) {
-            key.dptr = (char *)data.dptr +CNID_DID_OFS;
+            key.dptr = (unsigned char *)data.dptr +CNID_DID_OFS;
             key.dsize = data.dsize - CNID_DID_OFS;
             tdb_delete(db->tdb_didname, key); 
         
@@ -49,7 +49,7 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     /* search by did/name */
     data.dptr = make_tdb_data(cdb->flags, st, did, name, len);
     data.dsize = CNID_HEADER_LEN + len + 1;
-    key.dptr = (char *)data.dptr +CNID_DID_OFS;
+    key.dptr = (unsigned char *)data.dptr +CNID_DID_OFS;
     key.dsize = data.dsize - CNID_DID_OFS;
     altdata = tdb_fetch(db->tdb_didname, key);
     if (altdata.dptr) {
@@ -76,7 +76,7 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     memcpy(data.dptr, &id, sizeof(id));
 
     /* Update the old CNID with the new info. */
-    key.dptr = (char *) &id;
+    key.dptr = (unsigned char *) &id;
     key.dsize = sizeof(id);
     if (tdb_store(db->tdb_cnid, key, data, TDB_REPLACE)) {
         goto update_err;
@@ -85,13 +85,13 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
     /* Put in a new dev/ino mapping. */
     key.dptr = data.dptr +CNID_DEVINO_OFS;
     key.dsize = CNID_DEVINO_LEN;
-    altdata.dptr  = (char *) &id;
+    altdata.dptr  = (unsigned char *) &id;
     altdata.dsize = sizeof(id);
     if (tdb_store(db->tdb_devino, key, altdata, TDB_REPLACE)) {
         goto update_err;
     }
     /* put in a new did/name mapping. */
-    key.dptr = (char *) data.dptr +CNID_DID_OFS;
+    key.dptr = (unsigned char *) data.dptr +CNID_DID_OFS;
     key.dsize = data.dsize -CNID_DID_OFS;
 
     if (tdb_store(db->tdb_didname, key, altdata, TDB_REPLACE)) {
index 2716bb8f955ca79c002dde8237f8107f4141f7e5..481978b9f42f67f8f5897623c9bd62ba66810196 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: getusershell.c,v 1.4 2003-02-17 01:51:08 srittau Exp $
  *
  * Copyright (c) 1985 Regents of the University of California.
  * All rights reserved.
index ddbfe2d5f88a338e4722db6cc5b42a79a7a8353e..8faae19336149d309234b182002bdead6c3d9cdd 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: mktemp.c,v 1.4 2003-02-17 01:51:08 srittau Exp $
  *
  * Copyright (c) 1987 Regents of the University of California.
  * All rights reserved.
index 03dd3bb601f1d6cb849d43736c5017aa461a649d..eb73c9754e88c4a5c4c29778c8ddb32c1304f28f 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: rquota_xdr.c,v 1.4 2003-02-17 01:51:08 srittau Exp $
  *
  * taken from the quota-1.55 used on linux. here's the bsd copyright:
  *
index 5a60c24d5c25d30d223b820b3edf496c89009740..80757712192a8240421d71e8f10cce7588310d1a 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dsi_attn.c,v 1.8 2009-10-25 06:13:11 didg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
index 80bee3fe702a79cfbd18bd7a7ac4bd8539295aaf..892b982eade06df3553c83ab2d7b00a876f1617b 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dsi_close.c,v 1.4 2003-03-12 15:07:06 didg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
index 001279cd74ae6ad717eef7fe01a7880a77b3dfab..cde5def73b19e36edf140dec1f839e12518b303b 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dsi_getsess.c,v 1.7 2005-04-28 20:50:02 bfernhomberg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
@@ -36,7 +35,7 @@
 int dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval, afp_child_t **childp)
 {
   pid_t pid;
-  unsigned int ipc_fds[2];  
+  int ipc_fds[2];  
   afp_child_t *child;
 
   if (socketpair(PF_UNIX, SOCK_STREAM, 0, ipc_fds) < 0) {
@@ -121,7 +120,6 @@ int dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval, afp_chi
     /* set up the tickle timer */
     dsi->timer.it_interval.tv_sec = dsi->timer.it_value.tv_sec = tickleval;
     dsi->timer.it_interval.tv_usec = dsi->timer.it_value.tv_usec = 0;
-    signal(SIGPIPE, SIG_IGN); /* we catch these ourselves */
     dsi_opensession(dsi);
     *childp = NULL;
     return 0;
index aec872ab0c15f1aaea351ddeb9febe44860e9f9a..dac4f76b3760efa38c650d5e7b21dc7ba42d71d6 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dsi_getstat.c,v 1.4 2005-09-07 15:27:29 didg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
index e06e87d92420187948611b9d044995ab158065c6..f73147a81a9565309bcbe518042edf1f6865e106 100644 (file)
@@ -103,9 +103,29 @@ static void dsi_init_buffer(DSI *dsi)
     dsi->end = dsi->buffer + (dsi->dsireadbuf * dsi->server_quantum);
 }
 
+/*!
+ * Free any allocated ressources of the master afpd DSI objects and close server socket
+ */
+void dsi_free(DSI *dsi)
+{
+    close(dsi->serversock);
+    dsi->serversock = -1;
+
+    free(dsi->commands);
+    dsi->commands = NULL;
+
+    free(dsi->buffer);
+    dsi->buffer = NULL;
+
+#ifdef USE_ZEROCONF
+    free(dsi->bonjourname);
+    dsi->bonjourname = NULL;
+#endif
+}
+
 static struct itimerval itimer;
 /* accept the socket and do a little sanity checking */
-static int dsi_tcp_open(DSI *dsi)
+static pid_t dsi_tcp_open(DSI *dsi)
 {
     pid_t pid;
     SOCKLEN_T len;
index 40d0c0ad4cb43376dc0421c4b8fd504708fc15e2..a283d40b82670fbb1b3172788fca1e8bfa62a248 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dsi_tickle.c,v 1.8 2009-10-25 06:13:11 didg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
index 1cf25e64c6516ea65e4144f63eafcd625fdb72d2..65a479e1dac4a89d09fd5785b623715f382d6988 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: dsi_write.c,v 1.5 2009-10-20 04:31:41 didg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
index b44796bb24e30394d70cfd84c81784255b9068e5..f1ff81567aefcccb8da5c45730a8256a40f49920 100644 (file)
@@ -3,7 +3,6 @@
    @file       dictionary.c
    @author     N. Devillard
    @date       Sep 2007
-   @version    $Revision: 1.27 $
    @brief      Implements a dictionary for string variables.
 
    This module implements a simple dictionary object, i.e. a list
 /*--------------------------------------------------------------------------*/
 
 /*
-       $Id: dictionary.c,v 1.27 2007-11-23 21:39:18 ndevilla Exp $
-       $Revision: 1.27 $
 */
 /*---------------------------------------------------------------------------
                                                                Includes
  ---------------------------------------------------------------------------*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
 #include <atalk/dictionary.h>
 #include <atalk/compat.h>
 
index 6e89472b34be54aff750f48a3c53b073fedd04b4..93e14b6b46b55b6b29bbe7802b68ca70b416e881 100644 (file)
@@ -8,6 +8,10 @@
 */
 
 /*---------------------------- Includes ------------------------------------*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
 #include <ctype.h>
 
 #include <atalk/iniparser.h>
@@ -474,8 +478,7 @@ static line_status iniparser_line(
         strcpy(section, strstrip(section));
         strcpy(section, section);
         sta = LINE_SECTION ;
-    } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2
-           ||  sscanf (line, "%[^=] = '%[^\']'",   key, value) == 2
+    } else if (sscanf (line, "%[^=] = '%[^\']'",   key, value) == 2
            ||  sscanf (line, "%[^=] = %[^;#]",     key, value) == 2) {
         /* Usual key=value, with or without comments */
         strcpy(key, strstrip(key));
@@ -529,7 +532,6 @@ dictionary * iniparser_load(const char * ininame)
     char line    [ASCIILINESZ+1] ;
     char section [ASCIILINESZ+1] ;
     char key     [ASCIILINESZ+1] ;
-    char tmp     [ASCIILINESZ+1] ;
     char val     [ASCIILINESZ+1] ;
 
     int  last=0 ;
@@ -571,14 +573,6 @@ dictionary * iniparser_load(const char * ininame)
         len = (int)strlen(line)-1;
         if (len==0)
             continue;
-        /* Safety check against buffer overflows */
-        if (line[len]!='\n') {
-            LOG(log_error, logtype_default, "iniparser: input line too long in \"%s\" (lineno: %d)",
-                ininame, lineno);
-            dictionary_del(dict);
-            fclose(in);
-            return NULL ;
-        }
         /* Get rid of \n and spaces at end of line */
         while ((len>=0) &&
                 ((line[len]=='\n') || (isspace(line[len])))) {
diff --git a/libatalk/libatalk-3.0.1dev.abi b/libatalk/libatalk-3.0.1dev.abi
new file mode 100644 (file)
index 0000000..f671fca
--- /dev/null
@@ -0,0 +1,554 @@
+acl_ldap_readconfig: int (dictionary *)
+ad_close: int (struct adouble *, int)
+ad_convert: int (const char *, const struct stat *, const struct vol *, const char **)
+ad_copy_header: int (struct adouble *, struct adouble *)
+add_cachebyname: int (const char *, const uuidp_t, const uuidtype_t, const long unsigned int)
+add_cachebyuuid: int (uuidp_t, const char *, uuidtype_t, const long unsigned int)
+add_charset: charset_t (const char *)
+ad_dir: char *(const char *)
+ad_dtruncate: int (struct adouble *, const off_t)
+adflags2logstr: const char *(int)
+ad_flush: int (struct adouble *)
+ad_forcegetid: uint32_t (struct adouble *)
+adf_pread: ssize_t (struct ad_fd *, void *, size_t, off_t)
+adf_pwrite: ssize_t (struct ad_fd *, const void *, size_t, off_t)
+ad_getattr: int (const struct adouble *, uint16_t *)
+ad_getdate: int (const struct adouble *, unsigned int, uint32_t *)
+ad_getentryoff: off_t (const struct adouble *, int)
+ad_getfuid: uid_t (void)
+ad_getid: uint32_t (struct adouble *, const dev_t, const ino_t, const cnid_t, const void *)
+ad_hf_mode: mode_t (mode_t)
+ad_init: void (struct adouble *, const struct vol *)
+ad_init_old: void (struct adouble *, int, int)
+ad_lock: int (struct adouble *, uint32_t, int, off_t, off_t, int)
+ad_metadata: int (const char *, int, struct adouble *)
+ad_metadataat: int (int, const char *, int, struct adouble *)
+ad_mkdir: int (const char *, mode_t)
+ad_mode: int (const char *, mode_t)
+ad_open: int (struct adouble *, const char *, int, ...)
+ad_openat: int (struct adouble *, int, const char *, int, ...)
+ad_openforks: uint16_t (struct adouble *, uint16_t)
+ad_path: const char *(const char *, int)
+ad_path_ea: const char *(const char *, int)
+ad_path_osx: const char *(const char *, int)
+ad_read: ssize_t (struct adouble *, const uint32_t, off_t, char *, const size_t)
+ad_readfile_init: int (const struct adouble *, const int, off_t *, const int)
+ad_rebuild_adouble_header_ea: int (struct adouble *)
+ad_rebuild_adouble_header_v2: int (struct adouble *)
+ad_refresh: int (const char *, struct adouble *)
+ad_rtruncate: int (struct adouble *, const off_t)
+ad_setattr: int (const struct adouble *, const uint16_t)
+ad_setdate: int (struct adouble *, unsigned int, uint32_t)
+ad_setfuid: int (const uid_t)
+ad_setid: int (struct adouble *, const dev_t, const ino_t, const uint32_t, const cnid_t, const void *)
+ad_setname: int (struct adouble *, const char *)
+ad_size: off_t (const struct adouble *, const uint32_t)
+ad_stat: int (const char *, struct stat *)
+ad_testlock: int (struct adouble *, int, const off_t)
+ad_tmplock: int (struct adouble *, uint32_t, int, off_t, off_t, int)
+ad_unlock: void (struct adouble *, const int, int)
+ad_valid_header_osx: int (const char *)
+ad_write: ssize_t (struct adouble *, uint32_t, off_t, int, const char *, size_t)
+afp_config_parse: int (AFPObj *, char *)
+allow_severity: 5
+apply_ip_mask: void (struct sockaddr *, int)
+atalk_iconv: size_t (atalk_iconv_t, const char **, size_t *, char **, size_t *)
+atalk_iconv_close: int (atalk_iconv_t)
+atalk_iconv_open: atalk_iconv_t (const char *, const char *)
+atalk_register_charset: int (struct charset_functions *)
+balloc: int (bstring, int)
+ballocmin: int (bstring, int)
+bassign: int (bstring, const_bstring)
+bassignblk: int (bstring, const void *, int)
+bassigncstr: int (bstring, const char *)
+bassignformat: int (bstring, const char *, ...)
+bassigngets: int (bstring, bNgetc, void *, char)
+bassignmidstr: int (bstring, const_bstring, int, int)
+bcatblk: int (bstring, const void *, int)
+bcatcstr: int (bstring, const char *)
+bconcat: int (bstring, const_bstring)
+bconchar: int (bstring, char)
+bcstrfree: int (char *)
+bdelete: int (bstring, int, int)
+bdestroy: int (bstring)
+become_root: void (void)
+bfindreplace: int (bstring, const_bstring, const_bstring, int)
+bfindreplacecaseless: int (bstring, const_bstring, const_bstring, int)
+bformat: bstring (const char *, ...)
+bformata: int (bstring, const char *, ...)
+bfromcstr: bstring (const char *)
+bfromcstralloc: bstring (int, const char *)
+bgetsa: int (bstring, bNgetc, void *, char)
+bgetstream: bstring (bNgetc, void *, char)
+binchr: int (const_bstring, int, const_bstring)
+binchrr: int (const_bstring, int, const_bstring)
+binsert: int (bstring, int, const_bstring, unsigned char)
+binsertch: int (bstring, int, int, unsigned char)
+binstr: int (const_bstring, int, const_bstring)
+binstrcaseless: int (const_bstring, int, const_bstring)
+binstrr: int (const_bstring, int, const_bstring)
+binstrrcaseless: int (const_bstring, int, const_bstring)
+biseq: int (const_bstring, const_bstring)
+biseqcaseless: int (const_bstring, const_bstring)
+biseqcstr: int (const_bstring, const char *)
+biseqcstrcaseless: int (const_bstring, const char *)
+bisstemeqblk: int (const_bstring, const void *, int)
+bisstemeqcaselessblk: int (const_bstring, const void *, int)
+bjoin: bstring (const struct bstrList *, const_bstring)
+bjoinInv: bstring (const struct bstrList *, const_bstring)
+blk2bstr: bstring (const void *, int)
+bltrimws: int (bstring)
+bmidstr: bstring (const_bstring, int, int)
+bninchr: int (const_bstring, int, const_bstring)
+bninchrr: int (const_bstring, int, const_bstring)
+bpattern: int (bstring, int)
+bread: bstring (bNread, void *)
+breada: int (bstring, bNread, void *)
+brefcstr: bstring (char *)
+breplace: int (bstring, int, int, const_bstring, unsigned char)
+brtrimws: int (bstring)
+bsbufflength: int (struct bStream *, int)
+bsclose: void *(struct bStream *)
+bseof: int (const struct bStream *)
+bsetstr: int (bstring, int, const_bstring, unsigned char)
+bsopen: struct bStream *(bNread, void *)
+bspeek: int (bstring, const struct bStream *)
+bsplit: struct bstrList *(const_bstring, unsigned char)
+bsplitcb: int (const_bstring, unsigned char, int, int (*)(void *, int, int), void *)
+bsplits: struct bstrList *(const_bstring, const_bstring)
+bsplitscb: int (const_bstring, const_bstring, int, int (*)(void *, int, int), void *)
+bsplitstr: struct bstrList *(const_bstring, const_bstring)
+bsplitstrcb: int (const_bstring, const_bstring, int, int (*)(void *, int, int), void *)
+bsread: int (bstring, struct bStream *, int)
+bsreada: int (bstring, struct bStream *, int)
+bsreadln: int (bstring, struct bStream *, char)
+bsreadlna: int (bstring, struct bStream *, char)
+bsreadlns: int (bstring, struct bStream *, const_bstring)
+bsreadlnsa: int (bstring, struct bStream *, const_bstring)
+bssplitscb: int (struct bStream *, const_bstring, int (*)(void *, int, const_bstring), void *)
+bssplitstrcb: int (struct bStream *, const_bstring, int (*)(void *, int, const_bstring), void *)
+bstr2cstr: char *(const_bstring, char)
+bstrchrp: int (const_bstring, int, int)
+bstrcmp: int (const_bstring, const_bstring)
+bstrcpy: bstring (const_bstring)
+bstricmp: int (const_bstring, const_bstring)
+bstrListAlloc: int (struct bstrList *, int)
+bstrListAllocMin: int (struct bstrList *, int)
+bstrListCreate: struct bstrList *(void)
+bstrListCreateMin: struct bstrList *(int)
+bstrListDestroy: int (struct bstrList *)
+bstrListPop: bstring (struct bstrList *)
+bstrListPush: int (struct bstrList *, bstring)
+bstrncmp: int (const_bstring, const_bstring, int)
+bstrnicmp: int (const_bstring, const_bstring, int)
+bstrrchrp: int (const_bstring, int, int)
+bsunread: int (struct bStream *, const_bstring)
+btolower: int (bstring)
+btoupper: int (bstring)
+btrimws: int (bstring)
+btrunc: int (bstring, int)
+bunrefcstr: int (bstring)
+bvcformata: int (bstring, int, const char *, struct __va_list_tag *)
+charset_decompose: size_t (charset_t, char *, size_t, char *, size_t)
+charset_mac_centraleurope: {name = "MAC_CENTRALEUROPE", kTextEncoding = 29, pull = <mac_centraleurope_pull>, push = <mac_centraleurope_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_chinese_simp: {name = "MAC_CHINESE_SIMP", kTextEncoding = 25, pull = <mac_chinese_simp_pull>, push = <mac_chinese_simp_push>, flags = 85, iname = "EUC-CN", prev = 0x0, next = 0x0}
+charset_mac_chinese_trad: {name = "MAC_CHINESE_TRAD", kTextEncoding = 2, pull = <mac_chinese_trad_pull>, push = <mac_chinese_trad_push>, flags = 85, iname = "BIG-5", prev = 0x0, next = 0x0}
+charset_mac_cyrillic: {name = "MAC_CYRILLIC", kTextEncoding = 7, pull = <mac_cyrillic_pull>, push = <mac_cyrillic_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_greek: {name = "MAC_GREEK", kTextEncoding = 6, pull = <mac_greek_pull>, push = <mac_greek_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_hebrew: {name = "MAC_HEBREW", kTextEncoding = 5, pull = <mac_hebrew_pull>, push = <mac_hebrew_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_japanese: {name = "MAC_JAPANESE", kTextEncoding = 1, pull = <mac_japanese_pull>, push = <mac_japanese_push>, flags = 85, iname = "SHIFT_JIS", prev = 0x0, next = 0x0}
+charset_mac_korean: {name = "MAC_KOREAN", kTextEncoding = 3, pull = <mac_korean_pull>, push = <mac_korean_push>, flags = 85, iname = "EUC-KR", prev = 0x0, next = 0x0}
+charset_mac_roman: {name = "MAC_ROMAN", kTextEncoding = 0, pull = <mac_roman_pull>, push = <mac_roman_push>, flags = 21, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_turkish: {name = "MAC_TURKISH", kTextEncoding = 35, pull = <mac_turkish_pull>, push = <mac_turkish_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_precompose: size_t (charset_t, char *, size_t, char *, size_t)
+charset_strlower: size_t (charset_t, const char *, size_t, char *, size_t)
+charset_strupper: size_t (charset_t, const char *, size_t, char *, size_t)
+charset_to_ucs2_allocate: size_t (charset_t, uint16_t **, const char *)
+charset_to_utf8_allocate: size_t (charset_t, char **, const char *)
+charset_utf8: {name = "UTF8", kTextEncoding = 134217987, pull = <utf8_pull>, push = <utf8_push>, flags = 22, iname = 0x0, prev = 0x0, next = 0x0}
+charset_utf8_mac: {name = "UTF8-MAC", kTextEncoding = 134217987, pull = <utf8_pull>, push = <utf8_push>, flags = 27, iname = 0x0, prev = 0x0, next = 0x0}
+check_lockfile: int (const char *, const char *)
+cjk_char_pull: size_t (uint16_t, uint16_t *, const uint32_t *)
+cjk_char_push: size_t (uint16_t, uint8_t *)
+cjk_compose: uint16_t (uint16_t, uint16_t, const uint32_t *, size_t)
+cjk_compose_seq: uint16_t (const uint16_t *, size_t *, const uint32_t *, size_t)
+cjk_generic_pull: size_t (size_t (*)(uint16_t *, const uint8_t *, size_t *), void *, char **, size_t *, char **, size_t *)
+cjk_generic_push: size_t (size_t (*)(uint8_t *, const uint16_t *, size_t *), void *, char **, size_t *, char **, size_t *)
+cjk_lookup: uint16_t (uint16_t, const cjk_index_t *, const uint16_t *)
+cnid_add: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, const char *, const size_t, cnid_t)
+cnid_close: void (struct _cnid_db *)
+cnid_dbd_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_dbd_close: void (struct _cnid_db *)
+cnid_dbd_delete: int (struct _cnid_db *, const cnid_t)
+cnid_dbd_find: int (struct _cnid_db *, const char *, size_t, void *, size_t)
+cnid_dbd_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t)
+cnid_dbd_getstamp: int (struct _cnid_db *, void *, const size_t)
+cnid_dbd_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t)
+cnid_dbd_module: {name = "dbd", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 0}
+cnid_dbd_open: struct _cnid_db *(struct cnid_open_args *)
+cnid_dbd_rebuild_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_dbd_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_dbd_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t)
+cnid_delete: int (struct _cnid_db *, cnid_t)
+cnid_find: int (struct _cnid_db *, const char *, size_t, void *, size_t)
+cnid_get: cnid_t (struct _cnid_db *, const cnid_t, char *, const size_t)
+cnid_getstamp: int (struct _cnid_db *, void *, const size_t)
+cnid_init: void (void)
+cnid_last_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_last_close: void (struct _cnid_db *)
+cnid_last_delete: int (struct _cnid_db *, const cnid_t)
+cnid_last_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t)
+cnid_last_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t)
+cnid_last_module: {name = "last", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 0}
+cnid_last_open: struct _cnid_db *(struct cnid_open_args *)
+cnid_last_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_last_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t)
+cnid_lookup: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t)
+cnid_open: struct _cnid_db *(const char *, mode_t, char *, int, const char *, const char *)
+cnid_rebuild_add: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t, cnid_t)
+cnid_register: void (struct _cnid_module *)
+cnid_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_tdb_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_tdb_close: void (struct _cnid_db *)
+cnid_tdb_delete: int (struct _cnid_db *, const cnid_t)
+cnid_tdb_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t)
+cnid_tdb_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t)
+cnid_tdb_module: {name = "tdb", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 12}
+cnid_tdb_open: struct _cnid_db *(struct cnid_open_args *)
+cnid_tdb_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_tdb_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t)
+cnid_update: int (struct _cnid_db *, const cnid_t, const struct stat *, const cnid_t, char *, const size_t)
+compare_ip: int (const struct sockaddr *, const struct sockaddr *)
+convert_charset: size_t (charset_t, charset_t, charset_t, const char *, size_t, char *, size_t, uint16_t *)
+convert_string: size_t (charset_t, charset_t, const void *, size_t, void *, size_t)
+convert_string_allocate: size_t (charset_t, charset_t, const void *, size_t, char **)
+copy_ea: int (const char *, int, const char *, const char *, mode_t)
+copy_file: int (int, const char *, const char *, mode_t)
+copy_file_fd: int (int, int)
+copy_fork: int (int, struct adouble *, struct adouble *)
+create_lockfile: int (const char *, const char *)
+daemonize: int (int, int)
+decompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *)
+deny_severity: 3
+dequeue: void *(q_t *)
+_diacasemap: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 231, 203, 229, 128, 204, 129, 130, 131, 233, 230, 232, 234, 237, 235, 236, 132, 238, 241, 239, 133, 205, 242, 244, 243, 134, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 198, 183, 184, 184, 186, 187, 188, 189, 174, 175, 192, 193, 194, 195, 196, 197, 198, 199...}
+_dialowermap: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 138, 140, 141, 142, 150, 154, 159, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 132, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 190, 191, 176, 177, 178, 179, 180, 181, 198, 183, 185, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199...}
+dictionary_del: void (dictionary *)
+dictionary_dump: void (dictionary *, FILE *)
+dictionary_get: const char *(const dictionary *, const char *, const char *, const char *)
+dictionary_hash: unsigned int (char *)
+dictionary_new: dictionary *(int)
+dictionary_set: int (dictionary *, char *, char *, char *)
+dictionary_unset: void (dictionary *, char *, char *)
+dir_rx_set: int (mode_t)
+dsi_attention: int (DSI *, AFPUserBytes)
+dsi_close: void (DSI *)
+dsi_cmdreply: int (DSI *, const int)
+dsi_disconnect: int (DSI *)
+dsi_getsession: int (DSI *, server_child *, int, afp_child_t **)
+dsi_getstatus: void (DSI *)
+dsi_init: DSI *(AFPObj *, const char *, const char *, const char *)
+dsi_opensession: void (DSI *)
+dsi_read: ssize_t (DSI *, void *, const size_t)
+dsi_readdone: void (DSI *)
+dsi_readinit: ssize_t (DSI *, void *, const size_t, const size_t, const int)
+dsi_stream_read: size_t (DSI *, void *, const size_t)
+dsi_stream_read_file: ssize_t (DSI *, const int, off_t, const size_t, const int)
+dsi_stream_receive: int (DSI *)
+dsi_stream_send: int (DSI *, void *, size_t)
+dsi_stream_write: ssize_t (DSI *, void *, const size_t, int)
+dsi_tcp_init: int (DSI *, const char *, const char *, const char *)
+dsi_tickle: int (DSI *)
+dsi_write: size_t (DSI *, void *, const size_t)
+dsi_writeflush: void (DSI *)
+dsi_writeinit: size_t (DSI *, void *, const size_t)
+ea_chmod_dir: int (const struct vol *, const char *, mode_t, struct stat *)
+ea_chmod_file: int (const struct vol *, const char *, mode_t, struct stat *)
+ea_chown: int (const struct vol *, const char *, uid_t, gid_t)
+ea_close: int (struct ea *)
+ea_copyfile: int (const struct vol *, int, const char *, const char *)
+ea_deletefile: int (const struct vol *, int, const char *)
+ea_open: int (const struct vol *, const char *, eaflags_t, struct ea *)
+ea_openat: int (const struct vol *, int, const char *, eaflags_t, struct ea *)
+ea_path: char *(const struct ea *, const char *, int)
+ea_renamefile: int (const struct vol *, int, const char *, const char *)
+enqueue: qnode_t *(q_t *, void *)
+fault_setup: void (void (*)(void *))
+fdset_add_fd: void (int, struct pollfd **, struct polldata **, int *, int *, int, enum fdtype, void *)
+fdset_del_fd: void (struct pollfd **, struct polldata **, int *, int *, int)
+find_charset_functions: struct charset_functions *(const char *)
+_fini: <text variable, no debug info>
+freeifacelist: void (char **)
+fullpathname: const char *(const char *)
+getcwdpath: const char *(void)
+getdefextmap: struct extmap *(void)
+get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int)
+get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *)
+getextmap: struct extmap *(const char *)
+getifacelist: char **(void)
+getip_port: unsigned int (const struct sockaddr *)
+getip_string: const char *(const struct sockaddr *)
+getnamefromuuid: int (const uuidp_t, char **, uuidtype_t *)
+getuuidfromname: int (const char *, uuidtype_t, unsigned char *)
+getvolbyname: struct vol *(const char *)
+getvolbypath: struct vol *(AFPObj *, const char *)
+getvolbyvid: struct vol *(const uint16_t)
+getvolumes: struct vol *(void)
+gmem: int (gid_t, int, gid_t *)
+iniparser_dump: void (const dictionary *, FILE *)
+iniparser_dump_ini: void (const dictionary *, FILE *)
+iniparser_find_entry: int (const dictionary *, const char *)
+iniparser_freedict: void (dictionary *)
+iniparser_getboolean: int (const dictionary *, const char *, const char *, int)
+iniparser_getdouble: double (const dictionary *, const char *, const char *, double)
+iniparser_getint: int (const dictionary *, const char *, const char *, int)
+iniparser_getnsec: int (const dictionary *)
+iniparser_getsecname: const char *(const dictionary *, int)
+iniparser_getstrdup: char *(const dictionary *, const char *, const char *, const char *)
+iniparser_getstring: const char *(const dictionary *, const char *, const char *, const char *)
+iniparser_load: dictionary *(const char *)
+iniparser_set: int (dictionary *, char *, char *, char *)
+iniparser_unset: void (dictionary *, char *, char *)
+_init: <text variable, no debug info>
+init_iconv: void (void)
+initline: void (int, char *)
+initvol_vfs: void (struct vol *)
+ipc_child_write: int (int, uint16_t, int, void *)
+ipc_client_uds: int (const char *)
+ipc_server_read: int (server_child *, int)
+ipc_server_uds: int (const char *)
+islower_sp: int (uint32_t)
+islower_w: int (uint16_t)
+isupper_sp: int (uint32_t)
+isupper_w: int (uint16_t)
+lchdir: int (const char *)
+ldap_auth_dn: 0x0
+ldap_auth_method: 0
+ldap_auth_pw: 0x0
+ldap_config_valid: 0
+ldap_getnamefromuuid: int (const char *, char **, uuidtype_t *)
+ldap_getuuidfromname: int (const char *, uuidtype_t, char **)
+ldap_group_attr: 0x0
+ldap_groupbase: 0x0
+ldap_groupscope: 0
+ldap_name_attr: 0x0
+ldap_prefs: {{pref = 0x0, name = "ldap server", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap auth method", strorint = 1, intfromarray = 1, valid = -1}, {pref = 0x0, name = "ldap auth dn", strorint = 0, intfromarray = 0, valid = 0}, {pref = 0x0, name = "ldap auth pw", strorint = 0, intfromarray = 0, valid = 0}, {pref = 0x0, name = "ldap userbase", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap userscope", strorint = 1, intfromarray = 1, valid = -1}, {pref = 0x0, name = "ldap groupbase", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap groupscope", strorint = 1, intfromarray = 1, valid = -1}, {pref = 0x0, name = "ldap uuid attr", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap uuid string", strorint = 0, intfromarray = 0, valid = 0}, {pref = 0x0, name = "ldap name attr", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap group attr", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap uid attr", strorint = 0, intfromarray = 0, valid = 0}, {pref = 0x0, name = "ldap uuid encoding", strorint = 1, intfromarray = 1, valid = 0}, {pref = 0x0, name = 0x0, strorint = 0, intfromarray = 0, valid = -1}}
+ldap_server: 0x0
+ldap_uid_attr: 0x0
+ldap_userbase: 0x0
+ldap_userscope: 0
+ldap_uuid_attr: 0x0
+ldap_uuid_encoding: 0
+ldap_uuid_string: 0x0
+list_eas: int (const struct vol *, char *, size_t *, const char *, int)
+load_charset: int (struct vol *)
+load_volumes: int (AFPObj *, void (*)(const AFPObj *, struct vol *))
+localuuid_from_id: void (unsigned char *, uuidtype_t, unsigned int)
+lock_reg: int (int, int, int, off_t, int, off_t)
+log_config: {inited = false, syslog_opened = false, console = false, processname = '\0' <repeats 15 times>, syslog_facility = 0, syslog_display_options = 0}
+lstatat: int (int, const char *, struct stat *)
+make_log_entry: void (enum loglevels, enum logtypes, const char *, int, char *, ...)
+make_tdb_data: unsigned char *(uint32_t, const struct stat *, const cnid_t, const char *, const size_t)
+mb_generic_pull: size_t (int (*)(uint16_t *, const unsigned char *), void *, char **, size_t *, char **, size_t *)
+mb_generic_push: size_t (int (*)(unsigned char *, uint16_t), void *, char **, size_t *, char **, size_t *)
+netatalk_panic: void (const char *)
+netatalk_rmdir: int (int, const char *)
+netatalk_rmdir_all_errors: int (int, const char *)
+netatalk_unlink: int (const char *)
+netatalk_unlinkat: int (int, const char *)
+nftw: int (const char *, nftw_func_t, dir_notification_func_t, int, int)
+opendirat: DIR *(int, const char *)
+openflags2logstr: const char *(int)
+parseline: int (int, char *)
+posix_chmod: int (const char *, mode_t)
+posix_fchmod: int (int, mode_t)
+precompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *)
+prefs_array: {{pref = "ldap auth method", valuestring = "none", value = 0}, {pref = "ldap auth method", valuestring = "simple", value = 128}, {pref = "ldap auth method", valuestring = "sasl", value = 163}, {pref = "ldap userscope", valuestring = "base", value = 0}, {pref = "ldap userscope", valuestring = "one", value = 1}, {pref = "ldap userscope", valuestring = "sub", value = 2}, {pref = "ldap groupscope", valuestring = "base", value = 0}, {pref = "ldap groupscope", valuestring = "one", value = 1}, {pref = "ldap groupscope", valuestring = "sub", value = 2}, {pref = "ldap uuid encoding", valuestring = "ms-guid", value = 1}, {pref = "ldap uuid encoding", valuestring = "string", value = 0}, {pref = 0x0, valuestring = 0x0, value = 0}}
+prequeue: qnode_t *(q_t *, void *)
+queue_destroy: void (q_t *, void (*)(void *))
+queue_init: q_t *(void)
+randombytes: void (void *, int)
+readt: ssize_t (int, void *, const size_t, int, int)
+realpath_safe: char *(const char *)
+reconnect_ipc: int (AFPObj *)
+recv_fd: int (int, int)
+rel_path_in_vol: bstring (const char *, const char *)
+remove_acl_vfs: int (const char *)
+remove_ea: int (const struct vol *, const char *, const char *, int)
+run_cmd: int (const char *, char **)
+search_cachebyname: int (const char *, uuidtype_t *, unsigned char *)
+search_cachebyuuid: int (uuidp_t, char **, uuidtype_t *)
+send_fd: int (int, int)
+server_child_add: afp_child_t *(server_child *, int, pid_t, int)
+server_child_alloc: server_child *(const int, const int)
+server_child_free: void (server_child *)
+server_child_kill: void (server_child *, int, int)
+server_child_kill_one_by_id: void (server_child *, int, pid_t, uid_t, uint32_t, char *, uint32_t)
+server_child_remove: int (server_child *, const int, pid_t)
+server_child_setup: void (server_child *, const int, void (*)(const pid_t))
+server_child_transfer_session: int (server_child *, int, pid_t, uid_t, int, uint16_t)
+server_lock: pid_t (char *, char *, int)
+server_reset_signal: void (void)
+set_charset_name: int (charset_t, const char *)
+set_ea: int (const struct vol *, const char *, const char *, const char *, size_t, int)
+setfilmode: int (const char *, mode_t, struct stat *, mode_t)
+setnonblock: int (int, int)
+set_processname: void (const char *)
+setuplog: void (const char *, const char *)
+statat: int (int, const char *, struct stat *)
+strcasechr_sp: uint16_t *(const uint16_t *, uint32_t)
+strcasechr_w: uint16_t *(const uint16_t *, uint16_t)
+strcasecmp_w: int (const uint16_t *, const uint16_t *)
+strcasestr_w: uint16_t *(const uint16_t *, const uint16_t *)
+strcat_w: uint16_t *(uint16_t *, const uint16_t *)
+strchr_w: uint16_t *(const uint16_t *, uint16_t)
+strcmp_w: int (const uint16_t *, const uint16_t *)
+strdiacasecmp: int (const char *, const char *)
+strdup_w: uint16_t *(const uint16_t *)
+stripped_slashes_basename: char *(char *)
+strlcat: size_t (char *, const char *, size_t)
+strlcpy: size_t (char *, const char *, size_t)
+strlen_w: size_t (const uint16_t *)
+strlower_w: int (uint16_t *)
+strncasecmp_w: int (const uint16_t *, const uint16_t *, size_t)
+strncat_w: uint16_t *(uint16_t *, const uint16_t *, const size_t)
+strncmp_w: int (const uint16_t *, const uint16_t *, size_t)
+strncpy_w: uint16_t *(uint16_t *, const uint16_t *, const size_t)
+strndiacasecmp: int (const char *, const char *, size_t)
+strndup_w: uint16_t *(const uint16_t *, size_t)
+strnlen_w: size_t (const uint16_t *, size_t)
+strstr_w: uint16_t *(const uint16_t *, const uint16_t *)
+strupper_w: int (uint16_t *)
+sys_ea_copyfile: int (const struct vol *, int, const char *, const char *)
+sys_fgetxattr: ssize_t (int, const char *, void *, size_t)
+sys_fsetxattr: int (int, const char *, const void *, size_t, int)
+sys_ftruncate: int (int, off_t)
+sys_get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int)
+sys_get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *)
+sys_getxattr: ssize_t (const char *, const char *, void *, size_t)
+sys_getxattrfd: int (int, const char *, int, ...)
+sys_lgetxattr: ssize_t (const char *, const char *, void *, size_t)
+sys_list_eas: int (const struct vol *, char *, size_t *, const char *, int)
+sys_listxattr: ssize_t (const char *, char *, size_t)
+sys_llistxattr: ssize_t (const char *, char *, size_t)
+sys_lremovexattr: int (const char *, const char *)
+sys_lsetxattr: int (const char *, const char *, const void *, size_t, int)
+sys_remove_ea: int (const struct vol *, const char *, const char *, int)
+sys_removexattr: int (const char *, const char *)
+sys_sendfile: ssize_t (int, int, off_t *, size_t)
+sys_set_ea: int (const struct vol *, const char *, const char *, const char *, size_t, int)
+sys_setxattr: int (const char *, const char *, const void *, size_t, int)
+tdb_add_flags: void (struct tdb_context *, unsigned int)
+tdb_allocate: tdb_off_t (struct tdb_context *, tdb_len_t, struct tdb_record *)
+tdb_alloc_read: unsigned char *(struct tdb_context *, tdb_off_t, tdb_len_t)
+tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA)
+tdb_brlock: int (struct tdb_context *, tdb_off_t, int, int, int, size_t)
+tdb_brlock_upgrade: int (struct tdb_context *, tdb_off_t, size_t)
+tdb_chainlock: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_read: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA)
+tdb_chainunlock: int (struct tdb_context *, TDB_DATA)
+tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA)
+tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *)
+tdb_close: int (struct tdb_context *)
+tdb_convert: void *(void *, uint32_t)
+tdb_delete: int (struct tdb_context *, TDB_DATA)
+tdb_do_delete: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_dump_all: void (struct tdb_context *)
+tdb_enable_seqnum: void (struct tdb_context *)
+tdb_error: enum TDB_ERROR (struct tdb_context *)
+tdb_errorstr: const char *(struct tdb_context *)
+tdb_exists: int (struct tdb_context *, TDB_DATA)
+tdb_expand: int (struct tdb_context *, tdb_off_t)
+tdb_fd: int (struct tdb_context *)
+tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA)
+tdb_find_lock_hash: tdb_off_t (struct tdb_context *, TDB_DATA, uint32_t, int, struct tdb_record *)
+tdb_firstkey: TDB_DATA (struct tdb_context *)
+tdb_free: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_freelist_size: int (struct tdb_context *)
+tdb_get_flags: int (struct tdb_context *)
+tdb_get_logging_private: void *(struct tdb_context *)
+tdb_get_seqnum: int (struct tdb_context *)
+tdb_hash_size: int (struct tdb_context *)
+tdb_increment_seqnum_nonblock: void (struct tdb_context *)
+tdb_io_init: void (struct tdb_context *)
+tdb_lock: int (struct tdb_context *, int, int)
+tdb_lockall: int (struct tdb_context *)
+tdb_lockall_mark: int (struct tdb_context *)
+tdb_lockall_nonblock: int (struct tdb_context *)
+tdb_lockall_read: int (struct tdb_context *)
+tdb_lockall_read_nonblock: int (struct tdb_context *)
+tdb_lockall_unmark: int (struct tdb_context *)
+tdb_lock_nonblock: int (struct tdb_context *, int, int)
+tdb_lock_record: int (struct tdb_context *, tdb_off_t)
+tdb_log_fn: tdb_log_func (struct tdb_context *)
+tdb_map_size: size_t (struct tdb_context *)
+tdb_mmap: void (struct tdb_context *)
+tdb_munmap: int (struct tdb_context *)
+tdb_name: const char *(struct tdb_context *)
+tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA)
+tdb_null: {dptr = 0x0, dsize = 0}
+tdb_ofs_read: int (struct tdb_context *, tdb_off_t, tdb_off_t *)
+tdb_ofs_write: int (struct tdb_context *, tdb_off_t, tdb_off_t *)
+tdb_open: struct tdb_context *(const char *, int, int, int, mode_t)
+tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func)
+tdb_parse_data: int (struct tdb_context *, TDB_DATA, tdb_off_t, tdb_len_t, int (*)(TDB_DATA, TDB_DATA, void *), void *)
+tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *)
+tdb_printfreelist: int (struct tdb_context *)
+tdb_rec_free_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_rec_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_rec_write: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_remove_flags: void (struct tdb_context *, unsigned int)
+tdb_reopen: int (struct tdb_context *)
+tdb_reopen_all: int (int)
+tdb_repack: int (struct tdb_context *)
+tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *)
+tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *)
+tdb_set_max_dead: void (struct tdb_context *, int)
+tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int)
+_tdb_transaction_cancel: int (struct tdb_context *)
+tdb_transaction_cancel: int (struct tdb_context *)
+tdb_transaction_commit: int (struct tdb_context *)
+tdb_transaction_lock: int (struct tdb_context *, int)
+tdb_transaction_prepare_commit: int (struct tdb_context *)
+tdb_transaction_recover: int (struct tdb_context *)
+tdb_transaction_start: int (struct tdb_context *)
+tdb_transaction_unlock: int (struct tdb_context *)
+tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *)
+tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *)
+tdb_unlock: int (struct tdb_context *, int, int)
+tdb_unlockall: int (struct tdb_context *)
+tdb_unlockall_read: int (struct tdb_context *)
+tdb_unlock_record: int (struct tdb_context *, tdb_off_t)
+tdb_validate_freelist: int (struct tdb_context *, int *)
+tdb_wipe_all: int (struct tdb_context *)
+tdb_write_lock_record: int (struct tdb_context *, tdb_off_t)
+tdb_write_unlock_record: int (struct tdb_context *, tdb_off_t)
+tolower_sp: uint32_t (uint32_t)
+tolower_w: uint16_t (uint16_t)
+toupper_sp: uint32_t (uint32_t)
+toupper_w: uint16_t (uint16_t)
+type_configs: {{set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}}
+ucs2_to_charset: size_t (charset_t, const uint16_t *, char *, size_t)
+ucs2_to_charset_allocate: size_t (charset_t, char **, const uint16_t *)
+unbecome_root: void (void)
+unix_rename: int (int, const char *, int, const char *)
+unix_strlower: size_t (const char *, size_t, char *, size_t)
+unix_strupper: size_t (const char *, size_t, char *, size_t)
+unload_volumes: void (AFPObj *)
+utf8_charlen: size_t (char *)
+utf8_decompose: size_t (char *, size_t, char *, size_t)
+utf8_precompose: size_t (char *, size_t, char *, size_t)
+utf8_strlen_validate: size_t (char *)
+utf8_strlower: size_t (const char *, size_t, char *, size_t)
+utf8_strupper: size_t (const char *, size_t, char *, size_t)
+utf8_to_charset_allocate: size_t (charset_t, char **, const char *)
+uuid_bin2string: const char *(const unsigned char *)
+uuidcache_dump: void (void)
+uuid_string2bin: void (const char *, unsigned char *)
+uuidtype: {"", "USER", "GROUP", "LOCAL"}
+volume_free: void (struct vol *)
+volume_unlink: void (struct vol *)
+writet: ssize_t (int, void *, const size_t, int, int)
diff --git a/libatalk/libatalk-3.0.2.abi b/libatalk/libatalk-3.0.2.abi
new file mode 100644 (file)
index 0000000..8e73229
--- /dev/null
@@ -0,0 +1,565 @@
+acl_ldap_freeconfig: void (void)
+acl_ldap_readconfig: int (dictionary *)
+ad_close: int (struct adouble *, int)
+ad_convert: int (const char *, const struct stat *, const struct vol *, const char **)
+ad_copy_header: int (struct adouble *, struct adouble *)
+add_cachebyname: int (const char *, const uuidp_t, const uuidtype_t, const long unsigned int)
+add_cachebyuuid: int (uuidp_t, const char *, uuidtype_t, const long unsigned int)
+add_charset: charset_t (const char *)
+ad_dir: char *(const char *)
+ad_dtruncate: int (struct adouble *, const off_t)
+adflags2logstr: const char *(int)
+ad_flush: int (struct adouble *)
+ad_forcegetid: uint32_t (struct adouble *)
+adf_pread: ssize_t (struct ad_fd *, void *, size_t, off_t)
+adf_pwrite: ssize_t (struct ad_fd *, const void *, size_t, off_t)
+ad_getattr: int (const struct adouble *, uint16_t *)
+ad_getdate: int (const struct adouble *, unsigned int, uint32_t *)
+ad_getentryoff: off_t (const struct adouble *, int)
+ad_getfuid: uid_t (void)
+ad_getid: uint32_t (struct adouble *, const dev_t, const ino_t, const cnid_t, const void *)
+ad_hf_mode: mode_t (mode_t)
+ad_init: void (struct adouble *, const struct vol *)
+ad_init_old: void (struct adouble *, int, int)
+ad_lock: int (struct adouble *, uint32_t, int, off_t, off_t, int)
+ad_metadata: int (const char *, int, struct adouble *)
+ad_metadataat: int (int, const char *, int, struct adouble *)
+ad_mkdir: int (const char *, mode_t)
+ad_mode: int (const char *, mode_t)
+ad_open: int (struct adouble *, const char *, int, ...)
+ad_openat: int (struct adouble *, int, const char *, int, ...)
+ad_openforks: uint16_t (struct adouble *, uint16_t)
+ad_path: const char *(const char *, int)
+ad_path_ea: const char *(const char *, int)
+ad_path_osx: const char *(const char *, int)
+ad_read: ssize_t (struct adouble *, const uint32_t, off_t, char *, const size_t)
+ad_readfile_init: int (const struct adouble *, const int, off_t *, const int)
+ad_rebuild_adouble_header_ea: int (struct adouble *)
+ad_rebuild_adouble_header_v2: int (struct adouble *)
+ad_refresh: int (const char *, struct adouble *)
+ad_rtruncate: int (struct adouble *, const off_t)
+ad_setattr: int (const struct adouble *, const uint16_t)
+ad_setdate: int (struct adouble *, unsigned int, uint32_t)
+ad_setfuid: int (const uid_t)
+ad_setid: int (struct adouble *, const dev_t, const ino_t, const uint32_t, const cnid_t, const void *)
+ad_setname: int (struct adouble *, const char *)
+ad_size: off_t (const struct adouble *, const uint32_t)
+ad_stat: int (const char *, struct stat *)
+ad_testlock: int (struct adouble *, int, const off_t)
+ad_tmplock: int (struct adouble *, uint32_t, int, off_t, off_t, int)
+ad_unlock: void (struct adouble *, const int, int)
+ad_valid_header_osx: int (const char *)
+ad_write: ssize_t (struct adouble *, uint32_t, off_t, int, const char *, size_t)
+afp_config_free: void (AFPObj *)
+afp_config_parse: int (AFPObj *, char *)
+allow_severity: 5
+apply_ip_mask: void (struct sockaddr *, int)
+atalk_iconv: size_t (atalk_iconv_t, const char **, size_t *, char **, size_t *)
+atalk_iconv_close: int (atalk_iconv_t)
+atalk_iconv_open: atalk_iconv_t (const char *, const char *)
+atalk_register_charset: int (struct charset_functions *)
+balloc: int (bstring, int)
+ballocmin: int (bstring, int)
+basename_safe: const char *(const char *)
+bassign: int (bstring, const_bstring)
+bassignblk: int (bstring, const void *, int)
+bassigncstr: int (bstring, const char *)
+bassignformat: int (bstring, const char *, ...)
+bassigngets: int (bstring, bNgetc, void *, char)
+bassignmidstr: int (bstring, const_bstring, int, int)
+bcatblk: int (bstring, const void *, int)
+bcatcstr: int (bstring, const char *)
+bconcat: int (bstring, const_bstring)
+bconchar: int (bstring, char)
+bcstrfree: int (char *)
+bdelete: int (bstring, int, int)
+bdestroy: int (bstring)
+become_root: void (void)
+bfindreplace: int (bstring, const_bstring, const_bstring, int)
+bfindreplacecaseless: int (bstring, const_bstring, const_bstring, int)
+bformat: bstring (const char *, ...)
+bformata: int (bstring, const char *, ...)
+bfromcstr: bstring (const char *)
+bfromcstralloc: bstring (int, const char *)
+bgetsa: int (bstring, bNgetc, void *, char)
+bgetstream: bstring (bNgetc, void *, char)
+binchr: int (const_bstring, int, const_bstring)
+binchrr: int (const_bstring, int, const_bstring)
+binsert: int (bstring, int, const_bstring, unsigned char)
+binsertch: int (bstring, int, int, unsigned char)
+binstr: int (const_bstring, int, const_bstring)
+binstrcaseless: int (const_bstring, int, const_bstring)
+binstrr: int (const_bstring, int, const_bstring)
+binstrrcaseless: int (const_bstring, int, const_bstring)
+biseq: int (const_bstring, const_bstring)
+biseqcaseless: int (const_bstring, const_bstring)
+biseqcstr: int (const_bstring, const char *)
+biseqcstrcaseless: int (const_bstring, const char *)
+bisstemeqblk: int (const_bstring, const void *, int)
+bisstemeqcaselessblk: int (const_bstring, const void *, int)
+bjoin: bstring (const struct bstrList *, const_bstring)
+bjoinInv: bstring (const struct bstrList *, const_bstring)
+blk2bstr: bstring (const void *, int)
+bltrimws: int (bstring)
+bmidstr: bstring (const_bstring, int, int)
+bninchr: int (const_bstring, int, const_bstring)
+bninchrr: int (const_bstring, int, const_bstring)
+bpattern: int (bstring, int)
+bread: bstring (bNread, void *)
+breada: int (bstring, bNread, void *)
+brefcstr: bstring (char *)
+breplace: int (bstring, int, int, const_bstring, unsigned char)
+brtrimws: int (bstring)
+bsbufflength: int (struct bStream *, int)
+bsclose: void *(struct bStream *)
+bseof: int (const struct bStream *)
+bsetstr: int (bstring, int, const_bstring, unsigned char)
+bsopen: struct bStream *(bNread, void *)
+bspeek: int (bstring, const struct bStream *)
+bsplit: struct bstrList *(const_bstring, unsigned char)
+bsplitcb: int (const_bstring, unsigned char, int, int (*)(void *, int, int), void *)
+bsplits: struct bstrList *(const_bstring, const_bstring)
+bsplitscb: int (const_bstring, const_bstring, int, int (*)(void *, int, int), void *)
+bsplitstr: struct bstrList *(const_bstring, const_bstring)
+bsplitstrcb: int (const_bstring, const_bstring, int, int (*)(void *, int, int), void *)
+bsread: int (bstring, struct bStream *, int)
+bsreada: int (bstring, struct bStream *, int)
+bsreadln: int (bstring, struct bStream *, char)
+bsreadlna: int (bstring, struct bStream *, char)
+bsreadlns: int (bstring, struct bStream *, const_bstring)
+bsreadlnsa: int (bstring, struct bStream *, const_bstring)
+bssplitscb: int (struct bStream *, const_bstring, int (*)(void *, int, const_bstring), void *)
+bssplitstrcb: int (struct bStream *, const_bstring, int (*)(void *, int, const_bstring), void *)
+bstr2cstr: char *(const_bstring, char)
+bstrchrp: int (const_bstring, int, int)
+bstrcmp: int (const_bstring, const_bstring)
+bstrcpy: bstring (const_bstring)
+bstricmp: int (const_bstring, const_bstring)
+bstrListAlloc: int (struct bstrList *, int)
+bstrListAllocMin: int (struct bstrList *, int)
+bstrListCreate: struct bstrList *(void)
+bstrListCreateMin: struct bstrList *(int)
+bstrListDestroy: int (struct bstrList *)
+bstrListPop: bstring (struct bstrList *)
+bstrListPush: int (struct bstrList *, bstring)
+bstrncmp: int (const_bstring, const_bstring, int)
+bstrnicmp: int (const_bstring, const_bstring, int)
+bstrrchrp: int (const_bstring, int, int)
+bsunread: int (struct bStream *, const_bstring)
+btolower: int (bstring)
+btoupper: int (bstring)
+btrimws: int (bstring)
+btrunc: int (bstring, int)
+bunrefcstr: int (bstring)
+bvcformata: int (bstring, int, const char *, struct __va_list_tag *)
+charset_decompose: size_t (charset_t, char *, size_t, char *, size_t)
+charset_mac_centraleurope: {name = "MAC_CENTRALEUROPE", kTextEncoding = 29, pull = <mac_centraleurope_pull>, push = <mac_centraleurope_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_chinese_simp: {name = "MAC_CHINESE_SIMP", kTextEncoding = 25, pull = <mac_chinese_simp_pull>, push = <mac_chinese_simp_push>, flags = 85, iname = "EUC-CN", prev = 0x0, next = 0x0}
+charset_mac_chinese_trad: {name = "MAC_CHINESE_TRAD", kTextEncoding = 2, pull = <mac_chinese_trad_pull>, push = <mac_chinese_trad_push>, flags = 85, iname = "BIG-5", prev = 0x0, next = 0x0}
+charset_mac_cyrillic: {name = "MAC_CYRILLIC", kTextEncoding = 7, pull = <mac_cyrillic_pull>, push = <mac_cyrillic_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_greek: {name = "MAC_GREEK", kTextEncoding = 6, pull = <mac_greek_pull>, push = <mac_greek_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_hebrew: {name = "MAC_HEBREW", kTextEncoding = 5, pull = <mac_hebrew_pull>, push = <mac_hebrew_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_japanese: {name = "MAC_JAPANESE", kTextEncoding = 1, pull = <mac_japanese_pull>, push = <mac_japanese_push>, flags = 85, iname = "SHIFT_JIS", prev = 0x0, next = 0x0}
+charset_mac_korean: {name = "MAC_KOREAN", kTextEncoding = 3, pull = <mac_korean_pull>, push = <mac_korean_push>, flags = 85, iname = "EUC-KR", prev = 0x0, next = 0x0}
+charset_mac_roman: {name = "MAC_ROMAN", kTextEncoding = 0, pull = <mac_roman_pull>, push = <mac_roman_push>, flags = 21, iname = 0x0, prev = 0x0, next = 0x0}
+charset_mac_turkish: {name = "MAC_TURKISH", kTextEncoding = 35, pull = <mac_turkish_pull>, push = <mac_turkish_push>, flags = 17, iname = 0x0, prev = 0x0, next = 0x0}
+charset_precompose: size_t (charset_t, char *, size_t, char *, size_t)
+charset_strlower: size_t (charset_t, const char *, size_t, char *, size_t)
+charset_strupper: size_t (charset_t, const char *, size_t, char *, size_t)
+charset_to_ucs2_allocate: size_t (charset_t, uint16_t **, const char *)
+charset_to_utf8_allocate: size_t (charset_t, char **, const char *)
+charset_utf8: {name = "UTF8", kTextEncoding = 134217987, pull = <utf8_pull>, push = <utf8_push>, flags = 22, iname = 0x0, prev = 0x0, next = 0x0}
+charset_utf8_mac: {name = "UTF8-MAC", kTextEncoding = 134217987, pull = <utf8_pull>, push = <utf8_push>, flags = 27, iname = 0x0, prev = 0x0, next = 0x0}
+check_lockfile: int (const char *, const char *)
+cjk_char_pull: size_t (uint16_t, uint16_t *, const uint32_t *)
+cjk_char_push: size_t (uint16_t, uint8_t *)
+cjk_compose: uint16_t (uint16_t, uint16_t, const uint32_t *, size_t)
+cjk_compose_seq: uint16_t (const uint16_t *, size_t *, const uint32_t *, size_t)
+cjk_generic_pull: size_t (size_t (*)(uint16_t *, const uint8_t *, size_t *), void *, char **, size_t *, char **, size_t *)
+cjk_generic_push: size_t (size_t (*)(uint8_t *, const uint16_t *, size_t *), void *, char **, size_t *, char **, size_t *)
+cjk_lookup: uint16_t (uint16_t, const cjk_index_t *, const uint16_t *)
+cnid_add: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, const char *, const size_t, cnid_t)
+cnid_close: void (struct _cnid_db *)
+cnid_dbd_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_dbd_close: void (struct _cnid_db *)
+cnid_dbd_delete: int (struct _cnid_db *, const cnid_t)
+cnid_dbd_find: int (struct _cnid_db *, const char *, size_t, void *, size_t)
+cnid_dbd_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t)
+cnid_dbd_getstamp: int (struct _cnid_db *, void *, const size_t)
+cnid_dbd_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t)
+cnid_dbd_module: {name = "dbd", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 0}
+cnid_dbd_open: struct _cnid_db *(struct cnid_open_args *)
+cnid_dbd_rebuild_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_dbd_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_dbd_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t)
+cnid_dbd_wipe: int (struct _cnid_db *)
+cnid_delete: int (struct _cnid_db *, cnid_t)
+cnid_find: int (struct _cnid_db *, const char *, size_t, void *, size_t)
+cnid_get: cnid_t (struct _cnid_db *, const cnid_t, char *, const size_t)
+cnid_getstamp: int (struct _cnid_db *, void *, const size_t)
+cnid_init: void (void)
+cnid_last_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_last_close: void (struct _cnid_db *)
+cnid_last_delete: int (struct _cnid_db *, const cnid_t)
+cnid_last_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t)
+cnid_last_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t)
+cnid_last_module: {name = "last", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 0}
+cnid_last_open: struct _cnid_db *(struct cnid_open_args *)
+cnid_last_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_last_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t)
+cnid_lookup: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t)
+cnid_open: struct _cnid_db *(const char *, mode_t, char *, int, const char *, const char *)
+cnid_rebuild_add: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t, cnid_t)
+cnid_register: void (struct _cnid_module *)
+cnid_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_tdb_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t)
+cnid_tdb_close: void (struct _cnid_db *)
+cnid_tdb_delete: int (struct _cnid_db *, const cnid_t)
+cnid_tdb_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t)
+cnid_tdb_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t)
+cnid_tdb_module: {name = "tdb", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 12}
+cnid_tdb_open: struct _cnid_db *(struct cnid_open_args *)
+cnid_tdb_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t)
+cnid_tdb_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t)
+cnid_update: int (struct _cnid_db *, const cnid_t, const struct stat *, const cnid_t, char *, const size_t)
+cnid_wipe: int (struct _cnid_db *)
+compare_ip: int (const struct sockaddr *, const struct sockaddr *)
+convert_charset: size_t (charset_t, charset_t, charset_t, const char *, size_t, char *, size_t, uint16_t *)
+convert_string: size_t (charset_t, charset_t, const void *, size_t, void *, size_t)
+convert_string_allocate: size_t (charset_t, charset_t, const void *, size_t, char **)
+copy_ea: int (const char *, int, const char *, const char *, mode_t)
+copy_file: int (int, const char *, const char *, mode_t)
+copy_file_fd: int (int, int)
+copy_fork: int (int, struct adouble *, struct adouble *)
+create_lockfile: int (const char *, const char *)
+daemonize: int (int, int)
+decompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *)
+deny_severity: 3
+dequeue: void *(q_t *)
+_diacasemap: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 231, 203, 229, 128, 204, 129, 130, 131, 233, 230, 232, 234, 237, 235, 236, 132, 238, 241, 239, 133, 205, 242, 244, 243, 134, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 198, 183, 184, 184, 186, 187, 188, 189, 174, 175, 192, 193, 194, 195, 196, 197, 198, 199...}
+_dialowermap: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 138, 140, 141, 142, 150, 154, 159, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 132, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 190, 191, 176, 177, 178, 179, 180, 181, 198, 183, 185, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199...}
+dictionary_del: void (dictionary *)
+dictionary_dump: void (dictionary *, FILE *)
+dictionary_get: const char *(const dictionary *, const char *, const char *, const char *)
+dictionary_hash: unsigned int (char *)
+dictionary_new: dictionary *(int)
+dictionary_set: int (dictionary *, char *, char *, char *)
+dictionary_unset: void (dictionary *, char *, char *)
+dir_rx_set: int (mode_t)
+dsi_attention: int (DSI *, AFPUserBytes)
+dsi_close: void (DSI *)
+dsi_cmdreply: int (DSI *, const int)
+dsi_disconnect: int (DSI *)
+dsi_free: void (DSI *)
+dsi_getsession: int (DSI *, server_child *, int, afp_child_t **)
+dsi_getstatus: void (DSI *)
+dsi_init: DSI *(AFPObj *, const char *, const char *, const char *)
+dsi_opensession: void (DSI *)
+dsi_read: ssize_t (DSI *, void *, const size_t)
+dsi_readdone: void (DSI *)
+dsi_readinit: ssize_t (DSI *, void *, const size_t, const size_t, const int)
+dsi_stream_read: size_t (DSI *, void *, const size_t)
+dsi_stream_read_file: ssize_t (DSI *, const int, off_t, const size_t, const int)
+dsi_stream_receive: int (DSI *)
+dsi_stream_send: int (DSI *, void *, size_t)
+dsi_stream_write: ssize_t (DSI *, void *, const size_t, int)
+dsi_tcp_init: int (DSI *, const char *, const char *, const char *)
+dsi_tickle: int (DSI *)
+dsi_write: size_t (DSI *, void *, const size_t)
+dsi_writeflush: void (DSI *)
+dsi_writeinit: size_t (DSI *, void *, const size_t)
+ea_chmod_dir: int (const struct vol *, const char *, mode_t, struct stat *)
+ea_chmod_file: int (const struct vol *, const char *, mode_t, struct stat *)
+ea_chown: int (const struct vol *, const char *, uid_t, gid_t)
+ea_close: int (struct ea *)
+ea_copyfile: int (const struct vol *, int, const char *, const char *)
+ea_deletefile: int (const struct vol *, int, const char *)
+ea_open: int (const struct vol *, const char *, eaflags_t, struct ea *)
+ea_openat: int (const struct vol *, int, const char *, eaflags_t, struct ea *)
+ea_path: char *(const struct ea *, const char *, int)
+ea_renamefile: int (const struct vol *, int, const char *, const char *)
+enqueue: qnode_t *(q_t *, void *)
+fault_setup: void (void (*)(void *))
+fdset_add_fd: void (int, struct pollfd **, struct polldata **, int *, int *, int, enum fdtype, void *)
+fdset_del_fd: void (struct pollfd **, struct polldata **, int *, int *, int)
+find_charset_functions: struct charset_functions *(const char *)
+_fini: <text variable, no debug info>
+free_charset_names: void (void)
+freeifacelist: void (char **)
+fullpathname: const char *(const char *)
+getcwdpath: const char *(void)
+getdefextmap: struct extmap *(void)
+get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int)
+get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *)
+getextmap: struct extmap *(const char *)
+getifacelist: char **(void)
+getip_port: unsigned int (const struct sockaddr *)
+getip_string: const char *(const struct sockaddr *)
+getnamefromuuid: int (const uuidp_t, char **, uuidtype_t *)
+getuuidfromname: int (const char *, uuidtype_t, unsigned char *)
+getvolbyname: struct vol *(const char *)
+getvolbypath: struct vol *(AFPObj *, const char *)
+getvolbyvid: struct vol *(const uint16_t)
+getvolumes: struct vol *(void)
+gmem: int (gid_t, int, gid_t *)
+iniparser_dump: void (const dictionary *, FILE *)
+iniparser_dump_ini: void (const dictionary *, FILE *)
+iniparser_find_entry: int (const dictionary *, const char *)
+iniparser_freedict: void (dictionary *)
+iniparser_getboolean: int (const dictionary *, const char *, const char *, int)
+iniparser_getdouble: double (const dictionary *, const char *, const char *, double)
+iniparser_getint: int (const dictionary *, const char *, const char *, int)
+iniparser_getnsec: int (const dictionary *)
+iniparser_getsecname: const char *(const dictionary *, int)
+iniparser_getstrdup: char *(const dictionary *, const char *, const char *, const char *)
+iniparser_getstring: const char *(const dictionary *, const char *, const char *, const char *)
+iniparser_load: dictionary *(const char *)
+iniparser_set: int (dictionary *, char *, char *, char *)
+iniparser_unset: void (dictionary *, char *, char *)
+_init: <text variable, no debug info>
+init_iconv: void (void)
+initline: void (int, char *)
+initvol_vfs: void (struct vol *)
+ipc_child_write: int (int, uint16_t, int, void *)
+ipc_client_uds: int (const char *)
+ipc_server_read: int (server_child *, int)
+ipc_server_uds: int (const char *)
+islower_sp: int (uint32_t)
+islower_w: int (uint16_t)
+isupper_sp: int (uint32_t)
+isupper_w: int (uint16_t)
+ldap_auth_dn: 0x0
+ldap_auth_method: 0
+ldap_auth_pw: 0x0
+ldap_config_valid: 0
+ldap_getnamefromuuid: int (const char *, char **, uuidtype_t *)
+ldap_getuuidfromname: int (const char *, uuidtype_t, char **)
+ldap_group_attr: 0x0
+ldap_groupbase: 0x0
+ldap_groupscope: 0
+ldap_name_attr: 0x0
+ldap_prefs: {{pref = 0x0, name = "ldap server", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap auth method", strorint = 1, intfromarray = 1, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap auth dn", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap auth pw", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap userbase", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap userscope", strorint = 1, intfromarray = 1, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap groupbase", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap groupscope", strorint = 1, intfromarray = 1, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap uuid attr", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap uuid string", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap name attr", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap group attr", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap uid attr", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap uuid encoding", strorint = 1, intfromarray = 1, valid = 0, valid_save = 0}, {pref = 0x0, name = 0x0, strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}}
+ldap_server: 0x0
+ldap_uid_attr: 0x0
+ldap_userbase: 0x0
+ldap_userscope: 0
+ldap_uuid_attr: 0x0
+ldap_uuid_encoding: 0
+ldap_uuid_string: 0x0
+list_eas: int (const struct vol *, char *, size_t *, const char *, int)
+load_charset: int (struct vol *)
+load_volumes: int (AFPObj *)
+localuuid_from_id: void (unsigned char *, uuidtype_t, unsigned int)
+lock_reg: int (int, int, int, off_t, int, off_t)
+log_config: {inited = false, syslog_opened = false, console = false, processname = '\0' <repeats 15 times>, syslog_facility = 0, syslog_display_options = 0}
+make_log_entry: void (enum loglevels, enum logtypes, const char *, int, char *, ...)
+make_tdb_data: unsigned char *(uint32_t, const struct stat *, const cnid_t, const char *, const size_t)
+mb_generic_pull: size_t (int (*)(uint16_t *, const unsigned char *), void *, char **, size_t *, char **, size_t *)
+mb_generic_push: size_t (int (*)(unsigned char *, uint16_t), void *, char **, size_t *, char **, size_t *)
+netatalk_panic: void (const char *)
+netatalk_rmdir: int (int, const char *)
+netatalk_rmdir_all_errors: int (int, const char *)
+netatalk_unlink: int (const char *)
+netatalk_unlinkat: int (int, const char *)
+nftw: int (const char *, nftw_func_t, dir_notification_func_t, int, int)
+ochdir: int (const char *, int)
+ochmod: int (char *, mode_t, const struct stat *, int)
+ochown: int (const char *, uid_t, gid_t, int)
+opendirat: DIR *(int, const char *)
+openflags2logstr: const char *(int)
+ostat: int (const char *, struct stat *, int)
+ostatat: int (int, const char *, struct stat *, int)
+parseline: int (int, char *)
+posix_chmod: int (const char *, mode_t)
+posix_fchmod: int (int, mode_t)
+precompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *)
+prefs_array: {{pref = "ldap auth method", valuestring = "none", value = 0}, {pref = "ldap auth method", valuestring = "simple", value = 128}, {pref = "ldap auth method", valuestring = "sasl", value = 163}, {pref = "ldap userscope", valuestring = "base", value = 0}, {pref = "ldap userscope", valuestring = "one", value = 1}, {pref = "ldap userscope", valuestring = "sub", value = 2}, {pref = "ldap groupscope", valuestring = "base", value = 0}, {pref = "ldap groupscope", valuestring = "one", value = 1}, {pref = "ldap groupscope", valuestring = "sub", value = 2}, {pref = "ldap uuid encoding", valuestring = "ms-guid", value = 1}, {pref = "ldap uuid encoding", valuestring = "string", value = 0}, {pref = 0x0, valuestring = 0x0, value = 0}}
+prequeue: qnode_t *(q_t *, void *)
+queue_destroy: void (q_t *, void (*)(void *))
+queue_init: q_t *(void)
+randombytes: void (void *, int)
+readt: ssize_t (int, void *, const size_t, int, int)
+realpath_safe: char *(const char *)
+reconnect_ipc: int (AFPObj *)
+recv_fd: int (int, int)
+rel_path_in_vol: bstring (const char *, const char *)
+remove_acl_vfs: int (const char *)
+remove_ea: int (const struct vol *, const char *, const char *, int)
+run_cmd: int (const char *, char **)
+search_cachebyname: int (const char *, uuidtype_t *, unsigned char *)
+search_cachebyuuid: int (uuidp_t, char **, uuidtype_t *)
+send_fd: int (int, int)
+server_child_add: afp_child_t *(server_child *, int, pid_t, int)
+server_child_alloc: server_child *(const int, const int)
+server_child_free: void (server_child *)
+server_child_kill: void (server_child *, int, int)
+server_child_kill_one_by_id: void (server_child *, int, pid_t, uid_t, uint32_t, char *, uint32_t)
+server_child_remove: int (server_child *, const int, pid_t)
+server_child_setup: void (server_child *, const int, void (*)(const pid_t))
+server_child_transfer_session: int (server_child *, int, pid_t, uid_t, int, uint16_t)
+server_lock: pid_t (char *, char *, int)
+server_reset_signal: void (void)
+set_charset_name: int (charset_t, const char *)
+set_ea: int (const struct vol *, const char *, const char *, const char *, size_t, int)
+setfilmode: int (const struct vol *, const char *, mode_t, struct stat *)
+setnonblock: int (int, int)
+set_processname: void (const char *)
+setuplog: void (const char *, const char *)
+statat: int (int, const char *, struct stat *)
+strcasechr_sp: uint16_t *(const uint16_t *, uint32_t)
+strcasechr_w: uint16_t *(const uint16_t *, uint16_t)
+strcasecmp_w: int (const uint16_t *, const uint16_t *)
+strcasestr_w: uint16_t *(const uint16_t *, const uint16_t *)
+strcat_w: uint16_t *(uint16_t *, const uint16_t *)
+strchr_w: uint16_t *(const uint16_t *, uint16_t)
+strcmp_w: int (const uint16_t *, const uint16_t *)
+strdiacasecmp: int (const char *, const char *)
+strdup_w: uint16_t *(const uint16_t *)
+stripped_slashes_basename: char *(char *)
+strlcat: size_t (char *, const char *, size_t)
+strlcpy: size_t (char *, const char *, size_t)
+strlen_w: size_t (const uint16_t *)
+strlower_w: int (uint16_t *)
+strncasecmp_w: int (const uint16_t *, const uint16_t *, size_t)
+strncat_w: uint16_t *(uint16_t *, const uint16_t *, const size_t)
+strncmp_w: int (const uint16_t *, const uint16_t *, size_t)
+strncpy_w: uint16_t *(uint16_t *, const uint16_t *, const size_t)
+strndiacasecmp: int (const char *, const char *, size_t)
+strndup_w: uint16_t *(const uint16_t *, size_t)
+strnlen_w: size_t (const uint16_t *, size_t)
+strstr_w: uint16_t *(const uint16_t *, const uint16_t *)
+strtok_quote: char *(char *, const char *)
+strupper_w: int (uint16_t *)
+sys_ea_copyfile: int (const struct vol *, int, const char *, const char *)
+sys_fgetxattr: ssize_t (int, const char *, void *, size_t)
+sys_fsetxattr: int (int, const char *, const void *, size_t, int)
+sys_ftruncate: int (int, off_t)
+sys_get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int)
+sys_get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *)
+sys_getxattr: ssize_t (const char *, const char *, void *, size_t)
+sys_getxattrfd: int (int, const char *, int, ...)
+sys_lgetxattr: ssize_t (const char *, const char *, void *, size_t)
+sys_list_eas: int (const struct vol *, char *, size_t *, const char *, int)
+sys_listxattr: ssize_t (const char *, char *, size_t)
+sys_llistxattr: ssize_t (const char *, char *, size_t)
+sys_lremovexattr: int (const char *, const char *)
+sys_lsetxattr: int (const char *, const char *, const void *, size_t, int)
+sys_remove_ea: int (const struct vol *, const char *, const char *, int)
+sys_removexattr: int (const char *, const char *)
+sys_sendfile: ssize_t (int, int, off_t *, size_t)
+sys_set_ea: int (const struct vol *, const char *, const char *, const char *, size_t, int)
+sys_setxattr: int (const char *, const char *, const void *, size_t, int)
+tdb_add_flags: void (struct tdb_context *, unsigned int)
+tdb_allocate: tdb_off_t (struct tdb_context *, tdb_len_t, struct tdb_record *)
+tdb_alloc_read: unsigned char *(struct tdb_context *, tdb_off_t, tdb_len_t)
+tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA)
+tdb_brlock: int (struct tdb_context *, tdb_off_t, int, int, int, size_t)
+tdb_brlock_upgrade: int (struct tdb_context *, tdb_off_t, size_t)
+tdb_chainlock: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_read: int (struct tdb_context *, TDB_DATA)
+tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA)
+tdb_chainunlock: int (struct tdb_context *, TDB_DATA)
+tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA)
+tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *)
+tdb_close: int (struct tdb_context *)
+tdb_convert: void *(void *, uint32_t)
+tdb_delete: int (struct tdb_context *, TDB_DATA)
+tdb_do_delete: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_dump_all: void (struct tdb_context *)
+tdb_enable_seqnum: void (struct tdb_context *)
+tdb_error: enum TDB_ERROR (struct tdb_context *)
+tdb_errorstr: const char *(struct tdb_context *)
+tdb_exists: int (struct tdb_context *, TDB_DATA)
+tdb_expand: int (struct tdb_context *, tdb_off_t)
+tdb_fd: int (struct tdb_context *)
+tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA)
+tdb_find_lock_hash: tdb_off_t (struct tdb_context *, TDB_DATA, uint32_t, int, struct tdb_record *)
+tdb_firstkey: TDB_DATA (struct tdb_context *)
+tdb_free: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_freelist_size: int (struct tdb_context *)
+tdb_get_flags: int (struct tdb_context *)
+tdb_get_logging_private: void *(struct tdb_context *)
+tdb_get_seqnum: int (struct tdb_context *)
+tdb_hash_size: int (struct tdb_context *)
+tdb_increment_seqnum_nonblock: void (struct tdb_context *)
+tdb_io_init: void (struct tdb_context *)
+tdb_lock: int (struct tdb_context *, int, int)
+tdb_lockall: int (struct tdb_context *)
+tdb_lockall_mark: int (struct tdb_context *)
+tdb_lockall_nonblock: int (struct tdb_context *)
+tdb_lockall_read: int (struct tdb_context *)
+tdb_lockall_read_nonblock: int (struct tdb_context *)
+tdb_lockall_unmark: int (struct tdb_context *)
+tdb_lock_nonblock: int (struct tdb_context *, int, int)
+tdb_lock_record: int (struct tdb_context *, tdb_off_t)
+tdb_log_fn: tdb_log_func (struct tdb_context *)
+tdb_map_size: size_t (struct tdb_context *)
+tdb_mmap: void (struct tdb_context *)
+tdb_munmap: int (struct tdb_context *)
+tdb_name: const char *(struct tdb_context *)
+tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA)
+tdb_null: {dptr = 0x0, dsize = 0}
+tdb_ofs_read: int (struct tdb_context *, tdb_off_t, tdb_off_t *)
+tdb_ofs_write: int (struct tdb_context *, tdb_off_t, tdb_off_t *)
+tdb_open: struct tdb_context *(const char *, int, int, int, mode_t)
+tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func)
+tdb_parse_data: int (struct tdb_context *, TDB_DATA, tdb_off_t, tdb_len_t, int (*)(TDB_DATA, TDB_DATA, void *), void *)
+tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *)
+tdb_printfreelist: int (struct tdb_context *)
+tdb_rec_free_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_rec_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_rec_write: int (struct tdb_context *, tdb_off_t, struct tdb_record *)
+tdb_remove_flags: void (struct tdb_context *, unsigned int)
+tdb_reopen: int (struct tdb_context *)
+tdb_reopen_all: int (int)
+tdb_repack: int (struct tdb_context *)
+tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *)
+tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *)
+tdb_set_max_dead: void (struct tdb_context *, int)
+tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int)
+_tdb_transaction_cancel: int (struct tdb_context *)
+tdb_transaction_cancel: int (struct tdb_context *)
+tdb_transaction_commit: int (struct tdb_context *)
+tdb_transaction_lock: int (struct tdb_context *, int)
+tdb_transaction_prepare_commit: int (struct tdb_context *)
+tdb_transaction_recover: int (struct tdb_context *)
+tdb_transaction_start: int (struct tdb_context *)
+tdb_transaction_unlock: int (struct tdb_context *)
+tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *)
+tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *)
+tdb_unlock: int (struct tdb_context *, int, int)
+tdb_unlockall: int (struct tdb_context *)
+tdb_unlockall_read: int (struct tdb_context *)
+tdb_unlock_record: int (struct tdb_context *, tdb_off_t)
+tdb_validate_freelist: int (struct tdb_context *, int *)
+tdb_wipe_all: int (struct tdb_context *)
+tdb_write_lock_record: int (struct tdb_context *, tdb_off_t)
+tdb_write_unlock_record: int (struct tdb_context *, tdb_off_t)
+tolower_sp: uint32_t (uint32_t)
+tolower_w: uint16_t (uint16_t)
+toupper_sp: uint32_t (uint32_t)
+toupper_w: uint16_t (uint16_t)
+type_configs: {{set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}}
+ucs2_to_charset: size_t (charset_t, const uint16_t *, char *, size_t)
+ucs2_to_charset_allocate: size_t (charset_t, char **, const uint16_t *)
+unbecome_root: void (void)
+unix_rename: int (int, const char *, int, const char *)
+unix_strlower: size_t (const char *, size_t, char *, size_t)
+unix_strupper: size_t (const char *, size_t, char *, size_t)
+unload_volumes: void (AFPObj *)
+utf8_charlen: size_t (char *)
+utf8_decompose: size_t (char *, size_t, char *, size_t)
+utf8_precompose: size_t (char *, size_t, char *, size_t)
+utf8_strlen_validate: size_t (char *)
+utf8_strlower: size_t (const char *, size_t, char *, size_t)
+utf8_strupper: size_t (const char *, size_t, char *, size_t)
+utf8_to_charset_allocate: size_t (charset_t, char **, const char *)
+uuid_bin2string: const char *(const unsigned char *)
+uuidcache_dump: void (void)
+uuid_string2bin: void (const char *, unsigned char *)
+uuidtype: {"", "USER", "GROUP", "LOCAL"}
+volume_free: void (struct vol *)
+volume_unlink: void (struct vol *)
+writet: ssize_t (int, void *, const size_t, int, int)
index d549715f831b414fc098b334a97f6572c74ffc76..88ff7accd4d800287cb48828f6ad93ddbc83b98d 100644 (file)
@@ -25,7 +25,6 @@
    License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
 
-
 #include "tdb_private.h"
 
 /* check for an out of bounds access - if it is out of bounds then
@@ -212,7 +211,7 @@ void tdb_mmap(struct tdb_context *tdb)
        if (!(tdb->flags & TDB_NOMMAP)) {
                tdb->map_ptr = mmap(NULL, tdb->map_size, 
                                    PROT_READ|(tdb->read_only? 0:PROT_WRITE), 
-                                   MAP_SHARED|MAP_FILE, tdb->fd, 0);
+                                   MAP_SHARED, tdb->fd, 0);
 
                /*
                 * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!!
index 41389c41c97a349acf69d8f1239751295546a518..de5dd02b141f3ca5cae4115938f8195aaeea4fc1 100644 (file)
    License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
 
-#if 0
-#include "replace.h"
-#include "system/filesys.h"
-#include "system/time.h"
-#include "system/shmem.h"
-#include "system/select.h"
-#include "system/wait.h"
-#include "tdb.h"
-#endif
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
 
 #include <unistd.h>
 #include <stdint.h>
@@ -50,6 +44,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <sys/param.h>
+#include <stddef.h>
 
 #ifndef __STRING
 #define __STRING(x)    #x
 typedef uint32_t tdb_len_t;
 typedef uint32_t tdb_off_t;
 
-#ifndef offsetof
-#define offsetof(t,f) ((unsigned int)&((t *)0)->f)
-#endif
-
 #define TDB_MAGIC_FOOD "TDB file\n"
 #define TDB_VERSION (0x26011967 + 6)
 #define TDB_MAGIC (0x26011999U)
index 785e47720f1d7ab2e74ce2be611c93164386fdb9..4e772e165a16e4f60f0f7dd331d176bf542645da 100644 (file)
@@ -95,6 +95,16 @@ int set_charset_name(charset_t ch, const char *name)
     return 0;
 }
 
+void free_charset_names(void)
+{
+    for (int ch = 0; ch < MAX_CHARSETS; ch++) {
+        if (charset_names[ch]) {
+            free(charset_names[ch]);
+            charset_names[ch] = NULL;
+        }
+    }
+}
+
 static struct charset_functions* get_charset_functions (charset_t ch)
 {
     if (charsets[ch] != NULL)
@@ -693,7 +703,7 @@ char * debug_out ( char * seq, size_t len)
  *      for e.g. HFS cdroms.
  */
 
-static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, const char *src, size_t srclen, char* dest, size_t destlen, uint16_t *flags)
+static size_t pull_charset_flags (charset_t from_set, charset_t to_set, charset_t cap_set, const char *src, size_t srclen, char* dest, size_t destlen, uint16_t *flags)
 {
     const uint16_t option = (flags ? *flags : 0);
     size_t i_len, o_len;
@@ -702,6 +712,7 @@ static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, const c
     char* outbuf = dest;
     atalk_iconv_t descriptor;
     atalk_iconv_t descriptor_cap;
+    char escch;                 /* 150210: uninitialized OK, depends on j */
 
     if (srclen == (size_t)-1)
         srclen = strlen(src) + 1;
@@ -717,10 +728,30 @@ static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, const c
     i_len=srclen;
     o_len=destlen;
 
+    if ((option & CONV_ESCAPEDOTS) && i_len >= 2 && inbuf[0] == '.') {
+        if (o_len < 6) {
+            errno = E2BIG;
+            goto end;
+        }
+        ucs2_t ucs2 = ':';
+        memcpy(outbuf, &ucs2, sizeof(ucs2_t));
+        ucs2 = '2';
+        memcpy(outbuf + sizeof(ucs2_t), &ucs2, sizeof(ucs2_t));
+        ucs2 = 'e';
+        memcpy(outbuf + 2 * sizeof(ucs2_t), &ucs2, sizeof(ucs2_t));
+        outbuf += 6;
+        o_len -= 6;
+        inbuf++;
+        i_len--;
+        *flags |= CONV_REQESCAPE;
+    }
+
     while (i_len > 0) {
         for (j = 0; j < i_len; ++j)
-            if (inbuf[j] == ':')
+            if (inbuf[j] == ':' || inbuf[j] == '/') {
+                escch = inbuf[j];
                 break;
+            }
         j = i_len - j;
         i_len -= j;
 
@@ -750,48 +781,108 @@ static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, const c
         }
 
         if (j) {
-            /* we have a ':' */
+            /* we have a ':' or '/' */
             i_len = j, j = 0;
 
-            if ((option & CONV_UNESCAPEHEX)) {
-                /* treat it as a CAP hex encoded char */
-                char h[MAXPATHLEN];
-                size_t hlen = 0;
-
-                while (i_len >= 3 && inbuf[0] == ':' &&
-                       isxdigit(inbuf[1]) && isxdigit(inbuf[2])) {
-                    h[hlen++] = (hextoint(inbuf[1]) << 4) | hextoint(inbuf[2]);
-                    inbuf += 3;
-                    i_len -= 3;
-                }
-                if (hlen) {
-                    const char *h_buf = h;
-                    if (atalk_iconv(descriptor_cap, &h_buf, &hlen, &outbuf, &o_len) == (size_t)-1) {
-                        i_len += hlen * 3;
-                        inbuf -= hlen * 3;
-                        if (errno == EILSEQ && (option & CONV_IGNORE)) {
+            if (escch == ':') {
+                if ((option & CONV_UNESCAPEHEX)) {
+                    /* treat it as a CAP hex encoded char */
+                    char h[MAXPATHLEN];
+                    size_t hlen = 0;
+
+                    while (i_len >= 3 && inbuf[0] == ':' &&
+                           isxdigit(inbuf[1]) && isxdigit(inbuf[2])) {
+                        h[hlen++] = (hextoint(inbuf[1]) << 4) | hextoint(inbuf[2]);
+                        inbuf += 3;
+                        i_len -= 3;
+                    }
+                    if (hlen) {
+                        const char *h_buf = h;
+                        if (atalk_iconv(descriptor_cap, &h_buf, &hlen, &outbuf, &o_len) == (size_t)-1) {
+                            i_len += hlen * 3;
+                            inbuf -= hlen * 3;
+                            if (errno == EILSEQ && (option & CONV_IGNORE)) {
+                                *flags |= CONV_REQMANGLE;
+                                return destlen - o_len;
+                            }
+                            goto end;
+                        }
+                    } else {
+                        /* We have an invalid :xx sequence */
+                        errno = EILSEQ;
+                        if ((option & CONV_IGNORE)) {
                             *flags |= CONV_REQMANGLE;
                             return destlen - o_len;
                         }
                         goto end;
                     }
-                } else {
-                    /* We have an invalid :xx sequence */
-                    errno = EILSEQ;
-                    if ((option & CONV_IGNORE)) {
-                        *flags |= CONV_REQMANGLE;
-                        return destlen - o_len;
+                } else if (option & CONV_ESCAPEHEX) {
+                    if (o_len < 6) {
+                        errno = E2BIG;
+                        goto end;
                     }
-                    goto end;
+                    ucs2_t ucs2 = ':';
+                    memcpy(outbuf, &ucs2, sizeof(ucs2_t));
+                    ucs2 = '3';
+                    memcpy(outbuf + sizeof(ucs2_t), &ucs2, sizeof(ucs2_t));
+                    ucs2 = 'a';
+                    memcpy(outbuf + 2 * sizeof(ucs2_t), &ucs2, sizeof(ucs2_t));
+                    outbuf += 6;
+                    o_len -= 6;
+                    inbuf++;
+                    i_len--;
+                } else if (to_set == CH_UTF8_MAC || to_set == CH_MAC) {
+                    /* convert to a '/' */
+                    ucs2_t slash = 0x002f;
+                    memcpy(outbuf, &slash, sizeof(ucs2_t));
+                    outbuf += 2;
+                    o_len -= 2;
+                    inbuf++;
+                    i_len--;
+                } else {
+                    /* keep as ':' */
+                    ucs2_t ucs2 = 0x003a;
+                    memcpy(outbuf, &ucs2, sizeof(ucs2_t));
+                    outbuf += 2;
+                    o_len -= 2;
+                    inbuf++;
+                    i_len--;
                 }
             } else {
-                /* a ':' that we just convert to a '/' */
-                ucs2_t slash = 0x002f;
-                memcpy(outbuf, &slash, sizeof(ucs2_t));
-                outbuf += 2;
-                o_len -= 2;
-                inbuf++;
-                i_len--;
+                /* '/' */
+                if (option & CONV_ESCAPEHEX) {
+                    if (o_len < 6) {
+                        errno = E2BIG;
+                        goto end;
+                    }
+                    ucs2_t ucs2 = ':';
+                    memcpy(outbuf, &ucs2, sizeof(ucs2_t));
+                    ucs2 = '2';
+                    memcpy(outbuf + sizeof(ucs2_t), &ucs2, sizeof(ucs2_t));
+                    ucs2 = 'f';
+                    memcpy(outbuf + 2 * sizeof(ucs2_t), &ucs2, sizeof(ucs2_t));
+                    outbuf += 6;
+                    o_len -= 6;
+                    inbuf++;
+                    i_len--;
+                } else if ((from_set == CH_UTF8_MAC || from_set == CH_MAC)
+                           && (to_set != CH_UTF8_MAC  || to_set != CH_MAC)) {
+                    /* convert to ':' */
+                    ucs2_t ucs2 = 0x003a;
+                    memcpy(outbuf, &ucs2, sizeof(ucs2_t));
+                    outbuf += 2;
+                    o_len -= 2;
+                    inbuf++;
+                    i_len--;
+                } else {
+                    /* keep as '/' */
+                    ucs2_t ucs2 = 0x002f;
+                    memcpy(outbuf, &ucs2, sizeof(ucs2_t));
+                    outbuf += 2;
+                    o_len -= 2;
+                    inbuf++;
+                    i_len--;
+                }
             }
         }
     }
@@ -824,7 +915,6 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src
     char* outbuf = (char*)dest;
     atalk_iconv_t descriptor;
     atalk_iconv_t descriptor_cap;
-    char escch;                 /* 150210: uninitialized OK, depends on j */
 
     descriptor = conv_handles[CH_UCS2][to_set];
     descriptor_cap = conv_handles[CH_UCS2][cap_set];
@@ -837,42 +927,7 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src
     i_len=srclen;
     o_len=destlen;
 
-    if ((option & CONV_ESCAPEDOTS) &&
-        i_len >= 2 && SVAL(inbuf, 0) == 0x002e) { /* 0x002e = . */
-        if (o_len < 3) {
-            errno = E2BIG;
-            goto end;
-        }
-        *outbuf++ = ':';
-        *outbuf++ = '2';
-        *outbuf++ = 'e';
-        o_len -= 3;
-        inbuf += 2;
-        i_len -= 2;
-        *flags |= CONV_REQESCAPE;
-    }
-
     while (i_len >= 2) {
-        for (i = 0; i < i_len; i += 2) {
-            ucs2_t c = SVAL(inbuf, i);
-            switch (c) {
-            case 0x003a: /* 0x003a = ':' */
-                if ( ! (option & CONV_ALLOW_COLON)) {
-                    errno = EILSEQ;
-                    goto end;
-                }
-                escch = c;
-                j = i_len - i;
-                i_len = i;
-                break;
-            case 0x002f: /* 0x002f = '/' */
-                if (option & CONV_ALLOW_SLASH) break;
-                escch = c;
-                j = i_len - i;
-                i_len = i;
-                break;
-            }
-        }
         while (i_len > 0 &&
                atalk_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len) == (size_t)-1) {
             if (errno == EILSEQ) {
@@ -921,57 +976,8 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src
             }
             goto end;
         }
+    } /* while (i_len >= 2) */
 
-        if (j) {
-            /* we have a ':' or '/' */
-            i_len = j, j = 0;
-
-            if ((option & CONV_ESCAPEHEX)) {
-                /* CAP hex encode it */
-                if (o_len < 3) {
-                    errno = E2BIG;
-                    goto end;
-                }
-                switch (escch) {
-                case '/':
-                    *outbuf++ = ':';
-                    *outbuf++ = '2';
-                    *outbuf++ = 'f';
-                    break;
-                case ':':
-                    *outbuf++ = ':';
-                    *outbuf++ = '3';
-                    *outbuf++ = 'a';
-                    break;
-                default:
-                    /*
-                     *  THIS SHOULD NEVER BE REACHED !!!
-                     *  As a safety net I put in a ' ' here
-                     */
-                    *outbuf++ = ':';
-                    *outbuf++ = '2';
-                    *outbuf++ = '0';
-                    break;
-                }
-                o_len -= 3;
-                inbuf += 2;
-                i_len -= 2;
-            } else {
-                switch (escch) {
-                case '/':
-                case ':':
-                    *outbuf++ = ':';
-                    break;
-                default: /* should never be reached */
-                    *outbuf++ = ' ';
-                    break;
-                }
-                o_len--;
-                inbuf += 2;
-                i_len -= 2;
-            }
-        }
-    }
     if (i_len > 0) errno = EINVAL;
 end:
     return (i_len + j == 0 || (option & CONV_FORCE)) ? destlen - o_len : (size_t)-1;
@@ -991,7 +997,7 @@ size_t convert_charset ( charset_t from_set, charset_t to_set, charset_t cap_cha
     lazy_initialize_conv();
 
     /* convert from_set to UCS2 */
-    if ((size_t)(-1) == ( o_len = pull_charset_flags( from_set, cap_charset, src, src_len,
+    if ((size_t)(-1) == ( o_len = pull_charset_flags( from_set, to_set, cap_charset, src, src_len,
                                                       (char *) buffer, sizeof(buffer) -2, flags)) ) {
         LOG(log_error, logtype_default, "Conversion failed ( %s to CH_UCS2 )", charset_name(from_set));
         return (size_t) -1;
index bf3a5bca9ef1e951b966a362f514e57954893458..5d2c72e6f0e2678f5b2e99b0ad36b6224c851616 100644 (file)
@@ -1,6 +1,5 @@
 
 /*
- * $Id: mac_roman.h,v 1.2 2005-04-28 20:50:04 bfernhomberg Exp $
  *
  * 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
index ce3355df980c84c0f65e65f13f9b55ddd6556a86..0eba9a3c25faaa4ce255db5fdff95aaeaf1e315c 100644 (file)
@@ -291,12 +291,12 @@ int strcasecmp_w(const ucs2_t *a, const ucs2_t *b)
 
        while (*a && *b) {
                if ((0xD800 <= *a) && (*a < 0xDC00)) {
-                       if (ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1])) return ret;
+                       if ((ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1]))) return ret;
                        a++;
                        b++;
                        if (!(*a && *b)) return (tolower_w(*a) - tolower_w(*b)); /* avoid buffer over run */
                } else {
-                       if (ret = tolower_w(*a) - tolower_w(*b)) return ret;
+                       if ((ret = tolower_w(*a) - tolower_w(*b))) return ret;
                }
                a++;
                b++;
@@ -317,13 +317,13 @@ int strncasecmp_w(const ucs2_t *a, const ucs2_t *b, size_t len)
 
        while ((n < len) && *a && *b) {
                if ((0xD800 <= *a) && (*a < 0xDC00)) {
-                       if (ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1])) return ret;
+                       if ((ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1]))) return ret;
                        a++;
                        b++;
                        n++;
                        if (!((n < len) && *a && *b)) return (tolower_w(*a) - tolower_w(*b));
                } else {
-                       if (ret = tolower_w(*a) - tolower_w(*b)) return ret;
+                       if ((ret = tolower_w(*a) - tolower_w(*b))) return ret;
                }
                a++;
                b++;
@@ -607,7 +607,7 @@ size_t precompose_w (ucs2_t *name, size_t inplen, ucs2_t *comp, size_t *outlen)
                                base_sp = ((uint32_t)base << 16) | (uint32_t)comb;
                                do {
                                        comb_sp = ((uint32_t)in[1] << 16) | (uint32_t)in[2];
-                                       if (result_sp = do_precomposition_sp(base_sp, comb_sp)) {
+                                       if ((result_sp = do_precomposition_sp(base_sp, comb_sp))) {
                                                base_sp = result_sp;
                                                i += 4;
                                                in +=2;
@@ -641,7 +641,7 @@ size_t precompose_w (ucs2_t *name, size_t inplen, ucs2_t *comp, size_t *outlen)
                }
 
                /* Binary Search for BMP */
-               else if (result = do_precomposition(base, comb)) {
+               else if ((result = do_precomposition(base, comb))) {
                        base = result;
                }
                
index 65ad1d6ca9704b8e535a1aa6e71d2d1b5847e7fd..201951664cd4d81b2da6445ca4ebeb866f99be8d 100644 (file)
@@ -9,6 +9,7 @@ libutil_la_SOURCES = \
        cnid.c          \
        fault.c         \
        getiface.c      \
+       gettok.c        \
        locking.c   \
        logger.c        \
        module.c        \
index 3a32c12e0293a35329a95bef956c5000646c6eb4..f0ac17f1b41be54dc9ee86c091a96799c6bc2d36 100644 (file)
@@ -45,7 +45,9 @@
 
 #include <atalk/ftw.h>
 
+#ifndef HAVE_MEMPCPY
 #define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
+#endif
 
 #define NDEBUG 1
 #include <assert.h>
diff --git a/libatalk/util/gettok.c b/libatalk/util/gettok.c
new file mode 100644 (file)
index 0000000..4859fec
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ *
+ * Copyright (c) 1990,1994 Regents of The University of Michigan.
+ * All Rights Reserved.  See COPYRIGHT.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <sys/param.h>
+#include <string.h>
+#include <ctype.h>
+#include <pwd.h>
+
+#include <atalk/globals.h>
+
+static char    *l_curr;
+static char    *l_end;
+
+void initline( int len, char *line)
+{
+    l_curr = line;
+    l_end = line + len;
+}
+
+#define ST_QUOTE       0
+#define ST_WORD                1
+#define ST_BEGIN       2
+
+int
+parseline(int len, char *token)
+{
+    char       *p, *e;
+    int                state;
+
+    state = ST_BEGIN;
+    p = token;
+    e = token + len;
+
+    for (;;) {
+        if ( l_curr > l_end ) {                        /* end of line */
+            *token = '\0';
+            return( -1 );
+        }
+
+        switch ( *l_curr ) {
+        case '"' :
+            if ( state == ST_QUOTE ) {
+                state = ST_WORD;
+            } else {
+                state = ST_QUOTE;
+            }
+            break;
+
+        case '\0' :
+        case '\t' :
+        case '\n' :
+        case ' ' :
+            if ( state == ST_WORD ) {
+                *p = '\0';
+                return( p - token );
+            }
+            if ( state != ST_QUOTE ) {
+                break;
+            }
+            /* FALL THROUGH */
+
+        default :
+            if ( state == ST_BEGIN ) {
+                state = ST_WORD;
+            }
+            if ( p > e ) {                     /* end of token */
+                *token = '\0';
+                return( -1 );
+            }
+            *p++ = *l_curr;
+            break;
+        }
+
+        l_curr++;
+    }
+}
+
+#ifdef notdef
+void parseline(char *token, char *user)
+{
+    char               *p = pos, *t = token, *u, *q, buf[ MAXPATHLEN ];
+    struct passwd      *pwent;
+    int                        quoted = 0;
+
+    while ( isspace( *p )) {
+        p++;
+    }
+
+    /*
+     * If we've reached the end of the line, or a comment,
+     * don't return any more tokens.
+     */
+    if ( *p == '\0' || *p == '#' ) {
+        *token = '\0';
+        return;
+    }
+
+    if ( *p == '"' ) {
+        p++;
+        quoted = 1;
+    }
+    while ( *p != '\0' && ( quoted || !isspace( *p ))) {
+        if ( *p == '"' ) {
+            if ( quoted ) {
+                *t = '\0';
+                break;
+            }
+            quoted = 1;
+            p++;
+        } else {
+            *t++ = *p++;
+        }
+    }
+    pos = p;
+    *t = '\0';
+
+    /*
+     * We got to the end of the line without closing an open quote
+     */
+    if ( *p == '\0' && quoted ) {
+        *token = '\0';
+        return;
+    }
+
+    t = token;
+    if ( *t == '~' ) {
+        t++;
+        if ( *t == '\0' || *t == '/' ) {
+            u = user;
+            if ( *t == '/' ) {
+                t++;
+            }
+        } else {
+            u = t;
+            if (( q = strchr( t, '/' )) == NULL ) {
+                t = "";
+            } else {
+                *q = '\0';
+                t = q + 1;
+            }
+        }
+        if ( u == NULL || ( pwent = getpwnam( u )) == NULL ) {
+            *token = '\0';
+            return;
+        }
+        strcpy( buf, pwent->pw_dir );
+        if ( *t != '\0' ) {
+            strcat( buf, "/" );
+            strcat( buf, t );
+        }
+        strcpy( token, buf );
+    }
+    return;
+}
+#endif /* notdef */
index 2d5b913e8026bb8e3121d45efba5d7f5e7e1ea42..0b473b608ba38cf4534b13fc513f34390123b1d7 100644 (file)
@@ -1,5 +1,4 @@
 /*
-   $Id: locking.c,v 1.4 2010-01-05 19:05:52 franklahm Exp $
    Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
 
    This program is free software; you can redistribute it and/or modify
index c8a2a0a8acd2845c43bfbd088e81b7a496855a1b..55630d1b0d7ebe5a059dc6ae543a54901a14d09f 100644 (file)
@@ -59,10 +59,10 @@ Netatalk 2001 (c)
   "CNID",                            \
   "AFPDaemon",                       \
   "DSI",                             \
-  "ATalkDaemon",                     \
-  "PAPDaemon",                       \
   "UAMS",                            \
-  "end_of_list_marker"}              \
+  "FCE",                             \
+  "ad",                              \
+  "end_of_list_marker"}
 
 /* =========================================================================
    Config
@@ -85,9 +85,9 @@ UAM_MODULE_EXPORT logtype_conf_t type_configs[logtype_end_of_list_marker] = {
     DEFAULT_LOG_CONFIG, /* logtype_cnid */
     DEFAULT_LOG_CONFIG, /* logtype_afpd */
     DEFAULT_LOG_CONFIG, /* logtype_dsi */
-    DEFAULT_LOG_CONFIG, /* logtype_atalkd */
-    DEFAULT_LOG_CONFIG, /* logtype_papd */
-    DEFAULT_LOG_CONFIG /* logtype_uams */
+    DEFAULT_LOG_CONFIG, /* logtype_uams */
+    DEFAULT_LOG_CONFIG,  /* logtype_fce */
+    DEFAULT_LOG_CONFIG  /* logtype_ad */
 };
 
 static void syslog_setup(int loglevel, enum logtypes logtype, int display_options, int facility);
index 1e370373b3f810a7de13ce96b8f72b0f4d50ea0b..b651476524c73230cb3f3875fd8288bd52e86ec2 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id: module.c,v 1.5 2003-02-17 02:03:12 srittau Exp $
  */
 
 #ifdef HAVE_CONFIG_H
index 0c0a9416f0f60bb4c4948ee64f589d9ca5744ffc..b1ca02d139357e90c3bd9e9f5a741bfc991b41a9 100644 (file)
@@ -51,6 +51,7 @@
 #include <atalk/uuid.h>
 #include <atalk/netatalk_conf.h>
 #include <atalk/bstrlib.h>
+#include <atalk/bstradd.h>
 
 #define VOLPASSLEN  8
 #ifndef UUID_PRINTABLE_STRING_LENGTH
@@ -401,8 +402,11 @@ static char *volxlate(const AFPObj *obj,
 /*!
  * check access list
  *
- * this function wants something of the following form:
- * "@group,name,name2,@group2,name3" or "@group name name2 @group2 name3"
+ * this function wants a string consisting of names seperated by comma
+ * or space. Names may be quoted within a pair of quotes. Groups are
+ * denoted by a leading @ symbol.
+ * Example:
+ * user1 user2, user3, @group1 @group2, @group3 "user name1", "@group name1"
  * A NULL argument allows everybody to have access.
  * We return three things:
  *     -1: no list
@@ -411,26 +415,31 @@ static char *volxlate(const AFPObj *obj,
  */
 static int accessvol(const AFPObj *obj, const char *args, const char *name)
 {
-    char buf[MAXPATHLEN + 1], *p;
+    EC_INIT;
+    char *names = NULL, *p;
     struct group *gr;
 
     if (!args)
-        return -1;
+        EC_EXIT_STATUS(-1);
 
-    strlcpy(buf, args, sizeof(buf));
-    if ((p = strtok(buf, ", ")) == NULL) /* nothing, return okay */
-        return -1;
+    EC_NULL_LOG( names = strdup(args) );
+
+    if ((p = strtok_quote(names, ", ")) == NULL) /* nothing, return okay */
+        EC_EXIT_STATUS(-1);
 
     while (p) {
         if (*p == '@') { /* it's a group */
             if ((gr = getgrnam(p + 1)) && gmem(gr->gr_gid, obj->ngroups, obj->groups))
-                return 1;
+                EC_EXIT_STATUS(1);
         } else if (strcasecmp(p, name) == 0) /* it's a user name */
-            return 1;
-        p = strtok(NULL, ", ");
+            EC_EXIT_STATUS(1);
+        p = strtok_quote(NULL, ", ");
     }
 
-    return 0;
+EC_CLEANUP:
+    if (names)
+        free(names);
+    EC_EXIT;
 }
 
 static int hostaccessvol(const AFPObj *obj, const char *volname, const char *args)
@@ -505,13 +514,11 @@ static int hostaccessvol(const AFPObj *obj, const char *volname, const char *arg
  */
 static const char *getoption(const dictionary *conf, const char *vol, const char *opt, const char *defsec, const char *defval)
 {
-    EC_INIT;
     const char *result;
 
     if ((!(result = iniparser_getstring(conf, vol, opt, NULL))) && (defsec != NULL))
         result = iniparser_getstring(conf, defsec, opt, NULL);
     
-EC_CLEANUP:
     if (result == NULL)
         result = defval;
     return result;
@@ -530,13 +537,11 @@ EC_CLEANUP:
  */
 static int getoption_bool(const dictionary *conf, const char *vol, const char *opt, const char *defsec, int defval)
 {
-    EC_INIT;
     int result;
 
     if (((result = iniparser_getboolean(conf, vol, opt, -1)) == -1) && (defsec != NULL))
         result = iniparser_getboolean(conf, defsec, opt, -1);
     
-EC_CLEANUP:
     if (result == -1)
         result = defval;
     return result;
@@ -549,7 +554,7 @@ EC_CLEANUP:
  * @param pwd      (r) struct passwd of logged in user, may be NULL in master afpd
  * @param section  (r) volume name wo variables expanded (exactly as in iniconfig)
  * @param name     (r) volume name
- * @param path     (r) volume path
+ * @param path_in  (r) volume path
  * @param preset   (r) default preset, may be NULL
  * @returns            vol on success, NULL on error
  */
@@ -557,40 +562,55 @@ static struct vol *creatvol(AFPObj *obj,
                             const struct passwd *pwd,
                             const char *section,
                             const char *name,
-                            const char *path,
+                            const char *path_in,
                             const char *preset)
 {
     EC_INIT;
     struct vol  *volume = NULL;
     int         i, suffixlen, vlen, tmpvlen, u8mvlen, macvlen;
-    char        *tmpname;
+    char        tmpname[AFPVOL_U8MNAMELEN+1];
+    char        path[MAXPATHLEN + 1];
     ucs2_t      u8mtmpname[(AFPVOL_U8MNAMELEN+1)*2], mactmpname[(AFPVOL_MACNAMELEN+1)*2];
     char        suffix[6]; /* max is #FFFF */
     uint16_t    flags;
     const char  *val;
     char        *p, *q;
 
+    strlcpy(path, path_in, MAXPATHLEN);
+
     LOG(log_debug, logtype_afpd, "createvol(volume: '%s', path: \"%s\", preset: '%s'): BEGIN",
         name, path, preset ? preset : "-");
 
     if ( name == NULL || *name == '\0' ) {
-        if ((name = strrchr( path, '/' )) == NULL) {
+        if ((name = strrchr( path, '/' )) == NULL)
             EC_FAIL;
-        }
-
         /* if you wish to share /, you need to specify a name. */
         if (*++name == '\0')
             EC_FAIL;
     }
 
     /* Once volumes are loaded, we never change options again, we just delete em when they're removed from afp.conf */
+
     for (struct vol *vol = Volumes; vol; vol = vol->v_next) {
-        if (STRCMP(path, ==, vol->v_path)) {
-            LOG(log_debug, logtype_afpd, "createvol('%s'): already loaded", name);
+        if (STRCMP(name, ==, vol->v_localname) && vol->v_deleted) {
+            /* 
+             * reloading config, volume still present, nothing else to do,
+             * we don't change options for volumes once they're loaded
+             */
             vol->v_deleted = 0;
             volume = vol;
-            goto EC_CLEANUP;
+            EC_EXIT_STATUS(0);
+        }
+        if (STRCMP(path, ==, vol->v_path)) {
+            LOG(log_note, logtype_afpd, "volume \"%s\" path \"%s\" is the same as volumes \"%s\" path",
+                name, path, vol->v_configname);
+            EC_EXIT_STATUS(0);
         }
+        /*
+         * We could check for nested volume paths here, but
+         * nobody was able to come up with an implementation yet,
+         * that is simple, fast and correct.
+         */
     }
 
     /*
@@ -616,14 +636,14 @@ static struct vol *creatvol(AFPObj *obj,
     volume->v_vfs_ea = AFPVOL_EA_AUTO;
     volume->v_umask = obj->options.umask;
 
-    if (val = getoption(obj->iniconfig, section, "password", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "password", preset, NULL)))
         EC_NULL( volume->v_password = strdup(val) );
 
-    if (val = getoption(obj->iniconfig, section, "veto files", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "veto files", preset, NULL)))
         EC_NULL( volume->v_veto = strdup(val) );
 
     /* vol charset is in [G] and [V] */
-    if (val = getoption(obj->iniconfig, section, "vol charset", preset, NULL)) {
+    if ((val = getoption(obj->iniconfig, section, "vol charset", preset, NULL))) {
         if (strcasecmp(val, "UTF-8") == 0) {
             val = strdup("UTF8");
         }
@@ -633,7 +653,7 @@ static struct vol *creatvol(AFPObj *obj,
         EC_NULL( volume->v_volcodepage = strdup(obj->options.volcodepage) );
 
     /* mac charset is in [G] and [V] */
-    if (val = getoption(obj->iniconfig, section, "mac charset", preset, NULL)) {
+    if ((val = getoption(obj->iniconfig, section, "mac charset", preset, NULL))) {
         if (strncasecmp(val, "MAC", 3) != 0) {
             LOG(log_warning, logtype_afpd, "Is '%s' really mac charset? ", val);
         }
@@ -643,46 +663,46 @@ static struct vol *creatvol(AFPObj *obj,
     EC_NULL( volume->v_maccodepage = strdup(obj->options.maccodepage) );
 
     vlen = strlen(name);
-    tmpname = strdup(name);
+    strlcpy(tmpname, name, sizeof(tmpname));
     for(i = 0; i < vlen; i++)
         if(tmpname[i] == '/') tmpname[i] = ':';
 
     bstring dbpath;
-    EC_NULL_LOG( val = iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol dbpath", _PATH_STATEDIR "CNID/") );
-    EC_NULL_LOG( dbpath = bformat("%s/%s/", val, tmpname) );
-    EC_NULL_LOG( volume->v_dbpath = strdup(bdata(dbpath)) );
+    EC_NULL( val = iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol dbpath", _PATH_STATEDIR "CNID/") );
+    EC_NULL( dbpath = bformat("%s/%s/", val, tmpname) );
+    EC_NULL( volume->v_dbpath = strdup(cfrombstr(dbpath)) );
     bdestroy(dbpath);
 
-    if (val = getoption(obj->iniconfig, section, "cnid scheme", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "cnid scheme", preset, NULL)))
         EC_NULL( volume->v_cnidscheme = strdup(val) );
     else
         volume->v_cnidscheme = strdup(DEFAULT_CNID_SCHEME);
 
-    if (val = getoption(obj->iniconfig, section, "umask", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "umask", preset, NULL)))
         volume->v_umask = (int)strtol(val, NULL, 8);
 
-    if (val = getoption(obj->iniconfig, section, "directory perm", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "directory perm", preset, NULL)))
         volume->v_dperm = (int)strtol(val, NULL, 8);
 
-    if (val = getoption(obj->iniconfig, section, "file perm", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "file perm", preset, NULL)))
         volume->v_fperm = (int)strtol(val, NULL, 8);
 
-    if (val = getoption(obj->iniconfig, section, "vol size limit", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "vol size limit", preset, NULL)))
         volume->v_limitsize = (uint32_t)strtoul(val, NULL, 10);
 
-    if (val = getoption(obj->iniconfig, section, "preexec", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "preexec", preset, NULL)))
         EC_NULL( volume->v_preexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) );
 
-    if (val = getoption(obj->iniconfig, section, "postexec", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "postexec", preset, NULL)))
         EC_NULL( volume->v_postexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) );
 
-    if (val = getoption(obj->iniconfig, section, "root preexec", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "root preexec", preset, NULL)))
         EC_NULL( volume->v_root_preexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) );
 
-    if (val = getoption(obj->iniconfig, section, "root postexec", preset, NULL))
+    if ((val = getoption(obj->iniconfig, section, "root postexec", preset, NULL)))
         EC_NULL( volume->v_root_postexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) );
 
-    if (val = getoption(obj->iniconfig, section, "appledouble", preset, NULL)) {
+    if ((val = getoption(obj->iniconfig, section, "appledouble", preset, NULL))) {
         if (strcmp(val, "v2") == 0)
             volume->v_adouble = AD_VERSION2;
         else if (strcmp(val, "ea") == 0)
@@ -691,10 +711,10 @@ static struct vol *creatvol(AFPObj *obj,
         volume->v_adouble = AD_VERSION;
     }
 
-    if (val = getoption(obj->iniconfig, section, "cnid server", preset, NULL)) {
+    if ((val = getoption(obj->iniconfig, section, "cnid server", preset, NULL))) {
         EC_NULL( p = strdup(val) );
         volume->v_cnidserver = p;
-        if (q = strrchr(val, ':')) {
+        if ((q = strrchr(val, ':'))) {
             *q++ = 0;
             volume->v_cnidport = strdup(q);
         } else {
@@ -706,7 +726,7 @@ static struct vol *creatvol(AFPObj *obj,
         volume->v_cnidport = strdup(obj->options.Cnid_port);
     }
 
-    if (val = getoption(obj->iniconfig, section, "ea", preset, NULL)) {
+    if ((val = getoption(obj->iniconfig, section, "ea", preset, NULL))) {
         if (strcasecmp(val, "ad") == 0)
             volume->v_vfs_ea = AFPVOL_EA_AD;
         else if (strcasecmp(val, "sys") == 0)
@@ -715,7 +735,7 @@ static struct vol *creatvol(AFPObj *obj,
             volume->v_vfs_ea = AFPVOL_EA_NONE;
     }
 
-    if (val = getoption(obj->iniconfig, section, "casefold", preset, NULL)) {
+    if ((val = getoption(obj->iniconfig, section, "casefold", preset, NULL))) {
         if (strcasecmp(val, "tolower") == 0)
             volume->v_casefold = AFPVOL_UMLOWER;
         else if (strcasecmp(val, "toupper") == 0)
@@ -750,6 +770,8 @@ static struct vol *creatvol(AFPObj *obj,
 #endif
     if (!getoption_bool(obj->iniconfig, section, "convert appledouble", preset, 1))
         volume->v_flags |= AFPVOL_NOV2TOEACONV;
+    if (getoption_bool(obj->iniconfig, section, "follow symlinks", preset, 0))
+        volume->v_flags |= AFPVOL_FOLLOWSYM;
 
     if (getoption_bool(obj->iniconfig, section, "preexec close", preset, 0))
         volume->v_preexec_close = 1;
@@ -777,6 +799,8 @@ static struct vol *creatvol(AFPObj *obj,
         volume->v_ad_options |= ADVOL_UNIXPRIV;
     if ((volume->v_flags & AFPVOL_INV_DOTS))
         volume->v_ad_options |= ADVOL_INVDOTS;
+    if ((volume->v_flags & AFPVOL_FOLLOWSYM))
+        volume->v_ad_options |= ADVOL_FOLLO_SYML;
 
     /* Mac to Unix conversion flags*/
     if ((volume->v_flags & AFPVOL_EILSEQ))
@@ -802,7 +826,7 @@ static struct vol *creatvol(AFPObj *obj,
 
     /* Unicode Volume Name */
     /* Firstly convert name from unixcharset to UTF8-MAC */
-    flags = CONV_IGNORE | CONV_ALLOW_SLASH;
+    flags = CONV_IGNORE;
     tmpvlen = convert_charset(obj->options.unixcharset, CH_UTF8_MAC, 0, name, vlen, tmpname, AFPVOL_U8MNAMELEN, &flags);
     if (tmpvlen <= 0) {
         strcpy(tmpname, "???");
@@ -812,7 +836,7 @@ static struct vol *creatvol(AFPObj *obj,
     /* Do we have to mangle ? */
     if ( (flags & CONV_REQMANGLE) || (tmpvlen > obj->options.volnamelen)) {
         if (tmpvlen + suffixlen > obj->options.volnamelen) {
-            flags = CONV_FORCE | CONV_ALLOW_SLASH;
+            flags = CONV_FORCE;
             tmpvlen = convert_charset(obj->options.unixcharset, CH_UTF8_MAC, 0, name, vlen, tmpname, obj->options.volnamelen - suffixlen, &flags);
             tmpname[tmpvlen >= 0 ? tmpvlen : 0] = 0;
         }
@@ -828,7 +852,7 @@ static struct vol *creatvol(AFPObj *obj,
 
     /* Maccharset Volume Name */
     /* Firsty convert name from unixcharset to maccharset */
-    flags = CONV_IGNORE | CONV_ALLOW_SLASH;
+    flags = CONV_IGNORE;
     tmpvlen = convert_charset(obj->options.unixcharset, obj->options.maccharset, 0, name, vlen, tmpname, AFPVOL_U8MNAMELEN, &flags);
     if (tmpvlen <= 0) {
         strcpy(tmpname, "???");
@@ -838,7 +862,7 @@ static struct vol *creatvol(AFPObj *obj,
     /* Do we have to mangle ? */
     if ( (flags & CONV_REQMANGLE) || (tmpvlen > AFPVOL_MACNAMELEN)) {
         if (tmpvlen + suffixlen > AFPVOL_MACNAMELEN) {
-            flags = CONV_FORCE | CONV_ALLOW_SLASH;
+            flags = CONV_FORCE;
             tmpvlen = convert_charset(obj->options.unixcharset,
                                       obj->options.maccharset,
                                       0,
@@ -867,10 +891,9 @@ static struct vol *creatvol(AFPObj *obj,
     EC_NULL( volume->v_localname = strdup(name) );
     EC_NULL( volume->v_u8mname = strdup_w(u8mtmpname) );
     EC_NULL( volume->v_macname = strdup_w(mactmpname) );
-    EC_NULL( volume->v_path = malloc(strlen(path) + 1) );
-
+    EC_NULL( volume->v_path = strdup(path) ); 
+        
     volume->v_name = utf8_encoding(obj) ? volume->v_u8mname : volume->v_macname;
-    strcpy(volume->v_path, path);
 
 #ifdef __svr4__
     volume->v_qfd = -1;
@@ -913,10 +936,8 @@ static struct vol *creatvol(AFPObj *obj,
 EC_CLEANUP:
     LOG(log_debug, logtype_afpd, "createvol: END: %d", ret);
     if (ret != 0) {
-        if (volume) {
+        if (volume)
             volume_free(volume);
-            free(volume);
-        }
         return NULL;
     }
     return volume;
@@ -953,13 +974,11 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent)
     EC_INIT;
     static int regexerr = -1;
     static regex_t reg;
-    char        path[MAXPATHLEN + 1];
+    char        *realvolpath;
     char        volname[AFPVOL_U8MNAMELEN + 1];
-    char        tmp[MAXPATHLEN + 1];
+    char        path[MAXPATHLEN + 1], tmp[MAXPATHLEN + 1];
     const char  *preset, *default_preset, *p, *basedir;
-    char        *q, *u;
     int         i;
-    struct passwd   *pw;
     regmatch_t match[1];
 
     LOG(log_debug, logtype_afpd, "readvolfile: BEGIN");
@@ -987,6 +1006,9 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent)
                 /* no user home */
                 continue;
 
+            if ((realpath(pwent->pw_dir, tmp)) == NULL)
+                continue;
+
             /* check if user home matches our "basedir regex" */
             if ((basedir = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "basedir regex", NULL)) == NULL) {
                 LOG(log_error, logtype_afpd, "\"basedir regex =\" must be defined in [Homes] section");
@@ -998,18 +1020,19 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent)
                 char errbuf[1024];
                 regerror(regexerr, &reg, errbuf, sizeof(errbuf));
                 LOG(log_debug, logtype_default, "readvolfile: bad basedir regex: %s", errbuf);
+                continue;
             }
 
-            if (regexec(&reg, pwent->pw_dir, 1, match, 0) == REG_NOMATCH) {
-                LOG(log_debug, logtype_default, "readvolfile: user home \"%s\" doesn't match basedir regex \"%s\"",
-                    pwent->pw_dir, basedir);
+            if (regexec(&reg, tmp, 1, match, 0) == REG_NOMATCH) {
+                LOG(log_error, logtype_default, "readvolfile: user home \"%s\" doesn't match basedir regex \"%s\"",
+                    tmp, basedir);
                 continue;
             }
 
-            strlcpy(tmp, pwent->pw_dir, MAXPATHLEN);
-            strlcat(tmp, "/", MAXPATHLEN);
-            if (p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL))
+            if ((p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL))) {
+                strlcat(tmp, "/", MAXPATHLEN);
                 strlcat(tmp, p, MAXPATHLEN);
+            }
         } else {
             /* Get path */
             if ((p = iniparser_getstring(obj->iniconfig, secname, "path", NULL)) == NULL)
@@ -1040,9 +1063,166 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent)
 
         preset = iniparser_getstring(obj->iniconfig, secname, "vol preset", NULL);
 
-        creatvol(obj, pwent, secname, volname, path, preset ? preset : default_preset ? default_preset : NULL);
+        if ((realvolpath = realpath_safe(path)) == NULL)
+            continue;
+
+        creatvol(obj, pwent, secname, volname, realvolpath, preset ? preset : default_preset ? default_preset : NULL);
+        free(realvolpath);
+    }
+
+// EC_CLEANUP:
+    EC_EXIT;
+}
+
+static struct extmap    *Extmap = NULL, *Defextmap = NULL;
+static int              Extmap_cnt;
+
+static int setextmap(char *ext, char *type, char *creator)
+{
+    EC_INIT;
+    struct extmap *em;
+    int           cnt;
+
+    if (Extmap == NULL) {
+        EC_NULL_LOG( Extmap = calloc(1, sizeof( struct extmap )) );
+    }
+
+    ext++;
+
+    for (em = Extmap, cnt = 0; em->em_ext; em++, cnt++)
+        if ((strdiacasecmp(em->em_ext, ext)) == 0)
+            goto EC_CLEANUP;
+
+    EC_NULL_LOG( Extmap = realloc(Extmap, sizeof(struct extmap) * (cnt + 2)) );
+    (Extmap + cnt + 1)->em_ext = NULL;
+    em = Extmap + cnt;
+
+    EC_NULL( em->em_ext = strdup(ext) );
+
+    if ( *type == '\0' ) {
+        memcpy(em->em_type, "\0\0\0\0", sizeof( em->em_type ));
+    } else {
+        memcpy(em->em_type, type, sizeof( em->em_type ));
+    }
+    if ( *creator == '\0' ) {
+        memcpy(em->em_creator, "\0\0\0\0", sizeof( em->em_creator ));
+    } else {
+        memcpy(em->em_creator, creator, sizeof( em->em_creator ));
+    }
+
+EC_CLEANUP:
+    EC_EXIT;
+}
+
+/* -------------------------- */
+static int extmap_cmp(const void *map1, const void *map2)
+{
+    const struct extmap *em1 = map1;
+    const struct extmap *em2 = map2;
+    return strdiacasecmp(em1->em_ext, em2->em_ext);
+}
+
+static void sortextmap( void)
+{
+    struct extmap   *em;
+
+    Extmap_cnt = 0;
+    if ((em = Extmap) == NULL) {
+        return;
+    }
+    while (em->em_ext) {
+        em++;
+        Extmap_cnt++;
+    }
+    if (Extmap_cnt) {
+        qsort(Extmap, Extmap_cnt, sizeof(struct extmap), extmap_cmp);
+        if (*Extmap->em_ext == 0) {
+            /* the first line is really "." the default entry,
+             * we remove the leading '.' in setextmap
+             */
+            Defextmap = Extmap;
+        }
+    }
+}
+
+static void free_extmap( void)
+{
+    struct extmap   *em;
+
+    if (Extmap) {
+        for ( em = Extmap; em->em_ext; em++) {
+            free (em->em_ext);
+        }
+        free(Extmap);
+        Extmap = NULL;
+        Defextmap = Extmap;
+        Extmap_cnt = 0;
+    }
+}
+
+static int ext_cmp_key(const void *key, const void *obj)
+{
+    const char          *p = key;
+    const struct extmap *em = obj;
+    return strdiacasecmp(p, em->em_ext);
+}
+
+struct extmap *getextmap(const char *path)
+{
+    char      *p;
+    struct extmap *em;
+
+    if (!Extmap_cnt || NULL == ( p = strrchr( path, '.' )) ) {
+        return( Defextmap );
+    }
+    p++;
+    if (!*p) {
+        return( Defextmap );
+    }
+    em = bsearch(p, Extmap, Extmap_cnt, sizeof(struct extmap), ext_cmp_key);
+    if (em) {
+        return( em );
+    } else {
+        return( Defextmap );
+    }
+}
+
+struct extmap *getdefextmap(void)
+{
+    return( Defextmap );
+}
+
+static int readextmap(const char *file)
+{
+    EC_INIT;
+    FILE        *fp;
+    char        ext[256];
+    char        buf[256];
+    char        type[5], creator[5];
+
+    LOG(log_debug, logtype_afpd, "readextmap: loading \"%s\"", file);
+
+    EC_NULL_LOGSTR( fp = fopen(file, "r"), "Couldn't open extension maping file %s", file);
+
+    while (fgets(buf, sizeof(buf), fp) != NULL) {
+        initline(strlen(buf), buf);
+        parseline(sizeof(ext) - 1, ext);
+
+        switch (ext[0]) {
+        case '.' :
+            parseline(sizeof(type) - 1, type);
+            parseline(sizeof(creator) - 1, creator);
+            setextmap(ext, type, creator);
+            LOG(log_debug, logtype_afpd, "readextmap: mapping: '%s' -> %s/%s", ext, type, creator);
+            break;
+        }
     }
 
+    sortextmap();
+    EC_ZERO( fclose(fp) );
+
+    LOG(log_debug, logtype_afpd, "readextmap: done", file);
+
 EC_CLEANUP:
     EC_EXIT;
 }
@@ -1076,12 +1256,14 @@ void volume_unlink(struct vol *volume)
 }
 
 /*!
- * Free all resources allocated in a struct vol, only struct dir *v_root can't be freed
+ * Free all resources allocated in a struct vol in load_volumes()
+ *
+ * Actually opening a volume (afp_openvol()) will allocate additional
+ * ressources which are freed in closevol()
  */
 void volume_free(struct vol *vol)
 {
-    LOG(log_debug, logtype_afpd, "volume_free('%s'): BEGIN", vol->v_localname);
-
+    free(vol->v_configname);
     free(vol->v_localname);
     free(vol->v_u8mname);
     free(vol->v_macname);
@@ -1096,10 +1278,12 @@ void volume_free(struct vol *vol)
     free(vol->v_uuid);
     free(vol->v_cnidserver);
     free(vol->v_cnidport);
+    free(vol->v_preexec);
     free(vol->v_root_preexec);
     free(vol->v_postexec);
+    free(vol->v_root_postexec);
 
-    LOG(log_debug, logtype_afpd, "volume_free: END");
+    free(vol);
 }
 
 /*!
@@ -1128,7 +1312,7 @@ int load_charset(struct vol *vol)
  * @param obj       (r) handle
  * @param delvol_fn (r) callback called for deleted volumes
  */
-int load_volumes(AFPObj *obj, void (*delvol_fn)(const AFPObj *obj, struct vol *))
+int load_volumes(AFPObj *obj)
 {
     EC_INIT;
     int fd = -1;
@@ -1180,12 +1364,24 @@ int load_volumes(AFPObj *obj, void (*delvol_fn)(const AFPObj *obj, struct vol *)
 
     EC_ZERO_LOG( readvolfile(obj, pwent) );
 
-    for ( vol = Volumes; vol; vol = vol->v_next ) {
-        if (vol->v_deleted) {
+    struct vol *p, *prevvol;
+
+    vol = Volumes;
+    prevvol = NULL;
+
+    while (vol) {
+        if (vol->v_deleted && !(vol->v_flags & AFPVOL_OPEN)) {
             LOG(log_debug, logtype_afpd, "load_volumes: deleted: %s", vol->v_localname);
-            if (delvol_fn)
-                delvol_fn(obj, vol);
-            vol = Volumes;
+            if (prevvol)
+                prevvol->v_next = vol->v_next;
+            else
+                Volumes = NULL;
+            p = vol->v_next;
+            volume_free(vol);
+            vol = p;
+        } else {
+            prevvol = vol;
+            vol = vol->v_next;
         }
     }
 
@@ -1199,12 +1395,16 @@ EC_CLEANUP:
 
 void unload_volumes(AFPObj *obj)
 {
-    struct vol *vol;
+    struct vol *vol, *p;
 
     LOG(log_debug, logtype_afpd, "unload_volumes: BEGIN");
 
-    for (vol = Volumes; vol; vol = vol->v_next)
+    p = Volumes;
+    while (p) {
+        vol = p;
+        p = vol->v_next;
         volume_free(vol);
+    }
     Volumes = NULL;
     obj->options.volfile.mtime = 0;
     
@@ -1263,7 +1463,7 @@ struct vol *getvolbypath(AFPObj *obj, const char *path)
     const struct passwd *pw;
     char        volname[AFPVOL_U8MNAMELEN + 1];
     char        abspath[MAXPATHLEN + 1];
-    char        volpath[MAXPATHLEN + 1];
+    char        volpath[MAXPATHLEN + 1], *realvolpath = NULL;
     char        tmpbuf[MAXPATHLEN + 1];
     const char *secname, *basedir, *p = NULL, *subpath = NULL, *subpathconfig;
     char *user = NULL, *prw;
@@ -1333,7 +1533,7 @@ struct vol *getvolbypath(AFPObj *obj, const char *path)
         p++;
     EC_NULL_LOG( user = strdup(p) );
 
-    if (prw = strchr(user, '/'))
+    if ((prw = strchr(user, '/')))
         *prw++ = 0;
     if (prw != 0)
         subpath = prw;
@@ -1343,10 +1543,12 @@ struct vol *getvolbypath(AFPObj *obj, const char *path)
     strlcat(tmpbuf, "/", MAXPATHLEN);
 
     /* (6) */
-    if (subpathconfig = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL)) {
+    if ((subpathconfig = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL))) {
+        /*
         if (!subpath || strncmp(subpathconfig, subpath, strlen(subpathconfig)) != 0) {
             EC_FAIL;
         }
+        */
         strlcat(tmpbuf, subpathconfig, MAXPATHLEN);
         strlcat(tmpbuf, "/", MAXPATHLEN);
     }
@@ -1354,29 +1556,32 @@ struct vol *getvolbypath(AFPObj *obj, const char *path)
 
     /* (7) */
     if (volxlate(obj, volpath, sizeof(volpath) - 1, tmpbuf, pw, NULL, NULL) == NULL)
-        return NULL;
+        EC_FAIL;
 
+    EC_NULL( realvolpath = realpath_safe(volpath) );
     EC_NULL( pw = getpwnam(user) );
 
-    LOG(log_debug, logtype_afpd, "getvolbypath(\"%s\"): user: %s, homedir: %s => volpath: \"%s\"",
-        path, user, pw->pw_dir, volpath);
+    LOG(log_debug, logtype_afpd, "getvolbypath(\"%s\"): user: %s, homedir: %s => realvolpath: \"%s\"",
+        path, user, pw->pw_dir, realvolpath);
 
     /* do variable substitution for volume name */
     p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "home name", "$u's home");
     if (strstr(p, "$u") == NULL)
         p = "$u's home";
     strlcpy(tmpbuf, p, AFPVOL_U8MNAMELEN);
-    EC_NULL_LOG( volxlate(obj, volname, sizeof(volname) - 1, tmpbuf, pw, volpath, NULL) );
+    EC_NULL_LOG( volxlate(obj, volname, sizeof(volname) - 1, tmpbuf, pw, realvolpath, NULL) );
 
     const char  *preset, *default_preset;
     default_preset = iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol preset", NULL);
     preset = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "vol preset", NULL);
 
-    vol = creatvol(obj, pw, INISEC_HOMES, volname, volpath, preset ? preset : default_preset ? default_preset : NULL);
+    vol = creatvol(obj, pw, INISEC_HOMES, volname, realvolpath, preset ? preset : default_preset ? default_preset : NULL);
 
 EC_CLEANUP:
     if (user)
         free(user);
+    if (realvolpath)
+        free(realvolpath);
     if (ret != 0)
         vol = NULL;
     return vol;
@@ -1405,8 +1610,8 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
     EC_INIT;
     dictionary *config;
     struct afp_options *options = &AFPObj->options;
-    int i, c;
-    const char *p, *tmp;
+    int c;
+    const char *p;
     char *q, *r;
     char val[MAXVAL];
 
@@ -1456,7 +1661,8 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
     /* figure out options w values */
     options->loginmesg      = iniparser_getstrdup(config, INISEC_GLOBAL, "login message",  NULL);
     options->guest          = iniparser_getstrdup(config, INISEC_GLOBAL, "guest account",  "nobody");
-    options->passwdfile     = iniparser_getstrdup(config, INISEC_GLOBAL, "passwd file",_PATH_AFPDPWFILE);
+    options->extmapfile     = iniparser_getstrdup(config, INISEC_GLOBAL, "extmap file",    _PATH_CONFDIR "extmap.conf");
+    options->passwdfile     = iniparser_getstrdup(config, INISEC_GLOBAL, "passwd file",    _PATH_AFPDPWFILE);
     options->uampath        = iniparser_getstrdup(config, INISEC_GLOBAL, "uam path",       _PATH_AFPDUAMPATH);
     options->uamlist        = iniparser_getstrdup(config, INISEC_GLOBAL, "uam list",       "uams_dhx.so uams_dhx2.so");
     options->port           = iniparser_getstrdup(config, INISEC_GLOBAL, "afp port",       "548");
@@ -1465,6 +1671,7 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
     options->k5realm        = iniparser_getstrdup(config, INISEC_GLOBAL, "k5 realm",       NULL);
     options->listen         = iniparser_getstrdup(config, INISEC_GLOBAL, "afp listen",     NULL);
     options->ntdomain       = iniparser_getstrdup(config, INISEC_GLOBAL, "nt domain",      NULL);
+    options->addomain       = iniparser_getstrdup(config, INISEC_GLOBAL, "ad domain",      NULL);
     options->ntseparator    = iniparser_getstrdup(config, INISEC_GLOBAL, "nt separator",   NULL);
     options->mimicmodel     = iniparser_getstrdup(config, INISEC_GLOBAL, "mimic model",    NULL);
     options->adminauthuser  = iniparser_getstrdup(config, INISEC_GLOBAL, "admin auth user",NULL);
@@ -1550,11 +1757,11 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
             LOG(log_debug, logtype_afpd, "Locale charset is '%s'", p);
 #else /* system doesn't have LOCALE support */
             LOG(log_warning, logtype_afpd, "system doesn't have LOCALE support");
-            p = strdup("UTF8");
+            p = "UTF8";
 #endif
         }
         if (strcasecmp(p, "UTF-8") == 0) {
-            p = strdup("UTF8");
+            p = "UTF8";
         }
         options->unixcodepage = strdup(p);
         set_charset_name(CH_UNIX, p);
@@ -1567,7 +1774,7 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
         options->volcodepage = strdup(options->unixcodepage);
     } else {
         if (strcasecmp(p, "UTF-8") == 0) {
-            p = strdup("UTF8");
+            p = "UTF8";
         }
         options->volcodepage = strdup(p);
     }
@@ -1587,6 +1794,11 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
     options->maccharset = CH_MAC;
     LOG(log_debug, logtype_afpd, "Global mac charset is %s", options->maccodepage);
 
+    if (readextmap(options->extmapfile) != 0) {
+        LOG(log_error, logtype_afpd, "Couldn't load extension -> type/creator mappings file \"%s\"",
+            options->extmapfile);
+    }
+
     /* Check for sane values */
     if (options->tickleval <= 0)
         options->tickleval = 30;
@@ -1606,3 +1818,80 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
 EC_CLEANUP:
     EC_EXIT;
 }
+
+#define CONFIG_ARG_FREE(a) do {                     \
+    free(a);                                        \
+    a = NULL;                                       \
+    } while (0);
+
+/* get rid of any allocated afp_option buffers. */
+void afp_config_free(AFPObj *obj)
+{
+    if (obj->options.configfile)
+        CONFIG_ARG_FREE(obj->options.configfile);
+    if (obj->options.sigconffile)
+        CONFIG_ARG_FREE(obj->options.sigconffile);
+    if (obj->options.uuidconf)
+        CONFIG_ARG_FREE(obj->options.uuidconf);
+    if (obj->options.logconfig)
+        CONFIG_ARG_FREE(obj->options.logconfig);
+    if (obj->options.logfile)
+        CONFIG_ARG_FREE(obj->options.logfile);
+    if (obj->options.loginmesg)
+        CONFIG_ARG_FREE(obj->options.loginmesg);
+    if (obj->options.guest)
+        CONFIG_ARG_FREE(obj->options.guest);
+    if (obj->options.extmapfile)
+        CONFIG_ARG_FREE(obj->options.extmapfile);
+    if (obj->options.passwdfile)
+        CONFIG_ARG_FREE(obj->options.passwdfile);
+    if (obj->options.uampath)
+        CONFIG_ARG_FREE(obj->options.uampath);
+    if (obj->options.uamlist)
+        CONFIG_ARG_FREE(obj->options.uamlist);
+    if (obj->options.port)
+        CONFIG_ARG_FREE(obj->options.port);
+    if (obj->options.signatureopt)
+        CONFIG_ARG_FREE(obj->options.signatureopt);
+    if (obj->options.k5service)
+        CONFIG_ARG_FREE(obj->options.k5service);
+    if (obj->options.k5realm)
+        CONFIG_ARG_FREE(obj->options.k5realm);
+    if (obj->options.listen)
+        CONFIG_ARG_FREE(obj->options.listen);
+    if (obj->options.ntdomain)
+        CONFIG_ARG_FREE(obj->options.ntdomain);
+    if (obj->options.addomain)
+        CONFIG_ARG_FREE(obj->options.addomain);
+    if (obj->options.ntseparator)
+        CONFIG_ARG_FREE(obj->options.ntseparator);
+    if (obj->options.mimicmodel)
+        CONFIG_ARG_FREE(obj->options.mimicmodel);
+    if (obj->options.adminauthuser)
+        CONFIG_ARG_FREE(obj->options.adminauthuser);
+    if (obj->options.hostname)
+        CONFIG_ARG_FREE(obj->options.hostname);
+    if (obj->options.k5keytab)
+        CONFIG_ARG_FREE(obj->options.k5keytab);
+    if (obj->options.Cnid_srv)
+        CONFIG_ARG_FREE(obj->options.Cnid_srv);
+    if (obj->options.Cnid_port)
+        CONFIG_ARG_FREE(obj->options.Cnid_port);
+    if (obj->options.fqdn)
+        CONFIG_ARG_FREE(obj->options.fqdn);
+
+    if (obj->options.unixcodepage)
+        CONFIG_ARG_FREE(obj->options.unixcodepage);
+    if (obj->options.maccodepage)
+        CONFIG_ARG_FREE(obj->options.maccodepage);
+    if (obj->options.volcodepage)
+        CONFIG_ARG_FREE(obj->options.volcodepage);
+
+    obj->options.flags = 0;
+    obj->options.passwdbits = 0;
+
+    /* Free everything called from afp_config_parse() */
+    free_extmap();
+    iniparser_freedict(obj->iniconfig);
+    free_charset_names();
+}
index ada3e61052353b972776eae3fa85046dac7057f1..547d68d93935ca6af668db74a63fef2ebc487a00 100644 (file)
@@ -135,7 +135,7 @@ afp_child_t *server_child_add(server_child *children, int forkid, pid_t pid, int
     fork = (server_child_fork *) children->fork + forkid;
 
     /* if we already have an entry. just return. */
-    if (child = resolve_child(fork->table, pid))
+    if ((child = resolve_child(fork->table, pid)))
         goto exit;
 
     if ((child = calloc(1, sizeof(afp_child_t))) == NULL)
@@ -262,7 +262,6 @@ int server_child_transfer_session(server_child *children,
     EC_INIT;
     server_child_fork *fork;
     struct server_child_data *child;
-    int i;
 
     fork = (server_child_fork *) children->fork + forkid;
     if ((child = resolve_child(fork->table, pid)) == NULL) {
index d40e3a49ea4cb07bf1b7984fc418cb5ec11521ee..815c58d8c0337a9c43d37d2137d1b2ed57a8ddbc 100644 (file)
@@ -267,8 +267,6 @@ int ipc_server_read(server_child *children, int fd)
     LOG(log_debug, logtype_afpd, "ipc_server_read(%s): pid: %u",
         ipc_cmd_str[ipc.command], ipc.child_pid); 
 
-    int afp_socket;
-
     switch (ipc.command) {
 
        case IPC_DISCOLDSESSION:
index 0251eadaeba94652c2b45474881f648ea1c5dde2..6ae817e5547c701891ee7e2d6dcfd554283b9870 100644 (file)
@@ -126,9 +126,7 @@ int check_lockfile(const char *program, const char *pidfile)
  */
 int create_lockfile(const char *program, const char *pidfile)
 {
-    char buf[10];
     FILE *pf;
-    pid_t pid;
     int mask;
   
     if (check_lockfile(program, pidfile) != 0)
index 56c3e168eaea05c05705464a0f21830aedf60c03..7c80e22d5d761085503fd990b05b63b38157a569 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys/time.h>
 #include <time.h>
 #include <sys/wait.h>
+#include <libgen.h>
 
 #include <atalk/adouble.h>
 #include <atalk/ea.h>
@@ -227,20 +228,103 @@ char *stripped_slashes_basename(char *p)
     return (strrchr(p, '/') ? strrchr(p, '/') + 1 : p);
 }
 
+/*********************************************************************************
+ * chdir(), chmod(), chown(), stat() wrappers taking an additional option.
+ * Currently the only used options are O_NOFOLLOW, used to switch between symlink
+ * behaviour, and O_NETATALK_ACL for ochmod() indicating chmod_acl() shall be
+ * called which does special ACL handling depending on the filesytem
+ *********************************************************************************/
+
+int ostat(const char *path, struct stat *buf, int options)
+{
+    if (options & O_NOFOLLOW)
+        return lstat(path, buf);
+    else
+        return stat(path, buf);
+}
+
+int ochown(const char *path, uid_t owner, gid_t group, int options)
+{
+    if (options & O_NOFOLLOW)
+        return lchown(path, owner, group);
+    else
+        return chown(path, owner, group);
+}
+
+/*!
+ * chmod() wrapper for symlink and ACL handling
+ *
+ * @param path       (r) path
+ * @param mode       (r) requested mode
+ * @param sb         (r) stat() of path or NULL
+ * @param option     (r) O_NOFOLLOW | O_NETATALK_ACL
+ *
+ * Options description:
+ * O_NOFOLLOW: don't chmod() symlinks, do nothing, return 0
+ * O_NETATALK_ACL: call chmod_acl() instead of chmod()
+ */
+int ochmod(char *path, mode_t mode, const struct stat *st, int options)
+{
+    struct stat sb;
+
+    if (!st) {
+        if (lstat(path, &sb) != 0)
+            return -1;
+        st = &sb;
+    }
+
+    if (options & O_NOFOLLOW)
+        if (S_ISLNK(st->st_mode))
+            return 0;
+
+    if (options & O_NETATALK_ACL) {
+        return chmod_acl(path, mode);
+    } else {
+        return chmod(path, mode);
+    }
+}
+
+/* 
+ * @brief ostat/fsstatat multiplexer
+ *
+ * ostatat mulitplexes ostat and fstatat. If we dont HAVE_ATFUNCS, dirfd is ignored.
+ *
+ * @param dirfd   (r) Only used if HAVE_ATFUNCS, ignored else, -1 gives AT_FDCWD
+ * @param path    (r) pathname
+ * @param st      (rw) pointer to struct stat
+ */
+int ostatat(int dirfd, const char *path, struct stat *st, int options)
+{
+#ifdef HAVE_ATFUNCS
+    if (dirfd == -1)
+        dirfd = AT_FDCWD;
+    return fstatat(dirfd, path, st, (options & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0);
+#else
+    return ostat(path, st, options);
+#endif            
+
+    /* DEADC0DE */
+    return -1;
+}
+
 /*!
  * @brief symlink safe chdir replacement
  *
- * Only chdirs to dir if it doesn't contain symlinks.
+ * Only chdirs to dir if it doesn't contain symlinks or if symlink checking
+ * is disabled
  *
  * @returns 1 if a path element is a symlink, 0 otherwise, -1 on syserror
  */
-int lchdir(const char *dir)
+int ochdir(const char *dir, int options)
 {
     char buf[MAXPATHLEN+1];
     char cwd[MAXPATHLEN+1];
     char *test;
     int  i;
 
+    if (!(options & O_NOFOLLOW))
+        return chdir(dir);
+
     /*
      dir is a canonical path (without "../" "./" "//" )
      but may end with a / 
@@ -342,3 +426,84 @@ int gmem(gid_t gid, int ngroups, gid_t *groups)
     }
     return( 0 );
 }
+
+/*
+ * realpath() replacement that always allocates storage for returned path
+ */
+char *realpath_safe(const char *path)
+{
+    char *resolved_path;
+
+#ifdef REALPATH_TAKES_NULL
+    if ((resolved_path = realpath(path, NULL)) == NULL) {
+        LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path);
+        return NULL;
+    }
+    return resolved_path;
+#else
+    if ((resolved_path = malloc(MAXPATHLEN+1)) == NULL)
+        return NULL;
+    if (realpath(path, resolved_path) == NULL) {
+        free(resolved_path);
+        LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path);
+        return NULL;
+    }
+    /* Safe some memory */
+    char *tmp;
+    if ((tmp = strdup(resolved_path)) == NULL) {
+        free(resolved_path);
+        return NULL;
+    }
+    free(resolved_path);
+    resolved_path = tmp;
+    return resolved_path;
+#endif
+}
+
+/**
+ * Returns pointer to static buffer with basename of path
+ **/
+const char *basename_safe(const char *path)
+{
+    static char buf[MAXPATHLEN+1];
+    strlcpy(buf, path, MAXPATHLEN);
+    return basename(buf);
+}
+
+/**
+ * extended strtok allows the quoted strings
+ * modified strtok.c in glibc 2.0.6
+ **/
+char *strtok_quote(char *s, const char *delim)
+{
+    static char *olds = NULL;
+    char *token;
+
+    if (s == NULL)
+        s = olds;
+
+    /* Scan leading delimiters.  */
+    s += strspn (s, delim);
+    if (*s == '\0')
+        return NULL;
+
+    /* Find the end of the token.  */
+    token = s;
+
+    if (token[0] == '\"') {
+        token++;
+        s = strpbrk (token, "\"");
+    } else {
+        s = strpbrk (token, delim);
+    }
+
+    if (s == NULL) {
+        /* This token finishes the string.  */
+        olds = strchr (token, '\0');
+    } else {
+        /* Terminate the token and make OLDS point past it.  */
+        *s = '\0';
+        olds = s + 1;
+    }
+    return token;
+}
index cdc7c82820b32837e1832be46054491a5a88898c..19c23e0672c8ac78ba2287b448f19bffe0b6baf9 100644 (file)
@@ -79,7 +79,7 @@ static char *mtoupath(const struct vol *vol, const char *mpath)
     char         *u;
     size_t       inplen;
     size_t       outlen;
-    uint16_t     flags = CONV_ESCAPEHEX | CONV_ALLOW_COLON;
+    uint16_t     flags = CONV_ESCAPEHEX;
 
     if (!mpath)
         return NULL;
@@ -906,7 +906,7 @@ int ea_close(struct ea * restrict ea)
             if (ea->ea_count == 0) {
                 /* Check if EA header exists and remove it */
                 eaname = ea_path(ea, NULL, 0);
-                if ((lstatat(ea->dirfd, eaname, &st)) == 0) {
+                if ((statat(ea->dirfd, eaname, &st)) == 0) {
                     if ((netatalk_unlinkat(ea->dirfd, eaname)) != 0) {
                         LOG(log_error, logtype_afpd, "ea_close('%s'): unlink: %s",
                             eaname, strerror(errno));
@@ -1583,7 +1583,7 @@ int ea_chown(VFS_FUNC_ARGS_CHOWN)
         }
     }
 
-    if ((lchown(ea_path(&ea, NULL, 0), uid, gid)) != 0) {
+    if ((ochown(ea_path(&ea, NULL, 0), uid, gid, vol_syml_opt(vol))) != 0) {
         switch (errno) {
         case EPERM:
         case EACCES:
@@ -1600,7 +1600,7 @@ int ea_chown(VFS_FUNC_ARGS_CHOWN)
             ret = AFPERR_MISC;
             goto exit;
         }
-        if ((lchown(eaname, uid, gid)) != 0) {
+        if ((ochown(eaname, uid, gid, vol_syml_opt(vol))) != 0) {
             switch (errno) {
             case EPERM:
             case EACCES:
@@ -1644,7 +1644,7 @@ int ea_chmod_file(VFS_FUNC_ARGS_SETFILEMODE)
     }
 
     /* Set mode on EA header file */
-    if ((setfilmode(ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL, vol->v_umask)) != 0) {
+    if ((setfilmode(vol, ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL)) != 0) {
         LOG(log_error, logtype_afpd, "ea_chmod_file('%s'): %s", ea_path(&ea, NULL, 0), strerror(errno));
         switch (errno) {
         case EPERM:
@@ -1663,7 +1663,7 @@ int ea_chmod_file(VFS_FUNC_ARGS_SETFILEMODE)
             ret = AFPERR_MISC;
             goto exit;
         }
-        if ((setfilmode(eaname, ea_mode(mode), NULL, vol->v_umask)) != 0) {
+        if ((setfilmode(vol, eaname, ea_mode(mode), NULL)) != 0) {
             LOG(log_error, logtype_afpd, "ea_chmod_file('%s'): %s", eaname, strerror(errno));
             switch (errno) {
             case EPERM:
@@ -1712,7 +1712,7 @@ int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE)
     }
 
     /* Set mode on EA header */
-    if ((setfilmode(ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL, vol->v_umask)) != 0) {
+    if ((setfilmode(vol, ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL)) != 0) {
         LOG(log_error, logtype_afpd, "ea_chmod_dir('%s'): %s", ea_path(&ea, NULL, 0), strerror(errno));
         switch (errno) {
         case EPERM:
@@ -1742,7 +1742,7 @@ int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE)
             ret = AFPERR_MISC;
             goto exit;
         }
-        if ((setfilmode(eaname, ea_mode(mode), NULL, vol->v_umask)) != 0) {
+        if ((setfilmode(vol, eaname, ea_mode(mode), NULL)) != 0) {
             LOG(log_error, logtype_afpd, "ea_chmod_dir('%s'): %s", eaname, strerror(errno));
             switch (errno) {
             case EPERM:
index a30e6d96b5b40121d3d8cebf434cb53fc8942a47..374248bc8a9e4696eedf28519aeeec5a80fa7761 100644 (file)
@@ -439,6 +439,9 @@ int sys_ea_copyfile(VFS_FUNC_ARGS_COPYFILE)
                if (!*name)
                        continue;
 
+        if (STRCMP(name, ==, AD_EA_META))
+            continue;
+
         if (sfd != -1) {
             if (fchdir(sfd) == -1) {
                 LOG(log_error, logtype_afpd, "sys_ea_copyfile: cant chdir to sfd: %s",
index 26da70636ff1a683c19d124a631105798f0d0541..5206aa6d69d16698f62f8c2d9fd4c2c770ab7bf3 100644 (file)
@@ -876,7 +876,6 @@ static int solaris_attropen(const char *path, const char *attrpath, int oflag, m
             EC_FAIL;
         default:
             LOG(log_debug, logtype_default, "open(\"%s\"): %s", fullpathname(path), strerror(errno));
-            errno = ENOATTR;
             EC_FAIL;
         }
        }
@@ -888,7 +887,6 @@ static int solaris_attropen(const char *path, const char *attrpath, int oflag, m
             EC_FAIL;
         default:
             LOG(log_debug, logtype_default, "openat(\"%s\"): %s", fullpathname(path), strerror(errno));
-            errno = ENOATTR;
             EC_FAIL;
         }
        }
index 1c0556d95e2eebc2e9baeccc34227a112ceeed8a..bc90c75ad539bcdaa7f8a00e14271adf37538092 100644 (file)
@@ -33,7 +33,7 @@ int dir_rx_set(mode_t mode)
 }
 
 /* --------------------- */
-int setfilmode(const char * name, mode_t mode, struct stat *st, mode_t v_umask)
+int setfilmode(const struct vol *vol, const char *name, mode_t mode, struct stat *st)
 {
     struct stat sb;
     mode_t mask = S_IRWXU | S_IRWXG | S_IRWXO;  /* rwx for owner group and other, by default */
@@ -44,12 +44,9 @@ int setfilmode(const char * name, mode_t mode, struct stat *st, mode_t v_umask)
         st = &sb;
     }
 
-    if (S_ISLNK(st->st_mode))
-        return 0; /* we don't want to change link permissions */
-    
     mode |= st->st_mode & ~mask; /* keep other bits from previous mode */
 
-    if ( chmod_acl( name,  mode & ~v_umask ) < 0 && errno != EPERM ) {
+    if (ochmod((char *)name, mode & ~vol->v_umask, st, vol_syml_opt(vol) | O_NETATALK_ACL) < 0 && errno != EPERM ) {
         return -1;
     }
     return 0;
@@ -169,9 +166,6 @@ int copy_file(int dirfd, const char *src, const char *dst, mode_t mode)
     int    ret = 0;
     int    sfd = -1;
     int    dfd = -1;
-    ssize_t cc;
-    size_t  buflen;
-    char   filebuf[NETATALK_DIOSZ_STACK];
 
 #ifdef HAVE_ATFUNCS
     if (dirfd == -1)
@@ -334,29 +328,6 @@ int statat(int dirfd, const char *path, struct stat *st)
     return -1;
 }
 
-/* 
- * @brief lstat/fsstatat multiplexer
- *
- * lstatat mulitplexes lstat and fstatat. If we dont HAVE_ATFUNCS, dirfd is ignored.
- *
- * @param dirfd   (r) Only used if HAVE_ATFUNCS, ignored else, -1 gives AT_FDCWD
- * @param path    (r) pathname
- * @param st      (rw) pointer to struct stat
- */
-int lstatat(int dirfd, const char *path, struct stat *st)
-{
-#ifdef HAVE_ATFUNCS
-    if (dirfd == -1)
-        dirfd = AT_FDCWD;
-    return (fstatat(dirfd, path, st, AT_SYMLINK_NOFOLLOW));
-#else
-    return (lstat(path, st));
-#endif            
-
-    /* DEADC0DE */
-    return -1;
-}
-
 /* 
  * @brief opendir wrapper for *at semantics support
  *
index 8495d8c22fba19dd88789b82c6822bfb4a4fb3d6..3dd3ebb4057afab123d6c4d85ea5c074d2e4e157 100644 (file)
@@ -49,11 +49,11 @@ struct perm {
     gid_t gid;
 };
 
-typedef int (*rf_loop)(struct dirent *, char *, void *, int , mode_t );
+typedef int (*rf_loop)(const struct vol *, struct dirent *, char *, void *, int);
 
 /* ----------------------------- */
 static int 
-for_each_adouble(const char *from, const char *name, rf_loop fn, void *data, int flag, mode_t v_umask)
+for_each_adouble(const char *from, const char *name, rf_loop fn, const struct vol *vol, void *data, int flag)
 {
     char            buf[ MAXPATHLEN + 1];
     char            *m;
@@ -79,7 +79,7 @@ for_each_adouble(const char *from, const char *name, rf_loop fn, void *data, int
         }
         
         strlcat(buf, de->d_name, sizeof(buf));
-        if (fn && (ret = fn(de, buf, data, flag, v_umask))) {
+        if (fn && (ret = fn(vol, de, buf, data, flag))) {
            closedir(dp);
            return ret;
         }
@@ -127,7 +127,7 @@ static int RF_renamedir_adouble(VFS_FUNC_ARGS_RENAMEDIR)
 }
 
 /* ----------------- */
-static int deletecurdir_adouble_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask)
+static int deletecurdir_adouble_loop(const struct vol *vol, struct dirent *de, char *name, void *data _U_, int flag _U_)
 {
     struct stat st;
     int         err;
@@ -150,34 +150,33 @@ static int RF_deletecurdir_adouble(VFS_FUNC_ARGS_DELETECURDIR)
 
     /* delete stray .AppleDouble files. this happens to get .Parent files
        as well. */
-    if ((err = for_each_adouble("deletecurdir", ".AppleDouble", deletecurdir_adouble_loop, NULL, 1, vol->v_umask))) 
+    if ((err = for_each_adouble("deletecurdir", ".AppleDouble", deletecurdir_adouble_loop, vol, NULL, 1))) 
         return err;
     return netatalk_rmdir(-1, ".AppleDouble" );
 }
 
 /* ----------------- */
-static int adouble_setfilmode(const char * name, mode_t mode, struct stat *st, mode_t v_umask)
+static int adouble_setfilmode(const struct vol *vol, const char *name, mode_t mode, struct stat *st)
 {
-    return setfilmode(name, ad_hf_mode(mode), st, v_umask);
+    return setfilmode(vol, name, ad_hf_mode(mode), st);
 }
 
 static int RF_setfilmode_adouble(VFS_FUNC_ARGS_SETFILEMODE)
 {
-    return adouble_setfilmode(vol->ad_path(name, ADFLAGS_HF ), mode, st, vol->v_umask);
+    return adouble_setfilmode(vol, vol->ad_path(name, ADFLAGS_HF ), mode, st);
 }
 
 /* ----------------- */
 static int RF_setdirunixmode_adouble(VFS_FUNC_ARGS_SETDIRUNIXMODE)
 {
     const char *adouble = vol->ad_path(name, ADFLAGS_DIR );
-    int  dropbox = vol->v_flags;
 
     if (dir_rx_set(mode)) {
         if (chmod_acl(ad_dir(adouble), (DIRBITS | mode) & ~vol->v_umask) < 0 ) 
             return -1;
     }
 
-    if (adouble_setfilmode(vol->ad_path(name, ADFLAGS_DIR ), mode, st, vol->v_umask) < 0) 
+    if (adouble_setfilmode(vol, vol->ad_path(name, ADFLAGS_DIR ), mode, st) < 0) 
         return -1;
 
     if (!dir_rx_set(mode)) {
@@ -188,18 +187,18 @@ static int RF_setdirunixmode_adouble(VFS_FUNC_ARGS_SETDIRUNIXMODE)
 }
 
 /* ----------------- */
-static int setdirmode_adouble_loop(struct dirent *de _U_, char *name, void *data, int flag, mode_t v_umask)
+static int setdirmode_adouble_loop(const struct vol *vol, struct dirent *de _U_, char *name, void *data, int flag)
 {
     mode_t hf_mode = *(mode_t *)data;
     struct stat st;
 
-    if ( stat( name, &st ) < 0 ) {
+    if (ostat(name, &st, vol_syml_opt(vol)) < 0 ) {
         if (flag)
             return 0;
         LOG(log_error, logtype_afpd, "setdirmode: stat %s: %s", name, strerror(errno) );
     }
     else if (!S_ISDIR(st.st_mode)) {
-        if (setfilmode(name, hf_mode , &st, v_umask) < 0) {
+        if (setfilmode(vol, name, hf_mode, &st) < 0) {
                /* FIXME what do we do then? */
         }
     }
@@ -208,7 +207,6 @@ static int setdirmode_adouble_loop(struct dirent *de _U_, char *name, void *data
 
 static int RF_setdirmode_adouble(VFS_FUNC_ARGS_SETDIRMODE)
 {
-    int   dropbox = vol->v_flags;
     mode_t hf_mode = ad_hf_mode(mode);
     const char  *adouble = vol->ad_path(name, ADFLAGS_DIR );
     const char  *adouble_p = ad_dir(adouble);
@@ -218,7 +216,7 @@ static int RF_setdirmode_adouble(VFS_FUNC_ARGS_SETDIRMODE)
             return -1;
     }
 
-    if (for_each_adouble("setdirmode", adouble_p, setdirmode_adouble_loop, &hf_mode, 0, vol->v_umask))
+    if (for_each_adouble("setdirmode", adouble_p, setdirmode_adouble_loop, vol, &hf_mode, 0))
         return -1;
 
     if (!dir_rx_set(mode)) {
@@ -257,7 +255,7 @@ static int RF_renamefile_adouble(VFS_FUNC_ARGS_RENAMEFILE)
         if (errno == ENOENT) {
                struct adouble    ad;
 
-            if (lstatat(dirfd, adsrc, &st)) /* source has no ressource fork, */
+            if (ostatat(dirfd, adsrc, &st, vol_syml_opt(vol))) /* source has no ressource fork, */
                 return 0;
 
             /* We are here  because :
@@ -487,7 +485,7 @@ static int RF_renamedir_ea(VFS_FUNC_ARGS_RENAMEDIR)
 }
 
 /* Returns 1 if the entry is NOT an ._ file */
-static int deletecurdir_ea_osx_chkifempty_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask _U_)
+static int deletecurdir_ea_osx_chkifempty_loop(const struct vol *vol, struct dirent *de, char *name, void *data _U_, int flag _U_)
 {
     if (de->d_name[0] != '.' || de->d_name[0] == '_')
         return 1;
@@ -495,7 +493,7 @@ static int deletecurdir_ea_osx_chkifempty_loop(struct dirent *de, char *name, vo
     return 0;
 }
 
-static int deletecurdir_ea_osx_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask _U_)
+static int deletecurdir_ea_osx_loop(const struct vol *vol, struct dirent *de, char *name, void *data _U_, int flag _U_)
 {
     int ret;
     
@@ -515,7 +513,7 @@ static int RF_deletecurdir_ea(VFS_FUNC_ARGS_DELETECURDIR)
     /* first check if there's really no other file besides files starting with ._ */
     if ((err = for_each_adouble("deletecurdir_ea_osx", ".",
                                 deletecurdir_ea_osx_chkifempty_loop,
-                                NULL, 0, 0)) != 0) {
+                                vol, NULL, 0)) != 0) {
         if (err == 1)
             return AFPERR_DIRNEMPT;
         return AFPERR_MISC;
@@ -524,7 +522,7 @@ static int RF_deletecurdir_ea(VFS_FUNC_ARGS_DELETECURDIR)
     /* Now delete orphaned ._ files */
     if ((err = for_each_adouble("deletecurdir_ea_osx", ".",
                                 deletecurdir_ea_osx_loop,
-                                NULL, 0, 0)) != 0)
+                                vol, NULL, 0)) != 0)
         return err;
 
 #endif
@@ -542,7 +540,7 @@ static int RF_setdirunixmode_ea(VFS_FUNC_ARGS_SETDIRUNIXMODE)
 static int RF_setfilmode_ea(VFS_FUNC_ARGS_SETFILEMODE)
 {
 #ifndef HAVE_EAFD
-    return adouble_setfilmode(vol->ad_path(name, ADFLAGS_HF ), mode, st, vol->v_umask);
+    return adouble_setfilmode(vol, vol->ad_path(name, ADFLAGS_HF ), mode, st);
 #endif
     return 0;
 }
@@ -643,7 +641,7 @@ static int RF_renamefile_ea(VFS_FUNC_ARGS_RENAMEFILE)
         struct stat st;
 
         err = errno;
-        if (errno == ENOENT && lstatat(dirfd, adsrc, &st)) /* source has no ressource fork, */
+        if (errno == ENOENT && ostatat(dirfd, adsrc, &st, vol_syml_opt(vol))) /* source has no ressource fork, */
             return 0;
         errno = err;
         return -1;
index 6c541a8fe0e6fb42c6aecd76629029a3978e594b..8e1f9c69fc3e8ec838d054dcf0598267de4aab04 100644 (file)
@@ -1,5 +1,6 @@
 EXTRA_DIST = \
        afs-check.m4            \
+       ax_pthread.m4           \
        cnid-backend.m4         \
        config-checks.m4        \
        db3-check.m4            \
@@ -17,4 +18,3 @@ EXTRA_DIST = \
        summary.m4              \
        tcp-wrappers.m4         \
        util.m4
-
index 799cfa2649e6fefab6fd3ffe3fdfc0c9a1a19571..48925d88ce9aad993a6762a486d8d2f6bc4ff18b 100644 (file)
@@ -1,4 +1,3 @@
-dnl $Id: afs-check.m4,v 1.4 2005-08-11 20:15:35 didg Exp $
 dnl Autoconf macro to check whether AFS support should be enabled
 
 AC_DEFUN([AC_NETATALK_AFS_CHECK], [
diff --git a/macros/ax_pthread.m4 b/macros/ax_pthread.m4
new file mode 100644 (file)
index 0000000..9ede48e
--- /dev/null
@@ -0,0 +1,309 @@
+# ===========================================================================
+#        http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro figures out how to build C programs using POSIX threads. It
+#   sets the PTHREAD_LIBS output variable to the threads library and linker
+#   flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+#   flags that are needed. (The user can also force certain compiler
+#   flags/libs to be tested by setting these environment variables.)
+#
+#   Also sets PTHREAD_CC to any special C compiler that is needed for
+#   multi-threaded programs (defaults to the value of CC otherwise). (This
+#   is necessary on AIX to use the special cc_r compiler alias.)
+#
+#   NOTE: You are assumed to not only compile your program with these flags,
+#   but also link it with them as well. e.g. you should link with
+#   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+#   If you are only building threads programs, you may wish to use these
+#   variables in your default LIBS, CFLAGS, and CC:
+#
+#     LIBS="$PTHREAD_LIBS $LIBS"
+#     CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+#     CC="$PTHREAD_CC"
+#
+#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+#   Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+#   PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+#   PTHREAD_CFLAGS.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a threads library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_PTHREAD.
+#
+#   Please let the authors know if this macro fails on any platform, or if
+#   you have any other suggestions or comments. This macro was based on work
+#   by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+#   from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+#   Alejandro Forero Cuervo to the autoconf macro repository. We are also
+#   grateful for the helpful feedback of numerous users.
+#
+#   Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+#   Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+#   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 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 18
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
+        AC_MSG_RESULT($ax_pthread_ok)
+        if test x"$ax_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+        solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+        ;;
+
+        darwin*)
+        ax_pthread_flags="-pthread $ax_pthread_flags"
+        ;;
+esac
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+                pthread-config)
+                AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
+                if test x"$ax_pthread_config" = xno; then continue; fi
+                PTHREAD_CFLAGS="`pthread-config --cflags`"
+                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+                ;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+                        static void routine(void *a) { a = 0; }
+                        static void *start_routine(void *a) { return a; }],
+                       [pthread_t th; pthread_attr_t attr;
+                        pthread_create(&th, 0, start_routine, 0);
+                        pthread_join(th, 0);
+                        pthread_attr_init(&attr);
+                        pthread_cleanup_push(routine, 0);
+                        pthread_cleanup_pop(0) /* ; */])],
+                [ax_pthread_ok=yes],
+                [])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT($ax_pthread_ok)
+        if test "x$ax_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+        AC_MSG_CHECKING([for joinable pthread attribute])
+        attr_name=unknown
+        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+            AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+                           [int attr = $attr; return attr /* ; */])],
+                [attr_name=$attr; break],
+                [])
+        done
+        AC_MSG_RESULT($attr_name)
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case ${host_os} in
+            aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+            osf* | hpux*) flag="-D_REENTRANT";;
+            solaris*)
+            if test "$GCC" = "yes"; then
+                flag="-D_REENTRANT"
+            else
+                flag="-mt -D_REENTRANT"
+            fi
+            ;;
+        esac
+        AC_MSG_RESULT(${flag})
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+            ax_cv_PTHREAD_PRIO_INHERIT, [
+                AC_LINK_IFELSE([
+                    AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
+                    [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+                    [ax_cv_PTHREAD_PRIO_INHERIT=no])
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
+            AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: must compile with xlc_r or cc_r
+        if test x"$GCC" != xyes; then
+          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+        else
+          PTHREAD_CC=$CC
+        fi
+else
+        PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        :
+else
+        ax_pthread_ok=no
+        $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
index d2a5544a29f76ed5d800902fa9a54a9087102113..8eb5864d25710d397d0516b529067333199614bc 100644 (file)
@@ -1,5 +1,4 @@
 dnl Autoconf macro to check for the existence of grep
-dnl $Id: grep-check.m4,v 1.2 2002-02-14 18:02:04 jmarcus Exp $
 
 AC_DEFUN([AC_PROG_GREP], [
 AC_REQUIRE([AC_EXEEXT])dnl
index 7040eb0462a69526baabec134ebb1dc8cf6707fb..e77aac53ffdb1d3ed72b7bb762ac7093d7a1b218 100644 (file)
@@ -15,24 +15,28 @@ AC_DEFUN([AC_DEVELOPER], [
 
 dnl Whether to disable bundled libevent
 AC_DEFUN([AC_NETATALK_LIBEVENT], [
-    use_bundled_libevent=no
-    AC_MSG_CHECKING([whether to use bundled or installed libevent])
+    AC_MSG_CHECKING([whether to use bundled libevent])
+    AC_ARG_WITH(
+        libevent,
+        [AS_HELP_STRING([--with-libevent],[whether to use the bundled libevent (default: yes)])],
+        use_bundled_libevent=$withval,
+        use_bundled_libevent=yes
+    )
     AC_ARG_WITH(
         libevent-header,
         [AS_HELP_STRING([--with-libevent-header],[path to libevent header files])],
-        LIBEVENT_CFLAGS=-I$withval,
-        use_bundled_libevent=yes
+        [use_bundled_libevent=no; LIBEVENT_CFLAGS=-I$withval]
     )
     AC_ARG_WITH(
         libevent-lib,
-        [AS_HELP_STRING([--with-libevent-lib],[path to libevent header library])],
-        LIBEVENT_LDFLAGS=-L$withval,
-        use_bundled_libevent=yes
+        [AS_HELP_STRING([--with-libevent-lib],[path to libevent library])],
+        [use_bundled_libevent=no; LIBEVENT_LDFLAGS=-L$withval]
     )
-    AC_MSG_RESULT([$use_bundled_libevent])
-    if test x"$use_bundled_libevent" = x"yes" ; then
-        AC_CONFIG_SUBDIRS([libevent])
+    if test x"$LIBEVENT_CFLAGS" = x"-Iyes" -o x"$LIBEVENT_LDFLAGS" = x"-Lyes" ; then
+        AC_MSG_ERROR([--with-libevent requires a path])
     fi
+    AC_MSG_RESULT([$use_bundled_libevent])
+    AC_CONFIG_SUBDIRS([libevent])
     AC_SUBST(LIBEVENT_CFLAGS)
     AC_SUBST(LIBEVENT_LDFLAGS)
     AM_CONDITIONAL(USE_BUILTIN_LIBEVENT, test x"$use_bundled_libevent" = x"yes")
@@ -355,7 +359,7 @@ fi
 dnl ----- Linux specific -----
 if test x"$this_os" = "xlinux"; then 
        AC_MSG_RESULT([ * Linux specific configuration])
-       
+    AC_DEFINE(LINUX, 1, [OS is Linux]) 
        dnl ----- check if we need the quotactl wrapper
     AC_CHECK_HEADERS(linux/dqblk_xfs.h,,
                [AC_CHECK_HEADERS(linux/xqm.h linux/xfs_fs.h)
@@ -581,7 +585,7 @@ save_CFLAGS="$CFLAGS"
 save_LIBS="$LIBS"
 CFLAGS="$KRB5_CFLAGS"
 LIBS="$KRB5_LIBS"
-AC_CHECK_FUNCS([krb5_free_unparsed_name krb5_free_error_message])
+AC_CHECK_FUNCS([krb5_free_unparsed_name krb5_free_error_message krb5_free_keytab_entry_contents krb5_kt_free_entry])
 CFLAGS="$save_CFLAGS"
 LIBS="$save_LIBS"
 ])
index 6bc40cbad841562161bf2c1a6a1f3cd776cdb5e4..17a92898c6d7b4c8e7161c298c81ddb04f5044c4 100644 (file)
@@ -1,4 +1,3 @@
-dnl $Id: pam-check.m4,v 1.6 2010-01-11 13:06:02 franklahm Exp $
 dnl PAM finding macro
 
 AC_DEFUN([AC_NETATALK_PATH_PAM], [
@@ -98,6 +97,13 @@ AC_DEFUN([AC_NETATALK_PATH_PAM], [
            PAM_ACCOUNT=system
            PAM_PASSWORD=system
            PAM_SESSION=system
+        dnl Solaris 11+
+        elif test -f "$pampath/other" ; then
+           PAM_DIRECTIVE=include
+           PAM_AUTH=${PAMDIR}etc/pam.d/other
+           PAM_ACCOUNT=${PAMDIR}etc/pam.d/other
+           PAM_PASSWORD=${PAMDIR}etc/pam.d/other
+           PAM_SESSION=${PAMDIR}etc/pam.d/other
         dnl Fallback
         else
            PAM_DIRECTIVE=required
index 7ad755b973e52aaf02263c0896337acc54f30eaa..6ae7ea6f901a1e174fef04a88ccca740fa6a944d 100644 (file)
@@ -1,5 +1,4 @@
 dnl Autoconf macro to check for the existence of Perl
-dnl $Id: perl-check.m4,v 1.4 2002-03-12 11:03:49 srittau Exp $
 
 AC_DEFUN([AC_PROG_PERL], [
        AC_REQUIRE([AC_EXEEXT])dnl
index 3f47b85f37ef7f3ee45c4a107e151d7868349e51..75d5c9538553f708b3a3cc89c1d17a4e9f26c28c 100644 (file)
@@ -1,5 +1,4 @@
 dnl Autoconf macro to check for the existence of ps
-dnl $Id: ps-check.m4,v 1.2 2002-02-14 18:02:04 jmarcus Exp $
 
 AC_DEFUN([AC_PROG_PS], [
 AC_REQUIRE([AC_EXEEXT])dnl
index b7e0c3a213f659dfd041eb04be39cc672c061a17..703c3568d34d38b36029a2c2e342abb8713af5a3 100644 (file)
@@ -1,4 +1,3 @@
-dnl $Id: quota-check.m4,v 1.6 2005-07-20 23:58:21 didg Exp $
 dnl Autoconf macro to check for quota support
 dnl FIXME: This is in now way complete.
 
index 8d9c1b6c66650e5ca8f8f337057b8a229c69cccc..8a58142be879c1a8402dce97797e67feadee1ab6 100644 (file)
@@ -1,4 +1,3 @@
-dnl $Id: ssl-check.m4,v 1.14 2008-11-22 12:07:26 didg Exp $
 dnl Autoconf macro to check for SSL or OpenSSL
 
 AC_DEFUN([AC_NETATALK_CRYPT], [
index 94e84ac94ce565f2d103d882c6f1cbc7397ea3e5..6c696fc2ee07bb0a9b79c41d257b8b21470476ad 100644 (file)
@@ -69,8 +69,11 @@ AC_DEFUN([AC_NETATALK_LIBS_SUMMARY], [
        dnl # Display summary of libraries detected
 
        AC_MSG_RESULT([Using libraries:])
-       AC_MSG_RESULT([    LIBS = $LIBS])
-       AC_MSG_RESULT([    CFLAGS = $CFLAGS])
+       AC_MSG_RESULT([    LIBS           = $LIBS])
+       AC_MSG_RESULT([    CFLAGS         = $CFLAGS])
+       AC_MSG_RESULT([    PTHREADS:])
+       AC_MSG_RESULT([        LIBS   = $PTHREAD_LIBS])
+       AC_MSG_RESULT([        CFLAGS = $PTHREAD_CFLAGS])
        if test x"$neta_cv_have_openssl" = x"yes"; then
                AC_MSG_RESULT([    SSL:])
                AC_MSG_RESULT([        LIBS   = $SSL_LIBS])
@@ -116,4 +119,11 @@ AC_DEFUN([AC_NETATALK_LIBS_SUMMARY], [
                AC_MSG_RESULT([        LIBS   = $LDAP_LDLFLAGS $LDAP_LIBS])
                AC_MSG_RESULT([        CFLAGS = $LDAP_CFLAGS])
        fi
+    AC_MSG_RESULT([    LIBEVENT:])
+    if test x"$use_bundled_libevent" = x"yes"; then
+               AC_MSG_RESULT([        bundled])
+    else
+               AC_MSG_RESULT([        LIBS   = $LIBEVENT_CFLAGS])
+               AC_MSG_RESULT([        CFLAGS = $LIBEVENT_LDFLAGS])
+    fi
 ])
index 55b0f8c179428c464634cd6f5aa601b6f6521a9f..76b75a09cd05a85d633c1bdfd20645d83cb86f82 100644 (file)
@@ -1,4 +1,3 @@
-dnl $Id: tcp-wrappers.m4,v 1.4 2008-08-11 20:44:03 didg Exp $
 
 AC_DEFUN([AC_NETATALK_TCP_WRAPPERS], [
        check=maybe
index 4d85e8bec1adaf1bae6576a905d8456c3e6f9054..20b143643467aa181fb2bcb268e5e49881aa35e2 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: ad
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 02 Sep 2011
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "AD" "1" "02 Sep 2011" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
@@ -28,10 +37,10 @@ ad \- Netatalk compatible UNIX file utility suite\&.
 .SH "DESCRIPTION"
 .PP
 \fBad\fR
-is a UNIX file utlity suite with Netatalk compatibity\&. AppleDouble
+is a UNIX file utility suite with Netatalk compatibility\&. AppleDouble
 files in
 \&.AppleDouble
-directories and the CNID databases are updated as appropiate\&.
+directories and the CNID databases are updated as appropriate\&.
 .SH "AVAILABLE COMMANDS"
 .HP \w'\fBad\ ls\fR\ 'u
 \fBad ls\fR [\-dRl\ [u]] {file|dir\ [\&.\&.\&.]}
@@ -110,7 +119,7 @@ AFP Attributes:
   l = No delete                       (f/d)
   o = No copy                         (f)
 
-Note: any letter appearing in uppercase means the flag is set but it\'s a directory for which the flag is not allowed\&.
+Note: any letter appearing in uppercase means the flag is set but it\*(Aqs a directory for which the flag is not allowed\&.
 .fi
 .if n \{\
 .RE
@@ -121,7 +130,7 @@ Copy files and directories\&.
 .PP
 In the first synopsis form, the cp utility copies the contents of the source_file to the target_file\&. In the second synopsis form, the contents of each named source_file is copied to the destination target_directory\&. The names of the files themselves are not changed\&. If cp detects an attempt to copy a file to itself, the copy will fail\&.
 .PP
-Netatalk AFP volumes are detected by means of their "\&.AppleDesktop" directory which is located in their volume root\&. When a copy targetting an AFP volume is detected, its CNID database daemon is connected and all copies will also go through the CNID database\&. AppleDouble files are also copied and created as needed when the target is an AFP volume\&.
+Netatalk AFP volumes are detected by means of their "\&.AppleDesktop" directory which is located in their volume root\&. When a copy targeting an AFP volume is detected, its CNID database daemon is connected and all copies will also go through the CNID database\&. AppleDouble files are also copied and created as needed when the target is an AFP volume\&.
 .PP
 Options:
 .PP
@@ -137,7 +146,7 @@ For each existing destination pathname, remove it and create a new file, without
 .PP
 \-i
 .RS 4
-Cause cp to write a prompt to the standard error output before copying a file that would overwrite an existing file\&. If the response from the standard input begins with the character \'y\' or \'Y\', the file copy is attempted\&. (The \-i option overrides any pre\- vious \-f or \-n options\&.)
+Cause cp to write a prompt to the standard error output before copying a file that would overwrite an existing file\&. If the response from the standard input begins with the character \*(Aqy\*(Aq or \*(AqY\*(Aq, the file copy is attempted\&. (The \-i option overrides any pre\- vious \-f or \-n options\&.)
 .RE
 .PP
 \-n
@@ -192,7 +201,6 @@ source or destination is not an AFP volume
 source AFP volume != destination AFP volume
 .RE
 .sp
-.RE
 the files are copied and removed from the source\&.
 .PP
 Options:
@@ -204,7 +212,7 @@ Do not prompt for confirmation before overwriting the destination path\&. (The \
 .PP
 \-i
 .RS 4
-Cause mv to write a prompt to standard error before moving a file that would overwrite an existing file\&. If the response from the standard input begins with the character `y\' or `Y\', the move is attempted\&. (The \-i option overrides any previous \-f or \-n options\&.)
+Cause mv to write a prompt to standard error before moving a file that would overwrite an existing file\&. If the response from the standard input begins with the character `y\*(Aq or `Y\*(Aq, the move is attempted\&. (The \-i option overrides any previous \-f or \-n options\&.)
 .RE
 .PP
 \-n
index 1d4fbd7edf35e068790f2fc0f03ec943b0b7adff..5c4c67f49c2bc1be873ee85ae4f9b1695e384358 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: afpldaptest
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 22 Mar 2012
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "AFPLDAPTEST" "1" "22 Mar 2012" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
index 860eb693e49b9acaa342d6d6d7c024f5198da751..60d640c054de859e45e03d0436799de0e52583ed 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: afppasswd
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 22 Mar 2012
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "AFPPASSWD" "1" "22 Mar 2012" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
@@ -45,7 +54,7 @@ can either be called by root with parameters, or can be called by local system u
 .PP
 With this utility you can only change the passwords used by two specific UAMs\&. As they provide only weak password encryption, the use of the "Randnum exchange" and "2\-Way Randnum exchange" UAMs is deprecated unless one has to support very old AFP clients, that can not deal with the more secure "DHCAST128" and "DHX2" UAM instead\&. Please compare with the
 Authentication chapter
-inside Netatalk\'s documentation\&.
+inside Netatalk\*(Aqs documentation\&.
 .sp .5v
 .RE
 .SH "EXAMPLE"
index 37e9f6e649763563fd9fb1355dc531cf11a170fd..f8676fda90bce203e9ed4fbeca5940da97fc0e73 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: apple_dump
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 16 Jul 2012
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "APPLE_DUMP" "1" "16 Jul 2012" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
@@ -92,9 +101,9 @@ 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\&.
+There is no way to detect whether FinderInfo is FileInfo or DirInfo\&. By default, apple_dump examines whether file or directory, a parent directory is \&.AppleDouble, filename is \&._*, filename is \&.Parent, and so on\&.
 .PP
-If setting option \-e, \-f or \-d, assume FinderInfo and doesn\'t look for another file\&.
+If setting option \-e, \-f or \-d, assume FinderInfo and doesn\*(Aqt look for another file\&.
 .SH "SEE ALSO"
 .PP
 \fBad\fR(1),
index 4de42c58434efbf7dba702714d84b892905bf145..735f8eb7b5d638fd8f2fc24b87563559f8fe11b2 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     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/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 24 Jul 2012
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "ASIP\-STATUS\&.PL" "1" "24 Jul 2012" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
@@ -30,9 +39,9 @@ asip-status.pl \- Queries AFP servers for their capabilities
 .SH "DESCRIPTION"
 .PP
 \fBasip\-status\&.pl\fR
-is a perl script that sends a FPGetSrvrInfo request to an AFP server at HOSTNAME:PORT and displays the results, namely "Machine type", the server\'s name, supported AFP versions, UAMs and AFP flags, the "server signature" and the network addresses, the server provides AFP services on\&.
+is a perl script that sends a FPGetSrvrInfo request to an AFP server at HOSTNAME:PORT and displays the results, namely "Machine type", the server\*(Aqs name, supported AFP versions, UAMs and AFP flags, the "server signature" and the network addresses, the server provides AFP services on\&.
 .PP
-When you don\'t supply :PORT, then the default AFP port, 548, will be used\&.
+When you don\*(Aqt supply :PORT, then the default AFP port, 548, will be used\&.
 .SH "OPTIONS"
 .PP
 \fB\-d\fR
index d36189f18dcc4b7867e33e35dfd420665c8f49ac..214b31d3417f14e3809aebde8e3c24bf76ddeb1c 100644 (file)
@@ -1,13 +1,22 @@
 '\" t
 .\"     Title: dbd
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 14 Sep 2012
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 28 Dec 2012
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
 .\"  Language: English
 .\"
-.TH "DBD" "1" "14 Sep 2012" "Netatalk 3.0" "Netatalk 3.0"
+.TH "DBD" "1" "28 Dec 2012" "Netatalk 3.0" "Netatalk 3.0"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 dbd \- CNID database maintenance
 .SH "SYNOPSIS"
 .HP \w'\fBdbd\fR\fB\fR\ 'u
-\fBdbd\fR\fB\fR [\-evx] {\-d\ [\-i]  | \-s\ [\-c|\-n]  | \-r\ [\-c|\-f|\-C]  | \-u} \fIvolumepath\fR
+\fBdbd\fR\fB\fR [\-fsv] \fIvolumepath\fR
 .SH "DESCRIPTION"
 .PP
 \fBdbd\fR
-can dump, scan, reindex and rebuild
-\fINetatalk\fR
-dbd CNID databases\&. It must be run with appropiate permissions i\&.e\&. as root\&.
-\fBdbd\fR
-\fB\-s|\-r\fR
-can be run on active volumes, but
-\fBdbd \-rf\fR, which wipes the db before rebuilding it, checks and enforces that the chosen volume is not in use\&.
-.SH "COMMANDS"
-.PP
-\-d
-.RS 4
-Dump CNID database\&. With
-\fB\-i \fRdump indexes too\&.
-.RE
-.PP
-\-s
-.RS 4
-Scan volume:
-.sp
-Compare CNIDs in database with volume, test if \&.AppleDouble directories exist, test if AppleDouble files exist, report orphaned AppleDouble files, report directories inside \&.AppleDouble directories, check name encoding, heck for orphaned CNIDs in database (requires
-\fB\-e\fR)\&.
-.sp
-Options:
-.PP
-\-c
-.RS 4
-Don\'t check \&.AppleDouble stuff, only check orphaned\&.
-.RE
-.PP
-\-n
-.RS 4
-Don\'t open CNID database, skip CNID checks, only traverse filesystem
-.RE
-.RE
-.PP
-\-r
-.RS 4
-Rebuild volume:
-.sp
-Sync CNIDSs from database with volume, ensure \&.AppleDouble directories exist, ensure AppleDouble files exist, delete orphaned AppleDouble files, report directories inside \&.AppleDouble directories, check name encoding by roundtripping, delete orphaned CNIDs in database (requires
-\fB\-e\fR)\&.
-.sp
-Options:
-.PP
-\-C
-.RS 4
-Converts volume from adouble:v2 to adouble:ea
-.RE
+scans all file and directories of AFP volumes, updating the CNID database of the volume\&. It must be run with appropriate permissions i\&.e\&. as root\&.\&.
+.SH "OPTIONS"
 .PP
 \-c
 .RS 4
-Don\'t create \&.AppleDouble stuff, only cleanup orphaned\&.
+convert from adouble:v2 to adouble:ea
 .RE
 .PP
 \-f
 .RS 4
-Wipe database and rebuild from IDs stored in AppleDouble files, only available for volumes without
-\fBnocnidcache\fR
-option\&. Implies
-\fB\-e\fR\&.
-.RE
+delete and recreate CNID database
 .RE
 .PP
-\-u
+\-F
 .RS 4
-Upgrade:
-.sp
-Opens the database which triggers any necessary upgrades, then closes and exits\&.
+location of the afp\&.conf config file
 .RE
-.SH "OPTIONS"
 .PP
-\-e
+\-s
 .RS 4
-Only work on inactive volumes and lock them (exclusive)
+scan volume: treat the volume as read only and don\*(Aqt perform any filesystem modifications
 .RE
 .PP
-\-x
+\-t
 .RS 4
-Rebuild indexes (just for completeness, mostly useless!)
+show statistics while running
 .RE
 .PP
 \-v
 .RS 4
 verbose
 .RE
-.SH "WARNING"
-.PP
-In order to be able to run
-\fB\-rf\fR
-reconstructing the CNIDs in the database from the
-\fIAppleDouble\fR
-files, make sure you\'ve run a
-\fB\-r\fR
-rebuild sometimes before, where the CNIDs then would have been synched between database and
-\fIAppleDouble\fR
-files\&.
 .PP
-Also be careful about the option
-\fBnocnidcache\fR\&. Avoid this option if at all possible, because if prevents you from being able to use
-\fB\-f\fR\&.
+\-V
+.RS 4
+display version info
+.RE
 .SH "CNID BACKGROUND"
 .PP
-The CNID backends maintains name to ID mappings\&. If you change a filename outside afpd(8) (shell, samba), the CNID db will not know and not reflect that change\&. Netatalk tries to recover from such inconsistencies as gracefully as possible\&. The mechanisms to resolve such inconsistencies may fail sometimes, though, as this is not an easy task to accomplish\&. E\&.g\&. if several names in the path to the file or directory have changed, things may go wrong\&.
-.PP
-If you change a lot of filenames at once, chances are higher that the afpds fallback mechanisms fail, i\&.e\&. files will be assigned new IDs, even though the file hasn\'t changed\&.
+The CNID backends maintains name to ID mappings\&. If you change a filename outside afpd(8) (shell, samba), the CNID database will not reflect that change\&. Netatalk tries to recover from such inconsistencies as gracefully as possible\&.
 .SH "SEE ALSO"
 .PP
 \fBcnid_metad\fR(8),
index 40dd5c2a888b56b5d6d1fa45a6a2974998fd01ae..42ffb541355827f3b669c55c8834bd4ff96a677b 100644 (file)
@@ -1 +1 @@
-.so man1/megatron.1
+.so megatron.1
index 40dd5c2a888b56b5d6d1fa45a6a2974998fd01ae..42ffb541355827f3b669c55c8834bd4ff96a677b 100644 (file)
@@ -1 +1 @@
-.so man1/megatron.1
+.so megatron.1
index ea823a0b0c5daaa4de12241d156ff5252f22289d..6da607b7ca0df602c4918517cda7bd09a223a9c1 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: macusers
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 13 Oct 2011
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "MACUSERS" "1" "13 Oct 2011" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
index dfd37d044db01f500f06fbf99cd4a200bafbfe03..300bd4fd0688302944cda90d144db8a810624515 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: megatron
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 02 Sep 2011
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "MEGATRON" "1" "02 Sep 2011" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
@@ -50,7 +59,7 @@ the
 \fBnetatalk\fR
 Apple Filing Protocol (AppleShare) server\&. BinHex, MacBinary, and AppleSingle are commonly used formats for transferring Macintosh files between machines via email or file transfer protocols\&.
 \fBmegatron\fR
-uses its name to determine what type of tranformation is being asked of it\&.
+uses its name to determine what type of transformation is being asked of it\&.
 .PP
 If
 \fBmegatron\fR
@@ -59,7 +68,7 @@ is called as
 ,
 \fBunbin\fR
 or
-\fBunsingle\fR, it tries to convert file(s) from BinHex, MacBinary, or AppleSingle into AppleDouble format\&. BinHex is the format most often used to send Macintosh files by e\-mail\&. Usually these files have an extension of "\&.hqx"\&. MacBinary is the format most often used by terminal emulators "on the fly" when transferring Macintosh files in binary mode\&. MacBinary files often have an extension of "\&.bin"\&. Some Macintosh LAN\-based email packages use uuencoded AppleSingle format to "attach" or "enclose" files in email\&. AppleSingle files don\'t have a standard filename extension\&.
+\fBunsingle\fR, it tries to convert file(s) from BinHex, MacBinary, or AppleSingle into AppleDouble format\&. BinHex is the format most often used to send Macintosh files by e\-mail\&. Usually these files have an extension of "\&.hqx"\&. MacBinary is the format most often used by terminal emulators "on the fly" when transferring Macintosh files in binary mode\&. MacBinary files often have an extension of "\&.bin"\&. Some Macintosh LAN\-based email packages use uuencoded AppleSingle format to "attach" or "enclose" files in email\&. AppleSingle files don\*(Aqt have a standard filename extension\&.
 .PP
 If
 \fBmegatron\fR
@@ -68,7 +77,7 @@ is called as
 \fBsingle2bin\fR, or
 \fBmacbinary\fR, it will try to convert the file(s) from BinHex, AppleSingle, or AppleDouble into MacBinary\&. This last translation may be useful in moving Macintosh files from your
 \fBafpd\fR
-server to some other machine when you can\'t copy them from the server using a Macintosh for some reason\&.
+server to some other machine when you can\*(Aqt copy them from the server using a Macintosh for some reason\&.
 .PP
 If
 \fBmegatron\fR
@@ -77,7 +86,7 @@ is called with any other name, it uses the default translation, namely
 .PP
 If no source file is given, or if
 \fIsourcefile\fR
-is `\fB\-\fR\', and if the conversion is from a BinHex or MacBinary file,
+is `\fB\-\fR\*(Aq, and if the conversion is from a BinHex or MacBinary file,
 \fBmegatron\fR
 will read from standard input\&.
 .PP
index 43ebcb7b5399709021732df5764b274ae5a2367f..7208ce26c590edb3461cb03b8706e1409a960aa0 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: netatalk-config
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 09 June 2001
 .\"    Manual: The Netatalk Project
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "NETATALK\-CONFIG" "1" "09 June 2001" "Netatalk 3.0" "The Netatalk Project"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
index 40dd5c2a888b56b5d6d1fa45a6a2974998fd01ae..42ffb541355827f3b669c55c8834bd4ff96a677b 100644 (file)
@@ -1 +1 @@
-.so man1/megatron.1
+.so megatron.1
index 40dd5c2a888b56b5d6d1fa45a6a2974998fd01ae..42ffb541355827f3b669c55c8834bd4ff96a677b 100644 (file)
@@ -1 +1 @@
-.so man1/megatron.1
+.so megatron.1
index 40dd5c2a888b56b5d6d1fa45a6a2974998fd01ae..42ffb541355827f3b669c55c8834bd4ff96a677b 100644 (file)
@@ -1 +1 @@
-.so man1/megatron.1
+.so megatron.1
index 729d35edf5b8de6ce1ebdb671e3158f7febe643a..fabf30c6d44c60f83e4652feaba093ea2c43caf5 100644 (file)
@@ -1,13 +1,22 @@
 '\" t
 .\"     Title: uniconv
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 23 Mar 2012
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 19 Jan 2013
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
 .\"  Language: English
 .\"
-.TH "UNICONV" "1" "23 Mar 2012" "Netatalk 3.0" "Netatalk 3.0"
+.TH "UNICONV" "1" "19 Jan 2013" "Netatalk 3.0" "Netatalk 3.0"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -42,7 +51,7 @@ CNID backend used on this volume, usually cdb or dbd\&. Should match the backend
 .PP
 \-d
 .RS 4
-don\'t HEX encode leading dots (:2e), equivalent to
+don\*(Aqt HEX encode leading dots (:2e), equivalent to
 \fBuse dots = yes\fR
 in
 \fBafp.conf\fR(5)
@@ -65,7 +74,7 @@ Macintosh client codepage, required for HEX encoded volumes\&. Defaults to "MAC_
 .PP
 \-n
 .RS 4
-"dry run", don\'t do any real changes
+"dry run", don\*(Aqt do any real changes
 .RE
 .PP
 \-t
@@ -95,9 +104,11 @@ recommended to do a "dry run" first and to check the output for conversion error
 should
 \fInot\fR
 be running while you change the volume encoding\&. Remember to change
-\fBvolcodepage\fR
+\fBunix charset\fR
+or
+\fBvol charset\fR
 in
-\fBAppleVolumes.default\fR(5)
+\fBafp.conf\fR(5)
 to the new codepage, before restarting afpd\&.
 .PP
 In case of
@@ -120,7 +131,7 @@ cannot handle iso\-8859\&.adapted anymore\&.
 .PP
 The CNID backends maintains name to ID mappings\&. If you change a filename outside afpd(8) (shell, samba), the CNID db, i\&.e\&. the DIDNAME index, gets inconsistent\&. Netatalk tries to recover from such inconsistencies as gracefully as possible\&. The mechanisms to resolve such inconsistencies may fail sometimes, though, as this is not an easy task to accomplish\&. I\&.e\&. if several names in the path to the file or directory have changed, things may go wrong\&.
 .PP
-If you change a lot of filenames at once, chances are higher that the afpds fallback mechanisms fail, i\&.e\&. files will be assigned new IDs, even though the file hasn\'t changed\&.
+If you change a lot of filenames at once, chances are higher that the afpds fallback mechanisms fail, i\&.e\&. files will be assigned new IDs, even though the file hasn\*(Aqt changed\&.
 \fBuniconv\fR
 therefore updates the CNID entry for each file/directory directly after it changes the name to avoid inconsistencies\&. The two supported backends for volumes, dbd and cdb, use the same CNID db format\&. Therefore, you
 \fIcould\fR
index 40dd5c2a888b56b5d6d1fa45a6a2974998fd01ae..42ffb541355827f3b669c55c8834bd4ff96a677b 100644 (file)
@@ -1 +1 @@
-.so man1/megatron.1
+.so megatron.1
index fd2edf6ca7aa9b84d68dbd9844fdbb39687827fe..e9066c8bf8c851f080af69b4a24cc9b20d2ca34f 100644 (file)
@@ -14,8 +14,8 @@ SUFFIXES = .tmpl .
            -e "s@:COMPILED_BACKENDS:@${compiled_backends}@g" \
            <$< >$@
 
-GENERATED_MANS = afp.conf.5 afp_signature.conf.5 afp_voluuid.conf.5
-TEMPLATE_FILES = afp.conf.5.tmpl afp_signature.conf.5.tmpl afp_voluuid.conf.5.tmpl
+GENERATED_MANS = afp.conf.5 afp_signature.conf.5 afp_voluuid.conf.5 extmap.conf.5
+TEMPLATE_FILES = afp.conf.5.tmpl afp_signature.conf.5.tmpl afp_voluuid.conf.5.tmpl extmap.conf.5.tmpl
 NONGENERATED_MANS =
 
 man_MANS = $(GENERATED_MANS) $(NONGENERATED_MANS)
index 50e6f81e8d611b844144e26d99b69d8d309faa71..9f9d007b45dd1652d07e63269e14b6c60fe420d3 100644 (file)
@@ -1,13 +1,22 @@
 '\" t
 .\"     Title: afp.conf
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 25 Jul 2012
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 19 Jan 2013
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
 .\"  Language: English
 .\"
-.TH "AFP\&.CONF" "5" "25 Jul 2012" "Netatalk 3.0" "Netatalk 3.0"
+.TH "AFP\&.CONF" "5" "19 Jan 2013" "Netatalk 3.0" "Netatalk 3.0"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -37,8 +46,8 @@ The file consists of sections and parameters\&. A section begins with the name o
 .RS 4
 .\}
 .nf
-\fIname\fR = \fIvalue \fR
-      
+    \fIname\fR = \fIvalue \fR
+    
 .fi
 .if n \{\
 .RE
@@ -53,7 +62,7 @@ Only the first equals sign in a parameter is significant\&. Whitespace before or
 Any line beginning with a semicolon (\(lq;\(rq) or a hash (\(lq#\(rq) character is ignored, as are lines containing only whitespace\&.
 .PP
 Any line ending in a
-\(lq\e\(rq
+\(lq \e \(rq
 is continued on the next line in the customary UNIX fashion\&.
 .PP
 The values following the equals sign in parameters are all either a string (no quotes needed) or a boolean, which may be given as yes/no, 1/0 or true/false\&. Case is not significant in boolean values, but is preserved in string values\&. Some items such as create masks are numeric\&.
@@ -79,9 +88,9 @@ option is considered a
 \fIvol preset\fR
 which can be selected in other volume sections via the
 \fBvol preset\fR
-option and constitutes defaults for the volume\&. For any option speficied both in a preset
+option and constitutes defaults for the volume\&. For any option specified both in a preset
 \fIand\fR
-in a volume section the volume section setting completly substitutes the preset option\&.
+in a volume section the volume section setting completely substitutes the preset option\&.
 .PP
 The access rights granted by the server are masked by the access rights granted to the specified or guest UNIX user by the host system\&. The server does not grant more access than the host system grants\&.
 .PP
@@ -93,9 +102,8 @@ baz:
 .RS 4
 .\}
 .nf
-[baz]
-path = /foo/bar
-      
+ [baz]
+    path = /foo/bar 
 .fi
 .if n \{\
 .RE
@@ -109,12 +117,12 @@ Parameters in this section apply to the server as a whole\&. Parameters denoted
 This section enable sharing of the UNIX server user home directories\&. Specifying an optional
 \fBpath\fR
 parameter means that not the whole user home will be shared but the subdirectory
-\fBpath\fR\&. It is neccessary to define the
+\fBpath\fR\&. It is necessary to define the
 \fBbasedir regex\fR
 option\&. It should be a regex which matches the parent directory of the user homes\&. Parameters denoted by a (H) belong to volume sections\&. The optional parameter
 \fBhome name\fR
 can be used to change the AFP volume name which
-\fI$u\'s home\fR
+\fI$u\*(Aqs home\fR
 by default\&. See below under VARIABLE SUBSTITUTIONS\&.
 .PP
 The following example illustrates this\&. Given all user home directories are stored under
@@ -124,10 +132,9 @@ The following example illustrates this\&. Given all user home directories are st
 .RS 4
 .\}
 .nf
-[Homes]
-path = afp\-data
-basedir regex = /home
-      
+ [Homes]
+      path = afp\-data
+      basedir regex = /home
 .fi
 .if n \{\
 .RE
@@ -137,6 +144,24 @@ For a user
 \fIjohn\fR
 this results in an AFP home volume with a path of
 /home/john/afp\-data\&.
+.PP
+If
+\fBbasedir regex\fR
+contains symlink, set the canonicalized absolute path\&. When
+/home
+links to
+/usr/home:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ [Homes]
+      basedir regex = /usr/home
+.fi
+.if n \{\
+.RE
+.\}
 .SH "PARAMETERS"
 .PP
 Parameters define the specific attributes of sections\&.
@@ -170,7 +195,7 @@ if you specify an unknown variable, it will not get converted\&.
 .sp -1
 .IP "  2." 4.2
 .\}
-if you specify a known variable, but that variable doesn\'t have a value, it will get ignored\&.
+if you specify a known variable, but that variable doesn\*(Aqt have a value, it will get ignored\&.
 .RE
 .PP
 The variables which can be used for substitutions are:
@@ -182,7 +207,7 @@ basename
 .PP
 $c
 .RS 4
-client\'s ip address
+client\*(Aqs ip address
 .RE
 .PP
 $d
@@ -207,7 +232,7 @@ hostname
 .PP
 $i
 .RS 4
-client\'s ip, without port
+client\*(Aqs ip, without port
 .RE
 .PP
 $s
@@ -232,6 +257,11 @@ prints dollar sign ($)
 .SH "EXPLANATION OF GLOBAL PARAMETERS"
 .SS "Authentication Options"
 .PP
+ad domain = \fIDOMAIN\fR \fB(G)\fR
+.RS 4
+Append @DOMAIN to username when authenticating\&. Useful in Active Directory environments that otherwise would require the user to enter the full user@domain string\&.
+.RE
+.PP
 admin auth user = \fIuser\fR \fB(G)\fR
 .RS 4
 Specifying eg "\fBadmin auth user = root\fR" whenever a normal user login fails, afpd will try to authenticate as the specified
@@ -244,119 +274,9 @@ k5 keytab = \fIpath\fR \fB(G)\fR, k5 service = \fIservice\fR \fB(G)\fR, k5 realm
 These are required if the server supports the Kerberos 5 authentication UAM\&.
 .RE
 .PP
-ldap auth method = \fInone|simple|sasl\fR \fB(G)\fR
-.RS 4
-Authentication method:
-\fBnone | simple | sasl\fR
-.PP
-none
-.RS 4
-anonymous LDAP bind
-.RE
-.PP
-simple
-.RS 4
-simple LDAP bind
-.RE
-.PP
-sasl
+nt domain = \fIDOMAIN\fR \fB(G)\fR, nt separator = \fISEPARATOR\fR \fB(G)\fR
 .RS 4
-SASL\&. Not yet supported !
-.RE
-.RE
-.PP
-ldap auth dn = \fIdn\fR \fB(G)\fR
-.RS 4
-Distinguished Name of the user for simple bind\&.
-.sp
-.RE
-.PP
-ldap auth pw = \fIpassword\fR \fB(G)\fR
-.RS 4
-Distinguished Name of the user for simple bind\&.
-.sp
-.RE
-.PP
-ldap server = \fIhost\fR \fB(G)\fR
-.RS 4
-Name or IP address of your LDAP Server\&. This is only needed for explicit ACL support in order to be able to query LDAP for UUIDs\&.
-.sp
-You can use
-\fBafpldaptest\fR(1)
-to syntactically check your config\&.
-.RE
-.PP
-ldap userbase = \fIbase dn\fR \fB(G)\fR
-.RS 4
-DN of the user container in LDAP\&.
-.sp
-.RE
-.PP
-ldap userscope = \fIscope\fR \fB(G)\fR
-.RS 4
-Search scope for user search:
-\fBbase | one | sub\fR
-.sp
-.RE
-.PP
-ldap groupbase = \fIbase dn\fR \fB(G)\fR
-.RS 4
-DN of the group container in LDAP\&.
-.sp
-.RE
-.PP
-ldap groupscope = \fIscope\fR \fB(G)\fR
-.RS 4
-Search scope for user search:
-\fBbase | one | sub\fR
-.sp
-.RE
-.PP
-ldap uuid attr = \fIdn\fR \fB(G)\fR
-.RS 4
-Name of the LDAP attribute with the UUIDs\&.
-.sp
-Note: this is used both for users and groups\&.
-.sp
-.RE
-.PP
-ldap name attr = \fIdn\fR \fB(G)\fR
-.RS 4
-Name of the LDAP attribute with the users short name\&.
-.sp
-.RE
-.PP
-ldap uuid string = \fISTRING\fR \fB(G)\fR
-.RS 4
-Format of the uuid string in the directory\&. A series of x and \-, where every x denotes a value 0\-9a\-f and every \- is a seperator\&.
-.sp
-Default: xxxxxxxx\-xxxx\-xxxx\-xxxx\-xxxxxxxxxxxx
-.RE
-.PP
-ldap uuid encoding = \fIstring | ms\-guid (default: string)\fR \fB(G)\fR
-.RS 4
-Format of the UUID of the LDAP attribute, allows usage of the binary objectGUID fields from Active Directory\&. If left unspecified, string is the default, which passes through the ASCII UUID returned by most other LDAP stores\&. If set to ms\-guid, the internal UUID representation is converted to and from the binary format used in the objectGUID attribute found on objects in Active Directory when interacting with the server\&.
-.PP
-string
-.RS 4
-UUID is a string, use with eg OpenDirectory\&.
-.RE
-.PP
-ms\-guid
-.RS 4
-Binary objectGUID from Active Directory
-.RE
-.RE
-.PP
-ldap group attr = \fIdn\fR \fB(G)\fR
-.RS 4
-Name of the LDAP attribute with the groups short name\&.
-.sp
-.RE
-.PP
-nt domain = \fIDOMAIN\fR \fB(G)\fR, nt separator = \fISEPERATOR\fR \fB(G)\fR
-.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\&.
+Use for eg\&. winbind authentication, prepends both strings before the username from login and then tries to authenticate with the result through the available and active UAM authentication modules\&.
 .RE
 .PP
 save password = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
@@ -418,7 +338,7 @@ With OS X Apple introduced the AFP3 protocol\&. One of the big changes was, that
 .PP
 To be able to serve AFP3 and older clients at the same time,
 \fBafpd\fR
-needs to be able to convert between UTF\-8 and Mac charsets\&. Even OS X clients partly still rely on the mac charset\&. As there\'s no way,
+needs to be able to convert between UTF\-8 and Mac charsets\&. Even OS X clients partly still rely on the mac charset\&. As there\*(Aqs no way,
 \fBafpd\fR
 can detect the codepage a pre AFP3 client uses, you have to specify it using the
 \fBmac charset\fR
@@ -426,12 +346,12 @@ option\&. The default is MacRoman, which should be fine for most western users\&
 .PP
 As
 \fBafpd\fR
-needs to interact with UNIX operating system as well, it need\'s to be able to convert from UTF8\-MAC / Mac charset to the UNIX charset\&. By default
+needs to interact with UNIX operating system as well, it need\*(Aqs to be able to convert from UTF8\-MAC / Mac charset to the UNIX charset\&. By default
 \fBafpd\fR
 uses
 \fIUTF8\fR\&. You can set the UNIX charset using the
 \fBunix charset\fR
-option\&. If you\'re using extended characters in the configuration files for
+option\&. If you\*(Aqre using extended characters in the configuration files for
 \fBafpd\fR, make sure your terminal matches the
 \fBunix charset\fR\&.
 .PP
@@ -448,7 +368,7 @@ unix charset = \fICHARSET\fR \fB(G)\fR
 Specifies the servers unix charset, e\&.g\&.
 \fIISO\-8859\-15\fR
 or
-\fIEUC\-JP\fR\&. This is used to convert strings to/from the systems locale, e\&.g\&. for authenthication, server messages and volume names\&. If
+\fIEUC\-JP\fR\&. This is used to convert strings to/from the systems locale, e\&.g\&. for authentication, server messages and volume names\&. If
 \fILOCALE\fR
 is set, the systems locale is used\&. Defaults to
 \fIUTF8\fR\&.
@@ -474,7 +394,7 @@ Sets the minimum password length, if supported by the UAM
 .PP
 advertise ssh = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
 .RS 4
-Allows old Mac OS X clients (10\&.3\&.3\-10\&.4) to automagically establish a tunneled AFP connection through SSH\&. If this option is set, the server\'s answers to client\'s FPGetSrvrInfo requests contain an additional entry\&. It depends on both client\'s settings and a correctly configured and running
+Allows old Mac OS X clients (10\&.3\&.3\-10\&.4) to automagically establish a tunneled AFP connection through SSH\&. If this option is set, the server\*(Aqs answers to client\*(Aqs FPGetSrvrInfo requests contain an additional entry\&. It depends on both client\*(Aqs settings and a correctly configured and running
 \fBsshd\fR(8)
 on the server to let things work\&.
 .if n \{\
@@ -489,12 +409,12 @@ on the server to let things work\&.
 \fBNote\fR
 .ps -1
 .br
-Setting this option is not recommended since globally encrypting AFP connections via SSH will increase the server\'s load significantly\&. On the other hand, Apple\'s client side implementation of this feature in MacOS X versions prior to 10\&.3\&.4 contained a security flaw\&.
+Setting this option is not recommended since globally encrypting AFP connections via SSH will increase the server\*(Aqs load significantly\&. On the other hand, Apple\*(Aqs client side implementation of this feature in MacOS X versions prior to 10\&.3\&.4 contained a security flaw\&.
 .sp .5v
 .RE
 .RE
 .PP
-afp listen = \fIip address[:port] [ip adress[:port] \&.\&.\&.]\fR \fB(G)\fR
+afp listen = \fIip address[:port] [ip address[:port] \&.\&.\&.]\fR \fB(G)\fR
 .RS 4
 Specifies the IP address that the server should advertise
 \fBand\fR
@@ -508,7 +428,7 @@ Allows a different TCP port to be used for AFP\&. The default is 548\&. Also set
 option\&.
 .RE
 .PP
-cnid listen = \fIip address[:port] [ip adress[:port] \&.\&.\&.]\fR \fB(G)\fR
+cnid listen = \fIip address[:port] [ip address[:port] \&.\&.\&.]\fR \fB(G)\fR
 .RS 4
 Specifies the IP address that the CNID server should listen on\&. The default is
 \fBlocalhost:4700\fR\&.
@@ -534,7 +454,7 @@ Specifies a fully\-qualified domain name, with an optional port\&. This is disca
 .PP
 hostname = \fIname\fR \fB(G)\fR
 .RS 4
-Use this instead of the result from calling hostname for dertermening which IP address to advertise, therfore the hostname is resolved to an IP which is the advertised\&. This is NOT used for listening and it is also overwritten by
+Use this instead of the result from calling hostname for determining which IP address to advertise, therefore the hostname is resolved to an IP which is the advertised\&. This is NOT used for listening and it is also overwritten by
 \fBafp listen\fR\&.
 .RE
 .PP
@@ -545,7 +465,7 @@ Sets the maximum number of clients that can simultaneously connect to the server
 .PP
 server quantum = \fInumber\fR \fB(G)\fR
 .RS 4
-This specifies the DSI server quantum\&. The default value is 303840\&. The maximum value is 0xFFFFFFFFF, the minimum is 32000\&. If you specify a value that is out of range, the default value will be set\&. Do not change this value unless you\'re absolutely sure, what you\'re doing
+This specifies the DSI server quantum\&. The default value is 303840\&. The maximum value is 0xFFFFFFFFF, the minimum is 32000\&. If you specify a value that is out of range, the default value will be set\&. Do not change this value unless you\*(Aqre absolutely sure, what you\*(Aqre doing
 .RE
 .PP
 sleep time = \fInumber\fR \fB(G)\fR
@@ -585,18 +505,20 @@ Allows users of a certain group to be seen as the superuser when they log in\&.
 .PP
 afp read locks = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
 .RS 4
-Whether to apply locks to the byte region read in FPRead calls\&. The AFP spec mandates this, but it\'s not really in line with UNIX semantics and is a performance hug\&.
+Whether to apply locks to the byte region read in FPRead calls\&. The AFP spec mandates this, but it\*(Aqs not really in line with UNIX semantics and is a performance hug\&.
 .RE
 .PP
 basedir regex = \fIregex\fR \fB(H)\fR
 .RS 4
-Regular expression which matches the parent directory of the user homes\&. In the simple case this is just a path ie
+Regular expression which matches the parent directory of the user homes\&. If
+\fBbasedir regex\fR
+contains symlink, you must set the canonicalized absolute path\&. In the simple case this is just a path ie
 \fBbasedir regex = /home\fR
 .RE
 .PP
 close vol = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
 .RS 4
-Whether to close volumes possibly opened by clients when they\'re removed from the configuration and the configuration is reloaded\&.
+Whether to close volumes possibly opened by clients when they\*(Aqre removed from the configuration and the configuration is reloaded\&.
 .RE
 .PP
 cnid server = \fIipaddress[:port]\fR \fB(G)/(V)\fR
@@ -611,28 +533,9 @@ Maximum possible entries in the directory cache\&. The cache stores directories
 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\&.
 .RE
 .PP
-fce listener = \fIhost[:port]\fR \fB(G)\fR
-.RS 4
-Enables sending FCE events to the specified
-\fIhost\fR, default
-\fIport\fR
-is 12250 if not specified\&. Specifying mutliple listeners is done by having this option once for each of them\&.
-.RE
-.PP
-fce events = \fIfmod,fdel,ddel,fcre,dcre,tmsz\fR \fB(G)\fR
-.RS 4
-Speficies which FCE events are active, default is
-\fIfmod,fdel,ddel,fcre,dcre\fR\&.
-.RE
-.PP
-fce coalesce = \fIall|delete|create\fR \fB(G)\fR
-.RS 4
-Coalesce FCE events\&.
-.RE
-.PP
-fce holdfmod = \fIseconds\fR \fB(G)\fR
+extmap file = \fIpath\fR \fB(G)\fR
 .RS 4
-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\&.
+Sets the path to the file which defines file extension type/creator mappings\&. (default is :ETCDIR:/extmap\&.conf)\&.
 .RE
 .PP
 guest account = \fIname\fR \fB(G)\fR
@@ -643,12 +546,12 @@ Specifies the user that guests should use (default is "nobody")\&. The name shou
 home name = \fIname\fR \fB(H)\fR
 .RS 4
 AFP user home volume name\&. The default is
-\fIusers\'s home\fR\&.
+\fIuser\*(Aqs home\fR\&.
 .RE
 .PP
 keep sessions = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
 .RS 4
-Enable "Continuous AFP Service"\&. This means restarting AFP and CNID service daemons master processes, but keeping the AFP session processes\&. This can be used to install (most) updates to Netatalk without interruping active AFP sessions\&. Existing AFP sessions will still run the version from before updating, but new AFP sessions will run the updated code\&. After enabling this option when sending SIGQUIT to the
+Enable "Continuous AFP Service"\&. This means restarting AFP and CNID service daemons master processes, but keeping the AFP session processes\&. This can be used to install (most) updates to Netatalk without interrupting active AFP sessions\&. Existing AFP sessions will still run the version from before updating, but new AFP sessions will run the updated code\&. After enabling this option when sending SIGQUIT to the
 \fInetatalk\fR
 service controller process, the AFP and CNID daemons will exit and then the service controller will restart them\&. AFP session processes are notified of the master afpd shutdown, they will then sleep 15\-20 seconds and then try to reconnect their IPC channel to the master afpd process\&. The IPC channel between the AFP master service daemon and the AFP session child is used for keeping session state of AFP sessions in the AFP master process\&. The session state is needed when AFP clients experience eg network outages and try to reconnect to the AFP server\&.
 .RE
@@ -684,7 +587,7 @@ Use share reservations on Solaris\&. Solaris CIFS server uses this too, so this
 .PP
 vol dbpath = \fIpath\fR \fB(G)\fR
 .RS 4
-Sets the database information to be stored in path\&. You have to specifiy a writable location, even if the volume is read only\&. The default is
+Sets the database information to be stored in path\&. You have to specify a writable location, even if the volume is read only\&. The default is
 :STATEDIR:/netatalk/CNID/\&.
 .RE
 .PP
@@ -696,28 +599,28 @@ Max length of UTF8\-MAC volume name for Mac OS X\&. Note that Hangul is especial
 .RS 4
 .\}
 .nf
-73:  limit of Mac OS X 10\&.1
-80:  limit of Mac OS X 10\&.4/10\&.5 (default)
-255: limit of recent Mac OS X
+ 73: limit of Mac OS X 10\&.1 80: limit of Mac
+            OS X 10\&.4/10\&.5 (default) 255: limit of recent Mac OS
+            X
 .fi
 .if n \{\
 .RE
 .\}
 .sp
-Mac OS 9 and earlier are not influenced by this, because Maccharset volume name is always limitted to 27 bytes\&.
+Mac OS 9 and earlier are not influenced by this, because Maccharset volume name is always limited to 27 bytes\&.
 .RE
 .PP
 vol preset = \fIname\fR \fB(G)/(V)\fR
 .RS 4
 Use section
 \fBname\fR
-as option preset for all volumes (when set in the [Global] section) or for one volume (when set in that volume\'s section)\&.
+as option preset for all volumes (when set in the [Global] section) or for one volume (when set in that volume\*(Aqs section)\&.
 .RE
 .SS "Logging Options"
 .PP
 log file = \fIlogfile\fR \fB(G)\fR
 .RS 4
-If not specified Netatalk logs to syslogs daemon facilify\&. Otherwise it logs to
+If not specified Netatalk logs to syslogs daemon facility\&. Otherwise it logs to
 \fBlogfile\fR\&.
 .RE
 .PP
@@ -749,6 +652,33 @@ Both logtype and loglevels are case insensitive\&.
 .sp .5v
 .RE
 .RE
+.SS "Filesystem Change Events (FCE)"
+.PP
+Netatalk includes a nifty filesystem change event mechanism where afpd processes notify interested listeners about certain filesystem event by UDP network datagrams\&.
+.PP
+fce listener = \fIhost[:port]\fR \fB(G)\fR
+.RS 4
+Enables sending FCE events to the specified
+\fIhost\fR, default
+\fIport\fR
+is 12250 if not specified\&. Specifying multiple listeners is done by having this option once for each of them\&.
+.RE
+.PP
+fce events = \fIfmod,fdel,ddel,fcre,dcre,tmsz\fR \fB(G)\fR
+.RS 4
+Specifies which FCE events are active, default is
+\fIfmod,fdel,ddel,fcre,dcre\fR\&.
+.RE
+.PP
+fce coalesce = \fIall|delete|create\fR \fB(G)\fR
+.RS 4
+Coalesce FCE events\&.
+.RE
+.PP
+fce holdfmod = \fIseconds\fR \fB(G)\fR
+.RS 4
+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 multiple times for every "save"\&. Default: 60 seconds\&.
+.RE
 .SS "Debug Parameters"
 .PP
 These options are useful for debugging only\&.
@@ -765,16 +695,126 @@ Specify the number of tickles to send before timing out a connection\&. The defa
 .PP
 client polling = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
 .RS 4
-With this option enabled, afpd won\'t advertise that it is capable of server notifications, so that connected clients poll the server every 10 seconds to detect changes in opened server windows\&.
-\fINote\fR: Depending on the number of simultaneously connected clients and the network\'s speed, this can lead to a significant higher load on your network!
+With this option enabled, afpd won\*(Aqt advertise that it is capable of server notifications, so that connected clients poll the server every 10 seconds to detect changes in opened server windows\&.
+\fINote\fR: Depending on the number of simultaneously connected clients and the network\*(Aqs speed, this can lead to a significant higher load on your network!
 .sp
 Do not use this option any longer as present Netatalk correctly supports server notifications, allowing connected clients to update folder listings in case another client changed the contents\&.
 .RE
+.SS "Options for ACL handling"
+.PP
+For a basic mode of operation there\*(Aqs nothing to configure\&. afpd reads ACLs on the fly, calculating effective permissions and returning the calculated permissions via the so called UARights permission bits\&. On a Mac the Finder uses these bits to adjust permission in Finder windows\&. For example folder whos UNIX mode would only result in in read\-only permissions for a user will not be displayed with a read\-only icon and the user will be able to write to the folder given the folder has an ACL giving the user write access\&.
+.PP
+However, neither in Finder "Get Info" windows nor in Terminal will you be able to see the ACLs, that\*(Aqs a result of how ACLs in OS X are designed\&. If you want to be able to display ACLs on the client, things get more involved as you must then setup both client and server to be part on a authentication domain (directory service, eg LDAP, OpenDirectory)\&. The reason is, that in OS X ACLs are bound to UUIDs, not just uid\*(Aqs or gid\*(Aqs\&. Therefor afpd must be able to map every filesystem uid and gid to a UUID so that it can return the server side ACLs which are bound to UNIX uid and gid mapped to OS X UUIDs\&. Get it? Read on\&.
+.PP
+Netatalk can query a directory server using LDAP queries\&. Either the directory server already provides an UUID attribute for user and groups (Active Directory, Open Directory) or you reuse an unused attribute (or add a new one) to you directory server (eg OpenLDAP)\&.
+.PP
+The following LDAP options must be configured for Netatalk:
+.PP
+ldap auth method = \fInone|simple|sasl\fR \fB(G)\fR
+.RS 4
+Authentication method:
+\fBnone | simple | sasl\fR
+.PP
+none
+.RS 4
+anonymous LDAP bind
+.RE
+.PP
+simple
+.RS 4
+simple LDAP bind
+.RE
+.PP
+sasl
+.RS 4
+SASL\&. Not yet supported !
+.RE
+.RE
+.PP
+ldap auth dn = \fIdn\fR \fB(G)\fR
+.RS 4
+Distinguished Name of the user for simple bind\&.
+.RE
+.PP
+ldap auth pw = \fIpassword\fR \fB(G)\fR
+.RS 4
+Distinguished Name of the user for simple bind\&.
+.RE
+.PP
+ldap server = \fIhost\fR \fB(G)\fR
+.RS 4
+Name or IP address of your LDAP Server\&. This is only needed for explicit ACL support in order to be able to query LDAP for UUIDs\&.
+.sp
+You can use
+\fBafpldaptest\fR(1)
+to syntactically check your config\&.
+.RE
+.PP
+ldap userbase = \fIbase dn\fR \fB(G)\fR
+.RS 4
+DN of the user container in LDAP\&.
+.RE
+.PP
+ldap userscope = \fIscope\fR \fB(G)\fR
+.RS 4
+Search scope for user search:
+\fBbase | one | sub\fR
+.RE
+.PP
+ldap groupbase = \fIbase dn\fR \fB(G)\fR
+.RS 4
+DN of the group container in LDAP\&.
+.RE
+.PP
+ldap groupscope = \fIscope\fR \fB(G)\fR
+.RS 4
+Search scope for user search:
+\fBbase | one | sub\fR
+.RE
+.PP
+ldap uuid attr = \fIdn\fR \fB(G)\fR
+.RS 4
+Name of the LDAP attribute with the UUIDs\&.
+.sp
+Note: this is used both for users and groups\&.
+.RE
+.PP
+ldap name attr = \fIdn\fR \fB(G)\fR
+.RS 4
+Name of the LDAP attribute with the users short name\&.
+.RE
+.PP
+ldap uuid string = \fISTRING\fR \fB(G)\fR
+.RS 4
+Format of the uuid string in the directory\&. A series of x and \-, where every x denotes a value 0\-9a\-f and every \- is a separator\&.
+.sp
+Default: xxxxxxxx\-xxxx\-xxxx\-xxxx\-xxxxxxxxxxxx
+.RE
+.PP
+ldap uuid encoding = \fIstring | ms\-guid (default: string)\fR \fB(G)\fR
+.RS 4
+Format of the UUID of the LDAP attribute, allows usage of the binary objectGUID fields from Active Directory\&. If left unspecified, string is the default, which passes through the ASCII UUID returned by most other LDAP stores\&. If set to ms\-guid, the internal UUID representation is converted to and from the binary format used in the objectGUID attribute found on objects in Active Directory when interacting with the server\&.
+.PP
+string
+.RS 4
+UUID is a string, use with eg OpenDirectory\&.
+.RE
+.PP
+ms\-guid
+.RS 4
+Binary objectGUID from Active Directory
+.RE
+.RE
+.PP
+ldap group attr = \fIdn\fR \fB(G)\fR
+.RS 4
+Name of the LDAP attribute with the groups short name\&.
+.RE
 .SH "EXPLANATION OF VOLUME PARAMETERS"
 .SS "Parameters"
 .PP
 The section name defines the volume name which is the name that appears in the Chooser or the "connect to server" dialog on Macintoshes to represent the appropriate share\&. No two volumes may have the same name\&. The volume name cannot contain the
-\':\'
+\*(Aq:\*(Aq
 character\&. The volume name is mangled if it is very long\&. Mac charset volume name is limited to 27 characters\&. UTF8\-MAC volume name is limited to volnamelen parameter\&.
 .PP
 path = \fIPATH\fR \fB(V)\fR
@@ -782,7 +822,7 @@ path = \fIPATH\fR \fB(V)\fR
 The path name must be a fully qualified path name, or a path name using either the ~ shell shorthand or any of the substitution variables, which are listed below\&.
 .sp
 The volume name is the name that appears in the Chooser ot the "connect to server" dialog on Macintoshes to represent the appropriate share\&. If volumename is unspecified, the last component of pathname is used\&. No two volumes may have the same name\&. If there are spaces in the name, it should be in quotes (i\&.e\&. "File Share")\&. The volume name cannot contain the
-\':\'
+\*(Aq:\*(Aq
 character\&. The volume name is mangled if it is very long\&. Mac charset volume name is limited to 27 characters\&. UTF8\-MAC volume name is limited to volnamelen parameter\&.
 .RE
 .PP
@@ -796,12 +836,22 @@ vol size limit = \fIsize in MiB\fR \fB(V)\fR
 .RS 4
 Useful for Time Machine: limits the reported volume size, thus preventing Time Machine from using the whole real disk space for backup\&. Example: "vol size limit = 1000" would limit the reported disk space to 1 GB\&.
 \fBIMPORTANT: \fR
-This is an approimated calculation taking into accout the contents of Time Machine 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\&.
+This is an approximated calculation taking into account the contents of Time Machine 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
-valid users = \fIusers/groups\fR \fB(V)\fR
+valid users = \fIuser @group\fR \fB(V)\fR
 .RS 4
-The allow option allows the users and groups that access a share to be specified\&. Users and groups are specified, delimited by spaces or commas\&. Groups are designated by a @ prefix\&. Example: "valid users = user1 user2 @group"
+The allow option allows the users and groups that access a share to be specified\&. Users and groups are specified, delimited by spaces or commas\&. Groups are designated by a @ prefix\&. Names may be quoted in order to allow for spaces in names\&. Example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+valid users = user "user 2" @group \(lq@group 2"
+.fi
+.if n \{\
+.RE
+.\}
 .RE
 .PP
 invalid users = \fIusers/groups\fR \fB(V)\fR
@@ -840,10 +890,10 @@ auto
 Try
 \fBsys\fR
 (by setting an EA on the shared directory itself), fallback to
-\fBad\fR\&. Requires writeable volume for perfoming test\&. "\fBread only = yes\fR" overwrites
+\fBad\fR\&. Requires writable volume for performing test\&. "\fBread only = yes\fR" overwrites
 \fBauto\fR
 with
-\fBnone\fR\&. Use explicit "\fBea = sys|ad\fR" for read\-only volumes where appropiate\&.
+\fBnone\fR\&. Use explicit "\fBea = sys|ad\fR" for read\-only volumes where appropriate\&.
 .RE
 .PP
 sys
@@ -899,7 +949,7 @@ Add(or) with the client requested permissions:
 \fBfile perm\fR
 is for files only,
 \fBdirectory perm\fR
-is for directories only\&. Don\'t use with "\fBunix priv = no\fR"\&.
+is for directories only\&. Don\*(Aqt use with "\fBunix priv = no\fR"\&.
 .PP
 \fBExample.\ \&Volume for a collaborative workgroup\fR
 .sp
@@ -907,8 +957,8 @@ is for directories only\&. Don\'t use with "\fBunix priv = no\fR"\&.
 .RS 4
 .\}
 .nf
-file perm = 0660
-directory perm = 0770
+file perm = 0660 directory perm =
+                0770
 .fi
 .if n \{\
 .RE
@@ -918,7 +968,7 @@ directory perm = 0770
 .PP
 umask = \fImode\fR \fB(V)\fR
 .RS 4
-set perm mask\&. Don\'t use with "\fBunix priv = no\fR"\&.
+set perm mask\&. Don\*(Aqt use with "\fBunix priv = no\fR"\&.
 .RE
 .PP
 preexec = \fIcommand\fR \fB(V)\fR
@@ -953,7 +1003,7 @@ Allows certain users and groups to have read/write access to a share\&. This fol
 .PP
 veto files = \fIvetoed names\fR \fB(V)\fR
 .RS 4
-hide files and directories,where the path matches one of the \'/\' delimited vetoed names\&. The veto string must always be terminated with a \'/\', eg\&. "veto1/", "veto1/veto2/"\&.
+hide files and directories,where the path matches one of the \*(Aq/\*(Aq delimited vetoed names\&. The veto string must always be terminated with a \*(Aq/\*(Aq, eg\&. "veto1/", "veto1/veto2/"\&.
 .RE
 .SS "Volume options"
 .PP
@@ -975,11 +1025,16 @@ Whether automatic conversion from
 \fBappledouble = v2\fR
 to
 \fBappledouble = ea\fR
-is performed when accessing filesystems from clients\&. This is generally useful, but costs some performance\&. It\'s recommdable to run
+is performed when accessing filesystems from clients\&. This is generally useful, but costs some performance\&. It\*(Aqs recommendable to run
 \fBdbd\fR
 on volumes and do the conversion with that\&. Then this option can be set to no\&.
 .RE
 .PP
+follow symlinks = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
+.RS 4
+The default setting is false thus symlinks are not followed on the server\&. This is the same behaviour as OS X\*(Aqs AFP server\&. Setting the option to true causes afpd to follow symlinks on the server\&. symlinks may point outside of the AFP volume, currently afpd doesn\*(Aqt do any checks for "wide symlinks"\&.
+.RE
+.PP
 invisible dots = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
 .RS 4
 make dot files invisible\&.
@@ -1022,7 +1077,7 @@ Whether to stat volume path when enumerating volumes list, useful for automounti
 .PP
 time machine = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
 .RS 4
-Whether to enable Time Machine suport for this volume\&.
+Whether to enable Time Machine support for this volume\&.
 .RE
 .PP
 unix priv = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
@@ -1035,15 +1090,15 @@ and
 .RE
 .SH "CNID BACKENDS"
 .PP
-The AFP protocol mostly refers to files and directories by ID and not by name\&. Netatalk needs a way to store these ID\'s in a persistent way, to achieve this several different CNID backends are available\&. The CNID Databases are by default located in the
+The AFP protocol mostly refers to files and directories by ID and not by name\&. Netatalk needs a way to store these ID\*(Aqs in a persistent way, to achieve this several different CNID backends are available\&. The CNID Databases are by default located in the
 :STATEDIR:/netatalk/CNID/(volumename)/\&.AppleDB/
 directory\&.
 .PP
 cdb
 .RS 4
-"Concurrent database", backend is based on Oracle Berkely DB\&. With this backend several
+"Concurrent database", backend is based on Oracle Berkley DB\&. With this backend several
 \fBafpd\fR
-deamons access the CNID database directly\&. Berkeley DB locking is used to synchronize access, if more than one
+daemons access the CNID database directly\&. Berkeley DB locking is used to synchronize access, if more than one
 \fBafpd\fR
 process is active for a volume\&. The drawback is, that the crash of a single
 \fBafpd\fR
@@ -1062,7 +1117,7 @@ processes communicate with the daemon for database reads and updates\&. If built
 .PP
 last
 .RS 4
-This backend is an exception, in terms of ID persistency\&. ID\'s are only valid for the current session\&. This is basically what
+This backend is an exception, in terms of ID persistency\&. ID\*(Aqs are only valid for the current session\&. This is basically what
 \fBafpd\fR
 did in the 1\&.5 (and 1\&.6) versions\&. This backend is still available, as it is useful for e\&.g\&. sharing cdroms\&. Starting with Netatalk 3\&.0, it becomes the
 \fIread only mode\fR
@@ -1077,20 +1132,20 @@ now relies heavily on a persistent ID database\&. Aliases will likely not work a
 .PP
 Even though
 \fB\&./configure \-\-help\fR
-might show that there are other CNID backends available, be warned those are likely broken or mainly used for testing\&. Don\'t use them unless you know what you\'re doing, they may be removed without further notice from future versions\&.
+might show that there are other CNID backends available, be warned those are likely broken or mainly used for testing\&. Don\*(Aqt use them unless you know what you\*(Aqre doing, they may be removed without further notice from future versions\&.
 .SH "CHARSET OPTIONS"
 .PP
 With OS X Apple introduced the AFP3 protocol\&. One of the most important changes was that AFP3 uses unicode names encoded as UTF\-8 decomposed\&. Previous AFP/OS versions used codepages, like MacRoman, MacCentralEurope, etc\&.
 .PP
 \fBafpd\fR
-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
+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\&. \*(Aq/\*(Aq will be encoded to
 :2f, if
 \fBusedots\fR
-is not specified, a leading dot \'\&.\' will be encoded as
+is not specified, a leading dot \*(Aq\&.\*(Aq will be encoded as
 :2e\&.
 .PP
-This version now uses UTF\-8 as the default encoding for names\&. \'/\' will be converted to \':\'\&.
+This version now uses UTF\-8 as the default encoding for names\&. \*(Aq/\*(Aq will be converted to \*(Aq:\*(Aq\&.
 .PP
 The
 \fBvol charset\fR
@@ -1106,7 +1161,7 @@ to the selected
 will convert the UTF\-8
 character to
 \fBmac charset\fR
-first\&. If this conversion fails, you\'ll receive a \-50 error on the mac\&.
+first\&. If this conversion fails, you\*(Aqll receive a \-50 error on the mac\&.
 .PP
 \fINote\fR: Whenever you can, please stick with the default UTF\-8 volume format\&.
 .SH "SEE ALSO"
@@ -1114,4 +1169,5 @@ first\&. If this conversion fails, you\'ll receive a \-50 error on the mac\&.
 \fBafpd\fR(8),
 \fBafppasswd\fR(5),
 \fBafp_signature.conf\fR(5),
+\fBextmap.conf\fR(5),
 \fBcnid_metad\fR(8)
index 54e2267f557704e45023ac46971aa70c25d20611..2f5fe403c6ad3b33bc17d086cb824cecd2193542 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: afp_signature.conf
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 23 Mar 2012
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "AFP_SIGNATURE\&.CONF" "5" "23 Mar 2012" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
index 8d3626d04c17b3712a534a3ae48270e87ad2793b..a9fb2ddfc73ab4eccd0c27f70c8cab3ae3d9e770 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: afp_voluuid.conf
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 23 Mar 2012
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "AFP_VOLUUID\&.CONF" "5" "23 Mar 2012" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
diff --git a/man/man5/extmap.conf.5.tmpl b/man/man5/extmap.conf.5.tmpl
new file mode 100644 (file)
index 0000000..9c6679f
--- /dev/null
@@ -0,0 +1,77 @@
+'\" t
+.\"     Title: extmap.conf
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 19 Jan 2013
+.\"    Manual: Netatalk 3.0
+.\"    Source: Netatalk 3.0
+.\"  Language: English
+.\"
+.TH "EXTMAP\&.CONF" "5" "19 Jan 2013" "Netatalk 3.0" "Netatalk 3.0"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+extmap.conf \- Configuration file used by afpd(8) to specify file name extension mappings\&.
+.SH "SYNOPSIS"
+.HP \w'\fB:ETCDIR:/extmap\&.conf\fR\fB\fR\ 'u
+\fB:ETCDIR:/extmap\&.conf\fR\fB\fR
+.SH "DESCRIPTION"
+.PP
+
+:ETCDIR:/extmap\&.conf
+is the configuration file used by
+\fBafpd\fR
+to specify file name extension mappings\&.
+.PP
+The configuration lines are composed like:
+.PP
+\&.extension
+\fI[ type [ creator ] ]\fR
+.PP
+Any line beginning with a hash (\(lq#\(rq) character is ignored\&. The leading\-dot lines specify file name extension mappings\&. The extension \*(Aq\&.\*(Aq sets the default creator and type for otherwise untyped Unix files\&.
+.SH "EXAMPLES"
+.PP
+\fBExample.\ \&Extension is jpg. Type is "JPEG". Creator is "ogle".\fR
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\&.jpg "JPEG" "ogle"
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+\fBExample.\ \&Extension is lzh. Type is "LHA ". Creator is not defined.\fR
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\&.lzh "LHA "
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBafp.conf\fR(5),
+\fBafpd\fR(8)
index 3a913925f3bff9e797bd4df2f96f88a2daea127c..9f09a64b5d50afbd2ca8089f80600505cbff7202 100644 (file)
@@ -1,13 +1,22 @@
 '\" t
 .\"     Title: afpd
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 23 Mar 2012
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 19 Jan 2013
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
 .\"  Language: English
 .\"
-.TH "AFPD" "8" "23 Mar 2012" "Netatalk 3.0" "Netatalk 3.0"
+.TH "AFPD" "8" "19 Jan 2013" "Netatalk 3.0" "Netatalk 3.0"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -64,7 +73,7 @@ Specifies the configuration file to use\&. (Defaults to
 .RE
 .SH "SIGNALS"
 .PP
-To shut down a user\'s
+To shut down a user\*(Aqs
 \fBafpd\fR
 process it is recommended that
 \fBSIGKILL (\-9)\fR
@@ -105,7 +114,7 @@ to a child
 \fBafpd\fR
 enables
 \fImax_debug\fR
-logging for this process\&. The log is sent to fhe file
+logging for this process\&. The log is sent to the file
 /tmp/afpd\&.PID\&.XXXXXX\&. Sending another
 \fBSIGINT\fR
 will revert to the original log settings\&.
@@ -142,6 +151,11 @@ list of server signature
 list of UUID for Time Machine volume
 .RE
 .PP
+:ETCDIR:/extmap\&.conf
+.RS 4
+file name extension mapping
+.RE
+.PP
 :ETCDIR:/msg/message\&.pid
 .RS 4
 contains messages to be sent to users\&.
@@ -153,4 +167,5 @@ contains messages to be sent to users\&.
 \fBafp.conf\fR(5),
 \fBafp_signature.conf\fR(5),
 \fBafp_voluuid.conf\fR(5),
+\fBextmap.conf\fR(5),
 \fBdbd\fR(1)\&.
index 347921efa17139e8f3b1b3c4e5637372443f93ea..b5d8bc5df593016a1fbbf25785b430cce579e5bc 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: cnid_dbd
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 01 Jan 2012
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "CNID_DBD" "8" "01 Jan 2012" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
@@ -49,7 +58,7 @@ per netatalk volume\&.
 .PP
 \fBcnid_dbd\fR
 uses the
-\fBBerkleley DB\fR
+\fBBerkeley DB\fR
 database library and uses transactionally protected updates\&. The
 \fBdbd\fR
 backend with transactions will avoid corruption of the CNID database even if the system crashes unexpectedly\&.
@@ -60,7 +69,7 @@ inherits the effective userid and groupid from
 on startup, which is normally caused by
 \fBafpd\fR
 serving a netatalk volume to a client\&. It changes to the
-\fBBerkleley DB\fR
+\fBBerkeley DB\fR
 database home directory
 \fIdbdir\fR
 that is associated with the volume\&. If the userid inherited from
@@ -83,25 +92,19 @@ via the filedescriptor
 can be configured to run forever or to exit after a period of inactivity\&. If
 \fBcnid_dbd\fR
 receives a TERM or an INT signal it will exit cleanly after flushing dirty database buffers to disk and closing
-\fBBerkleley DB\fR
+\fBBerkeley DB\fR
 database environments\&. It is safe to terminate
 \fBcnid_dbd\fR
 this way, it will be restarted when necessary\&. Other signals are not handled and will cause an immediate exit, possibly leaving the CNID database in an inconsistent state (no transactions) or losing recent updates during recovery (transactions)\&.
 .PP
 The
-\fBBerkleley DB\fR
+\fBBerkeley DB\fR
 database subsystem will create files named log\&.xxxxxxxxxx in the database home directory
-\fIdbdir\fR, where xxxxxxxxxx is a monotonically increasing integer\&. These files contain ithe transactional database changes\&. They will be removed regularily, unless the
+\fIdbdir\fR, where xxxxxxxxxx is a monotonically increasing integer\&. These files contain the transactional database changes\&. They will be removed regularly, unless the
 \fBlogfile_autoremove\fR
 option is specified in the
 \fIdb_param\fR
 configuration file (see below) with a value of 0 (default 1)\&.
-.PP
-Do not use
-\fBcnid_dbd\fR
-for databases on NFS mounted file systems\&. It makes the whole point of securing database changes properly moot\&. Use the dbdir: Option in the appropriate
-\fBAppleVolumes\fR
-configuration file to put the database onto a local disk\&.
 .SH "OPTIONS"
 .PP
 \fB\-v, \-V\fR
@@ -121,7 +124,7 @@ on startup\&. If the file does not exist or a parameter is not listed, suitable
 .RS 4
 If set to 0, unused Berkeley DB transactional logfiles (log\&.xxxxxxxxxx in the database home directory) are not removed on startup of
 \fBcnid_dbd\fR
-and on a reqular basis\&. Default: 1\&.
+and on a regular basis\&. Default: 1\&.
 .RE
 .PP
 \fBcachesize\fR
@@ -132,7 +135,7 @@ process grabs that much memory on top of its normal memory footprint\&. It can b
 \fBdb_stat\fR
 utility with the
 \fB\-m\fR
-option that comes with Berkely DB can help you determine wether you need to change this value\&. The default is pretty conservative so that a large percentage of requests should be satisfied from the cache directly\&. If memory is not a bottleneck on your system you might want to leave it at that value\&. The
+option that comes with Berkley DB can help you determine ether you need to change this value\&. The default is pretty conservative so that a large percentage of requests should be satisfied from the cache directly\&. If memory is not a bottleneck on your system you might want to leave it at that value\&. The
 \fBBerkeley DB Tutorial and Reference Guide\fR
 has a section
 \fBSelecting a cache size\fR
@@ -178,7 +181,7 @@ exits\&. Default: 600\&. Set this to 0 to disable the timeout\&.
 .PP
 Note that the first version to appear
 \fIafter\fR
-Netatalk 2\&.1 ie Netatalk 2\&.1\&.1, will support BerkeleyDB updates on the fly without manual intervention\&. In other words Netatalk 2\&.1 does contain code to prepare the BerkeleyDB database for upgrades and to upgrade it in case it has been prepared before\&. That means it can\'t upgrade a 2\&.0\&.x version because that one didn\'t prepare the database\&.
+Netatalk 2\&.1 ie Netatalk 2\&.1\&.1, will support BerkeleyDB updates on the fly without manual intervention\&. In other words Netatalk 2\&.1 does contain code to prepare the BerkeleyDB database for upgrades and to upgrade it in case it has been prepared before\&. That means it can\*(Aqt upgrade a 2\&.0\&.x version because that one didn\*(Aqt prepare the database\&.
 .PP
 In order to update between older Netatalk releases using different BerkeleyDB library versions, follow this steps:
 .sp
index f96778f1b12bb761ed815e118ba41ce9aa03592a..4007a7cac31039efabbfdec9ed10ad3fc0c48f77 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: cnid_metad
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 23 Mar 2012
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "CNID_METAD" "8" "23 Mar 2012" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
@@ -62,7 +71,7 @@ Show version and exit\&.
 .PP
 \fBcnid_metad\fR
 does not block or catch any signals apart from SIGPIPE\&. It will therefore exit on most signals received\&. This will also cause all instances of
-\fBcnid_dbd\'s\fR
+\fBcnid_dbd\*(Aqs\fR
 started by that
 \fBcnid_metad\fR
 to exit gracefully\&. Since state about and IPC access to the subprocesses is only maintained in memory by
index 61cfffe327f3e1561899bbb12dfe5147a952438e..88cb179e28131377f5421f2612c50ecce3a76ad5 100644 (file)
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: netatalk
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
 .\"      Date: 22 Mar 2012
 .\"    Manual: Netatalk 3.0
 .\"    Source: Netatalk 3.0
@@ -9,6 +9,15 @@
 .\"
 .TH "NETATALK" "8" "22 Mar 2012" "Netatalk 3.0" "Netatalk 3.0"
 .\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
 .\" disable hyphenation
index 033c9e1d3784c3b4c0651100d0243c2aa02bf84f..01278ecd55a22555e620a8e6640729a42132abf5 100644 (file)
@@ -31,7 +31,6 @@ test_SOURCES =  test.c subtests.c afpfunc_helpers.c \
                                $(top_srcdir)/etc/afpd/file.c \
                                $(top_srcdir)/etc/afpd/filedir.c \
                                $(top_srcdir)/etc/afpd/fork.c \
-                               $(top_srcdir)/etc/afpd/gettok.c \
                                $(top_srcdir)/etc/afpd/hash.c \
                                $(top_srcdir)/etc/afpd/mangle.c \
                                $(top_srcdir)/etc/afpd/messages.c \
index 4387bdfca7e852f7cb45e4f943cd352501c69df5..92347f1cf824da1bec05ae7ef4eacc74ad4bcee1 100644 (file)
@@ -1,5 +1,4 @@
 /*
-  $Id: afpfunc_helpers.c,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $
   Copyright (c) 2010 Frank Lahm <franklahm@gmail.com>
 
   This program is free software; you can redistribute it and/or modify
index 2a0fcd23c43ec6a6ff12acefe613767e6a4a0a35..933f7f61dc85f570dd5ac69bc33f7c45d04ea0c3 100644 (file)
@@ -1,5 +1,4 @@
 /*
-  $Id: afpfunc_helpers.h,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $
   Copyright (c) 2010 Frank Lahm <franklahm@gmail.com>
 
   This program is free software; you can redistribute it and/or modify
index ee32144a51682eeaa2d0af8358133274406fce7b..2a190eae0acff3b986392b1ae9f7dc711b510732 100644 (file)
@@ -1,5 +1,4 @@
 /*
-  $Id: subtests.h,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $
   Copyright (c) 2010 Frank Lahm <franklahm@gmail.com>
 
   This program is free software; you can redistribute it and/or modify
index 1731ddc141fc4ad1ec27b9b9dc8541be7d4d5bdc..b25ec4dd9c9fd127a470463e0886d6eb18294fff 100644 (file)
@@ -67,7 +67,7 @@ int main(int argc, char **argv)
     TEST_int( afp_config_parse(&obj, NULL), 0);
     TEST_int( configinit(&obj), 0);
     TEST( cnid_init() );
-    TEST( load_volumes(&obj, NULL) );
+    TEST( load_volumes(&obj) );
     TEST_int( dircache_init(8192), 0);
     obj.afp_version = 32;
 
index 382a5bd5bfaaf1502b7626cbdb7192b265f2c05b..98d0c1ba9e7b0691e996e539479f668f247fb450 100644 (file)
@@ -1,5 +1,4 @@
 /*
-  $Id: test.h,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $
   Copyright (c) 2010 Frank Lahm <franklahm@gmail.com>
 
   This program is free software; you can redistribute it and/or modify