]> arthur.barton.de Git - netatalk.git/commitdiff
Convert server and volume options to boolean style
authorFrank Lahm <franklahm@googlemail.com>
Wed, 21 Mar 2012 14:15:18 +0000 (15:15 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Wed, 21 Mar 2012 14:15:18 +0000 (15:15 +0100)
libatalk/util/netatalk_conf.c
man/man5/afp.conf.5.tmpl

index 951573e398f61166d8b2cda2d72b0e38d84f56a9..e96c2547908374b5e8ca5731145b18700c38a711 100644 (file)
@@ -499,19 +499,47 @@ static int hostaccessvol(const AFPObj *obj, const char *volname, const char *arg
  * @param conf    (r) config handle
  * @param vol     (r) volume name (must be section name ie wo vars expanded)
  * @param opt     (r) option
- * @param def     (r) if "option" is not found in "name", try to find it in section "def"
+ * @param defsec  (r) if "option" is not found in "vol", try to find it in section "defsec"
+ * @param defval  (r) if neither "vol" nor "defsec" contain "opt" return "defval"
  *
- * @returns       const option string or NULL
+ * @returns       const option string from "vol" or "defsec", or "defval" if not found
  */
-static const char *getoption(const dictionary *conf, const char *vol, const char *opt, const char *def)
+static const char *getoption(const dictionary *conf, const char *vol, const char *opt, const char *defsec, const char *defval)
 {
     EC_INIT;
-    const char *result = NULL;
+    const char *result;
 
-    if ((!(result = iniparser_getstring(conf, vol, opt, NULL))) && (def != NULL))
-        result = iniparser_getstring(conf, def, opt, NULL);
+    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;
+}
+
+/*!
+ * Get boolean option from config, use default value if not set
+ *
+ * @param conf    (r) config handle
+ * @param vol     (r) volume name (must be section name ie wo vars expanded)
+ * @param opt     (r) option
+ * @param defsec  (r) if "option" is not found in "vol", try to find it in section "defsec"
+ * @param defval  (r) if neither "vol" nor "defsec" contain "opt" return "defval"
+ *
+ * @returns       const option string from "vol" or "defsec", or "defval" if not found
+ */
+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;
 }
 
@@ -572,41 +600,37 @@ static struct vol *creatvol(AFPObj *obj,
      * deny -> either no list (-1), or not in list (0)
      */
     if (pwd) {
-        if (accessvol(obj, getoption(obj->iniconfig, section, "invalid users", preset), pwd->pw_name) == 1)
+        if (accessvol(obj, getoption(obj->iniconfig, section, "invalid users", preset, NULL), pwd->pw_name) == 1)
             goto EC_CLEANUP;
-        if (accessvol(obj, getoption(obj->iniconfig, section, "valid users", preset), pwd->pw_name) == 0)
+        if (accessvol(obj, getoption(obj->iniconfig, section, "valid users", preset, NULL), pwd->pw_name) == 0)
             goto EC_CLEANUP;
-        if (hostaccessvol(obj, section, getoption(obj->iniconfig, section, "hosts deny", preset)) == 1)
+        if (hostaccessvol(obj, section, getoption(obj->iniconfig, section, "hosts deny", preset, NULL)) == 1)
             goto EC_CLEANUP;
-        if (hostaccessvol(obj, section, getoption(obj->iniconfig, section, "hosts allow", preset)) == 0)
+        if (hostaccessvol(obj, section, getoption(obj->iniconfig, section, "hosts allow", preset, NULL)) == 0)
             goto EC_CLEANUP;
     }
 
     EC_NULL( volume = calloc(1, sizeof(struct vol)) );
 
-    volume->v_flags = AFPVOL_USEDOTS | AFPVOL_UNIX_PRIV;
     EC_NULL( volume->v_configname = strdup(section));
 
-#ifdef HAVE_ACLS
-    volume->v_flags |= AFPVOL_ACLS;
-#endif
     volume->v_vfs_ea = AFPVOL_EA_AUTO;
     volume->v_umask = obj->options.umask;
 
-    if (val = getoption(obj->iniconfig, section, "password", preset))
+    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))
+    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))
+    if (val = getoption(obj->iniconfig, section, "vol charset", preset, NULL))
         EC_NULL( volume->v_volcodepage = strdup(val) );
     else
         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))
+    if (val = getoption(obj->iniconfig, section, "mac charset", preset, NULL))
         EC_NULL( volume->v_maccodepage = strdup(val) );
     else
         EC_NULL( volume->v_maccodepage = strdup(obj->options.maccodepage) );
@@ -614,39 +638,39 @@ static struct vol *creatvol(AFPObj *obj,
     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, name) );
-    volume->v_dbpath = strdup(bdata(dbpath));
+    EC_NULL_LOG( volume->v_dbpath = strdup(bdata(dbpath)) );
     bdestroy(dbpath);
 
-    if (val = getoption(obj->iniconfig, section, "cnid scheme", preset))
+    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))
+    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))
+    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))
+    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))
+    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))
+    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))
+    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))
+    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))
+    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)) {
+    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)
@@ -655,7 +679,7 @@ static struct vol *creatvol(AFPObj *obj,
         volume->v_adouble = AD_VERSION;
     }
 
-    if (val = getoption(obj->iniconfig, section, "cnid server", preset)) {
+    if (val = getoption(obj->iniconfig, section, "cnid server", preset, NULL)) {
         EC_NULL( p = strdup(val) );
         volume->v_cnidserver = p;
         if (q = strrchr(val, ':')) {
@@ -670,7 +694,7 @@ static struct vol *creatvol(AFPObj *obj,
         volume->v_cnidport = strdup(obj->options.Cnid_port);
     }
 
-    if (val = getoption(obj->iniconfig, section, "ea", preset)) {
+    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)
@@ -679,7 +703,7 @@ static struct vol *creatvol(AFPObj *obj,
             volume->v_vfs_ea = AFPVOL_EA_NONE;
     }
 
-    if (val = getoption(obj->iniconfig, section, "casefold", preset)) {
+    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)
@@ -690,47 +714,39 @@ static struct vol *creatvol(AFPObj *obj,
             volume->v_casefold = AFPVOL_ULOWERMUPPER;
     }
 
-    if (val = getoption(obj->iniconfig, section, "vol options", preset)) {
-        q = strdup(val);
-        if (p = strtok(q, ", ")) {
-            while (p) {
-                if (strcasecmp(p, "ro") == 0)
-                    volume->v_flags |= AFPVOL_RO;
-                else if (strcasecmp(p, "nohex") == 0)
-                    volume->v_flags |= AFPVOL_NOHEX;
-                else if (strcasecmp(p, "nousedots") == 0)
-                    volume->v_flags &= ~AFPVOL_USEDOTS;
-                else if (strcasecmp(p, "invisibledots") == 0)
-                    volume->v_flags |= volume->v_flags;
-                else if (strcasecmp(p, "nostat") == 0)
-                    volume->v_flags |= AFPVOL_NOSTAT;
-                else if (strcasecmp(p, "noupriv") == 0)
-                    volume->v_flags &= ~AFPVOL_UNIX_PRIV;
-                else if (strcasecmp(p, "nodev") == 0)
-                    volume->v_flags |= AFPVOL_NODEV;
-                else if (strcasecmp(p, "caseinsensitive") == 0)
-                    volume->v_flags |= AFPVOL_CASEINSEN;
-                else if (strcasecmp(p, "illegalseq") == 0)
-                    volume->v_flags |= AFPVOL_EILSEQ;
-                else if (strcasecmp(p, "tm") == 0)
-                    volume->v_flags |= AFPVOL_TM;
-                else if (strcasecmp(p, "searchdb") == 0)
-                    volume->v_flags |= AFPVOL_SEARCHDB;
-                else if (strcasecmp(p, "nonetids") == 0)
-                    volume->v_flags |= AFPVOL_NONETIDS;
-                else if (strcasecmp(p, "noacls") == 0)
-                    volume->v_flags &= ~AFPVOL_ACLS;
-                else if (strcasecmp(p, "nov2toeaconv") == 0)
-                    volume->v_flags |= AFPVOL_NOV2TOEACONV;
-                else if (strcasecmp(p, "preexec_close") == 0)
-                    volume->v_preexec_close = 1;
-                else if (strcasecmp(p, "root_preexec_close") == 0)
-                    volume->v_root_preexec_close = 1;
-                p = strtok(NULL, ", ");
-            }
-        }
-        free(q);
-    }
+    if (getoption_bool(obj->iniconfig, section, "read only", preset, 0))
+        volume->v_flags |= AFPVOL_RO;
+    if (!getoption_bool(obj->iniconfig, section, "hex encoding", preset, 1))
+        volume->v_flags |= AFPVOL_NOHEX;
+    if (getoption_bool(obj->iniconfig, section, "use dots", preset, 1))
+        volume->v_flags |= AFPVOL_USEDOTS;
+    if (getoption_bool(obj->iniconfig, section, "invisible dots", preset, 0))
+        volume->v_flags |= AFPVOL_INV_DOTS;
+    if (!getoption_bool(obj->iniconfig, section, "stat vol", preset, 1))
+        volume->v_flags |= AFPVOL_NOSTAT;
+    if (getoption_bool(obj->iniconfig, section, "unix priv", preset, 1))
+        volume->v_flags |= AFPVOL_UNIX_PRIV;
+    if (!getoption_bool(obj->iniconfig, section, "cnid dev", preset, 1))
+        volume->v_flags |= AFPVOL_NODEV;
+    if (getoption_bool(obj->iniconfig, section, "illegal seq", preset, 0))
+        volume->v_flags |= AFPVOL_EILSEQ;
+    if (getoption_bool(obj->iniconfig, section, "time machine", preset, 0))
+        volume->v_flags |= AFPVOL_TM;
+    if (getoption_bool(obj->iniconfig, section, "search db", preset, 0))
+        volume->v_flags |= AFPVOL_SEARCHDB;
+    if (!getoption_bool(obj->iniconfig, section, "network ids", preset, 1))
+        volume->v_flags |= AFPVOL_NONETIDS;
+#ifdef HAVE_ACLS
+    if (getoption_bool(obj->iniconfig, section, "acls", preset, 1))
+        volume->v_flags |= AFPVOL_ACLS;
+#endif
+    if (!getoption_bool(obj->iniconfig, section, "convert adouble", preset, 1))
+        volume->v_flags |= AFPVOL_NOV2TOEACONV;
+
+    if (getoption_bool(obj->iniconfig, section, "preexec close", preset, 0))
+        volume->v_preexec_close = 1;
+    if (getoption_bool(obj->iniconfig, section, "root preexec close", preset, 0))
+        volume->v_root_preexec_close = 1;
 
     /*
      * Handle read-only behaviour. semantics:
@@ -739,8 +755,8 @@ static struct vol *creatvol(AFPObj *obj,
      * 3) rwlist exists -> ro unless user is in it.
      */
     if (pwd) {
-        if (accessvol(obj, getoption(obj->iniconfig, section, "rolist", preset), pwd->pw_name) == 1
-            || accessvol(obj, getoption(obj->iniconfig, section, "rwlist", preset), pwd->pw_name) == 0)
+        if (accessvol(obj, getoption(obj->iniconfig, section, "rolist", preset, NULL), pwd->pw_name) == 1
+            || accessvol(obj, getoption(obj->iniconfig, section, "rwlist", preset, NULL), pwd->pw_name) == 0)
             volume->v_flags |= AFPVOL_RO;
     }
 
@@ -1372,44 +1388,30 @@ int afp_config_parse(AFPObj *AFPObj)
     options->logconfig = iniparser_getstrdup(config, INISEC_GLOBAL, "log level", "default:note");
     options->logfile   = iniparser_getstrdup(config, INISEC_GLOBAL, "log file",  NULL);
 
-    /* "server options" options wo values */
-    if (q = iniparser_getstrdup(config, INISEC_GLOBAL, "server options", NULL)) {
-        if (p = strtok(q, ", ")) {
-            while (p) {
-                if (strcasecmp(p, "nozeroconf") == 0)
-                    options->flags |= OPTION_NOZEROCONF;
-                if (strcasecmp(p, "icon") == 0)
-                    options->flags |= OPTION_CUSTOMICON;
-                if (strcasecmp(p, "noicon") == 0)
-                    options->flags &= ~OPTION_CUSTOMICON;
-                if (strcasecmp(p, "advertise_ssh") == 0)
-                    options->flags |= OPTION_ANNOUNCESSH;
-                if (strcasecmp(p, "noacl2maccess") == 0)
-                    options->flags &= ~OPTION_ACL2MACCESS;
-                if (strcasecmp(p, "keepsessions") == 0)
-                    options->flags |= OPTION_KEEPSESSIONS;
-                if (strcasecmp(p, "closevol") == 0)
-                    options->flags |= OPTION_CLOSEVOL;
-                if (strcasecmp(p, "client_polling") == 0)
-                    options->flags &= ~OPTION_SERVERNOTIF;
-                if (strcasecmp(p, "nosendfile") == 0)
-                    options->flags |= OPTION_NOSENDFILE;
-                if (strcasecmp(p, "nosavepassword") == 0)
-                    options->passwdbits |= PASSWD_NOSAVE;
-                if (strcasecmp(p, "savepassword") == 0)
-                    options->passwdbits &= ~PASSWD_NOSAVE;
-                if (strcasecmp(p, "nosetpassword") == 0)
-                    options->passwdbits &= ~PASSWD_SET;
-                if (strcasecmp(p, "setpassword") == 0)
-                    options->passwdbits |= PASSWD_SET;
-                p = strtok(NULL, ", ");
-            }
-        }
-        free(q);
-    }
-    /* figure out options w values */
+    /* "server options" boolean options */
+    if (!iniparser_getboolean(config, INISEC_GLOBAL, "zeroconf", 1))
+        options->flags |= OPTION_NOZEROCONF;
+    if (iniparser_getboolean(config, INISEC_GLOBAL, "icon", 0))
+        options->flags |= OPTION_CUSTOMICON;
+    if (iniparser_getboolean(config, INISEC_GLOBAL, "advertise ssh", 0))
+        options->flags |= OPTION_ANNOUNCESSH;
+    if (iniparser_getboolean(config, INISEC_GLOBAL, "map acls", 1))
+        options->flags |= OPTION_ACL2MACCESS;
+    if (iniparser_getboolean(config, INISEC_GLOBAL, "keep sessions", 0))
+        options->flags |= OPTION_KEEPSESSIONS;
+    if (iniparser_getboolean(config, INISEC_GLOBAL, "close vol", 0))
+        options->flags |= OPTION_CLOSEVOL;
+    if (!iniparser_getboolean(config, INISEC_GLOBAL, "client polling", 1))
+        options->flags |= OPTION_SERVERNOTIF;
+    if (!iniparser_getboolean(config, INISEC_GLOBAL, "use sendfile", 1))
+        options->flags |= OPTION_NOSENDFILE;
+    if (!iniparser_getboolean(config, INISEC_GLOBAL, "save password", 1))
+        options->passwdbits |= PASSWD_NOSAVE;
+    if (iniparser_getboolean(config, INISEC_GLOBAL, "set password", 0))
+        options->passwdbits |= PASSWD_SET;
 
-    options->loginmesg      = iniparser_getstrdup(config, INISEC_GLOBAL, "loginmesg",      "");
+    /* figure out options w values */
+    options->loginmesg      = iniparser_getstrdup(config, INISEC_GLOBAL, "login message",      "");
     options->guest          = iniparser_getstrdup(config, INISEC_GLOBAL, "guest account",  "nobody");
     options->passwdfile     = iniparser_getstrdup(config, INISEC_GLOBAL, "passwd file",_PATH_AFPDPWFILE);
     options->uampath        = iniparser_getstrdup(config, INISEC_GLOBAL, "uam path",       _PATH_AFPDUAMPATH);
index 782835f4168733975704aac73640836c72544b6a..74d378b22dd6da8f8236f5fd3e0c6c7f9ebbe60e 100644 (file)
@@ -150,7 +150,7 @@ in parentheses indicates that a parameter is specific to the [Global] section\&.
 indicates that a parameter can be specified in a volume specific section\&.
 .SH "VARIABLE SUBSTITUTIONS"
 .PP
-You can use variables in both volume path and volume name\&.
+You can use variables in volume names\&. The use of variables in paths is not supported for now\&.
 .sp
 .RS 4
 .ie n \{\
@@ -230,27 +230,18 @@ $$
 .RS 4
 prints dollar sign ($)
 .RE
+.SH "EXPLANATION OF GLOBAL PARAMETERS"
+.SS "Authentication Options"
 .PP
-\fBExample.\ \&Using variable substitution when defining volumes\fR
+save password = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
+.RS 4
+Enables or disables the ability of clients to save passwords locally\&.
+.RE
 .PP
-.if n \{\
+set password = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
 .RS 4
-.\}
-.nf
-          [Groupdir for $g]
-          /home/groups/$g
-
-          [$f is the best one]
-          ~
-        
-.fi
-.if n \{\
+Enables or disables the ability of clients to change their passwords via chooser or the "connect to server" dialog\&.
 .RE
-.\}
-.sp
-We define "groupdirs" for each primary group and use a personalized server name for homedir shares\&.
-.SH "EXPLANATION OF GLOBAL PARAMETERS"
-.SS "Authentication Methods"
 .PP
 uam list = \fIuam list\fR \fB(G)\fR
 .RS 4
@@ -458,6 +449,13 @@ Sets the minimum password length, if supported by the UAM
 .RE
 .SS "Network Options"
 .PP
+afp listen = \fIip address[:port] [ip adress[:port] \&.\&.\&.]\fR \fB(G)\fR
+.RS 4
+Specifies the IP address that the server should advertise
+\fBand\fR
+listens to\&. The default is advertise the first IP address of the system, but to listen for any incoming request\&. The network address may be specified either in dotted\-decimal format for IPv4 or in hexadecimal format for IPv6\&.
+.RE
+.PP
 fqdn = \fIname:port\fR \fB(G)\fR
 .RS 4
 Specifies a fully\-qualified domain name, with an optional port\&. This is discarded if the server cannot resolve it\&. This option is not honored by AppleShare clients <= 3\&.8\&.3\&. This option is disabled by default\&. Use with caution as this will involve a second name resolution step on the client side\&. Also note that afpd will advertise this name:port combination but not automatically listen to it\&.
@@ -469,13 +467,6 @@ Use this instead of the result from calling hostname for dertermening which IP a
 \fBafp listen\fR\&.
 .RE
 .PP
-afp listen = \fIip address[:port] [ip adress[:port] \&.\&.\&.]\fR \fB(G)\fR
-.RS 4
-Specifies the IP address that the server should advertise
-\fBand\fR
-listens to\&. The default is advertise the first IP address of the system, but to listen for any incoming request\&. The network address may be specified either in dotted\-decimal format for IPv4 or in hexadecimal format for IPv6\&.
-.RE
-.PP
 cnid listen = \fIip address[:port] [ip adress[:port] \&.\&.\&.]\fR \fB(G)\fR
 .RS 4
 Specifies the IP address that the CNID server should listen on\&. The default is
@@ -523,6 +514,40 @@ tcpsndbuf = \fInumber\fR \fB(G)\fR
 .RS 4
 Try to set TCP send buffer using setsockpt()\&. Often OSes impose restrictions on the applications ability to set this value\&.
 .RE
+.PP
+advertise ssh = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
+.RS 4
+Allows 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
+\fBsshd\fR(8)
+on the server to let things work\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\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\&.
+.sp .5v
+.RE
+.RE
+.PP
+zeroconf = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
+.RS 4
+Whether to use automatic Zeroconf
+service registration if support was compiled in\&.
+.RE
+.PP
+use sendfile = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
+.RS 4
+Whether to use sendfile
+syscall for sending file data to clients\&.
+.RE
 .SS "Miscellaneous Options"
 .PP
 vol dbpath = \fIpath\fR \fB(G)\fR
@@ -597,7 +622,7 @@ guest account = \fIname\fR \fB(G)\fR
 Specifies the user that guests should use (default is "nobody")\&. The name should be quoted\&.
 .RE
 .PP
-loginmesg = \fImessage\fR \fB(G)\fR
+login message = \fImessage\fR \fB(G)\fR
 .RS 4
 Sets a message to be displayed when clients logon to the server\&. The message should be in
 \fBunix charset\fR
@@ -651,6 +676,26 @@ Max length of UTF8\-MAC volume name for Mac OS X\&. Note that Hangul is especial
 .sp
 Mac OS 9 and earlier are not influenced by this, because Maccharset volume name is always limitted to 27 bytes\&.
 .RE
+.PP
+icon = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
+.RS 4
+Use the platform\-specific icon\&. Mac OS X doesn\'t display it\&.
+.RE
+.PP
+keep sessions = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
+.RS 4
+Enable "Continuous AFP Service"\&. This means the ability to stop the master afpd process with a SIGQUIT signal, possibly install an afpd update and start the afpd process\&. Existing AFP sessions afpd processes will remain unaffected\&. Technically they will be notified of the master afpd shutdown, sleep 15\-20 seconds and then try to reconnect their IPC channel to the master afpd process\&. If this reconnect fails, the sessions are in an undefined state\&. Therefor it\'s absolutely critical to restart the master process in time!
+.RE
+.PP
+map acls = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
+.RS 4
+Whether to map filesystem ACLs to effective permissions\&.
+.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\&.
+.RE
 .SS "Logging Options"
 .PP
 log file = \fIlogfile\fR \fB(G)\fR
@@ -687,91 +732,6 @@ Both logtype and loglevels are case insensitive\&.
 .sp .5v
 .RE
 .RE
-.SS "Server Options"
-.PP
-server options =
-\fIoption,[option,\&.\&.\&.]\fR
-\fB(G)\fR
-.PP
-server options =
-\fIoption [option \&.\&.\&.]\fR
-\fB(G)\fR
-.PP
-This allows multiple options to be specified in a comma or space delimited format\&. The available options are:
-.PP
-[no]savepassword \fB(G)\fR
-.RS 4
-Enables or disables the ability of clients to save passwords locally
-.RE
-.PP
-[no]setpassword \fB(G)\fR
-.RS 4
-Enables or disables the ability of clients to change their passwords via chooser or the "connect to server" dialog
-.RE
-.PP
-advertise_ssh \fB(G)\fR
-.RS 4
-Allows 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
-\fBsshd\fR(8)
-on the server to let things work\&.
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\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\&.
-.sp .5v
-.RE
-.RE
-.PP
-nozeroconf \fB(G)\fR
-.RS 4
-Disable automatic Zeroconf
-service registration if support was compiled in\&.
-.RE
-.PP
-client_polling \fB(G)\fR
-.RS 4
-With this switch 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!
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBNote\fR
-.ps -1
-.br
-Do not use this option any longer as Netatalk 2\&.x correctly supports server notifications, allowing connected clients to update folder listings in case another client changed the contents\&.
-.sp .5v
-.RE
-.RE
-.PP
-[no]icon \fB(G)\fR
-.RS 4
-[Don\'t] Use the platform\-specific icon\&. Recent Mac OS don\'t display it any longer\&.
-.RE
-.PP
-keepsessions \fB(G)\fR
-.RS 4
-Enable "Continuous AFP Service"\&. This means the ability to stop the master afpd process with a SIGQUIT signal, possibly install an afpd update and start the afpd process\&. Existing AFP sessions afpd processes will remain unaffected\&. Technically they will be notified of the master afpd shutdown, sleep 15\-20 seconds and then try to reconnect their IPC channel to the master afpd process\&. If this reconnect fails, the sessions are in an undefined state\&. Therefor it\'s absolutely critical to restart the master process in time!
-.RE
-.PP
-noacl2maccess \fB(G)\fR
-.RS 4
-Don\'t map filesystem ACLs to effective permissions\&.
-.RE
 .SS "Debug Parameters"
 .PP
 These options are useful for debugging only\&.
@@ -843,13 +803,6 @@ cnid scheme = \fIbackend\fR \fB(V)\fR
 set the CNID backend to be used for the volume, default is [:DEFAULT_CNID_SCHEME:] available schemes: [:COMPILED_BACKENDS:]
 .RE
 .PP
-cnid server = \fIhost[:port]\fR \fB(V)\fR
-.RS 4
-Query this servername or IP address (default:\fIlocalhost\fR) and port (default:
-\fI4700\fR) for CNIDs\&. Only used with CNID backend "\fIdbd\fR"\&. This option here overrides any setting from
-afp\&.conf:\fBcnid server\fR\&.
-.RE
-.PP
 ea = \fInone|auto|sys|ad\fR
 .RS 4
 Specify how Extended Attributes
@@ -985,82 +938,95 @@ hide files and directories,where the path matches one of the \'/\' delimited vet
 .RE
 .SS "Volume options"
 .PP
-vol options =
-\fIoption,[option,\&.\&.\&.]\fR
-\fB(V)\fR
+Boolean volume options\&.
 .PP
-vol options =
-\fIoption [option \&.\&.\&.]\fR
-\fB(V)\fR
+acls = \fIBOOLEAN\fR (default: \fItrue\fR) \fB(V)\fR
+.RS 4
+Whether to flag volumes as supporting ACLs\&. If ACL support is compiled in, this is true by default\&.
+.RE
 .PP
-This allows multiple options to be specified in a comma or space delimited format\&. The available options are:
+cnid dev = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
+.RS 4
+Whether to use the device number in the CNID backends\&. Helps when the device number is not constant across a reboot, eg cluster, \&.\&.\&.
+.RE
 .PP
-searchdb \fB(V)\fR
+convert adouble = \fIBOOLEAN\fR (default: \fItrue\fR) \fB(V)\fR
 .RS 4
-Use fast CNID database namesearch instead of slow recursive filesystem search\&. Relies on a consistent CNID database, ie Samba or local filesystem access lead to inaccurate or wrong results\&. Works only for "dbd" CNID db volumes\&.
+Whether automatic conversion from
+\fBapple double = v2\fR
+to
+\fBapple double = ea\fR
+is performed when accessing filesystems from clients\&. This is generally useful, but costs some performance\&. It\'s recommdable to run
+\fBdbd\fR
+on volumes and do the conversion with that\&. Then this option can be set to no\&.
 .RE
 .PP
-tm \fB(V)\fR
+hex encoding = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
 .RS 4
-Enable Time Machine suport for this volume\&.
+Whether :hex encoding is done for file and directory names containing the character
+/\&. Setting this option to no makes the
+/
+character illegal\&.
 .RE
 .PP
-invisibledots \fB(V)\fR
+invisible dots = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
 .RS 4
 make dot files invisible\&. Use without
 \fBnousedots\fR\&.
 .RE
 .PP
-nonetids \fB(V)\fR
+network ids = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
 .RS 4
-Try to force ACL unawareness on the client\&.
+Whether the server support network ids\&. Setting this to
+\fIno\fR
+will result in the client not using ACL AFP functions\&.
 .RE
 .PP
-preexec_close \fB(V)\fR
+preexec close = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
 .RS 4
-a non\-zero return code from preexec close the volume being immediately, preventing clients to mount/see the volume in question\&.
+A non\-zero return code from preexec close the volume being immediately, preventing clients to mount/see the volume in question\&.
 .RE
 .PP
-ro \fB(V)\fR
+read only = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
 .RS 4
-Specifies the share as being read only for all users\&. The \&.AppleDB directory has to be writeable, you can use the
-\fBvol dbpath\fR
-option to relocate it\&. Overwrites
+Specifies the share as being read only for all users\&. Overwrites
 \fBea = auto\fR
 with
 \fBea = none\fR
 .RE
 .PP
-root_preexec_close \fB(V)\fR
+root preexec close= \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
 .RS 4
-a non\-zero return code from root_preexec closes the volume immediately, preventing clients to mount/see the volume in question\&.
+A non\-zero return code from root_preexec closes the volume immediately, preventing clients to mount/see the volume in question\&.
 .RE
 .PP
-noupriv \fB(V)\fR
+search db = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
 .RS 4
-Don\'t use AFP3 unix privileges\&. This should not be set for OS X clients\&. See also: "\fBfile perm =\fR" and "\fBdirectory perm =\fR"\&.
+Use fast CNID database namesearch instead of slow recursive filesystem search\&. Relies on a consistent CNID database, ie Samba or local filesystem access lead to inaccurate or wrong results\&. Works only for "dbd" CNID db volumes\&.
 .RE
 .PP
-nousedots \fB(V)\fR
+stat vol = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
 .RS 4
-do :hex translation for dot files\&. See also
-\fBinvisibledots\fR\&.
+Whether to stat volume path when enumerating volumes list, useful for automounting or volumes created by a preexec script\&.
 .RE
 .PP
-nodev \fB(V)\fR
+time machine = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
 .RS 4
-always use 0 for device number, helps when the device number is not constant across a reboot, cluster, \&.\&.\&.
+Whether to enable Time Machine suport for this volume\&.
 .RE
 .PP
-nohex \fB(V)\fR
+unix priv = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
 .RS 4
-Disables :hex translations for anything except dot files\&. This option makes the
-\'/\' character illegal\&.
+Whether to use AFP3 UNIX privileges\&. This should be set for OS X clients\&. See also:
+\fBfile perm\fR
+and
+\fBdirectory perm\fR\&.
 .RE
 .PP
-nostat \fB(V)\fR
+use dots = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
 .RS 4
-don\'t stat volume path when enumerating volumes list, useful for automounting or volumes created by a preexec script\&.
+Whether to do :hex translation for dot files\&. See also
+\fBinvisible dots\fR\&.
 .RE
 .SH "CNID BACKENDS"
 .PP