]> arthur.barton.de Git - netatalk.git/commitdiff
Merge remote-tracking branch 'origin/branch-netatalk-3-0' into develop
authorRalph Boehme <sloowfranklin@gmail.com>
Tue, 14 May 2013 08:48:58 +0000 (10:48 +0200)
committerRalph Boehme <sloowfranklin@gmail.com>
Tue, 14 May 2013 08:48:58 +0000 (10:48 +0200)
101 files changed:
Makefile.am
configure.ac
doc/.gitignore
doc/DEVELOPER
doc/Makefile.am
doc/gfx_and_css/logo.ai [new file with mode: 0644]
doc/gfx_and_css/logo.pdf [new file with mode: 0644]
doc/gfx_and_css/logo.png [new file with mode: 0644]
doc/gfx_and_css/netatalk.css [new file with mode: 0644]
doc/html.xsl.in [new file with mode: 0644]
doc/man.xsl.in [new file with mode: 0644]
doc/manpages/Makefile.am [new file with mode: 0644]
doc/manpages/man1/.gitignore [new file with mode: 0644]
doc/manpages/man1/Makefile.am [new file with mode: 0644]
doc/manpages/man1/ad.1.xml [new file with mode: 0644]
doc/manpages/man1/afpldaptest.1.xml [new file with mode: 0644]
doc/manpages/man1/afppasswd.1.xml [new file with mode: 0644]
doc/manpages/man1/afpstats.1.xml [new file with mode: 0644]
doc/manpages/man1/apple_dump.1.xml [new file with mode: 0644]
doc/manpages/man1/asip-status.pl.1.xml [new file with mode: 0644]
doc/manpages/man1/dbd.1.xml [new file with mode: 0644]
doc/manpages/man1/macusers.1.xml [new file with mode: 0644]
doc/manpages/man1/megatron.1.xml [new file with mode: 0644]
doc/manpages/man1/netatalk-config.1.xml [new file with mode: 0644]
doc/manpages/man1/uniconv.1.xml [new file with mode: 0644]
doc/manpages/man5/.gitignore [new file with mode: 0644]
doc/manpages/man5/Makefile.am [new file with mode: 0644]
doc/manpages/man5/afp.conf.5.xml [new file with mode: 0644]
doc/manpages/man5/afp_signature.conf.5.xml [new file with mode: 0644]
doc/manpages/man5/afp_voluuid.conf.5.xml [new file with mode: 0644]
doc/manpages/man5/extmap.conf.5.xml [new file with mode: 0644]
doc/manpages/man8/.gitignore [new file with mode: 0644]
doc/manpages/man8/Makefile.am [new file with mode: 0644]
doc/manpages/man8/afpd.8.xml [new file with mode: 0644]
doc/manpages/man8/cnid_dbd.8.xml [new file with mode: 0644]
doc/manpages/man8/cnid_metad.8.xml [new file with mode: 0644]
doc/manpages/man8/netatalk.8.xml [new file with mode: 0644]
doc/manual/.gitignore [new file with mode: 0644]
doc/manual/Makefile.am [new file with mode: 0644]
doc/manual/configuration.xml [new file with mode: 0644]
doc/manual/install.xml [new file with mode: 0644]
doc/manual/intro.xml [new file with mode: 0644]
doc/manual/manual.xml.in [new file with mode: 0644]
doc/manual/upgrade.xml [new file with mode: 0644]
doc/netatalk.html [new file with mode: 0644]
doc/www/ReleaseNotes [new file with mode: 0644]
doc/www/asciidoc.conf [new file with mode: 0644]
doc/www/asciidoc.py [new file with mode: 0755]
doc/www/create-relnotes.sh [new file with mode: 0755]
doc/www/html5.conf [new file with mode: 0644]
doc/www/javascripts/asciidoc.js [new file with mode: 0644]
doc/www/lang-en.conf [new file with mode: 0644]
doc/www/netatalk-relnotes.conf [new file with mode: 0644]
doc/www/stylesheets/asciidoc.css [new file with mode: 0644]
macros/netatalk.m4
macros/summary.m4
man/.gitignore
man/man1/.gitignore
man/man1/Makefile.am
man/man1/ad.1 [deleted file]
man/man1/ad.1.in [new file with mode: 0644]
man/man1/afpldaptest.1.in [new file with mode: 0644]
man/man1/afpldaptest.1.tmpl [deleted file]
man/man1/afppasswd.1 [deleted file]
man/man1/afppasswd.1.in [new file with mode: 0644]
man/man1/afpstats.1.in [new file with mode: 0644]
man/man1/afpstats.1.tmpl [deleted file]
man/man1/apple_dump.1 [deleted file]
man/man1/apple_dump.1.in [new file with mode: 0644]
man/man1/asip-status.pl.1.in [new file with mode: 0644]
man/man1/asip-status.pl.1.tmpl [deleted file]
man/man1/dbd.1 [deleted file]
man/man1/dbd.1.in [new file with mode: 0644]
man/man1/macusers.1 [deleted file]
man/man1/macusers.1.in [new file with mode: 0644]
man/man1/megatron.1 [deleted file]
man/man1/megatron.1.in [new file with mode: 0644]
man/man1/netatalk-config.1 [deleted file]
man/man1/netatalk-config.1.in [new file with mode: 0644]
man/man1/uniconv.1.in [new file with mode: 0644]
man/man1/uniconv.1.tmpl [deleted file]
man/man5/.gitignore
man/man5/Makefile.am
man/man5/afp.conf.5.in [new file with mode: 0644]
man/man5/afp.conf.5.tmpl [deleted file]
man/man5/afp_signature.conf.5.in [new file with mode: 0644]
man/man5/afp_signature.conf.5.tmpl [deleted file]
man/man5/afp_voluuid.conf.5.in [new file with mode: 0644]
man/man5/afp_voluuid.conf.5.tmpl [deleted file]
man/man5/extmap.conf.5.in [new file with mode: 0644]
man/man5/extmap.conf.5.tmpl [deleted file]
man/man8/.gitignore
man/man8/Makefile.am
man/man8/afpd.8.in [new file with mode: 0644]
man/man8/afpd.8.tmpl [deleted file]
man/man8/cnid_dbd.8.in [new file with mode: 0644]
man/man8/cnid_dbd.8.tmpl [deleted file]
man/man8/cnid_metad.8.in [new file with mode: 0644]
man/man8/cnid_metad.8.tmpl [deleted file]
man/man8/netatalk.8.in [new file with mode: 0644]
man/man8/netatalk.8.tmpl [deleted file]

index 36a8c3cd3be5fcf8058916014c59682d6cf5a9af..4d714f2de666a4451205a3f4bf7657e29334a0bb 100644 (file)
@@ -1,9 +1,9 @@
 # Makefile.am for top level of netatalk package
 
 if USE_BUILTIN_LIBEVENT
-SUBDIRS = libevent include libatalk bin config etc man contrib distrib doc macros test
+SUBDIRS = libevent include libatalk bin config etc contrib distrib doc man macros test
 else
-SUBDIRS = include libatalk bin config etc man contrib distrib doc macros test
+SUBDIRS = include libatalk bin config etc contrib distrib doc man macros test
 endif
 
 EXTRA_DIST = CONTRIBUTORS COPYRIGHT COPYING NEWS VERSION
index d79766086256004481f73d33fe8e2670754fb9d7..421c9fef754f58fb0dcbd0659413a1566b7ef68a 100644 (file)
@@ -200,6 +200,9 @@ AC_NETATALK_FHS
 dnl netatalk lockfile path, must come after AC_NETATALK_FHS
 AC_NETATALK_LOCKFILE
 
+dnl Check for Docbook and build documentation if found
+AX_CHECK_DOCBOOK
+
 CFLAGS="-I\$(top_srcdir)/include -I\$(top_builddir)/include $CFLAGS"
 UAMS_PATH="${uams_path}"
 
@@ -251,6 +254,14 @@ AC_OUTPUT([Makefile
        distrib/initscripts/Makefile
        distrib/m4/Makefile
        doc/Makefile
+    doc/html.xsl
+    doc/man.xsl
+    doc/manual/Makefile
+    doc/manual/manual.xml
+    doc/manpages/Makefile
+    doc/manpages/man1/Makefile
+    doc/manpages/man5/Makefile
+    doc/manpages/man8/Makefile
        etc/Makefile
        etc/afpd/Makefile
        etc/cnid_dbd/Makefile
@@ -280,8 +291,26 @@ AC_OUTPUT([Makefile
        macros/Makefile
        man/Makefile
        man/man1/Makefile
+    man/man1/ad.1
+    man/man1/afpldaptest.1
+    man/man1/afppasswd.1
+    man/man1/afpstats.1
+    man/man1/apple_dump.1
+    man/man1/asip-status.pl.1
+    man/man1/dbd.1
+    man/man1/macusers.1
+    man/man1/netatalk-config.1
+    man/man1/uniconv.1
        man/man5/Makefile
+    man/man5/afp.conf.5
+    man/man5/afp_signature.conf.5
+    man/man5/afp_voluuid.conf.5
+    man/man5/extmap.conf.5
        man/man8/Makefile
+    man/man8/afpd.8
+    man/man8/cnid_dbd.8
+    man/man8/cnid_metad.8
+    man/man8/netatalk.8
        test/Makefile
        test/afpd/Makefile
        ],
index ade949aa9484fb06c410eaf6ec495e6885e769df..c8189ad19eff21550c168c583c8fda78a0752d30 100644 (file)
@@ -1,4 +1,4 @@
 Makefile.in
 Makefile
-.gitignore
-*.o
+html.xsl
+man.xsl
\ No newline at end of file
index 4a1e7de1ce6ac562ed49d931f4394702208c8c31..2ddb69f6fc410e91078436ff7b3ca81406592300 100644 (file)
@@ -288,3 +288,54 @@ filenames for the usock_file parameter.
 
 - There is no protection against a malicious user connecting to the
 cnid_dbd socket and changing the database.
+
+Documentation
+=============
+Netatalk documentation is in Docbook XML format. In order to build manpages
+and the html documentation from the Docbook docs you need the following:
+
+1. Install `xsltproc`
+
+2. Get the latest Docbook XSL stylesheet distribution from:
+   https://sourceforge.net/project/showfiles.php?group_id=21935
+   Tested docbook-xsl stylesheet version is 1.75.2.
+
+3. Fix indexterm bug in xsl stylesheet:
+   inside the xsl stylesheet distribution in manpages/inline.xsl remove these lines:
+
+        <!-- * indexterm instances produce groff comments like this: -->
+        <!-- * .\" primary: secondary: tertiary -->
+        <xsl:template match="indexterm">
+          <xsl:text>.\" </xsl:text>
+          <xsl:apply-templates/>
+          <xsl:text>&#10;</xsl:text>
+        </xsl:template>
+
+        <xsl:template match="primary">
+          <xsl:value-of select="normalize-space(.)"/>
+        </xsl:template>
+
+        <xsl:template match="secondary|tertiary">
+          <xsl:text>: </xsl:text>
+          <xsl:value-of select="normalize-space(.)"/>
+        </xsl:template>
+
+4. Add the following argument to configure
+   --with-docbook=PATH_TO_XML_STYLESHEET_DIR
+
+5. The manpages and html documentation are now automatically built when running `make html`.
+
+Editing Docbook Sources
+-----------------------
+Free WYSIWYG editor with only one minor drawback is XMLEditor from XMLmind:
+http://www.xmlmind.com/xmleditor/persoedition.html
+
+Drawback: in order to be able to edit any of the  nested xml files, you have to
+"promote" them to valid Docbook files by referencing the Docbook DTD, insert as line 2+3:
+       
+       <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+       "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+These changes will however prevent XMLeditor from opening the master xml file
+manual.xml. Before further processing can be done these changes then have to be
+reverted for any changed file.
index a6fcda87c26eefbfa516d8a595f87943f11a3cb7..e1b356f1a8b62786d6131a5023817d902ef90c66 100644 (file)
@@ -1,3 +1,9 @@
-# Makefile.am for INSTALL/
+SUBDIRS = manpages manual
+XSLTPROC=@XSLTPROC@
+XSLTPROC_FLAGS=@XSLTPROC_FLAGS@
+XHTML_STYLESHEET=$(top_srcdir)/doc/html.xsl
 
-EXTRA_DIST = DEVELOPER
+htmldir = $(prefix)/share/doc/@PACKAGE@
+dist_html_DATA = @PACKAGE@.html
+
+DISTCLEANFILES = html.xsl man.xsl
diff --git a/doc/gfx_and_css/logo.ai b/doc/gfx_and_css/logo.ai
new file mode 100644 (file)
index 0000000..0534656
--- /dev/null
@@ -0,0 +1,687 @@
+%PDF-1.5\r%âãÏÓ\r
+1 0 obj\r<</Metadata 458 0 R/Pages 2 0 R/OCProperties<</D<</RBGroups[]/ON[15 0 R 23 0 R 41 0 R 49 0 R 67 0 R 75 0 R 93 0 R 100 0 R 126 0 R 180 0 R 234 0 R 292 0 R 350 0 R 408 0 R]/OFF[119 0 R]/Order 407 0 R>>/OCGs[15 0 R 23 0 R 41 0 R 49 0 R 67 0 R 75 0 R 93 0 R 100 0 R 119 0 R 126 0 R 180 0 R 234 0 R 292 0 R 350 0 R 408 0 R]>>/Type/Catalog>>\rendobj\r458 0 obj\r<</Subtype/XML/Length 25612/Type/Metadata>>stream\r
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.1-c036 46.277092, Fri Feb 23 2007 14:16:18        ">
+   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+      <rdf:Description rdf:about=""
+            xmlns:dc="http://purl.org/dc/elements/1.1/">
+         <dc:format>application/pdf</dc:format>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:xap="http://ns.adobe.com/xap/1.0/"
+            xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/">
+         <xap:CreatorTool>Adobe Illustrator CS3</xap:CreatorTool>
+         <xap:CreateDate>2009-06-03T14:56:54-07:00</xap:CreateDate>
+         <xap:ModifyDate>2009-06-04T10:49:53-07:00</xap:ModifyDate>
+         <xap:MetadataDate>2009-06-04T10:49:53-07:00</xap:MetadataDate>
+         <xap:Thumbnails>
+            <rdf:Alt>
+               <rdf:li rdf:parseType="Resource">
+                  <xapGImg:width>256</xapGImg:width>
+                  <xapGImg:height>256</xapGImg:height>
+                  <xapGImg:format>JPEG</xapGImg:format>
+                  <xapGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXYq7FUm8y+cvKnle1F15h1a10uEglPrMqoz06iNCebn2UHFXjHmr/nMz8u9NLxaBY3mvTLXjJQW&#xA;du3+zlDS/wDJLFXlHmH/AJzM/M2/LJpFnp+jwn7DLG1zOPm8remf+ReKvP8AV/z5/OLVSTdebNQT&#xA;l1FpILMda9LYQ4qxW98z+Zb5uV7q17dMepmuJZD0p+0x7YqlmKuxVM7LzP5lsW5WWrXtqw6GG4lj&#xA;PSn7LDtirKtI/Pn84tKINr5s1B+PQXcgvB1r0uRNir0Dy9/zmZ+ZtgVTV7PT9YhH22aNrac/J4m9&#xA;Mf8AIvFXq/lX/nMz8u9SKRa/Y3mgzNTlJQXluv8As4gsv/JLFXs/lrzl5U80WpuvL2rWuqQgAv8A&#xA;VpVdkr0EiA80PswGKpzirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVYL+Y351fl/wCQ&#xA;IGGt6gJNRpWLSbWkt21RUVSoEYP80hUYq+X/AMwf+cvfP2vNJa+Wo08t6aagSR0mvHXp8UzDinj8&#xA;Cgj+Y4q8O1DUtR1K8kvdRupr28mNZbm4kaWVz4s7lmP0nFVBEd2CopZj0UCpxVM7XyxrVxQi3Man&#xA;9qUhPwPxfhiqZQeRbtv7+6RP9RS/6+GKo2PyLZD+8uZG/wBUKv6+WKqy+SdIA3eZvcsv8FxVzeSd&#xA;II2eZfcMv8VxVRk8i2R/u7mRf9YK36uOKoOfyLdLX0LpH8A6lP1c8VSy68sa1b1JtzIo/aiIf8B8&#xA;X4Yqljo6MVdSrDqpFDiqvp+pajpt5He6ddTWV5CaxXNvI0UqHxV0KsPoOKvcfy+/5y98/aC0dr5l&#xA;jTzJpooDJJSG8RenwzKOL+PxqSf5hir6g/Ln86vy/wDP8CjRNQEeo0rLpN1SK7WgqaJUiQD+aMsM&#xA;VZ1irsVdirsVdirsVdirsVdirsVdirsVdirsVS/X/MOieXtKn1bW72Kw062XlNczNxUeAHdmPQKN&#xA;ydhir5K/Nr/nLzW9WabSfIavpOmmqPq8gH1yUdKxLuIFPju/f4Ttir50uLi4uZ5Li4leaeVi8ssj&#xA;F3ZjuWZjUknFUTp+j6hqDf6NESlaGU7IPpOKsnsPJNpHR72Qzt3jT4U+/wC0fwxVP7WytLVONvCk&#xA;Q/yQAT8z1OKq+KuxV2KuxV2KuxV2KuxVQurK0uk43EKSj/KAJHyPUYqkF/5JtJKvZSGBu0b/ABJ9&#xA;/wBofjirGNQ0fUNPb/SYiErQSjdD9IxVDW9xcW08dxbyvDPEweKWNijqw3DKwoQRir6L/KX/AJy8&#xA;1vSWh0nz4r6tpooiavGB9ciHSsq7CdR47P3+I7Yq+tdA8w6J5h0qDVtEvYr/AE65XlDcwtyU+IPd&#xA;WHQqdwdjiqYYq7FXYq7FXYq7FXYq7FXYq7FXYqwj81Pzd8q/lxo313V5PWv5w36O0qJh69ww+/hG&#xA;D9pyKD3NAVXwr+Zn5sebvzD1c32uXHG1jY/UtMhJFtbr0+FSd2p1dtz8tsVYjbWtxdTLDbxmSVui&#xA;rirL9I8m28PGXUCJpeohH2B8/wCb9WKskRERQiKFVdgoFAB8hiq7FXYq7FXYq7FXYq7FXYq7FXYq&#xA;7FXYqtdEdSjqGVtipFQR8jirG9X8m283KXTyIZephP2D8v5f1YqxC5tbi1maG4jMcq9VbFWXfln+&#xA;bHm78vNXF9odxytZGH13TJiTbXC9PiUHZqdHXcfLbFX3V+Vf5u+VfzH0b67pEno38AX9I6VKw9e3&#xA;Y/dzjJ+y4FD7GoCrN8VdirsVdirsVdirsVdirsVebfnZ+dmi/lnoqO6LfeYL5W/RmmcqAgbGaYjd&#xA;YlP0sdh3KqvgvzV5r17zVrlzrmu3b3mo3TVeRuir+yiL0RF6Ko2GKqWj6Hd6nNSMcIFP7yYjYew8&#xA;TirPNN0qz06D0rdKE/bkO7Mfc4qr3FxBbQtNO4jiQVZjirrW4W5to7hAVSVQ6hutDuPwxVVxV2Ku&#xA;xV2KuxV2KuxV2KuxV2KuxV2KuxV2KoPUtKs9Rg9K4SpH2JBsyn2OKsD1jQ7vTJqSDnAx/dzAbH2P&#xA;gcVVfKvmvXvKuuW2uaFdvZ6jatVJF6Mv7SOvR0boynY4q+9PyT/OzRfzM0V3RFsfMFiq/pPTOVQA&#xA;dhNCTu0TH6VOx7FlXpOKuxV2KuxV2KuxV2KsI/N381NG/LjyrJq97Se/m5RaVp3KjXE9PvEaVBdu&#xA;w9yAVX58+a/NWueateu9d1y5a61G8flI5+yo/ZRF/ZRBsqjoMVa0DQJtTm5NVLRD+8k8f8lff9WK&#xA;s/t7eC3hWGBBHEgoqjFXXNzBawPPO4SJBVmOKsA1rW7jVrkIoKW4akMPuduTe+KvQYYlihjiX7Ma&#xA;hR8gKYqvxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVicnmO50vWrm1uazWnqcgP2kD/EOPtv0xVk9t&#xA;dW91Cs9u4kifowxV1xbwXELQzoJInFGU4qwDX9Am0ybktXtHP7uTw/yW9/14q35U81a55V16013Q&#xA;7lrXUbN+Ubj7LD9pHX9pHGzKeoxV+g35Rfmpo35j+VY9XsqQX8PGLVdO5Va3np95jehKN3HuCAqz&#xA;fFXYq7FXYq7FUv8AMOv6V5e0S91vVp1ttOsImmuZm7KvYDuzHZQNydhir87vzY/MzV/zD83XGuXx&#xA;aO1WsOmWVfht7YElV225H7TnufamKse0PR5tTuxGKrAlDNJ4DwHucVeh29vDbwJBCoSKMUVRiqoz&#xA;KqlmICgVJOwAGKvP/MeuvqNx6cRIs4j8A/mP8x/hiqE0OH1tXtI+o9VWI9lPI/qxV6ZirsVdirsV&#xA;dirsVdirsVdirsVdirsVdirsVYH50i4axz/37ErfdVf+NcVQOj61daZPzjPKFj+9hPRh/A++KvQr&#xA;G+t762S4t25Rt94PcH3xVfcW8NxA8Eyh4pBRlOKvPNc0ebTLsxmrQPUwyeI8D7jFWQ/lP+Zmr/l5&#xA;5ut9csS0lq1IdTsq/DcWxILLvtyH2kPY+1cVfoj5e1/SvMOiWWt6TOtzp1/Es1tMvdW7EdmU7MDu&#xA;DscVTDFXYq7FXYq+Ov8AnLz82m1bW18h6TNXTdJcSau6HaW8p8MRp1WAHf8AyzvuoxV862ttNdXE&#xA;dvCvKWQ8VGKvSdK02DTrNLeLcjeR+7MepxVGYqxfzlrBijGnQtR5BynI7L2X6e+KsNxVO/J0XPW0&#xA;b/faO33jj/xtirP8VdirsVdirsVdirsVdirsVdirsVdirsVdirDfPaUurV/5kYfca/xxVi+KppoG&#xA;syaZdhiSbaSgmT2/mHuMVeiRyJIiyIwZHAZWHQg7g4qhdV02DUbN7eXYneN+6sOhxV5tdW01rcSW&#xA;8y8ZYzxYYq+iv+cQ/wA2m0nW28h6tNTTdWcyaQ7naK8p8UQr0WcDb/LG27HFX2LirsVdirBfzq/M&#xA;aDyB+X+oa2GH6RkH1XSYjQ8ruUHgaHqIwDI3suKvzpuLie5uJbi4kaWeZ2kllc1Znc1ZmJ6kk4qz&#xA;DybpHo251CVf3swpCD2Tx/2X6sVZNiqldXEdtbyzyfYiUu30CuKvMLu6lurmW4lNXlYsfp7fRiqj&#xA;irJPIyj9JTt3EJH3uv8ATFWbYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FWH+fP76z/1X/WuKsVx&#xA;V2Ksy8l6oZIn0+U1aIc4Sf5Sdx9BxVlGKsZ85aR61uNQiX97CKTAd08f9j+rFWH29xPbXEVxbyNF&#xA;PC6yRSoaMroaqykdCCMVfot+Sv5jQef/AMv9P1ssP0jGPqurRCg43cQHM0HQSAiRfZsVZ1irsVfE&#xA;v/OXv5gtr3n6Py1ayV03y2npyAH4XvJgGmbb+ReKb9CG8cVeJaPp7ahqEVtvwJrKR2QbnFXpaIqI&#xA;qIOKqAFA6ADYYquxVjvnW7MWmpbqaG4ff/VTc/jTFWD4q7FWReR3A1SVD+1CafMMuKs4xV2KuxV2&#xA;KuxV2KuxV2KuxV2KuxV2KuxV2KsH87zh9TjiH+6ohX5sSf1UxVjuKuxVGaPeGz1K3uK0VXAf/VbZ&#xA;vwOKvTsVWuiujI45KwIYHoQdjirzTWNPbT9QltjXgDWInuh3XFXtv/OIX5gtoPn6Ty1dSU03zInp&#xA;xgn4UvIQWhbf+deSbdSV8MVfbWKpN5y8y2vlfypq3mG6AMOl2stzwJpzZFJSMHxd6KPnir8zdS1C&#xA;81LUbrUb2QzXl7NJcXMp6vLKxd2PzZicVZj5F0O8+pSagLeR/rB4ROEYjghoaEDu36sVZR+jtQ/5&#xA;Zpf+Ab+mKu/R2of8s0v/AADf0xVhfnew1R7+CNbSYqkXLaNzuzH2/wAnFWOfonVf+WOf/kW/9MVd&#xA;+idV/wCWOf8A5Fv/AExVMvLtpqdrrFvI1pOEZvTYmN6UccfDxxV6L+jtQ/5Zpf8AgG/pirv0dqH/&#xA;ACzS/wDAN/TFXfo7UP8Alml/4Bv6YqteyvEALwSKCQASjDc9BuMVbawvlBZraUKNySjUA+7FUFdX&#xA;UFpEZrhikQFS1CRQ9DsDiqBm8w2MTFSk5K05fuZBTlsteQHWm2KrB5n00mhWZfcxN/DFUVBrGmz/&#xA;AGJgCezhk/4mFxVGqrMvJQWU9CNxirfB/wCU/dirVD4Yq7FVryRorO7BVUEsT2AxV5lql4b3UJ7k&#xA;9JGPEH+UbL+AxVCYq7FXYq9S0+Uy2FtKeskSMf8AZKDiqIxVjPnaw9S0jvUHxQHhIf8AIbp9zfrx&#xA;Vimm6heabqNrqNlIYbyymjuLaUdUliYOjD5MoOKv0y8m+ZbXzR5U0nzDagCHVLWK54A14M6gvGT4&#xA;o9VPyxV4x/zmZ5qOm/l3Y6BE/GbXrweotftW9mBK/wDyVaLFXxfb289zcRW9vG0s8zrHFEgLMzsa&#xA;KqgbkknFX3V5O8/an5Y8q6V5ftPy+1/0NMtYrcMLaQc2RQHc/B1d6sfniqcf8rj17/y3+v8A/SNJ&#xA;/wA0Yq7/AJXHr3/lv9f/AOkaT/mjFUt1H8+vM1pcekn5YeZ7leIb1IrSUrv22jOKoX/oYbzT/wCW&#xA;o81/9Ic3/VLFXf8AQw3mn/y1Hmv/AKQ5v+qWKu/6GG80/wDlqPNf/SHN/wBUsVTPT/zv8wXdv6rf&#xA;lx5kt2qQYpbSVW2+ce4xVE/8rj17/wAt/r//AEjSf80Yq7/lcevf+W/1/wD6RpP+aMVYD+aX53a1&#xA;Ppthb/4A1+1EWqWMoubq0mihd45wwhjZkXlJJ9lAOpxVGebvz58zX3lTWrKT8sPM9pHdWFzC93Na&#xA;SrFEskLKZJCYxRUrU+2KsF8z/mxrd5/zj3D5Xk8ja5a2S6Pp1qPMMtvILEpAIQs4kKBfTl4fAeXc&#xA;Yq7zz+bGt6jq3mKeXyNrli17FoSyQ3FvIrQCzubp0MoKCguDKVj8SpxViM/n7VG6+V9TX5xP/wA0&#xA;4ql8/nTUW6+XdRX5xN/zTiqBfzhqSklNFv4z4hGH8MVWjz5qgNJdIunX3QhvvpiqOtdfg1Bfhglg&#xA;k7xTIVb6Ox+jFVs45dTx+eKsV8z3ogAtYj6juKyFeir4V8TirE3NWrSmKrcVdirsVem6MpGkWQJr&#xA;+4jP3qDiqNxVQvbVLq0mt26SoV+RI2P0HFXlzoyOyMKMpIYe4xV9pf8AOGfmo6l+Xd9oEr8ptBvD&#xA;6a1+zb3gMqf8lVlxV5R/zmZ5hN/+ZtnpCNWHR9PjVk8J7lmlc/TH6eKvKvyyv49M896Pq0tqLxNM&#xA;nW9+rs3AM8Hxx1YBqUkCnpir6n/6Gnv/APqXYv8ApKb/AKp4q7/oae//AOpdi/6Sm/6p4q7/AKGn&#xA;v/8AqXYv+kpv+qeKpN5g/wCcxtU0p4QvlaGVJg3xG7daFabf3R8cVSn/AKHj1X/qUYP+k1/+qOKu&#xA;/wCh49V/6lGD/pNf/qjirv8AoePVf+pRg/6TX/6o4q4f85x6nUV8owU70vX/AOqOKp63/OZMS6eL&#xA;79BQmM7BBdNz5Urx4+n1xVIz/wA5x6nU8fKMFO1b16/8mcVY355/5yx1DzXptjZSeW4bQWWo2mpB&#xA;1umfkbOUSiOhiWnKlK9sVTTX/wDnM3U9Y0LUtJbyrDCuo2s1o0wvHYoJ42j5U9IVpyrTFWL61/zk&#xA;rfap+Usf5dtoMUUMenWmm/pEXLMxFmIwJPT9MD4vR6ctq4q7zP8A85K32vX+r3j6DFbnVk0uNkFw&#xA;zen+ipp5lIPpivqfWaHwp3xVIJfzoupP+lUg/wCex/5oxVCS/mzcSf8AStQf89T/AM04qhJPzJnf&#xA;/jwUf89D/wA04qhJfPUr/wDHmo/2Z/5pxVCyebJXNRbhT2Ic/wBMVRCedpjbuksHKUD90/Lav+Vt&#xA;iqRz6i8zMzLVmNSScVQrNyNcVaxV2KtqpZgqirE0A9zir1WCIRQRxDpGqqP9iKYqqYq7FXnXme1+&#xA;r61cACiyESr/ALMVP/DVxV7R/wA4Z+YTYfmbeaQ7Uh1jT5FVPGe2ZZUP0R+pirz/APPnVzqv5xeb&#xA;Lonlw1CS0B36WYFsOv8AxhxVKfIsHK7up/5EVP8AgzX/AI0xV9R/kd+V3k3zX5Tu9R1u0ee7iv5L&#xA;dHWaSMCNYYXAojAfakOKo784PyX8raH5Mm1jy9ayQXNlLG9zylklDQOfTbZyejMpr4VxVb+Tf5Te&#xA;SPM3kqLVNYs5Jr1p5oy6zSxjihAX4UYDFWD/APOU/wCVvlXyz5e0i50C1eCZ5pmnLSyS1RFTYcy1&#xA;Kc64qnX5Ff8AOPf5W+bfyq0PzBrmmy3GqXv1r6xKlzPGD6V5NClERwookYGwxVnv/Qp/5Jf9Wef/&#xA;AKTLn/qpirxz/nJ38l/y+8h+UtK1Hy1YyWt3dX4t5neeaYGP0ZHpSRmA+JRir2P/AKFP/JL/AKs8&#xA;/wD0mXP/AFUxV3/Qp/5Jf9Wef/pMuf8Aqpirv+hT/wAkv+rPP/0mXP8A1UxV8Q+cNOtdN8263p1o&#xA;pS0sr+6t7dCSxEcUzIgJO5oq4q9P/wCcVfINh5r/ADIabVbKK+0fR7WS4uba5jWWCSSX9zCjo4ZW&#xA;+2ziv8uKvsT/AJVP+Vn/AFJuh/8AcNs/+qeKsH/O78t/y7078p/M99p/lbSLO9t7NngurewtopY2&#xA;5L8SOkYZT8jir5K/Irynonm381dD8v65C1xpd79a+sRI7Rk+lZzTJR0IYUeMHY4q+uP+hT/yS/6s&#xA;8/8A0mXP/VTFXf8AQp/5Jf8AVnn/AOky5/6qYqkH5gf84y/k/o/kPzJq9hpU0d9p2l3t3aSG7uGC&#xA;ywW7yRkqzkGjKNjirwD/AJxs/LnQPPvn+40vX4HuNLtdPmu5I0keIl1kiiT44yD1lrSuKvp7/oU/&#xA;8kv+rPP/ANJlz/1UxViv5qf84y/ldo/5deYdX0LTJoNV06yku7eVrmeQL6A9R6o7sp+BW6jFXx5p&#xA;8STX9tDIKxySojjpszAHFX3b/wBCn/kl/wBWef8A6TLn/qpir5u/5yd/Ljyn5D826Vp3lq1e1tLq&#xA;wFxMjyyTEyetIlayFiPhUYqx38gvKmk+avzY0PRdXga40yb6zJcxKzIf3NrLLGeSEHaRFxV9mf8A&#xA;Qv35Xf8AVtl/6SZ/+a8VeQ6J+Wej6p+dWoeWkgcaBpzyyzxB25CFEAVedeW8jqOuKvXX/ID8rEUu&#xA;+nyKqglmN1OAAOpJ54q+J/zXj0s+ZJLjSojDpkkkyWUZYsRCkh9OpYkk8WFcVRH5DaudK/OLyndA&#xA;8eeoR2hO/S8Btj0/4zYqxXzPetfeZdWvW3a6vbiYnbrJKzdtu+Ksh8ix0srmT+aQL/wK1/42xV9h&#xA;f84xf8oFf/8AbVm/6h7fFXqOuaTb6xo19pVx/cX0ElvIfASKVqPcVrirBvyEsriw8htY3K8Lm0v7&#xA;uCZPB45OLD7xirD/APnKpFfTfL6OOStJdBgehBSMHFWWf8442P1H8mtAta8hG19xP+S1/cMtfoOK&#xA;t/n9+ZOu/l55Gj1/RYLW4vHvYbUx3qSPFwkSRiaRSQty+AftYq+QPzS/P/zj+ZOj2mla5Z6dbW9n&#xA;cfWonsY543L8GjoxlmmFKOe2KvXPyw/5yt/MTzV5/wBD8u6hp2kRWWpXIgnkt4blZQpUmqF7l1B2&#xA;7qcVfVmKvmf87v8AnJrz55E/MS/8taRYaXPY2sdu8cl3FcPKTNCsjVMdxEvVtvhxV8n6zqlxq2sX&#xA;2q3KolxqFxLdTJGCEDzOZGChixpVtqk4q+zP+cNvKX6L/Li61+VALjzBds0b9zbWlYYwf+evqnFX&#xA;u7XUC3cdozUnljkljTxSJkVz9BlXFXn3/ORUzw/kr5qdKVNsiGvhJPGh/BsVfCPkLzrqvkjzZY+Z&#xA;9Kignv8AT/V9GK6V3hPrQvA3JY3ib7MppRhvir62/wCcd/z/APOP5k+Z9S0rXLPTra3s7I3UT2Mc&#xA;8bl/VSOjGWaYcaOe2KvfsVfEPm//AJy0/MbVtN1ry5c6do6WOoQ3WnTSRw3QlEUyNCzKWuWXlxba&#xA;qkV7Yqyv/nB7S+ep+a9VI/uYbS1Rtt/WeSRwNv8AilcVfWLyRxqGkYIpIUFiAOTEKo37kmgxVB69&#xA;piaroWo6W/2L+1mtWrsKTRsh6f62KvzF01Hj1i1RwVdLiNWU9QQ4BGKv1IxV8a/85tf8p/oX/bKH&#xA;/UTLiqT/APOKFh6f5m6ReuPimN0kf+qtnNU/S36sVfcWKsF8geW/qvmrzjr8qUk1HUDb25I/3Tbq&#xA;ORB8GkYg/wCrirf51eZv0B+XmpSxtxur9RYW29DyuAQ5HusQdh8sVfDHnqOtlbSfyyFf+CWv/GuK&#xA;se8sXrWPmXSb1dmtb23mB26xyq3fbtiqWYqzrySoGkOf5pmJ/wCBUYq+vP8AnGL/AJQK/wD+2rN/&#xA;1D2+KvXsVQem6Xbaebv6uOK3dw9060oA8gXn/wAEwLfTirxb/nKf/jn+Xf8AjLc/8RjxVm/5D/8A&#xA;kqND/wCjr/qMmxVMvzL/AC20L8w/Lq6BrU91b2aXCXQksnjSXnGrKBWWOZePxn9nFXyR/wA5Hfkd&#xA;5T/LOy0KfQbu/uX1OS4ScX0kMgUQrGV4elDDT7ZrWuKsO/IH/wAnL5T/AOY5f+Itir9FMVfBf/OW&#xA;H/k7dY/4wWf/AFDR4q8ltLW4u7qG0t0MlxcSLFDGOrO5Cqo+ZOKv028m+XLfy15T0jy/BQx6XaQ2&#xA;vNRQO0aAO/zdqsfnirFvLfmAa1+c3m60iblb+WdO06wIrUeveNNcykU/yVjU+64qgf8AnJqcQfkd&#xA;5ocjlWO1SnT+8vYUr9HLFX59Yq+iv+cJf+U/13/tlH/qJixV9lYq/LbVv+Oref8AGeT/AImcVfYn&#xA;/OFOl+h+Xesaiwo97qjRg+McEEVD1/mkYYq9Q/NXXzo2neXzy4Lf+YtIs5D0HCS7V2r7UjrirNcV&#xA;fm9590j9Efm9remgcY7fW5hEN/7trktH1/yCMVfpDir46/5zQt5Ln8x/L0EYq8umKi/M3MoxVU/5&#xA;x8to7b8zvL1vGKJEtyq/RZzYq+wcVaREQURQoJLEDbdjUn6Sa4q+df8AnKHWbl9b0jReLLbW9u13&#xA;y/Zd5nMf/CCL8cVfOHnZQdIQ/wAsykf8CwxVguKuxVnXklgdIcfyzMD/AMCpxV9ef84xf8oFf/8A&#xA;bVm/6h7fFXqdxqcFvqNnYybSXqymE16tCFYr/wACSfoxVF4q8K/5yn/45/l3/jLc/wDEY8VZv+Q/&#xA;/kqND/6Ov+oybFV/51fmLe/l75Gl8x2dnHfTx3EMAgmZlQiUkE1XfamKvjX84/z21b8z7bS4L/S4&#xA;NOGlvM8Zgd3LmYIDXn4eniqA/IH/AMnL5T/5jl/4i2Kv0UxV8F/85Yf+Tt1j/jBZ/wDUNHiqG/5x&#xA;i8pf4j/N/STInO00blqtx7G3p6P/ACXePFX37irzv8qPy01jyhqvmzVtY1GLUL7zPf8A152hVkWM&#xA;AyME+Lw9Uj5Yqln/ADlNLGn5F+Y1Y0aVrFEG+5F/A1PuU4q+AsVfRX/OEv8Ayn+u/wDbKP8A1ExY&#xA;q+ysVfltq3/HVvP+M8n/ABM4q+8/+cXdLNh+Segll4yXhubpxSn95cyBDv4xquKrf+chfKnnbzLp&#xA;flmDyrp/1+XTdag1O6AmggKLbI4U1meOu8h+zir1jFXwp/zkvpB0/wDP+6lA4x6ibC7QD3jSJj9L&#xA;wscVfdeKvj3/AJzLvJLL8y/Lt1GAXi0sEA9CDcSgj7jirv8AnHq7hvPzN8v3MJrHILojxB+pzVB+&#xA;RxV9hYqpW9zDcIzxNyCO8TezRsUYfeMVeM/85PeX/rGgaZrsa1ewna3mI/33cCoJ9leMD/ZYq+UP&#xA;OzAaQg/mmUD/AIFjirBcVTPzPZNY+ZdWsm2a1vbiEjbrHKy9tu2Ksh8iyVsrmP8AlkDf8EtP+NcV&#xA;fYX/ADjF/wAoFf8A/bVm/wCoe3xVH/nTr58v6l5N1jlxjtdTYzkdfRePhMPpjZsVengggEGoPQ4q&#xA;8K/5yn/45/l7/jLc/wDEY8VZh/zj1dx3f5QaFPF/ds16qnxCX861+njiq/8APb8vNa8/+QJvLujT&#xA;W1veyXME4kvGkSLjExLCsaStXw+HFXyL+Y//ADjZ558geWX8xazfaZcWUcscBjs5bh5eUpoppJBE&#xA;tPH4sVSf8gf/ACcvlP8A5jl/4i2Kv0UxV8F/85Yf+Tt1j/jBZ/8AUNHir2H/AJwp8pfVfLOt+aZo&#xA;6S6ncLZWjEb+jajk7L7PJLQ/6mKvd/PHm2w8oeU9T8yX6NJa6ZCZWiUgM7EhURSdqu7BRiqXfld+&#xA;Ydr+YHlKHzJaWUthbzSywpBOQzH0m4lgV2IJxVhn/OWJA/JLVwTQmezA9z9ZQ4q+C8VfRX/OEv8A&#xA;yn+u/wDbKP8A1ExYq+ysVfltq3/HVvP+M8n/ABM4q/SH8rNLGl/lr5WsOPFoNKsxKKU/eNCrSfe5&#xA;OKonzh5+8oeTbSC78zalHptvdSGK3eRXfm4XkQBGrnYDwxVPIZopoUmiYPFKoeNx0KsKgj6MVfJn&#xA;/OZGkel+YHk7V6UF5bm0r4m1uRJ/2NYq+tsVeA/85EfkB5x/MnzPpuq6HeadbW9nZC1lS+knjcv6&#xA;ryVURQzDjRx3xV5h+R3lvVvI3/ORVr5I1iaCe9sxNIZLVneEtLprz0RpEib7EgrVRuDir7NxVhP5&#xA;f639Z8w+ctIdqvp+qeqg8IrmMUH/AAcbH6cVTb8wPL/+IPJesaQF5y3Ns5t1/wCLo/3kX/JRFxV+&#xA;f/np6WVtEerSlqf6qkf8bYqx7yxZNfeZdJsl3a6vbeEDbrJKq99u+Ksq/PnSDpX5xebLUjjz1CS7&#xA;A36XgFyOv/GbFUp8iz8bu6g/nRX/AOANP+N8VfVH5E/mX5J8r+UbvT9d1L6ndy6hJcRxejPLWNoY&#xA;UDcoo3X7SNtXFUJ+ff5ieTvNWkaVb6DqH1ya2uHkmX0Z4uKslAayogO/hirNvJH56+Q4vKOlQa5q&#xA;pt9Wgt0hu4jb3LnlF8AblHG6Hmqhtj3xV5j/AM5P/mZ5S8weXNO/w/qH1ya3adZR6U0XH1giqayp&#xA;HXoemKpp+Qn59/lP5V/KfQtB17XfqerWf1r6zbfVbyXj6t5NKnxxQuhqjqdmxVn/AP0NH+RP/Uzf&#xA;9OOof9k+KvMP+cjfzw/K7zh+Wk+i+XNa+vam93byrb/VbuGqRsSx5zQxpt88VfP/AOUGv6T5f/Mv&#xA;y9rWrz/VtMsbtZbq44PJwQKRXhGruevYYq+z/wDoaP8AIn/qZv8Apx1D/snxV8kf85CebvL3m380&#xA;tS1zy/d/XdLuIrZIrj05YqmOBEccJljcUYEbjFXoH5ef85aWnkryXpXli08nfWI9Nh4PcfpH0/Vl&#xA;djJLJw+qvx5yOzU5GnjiqWfm9/zlHc/mF5Nk8sw+X/0PHPPFLcXH136zzjhJcR8PQhpVwrV5dumK&#xA;on8q/wDnKlPIPkbT/Ky+Vf0gbJp2e9+v+h6hmneWvp/V5ePEOF+12riqG/N7/nJ//lYnk2Ty3/hr&#xA;9F+pPFP9b+vfWKekSePp/V4etevLFXhWKvaP+cXPzC8n+R/N+rah5o1D9H2dzp5t4JfRnn5SetG/&#xA;HjAkrD4VO5FMVfS//Q0f5E/9TN/046h/2T4q+C7t4LjVZn9TjbzTsfVoTRGcnlx69N6Yq+8YP+cn&#xA;fyFghjhj8y8Y4lCIPqOobKooP+PfFXgn/OVX5ueTfPSeXLTypqP6QtrE3Ut63o3EAEknpLEKTxxV&#xA;2V+leuKvZ/J//OTf5NW3lHRLbU/MXoalBp9rHewmzvmKTpCqyryjgKGjgiqmnhirzH/nJX82Pyu8&#xA;66X5ck8uayL6/wBL1HnNF9Wu4SttKlZHrNDGpo0SbA19sVey/wDQ0f5E/wDUzf8ATjqH/ZPirv8A&#xA;oaP8if8AqZv+nHUP+yfFXgH/ACtHyJ/0Nj/jz9J/86p/1cvQuP8Aqz/Vf7n0/W/vvh+x79N8VfS3&#xA;/K+fyo/6vn/Tref9UcVeXeUfzQ8saX+b/mPWLi94+XtXVxHdelMaupRo29MIZOzD7PfFXqP/ACvj&#xA;8qP+r5/063n/AFRxV8Vfnbc6LL51u10ScXGlNLLcWkgR4xwnfkF4uFYcKcdx2xVT/IbSDqv5xeU7&#xA;UDlw1CO7I36WYNyen/GHFXoH/OZnl42H5m2erotIdY0+NmfxntmaJx9Efp4q8X8sXX1fWrck0WQm&#xA;Jv8AZig/4amKvRcVdiraippiqVeZ9NF3awQGUoC5c0Fa8RTx/wArFUhTybE3/H0w/wBgP64qiE8h&#xA;wt/x+MP9gP8AmrFUQn5cwt/x/MP+eY/5qxVER/lfA3/SwYf88h/zViqJj/KS3f8A6WTj/nkP+asV&#xA;REf5NWzf9LVx/wA8R/zXiqKsvyMtbi/trU6u6idbpi/oA0+rWU92Nuf7Rt+P01xVkXl7/nGOx1a/&#xA;8n2reYJYR5o0FtckcWyt6DKts3ogeoOY/wBK+1t06Yqm1j/ziPp1z581XyufMsyx6bYWd8t19UUl&#xA;zdyTIUKertx9DrXvirtf/wCcR9O0rzR5X0RfMs0q+Yri7gec2iqYRa2cl0CF9U8uRi49RirIv+hH&#xA;NK/6m6f/AKQk/wCq2Ku/6Ec0r/qbp/8ApCT/AKrYq7/oRzSv+pun/wCkJP8Aqtirv+hHNK/6m6f/&#xA;AKQk/wCq2Ku/6Ec0r/qbp/8ApCT/AKrYq7/oRzSv+pun/wCkJP8Aqtirv+hHNK/6m6f/AKQk/wCq&#xA;2Ku/6Ec0r/qbp/8ApCT/AKrYq7/oRzSv+pun/wCkJP8Aqtirv+hHNK/6m6f/AKQk/wCq2Ku/6Ec0&#xA;r/qbp/8ApCT/AKrYqyeL/nFWwSJEPmOZiqhS31Vd6Clf73FV/wD0Kxp//UxS/wDSMv8A1UxV3/Qr&#xA;Gn/9TFL/ANIy/wDVTFXyZ+alhZ6Z+YGtaTZ3RvLfTLg2S3DKELPAOEvwgtSkoYdcVeo/84Z+Xjf/&#xA;AJm3mrutYdH0+RlfwnuWWJB9MfqYq9X/AOczPKp1L8u7HX4k5TaDeD1Gp9m3vAIn/wCSqxYq+LUd&#xA;kdXU0ZSCp9xir1GyukurSG4XpKgb5EjcfQcVV8VbUVOKpP5k0xbqW3Bmkj4K32DTqR/TFUtj8sxN&#xA;/wAflwP9kP6Yqio/KMLf8f1yPk4/piqKj8kwt/0sbsfJx/TFUVH5Cgb/AKWd4Pk4/piqLi/Lm3b/&#xA;AKW18PlIP6Yqio/yxtm/6XGoD5SD+mKo3T/yntJtTtLc63qSCZbwl1lAYehp9zcCm37Rh4t/kk4q&#xA;ynyt+RFjqOp+RLdvMusQDXvLT6tI8U6hrdglofQg+H4Yv3/T2GKp5p3/ADjlp0/5la1oJ82a6kdl&#xA;pljdreLcKJ3NxLcIUduO6J6NVHucVd5n/wCcctO0/wA5eTdKXzZrsy61c3sT3EtwplgEFjLcBoTx&#xA;+EsY+Lf5JxVlX/QqWlf9Tt5k/wCkpP8AmjFXf9CpaV/1O3mT/pKT/mjFXf8AQqWlf9Tt5k/6Sk/5&#xA;oxV3/QqWlf8AU7eZP+kpP+aMVd/0KlpX/U7eZP8ApKT/AJoxV3/QqWlf9Tt5k/6Sk/5oxV3/AEKl&#xA;pX/U7eZP+kpP+aMVd/0KlpX/AFO3mT/pKT/mjFXf9CpaV/1O3mT/AKSk/wCaMVd/0KlpX/U7eZP+&#xA;kpP+aMVd/wBCpaV/1O3mT/pKT/mjFU6tf+ceNPt7eOAeatccRqFDtcKSadz8OKqn/Qv9h/1NGtf8&#xA;j1/5pxVJ/OX5SaL5Y8qat5guvNGs+jplrLccTcL8TIp4J9nq70UfPFXw5NLJNK80rF5ZGLu7GpLM&#xA;akk+5xV9o/8AOGflU6b+Xd9r8qcZtevD6bU+1b2YMSf8lWlxV7P5y8tWvmjypq3l66IEOqWsttzI&#xA;rwZ1ISQDxR6MPlir8zdS0+803UbrTr2Mw3llNJb3MR6pLExR1PyZSMVZX5Jv/UtJLJz8UB5xj/Ib&#xA;r9zfrxVk2KuxViHnxP3lm9Ooda/Iqf44qxTFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F&#xA;XYq7FXYq7FXqOmxmPTrWM9UhjU/QoGKonFWM+dr/ANO0jskPxTnnIP8AIXp97fqxVimm6fealqNr&#xA;p1lGZry9mjt7aIdXllYIij5swGKv0y8m+WrXyv5U0ny9akGHS7WK25gU5sigPIR4u9WPzxVOcVfE&#xA;v/OXv5fNoPn6PzLax003zInqSED4UvIQFmXb+deL79SW8MVeJaPqDafqEVyK8AaSgd0OzYq9LR1d&#xA;FdDyVgCpHQg7jFV2KsW87TWclrFGJUNzFJX0wasFIINadN6Yqw7FXYq7FXYq7FXYq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq7FXYq7FXYqrWkBuLqGAdZXVB/sjTFXqYAAAGwHQYq07qiM7niqgliegA3OKvNN&#xA;Y1BtQ1CW534E0iB7INhir23/AJxC/L5te8/SeZbqOum+W09SMkfC95MCsK7/AMi8n26EL44q+2sV&#xA;dirBfzq/LmDz/wDl/qGiBR+kYx9a0mU0HG7iB4Cp6CQExt7Nir86bi3ntriW3uI2inhdo5YnFGV0&#xA;NGVgehBGKsw8nawJbZrGdqPAOUTE9Y+4/wBj+rFUDr/muWZ2trBikI2ecbM/+qewxVjRJJqeuKtY&#xA;q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FV8UskUiyRsUkU1VlNCD88VTe283a&#xA;1DQNKsyjtIoP4rxOKq2p+bp73TmtRD6LyGkjq1QU8BttXFUjt7ee5uIre3jaWeZ1jiiQVZnc0VVA&#xA;6kk4q/Rb8lfy5g8gfl/p+iFR+kZB9a1aUUPK7lA5io6iMARr7LirOsVdirsVfHX/ADl5+UraTra+&#xA;fNJhppurOI9XRBtFeU+GU06LOBv/AJY33YYq+cVZlNVJBoRUbbEUOKtYq7FXYq7FXYq7FXYq7FXY&#xA;q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq+j/APnEP8pW1bW28+atDXTdJcx6QjjaW8p8&#xA;Uor1WAHb/LO26nFX2LirsVdirsVS/wAw6BpXmHRL3RNWgW506/iaG5hburdwezKd1I3B3GKvzu/N&#xA;j8s9X/LzzdcaHfBpLVqzaZe0+G4tiSFbbbkPsuOx9qYqwzFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq7FXYq7FXYq7FXYqzP8p/yz1f8AMPzdb6HYho7VaTane0+G3tgQGbfbkfsoO59q&#xA;4q/RHy9oGleXtEstE0mBbbTrCJYbaFeyr3J7sx3Yncnc4qmGKuxV2KuxV2KsI/N38q9G/MfyrJpF&#xA;7SC/h5S6VqPGrW89PvMb0Ade49wCFX58+a/KuueVdeu9C1y2a11GzfjIh+yw/ZdG/aRxurDqMVSu&#xA;IRGRRKSIyfiKipA8QDirKbfyZZ3EKzQX5kicVVgg/wCasVVP8Bw/8tjf8AP+asVd/gOH/lsb/gB/&#xA;zVirv8Bw/wDLY3/AD/mrFXf4Dh/5bG/4Af8ANWKu/wABw/8ALY3/AAA/5qxV3+A4f+Wxv+AH/NWK&#xA;u/wHD/y2N/wA/wCasVd/gOH/AJbG/wCAH/NWKu/wHD/y2N/wA/5qxV3+A4f+Wxv+AH/NWKu/wHD/&#xA;AMtjf8AP+asVd/gOH/lsb/gB/wA1Yq7/AAHD/wAtjf8AAD/mrFXf4Dh/5bG/4Af81Yq7/AcP/LY3&#xA;/AD/AJqxV3+A4f8Alsb/AIAf81Yq7/AcP/LY3/AD/mrFXf4Dh/5bG/4Af81Yqp3Hkyzt4WmnvzHE&#xA;gqzFB/zVirFpREJGERJjB+EsKEjxIGKpp5U8q655q1600LQ7ZrrUbx+MaD7Kj9p3b9lEG7MegxV+&#xA;g35RflXo35ceVY9IsqT383GXVdR40a4np94jSpCL2HuSSqzfFXYq7FXYq7FXYq7FXm352fknov5m&#xA;aKiO62PmCxVv0ZqfGoAO5hmA3aJj9Kncdwyr4L81eVNe8q65c6Hrto9nqNq1Hjboy/sujdHRuqsN&#xA;jiqlo+uXemTVjPOBj+8hJ2PuPA4qzzTdVs9Rg9W3epH24zsyn3GKozFXYq7FXYq7FXYq7FXYq7FX&#xA;Yq7FXYq7FXYq7FXYqg9S1Wz06D1bh6E/YjG7MfYYqwPWNcu9TmrIeECn93CDsPc+JxVV8q+VNe81&#xA;a5baHoVo95qN01EjXoq/tO7dERerMdhir70/JP8AJPRfyz0V0R1vvMF8q/pPU+NAQNxDCDusSn6W&#xA;O57BVXpOKuxV2KuxV2KuxV2KuxV2KsI/NT8ovKv5j6N9S1eP0b+AN+jtViUevbsfu5xk/aQmh9jQ&#xA;hV8K/mZ+U/m78vNXNjrlvytZGP1LU4QTbXC9fhYjZqdUbcfLfFWI211cWsyzW8hjlXoy4qy/SPOV&#xA;vNxi1ACGXoJh9g/P+X9WKskR0dQ6MGVtwwNQR8xiq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqtd0RS&#xA;7sFVdyxNAB8zirG9X85W8PKLTwJpehmP2B8v5v1YqxC5uri6maa4kMkrdWbFWXfln+U/m78w9XFj&#xA;odvxtY2H13U5gRbW69fiYDdqdEXc/LfFX3V+Vf5ReVfy40b6lpEfrX84X9I6rKo9e4YffwjB+ygN&#xA;B7mpKrN8VdirsVdirsVdirsVdirsVdirsVS/X/L2ieYdKn0nW7KK/wBOuV4zW0y8lPgR3Vh1DDcH&#xA;cYq+Svza/wCcQ9b0lptW8hs+raaKu+kSEfXIh1pE2wnUeGz9viO+KvnS4t7i2nkt7iJ4Z4mKSxSK&#xA;UdWGxVlNCCMVROn6xqGntW2lIStTEd0P+xOKsnsPO1pJRL2MwN3kT4k+77Q/HFU/tb20uk5W8ySj&#xA;/JIJHzHUYqr4q7FXYq7FXYq7FXYq7FVC6vbS1TlcTJEP8ogE/IdTiqQX/na0jqllGZ27SP8ACn3f&#xA;aP4YqxjUNY1DUGrcykpWoiGyD/YjFUNb29xczx29vE808rBIoo1LuzHYKqipJOKvov8AKX/nEPW9&#xA;WaHVvPjPpOmmjppEZH1yUdaStuIFPhu/b4Tvir610Dy9onl7SoNJ0SyisNOtl4w20K8VHiT3Zj1L&#xA;Hcnc4qmGKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVgv5jfkr+X/AJ/gY63p4j1GlItWtaRXa0FB&#xA;V6ESAfyyBhir5f8AzB/5xC8/aC0l15akTzJpoqRHHSG8RevxQseL+HwMSf5Rirw7UNN1HTbySy1G&#xA;1msryE0ltriNopUPgyOFYfSMVUEd0YMjFWHRgaHFUztfM+tW9ALgyKP2ZQH/ABPxfjiqZQeertf7&#xA;+1R/9Rin6+eKo2Pz1ZH+8tpF/wBUq36+OKqy+dtII3SZfYqv8GxVzedtIA2SZvYKv8WxVRk89WQ/&#xA;u7aRv9Yqv6uWKoKfz1dt/cWqJ/rsX/VwxVLbrzPrVxUG4Man9mIBPxHxfjiqWO7uxZ2LMerE1OKq&#xA;+n6bqOpXkdlp1rNe3kxpFbW8bSyufBUQMx+gYq9x/L7/AJxC8/a80d15lkTy3ppoTHJSa8devwwq&#xA;eKeHxsCP5Tir6g/Ln8lfy/8AIECnRNPEmo0pLq11SW7aooaPQCMH+WMKMVZ1irsVdirsVdirsVdi&#xA;rsVdirsVdirsVdirsVdirsVdirsVSbzL5N8qeaLUWvmHSbXVIQCE+sxK7JXqY3I5ofdSMVeMeav+&#xA;cM/y71IvLoF9eaDM1eMdReW6/wCwlKy/8lcVeUeYf+cM/wAzbAs+kXmn6xCPsKsjW05+aSr6Y/5G&#xA;Yq8/1f8AIb84tKJF15T1B+PU2kYvB1p1tjNirFb3yx5lsW43uk3tqw6ia3ljPSv7SjtiqWYq7FUz&#xA;svLHmW+bjZaTe3THoIbeWQ9K/sqe2Ksq0j8hvzi1UgWvlPUE5dDdxizHWnW5MOKvQPL3/OGf5m35&#xA;V9XvNP0eE/bVpGuZx8kiX0z/AMjMVer+Vf8AnDP8u9NKS6/fXmvTLTlHUWdu3+wiLS/8lcVez+Wv&#xA;JvlTyvam18vaTa6XCQA/1aJUZ6dDI4HNz7sTiqc4q7FXYq7FXYq7FXYq7FXYq7FX/9k=</xapGImg:image>
+               </rdf:li>
+            </rdf:Alt>
+         </xap:Thumbnails>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/">
+         <xapMM:DocumentID>uuid:1B95FEC551E111DEA13AAE68EE5F3A4D</xapMM:DocumentID>
+         <xapMM:InstanceID>uuid:58ad672b-c584-4acf-894c-9cb9832873ef</xapMM:InstanceID>
+         <xapMM:DerivedFrom rdf:parseType="Resource"/>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:xapTPg="http://ns.adobe.com/xap/1.0/t/pg/"
+            xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+            xmlns:xapG="http://ns.adobe.com/xap/1.0/g/">
+         <xapTPg:NPages>1</xapTPg:NPages>
+         <xapTPg:HasVisibleTransparency>True</xapTPg:HasVisibleTransparency>
+         <xapTPg:HasVisibleOverprint>False</xapTPg:HasVisibleOverprint>
+         <xapTPg:MaxPageSize rdf:parseType="Resource">
+            <stDim:w>3.000000</stDim:w>
+            <stDim:h>3.000000</stDim:h>
+            <stDim:unit>Inches</stDim:unit>
+         </xapTPg:MaxPageSize>
+         <xapTPg:PlateNames>
+            <rdf:Seq>
+               <rdf:li>Black</rdf:li>
+            </rdf:Seq>
+         </xapTPg:PlateNames>
+         <xapTPg:SwatchGroups>
+            <rdf:Seq>
+               <rdf:li rdf:parseType="Resource">
+                  <xapG:groupName>Default Swatch Group</xapG:groupName>
+                  <xapG:groupType>0</xapG:groupType>
+               </rdf:li>
+            </rdf:Seq>
+         </xapTPg:SwatchGroups>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/">
+         <illustrator:Type>Document</illustrator:Type>
+      </rdf:Description>
+   </rdf:RDF>
+</x:xmpmeta>
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                           
+<?xpacket end="w"?>\rendstream\rendobj\r2 0 obj\r<</Count 1/Type/Pages/Kids[5 0 R]>>\rendobj\r15 0 obj\r<</Intent 16 0 R/Usage 17 0 R/Name(Layer 1)/Type/OCG>>\rendobj\r23 0 obj\r<</Intent 24 0 R/Usage 25 0 R/Name(Layer 2)/Type/OCG>>\rendobj\r41 0 obj\r<</Intent 42 0 R/Usage 43 0 R/Name(Layer 1)/Type/OCG>>\rendobj\r49 0 obj\r<</Intent 50 0 R/Usage 51 0 R/Name(Layer 2)/Type/OCG>>\rendobj\r67 0 obj\r<</Intent 68 0 R/Usage 69 0 R/Name(Layer 1)/Type/OCG>>\rendobj\r75 0 obj\r<</Intent 76 0 R/Usage 77 0 R/Name(Layer 2)/Type/OCG>>\rendobj\r93 0 obj\r<</Intent 94 0 R/Usage 95 0 R/Name(Layer 1)/Type/OCG>>\rendobj\r100 0 obj\r<</Intent 101 0 R/Usage 102 0 R/Name(Layer 2)/Type/OCG>>\rendobj\r119 0 obj\r<</Intent 120 0 R/Usage 121 0 R/Name(Layer 1)/Type/OCG>>\rendobj\r126 0 obj\r<</Intent 127 0 R/Usage 128 0 R/Name(Layer 2)/Type/OCG>>\rendobj\r180 0 obj\r<</Intent 181 0 R/Usage 182 0 R/Name(Layer 2)/Type/OCG>>\rendobj\r234 0 obj\r<</Intent 235 0 R/Usage 236 0 R/Name(Layer 2)/Type/OCG>>\rendobj\r292 0 obj\r<</Intent 293 0 R/Usage 294 0 R/Name(Layer 2)/Type/OCG>>\rendobj\r350 0 obj\r<</Intent 351 0 R/Usage 352 0 R/Name(Layer 2)/Type/OCG>>\rendobj\r408 0 obj\r<</Intent 409 0 R/Usage 410 0 R/Name(Layer 2)/Type/OCG>>\rendobj\r409 0 obj\r[/View/Design]\rendobj\r410 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r351 0 obj\r[/View/Design]\rendobj\r352 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r293 0 obj\r[/View/Design]\rendobj\r294 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r235 0 obj\r[/View/Design]\rendobj\r236 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r181 0 obj\r[/View/Design]\rendobj\r182 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r127 0 obj\r[/View/Design]\rendobj\r128 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r120 0 obj\r[/View/Design]\rendobj\r121 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r101 0 obj\r[/View/Design]\rendobj\r102 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r94 0 obj\r[/View/Design]\rendobj\r95 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r76 0 obj\r[/View/Design]\rendobj\r77 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r68 0 obj\r[/View/Design]\rendobj\r69 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r50 0 obj\r[/View/Design]\rendobj\r51 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r42 0 obj\r[/View/Design]\rendobj\r43 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r24 0 obj\r[/View/Design]\rendobj\r25 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r16 0 obj\r[/View/Design]\rendobj\r17 0 obj\r<</CreatorInfo<</Subtype/Artwork/Creator(Adobe Illustrator 13.0)>>>>\rendobj\r407 0 obj\r[408 0 R]\rendobj\r5 0 obj\r<</Parent 2 0 R/Contents 452 0 R/BleedBox[0.0 0.0 216.0 216.0]/PieceInfo<</Illustrator 401 0 R>>/ArtBox[16.0 18.25 200.0 202.25]/Group 453 0 R/MediaBox[0.0 0.0 216.0 216.0]/Thumb 457 0 R/TrimBox[0.0 0.0 216.0 216.0]/Resources<</XObject<</Fm0 425 0 R/Fm1 431 0 R/Fm2 441 0 R/Fm3 447 0 R>>/Properties<</MC0 408 0 R>>/ExtGState<</GS0 416 0 R/GS1 448 0 R>>>>/Type/Page/LastModified(D:20090604104953-07'00')>>\rendobj\r452 0 obj\r<</Length 1187/Filter/FlateDecode>>stream\r
+H\89\94WÝnå4\10¾ÏSø\ 5âzl\8f=¾¥\v\­Ð\8a\v\1e bAb\vê®\84ÄÛóÍ8q\9c\9cs\8aPÕ&ãùûæÏ\99>ýôì\9e>>\a÷Ý\87g·¼-ÁE*ö»ê\9f¯¿.¿¸?qj?¾&v\7f,O?þ\1cÜoß\967GvN\8e\828jâ%\ 5r/¯&ÿº¬Y|\8b\8ax®Í­©ùÂrÐú\14÷²\8c\ 3JÕ3\8cìº+Õê\89\9b\1aÙ__\96+óª}5\7fq?péÏËòyù´EH\88n\8aJ\92¯9EW¢\97*m\8a\8c|FÈÙÇ\88D\15H\15\10Ì\8aÀ\88â\93d\8d\8b\82o\92\1c\15Ï\ 5\0\1aÎ\9bK    T\85pó"Ñåâc5áê3Þ\98\ 4\83\81\9dàoPäÙ×\96\1dÁ^Ð\f¬)xÎÙ  \ 2VvD\1eØU\81\ e\fçäIª+ð\9a\1cpP\\8d¾Uä\8d\9b' ¬ìK\89\b\0F²Ó\æ¨Ò %²\1eD¸X\8bx
\8f0ªd*¢dJ¤â5ø\92\93\1e¨mõA¦,\ 5ÊðAµ\93Ü¥\11d\9aøÍ×Pwe!¤\8b\12\81¡\fß 9æ\81\fd\97Þ\80\93h\9h~Cð\19Y\ 3@M\1ehønÉ\95ìS5ó\14\918Õè5\     %\89\88¥©¢ÑÙ7h\10!*\1c¨
+\a3\ 2ßÅzPK\ 3\15Î\e\1d³ñ3\ f\8dTÌh\ eæ\16´\18Mb\12fAPw\19¨2Ù\ 1Ê\974\f4H«\11ó\17t.     í\9b0Cè¾M\1a)\14ív$Öø=j ñ\82aøg±£Xy\1c}±Æ\f5Ï'hF.ÓAïñµ7¹öýßÓ¤\84Ó¤DÌ\15\1aºa\ 6ÐìcL\82KäÑH_\96\82«!\r\8aì\89n?\88ÁB\a\92A_1ITíµ\987ÊãU\ f\7f7t\a&F/°ÀMds>PaD\13ra6û+&\98J\ 1\ro9Þ\90È\88\82\a\a²\1d °\9a³+ÝcI¸EøBì\81\86ãõ\1a\b\ 6\8a9ßË."\v¢Y@\91*\9aáJ\8f,¢y3_É!-z|¦î%\94P0°\1eÀHÝ­\96èJÏ~oÉ!\8d[¦Ü\90w\81dd\ 4ß\1c6ýùRÖ®\8a¸:Ìy\9cZ\ 3\83l\94>SÊ*\8d«\0Ú\98÷FZëlj\83ljk\97Fy¬\85fZÙì+wOjj\90é¬{\ 3\9f\93\ 1\7f<-ç\19èT9%íLÝMRÁ<Ãÿÿó\82ø5\14µ|ÔI\87»\1cdÖ0{/\18S\13\16ú k
+Ãa,m¥8\86ø\ 6%nh*!:»xc\9cË\89/ièÃ\16{A   ÃV¦\ 3-+ʦ\9fà\bWVU½\8b\9bCm¥ß\ eµ\f\ 2íÂCÔªF5M4:DW\bý.ÕÞ¼l\1f\91qp1ÐcÁm_ðE¦Ä&\86OKl\98<\·¢ÛÓç¥\81Ñd\bÀJÁÇt\12Ð\1ch\15\87\ 5\9fÿ\93\84í\ 2C\800Ýõ,P4{\87\ 4\93Ä\9bnm¤[ÛÓ\ f¯Á}øk\86\8eU\ 2yz\az\17x\ fú&ñ\18ú&ð\ eôMâ}èÔ¡SCw 
+X\8fZ@\11±\ 6\85\98Ô\7f¬u\ 3\8f¯"°l\12
+\9dÏ|Dß\ 6¿\ 3?ñ     K\1aíü\8e\vv¹¶³;è\99}B\1dϨ±]\90\1f£Þ$\1e¢Þø\ fQoüG¨7ö\7f N\1dõÝÕØ\16~`ÑåiZø±±´¾ðc0\81cÅB^ëAÚÓVµýDëÞ°}îº+a¿¬1Ù¿½báWf<N®Ú7öÏþ7õ}áWK\9bä«\11:7\84\r\v«\9d\90ý_Q\8c\e\8e×¾DËÄ\gÍu²©\8b((Ýò\19Ï®V}ÁÒ\16¶ç˲¹êä$~²£\17Ì÷\1fñ\8fÙ§å_\ 1\ 6\0\1dï§\\rendstream\rendobj\r453 0 obj\r<</I false/K false/CS/DeviceCMYK/S/Transparency>>\rendobj\r457 0 obj\r<</Length 209/Filter[/ASCII85Decode/FlateDecode]/BitsPerComponent 8/ColorSpace 455 0 R/Width 27/Height 27>>stream\r
+8;Wj7_%"=*$tC/]^3R!p2\5ei:.#<:*2umX&QHWQSX?kZ@O:XR!2NU",:A&.IZ])d
+4sFGTN1#]GN(;N>&A>I\_UN-X/[rs;\^P(tkhZ2Z7Hcmh,559!+mO$N-ilCO;X7ru
+%4su8Hf\-trRT+fp'uERM?YVbeK1tUK;H$F2;_7f40XmgrX\d.MSJ41ioUrN`kD>a
+XoSNdk^<4~>\rendstream\rendobj\r416 0 obj\r<</OPM 1/BM/Normal/CA 1.0/OP false/SMask/None/ca 1.0/AIS false/op false/Type/ExtGState/SA true>>\rendobj\r448 0 obj\r<</OPM 1/BM/Normal/CA 0.5/OP false/SMask/None/ca 0.5/AIS false/op false/Type/ExtGState/SA true>>\rendobj\r425 0 obj\r<</Subtype/Form/Length 129/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]/Group 414 0 R/Resources<</Shading<</Sh0 422 0 R>>/ColorSpace<</CS0 418 0 R>>/ExtGState<</GS0 416 0 R>>>>/BBox[106.997 139.145 150.43 135.867]>>stream\r
+q
+150.43 135.867 -43.433 3.278 re
+W n
+q
+0 g
+1 i 
+/GS0 gs
+43.4326172 0 0 -43.4326172 106.9970703 137.5058594 cm
+BX /Sh0 sh EX Q
+Q
+\rendstream\rendobj\r431 0 obj\r<</Subtype/Form/Length 129/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]/Group 428 0 R/Resources<</Shading<</Sh0 422 0 R>>/ColorSpace<</CS0 418 0 R>>/ExtGState<</GS0 416 0 R>>>>/BBox[106.997 133.854 150.43 130.576]>>stream\r
+q
+150.43 130.576 -43.433 3.278 re
+W n
+q
+0 g
+1 i 
+/GS0 gs
+43.4326172 0 0 -43.4326172 106.9970703 132.2148438 cm
+BX /Sh0 sh EX Q
+Q
+\rendstream\rendobj\r441 0 obj\r<</Subtype/Form/Length 126/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]/Group 434 0 R/Resources<</Shading<</Sh0 437 0 R>>/ColorSpace<</CS0 418 0 R>>/ExtGState<</GS0 416 0 R>>>>/BBox[39.6411 84.9033 88.6143 81.626]>>stream\r
+q
+39.641 84.903 48.973 -3.277 re
+W n
+q
+0 g
+1 i 
+/GS0 gs
+-48.9736328 0 0 48.9736328 88.6142578 83.2646484 cm
+BX /Sh0 sh EX Q
+Q
+\rendstream\rendobj\r447 0 obj\r<</Subtype/Form/Length 126/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]/Group 444 0 R/Resources<</Shading<</Sh0 437 0 R>>/ColorSpace<</CS0 418 0 R>>/ExtGState<</GS0 416 0 R>>>>/BBox[39.6411 90.1943 88.6143 86.917]>>stream\r
+q
+39.641 90.194 48.973 -3.277 re
+W n
+q
+0 g
+1 i 
+/GS0 gs
+-48.9736328 0 0 48.9736328 88.6142578 88.5556641 cm
+BX /Sh0 sh EX Q
+Q
+\rendstream\rendobj\r444 0 obj\r<</I false/K false/S/Transparency/Type/Group>>\rendobj\r418 0 obj\r[/DeviceN[/Black]/DeviceCMYK 419 0 R 420 0 R]\rendobj\r419 0 obj\r<</Length 91/FunctionType 4/Filter/FlateDecode/Domain[0.0 1.0]/Range[0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]>>stream\r
+H\89ª6Ô3\0\ 3\ 5#\ 5C\85¢ü\9c\1c\ 5bD\f\142óRR+\102\ÉeE
\15É\19
+Å¥I\b
+ºèf (4\ 5\ 2Ë\9b\10Pi\ 2\18S!ªåÆ0\95F\ 4\8c4\82[^\90_ P\v\10`\0.§G±\rendstream\rendobj\r420 0 obj\r<</Subtype/NChannel/Process 421 0 R>>\rendobj\r421 0 obj\r<</Components[/Cyan/Magenta/Yellow/Black]/ColorSpace/DeviceCMYK>>\rendobj\r437 0 obj\r<</ColorSpace 418 0 R/AntiAlias false/Coords[0.0 0.0 1.0 0.0]/Function 438 0 R/Extend[true true]/Domain[0.0 1.0]/ShadingType 2>>\rendobj\r438 0 obj\r<</FunctionType 3/Encode[1.0 0.0 0.0 1.0]/Domain[0.0 1.0]/Functions[439 0 R 440 0 R]/Bounds[0.967026]>>\rendobj\r439 0 obj\r<</C0[0.735]/C1[0.0]/FunctionType 2/N 1.01602/Domain[0.0 1.0]>>\rendobj\r440 0 obj\r<</C0[0.735]/C1[0.735]/FunctionType 2/N 1.0/Domain[0.0 1.0]>>\rendobj\r434 0 obj\r<</I false/K false/S/Transparency/Type/Group>>\rendobj\r428 0 obj\r<</I false/K false/S/Transparency/Type/Group>>\rendobj\r422 0 obj\r<</ColorSpace 418 0 R/AntiAlias false/Coords[0.0 0.0 1.0 0.0]/Function 423 0 R/Extend[true true]/Domain[0.0 1.0]/ShadingType 2>>\rendobj\r423 0 obj\r<</FunctionType 3/Encode[1.0 0.0]/Domain[0.0 1.0]/Functions[424 0 R]/Bounds[]>>\rendobj\r424 0 obj\r<</C0[1.0]/C1[0.0]/FunctionType 2/N 1.01602/Domain[0.0 1.0]>>\rendobj\r414 0 obj\r<</I false/K false/S/Transparency/Type/Group>>\rendobj\r455 0 obj\r[/Indexed/DeviceRGB 255 456 0 R]\rendobj\r456 0 obj\r<</Length 428/Filter[/ASCII85Decode/FlateDecode]>>stream\r
+8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
+l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>\rendstream\rendobj\r401 0 obj\r<</Private 402 0 R/LastModified(D:20090604104953-07'00')>>\rendobj\r402 0 obj\r<</RoundtripVersion 13/ContainerVersion 11/CreatorVersion 13/AIMetaData 403 0 R/AIPrivateData1 404 0 R/AIPrivateData2 405 0 R/NumBlock 2/RoundtripStreamType 1>>\rendobj\r403 0 obj\r<</Length 860>>stream\r
+%!PS-Adobe-3.0 \r%%Creator: Adobe Illustrator(R) 13.0\r%%AI8_CreatorVersion: 13.0.2\r%%For: (admin) ()\r%%Title: (Netatalk_Logo.ai)\r%%CreationDate: 6/4/09 10:49 AM\r%%BoundingBox: 1168 738 1352 923\r%%HiResBoundingBox: 1168 738.25 1352 922.25\r%%DocumentProcessColors: Black\r%AI5_FileFormat 9.0\r%AI12_BuildNumber: 434\r%AI3_ColorUsage: Color\r%AI7_ImageSettings: 0\r%%CMYKProcessColor: 1 1 1 1 ([Registration])\r%AI3_TemplateBox: 1260.5 827.5 1260.5 827.5\r%AI3_TileBox: 972 472 1548 1206\r%AI3_DocumentPreview: None\r%AI5_ArtSize: 216 216\r%AI5_RulerUnits: 0\r%AI9_ColorModel: 2\r%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0\r%AI5_TargetResolution: 800\r%AI5_NumLayers: 1\r%AI9_OpenToView: 1107 936 4.86 1509 1080 26 1 0 50 75 0 0 1 0 1 0 1\r%AI5_OpenViewLayers: 7\r%%PageOrigin:0 0\r%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9\r%AI9_Flatten: 1\r%AI12_CMSettings: 00.6\r%%EndComments\r\rendstream\rendobj\r404 0 obj\r<</Length 16856>>stream\r
+%%BoundingBox: 1168 738 1352 923\r%%HiResBoundingBox: 1168 738.25 1352 922.25\r%AI7_Thumbnail: 128 128 8\r%%BeginData: 16714 Hex Bytes\r%0000330000660000990000CC0033000033330033660033990033CC0033FF\r%0066000066330066660066990066CC0066FF009900009933009966009999\r%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66\r%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333\r%3333663333993333CC3333FF3366003366333366663366993366CC3366FF\r%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99\r%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033\r%6600666600996600CC6600FF6633006633336633666633996633CC6633FF\r%6666006666336666666666996666CC6666FF669900669933669966669999\r%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33\r%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF\r%9933009933339933669933999933CC9933FF996600996633996666996699\r%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33\r%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF\r%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399\r%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933\r%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF\r%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC\r%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699\r%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33\r%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100\r%000011111111220000002200000022222222440000004400000044444444\r%550000005500000055555555770000007700000077777777880000008800\r%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB\r%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF\r%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF\r%524C45FD35FFA87D52522727FD09F8272752527D7DA8A8FD64FFA87D2727\r%FD19F8527DA8A8FD5CFF7D52FD21F827277DA8FD56FF7D52FD28F8277DA8\r%FD50FFA852FD2DF82752A8FD4CFF7D27FD14F827F827F8272727F827F827\r%FD13F8277DFD48FF7D27FD0FF8FD04275227522752275227522752275227\r%5227522727F827FD0FF87DFD44FF7DFD0FF8FD042752FD132752FD0627FD\r%0DF8277DFD40FFA827FD0BF8272752275227522752275227522752275227\r%522752275227522752275227522752275227522727F827FD0AF827A8FD3D\r%FF52FD0CF827275227272752272727522727275227272752272727522727\r%2752272727522727275227272752FD0427FD0BF852A8FD39FF7DFD0BF827\r%275227522752275227522752275227522752275227522752275227522752\r%275227522752275227522752275227522727FD09F8277DFD36FFA852FD0A\r%F82752FD2F27522727FD0AF827FD34FF7D27FD09F8272752275227522752\r%275227522752275227522752275227522752275227522752275227522752\r%275227522752275227522752275227522727FD09F8A8FD31FF52FD0AF852\r%272727522727275227272752272727522727275227272752272727522727\r%27522727275227272752272727522727275227272752272727522727FD09\r%F87DFD2FFF27FD08F8272752275227522752275227522752275227522752\r%275227522752275227522752275227522752275227522752275227522752\r%275227522752275227522752FD09F852FD2DFF27FD08F8272752FD3E27FD\r%09F827A8FD2AFFFD09F85227522752275227522752275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%52275227522752275227522752275227522727FD07F827A8FD27FFA8FD09\r%F85227272752272727522727275227272752272727522727275227272752\r%272727522727275227272752272727522727275227272752272727522727\r%275227272752272727522727FD08F8A8FD25FFA8FD07F827275227522752\r%275227272752275227522752275227522752275227522752275227522752\r%275227522752275227522752275227522752275227522752275227522752\r%2752275227522727FD08F8A8FD23FFA8FD08F82752FD0727F8F8FD4127FD\r%08F8A8FD22FFFD07F82727522752275227522727F8272752275227522752\r%275227522752275227522752275227522752275227522752275227522752\r%27522752275227522752275227522752272727522752275227522752FD07\r%F827A8FD20FFFD07F8FD0427522727275227F8F8F8272727522727275227\r%272752272727522727275227272752272727522727275227272752272727\r%5227272752272727522727275227272752F8F8F8522727275227272752FD\r%07F827A8FD1EFF27FD06F82727522752275227522727F8F8F85227522752\r%275227522752275227522752275227522752275227522752275227522752\r%27522752275227522752275227522752275227522727F8F8F85227522752\r%27522752FD07F827FD1DFF27FD06F8FD08275227FD05F8FD3927FD04F8FD\r%082752FD07F852FD1BFF7DFD06F82727522752275227522727FD05F85227\r%522752275227522752275227522752275227522752275227522752275227\r%52275227522752275227522752275227522752275227522752FD05F82727\r%52275227522752FD07F87DFD19FF7DFD07F8275227272752FD0427FD05F8\r%272752272727522727275227272752272727522727275227272752272727\r%52272727522727275227272752272727522727275227272752FD0427FD05\r%F8272752272727522727FD07F8A8FD18FF27FD05F8272752275227522752\r%2727FD06F827522752275227522752275227522752275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%522752FD07F8272752275227522727FD07F8FD17FF52FD06F82752FD0827\r%FD07F8FD3B27FD07F8FD0927FD06F827FD15FFA8FD06F827522752275227\r%522752FD07F8272752275227522752275227522752275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%522752275227FD08F8522752275227522727FD06F87DFD14FFFD07F82727\r%52272727522727FD09F85227272752272727522727275227272752272727\r%522727275227272752272727522727275227272752272727522727275227\r%272752272727522727FD09F85227272752FD0427FD06F8A8FD12FF52FD06\r%F852275227522752275227FD08F827275227522752275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%5227522752275227522752275227FD0AF8522752275227522727FD05F852\r%FD11FF7DFD06F8FD0B27FD09F8FD3B27FD0BF852FD0627FD07F8A8FD10FF\r%27FD05F82727522752275227522727FD09F8272752275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%522752275227522752275227522752275227FD0AF8272752275227522752\r%27FD05F827FD0FFF7DFD06F827272752272727522727FD0BF82727522727\r%275227272752272727522727275227272752272727522727275227272752\r%2727275227272752272727522727275227272752FD0427FD0BF8FD042752\r%FD0427FD06F87DFD0EFF27FD05F82752275227522752275227FD0AF82727\r%522752275227522752275227522752275227522752275227522752275227\r%52275227522752275227522752275227522752275227522752275227FD0C\r%F8522752275227522727FD05F827FD0DFF52FD06F8FD0B27FD0BF852FD3A\r%27FD0DF852FD0727FD06F87DFD0CFF27FD05F82727522752275227522752\r%FD0BF8272752275227522752275227522752275227522752275227522752\r%275227522752275227522752275227522752275227522752275227522752\r%275227FD0CF827275227522752275227FD05F827FD0BFF7DFD05F8FD0427\r%52272727522727FD0DF85227272752272727522727275227272752272727\r%522727275227272752272727522727275227272752272727522727275227\r%272752272727522727FD0DF8FD04275227272752FD06F87DFD0AFF27FD05\r%F8275227522752275227522727FD0BF82727522752275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%52275227522752275227522752275227FD0EF8522752275227522727FD05\r%F827FD09FF7DFD06F8FD0B27FD0DF8FD3A27FD0FF8FD0A27FD05F8A8FD08\r%FF52FD05F8272752275227522752275227FD0CF827275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%52275227522752275227522752275227522752FD0FF85227522752275227\r%5227FD05F852FD08FFFD06F82727275227272752FD0427FD0DF827275227\r%272752272727522727275227272752272727522727275227272752272727\r%5227272752272727522727275227272752272727522727FD10F827522727\r%275227272752FD06F8A8FD06FF7DFD06F85227272752272727522752FD0E\r%F8275227522727275227272752272727522727275227522752FD0B275227\r%522752275227522752275227522752275227522727FD0FF8272752275227\r%5227522727FD05F87DFD06FF52FD05F8FD05522752525227525227F827F8\r%27F827F827F827F827F827525227525252275252522752525227FD055227\r%522727FD07F827F827F8FD04275227272752FD0C27FD11F8FD0A27FD05F8\r%27FD06FFFD05F852FD29FFA87DFFFFFF7D7DFFFF27FF52A8527D527DFD0E\r%52275227522752FD0427FD11F82727522752275227522752FD05F827A8FD\r%04FF7DFD05F87DFD29FF7D7DFFFFFF7D52FFFF27FF7D7D52527D527DFD06\r%5227522752275252522752FD0627FD13F827275227272752FD0427FD05F8\r%7DFD04FF52FD05F8FD0D52FD1027FD0C522727F8272727F8272727F827F8\r%27F827F827F827F827F827F827F827F8F8F827275227522752275227FD12\r%F8272752275227522752275227FD05F852FD04FFFD05F827FD047D527D7D\r%7D52FD057DFD0F527D7D7D527D7D7D527D7D7D5252272752525227F87D52\r%2752FD0727F827F827F827F827F827F827F8FD0927FD13F852FD0A27FD05\r%F827FFFFFFA8FD05F87DFD2AFFA852FFFFFF7D7DFFFF27FF7DA8527D7D7D\r%527D527DFD0652275227522727275227522727F827F827FD0FF827275227\r%522752275227522727FD05F8A8FFFF7DFD05F87DA8FFA8A8A8FFA8A8A8FF\r%A8A8A8FFFD13A8FFA8FFFD05A8FF5252A8A8A85227FFA827A8527DFD0552\r%275227522752FD0827F827F8272727F827FD12F827522727275227272752\r%272727FD05F87DFFFF52FD04F827275227522752275227522752275227FD\r%12F827275227FD2AF827FD15F827275227522752275227522752FD05F852\r%FFFF27FD05F8FD0F27FD13F827FD42F8FD0D27FD06F8FFFFFD05F8272752\r%2752275227522752275227522727F8F8F827F8F8F827FD07F827FD07F827\r%FD08F8527D527D527D527D27FD06F827F8F8F827F8F8F827FD07F827F8F8\r%F827FD07F827FD08F82752275227522752275227522752FD05F827FFA8FD\r%06F852277DA8FFA8FF522727A8A8FFA8FF27F8F8FD08A8FF27F8FD0BA8FF\r%27FD06F8FD08FF52F8F8F8FD0CA852F8F827FFFD07A827F8F8F827FD05A8\r%7DFD05F8FD04A8FF7D2727FD04A8FF7D27FD05F8A87DFD05F82727277DFD\r%04FFA82752A8FD04FF52F827FD09FF52F8FD0CFF52FD05F87DFD08FF27F8\r%F827FD0CFF52F8F852FD08FF27F8F8F827FD05FF7DFD04F827FD06FF2752\r%FD05FF7D27FD05F87D52FD05F82727F87DFD05FF5227A8FD04FF52F8F8FD\r%09FF27F8A8FD0BFF27FD05F87DFD08FF27F8F8F8FD0CFF7DF8F852FD08FF\r%52F8F8F827A8FD04FF7DFD05F8FD05FF7D277DFD05FF2727FD05F85252FD\r%05F85227277DFD05FF7D27A8FD04FF522727FD09FF52F8FD0CFF7DFD04F8\r%27FD09FF27F8F827FD0CFF7DF8F8A8FD08FF7DF8F8F827FD05FF7DFD04F8\r%27FD05FFA827FD05FF7D272727FD04F85227FD04F8FD04277DFD05FFA827\r%A8FD04FF5227F8FD05FFA852527D27F8527D52A8FD05FF7D527D27FD04F8\r%52FD09FF27F8F8F852527DA8FD05FF7D7D5227F8F8A8FD08FFA8F8F8F827\r%FD05FF7DFD04F827FD05FF7D52FD05FF522752FD05F82727FD05F8522727\r%7DFD06FF52A8FD04FF522727A8FD04FF7DFD08F87DFD05FFFD08F87DFD09\r%FF27FD06F87DFD05FF27FD05F8FD09FFA8F8F8F827FD05FF7DFD04F852FD\r%05FFA87DFD05FF27522727FD04F827FD05F8FD04277DFD06FF52A8FD04FF\r%272727FD05FF7DFD08F8A8FD05FF27FD07F8FD05FF7DFFFFFFA827FD06F8\r%7DFD05FFFD05F827A8FFFFFFA8FD05FFF8F8F827FD05FF7DF8F8F82727FD\r%05FFA8A8FD04FF7D272727FD05F827FD06F85227277DFD06FFA8A8FD04FF\r%522752FD05FF7DFD08F8A8FD05FF27FD06F852FD04FFA8A8FD04FF27FD06\r%F8A8FD05FF27FD04F827FD05FFA8FD04FF52F8F827FD05FF7DF8F8272752\r%FD0BFF7D27522727FD0AF8272752277DFD06FFA8A8FD04FF522727FD05FF\r%A87D527DFD05F8A8FD05FF27FD06F87DFD04FF7D7DFD04FF27FD06F87DFD\r%05FF27FD04F852FD04FF7D7DFD04FF52F8F827FD05FF7DF8F8272727FD0A\r%FFA8FD0427FD0BF8275227277DFD0CFF522752FD09FF27FD04F87DFD05FF\r%27FD06F8FD05FF27A8FD04FFFD07F87DFD05FF27FD04F852FD04FF7D52FD\r%04FF7DF8F827FD05FF7DF8F8522752FD0AFF7D2727522727FD0AF8272727\r%F87DFD0CFF522727FD09FFFD05F8A8FD04FFA827FD05F827FD04FFA8F8A8\r%FFFFFFA8FD07F87DFD05FFFD05F87DFD04FF5252FD04FF7DF8F827A8FD04\r%FF7DF8FD0427FD0AFF7D27272752FD0BF8275227277DFD0CFF522752FD09\r%FF27FD04F87DFD05FF27FD05F87DFD04FF7DF8FD05FFFD07F87DFD05FF27\r%FD04F8A8FD04FF5227FD05FFF8F827FD05FF7DF827522752FD0AFFA85227\r%522727FD0AF8FD04277DFD0CFF522727FD05FFA8A87DA8FD05F8A8FD05FF\r%27FD05F8A8FD04FF2727FD04FFA8FD07F87DFD05FFFD05F8FD05FF2727FD\r%04FFA827F827FD05FF7DF8FD0427FD0BFF5227275227FD0AF8275227277D\r%FD0CFF522752FD05FFA8FD08F8A8FD05FF27FD04F827FD05FFA8A8FD05FF\r%FD07F87DFD05FF27F8F8F827FD05FF5227FD05FF27F827FD05FF7DF8F827\r%2752FD0BFF7D27522727FD0AF8FD04277DFD04FF7DFD07FF272727FD05FF\r%7DFD08F8A8FD05FF27FD04F852FD0BFFA8FD07F87DFD05FFFD04F827FD05\r%FFA8FD06FF52F827FD05FF7DF8F8F82727FD05FFA8FD05FFA8272727FD06\r%F827FD05F85227277DFD04FF7DA8FD06FF522752FD05FFA8FD08F8A8FD05\r%FF27FD04F8A8FD0CFFFD07F8A8FD05FF27F8F8F852FD0CFF52F827FD05FF\r%7DFD04F852FD05FFA8A8FD05FF52522727FD05F827FD04F8272752277DFD\r%04FF52A8FD06FF522727FD05FF7DFD08F8A8FD05FF27F8F8F827FD0CFFA8\r%FD07F87DFD05FF27F8F8F852FD0CFF7DF827FD05FF7DFD04F827FD05FF7D\r%7DFD05FF7D2727FD05F82752FD05F85227277DFD04FF5252FD06FF522727\r%FD06FF527D7D52FD04F87DFD05FF27F8F8F852FD05FF7D27A8FD04FFA8FD\r%07F87DFD05FF27F8F8F87DFD0CFFA8F8F8FD05FFA87D527DF827FD05FFA8\r%52FD05FF7D272727FD04F82727FD05F82727F87DFD04FF5227A8FD05FF52\r%27F8FD09FFA8FD04F8A8FD04FFA827F8F8F8A8FD05FF27F8A8FD04FFA8FD\r%07F87DFD05FFFD04F87DFD05FF5227A8FD05FFF827A8FFFFFFA8FD04FFF8\r%F8FD05FF7D52A8FD05FF2727FD05F8527DFD05F85227277DFD04FF7D27A8\r%FD05FF52F827FD09FFA8FD04F87DFD05FF27F8F827FD06FFF827A8FD04FF\r%A8FD07F87DFD05FF27F8F8F8FD06FF27F8A8FD05FF27F8FD09FFF8F8FD05\r%FFA827A8FD05FF7D27FD05F8527DFD05F82727277DFD04FF522752FD05FF\r%52F8F8FD09FF7DFD04F8A8FD05FF27F8F827FFA8FFA8FF7DF8F8FFFFFFA8\r%FF7DFD07F87DFD05FFFD04F8A8FD05FFF8F87DFD05FF2727FD08FFA8F8F8\r%FD05FFA8277DFD05FF7D27FD05F87DA8FD05F82727277DFD04FF7D2752FD\r%05FF52F8F8A8FD08FFA8FD04F87DFD05FF27FD04F827F827FD05F827F827\r%F827FD07F87DFD05FF27F8F827FD05FFA8F8F87DFD05FF52F8FD09FFF827\r%A8FD04FFA8277DFD05FFA827FD05F8A8A8FD06F852272727522752FD0527\r%52275227FD55F82752275227272752275227522727FD05F8FFFF27FD04F8\r%2727522752275227522752275227522727FD55F827275227272752272727\r%522727FD05F827FFFF52FD05F8FD04275227272752272727522727FD0DF8\r%27F8F8F827F8F8F827F8F8F827F8F8F827F827F82727F8F8272727F82727\r%27F8272727F8272727F8272727F8272727F8272727F8272727F8272727F8\r%272727F8272727F8272727F82727FD0C52FD05F827FFFF7DFD05F8275227\r%5227522752275227522752FD07275227522752275227FD08527D527D527D\r%5252527DA852FFFF52A8FFFFFF52A8FD38FFA8FD05F87DFFFFA8FD05F8FD\r%0E2752FD0B2752275227FD0C527D527D52FF52FFFF52A8FFFFFF27FD39FF\r%52FD05F8A8FFFFFF27FD05F8522752275227522752275227522727F827F8\r%27F827F827F827F827F827F827F827F827F827F827F827F827F8FD0527F8\r%FD3227FD04527D5252527D52525227FD05F8FD04FF27FD05F82752272727\r%5227272752FD0427F8F8F827F8F8F827F827F827F827F827F827F827F827\r%F827F827F827F827F852F852272727522752F82727522752275227522752\r%275227522752275227522752275227522752275227522752275227522752\r%27522752527D527D527D527D527D5252FD05F852FD04FF7DFD05F8272752\r%27522752275227522752FD05275227522752275227FD08527D527D527D52\r%FD057DA87DFFFF52A8FFFFFF52FD38FF7DFD05F87DFD04FFA8FD06F8FD0A\r%27522727F8FD0C275227522752275227FD08527D52A827FFFF527DFFA8FF\r%27A8FFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF\r%A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFFF52FD05\r%F8A8FD05FF27FD05F827522752275227522752275227FD04F827F8F8F827\r%F8F8F827F8F8F827F8F8F827F8F8F827F8F8F827F8F8F827F827F827F827\r%F827F827F827F827F827F827F827F827F827F827F827F827F827F827F827\r%F827F827F827F827F827F827F827F827F82727522752275227522752FD05\r%F852FD06FF7DFD05F827275227272752272727522727FD57F8FD0927FD06\r%F87DFD06FFA827FD05F8522752275227522752275227FD56F82727522752\r%2752275227FD06F8FD08FF27FD05F8FD0C27FD56F82752FD0827FD05F852\r%FD08FFA8FD05F827275227522752275227522727FD55F852275227522752\r%2752FD06F8A8FD09FF27FD05F82727522727275227272752FD56F8275227\r%272752272727FD05F827FD0AFF7DFD06F85227522752275227522727FD55\r%F8522752275227522727FD05F8A8FD0BFFFD06F8FD0727522727FD55F8FD\r%0927FD05F827A8FD0BFF7DFD05F82727522752275227FD58F82727522752\r%2752FD06F87DFD0DFF27FD05F82727522727FD5DF8272727FD07F8FD0EFF\r%7DFD06F8522752FD67F87DFD0FFF27FD06F827FD67F827FD10FFA8FD6EF8\r%A8FD11FF52FD6CF852FD12FFA827FD6BF8FD14FF7DFD6AF87DFD15FF52FD\r%68F852FD17FFFD67F827A8FD17FFA8FD66F87DFD19FF7DFD64F852FD1BFF\r%52FD62F852FD1DFF27FD60F827FD1FFF27FD07F852275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%5227522752275227522727FD07F8FD20FFA8FD08F8FD4F27FD07F8A8FD21\r%FFA827FD07F8522752275227522752275227522752275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%5227522752275227522752275227522752275227522727FD07F8FD24FF7D\r%FD08F8FD0427522727275227272752272727522727275227272752272727\r%522727275227272752272727522727275227272752272727522727275227\r%27275227272752272727522727275227FD08F8A8FD25FFA827FD07F82727\r%522752275227522752275227522752275227522752275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%52275227522752275227FD08F8FD28FFA827FD07F8FD4527FD09F8A8FD2A\r%FF27FD07F827275227522752275227522752275227522752275227522752\r%275227522752275227522752275227522752275227522752275227522752\r%275227522752275227522727FD08F827FD2DFF52FD09F8FD042752272727\r%522727275227272752272727522727275227272752272727522727275227\r%27275227272752272727522727275227272752272727522727FD08F827FD\r%2FFF7DFD09F8272752275227522752275227522752275227522752275227\r%522752275227522752275227522752275227522752275227522752275227\r%52275227522727FD08F87DFD31FFA8FD0AF8FD3827FD0AF87DFD34FF52FD\r%0AF827275227522752275227522752275227522752275227522752275227\r%52275227522752275227522752275227522752275227522727FD09F852FD\r%37FF7DFD0AF8FD0427522727275227272752272727522727275227272752\r%2727275227272752272727522727275227272752FD0427FD0BF87DFD3AFF\r%52FD0BF82727522752275227522752275227522752275227522752275227\r%522752275227522752275227522752275227FD0BF852FD3DFFA827FD0CF8\r%FD042752FD2027FD0DF8277DFD40FF7D27FD0DF827275227522752275227\r%52275227522752275227522752275227522752FD0427FD0CF8277DFD44FF\r%7DFD11F8FD042752272727522727275227522752FD0627FD0FF82752FD48\r%FF7D27FD11F827F8FD0B27F827FD12F827A8FD4CFFA827FD2EF8527DFD50\r%FFA87D2727FD27F8527DFD56FFA87D2727FD21F8527DFD5DFFA87D522727\r%FD17F827527DA8FD64FFA8A87D522727FD0BF8272752527D7DFD34FFFF\r%%EndData\r\rendstream\rendobj\r405 0 obj\r<</Length 23765>>stream\r
+%AI12_CompressedDatax\9cì}i_úÈÒèý\ 2|\aP\91\1d\92\10\12\82\8a\10   ¢¸áΦ"«\ 1fÎÿyñ|ö[ÝÙC\12Ârî\9cçÞû\9b\19G;\9dªêêªêªê®´ßWoÄòÝI»\17KÆ     ¯Çï/\88½Ö|"f¼¸Õ{6\1c.fs\115\ 5oB^\12zA§üYú]îxß\13gýÉ8\83\1fÅ)x( ·\83­î¨?\ ey\83!h¹íÏ\87=h»ìÍ[óÖpð^\9b|Mâ­~HÁ\a\0\8a­9ta\12t\82à¼$\91¡9oþ\ 2\9eó\93ŸÛ\1f\7fñ\93\7f\ 1\ e\92I{Ùd\1a\90¥(/G%¡C¥\7fÓ\9b\8aS)¥#\ 5¿Cß⤳\18õÆóº8éôf³Âd8\11g\19/?lu\ 6\1e\18Uê]è\ f{0\80QkîåÐPóg$õÎ/úÃîåbÔîÁÈè$\8d\9a\93ïøí»Yë\vèÆ¿£föýl\ 4-\8dÞ|\ eä\0lÄ®ÂE³ªG      $Êÿ\ 4\9foz_}Ì`àÁkH\82\eM\87À\ fi4\14CÄSÞ4ÅÂOý\1fr_ \18÷ãXÊKÃ\7fd\8a\ 6þP\ 4#=×\86Üû«ßû;ã½\9c\8c{ÒXóâ¼Ñÿ/ \9e"\19ô\9fÔz³\18öÄ»q\7f.\11\9f?ã¤\91^Lº½!ôUß\15\86-<@ü\ f©ý\94:ܶįÞ\1c¦f2\̱\80¤     ù\11p²ÖúÓC\9c'%\ 4WÓÞøvr\8fé#I\82õrIÆKÇÓ\f\8c\ 6\8bC\9aðR\f\ 6\9f"¼lJE\86ÿ\93 "\18\b\82\ 2\9a\ 5Æ×a*®ÄþW\7f\9c\91    cßËb¿«M\ f0,-ýÀ´ÇÓºÿ8å?\89H\18ï|Þ\eËD\83X\14.tÓLÄ\81\7fþÒ¸[\98\8c\10¿gHvanÇ0ñÃÉ\97ôLý\1d?\81·\17S\89xü÷;LM]ì\8f\11HÏ%~\92\ f\17ð¨,N\16Ó³ñçÄ\13\94ô²Þ\9a\7f\83ÜöÆÝ\19(\99Ô&ýé\95Þ\80ÖZÿ¯\9eÔ\ 6º6\r9»\15[\1d@ë½jÿô:sxYnÐ~k,úóÞj@\8d\ eâ\92èåÅÅìÛ{;\99\f\8c\8fT2åfÜ\8aúÿgà¨ã\17ÆWc\89ÓË\98ä\ efL \18ÿqX ·=\ 6\9f\f½Ð\1a\ eû_bkúÝïX!°x®b\92\9e­\81\fT\ìiïã?\95ÿ»\10Ë?£ödØ\9f\8d4iÔµÔ[â¼ß\19ö\1a\7ffóÞh5´bï\13Ö!\1dÛpkiüWo8\99ê\88T[Zã®÷¡%N\9d@£iúì\8f» !X\9f56NFS´\86z\eß­i\ f\93;ÿ\16\86\v1\1e¶Æ-Ñ\8bÛU\90Èü\80ü\82=3\9a$©M\ 5\9az\aè7}±\98\87òòc\9da,\8b­n\1fl*¸\10wãqkÔëz¿ä&XéB\1eËV0ç\0¦ëyö\1c{\ 4A(    E¡ ðB^à\84´À
+\8c\90\12h!)P\ 2)\10%¡T*\15K\85\12\97¸RºÄ\96\98RªD\97\92%ªD\96\88¢P,\15\8bÅB\91\8b\1í)²E¦\98*ÒÅd\91*\92E¢ \14J\85b¡Pà\vù\ 2WH\17Ø\ 2SH\15èB²@\15È\ 2Á\v|\89\ 5\9eçó<ǧy\96\14OóI\9eâI\9eðä\85|)_Ì\17ò|>\9fçòé<\9bgò©<\9dOæ©<\99'8\81+qE®Àñ\\9eã¸4Çr\f\97âh.ÉQ\1cÉ\11i!]J\17Ó\854\9fΧ¹tÚ\93\1f&\9dJÓéd\9aJ\93i\82\15Ø\12[d\v,ÏæY\ e\1e³,æX\9a\14\ 4#0%¦È\14\18\9eÉ3\1c\93fX\86aR\fÍ$\19\8a!=\f\91\12R¥T1UHñ©|\8aK¥Sl\8aI¥Rt
+|¬\14,Ô´@\97è"] y:Ost\9afi\86NÑ4xLI\9a¢I\9aH
+ÉR²\98,$ùdÞ\93ä\92é$\9bd\92)x\9eLRI2IP\ 2\8aT\81â©<ÅQàçP\f\95¢h*IQ\1485¤@Â|\90E²@òd\9eäÈ4É\92\f\99"i2é!)\12\9c\a\ 2¦\93\80\19!x\ 2Ø\ 6\9e\ 3\vÿ\0ñ\ 4 '\0\ 2x!Y\ fáõ¿ó"È\ 6\14Ð\8aZ\1a\1eÿ»®\85\9fy\90W@sq:E0^µ\8b±\11zñEU\92\15Yu)¾´\95ôÒÿ/\v/\88¯'\9dþ÷
+ïzâK\e\ 4&N1)ID8&Î\12ɤ*8ËOv$@\16\8e¡\95Õt|\81\93\9e \9f\7fþgØ\9by\12Õñäï1þÃ\9bñ\ 4\9fa½i-\86ó×\907q      âè\8dz\12\8d>Ä!=¥\vá½ò\10²»?\80ßn<\8aë_õ(\ 1\0á}ü\ 3\7f\9cÃ/?Ðô·\97ö^x\9f_        o\17Z\1fo<(æyìz\12Ò²päñ&\0\1f\13\b#ÒÈ[9Æzk\bÞw\ f\13Qo{ì"*DÒ̳\14gÕ;\9e:¯"Q`­ÃÁ\1a\80Ó³mi\f¸Ã&SE\12Ò#É{@`þ\97Ü\f\80L\8d6ÀeZ\95à\ f\82ë\16\88]Bù\ef\13ýÕï n´Ä?Òß\8f\17µK\bò,\1f\1ey\83ÿ\1a\rÇð8\ 6\1e©Øo/æ=\88<¢¨k^\14[ÿg@ì\0¾®Wç\eÂz±7\96úPÞÄ\19pF}\8a~Ìÿ _\b=\r\1e\8e\7fµÄÙ\11èG\ 3 C¬dèúWk¸Pú¢ö\99M?dê¥n2%3Ã_ÿC¹Óîãô\vé\829ÀD\b|/1\eVsHß;úÏ\8eq<\19Û\91¬\1fßpÒ\19ôºnƦôÜÑôo9zÒqô®æµßj\ f{n\ 4\7fåLþORôÌ_®U\1d\87¥\18\r¯³\98Í'£\7fÖ\92ýûä03k!·\ 5­y`:Ü\8aã¿]/\80\96ÿ RþoÐÒÙçßÿÁ«ñ?¬\ 6³a¿ó?Ý\16Ç\18. |¸éµ\86\ eÓëjjÿi»+oG­\18Ë\1f7cùóO\8f\85d\92é䪡üÝïοÝ\fGîø\ f\ f)M¯\1aÐw¯ÿõíÆ\84«=ÿá!y\13üdâ0 öd\ e^@­÷9\97¶ÈÜ\f\9dÿ\80\15\1f\9bºÆd!vzx\1fø\1f_òaaú§I\18õæ­.x@ÛÒÁmIÇ~WN9¸\91.]g\83\ 4£Ü\87÷SÚ~í\89ÞÉb>ì\8f{ÞÙ\\9c\f\14AcS2¥¦Îbk6ï\89±¿z\9dùDô¶[ÃÖ¸cÖ\10Ó+\9da\7fêíL\90\13ù/¯Øû\ 2\8d\95\91\10+(\9a÷þµ\82ö©Ø\9bõÄ¿zÞÉ_=q\8ar6\16 I¯Â\bo\7f6A'\ 1¼m´\8f\8b÷c1ô\14¡\98«ü\19ç½è;½7x ýÿÂ\19.¯¶ñî\b~0\86\18\14¨÷~I[7¨+J·§UfrÞ\968oOZb\17X2\ 4\16\129hM\12\ 6\16ó)\80r&\84\92){è$PÒë¹íÛV\ 5meW\95hJ×k.¶Æ³i\v¤½ó\a\10÷»ÞYÿ¿z.Ù !_ÙU7&Ò0\11uE\1cnAr¼¥n\7fÞj÷\87ýù\1f\14\99&½jò\ e\9f\eðÖZã¯Eë«ç­O¦ÊÔ\ 5\9f/zÝþb¤ã:ÊçÞ\8dû\1dÐ5Eÿ¬       ª\84b\92æ^]ÊÅ´j%\19eÒ§­n×$^£Öl`\1aèl:\99\9b\86}Em\95éèNûq\99\9br\v0OTMCþÌ\9b_Ì'ªpõ\96Ä\9aóN[S \7fÖ\1f-\86-MàHÛ\891òx\90?«·D\18\9f\95\1e:­ñÙ\1föª½?¦\11\19º¢\9dS`ÙLC¨i\85¡ccÑ\ 6Æ
+\13\e
+¸õ¢\80@CO+\890t}øîw¾ÍÔ\1e!":\13±Ûë.O£7q9\99\e\1e\93zN\8e'\9a}òöÇØ\18Nfx¿ØAÌtòEyaÂ\1cdJ¯\ 5¸o\ 1ÙÜ\82lsoô6WoØqWI\ 4\12÷\92\r\16]o\17¥ÞÊv
\1e\97\f¥É"\19¬\98ôR\r\19stt\ 1½\84UÓü\92Q\8d\86Ã\b\96û^ÉëEC¿\82­æªô²\ 3[õ¼\92:»f\96Ô}]nIo­f×
+á3ì>\99¬UBs)\13 ¶Ã\1e\ 6d\10%<d}¿Ù|\18ïJ\10±\f÷d]\ f:\83G¯Éý5¿ÄÍ;Óî\b\1e\ fÇ®\89\9av]\ 3\97\92\edZa¿¾ãt*Æûèàa|\b¾¹»\9eó\89²às´sOQ\8b\14åÜW\8a\10TcµÜµ\83úþ=ùü\9cõ櫺}\9bº-ñôgÒ\ 6\9eÎú_ã\96Á×±ì\88§¶-G\b+;bkê¢_kÖîÏG­©sW©\8f¸ì\95-õî\fÅxg2\ 6ó;G+§\ 3©¨§j¦Ûè\f«C_±\e\9f\88HµW0
+uü\ 4Sö=\11ÿ˸\1e\9b\15A\ fËb\12\11V pØ\9aÆ¿]öûË\9e¶é×h\10\87\90\ 1\9cawú\83_\90\14H\9bM7ïÀ\94ÍÑ¡e\99\16]êf©+¨4²åº4\86-éSP\90þøs²¢\9b¨Ûª^Ñ\15û1í\968s`.î\b,ëuA\9btöÁEgÕD¸è«3\12.zëÍ\ 4cÛ}Ô\12\a3#Õ.:«T»è«£ÚEo\93q[\9a\93Ïñ<Þ\1dNÅÏÉØIq§³xÇì5Úô\ 3ë\87\82Ç1tÕ­¿K=ÿ5\8d\8b\82×w«\9e_nÌ\10ô\93­\90!¨uè'\85ãö\10Å®83j/iÅqÜM    \98g3{Ì\9dQ\\89¦;£?N¶Oë8\99\7f÷D\a\86Ã\9a#\99\v{´¨\8f¼\8cËrCÚ.\89:£Àr¶½ôù 8B`MºÞö\1foQìÿ\85¨u´Vð¾æv8,¸\ 6ód·Üö\f:¼ÌHÔ ÇÌ®,)Z÷\f´Y®`ÈsZµ4\88\97\ fèó×R\0fî5ë´\86=\ 5ÖÊ~\ eK\91Ôi:ìüq\10Pܧ3\9e\14úÌ!¾S2;¶\96~\86\8e\14­è\83­ëª\15CT¬£\15É\92\ 13L\89e\9f\19IJò¨\92Ö\86kØû«7tТ\19¸D(\1cp´~ãÞ\17¬\82\7f9\8d\e\99RpÖÆÎ}\86d\aÇÒK1\8cÙÜ~·º=±7s°OSÉ:i¶\89µr\90À,\9as\8d\96¦\13<-G\e<\99v\1cÜ\ 5Üaæ0tÜ¡»X';dzÝY\81%c½\18w\\19\ 4Ü»5\1e+ù -¸]êµÊ
+\83Mפ4x\17oĽ\ f½6Äß­9\18Ï\97`ãáªþ\12òþE­\b(ÑÒ óô)kT($ì+ié#5w\87²#y¥£\17\85¸\9b¥í\bÛ\ 4ÁíÒÚ«u1%\90\97R*\96I\ 6®\97\86iE¬n=i8\1c\82aÁâðå ò¨ÛlÐ\9fB´2vX±Q7\11\f\888ë!Ä\ e+6ê\89²\ 2­yÏjvÎ'mT§ \9b\e\1d\1f¥ñ\9bظ2S¡«\88ôî6k\81è®\17\85w%)¬Ã\84\0·Ð\9aJùá~ÏÉãW\0ñh=¸q^Ó\95¾Bk6\a\rB\15t\8e\14R¨s±7\ 3rp\80R\9f\fû\9d?n\89¹uZ|\94\9ee\94Ü\82    ½ý^\8cÚãV\7f¨¸\e·ßÀ\18/*Ñ\ 17Î+;aÞ\99\\84çýû»7öÎZ\7f¡  h\8dõ¥«^¤áÞÖ\f\15+EAÝ\ 5\89{ïf\18$ü4\ 2û3Yx§ ªÞÉØÛ\93¦\0£\96À}µúc\94\1dÕ!\8az\ 1\99úê\18\9dO\10\88NÏÛÇ©Ô\96wØú\83v\ZÓ)pNÚ$\99-:ß\88¼³q\11'340\12¶10u\ 1ÔM>5ôý\99w1\1e 3ÜqgñÓMZGìO\9dÝ~¥3p\ 4kЭÎ7q\9a3U\8d\H\9aäÛßêö^V¿\84KPy5Ð¥R\8c\93\0\89­?¨.¶¡ß'°\1d*\102\9dêü¦\15"\Ó\12l\96¡\98ÒYK÷ãl¿½³¤\rÑ6ÛoÕýVì\8f.P`ºZ]\eóÖ¸Û\12ÝåL\94\97ä\ 3ó\7f.\1d\1d\80\95\e¡«\19Êë\82jçyÅBàjbe;\8a\88I·ÚÉ1×Ê¢X8wF[Ù\ 6Ê\8b\ eÁ²^@\8b ¹ÒIÅj\7f¼ÞÔH\e­\85ɸÛ_©Í\12'`e>Ó\12O6é,³d=èÂAç¡Ã´X\rÇ\89$\10/\9dô®ÒfÝ&\9b\ 6Þ\89&IUû\8a\93a\9d5Q:_LÆ\93η8\19õ´Q\98w0,½|÷g\r,\93KªñÄYn\ 1\b\0éù{"\ et6&e£@®vý\9d\8c\ 2\9eµ\ 2NÝÌLë8m\999ÒsKã\13þÜA¾=ùËYGÜ\9d¯X©üÖràH®Q×\96\8e#¬5/:_\8a¢l\ 4ÂJ%\2I§ÜðXúN\ 5\91\ 5ÒÏ\8f3nã\80]¢68\9eù\8e8i·æÒ\97\146°LKÄo\1a\7f\9a\\ 6x.myj0×\9b¿Uî'%q\ 1Ó}6î\80[gÒ\f\17Òmy:i3Ã~Ö\ 56ö?ûJ\0´jIÑiÇõ¢¥¹\11\ e×gv\9cðZÙNw&Ú¬Ð\ 6\92iW(-ÍÁz"¡÷>\9c\r\89I§ÍL\82À\13zIòYP#>9¨äûJ@\99o\14ÎÎÒ©b\ fÉ\ 2zH\9f^\1d>G\8e\1fN\ 2G­Çèyòð*ÆçÄòè;ó5ö\9d\v¾h0Pè·â³\ 3æ®Rbö3¹»rö\82>ÍÔ^\ 2\179qÑa\85\12u\91ö\934½O\10³âOñ+J\1cä\8eÞâáÜqt:ËͪTÂãÏ\1dÕ|¢Òé|Î\7fU®k¹cº×(ôO²\9db<\1eøZBUë6\ 1\1f[\14ü\19ö©</þ¼òôS,\9a\1fMj³üYcþ\1dÉ2û\v¡H\1f<ð?ÃÀ\83Ç_ü$ÎÛ\96À\ e\93½¿~~Éß\16â÷öHõý2¯¹ã\81ð\9aËÌâ£H1ê_\bÁr÷ÓãÇÌ\12>@[\8a\9f¯\ f,?Ì\r\1f3\9fü÷¼ðÍ>\91\ 6v|\1c\16;dí7w|\1ax\90à\0ɳÂÛ×Û\ 4~;ü-\9euÏ||,ýs\90oÄöÇ\12\r\8f­îÂãç~\82\91\93º\ e\16¾é÷£ã¼?y\18á/£\1f\91\!p'\14z\8bpöþ|ÿû¨Ói\rÐoýHé³ö-a&\89D\8b\15û\a\1f\99þÛy\97\1fúO\ 311ò²È×\1a\87¿\88þPîèü;éñ3G÷¯¹ü¸\13\18EN.\8e\12ìèå¤Ï²\89Ùg2/vÎÈÈ Cª\10;ÅóÙ=°\8d\rôØ\87$ÑÍô\v\89\16Ì/yq\12\8cE{ü\90­\8f¤\114kþ\áìxÿ¡\14åR3\98\97³gf?Ë\16&o\91ãûîs\86jï¿b°Ù±\1f\ 6\94eÂûhJ\9e\99\aæz\8cø\94å\a!&&\8bæ}·F\90¯û\17ÅDëøPðE\9eD\84\85A\ fÞ0\14ÜÅã'Ú{g4þ=\92\15\8eåß\8e\1fJU©{!Zú\90\80QMê\f\91\88d³¥(U<ý:\91á<\9c\1c\1fu\7f.ßðLª\ 4\ 3¼+>%c\81Nü¹JÀ«F\0\19<¹A\9dz4nKùøâ;f5øò§4óÄütò·Å\9fHñ3Qý-µZ\81\ 3\9eiß]suÿã]þªÀ×\8b\9f\8dþoî÷5óåñótóö]bæ\13Ó}*½\93\91{\9e~Ì_  Å\9f\87÷Bÿ\87I\1c}\8eü_Bá3L\ 2\ 3³\1f,{Ó\9dhøÒ\8dßQ5\7fU\vW\85b¨[\95x£0Z\92}\98ýù4~\1d9½oýJ\ 3Ê2éVîèv¾\97¿=\9f/\96\87fâ¬\8e\ fÊD<\8a>\ 5T\ 34çª0÷øKO]ÿ\17õq|Z$\84\97\\12\8bÀñDZP\ 4é\bG#ü\84{3Ï\95\91³ú\89U&B\92\9cÓïÙ\ 2s      Æ¢çÓy­\9c\7f?'±Ä\1cG¦G\1fBð³\1aÏ\13Ç·OTèàíX"ÄÈ\ efqÃõ\84àá4Tøfn\ 6¥H-.h\92
+
\9c \vÓ(u\91\84æ@©F\870´ýPáë»4c\8f:w7yö\89z0ÏA½2¼7ÀÞ+\97bÑ6g5%Ü W-xüùÛ\8bn\ 4,L\96+òµæÀ\8aZÜSׯÜd?AiJ\14A\95é\8b\99×\85P}x$\14SOT$[þ\88yüÚ¸`T\9dO¡TL±<\13»ºÇ\ 6'NVî£\18i1ñ1\ró?óî\88\1f\8eï'ùÛïÇ\ 3\0Q\8d¨\0¦¥èä\92\12\ ecìsþæó;\0¯½\1eòL¤ö-YËPñ3Pa\80ÚÉ·d\ 5\8f\15Å\84\ 3\82êëmRÈ}\9d<"\ 3ÿQlÓß\ fù;\7fgfìw\98¿¹}\1e¦\7f\86±clÑ´\85\0°hÏ'çÄ1?\bNûÂq\99\fêlûÓM¸¥ç ¬%:cM\12íE)xòû ­4¦§ ÉÁ9û\ 5äõ\1aKÏÓ\1f\91£³Ù'XìÎ~\8a'\17Ãç|ãã¼ ?åò\1f¹ãJ!\ e]>îÁ
\ eyòiñ\9eo,nií)î\fv\f\1aF9±\939\94fK¯\9f\89æñéUa̲ÕÖ>q>\7fÎ\11Õà¨\ 4?º<Q%»yé·óæ    \a¿=f¡­\95Ó·\91_<~\ 3°è{¶ä\17«Á¯\82òâ\ fü\16âêÒ;òÛ
+\ 2      \8e\ 4l*@¿Ó\eøí§(u\91;O%,*y¨\93\1e\ eÆ2*\9a\88Wß8\1ft\8b25\12I\888\f\ 5h@X¤ab\88\88¨\10ß\90Úd`xT\18\vzÛÌ"\95d3ÒÚ±Ì\9b\10úl\ 6üþ|ª{û|~u\f\9dîNáÇs^ÏJ\8c\96S¸x|­c\81ÄϧÀ¥\ 2å-¯q\16°\18'Êzj×\9d\bÓ4¨X(_Ya\16\10*w\7fÎ*|2°Cê§ý)É\v\96\1c\84y\99\ 6\9b±¸\99\12<\ 2é7\ 5¢üÔð'\12\v4/6\82á \16\9a~T\9a¨,3\v?@X¬\98%\8d\15sBa\87n̨³%S±lèÆ,3På\98yÔð\8e\8cO\ 5a¤F§¤Òp\9f³\ 6¤\b\9e\84ô1\8bõE\9b-ã¬J¼C\10¥îÀ     +U\91\15\12½\86\14@/¤\18Õ\8f4/èùº¬^)/\98å\8fÒÐ4\19S'^{GRïÂFb\88§D\1e\18Öd\84;Ä\)¿á\ 1¡aH#\r¼\18]¿pþö¾:\16r\81Þ-xú\9f\94~ÁàòcX+¿jÂÇE3#øÂqXÅ\88^;\93VVûØ\ 1x.ÅAîaÿî«Ð\7f\95:\83ßCi)Ó¹\13©yÝ>\9cÑ»\1d\91\a\1cÎ@,f\fh0¡Å¯XèTrýêg¡\17m\8d3D[Ä~î>\10ä
\8b\9b§bµúËë\aÄ¿÷ò7ãâU®ñ&¶Á\83\1dæF¤\11K\ 4Ç\ e\99Kbø~\1cû\10&æ§\89½Ð3\ 4¡÷ÓR'z\9bà\99(\15ÓÅ\8d$ßþ*öÂ¥\8aæ[!Oé|Ái\8c\91½°\97ô\95.tÓ;\11\10\9a¢Ø\96\e
+\93OÉ=[\ 2ðHÃk±Iââæ%\8fè\ 2O   ¼õÔÓ6Á\89\8bÐ\ 4yJ[\ 6'.B\13ÙëS%4\86\86&\85Ì\86Ø÷m E(éa\¬Èspç\1fÈþÑã9\8fÝX\8dO\1a¨ÿ»"\v\1cH+ñTå¥Xå\99\0 \bµùëÜs\98¿ö¿Î±;L\9c\97\82OúX\ 4\8b}\96©Æ\8bg?lKc\eD\16\88q2ûóã
+{?¬Ýæ¯îª î \9d\92pj\84Ø\ 5\15\12\f\13V\15 Ì\ f\99¯gìý{ü\9aÿ¿LhïªX\1eø{ ^×Ç(©Ñ\81ߢóòt¯Íq\91#úÒ\b¶f\13¤\1c\a$\vSÎ7\86¹\b¼ýõKvnN¯¨Ü\9d\8f\93#ÕÛp\ f\985 W\ 4ýÔÓ`¿ðýâË\0ÁïïÊì¿Æa¸qÐ}~p\11\81@¤þI«
+\92A\81Á\e? N|Ú\ 3\89Lw4$Ð4\9d\ebd\86\17\8eK/q\15
++¼½\86÷\85Òx\ 1ZIù¹QZ\92¬èAâ9Ívjçüu=W§BÍÑ¥Lè¢éÏ__6îQ¬­<xøIÊ<\9e\1c\12ì`Ñ®\13µi|X\9e]õD\13fY+M¸w\8dÙãWERÈ\89â÷\1d\9d¹x8Å\b\8e\88Ó£\ f\14Ý\15\88O®p¦\83}5å+<½à      2z7ó\19æàù-Ï\1dUcê\83[ú7ÞÏãX¬\14Í\89\15!\1c\8aÒ`®\1e ¾\89vÇ°:Ý\bÂ{È÷\8dF\9aÌ\1d·ßƹ\87ëÈaæ;ÒèÃâÇý`9×Yç¥\ 4F%V<\17Ã\1f\92\8c-K\8c¯\94\95zªúk\0æN{)&\7f\88W@\94\87Y¥¿I-é謽:B\90öB(8ù,ôg}\ 6e\15bÏà?\94~\v&\88.¢|\1dØk\1f¬Ü\8aö&Ér¡:Ä]2dÚw     º\1fjÖçùj\93ìJÓxR½ì\16»#.ª\b_p\ fâôS¢X¨ìK\8bQlâËÆ¥D\80\94={8Iez\1f\87=\99O\95z\82\1fÆoH\0Ú\18c·Ãã\970^Þ¥_Kïoþg þË\97ûåß\82ê\8aõ­Ê\1dX]æÀ\ f\9càÎÐ\9aóUj'\9eúF\1f\ 6[ìg\1c»Ëëuí\v<%öábÚ0®ÝROö8Yê\95Þ®Úïà\9b\1c!\83ó\19*u"ÄK\9e\ er×`þ\1eÒ\92/ £Oîç\8e\ e\8bg£þ3\9fº\7f\8cç¯Ãõ¯üÍmD\0\97_Y~@vE½«"-('\89âÙs-\8c\9c\8d\eÜ\ 5¬óqÃ\8aøôíáACxß?l\16?\81_ü0}\10-\9e\aCAìܨº\8f=\89/ÿ\0d\82Û;ú<h|[ ¥a\11½\99\95"aæS¿¼¡¹\9a¾óo¹û\83ù\Å\\83)þò1ó\9a\0\11\1f\9fº\8dÇ\f\8f\ 2>âì¹|,\83P×W\9c¡½øùüÌô\ 3×\17àÒEóB±Y [\rÍÐ/\15ñø\8f^'Ï/N\9dîÃìeçèÊÔå¨÷\16\1aà<Zæòë¨_\8aN\9e\8c)2ßH  ¯åÑ<\1c@ý~\14\v³$Eû3XK.¾%Gæ\94y,\17.\v÷§&Ù\90w/Dß3¸Í¿70ɹ_\9dw(\83"âÀÞ\87©Ç\8f7@,æ \ eúYe\98\13á·r\\1cÖR\9a\13,OâÛ¾¯øÙø\98\14ú{\a)\10lú*?Î\9eM¬d\bÍ\v\12º«IgÊ]|&ÈüU¦TÍ\1dñS½ç-Sv\1cÌ\891n\81lr.Ͼv/\8b\9fÜG¢ôÔ\9b\1f\9aøÉý\88\81[X÷ß\9aùÉ÷U\188f\14\16Õ]Â\7f¾hÄ\ 3Q§g:)É\9e0I+\ 1á\ 6ùÒm\9eån°Ûø^ü¼\9eÁ\8a,\99
+\99ÚʾPÈ¿~       \85Ü×Måà\84<Ës\89AÞºK>ü\93»¿=k  ÇŹ\8e\1a°Äû{¹ÌCï+\97\9e\8aï8/¹\8c¥D\85Âx®@\8aêßnG*¹yF(ÇåáÅ(\92\15X_~\9f\8e\9aêD%ÁP\96f(M\7f\rÒñs\98»ÿ¼]è`g\99óE1~Ó\8då2\97?\ 3\9ds\ e?n\99=a\\90·^TuýÍS5\98ý\11¬~\ 6ö\a\86\89ïÞÛ\87Âê\1e­gGåjQ¬¼ÍfÅh[(\1d\87\ eüw \8bÍ_~t\95M-ËËõ\1e,_\83'ä)\1d\91A°s´\1f\µÛDñóV\84`\8fø\1cé4ðlöúQö\v¾jNÜ\7f\9b\17?'bÜB`9X5¿BhoçQ(|\9e&5õ\91ã\17ä\1c°(\11+¹XÂÁãO\9f R\83ïb9ëï\81\8bÁ1R\ e¶sÿ4SÁ\1e  Á³î\ 3
+._\90\8dx,ö\8eßP¨°\88h\ 1 ²Ë\93\f\a\94\0^Qù'\7fEòI\b³O\a¹ãìt_¯\8b\8a\e\ 4¿u\13:.\12³è\13\93½£KùT¬z\8d\f\ 5¹\8c\ 5\84¾   Ô­å\9a´'ÔÆ¥Nj\f\98\90\ 5³\ 2y¶q!À\1c4ëùIþ3h\8d\ 58_MÛ\81\b\82÷D|e."IXIo\ f}®4Õ öҼؠ  ¾\9a|'æ Ä·ã<A\9d
+× T\1fD©Ó\14SÅ\eú«t\8eN\90CÇH\82Tnæ\86xãPö."'çOç:îÀªóÊ\ fÙÜ\ 1\ e\8dL\ 6m.°á\ 5²\177\99Ø籨\8eT\9f\82¸¨\84\b~8\9c~\98\ 2xMÆtËv»Ô&\8e\ 3z\ f^\86ÈH\ fòÃV\ fíJì£Í\1a"\7f3©Í\8bÑ«ß®â)\r\16*Õúõ\ 5c9,uö\98W\88d|¢PJßTÌÎÆoå¦\86\ 3å£ÏÑá!\84í?\8cæ\vYx\0\17`±Kq<Ù\80ÅÁ§8z(E®\ 2\11`à[Ì©_ö\ 2Ô°z\0\98\85¸\15f\8f_Åý\90;\1e
+!½\ fn\ 6Ö°×;¤Â¿\85Ë\12÷\81\17\94HvöÄiÆ\11¬%\1aÒIð:ÔD\11Êe¢¿\9f9\96\1d\93ð>L0`#\99a\8e}ü*åÓåÙ\1cm}Ç\84àyì¾@Þ\8dfG½Ìá\bÆ|\13ÒcÎþ\8e°\17\89lòi§g´\96\8b|º=ýÒ-     Øà>]·*àëM\88£ÏEO4\9bÞI¸\98н¡n\fc¡ñø\99_\92k\80¿Ý\10\84Ü\17\bycqÛ]-¿\f\ ez1\1fP\1cp\ 1âó@\81?r|\91oDs0/_á±\1e\v\16ÎRg±÷\9eOÇâ{È!dLâ\ 5ËѸÇÓ\83n\97¹¿{½O³§\85Jáû¹»\87"¬½Üñuò­X­\1eï©\9bÅæ×À\1f\13Z\87¥ÜÑë\1d¸\9dìu\84 ¢¿\1d°òO\ 3Xs?§ù\9baêÁ`\84[\8f¹Yèq¯X=O\82ØïóSãª")\88\1a\f0\88Uà'c#Åd\7fÃçÅN¡5(\86û\89Î\92ÍRÍ\95j©T#õb8\fP\7fbo?öE\14p\85sGoÄ\aóKÌú\80å'\17\12\82Tý0r\92/uAÏoó\ fÅ/úu\0Ó4Ïé\92\92R\97«Àk)Æ°}0ká=)\ 3¢\18«R¦ÛíÜf.ßÚ\váãuñ\8dÎ*tÏ\ 2Èf½\80\8bÕÜç\aÅÀOé©Ó~²\808\ 1öWbBþÆ'Êg(\f`\91e¿\ 5\93Y>Ç6R{
+¾%~\ eâ~¤ã]û±wÃÿüd+åÛw\b{\95@\19sù±Ôú\98F`Â&\19öî-ÒP\12\9a\98Y\ f$?\8c\91·å§ôí\1d2p\1f\b\1e`\81H4ü+\1c\v\9d\993çÕÉ\99É\83¼\ eÎ\910\1c3wõn\ 2tö.j\8cÝa\r\88     û\8cx]9EÑkàô\10¥\83¿ÁëeZ ë×\17Å×\9f8oê\9e¾\82åZV$öé©(¤³OÖ°\99ê7\7f\9d?`xz6fXövÚµÌZ3ª\ e½\16?ùù\ 2çmõ³\7fý²/\ 4«|:\7fU\r\ 35}\10\9fÀÜ\84OÓD\98\97O^\f\98\16k=\9c·jI(¶\9f(;\10íÜQõ
+¼'"úX<÷}\12\86ôù58*\17B\0Å\95\9c¾:+¥\94ñë³ö\99þ[ô+\7f[\9c\85\10¬b#\14½\86\8d\989¡À'\93R¤"%PQÛÛg     °\b¹\1aÙ5.[¥ãè¢Ø\16\82·¾ ûпmbe\80\15"ÖÔÈ+ûA\7f±=`\1eâ§d>)v¥±\10T'·(~í¿\1cH *Å÷s°c\9dT\87æ\99\'®\1f+ÛcØÑÛÁHZPª\ f\ 5\1e,\91_L_=ùBÄç{ì"qñò\9bBFø\9c\9eÑ\13p&_ÃQ æ:\ 6\ 3ÿX\80°\7fEüd*ù\f?8\98\97Hé"Â\81çÍÿ\80VN\17°\10\84îÿ;«Ö[Q¨ÒÊ{\85\8bKfÞ"þð\1c>÷¨UÛH'ãÐ\97\15&R7ó\17\83ô\10t\9f´aYåTðR/­\f@ÿ\91'SÁÝ´5V
+Q\8f\96ë¹´«\a\8cßÊG\87þ¤oè£Â8å\99\a\1f\ 6Ô·X\1eé\8bdS\1fläô¾\9d \12\91\8bpäô{\9eD¿Qôñu&©>¸V\7fÃ\ f\8e\92§·s\1e\1c\94ò ²\7fsÒB\91EV}
+&ó\86ùö\85\92\95\13_,\11¸ñø}\91ìàØ\17º|â|Ñï><úø\8cû"\8b\17½x,úbÄ\ 5E$N\9aA\8c>å+\84®é\195\83u1U\1cЧW\1fÙ$\9fN¦ÁÇ\1e=á´\1a>S¦=%*ï½\82Ç/\8aÙ\93v>:½<ÏU¹Y6]9~\88\v\93'ú¾$¾<\11Å'¡y+\9cäO:$80c\19Kòà:R\88\85o\0_\8d±\e®4 x²Æ\1d\0Ç\96:Õf¢x4»\ 5$Ñ3"A7¤ah\94ÍÒÂü\9ez\9b\f\ e\89î!\891_i`ÅWbv\f°Ó\8bH¶ì;Ä\ 3ÇóR\1cÄ\13³t\99Nÿ\1eýÀ\9få!¼Ý,\1a\91¾\88¯\17/×ÖHËì[*sö\16·Dúvp  î¾      ­\86\94éWË~k¤Ç¾ 8#ý¢5Ò:ùBïQ\99°\86Ôã×ÐÎ\ 2Ñ\8b\98\rÒÔw°\15h\96¬\91ÒÍGB Â\17\96\84.8I\aà
+^Z\8d\95\10n\1f\8a6H\99}\7f½\91ÏÛ!ý ÊûOw\1aR|\ 4VE[\8eå\ 2gíø£%\83_~Z\8c\8c´\1e\b\98Ø\9b<\9a\ f»\18)Èb»d\9cÓ&Hò+u~\89Ð\86\96g5þL\9f\\14"\80\94\9e,\89ÒÛ±`\8b45¼Ú\9bkH5I\96жķCÿ½\rR¡Ã\8c\ 3\12é,ÿ\9a´CZ\ 1\8eM\9e\9b\13ë±\1eï\ 5g\ 1öP´B*.>H\7f(xúüj\85\94\10¸RVC
+X\8c³zи\17\8f¬\91ÒÍWBx­ÜX\8etO\98\1dù\a\89û\86\15R\bÂËÑÅ¥ÍX\99ý@ï+we3R_B\9c\a\bix\89½×Bø\94Íù.\0);õøÍc­±|SFÚ\8c\ 5MH\99Fmp/!-½\f\ 4ÃH\9frDí¹\94²BêñÏö*¿3v°\7fÍ`´f¤\17a±o\8b47x/äm\90>\87\88F¦7ÃH\91\8c\99\18\\8d½T»½èÜ\12iãýôÈ\16éåKå\9c·B\8a,?ý\ î\ 3\8fiK\ 6ïÕö\17\8d¯v7m\89ô¾FNl\91Þ\95\13å!Fêñ[\8cµJÜO\939\e¤àw¼=|ä-\91>\9c¶ÃVHÁ&#´ïïùù\83\r\83_hâõê6d\8dôòêëç±x\1c¶Dú:\8f_c¤h}Y\1eë¨\1e9|´C*\10ï׿ÇÖH¯r!ñ9?+\98\90¢D\ fB[ú\8916\fNW|\ f\97DMBÚÚ\9b\97\8dJs*.\1e\9ei\844²¤4WûG¡·Å\b\1c>@{"\9aÇú\11¾9\90\91\ e¸°i¥9$..S\18)\15È\ 6+F¤qqöu¾\8f\90Æ4¤\80E6\10µ¸ïe\9f\11\0in¶d
+_&\9c\84ô4X\8a\9aØëË\vW\ 1        éë<sn`oè.rT9\ 1\17\19¡M,\9bÂ;2ÆÖ\ e\7f\0©°0#\15û§!\19iæ:n\1c\8e÷\1f\1ec¤ÉÓ»Z\r#EX¤±î?ÏRíç:BJ,1ø\92;Ü{\9c_\9f\ 1RjÉ:\8bùöø.âO\1e[?åÓ`\93\9b\97sËç\8b\96ï\988{\89Ìm\9e\ 6²dkVß·z
+3 D}~þ \88\9eZY\98J\e\ 2\80\97Äf¯ò=U\962«§c\91½z­¤LOÕÙ¯Ìçi2ûÄZ¿}vèË]=\94®m\9eÎ\8fªgçû3ë§UâÕã¯E"©\85Ísæý2\97]\ 4l\9eV?ë\19ö>fù4}ùD*+)\15µàX\8d8Pç2¶ü\949¼k=\97²6O\8f\83÷\85ã\87\9cé©Ê±\1a\1f~8\10û¼ÍÛ\95è{\81¹}±~z\91\17~NBÉ\90õÓË\eX\91\7ffï¥\88ÍóÇ\9fQr\96 l\9e\8e~'±A/mý´ùZgnZ1é]\v\8e½\86\9fUé^~ûý÷^±\87\16O[\8fÔÉ^\94\15ì8Ö{¼\14æ{W=ë·?\89×ïÀÏÙ\9eåSÿÃu÷>è»<µz*\8a'ï×\1e\7f2w\1d\f¢çñåç\14\7fvuÍ\8fÐÓ%#$æßG3ßk hùtñ\91   \86ýǾ\ füt\89cðü$\14Î=\84[ÚÛÙièxªF|Sl¤²\åà\a[/¢òQ/¨¡\19k\15\9aé#\v_¸zDú¢Å\9b\a_ôþ\râÊ÷î­/ø\1cZ ßê(þ,øbÕwð\85\1e\a¬ôZöd2\0j\1a9\8c\9c¸H\8f\ 3\10\8e>.p°\83£¤Ïc\15í~¢\7fÒ\ e\81\87·W\82p'a´\9bâ\1e\158©Çä`ç`¢_\82³ûIdþÏGR°Ó>¸\19è×}=Z:ôb\8ftOx\8bÙ"%\ 4\9e¹²AÊìC\944N\1e½kh\rH\9bo\ eH˾\94=ÒrYlªH\93ȻСMWö\7f\99Å\8b\82´<42øU\8f\94n\1cèÙ{\9d»Ñ!í\1e\1eîkH\ 1ËÑðîRCkb0\92¶©5RºÙ´Gº'|\11\ 6­4¢Å±\83\rR\88&!vhÛ!mÙ"EÞx\99ÈØ\8e\15{$¶H\91?rgÇÞ¨\86Tò.\8cc=;4Í*\19\ 5_\ 3£Ç¿É\13q¹èºêwµß3é¾MϽ«\13\9f\8b~ââ}à×Y\v4fÕZ~\9c\9f\9aT\17Þ\8e\ 6#üdv)I?üV@þß\19f\8cÂYUãËW7Àã\8b¨üã\94Ð¥op~\bÅ\95tôF¯OõC0\8f\81ç\82Lwë\86\aB3\93ì4ؽ5g\8d\0=\9føî\15ýèǾ\8a lJsÉÙ\1e ç¹H\86ù\1f\ 1uJJ 4³\97Í\96üº\1f`\195\7f[Ndé:×\ f\7f\95.òpÕÜ\ 5\90L\9c§ü~ü\ 3       \83\90)»RGP\8cdÛÉ\8a\8e\81\97ïêðç!Z¹\16a\8c\ fë\8b=Q3\13Q&\92Ð^`\14ÿ\90ø)åk0\14MT 3Äbá|m±\9aéøÇ\8d>&·\18ß)Y­Y\8dÏã×\8f\10ÿh=\16­fP\9b¿äéýíŪù\8b^Èò\82â!$cË#\ 4j\8fÂÎÌr?\7fåÆ\18Ʋ\16³\1c\80ÝÛ\v»ÇïBÜ5f\11\9f\81ßG·\92¥É\95Ê1½dMÈÖA ²\16çíø\9eÐ$ykηgÎ|÷81Ëdz\9aѱÙô\94^
+S=\ 2uôFÓãñ¯\9c\8d·\12Yz\9d\95U\10Ik\ 6\96«\87²Sf©\95¥\97«¹#=ضGÑ\8fg}Òu\89w%\14AW­Ì¶½V\86l\87\96<8ªÖÖ\1a\9aq\15\93Xý²¿\9aÕ\87\92\ eÙ\11BôZïwÚ¨ô2f\18\10\8fÊÚ\8c6£Sã2±b@6\16¦ôR\8c\e,\8cª\86\ 69'zõø¡ÑW×OS¶üò\8bÙ¢æ\937cÌg&ød·J_«B\13ÕIrÄ\ 1X!þì\ 2\985(Ð:C\ e6Û¦&f½kíÕ~]è\9d³ÖaIn    j'\9b¹\8c\96¢Ò\ fy®È±µX´\93{VÓ\89<%ã\84¢\1f²\15ÄIl\vÙhí]\90¶²\91ø\9eDNLtaIÎüÚPFýRü\13wn=È(\1f´ðÂÌSbØKÊ\ eÒSÓ\94ÀÛw¢£­ukzÊÈ\1f«\a\ 4\9b\85i\95Ïh\90ÅnÙhUuË\92Ç¿æü\ eÒ\8bõ½'kÝ\aâÛ>gf¡ñ%V\92Äí9¬\95\1a=.\:À÷½oGRNÖ}·3hëÒÉFö}\11pôù\r3¸Ê¥s?\7f¢ºT%\15\ 6X7Ð*9Óåñ»\ 5¶*îp¢Ë°'\8e\81ÙÉüú\83Ô¼º\1dpÌhi·ä\98Ñ¢­Í19³%\v\1aÅ?6cÆÀµ\82T¥´¾w¬Ñ\8aóü\88\9eyv\85åÐ9´Övì«bë^{üK\ e¶µ¯P1Gâ[håW\85z]ðÕ5\ 2ei7wy&ç§~\8d7r$¾>wÜ\87\eÙ·\âN¹>r\9b\19Kv¦\19\ 5;}q1MN!\9e\89\10ÉS²$e\95\15pC\88Ù·Ü\88'«Ô^!D\89\91Á\93
+Y.Qüã;½^L.miª)nÃ\19\92\8f\fÞ$¿Ñ§¶\83Åùz\bl\92\1a\ eoy\róa£ \10\86íÙ\92äñ¯EÔ\86\ 6@\951\9dÊý\9cíÈ\0Àø\ e×\8d÷mÇw\9a¹¾pf¹Ç%Ó\8bsÍWp\95Ï0xòú\\1fõ:û&w#T \90M]ºAZ_\9cs\9dv1ùÏ\19ñIî5]ȧgõ\f\16çnUÜ6ì\91£$ĬÔ\16Ì\9aêMÆÇÉܤàÈ\8e\91ç\v\17Q÷êìÒ¹YÁí2$N¹\ 4ð\93\ f\9c©±õß\972$É\83\fJ\14¬
+\8a]¤dÏ5ÿ]\91äõÓ$\0"è6½\81,¿õ"t¾´,o\90Þ\18\9d\13½ÙàÁã·ÉI¸\1dÐùÂE\8eγ"K\97<à~i·\8c±e\vÆò.®\93\ 3±Ë×\0wìò5FIÖÙMC¦ÁèJ££É\84Ñ\95®\9a]i#ó=~\17δ<\a\99ëý\ry§øc\12=ö{R«<a\ 3ï¦Uã2\984Æbk-\84\99ë\1dèKÕ¼\ 6n ç\99k\1f~*íWn\9a\8dN\9eÞù\93.\ 6äq\96ôªiÑÛÈ\0\80Å´ÞmÆ\18çd¡gy©³ñe\11wØõÖ!Õ\97\95ü1ãR\17
+F\8cç7`T\8f\rg½sÖ:£$\83\11Þz\7f\ 2%ßc¦1/í\8aºÍW!`     7ú"É\98\15\ 1#¶µÉ\ 5lÇr\8b-e\15Ï\9aÃ\92§Ûã[\rÇ\18H®A\8d¶'\8eál­\81\18Ê\8b9g¯³ÉëÀYsÝÓÅû\16À\8c;\84k-¢\86ýA¼"7Ææ\90\12µíj\87\ 1ï#\9b\16\9c\8d\13/\88V»M\1fû=>;'âñÖ%+uî§Ço\15\9f«\16-laÑîÖ·hv\19\12Ð\8d\1dX´ÙÀ¼[íÞ\83·\0f¿é£¬\95.w\90\100j{O©\0!Bco[Ý¿³²h\eèþÝú\16Í*w\81áloÑîv³÷\8aá¼Ûn\9då\88Þü.\81ÅÇc\9bÙº2LØ\11a\eA\e\ e­}\14Õ·\94I      @\0\9c\r\9b\ eu¹=øàâÌÕã½m í~K\1e¦ÓÊȪ\19øõÌ,\0[ÇÈbÝ·5³Íéú§\1fÌÊü\19ø¥=þ­\1d\14tä âά\84cväÖ¢\ 6\7fäH\82³õ\11\b\fÅÒ\13\Þy_ Ç^sl]rËÝ\ 4\flͬ\9fÓZ\18\95s\17ÆÕða\eÿÞ ¤/¿x-Ü.âC\11Ö\8a\ 5Lµc«WC\0æ&|´]\v\r\91\ 5\0Û:çR\80\19ê\1dl¿\8a\9fÒ²\Å\1e¶ñï\rPäµp«UìÁÊ¿·\82âñ¯\84ãj5t^\v\15\vÓÚ» ¶Y\rMk!:\12\1eÕÖB\19ËÒÙ\97\8d\8e#¡Ñ?Z­\85ÚZ©?<¥\1dðõ\ 5\80®7ÛpÔÀJ¬\95Î\19\v\14,¬ð(]xº\8aM\ 6\14Ò\85§\v R«²
+\8e¶Öȱ±ßíLJÖÒ6"zt©çN»§ 
+(?6\e<ØXùÕÇéÌ$Y+©$É.ÔË´0Å-\96¥¦í²d\9bO¶]\98Ú3\87 Íæä\9a}¼ß4\9f¥·c¥\vå\82H\9c\7f\1c8ÇFn\8f¼\15\0Ô¯yiÑÍËZ»7\bØܵ\10¯ä\98\9b|²ÝÎ\80q&\91$\e\8eß:\ 2³q1
\84Ãá[\90\btBU\96\89\84\v¢\9cÒÂ\ eÊ¥®Èr\ eHs\18¤Cá\16øôßf   Þ\1c°¾è÷O\ 3UÆÕ|±tìݪ\82ÎãßM\r\9ds\ 5ÝRÅÐ\865tÎ\15tRôº}\r\9ds\ 5\9dSµà:5tÎ\15tÆjÁÍkè\9c+è<þÝÔÐ9WÐ\99ª\ 57®¡s® óøwSCç\A\87Owì \86ι\1f®~ÚA\r\9ds\ 5\9d>\v·M\r\9ds\ 5\9dì\8f­®¡3\1eH¶¯0\9bZyÛ\8egàí+\81r¿k\91d\97é­\1f\8a«\ en\9f´\83.ê¥t^ß\96'kë\87+N\84ºÏô\ 2\9fêë\9c%·ßã«\aìO\9a­Å§å*\9bå\93fa\97Å`\11\17I\14ã\1e\9f\ 3°èÖãÃ\1eìêÊ9÷ã\8b¯Ò\17×L7mæ¬&ɾòqE\1aÌ\81¤å\929\94\1d]³hÎ\9d­iFujm8Û³^\ 1Õ\1aGA$Ý·;\fòVÚÍÞ\9ctvÔ²\98h½¡9ºîê©\9b\95ÅnÆ\93\90ë%\ 6\95õeÛ\8c±Rìf½mc\8e\92V\16»mt\14Äh-\811\ eûºúÐte\18\82@©Õ\fÒº¿&0ã\11,\88\11ã\8e\8d`\8aÉ-*\1f]Ú¬ÖÞ£ó\11\a]Ðë1|ÃpiB\ 5Û"ÓµJLå:>·%\8c«c{Áj/[ç\8f\99Sg«\13\87\91å4I·lU@´Ù\8eÕ m_ØoU\ 5\86Ï*ØÖ\81\9dÝ\89uêø\9c?]àú\9c]·l{ÂX\7fæJKZÙ\97¦eç§ç6$9¸ÒV\19x Êþ\f¼:u®æ\8f;Xu\ 6~\8d:¾±ó·\ 6öרã[Y\13c/\f\86\1a^\19Xc¼\eÉÒv>ì+SÖ\ 1f\U¶äØË\8a¨e-\8eÙo\85¬=HÙ¢mÊ1câ\97\15\97\ e:ͳ3\93?¶a\0ñUYYÀ(«ºmÞÒ¡^Îl-ì\0h\ 6Ƕòñ\96\94~¬Ðîùé\81\8b Æã&Ø[Jí:\ 4{6ß\88 øæÞá6 P\19\96eÔ¢\8f\99¶á\89¾TnÃ\19\19±\8fyìKÜVëþjvØo1\9aÄÞ\96\19ºï*¬b\87\93çRqþä\89úµ\13w~$õ:kÇ\8d~äÙªªX©bȱÖG©ô\19¯\93¶X
+\95\14Oɱ@ÎÂêØWDYÍÀFþ\18\90äw\9b¶Pý1[>Í\83nÕÕ¹Ì.àYA\94[>\99wq\8c" Tع\12\81U\95q¶$\99ê\91Q9ÛZ\19\19\a\92\92ë­bN\15vî22«N§»(\8as Éüí\8eSò|fÊÈ$\ f¸é\8a\98ÎMFæ\94¬îm\7fJíÜEFFÝã[\116\8cηÉÈ\18ï\1a «\81í\87f\91\91ÑNw¸/C[?#cQ-Èýnz@X?WK\15©\9bÕç­\93\91±Éó#Ƭ:iï²8\axø\92dw§$r\8b¥Bó̵oõ¹q7Îò´º\8b\9aÄÓ;ÒùÄ\80\9b@CÊÂUw\93ÔÁC³:9k\\91Ý\94¡\9d\84Ö?$gZ_¦UWG\17V\96\8f\99\8e.ØU\v®ª«[ï,£å        ÕªÛózÎuuÚ\1açX)¼ú\80\b.®³ÿH\95^\92Ý\1dÕ\ 3Ìû\ 1Ó±uh\v:\9fÈ\92\16:ÏÊï{î¢\1eN:\ f³"-¾u=Ü&ß\1f[¿\1eÎú\14ô®ëá¶:¡êº\1enÅ       Õ\1dÕÃa\9b¼µ\ 6®ª\87³ü"¨íùÀMëá̧¡\94í¿ÝÖÃY|w\14\ 1Ûq=\9c\8b¯\ 4ì \1eN7/ú#};®\87³\88Ål¶uP&eÓ\r:S½\98à,@®ÏD\9a>1lï[º9\13¹tJb3Ý¿Û¾¼\1e\19!\97'!WÂq:\19ìz\87\17Á1\ 5ÏëP£úc\18ζ5ö\12\94å¸Ùú\füj\8b\98\103\9fw\96ußQ\r-¶òP  \9bs!\8eA   ÕÛ\7f¬+½vR\11u5÷lïÐ+Àîí5ÇÆ\8eÙªa饹A9©É\e\a~ï@\r\9bÓ\9d|\r\18ÃqRCwÑ+\86³\85\1aê¡\80\12nù­\e        \8eý~ºõ×´l\8fY#`ÆO̬ú\1a\9a\1eÔÒ×\1aÑ\b\1c\16j[éJ;\ 5Ôº\8aÔ\87]T¤¾üî°"\15\80í®"õåw\a\15©ä^j\17\15©­½\8b¨3\14w\15©\0g+»©«\17sõU\91\95ÔX\86OëV¤ºÿ\f´>$¶>×\87\15Äᣩë\1e2B_ÔÉ\ 4£Kj\98       ®\98\bwy-¹\14ÎÖ\8eí´\14\ eùc+Oô\18\a¹A)\9cݼì¶\14n«¼¥ëR¸õâÊMKáLß z\17ÿ-¥p\96Y\85\9d\97ÂÙåÇ\Æg°~º1\ 5¦ï';\14>\19\ fH¬÷Ex³?ÖÜÙ\aÕPÁ\99\92>vþö \8b\ 42\ 2\10ù\16>L{füÈðz\9b\vÆjôB<áj\vÇáè\ 2ªò[ÊÑ鱸(n6\91äR"tÙQ\8båAÎ\0]K·ÆY\8a³âúá\v2ÙÏçO¶ø$Ü7r\899_+\89o'ï'·Å\ 1éñ\17øÄùCq¿wÞ(\9eF\1a·'\93\8f\b\ 3¿\95ëÐ3P\10\1e_\84.\15Èî\15%\9f\10§{uùä{\8bb·ËS}-\16*ØÁ;\89J±Ûþ}³®O_\19JÀ²\99ÂsÓ®ØíѶê\fÝÌG:TØákµm\902ûèRíW»b·\15\15vÓ¤=Rt­¶-Rt©ö\97]-VÈXag*v«§(\1dRc        \18¾jZEj.vC\17d\ eí*ìè\90C\85Ý\9eÐ\8aÛ"%\84êqÝ\ 6\8fÏO_\16\8aÝÞ\9d\8aÝ\ e\18{¤åëý'\réÒ}|þ«þEË\ eé\8d\ 3{/«÷¶HÁ\8e\95Jw\82qV\ f¤\ f\16(¿É·Ù-Â'  Wý\92\ 5ÂÔOÒ\17sOâ#\9cÉ»\80\18ÉLæ%mé\8417i³#ªEI\ 1\8b\ 5µàtæ~å\91\a\vlM\85\8c{DE\17\a\9cÜ\95ö\9c\98¾ª±Í¥_Î\9f\12_:seOTaÅyRçs\1ejôº³\9bä¬î\91³ü¦ÊV7É­\99\85[úèÙÆÕ\90\13\8f\9f\1dqã¹>ÇKäV\9cëÛÑ%r¶ã³¹÷ÍåYÝ\95$­¼kÀ5Ó]\1c¥4|KmóûãÜëËdÕ÷ò­\8e»º»\80nU¦wýjºMó0ëUÓYÅ\ 1Z\16nWÕtVµtÖß\87Ù¦\9aÎ*'h¡/[VÓYÕÒmQù¸Æ6¶íIû\8d«éLl1×Vï¨\9aÎ
+ÔÊ/\84¬]Mg\15Ô»[\91ש¦³Ú§Ñ­\95;ª¦³ª¥3í\8cì \9aÎ*Ïbü.Ü.ªé¬ríZôº«j:\87ï\í°\9aΪ\96Îxvt\17ÕtV\8b6\9eý\9dVÓY\91dþ²ñöÕtVóçñ¯å\9eº¨¦³\9a?ËÓP[UÓ-\83Zy§ð\ 6Õtö¾å.«éÖâØÆÕtˠзÔv]M·)ÇÖ«¦³\8a°<;¯¦³\ 2\80k«wZMg\ 5À³ój:«Ý\92¥3ð[WÓYÕÒ\99£×í«é¬ÊÇ\8c;#»¨¦³ª¥3¯/ÛWÓY1Ãp[ÖNªé\Trí \9aΪ\96Îá>¾í\ 3ÀÓ`QÄ\ 1 é~±¯\15.\86Ë\ 21\9f\89ï\16ws¸+|rm-$ïb×÷ÕY\91äè]lt_\9d£wá\8eO+o¶5\b©Ê%s\9dø\99\vÇÂ\9d\b\14çZ\81\82mÕ³5QË$¹2\ 5®n\97[K\9e¬H\92Nw\9c¹¨§wË'«\83\14N\16Æ\81O=·Úk¨ä2FD\16{Ï£sã\92`qÌÚ!3§[Åì/º[£fÍú\9a;ãw®Ü¹äë_sgoaÎ]ì\ f»½æΡ\92Ë]!\9d«o\82;\9fO\96/ºÛr@ç\vàضÅ-.®¹s\93Q<_ÿº\1fÛ\8c¢ÃEwnj\95
+N×Ü)µoë\9c\ 3¶Í
+%Oï"ûVc^ë;WÓêÎê,N3×®\8a_W\1fQ\82¡e\82[×òL«®Îb\80|ªgG­\véV\W°Z>«òyþ\1d\14Ò­<ûëqUah\7f\88ÃmU\1ab\f³\93CdUÛÔ\9fY\92ÝÜ°\85mär=Q}d»ÐY\7f\eÊn¿\a\95«Å7¸PÁ|\1aª±»ÓP\8d]\9e\86j¸<\rµâ`s}äVùVT>\86¶Þ
+ÁPl?\aîñ¯\ag³%Ï\10%a8Ûj \86b²Ýv\95«Ova`«\vk\1dn`7\17Öª\9f(ÖiN÷ðÄy\95vÿU@\ 4¬0_Ëó÷ù\110ÊÕÉpÝÚeËÊ\9f^ØÄJ\17÷½:8\11È[\v\99OPC\9bù\92¦\15\91¸í\19껵\w\87\9bòvv\83!Z+wV±y?±-dXG÷g\ 3W\17\r­®|<
+oëN\14\96¿R¼Ñn5\86³^=§Í=VK\9f(ÞtTæ{\12×¼\88Ǥ Î\85\fkîð"ß+¼TÈ\10ø]Y\99âR\r·ºáN«¯´¾ãn#5\ºánó{«×¹áÎÁ\eÇwÜí¢ò±\18ÙÑMy+ÔÇõMy;©K²»ãníQY~Ú{©.ÉÍE\93kßp·â¾×èr\ e\rwn¿j\8e\ e©ì¤°K>®a\1f½º/¬mí½¯¨\85õ¸/¬míµ-S\ 6.\82PCåã\ e
+k_~­ªÛ×ýÎ\95\ 4gÝl\96Õ7"\0Î\ e
+k\11\14å \93s,¶\1a\8eýwáôGktß\84´-czX«¾ÝB£§Æ]Ñ\8fPÌB\r\1f·Îkéî}³ÿ°\8cÁ\rpQÄô.\9ab-ã*¶²\8ci©"Ì]Ø®\9b\17ÛÀýqëÃX:­|t\95¦vSÄô.\9ab÷ÍãJTèé¶\88I½SxÙp\ 1Gïí\róZ\8e¡T\91\1aw[ÆäÊ1,Äc&Ç\10a)ÄW¬%.\1dæ­c\88Ï]¬[ãÊ?~Û~©Áò\9bõÒ\17Úm+ÂV\84Enwl$\8e\99ïhÜ0\81\8c@Y&'7ña\96Îo¬Ü\p¼[pûë\1eÛ3¼ä¹ªz^mÑ\9a\8e_\982U=;Õ¸jÚK$\84÷\98\15>¥Ì¬W\10ÅSÒ/\95èÝ\9e²M\8f¿ø$4o\8bO%1\97¯0·ç\ 5>Þ)\14øD\15\1dãlL\95\85Ç?4\92'g\97L÷°ÝM\87ÏVõp\1e?*N{v¸èî:S×\8b\92¡\1e.rÔ¹²+ÂK}\87ýǾ\89Þ&\e\v¶ìkÿf{B7a\8b\94\10nùk+¤\1e¿t\ f\9b¾JÌ\8côÃé\9a»\18§Cj¬\12\13g\99ÈL\97»0_tG?~×\8eljÿö\82¶¥iââ\83´,Â\ 3\8ea\ 6\1f\1f\8dtwÎ\99ÊðL·ë\19GúìTù7¢\f9XsíßäöÖ\16éa­÷ݵCÚ³BªÜû\96¾¼~´e0Qº|.Û MW\f\97\17\9a\91^c¤º\15y\1f«¦L\0þM.ÂÌ,;u¿#Û~òYk\ 5÷KÍ\15D:T\97úÉËd\8d±p:\15Å\15\16Ã¥»\9f\1cóÄ9«ÕÎéØdDúº\9cé\16³Ã\89ÛócNkósѸ¯@¹È\90Ø\97$ýº%Iª\80p j­£0v\85\8eíèhÕsÑö`\951\aë"\93T\ f\98\8f ¹\98\9bY\9e\8bë\1d­r(\03\7fyróª´U'4ås°®äib\12ÎMÏö\14×9²¹\8a$£hZè\8bk¦»?¥\85óÉN¥\80öyâ5õÅá\9cVN¢gùl¬Ñ\Å'K\9b×ͨî¾LëJ.wæê­ävûÒ!\a\8b¿\e·\93¯Æ\95Ðìï¨\1aé­´\83]\1e\18ÚËöù±·Ò\ e¾Û\bsnµe½æw­7Ì,\9bÏ\8e\96\11ZT\ 3è¶^leÔ\82\80Ù\9fÒr\93\1f3\1d\1aiS\13sÕlk¯æ<f·\16¦M-v\15#»H\a»L\ 6\v¶gæ¤Ý\ 47××\19\98uaÿ±+«\94\1dæ\98Óµ2øË\10\86\ 3\ 4åÕ_]0û#¶\91x·ì°8®WH\96\9e¯¾3Åu!Ù\9bù;\aÚì®]cµÊy3dc\15\92\96ë_\ 2'=Ûï\1c¸ðÆõ$-\9dSÚ¢\14Ðhï-K9Mß¹²/\ 5Üjþ\fu\16\81\93ûØÎ\84á>nZ÷·\ 2\96pA\97±ºÖ\ 1ØÊË\7f×áØÊû}Ü\ f\92Ú%Ç\92»ä\18m\vl©\xÙ;Ôôe\93*@·5\80æ\13Ý\e\14\88¹\b=\95¯jØ\81XYvìª\ 6\10ÍþæU\80æù³«\ 1Ô\9dPÝ 
+й\86ci_lÃ*@\93¨ØF\98Ëç`ífh\9b\eõ$\8emZ\ 5h\98\12\87\1aÀ¥\1a+[vls£\9e.FÞ 
\9e$c®Ä´_)ѳ4*\93÷´ö¥|kÝȶñ¥|ÆÛ²þ]\97òYe\15v\7f)ßê\eÙvq)\9f\14#\avÃ'ÛKùðNâz7àmp)\9fU\16\97ò9Þ\8f¼³KùÜÞ_¹Å¥|\86¬\ 2"ªF¿Ø\10uuçª4ØæV¿]|\e
+Ýë·\93\9d}\ej»{ý\8cC3\176mpÚÖò^?ç¬\90E\8dÕF÷ú\99¤Òt«ß¦ß\862ßëç\9c\15²\8dÄ×¼×Ïf\86ä[ýì¾\rµî½~®$yë{ý\9cO\86è2W[Ýëç¢\92k\a÷úI\95\vé\u}Ùò^?ç¡-ß_¹Ù½~ηúmt\ 3\88Ž~Î\ 3²>¡ºþ½~\96ÓäüUó\rîõs>qfó-h#wÜ\96\1fÙ\16\1fé¼¾­îõs^èð.Ï\ eîõs¾ÕoÍ/PÙÞëç\1cêÚ\9c\82^û^?«SSÚ­~[ßÇ·\83\9aw÷÷ú9CÁ³¿\83\9c7Tt'º·º×ϹpÖ¢"u£{ý¬7T\94[ýL·3l|¯ßò18ý­~Ê9¥\8dËSä{ý\9c\8d\99Ç´vmz¯\9få>\8dêBHQÒö÷ú9\1f¸6V¤n~¯\9f¡~kéV¿¥ï\mx¯\9f3\ 3\95\eÙ¶½×ÏQ×î\90$ïâ^?çÝá5îãÛâ+\1eÆûø¶¯{°¾Õoýj\ eë{ý\9c·\88íOÛ®w¯\9f³'/Õ¼o\7f¯\9fó­~»©J[u>Ããßͽ~ÎûÍæS\ 4\9bÞëç|«ß\16÷ñ­qHÃé>¾­?¦£Þê·\93ûøVÆÒ.¾Þ°|¯ß:Wñ\99,Ìv÷ú-\15[\18nõS+\86¶¼×O\15/Ë[ý6©J[ßͱ\95±5ïõsrs^~!Þßɽ~»¨{]}¯\9f»º×mïõS¡¸¼\e}³{ýÖ;seq¯ßæÅðê­~\86û\91õ»Jk×<9Ýêçð\95³µîõ³±c²\e°´\8amx¯\9fóA§¥\9cÒ\86÷úÙ\95ÇÑ«8æ¾æ)\13\95[ßë·^\¹é½~\ 6õt«ß6§\aõ÷ú9K\84Çe\92wÕ½~Î\8e¡º\93¸å½~Î\ 5±Ú\8a¼Ý½~ηúYøc\eÝëçä\ 4I>Ì.îõsëÃlw¯\9fq&Í·ú9V×®q¯\9fóâ°¢\8aÓõ½~Î\8b\83ì)¡­ÊøÒòP£\1dH\96Ö\85å\13\1f¦ïJ%\ f¸ABZ÷u©]¼\8bi«ÎÎ\aï\8de\8b&;FGo\8c»7\87\ 6µ\ f\8eô)/l\98Õ\vAp\99\80R\ 2\95Ö'»Í'\88PE\98\1cZøb\89ÀE<Yã\ e\94\99(R³¼/ü%^'bþÌaòá"\95O1\91Ù÷Yb²h\ 5*½4\17>}>xÚó\9dÍC¾¼p\93Øk¾1\99\83ÆÃ~Ñ?\187j\81Þ÷4æñ3\8dÚï;;èÖ¾r\83\8fËïj¯Áq\97/\95ßû\ 69­~6¾¯ûûrâbqÿ^\ e\ 5ßß\v\91ÐO3õs5ªG\8e\91§Ü\ô7\82\ 1QL\1eøö&½IÂO\1c|\1f\85\9ej\9dû\b\17¹\bf\7f\ fF5¤ûþqQ\14O3u_øµ|á£ø«aä¨Cç\b\81\12Âí\83@\94÷'\97Dùêò[\14û§1qñ\9d\rÌ\ 2ÑË6\1a¸O®´Ìþ\96"'éËg4%>\öF\94îÙwqöu¾\8f´òªgi\90äyÁõ¥ÙÙ¼ø$äkÂIþ¤£]\ 1)Ý#\18à\7f\995$éÆ÷Ý\ 1øÉbnÌ\ú\1e\11«±J#]|Ä\ fÂ\87þÇúAúhÈûë\8dòyà£qvBs\87\17LD-\ e\85iz)ÅØÚá\ f\88ED\98í g1\9fØ\7f\ 5IF\ 5\9c7°´\\89F}*èÕçÃ?4äV\91;!ç[ymhÚê£çÃ)\eð\80àL(ºôÀÿÞç\12óp1ÂÑí\ 4_¢*9h»8Ï}ÞÝ^æ+ÌÇe\84K\9d\9c
+ÜÁM·ðz¾_Á#¥øf¤$©5ÞUÉ\96\1f\82è·`¤\18õ/\84`åì\8c,½e\8e=þB¿\95 Ñä\8cK\9dÁ/G$\1e\a1ê½Ò\8d\12\89Öo\f­ñ\aèDD\f½\r\væÉd\90<½Û\8b\8a\ fà`\88H¤è\10þ\138\96\9bÀ\9f\99\bþ\13\7fµéæ\17\1ar\18N\0 ö¢ø·äÁññ\87ð\1e\12\9fo¹¯ÜQÍ'\ 2ÝU=¡Qbü¡>\bë\1f\14ümõ\ 1:9¬{tGvÕGqý\83¯\93\ 1¡{\10;8ûV\1e\\86ðHÉrm¯¥¶Epg\8f_ê^~\8bwÔG1\1d\9cò4C ¶\84¼$¤.    T°4"+L\8dB\7fR\12ìö\9b_\85}\1d\91º´§$úJÇuL·¾\1c\80°\ 4Ñý0×q©S\87) 8×\ 4þl<Ù©\á?e°\9d§g\12\87)D¢)D\12\17\8dA\12\9eÞFñS*ÄdT¶ÜÆ\15,Dè MPÃ\86¿\14åBo¹#âþ@/\92J9¦\14a\9a¢WSÔ     `\13\9eÝ\80%t`ÉÄþì8rw$2Ù;ú2Ͼv\83R,ÆS¡§\86O\96äæ3\95\1fMj³|õááC\134*´è\ e\14&<Dµ©£\8a\95\13ä\13>HrN\15\9fÎHI\ 1\8a\9d«\14þ\r$¹8¼£äÖÅó\eV{ª\14j½/­\81heÓUÍ\9eLý:\ 3 ê§\95\ 1@5ï`\ 2\96\f@\8a>\86ß\8eÏs\89Ùô\14[\81â¢U¿²4\0¦ûseY<\1fI¡      \98è\90´cu\0\1ckmDétÿ\vê\1c\8d£9\bÂ\9f/3ô4\11)Ý?V\10+_ä\13Í)2\88¯ÙÄ7bÂ\9flXÒýÖ^\83Æ\90Qt\ 36Y\9e\rÐ}\l\8d|\8a'XÙïEIL{uöX2\9e\9fw\99gËä\bX\86\17YJÔ\1fè\ 1\19\r|'\90\1e\87\8cºÏÍQη\1aQI~\ 5¢Î\80Æl\ 1Û\9f ÄÕw§²åË\9e%\88T»z*Ù\83,{_)|\fò]ð\1d§¼Ü¥\9c       ¡É¹ÀQR\8d\ 5î¤%Á ËwÁ4Ìï×\95iWÍÊ\ 1Ñ;-Kñ¼\9câ^®­ÆëÁIâ\aû^øbe¢·\97Jhë'nC·Ý^Ë\vù\89\18Ñ;<\18ÀñiC\aàì%\1a×G|x½ËÞ½\87Ñ\19ã\9b9r_î\f\92\ f\85äú\1c>QçºåM*\90?¾Ò\0\98kÞ1\88\85\ 1Då°¢¹t\88'R==\9a!°¿ÑK
+\96\91,ØÃh%\82~\8b«m   µ\r&,ÚøEÞÅ<(J\82F\ 4ãO:Î+£Æ\1f{øP¾ip\82LæÅ\18?\b\ fn^@@è²ùc\aÈY\94\aD\87^ñýÈ\8a·\83>{ 8:¡&z°/»AûK\83\83y8\92ç\85\ fUUï¢ò\1aßû¹Ã\8e\ 5òG\90ѯO05\1e¿áÂdì\94\12Ç\92ìÕ@.ا\16$Bº§}å\ 2­á{
+5º\8aÿ°\8e\ 5Ïb²\8dY\0\16\ 6]_­1!Txê¾)L\88Ç\f\7fU&¼éY@}]«,xÒ³@ùæ\86²\93\98\9dg\7fW1¡u|©1!ù<$Óæ\93Ñ:¤º»£¹=åK\14NL\88kÒÿè\9b$J\92\1c\88|óÙ\9d\1cä\168\v\87E{áÓ\98à£gÏ\87*\13\1e\1dä@úµÄÅ\17;Az\94\ e\ 4Þ\9e_\ 5     Àý\ 4\ 3@ë˦ \9aSM#\9cõA\9d\173\88\97ß-\87ñ.j\0ìµÒ\11D{æv\18ò\1dÜË zó-\87ñ½0\89\94\12\17ª¡o}©4d­³õûñ\86Ú­\0hN¬\0ÀXÜ\83x\99nkaêï6FÊílÔÛ¢-\r\1e¿»aôf+g#| \ 3pZø\9d\18vF²õï-\85ª>X8\ 3\90\11ÄÄ·\9a\95\8eK\9e¸§ZKº9Ò@\10\95\8bfGß³ù¢ÊNSG-!¼V\8c÷#¿OUÎ\92z\19\93\97D\17\8ciöìç×¥\8c5¿gÛMNs`?»:\19s\ 41^l£®øntq\ 3£a a±çL\83$cNªÒnoªñ
+\80oQ\93±\rA\fÜL§ã\8aÜ\1eÏ·Ñx\0ð»ØvEn¶\7fõ\7f>íï\e\10ô~%\1f;\9bª\ 4¥úÊ\88ñûN\92\8bLôæ¹4öÌÔ\90ùM\17\ eF/Rð\1c8iJ¡0Jgã\1cNL\8eÊ\94@Q­ILUÔ¸³\12Ä¡\rÚ\ fBþh%\8c#l´Ç\89>\ e\\89Ê\7f\16âÈQ«ÄÕ×tQ§> ËÒ0\16\95ÐW¢\e\ff\94G\99°ö\0ç¸\94\a¹¨ö\80
+\9cÖ²Ê\ 3!®{ðºxË)\ fj\84\1e\8b)"Äa\8a\1es9\17Ñx§Ç\\16\ 3\1dX¢r-!Gâå+\ 2\7f\7f,\15I\1ep#\90§ò\1d\85`C4Ý\9as2\88z!\82ºDá\a\vëuý,¦Dw\8b°\1c>ÕkqÜ\ 5\10<\82`×o\bä6\93ð£\8bþ|¤ð\19\92ýpòô\16ü]<\83¡\83xHÉ\15\9dá¹\ 4,\ 5òHFÚ¼\8ac,I>\9dL\1fõÞB\9f\85oF¸â\87éý´>fÅ!\ e\18\94ÇoÚ\ 1\99\ 3Ø\9bÄú`\97êø\96ÁÞ\11\1aXæî$SÈß\1d\1e}\14¾Ùê4\7f\9b\1f? ±ç(þ9ü&§\81:\8f}5\17\96T\ 5íC\9bgdaÚ5MlZ\10ùÇÁ\8doßàüg\14}ª%$ýÖڻǩ\ 5ÄþFXú\8d\7fJVP\1a¨       Bu|&Ñ\8a¢\r-A\8c\83^%\ f\13Χ\ 3rì+I\7f}"\8bÈã ¢¨Ü\eÌå`/\9eèïÕ\ f%y\81xw¦¤Xâ\ 1èÒ\8cáÓ$8\e+%hP6\16\8d%\95\89\90\95\83\9f¬¤rªfÁ;÷\84¤whë\ 5\15ÓÄñi\19\94ä|\92ÔÐúèX\ 5_\94UPO\80©'ºq\ 6\17\85}æä-ÎQF\vþ©L2h¥\94\91\91\12Ä&]\9cµ\aüpo,\90Ñi\81(\9e\1fO\bèrEê´òM:\98$\89@ù$¬\8cï2\82\r\9c\96\9fÿï¬\87á\92¤\97#HÎ\9b¸Y\f\95Øÿê\8f½QÏ\91'\91?#É»qw"\88½Þmï_ó⤳\18õÆsoÆ\9bÈ7
+ggéT±×\99t{^ü\85\8aÔ\a«\v°%ì²ä&í¶\8d\8eÐÍb|ñ\93+\ f*û7'­â'ÑÌê\ 4\1e¯\1c¡då\ 4m)\81\8bd\aǾÐå\13ç\8b~÷áÑÇgÜ\17Yd\1a¾èÅcÑ\17#.(\88\84\9b\96\e³:MxbFODZ\ faÂ>$\89®E¦1{ÒÎG§\97ç¹*7˦+Ç\ fqaòDß\97Ä\97'\ 2\7fá\13ïÆ`˳¼}Xãlwɤ\ 1\85_\ 5\88\9da\ 4?\8f¾èý[        \88\7f\ 5c­=4¾sôãÈ\17Ë'ë0êÃ7_¨?Ìúbãë\17\13çвçw»R)\99ùuÖªõW*4ûë®Uë¯TúuÇíZµþJ\ 5XÖ^«Ö_©ÔSëk¬Uë¯T2\96U\8b
+\9aZ»EÅÅ"åño\ eÑýú\ 4\92ìr\85Úf}òø-W(m§Ýx:\ 6Þ\81¹UÔ>ãBí±Ò#ÝWÕ\1e\8cY\10Y·sdÇêH÷+¾hèôÖBí\ fÌj/I Ø;iµ,½äñ\8efXý¾bª1\95;µ~QBµ\896\18è J\r#M}\9f\v%ê"-+;ÊHö~zh\9f \12\92|\8dÏÀ/þ\13~4'Ò\ 6'\15Èù^åÝÉB\1c\7f\97ì¤\1eÅÌJô\1fçqiáëG3\11¼Ý\93<8*\9d[\1d\0\83       »¬*Û\1dò\ fôàNÞJɲ!M{±7\88t'{\12QH®Få\95ó\8e\8c[ìh&\94µ±F¨{\19¤~O\92ÿe¤m
+X\19Ãx|\927\88\1c\84\97¼~\ 5qØÊÖd\83_:Þ¨\9c\ e&\8cw\88)\19­\83Ò[Ê´5`Ü[\88é7\ 6:éªioÁç\9b\aÕäʬn\ 2\80£§p9NWòJ²ýd\12\ 4\89]hi`*È5\93\86-\10fßçç\ f\8a
+\80Ρ    \0ÂÂ't Há±Lj{z²ò¡\15\19yy\89~ö®\84½8$ Y,\9fJÛý¯ÒÖ\14\13ý«qDÛ\9dDµ½ ,\ 6\1fq\8b\94\ 3¶NÒ©\a¼ç!\1fnðøù\87pKÙ\80ÀB%çÞÍÛ\ fÈ\83ÜpûA:\8b\15Ú2÷N®H\15¬Î6\fÒS\85     ¹dÄðùï\ f\85\ 5tBc\ 1¢f Û~@>µ"ɶL8Í\fÆ
+\13Â~ãöCÌí6\14þZ \15\13NV'\1a\9cäà4S\9fk;0\1e¿\8b\8d(\93\1c Ò\8b\80ÂE¼s¤pQ/H\8e;YÈà\ 6×\ 2±\ 4\0ߪg\0\80¿©¾\ 6\béF°e\8d\aýn©\ΰÅ0¤\83ØË\0LZé\b\ 2ß_±î0,Îûm3\8c»LÂv[\ f}\97Ì\ 5\88·\1c±Öö¨    \0:O\1eø\ en£Ý(B\r9\ 3À»¥\8e ¸yx;\1a
\88r\12Ï\ 4Âål\90ÑZ$ê\82\ 6\8fß\81\8a;2¶Í>-\19}c%\91Òö\97×\1e\ 6x3n¥RÖý%\10Ó\ 2±\92\95NK^ìà\8cÄ\0f{å
+¯YKf\1fí ÿêz\82c\15\92{
+?¤Ö\ f\9dÇøÐ÷«í\85\15ÎâuO欴 ª2æÄ\98ò[ÜÍüÚÏnù\8b\8ei2¶Ñä\94§\197&C/cf\10\95\83\b«aTb\ 2¡ÈØfF\ 3\9dÄ#ÝÒ Ë\98\99\8aö\9b\7f;\8doOIÝtêVd÷ :\all»\15\99ìÄNâ[i|\87)\98ÕÕå\8a\8cOI¥È Å7É3ü¢1/\1a$#\ 3\16Ý¡Ñ|Sbà\8b±\1a\ 3ÇÔx\18â·¡\14ñ*é\9d¦|¸L\8dýäÈ0\15\ f(¿\91A\1c«È±\96îô\1a:(\96:\89*'WùÇgtØ­\10W^\14\12j ©??
+ëл\9aè\f\19\8f£©\a\11ý\83ZD:B\8ag¿ª?D
+\86´§¾\93Ð?\98\16´C²¦\10\ få«.õçcËwAõ|ì¥ñ|,\18\ 3õ èe\1cÇ        H5      )¸\ 6\1dC2}IJQgåô\ 6ýy­\87Ýþ\8a Î^Ë\81)ÈbFÝa\8c^àM.\1e\89\17\92\89ë\84|rõô\f±íZ\ 6Û¹¾Ã`Ñ]*Çû8©\83nÒñË)\9f\18\8d\84æVÇ\16*t\9a;©T\14%ÝÎoøaü+\9c¯w>kÅê\99¯a\11\86\16\8cIkÓ\aGx*T\11\8eÕä¬\19\1e\8e\91×\86x];ÑÒ½©yý W~}J\7få\e\8b\83~é©[G©ö[R\93^|o²\9aÈk¾%\15ñº¥õgSOYõ¼ñCL> z]@æá!¡\88ý\ 3Àn¿¢\80ë\81\92\ f¸ b\82eì!\89\7fW+'RÊÙÔ     \1a_âP:".¿x1\96%þª\17\96¦DM\1dayÁÇÂQxHÈÇÂ\1fJ-9s\85\82\ 5\9c\1d\r\15ðÛqöTK¦&¨bì9\82\15MÕ¦\18\96\1c¬k¨:ìQ=í©Üà\ eªgúÞ\82úa\8fÔ\19\81ê\87®å*_¥Ô\17§_Qü\167e^ñHÉÒ[÷\19\13\8ct1&)¡\94g\ 1ýóøu\1a¨\9d\v\ 6CiSÂtb\ÙoàÑj\1f\97ÇWÎEðÑQå`ð쿳\1e\90^´Ýð^\1awõ[\r\1e¿\1fZ\1a½ùb\8a:¤ÞùÞW\7f\kýé\89\1eÒ+ýCÀ?èÿT*åe9ô/áM¡ÆZÛ\13Ä]½TÈ[\e{üï\89¼8/ö;óþdÜ\12ÿx3¨éñ¢vwVôf¼Rßwè{ä\r\ 21Ä;ô\86G!´½ñ\ e\ 4¾{\bo\1eþ{ü\epç§ð£\b\7f]y\888Ť¼_\1eB&\ 6\81?Îá\97\1fhúÛK{/¼Ï¯\84·\8b^¾ñ\90\14Cx92\1dO'      Ò;\82¿I2N°\1c©5\92$KÆi\8aà¼i\96\8bÃ\1f\9c¾)     \18\8eGkbÓ\10vS\0A\83ÅÒd\9c\19F§þ\ 5o%\89t\9cÃo©]\92t:\9eÂo©\80Ô&\r\9dÖ¤\12¥ÂÒH7\8c®ãùD\\9bÂ\ fÄ,i®\ 6\0*\99\8a³t\92\ 2\84T<ͦ9Ä\87d\92\8eÃ\ 3hcã$A§\0<\ 5à9\96ÄM4\95fQ\13©4qÀx\8aõ\16àM\8a\8e³).\r³ÏÅi:M¡~L<\99\ 2 i\92\81&&  Md*\9efȤ7M\ 1ý4 E¯\ 2©I\92¡a\9cé8Å¡7\93\\9cå \17ÃÄÓi\f\8b â\1c\rÏÒ\1c\15ç\98t\1a¿H¤â$\87\1aY"N£FhJÆSÀ\1cx\15^H2À\fx!\95b\18o\9a\ 6Â(\ 6¿I¥SÐÈBc
+\b¢9Ô\8feâ)\8ea¡    xL\13)ÄG \87H\92\18\18A\91øM\86\8d\ 3oq\13I%½¸\81I\ 2\ 4ÜÂ0RK\92\ 6
+M\0´\0¡\ 4!õI¥ÓX$\80ëTZ\82\8dç\ 1M[<Ťi©)\89_\ 4Z`\82\19\14\13'\92\f©\87\95JÆY\86\18¡\89Fs¤Q\ 5-\14\99ÖS\9e\ 2V&\93\8caxt\12È¢%.P0UÐ\r\ 4\85¢\81£\0\80a)\84\ fd\ 2ä1M³è\7fè-\12\1e¡\96\14\87ÿ\ f\rÀL\98\96$f\ 4¼\0ÔÃß\1c0\9bÅo\900\ 1è\ 5`\fzN !gñ¯ =è\ 1 Pº\82\86$j\87¿P·4AâÇð&L3É »CÊÄ\90\Rn\ 2ñ¤I\18:\8c:Îby\ 5\9esHªI\10æ$C\81´²é8ä±V"\9a¸\14Í@#\rò\9a¤\116<v\80\ 5\12F\80jz\9b\1eÜH3lZk¬!ùOI\80Ì\8dé4È\94¡\11\ 6J¦HZÂ\9dJ"µXÒÅ¿°ÖJÿ\f\10i`'\90l\924Ìy\12©ªÚD\ 3\ e\02ôàq¦\f\rHY\90\$©8\9166é{qxv\96[dlòkð«±\rÐ%\91µ@\93µÔ¦ïg$~\bc\83\89\83YJ¥5´Ø
+³òË\1a)Z\eØ\ 4\ 4\ 5·QË\7f&\11ÅÒ\væ¿(Vý\8b\ 2e°n!ô\18ÓÒ°,Ú´ai#°jSG\80Æ
+¶1\95¢\rÓ§µé\aÂÉX¬Út<Áª²Ü {\v&<M\98 «m:zÍ\94Iô2\1cÖA\1dµr\v\86ÆH\9ccÐR\91´nÓ\91\96\96\19lѤ\7f\93\85Õ\85´iÓÑk¤\fQ\e^H\10\11p=Å áHäõx¹´ÔKkBË\85QÐ)Pî¤\ e\14n¢q'\8aÀdã\16I\9f\f\91²%¢0ka\rÆð\10¸\14VDD+\97\94¸\8bͪ\f\f¿*÷\19\9a\ 3¿ÃK:^\ 59Ò \j\93n¤`pÌ\7f\9dÄÞ\82u\936"3&<"ä\rèû\8dtM:|°Þ\9b)R\9a 'ú\13tÖü\12xG\ 69\87Å
+p G\81\94\94Bîd\9cB\ 4\89\e\r\17ÅJk\83¾Mß\8d4\8dY\96¯$R\7fìÉ \83\ eë\ 6\9a5\1a\89'\89\1c\v\12Ò,¥°3F\9bÛH2Åj/£FpF¸48#\86Æ\14rc8D&ø\80©\94$\v\80\ 6¯\12ÆF\ 6<\13\f¯/Q©\89\
\1c!\99M\8a¢$±\ 3g\92N\ 1 à§qiN\12Ú\14        Ä&Í\8dæ·uò\17Ã\a\98ÐÊOÒ\80\81\ 5\96Òþ®y\82\97!oXí\86ü?\86ÕºÉ\7f+ÝHÉS½\82\90wÍÄ\19\82£õï\ 1Ù°ä\13\ 4­\7fYߨ"Ö¿nÙ¨¾þ)±9Í!ÇÑ\80\8a\ 2\87\14\19_\ 3*µQ\83ª{ݲÑ\80*\85\97à\94     \15\a\9e\1eM\99\8d:¨Úë\96\8dFTà,¦\88¤\11U
+¬4\b\8b\11\95Ö¨\87ª¾nÙhD\ 5Ö\v\ 6Tà"\82L\99\8dz¨êë\96\8d:Tà\13\81YPã<0K\14\9c\19³\1c·\18\8d\1a\12Ýë\96\8dêë|\e¤2x7\1e·F½®÷Kluûè,\1e ñ*¡ÆÀÒÿÑOþË\ 3Î4xu\fþ3\ 6\83\ 6\8f\ fûÝ
+\15\f)!|\1cyÒØ1C­\86ÎHmh­#ßq\r\93·\85©\e\9c\ e.â+Ïc½3\84Ñz\85\ 1¾³)³\12Ê\8dF%\ 4[\9eJ\9aõͲQ}ݨ\84zTª¾éQ©\8d\1aTÝë\96\8d\ 6T\9aÂèQ©ú¦G¥6ê j¯[6\1a
+£C¥é\9b\ e\95Ö¨\87ª¾nÙhD¥*\8c\1e\95ªozTj£\1eªúºe£\ e\95\83\12ê1«ú¦Ç¬6jHt¯[6ª¯ï^        \91\82#\84+\95PéèB      Õ®n\94P\a×V        aY\8f³I\1a¨ hÐ19^\ 2|,\89òQJcÍÐ\ba\17ÐX3¼mÕ¦¾üi\9d¡\vÆÀ¡¢É\14\97\fy\13\8d¹Ø\1f\7fy\83<\9fït\16£\9bɼ\85úêrtØ\89`Ác5\11\v\81\1c\99¦MĪ\8d*aº·­ÚvN,¸RÒü\1a\88%@çQÒÈ@¬Ú¨\11¦½mÕ¶{b\93ñ\14\8cÄÂLB¸C\1a\89Õ\1au\84©o[µí\9eXpXÓ\1cc"\96\82\9d\e\88U\eu\84©o[µí\98X³9#!\ 2cÀ»7ÑNÄ\19\92N\9ahW\eU:uo[µ©/Û\183Z³e1Ùl\80Uc\92i:N¦QB\v~\ 5ãÁ\82ÿ\ fö-\ 6n<Ç&%c\84Í\vÊ\©d¡|,"\ 1Ì[\fB\88\14Ì6K\eú\82'ÎH\80\95¾`\89b°l&S\1c¹\ 2*o\v\15çá¨T\8aÖC\95íÛ\963\96пéM\Næ7½ÎDì\ 2\ fÑãU<KÜôZÃ\8b\16\17ôö\ 6\vù³²ÌúÛÏ\898\92\1eÉÂá\ræ»\93vï=\7fÆ¡Ý\88ÆüÏ°÷®á7\88\10é}ì¢9¥\9cçÔ´>a\8e0Þ`ÈûøàhùI"Nr´Éò+\8dFËÏàÈÖhå-Ú´\97wnù\rÄ*FÞ@¬jùUÂtVÞ¢m÷ĪvÚ@¬bä\rĪ\96_#L³ò\16mÿ\ 6b\15;­'V5òzb5˯#Lµò\16mÿ\ 6b\15;m V1ò\ 6bU˯#Lµò\16m»&ÖÞò\ehW\8c¼\81vÕò«tꬼE\9böòÿ        Ë\8f\17\1a Á\8dåWú®¶üjO\17\96_\aõÿ[þ\15\96\80¿\97\8c\91I»¿#é/\96å ôàÐÎ,H\13HTÊËJyci\97\1dí\0\12\1c\8c\9fãÔÇ$\93Ö½\8dþÒmc£¿Òd\9c`ðþ±ò*GQ*dùw´      ­ V\1ec*Õ·u4wÔü#Þ\91¦A\82H)wJB\0E¤Y­\91\84¸9\ e3\ 5\96\80eâiÚؤÛo\97\9b \86úßÓ33\ 5M\rÃÍ2\a\r\14[\80f¨!óíP\1e\1d\v4\12¡\ 4Xÿé\19\83\11\ 6Á\85\90çÛaBpGÁÍB8\1dÅwÉ\90¡Q\1f'Èr    ×¼\14ðª\ 6]]^UÕ\80ÄôÔ\90¢ÄÌ\9cÔ"ÞôâIJT\85ļ<P\ 2O-\0Ê\0\93LjqI~QªBqF~9H\ 4¨\ 5¦\UÕÕß\8d\17\0¨K.\ 5\rendstream\rendobj\r454 0 obj\r<</CreationDate(D:20090603145654-07'00')/Creator(Adobe Illustrator CS3)/ModDate(D:20090604104953-07'00')>>\rendobj\rxref\r0 459\r0000000003 65535 f\r
+0000000016 00000 n\r
+0000026058 00000 n\r
+0000000004 00000 f\r
+0000000006 00000 f\r
+0000028981 00000 n\r
+0000000007 00000 f\r
+0000000008 00000 f\r
+0000000009 00000 f\r
+0000000010 00000 f\r
+0000000011 00000 f\r
+0000000012 00000 f\r
+0000000013 00000 f\r
+0000000014 00000 f\r
+0000000018 00000 f\r
+0000026109 00000 n\r
+0000028838 00000 n\r
+0000028869 00000 n\r
+0000000019 00000 f\r
+0000000020 00000 f\r
+0000000021 00000 f\r
+0000000022 00000 f\r
+0000000026 00000 f\r
+0000026180 00000 n\r
+0000028722 00000 n\r
+0000028753 00000 n\r
+0000000027 00000 f\r
+0000000028 00000 f\r
+0000000029 00000 f\r
+0000000030 00000 f\r
+0000000031 00000 f\r
+0000000032 00000 f\r
+0000000033 00000 f\r
+0000000034 00000 f\r
+0000000035 00000 f\r
+0000000036 00000 f\r
+0000000037 00000 f\r
+0000000038 00000 f\r
+0000000039 00000 f\r
+0000000040 00000 f\r
+0000000044 00000 f\r
+0000026251 00000 n\r
+0000028606 00000 n\r
+0000028637 00000 n\r
+0000000045 00000 f\r
+0000000046 00000 f\r
+0000000047 00000 f\r
+0000000048 00000 f\r
+0000000052 00000 f\r
+0000026322 00000 n\r
+0000028490 00000 n\r
+0000028521 00000 n\r
+0000000053 00000 f\r
+0000000054 00000 f\r
+0000000055 00000 f\r
+0000000056 00000 f\r
+0000000057 00000 f\r
+0000000058 00000 f\r
+0000000059 00000 f\r
+0000000060 00000 f\r
+0000000061 00000 f\r
+0000000062 00000 f\r
+0000000063 00000 f\r
+0000000064 00000 f\r
+0000000065 00000 f\r
+0000000066 00000 f\r
+0000000070 00000 f\r
+0000026393 00000 n\r
+0000028374 00000 n\r
+0000028405 00000 n\r
+0000000071 00000 f\r
+0000000072 00000 f\r
+0000000073 00000 f\r
+0000000074 00000 f\r
+0000000078 00000 f\r
+0000026464 00000 n\r
+0000028258 00000 n\r
+0000028289 00000 n\r
+0000000079 00000 f\r
+0000000080 00000 f\r
+0000000081 00000 f\r
+0000000082 00000 f\r
+0000000083 00000 f\r
+0000000084 00000 f\r
+0000000085 00000 f\r
+0000000086 00000 f\r
+0000000087 00000 f\r
+0000000088 00000 f\r
+0000000089 00000 f\r
+0000000090 00000 f\r
+0000000091 00000 f\r
+0000000092 00000 f\r
+0000000096 00000 f\r
+0000026535 00000 n\r
+0000028142 00000 n\r
+0000028173 00000 n\r
+0000000097 00000 f\r
+0000000098 00000 f\r
+0000000099 00000 f\r
+0000000103 00000 f\r
+0000026606 00000 n\r
+0000028024 00000 n\r
+0000028056 00000 n\r
+0000000104 00000 f\r
+0000000105 00000 f\r
+0000000106 00000 f\r
+0000000107 00000 f\r
+0000000108 00000 f\r
+0000000109 00000 f\r
+0000000110 00000 f\r
+0000000111 00000 f\r
+0000000112 00000 f\r
+0000000113 00000 f\r
+0000000114 00000 f\r
+0000000115 00000 f\r
+0000000116 00000 f\r
+0000000117 00000 f\r
+0000000118 00000 f\r
+0000000122 00000 f\r
+0000026680 00000 n\r
+0000027906 00000 n\r
+0000027938 00000 n\r
+0000000123 00000 f\r
+0000000124 00000 f\r
+0000000125 00000 f\r
+0000000129 00000 f\r
+0000026754 00000 n\r
+0000027788 00000 n\r
+0000027820 00000 n\r
+0000000130 00000 f\r
+0000000131 00000 f\r
+0000000132 00000 f\r
+0000000133 00000 f\r
+0000000134 00000 f\r
+0000000135 00000 f\r
+0000000136 00000 f\r
+0000000137 00000 f\r
+0000000138 00000 f\r
+0000000139 00000 f\r
+0000000140 00000 f\r
+0000000141 00000 f\r
+0000000142 00000 f\r
+0000000143 00000 f\r
+0000000144 00000 f\r
+0000000145 00000 f\r
+0000000146 00000 f\r
+0000000147 00000 f\r
+0000000148 00000 f\r
+0000000149 00000 f\r
+0000000150 00000 f\r
+0000000151 00000 f\r
+0000000152 00000 f\r
+0000000153 00000 f\r
+0000000154 00000 f\r
+0000000155 00000 f\r
+0000000156 00000 f\r
+0000000157 00000 f\r
+0000000158 00000 f\r
+0000000159 00000 f\r
+0000000160 00000 f\r
+0000000161 00000 f\r
+0000000162 00000 f\r
+0000000163 00000 f\r
+0000000164 00000 f\r
+0000000165 00000 f\r
+0000000166 00000 f\r
+0000000167 00000 f\r
+0000000168 00000 f\r
+0000000169 00000 f\r
+0000000170 00000 f\r
+0000000171 00000 f\r
+0000000172 00000 f\r
+0000000173 00000 f\r
+0000000174 00000 f\r
+0000000175 00000 f\r
+0000000176 00000 f\r
+0000000177 00000 f\r
+0000000178 00000 f\r
+0000000179 00000 f\r
+0000000183 00000 f\r
+0000026828 00000 n\r
+0000027670 00000 n\r
+0000027702 00000 n\r
+0000000184 00000 f\r
+0000000185 00000 f\r
+0000000186 00000 f\r
+0000000187 00000 f\r
+0000000188 00000 f\r
+0000000189 00000 f\r
+0000000190 00000 f\r
+0000000191 00000 f\r
+0000000192 00000 f\r
+0000000193 00000 f\r
+0000000194 00000 f\r
+0000000195 00000 f\r
+0000000196 00000 f\r
+0000000197 00000 f\r
+0000000198 00000 f\r
+0000000199 00000 f\r
+0000000200 00000 f\r
+0000000201 00000 f\r
+0000000202 00000 f\r
+0000000203 00000 f\r
+0000000204 00000 f\r
+0000000205 00000 f\r
+0000000206 00000 f\r
+0000000207 00000 f\r
+0000000208 00000 f\r
+0000000209 00000 f\r
+0000000210 00000 f\r
+0000000211 00000 f\r
+0000000212 00000 f\r
+0000000213 00000 f\r
+0000000214 00000 f\r
+0000000215 00000 f\r
+0000000216 00000 f\r
+0000000217 00000 f\r
+0000000218 00000 f\r
+0000000219 00000 f\r
+0000000220 00000 f\r
+0000000221 00000 f\r
+0000000222 00000 f\r
+0000000223 00000 f\r
+0000000224 00000 f\r
+0000000225 00000 f\r
+0000000226 00000 f\r
+0000000227 00000 f\r
+0000000228 00000 f\r
+0000000229 00000 f\r
+0000000230 00000 f\r
+0000000231 00000 f\r
+0000000232 00000 f\r
+0000000233 00000 f\r
+0000000237 00000 f\r
+0000026902 00000 n\r
+0000027552 00000 n\r
+0000027584 00000 n\r
+0000000238 00000 f\r
+0000000239 00000 f\r
+0000000240 00000 f\r
+0000000241 00000 f\r
+0000000242 00000 f\r
+0000000243 00000 f\r
+0000000244 00000 f\r
+0000000245 00000 f\r
+0000000246 00000 f\r
+0000000247 00000 f\r
+0000000248 00000 f\r
+0000000249 00000 f\r
+0000000250 00000 f\r
+0000000251 00000 f\r
+0000000252 00000 f\r
+0000000253 00000 f\r
+0000000254 00000 f\r
+0000000255 00000 f\r
+0000000256 00000 f\r
+0000000257 00000 f\r
+0000000258 00000 f\r
+0000000259 00000 f\r
+0000000260 00000 f\r
+0000000261 00000 f\r
+0000000262 00000 f\r
+0000000263 00000 f\r
+0000000264 00000 f\r
+0000000265 00000 f\r
+0000000266 00000 f\r
+0000000267 00000 f\r
+0000000268 00000 f\r
+0000000269 00000 f\r
+0000000270 00000 f\r
+0000000271 00000 f\r
+0000000272 00000 f\r
+0000000273 00000 f\r
+0000000274 00000 f\r
+0000000275 00000 f\r
+0000000276 00000 f\r
+0000000277 00000 f\r
+0000000278 00000 f\r
+0000000279 00000 f\r
+0000000280 00000 f\r
+0000000281 00000 f\r
+0000000282 00000 f\r
+0000000283 00000 f\r
+0000000284 00000 f\r
+0000000285 00000 f\r
+0000000286 00000 f\r
+0000000287 00000 f\r
+0000000288 00000 f\r
+0000000289 00000 f\r
+0000000290 00000 f\r
+0000000291 00000 f\r
+0000000295 00000 f\r
+0000026976 00000 n\r
+0000027434 00000 n\r
+0000027466 00000 n\r
+0000000296 00000 f\r
+0000000297 00000 f\r
+0000000298 00000 f\r
+0000000299 00000 f\r
+0000000300 00000 f\r
+0000000301 00000 f\r
+0000000302 00000 f\r
+0000000303 00000 f\r
+0000000304 00000 f\r
+0000000305 00000 f\r
+0000000306 00000 f\r
+0000000307 00000 f\r
+0000000308 00000 f\r
+0000000309 00000 f\r
+0000000310 00000 f\r
+0000000311 00000 f\r
+0000000312 00000 f\r
+0000000313 00000 f\r
+0000000314 00000 f\r
+0000000315 00000 f\r
+0000000316 00000 f\r
+0000000317 00000 f\r
+0000000318 00000 f\r
+0000000319 00000 f\r
+0000000320 00000 f\r
+0000000321 00000 f\r
+0000000322 00000 f\r
+0000000323 00000 f\r
+0000000324 00000 f\r
+0000000325 00000 f\r
+0000000326 00000 f\r
+0000000327 00000 f\r
+0000000328 00000 f\r
+0000000329 00000 f\r
+0000000330 00000 f\r
+0000000331 00000 f\r
+0000000332 00000 f\r
+0000000333 00000 f\r
+0000000334 00000 f\r
+0000000335 00000 f\r
+0000000336 00000 f\r
+0000000337 00000 f\r
+0000000338 00000 f\r
+0000000339 00000 f\r
+0000000340 00000 f\r
+0000000341 00000 f\r
+0000000342 00000 f\r
+0000000343 00000 f\r
+0000000344 00000 f\r
+0000000345 00000 f\r
+0000000346 00000 f\r
+0000000347 00000 f\r
+0000000348 00000 f\r
+0000000349 00000 f\r
+0000000353 00001 f\r
+0000027050 00000 n\r
+0000027316 00000 n\r
+0000027348 00000 n\r
+0000000354 00000 f\r
+0000000355 00000 f\r
+0000000356 00000 f\r
+0000000357 00000 f\r
+0000000358 00000 f\r
+0000000359 00000 f\r
+0000000360 00000 f\r
+0000000361 00000 f\r
+0000000362 00000 f\r
+0000000363 00000 f\r
+0000000364 00000 f\r
+0000000365 00000 f\r
+0000000366 00000 f\r
+0000000367 00000 f\r
+0000000368 00000 f\r
+0000000369 00000 f\r
+0000000370 00000 f\r
+0000000371 00000 f\r
+0000000372 00000 f\r
+0000000373 00000 f\r
+0000000374 00000 f\r
+0000000375 00000 f\r
+0000000376 00000 f\r
+0000000377 00000 f\r
+0000000378 00000 f\r
+0000000379 00000 f\r
+0000000380 00000 f\r
+0000000381 00000 f\r
+0000000382 00000 f\r
+0000000383 00000 f\r
+0000000384 00000 f\r
+0000000385 00000 f\r
+0000000386 00000 f\r
+0000000387 00000 f\r
+0000000388 00000 f\r
+0000000389 00000 f\r
+0000000390 00000 f\r
+0000000391 00000 f\r
+0000000392 00000 f\r
+0000000393 00000 f\r
+0000000394 00000 f\r
+0000000395 00000 f\r
+0000000396 00000 f\r
+0000000397 00001 f\r
+0000000398 00000 f\r
+0000000399 00000 f\r
+0000000400 00000 f\r
+0000000406 00000 f\r
+0000034768 00000 n\r
+0000034844 00000 n\r
+0000035022 00000 n\r
+0000035933 00000 n\r
+0000052842 00000 n\r
+0000000411 00001 f\r
+0000028954 00000 n\r
+0000027124 00000 n\r
+0000027198 00000 n\r
+0000027230 00000 n\r
+0000000412 00001 f\r
+0000000413 00001 f\r
+0000000415 00001 f\r
+0000034140 00000 n\r
+0000000417 00001 f\r
+0000031078 00000 n\r
+0000000426 00001 f\r
+0000032832 00000 n\r
+0000032895 00000 n\r
+0000033125 00000 n\r
+0000033180 00000 n\r
+0000033818 00000 n\r
+0000033964 00000 n\r
+0000034061 00000 n\r
+0000031306 00000 n\r
+0000000427 00001 f\r
+0000000429 00001 f\r
+0000033754 00000 n\r
+0000000430 00001 f\r
+0000000432 00001 f\r
+0000031673 00000 n\r
+0000000433 00001 f\r
+0000000435 00001 f\r
+0000033690 00000 n\r
+0000000436 00001 f\r
+0000000442 00001 f\r
+0000033263 00000 n\r
+0000033409 00000 n\r
+0000033530 00000 n\r
+0000033611 00000 n\r
+0000032040 00000 n\r
+0000000443 00001 f\r
+0000000445 00001 f\r
+0000032768 00000 n\r
+0000000446 00001 f\r
+0000000449 00001 f\r
+0000032404 00000 n\r
+0000031192 00000 n\r
+0000000450 00001 f\r
+0000000451 00001 f\r
+0000000000 00001 f\r
+0000029401 00000 n\r
+0000030659 00000 n\r
+0000076660 00000 n\r
+0000034204 00000 n\r
+0000034254 00000 n\r
+0000030726 00000 n\r
+0000000367 00000 n\r
+trailer\r<</Size 459/Root 1 0 R/Info 454 0 R/ID[<A3DACB2CAA994ADF839A177E1EF222F1><94FD791731084F1087F9FE9BDDF38204>]>>\rstartxref\r76784\r%%EOF\r
\ No newline at end of file
diff --git a/doc/gfx_and_css/logo.pdf b/doc/gfx_and_css/logo.pdf
new file mode 100644 (file)
index 0000000..593dca4
--- /dev/null
@@ -0,0 +1,201 @@
+%PDF-1.4\r%âãÏÓ\r
+1 0 obj\r<</Metadata 50 0 R/Pages 2 0 R/Type/Catalog>>\rendobj\r50 0 obj\r<</Subtype/XML/Length 26031/Type/Metadata>>stream\r
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.1-c036 46.277092, Fri Feb 23 2007 14:16:18        ">
+   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+      <rdf:Description rdf:about=""
+            xmlns:dc="http://purl.org/dc/elements/1.1/">
+         <dc:format>application/pdf</dc:format>
+         <dc:title>
+            <rdf:Alt>
+               <rdf:li xml:lang="x-default">Netatalk_Logo</rdf:li>
+            </rdf:Alt>
+         </dc:title>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:xap="http://ns.adobe.com/xap/1.0/"
+            xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/">
+         <xap:CreatorTool>Adobe Illustrator CS3</xap:CreatorTool>
+         <xap:CreateDate>2009-06-04T10:50:16-07:00</xap:CreateDate>
+         <xap:ModifyDate>2009-06-04T10:50:16-07:00</xap:ModifyDate>
+         <xap:MetadataDate>2009-06-04T10:50:16-07:00</xap:MetadataDate>
+         <xap:Thumbnails>
+            <rdf:Alt>
+               <rdf:li rdf:parseType="Resource">
+                  <xapGImg:width>256</xapGImg:width>
+                  <xapGImg:height>256</xapGImg:height>
+                  <xapGImg:format>JPEG</xapGImg:format>
+                  <xapGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXYq7FUm8y+cvKnle1F15h1a10uEglPrMqoz06iNCebn2UHFXjHmr/nMz8u9NLxaBY3mvTLXjJQW&#xA;du3+zlDS/wDJLFXlHmH/AJzM/M2/LJpFnp+jwn7DLG1zOPm8remf+ReKvP8AV/z5/OLVSTdebNQT&#xA;l1FpILMda9LYQ4qxW98z+Zb5uV7q17dMepmuJZD0p+0x7YqlmKuxVM7LzP5lsW5WWrXtqw6GG4lj&#xA;PSn7LDtirKtI/Pn84tKINr5s1B+PQXcgvB1r0uRNir0Dy9/zmZ+ZtgVTV7PT9YhH22aNrac/J4m9&#xA;Mf8AIvFXq/lX/nMz8u9SKRa/Y3mgzNTlJQXluv8As4gsv/JLFXs/lrzl5U80WpuvL2rWuqQgAv8A&#xA;VpVdkr0EiA80PswGKpzirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVYL+Y351fl/wCQ&#xA;IGGt6gJNRpWLSbWkt21RUVSoEYP80hUYq+X/AMwf+cvfP2vNJa+Wo08t6aagSR0mvHXp8UzDinj8&#xA;Cgj+Y4q8O1DUtR1K8kvdRupr28mNZbm4kaWVz4s7lmP0nFVBEd2CopZj0UCpxVM7XyxrVxQi3Man&#xA;9qUhPwPxfhiqZQeRbtv7+6RP9RS/6+GKo2PyLZD+8uZG/wBUKv6+WKqy+SdIA3eZvcsv8FxVzeSd&#xA;II2eZfcMv8VxVRk8i2R/u7mRf9YK36uOKoOfyLdLX0LpH8A6lP1c8VSy68sa1b1JtzIo/aiIf8B8&#xA;X4Yqljo6MVdSrDqpFDiqvp+pajpt5He6ddTWV5CaxXNvI0UqHxV0KsPoOKvcfy+/5y98/aC0dr5l&#xA;jTzJpooDJJSG8RenwzKOL+PxqSf5hir6g/Ln86vy/wDP8CjRNQEeo0rLpN1SK7WgqaJUiQD+aMsM&#xA;VZ1irsVdirsVdirsVdirsVdirsVdirsVdirsVS/X/MOieXtKn1bW72Kw062XlNczNxUeAHdmPQKN&#xA;ydhir5K/Nr/nLzW9WabSfIavpOmmqPq8gH1yUdKxLuIFPju/f4Ttir50uLi4uZ5Li4leaeVi8ssj&#xA;F3ZjuWZjUknFUTp+j6hqDf6NESlaGU7IPpOKsnsPJNpHR72Qzt3jT4U+/wC0fwxVP7WytLVONvCk&#xA;Q/yQAT8z1OKq+KuxV2KuxV2KuxV2KuxVQurK0uk43EKSj/KAJHyPUYqkF/5JtJKvZSGBu0b/ABJ9&#xA;/wBofjirGNQ0fUNPb/SYiErQSjdD9IxVDW9xcW08dxbyvDPEweKWNijqw3DKwoQRir6L/KX/AJy8&#xA;1vSWh0nz4r6tpooiavGB9ciHSsq7CdR47P3+I7Yq+tdA8w6J5h0qDVtEvYr/AE65XlDcwtyU+IPd&#xA;WHQqdwdjiqYYq7FXYq7FXYq7FXYq7FXYq7FXYqwj81Pzd8q/lxo313V5PWv5w36O0qJh69ww+/hG&#xA;D9pyKD3NAVXwr+Zn5sebvzD1c32uXHG1jY/UtMhJFtbr0+FSd2p1dtz8tsVYjbWtxdTLDbxmSVui&#xA;rirL9I8m28PGXUCJpeohH2B8/wCb9WKskRERQiKFVdgoFAB8hiq7FXYq7FXYq7FXYq7FXYq7FXYq&#xA;7FXYqtdEdSjqGVtipFQR8jirG9X8m283KXTyIZephP2D8v5f1YqxC5tbi1maG4jMcq9VbFWXfln+&#xA;bHm78vNXF9odxytZGH13TJiTbXC9PiUHZqdHXcfLbFX3V+Vf5u+VfzH0b67pEno38AX9I6VKw9e3&#xA;Y/dzjJ+y4FD7GoCrN8VdirsVdirsVdirsVdirsVebfnZ+dmi/lnoqO6LfeYL5W/RmmcqAgbGaYjd&#xA;YlP0sdh3KqvgvzV5r17zVrlzrmu3b3mo3TVeRuir+yiL0RF6Ko2GKqWj6Hd6nNSMcIFP7yYjYew8&#xA;TirPNN0qz06D0rdKE/bkO7Mfc4qr3FxBbQtNO4jiQVZjirrW4W5to7hAVSVQ6hutDuPwxVVxV2Ku&#xA;xV2KuxV2KuxV2KuxV2KuxV2KuxV2KoPUtKs9Rg9K4SpH2JBsyn2OKsD1jQ7vTJqSDnAx/dzAbH2P&#xA;gcVVfKvmvXvKuuW2uaFdvZ6jatVJF6Mv7SOvR0boynY4q+9PyT/OzRfzM0V3RFsfMFiq/pPTOVQA&#xA;dhNCTu0TH6VOx7FlXpOKuxV2KuxV2KuxV2KsI/N381NG/LjyrJq97Se/m5RaVp3KjXE9PvEaVBdu&#xA;w9yAVX58+a/NWueateu9d1y5a61G8flI5+yo/ZRF/ZRBsqjoMVa0DQJtTm5NVLRD+8k8f8lff9WK&#xA;s/t7eC3hWGBBHEgoqjFXXNzBawPPO4SJBVmOKsA1rW7jVrkIoKW4akMPuduTe+KvQYYlihjiX7Ma&#xA;hR8gKYqvxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVicnmO50vWrm1uazWnqcgP2kD/EOPtv0xVk9t&#xA;dW91Cs9u4kifowxV1xbwXELQzoJInFGU4qwDX9Am0ybktXtHP7uTw/yW9/14q35U81a55V16013Q&#xA;7lrXUbN+Ubj7LD9pHX9pHGzKeoxV+g35Rfmpo35j+VY9XsqQX8PGLVdO5Va3np95jehKN3HuCAqz&#xA;fFXYq7FXYq7FUv8AMOv6V5e0S91vVp1ttOsImmuZm7KvYDuzHZQNydhir87vzY/MzV/zD83XGuXx&#xA;aO1WsOmWVfht7YElV225H7TnufamKse0PR5tTuxGKrAlDNJ4DwHucVeh29vDbwJBCoSKMUVRiqoz&#xA;KqlmICgVJOwAGKvP/MeuvqNx6cRIs4j8A/mP8x/hiqE0OH1tXtI+o9VWI9lPI/qxV6ZirsVdirsV&#xA;dirsVdirsVdirsVdirsVdirsVYH50i4axz/37ErfdVf+NcVQOj61daZPzjPKFj+9hPRh/A++KvQr&#xA;G+t762S4t25Rt94PcH3xVfcW8NxA8Eyh4pBRlOKvPNc0ebTLsxmrQPUwyeI8D7jFWQ/lP+Zmr/l5&#xA;5ut9csS0lq1IdTsq/DcWxILLvtyH2kPY+1cVfoj5e1/SvMOiWWt6TOtzp1/Es1tMvdW7EdmU7MDu&#xA;DscVTDFXYq7FXYq+Ov8AnLz82m1bW18h6TNXTdJcSau6HaW8p8MRp1WAHf8AyzvuoxV862ttNdXE&#xA;dvCvKWQ8VGKvSdK02DTrNLeLcjeR+7MepxVGYqxfzlrBijGnQtR5BynI7L2X6e+KsNxVO/J0XPW0&#xA;b/faO33jj/xtirP8VdirsVdirsVdirsVdirsVdirsVdirsVdirDfPaUurV/5kYfca/xxVi+KppoG&#xA;syaZdhiSbaSgmT2/mHuMVeiRyJIiyIwZHAZWHQg7g4qhdV02DUbN7eXYneN+6sOhxV5tdW01rcSW&#xA;8y8ZYzxYYq+iv+cQ/wA2m0nW28h6tNTTdWcyaQ7naK8p8UQr0WcDb/LG27HFX2LirsVdirBfzq/M&#xA;aDyB+X+oa2GH6RkH1XSYjQ8ruUHgaHqIwDI3suKvzpuLie5uJbi4kaWeZ2kllc1Znc1ZmJ6kk4qz&#xA;DybpHo251CVf3swpCD2Tx/2X6sVZNiqldXEdtbyzyfYiUu30CuKvMLu6lurmW4lNXlYsfp7fRiqj&#xA;irJPIyj9JTt3EJH3uv8ATFWbYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FWH+fP76z/1X/WuKsVx&#xA;V2Ksy8l6oZIn0+U1aIc4Sf5Sdx9BxVlGKsZ85aR61uNQiX97CKTAd08f9j+rFWH29xPbXEVxbyNF&#xA;PC6yRSoaMroaqykdCCMVfot+Sv5jQef/AMv9P1ssP0jGPqurRCg43cQHM0HQSAiRfZsVZ1irsVfE&#xA;v/OXv5gtr3n6Py1ayV03y2npyAH4XvJgGmbb+ReKb9CG8cVeJaPp7ahqEVtvwJrKR2QbnFXpaIqI&#xA;qIOKqAFA6ADYYquxVjvnW7MWmpbqaG4ff/VTc/jTFWD4q7FWReR3A1SVD+1CafMMuKs4xV2KuxV2&#xA;KuxV2KuxV2KuxV2KuxV2KuxV2KsH87zh9TjiH+6ohX5sSf1UxVjuKuxVGaPeGz1K3uK0VXAf/VbZ&#xA;vwOKvTsVWuiujI45KwIYHoQdjirzTWNPbT9QltjXgDWInuh3XFXtv/OIX5gtoPn6Ty1dSU03zInp&#xA;xgn4UvIQWhbf+deSbdSV8MVfbWKpN5y8y2vlfypq3mG6AMOl2stzwJpzZFJSMHxd6KPnir8zdS1C&#xA;81LUbrUb2QzXl7NJcXMp6vLKxd2PzZicVZj5F0O8+pSagLeR/rB4ROEYjghoaEDu36sVZR+jtQ/5&#xA;Zpf+Ab+mKu/R2of8s0v/AADf0xVhfnew1R7+CNbSYqkXLaNzuzH2/wAnFWOfonVf+WOf/kW/9MVd&#xA;+idV/wCWOf8A5Fv/AExVMvLtpqdrrFvI1pOEZvTYmN6UccfDxxV6L+jtQ/5Zpf8AgG/pirv0dqH/&#xA;ACzS/wDAN/TFXfo7UP8Alml/4Bv6YqteyvEALwSKCQASjDc9BuMVbawvlBZraUKNySjUA+7FUFdX&#xA;UFpEZrhikQFS1CRQ9DsDiqBm8w2MTFSk5K05fuZBTlsteQHWm2KrB5n00mhWZfcxN/DFUVBrGmz/&#xA;AGJgCezhk/4mFxVGqrMvJQWU9CNxirfB/wCU/dirVD4Yq7FVryRorO7BVUEsT2AxV5lql4b3UJ7k&#xA;9JGPEH+UbL+AxVCYq7FXYq9S0+Uy2FtKeskSMf8AZKDiqIxVjPnaw9S0jvUHxQHhIf8AIbp9zfrx&#xA;Vimm6heabqNrqNlIYbyymjuLaUdUliYOjD5MoOKv0y8m+ZbXzR5U0nzDagCHVLWK54A14M6gvGT4&#xA;o9VPyxV4x/zmZ5qOm/l3Y6BE/GbXrweotftW9mBK/wDyVaLFXxfb289zcRW9vG0s8zrHFEgLMzsa&#xA;KqgbkknFX3V5O8/an5Y8q6V5ftPy+1/0NMtYrcMLaQc2RQHc/B1d6sfniqcf8rj17/y3+v8A/SNJ&#xA;/wA0Yq7/AJXHr3/lv9f/AOkaT/mjFUt1H8+vM1pcekn5YeZ7leIb1IrSUrv22jOKoX/oYbzT/wCW&#xA;o81/9Ic3/VLFXf8AQw3mn/y1Hmv/AKQ5v+qWKu/6GG80/wDlqPNf/SHN/wBUsVTPT/zv8wXdv6rf&#xA;lx5kt2qQYpbSVW2+ce4xVE/8rj17/wAt/r//AEjSf80Yq7/lcevf+W/1/wD6RpP+aMVYD+aX53a1&#xA;Ppthb/4A1+1EWqWMoubq0mihd45wwhjZkXlJJ9lAOpxVGebvz58zX3lTWrKT8sPM9pHdWFzC93Na&#xA;SrFEskLKZJCYxRUrU+2KsF8z/mxrd5/zj3D5Xk8ja5a2S6Pp1qPMMtvILEpAIQs4kKBfTl4fAeXc&#xA;Yq7zz+bGt6jq3mKeXyNrli17FoSyQ3FvIrQCzubp0MoKCguDKVj8SpxViM/n7VG6+V9TX5xP/wA0&#xA;4ql8/nTUW6+XdRX5xN/zTiqBfzhqSklNFv4z4hGH8MVWjz5qgNJdIunX3QhvvpiqOtdfg1Bfhglg&#xA;k7xTIVb6Ox+jFVs45dTx+eKsV8z3ogAtYj6juKyFeir4V8TirE3NWrSmKrcVdirsVem6MpGkWQJr&#xA;+4jP3qDiqNxVQvbVLq0mt26SoV+RI2P0HFXlzoyOyMKMpIYe4xV9pf8AOGfmo6l+Xd9oEr8ptBvD&#xA;6a1+zb3gMqf8lVlxV5R/zmZ5hN/+ZtnpCNWHR9PjVk8J7lmlc/TH6eKvKvyyv49M896Pq0tqLxNM&#xA;nW9+rs3AM8Hxx1YBqUkCnpir6n/6Gnv/APqXYv8ApKb/AKp4q7/oae//AOpdi/6Sm/6p4q7/AKGn&#xA;v/8AqXYv+kpv+qeKpN5g/wCcxtU0p4QvlaGVJg3xG7daFabf3R8cVSn/AKHj1X/qUYP+k1/+qOKu&#xA;/wCh49V/6lGD/pNf/qjirv8AoePVf+pRg/6TX/6o4q4f85x6nUV8owU70vX/AOqOKp63/OZMS6eL&#xA;79BQmM7BBdNz5Urx4+n1xVIz/wA5x6nU8fKMFO1b16/8mcVY355/5yx1DzXptjZSeW4bQWWo2mpB&#xA;1umfkbOUSiOhiWnKlK9sVTTX/wDnM3U9Y0LUtJbyrDCuo2s1o0wvHYoJ42j5U9IVpyrTFWL61/zk&#xA;rfap+Usf5dtoMUUMenWmm/pEXLMxFmIwJPT9MD4vR6ctq4q7zP8A85K32vX+r3j6DFbnVk0uNkFw&#xA;zen+ipp5lIPpivqfWaHwp3xVIJfzoupP+lUg/wCex/5oxVCS/mzcSf8AStQf89T/AM04qhJPzJnf&#xA;/jwUf89D/wA04qhJfPUr/wDHmo/2Z/5pxVCyebJXNRbhT2Ic/wBMVRCedpjbuksHKUD90/Lav+Vt&#xA;iqRz6i8zMzLVmNSScVQrNyNcVaxV2KtqpZgqirE0A9zir1WCIRQRxDpGqqP9iKYqqYq7FXnXme1+&#xA;r61cACiyESr/ALMVP/DVxV7R/wA4Z+YTYfmbeaQ7Uh1jT5FVPGe2ZZUP0R+pirz/APPnVzqv5xeb&#xA;Lonlw1CS0B36WYFsOv8AxhxVKfIsHK7up/5EVP8AgzX/AI0xV9R/kd+V3k3zX5Tu9R1u0ee7iv5L&#xA;dHWaSMCNYYXAojAfakOKo784PyX8raH5Mm1jy9ayQXNlLG9zylklDQOfTbZyejMpr4VxVb+Tf5Te&#xA;SPM3kqLVNYs5Jr1p5oy6zSxjihAX4UYDFWD/APOU/wCVvlXyz5e0i50C1eCZ5pmnLSyS1RFTYcy1&#xA;Kc64qnX5Ff8AOPf5W+bfyq0PzBrmmy3GqXv1r6xKlzPGD6V5NClERwookYGwxVnv/Qp/5Jf9Wef/&#xA;AKTLn/qpirxz/nJ38l/y+8h+UtK1Hy1YyWt3dX4t5neeaYGP0ZHpSRmA+JRir2P/AKFP/JL/AKs8&#xA;/wD0mXP/AFUxV3/Qp/5Jf9Wef/pMuf8Aqpirv+hT/wAkv+rPP/0mXP8A1UxV8Q+cNOtdN8263p1o&#xA;pS0sr+6t7dCSxEcUzIgJO5oq4q9P/wCcVfINh5r/ADIabVbKK+0fR7WS4uba5jWWCSSX9zCjo4ZW&#xA;+2ziv8uKvsT/AJVP+Vn/AFJuh/8AcNs/+qeKsH/O78t/y7078p/M99p/lbSLO9t7NngurewtopY2&#xA;5L8SOkYZT8jir5K/Irynonm381dD8v65C1xpd79a+sRI7Rk+lZzTJR0IYUeMHY4q+uP+hT/yS/6s&#xA;8/8A0mXP/VTFXf8AQp/5Jf8AVnn/AOky5/6qYqkH5gf84y/k/o/kPzJq9hpU0d9p2l3t3aSG7uGC&#xA;ywW7yRkqzkGjKNjirwD/AJxs/LnQPPvn+40vX4HuNLtdPmu5I0keIl1kiiT44yD1lrSuKvp7/oU/&#xA;8kv+rPP/ANJlz/1UxViv5qf84y/ldo/5deYdX0LTJoNV06yku7eVrmeQL6A9R6o7sp+BW6jFXx5p&#xA;8STX9tDIKxySojjpszAHFX3b/wBCn/kl/wBWef8A6TLn/qpir5u/5yd/Ljyn5D826Vp3lq1e1tLq&#xA;wFxMjyyTEyetIlayFiPhUYqx38gvKmk+avzY0PRdXga40yb6zJcxKzIf3NrLLGeSEHaRFxV9mf8A&#xA;Qv35Xf8AVtl/6SZ/+a8VeQ6J+Wej6p+dWoeWkgcaBpzyyzxB25CFEAVedeW8jqOuKvXX/ID8rEUu&#xA;+nyKqglmN1OAAOpJ54q+J/zXj0s+ZJLjSojDpkkkyWUZYsRCkh9OpYkk8WFcVRH5DaudK/OLyndA&#xA;8eeoR2hO/S8Btj0/4zYqxXzPetfeZdWvW3a6vbiYnbrJKzdtu+Ksh8ix0srmT+aQL/wK1/42xV9h&#xA;f84xf8oFf/8AbVm/6h7fFXqOuaTb6xo19pVx/cX0ElvIfASKVqPcVrirBvyEsriw8htY3K8Lm0v7&#xA;uCZPB45OLD7xirD/APnKpFfTfL6OOStJdBgehBSMHFWWf8442P1H8mtAta8hG19xP+S1/cMtfoOK&#xA;t/n9+ZOu/l55Gj1/RYLW4vHvYbUx3qSPFwkSRiaRSQty+AftYq+QPzS/P/zj+ZOj2mla5Z6dbW9n&#xA;cfWonsY543L8GjoxlmmFKOe2KvXPyw/5yt/MTzV5/wBD8u6hp2kRWWpXIgnkt4blZQpUmqF7l1B2&#xA;7qcVfVmKvmf87v8AnJrz55E/MS/8taRYaXPY2sdu8cl3FcPKTNCsjVMdxEvVtvhxV8n6zqlxq2sX&#xA;2q3KolxqFxLdTJGCEDzOZGChixpVtqk4q+zP+cNvKX6L/Li61+VALjzBds0b9zbWlYYwf+evqnFX&#xA;u7XUC3cdozUnljkljTxSJkVz9BlXFXn3/ORUzw/kr5qdKVNsiGvhJPGh/BsVfCPkLzrqvkjzZY+Z&#xA;9Kignv8AT/V9GK6V3hPrQvA3JY3ib7MppRhvir62/wCcd/z/APOP5k+Z9S0rXLPTra3s7I3UT2Mc&#xA;8bl/VSOjGWaYcaOe2KvfsVfEPm//AJy0/MbVtN1ry5c6do6WOoQ3WnTSRw3QlEUyNCzKWuWXlxba&#xA;qkV7Yqyv/nB7S+ep+a9VI/uYbS1Rtt/WeSRwNv8AilcVfWLyRxqGkYIpIUFiAOTEKo37kmgxVB69&#xA;piaroWo6W/2L+1mtWrsKTRsh6f62KvzF01Hj1i1RwVdLiNWU9QQ4BGKv1IxV8a/85tf8p/oX/bKH&#xA;/UTLiqT/APOKFh6f5m6ReuPimN0kf+qtnNU/S36sVfcWKsF8geW/qvmrzjr8qUk1HUDb25I/3Tbq&#xA;ORB8GkYg/wCrirf51eZv0B+XmpSxtxur9RYW29DyuAQ5HusQdh8sVfDHnqOtlbSfyyFf+CWv/GuK&#xA;se8sXrWPmXSb1dmtb23mB26xyq3fbtiqWYqzrySoGkOf5pmJ/wCBUYq+vP8AnGL/AJQK/wD+2rN/&#xA;1D2+KvXsVQem6Xbaebv6uOK3dw9060oA8gXn/wAEwLfTirxb/nKf/jn+Xf8AjLc/8RjxVm/5D/8A&#xA;kqND/wCjr/qMmxVMvzL/AC20L8w/Lq6BrU91b2aXCXQksnjSXnGrKBWWOZePxn9nFXyR/wA5Hfkd&#xA;5T/LOy0KfQbu/uX1OS4ScX0kMgUQrGV4elDDT7ZrWuKsO/IH/wAnL5T/AOY5f+Itir9FMVfBf/OW&#xA;H/k7dY/4wWf/AFDR4q8ltLW4u7qG0t0MlxcSLFDGOrO5Cqo+ZOKv028m+XLfy15T0jy/BQx6XaQ2&#xA;vNRQO0aAO/zdqsfnirFvLfmAa1+c3m60iblb+WdO06wIrUeveNNcykU/yVjU+64qgf8AnJqcQfkd&#xA;5ocjlWO1SnT+8vYUr9HLFX59Yq+iv+cJf+U/13/tlH/qJixV9lYq/LbVv+Oref8AGeT/AImcVfYn&#xA;/OFOl+h+Xesaiwo97qjRg+McEEVD1/mkYYq9Q/NXXzo2neXzy4Lf+YtIs5D0HCS7V2r7UjrirNcV&#xA;fm9590j9Efm9remgcY7fW5hEN/7trktH1/yCMVfpDir46/5zQt5Ln8x/L0EYq8umKi/M3MoxVU/5&#xA;x8to7b8zvL1vGKJEtyq/RZzYq+wcVaREQURQoJLEDbdjUn6Sa4q+df8AnKHWbl9b0jReLLbW9u13&#xA;y/Zd5nMf/CCL8cVfOHnZQdIQ/wAsykf8CwxVguKuxVnXklgdIcfyzMD/AMCpxV9ef84xf8oFf/8A&#xA;bVm/6h7fFXqdxqcFvqNnYybSXqymE16tCFYr/wACSfoxVF4q8K/5yn/45/l3/jLc/wDEY8VZv+Q/&#xA;/kqND/6Ov+oybFV/51fmLe/l75Gl8x2dnHfTx3EMAgmZlQiUkE1XfamKvjX84/z21b8z7bS4L/S4&#xA;NOGlvM8Zgd3LmYIDXn4eniqA/IH/AMnL5T/5jl/4i2Kv0UxV8F/85Yf+Tt1j/jBZ/wDUNHiqG/5x&#xA;i8pf4j/N/STInO00blqtx7G3p6P/ACXePFX37irzv8qPy01jyhqvmzVtY1GLUL7zPf8A152hVkWM&#xA;AyME+Lw9Uj5Yqln/ADlNLGn5F+Y1Y0aVrFEG+5F/A1PuU4q+AsVfRX/OEv8Ayn+u/wDbKP8A1ExY&#xA;q+ysVfltq3/HVvP+M8n/ABM4q+8/+cXdLNh+Segll4yXhubpxSn95cyBDv4xquKrf+chfKnnbzLp&#xA;flmDyrp/1+XTdag1O6AmggKLbI4U1meOu8h+zir1jFXwp/zkvpB0/wDP+6lA4x6ibC7QD3jSJj9L&#xA;wscVfdeKvj3/AJzLvJLL8y/Lt1GAXi0sEA9CDcSgj7jirv8AnHq7hvPzN8v3MJrHILojxB+pzVB+&#xA;RxV9hYqpW9zDcIzxNyCO8TezRsUYfeMVeM/85PeX/rGgaZrsa1ewna3mI/33cCoJ9leMD/ZYq+UP&#xA;OzAaQg/mmUD/AIFjirBcVTPzPZNY+ZdWsm2a1vbiEjbrHKy9tu2Ksh8iyVsrmP8AlkDf8EtP+NcV&#xA;fYX/ADjF/wAoFf8A/bVm/wCoe3xVH/nTr58v6l5N1jlxjtdTYzkdfRePhMPpjZsVengggEGoPQ4q&#xA;8K/5yn/45/l7/jLc/wDEY8VZh/zj1dx3f5QaFPF/ds16qnxCX861+njiq/8APb8vNa8/+QJvLujT&#xA;W1veyXME4kvGkSLjExLCsaStXw+HFXyL+Y//ADjZ558geWX8xazfaZcWUcscBjs5bh5eUpoppJBE&#xA;tPH4sVSf8gf/ACcvlP8A5jl/4i2Kv0UxV8F/85Yf+Tt1j/jBZ/8AUNHir2H/AJwp8pfVfLOt+aZo&#xA;6S6ncLZWjEb+jajk7L7PJLQ/6mKvd/PHm2w8oeU9T8yX6NJa6ZCZWiUgM7EhURSdqu7BRiqXfld+&#xA;Ydr+YHlKHzJaWUthbzSywpBOQzH0m4lgV2IJxVhn/OWJA/JLVwTQmezA9z9ZQ4q+C8VfRX/OEv8A&#xA;yn+u/wDbKP8A1ExYq+ysVfltq3/HVvP+M8n/ABM4q/SH8rNLGl/lr5WsOPFoNKsxKKU/eNCrSfe5&#xA;OKonzh5+8oeTbSC78zalHptvdSGK3eRXfm4XkQBGrnYDwxVPIZopoUmiYPFKoeNx0KsKgj6MVfJn&#xA;/OZGkel+YHk7V6UF5bm0r4m1uRJ/2NYq+tsVeA/85EfkB5x/MnzPpuq6HeadbW9nZC1lS+knjcv6&#xA;ryVURQzDjRx3xV5h+R3lvVvI3/ORVr5I1iaCe9sxNIZLVneEtLprz0RpEib7EgrVRuDir7NxVhP5&#xA;f639Z8w+ctIdqvp+qeqg8IrmMUH/AAcbH6cVTb8wPL/+IPJesaQF5y3Ns5t1/wCLo/3kX/JRFxV+&#xA;f/np6WVtEerSlqf6qkf8bYqx7yxZNfeZdJsl3a6vbeEDbrJKq99u+Ksq/PnSDpX5xebLUjjz1CS7&#xA;A36XgFyOv/GbFUp8iz8bu6g/nRX/AOANP+N8VfVH5E/mX5J8r+UbvT9d1L6ndy6hJcRxejPLWNoY&#xA;UDcoo3X7SNtXFUJ+ff5ieTvNWkaVb6DqH1ya2uHkmX0Z4uKslAayogO/hirNvJH56+Q4vKOlQa5q&#xA;pt9Wgt0hu4jb3LnlF8AblHG6Hmqhtj3xV5j/AM5P/mZ5S8weXNO/w/qH1ya3adZR6U0XH1giqayp&#xA;HXoemKpp+Qn59/lP5V/KfQtB17XfqerWf1r6zbfVbyXj6t5NKnxxQuhqjqdmxVn/AP0NH+RP/Uzf&#xA;9OOof9k+KvMP+cjfzw/K7zh+Wk+i+XNa+vam93byrb/VbuGqRsSx5zQxpt88VfP/AOUGv6T5f/Mv&#xA;y9rWrz/VtMsbtZbq44PJwQKRXhGruevYYq+z/wDoaP8AIn/qZv8Apx1D/snxV8kf85CebvL3m380&#xA;tS1zy/d/XdLuIrZIrj05YqmOBEccJljcUYEbjFXoH5ef85aWnkryXpXli08nfWI9Nh4PcfpH0/Vl&#xA;djJLJw+qvx5yOzU5GnjiqWfm9/zlHc/mF5Nk8sw+X/0PHPPFLcXH136zzjhJcR8PQhpVwrV5dumK&#xA;on8q/wDnKlPIPkbT/Ky+Vf0gbJp2e9+v+h6hmneWvp/V5ePEOF+12riqG/N7/nJ//lYnk2Ty3/hr&#xA;9F+pPFP9b+vfWKekSePp/V4etevLFXhWKvaP+cXPzC8n+R/N+rah5o1D9H2dzp5t4JfRnn5SetG/&#xA;HjAkrD4VO5FMVfS//Q0f5E/9TN/046h/2T4q+C7t4LjVZn9TjbzTsfVoTRGcnlx69N6Yq+8YP+cn&#xA;fyFghjhj8y8Y4lCIPqOobKooP+PfFXgn/OVX5ueTfPSeXLTypqP6QtrE3Ut63o3EAEknpLEKTxxV&#xA;2V+leuKvZ/J//OTf5NW3lHRLbU/MXoalBp9rHewmzvmKTpCqyryjgKGjgiqmnhirzH/nJX82Pyu8&#xA;66X5ck8uayL6/wBL1HnNF9Wu4SttKlZHrNDGpo0SbA19sVey/wDQ0f5E/wDUzf8ATjqH/ZPirv8A&#xA;oaP8if8AqZv+nHUP+yfFXgH/ACtHyJ/0Nj/jz9J/86p/1cvQuP8Aqz/Vf7n0/W/vvh+x79N8VfS3&#xA;/K+fyo/6vn/Tref9UcVeXeUfzQ8saX+b/mPWLi94+XtXVxHdelMaupRo29MIZOzD7PfFXqP/ACvj&#xA;8qP+r5/063n/AFRxV8Vfnbc6LL51u10ScXGlNLLcWkgR4xwnfkF4uFYcKcdx2xVT/IbSDqv5xeU7&#xA;UDlw1CO7I36WYNyen/GHFXoH/OZnl42H5m2erotIdY0+NmfxntmaJx9Efp4q8X8sXX1fWrck0WQm&#xA;Jv8AZig/4amKvRcVdiraippiqVeZ9NF3awQGUoC5c0Fa8RTx/wArFUhTybE3/H0w/wBgP64qiE8h&#xA;wt/x+MP9gP8AmrFUQn5cwt/x/MP+eY/5qxVER/lfA3/SwYf88h/zViqJj/KS3f8A6WTj/nkP+asV&#xA;REf5NWzf9LVx/wA8R/zXiqKsvyMtbi/trU6u6idbpi/oA0+rWU92Nuf7Rt+P01xVkXl7/nGOx1a/&#xA;8n2reYJYR5o0FtckcWyt6DKts3ogeoOY/wBK+1t06Yqm1j/ziPp1z581XyufMsyx6bYWd8t19UUl&#xA;zdyTIUKertx9DrXvirtf/wCcR9O0rzR5X0RfMs0q+Yri7gec2iqYRa2cl0CF9U8uRi49RirIv+hH&#xA;NK/6m6f/AKQk/wCq2Ku/6Ec0r/qbp/8ApCT/AKrYq7/oRzSv+pun/wCkJP8Aqtirv+hHNK/6m6f/&#xA;AKQk/wCq2Ku/6Ec0r/qbp/8ApCT/AKrYq7/oRzSv+pun/wCkJP8Aqtirv+hHNK/6m6f/AKQk/wCq&#xA;2Ku/6Ec0r/qbp/8ApCT/AKrYq7/oRzSv+pun/wCkJP8Aqtirv+hHNK/6m6f/AKQk/wCq2Ku/6Ec0&#xA;r/qbp/8ApCT/AKrYqyeL/nFWwSJEPmOZiqhS31Vd6Clf73FV/wD0Kxp//UxS/wDSMv8A1UxV3/Qr&#xA;Gn/9TFL/ANIy/wDVTFXyZ+alhZ6Z+YGtaTZ3RvLfTLg2S3DKELPAOEvwgtSkoYdcVeo/84Z+Xjf/&#xA;AJm3mrutYdH0+RlfwnuWWJB9MfqYq9X/AOczPKp1L8u7HX4k5TaDeD1Gp9m3vAIn/wCSqxYq+LUd&#xA;kdXU0ZSCp9xir1GyukurSG4XpKgb5EjcfQcVV8VbUVOKpP5k0xbqW3Bmkj4K32DTqR/TFUtj8sxN&#xA;/wAflwP9kP6Yqio/KMLf8f1yPk4/piqKj8kwt/0sbsfJx/TFUVH5Cgb/AKWd4Pk4/piqLi/Lm3b/&#xA;AKW18PlIP6Yqio/yxtm/6XGoD5SD+mKo3T/yntJtTtLc63qSCZbwl1lAYehp9zcCm37Rh4t/kk4q&#xA;ynyt+RFjqOp+RLdvMusQDXvLT6tI8U6hrdglofQg+H4Yv3/T2GKp5p3/ADjlp0/5la1oJ82a6kdl&#xA;pljdreLcKJ3NxLcIUduO6J6NVHucVd5n/wCcctO0/wA5eTdKXzZrsy61c3sT3EtwplgEFjLcBoTx&#xA;+EsY+Lf5JxVlX/QqWlf9Tt5k/wCkpP8AmjFXf9CpaV/1O3mT/pKT/mjFXf8AQqWlf9Tt5k/6Sk/5&#xA;oxV3/QqWlf8AU7eZP+kpP+aMVd/0KlpX/U7eZP8ApKT/AJoxV3/QqWlf9Tt5k/6Sk/5oxV3/AEKl&#xA;pX/U7eZP+kpP+aMVd/0KlpX/AFO3mT/pKT/mjFXf9CpaV/1O3mT/AKSk/wCaMVd/0KlpX/U7eZP+&#xA;kpP+aMVd/wBCpaV/1O3mT/pKT/mjFU6tf+ceNPt7eOAeatccRqFDtcKSadz8OKqn/Qv9h/1NGtf8&#xA;j1/5pxVJ/OX5SaL5Y8qat5guvNGs+jplrLccTcL8TIp4J9nq70UfPFXw5NLJNK80rF5ZGLu7GpLM&#xA;akk+5xV9o/8AOGflU6b+Xd9r8qcZtevD6bU+1b2YMSf8lWlxV7P5y8tWvmjypq3l66IEOqWsttzI&#xA;rwZ1ISQDxR6MPlir8zdS0+803UbrTr2Mw3llNJb3MR6pLExR1PyZSMVZX5Jv/UtJLJz8UB5xj/Ib&#xA;r9zfrxVk2KuxViHnxP3lm9Ooda/Iqf44qxTFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F&#xA;XYq7FXYq7FXqOmxmPTrWM9UhjU/QoGKonFWM+dr/ANO0jskPxTnnIP8AIXp97fqxVimm6fealqNr&#xA;p1lGZry9mjt7aIdXllYIij5swGKv0y8m+WrXyv5U0ny9akGHS7WK25gU5sigPIR4u9WPzxVOcVfE&#xA;v/OXv5fNoPn6PzLax003zInqSED4UvIQFmXb+deL79SW8MVeJaPqDafqEVyK8AaSgd0OzYq9LR1d&#xA;FdDyVgCpHQg7jFV2KsW87TWclrFGJUNzFJX0wasFIINadN6Yqw7FXYq7FXYq7FXYq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq7FXYq7FXYqrWkBuLqGAdZXVB/sjTFXqYAAAGwHQYq07qiM7niqgliegA3OKvNN&#xA;Y1BtQ1CW534E0iB7INhir23/AJxC/L5te8/SeZbqOum+W09SMkfC95MCsK7/AMi8n26EL44q+2sV&#xA;dirBfzq/LmDz/wDl/qGiBR+kYx9a0mU0HG7iB4Cp6CQExt7Nir86bi3ntriW3uI2inhdo5YnFGV0&#xA;NGVgehBGKsw8nawJbZrGdqPAOUTE9Y+4/wBj+rFUDr/muWZ2trBikI2ecbM/+qewxVjRJJqeuKtY&#xA;q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FV8UskUiyRsUkU1VlNCD88VTe283a&#xA;1DQNKsyjtIoP4rxOKq2p+bp73TmtRD6LyGkjq1QU8BttXFUjt7ee5uIre3jaWeZ1jiiQVZnc0VVA&#xA;6kk4q/Rb8lfy5g8gfl/p+iFR+kZB9a1aUUPK7lA5io6iMARr7LirOsVdirsVfHX/ADl5+UraTra+&#xA;fNJhppurOI9XRBtFeU+GU06LOBv/AJY33YYq+cVZlNVJBoRUbbEUOKtYq7FXYq7FXYq7FXYq7FXY&#xA;q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq+j/APnEP8pW1bW28+atDXTdJcx6QjjaW8p8&#xA;Uor1WAHb/LO26nFX2LirsVdirsVS/wAw6BpXmHRL3RNWgW506/iaG5hburdwezKd1I3B3GKvzu/N&#xA;j8s9X/LzzdcaHfBpLVqzaZe0+G4tiSFbbbkPsuOx9qYqwzFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq7FXYq7FXYq7FXYqzP8p/yz1f8AMPzdb6HYho7VaTane0+G3tgQGbfbkfsoO59q&#xA;4q/RHy9oGleXtEstE0mBbbTrCJYbaFeyr3J7sx3Yncnc4qmGKuxV2KuxV2KsI/N38q9G/MfyrJpF&#xA;7SC/h5S6VqPGrW89PvMb0Ade49wCFX58+a/KuueVdeu9C1y2a11GzfjIh+yw/ZdG/aRxurDqMVSu&#xA;IRGRRKSIyfiKipA8QDirKbfyZZ3EKzQX5kicVVgg/wCasVVP8Bw/8tjf8AP+asVd/gOH/lsb/gB/&#xA;zVirv8Bw/wDLY3/AD/mrFXf4Dh/5bG/4Af8ANWKu/wABw/8ALY3/AAA/5qxV3+A4f+Wxv+AH/NWK&#xA;u/wHD/y2N/wA/wCasVd/gOH/AJbG/wCAH/NWKu/wHD/y2N/wA/5qxV3+A4f+Wxv+AH/NWKu/wHD/&#xA;AMtjf8AP+asVd/gOH/lsb/gB/wA1Yq7/AAHD/wAtjf8AAD/mrFXf4Dh/5bG/4Af81Yq7/AcP/LY3&#xA;/AD/AJqxV3+A4f8Alsb/AIAf81Yq7/AcP/LY3/AD/mrFXf4Dh/5bG/4Af81Yqp3Hkyzt4WmnvzHE&#xA;gqzFB/zVirFpREJGERJjB+EsKEjxIGKpp5U8q655q1600LQ7ZrrUbx+MaD7Kj9p3b9lEG7MegxV+&#xA;g35RflXo35ceVY9IsqT383GXVdR40a4np94jSpCL2HuSSqzfFXYq7FXYq7FXYq7FXm352fknov5m&#xA;aKiO62PmCxVv0ZqfGoAO5hmA3aJj9Kncdwyr4L81eVNe8q65c6Hrto9nqNq1Hjboy/sujdHRuqsN&#xA;jiqlo+uXemTVjPOBj+8hJ2PuPA4qzzTdVs9Rg9W3epH24zsyn3GKozFXYq7FXYq7FXYq7FXYq7FX&#xA;Yq7FXYq7FXYq7FXYqg9S1Wz06D1bh6E/YjG7MfYYqwPWNcu9TmrIeECn93CDsPc+JxVV8q+VNe81&#xA;a5baHoVo95qN01EjXoq/tO7dERerMdhir70/JP8AJPRfyz0V0R1vvMF8q/pPU+NAQNxDCDusSn6W&#xA;O57BVXpOKuxV2KuxV2KuxV2KuxV2KsI/NT8ovKv5j6N9S1eP0b+AN+jtViUevbsfu5xk/aQmh9jQ&#xA;hV8K/mZ+U/m78vNXNjrlvytZGP1LU4QTbXC9fhYjZqdUbcfLfFWI211cWsyzW8hjlXoy4qy/SPOV&#xA;vNxi1ACGXoJh9g/P+X9WKskR0dQ6MGVtwwNQR8xiq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqtd0RS&#xA;7sFVdyxNAB8zirG9X85W8PKLTwJpehmP2B8v5v1YqxC5uri6maa4kMkrdWbFWXfln+U/m78w9XFj&#xA;odvxtY2H13U5gRbW69fiYDdqdEXc/LfFX3V+Vf5ReVfy40b6lpEfrX84X9I6rKo9e4YffwjB+ygN&#xA;B7mpKrN8VdirsVdirsVdirsVdirsVdirsVS/X/L2ieYdKn0nW7KK/wBOuV4zW0y8lPgR3Vh1DDcH&#xA;cYq+Svza/wCcQ9b0lptW8hs+raaKu+kSEfXIh1pE2wnUeGz9viO+KvnS4t7i2nkt7iJ4Z4mKSxSK&#xA;UdWGxVlNCCMVROn6xqGntW2lIStTEd0P+xOKsnsPO1pJRL2MwN3kT4k+77Q/HFU/tb20uk5W8ySj&#xA;/JIJHzHUYqr4q7FXYq7FXYq7FXYq7FVC6vbS1TlcTJEP8ogE/IdTiqQX/na0jqllGZ27SP8ACn3f&#xA;aP4YqxjUNY1DUGrcykpWoiGyD/YjFUNb29xczx29vE808rBIoo1LuzHYKqipJOKvov8AKX/nEPW9&#xA;WaHVvPjPpOmmjppEZH1yUdaStuIFPhu/b4Tvir610Dy9onl7SoNJ0SyisNOtl4w20K8VHiT3Zj1L&#xA;Hcnc4qmGKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVgv5jfkr+X/AJ/gY63p4j1GlItWtaRXa0FB&#xA;V6ESAfyyBhir5f8AzB/5xC8/aC0l15akTzJpoqRHHSG8RevxQseL+HwMSf5Rirw7UNN1HTbySy1G&#xA;1msryE0ltriNopUPgyOFYfSMVUEd0YMjFWHRgaHFUztfM+tW9ALgyKP2ZQH/ABPxfjiqZQeertf7&#xA;+1R/9Rin6+eKo2Pz1ZH+8tpF/wBUq36+OKqy+dtII3SZfYqv8GxVzedtIA2SZvYKv8WxVRk89WQ/&#xA;u7aRv9Yqv6uWKoKfz1dt/cWqJ/rsX/VwxVLbrzPrVxUG4Man9mIBPxHxfjiqWO7uxZ2LMerE1OKq&#xA;+n6bqOpXkdlp1rNe3kxpFbW8bSyufBUQMx+gYq9x/L7/AJxC8/a80d15lkTy3ppoTHJSa8devwwq&#xA;eKeHxsCP5Tir6g/Ln8lfy/8AIECnRNPEmo0pLq11SW7aooaPQCMH+WMKMVZ1irsVdirsVdirsVdi&#xA;rsVdirsVdirsVdirsVdirsVdirsVSbzL5N8qeaLUWvmHSbXVIQCE+sxK7JXqY3I5ofdSMVeMeav+&#xA;cM/y71IvLoF9eaDM1eMdReW6/wCwlKy/8lcVeUeYf+cM/wAzbAs+kXmn6xCPsKsjW05+aSr6Y/5G&#xA;Yq8/1f8AIb84tKJF15T1B+PU2kYvB1p1tjNirFb3yx5lsW43uk3tqw6ia3ljPSv7SjtiqWYq7FUz&#xA;svLHmW+bjZaTe3THoIbeWQ9K/sqe2Ksq0j8hvzi1UgWvlPUE5dDdxizHWnW5MOKvQPL3/OGf5m35&#xA;V9XvNP0eE/bVpGuZx8kiX0z/AMjMVer+Vf8AnDP8u9NKS6/fXmvTLTlHUWdu3+wiLS/8lcVez+Wv&#xA;JvlTyvam18vaTa6XCQA/1aJUZ6dDI4HNz7sTiqc4q7FXYq7FXYq7FXYq7FXYq7FX/9k=</xapGImg:image>
+               </rdf:li>
+            </rdf:Alt>
+         </xap:Thumbnails>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
+            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#">
+         <xapMM:DocumentID>uuid:94E82CBF528711DE830DC7B65C12678A</xapMM:DocumentID>
+         <xapMM:InstanceID>uuid:a8158099-b802-4d00-acfd-b4ab575a94be</xapMM:InstanceID>
+         <xapMM:DerivedFrom rdf:parseType="Resource">
+            <stRef:instanceID>uuid:94E82CBE528711DE830DC7B65C12678A</stRef:instanceID>
+            <stRef:documentID>uuid:1B95FEC551E111DEA13AAE68EE5F3A4D</stRef:documentID>
+         </xapMM:DerivedFrom>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:xapTPg="http://ns.adobe.com/xap/1.0/t/pg/"
+            xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+            xmlns:xapG="http://ns.adobe.com/xap/1.0/g/">
+         <xapTPg:NPages>1</xapTPg:NPages>
+         <xapTPg:HasVisibleTransparency>True</xapTPg:HasVisibleTransparency>
+         <xapTPg:HasVisibleOverprint>False</xapTPg:HasVisibleOverprint>
+         <xapTPg:MaxPageSize rdf:parseType="Resource">
+            <stDim:w>3.000000</stDim:w>
+            <stDim:h>3.000000</stDim:h>
+            <stDim:unit>Inches</stDim:unit>
+         </xapTPg:MaxPageSize>
+         <xapTPg:PlateNames>
+            <rdf:Seq>
+               <rdf:li>Black</rdf:li>
+            </rdf:Seq>
+         </xapTPg:PlateNames>
+         <xapTPg:SwatchGroups>
+            <rdf:Seq>
+               <rdf:li rdf:parseType="Resource">
+                  <xapG:groupName>Default Swatch Group</xapG:groupName>
+                  <xapG:groupType>0</xapG:groupType>
+               </rdf:li>
+            </rdf:Seq>
+         </xapTPg:SwatchGroups>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+         <pdf:Producer>Adobe PDF library 8.00</pdf:Producer>
+      </rdf:Description>
+   </rdf:RDF>
+</x:xmpmeta>
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                           
+<?xpacket end="w"?>\rendstream\rendobj\r2 0 obj\r<</Count 1/Type/Pages/Kids[5 0 R]>>\rendobj\r5 0 obj\r<</Parent 2 0 R/Contents 47 0 R/BleedBox[0.0 0.0 216.0 216.0]/ArtBox[16.0 18.25 200.0 202.25]/Group 48 0 R/MediaBox[0.0 0.0 216.0 216.0]/TrimBox[0.0 0.0 216.0 216.0]/Resources<</XObject<</Fm0 20 0 R/Fm1 26 0 R/Fm2 36 0 R/Fm3 42 0 R>>/Properties<</MC0<</Color[65535 20224 20224]/Visible true/Editable true/Dimmed false/Preview true/Printed true/Title(Layer 2)>>>>/ExtGState<</GS0 11 0 R/GS1 43 0 R>>>>/Type/Page>>\rendobj\r47 0 obj\r<</Length 1191/Filter/FlateDecode>>stream\r
+H\89\94\8eÝ6\fÝû+ô\ 3Ö\88¢\1eÔ¶IÛM³\bºèº\18$-ÐL\8bI\81\ 2ùû\1eR¶,ûÞ;E1\98±)¾\ e_2çé§_¿}úê\9e\vî»÷ïÜòº\ 4\17©Øïª\7f¾~Z~q\7fâÔ~|åìþX\9e~ü9¸ßþ^^\1dÙ99
+â¨\89\17\ eä\9e_LþeY\93ø\16Uf\15ñ¹6·ró%ËAëSÜó2\ e\88«Ï0²ë®T«§ÜÔÈþú¼\\99Wí«ù\8bû\81K\7f\9e\97ÏËÇ-BBtST¾&\8e®D/UÚ\14\19ù\84\90\93\8f\11\89*\90* rV\ 4F\14Ï\924.
+¾      ;*>\17\0h8o\8e\19T\85pó"Ñ¥âc5áê\13Þrö\89\18\ 6Cv\82¿A\91'_[r\ 4{A3°rð9%'\b\11yÈ®
+t`8±'©®Àk²ôæ\80\83âjô­"o¹y\ 2Ê\9a})\11\ 1ÀHr\9aË\14U\1a´Ä¬\a\11.Ö"\9e\82ñ#\8c*ÉE\94d&\15¯Á\97Äz ¶Õ\a\99²\14\aÕNæ.\8d yâ7_CÝ\95\85\90.\9alK\ 4\862|\83Ì1\rd »ô\ 6¼A\9dDãJAó\e\82\1a\0jò@ÃwcW\92çjæ)"qªÑk¸\12J\12\11KSE£\93oРBT8P\95\1cÌ\b|\17ëA-\rTrÚè\98\8c\9fòÐàbFS0· Åh\12\930\v\82ºË@\95È\ eP>Ö0Р­FÌ_й$´/c\86Ð}\9b4R(ÚíH¬ñ{Ô@â\ 5Ãðm±£Xó8úb\8d\19j\9a\8c¹L\a½Ç×ÞäÚ÷ÿL\93\12N\93\121Whè\86\19\8f1   \8eÉ£\91¾,\ 5W\ 3\ f\8aì\89n?\88ÁB\a\v_É ¯\98$ªöZÌ\e¥ñª\87¿\eº\ 3SF/d\81\9b\98Íù@\85\11eäÂlöWL0\95\ 2\1aÞR¼!\91\11\ 5\ f\ ed;@a5gWºÇ¸Eò\85Ø\ 3\rÇë5\10\fTÎé^v\11Y\10Í\ 2\8a\fWzd\11Í\9bò\95\1cÒ¢Çgê^B   \ 5\ 3ë\ 1\fînµDWzö{K\ eiÜ2å\86¼\v$!#øædÓ\9f/eíª\88«Ã\9cÇ©50ÈFé\939©4®\ 2hcÞ\e\93©\r²©­]\1aå±\16\9aieg_s÷¤¦\ 6ÉgÝ\eø\99\røãi9Ï@§Ê)igên\92
\19þÿ\9f\17į¡¨å£N:Üå \93\86Ù{Á\98\9a°Ð\aYS\18\ e\95â\18â\e\94¸¡©\84èìâ\8dq.'¾¤¡\ f\ 5%\f[\99\ e´¬(\9b~\82#\YUõ.n\ eµ\95~;Ô2\b´K\1e¢V5ª<Ñè\10]!ô»T{ófû\88\8c\83\8b\81\1e\v\82/2q61|ZbÃäáº\15Ý\9e>/\r\8c&C\0V
+>¦\93\80æ@«8$Ø\17|þO\12\v\f\ 1Ât׳@Ñì\1d\12°ØN\12¯ºµ\91nmO?¼\ 4÷þ¯\19:V       äé\rè]à-è\9bÄcè\9bÀ\eÐ7\89·¡S\87N\rÝ\81*`=j\ 1\1a\14"«ÿXë\ 6\1e_E`Ù$\14z>ó\11}\eü\ eüÄ',i´ó;î\99/ØåÚÎî gö     u<£ÆvAú\81~\8cz\93x\88zã?D½ñ\1f¡ÞØÿ\81\9a;껫±-üÀ¢ËÓ´ðcci}áÇ`\ 2Ç\8a\85¼Ö\83´§­jû\89Ö½aûÜuWÂ~Y#Û¿½báWf<N®Ú7öÏþ7õ}áWK\9bä\8b\11:7\84\r\v«\9d\90ý_Q\8c\e\8e×¾DËÄ\gÍu²©\8b((Ýò3\9e]­ú\82¥-lÏçesÕÉIüdG/\98ï?à\1f³\8fË¿\ 2\f\0~ĨÇ\rendstream\rendobj\r48 0 obj\r<</I false/K false/CS/DeviceCMYK/S/Transparency>>\rendobj\r11 0 obj\r<</OPM 1/BM/Normal/CA 1.0/OP false/SMask/None/ca 1.0/AIS false/op false/Type/ExtGState/SA true>>\rendobj\r43 0 obj\r<</OPM 1/BM/Normal/CA 0.5/OP false/SMask/None/ca 0.5/AIS false/op false/Type/ExtGState/SA true>>\rendobj\r20 0 obj\r<</Subtype/Form/Length 129/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]/Group 9 0 R/Resources<</Shading<</Sh0 17 0 R>>/ColorSpace<</CS0 13 0 R>>/ExtGState<</GS0 11 0 R>>>>/BBox[106.997 139.145 150.43 135.867]>>stream\r
+q
+150.43 135.867 -43.433 3.278 re
+W n
+q
+0 g
+1 i 
+/GS0 gs
+43.4326172 0 0 -43.4326172 106.9970703 137.5058594 cm
+BX /Sh0 sh EX Q
+Q
+\rendstream\rendobj\r26 0 obj\r<</Subtype/Form/Length 129/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]/Group 23 0 R/Resources<</Shading<</Sh0 17 0 R>>/ColorSpace<</CS0 13 0 R>>/ExtGState<</GS0 11 0 R>>>>/BBox[106.997 133.854 150.43 130.576]>>stream\r
+q
+150.43 130.576 -43.433 3.278 re
+W n
+q
+0 g
+1 i 
+/GS0 gs
+43.4326172 0 0 -43.4326172 106.9970703 132.2148438 cm
+BX /Sh0 sh EX Q
+Q
+\rendstream\rendobj\r36 0 obj\r<</Subtype/Form/Length 126/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]/Group 29 0 R/Resources<</Shading<</Sh0 32 0 R>>/ColorSpace<</CS0 13 0 R>>/ExtGState<</GS0 11 0 R>>>>/BBox[39.6411 84.9033 88.6143 81.626]>>stream\r
+q
+39.641 84.903 48.973 -3.277 re
+W n
+q
+0 g
+1 i 
+/GS0 gs
+-48.9736328 0 0 48.9736328 88.6142578 83.2646484 cm
+BX /Sh0 sh EX Q
+Q
+\rendstream\rendobj\r42 0 obj\r<</Subtype/Form/Length 126/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]/Group 39 0 R/Resources<</Shading<</Sh0 32 0 R>>/ColorSpace<</CS0 13 0 R>>/ExtGState<</GS0 11 0 R>>>>/BBox[39.6411 90.1943 88.6143 86.917]>>stream\r
+q
+39.641 90.194 48.973 -3.277 re
+W n
+q
+0 g
+1 i 
+/GS0 gs
+-48.9736328 0 0 48.9736328 88.6142578 88.5556641 cm
+BX /Sh0 sh EX Q
+Q
+\rendstream\rendobj\r39 0 obj\r<</I false/K false/S/Transparency/Type/Group>>\rendobj\r13 0 obj\r[/DeviceN[/Black]/DeviceCMYK 14 0 R 15 0 R]\rendobj\r14 0 obj\r<</Length 91/FunctionType 4/Filter/FlateDecode/Domain[0.0 1.0]/Range[0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]>>stream\r
+H\89ª6Ô3\0\ 3\ 5#\ 5C\85¢ü\9c\1c\ 5bD\f\142óRR+\102\ÉeE
\15É\19
+Å¥I\b
+ºèf (4\ 5\ 2Ë\9b\10Pi\ 2\18S!ªåÆ0\95F\ 4\8c4\82[^\90_ P\v\10`\0.§G±\rendstream\rendobj\r15 0 obj\r<</Subtype/NChannel/Process 16 0 R>>\rendobj\r16 0 obj\r<</Components[/Cyan/Magenta/Yellow/Black]/ColorSpace/DeviceCMYK>>\rendobj\r32 0 obj\r<</ColorSpace 13 0 R/AntiAlias false/Coords[0.0 0.0 1.0 0.0]/Function 33 0 R/Extend[true true]/Domain[0.0 1.0]/ShadingType 2>>\rendobj\r33 0 obj\r<</FunctionType 3/Encode[1.0 0.0 0.0 1.0]/Domain[0.0 1.0]/Functions[34 0 R 35 0 R]/Bounds[0.967026]>>\rendobj\r34 0 obj\r<</C0[0.735]/C1[0.0]/FunctionType 2/N 1.01602/Domain[0.0 1.0]>>\rendobj\r35 0 obj\r<</C0[0.735]/C1[0.735]/FunctionType 2/N 1.0/Domain[0.0 1.0]>>\rendobj\r29 0 obj\r<</I false/K false/S/Transparency/Type/Group>>\rendobj\r23 0 obj\r<</I false/K false/S/Transparency/Type/Group>>\rendobj\r17 0 obj\r<</ColorSpace 13 0 R/AntiAlias false/Coords[0.0 0.0 1.0 0.0]/Function 18 0 R/Extend[true true]/Domain[0.0 1.0]/ShadingType 2>>\rendobj\r18 0 obj\r<</FunctionType 3/Encode[1.0 0.0]/Domain[0.0 1.0]/Functions[19 0 R]/Bounds[]>>\rendobj\r19 0 obj\r<</C0[1.0]/C1[0.0]/FunctionType 2/N 1.01602/Domain[0.0 1.0]>>\rendobj\r9 0 obj\r<</I false/K false/S/Transparency/Type/Group>>\rendobj\r49 0 obj\r<</CreationDate(D:20090604105016-07'00')/Creator(Adobe Illustrator CS3)/Producer(Adobe PDF library 8.00)/ModDate(D:20090604105016-07'00')/Title(Netatalk_Logo)>>\rendobj\rxref\r0 51\r0000000003 65535 f\r
+0000000016 00000 n\r
+0000026186 00000 n\r
+0000000004 00001 f\r
+0000000006 00000 f\r
+0000026237 00000 n\r
+0000000007 00001 f\r
+0000000008 00001 f\r
+0000000010 00001 f\r
+0000031007 00000 n\r
+0000000012 00001 f\r
+0000027992 00000 n\r
+0000000021 00001 f\r
+0000029722 00000 n\r
+0000029782 00000 n\r
+0000030011 00000 n\r
+0000030064 00000 n\r
+0000030691 00000 n\r
+0000030834 00000 n\r
+0000030929 00000 n\r
+0000028218 00000 n\r
+0000000022 00001 f\r
+0000000024 00001 f\r
+0000030628 00000 n\r
+0000000025 00001 f\r
+0000000027 00001 f\r
+0000028579 00000 n\r
+0000000028 00001 f\r
+0000000030 00001 f\r
+0000030565 00000 n\r
+0000000031 00001 f\r
+0000000037 00001 f\r
+0000030146 00000 n\r
+0000030289 00000 n\r
+0000030407 00000 n\r
+0000030487 00000 n\r
+0000028941 00000 n\r
+0000000038 00001 f\r
+0000000040 00001 f\r
+0000029659 00000 n\r
+0000000041 00001 f\r
+0000000044 00001 f\r
+0000029300 00000 n\r
+0000028105 00000 n\r
+0000000045 00001 f\r
+0000000046 00001 f\r
+0000000000 00001 f\r
+0000026665 00000 n\r
+0000027926 00000 n\r
+0000031069 00000 n\r
+0000000077 00000 n\r
+trailer\r<</Size 51/Root 1 0 R/Info 49 0 R/ID[<8382E707CCB44A8FBBDD373DCFC0BC17><2861F2D7C5014E0FA17536D73E45D784>]>>\rstartxref\r31246\r%%EOF\r
\ No newline at end of file
diff --git a/doc/gfx_and_css/logo.png b/doc/gfx_and_css/logo.png
new file mode 100644 (file)
index 0000000..8138256
Binary files /dev/null and b/doc/gfx_and_css/logo.png differ
diff --git a/doc/gfx_and_css/netatalk.css b/doc/gfx_and_css/netatalk.css
new file mode 100644 (file)
index 0000000..8096a61
--- /dev/null
@@ -0,0 +1,251 @@
+BODY {
+       /* font-family: helvetica, arial, "lucida sans", sans-serif; */
+       font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;;
+       background-color: white;
+       font-size: 1em;
+       margin-left: 15px;
+       margin-right: 15px;
+}
+
+.pdparam{
+       /* font-family: helvetica, arial, "lucida sans", sans-serif; */
+       font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;;
+       font-size: 12px;
+}
+
+TD {
+       /* font-family: helvetica, arial, "lucida sans", sans-serif; */
+       font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;;
+       font-size: 12px;
+}
+
+H1, H2, H3 {
+       font-size: 130%;
+       padding: 2px;
+       margin-top: 0px;
+}
+
+H1 {
+       background-color: #424242;
+       color: #FFFFFF;
+}
+
+H2 {
+       background-color: #424242;
+       color: #FFFFFF;
+       text-decoration: none;
+}
+
+H3 {
+       background-color: #330000;
+       color: #FFFFFF;
+}
+
+H4 {
+       color: #330000;
+       font-size: 120%;
+}
+
+H5 {
+       font-size: 100%;
+       color: #330000;
+}
+
+.term {
+       color: black;
+}
+
+TR.qandadiv TD {
+       padding-top: 1em;
+}
+
+DIV.navheader {
+       font-size: 80%;
+       margin-top: 15px;
+}
+
+div.titlepage {
+       margin-top: 15px;
+}
+
+DIV.navheader th{
+       font-size: 100%;
+}
+
+DIV.navfooter {
+       font-size: 80%;
+}
+
+A:link {
+       color: #660000;
+}
+
+A:visited {
+       color: #CC0000;
+}
+
+A:active {
+       color: #FF0033;
+}
+
+TR.question {
+       color: #33C;
+       font-weight: bold;
+}
+
+TR.question TD {
+       padding-top: 1em;
+}
+
+DIV.variablelist {
+       padding-left: 2em;
+       color: #33C;
+}
+
+P {
+       color: black;
+}
+
+DIV.caution, DIV.tip, DIV.important {
+       border: dashed 1px;
+       background-color: #EEEEFF;
+       width: 60em;
+       padding: 5px;
+}
+
+PRE.programlisting, PRE.screen {
+       border: #630 1px dashed;
+       color: #993300;
+       padding: 2px;
+       font-size: 120%;
+}
+DIV.warning { 
+       border: dashed 1px;
+       background-color: #BFBFBF;
+       width: 60em;
+       padding: 5px;
+} 
+
+DIV.note { 
+       border: dashed 1px;
+       background-color: #f2f2f2;
+       width: 60em;
+       padding: 5px;
+} 
+
+DIV.author {
+       padding-top: 1em;
+}
+
+DIV.revhistory table{
+       font-size: 12px;
+       border-collapse: collapse;
+       border-spacing: 0;
+       border: 0px;
+}
+
+DIV.revhistory tr {
+       border: 0px;
+}
+
+DIV.revhistory td {
+       border: 0px;
+}
+
+DIV.revhistory th {
+       border: 0px;
+}
+
+div.book, div.chapter, div.refentry {
+       font-size: 12px;
+}
+
+div.indexdiv {
+       font-size: 12px;
+}
+
+tt {
+       font-size: 12px;
+}
+
+/**
+ * netatalk
+ */
+/* definitions for the header */
+div#header {
+    margin-top: 15px;
+    margin-left: -15px;
+    margin-right: -15px;
+    height: 109px;
+    white-space: nowrap;
+    background-color: #424242;
+    background-image: url(/gfx/bg.gif);
+    background-repeat: no-repeat;
+    background-position: 380px 0px;
+}
+
+div#logo {
+       position: absolute;
+       margin-top: 0px;
+       margin-left: 25px;
+       width: 225px;
+       height: 109px;
+       padding: 0px;
+       background-image: url(/gfx/netatalklogo.gif);
+       background-repeat: no-repeat;
+}
+
+#logo img {
+    border: 0px;
+}
+
+div#menlinks {
+       position: absolute;
+       left: 272px;
+       top: 102px;
+       font-family: Geneva, Arial, Helvetica, sans-serif;
+       font-size: 12px;
+       font-weight: normal;
+       color: #FFFFFF;
+       text-decoration: none;
+       white-space: nowrap;
+
+}
+
+div#menlinks a, div#menlinks a:visited {
+    color: #FFFFFF;
+    margin-right: 15px;
+    text-decoration: none;
+}
+
+#menlinks img {
+   border: 0px;
+}
+
+.italic {
+        font-family: Geneva, Arial, Helvetica, sans-serif;
+        font-size: 11px;
+        font-style: italic;
+        font-weight: normal;
+        color: #000000;
+        text-decoration: none;
+}
+
+a, a:visited {
+  text-decoration: none;
+  color: #660000;
+}
+
+/* definitions for the footer */
+div.footer {
+       margin-left: 210px;
+       margin-top: 22px;
+       font-size: 75%;
+       width: 145px;
+       text-align: left;
+       white-space: nowrap;
+}
+
+.footer img {
+   padding-right: 5px;
+}
diff --git a/doc/html.xsl.in b/doc/html.xsl.in
new file mode 100644 (file)
index 0000000..b2fbfd3
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version='1.0'?> 
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
+       <xsl:import href="@DOCBOOK_ROOT@/xhtml/chunk.xsl"/> 
+       <xsl:param name="use.id.as.filename" select="'1'"/>
+       <xsl:param name="chunk.section.depth" select="0"></xsl:param>
+       <xsl:param name="chunk.separate.lots" select="1"></xsl:param>
+       <xsl:param name="html.stylesheet" select="'http://netatalk.sourceforge.net/css/netatalk.css'"/>
+
+       <xsl:template name="user.header.navigation">
+               <xsl:variable name="codefile" select="document('netatalk.html',/)"/>
+               <xsl:copy-of select="$codefile/*/node()"/>
+       </xsl:template>
+</xsl:stylesheet>
diff --git a/doc/man.xsl.in b/doc/man.xsl.in
new file mode 100644 (file)
index 0000000..fca9fec
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version='1.0'?> 
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
+<xsl:import href="@DOCBOOK_ROOT@/manpages/docbook.xsl"/> 
+
+<!-- * Collect date from <refmiscinfo class="date"> -->
+<xsl:param name="refentry.date.profile.enabled">1</xsl:param>
+<xsl:param name="refentry.date.profile">
+  (//refmiscinfo[@class='date'])[last()]
+</xsl:param>
+
+<!-- * Suppress extra :VERSION: -->
+<xsl:param name="refentry.version.suppress">1</xsl:param>
+
+<!-- * Example without numbering -->
+<xsl:param name="local.l10n.xml" select="document('')"/>
+<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
+<l:l10n language="en">
+ <l:context name="title">
+    <l:template name="example" text="Example.&#160;%t"/>
+ </l:context>
+ <l:context name="title-numbered">
+    <l:template name="example" text="Example.&#160;%t"/>
+ </l:context>
+</l:l10n>
+</l:i18n>
+</xsl:stylesheet>
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
new file mode 100644 (file)
index 0000000..4bc3be5
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = man1 man5 man8
\ No newline at end of file
diff --git a/doc/manpages/man1/.gitignore b/doc/manpages/man1/.gitignore
new file mode 100644 (file)
index 0000000..7943d1d
--- /dev/null
@@ -0,0 +1 @@
+*\.1
\ No newline at end of file
diff --git a/doc/manpages/man1/Makefile.am b/doc/manpages/man1/Makefile.am
new file mode 100644 (file)
index 0000000..dc3d658
--- /dev/null
@@ -0,0 +1,40 @@
+XSLTPROC=@XSLTPROC@
+XSLTPROC_FLAGS=@XSLTPROC_FLAGS@
+MAN_STYLESHEET=$(top_srcdir)/doc/man.xsl
+CLEANFILES =
+
+MAN_MANPAGES = \
+       ad.1 \
+       afpldaptest.1 \
+       afppasswd.1 \
+       afpstats.1 \
+       apple_dump.1 \
+       asip-status.pl.1 \
+       dbd.1 \
+       macusers.1 \
+       megatron.1 \
+       netatalk-config.1 \
+       uniconv.1
+
+EXTRA_DIST = \
+       ad.1.xml \
+       afpldaptest.1.xml \
+       afppasswd.1.xml \
+       afpstats.1.xml \
+       apple_dump.1.xml \
+       asip-status.pl.1.xml \
+       dbd.1.xml \
+       macusers.1.xml \
+       megatron.1.xml \
+       netatalk-config.1.xml \
+       uniconv.1.xml
+
+if HAVE_XSLTPROC
+CLEANFILES += $(MAN_MANPAGES)
+
+%.1 : $(MAN_STYLESHEET) %.1.xml
+       @xsltproc $(MAN_STYLESHEET) $<
+       @cp $@ $(top_builddir)/man/man1/$@.in
+
+html-local: $(MAN_MANPAGES)
+endif
\ No newline at end of file
diff --git a/doc/manpages/man1/ad.1.xml b/doc/manpages/man1/ad.1.xml
new file mode 100644 (file)
index 0000000..b6a9f55
--- /dev/null
@@ -0,0 +1,402 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="ad.1">
+  <refmeta>
+    <refentrytitle>ad</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">02 Sep 2011</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>ad</refname>
+
+    <refpurpose>Netatalk compatible UNIX file utility suite.</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>ad</command>
+
+      <arg choice="req">ls | cp | mv | rm</arg>
+
+      <arg>...</arg>
+    </cmdsynopsis>
+
+    <cmdsynopsis>
+      <command>ad</command>
+
+      <arg choice="req">-v | --version</arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><command>ad</command> is a UNIX file utility suite with Netatalk
+    compatibility. AppleDouble<indexterm>
+        <primary>AppleDouble</primary>
+      </indexterm> files in <filename>.AppleDouble</filename> directories and
+    the CNID databases are updated as appropriate.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Available Commands</title>
+
+    <cmdsynopsis>
+      <command>ad ls</command>
+
+      <arg>-dRl<arg>u</arg></arg>
+
+      <arg choice="req">file|dir <arg>...</arg></arg>
+    </cmdsynopsis>
+
+    <para>List files and directories.</para>
+
+    <cmdsynopsis>
+      <command>ad cp</command>
+
+      <arg choice="opt">-aipvf</arg>
+
+      <arg choice="req">src_file</arg>
+
+      <arg choice="req">dst_file</arg>
+    </cmdsynopsis>
+
+    <cmdsynopsis>
+      <command>ad cp -R</command>
+
+      <arg choice="opt">-aipvf</arg>
+
+      <arg choice="req">src_file|src_directory ...</arg>
+
+      <arg choice="req">dst_directory</arg>
+    </cmdsynopsis>
+
+    <para>Copy files and directories.</para>
+
+    <cmdsynopsis>
+      <command>ad mv</command>
+
+      <arg choice="opt">-finv</arg>
+
+      <arg choice="req">src_file</arg>
+
+      <arg choice="req">dst_file</arg>
+    </cmdsynopsis>
+
+    <cmdsynopsis>
+      <command>ad mv</command>
+
+      <arg choice="opt">-finv</arg>
+
+      <arg choice="req">src_file|src_directory ...</arg>
+
+      <arg choice="req">dst_directory</arg>
+    </cmdsynopsis>
+
+    <para>Move files and directories.</para>
+
+    <cmdsynopsis>
+      <command>ad rm</command>
+
+      <arg choice="opt">-Rv</arg>
+
+      <arg choice="req">file|directory</arg>
+    </cmdsynopsis>
+
+    <cmdsynopsis>
+      <command>ad -v|--version</command>
+    </cmdsynopsis>
+
+    <para>Show version.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>ad ls</title>
+
+    <para>List files and directories. Options:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>-d</term>
+
+        <listitem>
+          <para>Directories are listed as plain files</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-R</term>
+
+        <listitem>
+          <para>list subdirectories recursively</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-l</term>
+
+        <listitem>
+          <para>Long output, list AFP info</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-u</term>
+
+        <listitem>
+          <para>List UNIX info</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para><emphasis>Long output description</emphasis></para>
+
+    <programlisting>&lt;unixinfo&gt; &lt;FinderFlags&gt; &lt;AFP Attributes&gt; &lt;Color&gt; &lt;Type&gt; &lt;Creator&gt; &lt;CNID from AppleDouble&gt; &lt;name&gt;
+
+FinderFlags (valid for (f)iles and/or (d)irectories):
+
+  d = On Desktop                      (f/d)
+  e = Hidden extension                (f/d)
+  m = Shared (can run multiple times) (f)
+  n = No INIT resources               (f)
+  i = Inited                          (f/d)
+  c = Custom icon                     (f/d)
+  t = Stationery                      (f)
+  s = Name locked                     (f/d)
+  b = Bundle                          (f/d)
+  v = Invisible                       (f/d)
+  a = Alias file                      (f/d)
+
+AFP Attributes:
+
+  y = System                          (f/d)
+  w = No write                        (f)
+  p = Needs backup                    (f/d)
+  r = No rename                       (f/d)
+  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.</programlisting>
+  </refsect1>
+
+  <refsect1>
+    <title>ad cp</title>
+
+    <para>Copy files and directories.</para>
+
+    <para>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.</para>
+
+    <para>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.</para>
+
+    <para>Options:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>-a</term>
+
+        <listitem>
+          <para>Archive mode. Same as -Rp.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-f</term>
+
+        <listitem>
+          <para>For each existing destination pathname, remove it and create a
+          new file, without prompting for confirmation regardless of its
+          permis- sions. (The -f option overrides any previous -i or -n
+          options.)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-i</term>
+
+        <listitem>
+          <para>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.)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-n</term>
+
+        <listitem>
+          <para>Do not overwrite an existing file. (The -n option overrides
+          any previous -f or -i options.)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-p</term>
+
+        <listitem>
+          <para>Cause cp to preserve the following attributes of each source
+          file in the copy: modification time, access time, file flags, file
+          mode, user ID, and group ID, as allowed by permissions. If the user
+          ID and group ID cannot be preserved, no error message is displayed
+          and the exit value is not altered.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-R</term>
+
+        <listitem>
+          <para>If source_file designates a directory, cp copies the directory
+          and the entire subtree connected at that point.If the source_file
+          ends in a /, the contents of the directory are copied rather than
+          the directory itself.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-v</term>
+
+        <listitem>
+          <para>Cause cp to be verbose, showing files as they are
+          copied.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-x</term>
+
+        <listitem>
+          <para>File system mount points are not traversed.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>ad mv</title>
+
+    <para>Move files and directories.</para>
+
+    <para>Move files around within an AFP volume, updating the CNID database
+    as needed. If either:<itemizedlist>
+        <listitem>
+          <para>source or destination is not an AFP volume</para>
+        </listitem>
+
+        <listitem>
+          <para>source AFP volume != destination AFP volume</para>
+        </listitem>
+      </itemizedlist>the files are copied and removed from the source.</para>
+
+    <para>Options:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>-f</term>
+
+        <listitem>
+          <para>Do not prompt for confirmation before overwriting the
+          destination path. (The -f option overrides any previous -i or -n
+          options.)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-i</term>
+
+        <listitem>
+          <para>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.)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-n</term>
+
+        <listitem>
+          <para>Do not overwrite an existing file. (The -n option overrides
+          any previous -f or -i options.)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-v</term>
+
+        <listitem>
+          <para>Cause mv to be verbose, showing files after they are
+          moved.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>ad rm</title>
+
+    <para>Remove files and directories.</para>
+
+    <para>The rm utility attempts to remove the non-directory type files
+    specified on the command line. If the files and directories reside on an
+    AFP volume, the corresponding CNIDs are deleted from the volumes
+    database.</para>
+
+    <para>The options are as follows:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>-R</term>
+
+        <listitem>
+          <para>Attempt to remove the file hierarchy rooted in each file
+          argument.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-v</term>
+
+        <listitem>
+          <para>Be verbose when deleting files, showing them as they are
+          removed.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Reporting Bugs</title>
+
+    <para>Report bugs to the Netatalk-devel list
+    &lt;netatalk-devel@lists.sourceforge.net&gt;.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See also</title>
+
+    <para><citerefentry>
+        <refentrytitle>dbd</refentrytitle>
+
+        <manvolnum>1</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>apple_dump</refentrytitle>
+
+        <manvolnum>1</manvolnum>
+      </citerefentry>.</para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man1/afpldaptest.1.xml b/doc/manpages/man1/afpldaptest.1.xml
new file mode 100644 (file)
index 0000000..a7e73cd
--- /dev/null
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="afpldaptest.1">
+  <refmeta>
+    <refentrytitle>afpldaptest</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">22 Mar 2012</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv id="name">
+    <refname>afpldaptest</refname>
+
+    <refpurpose>Syntactically check ldap parameters in afp.conf</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv id="synopsis">
+    <cmdsynopsis>
+      <command>afpldaptest<indexterm><primary>afpldaptest</primary></indexterm></command>
+
+      <group choice="req">
+        <arg choice="plain">-u <replaceable>USER</replaceable></arg>
+        <arg choice="plain">-g <replaceable>GROUP</replaceable></arg>
+        <arg choice="plain">-i <replaceable>UUID</replaceable></arg>
+      </group>
+
+      <sbr />
+
+      <command>afpldaptest<indexterm><primary>afpldaptest</primary></indexterm></command>
+
+      <group choice="req">
+        <arg choice="plain">-h</arg>
+        <arg choice="plain">-?</arg>
+        <arg choice="plain">-:</arg>
+      </group>
+
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1 id="description">
+    <title>DESCRIPTION</title>
+
+    <para><command>afpldaptest</command> is a simple command to syntactically
+    check ldap parameters in @pkgconfdir@/afp.conf.</para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <variablelist remap="TP">
+      <varlistentry>
+        <term><option>-u</option> <replaceable>USER</replaceable></term>
+
+        <listitem>
+          <para>Show uuid for <replaceable>USER</replaceable>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-g</option> <replaceable>GROUP</replaceable></term>
+
+        <listitem>
+          <para>Show uuid for <replaceable>GROUP</replaceable>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-i</option> <replaceable>UUID</replaceable></term>
+
+        <listitem>
+          <para>Show user, group or local-uuid for
+         <replaceable>UUID</replaceable>.</para>
+        </listitem>
+
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-h, -?, -:</option></term>
+
+        <listitem>
+          <para>Show the help and exit.</para>
+        </listitem>
+
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+  <refsect1 id="see_also">
+    <title>SEE ALSO</title>
+
+    <para><citerefentry><refentrytitle>afp.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man1/afppasswd.1.xml b/doc/manpages/man1/afppasswd.1.xml
new file mode 100644 (file)
index 0000000..e67727f
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="afppasswd.1">
+  <refmeta>
+    <refentrytitle>afppasswd</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">22 Mar 2012</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>afppasswd</refname>
+
+    <refpurpose>netatalk password maintenance utility</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>afppasswd<indexterm>
+          <primary>afppasswd</primary>
+        </indexterm><indexterm>
+          <primary>UAM</primary>
+
+          <secondary>User Authentication Module</secondary>
+        </indexterm></command>
+
+      <arg choice="opt">-acfn</arg>
+
+      <arg choice="opt"><arg choice="plain">-p
+      <replaceable>passwd</replaceable></arg><arg
+      choice="plain"><replaceable>file</replaceable></arg></arg>
+
+      <arg choice="opt"><arg choice="plain">-u
+      <replaceable>minimum</replaceable></arg><arg
+      choice="plain"><replaceable>uid</replaceable></arg></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>DESCRIPTION</title>
+
+    <para><command>afppasswd</command> allows the maintenance of afppasswd
+    files created by netatalk for use by the uams_randnum.so UAM (providing
+    the "Randnum exchange" and "2-Way Randnum exchange" User Authentication
+    Modules).</para>
+
+    <para><command>afppasswd</command> can either be called by root with
+    parameters, or can be called by local system users with no parameters to
+    change their AFP passwords.</para>
+
+    <note>
+      <para>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 <link linkend="authentication">Authentication chapter</link> inside
+      Netatalk's documentation.</para>
+    </note>
+  </refsect1>
+
+  <refsect1>
+    <title>EXAMPLE</title>
+
+    <para>Local user changing their own password:</para>
+
+    <screen><prompt>example%</prompt> <userinput>afppasswd</userinput>
+<computeroutput>Enter NEW AFP password:</computeroutput> <userinput>(hidden)</userinput>
+<computeroutput>Enter NEW AFP password again:</computeroutput> <userinput>(hidden)</userinput>
+<computeroutput>afppasswd: updated password.</computeroutput>
+</screen>
+  </refsect1>
+
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <variablelist remap="TP">
+      <varlistentry>
+        <term><option>-a</option></term>
+
+        <listitem>
+          <para>Add a new user to the <command>afppasswd</command>
+          file.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-c</option></term>
+
+        <listitem>
+          <para>Create and/or initialize <command>afppasswd</command> file or
+          specific user.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-f</option></term>
+
+        <listitem>
+          <para>Force the current action.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-p</option><replaceable> path</replaceable></term>
+
+        <listitem>
+          <para>Path to <command>afppasswd</command> file.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-n</option></term>
+
+        <listitem>
+          <para>If cracklib support is built into <emphasis
+          remap="B">netatalk</emphasis> this option will cause cracklib
+          checking to be disabled, if the superuser does not want to have the
+          password run against the cracklib dictionary.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-u</option><replaceable> minimum
+        uid</replaceable></term>
+
+        <listitem>
+          <para>This is the minimum <emphasis remap="I">user id</emphasis>
+          (uid) that <command>afppasswd</command> will use when creating
+          users.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>SEE ALSO</title>
+
+    <para><citerefentry>
+        <refentrytitle>afpd</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afp.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>.</para>
+  </refsect1>
+</refentry>
\ No newline at end of file
diff --git a/doc/manpages/man1/afpstats.1.xml b/doc/manpages/man1/afpstats.1.xml
new file mode 100644 (file)
index 0000000..c2e9799
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="afpstats.1">
+  <refmeta>
+    <refentrytitle>afpstats</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">24 Mar 2013</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv id="name">
+    <refname>afpstats</refname>
+
+    <refpurpose>List AFP statistics</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv id="synopsis">
+    <cmdsynopsis>
+      <command>afpstats<indexterm><primary>afpstats</primary></indexterm></command>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1 id="description">
+    <title>DESCRIPTION</title>
+
+    <para><command>afpstats</command> list AFP statistics via D-Bus IPC.</para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>NOTE</title>
+
+    <para><command>afpd</command> must support D-Bus. Check it by
+    "<command>afpd -V</command>".</para>
+
+    <para>"<option>afpstats = yes</option>" must be set in
+    <filename>@pkgconfdir@/afp.conf</filename>.</para>
+
+  </refsect1>
+
+  <refsect1 id="see_also">
+    <title>SEE ALSO</title>
+
+    <para><citerefentry><refentrytitle>afpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>afp.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum></citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man1/apple_dump.1.xml b/doc/manpages/man1/apple_dump.1.xml
new file mode 100644 (file)
index 0000000..2457d1d
--- /dev/null
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="apple_dump.1">
+  <refmeta>
+    <refentrytitle>apple_dump</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">16 Jul 2012</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv id="name">
+    <refname>apple_dump</refname>
+
+    <refpurpose>Dump AppleSingle/AppleDouble format data</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv id="synopsis">
+    <cmdsynopsis>
+      <command>apple_dump<indexterm><primary>apple_dump</primary></indexterm></command>
+
+      <arg choice="opt"><arg choice="plain">-a</arg></arg>
+
+      <group choice="opt">
+        <arg choice="plain"><replaceable>FILE</replaceable></arg>
+        <arg choice="plain"><replaceable>DIR</replaceable></arg>
+      </group>
+
+      <sbr />
+
+      <command>apple_dump<indexterm><primary>apple_dump</primary></indexterm></command>
+
+      <arg choice="plain">-e</arg>
+
+      <group choice="plain">
+        <arg choice="plain"><replaceable>FILE</replaceable></arg>
+        <arg choice="plain"><replaceable>DIR</replaceable></arg>
+      </group>
+
+      <sbr />
+
+      <command>apple_dump<indexterm><primary>apple_dump</primary></indexterm></command>
+
+      <arg choice="plain">-f</arg>
+
+      <arg choice="opt"><replaceable>FILE</replaceable></arg>
+
+      <sbr />
+
+      <command>apple_dump<indexterm><primary>apple_dump</primary></indexterm></command>
+
+      <arg choice="plain">-d</arg>
+
+      <arg choice="opt"><replaceable>FILE</replaceable></arg>
+
+      <sbr />
+
+      <command>apple_dump<indexterm><primary>apple_dump</primary></indexterm></command>
+
+      <group choice="plain">
+        <arg choice="plain">-h</arg>
+        <arg choice="plain">-help</arg>
+        <arg choice="plain">--help</arg>
+      </group>
+
+      <sbr />
+
+      <command>apple_dump<indexterm><primary>apple_dump</primary></indexterm></command>
+
+      <group choice="plain">
+        <arg choice="plain">-v</arg>
+        <arg choice="plain">-version</arg>
+        <arg choice="plain">--version</arg>
+      </group>
+
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1 id="description">
+    <title>DESCRIPTION</title>
+
+    <para><command>apple_dump</command> is a perl script to dump
+    AppleSingle/AppleDouble format data. </para>
+    <para>This script can dump various AppleSingle/AppleDouble data created
+    by mailer, archiver, Mac OS X, Netatalk and so on.</para>
+    <para>With no <replaceable>FILE</replaceable>|<replaceable>DIR</replaceable>, or when <replaceable>FILE</replaceable>|<replaceable>DIR</replaceable> is -, read standard input.</para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <variablelist remap="TP">
+      <varlistentry>
+        <term><option>-a</option> [<replaceable>FILE</replaceable>|<replaceable>DIR</replaceable>]</term>
+
+        <listitem>
+          <para>This is default.
+          Dump a AppleSingle/AppleDouble file for
+          <replaceable>FILE</replaceable> or <replaceable>DIR</replaceable>
+          automatically.
+          If FILE is not AppleSingle/AppleDouble format,
+          look for extended attribute, 
+          <replaceable>.AppleDouble/FILE</replaceable> and
+          <replaceable>._FILE</replaceable>.
+          If <replaceable>DIR</replaceable>, look for
+          extended attribute, 
+          <replaceable>DIR/.AppleDouble/.Parent</replaceable> and
+          <replaceable>._DIR</replaceable>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-e</option> <replaceable>FILE</replaceable>|<replaceable>DIR</replaceable></term>
+
+        <listitem>
+          <para>Dump extended attribute of<replaceable>FILE</replaceable> or <replaceable>DIR</replaceable>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-f</option> [<replaceable>FILE</replaceable>]</term>
+
+        <listitem>
+          <para>Dump <replaceable>FILE</replaceable>. Assume FinderInfo to be FileInfo.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-d</option> [<replaceable>FILE</replaceable>]</term>
+
+        <listitem>
+          <para>Dump <replaceable>FILE</replaceable>. Assume FinderInfo to be DirInfo.</para>
+        </listitem>
+
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-h, -help, --help</option></term>
+
+        <listitem>
+          <para>Display the help and exit</para>
+        </listitem>
+
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-v, -version, --version</option></term>
+
+        <listitem>
+          <para>Show version and exit</para>
+        </listitem>
+
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>NOTE</title>
+
+    <para>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.</para>
+
+    <para>If setting option -e, -f or -d,  assume FinderInfo and doesn't look
+    for another file.</para>
+
+  </refsect1>
+
+  <refsect1 id="see_also">
+    <title>SEE ALSO</title>
+
+    <para><citerefentry><refentrytitle>ad</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>getfattr</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>attr</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>runat</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>getextattr</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>lsextattr</refentrytitle><manvolnum>8</manvolnum></citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man1/asip-status.pl.1.xml b/doc/manpages/man1/asip-status.pl.1.xml
new file mode 100644 (file)
index 0000000..859b063
--- /dev/null
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="asip-status.pl.1">
+  <refmeta>
+    <refentrytitle>asip-status.pl</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">24 Jul 2012</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>asip-status.pl</refname>
+
+    <refpurpose>Queries AFP servers for their capabilities</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>asip-status.pl<indexterm>
+          <primary>asip-status.pl</primary>
+        </indexterm></command>
+
+      <arg choice="opt">-d</arg>
+      <arg choice="opt">-i</arg>
+      <arg choice="opt">-x</arg>
+
+      <arg choice="plain">HOSTNAME[:PORT]</arg>
+    </cmdsynopsis>
+
+    <sbr />
+
+    <cmdsynopsis>
+      <command>asip-status.pl<indexterm>
+          <primary>asip-status.pl</primary>
+        </indexterm></command>
+
+      <group choice="plain">
+        <arg choice="plain">-v</arg>
+        <arg choice="plain">-version</arg>
+        <arg choice="plain">--version</arg>
+      </group>
+    </cmdsynopsis>
+
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>DESCRIPTION</title>
+
+    <para><emphasis remap="B">asip-status.pl</emphasis> 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.</para>
+
+    <para>When you don't supply :PORT, then the default AFP port, 548, will be
+    used.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <variablelist remap="TP">
+      <varlistentry>
+        <term><option>-d</option></term>
+
+        <listitem>
+          <para>Enable debug output.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-i</option></term>
+
+        <listitem>
+          <para>Show icon if it exists.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-x</option></term>
+
+        <listitem>
+          <para>Enable hex dump output.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-v, -version, --version</option></term>
+
+        <listitem>
+          <para>Show version.</para>
+        </listitem>
+
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>EXAMPLES</title>
+
+    <para><programlisting><emphasis remap="B">asip-status.pl</emphasis> 192.168.1.15
+AFP reply from 192.168.1.15:548
+Flags: 1  Cmd: 3  ID: 57005
+Reply: DSIGetStatus
+Request ID: 57005
+Machine type: Macintosh
+AFP versions: AFPVersion 1.1,AFPVersion 2.0,AFPVersion 2.1,AFP2.2
+UAMs: Cleartxt passwrd,Randnum exchange,2-Way Randnum exchange
+Volume Icon &amp; Mask: Yes
+Flags: 
+    SupportsCopyFile
+    SupportsChgPwd
+    SupportsServerMessages
+    SupportsServerSignature
+    SupportsTCP/IP
+    SupportsSuperClient
+Server name: bookchan
+Signature:
+04 1d 65 23 04 1d 65 23 04 1d 65 23 04 1d 65 23  ..e#..e#..e#..e#
+                                                  
+Network address: 192.168.1.15:548 (TCP/IP address and port)
+Network address: 65280.128 (ddp address)
+</programlisting></para>
+
+    <para><programlisting><emphasis remap="B">asip-status.pl</emphasis> myserver:10548
+AFP reply from myserver:10548
+Flags: 1  Cmd: 3  ID: 57005
+Reply: DSIGetStatus
+Request ID: 57005
+Machine type: Netatalk3.0
+AFP versions: AFP2.2,AFPX03,AFP3.1,AFP3.2,AFP3.3
+UAMs: DHX2,DHCAST128
+Volume Icon &amp; Mask: Yes
+Flags: 
+    SupportsCopyFile
+    SupportsServerMessages
+    SupportsServerSignature
+    SupportsTCP/IP
+    SupportsSrvrNotifications
+    SupportsOpenDirectory
+    SupportsUTF8Servername
+    SupportsUUIDs
+    SupportsExtSleep
+    SupportsSuperClient
+Server name: myserver
+Signature:
+8a c6 12 3a 0e d9 95 3e 6f 31 e3 a9 17 f5 70 f6  ...:...>o1....p.
+                                                  
+Network address: 192.168.1.154:10548 (TCP/IP address and port)
+UTF8 Servername: myserver
+</programlisting></para>
+  </refsect1>
+
+  <refsect1>
+    <title>REPORTING BUGS</title>
+
+    <para>Report bugs to the Netatalk-devel list
+    &lt;netatalk-devel@lists.sourceforge.net&gt;.</para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man1/dbd.1.xml b/doc/manpages/man1/dbd.1.xml
new file mode 100644 (file)
index 0000000..36b7aba
--- /dev/null
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="dbd.1">
+  <refmeta>
+    <refentrytitle>dbd</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">28 Dec 2012</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>dbd</refname>
+
+    <refpurpose>CNID database maintenance</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>dbd<indexterm>
+          <primary>dbd</primary>
+        </indexterm></command>
+
+      <arg choice="opt">-fsv</arg>
+
+      <arg choice="plain"><replaceable>volumepath</replaceable></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><command>dbd</command> 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..</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Options</title>
+
+    <variablelist>
+      <varlistentry>
+        <term>-c</term>
+
+        <listitem>
+          <para>convert from adouble:v2 to adouble:ea</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-f</term>
+
+        <listitem>
+          <para>delete and recreate CNID database</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-F</term>
+
+        <listitem>
+          <para>location of the afp.conf config file</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-s</term>
+
+        <listitem>
+          <para>scan volume: treat the volume as read only and don't perform
+          any filesystem modifications</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-t</term>
+
+        <listitem>
+          <para>show statistics while running</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-v</term>
+
+        <listitem>
+          <para>verbose</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-V</term>
+
+        <listitem>
+          <para>display version info</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>CNID background</title>
+
+    <para>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.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See also</title>
+
+    <para><citerefentry>
+        <refentrytitle>cnid_metad</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>cnid_dbd</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man1/macusers.1.xml b/doc/manpages/man1/macusers.1.xml
new file mode 100644 (file)
index 0000000..5cfee6f
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="macusers.1">
+  <refmeta>
+    <refentrytitle>macusers</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">13 Oct 2011</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv id="name">
+    <refname>macusers</refname>
+
+    <refpurpose>List the users connecting via AFP</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv id="synopsis">
+    <cmdsynopsis>
+      <command>macusers<indexterm><primary>macusers</primary></indexterm></command>
+    </cmdsynopsis>
+
+    <cmdsynopsis>
+      <command>macusers<indexterm><primary>macusers</primary></indexterm></command>
+
+      <group choice="plain">
+        <arg choice="plain">-v</arg>
+        <arg choice="plain">-version</arg>
+        <arg choice="plain">--version</arg>
+        <arg choice="plain">-h</arg>
+        <arg choice="plain">-help</arg>
+        <arg choice="plain">--help</arg>
+      </group>
+
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1 id="description">
+    <title>DESCRIPTION</title>
+
+    <para><command>macusers</command> list the users connecting via AFP.</para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <variablelist remap="TP">
+      <varlistentry>
+        <term><option>-v, -version, --version</option></term>
+
+        <listitem>
+          <para>Show version and exit</para>
+        </listitem>
+
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-h, -help, --help</option></term>
+
+        <listitem>
+          <para>Display the help and exit</para>
+        </listitem>
+
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1 id="see_also">
+    <title>SEE ALSO</title>
+
+    <para><citerefentry><refentrytitle>afpd</refentrytitle><manvolnum>8</manvolnum></citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man1/megatron.1.xml b/doc/manpages/man1/megatron.1.xml
new file mode 100644 (file)
index 0000000..20b6405
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="megatron.1">
+  <refmeta>
+    <refentrytitle>megatron</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">02 Sep 2011</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv id="name">
+    <refname>megatron</refname>
+
+    <refname>unhex</refname>
+
+    <refname>unbin</refname>
+
+    <refname>unsingle</refname>
+
+    <refname>hqx2bin</refname>
+
+    <refname>single2bin</refname>
+
+    <refname>macbinary</refname>
+
+    <refpurpose>Macintosh file format transformer</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv id="synopsis">
+    <cmdsynopsis>
+      <command>megatron<indexterm><primary>megatron</primary></indexterm></command>
+
+      <arg choice="opt" rep="repeat"><replaceable>sourcefile</replaceable></arg>
+
+      <sbr />
+
+      <command>unbin<indexterm><primary>unbin</primary></indexterm></command>
+
+      <arg choice="opt" rep="repeat"><replaceable>sourcefile</replaceable></arg>
+
+      <sbr />
+
+      <command>unhex<indexterm><primary>unhex</primary></indexterm></command>
+
+      <arg choice="opt" rep="repeat"><replaceable>sourcefile</replaceable></arg>
+
+      <sbr />
+
+      <command>unsingle<indexterm><primary>unsingle</primary></indexterm></command>
+
+      <arg choice="opt" rep="repeat"><replaceable>sourcefile</replaceable></arg>
+
+      <sbr />
+
+      <command>hqx2bin<indexterm><primary>hqx2bin</primary></indexterm></command>
+
+      <arg choice="opt" rep="repeat"><replaceable>sourcefile</replaceable></arg>
+
+      <sbr />
+
+      <command>single2bin<indexterm><primary>single2bin</primary></indexterm></command>
+
+      <arg choice="opt" rep="repeat"><replaceable>sourcefile</replaceable></arg>
+
+      <sbr />
+
+      <command>macbinary<indexterm><primary>macbinary</primary></indexterm></command>
+
+      <arg choice="opt" rep="repeat"><replaceable>sourcefile</replaceable></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1 id="description">
+    <title>DESCRIPTION</title>
+
+    <para><command>megatron</command> is used to transform files from BinHex,
+    MacBinary, AppleSingle, or <emphasis remap="B" role="bold">netatalk</emphasis> style
+    AppleDouble formats into MacBinary or <emphasis remap="B">netatalk</emphasis>
+    style AppleDouble formats. The <emphasis remap="B">netatalk</emphasis>
+    style AppleDouble format is the file format used by <emphasis remap="B">afpd,</emphasis>
+    the <emphasis remap="B">netatalk</emphasis> 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. <command>megatron</command> uses its name to
+    determine what type of transformation is being asked of it.</para>
+
+    <para>If <command>megatron</command> is called as <command>unhex</command>
+    , <command>unbin</command> or <command>unsingle</command>, 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 &#34;.hqx&#34;. MacBinary
+    is the format most often used by terminal emulators &#34;on the fly&#34;
+    when transferring Macintosh files in binary mode. MacBinary files often
+    have an extension of &#34;.bin&#34;. Some Macintosh LAN-based email
+    packages use uuencoded AppleSingle format to &#34;attach&#34; or
+    &#34;enclose&#34; files in email. AppleSingle files don&#39;t have a
+    standard filename extension.</para>
+
+    <para>If <command>megatron</command> is called as <command>hqx2bin</command>,
+    <command>single2bin</command>, or <command>macbinary</command>, 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 <command>afpd</command> server to some other machine when you
+    can&#39;t copy them from the server using a Macintosh for some reason.</para>
+
+    <para>If <command>megatron</command> is called with any other name, it
+    uses the default translation, namely <command>unhex</command>.</para>
+
+    <para>If no source file is given, or if <emphasis remap="I">sourcefile</emphasis>
+    is `<emphasis remap="" role="bold">-</emphasis>&#39;, and if the
+    conversion is from a BinHex or MacBinary file, <command>megatron</command>
+    will read from standard input.</para>
+
+    <para>The filename used to store any output file is the filename that is
+    encoded in the source file. MacBinary files are created with a
+    &#34;.bin&#34; extension. In the case of conflicts, the old file is
+    overwritten!</para>
+  </refsect1>
+
+  <refsect1 id="options">
+    <title>OPTIONS</title>
+
+    <variablelist remap="TP">
+      <varlistentry>
+        <term><option>-v, --version</option></term>
+
+        <listitem>
+          <para>Show version.</para>
+        </listitem>
+
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+  <refsect1 id="see_also">
+    <title>SEE ALSO</title>
+
+    <para><citerefentry><refentrytitle>afpd</refentrytitle><manvolnum>8</manvolnum></citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man1/netatalk-config.1.xml b/doc/manpages/man1/netatalk-config.1.xml
new file mode 100644 (file)
index 0000000..69da13f
--- /dev/null
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="netatalkconfig.1">
+  <refmeta>
+    <refentrytitle>netatalk-config</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">09 June 2001</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+
+    <refmiscinfo class="manual">The Netatalk Project</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>netatalk-config</refname>
+
+    <refpurpose>script to get information about the installed version of
+    netatalk</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>netatalk-config<indexterm><primary>netatalk-config</primary></indexterm></command>
+
+      <arg choice="opt"><arg choice="plain">--prefix </arg><arg choice="opt"><replaceable>=DIR</replaceable></arg></arg>
+
+      <arg choice="opt"><arg choice="plain">--exec_prefix </arg><arg
+      choice="opt"><replaceable>=DIR</replaceable></arg></arg>
+
+      <arg choice="opt">--help</arg>
+
+      <arg choice="opt">--version</arg>
+
+      <arg choice="opt">--libs</arg>
+
+      <arg choice="opt">--libs-dirs</arg>
+
+      <arg choice="opt">--libs-names</arg>
+
+      <arg choice="opt">--cflags</arg>
+
+      <arg choice="opt">--macros</arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>DESCRIPTION</title>
+
+    <para><command>netatalk-config</command> is a tool that is used to
+    determine the compiler and linker flags that should be used
+    to compile and link programs that use the <emphasis remap="I">netatalk</emphasis>
+    run-time libraries.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <para><command>netatalk-config</command> accepts the following options:</para>
+
+    <variablelist remap="TP">
+      <varlistentry>
+        <term><option>--help</option></term>
+
+        <listitem>
+          <para>Print a short help for this command and exit.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--version</option></term>
+
+        <listitem>
+          <para>Print the currently installed version of <emphasis remap="I">netatalk</emphasis>
+          on the standard output.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--libs</option></term>
+
+        <listitem>
+          <para>Print the linker flags that are necessary to link against the
+          <emphasis remap="I">netatalk</emphasis> run-time libraries.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--libs-dirs</option></term>
+
+        <listitem>
+          <para>Print only the -l/-R part of --libs.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--libs-names</option></term>
+
+        <listitem>
+          <para>Print only the -l part of --libs.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--cflags</option></term>
+
+        <listitem>
+          <para>Print the compiler flags that are necessary to compile a
+          program linked against the <emphasis remap="I">netatalk</emphasis>
+          run-time libraries.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--macros</option></term>
+
+        <listitem>
+          <para>Print the <emphasis remap="I">netatalk</emphasis> m4
+          directory.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--prefix=PREFIX</option></term>
+
+        <listitem>
+          <para>If specified, use PREFIX instead of the installation prefix
+          that <emphasis remap="I">netatalk</emphasis> was built with when
+          computing the output for the --cflags and --libs options. This
+          option is also used for the exec prefix if --exec-prefix was not
+          specified. This option must be specified before any --libs or
+          --cflags options.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--exec\_prefix=PREFIX</option></term>
+
+        <listitem>
+          <para>If specified, use PREFIX instead of the installation exec
+          prefix that <emphasis remap="I">netatalk</emphasis> was built with
+          when computing the output for the --cflags and --libs options. This
+          option must be specified before any --libs or --cflags options.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>COPYRIGHT</title>
+
+    <para>Copyright © 1998 Owen Taylor</para>
+
+    <para>Permission to use, copy, modify, and distribute this software and
+    its documentation for any purpose and without fee is hereby granted,
+    provided that the above copyright notice appear in all copies and that
+    both that copyright notice and this permission notice appear in supporting
+    documentation.</para>
+
+    <para>Man page adapted for <command>netatalk-config</command> by Sebastian
+    Rittau in 2001.</para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man1/uniconv.1.xml b/doc/manpages/man1/uniconv.1.xml
new file mode 100644 (file)
index 0000000..d563c28
--- /dev/null
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="uniconv.1">
+
+  <refmeta>
+    <refentrytitle>uniconv</refentrytitle>
+
+    <manvolnum>1</manvolnum>
+
+    <refmiscinfo class="date">19 Jan 2013</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>uniconv</refname>
+
+    <refpurpose>convert Netatalk volume encoding</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>uniconv<indexterm><primary>uniconv</primary></indexterm></command>
+
+      <arg choice="opt">-ndv</arg>
+
+      <arg choice="plain">-c <replaceable>cnidbackend</replaceable></arg>
+
+      <arg choice="plain">-f <replaceable>fromcode</replaceable></arg>
+
+      <arg choice="plain">-t <replaceable>tocode</replaceable></arg>
+
+      <arg>-m <replaceable>maccode</replaceable></arg>
+
+      <arg choice="plain"><replaceable>volumepath</replaceable></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><command>uniconv</command> converts the volume encoding of
+    <replaceable>volumepath</replaceable> from the <replaceable>fromcode</replaceable>
+    to the <replaceable>tocode</replaceable> encoding.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Options</title>
+
+    <variablelist>
+      <varlistentry>
+        <term>-c</term>
+
+        <listitem>
+          <para>CNID backend used on this volume, usually cdb or dbd. Should
+          match the backend selected with afpd for this volume. If not
+          specified, the default CNID backend "@DEFAULT_CNID_SCHEME@" is
+          used</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-d</term>
+
+        <listitem>
+          <para>don't HEX encode leading dots (:2e), equivalent to
+          <option>use dots = yes</option> in <citerefentry><refentrytitle>afp.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry></para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-f</term>
+
+        <listitem>
+          <para>encoding to convert from, use ASCII for HEX encoded volumes</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-h</term>
+
+        <listitem>
+          <para>display help</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-m</term>
+
+        <listitem>
+          <para>Macintosh client codepage, required for HEX encoded volumes.
+          Defaults to "MAC_ROMAN"</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-n</term>
+
+        <listitem>
+          <para>"dry run", don't do any real changes</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-t</term>
+
+        <listitem>
+          <para>volume encoding to convert to, e.g. UTF8</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-v</term>
+
+        <listitem>
+          <para>verbose output, use twice for maximum logging.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-V</term>
+
+        <listitem>
+          <para>print version and exit</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para></para>
+  </refsect1>
+
+  <refsect1>
+    <title>WARNING</title>
+
+    <para>Setting the wrong options might render your data unusable!!! Make
+    sure you know what you are doing. Always backup your data first.</para>
+
+    <para>It is <emphasis role="bold">*strongly*</emphasis> recommended to do
+    a "dry run" first and to check the output for conversion errors.</para>
+
+    <para><citerefentry><refentrytitle>afpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    should <emphasis>not</emphasis> be running while you change the volume
+    encoding. Remember to change <option>unix charset</option> or
+    <option>vol charset</option> in
+    <citerefentry><refentrytitle>afp.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+    to the new codepage, before restarting afpd.</para>
+
+    <para>In case of <emphasis role="bold">MacChineseTraditional</emphasis>,
+    <emphasis role="bold">MacJapanese</emphasis> or
+    <emphasis role="bold">MacKorean</emphasis>,
+    uniconv cannot be used.</para>
+
+    <para><emphasis role="bold">USE AT YOUR OWN RISK!!!</emphasis></para>
+  </refsect1>
+
+  <refsect1>
+    <title>Selectable charsets</title>
+
+    <para>Netatalk provides internal support for UTF-8 (pre- and decomposed)
+    and HEX. If you want to use other charsets, they must be provided by
+    <citerefentry><refentrytitle>iconv</refentrytitle><manvolnum>1</manvolnum></citerefentry></para>
+
+    <para><command>uniconv</command> also knows iso-8859.adapted, an old style
+    1.x NLS widely used. This is only intended for upgrading old volumes,
+    <citerefentry><refentrytitle>afpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    cannot handle iso-8859.adapted anymore.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>CNID background</title>
+
+    <para>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.</para>
+
+    <para>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. <command>uniconv</command>
+    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
+    <emphasis>could</emphasis> use <command>uniconv</command> with cdb and
+    <command>afpd</command> with dbd later.</para>
+
+    <para><emphasis role="bold">Warning</emphasis>: There must not be two
+    processes opening the CNID database using different backends at once! If a
+    volume is still opened with dbd (cnid_metad/cnid_dbd) and you start
+    <command>uniconv</command> with cdb, the result will be a corrupted CNID
+    database, as the two backends use different locking schemes. You might run
+    into additional problems, e.g. if dbd is compiled with transactions, cdb
+    will not update the transaction logs.</para>
+
+    <para>In general, it is recommended to use the same backend for
+    <command>uniconv</command> you are using with
+    <citerefentry><refentrytitle>afpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+
+    <para>convert 1.x CAP encoded volume to UTF-8, clients used MacRoman
+    codepage, cnidscheme is dbd:</para>
+
+    <screen><prompt>example%</prompt><userinput> uniconv -c dbd -f ASCII -t UTF8 -m MAC_ROMAN /path/to/share</userinput></screen>
+
+    <para>convert iso8859-1 volume to UTF-8, cnidscheme is cdb:</para>
+
+    <screen><prompt>example%</prompt><userinput> uniconv -c cdb -f ISO-8859-1 -t UTF8 -m MAC_ROMAN /path/to/share</userinput></screen>
+
+    <para>convert 1.x volume using iso8859-1 adapted NLS to HEX encoding:</para>
+
+    <screen><prompt>example%</prompt><userinput> uniconv -f ISO-8859-ADAPTED -t ASCII -m MAC_ROMAN/path/to/share</userinput></screen>
+
+    <para>convert UTF-8 volume to HEX, for MacCyrillic clients:</para>
+
+    <screen><prompt>example%</prompt><userinput> uniconv -f UTF8 -t ASCII -m MAC_CYRILLIC /path/to/share</userinput></screen>
+  </refsect1>
+
+  <refsect1>
+    <title>See also</title>
+
+    <para><citerefentry><refentrytitle>afp.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,<citerefentry><refentrytitle>afpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,<citerefentry><refentrytitle>iconv</refentrytitle><manvolnum>1</manvolnum></citerefentry>,<citerefentry><refentrytitle>cnid_metad</refentrytitle><manvolnum>8</manvolnum></citerefentry>,<citerefentry><refentrytitle>cnid_dbd</refentrytitle><manvolnum>8</manvolnum></citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man5/.gitignore b/doc/manpages/man5/.gitignore
new file mode 100644 (file)
index 0000000..2fc1d34
--- /dev/null
@@ -0,0 +1 @@
+*\.5
diff --git a/doc/manpages/man5/Makefile.am b/doc/manpages/man5/Makefile.am
new file mode 100644 (file)
index 0000000..82fee7c
--- /dev/null
@@ -0,0 +1,26 @@
+XSLTPROC=@XSLTPROC@
+XSLTPROC_FLAGS=@XSLTPROC_FLAGS@
+MAN_STYLESHEET=$(top_srcdir)/doc/man.xsl
+CLEANFILES =
+
+MAN_MANPAGES = \
+       afp.conf.5 \
+       afp_signature.conf.5 \
+       afp_voluuid.conf.5 \
+       extmap.conf.5
+
+EXTRA_DIST = \
+       afp_signature.conf.5.xml \
+       afp_voluuid.conf.5.xml \
+       afp.conf.5.xml \
+       extmap.conf.5.xml
+
+if HAVE_XSLTPROC
+CLEANFILES += $(MAN_MANPAGES)
+
+%.5 : $(MAN_STYLESHEET) %.5.xml
+       @xsltproc $(MAN_STYLESHEET) $<
+       @cp $@ $(top_builddir)/man/man5/$@.in
+
+html-local: $(MAN_MANPAGES)
+endif
\ No newline at end of file
diff --git a/doc/manpages/man5/afp.conf.5.xml b/doc/manpages/man5/afp.conf.5.xml
new file mode 100644 (file)
index 0000000..f5a5510
--- /dev/null
@@ -0,0 +1,1960 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="afp.conf.5">
+  <refmeta>
+    <refentrytitle>afp.conf</refentrytitle>
+
+    <manvolnum>5</manvolnum>
+
+    <refmiscinfo class="date">30 Apr 2013</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>afp.conf</refname>
+
+    <refpurpose>Netatalk configuration file <indexterm>
+        <primary>afp.conf</primary>
+      </indexterm></refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>SYNOPSIS</title>
+
+    <para>The <filename>afp.conf</filename> file is the configuration file for
+    the <emphasis role="bold">Netatalk</emphasis> AFP file server.</para>
+
+    <para>All AFP specific configuration and AFP volume definitions are done
+    via this file.</para>
+  </refsect1>
+
+  <refsect1 id="FILEFORMATSECT">
+    <title>FILE FORMAT</title>
+
+    <para>The file consists of sections and parameters. A section begins with
+    the name of the section in square brackets and continues until the next
+    section begins. Sections contain parameters of the form: <programlisting>
+    <replaceable>name</replaceable> = <replaceable>value </replaceable>
+    </programlisting></para>
+
+    <para>The file is line-based - that is, each newline-terminated line
+    represents either a comment, a section name or a parameter.</para>
+
+    <para>Section and parameter names are case sensitive.</para>
+
+    <para>Only the first equals sign in a parameter is significant. Whitespace
+    before or after the first equals sign is discarded. Leading, trailing and
+    internal whitespace in section and parameter names is irrelevant. Leading
+    and trailing whitespace in a parameter value is discarded. Internal
+    whitespace within a parameter value is retained verbatim.</para>
+
+    <para>Any line beginning with a semicolon (<quote>;</quote>) or a hash
+    (<quote>#</quote>) character is ignored, as are lines containing only
+    whitespace.</para>
+
+    <para>Any line ending in a <quote> <literal>\</literal> </quote> is
+    continued on the next line in the customary UNIX fashion.</para>
+
+    <para>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.</para>
+
+    <para>The parameter <option>include =
+    <replaceable>path</replaceable></option> allows you to include one config
+    file inside another. The file is included literally, as though typed in
+    place. Nested includes are not supported.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>SECTION DESCRIPTIONS</title>
+
+    <para>Each section in the configuration file (except for the [Global]
+    section) describes a shared resource (known as a <quote>volume</quote>).
+    The section name is the name of the volume and the parameters within the
+    section define the volume attributes and options.</para>
+
+    <para>There are two special sections, [Global] and [Homes], which are
+    described under <emphasis>special sections</emphasis>. The following notes
+    apply to ordinary section descriptions.</para>
+
+    <para>A volume consists of a directory to which access is being given plus
+    a description of the access rights which are granted to the user of the
+    service. For volumes the <option>path</option> option must specify the
+    directory to share.</para>
+
+    <para>Any volume section without <option>path</option> option is
+    considered a <emphasis>vol preset</emphasis> which can be selected in
+    other volume sections via the <option>vol preset</option> option and
+    constitutes defaults for the volume. For any option specified both in a
+    preset <emphasis>and</emphasis> in a volume section the volume section
+    setting completely substitutes the preset option.</para>
+
+    <para>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.</para>
+
+    <para>The following sample section defines an AFP volume. The user has
+    full access to the path <filename>/foo/bar</filename>. The share is
+    accessed via the share name <literal>baz</literal>: <programlisting> [baz]
+    path = /foo/bar </programlisting></para>
+  </refsect1>
+
+  <refsect1>
+    <title>SPECIAL SECTIONS</title>
+
+    <refsect2>
+      <title>The [Global] section</title>
+
+      <para>Parameters in this section apply to the server as a whole.
+      Parameters denoted by a (G) below are must be set in this
+      section.</para>
+    </refsect2>
+
+    <refsect2>
+      <title>The [Homes] section</title>
+
+      <para>This section enable sharing of the UNIX server user home
+      directories. Specifying an optional <option>path</option> parameter
+      means that not the whole user home will be shared but the subdirectory
+      <option>path</option>. It is necessary to define the <option>basedir
+      regex</option> 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 <option>home name</option> can
+      be used to change the AFP volume name which <emphasis>$u's
+      home</emphasis> by default. See below under VARIABLE
+      SUBSTITUTIONS.</para>
+
+      <para>The following example illustrates this. Given all user home
+      directories are stored under <filename>/home</filename>:
+      <programlisting> [Homes]
+      path = afp-data
+      basedir regex = /home</programlisting> For a user
+      <emphasis>john</emphasis> this results in an AFP home volume with a path
+      of <filename>/home/john/afp-data</filename>.</para>
+
+      <para>If <option>basedir regex</option> contains symlink, set the
+      canonicalized absolute path. When <filename>/home</filename> links to
+      <filename>/usr/home</filename>: <programlisting> [Homes]
+      basedir regex = /usr/home</programlisting></para>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>PARAMETERS</title>
+
+    <para>Parameters define the specific attributes of sections.</para>
+
+    <para>Some parameters are specific to the [Global] section (e.g.,
+    <emphasis>log type</emphasis>). All others are permissible only in volume
+    sections. The letter <emphasis>G</emphasis> in parentheses indicates that
+    a parameter is specific to the [Global] section. The letter
+    <emphasis>V</emphasis> indicates that a parameter can be specified in a
+    volume specific section.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>VARIABLE SUBSTITUTIONS</title>
+
+    <para>You can use variables in volume names. The use of variables in paths
+    is not supported for now.</para>
+
+    <orderedlist>
+      <listitem>
+        <para>if you specify an unknown variable, it will not get
+        converted.</para>
+      </listitem>
+
+      <listitem>
+        <para>if you specify a known variable, but that variable doesn't have
+        a value, it will get ignored.</para>
+      </listitem>
+    </orderedlist>
+
+    <para>The variables which can be used for substitutions are:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>$b</term>
+
+        <listitem>
+          <para>basename</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>$c</term>
+
+        <listitem>
+          <para>client's ip address</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>$d</term>
+
+        <listitem>
+          <para>volume pathname on server</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>$f</term>
+
+        <listitem>
+          <para>full name (contents of the gecos field in the passwd
+          file)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>$g</term>
+
+        <listitem>
+          <para>group name</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>$h</term>
+
+        <listitem>
+          <para>hostname</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>$i</term>
+
+        <listitem>
+          <para>client's ip, without port</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>$s</term>
+
+        <listitem>
+          <para>server name (this can be the hostname)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>$u</term>
+
+        <listitem>
+          <para>user name (if guest, it is the user that guest is running
+          as)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>$v</term>
+
+        <listitem>
+          <para>volume name</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>$$</term>
+
+        <listitem>
+          <para>prints dollar sign ($)</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>EXPLANATION OF GLOBAL PARAMETERS</title>
+
+    <refsect2>
+      <title>Authentication Options</title>
+
+      <variablelist>
+        <varlistentry>
+          <term>ad domain = <parameter>DOMAIN</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Append @DOMAIN to username when authenticating. Useful in
+            Active Directory environments that otherwise would require the
+            user to enter the full user@domain string.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>admin auth user = <parameter>user</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Specifying eg "<option>admin auth user = root</option>"
+            whenever a normal user login fails, afpd will try to authenticate
+            as the specified <option>admin auth user</option>. If this
+            succeeds, a normal session is created for the original connecting
+            user. Said differently: if you know the password of <option>admin
+            auth user</option>, you can authenticate as any other user.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>k5 keytab = <replaceable>path</replaceable>
+          <type>(G)</type></term>
+
+          <term>k5 service = <replaceable>service</replaceable>
+          <type>(G)</type></term>
+
+          <term>k5 realm = <replaceable>realm</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>These are required if the server supports the Kerberos 5
+            authentication UAM.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>nt domain = <parameter>DOMAIN</parameter>
+          <type>(G)</type></term>
+
+          <term>nt separator = <parameter>SEPARATOR</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>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.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>save password = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>yes</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>Enables or disables the ability of clients to save passwords
+            locally.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>set password = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>Enables or disables the ability of clients to change their
+            passwords via chooser or the "connect to server" dialog.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>uam list = <replaceable>uam list</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Space or comma separated list of UAMs. (The default is
+            "uams_dhx.so uams_dhx2.so").</para>
+
+            <para>The most commonly used UAMs are:</para>
+
+            <variablelist>
+              <varlistentry>
+                <term>uams_guest.so</term>
+
+                <listitem>
+                  <para>allows guest logins</para>
+                </listitem>
+              </varlistentry>
+
+              <varlistentry>
+                <term>uams_clrtxt.so</term>
+
+                <listitem>
+                  <para>(uams_pam.so or uams_passwd.so) Allow logins with
+                  passwords transmitted in the clear. (legacy)</para>
+                </listitem>
+              </varlistentry>
+
+              <varlistentry>
+                <term>uams_randum.so</term>
+
+                <listitem>
+                  <para>allows Random Number and Two-Way Random Number
+                  Exchange for authentication (requires a separate file
+                  containing the passwords, either @pkgconfdir@/afppasswd file or
+                  the one specified via "<option>passwd file</option>". See
+                  <citerefentry>
+                      <refentrytitle>afppasswd</refentrytitle>
+
+                      <manvolnum>1</manvolnum>
+                    </citerefentry> for details. (legacy)</para>
+                </listitem>
+              </varlistentry>
+
+              <varlistentry>
+                <term>uams_dhx.so</term>
+
+                <listitem>
+                  <para>(uams_dhx_pam.so or uams_dhx_passwd.so) Allow
+                  Diffie-Hellman eXchange (DHX) for authentication.</para>
+                </listitem>
+              </varlistentry>
+
+              <varlistentry>
+                <term>uams_dhx2.so</term>
+
+                <listitem>
+                  <para>(uams_dhx2_pam.so or uams_dhx2_passwd.so) Allow
+                  Diffie-Hellman eXchange 2 (DHX2) for authentication.</para>
+                </listitem>
+              </varlistentry>
+
+              <varlistentry>
+                <term>uam_gss.so</term>
+
+                <listitem>
+                  <para>Allow Kerberos V for authentication (optional)</para>
+                </listitem>
+              </varlistentry>
+            </variablelist>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>uam path = <replaceable>path</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Sets the default path for UAMs for this server (default is
+            @libdir@/netatalk).</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>Charset Options</title>
+
+      <para>With OS X Apple introduced the AFP3 protocol. One of the big
+      changes was, that AFP3 uses Unicode names encoded as Decomposed UTF-8
+      (UTF8-MAC). Previous AFP/OS versions used charsets like MacRoman,
+      MacCentralEurope, etc.</para>
+
+      <para>To be able to serve AFP3 and older clients at the same time,
+      <command>afpd</command> 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, <command>afpd</command> can detect the codepage a pre
+      AFP3 client uses, you have to specify it using the <option>mac
+      charset</option> option. The default is MacRoman, which should be fine
+      for most western users.</para>
+
+      <para>As <command>afpd</command> 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 <command>afpd</command> uses
+      <emphasis>UTF8</emphasis>. You can set the UNIX charset using the
+      <option>unix charset</option> option. If you're using extended
+      characters in the configuration files for <command>afpd</command>, make
+      sure your terminal matches the <option>unix charset</option>.</para>
+
+      <variablelist>
+        <varlistentry>
+          <term>mac charset = <parameter>CHARSET</parameter>
+          <type>(G)/(V)</type></term>
+
+          <listitem>
+            <para>Specifies the Mac clients charset, e.g.
+            <emphasis>MAC_ROMAN</emphasis>. This is used to convert strings
+            and filenames to the clients codepage for OS9 and Classic, i.e.
+            for authentication and AFP messages (SIGUSR2 messaging). This will
+            also be the default for the volumes <option>mac charset</option>.
+            Defaults to <emphasis>MAC_ROMAN</emphasis>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>unix charset = <parameter>CHARSET</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Specifies the servers unix charset, e.g.
+            <emphasis>ISO-8859-15</emphasis> or <emphasis>EUC-JP</emphasis>.
+            This is used to convert strings to/from the systems locale, e.g.
+            for authentication, server messages and volume names. If
+            <emphasis>LOCALE</emphasis> is set, the systems locale is used.
+            Defaults to <emphasis>UTF8</emphasis>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>vol charset = <parameter>CHARSET</parameter>
+          <type>(G)/(V)</type></term>
+
+          <listitem>
+            <para>Specifies the encoding of the volumes filesystem. By
+            default, it is the same as <option>unix charset</option>.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>Password Options</title>
+
+      <variablelist>
+        <varlistentry>
+          <term>passwd file = <parameter>path</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Sets the path to the Randnum UAM passwd file for this server
+            (default is @pkgconfdir@/afppasswd).</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>passwd minlen = <parameter>number</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Sets the minimum password length, if supported by the
+            UAM</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>Network Options</title>
+
+      <variablelist>
+        <varlistentry>
+          <term>advertise ssh = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>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 <citerefentry>
+                <refentrytitle>sshd</refentrytitle>
+
+                <manvolnum>8</manvolnum>
+              </citerefentry> on the server to let things work.</para>
+
+            <note>
+              <para>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.</para>
+            </note>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>afp listen = <replaceable>ip address[:port] [ip address[:port]
+          ...]</replaceable> <type>(G)</type></term>
+
+          <listitem>
+            <para>Specifies the IP address that the server should advertise
+            <emphasis role="bold">and</emphasis> 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.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>afp port = <replaceable>port number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Allows a different TCP port to be used for AFP. The default
+            is 548. Also sets the default port applied when none specified in
+            an <option>afp listen</option> option.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>cnid listen = <replaceable>ip address[:port] [ip
+          address[:port] ...]</replaceable> <type>(G)</type></term>
+
+          <listitem>
+            <para>Specifies the IP address that the CNID server should listen
+            on. The default is <emphasis
+            role="bold">localhost:4700</emphasis>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>disconnect time = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Keep disconnected AFP sessions for
+            <parameter>number</parameter> hours before dropping them. Default
+            is 24 hours.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>dsireadbuf = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Scale factor that determines the size of the DSI/TCP
+            readahead buffer, default is 12. This is multiplies with the DSI
+            server quantum (default ~300k) to give the size of the buffer.
+            Increasing this value might increase throughput in fast local
+            networks for volume to volume copies. <emphasis>Note</emphasis>:
+            This buffer is allocated per afpd child process, so specifying
+            large values will eat up large amount of memory (buffer size *
+            number of clients).</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>fqdn = <replaceable>name:port</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>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 &lt;= 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.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>hostname = <replaceable>name</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>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 <option>afp
+            listen</option>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>max connections = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Sets the maximum number of clients that can simultaneously
+            connect to the server (default is 200).</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>server quantum = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>This specifies the DSI server quantum. The default value is
+            1 MB. 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</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>sleep time = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Keep sleeping AFP sessions for <parameter>number</parameter>
+            hours before disconnecting clients in sleep mode. Default is 10
+            hours.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>tcprcvbuf = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Try to set TCP receive buffer using setsockpt(). Often OSes
+            impose restrictions on the applications ability to set this
+            value.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>tcpsndbuf = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Try to set TCP send buffer using setsockpt(). Often OSes
+            impose restrictions on the applications ability to set this
+            value.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>use sendfile = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>yes</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>Whether to use sendfile<indexterm>
+                <primary>sendfile</primary>
+              </indexterm> syscall for sending file data to clients.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>zeroconf = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>yes</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>Whether to use automatic Zeroconf<indexterm>
+                <primary>Zeroconf</primary>
+
+                <secondary>Bonjour</secondary>
+              </indexterm> service registration if Avahi or mDNSResponder were
+            compiled in.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>Miscellaneous Options</title>
+
+      <variablelist>
+        <varlistentry>
+          <term>admin group = <replaceable>group</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Allows users of a certain group to be seen as the superuser
+            when they log in. This option is disabled by default.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>afp read locks = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>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.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>afpstats = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>Whether to provide AFP runtime statistics (connected
+            users, open volumes) via dbus.</para>            
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>basedir regex = <replaceable>regex</replaceable>
+          <type>(H)</type></term>
+
+          <listitem>
+            <para>Regular expression which matches the parent directory of the
+            user homes. If <option>basedir regex</option> contains symlink,
+            you must set the canonicalized absolute path. In the simple case
+            this is just a path ie <option>basedir regex =
+            /home</option></para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>close vol = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>Whether to close volumes possibly opened by clients when
+            they're removed from the configuration and the configuration is
+            reloaded.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>cnid server = <replaceable>ipaddress[:port]</replaceable>
+          <type>(G)/(V)</type></term>
+
+          <listitem>
+            <para>Specifies the IP address and port of a cnid_metad server,
+            required for CNID dbd backend. Defaults to localhost:4700. The
+            network address may be specified either in dotted-decimal format
+            for IPv4 or in hexadecimal format for IPv6.-</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>dircachesize = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Maximum possible entries in the directory cache. The cache
+            stores directories and files. It is used to cache the full path to
+            directories and CNIDs which considerably speeds up directory
+            enumeration.</para>
+
+            <para>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.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>extmap file = <parameter>path</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Sets the path to the file which defines file extension
+            type/creator mappings. (default is @pkgconfdir@/extmap.conf).</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>guest account = <replaceable>name</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Specifies the user that guests should use (default is
+            "nobody"). The name should be quoted.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>home name = <replaceable>name</replaceable>
+          <type>(H)</type></term>
+
+          <listitem>
+            <para>AFP user home volume name. The default is <emphasis>user's
+            home</emphasis>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>login message = <replaceable>message</replaceable>
+          <type>(G)/(V)</type></term>
+
+          <listitem>
+            <para>Sets a message to be displayed when clients logon to the
+            server. The message should be in <option>unix charset</option> and
+            should be quoted. Extended characters are allowed.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>mimic model = <replaceable>model</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Specifies the icon model that appears on clients. Defaults
+            to off. Note that afpd must support Zeroconf.
+            Examples: RackMac (same as Xserve), PowerBook, PowerMac,
+            Macmini, iMac, MacBook, MacBookPro, MacBookAir, MacPro,
+            AppleTV1,1, AirPort.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>signature = &lt;text&gt; <type>(G)</type></term>
+
+          <listitem>
+            <para>Specify a server signature. The maximum length is 16
+            characters. This option is useful for clustered environments, to
+            provide fault isolation etc. By default, afpd generate signature
+            and saving it to
+            <filename>@localstatedir@/netatalk/afp_signature.conf</filename>
+            automatically (based on random number). See also
+            asip-status.pl(1).</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>solaris share reservations =
+          <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>yes</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>Use share reservations on Solaris. Solaris CIFS server uses
+            this too, so this makes a lock coherent multi protocol
+            server.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>vol dbpath = <replaceable>path</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>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
+            <filename>@localstatedir@/netatalk/CNID/</filename>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>volnamelen = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Max length of UTF8-MAC volume name for Mac OS X. Note that
+            Hangul is especially sensitive to this.</para>
+
+            <para><programlisting> 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</programlisting> Mac OS 9 and earlier are not influenced by
+            this, because Maccharset volume name is always limited to 27
+            bytes.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>vol preset = <replaceable>name</replaceable>
+          <type>(G)/(V)</type></term>
+
+          <listitem>
+            <para>Use section <option>name</option> as option preset for all
+            volumes (when set in the [Global] section) or for one volume (when
+            set in that volume's section).</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>Logging Options</title>
+
+      <variablelist>
+        <varlistentry>
+          <term>log file = <replaceable>logfile</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>If not specified Netatalk logs to syslogs daemon facility.
+            Otherwise it logs to <option>logfile</option>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>log level = <replaceable>type:level [type:level
+          ...]</replaceable> <type>(G)</type></term>
+
+          <term>log level = <replaceable>type:level,[type:level,
+          ...]</replaceable> <type>(G)</type></term>
+
+          <listitem>
+            <para>Specify that any message of a loglevel up to the given
+            <option>log level</option> should be logged.</para>
+
+            <para>By default afpd logs to syslog with a default logging setup
+            equivalent to <option>default:note</option></para>
+
+            <para>logtypes: default, afpdaemon, logger, uamsdaemon</para>
+
+            <para>loglevels: severe, error, warn, note, info, debug, debug6,
+            debug7, debug8, debug9, maxdebug</para>
+
+            <note>
+              <para>Both logtype and loglevels are case insensitive.</para>
+            </note>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2 id="fceconf">
+      <title>Filesystem Change Events (FCE<indexterm>
+          <primary>FCE</primary>
+        </indexterm>)</title>
+
+      <para>Netatalk includes a nifty filesystem change event mechanism where
+      afpd processes notify interested listeners about certain filesystem
+      event by UDP network datagrams.</para>
+
+      <variablelist>
+        <varlistentry>
+          <term>fce listener = <replaceable>host[:port]</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Enables sending FCE events to the specified
+            <parameter>host</parameter>, default <parameter>port</parameter>
+            is 12250 if not specified. Specifying multiple listeners is done
+            by having this option once for each of them.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>fce events =
+          <replaceable>fmod,fdel,ddel,fcre,dcre,tmsz</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Specifies which FCE events are active, default is
+            <parameter>fmod,fdel,ddel,fcre,dcre</parameter>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>fce coalesce = <replaceable>all|delete|create</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Coalesce FCE events.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>fce holdfmod = <replaceable>seconds</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>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.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>Debug Parameters</title>
+
+      <para>These options are useful for debugging only.</para>
+
+      <variablelist>
+        <varlistentry>
+          <term>tickleval = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Sets the tickle timeout interval (in seconds). Defaults to
+            30.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>timeout = <replaceable>number</replaceable>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Specify the number of tickles to send before timing out a
+            connection. The default is 4, therefore a connection will timeout
+            after 2 minutes.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>client polling = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(G)</type></term>
+
+          <listitem>
+            <para>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. <emphasis>Note</emphasis>: Depending on the number of
+            simultaneously connected clients and the network's speed, this can
+            lead to a significant higher load on your network!</para>
+
+            <para>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.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2 id="acl_options">
+      <title>Options for ACL handling</title>
+
+      <para>By default, the effective permission of the authenticated user are
+      only mapped to the mentioned UARights permission structure, not the UNIX
+      mode. You can adjust this behaviour with the configuration option
+      <option>mac acls</option>:</para>
+
+      <variablelist id="mac_acls">
+        <varlistentry>
+          <term>map acls = <parameter>none|rights|mode</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para><variablelist>
+                <varlistentry>
+                  <term>none</term>
+
+                  <listitem>
+                    <para>no mapping of ACLs </para>
+                  </listitem>
+                </varlistentry>
+
+                <varlistentry>
+                  <term>rights</term>
+
+                  <listitem>
+                    <para>effective permissions are mapped to UARights
+                    structure. This is the default.</para>
+                  </listitem>
+                </varlistentry>
+
+                <varlistentry>
+                  <term>mode</term>
+
+                  <listitem>
+                    <para>ACLs are additionally mapped to the UNIX mode of the
+                    filesystem object.</para>
+                  </listitem>
+                </varlistentry>
+              </variablelist></para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+
+      <para>If you want to be able to display ACLs on the client, you must
+      setup both client and server as part on a authentication domain
+      (directory service, eg LDAP, Open Directory, Active Directory). The
+      reason is, in OS X ACLs are bound to UUIDs, not just uid's or gid's.
+      Therefor Netatalk 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.</para>
+
+      <para>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).</para>
+
+      <para>The following LDAP options must be configured for Netatalk:</para>
+
+      <variablelist>
+        <varlistentry>
+          <term>ldap auth method = <parameter>none|simple|sasl</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Authentication method: <option>none | simple |
+            sasl</option></para>
+
+            <para><variablelist>
+                <varlistentry>
+                  <term>none</term>
+
+                  <listitem>
+                    <para>anonymous LDAP bind</para>
+                  </listitem>
+                </varlistentry>
+
+                <varlistentry>
+                  <term>simple</term>
+
+                  <listitem>
+                    <para>simple LDAP bind</para>
+                  </listitem>
+                </varlistentry>
+
+                <varlistentry>
+                  <term>sasl</term>
+
+                  <listitem>
+                    <para>SASL. Not yet supported !</para>
+                  </listitem>
+                </varlistentry>
+              </variablelist></para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap auth dn = <parameter>dn</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Distinguished Name of the user for simple bind.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap auth pw = <parameter>password</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Distinguished Name of the user for simple bind.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap server = <parameter>host</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>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.</para>
+
+            <para>You can use <citerefentry>
+                <refentrytitle>afpldaptest</refentrytitle>
+
+                <manvolnum>1</manvolnum>
+              </citerefentry> to syntactically check your config.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap userbase = <parameter>base dn</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>DN of the user container in LDAP.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap userscope = <parameter>scope</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Search scope for user search: <option>base | one |
+            sub</option></para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap groupbase = <parameter>base dn</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>DN of the group container in LDAP.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap groupscope = <parameter>scope</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Search scope for user search: <option>base | one |
+            sub</option></para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap uuid attr = <parameter>dn</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Name of the LDAP attribute with the UUIDs.</para>
+
+            <para>Note: this is used both for users and groups.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap name attr = <parameter>dn</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Name of the LDAP attribute with the users short name.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap uuid string = <parameter>STRING</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>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.</para>
+
+            <para>Default: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap uuid encoding = <parameter>string | ms-guid (default:
+          string)</parameter> <type>(G)</type></term>
+
+          <listitem>
+            <para>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.</para>
+
+            <para><variablelist>
+                <varlistentry>
+                  <term>string</term>
+
+                  <listitem>
+                    <para>UUID is a string, use with eg OpenDirectory.</para>
+                  </listitem>
+                </varlistentry>
+
+                <varlistentry>
+                  <term>ms-guid</term>
+
+                  <listitem>
+                    <para>Binary objectGUID from Active Directory</para>
+                  </listitem>
+                </varlistentry>
+              </variablelist></para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ldap group attr = <parameter>dn</parameter>
+          <type>(G)</type></term>
+
+          <listitem>
+            <para>Name of the LDAP attribute with the groups short
+            name.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>EXPLANATION OF VOLUME PARAMETERS</title>
+
+    <refsect2>
+      <title>Parameters</title>
+
+      <para>The section name defines the volume name.
+      No two volumes may have the same
+      name. The volume name cannot contain the <keycode>':'</keycode>
+      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.</para>
+
+      <variablelist>
+        <varlistentry>
+          <term>path = <replaceable>PATH</replaceable> <type>(V)</type></term>
+
+          <listitem>
+            <para>The path name must be a fully qualified path name.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>appledouble = <replaceable>ea|v2</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>Specify the format of the metadata files, which are used for
+            saving Mac resource fork as well. Earlier versions used
+            AppleDouble v2, the new default format is <emphasis
+            role="bold">ea</emphasis>.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>vol size limit = <replaceable>size in MiB</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>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. <emphasis role="bold">IMPORTANT:
+            </emphasis> 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.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>valid users = <replaceable>user @group</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>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:
+            <programlisting>valid users = user "user 2" @group “@group 2"</programlisting></para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>invalid users = <replaceable>users/groups</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>The deny option specifies users and groups who are not
+            allowed access to the share. It follows the same format as the
+            "valid users" option.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>hosts allow = <replaceable>IP host address/IP netmask bits [
+          ... ]</replaceable> <type>(V)</type></term>
+
+          <listitem>
+            <para>Only listed hosts and networks are allowed, all others are
+            rejected. The network address may be specified either in
+            dotted-decimal format for IPv4 or in hexadecimal format for
+            IPv6.</para>
+
+            <para>Example: hosts allow = 10.1.0.0/16 10.2.1.100
+            2001:0db8:1234::/48</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>hosts deny = <replaceable>IP host address/IP netmask bits [
+          ... ]</replaceable> <type>(V)</type></term>
+
+          <listitem>
+            <para>Listed hosts and nets are rejected, all others are
+            allowed.</para>
+
+            <para>Example: hosts deny = 192.168.100/24 10.1.1.1
+            2001:db8::1428:57ab</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>cnid scheme = <replaceable>backend</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>set the CNID backend to be used for the volume, default is
+            [@DEFAULT_CNID_SCHEME@] available schemes:
+            [@compiled_backends@]</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>ea = <replaceable>none|auto|sys|ad</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>Specify how Extended Attributes<indexterm>
+                <primary>Extended Attributes</primary>
+              </indexterm> are stored. <option>auto</option> is the
+            default.</para>
+
+            <variablelist>
+              <varlistentry>
+                <term>auto</term>
+
+                <listitem>
+                  <para>Try <option>sys</option> (by setting an EA on the
+                  shared directory itself), fallback to <option>ad</option>.
+                  Requires writable volume for performing test. "<option>read
+                  only = yes</option>" overwrites <option>auto</option> with
+                  <option>none</option>. Use explicit "<option>ea =
+                  sys|ad</option>" for read-only volumes where
+                  appropriate.</para>
+                </listitem>
+              </varlistentry>
+
+              <varlistentry>
+                <term>sys</term>
+
+                <listitem>
+                  <para>Use filesystem Extended Attributes.</para>
+                </listitem>
+              </varlistentry>
+
+              <varlistentry>
+                <term>ad</term>
+
+                <listitem>
+                  <para>Use files in <emphasis>.AppleDouble</emphasis>
+                  directories.</para>
+                </listitem>
+              </varlistentry>
+
+              <varlistentry>
+                <term>none</term>
+
+                <listitem>
+                  <para>No Extended Attributes support.</para>
+                </listitem>
+              </varlistentry>
+            </variablelist>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>mac charset = <replaceable>CHARSET</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>specifies the Mac client charset for this Volume, e.g.
+            <emphasis>MAC_ROMAN</emphasis>, <emphasis>MAC_CYRILLIC</emphasis>.
+            If not specified the global setting is applied. This setting is
+            only required if you need volumes, where the Mac charset differs
+            from the one globally set in the [Global] section.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>casefold = <option>option</option> <type>(V)</type></term>
+
+          <listitem>
+            <para>The casefold option handles, if the case of filenames should
+            be changed. The available options are:</para>
+
+            <para><option>tolower</option> - Lowercases names in both
+            directions.</para>
+
+            <para><option>toupper</option> - Uppercases names in both
+            directions.</para>
+
+            <para><option>xlatelower</option> - Client sees lowercase, server
+            sees uppercase.</para>
+
+            <para><option>xlateupper</option> - Client sees uppercase, server
+            sees lowercase.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>password = <replaceable>password</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>This option allows you to set a volume password, which can
+            be a maximum of 8 characters long (using ASCII strongly
+            recommended at the time of this writing).</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>file perm = <replaceable>mode</replaceable>
+          <type>(V)</type></term>
+
+          <term>directory perm = <replaceable>mode</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>Add(or) with the client requested permissions: <option>file
+            perm</option> is for files only, <option>directory perm</option>
+            is for directories only. Don't use with "<option>unix priv =
+            no</option>".</para>
+
+            <example>
+              <title>Volume for a collaborative workgroup</title>
+
+              <para><programlisting>file perm = 0660 directory perm =
+              0770</programlisting></para>
+            </example>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>umask = <replaceable>mode</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>set perm mask. Don't use with "<option>unix priv =
+            no</option>".</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>preexec = <replaceable>command</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>command to be run when the volume is mounted, ignored for
+            user defined volumes</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>postexec = <replaceable>command</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>command to be run when the volume is closed, ignored for
+            user defined volumes</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>root preexec = <replaceable>command</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>command to be run as root when the volume is mounted,
+            ignored for user defined volumes</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>root postexec = <replaceable>command</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>command to be run as root when the volume is closed, ignored
+            for user defined volumes</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>rolist = <option>users/groups</option> <type>(V)</type></term>
+
+          <listitem>
+            <para>Allows certain users and groups to have read-only access to
+            a share. This follows the allow option format.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>rwlist = <replaceable>users/groups</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>Allows certain users and groups to have read/write access to
+            a share. This follows the allow option format.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>veto files = <replaceable>vetoed names</replaceable>
+          <type>(V)</type></term>
+
+          <listitem>
+            <para>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/".</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
+      <title>Volume options</title>
+
+      <para>Boolean volume options.</para>
+
+      <variablelist>
+        <varlistentry>
+          <term>acls = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>yes</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>Whether to flag volumes as supporting ACLs. If ACL support
+            is compiled in, this is yes by default.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>cnid dev = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>yes</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>Whether to use the device number in the CNID backends. Helps
+            when the device number is not constant across a reboot, eg
+            cluster, ...</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>convert appledouble = <replaceable>BOOLEAN</replaceable>
+          (default: <emphasis>yes</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>Whether automatic conversion from <option>appledouble =
+            v2</option> to <option>appledouble = ea</option> is performed when
+            accessing filesystems from clients. This is generally useful, but
+            costs some performance. It's recommendable to run
+            <command>dbd</command> on volumes and do the conversion with that.
+            Then this option can be set to no.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>follow symlinks = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>The default setting is false thus 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".</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>invisible dots = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>make dot files invisible. WARNING: enabling this option will
+              lead to unwanted sideeffects were OS X applications when saving
+              files to a temporary file starting with a dot first, then renaming
+              the temp file to its final name, result in the saved file being
+              invisible. The only thing this option is useful for is making
+              files that start with a dot invisible on Mac OS 9. It's
+              completely useless on Mac OS X, as both in Finder and in Terminal
+              files starting with a dot are hidden anyway.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>network ids = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>yes</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>Whether the server support network ids. Setting this to
+            <emphasis>no</emphasis> will result in the client not using ACL
+            AFP functions.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>preexec close = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>A non-zero return code from preexec close the volume being
+            immediately, preventing clients to mount/see the volume in
+            question.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>read only = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>Specifies the share as being read only for all users.
+            Overwrites <option>ea = auto</option> with <option>ea =
+            none</option></para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>root preexec close= <replaceable>BOOLEAN</replaceable>
+          (default: <emphasis>no</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>A non-zero return code from root_preexec closes the volume
+            immediately, preventing clients to mount/see the volume in
+            question.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>search db = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>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.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>stat vol = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>yes</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>Whether to stat volume path when enumerating volumes list,
+            useful for automounting or volumes created by a preexec
+            script.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>time machine = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>no</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>Whether to enable Time Machine support for this
+            volume.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>unix priv = <replaceable>BOOLEAN</replaceable> (default:
+          <emphasis>yes</emphasis>) <type>(V)</type></term>
+
+          <listitem>
+            <para>Whether to use AFP3 UNIX privileges. This should be set for
+            OS X clients. See also: <option>file perm</option>,
+            <option>directory perm</option> and <option>umask</option>.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <refsect1>
+    <title>CNID backends</title>
+
+    <para>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
+    <filename>@localstatedir@/netatalk/CNID/(volumename)/.AppleDB/</filename>
+    directory.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>cdb</term>
+
+        <listitem>
+          <para>"Concurrent database", backend is based on Oracle Berkley DB.
+          With this backend several <command>afpd</command> daemons access the
+          CNID database directly. Berkeley DB locking is used to synchronize
+          access, if more than one <command>afpd</command> process is active
+          for a volume. The drawback is, that the crash of a single
+          <command>afpd</command> process might corrupt the database.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>dbd</term>
+
+        <listitem>
+          <para>Access to the CNID database is restricted to the
+          <command>cnid_metad</command> daemon process.
+          <command>afpd</command> processes communicate with the daemon for
+          database reads and updates. If built with Berkeley DB transactions
+          the probability for database corruption is practically zero, but
+          performance can be slower than with <option>cdb</option></para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>last</term>
+
+        <listitem>
+          <para>This backend is an exception, in terms of ID persistency. ID's
+          are only valid for the current session. This is basically what
+          <command>afpd</command> 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 <emphasis>read only
+          mode</emphasis> automatically.</para>
+
+          <para><emphasis role="bold">Warning</emphasis>: It is
+          <emphasis>NOT</emphasis> recommended to use this backend for volumes
+          anymore, as <command>afpd</command> now relies heavily on a
+          persistent ID database. Aliases will likely not work and filename
+          mangling is not supported.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>Even though <command>./configure --help</command> 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.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Charset options</title>
+
+    <para>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.</para>
+
+    <para><command>afpd</command> 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 (&gt;0x7F) would be converted to a :xx sequence,
+    e.g. the Apple Logo (MacRoman: 0xF0) was saved as <literal>:f0</literal>.
+    Some special characters will be converted as to :xx notation as well.
+    '<keycode>/</keycode>' will be encoded to <literal>:2f</literal>, if
+    <option>usedots</option> is not specified, a leading dot
+    '<keycode>.</keycode>' will be encoded as <literal>:2e</literal>.</para>
+
+    <para>This version now uses UTF-8 as the default encoding for names.
+    '<keycode>/</keycode>' will be converted to '<keycode>:</keycode>'.</para>
+
+    <para>The <option>vol charset</option> option will allow you to select
+    another volume encoding. E.g. for western users another useful setting
+    could be vol charset ISO-8859-15. <command>afpd</command> will accept any
+    <citerefentry>
+        <refentrytitle><command>iconv</command></refentrytitle>
+
+        <manvolnum>1</manvolnum>
+      </citerefentry> provided charset. If a character cannot be converted
+    from the <option>mac charset</option> to the selected <option>vol
+    charset</option>, afpd will save it as a CAP encoded character. For AFP3
+    clients, <command>afpd</command> will convert the UTF-8<indexterm>
+        <primary>UTF8</primary>
+
+        <secondary>afpd's vol charset setting</secondary>
+      </indexterm><indexterm>
+        <primary>UTF8-MAC</primary>
+
+        <secondary>afpd's vol charset setting</secondary>
+      </indexterm><indexterm>
+        <primary>ISO-8859-15</primary>
+
+        <secondary>afpd's vol charset setting</secondary>
+      </indexterm><indexterm>
+        <primary>ISO-8859-1</primary>
+
+        <secondary>afpd's vol charset setting</secondary>
+      </indexterm> character to <option>mac charset</option> first. If this
+    conversion fails, you'll receive a -50 error on the mac.</para>
+
+    <para><emphasis>Note</emphasis>: Whenever you can, please stick with the
+    default UTF-8 volume format.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>SEE ALSO</title>
+
+    <para><citerefentry>
+        <refentrytitle>afpd</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afppasswd</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afp_signature.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>extmap.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>cnid_metad</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man5/afp_signature.conf.5.xml b/doc/manpages/man5/afp_signature.conf.5.xml
new file mode 100644 (file)
index 0000000..287b6d7
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="afp_signature.conf.5">
+
+  <refmeta>
+    <refentrytitle>afp_signature.conf</refentrytitle>
+
+    <manvolnum>5</manvolnum>
+
+    <refmiscinfo class="date">23 Mar 2012</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>afp_signature.conf</refname>
+
+    <refpurpose>Configuration file used by afpd(8) to specify server
+        signature<indexterm>
+        <primary>afp_signature.conf</primary>
+      </indexterm></refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><filename>@localstatedir@/netatalk/afp_signature.conf</filename> is the
+    configuration file used by <command>afpd</command> to specify
+    server signature automagically. The configuration lines are
+    composed like:</para>
+
+    <para><replaceable>"server name"</replaceable>
+    <replaceable>hexa-string</replaceable></para>
+
+    <para>The first field is server name. Server names must be quoted
+    if they contain spaces. The second field is the hexadecimal string
+    of 32 characters for 16-bytes server signature.</para>
+    <para>The leading spaces and tabs are ignored. Blank lines are ignored.
+    The lines prefixed with # are ignored. The illegal lines are ignored.
+    </para>
+
+    <note>
+        <para>Server Signature is unique 16-bytes identifier used to
+        prevent logging on to the same server twice. </para>
+        <para>Netatalk 2.0 and earlier generated server signature by using
+        gethostid(). There was a problem that another servers have the same
+        signature because the hostid is not unique enough.</para>
+        <para>Current netatalk generates the signature from random numbers and
+        saves it into afp_signature.conf. When starting next time, it
+        is read from this file. </para>
+        <para>This file should not be thoughtlessly edited and be copied
+        onto another server. If it wants to set the signature intentionally,
+        use the option "signature ="  in afp.conf. In this case,
+        afp_signature.conf is not used.</para>
+    </note>
+
+    <para></para>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+
+    <example>
+      <title>afp_signature.conf</title>
+
+      <programlisting># This is a comment.
+"My Server" 74A0BB94EC8C13988B2E75042347E528</programlisting>
+    </example>
+  </refsect1>
+
+  <refsect1>
+    <title>See also</title>
+
+    <para><citerefentry>
+        <refentrytitle>afpd</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afp.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>asip-status.pl</refentrytitle>
+
+        <manvolnum>1</manvolnum>
+      </citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man5/afp_voluuid.conf.5.xml b/doc/manpages/man5/afp_voluuid.conf.5.xml
new file mode 100644 (file)
index 0000000..0956b47
--- /dev/null
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="afp_voluuid.conf.5">
+
+  <refmeta>
+    <refentrytitle>afp_voluuid.conf</refentrytitle>
+
+    <manvolnum>5</manvolnum>
+
+    <refmiscinfo class="date">23 Mar 2012</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>afp_voluuid.conf</refname>
+
+    <refpurpose>Configuration file used by afpd(8) to specify UUID
+        for Time Machine volume<indexterm>
+        <primary>afp_voluuid.conf</primary>
+      </indexterm></refpurpose>
+  </refnamediv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><filename>@localstatedir@/netatalk/afp_voluuid.conf</filename> is the
+    configuration file used by <command>afpd</command> to specify
+    UUID of Time Machine volume automagically. The configuration
+    lines are composed like:</para>
+
+    <para><replaceable>"volume name"</replaceable>
+    <replaceable>uuid-string</replaceable></para>
+
+    <para>The first field is volume name. Volume names must be quoted
+    if they contain spaces. The second field is the 36 character
+    hexadecimal ASCII string representation of a UUID.</para>
+    <para>The leading spaces and tabs are ignored. Blank lines are ignored.
+    The lines prefixed with # are ignored. The illegal lines are ignored.
+    </para>
+
+    <note>
+        <para>This UUID is advertised by Zeroconf in order to provide
+        robust disambiguation of Time Machine volume.</para>
+        <para>The afpd generates the UUID from random numbers and saves it
+        into afp_voluuid.conf, only when setting "time machine = yes" option
+        in afp.conf.</para>
+        <para>This file should not be thoughtlessly edited and be copied
+        onto another server.</para>
+    </note>
+
+    <para></para>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+
+    <example>
+      <title>afp_voluuid.conf three TM volumes on one netatalk</title>
+
+      <programlisting># This is a comment.
+"Backup for John Smith" 1573974F-0ABD-69CC-C40A-8519B681A0E1
+"bob" 39A487F4-55AA-8240-E584-69AA01800FE9
+mary 6331E2D1-446C-B68C-3066-D685AADBE911</programlisting>
+    </example>
+  </refsect1>
+
+  <refsect1>
+    <title>See also</title>
+
+    <para><citerefentry>
+        <refentrytitle>afpd</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afp.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>avahi-daemon</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>mDNSResponder</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man5/extmap.conf.5.xml b/doc/manpages/man5/extmap.conf.5.xml
new file mode 100644 (file)
index 0000000..4265928
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="extmap.conf.5">
+  <refmeta>
+    <refentrytitle>extmap.conf</refentrytitle>
+
+    <manvolnum>5</manvolnum>
+
+    <refmiscinfo class="date">19 Jan 2013</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>extmap.conf</refname>
+
+    <refpurpose>Configuration file used by afpd(8) to
+    specify file name extension mappings.<indexterm>
+        <primary>extmap.conf</primary>
+      </indexterm>
+      </refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv id="synopsis">
+    <cmdsynopsis>
+      <command>@pkgconfdir@/extmap.conf<indexterm><primary>extmap.conf</primary></indexterm></command>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+    <filename>@pkgconfdir@/extmap.conf</filename> is the
+    configuration file used by <command>afpd</command> to
+    specify file name extension mappings.</para>
+
+    <para>The configuration lines are composed like:</para>
+
+    <para><filename>.extension</filename> <replaceable>[ type [
+    creator ] ]</replaceable></para>
+
+    <para>Any line beginning with a hash (“#”) character is ignored.
+    The leading-dot lines specify file name extension mappings.
+    The extension '.' sets the default creator and type for otherwise
+    untyped Unix files.</para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+
+    <example>
+      <title>Extension is jpg. Type is "JPEG". Creator is "ogle".</title>
+
+            <programlisting>.jpg "JPEG" "ogle"</programlisting>
+          </example>
+
+    <example>
+      <title>Extension is lzh. Type is "LHA ". Creator is not defined.</title>
+
+            <programlisting>.lzh "LHA "</programlisting>
+          </example>
+
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para><citerefentry>
+        <refentrytitle>afp.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afpd</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man8/.gitignore b/doc/manpages/man8/.gitignore
new file mode 100644 (file)
index 0000000..c756d8f
--- /dev/null
@@ -0,0 +1 @@
+*\.8
diff --git a/doc/manpages/man8/Makefile.am b/doc/manpages/man8/Makefile.am
new file mode 100644 (file)
index 0000000..3f23a78
--- /dev/null
@@ -0,0 +1,26 @@
+XSLTPROC=@XSLTPROC@
+XSLTPROC_FLAGS=@XSLTPROC_FLAGS@
+MAN_STYLESHEET=$(top_srcdir)/doc/man.xsl
+CLEANFILES =
+
+MAN_MANPAGES = \
+       afpd.8 \
+       cnid_dbd.8 \
+       cnid_metad.8 \
+       netatalk.8
+
+EXTRA_DIST = \
+       afpd.8.xml \
+       cnid_dbd.8.xml \
+       cnid_metad.8.xml \
+       netatalk.8.xml
+
+if HAVE_XSLTPROC
+CLEANFILES += $(MAN_MANPAGES)
+
+%.8 : $(MAN_STYLESHEET) %.8.xml
+       @xsltproc $(MAN_STYLESHEET) $<
+       @cp $@ $(top_builddir)/man/man8/$@.in
+
+html-local: $(MAN_MANPAGES)
+endif
\ No newline at end of file
diff --git a/doc/manpages/man8/afpd.8.xml b/doc/manpages/man8/afpd.8.xml
new file mode 100644 (file)
index 0000000..fff2758
--- /dev/null
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="afpd.8">
+  <refmeta>
+    <refentrytitle>afpd</refentrytitle>
+
+    <manvolnum>8</manvolnum>
+
+    <refmiscinfo class="date">19 Jan 2013</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>afpd</refname>
+
+    <refpurpose>Apple Filing Protocol daemon</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>afpd<indexterm>
+          <primary>afpd</primary>
+        </indexterm></command>
+
+      <arg choice="opt">-d</arg>
+
+      <arg choice="opt">-F <replaceable>configfile</replaceable></arg>
+
+      <sbr />
+
+      <command>afpd<indexterm>
+          <primary>afpd</primary>
+        </indexterm></command>
+
+      <group choice="plain">
+        <arg choice="plain">-v</arg>
+        <arg choice="plain">-V</arg>
+        <arg choice="plain">-h</arg>
+      </group>
+
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><command>afpd</command> provides an Apple Filing Protocol (AFP)
+    interface to the Unix file system. It is normally started at boot time
+    by <command>netatalk</command>(8).</para>
+
+    <para><filename>@pkgconfdir@/afp.conf</filename> is the configuration file
+    used by <command>afpd</command> to determine the behavior and
+    configuration of a file server.</para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Options</title>
+
+    <variablelist>
+      <varlistentry>
+        <term>-d</term>
+
+        <listitem>
+          <para>Specifies that the daemon should not fork.</para>
+        </listitem>
+      </varlistentry>
+
+
+      <varlistentry>
+        <term>-v</term>
+
+        <listitem>
+          <para>Print version information and exit.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-V</term>
+
+        <listitem>
+          <para>Print verbose information and exit.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-h</term>
+
+        <listitem>
+          <para>Print help and exit.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>-F <replaceable>configfile</replaceable></term>
+
+        <listitem>
+          <para>Specifies the configuration file to use. (Defaults to
+          <filename>@pkgconfdir@/afp.conf</filename>.)</para>
+        </listitem>
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>SIGNALS</title>
+
+    <para>To shut down a user's <command>afpd</command> process it is
+      recommended that <command>SIGKILL (-9)</command>
+      <emphasis>NOT</emphasis> be used, except as a last resort, as this
+      may leave the CNID database in an inconsistent state. The safe way
+      to terminate an <command>afpd</command> is to send it a
+      <command>SIGTERM (-15)</command> signal and wait for it to die on
+      its own.</para>
+    <para>SIGTERM and SIGUSR1 signals that are sent to the main <command>afpd</command> process
+    are propagated to the children, so all will be affected.</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>SIGTERM</term>
+        <listitem>
+          <para>Clean exit. Propagates from master to childs.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>SIGQUIT</term>
+        <listitem>
+          <para>Send this to the master <command>afpd</command>, it will
+          exit leaving all children running! Can be used to implement
+          AFP service without downtime.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>SIGHUP</term>
+        <listitem>
+          <para>Sending a <command>SIGHUP</command> to afpd will cause it to
+          reload its configuration files.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>SIGINT</term>
+        <listitem>
+          <para>Sending a <command>SIGINT</command> to a child
+          <command>afpd</command> enables <emphasis>max_debug</emphasis>
+          logging for this process. The log is sent to the file
+          <filename>/tmp/afpd.PID.XXXXXX</filename>. Sending another
+          <command>SIGINT</command> will revert to the original log settings.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>SIGUSR1</term>
+        <listitem>
+          <para>The <command>afpd</command> process will send the message "The
+          server is going down for maintenance." to the client and shut itself
+          down in 5 minutes. New connections are not allowed. If this is sent
+          to a child afpd, the other children are not affected. However, the
+          main process will still exit, disabling all new connections.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>SIGUSR2</term>
+        <listitem>
+          <para>The <command>afpd</command> process will look in the message
+          directory configured at build time for a file named message.pid. For
+          each one found, a the contents will be sent as a message to the
+          associated AFP client. The file is removed after the message is
+          sent. This should only be sent to a child
+          <command>afpd</command>.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>FILES</title>
+
+    <variablelist>
+      <varlistentry>
+        <term><filename>@pkgconfdir@/afp.conf</filename></term>
+
+        <listitem>
+          <para>configuration file used by afpd</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><filename>@localstatedir@/netatalk/afp_signature.conf</filename></term>
+
+        <listitem>
+          <para>list of server signature</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><filename>@localstatedir@/netatalk/afp_voluuid.conf</filename></term>
+
+        <listitem>
+          <para>list of UUID for Time Machine volume</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><filename>@pkgconfdir@/extmap.conf</filename></term>
+
+        <listitem>
+          <para>file name extension mapping</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><filename>@pkgconfdir@/msg/message.pid</filename></term>
+
+        <listitem>
+          <para>contains messages to be sent to users.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>SEE ALSO</title>
+
+    <para><citerefentry>
+        <refentrytitle>netatalk</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>hosts_access</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afp.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afp_signature.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afp_voluuid.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>extmap.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>dbd</refentrytitle>
+
+        <manvolnum>1</manvolnum>
+      </citerefentry>.</para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man8/cnid_dbd.8.xml b/doc/manpages/man8/cnid_dbd.8.xml
new file mode 100644 (file)
index 0000000..9162047
--- /dev/null
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="cnid_dbd.8">
+  <refmeta>
+    <refentrytitle>cnid_dbd</refentrytitle>
+
+    <manvolnum>8</manvolnum>
+
+    <refmiscinfo class="date">01 Jan 2012</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>cnid_dbd</refname>
+
+    <refpurpose>implement access to CNID databases through a dedicated daemon
+    process</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>cnid_dbd<indexterm>
+          <primary>cnid_dbd</primary>
+        </indexterm><indexterm>
+          <primary>CNID backend</primary>
+        </indexterm><indexterm>
+          <primary>NFS</primary>
+
+          <secondary>Network File System</secondary>
+        </indexterm></command>
+
+      <sbr />
+
+      <command>cnid_dbd<indexterm>
+          <primary>cnid_dbd</primary>
+        </indexterm></command>
+
+        <group choice="plain">
+          <arg choice="plain">-v</arg>
+          <arg choice="plain">-V</arg>
+        </group>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>DESCRIPTION</title>
+
+    <para><command>cnid_dbd</command> provides an interface for storage and
+    retrieval of catalog node IDs (CNIDs) and related information to the
+    <emphasis remap="B">afpd</emphasis> daemon. CNIDs are a component of
+    Macintosh based file systems with semantics that map not easily onto Unix
+    file systems. This makes separate storage in a database necessary.
+    <command>cnid_dbd</command> is part of the <emphasis remap="B">CNID
+    backend</emphasis> framework of <emphasis remap="B">afpd</emphasis> and
+    implements the <emphasis remap="B">dbd</emphasis> backend.</para>
+
+    <para><command>cnid_dbd</command> is never started via the command line or
+    system startup scripts but only by the <emphasis
+    remap="B">cnid_metad</emphasis> daemon. There is one instance of
+    <command>cnid_dbd</command> per netatalk volume.</para>
+
+    <para><command>cnid_dbd</command> uses the <emphasis remap="B">Berkeley
+    DB</emphasis> database library and uses transactionally protected updates.
+    The <emphasis remap="B">dbd</emphasis> backend with transactions will
+    avoid corruption of the CNID database even if the system crashes
+    unexpectedly.</para>
+
+    <para><command>cnid_dbd</command> inherits the effective userid and
+    groupid from <emphasis remap="B">cnid_metad</emphasis> on startup, which
+    is normally caused by <emphasis remap="B">afpd</emphasis> serving a
+    netatalk volume to a client. It changes to the <emphasis
+    remap="B">Berkeley DB</emphasis> database home directory <emphasis
+    remap="I">dbdir</emphasis> that is associated with the volume. If the
+    userid inherited from <emphasis remap="B">cnid_metad</emphasis> is 0
+    (root), <command>cnid_dbd</command> will change userid and groupid to the
+    owner and group of the database home directory. Otherwise, it will
+    continue to use the inherited values. <command>cnid_dbd</command> will
+    then attempt to open the database and start serving requests using
+    filedescriptor <emphasis remap="I">clntfd</emphasis>. Subsequent instances
+    of <emphasis remap="B">afpd</emphasis> that want to access the same volume
+    are redirected to the running <command>cnid_dbd</command> process by
+    <emphasis remap="B">cnid_metad</emphasis> via the filedescriptor <emphasis
+    remap="I">ctrlfd</emphasis>.</para>
+
+    <para><command>cnid_dbd</command> can be configured to run forever or to
+    exit after a period of inactivity. If <command>cnid_dbd</command> receives
+    a TERM or an INT signal it will exit cleanly after flushing dirty database
+    buffers to disk and closing <emphasis remap="B">Berkeley DB</emphasis>
+    database environments. It is safe to terminate <command>cnid_dbd</command>
+    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).</para>
+
+    <para>The <emphasis remap="B">Berkeley DB</emphasis> database subsystem
+    will create files named log.xxxxxxxxxx in the database home directory
+    <emphasis remap="I">dbdir</emphasis>, where xxxxxxxxxx is a monotonically
+    increasing integer. These files contain the transactional database
+    changes. They will be removed regularly, unless the <emphasis
+    remap="B">logfile_autoremove</emphasis> option is specified in the
+    <emphasis remap="I">db_param</emphasis> configuration file (see
+    below) with a value of 0 (default 1).</para>
+  </refsect1>
+
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <variablelist remap="TP">
+      <varlistentry>
+        <term><option>-v, -V</option></term>
+       
+        <listitem>
+          <para>Show version and exit.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>CONFIGURATION</title>
+
+    <para><command>cnid_dbd</command> reads configuration information from the
+    file <emphasis remap="I">db_param</emphasis> in the database directory
+    <emphasis remap="I">dbdir</emphasis> on startup. If the file does not
+    exist or a parameter is not listed, suitable default values are used. The
+    format for a single parameter is the parameter name, followed by one or
+    more spaces, followed by the parameter value, followed by a newline. The
+    following parameters are currently recognized:</para>
+
+    <variablelist remap="TP">
+      <varlistentry>
+        <term><emphasis remap="B">logfile_autoremove</emphasis></term>
+
+        <listitem>
+          <para>If set to 0, unused Berkeley DB transactional logfiles
+          (log.xxxxxxxxxx in the database home directory) are not removed on
+          startup of <command>cnid_dbd</command> and on a regular basis.
+          Default: 1.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><emphasis remap="B">cachesize</emphasis></term>
+
+        <listitem>
+          <para>Determines the size of the Berkeley DB cache in kilobytes.
+          Default: 8192. Each <command>cnid_dbd</command> process grabs that
+          much memory on top of its normal memory footprint. It can be used to
+          tune database performance. The <emphasis
+          remap="B">db_stat</emphasis> utility with the <option>-m</option>
+          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 <emphasis
+          remap="B">Berkeley DB Tutorial and Reference Guide</emphasis> has a
+          section <emphasis remap="B">Selecting a cache size</emphasis> that
+          gives more detailed information.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><emphasis remap="B">flush_frequency</emphasis></term>
+
+        <term><emphasis remap="B">flush_interval</emphasis></term>
+
+        <listitem>
+          <para><emphasis remap="I">flush_frequency</emphasis> (Default: 1000)
+          and <emphasis remap="I">flush_interval</emphasis> (Default: 1800)
+          control how often changes to the database are checkpointed. Both of
+          these operations are performed if either i) more than <emphasis
+          remap="I">flush_frequency</emphasis> requests have been received or
+          ii) more than <emphasis remap="I">flush_interval</emphasis> seconds
+          have elapsed since the last save/checkpoint. Be careful to check
+          your harddisk configuration for on disk cache settings. Many IDE
+          disks just cache writes as the default behaviour, so even flushing
+          database files to disk will not have the desired effect.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><emphasis remap="B">fd_table_size</emphasis></term>
+
+        <listitem>
+          <para>is the maximum number of connections (filedescriptors) that
+          can be open for <emphasis remap="B">afpd</emphasis> client processes
+          in <emphasis remap="B">cnid_dbd.</emphasis> Default: 512. If this
+          number is exceeded, one of the existing connections is closed and
+          reused. The affected <emphasis remap="B">afpd</emphasis> process
+          will transparently reconnect later, which causes slight overhead. On
+          the other hand, setting this parameter too high could affect
+          performance in <command>cnid_dbd</command> since all descriptors
+          have to be checked in a <function>select()</function> system call,
+          or worse, you might exceed the per process limit of open file
+          descriptors on your system. It is safe to set the value to 1 on
+          volumes where only one <emphasis remap="B">afpd</emphasis> client
+          process is expected to run, e.g. home directories.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><emphasis remap="B">idle_timeout</emphasis></term>
+
+        <listitem>
+          <para>is the number of seconds of inactivity before an idle
+          <command>cnid_dbd</command> exits. Default: 600. Set this to 0 to
+          disable the timeout.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>UPDATING</title>
+
+    <para>Note that the first version to appear <emphasis>after</emphasis>
+    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.</para>
+
+    <para>In order to update between older Netatalk releases using different
+    BerkeleyDB library versions, follow this steps:</para>
+
+    <itemizedlist>
+      <listitem>
+        <para>Stop the to be upgraded old version of Netatalk</para>
+      </listitem>
+
+      <listitem>
+        <para>Using the old BerkeleyDB utilities run <command>db_recover -h
+        &lt;path to .AppleDB&gt;</command></para>
+      </listitem>
+
+      <listitem>
+        <para>Using the new BerkeleyDB utilities run <command>db_upgrade -v -h
+        &lt;path to .AppleDB&gt; -f cnid2.db</command></para>
+      </listitem>
+
+      <listitem>
+        <para>Again using the new BerkeleyDB utilities run
+        <command>db_checkpoint -1 -h &lt;path to .AppleDB&gt;</command></para>
+      </listitem>
+
+      <listitem>
+        <para>Start the the new version of Netatalk</para>
+      </listitem>
+    </itemizedlist>
+
+  </refsect1>
+
+  <refsect1>
+    <title>SEE ALSO</title>
+
+    <para><citerefentry>
+        <refentrytitle>cnid_metad</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afpd</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>dbd</refentrytitle>
+
+        <manvolnum>1</manvolnum>
+      </citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man8/cnid_metad.8.xml b/doc/manpages/man8/cnid_metad.8.xml
new file mode 100644 (file)
index 0000000..3bd833b
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="cnid_metad.8">
+  <refmeta>
+    <refentrytitle>cnid_metad</refentrytitle>
+
+    <manvolnum>8</manvolnum>
+
+    <refmiscinfo class="date">23 Mar 2012</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>cnid_metad</refname>
+
+    <refpurpose>start cnid_dbd daemons on request</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>cnid_metad<indexterm>
+          <primary>cnid_metad</primary>
+        </indexterm></command>
+
+      <arg choice="opt">-d</arg>
+
+      <arg choice="opt"><arg choice="plain">-F </arg><arg
+      choice="plain"><replaceable>configuration file</replaceable></arg></arg>
+
+      <sbr />
+
+      <command>cnid_metad<indexterm>
+          <primary>cnid_metad</primary>
+        </indexterm></command>
+
+       <group choice="plain">
+         <arg choice="plain">-v</arg>
+         <arg choice="plain">-V</arg>
+       </group>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>DESCRIPTION</title>
+
+    <para><command>cnid_metad</command> waits for requests from <emphasis
+    remap="B">afpd</emphasis> to start up instances of the <emphasis
+    remap="B">cnid_dbd</emphasis> daemon. It keeps track of the status of a
+    <emphasis remap="B">cnid_dbd</emphasis> instance once started and will
+    restart it if necessary. <command>cnid_metad</command> is normally started
+    at boot time by <command>netatalk</command>(8) and runs
+    until shutdown.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <variablelist remap="TP">
+     <varlistentry>
+        <term><option>-d</option></term>
+
+        <listitem>
+          <para><emphasis remap="B">cnid_metad will remain in the foreground
+          and</emphasis> will also leave the standard input, standard output
+          and standard error file descriptors open. Useful for
+          debugging.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-F</option> <replaceable>configuration file</replaceable></term>
+
+        <listitem>
+          <para>Use <emphasis remap="I">configuration file</emphasis> as the
+            configuration file. The default is
+            <emphasis remap="I">@pkgconfdir@/afp.conf</emphasis>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-v, -V</option></term>
+
+        <listitem>
+          <para>Show version and exit.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>CAVEATS</title>
+
+    <para><command>cnid_metad</command> 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 <emphasis remap="B">cnid_dbd's</emphasis>
+    started by that <command>cnid_metad</command> to exit gracefully. Since
+    state about and IPC access to the subprocesses is only maintained in
+    memory by <command>cnid_metad</command> this is desired behaviour. As soon
+    as <command>cnid_metad</command> is restarted <emphasis
+    remap="B">afpd</emphasis> processes will transparently reconnect.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>SEE ALSO</title>
+
+    <para><citerefentry>
+        <refentrytitle>netatalk</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>cnid_dbd</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afpd</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>dbd</refentrytitle>
+
+        <manvolnum>1</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afp.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry></para>
+  </refsect1>
+</refentry>
diff --git a/doc/manpages/man8/netatalk.8.xml b/doc/manpages/man8/netatalk.8.xml
new file mode 100644 (file)
index 0000000..8c98011
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry id="netatalk.8">
+  <refmeta>
+    <refentrytitle>netatalk</refentrytitle>
+
+    <manvolnum>8</manvolnum>
+
+    <refmiscinfo class="date">22 Mar 2012</refmiscinfo>
+
+    <refmiscinfo class="source">@NETATALK_VERSION@</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>netatalk</refname>
+
+    <refpurpose>Netatalk AFP server service controller daemon</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>netatalk<indexterm>
+          <primary>netatalk</primary>
+        </indexterm></command>
+
+      <sbr />
+
+      <command>netatalk<indexterm>
+          <primary>netatalk</primary>
+        </indexterm></command>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><command>netatalk</command> is the service controller daemon
+    responsible for starting and restarting the AFP daemon
+    <command>afpd</command> and the CNID daemon <command>cnid_metad</command>.
+    It is normally started at boot time from /etc/rc.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>SIGNALS</title>
+
+    <variablelist>
+      <varlistentry>
+        <term>SIGTERM</term>
+
+        <listitem>
+          <para>Stop Netatalk service, AFP and CNID daemons</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>SIGHUP</term>
+
+        <listitem>
+          <para>Sending a <command>SIGHUP</command> will cause the AFP daemon
+          reload its configuration file.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>FILES</title>
+
+    <variablelist>
+      <varlistentry>
+        <term><filename>@pkgconfdir@/afp.conf</filename></term>
+
+        <listitem>
+          <para>configuration file used by afpd and cnid_metad</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>SEE ALSO</title>
+
+    <para><citerefentry>
+        <refentrytitle>afpd</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>cnid_metad</refentrytitle>
+
+        <manvolnum>8</manvolnum>
+      </citerefentry>, <citerefentry>
+        <refentrytitle>afp.conf</refentrytitle>
+
+        <manvolnum>5</manvolnum>
+      </citerefentry>.</para>
+  </refsect1>
+</refentry>
diff --git a/doc/manual/.gitignore b/doc/manual/.gitignore
new file mode 100644 (file)
index 0000000..8eb18aa
--- /dev/null
@@ -0,0 +1 @@
+manual.xml
diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am
new file mode 100644 (file)
index 0000000..7f2b61d
--- /dev/null
@@ -0,0 +1,7 @@
+EXTRA_DIST = \
+       configuration.xml \
+       install.xml \
+       intro.xml \
+       upgrade.xml
+
+DISTCLEANFILES = manual.xml
diff --git a/doc/manual/configuration.xml b/doc/manual/configuration.xml
new file mode 100644 (file)
index 0000000..3bf6e0f
--- /dev/null
@@ -0,0 +1,1554 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter id="configuration">
+  <title>Setting up Netatalk</title>
+
+  <sect1>
+    <title>File Services<indexterm>
+        <primary>File Services</primary>
+
+        <secondary>Netatalk's File Services</secondary>
+      </indexterm></title>
+
+    <para>Netatalk supplies AFP<indexterm>
+        <primary>AFP</primary>
+
+        <secondary>Apple Filing Protocol</secondary>
+      </indexterm> services.</para>
+
+    <sect2>
+      <title>Setting up the AFP file server</title>
+
+      <para>AFP (the Apple Filing Protocol) is the protocol Apple Macintoshes
+      use for file services. The protocol has evolved over the years. The
+      latest changes to the protocol, called "AFP 3.3", were added with the
+      release of Snow Leopard<indexterm>
+          <primary>Snow Leopard</primary>
+
+          <secondary>Mac OS X 10.6</secondary>
+        </indexterm> (Mac OS X 10.6).</para>
+
+      <para>The afpd daemon offers the fileservices to Apple clients. The only
+      configuration file is <filename>afp.conf</filename>. It uses a ini style
+      configuration syntax.</para>
+
+      <para>Mac OS X 10.5 (Leopard) added support for Time Machine backups
+      over AFP. Two new functions ensure that backups are written to spinning
+      disk, not just in the server's cache. Different host operating systems
+      honour this cache flushing differently. To make a volume a Time Machine
+      target use the volume option "<option>time machine =
+      yes</option>".</para>
+
+      <para>Starting with Netatalk 2.1 UNIX symlinks<indexterm>
+          <primary>symlink</primary>
+
+          <secondary>UNIX symlink</secondary>
+        </indexterm> can be used on the server. Semantics are the same as for
+      eg NFS, ie they are not resolved on the server side but instead it's
+      completely up to the client to resolve them, resulting in links that
+      point somewhere inside the clients filesystem view.</para>
+
+      <sect3>
+        <title>afp.conf</title>
+
+        <para><filename>afp.conf</filename> is the configuration file used by
+        afpd to determine the behaviour and configuration of the AFP file
+        serverand the AFP volume that it provides.</para>
+
+        <para>The <filename>afp.conf</filename> is divided into several
+        sections:<variablelist>
+            <varlistentry>
+              <term>[Global]</term>
+
+              <listitem>
+                <para>The global section defines general server options</para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
+              <term>[Homes]</term>
+
+              <listitem>
+                <para>The homes section defines user home volumes</para>
+              </listitem>
+            </varlistentry>
+          </variablelist>Any section not called <option>Global</option> or
+        <option>Homes</option> is interpreted as an AFP volume.</para>
+
+        <para>For sharing user homes by defining a <option>Homes</option>
+        section you must specify the option <option>basedir regex</option>
+        which can be a simple string with the path to the parent directory of
+        all user homes or a regular expression.</para>
+
+        <para>Example:</para>
+
+        <para><programlisting>[Homes]
+basedir regex = /home
+</programlisting></para>
+
+        <para>Now any user logging into the AFP server will have a user volume
+        available whos path is <filename>/home/NAME</filename>.</para>
+
+        <para>A more complex setup would be a server with a large amount of
+        user homes which are split across eg two different
+        filesystems:<itemizedlist>
+            <listitem>
+              <para>/RAID1/homes</para>
+            </listitem>
+
+            <listitem>
+              <para>/RAID2/morehomes</para>
+            </listitem>
+          </itemizedlist>The following configuration is
+        required:<programlisting>[Homes]
+basedir regex = /RAID./.*homes
+</programlisting></para>
+
+        <para>If <option>basedir regex</option> contains symlink, set the
+        canonicalized absolute path. When <filename>/home</filename> links to
+        <filename>/usr/home</filename>: <programlisting>[Homes]
+basedir regex = /usr/home</programlisting></para>
+
+        <para>For a more detailed explanation of the available options, please
+        refer to the <citerefentry>
+            <refentrytitle>afp.conf</refentrytitle>
+
+            <manvolnum>5</manvolnum>
+          </citerefentry> man page.</para>
+      </sect3>
+    </sect2>
+
+    <sect2 id="CNID-backends">
+      <title>CNID<indexterm>
+          <primary>CNID</primary>
+
+          <secondary>Catalog Node ID</secondary>
+        </indexterm> backends<indexterm>
+          <primary>Backend</primary>
+
+          <secondary>CNID backend</secondary>
+        </indexterm></title>
+
+      <para>Unlike other protocols like SMB or NFS, the AFP protocol mostly
+      refers to files and directories by ID and not by a path (the IDs are
+      also called CNID, that means Catalog Node ID). A typical AFP request
+      uses a directory ID<indexterm>
+          <primary>DID</primary>
+
+          <secondary>Directory ID</secondary>
+        </indexterm> and a filename, something like <phrase>"server, please
+      open the file named 'Test' in the directory with id 167"</phrase>. For
+      example "Aliases" on the Mac basically work by ID (with a fallback to
+      the absolute path in more recent AFP clients. But this applies only to
+      Finder, not to applications).</para>
+
+      <para>Every file in an AFP volume has to have a unique file ID<indexterm>
+          <primary>FID</primary>
+
+          <secondary>File ID</secondary>
+        </indexterm>, IDs must, according to the specs, never be reused, and
+      IDs are 32 bit numbers (Directory IDs use the same ID pool). So, after
+      ~4 billion files/folders have been written to an AFP volume, the ID pool
+      is depleted and no new file can be written to the volume. No whining
+      please :-)</para>
+
+      <para>Netatalk needs to map IDs to files and folders in the host
+      filesystem. To achieve this, several different CNID backends<indexterm>
+          <primary>CNID backend</primary>
+        </indexterm> are available and can be choosed by the <option>cnid
+      scheme</option><indexterm>
+          <primary>cnidscheme</primary>
+
+          <secondary>specifying a CNID backend</secondary>
+        </indexterm> option in the <citerefentry>
+          <refentrytitle>afp.conf</refentrytitle>
+
+          <manvolnum>5</manvolnum>
+        </citerefentry> configuration file. A CNID backend is basically a
+      database storing ID &lt;-&gt; name mappings.</para>
+
+      <para>The CNID Databases are by default located in
+      <filename>/var/netatalk/CNID</filename>.</para>
+
+      <para>There is a command line utility called <command>dbd</command>
+      available which can be used to verify, repair and rebuild the CNID
+      database.</para>
+
+      <note>
+        <para>There are some CNID related things you should keep in mind when
+        working with netatalk:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>Don't nest volumes<indexterm>
+                <primary>Nested volumes</primary>
+              </indexterm>.</para>
+          </listitem>
+
+          <listitem>
+            <para>CNID backends are databases, so they turn afpd into a file
+            server/database mix.</para>
+          </listitem>
+
+          <listitem>
+            <para>If there's no more space on the filesystem left, the
+            database will get corrupted. You can work around this by either
+            using the <option>vol dbpath</option> option and put the database
+            files into another location or, if you use quotas, make sure the
+            CNID database folder is owned by a user/group without a
+            quota<indexterm>
+                <primary>Quotas</primary>
+
+                <secondary>Disk usage quotas</secondary>
+              </indexterm>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Be careful with CNID databases for volumes that are mounted
+            via NFS. That is a pretty audacious decision to make anyway, but
+            putting a database there as well is really asking for trouble,
+            i.e. database corruption. Use the <option>vol dbpath</option>
+            directive to put the databases onto a local disk if you must use
+            NFS<indexterm>
+                <primary>NFS</primary>
+
+                <secondary>Network File System</secondary>
+              </indexterm> mounted volumes.</para>
+          </listitem>
+        </itemizedlist>
+      </note>
+
+      <sect3>
+        <title>cdb<indexterm>
+            <primary>CDB</primary>
+
+            <secondary>"cdb" CNID backend</secondary>
+          </indexterm></title>
+
+        <para>The "concurrent database" backend is based on Berkeley DB. With
+        this backend, several afpd daemons access the CNID database directly.
+        Berkeley DB locking is used to synchronize access, if more than one
+        afpd process is active for a volume. The drawback is, that the crash
+        of a single afpd process might corrupt the database. cdb should only
+        be used when sharing home directories for a larger number of users
+        <emphasis>and</emphasis> it has been determined that a large number of
+        <command>cnid_dbd</command> processes is problematic.</para>
+      </sect3>
+
+      <sect3>
+        <title>dbd<indexterm>
+            <primary>DBD</primary>
+
+            <secondary>"dbd" CNID backend</secondary>
+          </indexterm></title>
+
+        <para>Access to the CNID database is restricted to the cnid_dbd daemon
+        process. afpd processes communicate with the daemon for database reads
+        and updates. The probability for database corruption is practically
+        zero.</para>
+
+        <para>This is the default backend since Netatalk 2.1.</para>
+      </sect3>
+
+      <sect3>
+        <title>tdb<indexterm>
+            <primary>tdb</primary>
+
+            <secondary>"tdb" CNID backend</secondary>
+          </indexterm></title>
+
+        <para><abbrev>tdb</abbrev> is another persistent CNID database, it's
+        Samba's <emphasis>Trivial Database</emphasis>. It could be used
+        instead of <abbrev>cdb</abbrev> for user volumes.<important>
+            <para>Only ever use it for volumes that are
+            <emphasis>not</emphasis> shared and accessed by multiple clients
+            at once !</para>
+          </important>This backend is also used internally (as in-memory CNID
+        database) as a fallback in case opening the primary database can't be
+        opened, because <abbrev>tdb</abbrev> can work as in-memory database.
+        This of course means upon restart the CNIDs are gone.</para>
+      </sect3>
+
+      <sect3>
+        <title>last<indexterm>
+            <primary>Last</primary>
+
+            <secondary>"last" CNID backend</secondary>
+          </indexterm></title>
+
+        <para>The last backend is a in-memory tdb database. It is not
+        persistent. Starting with netatalk 3.0, it becomes the <emphasis> read
+        only mode</emphasis> automatically. This is useful e.g. for
+        CD-ROMs.</para>
+      </sect3>
+    </sect2>
+
+    <sect2 id="charsets">
+      <title>Charsets<indexterm>
+          <primary>Charset</primary>
+
+          <secondary>character set</secondary>
+        </indexterm>/Unicode<indexterm>
+          <primary>Unicode</primary>
+        </indexterm></title>
+
+      <para></para>
+
+      <sect3>
+        <title>Why Unicode?</title>
+
+        <para>Internally, computers don't know anything about characters and
+        texts, they only know numbers. Therefore, each letter is assigned a
+        number. A character set, often referred to as
+        <emphasis>charset</emphasis> or
+        <emphasis>codepage</emphasis><indexterm>
+            <primary>Codepage</primary>
+          </indexterm>, defines the mappings between numbers and
+        letters.</para>
+
+        <para>If two or more computer systems need to communicate with each
+        other, the have to use the same character set. In the 1960s the
+        ASCII<indexterm>
+            <primary>ASCII</primary>
+
+            <secondary>American Standard Code for Information
+            Interchange</secondary>
+          </indexterm> (American Standard Code for Information Interchange)
+        character set was defined by the American Standards Association. The
+        original form of ASCII represented 128 characters, more than enough to
+        cover the English alphabet and numerals. Up to date, ASCII has been
+        the normative character scheme used by computers.</para>
+
+        <para>Later versions defined 256 characters to produce a more
+        international fluency and to include some slightly esoteric graphical
+        characters. Using this mode of encoding each character takes exactly
+        one byte. Obviously, 256 characters still wasn't enough to map all the
+        characters used in the various languages into one character
+        set.</para>
+
+        <para>As a result localized character sets were defined later, e.g the
+        ISO-8859 character sets. Most operating system vendors introduced
+        their own characters sets to satisfy their needs, e.g. IBM defined the
+        <emphasis>codepage 437 (DOSLatinUS)</emphasis>, Apple introduced the
+        <emphasis>MacRoman</emphasis><indexterm>
+            <primary>MacRoman</primary>
+
+            <secondary>MacRoman charset</secondary>
+          </indexterm> codepage and so on. The characters that were assigned
+        number larger than 127 were referred to as
+        <emphasis>extended</emphasis> characters. These character sets
+        conflict with another, as they use the same number for different
+        characters, or vice versa.</para>
+
+        <para>Almost all of those characters sets defined 256 characters,
+        where the first 128 (0-127) character mappings are identical to ASCII.
+        As a result, communication between systems using different codepages
+        was effectively limited to the ASCII charset.</para>
+
+        <para>To solve this problem new, larger character sets were defined.
+        To make room for more character mappings, these character sets use at
+        least 2 bytes to store a character. They are therefore referred to as
+        <emphasis>multibyte</emphasis> character sets.</para>
+
+        <para>One standardized multibyte charset encoding scheme is known as
+        <ulink url="http://www.unicode.org/">unicode</ulink>. A big advantage
+        of using a multibyte charset is that you only need one. There is no
+        need to make sure two computers use the same charset when they are
+        communicating.</para>
+      </sect3>
+
+      <sect3>
+        <title>character sets used by Apple</title>
+
+        <para>In the past, Apple clients used single-byte charsets to
+        communicate over the network. Over the years Apple defined a number of
+        codepages, western users will most likely be using the
+        <emphasis>MacRoman</emphasis> codepage.</para>
+
+        <para>Codepages defined by Apple include:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>MacArabic, MacFarsi</para>
+          </listitem>
+
+          <listitem>
+            <para>MacCentralEurope</para>
+          </listitem>
+
+          <listitem>
+            <para>MacChineseSimple</para>
+          </listitem>
+
+          <listitem>
+            <para>MacChineseTraditional</para>
+          </listitem>
+
+          <listitem>
+            <para>MacCroation</para>
+          </listitem>
+
+          <listitem>
+            <para>MacCyrillic</para>
+          </listitem>
+
+          <listitem>
+            <para>MacDevanagari</para>
+          </listitem>
+
+          <listitem>
+            <para>MacGreek</para>
+          </listitem>
+
+          <listitem>
+            <para>MacHebrew</para>
+          </listitem>
+
+          <listitem>
+            <para>MacIcelandic</para>
+          </listitem>
+
+          <listitem>
+            <para>MacJapanese</para>
+          </listitem>
+
+          <listitem>
+            <para>MacKorean</para>
+          </listitem>
+
+          <listitem>
+            <para>MacRoman</para>
+          </listitem>
+
+          <listitem>
+            <para>MacRomanian</para>
+          </listitem>
+
+          <listitem>
+            <para>MacThai</para>
+          </listitem>
+
+          <listitem>
+            <para>MacTurkish</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Starting with Mac OS X and AFP3, <ulink
+        url="http://www.utf-8.com/">UTF-8</ulink> is used. UTF-8 encodes
+        Unicode characters in an ASCII compatible way, each Unicode character
+        is encoded into 1-6 ASCII characters. UTF-8 is therefore not really a
+        charset itself, it's an encoding of the Unicode charset.</para>
+
+        <para>To complicate things, Unicode defines several <emphasis> <ulink
+        url="http://www.unicode.org/reports/tr15/index.html">normalization</ulink>
+        </emphasis> forms. While <ulink
+        url="http://www.samba.org">samba</ulink><indexterm>
+            <primary>Samba</primary>
+          </indexterm> uses <emphasis>precomposed</emphasis><indexterm>
+            <primary>Precomposed</primary>
+
+            <secondary>Precomposed Unicode normalization</secondary>
+          </indexterm> Unicode, which most Unix tools prefer as well, Apple
+        decided to use the <emphasis>decomposed</emphasis><indexterm>
+            <primary>Decomposed</primary>
+
+            <secondary>Decomposed Unicode normalization</secondary>
+          </indexterm> normalization.</para>
+
+        <para>For example lets take the German character
+        '<keycode>ä</keycode>'. Using the precomposed normalization, Unicode
+        maps this character to 0xE4. In decomposed normalization, 'ä' is
+        actually mapped to two characters, 0x61 and 0x308. 0x61 is the mapping
+        for an 'a', 0x308 is the mapping for a <emphasis>COMBINING
+        DIAERESIS</emphasis>.</para>
+
+        <para>Netatalk refers to precomposed UTF-8 as
+        <emphasis>UTF8</emphasis><indexterm>
+            <primary>UTF8</primary>
+
+            <secondary>Netatalk's precomposed UTF-8 encoding</secondary>
+          </indexterm> and to decomposed UTF-8 as
+        <emphasis>UTF8-MAC</emphasis><indexterm>
+            <primary>UTF8-MAC</primary>
+
+            <secondary>Netatalk's decomposed UTF-8 encoding</secondary>
+          </indexterm>.</para>
+      </sect3>
+
+      <sect3>
+        <title>afpd and character sets</title>
+
+        <para>To support new AFP 3.x and older AFP 2.x clients at the same
+        time, afpd needs to be able to convert between the various charsets
+        used. AFP 3.x clients always use UTF8-MAC, AFP 2.x clients use one of
+        the Apple codepages.</para>
+
+        <para>At the time of this writing, netatalk supports the following
+        Apple codepages:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>MAC_CENTRALEUROPE</para>
+          </listitem>
+
+          <listitem>
+            <para>MAC_CHINESE_SIMP</para>
+          </listitem>
+
+          <listitem>
+            <para>MAC_CHINESE_TRAD</para>
+          </listitem>
+
+          <listitem>
+            <para>MAC_CYRILLIC</para>
+          </listitem>
+
+          <listitem>
+            <para>MAC_GREEK</para>
+          </listitem>
+
+          <listitem>
+            <para>MAC_HEBREW</para>
+          </listitem>
+
+          <listitem>
+            <para>MAC_JAPANESE</para>
+          </listitem>
+
+          <listitem>
+            <para>MAC_KOREAN</para>
+          </listitem>
+
+          <listitem>
+            <para>MAC_ROMAN</para>
+          </listitem>
+
+          <listitem>
+            <para>MAC_TURKISH</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>afpd handles three different character set options:</para>
+
+        <variablelist>
+          <varlistentry>
+            <term>unix charset<indexterm>
+                <primary>unix charset</primary>
+
+                <secondary>afpd's unix charset setting</secondary>
+              </indexterm></term>
+
+            <listitem>
+              <para>This is the codepage used internally by your operating
+              system. If not specified, it defaults to <option>UTF8</option>.
+              If <option>LOCALE</option> is specified and your system support
+              Unix locales, afpd tries to detect the codepage. afpd uses this
+              codepage to read its configuration files, so you can use
+              extended characters for volume names, login messages, etc. see
+              <citerefentry>
+                  <refentrytitle>afp.conf</refentrytitle>
+
+                  <manvolnum>5</manvolnum>
+                </citerefentry>.</para>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>mac charset<indexterm>
+                <primary>mac charset</primary>
+
+                <secondary>afpd's mac charset setting</secondary>
+              </indexterm></term>
+
+            <listitem>
+              <para>As already mentioned, older Mac OS clients (up to AFP 2.2)
+              use codepages to communicate with afpd. However, there is no
+              support for negotiating the codepage used by the client in the
+              AFP protocol. If not specified otherwise, afpd assumes the
+              <emphasis>MacRoman</emphasis> codepage is used. In case you're
+              clients use another codepage, e.g.
+              <emphasis>MacCyrillic</emphasis>, you'll <emphasis
+              role="bold">have</emphasis> to explicitly configure this. see
+              <citerefentry>
+                  <refentrytitle>afp.conf</refentrytitle>
+
+                  <manvolnum>5</manvolnum>
+                </citerefentry>.</para>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>vol charset<indexterm>
+                <primary>vol charset</primary>
+
+                <secondary>afpd's vol charset setting</secondary>
+              </indexterm></term>
+
+            <listitem>
+              <para>This defines the charset afpd should use for filenames on
+              disk. By default, it is the same as <option>unix
+              charset</option>. If you have <ulink
+              url="http://www.gnu.org/software/libiconv/">iconv</ulink><indexterm>
+                  <primary>Iconv</primary>
+
+                  <secondary>iconv encoding conversion engine</secondary>
+                </indexterm> installed, you can use any iconv provided charset
+              as well.</para>
+
+              <para>afpd 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<indexterm>
+                  <primary>CAP encoding</primary>
+
+                  <secondary>CAP style character encoding</secondary>
+                </indexterm>. An extended character (&gt;0x7F) would be
+              converted to a :xx hex sequence, e.g. the Apple Logo (MacRoman:
+              0xF0) was saved as :f0. Some special characters will be
+              converted as to :xx notation as well. '/' will be encoded to
+              :2f, if <option>usedots</option> was not specified, a leading
+              dot '.' will be encoded as :2e.</para>
+
+              <para>Even though this version now uses <option>UTF8</option> as
+              the default encoding for filenames, '/' will be converted to
+              ':'. For western users another useful setting could be
+              <option>vol charset = ISO-8859-15</option>.</para>
+
+              <para>If a character cannot be converted from the <option>mac
+              charset</option> to the selected <option>vol charset</option>,
+              afpd will save it as a CAP encoded character. For AFP3 clients,
+              afpd will convert the UTF8 character to <option>mac
+              charset</option> first. If this conversion fails, you'll receive
+              a -50 error on the mac. <emphasis>Note</emphasis>: Whenever you
+              can, please stick with the default UTF8 volume format. see
+              <citerefentry>
+                  <refentrytitle>afp.conf</refentrytitle>
+
+                  <manvolnum>5</manvolnum>
+                </citerefentry>.</para>
+            </listitem>
+          </varlistentry>
+        </variablelist>
+      </sect3>
+    </sect2>
+
+    <sect2 id="authentication">
+      <title>Authentication<indexterm>
+          <primary>Authentication</primary>
+
+          <secondary>between AFP client and server</secondary>
+        </indexterm></title>
+
+      <sect3>
+        <title>AFP authentication basics</title>
+
+        <para>Apple chose a flexible model called "User Authentication
+        Modules"<indexterm>
+            <primary>UAM</primary>
+
+            <secondary>User Authentication Module</secondary>
+          </indexterm> (UAMs) for authentication purposes between AFP client
+        and server. An AFP client initially connecting to an AFP server will
+        ask for the list of UAMs which the server provides, and will choose
+        the one with strongest encryption that the client supports.</para>
+
+        <para>Several UAMs have been developed by Apple over the time, some by
+        3rd-party developers.</para>
+      </sect3>
+
+      <sect3>
+        <title>UAMs supported by Netatalk</title>
+
+        <para>Netatalk supports the following ones by default:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>"No User Authent"<indexterm>
+                <primary>No User Authent</primary>
+
+                <secondary>"No User Authent" UAM (guest access)</secondary>
+              </indexterm> UAM (guest access without authentication)</para>
+          </listitem>
+
+          <listitem>
+            <para>"Cleartxt Passwrd"<indexterm>
+                <primary>Cleartxt Passwrd</primary>
+
+                <secondary>"Cleartxt Passwrd" UAM</secondary>
+              </indexterm> UAM (no password encryption)</para>
+          </listitem>
+
+          <listitem>
+            <para>"Randnum exchange"<indexterm>
+                <primary>Randnum exchange</primary>
+
+                <secondary>"Randnum exchange" UAM</secondary>
+              </indexterm>/"2-Way Randnum exchange"<indexterm>
+                <primary>2-Way Randnum exchange</primary>
+
+                <secondary>"2-Way Randnum exchange" UAM</secondary>
+              </indexterm> UAMs (weak password encryption, separate password
+            storage)</para>
+          </listitem>
+
+          <listitem>
+            <para>"DHCAST128"<indexterm>
+                <primary>DHCAST128</primary>
+
+                <secondary>"DHCAST128" UAM</secondary>
+              </indexterm> UAM (stronger password encryption)</para>
+          </listitem>
+
+          <listitem>
+            <para>"DHX2"<indexterm>
+                <primary>DHX2</primary>
+
+                <secondary>"DHX2" UAM</secondary>
+              </indexterm> UAM (successor of DHCAST128)</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>There exist other optional UAMs as well:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>"PGPuam 1.0"<indexterm>
+                <primary>PGPuam 1.0</primary>
+
+                <secondary>"PGPuam 1.0" UAM</secondary>
+              </indexterm><indexterm>
+                <primary>uams_pgp.so</primary>
+
+                <secondary>"PGPuam 1.0" UAM</secondary>
+              </indexterm> UAM (PGP-based authentication for pre-Mac OS X
+            clients. You'll also need the <ulink
+            url="http://www.vmeng.com/vinnie/papers/pgpuam.html">PGPuam
+            client</ulink> to let this work)</para>
+
+            <para>You'll have to add <filename>"--enable-pgp-uam"</filename>
+            to your configure switches to have this UAM available.</para>
+          </listitem>
+
+          <listitem>
+            <para>"Kerberos IV"<indexterm>
+                <primary>Kerberos IV</primary>
+
+                <secondary>"Kerberos IV" UAM</secondary>
+              </indexterm><indexterm>
+                <primary>uams_krb4.so</primary>
+
+                <secondary>"Kerberos IV" UAM</secondary>
+              </indexterm>/"AFS Kerberos"<indexterm>
+                <primary>AFS Kerberos</primary>
+
+                <secondary>"AFS Kerberos" UAM (Kerberos IV)</secondary>
+              </indexterm> UAMs (suitable to use <ulink
+            url="http://web.mit.edu/macdev/KfM/Common/Documentation/faq.html">Kerberos
+            v4 based authentication</ulink> and AFS file servers)</para>
+
+            <para>Use <filename>"--enable-krb4-uam"</filename> at compile time
+            to activate the build of this UAM.</para>
+          </listitem>
+
+          <listitem>
+            <para>"Client Krb v2"<indexterm>
+                <primary>Client Krb v2</primary>
+
+                <secondary>"Client Krb v2" UAM (Kerberos V)</secondary>
+              </indexterm> UAM (Kerberos V, suitable for "Single Sign On"
+            Scenarios with OS X clients -- see below)</para>
+
+            <para><filename>"--enable-krbV-uam"</filename> will provide you
+            with the ability to use this UAM.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>You can configure which UAMs should be activated by defining
+        "<option>uam list</option>" in <option>Global</option> section.
+        <command>afpd</command> will log which UAMs it's using and if problems
+        occur while activating them in either
+        <filename>netatalk.log</filename> or syslog at startup time.
+        <citerefentry>
+            <refentrytitle>asip-status.pl</refentrytitle>
+
+            <manvolnum>1</manvolnum>
+          </citerefentry> can be used to query the available UAMs of AFP
+        servers as well.</para>
+
+        <para>Having a specific UAM available at the server does not
+        automatically mean that a client can use it. Client-side support is
+        also necessary. For older Macintoshes running Mac OS &lt; X DHCAST128
+        support exists since AppleShare client 3.8.x.</para>
+
+        <para>On OS X, there exist some client-side techniques to make the
+        AFP-client more verbose, so one can have a look what's happening while
+        negotiating the UAMs to use. Compare with this <ulink
+        url="http://article.gmane.org/gmane.network.netatalk.devel/7383/">hint</ulink>.</para>
+      </sect3>
+
+      <sect3>
+        <title>Which UAMs to activate?</title>
+
+        <para>It depends primarily on your needs and on the kind of Mac OS
+        versions you have to support. Basically one should try to use
+        DHCAST128 and DHX2 where possible because of its strength of password
+        encryption.</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>Unless you really have to supply guest access to your
+            server's volumes ensure that you disable "No User Authent" since
+            it might lead accidentally to unauthorized access. In case you
+            must enable guest access take care that you enforce this on a per
+            volume base using the access controls.</para>
+          </listitem>
+
+          <listitem>
+            <para>The "ClearTxt Passwrd" UAM is as bad as it sounds since
+            passwords go unencrypted over the wire. Try to avoid it at both
+            the server's side as well as on the client's. Note: If you want to
+            provide Mac OS 8/9 clients with NetBoot-services then you need
+            uams_cleartext.so since the AFP-client integrated into the Mac's
+            firmware can only deal with this basic form of
+            authentication.</para>
+          </listitem>
+
+          <listitem>
+            <para>Since "Randnum exchange"/"2-Way Randnum exchange" uses only
+            56 bit DES for encryption it should be avoided as well. Another
+            disadvantage is the fact that the passwords have to be stored in
+            cleartext on the server and that it doesn't integrate into both
+            PAM scenarios or classic /etc/shadow (you have to administrate
+            passwords separately by using the <citerefentry>
+                <refentrytitle>afppasswd</refentrytitle>
+
+                <manvolnum>1</manvolnum>
+              </citerefentry> utility, if clients should use these
+            UAMs)</para>
+          </listitem>
+
+          <listitem>
+            <para>"DHCAST128" or "DHX2" should be a good compromise for most
+            people since it combines stronger encryption with PAM
+            integration.</para>
+          </listitem>
+
+          <listitem>
+            <para>Using the Kerberos V<indexterm>
+                <primary>Kerberos V</primary>
+
+                <secondary>"Client Krb v2" UAM</secondary>
+              </indexterm> ("Client Krb v2") UAM, it's possible to implement
+            real single sign on scenarios using Kerberos tickets. The password
+            is not sent over the network. Instead, the user password is used
+            to decrypt a service ticket for the appleshare server. The service
+            ticket contains an encryption key for the client and some
+            encrypted data (which only the appleshare server can decrypt). The
+            encrypted portion of the service ticket is sent to the server and
+            used to authenticate the user. Because of the way that the afpd
+            service principal detection is implemented, this authentication
+            method is vulnerable to man-in-the-middle attacks.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>For a more detailed overview over the technical implications of
+        the different UAMs, please have a look at Apple's <ulink
+        url="http://developer.apple.com/library/mac/#documentation/Networking/Conceptual/AFP/AFPSecurity/AFPSecurity.html#//apple_ref/doc/uid/TP40000854-CH232-SW1">File
+        Server Security</ulink> pages.</para>
+      </sect3>
+
+      <sect3>
+        <title>Using different authentication sources with specific
+        UAMs</title>
+
+        <para>Some UAMs provide the ability to use different authentication
+        "backends", namely <filename>uams_cleartext.so</filename>,
+        <filename>uams_dhx.so</filename> and
+        <filename>uams_dhx2.so</filename>. They can use either classic Unix
+        passwords from <filename>/etc/passwd</filename>
+        (<filename>/etc/shadow</filename>) or PAM if the system supports that.
+        <filename>uams_cleartext.so</filename> can be symlinked to either
+        <filename>uams_passwd.so</filename> or
+        <filename>uams_pam.so</filename>, <filename>uams_dhx.so</filename> to
+        <filename>uams_dhx_passwd.so</filename> or
+        <filename>uams_dhx_pam.so</filename> and
+        <filename>uams_dhx2.so</filename> to
+        <filename>uams_dhx2_passwd.so</filename> or
+        <filename>uams_dhx2_pam.so</filename>.</para>
+
+        <para>So, if it looks like this in Netatalk's UAMs folder (per default
+        <filename>/etc/netatalk/uams/</filename>):<programlisting>uams_clrtxt.so -&gt; uams_pam.so
+uams_dhx.so -&gt; uams_dhx_pam.so
+uams_dhx2.so -&gt; uams_dhx2_pam.so</programlisting> then you're using PAM,
+        otherwise classic Unix passwords. The main advantage of using PAM is
+        that one can integrate Netatalk in centralized authentication
+        scenarios, eg. via LDAP, NIS and the like. Please always keep in mind
+        that the protection of your user's login credentials in such scenarios
+        also depends on the strength of encryption that the UAM in question
+        supplies. So think about eliminating weak UAMs like "ClearTxt Passwrd"
+        and "Randnum exchange" completely from your network.</para>
+      </sect3>
+
+      <sect3>
+        <title>Netatalk UAM overview table</title>
+
+        <para>A small overview of the most common used UAMs.</para>
+
+        <table orient="land">
+          <title>Netatalk UAM overview</title>
+
+          <tgroup align="center" cols="7">
+            <colspec colname="col1" colnum="1" colwidth="0.5*" />
+
+            <colspec colname="uam_guest" colnum="2" colwidth="1*" />
+
+            <colspec colname="uam_clrtxt" colnum="3" colwidth="1*" />
+
+            <colspec colname="uam_randnum" colnum="4" colwidth="1*" />
+
+            <colspec colname="uam_dhx" colnum="5" colwidth="1*" />
+
+            <colspec colname="uam_dhx2" colnum="6" colwidth="1*" />
+
+            <colspec colname="uam_gss" colnum="7" colwidth="1*" />
+
+            <tbody>
+              <row>
+                <entry align="center" rotate="0" valign="middle">UAM</entry>
+
+                <entry>No User Authent<indexterm>
+                    <primary>uams_guest.so</primary>
+
+                    <secondary>"No User Authent" UAM (guest
+                    access)</secondary>
+                  </indexterm></entry>
+
+                <entry>Cleartxt Passwrd<indexterm>
+                    <primary>uams_cleartxt.so</primary>
+
+                    <secondary>"Cleartxt Passwrd" UAM</secondary>
+                  </indexterm></entry>
+
+                <entry>(2-Way) Randnum exchange<indexterm>
+                    <primary>uams_randnum.so</primary>
+
+                    <secondary>"(2-Way) Randnum exchange" UAM</secondary>
+                  </indexterm></entry>
+
+                <entry>DHCAST128<indexterm>
+                    <primary>uams_dhx.so</primary>
+
+                    <secondary>"DHCAST128" UAM</secondary>
+                  </indexterm></entry>
+
+                <entry>DHX2<indexterm>
+                    <primary>uams_dhx2.so</primary>
+
+                    <secondary>"DHX2" UAM</secondary>
+                  </indexterm></entry>
+
+                <entry>Client Krb v2<indexterm>
+                    <primary>uams_gss.so</primary>
+
+                    <secondary>"Client Krb v2" UAM (Kerberos V)</secondary>
+                  </indexterm></entry>
+              </row>
+
+              <row>
+                <entry align="center" rotate="0" valign="middle">pssword
+                length</entry>
+
+                <entry>guest access</entry>
+
+                <entry>max. 8 characters</entry>
+
+                <entry>max. 8 characters</entry>
+
+                <entry>max. 64 characters</entry>
+
+                <entry>max. 256 characters</entry>
+
+                <entry>Kerberos tickets</entry>
+              </row>
+
+              <row>
+                <entry align="center" rotate="0" valign="middle">Client
+                support</entry>
+
+                <entry>built-in into all Mac OS versions</entry>
+
+                <entry>built-in in all Mac OS versions except 10.0. Has to be
+                activated explicitly in recent Mac OS X versions</entry>
+
+                <entry>built-in into almost all Mac OS versions</entry>
+
+                <entry>built-in since AppleShare client 3.8.4, available as a
+                plug-in for 3.8.3, integrated in Mac OS X' AFP client</entry>
+
+                <entry>built-in since Mac OS X 10.2</entry>
+
+                <entry>built-in since Mac OS X 10.2</entry>
+              </row>
+
+              <row>
+                <entry align="center" rotate="0"
+                valign="middle">Encryption</entry>
+
+                <entry>Enables guest access without authentication between
+                client and server.</entry>
+
+                <entry>Password will be sent in cleartext over the wire. Just
+                as bad as it sounds, therefore avoid at all if possible (note:
+                providing NetBoot services requires the ClearTxt UAM)</entry>
+
+                <entry>8-byte random numbers are sent over the wire,
+                comparable with DES, 56 bits. Vulnerable to offline dictionary
+                attack. Requires passwords in clear on the server.</entry>
+
+                <entry>Password will be encrypted with 128 bit SSL, user will
+                be authenticated against the server but not vice versa.
+                Therefor weak against man-in-the-middle attacks.</entry>
+
+                <entry>Password will be encrypted using libgcrypt with CAST
+                128 in CBC mode. User will be authenticated against the server
+                but not vice versa. Therefor weak against man-in-the-middle
+                attacks.</entry>
+
+                <entry>Password is not sent over the network. Due to the
+                service principal detection method, this authentication method
+                is vulnerable to man-in-the-middle attacks.</entry>
+              </row>
+
+              <row>
+                <entry align="center" rotate="0" valign="middle">Server
+                support</entry>
+
+                <entry align="center" valign="middle">uams_guest.so</entry>
+
+                <entry align="center" valign="middle">uams_cleartxt.so</entry>
+
+                <entry align="center" valign="middle">uams_randnum.so</entry>
+
+                <entry align="center" valign="middle">uams_dhx.so</entry>
+
+                <entry align="center" valign="middle">uams_dhx2.so</entry>
+
+                <entry align="center" valign="middle">uams_gss.so</entry>
+              </row>
+
+              <row>
+                <entry align="center" rotate="0" valign="middle">Password
+                storage method</entry>
+
+                <entry align="center" valign="middle">None</entry>
+
+                <entry align="center" valign="middle">Either /etc/passwd
+                (/etc/shadow) or PAM</entry>
+
+                <entry align="center" valign="middle">Passwords stored in
+                clear text in a separate text file</entry>
+
+                <entry align="center" valign="middle">Either /etc/passwd
+                (/etc/shadow) or PAM</entry>
+
+                <entry align="center" valign="middle">Either /etc/passwd
+                (/etc/shadow) or PAM</entry>
+
+                <entry align="center" valign="middle">At the Kerberos Key
+                Distribution Center*</entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </table>
+
+        <para>* Have a look at this <ulink
+        url="http://cryptnet.net/fdp/admin/kerby-infra/en/kerby-infra.html">Kerberos
+        overview</ulink></para>
+      </sect3>
+
+      <sect3 id="sshtunnel">
+        <title>SSH tunneling</title>
+
+        <para>Tunneling and all sort of VPN stuff has nothing to do with AFP
+        authentication and UAMs in general. But since Apple introduced an
+        option called "Allow Secure Connections Using SSH" and many people
+        tend to confuse both things, we'll speak about that here too.</para>
+
+        <sect4 id="manualsshtunnel">
+          <title>Manually tunneling an AFP session</title>
+
+          <para>This works since the first AFP servers that spoke "AFP over
+          TCP" appeared in networks. One simply tunnels the remote server's
+          AFP port to a local port different than 548 and connects locally to
+          this port afterwards. On OS X this can be done by</para>
+
+          <programlisting>ssh -l $USER $SERVER -L 10548:127.0.0.1:548 sleep 3000</programlisting>
+
+          <para>After establishing the tunnel one will use
+          <filename>"afp://127.0.0.1:10548"</filename> in the "Connect to
+          server" dialog. All AFP traffic including the initial connection
+          attempts will be sent encrypted over the wire since the local AFP
+          client will connect to the Mac's local port 10548 which will be
+          forwarded to the remote server's AFP port (we used the default 548)
+          over SSH.</para>
+
+          <para>These sorts of tunnels are an ideal solution if you've to
+          access an AFP server providing weak authentications mechanisms
+          through the Internet without having the ability to use a "real" VPN.
+          Note that you can let <command>ssh</command> compress the data by
+          using its "-C" switch and that the tunnel endpoints can be different
+          from both AFP client and server (compare with the SSH documentation
+          for details).</para>
+        </sect4>
+
+        <sect4 id="autosshtunnel">
+          <title>Automatically establishing a tunneled AFP connection</title>
+
+          <para>From Mac OS X 10.2 to 10.4, Apple added an "Allow Secure
+          Connections Using SSH" checkbox to the "Connect to Server" dialog.
+          The idea behind: When the server signals that it can be contacted by
+          SSH then Mac OS X' AFP client tries to establish the tunnel and
+          automagically sends all AFP traffic through it.</para>
+
+          <para>But it took until the release of Mac OS X 10.3 that this
+          feature worked the first time... partly. In case, the SSH tunnel
+          can't be established the AFP client <emphasis
+          role="strong">silently</emphasis> fell back to an unencrypted AFP
+          connection attempt.</para>
+
+          <para>Netatalk's afpd will report that it is capable of handling SSH
+          tunneled AFP requests, when both "<option>advertise ssh</option>"
+          and "<option>fqdn</option>" options are set in
+          <option>Global</option> section (double check with <citerefentry>
+              <refentrytitle>asip-status.pl</refentrytitle>
+
+              <manvolnum>1</manvolnum>
+            </citerefentry> after you restarted afpd when you made changes to
+          the settings). But there are a couple of reasons why you don't want
+          to use this option at all:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>Tunneling TCP over TCP (as SSH does) is not the best idea.
+              There exist better solutions like VPNs based on the IP
+              layer.</para>
+            </listitem>
+
+            <listitem>
+              <para>Since this SSH kludge isn't a normal UAM that integrates
+              directly into the AFP authentication mechanisms but instead uses
+              a single flag signalling clients whether they can <emphasis
+              role="strong">try</emphasis> to establish a tunnel or not, it
+              makes life harder to see what's happening when things go
+              wrong.</para>
+            </listitem>
+
+            <listitem>
+              <para>You cannot control which machines are logged on by
+              Netatalk tools like a <command>macusers</command> since all
+              connection attempts seem to be made from localhost.</para>
+            </listitem>
+
+            <listitem>
+              <para>On the other side you've to limit access to afpd to
+              localhost only (TCP wrappers) when you want to ensure that all
+              AFP sessions are SSH encrypted or...</para>
+            </listitem>
+
+            <listitem>
+              <para>...when you're using 10.2 - 10.3.3 then you get the
+              opposite of what you'd expect: potentially unencrypted AFP
+              communication (including logon credentials) on the network
+              without a single notification that establishing the tunnel
+              failed. Apple fixed that not until Mac OS X 10.3.4.</para>
+            </listitem>
+
+            <listitem>
+              <para>Encrypting all AFP sessions via SSH can lead to a
+              significantly higher load on the Netatalk server</para>
+            </listitem>
+          </itemizedlist>
+        </sect4>
+      </sect3>
+    </sect2>
+
+    <sect2 id="acls">
+      <title>ACL Support<indexterm>
+          <primary>ACLs</primary>
+        </indexterm></title>
+
+      <para>ACL support for AFP is implemented for ZFS ACLs on Solaris and
+      derived platforms and for POSIX 1e ACLs on Linux.</para>
+
+      <sect3>
+        <title>Configuration</title>
+
+        <para>For a basic mode of operation there's nothing to configure.
+        Netatalk reads ACLs on the fly and calculates effective permissions
+        which are then send to the AFP client via the so called
+        UARights<indexterm>
+            <primary>UARights</primary>
+          </indexterm> 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.</para>
+
+        <para>By default, the effective permission of the authenticated user
+        are only mapped to the mentioned UARights<indexterm>
+            <primary>UARights</primary>
+          </indexterm>permission structure, not the UNIX mode. You can adjust
+        this behaviour with the configuration option <link
+        linkend="map_acls">map acls</link>.</para>
+
+        <para>However, neither in Finder "Get Info" windows nor in Terminal
+        will you be able to see the ACLs, that's 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's or gid's. 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.</para>
+
+        <para>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).</para>
+
+        <para>In detail:</para>
+
+        <orderedlist>
+          <listitem>
+            <para>For Solaris/ZFS: ZFS Volumes</para>
+
+            <para>You should configure a ZFS ACL know for any volume you want
+            to use with Netatalk:</para>
+
+            <screen>aclinherit = passthrough
+aclmode = passthrough</screen>
+
+            <para>For an explanation of what this knob does and how to apply
+            it, check your hosts ZFS documentation (eg man zfs).</para>
+          </listitem>
+
+          <listitem>
+            <para>Authentication Domain</para>
+
+            <para>Your server and the clients must be part of a security
+            association where identity data is coming from a common source.
+            ACLs in Darwin are based on UUIDs and so is the ACL specification
+            in AFP 3.2. Therefor your source of identity data has to provide
+            an attribute for every user and group where a UUID is stored as a
+            ASCII string. In other words:</para>
+
+            <itemizedlist>
+              <listitem>
+                <para>you need an Open Directory Server or an LDAP server
+                where you store UUIDs in some attribute</para>
+              </listitem>
+
+              <listitem>
+                <para>your clients must be configured to use this
+                server</para>
+              </listitem>
+
+              <listitem>
+                <para>your server should be configured to use this server via
+                nsswitch and PAM</para>
+              </listitem>
+
+              <listitem>
+                <para>configure Netatalk via the special <link
+                linkend="acl_options">LDAP options for ACLs</link> in <link
+                linkend="afp.conf.5">afp.conf</link> so that Netatalk is able
+                to retrieve the UUID for users and groups via LDAP search
+                queries</para>
+              </listitem>
+            </itemizedlist>
+          </listitem>
+        </orderedlist>
+      </sect3>
+
+      <sect3>
+        <title>OS X ACLs</title>
+
+        <para>With Access Control Lists (ACLs) Mac OS X offers a powerful
+        extension of the traditional UNIX permissions model. An ACL is an
+        ordered list of Access Control Entries (ACEs) explicitly granting or
+        denying a set of permissions to a given user or group.</para>
+
+        <para>Unlike UNIX permissions, which are bound to user or group IDs,
+        ACLs are tied to UUIDs. For this reason accessing an object's ACL
+        requires server and client to use a common directory service which
+        translates between UUIDs and user/group IDs.</para>
+
+        <para>ACLs and UNIX permissions interact in a rather simple way. As
+        ACLs are optional UNIX permissions act as a default mechanism for
+        access control. Changing an objects's UNIX permissions will leave it's
+        ACL intact and modifying an ACL will never change the object's UNIX
+        permissions. While doing access checks, OS X first examines an
+        object's ACL evaluating ACEs in order until all requested rights have
+        been granted, a requested right has been explicitly denied by an ACE
+        or the end of the list has been reached. In case there is no ACL or
+        the permissions granted by the ACL are not sufficient to fulfill the
+        request, OS X next evaluates the object's UNIX permissions. Therefore
+        ACLs always have precedence over UNIX permissions.</para>
+      </sect3>
+
+      <sect3>
+        <title>ZFS ACLs</title>
+
+        <para>ZFS ACLs closely match OS X ACLs. Both offer mostly identical
+        fine grained permissions and inheritance settings.</para>
+      </sect3>
+
+      <sect3>
+        <title>POSIX ACLs</title>
+
+        <sect4>
+          <title>Overview</title>
+
+          <para>Compared to OS X or NFSv4 ACLs, Posix ACLs represent a
+          different, less versatile approach to overcome the limitations of
+          the traditional UNIX permissions. Implementations are based on the
+          withdrawn Posix 1003.1e standard.</para>
+
+          <para>The standard defines two types of ACLs. Files and directories
+          can have access ACLs which are consulted for access checks.
+          Directories can also have default ACLs irrelevant to access checks.
+          When a new object is created inside a directory with a default ACL,
+          the default ACL is applied to the new object as it's access ACL.
+          Subdirectories inherit default ACLs from their parent. There are no
+          further mechanisms of inheritance control. </para>
+
+          <para>Architectural differences between Posix ACLs and OS X ACLs
+          especially involve:</para>
+
+          <para><itemizedlist>
+              <listitem>
+                <para>No fine-granular permissions model. Like UNIX
+                permissions Posix ACLs only differentiate between read, write
+                and execute permissions.</para>
+              </listitem>
+
+              <listitem>
+                <para>Entries within an ACL are unordered.</para>
+              </listitem>
+
+              <listitem>
+                <para>Posix ACLs can only grant rights. There is no way to
+                explicitly deny rights by an entry.</para>
+              </listitem>
+
+              <listitem>
+                <para>UNIX permissions are integrated into an ACL as special
+                entries.</para>
+              </listitem>
+            </itemizedlist></para>
+
+          <para>Posix 1003.1e defines 6 different types of ACL entries. The
+          first three types are used to integrate standard UNIX permissions.
+          They form a minimal ACL, their presence is mandatory and only one
+          entry of each type is allowed within an ACL.</para>
+
+          <para><itemizedlist>
+              <listitem>
+                <para>ACL_USER_OBJ: the owner's access rights.</para>
+              </listitem>
+
+              <listitem>
+                <para>ACL_GROUP_OBJ: the owning group's access rights.</para>
+              </listitem>
+
+              <listitem>
+                <para>ACL_OTHER: everybody's access rights.</para>
+              </listitem>
+            </itemizedlist></para>
+
+          <para>The remaining entry types expand the traditional permissions
+          model:</para>
+
+          <para><itemizedlist>
+              <listitem>
+                <para>ACL_USER: grants access rights to a certain user.</para>
+              </listitem>
+
+              <listitem>
+                <para>ACL_GROUP: grants access rights to a certain
+                group.</para>
+              </listitem>
+
+              <listitem>
+                <para>ACL_MASK: limits the maximum access rights which can be
+                granted by entries of type ACL_GROUP_OBJ, ACL_USER and
+                ACL_GROUP. As the name suggests, this entry acts as a mask.
+                Only one ACL_MASK entry is allowed per ACL. If an ACL contains
+                ACL_USER or ACL_GROUP entries, an ACL_MASK entry must be
+                present too, otherwise it is optional.</para>
+              </listitem>
+            </itemizedlist></para>
+
+          <para>In order to maintain compatibility with applications not aware
+          of ACLs, Posix 1003.1e changes the semantics of system calls and
+          utilities which retrieve or manipulate an objects UNIX permissions.
+          In case an object only has a minimal ACL, the group permissions bits
+          of the UNIX permissions correspond to the value of the ACL_GROUP_OBJ
+          entry.</para>
+
+          <para>However, if the ACL also contains an ACL_MASK entry, the
+          behavior of those system calls and utilities is different. The group
+          permissions bits of the UNIX permissions correspond to the value of
+          the ACL_MASK entry, i. e. calling "chmod g-w" will not only revoke
+          write access for the group, but for all entities which have been
+          granted write access by ACL_USER or ACL_GROUP entries.</para>
+        </sect4>
+
+        <sect4>
+          <title>Mapping POSIX ACLs to OS X ACLs</title>
+
+          <para>When a client wants to read an object's ACL, afpd maps it's
+          Posix ACL onto an equivalent OS X ACL. Writing an object's ACL
+          requires afpd to map an OS X ACL onto a Posix ACL. Due to
+          architectural restrictions of Posix ACLs, it is usually impossible
+          to find an exact mapping so that the result of the mapping process
+          will be an approximation of the original ACL's semantic.</para>
+
+          <para><itemizedlist>
+              <listitem>
+                <para>afpd silently discard entries which deny a set of
+                permissions because they they can't be represented within the
+                Posix architecture. </para>
+              </listitem>
+
+              <listitem>
+                <para>As entries within Posix ACLs are unordered, it is
+                impossible to preserve order.</para>
+              </listitem>
+
+              <listitem>
+                <para>Inheritance control is subject to severe limitations as
+                well:<itemizedlist>
+                    <listitem>
+                      <para>Entries with the only_inherit flag set will only
+                      become part of the directory's default ACL.</para>
+                    </listitem>
+
+                    <listitem>
+                      <para>Entries with at least one of the flags
+                      file_inherit, directory_inherit or limit_inherit set,
+                      will become part of the directory's access and default
+                      ACL, but the restrictions they impose on inheritance
+                      will be ignored.</para>
+                    </listitem>
+                  </itemizedlist></para>
+              </listitem>
+
+              <listitem>
+                <para>The lack of a fine-granular permission model on the
+                Posix side will normally result in an increase of granted
+                permissions.</para>
+              </listitem>
+            </itemizedlist></para>
+
+          <para>As OS X clients aren't aware of the Posix 1003.1e specific
+          relationship between UNIX permissions and ACL_MASK, afpd does not
+          expose this feature to the client to avoid compatibility issues and
+          handles *unix permissions and ACLs the same way as Apple's reference
+          implementation of AFP does. When an object's UNIX permissions are
+          requested, afpd calculates proper group rights and returns the
+          result together with the owner's and everybody's access rights to
+          the caller via "permissions" and "ua_permissions" members of the
+          FPUnixPrivs structure (see Apple Filing Protocol Reference, page
+          181). Changing an object's permissions, afpd always updates
+          ACL_USER_OBJ, ACL_GROUP_OBJ and ACL_OTHERS. If an ACL_MASK entry is
+          present too, afpd recalculates it's value so that the new group
+          rights become effective and existing entries of type ACL_USER or
+          ACL_GROUP stay intact.</para>
+        </sect4>
+      </sect3>
+    </sect2>
+
+    <sect2 id="fce">
+      <title>Filesystem Change Events<indexterm>
+          <primary>FCE</primary>
+        </indexterm></title>
+
+      <para>Netatalk includes a nifty filesystem change event mechanism where
+      afpd processes notfiy interested listeners about certain filesystem
+      event by UDP network datagrams.</para>
+
+      <para>For the format of the UDP packets and for an example C application
+      that demonstrates how to use these in a listener, take a look at the
+      Netatalk sourcefile <filename>bin/misc/fce.c</filename>.</para>
+
+      <para>The currently supported FCE events are<itemizedlist>
+          <listitem>
+            <para>file modification (fmod)</para>
+          </listitem>
+
+          <listitem>
+            <para>file deletion (fdel)</para>
+          </listitem>
+
+          <listitem>
+            <para>directory deletion (ddel)</para>
+          </listitem>
+
+          <listitem>
+            <para>file creation (fcre)</para>
+          </listitem>
+
+          <listitem>
+            <para>directory deletion (ddel)</para>
+          </listitem>
+        </itemizedlist></para>
+
+      <para>For details on the available simple configuration options take a
+      look at <filename><link
+      linkend="fceconf">afp.conf</link></filename>.</para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Starting and stopping Netatalk</title>
+
+    <para>The Netatalk distribution comes with several operating system
+    specific startup script templates that are tailored according to the
+    options given to the "configure" script before compiling. Currently,
+    templates are provided for RedHat (sysv style), RedHat (systemd style),
+    SUSE (sysv style), SUSE (systemd style), Gentoo, NetBSD, Debian and
+    Solaris. You can select to install the generated startup script(s)
+    <indexterm>
+        <primary>Startscript</primary>
+
+        <secondary>startup script</secondary>
+      </indexterm> by specifying a system type to "configure". To
+    automatically install startup scripts give one of the available
+    <option>--with-init-style</option> option to "configure".</para>
+
+    <para>Since new releases of Linux distributions appear all the time and
+    the startup procedure for the other systems mentioned above might change
+    as well, it is probably a good idea to not blindly install a startup
+    script but to look at it first to see if it will work on your system. If
+    you use Netatalk as part of a fixed setup, like a Linux distribution, an
+    RPM or a BSD package, things will probably have been arranged properly for
+    you. The following therefore applies mostly for people who have compiled
+    Netatalk themselves.</para>
+
+    <para>The following daemon need to be started by whatever startup script
+    mechanism is used:</para>
+
+    <itemizedlist>
+      <listitem>
+        <para>netatalk<indexterm>
+            <primary>netatalk</primary>
+          </indexterm></para>
+      </listitem>
+    </itemizedlist>
+
+    <para>Additionally, make sure that the configuration file
+    <filename>afp.conf</filename> is in the right place.</para>
+  </sect1>
+</chapter>
diff --git a/doc/manual/install.xml b/doc/manual/install.xml
new file mode 100644 (file)
index 0000000..a64b384
--- /dev/null
@@ -0,0 +1,347 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter id="installation">
+  <chapterinfo>
+    <date>24.8.2012</date>
+  </chapterinfo>
+
+  <title>Installation</title>
+
+  <warning>
+    <para>If you have previously used an older version of Netatalk, please
+    read the chapter about <link linkend="upgrade">upgrading</link> first
+    !!!</para>
+  </warning>
+
+  <para></para>
+
+  <sect1>
+    <title>How to obtain Netatalk</title>
+
+    <para>Please have a look at the netatalk page on sourceforge for the most
+    recent informations on this issue.</para>
+
+    <para><ulink
+    url="http://sourceforge.net/projects/netatalk/">http://sourceforge.net/projects/netatalk/</ulink></para>
+
+    <sect2>
+      <title>Binary packages</title>
+
+      <para>Binary packages of Netatalk are included in some Linux and UNIX
+      distributions. You might want to have a look at the usual locations,
+      too.</para>
+
+      <para>Ubuntu package: <ulink
+      url="https://launchpad.net/ubuntu">https://launchpad.net/ubuntu
+      </ulink></para>
+
+      <para>Debian package: <ulink
+      url="http://packages.debian.org/">http://packages.debian.org/
+      </ulink></para>
+
+      <para>various RPM package: <ulink
+      url="http://rpmfind.net/">http://rpmfind.net/ </ulink></para>
+
+      <para>Fedora/RHEL package: <ulink
+      url="http://koji.fedoraproject.org/koji/search">http://koji.fedoraproject.org/koji/search
+      </ulink></para>
+
+      <para>Gentoo package: <ulink
+      url="http://packages.gentoo.org/">http://packages.gentoo.org/
+      </ulink></para>
+
+      <para>openSUSE package: <ulink
+      url="http://software.opensuse.org/">http://software.opensuse.org/
+      </ulink></para>
+
+      <para>Solaris package: <ulink
+      url="http://www.blastwave.org/">http://www.blastwave.org/
+      </ulink></para>
+
+      <para>FreeBSD ports: <ulink
+      url="http://www.freebsd.org/ports/index.html">http://www.freebsd.org/ports/index.html
+      </ulink></para>
+
+      <para>NetBSD pkgsrc: <ulink
+      url="http://pkgsrc.se/search.php">http://pkgsrc.se/search.php
+      </ulink></para>
+
+      <para>OpenBSD ports:<ulink
+      url="http://openports.se/search.php">http://openports.se/search.php
+      </ulink></para>
+
+      <para>etc.<indexterm>
+          <primary>RPM</primary>
+
+          <secondary>Red Hat Package Manager package</secondary>
+        </indexterm><indexterm>
+          <primary>Deb</primary>
+
+          <secondary>Debian package</secondary>
+        </indexterm><indexterm>
+          <primary>Ports</primary>
+
+          <secondary>FreeBSD port</secondary>
+        </indexterm></para>
+    </sect2>
+
+    <sect2>
+      <title>Source packages</title>
+
+      <sect3>
+        <title>Tarballs</title>
+
+        <para>Prepacked tarballs in .tar.gz and tar.bz2 format are available
+        on the netatalk page on <ulink
+        url="http://netatalk.sourceforge.net/">sourceforge</ulink>.</para>
+      </sect3>
+
+      <sect3>
+        <title>Git</title>
+
+        <para>Downloading the Git repository can be done quickly and
+        easily.</para>
+
+        <orderedlist>
+          <listitem>
+            <para>Make sure you have Git installed. <command>which
+            git</command> should produce a path to git.</para>
+
+            <screen><prompt>$&gt;</prompt> <userinput>which git</userinput>
+<computeroutput>/usr/bin/git</computeroutput></screen>
+          </listitem>
+
+          <listitem>
+            <para>If you don't have one make a source directory.
+            <command>cd</command> to this directory.</para>
+
+            <screen><prompt>$&gt;</prompt> <userinput>mkdir /path/to/new/source/dir</userinput>
+<prompt>$&gt;</prompt> <userinput>cd /path/to/new/source/dir</userinput></screen>
+          </listitem>
+
+          <listitem>
+            <para>Now get the source:</para>
+
+            <screen><prompt>$&gt;</prompt> <userinput>git clone git://git.code.sf.net/p/netatalk/code netatalk-code
+</userinput><computeroutput>Initialized empty Git repository in /path/to/new/source/dir/netatalk/.git/
+remote: Counting objects: 2503, done.
+...
+</computeroutput></screen>
+
+            <para>This will create a local directory called "netatalk-code"
+            containing a complete and fresh copy of the whole Netatalk source
+            from the Git repository.</para>
+          </listitem>
+
+          <listitem>
+            <para>In order to keep your repository copy updated, occasionally
+            run:</para>
+
+            <screen><prompt>$&gt;</prompt> <userinput>git pull</userinput></screen>
+          </listitem>
+
+          <listitem>
+            <para>Now <command>cd</command> to the netatalk directory and run
+            <command>./bootstrap</command>. This will create the
+            <filename>configure</filename> script required in the next
+            step.</para>
+
+            <screen><prompt>$&gt;</prompt> <userinput>./bootstrap</userinput></screen>
+          </listitem>
+        </orderedlist>
+
+        <para></para>
+      </sect3>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Compiling Netatalk</title>
+
+    <sect2>
+      <title>Prerequisites</title>
+
+      <sect3>
+        <title>Required third party software</title>
+
+        <itemizedlist>
+          <listitem>
+            <para>Berkeley DB<indexterm>
+                <primary>BDB</primary>
+
+                <secondary>Berkeley DB</secondary>
+              </indexterm>.</para>
+
+            <para>At the time of writing, the following versions are
+            supported:</para>
+
+            <itemizedlist>
+              <listitem>
+                <para>minimum 4.6.x</para>
+              </listitem>
+            </itemizedlist>
+
+            <para>In case Berkeley DB is not installed on your system, please
+            download it from:</para>
+
+            <para><ulink
+            url="http://www.oracle.com/technetwork/products/berkeleydb/downloads/index.html">
+            http://www.oracle.com/technetwork/products/berkeleydb/downloads/index.html</ulink></para>
+
+            <para>and follow the <link linkend="build-bdb">installation
+            instructions</link>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Libgcrypt</para>
+
+            <para>Required for OS X 10.7 and later. Libgcrypt is needed for
+            DHX2.</para>
+
+            <para>Libgcrypt can be downloaded from: <ulink
+            url="http://directory.fsf.org/wiki/Libgcrypt">
+            http://directory.fsf.org/wiki/Libgcrypt</ulink>.</para>
+          </listitem>
+        </itemizedlist>
+      </sect3>
+
+      <sect3>
+        <title>Optional third party software</title>
+
+        <para>Netatalk can use the following third party software to enhance
+        it's functionality.</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>mDNSresponderPOSIX or Avahi for Bonjour (aka
+            Zeroconf)</para>
+
+            <para>Mac OS X 10.2 and later use Bonjour (aka Zeroconf) for
+            service discovery.</para>
+
+            <para>Avahi must be build with DBUS support (
+            <userinput>--enable-dbus</userinput>).</para>
+
+            <para>You can download Avahi from: <ulink
+            url="http://www.avahi.org/">http://www.avahi.org/</ulink>.</para>
+
+            <para>You can download mDNSresponder from: <ulink
+            url="http://opensource.apple.com/tarballs/mDNSResponder/">http://opensource.apple.com/tarballs/mDNSResponder/</ulink>.</para>
+          </listitem>
+
+          <listitem>
+            <para>TCP wrappers</para>
+
+            <para>Wietse Venema's network logger, also known as TCPD or
+            LOG_TCP.</para>
+
+            <para>Security options are: access control per host, domain and/or
+            service; detection of host name spoofing or host address spoofing;
+            booby traps to implement an early-warning system.</para>
+
+            <para>TCP Wrappers can be downloaded from: <ulink
+            url="ftp://ftp.porcupine.org/pub/security">ftp://ftp.porcupine.org/pub/security</ulink>/</para>
+          </listitem>
+
+          <listitem>
+            <para>PAM<indexterm>
+                <primary>PAM</primary>
+
+                <secondary>Pluggable Authentication Modules</secondary>
+              </indexterm></para>
+
+            <para>PAM provides a flexible mechanism for authenticating users.
+            PAM was invented by SUN<indexterm>
+                <primary>SUN</primary>
+
+                <secondary>Sun Microsystems</secondary>
+              </indexterm> Microsystems. Linux-PAM is a suite of shared
+            libraries that enable the local system administrator to choose how
+            applications authenticate users.</para>
+
+            <para>You can get the Linux PAM documentation and sources from
+            <ulink
+            url="http://www.kernel.org/pub/linux/libs/pam/">http://www.kernel.org/pub/linux/libs/pam/</ulink>.</para>
+          </listitem>
+
+          <listitem>
+            <para>iconv</para>
+
+            <para>iconv provides conversion routines for many character
+            encodings. Netatalk uses it to provide charsets it does not have
+            built in conversions for, like ISO-8859-1. On glibc systems,
+            Netatalk can use the glibc provided iconv implementation.
+            Otherwise you can use the GNU libiconv implementation.</para>
+
+            <para>You can download GNU libiconv from: <olink><ulink
+            url="http://www.gnu.org/software/libiconv/">http://www.gnu.org/software/libiconv/</ulink></olink>.</para>
+          </listitem>
+        </itemizedlist>
+      </sect3>
+    </sect2>
+
+    <sect2 id="compiling-netatalk">
+      <title>Compiling<indexterm>
+          <primary>Compile</primary>
+
+          <secondary>Compiling Netatalk from Source</secondary>
+        </indexterm> Netatalk</title>
+
+      <sect3>
+        <title>Configuring the build</title>
+
+        <para>To build the binaries, first run the program
+        <command>./configure</command> in the source directory. This should
+        automatically configure Netatalk for your operating system. If you
+        have unusual needs, then you may wish to run</para>
+
+        <screen>$&gt; <userinput>./configure --help</userinput></screen>
+
+        <para>to see what special options you can enable.</para>
+
+        <para>The most used configure options are:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><option>--with-init-style</option>=redhat-sysv|redhat-systemd|suse-sysv|suse-systemd|gentoo|netbsd|debian|solaris|systemd</para>
+
+            <para>This option helps netatalk to determine where to install the
+            start scripts.</para>
+          </listitem>
+
+          <listitem>
+            <para><option>--with-bdb</option>=<replaceable>/path/to/bdb/installation/</replaceable></para>
+
+            <para>In case you installed Berkeley DB in a non-standard
+            location, you will <emphasis>have</emphasis> to give the install
+            location to netatalk, using this switch.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Now run configure with any options you need</para>
+
+        <screen><prompt>$&gt;</prompt> <userinput>./configure [arguments]</userinput></screen>
+
+        <para>Configure will end up in an overview showing the settings the
+        Netatalk Makefiles have been created with.</para>
+
+        <para>If this step fails please visit the <ulink
+        url="http://netatalk.sourceforge.net/wiki/index.php/Troubleshooting">troubleshooting
+        guide</ulink>.</para>
+
+        <para>Next, running</para>
+
+        <screen><prompt>$&gt;</prompt> <userinput>make</userinput></screen>
+
+        <para>should produce the Netatalk binaries (this step can take several
+        minutes to complete).</para>
+
+        <para>When the process finished you can use</para>
+
+        <screen><prompt>$&gt;</prompt> <userinput>make install</userinput></screen>
+
+        <para>to install the binaries and documentation (must be done as
+        "root" when using default locations).</para>
+      </sect3>
+    </sect2>
+  </sect1>
+</chapter>
diff --git a/doc/manual/intro.xml b/doc/manual/intro.xml
new file mode 100644 (file)
index 0000000..0b70a9a
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter id="intro">
+  <title>Introduction to Netatalk</title>
+
+  <para>Netatalk is an OpenSource software package, that can be used to turn
+  a *NIX machine into an extremely high-performance and
+  reliable file server for Macintosh computers.</para>
+
+  <para>Using Netatalk's AFP 3.3 compliant file-server leads to significantly
+  higher transmission speeds compared with Macs accessing a server via
+  SaMBa/NFS while providing clients with the best possible user experience
+  (full support for Macintosh metadata, flawlessly supporting mixed
+  environments of classic Mac OS and OS X clients)</para>
+
+</chapter>
diff --git a/doc/manual/manual.xml.in b/doc/manual/manual.xml.in
new file mode 100644 (file)
index 0000000..eab6e62
--- /dev/null
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+
+<!ENTITY Intro SYSTEM "netatalk/intro.xml">
+<!ENTITY Install SYSTEM "netatalk/install.xml">
+<!ENTITY Upgrade SYSTEM "netatalk/upgrade.xml">
+<!ENTITY Configuration SYSTEM "netatalk/configuration.xml">
+
+<!ENTITY ad.1 SYSTEM "man/man1/ad.1.xml">
+<!ENTITY afpd.8 SYSTEM "man/man8/afpd.8.xml">
+<!ENTITY cnid_dbd.8 SYSTEM "man/man8/cnid_dbd.8.xml">
+<!ENTITY cnid_metad.8 SYSTEM "man/man8/cnid_metad.8.xml">
+<!ENTITY afp.conf.5 SYSTEM "man/man5/afp.conf.5.xml">
+<!ENTITY afp_signature.conf.5 SYSTEM "man/man5/afp_signature.conf.5.xml">
+<!ENTITY afp_voluuid.conf.5 SYSTEM "man/man5/afp_voluuid.conf.5.xml">
+<!ENTITY afpldaptest.1 SYSTEM "man/man1/afpldaptest.1.xml">
+<!ENTITY afppasswd.1 SYSTEM "man/man1/afppasswd.1.xml">
+<!ENTITY afpstats.1 SYSTEM "man/man1/afpstats.1.xml">
+<!ENTITY apple_dump.1 SYSTEM "man/man1/apple_dump.1.xml">
+<!ENTITY extmap.conf.5 SYSTEM "man/man5/extmap.conf.5.xml">
+<!ENTITY macusers.1 SYSTEM "man/man1/macusers.1.xml">
+<!ENTITY megatron.1 SYSTEM "man/man1/megatron.1.xml">
+<!ENTITY netatalk.8 SYSTEM "man/man8/netatalk.8.xml">
+<!ENTITY netatalk-config.1 SYSTEM "man/man1/netatalk-config.1.xml">
+<!ENTITY uniconv.1 SYSTEM "man/man1/uniconv.1.xml">
+<!ENTITY asip-status.pl.1 SYSTEM "man/man1/asip-status.pl.1.xml">
+<!ENTITY dbd.1 SYSTEM "man/man1/dbd.1.xml">
+]>
+<book id="netatalk-manual">
+  <title>Netatalk 3.0 Manual</title>
+  
+  <bookinfo>
+    <date>03-24-2013</date>
+    <releaseinfo>@NETATALK_VERSION@</releaseinfo>
+  </bookinfo>
+
+ <?latex \setcounter{page}{3} ?>
+<preface>
+        <title>Legal Notice</title>
+<para>
+This documentation is distributed under the GNU General Public License (GPL) version 2.  
+A copy of the license is included in this documentation, as well as within the Netatalk source
+distribution.  An on-line copy can be found at <ulink
+url="http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt">http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt</ulink>
+</para>
+</preface>
+
+  <?latex \cleardoublepage ?>
+  <!-- Contents -->
+  <toc/>
+  <?latex \cleardoublepage ?>
+  <?latex \pagenumbering{arabic} ?>
+
+  &Intro;
+  <?latex \cleardoublepage ?>
+
+  &Install;
+  <?latex \cleardoublepage ?>
+
+  &Configuration;
+  <?latex \cleardoublepage ?>
+
+  &Upgrade;
+  <?latex \cleardoublepage ?>
+
+  <chapter id="man-pages">
+    <title>Manual Pages</title>
+
+    <para>This is a collection of the man pages delivered with Netatalk.</para>
+
+    &ad.1;
+
+    &afp.conf.5;
+
+    &afp_signature.conf.5;
+
+    &afp_voluuid.conf.5;
+
+    &afpd.8;
+
+    &afpldaptest.1;
+
+    &afppasswd.1;
+
+    &afpstats.1;
+
+    &apple_dump.1;
+
+    &asip-status.pl.1;
+
+    &cnid_dbd.8;
+
+    &cnid_metad.8;
+
+    &dbd.1;
+
+    &extmap.conf.5;
+
+    &macusers.1;
+
+    &megatron.1;
+
+    &netatalk.8;
+
+    &netatalk-config.1;
+
+    &uniconv.1;
+  </chapter>
+  <?latex \cleardoublepage ?>
+
+  <?latex \include{gpl}?>
+  <?latex \cleardoublepage ?>
+
+  <index id="manual-index"><title>Index</title></index>
+</book>
diff --git a/doc/manual/upgrade.xml b/doc/manual/upgrade.xml
new file mode 100644 (file)
index 0000000..ebd1963
--- /dev/null
@@ -0,0 +1,1555 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter id="upgrade">
+  <chapterinfo>
+    <date>2.15.2013</date>
+
+    <author>
+      <firstname>Frank</firstname>
+
+      <surname>Lahm</surname>
+    </author>
+
+    <pubdate>15 Feb, 2013</pubdate>
+  </chapterinfo>
+
+  <title>Upgrading from Netatalk 2</title>
+
+  <sect1>
+    <title>Overview</title>
+
+    <para>There are two major changes in Netatalk:<orderedlist>
+        <listitem>
+          <para>New configuration file <filename><link
+          linkend="afp.conf.5">afp.conf</link></filename>, obsoleting all
+          previous configuration files</para>
+        </listitem>
+
+        <listitem>
+          <para>New AppleDouble backend "<option>appledouble = ea</option>"
+          which stores Mac metadata and resource forks in extended attributes
+          of the filesystem</para>
+        </listitem>
+      </orderedlist></para>
+
+    <sect2>
+      <title>New configuration</title>
+
+      <para><itemizedlist>
+          <listitem>
+            <para>ini style syntax (like Samba’s smb.conf)</para>
+          </listitem>
+
+          <listitem>
+            <para>one to rule them all: configure AFP settings and volumes in
+            one file</para>
+          </listitem>
+
+          <listitem>
+            <para>obsoletes <filename>afpd.conf</filename>,
+            <filename>netatalk.conf</filename>,
+            <filename>AppleVolumes.default</filename> and
+            <filename>afp_ldap.conf</filename></para>
+          </listitem>
+        </itemizedlist><warning>
+          <para>most option names have changed, read the full manpage <link
+          linkend="afp.conf.5">afp.conf</link> for details</para>
+        </warning></para>
+    </sect2>
+
+    <sect2>
+      <title>New AppleDouble backend</title>
+
+      <para>New AppleDouble backend "<option>appledouble = ea</option>" which
+      stores Mac metadata and resource forks in extended attributes of the
+      filesystem.<itemizedlist>
+          <listitem>
+            <para>default backend (!)</para>
+          </listitem>
+
+          <listitem>
+            <para>requires a filesystem with Extended Attributes, fallback is
+            "<option>appledouble = v2</option>"</para>
+          </listitem>
+
+          <listitem>
+            <para>converts filesystems from "<option>appledouble = v2</option>"
+            to "<option>appledouble = ea</option>" on the fly when accessed
+            (can be disabled)</para>
+          </listitem>
+
+          <listitem>
+            <para><command><link linkend="dbd.1">dbd</link></command> can be
+            used to do conversion in one shot</para>
+          </listitem>
+        </itemizedlist></para>
+
+      <para>Implementation details:<itemizedlist>
+          <listitem>
+            <para>stores Mac Metadata (eg FinderInfo, AFP Flags, Comment,
+            CNID) in an Extended Attributed named
+            “<filename>org.netatalk.Metadata</filename>”</para>
+          </listitem>
+
+          <listitem>
+            <para>stores Mac ResourceFork either in<itemizedlist>
+                <listitem>
+                  <para>an Extended Attribute named
+                  “<filename>org.netatalk.ResourceFork</filename>”
+                  on Solaris (FreeBSD?) w. ZFS, or in</para>
+                </listitem>
+
+                <listitem>
+                  <para>an extra AppleDouble file named “<filename>._file</filename>” for a file
+                  named “<filename>file</filename>”</para>
+                </listitem>
+              </itemizedlist></para>
+          </listitem>
+
+          <listitem>
+            <para>the format of the ._ file is exactly as the Mac’s CIFS
+            client expects it when accessing the same filesystem via a CIFS
+            server (Samba), thus you can have parallel access from Macs to the
+            same dataset via AFP and CIFS without the risk of loosing data
+            (resources or metadata). Accessing the same dataset with CIFS
+            from Windows clients will still break the coupling of
+            “<filename>file</filename>” and “<filename>._file</filename>”
+            on non ZFS filesystems (see above), so for this we still
+            need an enhanced Samba VFS module (in the works).</para>
+          </listitem>
+        </itemizedlist></para>
+
+      <para>As these days the only applications making use of Resource Forks
+      are Adobe Photoshop (image preview) and Postscript Type 1 fonts, even on
+      eg Linux you’ll get rid of 99% of any extra Netatalk AppleDouble files
+      (and folders).</para>
+    </sect2>
+
+    <sect2>
+      <title>Other major changes</title>
+
+      <para><itemizedlist>
+          <listitem>
+            <para>New service controller daemon <link
+            linkend="netatalk.8">netatalk</link> which is responsible for
+            starting and restarting the AFP and CNID daemons. All bundled
+            start scripts have been updated, make sure to update yours!</para>
+          </listitem>
+
+          <listitem>
+            <para>The CNID databases are now stored under
+              <filename>/var/netatalk/CNID/</filename>
+              by default. You can use configure --localstatedir=PATH at
+              compile time to change the location.</para>
+          </listitem>
+
+          <listitem>
+            <para>Netatalk 2.x volume options “usedots” and “upriv” now
+            enabled by default</para>
+          </listitem>
+
+          <listitem>
+            <para>Removed SLP and AFP proxy support</para>
+          </listitem>
+
+          <listitem>
+            <para>Removed type/creator extension mapping
+            support</para>
+          </listitem>
+        </itemizedlist></para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Upgrading</title>
+
+    <para><orderedlist>
+        <listitem>
+          <para>Stop Netatalk 2.x</para>
+        </listitem>
+
+        <listitem>
+          <para>Install Netatalk 3</para>
+        </listitem>
+
+        <listitem>
+          <para>Manually recreate configuration in
+          <option>afp.conf</option> and <option>extmap.conf</option></para>
+        </listitem>
+
+        <listitem>
+          <para>Update your Netatalk start script (SMF, systemd, whatever...)
+          to only start <link linkend="netatalk.8">netatalk</link></para>
+        </listitem>
+
+        <listitem>
+          <para>Move <filename>afp_voluuid.conf</filename> and
+          <filename>afp_signature.conf</filename> to the localstate directory (default
+          <filename>/var/netatalk/</filename>), you can use <command>afpd -v</command>
+          in order to find the correct path</para>
+        </listitem>
+
+        <listitem>
+          <para>Start Netatalk 3</para>
+        </listitem>
+      </orderedlist></para>
+  </sect1>
+
+  <sect1>
+    <title>Notes</title>
+
+    <itemizedlist>
+      <listitem>
+        <para>Solaris ZFS permissions</para>
+
+        <para>On Solaris with ZFS you have to make sure users have
+        filesystem permissions to read, create, modify (default: yes) and
+        delete (default: no) extended attributes.</para>
+
+        <para>To grant this right to a group “staff” you’d use this
+        command:</para>
+
+        <para><command>pfexec chmod A+group:staff:RW:fd:allow
+        /Volumes/test/</command></para>
+
+        <para>Remember to run this once before you share a volume so that
+        this permission inherits appropiately (fd flags in above
+        command).</para>
+      </listitem>
+    </itemizedlist>
+  </sect1>
+  <sect1>
+    <title>Table with old and new configuration file names</title>
+    <para><table frame="all">
+        <title>old and new configuration file names</title>
+        <tgroup cols="3">
+          <colspec colname="c1" colnum="1" colwidth="1.0*"/>
+          <colspec colname="c2" colnum="2" colwidth="1.0*"/>
+          <colspec colname="c3" colnum="3" colwidth="1.0*"/>
+          <thead>
+            <row>
+              <entry>Old File Name</entry>
+              <entry>New File Name</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>-</entry>
+              <entry><filename>etc/afp.conf</filename></entry>
+              <entry>new ini-style format</entry>
+            </row>
+            <row>
+              <entry>-</entry>
+              <entry><filename>etc/extmap.conf</filename></entry>
+              <entry>starting with netatalk 3.0.2</entry>
+            </row>
+            <row>
+              <entry><filename>etc/netatalk/afp_signature.conf</filename></entry>
+              <entry><filename>var/netatalk/afp_signature.conf</filename></entry>
+              <entry>moved to $localstatedir</entry>
+            </row>
+            <row>
+              <entry><filename>etc/netatalk/afp_voluuid.conf</filename></entry>
+              <entry><filename>var/netatalk/afp_voluuid.conf</filename></entry>
+              <entry>moved to $localstatedir</entry>
+            </row>
+            <row>
+              <entry><filename>etc/netatalk/netatalk.conf</filename>
+              (<filename>/etc/default/netatalk</filename>)</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry><filename>etc/netatalk/afpd.conf</filename></entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry><filename>etc/netatalk/afp_ldap.conf</filename></entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry><filename>etc/netatalk/AppleVolumes.default</filename></entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry><filename>etc/netatalk/AppleVolumes.system</filename></entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry><filename>~/.AppleVolumes</filename></entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table></para>
+  </sect1>
+
+  <sect1>
+    <title>Table with old and new option names</title>
+    <para><table frame="all">
+        <title>from netatalk.conf (/etc/default/netatalk) to afp.conf</title>
+        <tgroup cols="6">
+          <colspec colname="c1" colnum="1" colwidth="1.0*"/>
+          <colspec colname="c2" colnum="2" colwidth="1.0*"/>
+          <colspec colname="c3" colnum="3" colwidth="1.0*"/>
+          <colspec colname="c4" colnum="4" colwidth="1.0*"/>
+          <colspec colname="c5" colnum="5" colwidth="1.0*"/>
+          <colspec colname="c6" colnum="6" colwidth="1.0*"/>
+          <thead>
+            <row>
+              <entry>Old netatalk.conf</entry>
+              <entry>New afp.conf</entry>
+              <entry>Old Default Value</entry>
+              <entry>New Default Value</entry>
+              <entry>Section</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>ATALK_NAME</entry>
+              <entry>hostname</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>use gethostname() by default</entry>
+            </row>
+            <row>
+              <entry>ATALK_UNIX_CHARSET</entry>
+              <entry>unix charset</entry>
+              <entry><emphasis role="bold">LOCALE</emphasis></entry>
+              <entry><emphasis role="bold">UTF8</emphasis></entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ATALK_MAC_CHARSET</entry>
+              <entry>mac charset</entry>
+              <entry>MAC_ROMAN</entry>
+              <entry>MAC_ROMAN</entry>
+              <entry>(G)/(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>CNID_METAD_RUN</entry>
+              <entry>-</entry>
+              <entry>yes</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>controlled by netatalk(8)</entry>
+            </row>
+            <row>
+              <entry>AFPD_RUN</entry>
+              <entry>-</entry>
+              <entry>yes</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>controlled by netatalk(8)</entry>
+            </row>
+            <row>
+              <entry>AFPD_MAX_CLIENTS</entry>
+              <entry>max connections</entry>
+              <entry><emphasis role="bold">20</emphasis></entry>
+              <entry><emphasis role="bold">200</emphasis></entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>AFPD_UAMLIST</entry>
+              <entry>uam list</entry>
+              <entry>-U uams_dhx.so,uams_dhx2.so</entry>
+              <entry>uams_dhx.so uams_dhx2.so</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>AFPD_GUEST</entry>
+              <entry>guest account</entry>
+              <entry>nobody</entry>
+              <entry>nobody</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>CNID_CONFIG</entry>
+              <entry>log level</entry>
+              <entry>-l log_note</entry>
+              <entry>cnid:note</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>CNID_CONFIG</entry>
+              <entry>log file</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ATALKD_RUN</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>AppleTalk is obsoleted</entry>
+            </row>
+            <row>
+              <entry>PAPD_RUN</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>AppleTalk is obsoleted</entry>
+            </row>
+            <row>
+              <entry>TIMELORD_RUN</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>AppleTalk is obsoleted</entry>
+            </row>
+            <row>
+              <entry>A2BOOT_RUN</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>AppleTalk is obsoleted</entry>
+            </row>
+            <row>
+              <entry>ATALK_BGROUND</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>AppleTalk is obsoleted</entry>
+            </row>
+            <row>
+              <entry>ATALK_ZONE</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>AppleTalk is obsoleted</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table><table frame="all">
+        <title>from afpd.conf to afp.conf</title>
+        <tgroup cols="6">
+          <colspec colname="c1" colnum="1" colwidth="1.0*"/>
+          <colspec colname="c2" colnum="2" colwidth="1.0*"/>
+          <colspec colname="c3" colnum="3" colwidth="1.0*"/>
+          <colspec colname="c4" colnum="4" colwidth="1.0*"/>
+          <colspec colname="c5" colnum="5" colwidth="1.0*"/>
+          <colspec colname="c6" colnum="6" colwidth="1.0*"/>
+          <thead>
+            <row>
+              <entry>Old afpd.conf</entry>
+              <entry>New afp.conf</entry>
+              <entry>Old Default Value</entry>
+              <entry>New Default Value</entry>
+              <entry>Section</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>1st field ("-" or "server name")</entry>
+              <entry>hostname</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>use gethostname() by default</entry>
+            </row>
+            <row>
+              <entry>-uamlist</entry>
+              <entry>uam list</entry>
+              <entry>-U uams_dhx.so,uams_dhx2.so</entry>
+              <entry>uams_dhx.so uams_dhx2.so</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-nozeroconf</entry>
+              <entry>zeroconf</entry>
+              <entry>-</entry>
+              <entry>yes (if supported)</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-advertise_ssh</entry>
+              <entry>advertise ssh</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-[no]savepassword</entry>
+              <entry>save password</entry>
+              <entry>-savepassword</entry>
+              <entry>yes</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-[no]setpassword</entry>
+              <entry>set password</entry>
+              <entry>-nosetpassword</entry>
+              <entry>no</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-client_polling</entry>
+              <entry>client polling</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-hostname</entry>
+              <entry>hostname</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>use gethostname() by default</entry>
+            </row>
+            <row>
+              <entry>-loginmesg</entry>
+              <entry>login message</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)/(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-guestname</entry>
+              <entry>guest account</entry>
+              <entry>nobody</entry>
+              <entry>nobody</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-passwdfile</entry>
+              <entry>passwd file</entry>
+              <entry>afppasswd</entry>
+              <entry>afppasswd</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-passwdminlen</entry>
+              <entry>passwd minlen</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-tickleval</entry>
+              <entry>tickleval</entry>
+              <entry>30</entry>
+              <entry>30</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-timeout</entry>
+              <entry>timeout</entry>
+              <entry>4</entry>
+              <entry>4</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-sleep</entry>
+              <entry>sleep time</entry>
+              <entry>10</entry>
+              <entry>10</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-dsireadbuf</entry>
+              <entry>dsireadbuf</entry>
+              <entry>12</entry>
+              <entry>12</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-server_quantum</entry>
+              <entry>server quantum</entry>
+              <entry>303840</entry>
+              <entry>303840</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-volnamelen</entry>
+              <entry>volnamelen</entry>
+              <entry>80</entry>
+              <entry>80</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-setuplog</entry>
+              <entry>log level</entry>
+              <entry>default log_note</entry>
+              <entry>default:note</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-setuplog</entry>
+              <entry>log file</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-admingroup</entry>
+              <entry>admingroup</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-k5service</entry>
+              <entry>k5 service</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-k5realm</entry>
+              <entry>k5 realm</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-k5keytab</entry>
+              <entry>k5 keytab</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-uampath</entry>
+              <entry>uam path</entry>
+              <entry><emphasis role="bold">etc/netatalk/uams/</emphasis></entry>
+              <entry><emphasis role="bold">lib/netatalk/</emphasis></entry>
+              <entry>(G)</entry>
+              <entry>moved to $libdir</entry>
+            </row>
+            <row>
+              <entry>-ipaddr</entry>
+              <entry>afp listen</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-cnidserver</entry>
+              <entry>cnid server</entry>
+              <entry>localhost:4700</entry>
+              <entry>localhost:4700</entry>
+              <entry>(G)/(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-port</entry>
+              <entry>port</entry>
+              <entry>548</entry>
+              <entry>548</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-signature</entry>
+              <entry>signature</entry>
+              <entry>auto</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-fqdn</entry>
+              <entry>fqdn</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-unixcodepage</entry>
+              <entry>unix charset</entry>
+              <entry><emphasis role="bold">LOCALE</emphasis></entry>
+              <entry><emphasis role="bold">UTF8</emphasis></entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-maccodepage</entry>
+              <entry>mac charset</entry>
+              <entry>MAC_ROMAN</entry>
+              <entry>MAC_ROMAN</entry>
+              <entry>(G)/(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-closevol</entry>
+              <entry>close vol</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-ntdomain</entry>
+              <entry>nt domain</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-ntseparator</entry>
+              <entry>nt separator</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-dircachesize</entry>
+              <entry>dircachesize</entry>
+              <entry>8192</entry>
+              <entry>8192</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-tcpsndbuf</entry>
+              <entry>tcpsndbuf</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>OS default</entry>
+            </row>
+            <row>
+              <entry>-tcprcvbuf</entry>
+              <entry>tcprcvbuf</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>OS default</entry>
+            </row>
+            <row>
+              <entry>-fcelistener</entry>
+              <entry>fce listener</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-fcecoalesce</entry>
+              <entry>fce coalesce</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-fceevents</entry>
+              <entry>fce events</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-fceholdfmod</entry>
+              <entry>fce holdfmod</entry>
+              <entry>60</entry>
+              <entry>60</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-mimicmodel</entry>
+              <entry>mimic model</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-adminauthuser</entry>
+              <entry>admin auth user</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-noacl2maccess</entry>
+              <entry>map acls</entry>
+              <entry>-</entry>
+              <entry>yes</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>-[no]tcp</entry>
+              <entry>-</entry>
+              <entry>-tcp</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>always TCP only</entry>
+            </row>
+            <row>
+              <entry>-[no]ddp</entry>
+              <entry>-</entry>
+              <entry>-noddp</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>AppleTalk is obsoleted</entry>
+            </row>
+            <row>
+              <entry>-[no]transall</entry>
+              <entry>-</entry>
+              <entry>-tcp -noddp</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>always TCP only</entry>
+            </row>
+            <row>
+              <entry>-nodebug</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>-[no]slp</entry>
+              <entry>-</entry>
+              <entry>-noslp</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>SLP support is obsoleted</entry>
+            </row>
+            <row>
+              <entry>-[no]uservolfirst</entry>
+              <entry>-</entry>
+              <entry>-nouservolfirst</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>uservol is obsoleted</entry>
+            </row>
+            <row>
+              <entry>-[no]uservol</entry>
+              <entry>-</entry>
+              <entry>-uservol</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>uservol is obsoleted</entry>
+            </row>
+            <row>
+              <entry>-proxy</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>AppleTalk is obsoleted</entry>
+            </row>
+            <row>
+              <entry>-defaultvol</entry>
+              <entry>-</entry>
+              <entry>AppleVolumes.default</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>afp.conf only</entry>
+            </row>
+            <row>
+              <entry>-systemvol</entry>
+              <entry>-</entry>
+              <entry>AppleVolumes.system</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>afp.conf only</entry>
+            </row>
+            <row>
+              <entry>-loginmaxfail</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>not supported from the biginning</entry>
+            </row>
+            <row>
+              <entry>-unsetuplog</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>-authprintdir</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>AppleTalk is obsoleted</entry>
+            </row>
+            <row>
+              <entry>-ddpaddr</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>AppleTalk is obsoleted</entry>
+            </row>
+            <row>
+              <entry>-[no]icon</entry>
+              <entry>-</entry>
+              <entry>-noicon</entry>
+              <entry></entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>-keepsessions</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete. Use kill -HUP.</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table><table frame="all">
+        <title>from afp_ldap.conf to afp.conf</title>
+        <tgroup cols="6">
+          <colspec colname="c1" colnum="1" colwidth="1.0*"/>
+          <colspec colname="c2" colnum="2" colwidth="1.0*"/>
+          <colspec colname="c3" colnum="3" colwidth="1.0*"/>
+          <colspec colname="c4" colnum="4" colwidth="1.0*"/>
+          <colspec colname="c5" colnum="5" colwidth="1.0*"/>
+          <colspec colname="c6" colnum="6" colwidth="1.0*"/>
+          <thead>
+            <row>
+              <entry>Old afp_ldap.conf</entry>
+              <entry>New afp.conf</entry>
+              <entry>Old Default Value</entry>
+              <entry>New Defalut Value</entry>
+              <entry>Section</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>ldap_server</entry>
+              <entry>ldap server</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ldap_auth_method</entry>
+              <entry>ldap auth method</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ldap_auth_dn</entry>
+              <entry>ldap auth dn</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ldap_auth_pw</entry>
+              <entry>ldap auth pw</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ldap_userbase</entry>
+              <entry>ldap userbase</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ldap_userscope</entry>
+              <entry>ldap userscope</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ldap_groupbase</entry>
+              <entry>ldap groupbase</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ldap_groupscope</entry>
+              <entry>ldap groupscope</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ldap_uuid_attr</entry>
+              <entry>ldap uuid attr</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ldap_uuid_string</entry>
+              <entry>ldap uuid string</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ldap_name_attr</entry>
+              <entry>ldap name attr</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry> ldap_group_attr</entry>
+              <entry>ldap group attr</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(G)</entry>
+              <entry>-</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table><table frame="all">
+        <title>from AppleVolumes.* to afp.conf</title>
+        <tgroup cols="6">
+          <colspec colname="c1" colnum="1" colwidth="1.0*"/>
+          <colspec colname="c2" colnum="2" colwidth="1.0*"/>
+          <colspec colname="c3" colnum="3" colwidth="1.0*"/>
+          <colspec colname="c4" colnum="4" colwidth="1.0*"/>
+          <colspec colname="c5" colnum="5" colwidth="1.0*"/>
+          <colspec colname="c6" colnum="6" colwidth="1.0*"/>
+          <thead>
+            <row>
+              <entry>Old AppleVolumes.*</entry>
+              <entry>New afp.conf</entry>
+              <entry>Old Default Value</entry>
+              <entry>New Defalut Value</entry>
+              <entry>Section</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry>(leading-dot lines)</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>move to extmap.conf</entry>
+            </row>
+            <row>
+              <entry>:DEFAULT:</entry>
+              <entry>-</entry>
+              <entry>options:upriv,usedots</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>use "vol preset ="</entry>
+            </row>
+            <row>
+              <entry>1st field ("~")</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>use [Homes] section</entry>
+            </row>
+            <row>
+              <entry>1st field ("/path")</entry>
+              <entry>path</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>2nd field</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>use section name</entry>
+            </row>
+            <row>
+              <entry>allow:</entry>
+              <entry>valid users</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>deny:</entry>
+              <entry>invalid users</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>rwlist:</entry>
+              <entry>rwlist</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>rolist:</entry>
+              <entry>rolist</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>volcharset:</entry>
+              <entry>vol charset</entry>
+              <entry><emphasis role="bold">UTF8</emphasis></entry>
+              <entry><emphasis role="bold">(same as unix charset)</emphasis></entry>
+              <entry>(G)/(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>maccharset:</entry>
+              <entry>mac charset</entry>
+              <entry>MAC_ROMAN</entry>
+              <entry>MAC_ROMAN</entry>
+              <entry>(G)/(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>veto:</entry>
+              <entry>veto files</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>cnidscheme:</entry>
+              <entry>cnid scheme</entry>
+              <entry>dbd</entry>
+              <entry>dbd</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>casefold:</entry>
+              <entry>casefold</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>adouble:</entry>
+              <entry>appledouble</entry>
+              <entry><emphasis role="bold">v2</emphasis></entry>
+              <entry><emphasis role="bold">ea</emphasis></entry>
+              <entry>(V)</entry>
+              <entry>v1, osx and sfm are obsoleted</entry>
+            </row>
+            <row>
+              <entry>cnidserver:</entry>
+              <entry>cnid server</entry>
+              <entry>localhost:4700</entry>
+              <entry>localhost:4700</entry>
+              <entry>(G)/(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>dbpath:</entry>
+              <entry>vol dbpath</entry>
+              <entry><emphasis role="bold">(volume directory)</emphasis></entry>
+              <entry><emphasis role="bold">var/netatalk/CNID/</emphasis></entry>
+              <entry>(G)</entry>
+              <entry>moved to $localstatedir</entry>
+            </row>
+            <row>
+              <entry>umask:</entry>
+              <entry>umask</entry>
+              <entry>0000</entry>
+              <entry>0000</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>dperm:</entry>
+              <entry>directory perm</entry>
+              <entry>0000</entry>
+              <entry>0000</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>fperm:</entry>
+              <entry>file perm</entry>
+              <entry>0000</entry>
+              <entry>0000</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>password:</entry>
+              <entry>password</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>root_preexec:</entry>
+              <entry>root preexec</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>preexec:</entry>
+              <entry>preexec</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>root_postexec:</entry>
+              <entry>root postexec</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>postexec:</entry>
+              <entry>postexec</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>allowed_hosts:</entry>
+              <entry>hosts allow</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>denied_hosts:</entry>
+              <entry>hosts deny</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>ea:</entry>
+              <entry>ea</entry>
+              <entry>auto</entry>
+              <entry>auto</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>volsizelimit:</entry>
+              <entry>vol size limit</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>perm:</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>Use "directory perm" and "file perm"</entry>
+            </row>
+            <row>
+              <entry>forceuid:</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>forcegid:</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>options:ro</entry>
+              <entry>read only</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:invisibledots</entry>
+              <entry>invisible dots</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:nostat</entry>
+              <entry>stat vol</entry>
+              <entry>-</entry>
+              <entry>yes</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:preexec_close</entry>
+              <entry>preexec close</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:root_preexec_close</entry>
+              <entry>root preexec close</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:upriv</entry>
+              <entry>unix priv</entry>
+              <entry>-</entry>
+              <entry><emphasis role="bold">yes</emphasis></entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:nodev</entry>
+              <entry>cnid dev</entry>
+              <entry>-</entry>
+              <entry>yes</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:illegalseq</entry>
+              <entry>illegal seq</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:tm</entry>
+              <entry>time machine</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:searchdb</entry>
+              <entry>search db</entry>
+              <entry>-</entry>
+              <entry>no</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:nonetids</entry>
+              <entry>network ids</entry>
+              <entry>-</entry>
+              <entry>yes</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:noacls</entry>
+              <entry>acls</entry>
+              <entry>-</entry>
+              <entry>yes</entry>
+              <entry>(V)</entry>
+              <entry>-</entry>
+            </row>
+            <row>
+              <entry>options:nohex</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>auto-convert from ":2f" to ":"</entry>
+            </row>
+            <row>
+              <entry>options:usedots</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>auto-convert from ":2e" to "."</entry>
+            </row>
+            <row>
+              <entry>options:nofileid</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>options:prodos</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>options:mswindows</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>options:crlf</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>options:noadouble</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>options:limitsize</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>options:dropbox</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>options:dropkludge</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>options:nocnidcache</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+            <row>
+              <entry>options:caseinsensitive</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>-</entry>
+              <entry>obsolete</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table></para>
+  </sect1>
+
+  <sect1>
+    <title>To Do</title>
+
+    <para><itemizedlist>
+        <listitem>
+          <para>test <command>ad</command> utils with <option>appledouble =
+          ea</option></para>
+        </listitem>
+      </itemizedlist></para>
+  </sect1>
+</chapter>
diff --git a/doc/netatalk.html b/doc/netatalk.html
new file mode 100644 (file)
index 0000000..b0b7904
--- /dev/null
@@ -0,0 +1,14 @@
+<html>
+    <div id="header">
+        <div id="logo"></div>
+        <div id="menlinks">
+          <a href="/" title="Return to Netatalk home">[main]</a>
+          <a href="http://netatalk.sourceforge.net/wiki/" title="Netatalk Wiki">[wiki]</a>
+          <a href="/3.0/htmldocs" title="Netatalk Manual">[documentation]</a>
+          <a href="http://sourceforge.net/project/showfiles.php?group_id=8642" title="Download Netatalk from sourceforge">[downloads]</a>
+          <a href="/support.php" title="Support">[support]</a>
+          <a href="/links.php" title="Netatalk related links">[links]</a>
+          <img src="/gfx/end.gif" alt="" width="125" height="7" />
+        </div>
+    </div>
+</html>
diff --git a/doc/www/ReleaseNotes b/doc/www/ReleaseNotes
new file mode 100644 (file)
index 0000000..ab0441a
--- /dev/null
@@ -0,0 +1,294 @@
+Netatalk 3.0.3
+==============
+
+The Netatalk development team is proud to announce version 3.0.3 of
+the Netatalk File Sharing suite. This is the latest update to the 3.0
+release series. All users are encouraged to upgrade their systems to 3.0.3.
+
+Netatalk is a freely-available Open Source AFP fileserver.
+A *NIX/*BSD system running Netatalk is capable of serving many Macintosh
+clients simultaneously as an AppleShare file server (AFP).
+
+The suite contains:
+
+* netatalk   - the main server service controller
+* afpd       - the AFP file server daemin
+* cnid_metad - the CNID database multiplexing daemon
+* cnid_dbd   - the CNID database daemon serving CNIDs for AFP volumes
+* various supporting programs and utilities
+
+Summary of major new features and enhancements in 3.0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* New ini style configuration file afp.conf which replaces all previous
+  configuration files
+* New default AppleDouble backend using filesystem Extended Attributes,
+  conversion from AppleDouble v2 is done automatically on access
+* New service controller process "netatalk" responsible for starting and
+  restarting afpd and cnid_metad as necessary
+* AppleTalk support has been removed
+* Coherent cross-platform locking with Solaris CIFS server
+
+Please make sure to read the upgrading section in the Netatalk online
+manual before trying to upgrade your system to 3.0!
+
+  http://netatalk.sourceforge.net/3.0/htmldocs/upgrade.html
+
+License
+~~~~~~~
+
+Netatalk is a Free/Open Source Software project and is released under
+the GNU General Public License (GPLv2).  The full license text is available
+at:
+
+  http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+
+Changes in 3.0.3
+~~~~~~~~~~~~~~~~
+* UPD: afpd: Increase default DSI server quantum to 1 MB
+* UPD: bundled libevent2 is now static
+* NEW: --with-lockfile=PATH configure option for specifying an
+       alternative path for the netatalk lockfile.
+* UPD: systemd service file use PIDFile and ExecReload.
+       From FR #70.
+* UPD: RedHat sysvinit: rm graceful, reimplement reload, add condrestart
+* FIX: Couldn't create folders on FreeBSD 9.1 ZFS fileystems.
+       Fixed bug #491.
+* FIX: Fix an issue with user homes when user home directory has not the
+       same name as the username.
+       Fixes bug #497.
+* UPD: Fix PAM config install, new default installation dir is
+       $sysconfdir/pam.d/. Add configure option --with-pam-confdir
+       to specify alternative path.
+* NEW: AFP stats about active session via dbus IPC. Client side python
+       program `afpstats`. Requires dbus, dbus-glib any python-dbus.
+       configure option --dbus-sysconf-dir for specifying dbus
+       system security configuration files.
+       New option 'afpstats' (default: no) which determines whether
+       to enable the feature or not.
+* NEW: configure option --with-init-dir
+* NEW: dtrace probes, cf include/atalk/afp_dtrace.d for available
+       probes.
+* UPD: Reload groups when reloading volumes. FR #71.
+* FIX: Attempt to read read-only ._ rfork results in disconnect.
+       Fixes bug #502.
+* FIX: File's ressource fork can't be read if metadata EA is missing.
+       Fixes bug #501.
+* FIX: Conversion from adouble v2 to ea for directories.
+       Fixes bug #500.
+* FIX: Error messages when mounting read-only filesystems.
+       Fixes bug #504.
+* FIX: Permissions of ._ AppleDouble ressource fork after conversion
+       from v2 to ea.
+       Fixes bug #505.
+* UPD: Use FreeBSD sendfile() capability to send protocol header.
+       From FR #75.
+* UPD: Increase IO size when sendfile() is not used.
+       From FR #76.
+* FIX: Can't set Finder label on symlinked folder with "follow symlinks = yes".
+       Fixes bug #508.
+* FIX: Setting POSIX ACLs on Linux
+       Fixes bug #506.
+* FIX: "ad ls" segfault if requested object is not in an AFP volume.
+       Fixes bug #496.
+
+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
+       afp.conf, allowing for usage of the binary objectGUID fields from
+       Active Directory.
+* FIX: afpd: Fix a Solaris 10 SPARC sendfilev bug
+* FIX: afpd: Fix a crash on FreeBSD
+* FIX: afpd: Fixes open file handle refcounting bug which was reported as
+       being unable to play movies off a Netatalk AFP share.
+       Bug ID 3559783.
+* FIX: afpd: Fix a possible data corruption when reading from and writing
+       to the server simultaniously under load
+* FIX: Fix possible alignment violations due to bad casts
+* FIX: dbd: Fix logging
+* FIX: apple_dump: Extended Attributes AppleDouble support for *BSD
+* FIX: handling of '/' and ':' in volume name
+* UPD: Install relevant includes necessary for building programs with
+       installed headers and shared lib libatalk
+* UPD: libevent configure args to pick up installed version. Removed
+       configure arg --disable-libevent, added configure args
+       --with-libevent-header|lib.
+* UPD: gentoo initscript: merge from portage netatalk.init,v 1.1
+* REM: Remove --with-smbsharemodes configure option, it was an
+       empty stub not yet implemented
+
+Changes in 3.0
+~~~~~~~~~~~~~~
+
+* UPD: afpd: force read only mode if cnid scheme is last
+* REM: afpd: removed global option "icon"
+* FIX: CNID path for user homes
+
+Changes in 3.0 beta2
+~~~~~~~~~~~~~~~~~~~~
+
+* UPD: Solaris and friends: Replace initscript with SMF manifest
+* FIX: Solaris and friends: resource fork handling
+
+Changes in 3.0 beta1
+~~~~~~~~~~~~~~~~~~~~
+
+* UPD: afpd: Performance tuning of read/write AFP operations. New option
+       "afp read locks" (default: no) which disables that the server
+       applies UNIX byte range locks to regions of files in AFP read and
+       write calls.
+* UPD: apple_dump: Extended Attributes AppleDouble support.
+       (*BSD is not supported yet)
+
+Changes in 3.0 alpha3
+~~~~~~~~~~~~~~~~~~~~~
+
+* NEW: afpd: Per volume "login message", NetAFP bug ID #18
+* NEW: afpd: Cross-platform locking (share modes) on Solaris and derivates
+       with Solaris CIFS/SMB server. Uses new Solaris fcntl F_SHARE share
+       reservation locking primitives. Enabled by default, set global
+       "solaris share reservations" option to false to disable it.
+* NEW: ad: ad set subcommand for changing Mac metadata on the server
+* UPD: unix charset is UTF8 by default
+       vol charset is same value as unix charset by default
+* UPD: .AppleDesktop/ are stored in $localstatedir/netatalk/CNID
+       (default: /var/netatalk/CNID), databases found in AFP volumes are
+       automatically moved
+* FIX: afpd: Server info packet was malformed resulting in broken
+       server names being displayed on clients
+* FIX: afpd: Byte order detection. Fixes an error where Netatalk on
+       OpenIndiana returned wrong volume size information.
+
+Changes in 3.0 alpha2
+~~~~~~~~~~~~~~~~~~~~~
+
+* UPD: afpd: Store '.' as is and '/' as ':' on the server, don't
+       CAP hexencode as "2e" and "2f" respectively
+* UPD: afdp: Automatic name conversion, renaming files and directories
+       containing CAP sequences to their not enscaped forms
+* UPD: afpd: Correct handling of user homes and users without homes
+* UPD: afpd: Perform complete automatic adouble:v2 to adouble:ea conversion
+       as root. Previously only unlinking the adouble:v2 file was done as root
+* UPD: dbd: -C option removes CAP encoding
+* UPD: Add graceful option to RedHat init script
+* UPD: Add --disable-bundled-libevent configure options When set to yes,
+       we rely on a properly installed version on libevent CPPFLAGS and LDFLAGS
+       should be set properly to pick that up
+* UPD: Run ldconfig on Linux at the end of make install
+* FIX: afpd: ad cp on appledouble = ea volumes
+* FIX: dbd: ignore ._ appledouble files
+* REM: Volumes options "use dots" and "hex encoding"
+
+Changes in 3.0 alpha1
+~~~~~~~~~~~~~~~~~~~~~
+
+* NEW: Central configuration file afp.conf which replaces all previous files
+* NEW: netatalk: service controller starting and restarting afpd and cnid_metad
+       as necessary
+* NEW: afpd: Extended Attributes AppleDouble backend (default)
+* UPD: CNID databases are stored in $localstatedir/netatalk/CNID
+       (default: /var/netatalk/CNID), databases found in AFP volumes are
+       automatically moved
+* UPD: Start scripts and service manifests have been changed to only start
+       the new netatalk service controller process
+* UPD: afpd: UNIX privileges and use dots enabled by default
+* UPD: afpd: Support for arbitrary AFP volumes using variable expansion has been
+       removed
+* UPD: afpd: afp_voluuid.conf and afp_signature.conf location has been
+       changed to $localstatedir/netatalk/ (default: /var/netatalk/)
+* UPD: afpd: default server messages dir changed to $localstatedir/netatalk/msg/
+* UPD: dbd: new option -C for conversion from AppleDouble v2 to ea
+* REM: AppleTalk support has been removed
+* REM: afpd: SLP and AFP proxy support have been removed
+* REM: afpd: legacy file extension to type/creator mapping has been removed
+* REM: afpd: AppleDouble backends v1, osx and sfm have been removed
+
+
+Supported Platforms
+~~~~~~~~~~~~~~~~~~~
+
+As of Netatalk 3.0 the following operating systems are supported:
+
+ * FreeBSD
+ * Linux
+ * OpenBSD
+ * NetBSD
+ * Solaris and derivates
+
+Netatalk may compile and run on other operating systems as well, but
+it is not well-tested on those.  We welcome patches and suggestions
+for enhancing the portability of Netatalk as well as success and failure
+stories.  Please write to netatalk-devel@lists.sourceforge.net.
+
+Availability
+~~~~~~~~~~~~
+
+Netatalk tar-balls can be found at:
+
+http://sourceforge.net/project/showfiles.php?group_id=8642
+
+Netatalk is also available via anonymous git.  See the SourceForge project
+site for anonymous git instructions. 
+
+Contact
+~~~~~~~
+
+For more information about Netatalk, see its web page at:
+
+http://netatalk.sourceforge.net/
+
+The project is hosted at SourceForge.  The SourceForge project page is
+located at:
+
+http://sourceforge.net/projects/netatalk/
+
+The Netatalk development team can be reached via the mailing list
+netatalk-devel@lists.sourceforge.net.  For subscription information and
+archives see Netatalk's SourceForge project page.
+
+netatalk-admins@lists.sourceforge.net is a mailing list for Netatalk
+system administrators.  For subscription information and archives see
+the Netatalk web page.
+
+Acknowledgements
+~~~~~~~~~~~~~~~~
+
+We would like to thank all contributors to the Netatalk project for
+their commitment.  Without the many suggestions, bug and problem reports,
+patches, and reviews this project wouldn't be where it is.
+
+ - The Netatalk Development Team, January 2013
diff --git a/doc/www/asciidoc.conf b/doc/www/asciidoc.conf
new file mode 100644 (file)
index 0000000..85b3df4
--- /dev/null
@@ -0,0 +1,610 @@
+#
+# asciidoc.conf
+#
+# Asciidoc global configuration file.
+# Contains backend independent configuration settings that are applied to all
+# AsciiDoc documents.
+#
+
+[miscellaneous]
+tabsize=8
+textwidth=70
+newline=\r\n
+
+[attributes]
+backend-alias-html=xhtml11
+backend-alias-docbook=docbook45
+toclevels=2
+sectids=
+iconsdir=./images/icons
+encoding=UTF-8
+# Uncomment to use xhtml11 quirks mode CSS.
+#quirks=
+# Uncomment to use the Pygments source highlighter instead of GNU highlighter.
+#pygments=
+# Uncomment to use deprecated quote attributes.
+#deprecated-quotes=
+empty=
+# Attribute and AttributeList element patterns.
+attributeentry-pattern=^:(?P<attrname>\w[^.]*?)(\.(?P<attrname2>.*?))?:(\s+(?P<attrvalue>.*))?$
+attributelist-pattern=(?u)(^\[\[(?P<id>[\w_:][\w_:.-]*)(,(?P<reftext>.*?))?\]\]$)|(^\[(?P<attrlist>.*)\]$)
+# Substitution attributes for escaping AsciiDoc processing.
+amp=&
+lt=<
+gt=>
+brvbar=|
+nbsp=&#160;
+zwsp=&#8203;
+wj=&#8288;
+deg=&#176;
+backslash=\
+two-colons=::
+two-semicolons=;;
+# DEPRECATED: underscore attribute names.
+two_colons=::
+two_semicolons=;;
+# Left and right single and double quote characters.
+# See http://en.wikipedia.org/wiki/Non-English_usage_of_quotation_marks
+lsquo=&#8216;
+rsquo=&#8217;
+ldquo=&#8220;
+rdquo=&#8221;
+
+[titles]
+subs=specialcharacters,quotes,replacements,macros,attributes,replacements2
+# Double-line title pattern and underlines.
+sectiontitle=^(?P<title>.*?)$
+underlines="==","--","~~","^^","++"
+# Single-line title patterns.
+sect0=^= +(?P<title>[\S].*?)( +=)?$
+sect1=^== +(?P<title>[\S].*?)( +==)?$
+sect2=^=== +(?P<title>[\S].*?)( +===)?$
+sect3=^==== +(?P<title>[\S].*?)( +====)?$
+sect4=^===== +(?P<title>[\S].*?)( +=====)?$
+blocktitle=^\.(?P<title>([^.\s].*)|(\.[^.\s].*))$
+
+[specialcharacters]
+&=&amp;
+<=&lt;
+>=&gt;
+
+[quotes]
+# The order is important, quotes are processed in conf file order.
+**=#strong
+*=strong
+``|''=doublequoted
+'=emphasis
+`|'=singlequoted
+ifdef::no-inline-literal[]
+`=monospaced
+endif::no-inline-literal[]
+# +++ and $$ quoting is applied to the +++ and $$ inline passthrough
+# macros to allow quoted attributes to be used.
+# This trick only works with inline passthrough macros.
++++=#unquoted
+$$=#unquoted
+++=#monospaced
++=monospaced
+__=#emphasis
+_=emphasis
+\##=#unquoted
+\#=unquoted
+^=#superscript
+~=#subscript
+
+[specialwords]
+emphasizedwords=
+strongwords=
+monospacedwords=
+
+[replacements]
+# Replacements performed in order of configuration file entry.  The first entry
+# of each replacement pair performs the (non-escaped) replacement, the second
+# strips the backslash from the escaped replacement.
+
+# (C) Copyright (entity reference &copy;)
+(?<!\\)\(C\)=&#169;
+\\\(C\)=(C)
+
+# (R) registered trade mark (entity reference &reg;
+(?<!\\)\(R\)=&#174;
+\\\(R\)=(R)
+
+# (TM) Trademark (entity reference &trade;)
+(?<!\\)\(TM\)=&#8482;
+\\\(TM\)=(TM)
+
+# -- Spaced and unspaced em dashes (entity reference &mdash;).
+# Space on both sides is translated to thin space characters.
+(^-- )=&#8212;&#8201;
+(\n-- )|( -- )|( --\n)=&#8201;&#8212;&#8201;
+(\w)--(\w)=\1&#8212;\2
+\\--(?!-)=--
+
+# Replace vertical typewriter apostrophe with punctuation apostrophe.
+(\w)'(\w)=\1&#8217;\2
+(\w)\\'(\w)=\1'\2
+
+# ... Ellipsis (entity reference &hellip;)
+(?<!\\)\.\.\.=&#8230;
+\\\.\.\.=...
+
+# Arrows from the Arrows block of Unicode.
+# -> right arrow
+(?<!\\)-&gt;=&#8594;
+\\-&gt;=-&gt;
+# => right double arrow
+(?<!\\)\=&gt;=&#8658;
+\\\=&gt;==&gt;
+# <- left arrow
+(?<!\\)&lt;-=&#8592;
+\\&lt;-=&lt;-
+# <= left double arrow
+(?<!\\)&lt;\==&#8656;
+\\&lt;\==&lt;=
+
+# Arbitrary entity references.
+(?<!\\)&amp;([:_#a-zA-Z][:_.\-\w]*?;)=&\1
+\\(&amp;[:_#a-zA-Z][:_.\-\w]*?;)=\1
+
+#-----------
+# Paragraphs
+#-----------
+[paradef-default]
+delimiter=(?s)(?P<text>\S.*)
+posattrs=style
+style=normal
+template::[paragraph-styles]
+
+[paradef-literal]
+delimiter=(?s)(?P<text>\s+.*)
+options=listelement
+posattrs=style
+style=literal
+template::[paragraph-styles]
+
+[paradef-admonition]
+delimiter=(?s)^\s*(?P<style>NOTE|TIP|IMPORTANT|WARNING|CAUTION):\s+(?P<text>.+)
+template::[paragraph-styles]
+
+[paragraph-styles]
+normal-style=template="paragraph"
+verse-style=template="verseparagraph",posattrs=["style","attribution","citetitle"]
+quote-style=template="quoteparagraph",posattrs=["style","attribution","citetitle"]
+literal-style=template="literalparagraph",subs=["verbatim"]
+listing-style=template="listingparagraph",subs=["verbatim"]
+NOTE-style=template="admonitionparagraph",name="note",caption="{note-caption}"
+TIP-style=template="admonitionparagraph",name="tip",caption="{tip-caption}"
+IMPORTANT-style=template="admonitionparagraph",name="important",caption="{important-caption}"
+WARNING-style=template="admonitionparagraph",name="warning",caption="{warning-caption}"
+CAUTION-style=template="admonitionparagraph",name="caution",caption="{caution-caption}"
+
+[literalparagraph]
+template::[literalblock]
+
+[verseparagraph]
+template::[verseblock]
+
+[quoteparagraph]
+template::[quoteblock]
+
+[listingparagraph]
+template::[listingblock]
+
+[macros]
+#--------------
+# Inline macros
+#--------------
+# Backslash prefix required for escape processing.
+# (?s) re flag for line spanning.
+
+# Macros using default syntax.
+(?su)(?<!\w)[\\]?(?P<name>http|https|ftp|file|irc|mailto|callto|image|link|anchor|xref|indexterm):(?P<target>\S*?)\[(?P<attrlist>.*?)\]=
+
+# These URL types don't require any special attribute list formatting.
+(?su)(?<!\S)[\\]?(?P<name>http|https|ftp|file|irc):(?P<target>//[^\s<>]*[\w/])=
+# Allow a leading parenthesis and square bracket.
+(?su)(?<\=[([])[\\]?(?P<name>http|https|ftp|file|irc):(?P<target>//[^\s<>]*[\w/])=
+# Allow <> brackets.
+(?su)[\\]?&lt;(?P<name>http|https|ftp|file|irc):(?P<target>//[^\s<>]*[\w/])&gt;=
+
+# Email addresses don't require special attribute list formatting.
+# The before ">: and after "< character exclusions stop multiple substitution.
+(?su)(?<![">:\w._/-])[\\]?(?P<target>\w[\w._-]*@[\w._-]*\w)(?!["<\w_-])=mailto
+
+# Allow footnote macros hard up against the preceding word so the footnote mark
+# can be placed against the noted text without an intervening space
+# (http://groups.google.com/group/asciidoc/browse_frm/thread/e1dcb7ee0efc17b5).
+(?su)[\\]?(?P<name>footnote|footnoteref):(?P<target>\S*?)\[(?P<attrlist>.*?)\]=
+
+# Anchor: [[[id]]]. Bibliographic anchor.
+(?su)[\\]?\[\[\[(?P<attrlist>[\w_:][\w_:.-]*?)\]\]\]=anchor3
+# Anchor: [[id,xreflabel]]
+(?su)[\\]?\[\[(?P<attrlist>[\w"_:].*?)\]\]=anchor2
+# Link: <<id,text>>
+(?su)[\\]?&lt;&lt;(?P<attrlist>[\w"_:].*?)&gt;&gt;=xref2
+
+ifdef::asciidoc7compatible[]
+# Index term: ++primary,secondary,tertiary++
+(?su)(?<!\S)[\\]?\+\+(?P<attrlist>[^+].*?)\+\+(?!\+)=indexterm
+# Index term: +primary+
+# Follows ++...++ macro otherwise it will match them.
+(?<!\S)[\\]?\+(?P<attrlist>[^\s\+][^+].*?)\+(?!\+)=indexterm2
+endif::asciidoc7compatible[]
+
+ifndef::asciidoc7compatible[]
+# Index term: (((primary,secondary,tertiary)))
+(?su)(?<!\()[\\]?\(\(\((?P<attrlist>[^(].*?)\)\)\)(?!\))=indexterm
+# Index term: ((primary))
+# Follows (((...))) macro otherwise it will match them.
+(?<!\()[\\]?\(\((?P<attrlist>[^\s\(][^(].*?)\)\)(?!\))=indexterm2
+endif::asciidoc7compatible[]
+
+# Callout
+[\\]?&lt;(?P<index>\d+)&gt;=callout
+
+# Passthrough macros.
+(?su)[\\]?(?P<name>pass):(?P<subslist>\S*?)\[(?P<passtext>.*?)(?<!\\)\]=[]
+
+# Triple-plus and double-dollar inline passthroughs.
+(?su)[\\]?\+\+\+(?P<passtext>.*?)\+\+\+=pass[]
+(?su)[\\]?\$\$(?P<passtext>.*?)\$\$=pass[specialcharacters]
+
+# Inline literal.
+ifndef::no-inline-literal[]
+(?su)(?<![`\w])([\\]?`(?P<passtext>[^`\s]|[^`\s].*?\S)`)(?![`\w])=literal[specialcharacters]
+endif::no-inline-literal[]
+
+# Inline comment.
+(?mu)^[\\]?//(?P<passtext>[^/].*|)$=comment[specialcharacters]
+
+# Default (catchall) inline macro is not implemented so there is no ambiguity
+# with previous definition that could result in double substitution of escaped
+# references.
+#(?su)[\\]?(?P<name>\w(\w|-)*?):(?P<target>\S*?)\[(?P<passtext>.*?)(?<!\\)\]=
+
+#-------------
+# Block macros
+#-------------
+# Macros using default syntax.
+(?u)^(?P<name>image|unfloat)::(?P<target>\S*?)(\[(?P<attrlist>.*?)\])$=#
+
+# Passthrough macros.
+(?u)^(?P<name>pass)::(?P<subslist>\S*?)(\[(?P<passtext>.*?)\])$=#
+
+^'{3,}$=#ruler
+^<{3,}$=#pagebreak
+^//(?P<passtext>[^/].*|)$=#comment[specialcharacters]
+
+[unfloat-blockmacro]
+# Implemented in HTML backends.
+
+#-----------------
+# Delimited blocks
+#-----------------
+[blockdef-comment]
+delimiter=^/{4,}$
+options=skip
+
+[blockdef-sidebar]
+delimiter=^\*{4,}$
+template=sidebarblock
+options=sectionbody
+posattrs=style
+# DEPRECATED: Use Openblock instead.
+abstract-style=template="abstractblock"
+
+[blockdef-open]
+# A block without opening or closing tags.
+delimiter=^--$
+template=openblock
+options=sectionbody
+posattrs=style
+abstract-style=template="abstractblock"
+partintro-style=template="partintroblock"
+
+[blockdef-pass]
+delimiter=^\+{4,}$
+template=passblock
+# Default subs choosen for backward compatibility.
+subs=attributes,macros
+posattrs=style
+pass-style=template="passblock",subs=[]
+
+[blockdef-listing]
+delimiter=^-{4,}$
+template=listingblock
+subs=verbatim
+posattrs=style
+
+[blockdef-literal]
+delimiter=^\.{4,}$
+template=literalblock
+subs=verbatim
+posattrs=style
+listing-style=template="listingblock"
+# DEPRECATED: Use verse style on quote blocks instead.
+verse-style=template="verseblock",subs="normal"
+
+[blockdef-quote]
+delimiter=^_{4,}$
+subs=normal
+style=quote
+posattrs=style,attribution,citetitle
+quote-style=template="quoteblock",options=("sectionbody",)
+verse-style=template="verseblock"
+
+[blockdef-example]
+delimiter=^={4,}$
+template=exampleblock
+options=sectionbody
+posattrs=style
+NOTE-style=template="admonitionblock",name="note",caption="{note-caption}"
+TIP-style=template="admonitionblock",name="tip",caption="{tip-caption}"
+IMPORTANT-style=template="admonitionblock",name="important",caption="{important-caption}"
+WARNING-style=template="admonitionblock",name="warning",caption="{warning-caption}"
+CAUTION-style=template="admonitionblock",name="caution",caption="{caution-caption}"
+
+# For use by custom filters.
+# DEPRECATED: No longer used, a styled listing block (blockdef-listing) is preferable.
+[blockdef-filter]
+delimiter=^~{4,}$
+template=listingblock
+subs=none
+posattrs=style
+
+#-------
+# Lists
+#-------
+[listdef-bulleted]
+# - bullets.
+delimiter=^\s*- +(?P<text>.+)$
+posattrs=style
+type=bulleted
+tags=bulleted
+callout-style=tags="callout"
+bibliography-style=tags="bibliography"
+
+[listdef-bulleted1]
+# * bullets.
+template::[listdef-bulleted]
+delimiter=^\s*\* +(?P<text>.+)$
+
+[listdef-bulleted2]
+# ** bullets.
+template::[listdef-bulleted]
+delimiter=^\s*\*{2} +(?P<text>.+)$
+
+[listdef-bulleted3]
+# *** bullets.
+template::[listdef-bulleted]
+delimiter=^\s*\*{3} +(?P<text>.+)$
+
+[listdef-bulleted4]
+# **** bullets.
+template::[listdef-bulleted]
+delimiter=^\s*\*{4} +(?P<text>.+)$
+
+[listdef-bulleted5]
+# ***** bullets.
+template::[listdef-bulleted]
+delimiter=^\s*\*{5} +(?P<text>.+)$
+
+[listdef-arabic]
+# Arabic numbering.
+delimiter=^\s*(?P<index>\d+\.) +(?P<text>.+)$
+posattrs=style
+type=numbered
+tags=numbered
+style=arabic
+
+[listdef-loweralpha]
+# Lower alpha numbering.
+template::[listdef-arabic]
+delimiter=^\s*(?P<index>[a-z]\.) +(?P<text>.+)$
+style=loweralpha
+
+[listdef-upperalpha]
+# Upper alpha numbering.
+template::[listdef-arabic]
+delimiter=^\s*(?P<index>[A-Z]\.) +(?P<text>.+)$
+style=upperalpha
+
+[listdef-lowerroman]
+# Lower roman numbering.
+template::[listdef-arabic]
+delimiter=^\s*(?P<index>[ivx]+\)) +(?P<text>.+)$
+style=lowerroman
+
+[listdef-upperroman]
+# Upper roman numbering.
+template::[listdef-arabic]
+delimiter=^\s*(?P<index>[IVX]+\)) +(?P<text>.+)$
+style=upperroman
+
+[listdef-numbered1]
+# . numbering.
+template::[listdef-arabic]
+delimiter=^\s*\. +(?P<text>.+)$
+
+[listdef-numbered2]
+# .. numbering.
+template::[listdef-loweralpha]
+delimiter=^\s*\.{2} +(?P<text>.+)$
+
+[listdef-numbered3]
+# ... numbering.
+template::[listdef-lowerroman]
+delimiter=^\s*\.{3} +(?P<text>.+)$
+
+[listdef-numbered4]
+# .... numbering.
+template::[listdef-upperalpha]
+delimiter=^\s*\.{4} +(?P<text>.+)$
+
+[listdef-numbered5]
+# ..... numbering.
+template::[listdef-upperroman]
+delimiter=^\s*\.{5} +(?P<text>.+)$
+
+[listdef-labeled]
+# label:: item.
+delimiter=^\s*(?P<label>.*[^:])::(\s+(?P<text>.+))?$
+posattrs=style
+type=labeled
+tags=labeled
+vertical-style=tags="labeled"
+horizontal-style=tags="horizontal"
+glossary-style=tags="glossary"
+qanda-style=tags="qanda"
+
+[listdef-labeled2]
+# label;; item.
+template::[listdef-labeled]
+delimiter=^\s*(?P<label>.*[^;]);;(\s+(?P<text>.+))?$
+
+[listdef-labeled3]
+# label::: item.
+template::[listdef-labeled]
+delimiter=^\s*(?P<label>.*[^:]):{3}(\s+(?P<text>.+))?$
+
+[listdef-labeled4]
+# label:::: item.
+template::[listdef-labeled]
+delimiter=^\s*(?P<label>.*[^:]):{4}(\s+(?P<text>.+))?$
+
+[listdef-callout]
+posattrs=style
+delimiter=^<?(?P<index>\d*>) +(?P<text>.+)$
+type=callout
+tags=callout
+style=arabic
+
+# DEPRECATED: Old list syntax.
+[listdef-qanda]
+posattrs=style
+delimiter=^\s*(?P<label>.*\S)\?\?$
+type=labeled
+tags=qanda
+
+# DEPRECATED: Old list syntax.
+[listdef-bibliography]
+posattrs=style
+delimiter=^\+ +(?P<text>.+)$
+type=bulleted
+tags=bibliography
+
+# DEPRECATED: Old list syntax.
+[listdef-glossary]
+delimiter=^(?P<label>.*\S):-$
+posattrs=style
+type=labeled
+tags=glossary
+
+#-------
+# Tables
+#-------
+[tabledef-default]
+delimiter=^\|={3,}$
+posattrs=style
+template=table
+default-style=tags="default"
+verse-style=tags="verse"
+literal-style=tags="literal",subs=["specialcharacters"]
+emphasis-style=tags="emphasis"
+strong-style=tags="strong"
+monospaced-style=tags="monospaced"
+header-style=tags="header"
+asciidoc-style=tags="asciidoc",subs=[],filter='python "{asciidoc-file}" -b {backend} {asciidoc-args}{lang? -a "lang={lang}@"}{icons? -a icons -a "iconsdir={iconsdir}"}{imagesdir? -a "imagesdir={imagesdir}"}{data-uri? -a data-uri} -a "indir={indir}"{trace? -a "trace={trace}"} -s -'
+
+[tabledef-nested]
+# Same as [tabledef-default] but with different delimiter and separator.
+delimiter=^!={3,}$
+separator=((?<!\S)((?P<span>[\d.]+)(?P<op>[*+]))?(?P<align>[<\^>.]{,3})?(?P<style>[a-z])?)?!
+posattrs=style
+template=table
+verse-style=tags="verse"
+literal-style=tags="literal",subs=["specialcharacters"]
+emphasis-style=tags="emphasis"
+strong-style=tags="strong"
+monospaced-style=tags="monospaced"
+header-style=tags="header"
+asciidoc-style=tags="asciidoc",subs=[],filter='python "{asciidoc-file}" -b {backend} {asciidoc-args}{lang? -a "lang={lang}@"} -s -'
+
+#----------------------------------------
+# Common block and macro markup templates
+#----------------------------------------
+[comment-inlinemacro]
+# Outputs nothing.
+
+[comment-blockmacro]
+# Outputs nothing.
+
+[pass-blockmacro]
+{passtext}
+
+[pass-inlinemacro]
+template::[pass-blockmacro]
+
+[passblock]
+|
+
+[filter-image-blockmacro]
+# Synthesize missing target attribute for filter generated file names.
+# The tag split | ensures missing target file names are auto-generated
+# before the filter is executed, the remainder (the [image-blockmacro])
+# is excuted after the filter to ensure data URI encoding comes after
+# the image is created.
+{target%}{counter2:target-number}
+{target%}{set2:target:{docname}__{target-number}.png}
+|
+template::[image-blockmacro]
+
+#----------------------------------
+# Default special section templates
+#----------------------------------
+[abstract]
+template::[sect1]
+
+[colophon]
+template::[sect1]
+
+[dedication]
+template::[sect1]
+
+[preface]
+template::[sect1]
+
+[appendix]
+template::[sect1]
+
+[glossary]
+template::[sect1]
+
+[bibliography]
+template::[sect1]
+
+[index]
+template::[sect1]
+
+[synopsis]
+template::[sect1]
+
+#--------------------------------------------------------------------
+# Deprecated old table definitions.
+#
+
+[old_tabledef-default]
+fillchar=-
+format=fixed
+
+[old_tabledef-csv]
+fillchar=~
+format=csv
+
+[old_tabledef-dsv]
+fillchar=_
+format=dsv
+
+# End of deprecated old table definitions.
+#--------------------------------------------------------------------
diff --git a/doc/www/asciidoc.py b/doc/www/asciidoc.py
new file mode 100755 (executable)
index 0000000..7846de3
--- /dev/null
@@ -0,0 +1,5902 @@
+#!/usr/bin/env python
+"""
+asciidoc - converts an AsciiDoc text file to HTML or DocBook
+
+Copyright (C) 2002-2010 Stuart Rackham. Free use of this software is granted
+under the terms of the GNU General Public License (GPL).
+"""
+
+import sys, os, re, time, traceback, tempfile, subprocess, codecs, locale, unicodedata
+
+### Used by asciidocapi.py ###
+VERSION = '8.6.5'           # See CHANGLOG file for version history.
+
+MIN_PYTHON_VERSION = 2.4    # Require this version of Python or better.
+
+#---------------------------------------------------------------------------
+# Program constants.
+#---------------------------------------------------------------------------
+DEFAULT_BACKEND = 'html'
+DEFAULT_DOCTYPE = 'article'
+# Allowed substitution options for List, Paragraph and DelimitedBlock
+# definition subs entry.
+SUBS_OPTIONS = ('specialcharacters','quotes','specialwords',
+    'replacements', 'attributes','macros','callouts','normal','verbatim',
+    'none','replacements2')
+# Default value for unspecified subs and presubs configuration file entries.
+SUBS_NORMAL = ('specialcharacters','quotes','attributes',
+    'specialwords','replacements','macros','replacements2')
+SUBS_VERBATIM = ('specialcharacters','callouts')
+
+NAME_RE = r'(?u)[^\W\d][-\w]*'  # Valid section or attribute name.
+OR, AND = ',', '+'              # Attribute list separators.
+
+
+#---------------------------------------------------------------------------
+# Utility functions and classes.
+#---------------------------------------------------------------------------
+
+class EAsciiDoc(Exception): pass
+
+class OrderedDict(dict):
+    """
+    Dictionary ordered by insertion order.
+    Python Cookbook: Ordered Dictionary, Submitter: David Benjamin.
+    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747
+    """
+    def __init__(self, d=None, **kwargs):
+        self._keys = []
+        if d is None: d = kwargs
+        dict.__init__(self, d)
+    def __delitem__(self, key):
+        dict.__delitem__(self, key)
+        self._keys.remove(key)
+    def __setitem__(self, key, item):
+        dict.__setitem__(self, key, item)
+        if key not in self._keys: self._keys.append(key)
+    def clear(self):
+        dict.clear(self)
+        self._keys = []
+    def copy(self):
+        d = dict.copy(self)
+        d._keys = self._keys[:]
+        return d
+    def items(self):
+        return zip(self._keys, self.values())
+    def keys(self):
+        return self._keys
+    def popitem(self):
+        try:
+            key = self._keys[-1]
+        except IndexError:
+            raise KeyError('dictionary is empty')
+        val = self[key]
+        del self[key]
+        return (key, val)
+    def setdefault(self, key, failobj = None):
+        dict.setdefault(self, key, failobj)
+        if key not in self._keys: self._keys.append(key)
+    def update(self, d=None, **kwargs):
+        if d is None:
+            d = kwargs
+        dict.update(self, d)
+        for key in d.keys():
+            if key not in self._keys: self._keys.append(key)
+    def values(self):
+        return map(self.get, self._keys)
+
+class AttrDict(dict):
+    """
+    Like a dictionary except values can be accessed as attributes i.e. obj.foo
+    can be used in addition to obj['foo'].
+    If an item is not present None is returned.
+    """
+    def __getattr__(self, key):
+        try: return self[key]
+        except KeyError: return None
+    def __setattr__(self, key, value):
+        self[key] = value
+    def __delattr__(self, key):
+        try: del self[key]
+        except KeyError, k: raise AttributeError, k
+    def __repr__(self):
+        return '<AttrDict ' + dict.__repr__(self) + '>'
+    def __getstate__(self):
+        return dict(self)
+    def __setstate__(self,value):
+        for k,v in value.items(): self[k]=v
+
+class InsensitiveDict(dict):
+    """
+    Like a dictionary except key access is case insensitive.
+    Keys are stored in lower case.
+    """
+    def __getitem__(self, key):
+        return dict.__getitem__(self, key.lower())
+    def __setitem__(self, key, value):
+        dict.__setitem__(self, key.lower(), value)
+    def has_key(self, key):
+        return dict.has_key(self,key.lower())
+    def get(self, key, default=None):
+        return dict.get(self, key.lower(), default)
+    def update(self, dict):
+        for k,v in dict.items():
+            self[k] = v
+    def setdefault(self, key, default = None):
+        return dict.setdefault(self, key.lower(), default)
+
+
+class Trace(object):
+    """
+    Used in conjunction with the 'trace' attribute to generate diagnostic
+    output. There is a single global instance of this class named trace.
+    """
+    SUBS_NAMES = ('specialcharacters','quotes','specialwords',
+                  'replacements', 'attributes','macros','callouts',
+                  'replacements2')
+    def __init__(self):
+        self.name_re = ''        # Regexp pattern to match trace names.
+        self.linenos = True
+        self.offset = 0
+    def __call__(self, name, before, after=None):
+        """
+        Print trace message if tracing is on and the trace 'name' matches the
+        document 'trace' attribute (treated as a regexp).
+        'before' is the source text before substitution; 'after' text is the
+        source text after substitutuion.
+        The 'before' and 'after' messages are only printed if they differ.
+        """
+        name_re = document.attributes.get('trace')
+        if name_re == 'subs':    # Alias for all the inline substitutions.
+            name_re = '|'.join(self.SUBS_NAMES)
+        self.name_re = name_re
+        if self.name_re is not None:
+            msg = message.format(name, 'TRACE: ', self.linenos, offset=self.offset)
+            if before != after and re.match(self.name_re,name):
+                if is_array(before):
+                    before = '\n'.join(before)
+                if after is None:
+                    msg += '\n%s\n' % before
+                else:
+                    if is_array(after):
+                        after = '\n'.join(after)
+                    msg += '\n<<<\n%s\n>>>\n%s\n' % (before,after)
+                message.stderr(msg)
+
+class Message:
+    """
+    Message functions.
+    """
+    PROG = os.path.basename(os.path.splitext(__file__)[0])
+
+    def __init__(self):
+        # Set to True or False to globally override line numbers method
+        # argument. Has no effect when set to None.
+        self.linenos = None
+        self.messages = []
+
+    def stdout(self,msg):
+        print msg
+
+    def stderr(self,msg=''):
+        self.messages.append(msg)
+        if __name__ == '__main__':
+            sys.stderr.write('%s: %s%s' % (self.PROG, msg, os.linesep))
+
+    def verbose(self, msg,linenos=True):
+        if config.verbose:
+            msg = self.format(msg,linenos=linenos)
+            self.stderr(msg)
+
+    def warning(self, msg,linenos=True,offset=0):
+        msg = self.format(msg,'WARNING: ',linenos,offset=offset)
+        document.has_warnings = True
+        self.stderr(msg)
+
+    def deprecated(self, msg, linenos=True):
+        msg = self.format(msg, 'DEPRECATED: ', linenos)
+        self.stderr(msg)
+
+    def format(self, msg, prefix='', linenos=True, cursor=None, offset=0):
+        """Return formatted message string."""
+        if self.linenos is not False and ((linenos or self.linenos) and reader.cursor):
+            if cursor is None:
+                cursor = reader.cursor
+            prefix += '%s: line %d: ' % (os.path.basename(cursor[0]),cursor[1]+offset)
+        return prefix + msg
+
+    def error(self, msg, cursor=None, halt=False):
+        """
+        Report fatal error.
+        If halt=True raise EAsciiDoc exception.
+        If halt=False don't exit application, continue in the hope of reporting
+        all fatal errors finishing with a non-zero exit code.
+        """
+        if halt:
+            raise EAsciiDoc, self.format(msg,linenos=False,cursor=cursor)
+        else:
+            msg = self.format(msg,'ERROR: ',cursor=cursor)
+            self.stderr(msg)
+            document.has_errors = True
+
+    def unsafe(self, msg):
+        self.error('unsafe: '+msg)
+
+
+def userdir():
+    """
+    Return user's home directory or None if it is not defined.
+    """
+    result = os.path.expanduser('~')
+    if result == '~':
+        result = None
+    return result
+
+def localapp():
+    """
+    Return True if we are not executing the system wide version
+    i.e. the configuration is in the executable's directory.
+    """
+    return os.path.isfile(os.path.join(APP_DIR, 'asciidoc.conf'))
+
+def file_in(fname, directory):
+    """Return True if file fname resides inside directory."""
+    assert os.path.isfile(fname)
+    # Empty directory (not to be confused with None) is the current directory.
+    if directory == '':
+        directory = os.getcwd()
+    else:
+        assert os.path.isdir(directory)
+        directory = os.path.realpath(directory)
+    fname = os.path.realpath(fname)
+    return os.path.commonprefix((directory, fname)) == directory
+
+def safe():
+    return document.safe
+
+def is_safe_file(fname, directory=None):
+    # A safe file must reside in directory directory (defaults to the source
+    # file directory).
+    if directory is None:
+        if document.infile == '<stdin>':
+           return not safe()
+        directory = os.path.dirname(document.infile)
+    elif directory == '':
+        directory = '.'
+    return (
+        not safe()
+        or file_in(fname, directory)
+        or file_in(fname, APP_DIR)
+        or file_in(fname, CONF_DIR)
+    )
+
+def safe_filename(fname, parentdir):
+    """
+    Return file name which must reside in the parent file directory.
+    Return None if file is not found or not safe.
+    """
+    if not os.path.isabs(fname):
+        # Include files are relative to parent document
+        # directory.
+        fname = os.path.normpath(os.path.join(parentdir,fname))
+    if not os.path.isfile(fname):
+        message.warning('include file not found: %s' % fname)
+        return None
+    if not is_safe_file(fname, parentdir):
+        message.unsafe('include file: %s' % fname)
+        return None
+    return fname
+
+def assign(dst,src):
+    """Assign all attributes from 'src' object to 'dst' object."""
+    for a,v in src.__dict__.items():
+        setattr(dst,a,v)
+
+def strip_quotes(s):
+    """Trim white space and, if necessary, quote characters from s."""
+    s = s.strip()
+    # Strip quotation mark characters from quoted strings.
+    if len(s) >= 3 and s[0] == '"' and s[-1] == '"':
+        s = s[1:-1]
+    return s
+
+def is_re(s):
+    """Return True if s is a valid regular expression else return False."""
+    try: re.compile(s)
+    except: return False
+    else: return True
+
+def re_join(relist):
+    """Join list of regular expressions re1,re2,... to single regular
+    expression (re1)|(re2)|..."""
+    if len(relist) == 0:
+        return None
+    result = []
+    # Delete named groups to avoid ambiguity.
+    for s in relist:
+        result.append(re.sub(r'\?P<\S+?>','',s))
+    result = ')|('.join(result)
+    result = '('+result+')'
+    return result
+
+def validate(value,rule,errmsg):
+    """Validate value against rule expression. Throw EAsciiDoc exception with
+    errmsg if validation fails."""
+    try:
+        if not eval(rule.replace('$',str(value))):
+            raise EAsciiDoc,errmsg
+    except Exception:
+        raise EAsciiDoc,errmsg
+    return value
+
+def lstrip_list(s):
+    """
+    Return list with empty items from start of list removed.
+    """
+    for i in range(len(s)):
+        if s[i]: break
+    else:
+        return []
+    return s[i:]
+
+def rstrip_list(s):
+    """
+    Return list with empty items from end of list removed.
+    """
+    for i in range(len(s)-1,-1,-1):
+        if s[i]: break
+    else:
+        return []
+    return s[:i+1]
+
+def strip_list(s):
+    """
+    Return list with empty items from start and end of list removed.
+    """
+    s = lstrip_list(s)
+    s = rstrip_list(s)
+    return s
+
+def is_array(obj):
+    """
+    Return True if object is list or tuple type.
+    """
+    return isinstance(obj,list) or isinstance(obj,tuple)
+
+def dovetail(lines1, lines2):
+    """
+    Append list or tuple of strings 'lines2' to list 'lines1'.  Join the last
+    non-blank item in 'lines1' with the first non-blank item in 'lines2' into a
+    single string.
+    """
+    assert is_array(lines1)
+    assert is_array(lines2)
+    lines1 = strip_list(lines1)
+    lines2 = strip_list(lines2)
+    if not lines1 or not lines2:
+        return list(lines1) + list(lines2)
+    result = list(lines1[:-1])
+    result.append(lines1[-1] + lines2[0])
+    result += list(lines2[1:])
+    return result
+
+def dovetail_tags(stag,content,etag):
+    """Merge the end tag with the first content line and the last
+    content line with the end tag. This ensures verbatim elements don't
+    include extraneous opening and closing line breaks."""
+    return dovetail(dovetail(stag,content), etag)
+
+def parse_attributes(attrs,dict):
+    """Update a dictionary with name/value attributes from the attrs string.
+    The attrs string is a comma separated list of values and keyword name=value
+    pairs. Values must preceed keywords and are named '1','2'... The entire
+    attributes list is named '0'. If keywords are specified string values must
+    be quoted. Examples:
+
+    attrs: ''
+    dict: {}
+
+    attrs: 'hello,world'
+    dict: {'2': 'world', '0': 'hello,world', '1': 'hello'}
+
+    attrs: '"hello", planet="earth"'
+    dict: {'planet': 'earth', '0': '"hello",planet="earth"', '1': 'hello'}
+    """
+    def f(*args,**keywords):
+        # Name and add aguments '1','2'... to keywords.
+        for i in range(len(args)):
+            if not str(i+1) in keywords:
+                keywords[str(i+1)] = args[i]
+        return keywords
+
+    if not attrs:
+        return
+    dict['0'] = attrs
+    # Replace line separators with spaces so line spanning works.
+    s = re.sub(r'\s', ' ', attrs)
+    try:
+        d = eval('f('+s+')')
+        # Attributes must evaluate to strings, numbers or None.
+        for v in d.values():
+            if not (isinstance(v,str) or isinstance(v,int) or isinstance(v,float) or v is None):
+                raise Exception
+    except Exception:
+        s = s.replace('"','\\"')
+        s = s.split(',')
+        s = map(lambda x: '"' + x.strip() + '"', s)
+        s = ','.join(s)
+        try:
+            d = eval('f('+s+')')
+        except Exception:
+            return  # If there's a syntax error leave with {0}=attrs.
+        for k in d.keys():  # Drop any empty positional arguments.
+            if d[k] == '': del d[k]
+    dict.update(d)
+    assert len(d) > 0
+
+def parse_named_attributes(s,attrs):
+    """Update a attrs dictionary with name="value" attributes from the s string.
+    Returns False if invalid syntax.
+    Example:
+    attrs: 'star="sun",planet="earth"'
+    dict: {'planet':'earth', 'star':'sun'}
+    """
+    def f(**keywords): return keywords
+
+    try:
+        d = eval('f('+s+')')
+        attrs.update(d)
+        return True
+    except Exception:
+        return False
+
+def parse_list(s):
+    """Parse comma separated string of Python literals. Return a tuple of of
+    parsed values."""
+    try:
+        result = eval('tuple(['+s+'])')
+    except Exception:
+        raise EAsciiDoc,'malformed list: '+s
+    return result
+
+def parse_options(options,allowed,errmsg):
+    """Parse comma separated string of unquoted option names and return as a
+    tuple of valid options. 'allowed' is a list of allowed option values.
+    If allowed=() then all legitimate names are allowed.
+    'errmsg' is an error message prefix if an illegal option error is thrown."""
+    result = []
+    if options:
+        for s in re.split(r'\s*,\s*',options):
+            if (allowed and s not in allowed) or not is_name(s):
+                raise EAsciiDoc,'%s: %s' % (errmsg,s)
+            result.append(s)
+    return tuple(result)
+
+def symbolize(s):
+    """Drop non-symbol characters and convert to lowercase."""
+    return re.sub(r'(?u)[^\w\-_]', '', s).lower()
+
+def is_name(s):
+    """Return True if s is valid attribute, macro or tag name
+    (starts with alpha containing alphanumeric and dashes only)."""
+    return re.match(r'^'+NAME_RE+r'$',s) is not None
+
+def subs_quotes(text):
+    """Quoted text is marked up and the resulting text is
+    returned."""
+    keys = config.quotes.keys()
+    for q in keys:
+        i = q.find('|')
+        if i != -1 and q != '|' and q != '||':
+            lq = q[:i]      # Left quote.
+            rq = q[i+1:]    # Right quote.
+        else:
+            lq = rq = q
+        tag = config.quotes[q]
+        if not tag: continue
+        # Unconstrained quotes prefix the tag name with a hash.
+        if tag[0] == '#':
+            tag = tag[1:]
+            # Unconstrained quotes can appear anywhere.
+            reo = re.compile(r'(?msu)(^|.)(\[(?P<attrlist>[^[\]]+?)\])?' \
+                    + r'(?:' + re.escape(lq) + r')' \
+                    + r'(?P<content>.+?)(?:'+re.escape(rq)+r')')
+        else:
+            # The text within constrained quotes must be bounded by white space.
+            # Non-word (\W) characters are allowed at boundaries to accomodate
+            # enveloping quotes and punctuation e.g. a='x', ('x'), 'x', ['x'].
+            reo = re.compile(r'(?msu)(^|[^\w;:}])(\[(?P<attrlist>[^[\]]+?)\])?' \
+                + r'(?:' + re.escape(lq) + r')' \
+                + r'(?P<content>\S|\S.*?\S)(?:'+re.escape(rq)+r')(?=\W|$)')
+        pos = 0
+        while True:
+            mo = reo.search(text,pos)
+            if not mo: break
+            if text[mo.start()] == '\\':
+                # Delete leading backslash.
+                text = text[:mo.start()] + text[mo.start()+1:]
+                # Skip past start of match.
+                pos = mo.start() + 1
+            else:
+                attrlist = {}
+                parse_attributes(mo.group('attrlist'), attrlist)
+                stag,etag = config.tag(tag, attrlist)
+                s = mo.group(1) + stag + mo.group('content') + etag
+                text = text[:mo.start()] + s + text[mo.end():]
+                pos = mo.start() + len(s)
+    return text
+
+def subs_tag(tag,dict={}):
+    """Perform attribute substitution and split tag string returning start, end
+    tag tuple (c.f. Config.tag())."""
+    if not tag:
+        return [None,None]
+    s = subs_attrs(tag,dict)
+    if not s:
+        message.warning('tag \'%s\' dropped: contains undefined attribute' % tag)
+        return [None,None]
+    result = s.split('|')
+    if len(result) == 1:
+        return result+[None]
+    elif len(result) == 2:
+        return result
+    else:
+        raise EAsciiDoc,'malformed tag: %s' % tag
+
+def parse_entry(entry, dict=None, unquote=False, unique_values=False,
+        allow_name_only=False, escape_delimiter=True):
+    """Parse name=value entry to dictionary 'dict'. Return tuple (name,value)
+    or None if illegal entry.
+    If name= then value is set to ''.
+    If name and allow_name_only=True then value is set to ''.
+    If name! and allow_name_only=True then value is set to None.
+    Leading and trailing white space is striped from 'name' and 'value'.
+    'name' can contain any printable characters.
+    If the '=' delimiter character is allowed in  the 'name' then
+    it must be escaped with a backslash and escape_delimiter must be True.
+    If 'unquote' is True leading and trailing double-quotes are stripped from
+    'name' and 'value'.
+    If unique_values' is True then dictionary entries with the same value are
+    removed before the parsed entry is added."""
+    if escape_delimiter:
+        mo = re.search(r'(?:[^\\](=))',entry)
+    else:
+        mo = re.search(r'(=)',entry)
+    if mo:  # name=value entry.
+        if mo.group(1):
+            name = entry[:mo.start(1)]
+            if escape_delimiter:
+                name = name.replace(r'\=','=')  # Unescape \= in name.
+            value = entry[mo.end(1):]
+    elif allow_name_only and entry:         # name or name! entry.
+        name = entry
+        if name[-1] == '!':
+            name = name[:-1]
+            value = None
+        else:
+            value = ''
+    else:
+        return None
+    if unquote:
+        name = strip_quotes(name)
+        if value is not None:
+            value = strip_quotes(value)
+    else:
+        name = name.strip()
+        if value is not None:
+            value = value.strip()
+    if not name:
+        return None
+    if dict is not None:
+        if unique_values:
+            for k,v in dict.items():
+                if v == value: del dict[k]
+        dict[name] = value
+    return name,value
+
+def parse_entries(entries, dict, unquote=False, unique_values=False,
+        allow_name_only=False,escape_delimiter=True):
+    """Parse name=value entries from  from lines of text in 'entries' into
+    dictionary 'dict'. Blank lines are skipped."""
+    entries = config.expand_templates(entries)
+    for entry in entries:
+        if entry and not parse_entry(entry, dict, unquote, unique_values,
+                allow_name_only, escape_delimiter):
+            raise EAsciiDoc,'malformed section entry: %s' % entry
+
+def dump_section(name,dict,f=sys.stdout):
+    """Write parameters in 'dict' as in configuration file section format with
+    section 'name'."""
+    f.write('[%s]%s' % (name,writer.newline))
+    for k,v in dict.items():
+        k = str(k)
+        k = k.replace('=',r'\=')    # Escape = in name.
+        # Quote if necessary.
+        if len(k) != len(k.strip()):
+            k = '"'+k+'"'
+        if v and len(v) != len(v.strip()):
+            v = '"'+v+'"'
+        if v is None:
+            # Don't dump undefined attributes.
+            continue
+        else:
+            s = k+'='+v
+        if s[0] == '#':
+            s = '\\' + s    # Escape so not treated as comment lines.
+        f.write('%s%s' % (s,writer.newline))
+    f.write(writer.newline)
+
+def update_attrs(attrs,dict):
+    """Update 'attrs' dictionary with parsed attributes in dictionary 'dict'."""
+    for k,v in dict.items():
+        if not is_name(k):
+            raise EAsciiDoc,'illegal attribute name: %s' % k
+        attrs[k] = v
+
+def is_attr_defined(attrs,dic):
+    """
+    Check if the sequence of attributes is defined in dictionary 'dic'.
+    Valid 'attrs' sequence syntax:
+    <attr> Return True if single attrbiute is defined.
+    <attr1>,<attr2>,... Return True if one or more attributes are defined.
+    <attr1>+<attr2>+... Return True if all the attributes are defined.
+    """
+    if OR in attrs:
+        for a in attrs.split(OR):
+            if dic.get(a.strip()) is not None:
+                return True
+        else: return False
+    elif AND in attrs:
+        for a in attrs.split(AND):
+            if dic.get(a.strip()) is None:
+                return False
+        else: return True
+    else:
+        return dic.get(attrs.strip()) is not None
+
+def filter_lines(filter_cmd, lines, attrs={}):
+    """
+    Run 'lines' through the 'filter_cmd' shell command and return the result.
+    The 'attrs' dictionary contains additional filter attributes.
+    """
+    def findfilter(name,dir,filter):
+        """Find filter file 'fname' with style name 'name' in directory
+        'dir'. Return found file path or None if not found."""
+        if name:
+            result = os.path.join(dir,'filters',name,filter)
+            if os.path.isfile(result):
+                return result
+        result = os.path.join(dir,'filters',filter)
+        if os.path.isfile(result):
+            return result
+        return None
+
+    # Return input lines if there's not filter.
+    if not filter_cmd or not filter_cmd.strip():
+        return lines
+    # Perform attributes substitution on the filter command.
+    s = subs_attrs(filter_cmd, attrs)
+    if not s:
+        message.error('undefined filter attribute in command: %s' % filter_cmd)
+        return []
+    filter_cmd = s.strip()
+    # Parse for quoted and unquoted command and command tail.
+    # Double quoted.
+    mo = re.match(r'^"(?P<cmd>[^"]+)"(?P<tail>.*)$', filter_cmd)
+    if not mo:
+        # Single quoted.
+        mo = re.match(r"^'(?P<cmd>[^']+)'(?P<tail>.*)$", filter_cmd)
+        if not mo:
+            # Unquoted catch all.
+            mo = re.match(r'^(?P<cmd>\S+)(?P<tail>.*)$', filter_cmd)
+    cmd = mo.group('cmd').strip()
+    found = None
+    if not os.path.dirname(cmd):
+        # Filter command has no directory path so search filter directories.
+        filtername = attrs.get('style')
+        d = document.attributes.get('docdir')
+        if d:
+            found = findfilter(filtername, d, cmd)
+        if not found:
+            if USER_DIR:
+                found = findfilter(filtername, USER_DIR, cmd)
+            if not found:
+                if localapp():
+                    found = findfilter(filtername, APP_DIR, cmd)
+                else:
+                    found = findfilter(filtername, CONF_DIR, cmd)
+    else:
+        if os.path.isfile(cmd):
+            found = cmd
+        else:
+            message.warning('filter not found: %s' % cmd)
+    if found:
+        filter_cmd = '"' + found + '"' + mo.group('tail')
+    if sys.platform == 'win32':
+        # Windows doesn't like running scripts directly so explicitly
+        # specify interpreter.
+        if found:
+            if cmd.endswith('.py'):
+                filter_cmd = 'python ' + filter_cmd
+            elif cmd.endswith('.rb'):
+                filter_cmd = 'ruby ' + filter_cmd
+    message.verbose('filtering: ' + filter_cmd)
+    try:
+        p = subprocess.Popen(filter_cmd, shell=True,
+                stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+        output = p.communicate(os.linesep.join(lines))[0]
+    except Exception:
+        raise EAsciiDoc,'filter error: %s: %s' % (filter_cmd, sys.exc_info()[1])
+    if output:
+        result = [s.rstrip() for s in output.split(os.linesep)]
+    else:
+        result = []
+    filter_status = p.wait()
+    if filter_status:
+        message.warning('filter non-zero exit code: %s: returned %d' %
+               (filter_cmd, filter_status))
+    if lines and not result:
+        message.warning('no output from filter: %s' % filter_cmd)
+    return result
+
+def system(name, args, is_macro=False, attrs=None):
+    """
+    Evaluate a system attribute ({name:args}) or system block macro
+    (name::[args]).
+    If is_macro is True then we are processing a system block macro otherwise
+    it's a system attribute.
+    The attrs dictionary is updated by the counter and set system attributes.
+    NOTE: The include1 attribute is used internally by the include1::[] macro
+    and is not for public use.
+    """
+    if is_macro:
+        syntax = '%s::[%s]' % (name,args)
+        separator = '\n'
+    else:
+        syntax = '{%s:%s}' % (name,args)
+        separator = writer.newline
+    if name not in ('eval','eval3','sys','sys2','sys3','include','include1','counter','counter2','set','set2','template'):
+        if is_macro:
+            msg = 'illegal system macro name: %s' % name
+        else:
+            msg = 'illegal system attribute name: %s' % name
+        message.warning(msg)
+        return None
+    if is_macro:
+        s = subs_attrs(args)
+        if s is None:
+            message.warning('skipped %s: undefined attribute in: %s' % (name,args))
+            return None
+        args = s
+    if name != 'include1':
+        message.verbose('evaluating: %s' % syntax)
+    if safe() and name not in ('include','include1'):
+        message.unsafe(syntax)
+        return None
+    result = None
+    if name in ('eval','eval3'):
+        try:
+            result = eval(args)
+            if result is True:
+                result = ''
+            elif result is False:
+                result = None
+            elif result is not None:
+                result = str(result)
+        except Exception:
+            message.warning('%s: evaluation error' % syntax)
+    elif name in ('sys','sys2','sys3'):
+        result = ''
+        fd,tmp = tempfile.mkstemp()
+        os.close(fd)
+        try:
+            cmd = args
+            cmd = cmd + (' > %s' % tmp)
+            if name == 'sys2':
+                cmd = cmd + ' 2>&1'
+            if os.system(cmd):
+                message.warning('%s: non-zero exit status' % syntax)
+            try:
+                if os.path.isfile(tmp):
+                    lines = [s.rstrip() for s in open(tmp)]
+                else:
+                    lines = []
+            except Exception:
+                raise EAsciiDoc,'%s: temp file read error' % syntax
+            result = separator.join(lines)
+        finally:
+            if os.path.isfile(tmp):
+                os.remove(tmp)
+    elif name in ('counter','counter2'):
+        mo = re.match(r'^(?P<attr>[^:]*?)(:(?P<seed>.*))?$', args)
+        attr = mo.group('attr')
+        seed = mo.group('seed')
+        if seed and (not re.match(r'^\d+$', seed) and len(seed) > 1):
+            message.warning('%s: illegal counter seed: %s' % (syntax,seed))
+            return None
+        if not is_name(attr):
+            message.warning('%s: illegal attribute name' % syntax)
+            return None
+        value = document.attributes.get(attr)
+        if value:
+            if not re.match(r'^\d+$', value) and len(value) > 1:
+                message.warning('%s: illegal counter value: %s'
+                                % (syntax,value))
+                return None
+            if re.match(r'^\d+$', value):
+                expr = value + '+1'
+            else:
+                expr = 'chr(ord("%s")+1)' % value
+            try:
+                result = str(eval(expr))
+            except Exception:
+                message.warning('%s: evaluation error: %s' % (syntax, expr))
+        else:
+            if seed:
+                result = seed
+            else:
+                result = '1'
+        document.attributes[attr] = result
+        if attrs is not None:
+            attrs[attr] = result
+        if name == 'counter2':
+            result = ''
+    elif name in ('set','set2'):
+        mo = re.match(r'^(?P<attr>[^:]*?)(:(?P<value>.*))?$', args)
+        attr = mo.group('attr')
+        value = mo.group('value')
+        if value is None:
+            value = ''
+        if attr.endswith('!'):
+            attr = attr[:-1]
+            value = None
+        if not is_name(attr):
+            message.warning('%s: illegal attribute name' % syntax)
+        else:
+            if attrs is not None:
+                attrs[attr] = value
+            if name != 'set2':  # set2 only updates local attributes.
+                document.attributes[attr] = value
+        if value is None:
+            result = None
+        else:
+            result = ''
+    elif name == 'include':
+        if not os.path.exists(args):
+            message.warning('%s: file does not exist' % syntax)
+        elif not is_safe_file(args):
+            message.unsafe(syntax)
+        else:
+            result = [s.rstrip() for s in open(args)]
+            if result:
+                result = subs_attrs(result)
+                result = separator.join(result)
+                result = result.expandtabs(reader.tabsize)
+            else:
+                result = ''
+    elif name == 'include1':
+        result = separator.join(config.include1[args])
+    elif name == 'template':
+        if not args in config.sections:
+            message.warning('%s: template does not exist' % syntax)
+        else:
+            result = []
+            for line in  config.sections[args]:
+                line = subs_attrs(line)
+                if line is not None:
+                    result.append(line)
+            result = '\n'.join(result)
+    else:
+        assert False
+    if result and name in ('eval3','sys3'):
+        macros.passthroughs.append(result)
+        result = '\x07' + str(len(macros.passthroughs)-1) + '\x07'
+    return result
+
+def subs_attrs(lines, dictionary=None):
+    """Substitute 'lines' of text with attributes from the global
+    document.attributes dictionary and from 'dictionary' ('dictionary'
+    entries take precedence). Return a tuple of the substituted lines.  'lines'
+    containing undefined attributes are deleted. If 'lines' is a string then
+    return a string.
+
+    - Attribute references are substituted in the following order: simple,
+      conditional, system.
+    - Attribute references inside 'dictionary' entry values are substituted.
+    """
+
+    def end_brace(text,start):
+        """Return index following end brace that matches brace at start in
+        text."""
+        assert text[start] == '{'
+        n = 0
+        result = start
+        for c in text[start:]:
+            # Skip braces that are followed by a backslash.
+            if result == len(text)-1 or text[result+1] != '\\':
+                if c == '{': n = n + 1
+                elif c == '}': n = n - 1
+            result = result + 1
+            if n == 0: break
+        return result
+
+    if type(lines) == str:
+        string_result = True
+        lines = [lines]
+    else:
+        string_result = False
+    if dictionary is None:
+        attrs = document.attributes
+    else:
+        # Remove numbered document attributes so they don't clash with
+        # attribute list positional attributes.
+        attrs = {}
+        for k,v in document.attributes.items():
+            if not re.match(r'^\d+$', k):
+                attrs[k] = v
+        # Substitute attribute references inside dictionary values.
+        for k,v in dictionary.items():
+            if v is None:
+                del dictionary[k]
+            else:
+                v = subs_attrs(str(v))
+                if v is None:
+                    del dictionary[k]
+                else:
+                    dictionary[k] = v
+        attrs.update(dictionary)
+    # Substitute all attributes in all lines.
+    result = []
+    for line in lines:
+        # Make it easier for regular expressions.
+        line = line.replace('\\{','{\\')
+        line = line.replace('\\}','}\\')
+        # Expand simple attributes ({name}).
+        # Nested attributes not allowed.
+        reo = re.compile(r'(?su)\{(?P<name>[^\\\W][-\w]*?)\}(?!\\)')
+        pos = 0
+        while True:
+            mo = reo.search(line,pos)
+            if not mo: break
+            s =  attrs.get(mo.group('name'))
+            if s is None:
+                pos = mo.end()
+            else:
+                s = str(s)
+                line = line[:mo.start()] + s + line[mo.end():]
+                pos = mo.start() + len(s)
+        # Expand conditional attributes.
+        # Single name -- higher precedence.
+        reo1 = re.compile(r'(?su)\{(?P<name>[^\\\W][-\w]*?)' \
+                          r'(?P<op>\=|\?|!|#|%|@|\$)' \
+                          r'(?P<value>.*?)\}(?!\\)')
+        # Multiple names (n1,n2,... or n1+n2+...) -- lower precedence.
+        reo2 = re.compile(r'(?su)\{(?P<name>[^\\\W][-\w'+OR+AND+r']*?)' \
+                          r'(?P<op>\=|\?|!|#|%|@|\$)' \
+                          r'(?P<value>.*?)\}(?!\\)')
+        for reo in [reo1,reo2]:
+            pos = 0
+            while True:
+                mo = reo.search(line,pos)
+                if not mo: break
+                attr = mo.group()
+                name =  mo.group('name')
+                if reo == reo2:
+                    if OR in name:
+                        sep = OR
+                    else:
+                        sep = AND
+                    names = [s.strip() for s in name.split(sep) if s.strip() ]
+                    for n in names:
+                        if not re.match(r'^[^\\\W][-\w]*$',n):
+                            message.error('illegal attribute syntax: %s' % attr)
+                    if sep == OR:
+                        # Process OR name expression: n1,n2,...
+                        for n in names:
+                            if attrs.get(n) is not None:
+                                lval = ''
+                                break
+                        else:
+                            lval = None
+                    else:
+                        # Process AND name expression: n1+n2+...
+                        for n in names:
+                            if attrs.get(n) is None:
+                                lval = None
+                                break
+                        else:
+                            lval = ''
+                else:
+                    lval =  attrs.get(name)
+                op = mo.group('op')
+                # mo.end() not good enough because '{x={y}}' matches '{x={y}'.
+                end = end_brace(line,mo.start())
+                rval = line[mo.start('value'):end-1]
+                UNDEFINED = '{zzzzz}'
+                if lval is None:
+                    if op == '=': s = rval
+                    elif op == '?': s = ''
+                    elif op == '!': s = rval
+                    elif op == '#': s = UNDEFINED   # So the line is dropped.
+                    elif op == '%': s = rval
+                    elif op in ('@','$'):
+                        s = UNDEFINED               # So the line is dropped.
+                    else:
+                        assert False, 'illegal attribute: %s' % attr
+                else:
+                    if op == '=': s = lval
+                    elif op == '?': s = rval
+                    elif op == '!': s = ''
+                    elif op == '#': s = rval
+                    elif op == '%': s = UNDEFINED   # So the line is dropped.
+                    elif op in ('@','$'):
+                        v = re.split(r'(?<!\\):',rval)
+                        if len(v) not in (2,3):
+                            message.error('illegal attribute syntax: %s' % attr)
+                            s = ''
+                        elif not is_re('^'+v[0]+'$'):
+                            message.error('illegal attribute regexp: %s' % attr)
+                            s = ''
+                        else:
+                            v = [s.replace('\\:',':') for s in v]
+                            re_mo = re.match('^'+v[0]+'$',lval)
+                            if op == '@':
+                                if re_mo:
+                                    s = v[1]         # {<name>@<re>:<v1>[:<v2>]}
+                                else:
+                                    if len(v) == 3:   # {<name>@<re>:<v1>:<v2>}
+                                        s = v[2]
+                                    else:             # {<name>@<re>:<v1>}
+                                        s = ''
+                            else:
+                                if re_mo:
+                                    if len(v) == 2:   # {<name>$<re>:<v1>}
+                                        s = v[1]
+                                    elif v[1] == '':  # {<name>$<re>::<v2>}
+                                        s = UNDEFINED # So the line is dropped.
+                                    else:             # {<name>$<re>:<v1>:<v2>}
+                                        s = v[1]
+                                else:
+                                    if len(v) == 2:   # {<name>$<re>:<v1>}
+                                        s = UNDEFINED # So the line is dropped.
+                                    else:             # {<name>$<re>:<v1>:<v2>}
+                                        s = v[2]
+                    else:
+                        assert False, 'illegal attribute: %s' % attr
+                s = str(s)
+                line = line[:mo.start()] + s + line[end:]
+                pos = mo.start() + len(s)
+        # Drop line if it contains  unsubstituted {name} references.
+        skipped = re.search(r'(?su)\{[^\\\W][-\w]*?\}(?!\\)', line)
+        if skipped:
+            trace('dropped line', line)
+            continue;
+        # Expand system attributes (eval has precedence).
+        reos = [
+            re.compile(r'(?su)\{(?P<action>eval):(?P<expr>.*?)\}(?!\\)'),
+            re.compile(r'(?su)\{(?P<action>[^\\\W][-\w]*?):(?P<expr>.*?)\}(?!\\)'),
+        ]
+        skipped = False
+        for reo in reos:
+            pos = 0
+            while True:
+                mo = reo.search(line,pos)
+                if not mo: break
+                expr = mo.group('expr')
+                action = mo.group('action')
+                expr = expr.replace('{\\','{')
+                expr = expr.replace('}\\','}')
+                s = system(action, expr, attrs=dictionary)
+                if dictionary is not None and action in ('counter','counter2','set','set2'):
+                    # These actions create and update attributes.
+                    attrs.update(dictionary)
+                if s is None:
+                    # Drop line if the action returns None.
+                    skipped = True
+                    break
+                line = line[:mo.start()] + s + line[mo.end():]
+                pos = mo.start() + len(s)
+            if skipped:
+                break
+        if not skipped:
+            # Remove backslash from escaped entries.
+            line = line.replace('{\\','{')
+            line = line.replace('}\\','}')
+            result.append(line)
+    if string_result:
+        if result:
+            return '\n'.join(result)
+        else:
+            return None
+    else:
+        return tuple(result)
+
+def char_encoding():
+    encoding = document.attributes.get('encoding')
+    if encoding:
+        try:
+            codecs.lookup(encoding)
+        except LookupError,e:
+            raise EAsciiDoc,str(e)
+    return encoding
+
+def char_len(s):
+    return len(char_decode(s))
+
+east_asian_widths = {'W': 2,   # Wide
+                     'F': 2,   # Full-width (wide)
+                     'Na': 1,  # Narrow
+                     'H': 1,   # Half-width (narrow)
+                     'N': 1,   # Neutral (not East Asian, treated as narrow)
+                     'A': 1}   # Ambiguous (s/b wide in East Asian context,
+                               # narrow otherwise, but that doesn't work)
+"""Mapping of result codes from `unicodedata.east_asian_width()` to character
+column widths."""
+
+def column_width(s):
+    text = char_decode(s)
+    if isinstance(text, unicode):
+        width = 0
+        for c in text:
+            width += east_asian_widths[unicodedata.east_asian_width(c)]
+        return width
+    else:
+        return len(text)
+
+def char_decode(s):
+    if char_encoding():
+        try:
+            return s.decode(char_encoding())
+        except Exception:
+            raise EAsciiDoc, \
+                "'%s' codec can't decode \"%s\"" % (char_encoding(), s)
+    else:
+        return s
+
+def char_encode(s):
+    if char_encoding():
+        return s.encode(char_encoding())
+    else:
+        return s
+
+def time_str(t):
+    """Convert seconds since the Epoch to formatted local time string."""
+    t = time.localtime(t)
+    s = time.strftime('%H:%M:%S',t)
+    if time.daylight and t.tm_isdst == 1:
+        result = s + ' ' + time.tzname[1]
+    else:
+        result = s + ' ' + time.tzname[0]
+    # Attempt to convert the localtime to the output encoding.
+    try:
+        result = char_encode(result.decode(locale.getdefaultlocale()[1]))
+    except Exception:
+        pass
+    return result
+
+def date_str(t):
+    """Convert seconds since the Epoch to formatted local date string."""
+    t = time.localtime(t)
+    return time.strftime('%Y-%m-%d',t)
+
+
+class Lex:
+    """Lexical analysis routines. Static methods and attributes only."""
+    prev_element = None
+    prev_cursor = None
+    def __init__(self):
+        raise AssertionError,'no class instances allowed'
+    @staticmethod
+    def next():
+        """Returns class of next element on the input (None if EOF).  The
+        reader is assumed to be at the first line following a previous element,
+        end of file or line one.  Exits with the reader pointing to the first
+        line of the next element or EOF (leading blank lines are skipped)."""
+        reader.skip_blank_lines()
+        if reader.eof(): return None
+        # Optimization: If we've already checked for an element at this
+        # position return the element.
+        if Lex.prev_element and Lex.prev_cursor == reader.cursor:
+            return Lex.prev_element
+        if AttributeEntry.isnext():
+            result = AttributeEntry
+        elif AttributeList.isnext():
+            result = AttributeList
+        elif BlockTitle.isnext() and not tables_OLD.isnext():
+            result = BlockTitle
+        elif Title.isnext():
+            if AttributeList.style() == 'float':
+                result = FloatingTitle
+            else:
+                result = Title
+        elif macros.isnext():
+            result = macros.current
+        elif lists.isnext():
+            result = lists.current
+        elif blocks.isnext():
+            result = blocks.current
+        elif tables_OLD.isnext():
+            result = tables_OLD.current
+        elif tables.isnext():
+            result = tables.current
+        else:
+            if not paragraphs.isnext():
+                raise EAsciiDoc,'paragraph expected'
+            result = paragraphs.current
+        # Optimization: Cache answer.
+        Lex.prev_cursor = reader.cursor
+        Lex.prev_element = result
+        return result
+
+    @staticmethod
+    def canonical_subs(options):
+        """Translate composite subs values."""
+        if len(options) == 1:
+            if options[0] == 'none':
+                options = ()
+            elif options[0] == 'normal':
+                options = config.subsnormal
+            elif options[0] == 'verbatim':
+                options = config.subsverbatim
+        return options
+
+    @staticmethod
+    def subs_1(s,options):
+        """Perform substitution specified in 'options' (in 'options' order)."""
+        if not s:
+            return s
+        if document.attributes.get('plaintext') is not None:
+            options = ('specialcharacters',)
+        result = s
+        options = Lex.canonical_subs(options)
+        for o in options:
+            if o == 'specialcharacters':
+                result = config.subs_specialchars(result)
+            elif o == 'attributes':
+                result = subs_attrs(result)
+            elif o == 'quotes':
+                result = subs_quotes(result)
+            elif o == 'specialwords':
+                result = config.subs_specialwords(result)
+            elif o in ('replacements','replacements2'):
+                result = config.subs_replacements(result,o)
+            elif o == 'macros':
+                result = macros.subs(result)
+            elif o == 'callouts':
+                result = macros.subs(result,callouts=True)
+            else:
+                raise EAsciiDoc,'illegal substitution option: %s' % o
+            trace(o, s, result)
+            if not result:
+                break
+        return result
+
+    @staticmethod
+    def subs(lines,options):
+        """Perform inline processing specified by 'options' (in 'options'
+        order) on sequence of 'lines'."""
+        if not lines or not options:
+            return lines
+        options = Lex.canonical_subs(options)
+        # Join lines so quoting can span multiple lines.
+        para = '\n'.join(lines)
+        if 'macros' in options:
+            para = macros.extract_passthroughs(para)
+        for o in options:
+            if o == 'attributes':
+                # If we don't substitute attributes line-by-line then a single
+                # undefined attribute will drop the entire paragraph.
+                lines = subs_attrs(para.split('\n'))
+                para = '\n'.join(lines)
+            else:
+                para = Lex.subs_1(para,(o,))
+        if 'macros' in options:
+            para = macros.restore_passthroughs(para)
+        return para.splitlines()
+
+    @staticmethod
+    def set_margin(lines, margin=0):
+        """Utility routine that sets the left margin to 'margin' space in a
+        block of non-blank lines."""
+        # Calculate width of block margin.
+        lines = list(lines)
+        width = len(lines[0])
+        for s in lines:
+            i = re.search(r'\S',s).start()
+            if i < width: width = i
+        # Strip margin width from all lines.
+        for i in range(len(lines)):
+            lines[i] = ' '*margin + lines[i][width:]
+        return lines
+
+#---------------------------------------------------------------------------
+# Document element classes parse AsciiDoc reader input and write DocBook writer
+# output.
+#---------------------------------------------------------------------------
+class Document(object):
+
+    # doctype property.
+    def getdoctype(self):
+        return self.attributes.get('doctype')
+    def setdoctype(self,doctype):
+        self.attributes['doctype'] = doctype
+    doctype = property(getdoctype,setdoctype)
+
+    # backend property.
+    def getbackend(self):
+        return self.attributes.get('backend')
+    def setbackend(self,backend):
+        if backend:
+            backend = self.attributes.get('backend-alias-' + backend, backend)
+        self.attributes['backend'] = backend
+    backend = property(getbackend,setbackend)
+
+    def __init__(self):
+        self.infile = None      # Source file name.
+        self.outfile = None     # Output file name.
+        self.attributes = InsensitiveDict()
+        self.level = 0          # 0 => front matter. 1,2,3 => sect1,2,3.
+        self.has_errors = False # Set true if processing errors were flagged.
+        self.has_warnings = False # Set true if warnings were flagged.
+        self.safe = False       # Default safe mode.
+    def update_attributes(self,attrs=None):
+        """
+        Set implicit attributes and attributes in 'attrs'.
+        """
+        t = time.time()
+        self.attributes['localtime'] = time_str(t)
+        self.attributes['localdate'] = date_str(t)
+        self.attributes['asciidoc-version'] = VERSION
+        self.attributes['asciidoc-file'] = APP_FILE
+        self.attributes['asciidoc-dir'] = APP_DIR
+        self.attributes['asciidoc-confdir'] = CONF_DIR
+        self.attributes['user-dir'] = USER_DIR
+        if config.verbose:
+            self.attributes['verbose'] = ''
+        # Update with configuration file attributes.
+        if attrs:
+            self.attributes.update(attrs)
+        # Update with command-line attributes.
+        self.attributes.update(config.cmd_attrs)
+        # Extract miscellaneous configuration section entries from attributes.
+        if attrs:
+            config.load_miscellaneous(attrs)
+        config.load_miscellaneous(config.cmd_attrs)
+        self.attributes['newline'] = config.newline
+        # File name related attributes can't be overridden.
+        if self.infile is not None:
+            if self.infile and os.path.exists(self.infile):
+                t = os.path.getmtime(self.infile)
+            elif self.infile == '<stdin>':
+                t = time.time()
+            else:
+                t = None
+            if t:
+                self.attributes['doctime'] = time_str(t)
+                self.attributes['docdate'] = date_str(t)
+            if self.infile != '<stdin>':
+                self.attributes['infile'] = self.infile
+                self.attributes['indir'] = os.path.dirname(self.infile)
+                self.attributes['docfile'] = self.infile
+                self.attributes['docdir'] = os.path.dirname(self.infile)
+                self.attributes['docname'] = os.path.splitext(
+                        os.path.basename(self.infile))[0]
+        if self.outfile:
+            if self.outfile != '<stdout>':
+                self.attributes['outfile'] = self.outfile
+                self.attributes['outdir'] = os.path.dirname(self.outfile)
+                if self.infile == '<stdin>':
+                    self.attributes['docname'] = os.path.splitext(
+                            os.path.basename(self.outfile))[0]
+                ext = os.path.splitext(self.outfile)[1][1:]
+            elif config.outfilesuffix:
+                ext = config.outfilesuffix[1:]
+            else:
+                ext = ''
+            if ext:
+                self.attributes['filetype'] = ext
+                self.attributes['filetype-'+ext] = ''
+    def load_lang(self):
+        """
+        Load language configuration file.
+        """
+        lang = self.attributes.get('lang')
+        if lang is None:
+            filename = 'lang-en.conf'   # Default language file.
+        else:
+            filename = 'lang-' + lang + '.conf'
+        if config.load_from_dirs(filename):
+            self.attributes['lang'] = lang  # Reinstate new lang attribute.
+        else:
+            if lang is None:
+                # The default language file must exist.
+                message.error('missing conf file: %s' % filename, halt=True)
+            else:
+                message.warning('missing language conf file: %s' % filename)
+    def set_deprecated_attribute(self,old,new):
+        """
+        Ensures the 'old' name of an attribute that was renamed to 'new' is
+        still honored.
+        """
+        if self.attributes.get(new) is None:
+            if self.attributes.get(old) is not None:
+                self.attributes[new] = self.attributes[old]
+        else:
+            self.attributes[old] = self.attributes[new]
+    def consume_attributes_and_comments(self,comments_only=False,noblanks=False):
+        """
+        Returns True if one or more attributes or comments were consumed.
+        If 'noblanks' is True then consumation halts if a blank line is
+        encountered.
+        """
+        result = False
+        finished = False
+        while not finished:
+            finished = True
+            if noblanks and not reader.read_next(): return result
+            if blocks.isnext() and 'skip' in blocks.current.options:
+                result = True
+                finished = False
+                blocks.current.translate()
+            if noblanks and not reader.read_next(): return result
+            if macros.isnext() and macros.current.name == 'comment':
+                result = True
+                finished = False
+                macros.current.translate()
+            if not comments_only:
+                if AttributeEntry.isnext():
+                    result = True
+                    finished = False
+                    AttributeEntry.translate()
+                if AttributeList.isnext():
+                    result = True
+                    finished = False
+                    AttributeList.translate()
+        return result
+    def parse_header(self,doctype,backend):
+        """
+        Parses header, sets corresponding document attributes and finalizes
+        document doctype and backend properties.
+        Returns False if the document does not have a header.
+        'doctype' and 'backend' are the doctype and backend option values
+        passed on the command-line, None if no command-line option was not
+        specified.
+        """
+        assert self.level == 0
+        # Skip comments and attribute entries that preceed the header.
+        self.consume_attributes_and_comments()
+        if doctype is not None:
+            # Command-line overrides header.
+            self.doctype = doctype
+        elif self.doctype is None:
+            # Was not set on command-line or in document header.
+            self.doctype = DEFAULT_DOCTYPE
+        # Process document header.
+        has_header = (Title.isnext() and Title.level == 0
+                      and AttributeList.style() != 'float')
+        if self.doctype == 'manpage' and not has_header:
+            message.error('manpage document title is mandatory',halt=True)
+        if has_header:
+            Header.parse()
+        # Command-line entries override header derived entries.
+        self.attributes.update(config.cmd_attrs)
+        # DEPRECATED: revision renamed to revnumber.
+        self.set_deprecated_attribute('revision','revnumber')
+        # DEPRECATED: date renamed to revdate.
+        self.set_deprecated_attribute('date','revdate')
+        if doctype is not None:
+            # Command-line overrides header.
+            self.doctype = doctype
+        if backend is not None:
+            # Command-line overrides header.
+            self.backend = backend
+        elif self.backend is None:
+            # Was not set on command-line or in document header.
+            self.backend = DEFAULT_BACKEND
+        else:
+            # Has been set in document header.
+            self.backend = self.backend # Translate alias in header.
+        assert self.doctype in ('article','manpage','book'), 'illegal document type'
+        return has_header
+    def translate(self,has_header):
+        if self.doctype == 'manpage':
+            # Translate mandatory NAME section.
+            if Lex.next() is not Title:
+                message.error('name section expected')
+            else:
+                Title.translate()
+                if Title.level != 1:
+                    message.error('name section title must be at level 1')
+                if not isinstance(Lex.next(),Paragraph):
+                    message.error('malformed name section body')
+                lines = reader.read_until(r'^$')
+                s = ' '.join(lines)
+                mo = re.match(r'^(?P<manname>.*?)\s+-\s+(?P<manpurpose>.*)$',s)
+                if not mo:
+                    message.error('malformed name section body')
+                self.attributes['manname'] = mo.group('manname').strip()
+                self.attributes['manpurpose'] = mo.group('manpurpose').strip()
+                names = [s.strip() for s in self.attributes['manname'].split(',')]
+                if len(names) > 9:
+                    message.warning('to many manpage names')
+                for i,name in enumerate(names):
+                    self.attributes['manname%d' % (i+1)] = name
+        if has_header:
+            # Do postponed substitutions (backend confs have been loaded).
+            self.attributes['doctitle'] = Title.dosubs(self.attributes['doctitle'])
+            if config.header_footer:
+                hdr = config.subs_section('header',{})
+                writer.write(hdr,trace='header')
+            if 'title' in self.attributes:
+                del self.attributes['title']
+            self.consume_attributes_and_comments()
+            if self.doctype in ('article','book'):
+                # Translate 'preamble' (untitled elements between header
+                # and first section title).
+                if Lex.next() is not Title:
+                    stag,etag = config.section2tags('preamble')
+                    writer.write(stag,trace='preamble open')
+                    Section.translate_body()
+                    writer.write(etag,trace='preamble close')
+            elif self.doctype == 'manpage' and 'name' in config.sections:
+                writer.write(config.subs_section('name',{}), trace='name')
+        else:
+            self.process_author_names()
+            if config.header_footer:
+                hdr = config.subs_section('header',{})
+                writer.write(hdr,trace='header')
+            if Lex.next() is not Title:
+                Section.translate_body()
+        # Process remaining sections.
+        while not reader.eof():
+            if Lex.next() is not Title:
+                raise EAsciiDoc,'section title expected'
+            Section.translate()
+        Section.setlevel(0) # Write remaining unwritten section close tags.
+        # Substitute document parameters and write document footer.
+        if config.header_footer:
+            ftr = config.subs_section('footer',{})
+            writer.write(ftr,trace='footer')
+    def parse_author(self,s):
+        """ Return False if the author is malformed."""
+        attrs = self.attributes # Alias for readability.
+        s = s.strip()
+        mo = re.match(r'^(?P<name1>[^<>\s]+)'
+                '(\s+(?P<name2>[^<>\s]+))?'
+                '(\s+(?P<name3>[^<>\s]+))?'
+                '(\s+<(?P<email>\S+)>)?$',s)
+        if not mo:
+            # Names that don't match the formal specification.
+            if s:
+                attrs['firstname'] = s
+            return
+        firstname = mo.group('name1')
+        if mo.group('name3'):
+            middlename = mo.group('name2')
+            lastname = mo.group('name3')
+        else:
+            middlename = None
+            lastname = mo.group('name2')
+        firstname = firstname.replace('_',' ')
+        if middlename:
+            middlename = middlename.replace('_',' ')
+        if lastname:
+            lastname = lastname.replace('_',' ')
+        email = mo.group('email')
+        if firstname:
+            attrs['firstname'] = firstname
+        if middlename:
+            attrs['middlename'] = middlename
+        if lastname:
+            attrs['lastname'] = lastname
+        if email:
+            attrs['email'] = email
+        return
+    def process_author_names(self):
+        """ Calculate any missing author related attributes."""
+        attrs = self.attributes # Alias for readability.
+        firstname = attrs.get('firstname','')
+        middlename = attrs.get('middlename','')
+        lastname = attrs.get('lastname','')
+        author = attrs.get('author')
+        initials = attrs.get('authorinitials')
+        if author and not (firstname or middlename or lastname):
+            self.parse_author(author)
+            attrs['author'] = author.replace('_',' ')
+            self.process_author_names()
+            return
+        if not author:
+            author = '%s %s %s' % (firstname, middlename, lastname)
+            author = author.strip()
+            author = re.sub(r'\s+',' ', author)
+        if not initials:
+            initials = (char_decode(firstname)[:1] +
+                       char_decode(middlename)[:1] + char_decode(lastname)[:1])
+            initials = char_encode(initials).upper()
+        names = [firstname,middlename,lastname,author,initials]
+        for i,v in enumerate(names):
+            v = config.subs_specialchars(v)
+            v = subs_attrs(v)
+            names[i] = v
+        firstname,middlename,lastname,author,initials = names
+        if firstname:
+            attrs['firstname'] = firstname
+        if middlename:
+            attrs['middlename'] = middlename
+        if lastname:
+            attrs['lastname'] = lastname
+        if author:
+            attrs['author'] = author
+        if initials:
+            attrs['authorinitials'] = initials
+        if author:
+            attrs['authored'] = ''
+
+
+class Header:
+    """Static methods and attributes only."""
+    REV_LINE_RE = r'^(\D*(?P<revnumber>.*?),)?(?P<revdate>.*?)(:\s*(?P<revremark>.*))?$'
+    RCS_ID_RE = r'^\$Id: \S+ (?P<revnumber>\S+) (?P<revdate>\S+) \S+ (?P<author>\S+) (\S+ )?\$$'
+    def __init__(self):
+        raise AssertionError,'no class instances allowed'
+    @staticmethod
+    def parse():
+        assert Lex.next() is Title and Title.level == 0
+        attrs = document.attributes # Alias for readability.
+        # Postpone title subs until backend conf files have been loaded.
+        Title.translate(skipsubs=True)
+        attrs['doctitle'] = Title.attributes['title']
+        document.consume_attributes_and_comments(noblanks=True)
+        s = reader.read_next()
+        mo = None
+        if s:
+            # Process first header line after the title that is not a comment
+            # or an attribute entry.
+            s = reader.read()
+            mo = re.match(Header.RCS_ID_RE,s)
+            if not mo:
+                document.parse_author(s)
+                document.consume_attributes_and_comments(noblanks=True)
+                if reader.read_next():
+                    # Process second header line after the title that is not a
+                    # comment or an attribute entry.
+                    s = reader.read()
+                    s = subs_attrs(s)
+                    if s:
+                        mo = re.match(Header.RCS_ID_RE,s)
+                        if not mo:
+                            mo = re.match(Header.REV_LINE_RE,s)
+            document.consume_attributes_and_comments(noblanks=True)
+        s = attrs.get('revnumber')
+        if s:
+            mo = re.match(Header.RCS_ID_RE,s)
+        if mo:
+            revnumber = mo.group('revnumber')
+            if revnumber:
+                attrs['revnumber'] = revnumber.strip()
+            author = mo.groupdict().get('author')
+            if author and 'firstname' not in attrs:
+                document.parse_author(author)
+            revremark = mo.groupdict().get('revremark')
+            if revremark is not None:
+                revremark = [revremark]
+                # Revision remarks can continue on following lines.
+                while reader.read_next():
+                    if document.consume_attributes_and_comments(noblanks=True):
+                        break
+                    revremark.append(reader.read())
+                revremark = Lex.subs(revremark,['normal'])
+                revremark = '\n'.join(revremark).strip()
+                attrs['revremark'] = revremark
+            revdate = mo.group('revdate')
+            if revdate:
+                attrs['revdate'] = revdate.strip()
+            elif revnumber or revremark:
+                # Set revision date to ensure valid DocBook revision.
+                attrs['revdate'] = attrs['docdate']
+        document.process_author_names()
+        if document.doctype == 'manpage':
+            # manpage title formatted like mantitle(manvolnum).
+            mo = re.match(r'^(?P<mantitle>.*)\((?P<manvolnum>.*)\)$',
+                          attrs['doctitle'])
+            if not mo:
+                message.error('malformed manpage title')
+            else:
+                mantitle = mo.group('mantitle').strip()
+                mantitle = subs_attrs(mantitle)
+                if mantitle is None:
+                    message.error('undefined attribute in manpage title')
+                # mantitle is lowered only if in ALL CAPS
+                if mantitle == mantitle.upper():
+                    mantitle = mantitle.lower()
+                attrs['mantitle'] = mantitle;
+                attrs['manvolnum'] = mo.group('manvolnum').strip()
+
+class AttributeEntry:
+    """Static methods and attributes only."""
+    pattern = None
+    subs = None
+    name = None
+    name2 = None
+    value = None
+    attributes = {}     # Accumulates all the parsed attribute entries.
+    def __init__(self):
+        raise AssertionError,'no class instances allowed'
+    @staticmethod
+    def isnext():
+        result = False  # Assume not next.
+        if not AttributeEntry.pattern:
+            pat = document.attributes.get('attributeentry-pattern')
+            if not pat:
+                message.error("[attributes] missing 'attributeentry-pattern' entry")
+            AttributeEntry.pattern = pat
+        line = reader.read_next()
+        if line:
+            # Attribute entry formatted like :<name>[.<name2>]:[ <value>]
+            mo = re.match(AttributeEntry.pattern,line)
+            if mo:
+                AttributeEntry.name = mo.group('attrname')
+                AttributeEntry.name2 = mo.group('attrname2')
+                AttributeEntry.value = mo.group('attrvalue') or ''
+                AttributeEntry.value = AttributeEntry.value.strip()
+                result = True
+        return result
+    @staticmethod
+    def translate():
+        assert Lex.next() is AttributeEntry
+        attr = AttributeEntry    # Alias for brevity.
+        reader.read()            # Discard attribute entry from reader.
+        while attr.value.endswith(' +'):
+            if not reader.read_next(): break
+            attr.value = attr.value[:-1] + reader.read().strip()
+        if attr.name2 is not None:
+            # Configuration file attribute.
+            if attr.name2 != '':
+                # Section entry attribute.
+                section = {}
+                # Some sections can have name! syntax.
+                if attr.name in ('attributes','miscellaneous') and attr.name2[-1] == '!':
+                    section[attr.name] = [attr.name2]
+                else:
+                   section[attr.name] = ['%s=%s' % (attr.name2,attr.value)]
+                config.load_sections(section)
+                config.load_miscellaneous(config.conf_attrs)
+            else:
+                # Markup template section attribute.
+                if attr.name in config.sections:
+                    config.sections[attr.name] = [attr.value]
+                else:
+                    message.warning('missing configuration section: %s' % attr.name)
+        else:
+            # Normal attribute.
+            if attr.name[-1] == '!':
+                # Names like name! undefine the attribute.
+                attr.name = attr.name[:-1]
+                attr.value = None
+            # Strip white space and illegal name chars.
+            attr.name = re.sub(r'(?u)[^\w\-_]', '', attr.name).lower()
+            # Don't override most command-line attributes.
+            if attr.name in config.cmd_attrs \
+                    and attr.name not in ('trace','numbered'):
+                return
+            # Update document attributes with attribute value.
+            if attr.value is not None:
+                mo = re.match(r'^pass:(?P<attrs>.*)\[(?P<value>.*)\]$', attr.value)
+                if mo:
+                    # Inline passthrough syntax.
+                    attr.subs = mo.group('attrs')
+                    attr.value = mo.group('value')  # Passthrough.
+                else:
+                    # Default substitution.
+                    # DEPRECATED: attributeentry-subs
+                    attr.subs = document.attributes.get('attributeentry-subs',
+                                'specialcharacters,attributes')
+                attr.subs = parse_options(attr.subs, SUBS_OPTIONS,
+                            'illegal substitution option')
+                attr.value = Lex.subs((attr.value,), attr.subs)
+                attr.value = writer.newline.join(attr.value)
+                document.attributes[attr.name] = attr.value
+            elif attr.name in document.attributes:
+                del document.attributes[attr.name]
+            attr.attributes[attr.name] = attr.value
+
+class AttributeList:
+    """Static methods and attributes only."""
+    pattern = None
+    match = None
+    attrs = {}
+    def __init__(self):
+        raise AssertionError,'no class instances allowed'
+    @staticmethod
+    def initialize():
+        if not 'attributelist-pattern' in document.attributes:
+            message.error("[attributes] missing 'attributelist-pattern' entry")
+        AttributeList.pattern = document.attributes['attributelist-pattern']
+    @staticmethod
+    def isnext():
+        result = False  # Assume not next.
+        line = reader.read_next()
+        if line:
+            mo = re.match(AttributeList.pattern, line)
+            if mo:
+                AttributeList.match = mo
+                result = True
+        return result
+    @staticmethod
+    def translate():
+        assert Lex.next() is AttributeList
+        reader.read()   # Discard attribute list from reader.
+        attrs = {}
+        d = AttributeList.match.groupdict()
+        for k,v in d.items():
+            if v is not None:
+                if k == 'attrlist':
+                    v = subs_attrs(v)
+                    if v:
+                        parse_attributes(v, attrs)
+                else:
+                    AttributeList.attrs[k] = v
+        AttributeList.subs(attrs)
+        AttributeList.attrs.update(attrs)
+    @staticmethod
+    def subs(attrs):
+        '''Substitute single quoted attribute values normally.'''
+        reo = re.compile(r"^'.*'$")
+        for k,v in attrs.items():
+            if reo.match(str(v)):
+                attrs[k] = Lex.subs_1(v[1:-1],SUBS_NORMAL)
+    @staticmethod
+    def style():
+        return AttributeList.attrs.get('style') or AttributeList.attrs.get('1')
+    @staticmethod
+    def consume(d):
+        """Add attribute list to the dictionary 'd' and reset the
+        list."""
+        if AttributeList.attrs:
+            d.update(AttributeList.attrs)
+            AttributeList.attrs = {}
+            # Generate option attributes.
+            if 'options' in d:
+                options = parse_options(d['options'], (), 'illegal option name')
+                for option in options:
+                    d[option+'-option'] = ''
+
+class BlockTitle:
+    """Static methods and attributes only."""
+    title = None
+    pattern = None
+    def __init__(self):
+        raise AssertionError,'no class instances allowed'
+    @staticmethod
+    def isnext():
+        result = False  # Assume not next.
+        line = reader.read_next()
+        if line:
+            mo = re.match(BlockTitle.pattern,line)
+            if mo:
+                BlockTitle.title = mo.group('title')
+                result = True
+        return result
+    @staticmethod
+    def translate():
+        assert Lex.next() is BlockTitle
+        reader.read()   # Discard title from reader.
+        # Perform title substitutions.
+        if not Title.subs:
+            Title.subs = config.subsnormal
+        s = Lex.subs((BlockTitle.title,), Title.subs)
+        s = writer.newline.join(s)
+        if not s:
+            message.warning('blank block title')
+        BlockTitle.title = s
+    @staticmethod
+    def consume(d):
+        """If there is a title add it to dictionary 'd' then reset title."""
+        if BlockTitle.title:
+            d['title'] = BlockTitle.title
+            BlockTitle.title = None
+
+class Title:
+    """Processes Header and Section titles. Static methods and attributes
+    only."""
+    # Class variables
+    underlines = ('==','--','~~','^^','++') # Levels 0,1,2,3,4.
+    subs = ()
+    pattern = None
+    level = 0
+    attributes = {}
+    sectname = None
+    section_numbers = [0]*len(underlines)
+    dump_dict = {}
+    linecount = None    # Number of lines in title (1 or 2).
+    def __init__(self):
+        raise AssertionError,'no class instances allowed'
+    @staticmethod
+    def translate(skipsubs=False):
+        """Parse the Title.attributes and Title.level from the reader. The
+        real work has already been done by parse()."""
+        assert Lex.next() in (Title,FloatingTitle)
+        # Discard title from reader.
+        for i in range(Title.linecount):
+            reader.read()
+        Title.setsectname()
+        if not skipsubs:
+            Title.attributes['title'] = Title.dosubs(Title.attributes['title'])
+    @staticmethod
+    def dosubs(title):
+        """
+        Perform title substitutions.
+        """
+        if not Title.subs:
+            Title.subs = config.subsnormal
+        title = Lex.subs((title,), Title.subs)
+        title = writer.newline.join(title)
+        if not title:
+            message.warning('blank section title')
+        return title
+    @staticmethod
+    def isnext():
+        lines = reader.read_ahead(2)
+        return Title.parse(lines)
+    @staticmethod
+    def parse(lines):
+        """Parse title at start of lines tuple."""
+        if len(lines) == 0: return False
+        if len(lines[0]) == 0: return False # Title can't be blank.
+        # Check for single-line titles.
+        result = False
+        for level in range(len(Title.underlines)):
+            k = 'sect%s' % level
+            if k in Title.dump_dict:
+                mo = re.match(Title.dump_dict[k], lines[0])
+                if mo:
+                    Title.attributes = mo.groupdict()
+                    Title.level = level
+                    Title.linecount = 1
+                    result = True
+                    break
+        if not result:
+            # Check for double-line titles.
+            if not Title.pattern: return False  # Single-line titles only.
+            if len(lines) < 2: return False
+            title,ul = lines[:2]
+            title_len = column_width(title)
+            ul_len = char_len(ul)
+            if ul_len < 2: return False
+            # Fast elimination check.
+            if ul[:2] not in Title.underlines: return False
+            # Length of underline must be within +-3 of title.
+            if not ((ul_len-3 < title_len < ul_len+3)
+                    # Next test for backward compatibility.
+                    or (ul_len-3 < char_len(title) < ul_len+3)):
+                return False
+            # Check for valid repetition of underline character pairs.
+            s = ul[:2]*((ul_len+1)/2)
+            if ul != s[:ul_len]: return False
+            # Don't be fooled by back-to-back delimited blocks, require at
+            # least one alphanumeric character in title.
+            if not re.search(r'(?u)\w',title): return False
+            mo = re.match(Title.pattern, title)
+            if mo:
+                Title.attributes = mo.groupdict()
+                Title.level = list(Title.underlines).index(ul[:2])
+                Title.linecount = 2
+                result = True
+        # Check for expected pattern match groups.
+        if result:
+            if not 'title' in Title.attributes:
+                message.warning('[titles] entry has no <title> group')
+                Title.attributes['title'] = lines[0]
+            for k,v in Title.attributes.items():
+                if v is None: del Title.attributes[k]
+        try:
+            Title.level += int(document.attributes.get('leveloffset','0'))
+        except:
+            pass
+        Title.attributes['level'] = str(Title.level)
+        return result
+    @staticmethod
+    def load(entries):
+        """Load and validate [titles] section entries dictionary."""
+        if 'underlines' in entries:
+            errmsg = 'malformed [titles] underlines entry'
+            try:
+                underlines = parse_list(entries['underlines'])
+            except Exception:
+                raise EAsciiDoc,errmsg
+            if len(underlines) != len(Title.underlines):
+                raise EAsciiDoc,errmsg
+            for s in underlines:
+                if len(s) !=2:
+                    raise EAsciiDoc,errmsg
+            Title.underlines = tuple(underlines)
+            Title.dump_dict['underlines'] = entries['underlines']
+        if 'subs' in entries:
+            Title.subs = parse_options(entries['subs'], SUBS_OPTIONS,
+                'illegal [titles] subs entry')
+            Title.dump_dict['subs'] = entries['subs']
+        if 'sectiontitle' in entries:
+            pat = entries['sectiontitle']
+            if not pat or not is_re(pat):
+                raise EAsciiDoc,'malformed [titles] sectiontitle entry'
+            Title.pattern = pat
+            Title.dump_dict['sectiontitle'] = pat
+        if 'blocktitle' in entries:
+            pat = entries['blocktitle']
+            if not pat or not is_re(pat):
+                raise EAsciiDoc,'malformed [titles] blocktitle entry'
+            BlockTitle.pattern = pat
+            Title.dump_dict['blocktitle'] = pat
+        # Load single-line title patterns.
+        for k in ('sect0','sect1','sect2','sect3','sect4'):
+            if k in entries:
+                pat = entries[k]
+                if not pat or not is_re(pat):
+                    raise EAsciiDoc,'malformed [titles] %s entry' % k
+                Title.dump_dict[k] = pat
+        # TODO: Check we have either a Title.pattern or at least one
+        # single-line title pattern -- can this be done here or do we need
+        # check routine like the other block checkers?
+    @staticmethod
+    def dump():
+        dump_section('titles',Title.dump_dict)
+    @staticmethod
+    def setsectname():
+        """
+        Set Title section name:
+        If the first positional or 'template' attribute is set use it,
+        next search for section title in [specialsections],
+        if not found use default 'sect<level>' name.
+        """
+        sectname = AttributeList.attrs.get('1')
+        if sectname and sectname != 'float':
+            Title.sectname = sectname
+        elif 'template' in AttributeList.attrs:
+            Title.sectname = AttributeList.attrs['template']
+        else:
+            for pat,sect in config.specialsections.items():
+                mo = re.match(pat,Title.attributes['title'])
+                if mo:
+                    title = mo.groupdict().get('title')
+                    if title is not None:
+                        Title.attributes['title'] = title.strip()
+                    else:
+                        Title.attributes['title'] = mo.group().strip()
+                    Title.sectname = sect
+                    break
+            else:
+                Title.sectname = 'sect%d' % Title.level
+    @staticmethod
+    def getnumber(level):
+        """Return next section number at section 'level' formatted like
+        1.2.3.4."""
+        number = ''
+        for l in range(len(Title.section_numbers)):
+            n = Title.section_numbers[l]
+            if l == 0:
+                continue
+            elif l < level:
+                number = '%s%d.' % (number, n)
+            elif l == level:
+                number = '%s%d.' % (number, n + 1)
+                Title.section_numbers[l] = n + 1
+            elif l > level:
+                # Reset unprocessed section levels.
+                Title.section_numbers[l] = 0
+        return number
+
+
+class FloatingTitle(Title):
+    '''Floated titles are translated differently.'''
+    @staticmethod
+    def isnext():
+        return Title.isnext() and AttributeList.style() == 'float'
+    @staticmethod
+    def translate():
+        assert Lex.next() is FloatingTitle
+        Title.translate()
+        Section.set_id()
+        AttributeList.consume(Title.attributes)
+        template = 'floatingtitle'
+        if template in config.sections:
+            stag,etag = config.section2tags(template,Title.attributes)
+            writer.write(stag,trace='floating title')
+        else:
+            message.warning('missing template section: [%s]' % template)
+
+
+class Section:
+    """Static methods and attributes only."""
+    endtags = []  # Stack of currently open section (level,endtag) tuples.
+    ids = []      # List of already used ids.
+    def __init__(self):
+        raise AssertionError,'no class instances allowed'
+    @staticmethod
+    def savetag(level,etag):
+        """Save section end."""
+        Section.endtags.append((level,etag))
+    @staticmethod
+    def setlevel(level):
+        """Set document level and write open section close tags up to level."""
+        while Section.endtags and Section.endtags[-1][0] >= level:
+            writer.write(Section.endtags.pop()[1],trace='section close')
+        document.level = level
+    @staticmethod
+    def gen_id(title):
+        """
+        The normalized value of the id attribute is an NCName according to
+        the 'Namespaces in XML' Recommendation:
+        NCName          ::=     NCNameStartChar NCNameChar*
+        NCNameChar      ::=     NameChar - ':'
+        NCNameStartChar ::=     Letter | '_'
+        NameChar        ::=     Letter | Digit | '.' | '-' | '_' | ':'
+        """
+        # Replace non-alpha numeric characters in title with underscores and
+        # convert to lower case.
+        base_ident = char_encode(re.sub(r'(?u)\W+', '_',
+                char_decode(title)).strip('_').lower())
+        # Prefix the ID name with idprefix attribute or underscore if not
+        # defined. Prefix ensures the ID does not clash with existing IDs.
+        idprefix = document.attributes.get('idprefix','_')
+        base_ident = idprefix + base_ident
+        i = 1
+        while True:
+            if i == 1:
+                ident = base_ident
+            else:
+                ident = '%s_%d' % (base_ident, i)
+            if ident not in Section.ids:
+                Section.ids.append(ident)
+                return ident
+            else:
+                ident = base_ident
+            i += 1
+    @staticmethod
+    def set_id():
+        if not document.attributes.get('sectids') is None \
+                and 'id' not in AttributeList.attrs:
+            # Generate ids for sections.
+            AttributeList.attrs['id'] = Section.gen_id(Title.attributes['title'])
+    @staticmethod
+    def translate():
+        assert Lex.next() is Title
+        prev_sectname = Title.sectname
+        Title.translate()
+        if Title.level == 0 and document.doctype != 'book':
+            message.error('only book doctypes can contain level 0 sections')
+        if Title.level > document.level \
+                and 'basebackend-docbook' in document.attributes \
+                and prev_sectname in ('colophon','abstract', \
+                    'dedication','glossary','bibliography'):
+            message.error('%s section cannot contain sub-sections' % prev_sectname)
+        if Title.level > document.level+1:
+            # Sub-sections of multi-part book level zero Preface and Appendices
+            # are meant to be out of sequence.
+            if document.doctype == 'book' \
+                    and document.level == 0 \
+                    and Title.level == 2 \
+                    and prev_sectname in ('preface','appendix'):
+                pass
+            else:
+                message.warning('section title out of sequence: '
+                    'expected level %d, got level %d'
+                    % (document.level+1, Title.level))
+        Section.set_id()
+        Section.setlevel(Title.level)
+        if 'numbered' in document.attributes:
+            Title.attributes['sectnum'] = Title.getnumber(document.level)
+        else:
+            Title.attributes['sectnum'] = ''
+        AttributeList.consume(Title.attributes)
+        stag,etag = config.section2tags(Title.sectname,Title.attributes)
+        Section.savetag(Title.level,etag)
+        writer.write(stag,trace='section open: level %d: %s' %
+                (Title.level, Title.attributes['title']))
+        Section.translate_body()
+    @staticmethod
+    def translate_body(terminator=Title):
+        isempty = True
+        next = Lex.next()
+        while next and next is not terminator:
+            if isinstance(terminator,DelimitedBlock) and next is Title:
+                message.error('section title not permitted in delimited block')
+            next.translate()
+            next = Lex.next()
+            isempty = False
+        # The section is not empty if contains a subsection.
+        if next and isempty and Title.level > document.level:
+            isempty = False
+        # Report empty sections if invalid markup will result.
+        if isempty:
+            if document.backend == 'docbook' and Title.sectname != 'index':
+                message.error('empty section is not valid')
+
+class AbstractBlock:
+    def __init__(self):
+        # Configuration parameter names common to all blocks.
+        self.CONF_ENTRIES = ('delimiter','options','subs','presubs','postsubs',
+                             'posattrs','style','.*-style','template','filter')
+        self.start = None   # File reader cursor at start delimiter.
+        self.name=None      # Configuration file section name.
+        # Configuration parameters.
+        self.delimiter=None # Regular expression matching block delimiter.
+        self.delimiter_reo=None # Compiled delimiter.
+        self.template=None  # template section entry.
+        self.options=()     # options entry list.
+        self.presubs=None   # presubs/subs entry list.
+        self.postsubs=()    # postsubs entry list.
+        self.filter=None    # filter entry.
+        self.posattrs=()    # posattrs entry list.
+        self.style=None     # Default style.
+        self.styles=OrderedDict() # Each entry is a styles dictionary.
+        # Before a block is processed it's attributes (from it's
+        # attributes list) are merged with the block configuration parameters
+        # (by self.merge_attributes()) resulting in the template substitution
+        # dictionary (self.attributes) and the block's processing parameters
+        # (self.parameters).
+        self.attributes={}
+        # The names of block parameters.
+        self.PARAM_NAMES=('template','options','presubs','postsubs','filter')
+        self.parameters=None
+        # Leading delimiter match object.
+        self.mo=None
+    def short_name(self):
+        """ Return the text following the last dash in the section name."""
+        i = self.name.rfind('-')
+        if i == -1:
+            return self.name
+        else:
+            return self.name[i+1:]
+    def error(self, msg, cursor=None, halt=False):
+        message.error('[%s] %s' % (self.name,msg), cursor, halt)
+    def is_conf_entry(self,param):
+        """Return True if param matches an allowed configuration file entry
+        name."""
+        for s in self.CONF_ENTRIES:
+            if re.match('^'+s+'$',param):
+                return True
+        return False
+    def load(self,name,entries):
+        """Update block definition from section 'entries' dictionary."""
+        self.name = name
+        self.update_parameters(entries, self, all=True)
+    def update_parameters(self, src, dst=None, all=False):
+        """
+        Parse processing parameters from src dictionary to dst object.
+        dst defaults to self.parameters.
+        If all is True then copy src entries that aren't parameter names.
+        """
+        dst = dst or self.parameters
+        msg = '[%s] malformed entry %%s: %%s' % self.name
+        def copy(obj,k,v):
+            if isinstance(obj,dict):
+                obj[k] = v
+            else:
+                setattr(obj,k,v)
+        for k,v in src.items():
+            if not re.match(r'\d+',k) and not is_name(k):
+                raise EAsciiDoc, msg % (k,v)
+            if k == 'template':
+                if not is_name(v):
+                    raise EAsciiDoc, msg % (k,v)
+                copy(dst,k,v)
+            elif k == 'filter':
+                copy(dst,k,v)
+            elif k == 'options':
+                if isinstance(v,str):
+                    v = parse_options(v, (), msg % (k,v))
+                    # Merge with existing options.
+                    v = tuple(set(dst.options).union(set(v)))
+                copy(dst,k,v)
+            elif k in ('subs','presubs','postsubs'):
+                # Subs is an alias for presubs.
+                if k == 'subs': k = 'presubs'
+                if isinstance(v,str):
+                    v = parse_options(v, SUBS_OPTIONS, msg % (k,v))
+                copy(dst,k,v)
+            elif k == 'delimiter':
+                if v and is_re(v):
+                    copy(dst,k,v)
+                else:
+                    raise EAsciiDoc, msg % (k,v)
+            elif k == 'style':
+                if is_name(v):
+                    copy(dst,k,v)
+                else:
+                    raise EAsciiDoc, msg % (k,v)
+            elif k == 'posattrs':
+                v = parse_options(v, (), msg % (k,v))
+                copy(dst,k,v)
+            else:
+                mo = re.match(r'^(?P<style>.*)-style$',k)
+                if mo:
+                    if not v:
+                        raise EAsciiDoc, msg % (k,v)
+                    style = mo.group('style')
+                    if not is_name(style):
+                        raise EAsciiDoc, msg % (k,v)
+                    d = {}
+                    if not parse_named_attributes(v,d):
+                        raise EAsciiDoc, msg % (k,v)
+                    if 'subs' in d:
+                        # Subs is an alias for presubs.
+                        d['presubs'] = d['subs']
+                        del d['subs']
+                    self.styles[style] = d
+                elif all or k in self.PARAM_NAMES:
+                    copy(dst,k,v) # Derived class specific entries.
+    def get_param(self,name,params=None):
+        """
+        Return named processing parameter from params dictionary.
+        If the parameter is not in params look in self.parameters.
+        """
+        if params and name in params:
+            return params[name]
+        elif name in self.parameters:
+            return self.parameters[name]
+        else:
+            return None
+    def get_subs(self,params=None):
+        """
+        Return (presubs,postsubs) tuple.
+        """
+        presubs = self.get_param('presubs',params)
+        postsubs = self.get_param('postsubs',params)
+        return (presubs,postsubs)
+    def dump(self):
+        """Write block definition to stdout."""
+        write = lambda s: sys.stdout.write('%s%s' % (s,writer.newline))
+        write('['+self.name+']')
+        if self.is_conf_entry('delimiter'):
+            write('delimiter='+self.delimiter)
+        if self.template:
+            write('template='+self.template)
+        if self.options:
+            write('options='+','.join(self.options))
+        if self.presubs:
+            if self.postsubs:
+                write('presubs='+','.join(self.presubs))
+            else:
+                write('subs='+','.join(self.presubs))
+        if self.postsubs:
+            write('postsubs='+','.join(self.postsubs))
+        if self.filter:
+            write('filter='+self.filter)
+        if self.posattrs:
+            write('posattrs='+','.join(self.posattrs))
+        if self.style:
+            write('style='+self.style)
+        if self.styles:
+            for style,d in self.styles.items():
+                s = ''
+                for k,v in d.items(): s += '%s=%r,' % (k,v)
+                write('%s-style=%s' % (style,s[:-1]))
+    def validate(self):
+        """Validate block after the complete configuration has been loaded."""
+        if self.is_conf_entry('delimiter') and not self.delimiter:
+            raise EAsciiDoc,'[%s] missing delimiter' % self.name
+        if self.style:
+            if not is_name(self.style):
+                raise EAsciiDoc, 'illegal style name: %s' % self.style
+            if not self.style in self.styles:
+                if not isinstance(self,List):   # Lists don't have templates.
+                    message.warning('[%s] \'%s\' style not in %s' % (
+                        self.name,self.style,self.styles.keys()))
+        # Check all styles for missing templates.
+        all_styles_have_template = True
+        for k,v in self.styles.items():
+            t = v.get('template')
+            if t and not t in config.sections:
+                # Defer check if template name contains attributes.
+                if not re.search(r'{.+}',t):
+                    message.warning('missing template section: [%s]' % t)
+            if not t:
+                all_styles_have_template = False
+        # Check we have a valid template entry or alternatively that all the
+        # styles have templates.
+        if self.is_conf_entry('template') and not 'skip' in self.options:
+            if self.template:
+                if not self.template in config.sections:
+                    # Defer check if template name contains attributes.
+                    if not re.search(r'{.+}',self.template):
+                        message.warning('missing template section: [%s]'
+                                        % self.template)
+            elif not all_styles_have_template:
+                if not isinstance(self,List): # Lists don't have templates.
+                    message.warning('missing styles templates: [%s]' % self.name)
+    def isnext(self):
+        """Check if this block is next in document reader."""
+        result = False
+        reader.skip_blank_lines()
+        if reader.read_next():
+            if not self.delimiter_reo:
+                # Cache compiled delimiter optimization.
+                self.delimiter_reo = re.compile(self.delimiter)
+            mo = self.delimiter_reo.match(reader.read_next())
+            if mo:
+                self.mo = mo
+                result = True
+        return result
+    def translate(self):
+        """Translate block from document reader."""
+        if not self.presubs:
+            self.presubs = config.subsnormal
+        if reader.cursor:
+            self.start = reader.cursor[:]
+    def merge_attributes(self,attrs,params=[]):
+        """
+        Use the current blocks attribute list (attrs dictionary) to build a
+        dictionary of block processing parameters (self.parameters) and tag
+        substitution attributes (self.attributes).
+
+        1. Copy the default parameters (self.*) to self.parameters.
+        self.parameters are used internally to render the current block.
+        Optional params array of additional parameters.
+
+        2. Copy attrs to self.attributes. self.attributes are used for template
+        and tag substitution in the current block.
+
+        3. If a style attribute was specified update self.parameters with the
+        corresponding style parameters; if there are any style parameters
+        remaining add them to self.attributes (existing attribute list entries
+        take precedence).
+
+        4. Set named positional attributes in self.attributes if self.posattrs
+        was specified.
+
+        5. Finally self.parameters is updated with any corresponding parameters
+        specified in attrs.
+
+        """
+
+        def check_array_parameter(param):
+            # Check the parameter is a sequence type.
+            if not is_array(self.parameters[param]):
+                message.error('malformed presubs attribute: %s' %
+                        self.parameters[param])
+                # Revert to default value.
+                self.parameters[param] = getattr(self,param)
+
+        params = list(self.PARAM_NAMES) + params
+        self.attributes = {}
+        if self.style:
+            # If a default style is defined make it available in the template.
+            self.attributes['style'] = self.style
+        self.attributes.update(attrs)
+        # Calculate dynamic block parameters.
+        # Start with configuration file defaults.
+        self.parameters = AttrDict()
+        for name in params:
+            self.parameters[name] = getattr(self,name)
+        # Load the selected style attributes.
+        posattrs = self.posattrs
+        if posattrs and posattrs[0] == 'style':
+            # Positional attribute style has highest precedence.
+            style = self.attributes.get('1')
+        else:
+            style = None
+        if not style:
+            # Use explicit style attribute, fall back to default style.
+            style = self.attributes.get('style',self.style)
+        if style:
+            if not is_name(style):
+                message.error('illegal style name: %s' % style)
+                style = self.style
+            # Lists have implicit styles and do their own style checks.
+            elif style not in self.styles and not isinstance(self,List):
+                message.warning('missing style: [%s]: %s' % (self.name,style))
+                style = self.style
+            if style in self.styles:
+                self.attributes['style'] = style
+                for k,v in self.styles[style].items():
+                    if k == 'posattrs':
+                        posattrs = v
+                    elif k in params:
+                        self.parameters[k] = v
+                    elif not k in self.attributes:
+                        # Style attributes don't take precedence over explicit.
+                        self.attributes[k] = v
+        # Set named positional attributes.
+        for i,v in enumerate(posattrs):
+            if str(i+1) in self.attributes:
+                self.attributes[v] = self.attributes[str(i+1)]
+        # Override config and style attributes with attribute list attributes.
+        self.update_parameters(attrs)
+        check_array_parameter('options')
+        check_array_parameter('presubs')
+        check_array_parameter('postsubs')
+
+class AbstractBlocks:
+    """List of block definitions."""
+    PREFIX = ''         # Conf file section name prefix set in derived classes.
+    BLOCK_TYPE = None   # Block type set in derived classes.
+    def __init__(self):
+        self.current=None
+        self.blocks = []        # List of Block objects.
+        self.default = None     # Default Block.
+        self.delimiters = None  # Combined delimiters regular expression.
+    def load(self,sections):
+        """Load block definition from 'sections' dictionary."""
+        for k in sections.keys():
+            if re.match(r'^'+ self.PREFIX + r'.+$',k):
+                d = {}
+                parse_entries(sections.get(k,()),d)
+                for b in self.blocks:
+                    if b.name == k:
+                        break
+                else:
+                    b = self.BLOCK_TYPE()
+                    self.blocks.append(b)
+                try:
+                    b.load(k,d)
+                except EAsciiDoc,e:
+                    raise EAsciiDoc,'[%s] %s' % (k,str(e))
+    def dump(self):
+        for b in self.blocks:
+            b.dump()
+    def isnext(self):
+        for b in self.blocks:
+            if b.isnext():
+                self.current = b
+                return True;
+        return False
+    def validate(self):
+        """Validate the block definitions."""
+        # Validate delimiters and build combined lists delimiter pattern.
+        delimiters = []
+        for b in self.blocks:
+            assert b.__class__ is self.BLOCK_TYPE
+            b.validate()
+            if b.delimiter:
+                delimiters.append(b.delimiter)
+        self.delimiters = re_join(delimiters)
+
+class Paragraph(AbstractBlock):
+    def __init__(self):
+        AbstractBlock.__init__(self)
+        self.text=None          # Text in first line of paragraph.
+    def load(self,name,entries):
+        AbstractBlock.load(self,name,entries)
+    def dump(self):
+        AbstractBlock.dump(self)
+        write = lambda s: sys.stdout.write('%s%s' % (s,writer.newline))
+        write('')
+    def isnext(self):
+        result = AbstractBlock.isnext(self)
+        if result:
+            self.text = self.mo.groupdict().get('text')
+        return result
+    def translate(self):
+        AbstractBlock.translate(self)
+        attrs = self.mo.groupdict().copy()
+        if 'text' in attrs: del attrs['text']
+        BlockTitle.consume(attrs)
+        AttributeList.consume(attrs)
+        self.merge_attributes(attrs)
+        reader.read()   # Discard (already parsed item first line).
+        body = reader.read_until(paragraphs.terminators)
+        body = [self.text] + list(body)
+        presubs = self.parameters.presubs
+        postsubs = self.parameters.postsubs
+        if document.attributes.get('plaintext') is None:
+            body = Lex.set_margin(body) # Move body to left margin.
+        body = Lex.subs(body,presubs)
+        template = self.parameters.template
+        template = subs_attrs(template,attrs)
+        stag = config.section2tags(template, self.attributes,skipend=True)[0]
+        if self.parameters.filter:
+            body = filter_lines(self.parameters.filter,body,self.attributes)
+        body = Lex.subs(body,postsubs)
+        etag = config.section2tags(template, self.attributes,skipstart=True)[1]
+        # Write start tag, content, end tag.
+        writer.write(dovetail_tags(stag,body,etag),trace='paragraph')
+
+class Paragraphs(AbstractBlocks):
+    """List of paragraph definitions."""
+    BLOCK_TYPE = Paragraph
+    PREFIX = 'paradef-'
+    def __init__(self):
+        AbstractBlocks.__init__(self)
+        self.terminators=None    # List of compiled re's.
+    def initialize(self):
+        self.terminators = [
+                re.compile(r'^\+$|^$'),
+                re.compile(AttributeList.pattern),
+                re.compile(blocks.delimiters),
+                re.compile(tables.delimiters),
+                re.compile(tables_OLD.delimiters),
+            ]
+    def load(self,sections):
+        AbstractBlocks.load(self,sections)
+    def validate(self):
+        AbstractBlocks.validate(self)
+        # Check we have a default paragraph definition, put it last in list.
+        for b in self.blocks:
+            if b.name == 'paradef-default':
+                self.blocks.append(b)
+                self.default = b
+                self.blocks.remove(b)
+                break
+        else:
+            raise EAsciiDoc,'missing section: [paradef-default]'
+
+class List(AbstractBlock):
+    NUMBER_STYLES= ('arabic','loweralpha','upperalpha','lowerroman',
+                    'upperroman')
+    def __init__(self):
+        AbstractBlock.__init__(self)
+        self.CONF_ENTRIES += ('type','tags')
+        self.PARAM_NAMES += ('tags',)
+        # tabledef conf file parameters.
+        self.type=None
+        self.tags=None      # Name of listtags-<tags> conf section.
+        # Calculated parameters.
+        self.tag=None       # Current tags AttrDict.
+        self.label=None     # List item label (labeled lists).
+        self.text=None      # Text in first line of list item.
+        self.index=None     # Matched delimiter 'index' group (numbered lists).
+        self.type=None      # List type ('numbered','bulleted','labeled').
+        self.ordinal=None   # Current list item ordinal number (1..)
+        self.number_style=None # Current numbered list style ('arabic'..)
+    def load(self,name,entries):
+        AbstractBlock.load(self,name,entries)
+    def dump(self):
+        AbstractBlock.dump(self)
+        write = lambda s: sys.stdout.write('%s%s' % (s,writer.newline))
+        write('type='+self.type)
+        write('tags='+self.tags)
+        write('')
+    def validate(self):
+        AbstractBlock.validate(self)
+        tags = [self.tags]
+        tags += [s['tags'] for s in self.styles.values() if 'tags' in s]
+        for t in tags:
+            if t not in lists.tags:
+                self.error('missing section: [listtags-%s]' % t,halt=True)
+    def isnext(self):
+        result = AbstractBlock.isnext(self)
+        if result:
+            self.label = self.mo.groupdict().get('label')
+            self.text = self.mo.groupdict().get('text')
+            self.index = self.mo.groupdict().get('index')
+        return result
+    def translate_entry(self):
+        assert self.type == 'labeled'
+        entrytag = subs_tag(self.tag.entry, self.attributes)
+        labeltag = subs_tag(self.tag.label, self.attributes)
+        writer.write(entrytag[0],trace='list entry open')
+        writer.write(labeltag[0],trace='list label open')
+        # Write labels.
+        while Lex.next() is self:
+            reader.read()   # Discard (already parsed item first line).
+            writer.write_tag(self.tag.term, [self.label],
+                             self.presubs, self.attributes,trace='list term')
+            if self.text: break
+        writer.write(labeltag[1],trace='list label close')
+        # Write item text.
+        self.translate_item()
+        writer.write(entrytag[1],trace='list entry close')
+    def translate_item(self):
+        if self.type == 'callout':
+            self.attributes['coids'] = calloutmap.calloutids(self.ordinal)
+        itemtag = subs_tag(self.tag.item, self.attributes)
+        writer.write(itemtag[0],trace='list item open')
+        # Write ItemText.
+        text = reader.read_until(lists.terminators)
+        if self.text:
+            text = [self.text] + list(text)
+        if text:
+            writer.write_tag(self.tag.text, text, self.presubs, self.attributes,trace='list text')
+        # Process explicit and implicit list item continuations.
+        while True:
+            continuation = reader.read_next() == '+'
+            if continuation: reader.read()  # Discard continuation line.
+            while Lex.next() in (BlockTitle,AttributeList):
+                # Consume continued element title and attributes.
+                Lex.next().translate()
+            if not continuation and BlockTitle.title:
+                # Titled elements terminate the list.
+                break
+            next = Lex.next()
+            if next in lists.open:
+                break
+            elif isinstance(next,List):
+                next.translate()
+            elif isinstance(next,Paragraph) and 'listelement' in next.options:
+                next.translate()
+            elif continuation:
+                # This is where continued elements are processed.
+                if next is Title:
+                    message.error('section title not allowed in list item',halt=True)
+                next.translate()
+            else:
+                break
+        writer.write(itemtag[1],trace='list item close')
+
+    @staticmethod
+    def calc_style(index):
+        """Return the numbered list style ('arabic'...) of the list item index.
+        Return None if unrecognized style."""
+        if re.match(r'^\d+[\.>]$', index):
+            style = 'arabic'
+        elif re.match(r'^[ivx]+\)$', index):
+            style = 'lowerroman'
+        elif re.match(r'^[IVX]+\)$', index):
+            style = 'upperroman'
+        elif re.match(r'^[a-z]\.$', index):
+            style = 'loweralpha'
+        elif re.match(r'^[A-Z]\.$', index):
+            style = 'upperalpha'
+        else:
+            assert False
+        return style
+
+    @staticmethod
+    def calc_index(index,style):
+        """Return the ordinal number of (1...) of the list item index
+        for the given list style."""
+        def roman_to_int(roman):
+            roman = roman.lower()
+            digits = {'i':1,'v':5,'x':10}
+            result = 0
+            for i in range(len(roman)):
+                digit = digits[roman[i]]
+                # If next digit is larger this digit is negative.
+                if i+1 < len(roman) and digits[roman[i+1]] > digit:
+                    result -= digit
+                else:
+                    result += digit
+            return result
+        index = index[:-1]
+        if style == 'arabic':
+            ordinal = int(index)
+        elif style == 'lowerroman':
+            ordinal = roman_to_int(index)
+        elif style == 'upperroman':
+            ordinal = roman_to_int(index)
+        elif style == 'loweralpha':
+            ordinal = ord(index) - ord('a') + 1
+        elif style == 'upperalpha':
+            ordinal = ord(index) - ord('A') + 1
+        else:
+            assert False
+        return ordinal
+
+    def check_index(self):
+        """Check calculated self.ordinal (1,2,...) against the item number
+        in the document (self.index) and check the number style is the same as
+        the first item (self.number_style)."""
+        assert self.type in ('numbered','callout')
+        if self.index:
+            style = self.calc_style(self.index)
+            if style != self.number_style:
+                message.warning('list item style: expected %s got %s' %
+                        (self.number_style,style), offset=1)
+            ordinal = self.calc_index(self.index,style)
+            if ordinal != self.ordinal:
+                message.warning('list item index: expected %s got %s' %
+                        (self.ordinal,ordinal), offset=1)
+
+    def check_tags(self):
+        """ Check that all necessary tags are present. """
+        tags = set(Lists.TAGS)
+        if self.type != 'labeled':
+            tags = tags.difference(['entry','label','term'])
+        missing = tags.difference(self.tag.keys())
+        if missing:
+            self.error('missing tag(s): %s' % ','.join(missing), halt=True)
+    def translate(self):
+        AbstractBlock.translate(self)
+        if self.short_name() in ('bibliography','glossary','qanda'):
+            message.deprecated('old %s list syntax' % self.short_name())
+        lists.open.append(self)
+        attrs = self.mo.groupdict().copy()
+        for k in ('label','text','index'):
+            if k in attrs: del attrs[k]
+        if self.index:
+            # Set the numbering style from first list item.
+            attrs['style'] = self.calc_style(self.index)
+        BlockTitle.consume(attrs)
+        AttributeList.consume(attrs)
+        self.merge_attributes(attrs,['tags'])
+        if self.type in ('numbered','callout'):
+            self.number_style = self.attributes.get('style')
+            if self.number_style not in self.NUMBER_STYLES:
+                message.error('illegal numbered list style: %s' % self.number_style)
+                # Fall back to default style.
+                self.attributes['style'] = self.number_style = self.style
+        self.tag = lists.tags[self.parameters.tags]
+        self.check_tags()
+        if 'width' in self.attributes:
+            # Set horizontal list 'labelwidth' and 'itemwidth' attributes.
+            v = str(self.attributes['width'])
+            mo = re.match(r'^(\d{1,2})%?$',v)
+            if mo:
+                labelwidth = int(mo.group(1))
+                self.attributes['labelwidth'] = str(labelwidth)
+                self.attributes['itemwidth'] = str(100-labelwidth)
+            else:
+                self.error('illegal attribute value: width="%s"' % v)
+        stag,etag = subs_tag(self.tag.list, self.attributes)
+        if stag:
+            writer.write(stag,trace='list open')
+        self.ordinal = 0
+        # Process list till list syntax changes or there is a new title.
+        while Lex.next() is self and not BlockTitle.title:
+            self.ordinal += 1
+            document.attributes['listindex'] = str(self.ordinal)
+            if self.type in ('numbered','callout'):
+                self.check_index()
+            if self.type in ('bulleted','numbered','callout'):
+                reader.read()   # Discard (already parsed item first line).
+                self.translate_item()
+            elif self.type == 'labeled':
+                self.translate_entry()
+            else:
+                raise AssertionError,'illegal [%s] list type' % self.name
+        if etag:
+            writer.write(etag,trace='list close')
+        if self.type == 'callout':
+            calloutmap.validate(self.ordinal)
+            calloutmap.listclose()
+        lists.open.pop()
+        if len(lists.open):
+            document.attributes['listindex'] = str(lists.open[-1].ordinal)
+
+class Lists(AbstractBlocks):
+    """List of List objects."""
+    BLOCK_TYPE = List
+    PREFIX = 'listdef-'
+    TYPES = ('bulleted','numbered','labeled','callout')
+    TAGS = ('list', 'entry','item','text', 'label','term')
+    def __init__(self):
+        AbstractBlocks.__init__(self)
+        self.open = []  # A stack of the current and parent lists.
+        self.tags={}    # List tags dictionary. Each entry is a tags AttrDict.
+        self.terminators=None    # List of compiled re's.
+    def initialize(self):
+        self.terminators = [
+                re.compile(r'^\+$|^$'),
+                re.compile(AttributeList.pattern),
+                re.compile(lists.delimiters),
+                re.compile(blocks.delimiters),
+                re.compile(tables.delimiters),
+                re.compile(tables_OLD.delimiters),
+            ]
+    def load(self,sections):
+        AbstractBlocks.load(self,sections)
+        self.load_tags(sections)
+    def load_tags(self,sections):
+        """
+        Load listtags-* conf file sections to self.tags.
+        """
+        for section in sections.keys():
+            mo = re.match(r'^listtags-(?P<name>\w+)$',section)
+            if mo:
+                name = mo.group('name')
+                if name in self.tags:
+                    d = self.tags[name]
+                else:
+                    d = AttrDict()
+                parse_entries(sections.get(section,()),d)
+                for k in d.keys():
+                    if k not in self.TAGS:
+                        message.warning('[%s] contains illegal list tag: %s' %
+                                (section,k))
+                self.tags[name] = d
+    def validate(self):
+        AbstractBlocks.validate(self)
+        for b in self.blocks:
+            # Check list has valid type.
+            if not b.type in Lists.TYPES:
+                raise EAsciiDoc,'[%s] illegal type' % b.name
+            b.validate()
+    def dump(self):
+        AbstractBlocks.dump(self)
+        for k,v in self.tags.items():
+            dump_section('listtags-'+k, v)
+
+
+class DelimitedBlock(AbstractBlock):
+    def __init__(self):
+        AbstractBlock.__init__(self)
+    def load(self,name,entries):
+        AbstractBlock.load(self,name,entries)
+    def dump(self):
+        AbstractBlock.dump(self)
+        write = lambda s: sys.stdout.write('%s%s' % (s,writer.newline))
+        write('')
+    def isnext(self):
+        return AbstractBlock.isnext(self)
+    def translate(self):
+        AbstractBlock.translate(self)
+        reader.read()   # Discard delimiter.
+        attrs = {}
+        if self.short_name() != 'comment':
+            BlockTitle.consume(attrs)
+            AttributeList.consume(attrs)
+        self.merge_attributes(attrs)
+        options = self.parameters.options
+        if 'skip' in options:
+            reader.read_until(self.delimiter,same_file=True)
+        elif safe() and self.name == 'blockdef-backend':
+            message.unsafe('Backend Block')
+            reader.read_until(self.delimiter,same_file=True)
+        else:
+            template = self.parameters.template
+            template = subs_attrs(template,attrs)
+            name = self.short_name()+' block'
+            if 'sectionbody' in options:
+                # The body is treated like a section body.
+                stag,etag = config.section2tags(template,self.attributes)
+                writer.write(stag,trace=name+' open')
+                Section.translate_body(self)
+                writer.write(etag,trace=name+' close')
+            else:
+                stag = config.section2tags(template,self.attributes,skipend=True)[0]
+                body = reader.read_until(self.delimiter,same_file=True)
+                presubs = self.parameters.presubs
+                postsubs = self.parameters.postsubs
+                body = Lex.subs(body,presubs)
+                if self.parameters.filter:
+                    body = filter_lines(self.parameters.filter,body,self.attributes)
+                body = Lex.subs(body,postsubs)
+                # Write start tag, content, end tag.
+                etag = config.section2tags(template,self.attributes,skipstart=True)[1]
+                writer.write(dovetail_tags(stag,body,etag),trace=name)
+            trace(self.short_name()+' block close',etag)
+        if reader.eof():
+            self.error('missing closing delimiter',self.start)
+        else:
+            delimiter = reader.read()   # Discard delimiter line.
+            assert re.match(self.delimiter,delimiter)
+
+class DelimitedBlocks(AbstractBlocks):
+    """List of delimited blocks."""
+    BLOCK_TYPE = DelimitedBlock
+    PREFIX = 'blockdef-'
+    def __init__(self):
+        AbstractBlocks.__init__(self)
+    def load(self,sections):
+        """Update blocks defined in 'sections' dictionary."""
+        AbstractBlocks.load(self,sections)
+    def validate(self):
+        AbstractBlocks.validate(self)
+
+class Column:
+    """Table column."""
+    def __init__(self, width=None, align_spec=None, style=None):
+        self.width = width or '1'
+        self.halign, self.valign = Table.parse_align_spec(align_spec)
+        self.style = style      # Style name or None.
+        # Calculated attribute values.
+        self.abswidth = None    # 1..   (page units).
+        self.pcwidth = None     # 1..99 (percentage).
+
+class Cell:
+    def __init__(self, data, span_spec=None, align_spec=None, style=None):
+        self.data = data
+        self.span, self.vspan = Table.parse_span_spec(span_spec)
+        self.halign, self.valign = Table.parse_align_spec(align_spec)
+        self.style = style
+    def __repr__(self):
+        return '<Cell: %d.%d %s.%s %s "%s">' % (
+                self.span, self.vspan,
+                self.halign, self.valign,
+                self.style or '',
+                self.data)
+
+class Table(AbstractBlock):
+    ALIGN = {'<':'left', '>':'right', '^':'center'}
+    VALIGN = {'<':'top', '>':'bottom', '^':'middle'}
+    FORMATS = ('psv','csv','dsv')
+    SEPARATORS = dict(
+        csv=',',
+        dsv=r':|\n',
+        # The count and align group matches are not exact.
+        psv=r'((?<!\S)((?P<span>[\d.]+)(?P<op>[*+]))?(?P<align>[<\^>.]{,3})?(?P<style>[a-z])?)?\|'
+    )
+    def __init__(self):
+        AbstractBlock.__init__(self)
+        self.CONF_ENTRIES += ('format','tags','separator')
+        # tabledef conf file parameters.
+        self.format='psv'
+        self.separator=None
+        self.tags=None          # Name of tabletags-<tags> conf section.
+        # Calculated parameters.
+        self.abswidth=None      # 1..   (page units).
+        self.pcwidth = None     # 1..99 (percentage).
+        self.rows=[]            # Parsed rows, each row is a list of Cells.
+        self.columns=[]         # List of Columns.
+    @staticmethod
+    def parse_align_spec(align_spec):
+        """
+        Parse AsciiDoc cell alignment specifier and return 2-tuple with
+        horizonatal and vertical alignment names. Unspecified alignments
+        set to None.
+        """
+        result = (None, None)
+        if align_spec:
+            mo = re.match(r'^([<\^>])?(\.([<\^>]))?$', align_spec)
+            if mo:
+                result = (Table.ALIGN.get(mo.group(1)),
+                          Table.VALIGN.get(mo.group(3)))
+        return result
+    @staticmethod
+    def parse_span_spec(span_spec):
+        """
+        Parse AsciiDoc cell span specifier and return 2-tuple with horizonatal
+        and vertical span counts. Set default values (1,1) if not
+        specified.
+        """
+        result = (None, None)
+        if span_spec:
+            mo = re.match(r'^(\d+)?(\.(\d+))?$', span_spec)
+            if mo:
+                result = (mo.group(1) and int(mo.group(1)),
+                          mo.group(3) and int(mo.group(3)))
+        return (result[0] or 1, result[1] or 1)
+    def load(self,name,entries):
+        AbstractBlock.load(self,name,entries)
+    def dump(self):
+        AbstractBlock.dump(self)
+        write = lambda s: sys.stdout.write('%s%s' % (s,writer.newline))
+        write('format='+self.format)
+        write('')
+    def validate(self):
+        AbstractBlock.validate(self)
+        if self.format not in Table.FORMATS:
+            self.error('illegal format=%s' % self.format,halt=True)
+        self.tags = self.tags or 'default'
+        tags = [self.tags]
+        tags += [s['tags'] for s in self.styles.values() if 'tags' in s]
+        for t in tags:
+            if t not in tables.tags:
+                self.error('missing section: [tabletags-%s]' % t,halt=True)
+        if self.separator:
+            # Evaluate escape characters.
+            self.separator = eval('"'+self.separator+'"')
+        #TODO: Move to class Tables
+        # Check global table parameters.
+        elif config.pagewidth is None:
+            self.error('missing [miscellaneous] entry: pagewidth')
+        elif config.pageunits is None:
+            self.error('missing [miscellaneous] entry: pageunits')
+    def validate_attributes(self):
+        """Validate and parse table attributes."""
+        # Set defaults.
+        format = self.format
+        tags = self.tags
+        separator = self.separator
+        abswidth = float(config.pagewidth)
+        pcwidth = 100.0
+        for k,v in self.attributes.items():
+            if k == 'format':
+                if v not in self.FORMATS:
+                    self.error('illegal %s=%s' % (k,v))
+                else:
+                    format = v
+            elif k == 'tags':
+                if v not in tables.tags:
+                    self.error('illegal %s=%s' % (k,v))
+                else:
+                    tags = v
+            elif k == 'separator':
+                separator = v
+            elif k == 'width':
+                if not re.match(r'^\d{1,3}%$',v) or int(v[:-1]) > 100:
+                    self.error('illegal %s=%s' % (k,v))
+                else:
+                    abswidth = float(v[:-1])/100 * config.pagewidth
+                    pcwidth = float(v[:-1])
+        # Calculate separator if it has not been specified.
+        if not separator:
+            separator = Table.SEPARATORS[format]
+        if format == 'csv':
+            if len(separator) > 1:
+                self.error('illegal csv separator=%s' % separator)
+                separator = ','
+        else:
+            if not is_re(separator):
+                self.error('illegal regular expression: separator=%s' %
+                        separator)
+        self.parameters.format = format
+        self.parameters.tags = tags
+        self.parameters.separator = separator
+        self.abswidth = abswidth
+        self.pcwidth = pcwidth
+    def get_tags(self,params):
+        tags = self.get_param('tags',params)
+        assert(tags and tags in tables.tags)
+        return tables.tags[tags]
+    def get_style(self,prefix):
+        """
+        Return the style dictionary whose name starts with 'prefix'.
+        """
+        if prefix is None:
+            return None
+        names = self.styles.keys()
+        names.sort()
+        for name in names:
+            if name.startswith(prefix):
+                return self.styles[name]
+        else:
+            self.error('missing style: %s*' % prefix)
+            return None
+    def parse_cols(self, cols, halign, valign):
+        """
+        Build list of column objects from table 'cols', 'halign' and 'valign'
+        attributes.
+        """
+        # [<multiplier>*][<align>][<width>][<style>]
+        COLS_RE1 = r'^((?P<count>\d+)\*)?(?P<align>[<\^>.]{,3})?(?P<width>\d+%?)?(?P<style>[a-z]\w*)?$'
+        # [<multiplier>*][<width>][<align>][<style>]
+        COLS_RE2 = r'^((?P<count>\d+)\*)?(?P<width>\d+%?)?(?P<align>[<\^>.]{,3})?(?P<style>[a-z]\w*)?$'
+        reo1 = re.compile(COLS_RE1)
+        reo2 = re.compile(COLS_RE2)
+        cols = str(cols)
+        if re.match(r'^\d+$',cols):
+            for i in range(int(cols)):
+                self.columns.append(Column())
+        else:
+            for col in re.split(r'\s*,\s*',cols):
+                mo = reo1.match(col)
+                if not mo:
+                    mo = reo2.match(col)
+                if mo:
+                    count = int(mo.groupdict().get('count') or 1)
+                    for i in range(count):
+                        self.columns.append(
+                            Column(mo.group('width'), mo.group('align'),
+                                   self.get_style(mo.group('style')))
+                        )
+                else:
+                    self.error('illegal column spec: %s' % col,self.start)
+        # Set column (and indirectly cell) default alignments.
+        for col in self.columns:
+            col.halign = col.halign or halign or document.attributes.get('halign') or 'left'
+            col.valign = col.valign or valign or document.attributes.get('valign') or 'top'
+        # Validate widths and calculate missing widths.
+        n = 0; percents = 0; props = 0
+        for col in self.columns:
+            if col.width:
+                if col.width[-1] == '%': percents += int(col.width[:-1])
+                else: props += int(col.width)
+                n += 1
+        if percents > 0 and props > 0:
+            self.error('mixed percent and proportional widths: %s'
+                    % cols,self.start)
+        pcunits = percents > 0
+        # Fill in missing widths.
+        if n < len(self.columns) and percents < 100:
+            if pcunits:
+                width = float(100 - percents)/float(len(self.columns) - n)
+            else:
+                width = 1
+            for col in self.columns:
+                if not col.width:
+                    if pcunits:
+                        col.width = str(int(width))+'%'
+                        percents += width
+                    else:
+                        col.width = str(width)
+                        props += width
+        # Calculate column alignment and absolute and percent width values.
+        percents = 0
+        for col in self.columns:
+            if pcunits:
+                col.pcwidth = float(col.width[:-1])
+            else:
+                col.pcwidth = (float(col.width)/props)*100
+            col.abswidth = self.abswidth * (col.pcwidth/100)
+            if config.pageunits in ('cm','mm','in','em'):
+                col.abswidth = '%.2f' % round(col.abswidth,2)
+            else:
+                col.abswidth = '%d' % round(col.abswidth)
+            percents += col.pcwidth
+            col.pcwidth = int(col.pcwidth)
+        if round(percents) > 100:
+            self.error('total width exceeds 100%%: %s' % cols,self.start)
+        elif round(percents) < 100:
+            self.error('total width less than 100%%: %s' % cols,self.start)
+    def build_colspecs(self):
+        """
+        Generate column related substitution attributes.
+        """
+        cols = []
+        i = 1
+        for col in self.columns:
+            colspec = self.get_tags(col.style).colspec
+            if colspec:
+                self.attributes['halign'] = col.halign
+                self.attributes['valign'] = col.valign
+                self.attributes['colabswidth'] = col.abswidth
+                self.attributes['colpcwidth'] = col.pcwidth
+                self.attributes['colnumber'] = str(i)
+                s = subs_attrs(colspec, self.attributes)
+                if not s:
+                    message.warning('colspec dropped: contains undefined attribute')
+                else:
+                    cols.append(s)
+            i += 1
+        if cols:
+            self.attributes['colspecs'] = writer.newline.join(cols)
+    def parse_rows(self, text):
+        """
+        Parse the table source text into self.rows (a list of rows, each row
+        is a list of Cells.
+        """
+        reserved = {}  # Cols reserved by rowspans (indexed by row number).
+        if self.parameters.format in ('psv','dsv'):
+            ri = 0  # Current row index 0..
+            cells = self.parse_psv_dsv(text)
+            row = []
+            ci = 0  # Column counter 0..colcount
+            for cell in cells:
+                colcount = len(self.columns) - reserved.get(ri,0)
+                if cell.vspan > 1:
+                    # Reserve spanned columns from ensuing rows.
+                    for i in range(1, cell.vspan):
+                        reserved[ri+i] = reserved.get(ri+i, 0) + cell.span
+                ci += cell.span
+                if ci <= colcount:
+                    row.append(cell)
+                if ci >= colcount:
+                    self.rows.append(row)
+                    ri += 1
+                    row = []
+                    ci = 0
+                if ci > colcount:
+                    message.warning('table row %d: span exceeds number of columns'
+                            % ri)
+        elif self.parameters.format == 'csv':
+            self.rows = self.parse_csv(text)
+        else:
+            assert True,'illegal table format'
+        # Check that all row spans match.
+        for ri,row in enumerate(self.rows):
+            row_span = 0
+            for cell in row:
+                row_span += cell.span
+            row_span += reserved.get(ri,0)
+            if ri == 0:
+                header_span = row_span
+            if row_span < header_span:
+                message.warning('table row %d: does not span all columns' % (ri+1))
+            if row_span > header_span:
+                message.warning('table row %d: exceeds columns span' % (ri+1))
+        # Check that now row spans exceed the number of rows.
+        if len([x for x in reserved.keys() if x >= len(self.rows)]) > 0:
+            message.warning('one or more cell spans exceed the available rows')
+    def subs_rows(self, rows, rowtype='body'):
+        """
+        Return a string of output markup from a list of rows, each row
+        is a list of raw data text.
+        """
+        tags = tables.tags[self.parameters.tags]
+        if rowtype == 'header':
+            rtag = tags.headrow
+        elif rowtype == 'footer':
+            rtag = tags.footrow
+        else:
+            rtag = tags.bodyrow
+        result = []
+        stag,etag = subs_tag(rtag,self.attributes)
+        for row in rows:
+            result.append(stag)
+            result += self.subs_row(row,rowtype)
+            result.append(etag)
+        return writer.newline.join(result)
+    def subs_row(self, row, rowtype):
+        """
+        Substitute the list of Cells using the data tag.
+        Returns a list of marked up table cell elements.
+        """
+        result = []
+        i = 0
+        for cell in row:
+            if i >= len(self.columns):
+                break   # Skip cells outside the header width.
+            col = self.columns[i]
+            self.attributes['halign'] = cell.halign or col.halign
+            self.attributes['valign'] = cell.valign or  col.valign
+            self.attributes['colabswidth'] = col.abswidth
+            self.attributes['colpcwidth'] = col.pcwidth
+            self.attributes['colnumber'] = str(i+1)
+            self.attributes['colspan'] = str(cell.span)
+            self.attributes['colstart'] = self.attributes['colnumber']
+            self.attributes['colend'] = str(i+cell.span)
+            self.attributes['rowspan'] = str(cell.vspan)
+            self.attributes['morerows'] = str(cell.vspan-1)
+            # Fill missing column data with blanks.
+            if i > len(self.columns) - 1:
+                data = ''
+            else:
+                data = cell.data
+            if rowtype == 'header':
+                # Use table style unless overriden by cell style.
+                colstyle = cell.style
+            else:
+                # If the cell style is not defined use the column style.
+                colstyle = cell.style or col.style
+            tags = self.get_tags(colstyle)
+            presubs,postsubs = self.get_subs(colstyle)
+            data = [data]
+            data = Lex.subs(data, presubs)
+            data = filter_lines(self.get_param('filter',colstyle),
+                                data, self.attributes)
+            data = Lex.subs(data, postsubs)
+            if rowtype != 'header':
+                ptag = tags.paragraph
+                if ptag:
+                    stag,etag = subs_tag(ptag,self.attributes)
+                    text = '\n'.join(data).strip()
+                    data = []
+                    for para in re.split(r'\n{2,}',text):
+                        data += dovetail_tags([stag],para.split('\n'),[etag])
+            if rowtype == 'header':
+                dtag = tags.headdata
+            elif rowtype == 'footer':
+                dtag = tags.footdata
+            else:
+                dtag = tags.bodydata
+            stag,etag = subs_tag(dtag,self.attributes)
+            result = result + dovetail_tags([stag],data,[etag])
+            i += cell.span
+        return result
+    def parse_csv(self,text):
+        """
+        Parse the table source text and return a list of rows, each row
+        is a list of Cells.
+        """
+        import StringIO
+        import csv
+        rows = []
+        rdr = csv.reader(StringIO.StringIO('\r\n'.join(text)),
+                     delimiter=self.parameters.separator, skipinitialspace=True)
+        try:
+            for row in rdr:
+                rows.append([Cell(data) for data in row])
+        except Exception:
+            self.error('csv parse error: %s' % row)
+        return rows
+    def parse_psv_dsv(self,text):
+        """
+        Parse list of PSV or DSV table source text lines and return a list of
+        Cells.
+        """
+        def append_cell(data, span_spec, op, align_spec, style):
+            op = op or '+'
+            if op == '*':   # Cell multiplier.
+                span = Table.parse_span_spec(span_spec)[0]
+                for i in range(span):
+                    cells.append(Cell(data, '1', align_spec, style))
+            elif op == '+': # Column spanner.
+                cells.append(Cell(data, span_spec, align_spec, style))
+            else:
+                self.error('illegal table cell operator')
+        text = '\n'.join(text)
+        separator = '(?msu)'+self.parameters.separator
+        format = self.parameters.format
+        start = 0
+        span = None
+        op = None
+        align = None
+        style = None
+        cells = []
+        data = ''
+        for mo in re.finditer(separator,text):
+            data += text[start:mo.start()]
+            if data.endswith('\\'):
+                data = data[:-1]+mo.group() # Reinstate escaped separators.
+            else:
+                append_cell(data, span, op, align, style)
+                span = mo.groupdict().get('span')
+                op = mo.groupdict().get('op')
+                align = mo.groupdict().get('align')
+                style = mo.groupdict().get('style')
+                if style:
+                    style = self.get_style(style)
+                data = ''
+            start = mo.end()
+        # Last cell follows final separator.
+        data += text[start:]
+        append_cell(data, span, op, align, style)
+        # We expect a dummy blank item preceeding first PSV cell.
+        if format == 'psv':
+            if cells[0].data.strip() != '':
+                self.error('missing leading separator: %s' % separator,
+                        self.start)
+            else:
+                cells.pop(0)
+        return cells
+    def translate(self):
+        AbstractBlock.translate(self)
+        reader.read()   # Discard delimiter.
+        # Reset instance specific properties.
+        self.columns = []
+        self.rows = []
+        attrs = {}
+        BlockTitle.consume(attrs)
+        # Mix in document attribute list.
+        AttributeList.consume(attrs)
+        self.merge_attributes(attrs)
+        self.validate_attributes()
+        # Add global and calculated configuration parameters.
+        self.attributes['pagewidth'] = config.pagewidth
+        self.attributes['pageunits'] = config.pageunits
+        self.attributes['tableabswidth'] = int(self.abswidth)
+        self.attributes['tablepcwidth'] = int(self.pcwidth)
+        # Read the entire table.
+        text = reader.read_until(self.delimiter)
+        if reader.eof():
+            self.error('missing closing delimiter',self.start)
+        else:
+            delimiter = reader.read()   # Discard closing delimiter.
+            assert re.match(self.delimiter,delimiter)
+        if len(text) == 0:
+            message.warning('[%s] table is empty' % self.name)
+            return
+        cols = attrs.get('cols')
+        if not cols:
+            # Calculate column count from number of items in first line.
+            if self.parameters.format == 'csv':
+                cols = text[0].count(self.parameters.separator) + 1
+            else:
+                cols = 0
+                for cell in self.parse_psv_dsv(text[:1]):
+                    cols += cell.span
+        self.parse_cols(cols, attrs.get('halign'), attrs.get('valign'))
+        # Set calculated attributes.
+        self.attributes['colcount'] = len(self.columns)
+        self.build_colspecs()
+        self.parse_rows(text)
+        # The 'rowcount' attribute is used by the experimental LaTeX backend.
+        self.attributes['rowcount'] = str(len(self.rows))
+        # Generate headrows, footrows, bodyrows.
+        # Headrow, footrow and bodyrow data replaces same named attributes in
+        # the table markup template. In order to ensure this data does not get
+        # a second attribute substitution (which would interfere with any
+        # already substituted inline passthroughs) unique placeholders are used
+        # (the tab character does not appear elsewhere since it is expanded on
+        # input) which are replaced after template attribute substitution.
+        headrows = footrows = bodyrows = None
+        if self.rows and 'header' in self.parameters.options:
+            headrows = self.subs_rows(self.rows[0:1],'header')
+            self.attributes['headrows'] = '\x07headrows\x07'
+            self.rows = self.rows[1:]
+        if self.rows and 'footer' in self.parameters.options:
+            footrows = self.subs_rows( self.rows[-1:], 'footer')
+            self.attributes['footrows'] = '\x07footrows\x07'
+            self.rows = self.rows[:-1]
+        if self.rows:
+            bodyrows = self.subs_rows(self.rows)
+            self.attributes['bodyrows'] = '\x07bodyrows\x07'
+        table = subs_attrs(config.sections[self.parameters.template],
+                           self.attributes)
+        table = writer.newline.join(table)
+        # Before we finish replace the table head, foot and body place holders
+        # with the real data.
+        if headrows:
+            table = table.replace('\x07headrows\x07', headrows, 1)
+        if footrows:
+            table = table.replace('\x07footrows\x07', footrows, 1)
+        if bodyrows:
+            table = table.replace('\x07bodyrows\x07', bodyrows, 1)
+        writer.write(table,trace='table')
+
+class Tables(AbstractBlocks):
+    """List of tables."""
+    BLOCK_TYPE = Table
+    PREFIX = 'tabledef-'
+    TAGS = ('colspec', 'headrow','footrow','bodyrow',
+            'headdata','footdata', 'bodydata','paragraph')
+    def __init__(self):
+        AbstractBlocks.__init__(self)
+        # Table tags dictionary. Each entry is a tags dictionary.
+        self.tags={}
+    def load(self,sections):
+        AbstractBlocks.load(self,sections)
+        self.load_tags(sections)
+    def load_tags(self,sections):
+        """
+        Load tabletags-* conf file sections to self.tags.
+        """
+        for section in sections.keys():
+            mo = re.match(r'^tabletags-(?P<name>\w+)$',section)
+            if mo:
+                name = mo.group('name')
+                if name in self.tags:
+                    d = self.tags[name]
+                else:
+                    d = AttrDict()
+                parse_entries(sections.get(section,()),d)
+                for k in d.keys():
+                    if k not in self.TAGS:
+                        message.warning('[%s] contains illegal table tag: %s' %
+                                (section,k))
+                self.tags[name] = d
+    def validate(self):
+        AbstractBlocks.validate(self)
+        # Check we have a default table definition,
+        for i in range(len(self.blocks)):
+            if self.blocks[i].name == 'tabledef-default':
+                default = self.blocks[i]
+                break
+        else:
+            raise EAsciiDoc,'missing section: [tabledef-default]'
+        # Propagate defaults to unspecified table parameters.
+        for b in self.blocks:
+            if b is not default:
+                if b.format is None: b.format = default.format
+                if b.template is None: b.template = default.template
+        # Check tags and propagate default tags.
+        if not 'default' in self.tags:
+            raise EAsciiDoc,'missing section: [tabletags-default]'
+        default = self.tags['default']
+        for tag in ('bodyrow','bodydata','paragraph'): # Mandatory default tags.
+            if tag not in default:
+                raise EAsciiDoc,'missing [tabletags-default] entry: %s' % tag
+        for t in self.tags.values():
+            if t is not default:
+                if t.colspec is None: t.colspec = default.colspec
+                if t.headrow is None: t.headrow = default.headrow
+                if t.footrow is None: t.footrow = default.footrow
+                if t.bodyrow is None: t.bodyrow = default.bodyrow
+                if t.headdata is None: t.headdata = default.headdata
+                if t.footdata is None: t.footdata = default.footdata
+                if t.bodydata is None: t.bodydata = default.bodydata
+                if t.paragraph is None: t.paragraph = default.paragraph
+        # Use body tags if header and footer tags are not specified.
+        for t in self.tags.values():
+            if not t.headrow: t.headrow = t.bodyrow
+            if not t.footrow: t.footrow = t.bodyrow
+            if not t.headdata: t.headdata = t.bodydata
+            if not t.footdata: t.footdata = t.bodydata
+        # Check table definitions are valid.
+        for b in self.blocks:
+            b.validate()
+    def dump(self):
+        AbstractBlocks.dump(self)
+        for k,v in self.tags.items():
+            dump_section('tabletags-'+k, v)
+
+class Macros:
+    # Default system macro syntax.
+    SYS_RE = r'(?u)^(?P<name>[\\]?\w(\w|-)*?)::(?P<target>\S*?)' + \
+             r'(\[(?P<attrlist>.*?)\])$'
+    def __init__(self):
+        self.macros = []        # List of Macros.
+        self.current = None     # The last matched block macro.
+        self.passthroughs = []
+        # Initialize default system macro.
+        m = Macro()
+        m.pattern = self.SYS_RE
+        m.prefix = '+'
+        m.reo = re.compile(m.pattern)
+        self.macros.append(m)
+    def load(self,entries):
+        for entry in entries:
+            m = Macro()
+            m.load(entry)
+            if m.name is None:
+                # Delete undefined macro.
+                for i,m2 in enumerate(self.macros):
+                    if m2.pattern == m.pattern:
+                        del self.macros[i]
+                        break
+                else:
+                    message.warning('unable to delete missing macro: %s' % m.pattern)
+            else:
+                # Check for duplicates.
+                for m2 in self.macros:
+                    if m2.pattern == m.pattern:
+                        message.verbose('macro redefinition: %s%s' % (m.prefix,m.name))
+                        break
+                else:
+                    self.macros.append(m)
+    def dump(self):
+        write = lambda s: sys.stdout.write('%s%s' % (s,writer.newline))
+        write('[macros]')
+        # Dump all macros except the first (built-in system) macro.
+        for m in self.macros[1:]:
+            # Escape = in pattern.
+            macro = '%s=%s%s' % (m.pattern.replace('=',r'\='), m.prefix, m.name)
+            if m.subslist is not None:
+                macro += '[' + ','.join(m.subslist) + ']'
+            write(macro)
+        write('')
+    def validate(self):
+        # Check all named sections exist.
+        if config.verbose:
+            for m in self.macros:
+                if m.name and m.prefix != '+':
+                    m.section_name()
+    def subs(self,text,prefix='',callouts=False):
+        # If callouts is True then only callout macros are processed, if False
+        # then all non-callout macros are processed.
+        result = text
+        for m in self.macros:
+            if m.prefix == prefix:
+                if callouts ^ (m.name != 'callout'):
+                    result = m.subs(result)
+        return result
+    def isnext(self):
+        """Return matching macro if block macro is next on reader."""
+        reader.skip_blank_lines()
+        line = reader.read_next()
+        if line:
+            for m in self.macros:
+                if m.prefix == '#':
+                    if m.reo.match(line):
+                        self.current = m
+                        return m
+        return False
+    def match(self,prefix,name,text):
+        """Return re match object matching 'text' with macro type 'prefix',
+        macro name 'name'."""
+        for m in self.macros:
+            if m.prefix == prefix:
+                mo = m.reo.match(text)
+                if mo:
+                    if m.name == name:
+                        return mo
+                    if re.match(name,mo.group('name')):
+                        return mo
+        return None
+    def extract_passthroughs(self,text,prefix=''):
+        """ Extract the passthrough text and replace with temporary
+        placeholders."""
+        self.passthroughs = []
+        for m in self.macros:
+            if m.has_passthrough() and m.prefix == prefix:
+                text = m.subs_passthroughs(text, self.passthroughs)
+        return text
+    def restore_passthroughs(self,text):
+        """ Replace passthough placeholders with the original passthrough
+        text."""
+        for i,v in enumerate(self.passthroughs):
+            text = text.replace('\x07'+str(i)+'\x07', self.passthroughs[i])
+        return text
+
+class Macro:
+    def __init__(self):
+        self.pattern = None     # Matching regular expression.
+        self.name = ''          # Conf file macro name (None if implicit).
+        self.prefix = ''        # '' if inline, '+' if system, '#' if block.
+        self.reo = None         # Compiled pattern re object.
+        self.subslist = []      # Default subs for macros passtext group.
+    def has_passthrough(self):
+        return self.pattern.find(r'(?P<passtext>') >= 0
+    def section_name(self,name=None):
+        """Return macro markup template section name based on macro name and
+        prefix.  Return None section not found."""
+        assert self.prefix != '+'
+        if not name:
+            assert self.name
+            name = self.name
+        if self.prefix == '#':
+            suffix = '-blockmacro'
+        else:
+            suffix = '-inlinemacro'
+        if name+suffix in config.sections:
+            return name+suffix
+        else:
+            message.warning('missing macro section: [%s]' % (name+suffix))
+            return None
+    def load(self,entry):
+        e = parse_entry(entry)
+        if e is None:
+            # Only the macro pattern was specified, mark for deletion.
+            self.name = None
+            self.pattern = entry
+            return
+        if not is_re(e[0]):
+            raise EAsciiDoc,'illegal macro regular expression: %s' % e[0]
+        pattern, name = e
+        if name and name[0] in ('+','#'):
+            prefix, name = name[0], name[1:]
+        else:
+            prefix = ''
+        # Parse passthrough subslist.
+        mo = re.match(r'^(?P<name>[^[]*)(\[(?P<subslist>.*)\])?$', name)
+        name = mo.group('name')
+        if name and not is_name(name):
+            raise EAsciiDoc,'illegal section name in macro entry: %s' % entry
+        subslist = mo.group('subslist')
+        if subslist is not None:
+            # Parse and validate passthrough subs.
+            subslist = parse_options(subslist, SUBS_OPTIONS,
+                                 'illegal subs in macro entry: %s' % entry)
+        self.pattern = pattern
+        self.reo = re.compile(pattern)
+        self.prefix = prefix
+        self.name = name
+        self.subslist = subslist or []
+
+    def subs(self,text):
+        def subs_func(mo):
+            """Function called to perform macro substitution.
+            Uses matched macro regular expression object and returns string
+            containing the substituted macro body."""
+            # Check if macro reference is escaped.
+            if mo.group()[0] == '\\':
+                return mo.group()[1:]   # Strip leading backslash.
+            d = mo.groupdict()
+            # Delete groups that didn't participate in match.
+            for k,v in d.items():
+                if v is None: del d[k]
+            if self.name:
+                name = self.name
+            else:
+                if not 'name' in d:
+                    message.warning('missing macro name group: %s' % mo.re.pattern)
+                    return ''
+                name = d['name']
+            section_name = self.section_name(name)
+            if not section_name:
+                return ''
+            # If we're dealing with a block macro get optional block ID and
+            # block title.
+            if self.prefix == '#' and self.name != 'comment':
+                AttributeList.consume(d)
+                BlockTitle.consume(d)
+            # Parse macro attributes.
+            if 'attrlist' in d:
+                if d['attrlist'] in (None,''):
+                    del d['attrlist']
+                else:
+                    if self.prefix == '':
+                        # Unescape ] characters in inline macros.
+                        d['attrlist'] = d['attrlist'].replace('\\]',']')
+                    parse_attributes(d['attrlist'],d)
+                    # Generate option attributes.
+                    if 'options' in d:
+                        options = parse_options(d['options'], (),
+                                '%s: illegal option name' % name)
+                        for option in options:
+                            d[option+'-option'] = ''
+                    # Substitute single quoted attribute values in block macros.
+                    if self.prefix == '#':
+                        AttributeList.subs(d)
+            if name == 'callout':
+                listindex =int(d['index'])
+                d['coid'] = calloutmap.add(listindex)
+            # The alt attribute is the first image macro positional attribute.
+            if name == 'image' and '1' in d:
+                d['alt'] = d['1']
+            # Unescape special characters in LaTeX target file names.
+            if document.backend == 'latex' and 'target' in d and d['target']:
+                if not '0' in d:
+                    d['0'] = d['target']
+                d['target']= config.subs_specialchars_reverse(d['target'])
+            # BUG: We've already done attribute substitution on the macro which
+            # means that any escaped attribute references are now unescaped and
+            # will be substituted by config.subs_section() below. As a partial
+            # fix have withheld {0} from substitution but this kludge doesn't
+            # fix it for other attributes containing unescaped references.
+            # Passthrough macros don't have this problem.
+            a0 = d.get('0')
+            if a0:
+                d['0'] = chr(0)  # Replace temporarily with unused character.
+            body = config.subs_section(section_name,d)
+            if len(body) == 0:
+                result = ''
+            elif len(body) == 1:
+                result = body[0]
+            else:
+                if self.prefix == '#':
+                    result = writer.newline.join(body)
+                else:
+                    # Internally processed inline macros use UNIX line
+                    # separator.
+                    result = '\n'.join(body)
+            if a0:
+                result = result.replace(chr(0), a0)
+            return result
+
+        return self.reo.sub(subs_func, text)
+
+    def translate(self):
+        """ Block macro translation."""
+        assert self.prefix == '#'
+        s = reader.read()
+        before = s
+        if self.has_passthrough():
+            s = macros.extract_passthroughs(s,'#')
+        s = subs_attrs(s)
+        if s:
+            s = self.subs(s)
+            if self.has_passthrough():
+                s = macros.restore_passthroughs(s)
+            if s:
+                trace('macro block',before,s)
+                writer.write(s)
+
+    def subs_passthroughs(self, text, passthroughs):
+        """ Replace macro attribute lists in text with placeholders.
+        Substitute and append the passthrough attribute lists to the
+        passthroughs list."""
+        def subs_func(mo):
+            """Function called to perform inline macro substitution.
+            Uses matched macro regular expression object and returns string
+            containing the substituted macro body."""
+            # Don't process escaped macro references.
+            if mo.group()[0] == '\\':
+                return mo.group()
+            d = mo.groupdict()
+            if not 'passtext' in d:
+                message.warning('passthrough macro %s: missing passtext group' %
+                        d.get('name',''))
+                return mo.group()
+            passtext = d['passtext']
+            if re.search('\x07\\d+\x07', passtext):
+                message.warning('nested inline passthrough')
+                return mo.group()
+            if d.get('subslist'):
+                if d['subslist'].startswith(':'):
+                    message.error('block macro cannot occur here: %s' % mo.group(),
+                          halt=True)
+                subslist = parse_options(d['subslist'], SUBS_OPTIONS,
+                          'illegal passthrough macro subs option')
+            else:
+                subslist = self.subslist
+            passtext = Lex.subs_1(passtext,subslist)
+            if passtext is None: passtext = ''
+            if self.prefix == '':
+                # Unescape ] characters in inline macros.
+                passtext = passtext.replace('\\]',']')
+            passthroughs.append(passtext)
+            # Tabs guarantee the placeholders are unambiguous.
+            result = (
+                text[mo.start():mo.start('passtext')] +
+                '\x07' + str(len(passthroughs)-1) + '\x07' +
+                text[mo.end('passtext'):mo.end()]
+            )
+            return result
+
+        return self.reo.sub(subs_func, text)
+
+
+class CalloutMap:
+    def __init__(self):
+        self.comap = {}         # key = list index, value = callouts list.
+        self.calloutindex = 0   # Current callout index number.
+        self.listnumber = 1     # Current callout list number.
+    def listclose(self):
+        # Called when callout list is closed.
+        self.listnumber += 1
+        self.calloutindex = 0
+        self.comap = {}
+    def add(self,listindex):
+        # Add next callout index to listindex map entry. Return the callout id.
+        self.calloutindex += 1
+        # Append the coindex to a list in the comap dictionary.
+        if not listindex in self.comap:
+            self.comap[listindex] = [self.calloutindex]
+        else:
+            self.comap[listindex].append(self.calloutindex)
+        return self.calloutid(self.listnumber, self.calloutindex)
+    @staticmethod
+    def calloutid(listnumber,calloutindex):
+        return 'CO%d-%d' % (listnumber,calloutindex)
+    def calloutids(self,listindex):
+        # Retieve list of callout indexes that refer to listindex.
+        if listindex in self.comap:
+            result = ''
+            for coindex in self.comap[listindex]:
+                result += ' ' + self.calloutid(self.listnumber,coindex)
+            return result.strip()
+        else:
+            message.warning('no callouts refer to list item '+str(listindex))
+            return ''
+    def validate(self,maxlistindex):
+        # Check that all list indexes referenced by callouts exist.
+        for listindex in self.comap.keys():
+            if listindex > maxlistindex:
+                message.warning('callout refers to non-existent list item '
+                        + str(listindex))
+
+#---------------------------------------------------------------------------
+# Input stream Reader and output stream writer classes.
+#---------------------------------------------------------------------------
+
+UTF8_BOM = '\xef\xbb\xbf'
+
+class Reader1:
+    """Line oriented AsciiDoc input file reader. Processes include and
+    conditional inclusion system macros. Tabs are expanded and lines are right
+    trimmed."""
+    # This class is not used directly, use Reader class instead.
+    READ_BUFFER_MIN = 10        # Read buffer low level.
+    def __init__(self):
+        self.f = None           # Input file object.
+        self.fname = None       # Input file name.
+        self.next = []          # Read ahead buffer containing
+                                # [filename,linenumber,linetext] lists.
+        self.cursor = None      # Last read() [filename,linenumber,linetext].
+        self.tabsize = 8        # Tab expansion number of spaces.
+        self.parent = None      # Included reader's parent reader.
+        self._lineno = 0        # The last line read from file object f.
+        self.current_depth = 0  # Current include depth.
+        self.max_depth = 5      # Initial maxiumum allowed include depth.
+        self.bom = None         # Byte order mark (BOM).
+        self.infile = None      # Saved document 'infile' attribute.
+        self.indir = None       # Saved document 'indir' attribute.
+    def open(self,fname):
+        self.fname = fname
+        message.verbose('reading: '+fname)
+        if fname == '<stdin>':
+            self.f = sys.stdin
+            self.infile = None
+            self.indir = None
+        else:
+            self.f = open(fname,'rb')
+            self.infile = fname
+            self.indir = os.path.dirname(fname)
+        document.attributes['infile'] = self.infile
+        document.attributes['indir'] = self.indir
+        self._lineno = 0            # The last line read from file object f.
+        self.next = []
+        # Prefill buffer by reading the first line and then pushing it back.
+        if Reader1.read(self):
+            if self.cursor[2].startswith(UTF8_BOM):
+                self.cursor[2] = self.cursor[2][len(UTF8_BOM):]
+                self.bom = UTF8_BOM
+            self.unread(self.cursor)
+            self.cursor = None
+    def closefile(self):
+        """Used by class methods to close nested include files."""
+        self.f.close()
+        self.next = []
+    def close(self):
+        self.closefile()
+        self.__init__()
+    def read(self, skip=False):
+        """Read next line. Return None if EOF. Expand tabs. Strip trailing
+        white space. Maintain self.next read ahead buffer. If skip=True then
+        conditional exclusion is active (ifdef and ifndef macros)."""
+        # Top up buffer.
+        if len(self.next) <= self.READ_BUFFER_MIN:
+            s = self.f.readline()
+            if s:
+                self._lineno = self._lineno + 1
+            while s:
+                if self.tabsize != 0:
+                    s = s.expandtabs(self.tabsize)
+                s = s.rstrip()
+                self.next.append([self.fname,self._lineno,s])
+                if len(self.next) > self.READ_BUFFER_MIN:
+                    break
+                s = self.f.readline()
+                if s:
+                    self._lineno = self._lineno + 1
+        # Return first (oldest) buffer entry.
+        if len(self.next) > 0:
+            self.cursor = self.next[0]
+            del self.next[0]
+            result = self.cursor[2]
+            # Check for include macro.
+            mo = macros.match('+',r'include[1]?',result)
+            if mo and not skip:
+                # Don't process include macro once the maximum depth is reached.
+                if self.current_depth >= self.max_depth:
+                    return result
+                # Perform attribute substitution on include macro file name.
+                fname = subs_attrs(mo.group('target'))
+                if not fname:
+                    return Reader1.read(self)   # Return next input line.
+                if self.fname != '<stdin>':
+                    fname = os.path.expandvars(os.path.expanduser(fname))
+                    fname = safe_filename(fname, os.path.dirname(self.fname))
+                    if not fname:
+                        return Reader1.read(self)   # Return next input line.
+                    if mo.group('name') == 'include1':
+                        if not config.dumping:
+                            # Store the include file in memory for later
+                            # retrieval by the {include1:} system attribute.
+                            config.include1[fname] = [
+                                s.rstrip() for s in open(fname)]
+                            return '{include1:%s}' % fname
+                        else:
+                            # This is a configuration dump, just pass the macro
+                            # call through.
+                            return result
+                # Parse include macro attributes.
+                attrs = {}
+                parse_attributes(mo.group('attrlist'),attrs)
+                # Clone self and set as parent (self assumes the role of child).
+                parent = Reader1()
+                assign(parent,self)
+                self.parent = parent
+                # Set attributes in child.
+                if 'tabsize' in attrs:
+                    self.tabsize = int(validate(attrs['tabsize'],
+                        'int($)>=0',
+                        'illegal include macro tabsize argument'))
+                else:
+                    self.tabsize = config.tabsize
+                if 'depth' in attrs:
+                    attrs['depth'] = int(validate(attrs['depth'],
+                        'int($)>=1',
+                        'illegal include macro depth argument'))
+                    self.max_depth = self.current_depth + attrs['depth']
+                # Process included file.
+                self.open(fname)
+                self.current_depth = self.current_depth + 1
+                result = Reader1.read(self)
+        else:
+            if not Reader1.eof(self):
+                result = Reader1.read(self)
+            else:
+                result = None
+        return result
+    def eof(self):
+        """Returns True if all lines have been read."""
+        if len(self.next) == 0:
+            # End of current file.
+            if self.parent:
+                self.closefile()
+                assign(self,self.parent)    # Restore parent reader.
+                document.attributes['infile'] = self.infile
+                document.attributes['indir'] = self.indir
+                return Reader1.eof(self)
+            else:
+                return True
+        else:
+            return False
+    def read_next(self):
+        """Like read() but does not advance file pointer."""
+        if Reader1.eof(self):
+            return None
+        else:
+            return self.next[0][2]
+    def unread(self,cursor):
+        """Push the line (filename,linenumber,linetext) tuple back into the read
+        buffer. Note that it's up to the caller to restore the previous
+        cursor."""
+        assert cursor
+        self.next.insert(0,cursor)
+
+class Reader(Reader1):
+    """ Wraps (well, sought of) Reader1 class and implements conditional text
+    inclusion."""
+    def __init__(self):
+        Reader1.__init__(self)
+        self.depth = 0          # if nesting depth.
+        self.skip = False       # true if we're skipping ifdef...endif.
+        self.skipname = ''      # Name of current endif macro target.
+        self.skipto = -1        # The depth at which skipping is reenabled.
+    def read_super(self):
+        result = Reader1.read(self,self.skip)
+        if result is None and self.skip:
+            raise EAsciiDoc,'missing endif::%s[]' % self.skipname
+        return result
+    def read(self):
+        result = self.read_super()
+        if result is None:
+            return None
+        while self.skip:
+            mo = macros.match('+',r'ifdef|ifndef|ifeval|endif',result)
+            if mo:
+                name = mo.group('name')
+                target = mo.group('target')
+                attrlist = mo.group('attrlist')
+                if name == 'endif':
+                    self.depth -= 1
+                    if self.depth < 0:
+                        raise EAsciiDoc,'mismatched macro: %s' % result
+                    if self.depth == self.skipto:
+                        self.skip = False
+                        if target and self.skipname != target:
+                            raise EAsciiDoc,'mismatched macro: %s' % result
+                else:
+                    if name in ('ifdef','ifndef'):
+                        if not target:
+                            raise EAsciiDoc,'missing macro target: %s' % result
+                        if not attrlist:
+                            self.depth += 1
+                    elif name == 'ifeval':
+                        if not attrlist:
+                            raise EAsciiDoc,'missing ifeval condition: %s' % result
+                        self.depth += 1
+            result = self.read_super()
+            if result is None:
+                return None
+        mo = macros.match('+',r'ifdef|ifndef|ifeval|endif',result)
+        if mo:
+            name = mo.group('name')
+            target = mo.group('target')
+            attrlist = mo.group('attrlist')
+            if name == 'endif':
+                self.depth = self.depth-1
+            else:
+                if not target and name in ('ifdef','ifndef'):
+                    raise EAsciiDoc,'missing macro target: %s' % result
+                defined = is_attr_defined(target, document.attributes)
+                if name == 'ifdef':
+                    if attrlist:
+                        if defined: return attrlist
+                    else:
+                        self.skip = not defined
+                elif name == 'ifndef':
+                    if attrlist:
+                        if not defined: return attrlist
+                    else:
+                        self.skip = defined
+                elif name == 'ifeval':
+                    if not attrlist:
+                        raise EAsciiDoc,'missing ifeval condition: %s' % result
+                    cond = False
+                    attrlist = subs_attrs(attrlist)
+                    if attrlist:
+                        try:
+                            cond = eval(attrlist)
+                        except Exception,e:
+                            raise EAsciiDoc,'error evaluating ifeval condition: %s: %s' % (result, str(e))
+                    self.skip = not cond
+                if not attrlist or name == 'ifeval':
+                    if self.skip:
+                        self.skipto = self.depth
+                        self.skipname = target
+                    self.depth = self.depth+1
+            result = self.read()
+        if result:
+            # Expand executable block macros.
+            mo = macros.match('+',r'eval|sys|sys2',result)
+            if mo:
+                action = mo.group('name')
+                cmd = mo.group('attrlist')
+                s = system(action, cmd, is_macro=True)
+                if s is not None:
+                    self.cursor[2] = s  # So we don't re-evaluate.
+                    result = s
+        if result:
+            # Unescape escaped system macros.
+            if macros.match('+',r'\\eval|\\sys|\\sys2|\\ifdef|\\ifndef|\\endif|\\include|\\include1',result):
+                result = result[1:]
+        return result
+    def eof(self):
+        return self.read_next() is None
+    def read_next(self):
+        save_cursor = self.cursor
+        result = self.read()
+        if result is not None:
+            self.unread(self.cursor)
+            self.cursor = save_cursor
+        return result
+    def read_lines(self,count=1):
+        """Return tuple containing count lines."""
+        result = []
+        i = 0
+        while i < count and not self.eof():
+            result.append(self.read())
+        return tuple(result)
+    def read_ahead(self,count=1):
+        """Same as read_lines() but does not advance the file pointer."""
+        result = []
+        putback = []
+        save_cursor = self.cursor
+        try:
+            i = 0
+            while i < count and not self.eof():
+                result.append(self.read())
+                putback.append(self.cursor)
+                i = i+1
+            while putback:
+                self.unread(putback.pop())
+        finally:
+            self.cursor = save_cursor
+        return tuple(result)
+    def skip_blank_lines(self):
+        reader.read_until(r'\s*\S+')
+    def read_until(self,terminators,same_file=False):
+        """Like read() but reads lines up to (but not including) the first line
+        that matches the terminator regular expression, regular expression
+        object or list of regular expression objects. If same_file is True then
+        the terminating pattern must occur in the file the was being read when
+        the routine was called."""
+        if same_file:
+            fname = self.cursor[0]
+        result = []
+        if not isinstance(terminators,list):
+            if isinstance(terminators,basestring):
+                terminators = [re.compile(terminators)]
+            else:
+                terminators = [terminators]
+        while not self.eof():
+            save_cursor = self.cursor
+            s = self.read()
+            if not same_file or fname == self.cursor[0]:
+                for reo in terminators:
+                    if reo.match(s):
+                        self.unread(self.cursor)
+                        self.cursor = save_cursor
+                        return tuple(result)
+            result.append(s)
+        return tuple(result)
+
+class Writer:
+    """Writes lines to output file."""
+    def __init__(self):
+        self.newline = '\r\n'            # End of line terminator.
+        self.f = None                    # Output file object.
+        self.fname = None                # Output file name.
+        self.lines_out = 0               # Number of lines written.
+        self.skip_blank_lines = False    # If True don't output blank lines.
+    def open(self,fname,bom=None):
+        '''
+        bom is optional byte order mark.
+        http://en.wikipedia.org/wiki/Byte-order_mark
+        '''
+        self.fname = fname
+        if fname == '<stdout>':
+            self.f = sys.stdout
+        else:
+            self.f = open(fname,'wb+')
+        message.verbose('writing: '+writer.fname,False)
+        if bom:
+            self.f.write(bom)
+        self.lines_out = 0
+    def close(self):
+        if self.fname != '<stdout>':
+            self.f.close()
+    def write_line(self, line=None):
+        if not (self.skip_blank_lines and (not line or not line.strip())):
+            self.f.write((line or '') + self.newline)
+            self.lines_out = self.lines_out + 1
+    def write(self,*args,**kwargs):
+        """Iterates arguments, writes tuple and list arguments one line per
+        element, else writes argument as single line. If no arguments writes
+        blank line. If argument is None nothing is written. self.newline is
+        appended to each line."""
+        if 'trace' in kwargs and len(args) > 0:
+            trace(kwargs['trace'],args[0])
+        if len(args) == 0:
+            self.write_line()
+            self.lines_out = self.lines_out + 1
+        else:
+            for arg in args:
+                if is_array(arg):
+                    for s in arg:
+                        self.write_line(s)
+                elif arg is not None:
+                    self.write_line(arg)
+    def write_tag(self,tag,content,subs=None,d=None,**kwargs):
+        """Write content enveloped by tag.
+        Substitutions specified in the 'subs' list are perform on the
+        'content'."""
+        if subs is None:
+            subs = config.subsnormal
+        stag,etag = subs_tag(tag,d)
+        content = Lex.subs(content,subs)
+        if 'trace' in kwargs:
+            trace(kwargs['trace'],[stag]+content+[etag])
+        if stag:
+            self.write(stag)
+        if content:
+            self.write(content)
+        if etag:
+            self.write(etag)
+
+#---------------------------------------------------------------------------
+# Configuration file processing.
+#---------------------------------------------------------------------------
+def _subs_specialwords(mo):
+    """Special word substitution function called by
+    Config.subs_specialwords()."""
+    word = mo.re.pattern                    # The special word.
+    template = config.specialwords[word]    # The corresponding markup template.
+    if not template in config.sections:
+        raise EAsciiDoc,'missing special word template [%s]' % template
+    if mo.group()[0] == '\\':
+        return mo.group()[1:]   # Return escaped word.
+    args = {}
+    args['words'] = mo.group()  # The full match string is argument 'words'.
+    args.update(mo.groupdict()) # Add other named match groups to the arguments.
+    # Delete groups that didn't participate in match.
+    for k,v in args.items():
+        if v is None: del args[k]
+    lines = subs_attrs(config.sections[template],args)
+    if len(lines) == 0:
+        result = ''
+    elif len(lines) == 1:
+        result = lines[0]
+    else:
+        result = writer.newline.join(lines)
+    return result
+
+class Config:
+    """Methods to process configuration files."""
+    # Non-template section name regexp's.
+    ENTRIES_SECTIONS= ('tags','miscellaneous','attributes','specialcharacters',
+            'specialwords','macros','replacements','quotes','titles',
+            r'paradef-.+',r'listdef-.+',r'blockdef-.+',r'tabledef-.+',
+            r'tabletags-.+',r'listtags-.+','replacements2',
+            r'old_tabledef-.+')
+    def __init__(self):
+        self.sections = OrderedDict()   # Keyed by section name containing
+                                        # lists of section lines.
+        # Command-line options.
+        self.verbose = False
+        self.header_footer = True       # -s, --no-header-footer option.
+        # [miscellaneous] section.
+        self.tabsize = 8
+        self.textwidth = 70             # DEPRECATED: Old tables only.
+        self.newline = '\r\n'
+        self.pagewidth = None
+        self.pageunits = None
+        self.outfilesuffix = ''
+        self.subsnormal = SUBS_NORMAL
+        self.subsverbatim = SUBS_VERBATIM
+
+        self.tags = {}          # Values contain (stag,etag) tuples.
+        self.specialchars = {}  # Values of special character substitutions.
+        self.specialwords = {}  # Name is special word pattern, value is macro.
+        self.replacements = OrderedDict()   # Key is find pattern, value is
+                                            #replace pattern.
+        self.replacements2 = OrderedDict()
+        self.specialsections = {} # Name is special section name pattern, value
+                                  # is corresponding section name.
+        self.quotes = OrderedDict()    # Values contain corresponding tag name.
+        self.fname = ''         # Most recently loaded configuration file name.
+        self.conf_attrs = {}    # Attributes entries from conf files.
+        self.cmd_attrs = {}     # Attributes from command-line -a options.
+        self.loaded = []        # Loaded conf files.
+        self.include1 = {}      # Holds include1::[] files for {include1:}.
+        self.dumping = False    # True if asciidoc -c option specified.
+
+    def init(self, cmd):
+        """
+        Check Python version and locate the executable and configuration files
+        directory.
+        cmd is the asciidoc command or asciidoc.py path.
+        """
+        if float(sys.version[:3]) < MIN_PYTHON_VERSION:
+            message.stderr('FAILED: Python 2.3 or better required')
+            sys.exit(1)
+        if not os.path.exists(cmd):
+            message.stderr('FAILED: Missing asciidoc command: %s' % cmd)
+            sys.exit(1)
+        global APP_FILE
+        APP_FILE = os.path.realpath(cmd)
+        global APP_DIR
+        APP_DIR = os.path.dirname(APP_FILE)
+        global USER_DIR
+        USER_DIR = userdir()
+        if USER_DIR is not None:
+            USER_DIR = os.path.join(USER_DIR,'.asciidoc')
+            if not os.path.isdir(USER_DIR):
+                USER_DIR = None
+
+    def load_file(self, fname, dir=None, include=[], exclude=[]):
+        """
+        Loads sections dictionary with sections from file fname.
+        Existing sections are overlaid.
+        The 'include' list contains the section names to be loaded.
+        The 'exclude' list contains section names not to be loaded.
+        Return False if no file was found in any of the locations.
+        """
+        if dir:
+            fname = os.path.join(dir, fname)
+        # Sliently skip missing configuration file.
+        if not os.path.isfile(fname):
+            return False
+        # Don't load conf files twice (local and application conf files are the
+        # same if the source file is in the application directory).
+        if os.path.realpath(fname) in self.loaded:
+            return True
+        rdr = Reader()  # Reader processes system macros.
+        message.linenos = False         # Disable document line numbers.
+        rdr.open(fname)
+        message.linenos = None
+        self.fname = fname
+        reo = re.compile(r'(?u)^\[(?P<section>[^\W\d][\w-]*)\]\s*$')
+        sections = OrderedDict()
+        section,contents = '',[]
+        while not rdr.eof():
+            s = rdr.read()
+            if s and s[0] == '#':       # Skip comment lines.
+                continue
+            if s[:2] == '\\#':          # Unescape lines starting with '#'.
+                s = s[1:]
+            s = s.rstrip()
+            found = reo.findall(s)
+            if found:
+                if section:             # Store previous section.
+                    if section in sections \
+                        and self.entries_section(section):
+                        if ''.join(contents):
+                            # Merge entries.
+                            sections[section] = sections[section] + contents
+                        else:
+                            del sections[section]
+                    else:
+                        sections[section] = contents
+                section = found[0].lower()
+                contents = []
+            else:
+                contents.append(s)
+        if section and contents:        # Store last section.
+            if section in sections \
+                and self.entries_section(section):
+                if ''.join(contents):
+                    # Merge entries.
+                    sections[section] = sections[section] + contents
+                else:
+                    del sections[section]
+            else:
+                sections[section] = contents
+        rdr.close()
+        if include:
+            for s in set(sections) - set(include):
+                del sections[s]
+        if exclude:
+            for s in set(sections) & set(exclude):
+                del sections[s]
+        attrs = {}
+        self.load_sections(sections,attrs)
+        if not include:
+            # If all sections are loaded mark this file as loaded.
+            self.loaded.append(os.path.realpath(fname))
+        document.update_attributes(attrs) # So they are available immediately.
+        return True
+
+    def load_sections(self,sections,attrs=None):
+        """
+        Loads sections dictionary. Each dictionary entry contains a
+        list of lines.
+        Updates 'attrs' with parsed [attributes] section entries.
+        """
+        # Delete trailing blank lines from sections.
+        for k in sections.keys():
+            for i in range(len(sections[k])-1,-1,-1):
+                if not sections[k][i]:
+                    del sections[k][i]
+                elif not self.entries_section(k):
+                    break
+        # Add/overwrite new sections.
+        self.sections.update(sections)
+        self.parse_tags()
+        # Internally [miscellaneous] section entries are just attributes.
+        d = {}
+        parse_entries(sections.get('miscellaneous',()), d, unquote=True,
+                allow_name_only=True)
+        parse_entries(sections.get('attributes',()), d, unquote=True,
+                allow_name_only=True)
+        update_attrs(self.conf_attrs,d)
+        if attrs is not None:
+            attrs.update(d)
+        d = {}
+        parse_entries(sections.get('titles',()),d)
+        Title.load(d)
+        parse_entries(sections.get('specialcharacters',()),self.specialchars,escape_delimiter=False)
+        parse_entries(sections.get('quotes',()),self.quotes)
+        self.parse_specialwords()
+        self.parse_replacements()
+        self.parse_replacements('replacements2')
+        self.parse_specialsections()
+        paragraphs.load(sections)
+        lists.load(sections)
+        blocks.load(sections)
+        tables_OLD.load(sections)
+        tables.load(sections)
+        macros.load(sections.get('macros',()))
+
+    def get_load_dirs(self):
+        """
+        Return list of well known paths with conf files.
+        """
+        result = []
+        if localapp():
+            # Load from folders in asciidoc executable directory.
+            result.append(APP_DIR)
+        else:
+            # Load from global configuration directory.
+            result.append(CONF_DIR)
+        # Load configuration files from ~/.asciidoc if it exists.
+        if USER_DIR is not None:
+            result.append(USER_DIR)
+        return result
+
+    def find_in_dirs(self, filename, dirs=None):
+        """
+        Find conf files from dirs list.
+        Return list of found file paths.
+        Return empty list if not found in any of the locations.
+        """
+        result = []
+        if dirs is None:
+            dirs = self.get_load_dirs()
+        for d in dirs:
+            f = os.path.join(d,filename)
+            if os.path.isfile(f):
+                result.append(f)
+        return result
+
+    def load_from_dirs(self, filename, dirs=None, include=[]):
+        """
+        Load conf file from dirs list.
+        If dirs not specified try all the well known locations.
+        Return False if no file was sucessfully loaded.
+        """
+        count = 0
+        for f in self.find_in_dirs(filename,dirs):
+            if self.load_file(f, include=include):
+                count += 1
+        return count != 0
+
+    def load_backend(self, dirs=None):
+        """
+        Load the backend configuration files from dirs list.
+        If dirs not specified try all the well known locations.
+        """
+        if dirs is None:
+            dirs = self.get_load_dirs()
+        for d in dirs:
+            conf = document.backend + '.conf'
+            self.load_file(conf,d)
+            conf = document.backend + '-' + document.doctype + '.conf'
+            self.load_file(conf,d)
+
+    def load_filters(self, dirs=None):
+        """
+        Load filter configuration files from 'filters' directory in dirs list.
+        If dirs not specified try all the well known locations.
+        """
+        if dirs is None:
+            dirs = self.get_load_dirs()
+        for d in dirs:
+            # Load filter .conf files.
+            filtersdir = os.path.join(d,'filters')
+            for dirpath,dirnames,filenames in os.walk(filtersdir):
+                for f in filenames:
+                    if re.match(r'^.+\.conf$',f):
+                        self.load_file(f,dirpath)
+
+    def load_miscellaneous(self,d):
+        """Set miscellaneous configuration entries from dictionary 'd'."""
+        def set_misc(name,rule='True',intval=False):
+            if name in d:
+                errmsg = 'illegal [miscellaneous] %s entry' % name
+                if intval:
+                    setattr(self, name, int(validate(d[name],rule,errmsg)))
+                else:
+                    setattr(self, name, validate(d[name],rule,errmsg))
+        set_misc('tabsize','int($)>0',intval=True)
+        set_misc('textwidth','int($)>0',intval=True) # DEPRECATED: Old tables only.
+        set_misc('pagewidth','"%f" % $')
+        if 'pagewidth' in d:
+            self.pagewidth = float(self.pagewidth)
+        set_misc('pageunits')
+        set_misc('outfilesuffix')
+        if 'newline' in d:
+            # Convert escape sequences to their character values.
+            self.newline = eval('"'+d['newline']+'"')
+        if 'subsnormal' in d:
+            self.subsnormal = parse_options(d['subsnormal'],SUBS_OPTIONS,
+                    'illegal [%s] %s: %s' %
+                    ('miscellaneous','subsnormal',d['subsnormal']))
+        if 'subsverbatim' in d:
+            self.subsverbatim = parse_options(d['subsverbatim'],SUBS_OPTIONS,
+                    'illegal [%s] %s: %s' %
+                    ('miscellaneous','subsverbatim',d['subsverbatim']))
+
+    def validate(self):
+        """Check the configuration for internal consistancy. Called after all
+        configuration files have been loaded."""
+        message.linenos = False     # Disable document line numbers.
+        # Heuristic to validate that at least one configuration file was loaded.
+        if not self.specialchars or not self.tags or not lists:
+            raise EAsciiDoc,'incomplete configuration files'
+        # Check special characters are only one character long.
+        for k in self.specialchars.keys():
+            if len(k) != 1:
+                raise EAsciiDoc,'[specialcharacters] ' \
+                                'must be a single character: %s' % k
+        # Check all special words have a corresponding inline macro body.
+        for macro in self.specialwords.values():
+            if not is_name(macro):
+                raise EAsciiDoc,'illegal special word name: %s' % macro
+            if not macro in self.sections:
+                message.warning('missing special word macro: [%s]' % macro)
+        # Check all text quotes have a corresponding tag.
+        for q in self.quotes.keys()[:]:
+            tag = self.quotes[q]
+            if not tag:
+                del self.quotes[q]  # Undefine quote.
+            else:
+                if tag[0] == '#':
+                    tag = tag[1:]
+                if not tag in self.tags:
+                    message.warning('[quotes] %s missing tag definition: %s' % (q,tag))
+        # Check all specialsections section names exist.
+        for k,v in self.specialsections.items():
+            if not v:
+                del self.specialsections[k]
+            elif not v in self.sections:
+                message.warning('missing specialsections section: [%s]' % v)
+        paragraphs.validate()
+        lists.validate()
+        blocks.validate()
+        tables_OLD.validate()
+        tables.validate()
+        macros.validate()
+        message.linenos = None
+
+    def entries_section(self,section_name):
+        """
+        Return True if conf file section contains entries, not a markup
+        template.
+        """
+        for name in self.ENTRIES_SECTIONS:
+            if re.match(name,section_name):
+                return True
+        return False
+
+    def dump(self):
+        """Dump configuration to stdout."""
+        # Header.
+        hdr = ''
+        hdr = hdr + '#' + writer.newline
+        hdr = hdr + '# Generated by AsciiDoc %s for %s %s.%s' % \
+            (VERSION,document.backend,document.doctype,writer.newline)
+        t = time.asctime(time.localtime(time.time()))
+        hdr = hdr + '# %s%s' % (t,writer.newline)
+        hdr = hdr + '#' + writer.newline
+        sys.stdout.write(hdr)
+        # Dump special sections.
+        # Dump only the configuration file and command-line attributes.
+        # [miscellanous] entries are dumped as part of the [attributes].
+        d = {}
+        d.update(self.conf_attrs)
+        d.update(self.cmd_attrs)
+        dump_section('attributes',d)
+        Title.dump()
+        dump_section('quotes',self.quotes)
+        dump_section('specialcharacters',self.specialchars)
+        d = {}
+        for k,v in self.specialwords.items():
+            if v in d:
+                d[v] = '%s "%s"' % (d[v],k)   # Append word list.
+            else:
+                d[v] = '"%s"' % k
+        dump_section('specialwords',d)
+        dump_section('replacements',self.replacements)
+        dump_section('replacements2',self.replacements2)
+        dump_section('specialsections',self.specialsections)
+        d = {}
+        for k,v in self.tags.items():
+            d[k] = '%s|%s' % v
+        dump_section('tags',d)
+        paragraphs.dump()
+        lists.dump()
+        blocks.dump()
+        tables_OLD.dump()
+        tables.dump()
+        macros.dump()
+        # Dump remaining sections.
+        for k in self.sections.keys():
+            if not self.entries_section(k):
+                sys.stdout.write('[%s]%s' % (k,writer.newline))
+                for line in self.sections[k]:
+                    sys.stdout.write('%s%s' % (line,writer.newline))
+                sys.stdout.write(writer.newline)
+
+    def subs_section(self,section,d):
+        """Section attribute substitution using attributes from
+        document.attributes and 'd'.  Lines containing undefinded
+        attributes are deleted."""
+        if section in self.sections:
+            return subs_attrs(self.sections[section],d)
+        else:
+            message.warning('missing section: [%s]' % section)
+            return ()
+
+    def parse_tags(self):
+        """Parse [tags] section entries into self.tags dictionary."""
+        d = {}
+        parse_entries(self.sections.get('tags',()),d)
+        for k,v in d.items():
+            if v is None:
+                if k in self.tags:
+                    del self.tags[k]
+            elif v == '':
+                self.tags[k] = (None,None)
+            else:
+                mo = re.match(r'(?P<stag>.*)\|(?P<etag>.*)',v)
+                if mo:
+                    self.tags[k] = (mo.group('stag'), mo.group('etag'))
+                else:
+                    raise EAsciiDoc,'[tag] %s value malformed' % k
+
+    def tag(self, name, d=None):
+        """Returns (starttag,endtag) tuple named name from configuration file
+        [tags] section. Raise error if not found. If a dictionary 'd' is
+        passed then merge with document attributes and perform attribute
+        substitution on tags."""
+        if not name in self.tags:
+            raise EAsciiDoc, 'missing tag: %s' % name
+        stag,etag = self.tags[name]
+        if d is not None:
+            # TODO: Should we warn if substitution drops a tag?
+            if stag:
+                stag = subs_attrs(stag,d)
+            if etag:
+                etag = subs_attrs(etag,d)
+        if stag is None: stag = ''
+        if etag is None: etag = ''
+        return (stag,etag)
+
+    def parse_specialsections(self):
+        """Parse specialsections section to self.specialsections dictionary."""
+        # TODO: This is virtually the same as parse_replacements() and should
+        # be factored to single routine.
+        d = {}
+        parse_entries(self.sections.get('specialsections',()),d,unquote=True)
+        for pat,sectname in d.items():
+            pat = strip_quotes(pat)
+            if not is_re(pat):
+                raise EAsciiDoc,'[specialsections] entry ' \
+                                'is not a valid regular expression: %s' % pat
+            if sectname is None:
+                if pat in self.specialsections:
+                    del self.specialsections[pat]
+            else:
+                self.specialsections[pat] = sectname
+
+    def parse_replacements(self,sect='replacements'):
+        """Parse replacements section into self.replacements dictionary."""
+        d = OrderedDict()
+        parse_entries(self.sections.get(sect,()), d, unquote=True)
+        for pat,rep in d.items():
+            if not self.set_replacement(pat, rep, getattr(self,sect)):
+                raise EAsciiDoc,'[%s] entry in %s is not a valid' \
+                    ' regular expression: %s' % (sect,self.fname,pat)
+
+    @staticmethod
+    def set_replacement(pat, rep, replacements):
+        """Add pattern and replacement to replacements dictionary."""
+        pat = strip_quotes(pat)
+        if not is_re(pat):
+            return False
+        if rep is None:
+            if pat in replacements:
+                del replacements[pat]
+        else:
+            replacements[pat] = strip_quotes(rep)
+        return True
+
+    def subs_replacements(self,s,sect='replacements'):
+        """Substitute patterns from self.replacements in 's'."""
+        result = s
+        for pat,rep in getattr(self,sect).items():
+            result = re.sub(pat, rep, result)
+        return result
+
+    def parse_specialwords(self):
+        """Parse special words section into self.specialwords dictionary."""
+        reo = re.compile(r'(?:\s|^)(".+?"|[^"\s]+)(?=\s|$)')
+        for line in self.sections.get('specialwords',()):
+            e = parse_entry(line)
+            if not e:
+                raise EAsciiDoc,'[specialwords] entry in %s is malformed: %s' \
+                    % (self.fname,line)
+            name,wordlist = e
+            if not is_name(name):
+                raise EAsciiDoc,'[specialwords] name in %s is illegal: %s' \
+                    % (self.fname,name)
+            if wordlist is None:
+                # Undefine all words associated with 'name'.
+                for k,v in self.specialwords.items():
+                    if v == name:
+                        del self.specialwords[k]
+            else:
+                words = reo.findall(wordlist)
+                for word in words:
+                    word = strip_quotes(word)
+                    if not is_re(word):
+                        raise EAsciiDoc,'[specialwords] entry in %s ' \
+                            'is not a valid regular expression: %s' \
+                            % (self.fname,word)
+                    self.specialwords[word] = name
+
+    def subs_specialchars(self,s):
+        """Perform special character substitution on string 's'."""
+        """It may seem like a good idea to escape special characters with a '\'
+        character, the reason we don't is because the escape character itself
+        then has to be escaped and this makes including code listings
+        problematic. Use the predefined {amp},{lt},{gt} attributes instead."""
+        result = ''
+        for ch in s:
+            result = result + self.specialchars.get(ch,ch)
+        return result
+
+    def subs_specialchars_reverse(self,s):
+        """Perform reverse special character substitution on string 's'."""
+        result = s
+        for k,v in self.specialchars.items():
+            result = result.replace(v, k)
+        return result
+
+    def subs_specialwords(self,s):
+        """Search for word patterns from self.specialwords in 's' and
+        substitute using corresponding macro."""
+        result = s
+        for word in self.specialwords.keys():
+            result = re.sub(word, _subs_specialwords, result)
+        return result
+
+    def expand_templates(self,entries):
+        """Expand any template::[] macros in a list of section entries."""
+        result = []
+        for line in entries:
+            mo = macros.match('+',r'template',line)
+            if mo:
+                s = mo.group('attrlist')
+                if s in self.sections:
+                    result += self.expand_templates(self.sections[s])
+                else:
+                    message.warning('missing section: [%s]' % s)
+                    result.append(line)
+            else:
+                result.append(line)
+        return result
+
+    def expand_all_templates(self):
+        for k,v in self.sections.items():
+            self.sections[k] = self.expand_templates(v)
+
+    def section2tags(self, section, d={}, skipstart=False, skipend=False):
+        """Perform attribute substitution on 'section' using document
+        attributes plus 'd' attributes. Return tuple (stag,etag) containing
+        pre and post | placeholder tags. 'skipstart' and 'skipend' are
+        used to suppress substitution."""
+        assert section is not None
+        if section in self.sections:
+            body = self.sections[section]
+        else:
+            message.warning('missing section: [%s]' % section)
+            body = ()
+        # Split macro body into start and end tag lists.
+        stag = []
+        etag = []
+        in_stag = True
+        for s in body:
+            if in_stag:
+                mo = re.match(r'(?P<stag>.*)\|(?P<etag>.*)',s)
+                if mo:
+                    if mo.group('stag'):
+                        stag.append(mo.group('stag'))
+                    if mo.group('etag'):
+                        etag.append(mo.group('etag'))
+                    in_stag = False
+                else:
+                    stag.append(s)
+            else:
+                etag.append(s)
+        # Do attribute substitution last so {brkbar} can be used to escape |.
+        # But don't do attribute substitution on title -- we've already done it.
+        title = d.get('title')
+        if title:
+            d['title'] = chr(0)  # Replace with unused character.
+        if not skipstart:
+            stag = subs_attrs(stag, d)
+        if not skipend:
+            etag = subs_attrs(etag, d)
+        # Put the {title} back.
+        if title:
+            stag = map(lambda x: x.replace(chr(0), title), stag)
+            etag = map(lambda x: x.replace(chr(0), title), etag)
+            d['title'] = title
+        return (stag,etag)
+
+
+#---------------------------------------------------------------------------
+# Deprecated old table classes follow.
+# Naming convention is an _OLD name suffix.
+# These will be removed from future versions of AsciiDoc
+
+def join_lines_OLD(lines):
+    """Return a list in which lines terminated with the backslash line
+    continuation character are joined."""
+    result = []
+    s = ''
+    continuation = False
+    for line in lines:
+        if line and line[-1] == '\\':
+            s = s + line[:-1]
+            continuation = True
+            continue
+        if continuation:
+            result.append(s+line)
+            s = ''
+            continuation = False
+        else:
+            result.append(line)
+    if continuation:
+        result.append(s)
+    return result
+
+class Column_OLD:
+    """Table column."""
+    def __init__(self):
+        self.colalign = None    # 'left','right','center'
+        self.rulerwidth = None
+        self.colwidth = None    # Output width in page units.
+
+class Table_OLD(AbstractBlock):
+    COL_STOP = r"(`|'|\.)"  # RE.
+    ALIGNMENTS = {'`':'left', "'":'right', '.':'center'}
+    FORMATS = ('fixed','csv','dsv')
+    def __init__(self):
+        AbstractBlock.__init__(self)
+        self.CONF_ENTRIES += ('template','fillchar','format','colspec',
+                              'headrow','footrow','bodyrow','headdata',
+                              'footdata', 'bodydata')
+        # Configuration parameters.
+        self.fillchar=None
+        self.format=None    # 'fixed','csv','dsv'
+        self.colspec=None
+        self.headrow=None
+        self.footrow=None
+        self.bodyrow=None
+        self.headdata=None
+        self.footdata=None
+        self.bodydata=None
+        # Calculated parameters.
+        self.underline=None     # RE matching current table underline.
+        self.isnumeric=False    # True if numeric ruler.
+        self.tablewidth=None    # Optional table width scale factor.
+        self.columns=[]         # List of Columns.
+        # Other.
+        self.check_msg=''       # Message set by previous self.validate() call.
+    def load(self,name,entries):
+        AbstractBlock.load(self,name,entries)
+        """Update table definition from section entries in 'entries'."""
+        for k,v in entries.items():
+            if k == 'fillchar':
+                if v and len(v) == 1:
+                    self.fillchar = v
+                else:
+                    raise EAsciiDoc,'malformed table fillchar: %s' % v
+            elif k == 'format':
+                if v in Table_OLD.FORMATS:
+                    self.format = v
+                else:
+                    raise EAsciiDoc,'illegal table format: %s' % v
+            elif k == 'colspec':
+                self.colspec = v
+            elif k == 'headrow':
+                self.headrow = v
+            elif k == 'footrow':
+                self.footrow = v
+            elif k == 'bodyrow':
+                self.bodyrow = v
+            elif k == 'headdata':
+                self.headdata = v
+            elif k == 'footdata':
+                self.footdata = v
+            elif k == 'bodydata':
+                self.bodydata = v
+    def dump(self):
+        AbstractBlock.dump(self)
+        write = lambda s: sys.stdout.write('%s%s' % (s,writer.newline))
+        write('fillchar='+self.fillchar)
+        write('format='+self.format)
+        if self.colspec:
+            write('colspec='+self.colspec)
+        if self.headrow:
+            write('headrow='+self.headrow)
+        if self.footrow:
+            write('footrow='+self.footrow)
+        write('bodyrow='+self.bodyrow)
+        if self.headdata:
+            write('headdata='+self.headdata)
+        if self.footdata:
+            write('footdata='+self.footdata)
+        write('bodydata='+self.bodydata)
+        write('')
+    def validate(self):
+        AbstractBlock.validate(self)
+        """Check table definition and set self.check_msg if invalid else set
+        self.check_msg to blank string."""
+        # Check global table parameters.
+        if config.textwidth is None:
+            self.check_msg = 'missing [miscellaneous] textwidth entry'
+        elif config.pagewidth is None:
+            self.check_msg = 'missing [miscellaneous] pagewidth entry'
+        elif config.pageunits is None:
+            self.check_msg = 'missing [miscellaneous] pageunits entry'
+        elif self.headrow is None:
+            self.check_msg = 'missing headrow entry'
+        elif self.footrow is None:
+            self.check_msg = 'missing footrow entry'
+        elif self.bodyrow is None:
+            self.check_msg = 'missing bodyrow entry'
+        elif self.headdata is None:
+            self.check_msg = 'missing headdata entry'
+        elif self.footdata is None:
+            self.check_msg = 'missing footdata entry'
+        elif self.bodydata is None:
+            self.check_msg = 'missing bodydata entry'
+        else:
+            # No errors.
+            self.check_msg = ''
+    def isnext(self):
+        return AbstractBlock.isnext(self)
+    def parse_ruler(self,ruler):
+        """Parse ruler calculating underline and ruler column widths."""
+        fc = re.escape(self.fillchar)
+        # Strip and save optional tablewidth from end of ruler.
+        mo = re.match(r'^(.*'+fc+r'+)([\d\.]+)$',ruler)
+        if mo:
+            ruler = mo.group(1)
+            self.tablewidth = float(mo.group(2))
+            self.attributes['tablewidth'] = str(float(self.tablewidth))
+        else:
+            self.tablewidth = None
+            self.attributes['tablewidth'] = '100.0'
+        # Guess whether column widths are specified numerically or not.
+        if ruler[1] != self.fillchar:
+            # If the first column does not start with a fillchar then numeric.
+            self.isnumeric = True
+        elif ruler[1:] == self.fillchar*len(ruler[1:]):
+            # The case of one column followed by fillchars is numeric.
+            self.isnumeric = True
+        else:
+            self.isnumeric = False
+        # Underlines must be 3 or more fillchars.
+        self.underline = r'^' + fc + r'{3,}$'
+        splits = re.split(self.COL_STOP,ruler)[1:]
+        # Build self.columns.
+        for i in range(0,len(splits),2):
+            c = Column_OLD()
+            c.colalign = self.ALIGNMENTS[splits[i]]
+            s = splits[i+1]
+            if self.isnumeric:
+                # Strip trailing fillchars.
+                s = re.sub(fc+r'+$','',s)
+                if s == '':
+                    c.rulerwidth = None
+                else:
+                    c.rulerwidth = int(validate(s,'int($)>0',
+                        'malformed ruler: bad width'))
+            else:   # Calculate column width from inter-fillchar intervals.
+                if not re.match(r'^'+fc+r'+$',s):
+                    raise EAsciiDoc,'malformed ruler: illegal fillchars'
+                c.rulerwidth = len(s)+1
+            self.columns.append(c)
+        # Fill in unspecified ruler widths.
+        if self.isnumeric:
+            if self.columns[0].rulerwidth is None:
+                prevwidth = 1
+            for c in self.columns:
+                if c.rulerwidth is None:
+                    c.rulerwidth = prevwidth
+                prevwidth = c.rulerwidth
+    def build_colspecs(self):
+        """Generate colwidths and colspecs. This can only be done after the
+        table arguments have been parsed since we use the table format."""
+        self.attributes['cols'] = len(self.columns)
+        # Calculate total ruler width.
+        totalwidth = 0
+        for c in self.columns:
+            totalwidth = totalwidth + c.rulerwidth
+        if totalwidth <= 0:
+            raise EAsciiDoc,'zero width table'
+        # Calculate marked up colwidths from rulerwidths.
+        for c in self.columns:
+            # Convert ruler width to output page width.
+            width = float(c.rulerwidth)
+            if self.format == 'fixed':
+                if self.tablewidth is None:
+                    # Size proportional to ruler width.
+                    colfraction = width/config.textwidth
+                else:
+                    # Size proportional to page width.
+                    colfraction = width/totalwidth
+            else:
+                    # Size proportional to page width.
+                colfraction = width/totalwidth
+            c.colwidth = colfraction * config.pagewidth # To page units.
+            if self.tablewidth is not None:
+                c.colwidth = c.colwidth * self.tablewidth   # Scale factor.
+                if self.tablewidth > 1:
+                    c.colwidth = c.colwidth/100 # tablewidth is in percent.
+        # Build colspecs.
+        if self.colspec:
+            cols = []
+            i = 0
+            for c in self.columns:
+                i += 1
+                self.attributes['colalign'] = c.colalign
+                self.attributes['colwidth'] = str(int(c.colwidth))
+                self.attributes['colnumber'] = str(i + 1)
+                s = subs_attrs(self.colspec,self.attributes)
+                if not s:
+                    message.warning('colspec dropped: contains undefined attribute')
+                else:
+                    cols.append(s)
+            self.attributes['colspecs'] = writer.newline.join(cols)
+    def split_rows(self,rows):
+        """Return a two item tuple containing a list of lines up to but not
+        including the next underline (continued lines are joined ) and the
+        tuple of all lines after the underline."""
+        reo = re.compile(self.underline)
+        i = 0
+        while not reo.match(rows[i]):
+            i = i+1
+        if i == 0:
+            raise EAsciiDoc,'missing table rows'
+        if i >= len(rows):
+            raise EAsciiDoc,'closing [%s] underline expected' % self.name
+        return (join_lines_OLD(rows[:i]), rows[i+1:])
+    def parse_rows(self, rows, rtag, dtag):
+        """Parse rows list using the row and data tags. Returns a substituted
+        list of output lines."""
+        result = []
+        # Source rows are parsed as single block, rather than line by line, to
+        # allow the CSV reader to handle multi-line rows.
+        if self.format == 'fixed':
+            rows = self.parse_fixed(rows)
+        elif self.format == 'csv':
+            rows = self.parse_csv(rows)
+        elif self.format == 'dsv':
+            rows = self.parse_dsv(rows)
+        else:
+            assert True,'illegal table format'
+        # Substitute and indent all data in all rows.
+        stag,etag = subs_tag(rtag,self.attributes)
+        for row in rows:
+            result.append('  '+stag)
+            for data in self.subs_row(row,dtag):
+                result.append('    '+data)
+            result.append('  '+etag)
+        return result
+    def subs_row(self, data, dtag):
+        """Substitute the list of source row data elements using the data tag.
+        Returns a substituted list of output table data items."""
+        result = []
+        if len(data) < len(self.columns):
+            message.warning('fewer row data items then table columns')
+        if len(data) > len(self.columns):
+            message.warning('more row data items than table columns')
+        for i in range(len(self.columns)):
+            if i > len(data) - 1:
+                d = ''  # Fill missing column data with blanks.
+            else:
+                d = data[i]
+            c = self.columns[i]
+            self.attributes['colalign'] = c.colalign
+            self.attributes['colwidth'] = str(int(c.colwidth))
+            self.attributes['colnumber'] = str(i + 1)
+            stag,etag = subs_tag(dtag,self.attributes)
+            # Insert AsciiDoc line break (' +') where row data has newlines
+            # ('\n').  This is really only useful when the table format is csv
+            # and the output markup is HTML. It's also a bit dubious in that it
+            # assumes the user has not modified the shipped line break pattern.
+            subs = self.get_subs()[0]
+            if 'replacements' in subs:
+                # Insert line breaks in cell data.
+                d = re.sub(r'(?m)\n',r' +\n',d)
+                d = d.split('\n')    # So writer.newline is written.
+            else:
+                d = [d]
+            result = result + [stag] + Lex.subs(d,subs) + [etag]
+        return result
+    def parse_fixed(self,rows):
+        """Parse the list of source table rows. Each row item in the returned
+        list contains a list of cell data elements."""
+        result = []
+        for row in rows:
+            data = []
+            start = 0
+            # build an encoded representation
+            row = char_decode(row)
+            for c in self.columns:
+                end = start + c.rulerwidth
+                if c is self.columns[-1]:
+                    # Text in last column can continue forever.
+                    # Use the encoded string to slice, but convert back
+                    # to plain string before further processing
+                    data.append(char_encode(row[start:]).strip())
+                else:
+                    data.append(char_encode(row[start:end]).strip())
+                start = end
+            result.append(data)
+        return result
+    def parse_csv(self,rows):
+        """Parse the list of source table rows. Each row item in the returned
+        list contains a list of cell data elements."""
+        import StringIO
+        import csv
+        result = []
+        rdr = csv.reader(StringIO.StringIO('\r\n'.join(rows)),
+            skipinitialspace=True)
+        try:
+            for row in rdr:
+                result.append(row)
+        except Exception:
+            raise EAsciiDoc,'csv parse error: %s' % row
+        return result
+    def parse_dsv(self,rows):
+        """Parse the list of source table rows. Each row item in the returned
+        list contains a list of cell data elements."""
+        separator = self.attributes.get('separator',':')
+        separator = eval('"'+separator+'"')
+        if len(separator) != 1:
+            raise EAsciiDoc,'malformed dsv separator: %s' % separator
+        # TODO If separator is preceeded by an odd number of backslashes then
+        # it is escaped and should not delimit.
+        result = []
+        for row in rows:
+            # Skip blank lines
+            if row == '': continue
+            # Unescape escaped characters.
+            row = eval('"'+row.replace('"','\\"')+'"')
+            data = row.split(separator)
+            data = [s.strip() for s in data]
+            result.append(data)
+        return result
+    def translate(self):
+        message.deprecated('old tables syntax')
+        AbstractBlock.translate(self)
+        # Reset instance specific properties.
+        self.underline = None
+        self.columns = []
+        attrs = {}
+        BlockTitle.consume(attrs)
+        # Add relevant globals to table substitutions.
+        attrs['pagewidth'] = str(config.pagewidth)
+        attrs['pageunits'] = config.pageunits
+        # Mix in document attribute list.
+        AttributeList.consume(attrs)
+        # Validate overridable attributes.
+        for k,v in attrs.items():
+            if k == 'format':
+                if v not in self.FORMATS:
+                    raise EAsciiDoc, 'illegal [%s] %s: %s' % (self.name,k,v)
+                self.format = v
+            elif k == 'tablewidth':
+                try:
+                    self.tablewidth = float(attrs['tablewidth'])
+                except Exception:
+                    raise EAsciiDoc, 'illegal [%s] %s: %s' % (self.name,k,v)
+        self.merge_attributes(attrs)
+        # Parse table ruler.
+        ruler = reader.read()
+        assert re.match(self.delimiter,ruler)
+        self.parse_ruler(ruler)
+        # Read the entire table.
+        table = []
+        while True:
+            line = reader.read_next()
+            # Table terminated by underline followed by a blank line or EOF.
+            if len(table) > 0 and re.match(self.underline,table[-1]):
+                if line in ('',None):
+                    break;
+            if line is None:
+                raise EAsciiDoc,'closing [%s] underline expected' % self.name
+            table.append(reader.read())
+        # EXPERIMENTAL: The number of lines in the table, requested by Benjamin Klum.
+        self.attributes['rows'] = str(len(table))
+        if self.check_msg:  # Skip if table definition was marked invalid.
+            message.warning('skipping %s table: %s' % (self.name,self.check_msg))
+            return
+        # Generate colwidths and colspecs.
+        self.build_colspecs()
+        # Generate headrows, footrows, bodyrows.
+        # Headrow, footrow and bodyrow data replaces same named attributes in
+        # the table markup template. In order to ensure this data does not get
+        # a second attribute substitution (which would interfere with any
+        # already substituted inline passthroughs) unique placeholders are used
+        # (the tab character does not appear elsewhere since it is expanded on
+        # input) which are replaced after template attribute substitution.
+        headrows = footrows = []
+        bodyrows,table = self.split_rows(table)
+        if table:
+            headrows = bodyrows
+            bodyrows,table = self.split_rows(table)
+            if table:
+                footrows,table = self.split_rows(table)
+        if headrows:
+            headrows = self.parse_rows(headrows, self.headrow, self.headdata)
+            headrows = writer.newline.join(headrows)
+            self.attributes['headrows'] = '\x07headrows\x07'
+        if footrows:
+            footrows = self.parse_rows(footrows, self.footrow, self.footdata)
+            footrows = writer.newline.join(footrows)
+            self.attributes['footrows'] = '\x07footrows\x07'
+        bodyrows = self.parse_rows(bodyrows, self.bodyrow, self.bodydata)
+        bodyrows = writer.newline.join(bodyrows)
+        self.attributes['bodyrows'] = '\x07bodyrows\x07'
+        table = subs_attrs(config.sections[self.template],self.attributes)
+        table = writer.newline.join(table)
+        # Before we finish replace the table head, foot and body place holders
+        # with the real data.
+        if headrows:
+            table = table.replace('\x07headrows\x07', headrows, 1)
+        if footrows:
+            table = table.replace('\x07footrows\x07', footrows, 1)
+        table = table.replace('\x07bodyrows\x07', bodyrows, 1)
+        writer.write(table,trace='table')
+
+class Tables_OLD(AbstractBlocks):
+    """List of tables."""
+    BLOCK_TYPE = Table_OLD
+    PREFIX = 'old_tabledef-'
+    def __init__(self):
+        AbstractBlocks.__init__(self)
+    def load(self,sections):
+        AbstractBlocks.load(self,sections)
+    def validate(self):
+        # Does not call AbstractBlocks.validate().
+        # Check we have a default table definition,
+        for i in range(len(self.blocks)):
+            if self.blocks[i].name == 'old_tabledef-default':
+                default = self.blocks[i]
+                break
+        else:
+            raise EAsciiDoc,'missing section: [OLD_tabledef-default]'
+        # Set default table defaults.
+        if default.format is None: default.subs = 'fixed'
+        # Propagate defaults to unspecified table parameters.
+        for b in self.blocks:
+            if b is not default:
+                if b.fillchar is None: b.fillchar = default.fillchar
+                if b.format is None: b.format = default.format
+                if b.template is None: b.template = default.template
+                if b.colspec is None: b.colspec = default.colspec
+                if b.headrow is None: b.headrow = default.headrow
+                if b.footrow is None: b.footrow = default.footrow
+                if b.bodyrow is None: b.bodyrow = default.bodyrow
+                if b.headdata is None: b.headdata = default.headdata
+                if b.footdata is None: b.footdata = default.footdata
+                if b.bodydata is None: b.bodydata = default.bodydata
+        # Check all tables have valid fill character.
+        for b in self.blocks:
+            if not b.fillchar or len(b.fillchar) != 1:
+                raise EAsciiDoc,'[%s] missing or illegal fillchar' % b.name
+        # Build combined tables delimiter patterns and assign defaults.
+        delimiters = []
+        for b in self.blocks:
+            # Ruler is:
+            #   (ColStop,(ColWidth,FillChar+)?)+, FillChar+, TableWidth?
+            b.delimiter = r'^(' + Table_OLD.COL_STOP \
+                + r'(\d*|' + re.escape(b.fillchar) + r'*)' \
+                + r')+' \
+                + re.escape(b.fillchar) + r'+' \
+                + '([\d\.]*)$'
+            delimiters.append(b.delimiter)
+            if not b.headrow:
+                b.headrow = b.bodyrow
+            if not b.footrow:
+                b.footrow = b.bodyrow
+            if not b.headdata:
+                b.headdata = b.bodydata
+            if not b.footdata:
+                b.footdata = b.bodydata
+        self.delimiters = re_join(delimiters)
+        # Check table definitions are valid.
+        for b in self.blocks:
+            b.validate()
+            if config.verbose:
+                if b.check_msg:
+                    message.warning('[%s] table definition: %s' % (b.name,b.check_msg))
+
+# End of deprecated old table classes.
+#---------------------------------------------------------------------------
+
+#---------------------------------------------------------------------------
+# Filter commands.
+#---------------------------------------------------------------------------
+import shutil, zipfile
+
+def die(msg):
+    message.stderr(msg)
+    sys.exit(1)
+
+def unzip(zip_file, destdir):
+    """
+    Unzip Zip file to destination directory.
+    Throws exception if error occurs.
+    """
+    zipo = zipfile.ZipFile(zip_file, 'r')
+    try:
+        for zi in zipo.infolist():
+            outfile = zi.filename
+            if not outfile.endswith('/'):
+                d, outfile = os.path.split(outfile)
+                directory = os.path.normpath(os.path.join(destdir, d))
+                if not os.path.isdir(directory):
+                    os.makedirs(directory)
+                outfile = os.path.join(directory, outfile)
+                perms = (zi.external_attr >> 16) & 0777
+                message.verbose('extracting: %s' % outfile)
+                fh = os.open(outfile, os.O_CREAT | os.O_WRONLY, perms)
+                try:
+                    os.write(fh, zipo.read(zi.filename))
+                finally:
+                    os.close(fh)
+    finally:
+        zipo.close()
+
+class Filter:
+    """
+    --filter option commands.
+    """
+
+    @staticmethod
+    def get_filters_dir():
+        """
+        Return path of .asciidoc/filters in user's home direcory or None if
+        user home not defined.
+        """
+        result = userdir()
+        if result:
+            result = os.path.join(result,'.asciidoc','filters')
+        return result
+
+    @staticmethod
+    def install(args):
+        """
+        Install filter Zip file.
+        args[0] is filter zip file path.
+        args[1] is optional destination filters directory.
+        """
+        if len(args) not in (1,2):
+            die('invalid number of arguments: --filter install %s'
+                    % ' '.join(args))
+        zip_file = args[0]
+        if not os.path.isfile(zip_file):
+            die('file not found: %s' % zip_file)
+        reo = re.match(r'^\w+',os.path.split(zip_file)[1])
+        if not reo:
+            die('filter file name does not start with legal filter name: %s'
+                    % zip_file)
+        filter_name = reo.group()
+        if len(args) == 2:
+            filters_dir = args[1]
+            if not os.path.isdir(filters_dir):
+                die('directory not found: %s' % filters_dir)
+        else:
+            filters_dir = Filter.get_filters_dir()
+            if not filters_dir:
+                die('user home directory is not defined')
+        filter_dir = os.path.join(filters_dir, filter_name)
+        if os.path.exists(filter_dir):
+            die('filter is already installed: %s' % filter_dir)
+        try:
+            os.makedirs(filter_dir)
+        except Exception,e:
+            die('failed to create filter directory: %s' % str(e))
+        try:
+            unzip(zip_file, filter_dir)
+        except Exception,e:
+            die('failed to extract filter: %s' % str(e))
+
+    @staticmethod
+    def remove(args):
+        """
+        Delete filter from .asciidoc/filters/ in user's home directory.
+        args[0] is filter name.
+        args[1] is optional filters directory.
+        """
+        if len(args) not in (1,2):
+            die('invalid number of arguments: --filter remove %s'
+                    % ' '.join(args))
+        filter_name = args[0]
+        if not re.match(r'^\w+$',filter_name):
+            die('illegal filter name: %s' % filter_name)
+        if len(args) == 2:
+            d = args[1]
+            if not os.path.isdir(d):
+                die('directory not found: %s' % d)
+        else:
+            d = Filter.get_filters_dir()
+            if not d:
+                die('user directory is not defined')
+        filter_dir = os.path.join(d, filter_name)
+        if not os.path.isdir(filter_dir):
+            die('cannot find filter: %s' % filter_dir)
+        try:
+            message.verbose('removing: %s' % filter_dir)
+            shutil.rmtree(filter_dir)
+        except Exception,e:
+            die('failed to delete filter: %s' % str(e))
+
+    @staticmethod
+    def list():
+        """
+        List all filter directories (global and local).
+        """
+        for d in [os.path.join(d,'filters') for d in config.get_load_dirs()]:
+            if os.path.isdir(d):
+                for f in os.walk(d).next()[1]:
+                    message.stdout(os.path.join(d,f))
+
+
+#---------------------------------------------------------------------------
+# Application code.
+#---------------------------------------------------------------------------
+# Constants
+# ---------
+APP_FILE = None             # This file's full path.
+APP_DIR = None              # This file's directory.
+USER_DIR = None             # ~/.asciidoc
+# Global configuration files directory (set by Makefile build target).
+CONF_DIR = '/etc/asciidoc'
+HELP_FILE = 'help.conf'     # Default (English) help file.
+
+# Globals
+# -------
+document = Document()       # The document being processed.
+config = Config()           # Configuration file reader.
+reader = Reader()           # Input stream line reader.
+writer = Writer()           # Output stream line writer.
+message = Message()         # Message functions.
+paragraphs = Paragraphs()   # Paragraph definitions.
+lists = Lists()             # List definitions.
+blocks = DelimitedBlocks()  # DelimitedBlock definitions.
+tables_OLD = Tables_OLD()   # Table_OLD definitions.
+tables = Tables()           # Table definitions.
+macros = Macros()           # Macro definitions.
+calloutmap = CalloutMap()   # Coordinates callouts and callout list.
+trace = Trace()             # Implements trace attribute processing.
+
+### Used by asciidocapi.py ###
+# List of message strings written to stderr.
+messages = message.messages
+
+
+def asciidoc(backend, doctype, confiles, infile, outfile, options):
+    """Convert AsciiDoc document to DocBook document of type doctype
+    The AsciiDoc document is read from file object src the translated
+    DocBook file written to file object dst."""
+    def load_conffiles(include=[], exclude=[]):
+        # Load conf files specified on the command-line and by the conf-files attribute.
+        files = document.attributes.get('conf-files','')
+        files = [f.strip() for f in files.split('|') if f.strip()]
+        files += confiles
+        if files:
+            for f in files:
+                if os.path.isfile(f):
+                    config.load_file(f, include=include, exclude=exclude)
+                else:
+                    raise EAsciiDoc,'configuration file %s missing' % f
+
+    try:
+        if doctype not in (None,'article','manpage','book'):
+            raise EAsciiDoc,'illegal document type'
+        # Set processing options.
+        for o in options:
+            if o == '-c': config.dumping = True
+            if o == '-s': config.header_footer = False
+            if o == '-v': config.verbose = True
+        document.update_attributes()
+        if '-e' not in options:
+            # Load asciidoc.conf files in two passes: the first for attributes
+            # the second for everything. This is so that locally set attributes
+            # available are in the global asciidoc.conf
+            if not config.load_from_dirs('asciidoc.conf',include=['attributes']):
+                raise EAsciiDoc,'configuration file asciidoc.conf missing'
+            load_conffiles(include=['attributes'])
+            config.load_from_dirs('asciidoc.conf')
+            if infile != '<stdin>':
+                indir = os.path.dirname(infile)
+                config.load_file('asciidoc.conf', indir,
+                                include=['attributes','titles','specialchars'])
+        else:
+            load_conffiles(include=['attributes','titles','specialchars'])
+        document.update_attributes()
+        # Check the infile exists.
+        if infile != '<stdin>':
+            if not os.path.isfile(infile):
+                raise EAsciiDoc,'input file %s missing' % infile
+        document.infile = infile
+        AttributeList.initialize()
+        # Open input file and parse document header.
+        reader.tabsize = config.tabsize
+        reader.open(infile)
+        has_header = document.parse_header(doctype,backend)
+        # doctype is now finalized.
+        document.attributes['doctype-'+document.doctype] = ''
+        # Load backend configuration files.
+        if '-e' not in options:
+            f = document.backend + '.conf'
+            if not config.find_in_dirs(f):
+                message.warning('missing backend conf file: %s' % f, linenos=False)
+            config.load_backend()
+        # backend is now known.
+        document.attributes['backend-'+document.backend] = ''
+        document.attributes[document.backend+'-'+document.doctype] = ''
+        doc_conffiles = []
+        if '-e' not in options:
+            # Load filters and language file.
+            config.load_filters()
+            document.load_lang()
+            if infile != '<stdin>':
+                # Load local conf files (files in the source file directory).
+                config.load_file('asciidoc.conf', indir)
+                config.load_backend([indir])
+                config.load_filters([indir])
+                # Load document specific configuration files.
+                f = os.path.splitext(infile)[0]
+                doc_conffiles = [
+                        f for f in (f+'.conf', f+'-'+document.backend+'.conf')
+                        if os.path.isfile(f) ]
+                for f in doc_conffiles:
+                    config.load_file(f)
+        load_conffiles()
+        # Build asciidoc-args attribute.
+        args = ''
+        # Add custom conf file arguments.
+        for f in doc_conffiles + confiles:
+            args += ' --conf-file "%s"' % f
+        # Add command-line and header attributes.
+        attrs = {}
+        attrs.update(AttributeEntry.attributes)
+        attrs.update(config.cmd_attrs)
+        if 'title' in attrs:    # Don't pass the header title.
+            del attrs['title']
+        for k,v in attrs.items():
+            if v:
+                args += ' --attribute "%s=%s"' % (k,v)
+            else:
+                args += ' --attribute "%s"' % k
+        document.attributes['asciidoc-args'] = args
+        # Build outfile name.
+        if outfile is None:
+            outfile = os.path.splitext(infile)[0] + '.' + document.backend
+            if config.outfilesuffix:
+                # Change file extension.
+                outfile = os.path.splitext(outfile)[0] + config.outfilesuffix
+        document.outfile = outfile
+        # Document header attributes override conf file attributes.
+        document.attributes.update(AttributeEntry.attributes)
+        document.update_attributes()
+        # Configuration is fully loaded so can expand templates.
+        config.expand_all_templates()
+        # Check configuration for consistency.
+        config.validate()
+        paragraphs.initialize()
+        lists.initialize()
+        if config.dumping:
+            config.dump()
+        else:
+            writer.newline = config.newline
+            try:
+                writer.open(outfile, reader.bom)
+                try:
+                    document.translate(has_header) # Generate the output.
+                finally:
+                    writer.close()
+            finally:
+                reader.closefile()
+    except KeyboardInterrupt:
+        raise
+    except Exception,e:
+        # Cleanup.
+        if outfile and outfile != '<stdout>' and os.path.isfile(outfile):
+            os.unlink(outfile)
+        # Build and print error description.
+        msg = 'FAILED: '
+        if reader.cursor:
+            msg = message.format('', msg)
+        if isinstance(e, EAsciiDoc):
+            message.stderr('%s%s' % (msg,str(e)))
+        else:
+            if __name__ == '__main__':
+                message.stderr(msg+'unexpected error:')
+                message.stderr('-'*60)
+                traceback.print_exc(file=sys.stderr)
+                message.stderr('-'*60)
+            else:
+                message.stderr('%sunexpected error: %s' % (msg,str(e)))
+        sys.exit(1)
+
+def usage(msg=''):
+    if msg:
+        message.stderr(msg)
+    show_help('default', sys.stderr)
+
+def show_help(topic, f=None):
+    """Print help topic to file object f."""
+    if f is None:
+        f = sys.stdout
+    # Select help file.
+    lang = config.cmd_attrs.get('lang')
+    if lang and lang != 'en':
+        help_file = 'help-' + lang + '.conf'
+    else:
+        help_file = HELP_FILE
+    # Print [topic] section from help file.
+    config.load_from_dirs(help_file)
+    if len(config.sections) == 0:
+        # Default to English if specified language help files not found.
+        help_file = HELP_FILE
+        config.load_from_dirs(help_file)
+    if len(config.sections) == 0:
+        message.stderr('no help topics found')
+        sys.exit(1)
+    n = 0
+    for k in config.sections:
+        if re.match(re.escape(topic), k):
+            n += 1
+            lines = config.sections[k]
+    if n == 0:
+        if topic != 'topics':
+            message.stderr('help topic not found: [%s] in %s' % (topic, help_file))
+        message.stderr('available help topics: %s' % ', '.join(config.sections.keys()))
+        sys.exit(1)
+    elif n > 1:
+        message.stderr('ambiguous help topic: %s' % topic)
+    else:
+        for line in lines:
+            print >>f, line
+
+### Used by asciidocapi.py ###
+def execute(cmd,opts,args):
+    """
+    Execute asciidoc with command-line options and arguments.
+    cmd is asciidoc command or asciidoc.py path.
+    opts and args conform to values returned by getopt.getopt().
+    Raises SystemExit if an error occurs.
+
+    Doctests:
+
+    1. Check execution:
+
+       >>> import StringIO
+       >>> infile = StringIO.StringIO('Hello *{author}*')
+       >>> outfile = StringIO.StringIO()
+       >>> opts = []
+       >>> opts.append(('--backend','html4'))
+       >>> opts.append(('--no-header-footer',None))
+       >>> opts.append(('--attribute','author=Joe Bloggs'))
+       >>> opts.append(('--out-file',outfile))
+       >>> execute(__file__, opts, [infile])
+       >>> print outfile.getvalue()
+       <p>Hello <strong>Joe Bloggs</strong></p>
+
+       >>>
+
+    """
+    config.init(cmd)
+    if len(args) > 1:
+        usage('To many arguments')
+        sys.exit(1)
+    backend = None
+    doctype = None
+    confiles = []
+    outfile = None
+    options = []
+    help_option = False
+    for o,v in opts:
+        if o in ('--help','-h'):
+            help_option = True
+        #DEPRECATED: --unsafe option.
+        if o == '--unsafe':
+            document.safe = False
+        if o == '--safe':
+            document.safe = True
+        if o == '--version':
+            print('asciidoc %s' % VERSION)
+            sys.exit(0)
+        if o in ('-b','--backend'):
+            backend = v
+#            config.cmd_attrs['backend'] = v
+        if o in ('-c','--dump-conf'):
+            options.append('-c')
+        if o in ('-d','--doctype'):
+            doctype = v
+#            config.cmd_attrs['doctype'] = v
+        if o in ('-e','--no-conf'):
+            options.append('-e')
+        if o in ('-f','--conf-file'):
+            confiles.append(v)
+        if o in ('-n','--section-numbers'):
+            o = '-a'
+            v = 'numbered'
+        if o in ('-a','--attribute'):
+            e = parse_entry(v, allow_name_only=True)
+            if not e:
+                usage('Illegal -a option: %s' % v)
+                sys.exit(1)
+            k,v = e
+            # A @ suffix denotes don't override existing document attributes.
+            if v and v[-1] == '@':
+                document.attributes[k] = v[:-1]
+            else:
+                config.cmd_attrs[k] = v
+        if o in ('-o','--out-file'):
+            outfile = v
+        if o in ('-s','--no-header-footer'):
+            options.append('-s')
+        if o in ('-v','--verbose'):
+            options.append('-v')
+    if help_option:
+        if len(args) == 0:
+            show_help('default')
+        else:
+            show_help(args[-1])
+        sys.exit(0)
+    if len(args) == 0 and len(opts) == 0:
+        usage()
+        sys.exit(0)
+    if len(args) == 0:
+        usage('No source file specified')
+        sys.exit(1)
+#    if not backend:
+#        usage('No --backend option specified')
+#        sys.exit(1)
+    stdin,stdout = sys.stdin,sys.stdout
+    try:
+        infile = args[0]
+        if infile == '-':
+            infile = '<stdin>'
+        elif isinstance(infile, str):
+            infile = os.path.abspath(infile)
+        else:   # Input file is file object from API call.
+            sys.stdin = infile
+            infile = '<stdin>'
+        if outfile == '-':
+            outfile = '<stdout>'
+        elif isinstance(outfile, str):
+            outfile = os.path.abspath(outfile)
+        elif outfile is None:
+            if infile == '<stdin>':
+                outfile = '<stdout>'
+        else:   # Output file is file object from API call.
+            sys.stdout = outfile
+            outfile = '<stdout>'
+        # Do the work.
+        asciidoc(backend, doctype, confiles, infile, outfile, options)
+        if document.has_errors:
+            sys.exit(1)
+    finally:
+        sys.stdin,sys.stdout = stdin,stdout
+
+if __name__ == '__main__':
+    # Process command line options.
+    import getopt
+    try:
+        #DEPRECATED: --unsafe option.
+        opts,args = getopt.getopt(sys.argv[1:],
+            'a:b:cd:ef:hno:svw:',
+            ['attribute=','backend=','conf-file=','doctype=','dump-conf',
+            'help','no-conf','no-header-footer','out-file=',
+            'section-numbers','verbose','version','safe','unsafe',
+            'doctest','filter'])
+    except getopt.GetoptError:
+        message.stderr('illegal command options')
+        sys.exit(1)
+    if '--doctest' in [opt[0] for opt in opts]:
+        # Run module doctests.
+        import doctest
+        options = doctest.NORMALIZE_WHITESPACE + doctest.ELLIPSIS
+        failures,tries = doctest.testmod(optionflags=options)
+        if failures == 0:
+            message.stderr('All doctests passed')
+            sys.exit(0)
+        else:
+            sys.exit(1)
+    if '--filter' in [opt[0] for opt in opts]:
+        config.init(sys.argv[0])
+        config.verbose = bool(set(['-v','--verbose']) & set([opt[0] for opt in opts]))
+        if not args:
+            die('missing --filter command')
+        elif args[0] == 'install':
+            Filter.install(args[1:])
+        elif args[0] == 'remove':
+            Filter.remove(args[1:])
+        elif args[0] == 'list':
+            Filter.list()
+        else:
+            die('illegal --filter command: %s' % args[0])
+        sys.exit(0)
+    try:
+        execute(sys.argv[0],opts,args)
+    except KeyboardInterrupt:
+        sys.exit(1)
diff --git a/doc/www/create-relnotes.sh b/doc/www/create-relnotes.sh
new file mode 100755 (executable)
index 0000000..9e731e8
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+# 
+# This script requires asciidoc http://www.methods.co.nz/asciidoc/
+
+# (echo -e "Netatalk NEWS\n-------------\n\n" ; cat NEWS) | ./asciidoc.py -f netatalk-news.conf -b css -o NEWS.html - && chmod g+w NEWS.html
+./asciidoc.py -f netatalk-relnotes.conf -b html5 -o ReleaseNotes.html ReleaseNotes && chmod g+w ReleaseNotes.html
diff --git a/doc/www/html5.conf b/doc/www/html5.conf
new file mode 100644 (file)
index 0000000..cedc3fd
--- /dev/null
@@ -0,0 +1,686 @@
+#
+# html5.conf
+#
+# Asciidoc configuration file.
+# html5 backend.
+#
+
+[miscellaneous]
+outfilesuffix=.html
+
+[attributes]
+basebackend=html
+basebackend-html=
+basebackend-html5=
+
+[replacements2]
+# Line break.
+(?m)^(.*)\s\+$=\1<br>
+
+[replacements]
+ifdef::asciidoc7compatible[]
+# Superscripts.
+\^(.+?)\^=<sup>\1</sup>
+# Subscripts.
+~(.+?)~=<sub>\1</sub>
+endif::asciidoc7compatible[]
+
+[ruler-blockmacro]
+<hr>
+
+[pagebreak-blockmacro]
+<div style="page-break-after:always"></div>
+
+[blockdef-pass]
+asciimath-style=template="asciimathblock",subs=[]
+latexmath-style=template="latexmathblock",subs=[]
+
+[macros]
+(?u)^(?P<name>audio|video)::(?P<target>\S*?)(\[(?P<attrlist>.*?)\])$=#
+# math macros.
+# Special characters are escaped in HTML math markup.
+(?su)[\\]?(?P<name>asciimath|latexmath):(?P<subslist>\S*?)\[(?P<passtext>.*?)(?<!\\)\]=[specialcharacters]
+(?u)^(?P<name>asciimath|latexmath)::(?P<subslist>\S*?)(\[(?P<passtext>.*?)\])$=#[specialcharacters]
+
+[asciimath-inlinemacro]
+`{passtext}`
+
+[asciimath-blockmacro]
+<div class="mathblock{role? {role}}"{id? id="{id}"}>
+<div class="content">
+<div class="title">{title}</div>
+`{passtext}`
+</div></div>
+
+[asciimathblock]
+<div class="mathblock{role? {role}}"{id? id="{id}"}>
+<div class="content">
+<div class="title">{title}</div>
+`|`
+</div></div>
+
+[latexmath-inlinemacro]
+{passtext}
+
+[latexmath-blockmacro]
+<div class="mathblock{role? {role}}"{id? id="{id}"}>
+<div class="content">
+<div class="title">{title}</div>
+{passtext}
+</div></div>
+
+[latexmathblock]
+<div class="mathblock{role? {role}}"{id? id="{id}"}>
+<div class="content">
+<div class="title">{title}</div>
+|
+</div></div>
+
+[image-inlinemacro]
+<span class="image{role? {role}}">
+<a class="image" href="{link}">
+{data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}{title? title="{title}"}>
+{data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}{title? title="{title}"} src="data:image/{eval:os.path.splitext('{target}')[1][1:]};base64,
+{data-uri#}{sys3:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join("{indir={outdir}}","{imagesdir=}","{target}")}"}">
+{link#}</a>
+</span>
+
+[image-blockmacro]
+<div class="imageblock{style? {style}}{role? {role}}"{id? id="{id}"}{align? style="text-align:{align};"}{float? style="float:{float};"}>
+<div class="content">
+<a class="image" href="{link}">
+{data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}>
+{data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"} src="data:image/{eval:os.path.splitext('{target}')[1][1:]};base64,
+{data-uri#}{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join("{indir={outdir}}","{imagesdir=}","{target}")}"}">
+{link#}</a>
+</div>
+<div class="title">{caption={figure-caption} {counter:figure-number}. }{title}</div>
+</div>
+
+[audio-blockmacro]
+<div class="audioblock{role? {role}}"{id? id="{id}"}>
+<div class="title">{caption=}{title}</div>
+<div class="content">
+<audio src="{imagesdir=}{imagesdir?/}{target}"{autoplay-option? autoplay}{nocontrols-option! controls}{loop-option? loop}>
+Your browser does not support the audio tag.
+</audio>
+</div></div>
+
+[video-blockmacro]
+<div class="videoblock{role? {role}}"{id? id="{id}"}>
+<div class="title">{caption=}{title}</div>
+<div class="content">
+<video src="{imagesdir=}{imagesdir?/}{target}"{width? width="{width}"}{height? height="{height}"}{poster? poster="{poster}"}{autoplay-option? autoplay}{nocontrols-option! controls}{loop-option? loop}>
+Your browser does not support the video tag.
+</video>
+</div></div>
+
+[unfloat-blockmacro]
+<div style="clear:both;"></div>
+
+[indexterm-inlinemacro]
+# Index term.
+{empty}
+
+[indexterm2-inlinemacro]
+# Index term.
+# Single entry index term that is visible in the primary text flow.
+{1}
+
+[footnote-inlinemacro]
+# footnote:[<text>].
+<span class="footnote"><br>[{0}]<br></span>
+
+[footnoteref-inlinemacro]
+# footnoteref:[<id>], create reference to footnote.
+{2%}<span class="footnoteref"><br><a href="#_footnote_{1}">[{1}]</a><br></span>
+# footnoteref:[<id>,<text>], create footnote with ID.
+{2#}<span class="footnote" id="_footnote_{1}"><br>[{2}]<br></span>
+
+[callout-inlinemacro]
+ifndef::icons[]
+<b>&lt;{index}&gt;</b>
+endif::icons[]
+ifdef::icons[]
+ifndef::data-uri[]
+<img src="{icon={iconsdir}/callouts/{index}.png}" alt="{index}">
+endif::data-uri[]
+ifdef::data-uri[]
+<img alt="{index}" src="data:image/png;base64,
+{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join("{indir={outdir}}","{icon={iconsdir}/callouts/{index}.png}")}"}">
+endif::data-uri[]
+endif::icons[]
+
+# Comment line macros.
+[comment-inlinemacro]
+{showcomments#}<br><span class="comment">{passtext}</span><br>
+
+[comment-blockmacro]
+{showcomments#}<p><span class="comment">{passtext}</span></p>
+
+[literal-inlinemacro]
+# Inline literal.
+<span class="monospaced">{passtext}</span>
+
+# List tags.
+[listtags-bulleted]
+list=<div class="ulist{style? {style}}{compact-option? compact}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ul>|</ul></div>
+item=<li>|</li>
+text=<p>|</p>
+
+[listtags-numbered]
+# The start attribute is not valid XHTML 1.1 but all browsers support it.
+list=<div class="olist{style? {style}}{compact-option? compact}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ol class="{style}"{start? start="{start}"}>|</ol></div>
+item=<li>|</li>
+text=<p>|</p>
+
+[listtags-labeled]
+list=<div class="dlist{compact-option? compact}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<dl>|</dl></div>
+entry=
+label=
+term=<dt class="hdlist1{strong-option? strong}">|</dt>
+item=<dd>|</dd>
+text=<p>|</p>
+
+[listtags-horizontal]
+list=<div class="hdlist{compact-option? compact}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<table>{labelwidth?<col width="{labelwidth}%">}{itemwidth?<col width="{itemwidth}%">}|</table></div>
+label=<td class="hdlist1{strong-option? strong}">|</td>
+term=|<br>
+entry=<tr>|</tr>
+item=<td class="hdlist2">|</td>
+text=<p style="margin-top: 0;">|</p>
+
+[listtags-qanda]
+list=<div class="qlist{style? {style}}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ol>|</ol></div>
+entry=<li>|</li>
+label=
+term=<p><em>|</em></p>
+item=
+text=<p>|</p>
+
+[listtags-callout]
+ifndef::icons[]
+list=<div class="colist{style? {style}}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ol>|</ol></div>
+item=<li>|</li>
+text=<p>|</p>
+endif::icons[]
+ifdef::icons[]
+list=<div class="colist{style? {style}}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<table>|</table></div>
+ifndef::data-uri[]
+item=<tr><td><img src="{iconsdir}/callouts/{listindex}.png" alt="{listindex}"></td><td>|</td></tr>
+endif::data-uri[]
+ifdef::data-uri[]
+item=<tr><td><img alt="{listindex}" src="data:image/png;base64, {sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join("{indir={outdir}}","{icon={iconsdir}/callouts/{listindex}.png}")}"}"></td><td>|</td></tr>
+endif::data-uri[]
+text=|
+endif::icons[]
+
+[listtags-glossary]
+list=<div class="dlist{style? {style}}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<dl>|</dl></div>
+label=
+entry=
+term=<dt>|</dt>
+item=<dd>|</dd>
+text=<p>|</p>
+
+[listtags-bibliography]
+list=<div class="ulist{style? {style}}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ul>|</ul></div>
+item=<li>|</li>
+text=<p>|</p>
+
+[tags]
+# Quoted text.
+emphasis=<em>{1?<span class="{1}">}|{1?</span>}</em>
+strong=<strong>{1?<span class="{1}">}|{1?</span>}</strong>
+monospaced=<span class="monospaced{1? {1}}">|</span>
+singlequoted={lsquo}{1?<span class="{1}">}|{1?</span>}{rsquo}
+doublequoted={ldquo}{1?<span class="{1}">}|{1?</span>}{rdquo}
+unquoted={1?<span class="{1}">}|{1?</span>}
+superscript=<sup>{1?<span class="{1}">}|{1?</span>}</sup>
+subscript=<sub>{1?<span class="{1}">}|{1?</span>}</sub>
+
+ifdef::deprecated-quotes[]
+# Override with deprecated quote attributes.
+emphasis={role?<span class="{role}">}<em{1,2,3? style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</em>{role?</span>}
+strong={role?<span class="{role}">}<strong{1,2,3? style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</strong>{role?</span>}
+monospaced=<span class="monospaced{role? {role}}"{1,2,3? style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</span>
+singlequoted={role?<span class="{role}">}{1,2,3?<span style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?">}{amp}#8216;|{amp}#8217;{1,2,3?</span>}{role?</span>}
+doublequoted={role?<span class="{role}">}{1,2,3?<span style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?">}{amp}#8220;|{amp}#8221;{1,2,3?</span>}{role?</span>}
+unquoted={role?<span class="{role}">}{1,2,3?<span style="{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}">}|{1,2,3?</span>}{role?</span>}
+superscript={role?<span class="{role}">}<sup{1,2,3? style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</sup>{role?</span>}
+subscript={role?<span class="{role}">}<sub{1,2,3? style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</sub>{role?</span>}
+endif::deprecated-quotes[]
+
+# Inline macros
+[http-inlinemacro]
+<a href="{name}:{target}">{0={name}:{target}}</a>
+[https-inlinemacro]
+<a href="{name}:{target}">{0={name}:{target}}</a>
+[ftp-inlinemacro]
+<a href="{name}:{target}">{0={name}:{target}}</a>
+[file-inlinemacro]
+<a href="{name}:{target}">{0={name}:{target}}</a>
+[irc-inlinemacro]
+<a href="{name}:{target}">{0={name}:{target}}</a>
+[mailto-inlinemacro]
+<a href="mailto:{target}">{0={target}}</a>
+[link-inlinemacro]
+<a href="{target}">{0={target}}</a>
+[callto-inlinemacro]
+<a href="{name}:{target}">{0={target}}</a>
+# anchor:id[text]
+[anchor-inlinemacro]
+<a id="{target}"></a>
+# [[id,text]]
+[anchor2-inlinemacro]
+<a id="{1}"></a>
+# [[[id]]]
+[anchor3-inlinemacro]
+<a id="{1}"></a>[{1}]
+# xref:id[text]
+[xref-inlinemacro]
+<a href="#{target}">{0=[{target}]}</a>
+# <<id,text>>
+[xref2-inlinemacro]
+<a href="#{1}">{2=[{1}]}</a>
+
+# Special word substitution.
+[emphasizedwords]
+<em>{words}</em>
+[monospacedwords]
+<span class="monospaced">{words}</span>
+[strongwords]
+<strong>{words}</strong>
+
+# Paragraph substitution.
+[paragraph]
+<div class="paragraph{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<p>
+|
+</p></div>
+
+[admonitionparagraph]
+template::[admonitionblock]
+
+# Delimited blocks.
+[listingblock]
+<div class="listingblock{role? {role}}"{id? id="{id}"}>
+<div class="title">{caption=}{title}</div>
+<div class="content monospaced">
+<pre>
+|
+</pre>
+</div></div>
+
+[literalblock]
+<div class="literalblock{role? {role}}"{id? id="{id}"}>
+<div class="title">{title}</div>
+<div class="content monospaced">
+<pre>
+|
+</pre>
+</div></div>
+
+[sidebarblock]
+<div class="sidebarblock{role? {role}}"{id? id="{id}"}>
+<div class="content">
+<div class="title">{title}</div>
+|
+</div></div>
+
+[openblock]
+<div class="openblock{role? {role}}"{id? id="{id}"}>
+<div class="title">{title}</div>
+<div class="content">
+|
+</div></div>
+
+[partintroblock]
+template::[openblock]
+
+[abstractblock]
+template::[quoteblock]
+
+[quoteblock]
+<div class="quoteblock{role? {role}}"{id? id="{id}"}>
+<div class="title">{title}</div>
+<div class="content">
+|
+</div>
+<div class="attribution">
+<em>{citetitle}</em>{attribution?<br>}
+&#8212; {attribution}
+</div></div>
+
+[verseblock]
+<div class="verseblock{role? {role}}"{id? id="{id}"}>
+<div class="title">{title}</div>
+<pre class="content">
+|
+</pre>
+<div class="attribution">
+<em>{citetitle}</em>{attribution?<br>}
+&#8212; {attribution}
+</div></div>
+
+[exampleblock]
+<div class="exampleblock{role? {role}}"{id? id="{id}"}>
+<div class="title">{caption={example-caption} {counter:example-number}. }{title}</div>
+<div class="content">
+|
+</div></div>
+
+[admonitionblock]
+<div class="admonitionblock{role? {role}}"{id? id="{id}"}>
+<table><tr>
+<td class="icon">
+{data-uri%}{icons#}<img src="{icon={iconsdir}/{name}.png}" alt="{caption}">
+{data-uri#}{icons#}<img alt="{caption}" src="data:image/png;base64,
+{data-uri#}{icons#}{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join("{indir={outdir}}","{icon={iconsdir}/{name}.png}")}"}">
+{icons%}<div class="title">{caption}</div>
+</td>
+<td class="content">
+<div class="title">{title}</div>
+|
+</td>
+</tr></table>
+</div>
+
+# Tables.
+[tabletags-default]
+colspec=<col{autowidth-option! style="width:{colpcwidth}%;"}>
+bodyrow=<tr>|</tr>
+headdata=<th class="tableblock halign-{halign=left} valign-{valign=top}" {colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }>|</th>
+bodydata=<td class="tableblock halign-{halign=left} valign-{valign=top}" {colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }>|</td>
+paragraph=<p class="tableblock">|</p>
+
+[tabletags-header]
+paragraph=<p class="tableblock header">|</p>
+
+[tabletags-emphasis]
+paragraph=<p class="tableblock"><em>|</em></p>
+
+[tabletags-strong]
+paragraph=<p class="tableblock"><strong>|</strong></p>
+
+[tabletags-monospaced]
+paragraph=<p class="tableblock monospaced">|</p>
+
+[tabletags-verse]
+bodydata=<td class="tableblock halign-{halign=left} valign-{valign=top}" {colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }><div class="verse">|</div></td>
+paragraph=
+
+[tabletags-literal]
+bodydata=<td class="tableblock halign-{halign=left} valign-{valign=top}" {colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }><div class="literal monospaced"><pre>|</pre></div></td>
+paragraph=
+
+[tabletags-asciidoc]
+bodydata=<td class="tableblock halign-{halign=left} valign-{valign=top}" {colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }><div>|</div></td>
+paragraph=
+
+[table]
+<table class="tableblock frame-{frame=all} grid-{grid=all}{role? {role}}"{id? id="{id}"}
+style="
+margin-left:{align@left:0}{align@center|right:auto}; margin-right:{align@left|center:auto}{align@right:0};
+float:{float};
+{autowidth-option%}width:{tablepcwidth}%;
+{autowidth-option#}{width#style=width:{tablepcwidth}%;}
+">
+<caption class="title">{caption={table-caption} {counter:table-number}. }{title}</caption>
+{colspecs}
+{headrows#}<thead>
+{headrows}
+{headrows#}</thead>
+{footrows#}<tfoot>
+{footrows}
+{footrows#}</tfoot>
+<tbody>
+{bodyrows}
+</tbody>
+</table>
+
+#--------------------------------------------------------------------
+# Deprecated old table definitions.
+#
+
+[miscellaneous]
+# Screen width in pixels.
+pagewidth=800
+pageunits=px
+
+[old_tabledef-default]
+template=old_table
+colspec=<col style="width:{colwidth}{pageunits};" />
+bodyrow=<tr>|</tr>
+headdata=<th class="tableblock halign-{colalign=left}">|</th>
+footdata=<td class="tableblock halign-{colalign=left}">|</td>
+bodydata=<td class="tableblock halign-{colalign=left}">|</td>
+
+[old_table]
+<table class="tableblock frame-{frame=all} grid-{grid=all}"{id? id="{id}"}>
+<caption class="title">{caption={table-caption}}{title}</caption>
+{colspecs}
+{headrows#}<thead>
+{headrows}
+{headrows#}</thead>
+{footrows#}<tfoot>
+{footrows}
+{footrows#}</tfoot>
+<tbody style="vertical-align:top;">
+{bodyrows}
+</tbody>
+</table>
+
+# End of deprecated old table definitions.
+#--------------------------------------------------------------------
+
+[floatingtitle]
+<h{level@0:1}{level@1:2}{level@2:3}{level@3:4}{level@4:5}{id? id="{id}"} class="float">{title}</h{level@0:1}{level@1:2}{level@2:3}{level@3:4}{level@4:5}>
+
+[preamble]
+# Untitled elements between header and first section title.
+<div id="preamble">
+<div class="sectionbody">
+|
+</div>
+</div>
+
+# Document sections.
+[sect0]
+<h1{id? id="{id}"}>{title}</h1>
+|
+
+[sect1]
+<div class="sect1{style? {style}}{role? {role}}">
+<h2{id? id="{id}"}>{numbered?{sectnum} }{title}</h2>
+<div class="sectionbody">
+|
+</div>
+</div>
+
+[sect2]
+<div class="sect2{style? {style}}{role? {role}}">
+<h3{id? id="{id}"}>{numbered?{sectnum} }{title}</h3>
+|
+</div>
+
+[sect3]
+<div class="sect3{style? {style}}{role? {role}}">
+<h4{id? id="{id}"}>{numbered?{sectnum} }{title}</h4>
+|
+</div>
+
+[sect4]
+<div class="sect4{style? {style}}{role? {role}}">
+<h5{id? id="{id}"}>{title}</h5>
+|
+</div>
+
+[appendix]
+<div class="sect1{style? {style}}{role? {role}}">
+<h2{id? id="{id}"}>{numbered?{sectnum} }{appendix-caption} {counter:appendix-number:A}: {title}</h2>
+<div class="sectionbody">
+|
+</div>
+</div>
+
+[toc]
+<div id="toc">
+  <div id="toctitle">{toc-title}</div>
+  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
+</div>
+
+[header]
+<!DOCTYPE html>
+<html lang="{lang=en}">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset={encoding}">
+<meta name="generator" content="AsciiDoc {asciidoc-version}">
+<meta name="description" content="{description}">
+<meta name="keywords" content="{keywords}">
+<title>{title}</title>
+{title%}<title>{doctitle=}</title>
+ifdef::linkcss[]
+<link rel="stylesheet" href="{stylesdir=.}/{theme=asciidoc}.css" type="text/css">
+{doctype-manpage}<link rel="stylesheet" href="{stylesdir=.}/{theme=asciidoc}-manpage.css" type="text/css">
+ifdef::pygments[<link rel="stylesheet" href="{stylesdir=.}/pygments.css" type="text/css">]
+ifdef::toc2[<link rel="stylesheet" href="{stylesdir=.}/toc2.css" type="text/css" />]
+<link rel="stylesheet" href="{stylesdir=.}/{stylesheet}" type="text/css">
+endif::linkcss[]
+ifndef::linkcss[]
+<style type="text/css">
+include1::{stylesdir=./stylesheets}/{theme=asciidoc}.css[]
+ifdef::doctype-manpage[]
+include1::{stylesdir=./stylesheets}/{theme=asciidoc}-manpage.css[]
+endif::doctype-manpage[]
+ifdef::pygments[]
+include1::{stylesdir=./stylesheets}/pygments.css[]
+endif::pygments[]
+ifdef::toc2[]
+include1::{stylesdir=./stylesheets}/toc2.css[]
+endif::toc2[]
+include1::{stylesheet}[]
+</style>
+endif::linkcss[]
+ifndef::disable-javascript[]
+ifdef::linkcss[]
+<script type="text/javascript" src="{scriptsdir=.}/asciidoc.js"></script>
+<script type="text/javascript">
+#TODO: Escape not necessary in HTML5?
+# Escape as CDATA to pass validators.
+/*<![CDATA[*/
+asciidoc.install({toc,toc2?{toclevels}});
+/*]]>*/
+</script>
+endif::linkcss[]
+ifndef::linkcss[]
+<script type="text/javascript">
+# Escape as CDATA to pass validators.
+/*<![CDATA[*/
+include1::{scriptsdir=./javascripts}/asciidoc.js[]
+asciidoc.install({toc,toc2?{toclevels}});
+/*]]>*/
+</script>
+endif::linkcss[]
+endif::disable-javascript[]
+ifdef::asciimath[]
+ifdef::linkcss[]
+<script type="text/javascript" src="{scriptsdir=.}/ASCIIMathML.js"></script>
+endif::linkcss[]
+ifndef::linkcss[]
+<script type="text/javascript">
+# Escape as CDATA to pass validators.
+/*<![CDATA[*/
+include1::{scriptsdir=./javascripts}/ASCIIMathML.js[]
+/*]]>*/
+</script>
+endif::linkcss[]
+endif::asciimath[]
+ifdef::latexmath[]
+ifdef::linkcss[]
+<script type="text/javascript" src="{scriptsdir=.}/LaTeXMathML.js"></script>
+endif::linkcss[]
+ifndef::linkcss[]
+<script type="text/javascript">
+# Escape as CDATA to pass validators.
+/*<![CDATA[*/
+include1::{scriptsdir=./javascripts}/LaTeXMathML.js[]
+/*]]>*/
+</script>
+endif::linkcss[]
+endif::latexmath[]
+{docinfo1,docinfo2#}{include:{docdir}/docinfo.html}
+{docinfo,docinfo2#}{include:{docdir}/{docname}-docinfo.html}
+</head>
+<body class="{doctype}"{max-width? style="max-width:{max-width}"}>
+# Article, book header.
+ifndef::doctype-manpage[]
+<div id="header">
+ifndef::notitle[<h1>{doctitle}</h1>]
+ifdef::doctitle[]
+<span id="author">{author}</span><br>
+<span id="email" class="monospaced">&lt;<a href="mailto:{email}">{email}</a>&gt;</span><br>
+<span id="revnumber">version {revnumber}{revdate?,}</span>
+<span id="revdate">{revdate}</span>
+<br><span id="revremark">{revremark}</span>
+endif::doctitle[]
+ifdef::toc,toc2[{template:toc}]
+</div>
+endif::doctype-manpage[]
+# Man page header.
+ifdef::doctype-manpage[]
+<div id="header">
+<h1>
+{doctitle} Manual Page
+</h1>
+ifdef::toc,toc2[{template:toc}]
+<h2>{manname-title}</h2>
+<div class="sectionbody">
+<p>{manname} -
+   {manpurpose}
+</p>
+</div>
+</div>
+endif::doctype-manpage[]
+<div id="content">
+
+[footer]
+</div>
+{disable-javascript%<div id="footnotes"><hr></div>}
+<div id="footer">
+<div id="footer-text">
+template::[footer-text]
+</div>
+ifdef::badges[]
+<div id="footer-badges">
+ifndef::icons[]
+Valid <a href="http://validator.w3.org/check?uri=referer">XHTML</a>
+and <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>.
+endif::icons[]
+ifdef::icons[]
+<a href="http://validator.w3.org/check?uri=referer">
+  <img style="border:0;width:88px;height:31px"
+    src="http://www.w3.org/Icons/valid-xhtml11-blue"
+    alt="Valid XHTML 1.1" height="31" width="88">
+</a>
+<a href="http://jigsaw.w3.org/css-validator/">
+  <img style="border:0;width:88px;height:31px"
+    src="http://jigsaw.w3.org/css-validator/images/vcss-blue"
+    alt="Valid CSS!">
+</a>
+<a href="http://www.mozilla.org/products/firefox/">
+  <img style="border:none; width:110px; height:32px;"
+       src="http://www.spreadfirefox.com/community/images/affiliates/Buttons/110x32/safer.gif"
+       alt="Get Firefox!">
+</a>
+endif::icons[]
+</div>
+endif::badges[]
+</div>
+</body>
+</html>
+
+ifdef::doctype-manpage[]
+[synopsis]
+template::[sect1]
+endif::doctype-manpage[]
+
diff --git a/doc/www/javascripts/asciidoc.js b/doc/www/javascripts/asciidoc.js
new file mode 100644 (file)
index 0000000..2ad6c41
--- /dev/null
@@ -0,0 +1,189 @@
+var asciidoc = {  // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+  function getText(el) {
+    var text = "";
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+        text += i.data;
+      else if (i.firstChild != null)
+        text += getText(i);
+    }
+    return text;
+  }
+
+  function TocEntry(el, text, toclevel) {
+    this.element = el;
+    this.text = text;
+    this.toclevel = toclevel;
+  }
+
+  function tocEntries(el, toclevels) {
+    var result = new Array;
+    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
+    // Function that scans the DOM tree for header elements (the DOM2
+    // nodeIterator API would be a better technique but not supported by all
+    // browsers).
+    var iterate = function (el) {
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+          var mo = re.exec(i.tagName);
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+          }
+          iterate(i);
+        }
+      }
+    }
+    iterate(el);
+    return result;
+  }
+
+  var toc = document.getElementById("toc");
+  if (!toc) {
+    return;
+  }
+
+  // Delete existing TOC entries in case we're reloading the TOC.
+  var tocEntriesToRemove = [];
+  var i;
+  for (i = 0; i < toc.childNodes.length; i++) {
+    var entry = toc.childNodes[i];
+    if (entry.nodeName == 'DIV'
+     && entry.getAttribute("class")
+     && entry.getAttribute("class").match(/^toclevel/))
+      tocEntriesToRemove.push(entry);
+  }
+  for (i = 0; i < tocEntriesToRemove.length; i++) {
+    toc.removeChild(tocEntriesToRemove[i]);
+  }
+  
+  // Rebuild TOC entries.
+  var entries = tocEntries(document.getElementById("content"), toclevels);
+  for (var i = 0; i < entries.length; ++i) {
+    var entry = entries[i];
+    if (entry.element.id == "")
+      entry.element.id = "_toc_" + i;
+    var a = document.createElement("a");
+    a.href = "#" + entry.element.id;
+    a.appendChild(document.createTextNode(entry.text));
+    var div = document.createElement("div");
+    div.appendChild(a);
+    div.className = "toclevel" + entry.toclevel;
+    toc.appendChild(div);
+  }
+  if (entries.length == 0)
+    toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+  // Delete existing footnote entries in case we're reloading the footnodes.
+  var i;
+  var noteholder = document.getElementById("footnotes");
+  if (!noteholder) {
+    return;
+  }
+  var entriesToRemove = [];
+  for (i = 0; i < noteholder.childNodes.length; i++) {
+    var entry = noteholder.childNodes[i];
+    if (entry.nodeName == 'DIV' && entry.getAttribute("class") == "footnote")
+      entriesToRemove.push(entry);
+  }
+  for (i = 0; i < entriesToRemove.length; i++) {
+    noteholder.removeChild(entriesToRemove[i]);
+  }
+
+  // Rebuild footnote entries.
+  var cont = document.getElementById("content");
+  var spans = cont.getElementsByTagName("span");
+  var refs = {};
+  var n = 0;
+  for (i=0; i<spans.length; i++) {
+    if (spans[i].className == "footnote") {
+      n++;
+      var note = spans[i].getAttribute("data-note");
+      if (!note) {
+        // Use [\s\S] in place of . so multi-line matches work.
+        // Because JavaScript has no s (dotall) regex flag.
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+        spans[i].innerHTML =
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+        spans[i].setAttribute("data-note", note);
+      }
+      noteholder.innerHTML +=
+        "<div class='footnote' id='_footnote_" + n + "'>" +
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+        n + "</a>. " + note + "</div>";
+      var id =spans[i].getAttribute("id");
+      if (id != null) refs["#"+id] = n;
+    }
+  }
+  if (n == 0)
+    noteholder.parentNode.removeChild(noteholder);
+  else {
+    // Process footnoterefs.
+    for (i=0; i<spans.length; i++) {
+      if (spans[i].className == "footnoteref") {
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+        href = href.match(/#.*/)[0];  // Because IE return full URL.
+        n = refs[href];
+        spans[i].innerHTML =
+          "[<a href='#_footnote_" + n +
+          "' title='View footnote' class='footnote'>" + n + "</a>]";
+      }
+    }
+  }
+},
+
+install: function(toclevels) {
+  var timerId;
+
+  function reinstall() {
+    asciidoc.footnotes();
+    if (toclevels) {
+      asciidoc.toc(toclevels);
+    }
+  }
+
+  function reinstallAndRemoveTimer() {
+    clearInterval(timerId);
+    reinstall();
+  }
+
+  timerId = setInterval(reinstall, 500);
+  if (document.addEventListener)
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+  else
+    window.onload = reinstallAndRemoveTimer;
+}
+
+}
diff --git a/doc/www/lang-en.conf b/doc/www/lang-en.conf
new file mode 100644 (file)
index 0000000..9d1c6d4
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# AsciiDoc English language configuration file.
+#
+
+[attributes]
+# Captions, used by (X)HTML backends.
+# Captions on RHS are displayed in outputs.
+ifdef::basebackend-html[]
+
+caution-caption=Caution
+important-caption=Important
+note-caption=Note
+tip-caption=Tip
+warning-caption=Warning
+figure-caption=Figure
+table-caption=Table
+example-caption=Example
+toc-title=Table of Contents
+appendix-caption=Appendix
+# Man page NAME section title.
+manname-title=NAME
+
+[footer-text]
+Version {revnumber}{basebackend-xhtml11?<br />}{basebackend-xhtml11=<br>}
+Last updated {docdate} {doctime}
+
+endif::basebackend-html[]
+
+
+[specialsections]
+# DocBook special sections.
+# The regular expression on LHS is matched against source titles.
+ifdef::basebackend-docbook[]
+
+ifdef::doctype-article[]
+^Abstract$=abstract
+endif::doctype-article[]
+
+ifdef::doctype-book[]
+^Colophon$=colophon
+^Dedication$=dedication
+^Preface$=preface
+endif::doctype-book[]
+
+^Index$=index
+^(Bibliography|References)$=bibliography
+^Glossary$=glossary
+^Appendix [A-Z][:.](?P<title>.*)$=appendix
+
+endif::basebackend-docbook[]
+
+ifdef::doctype-manpage[]
+(?i)^SYNOPSIS$=synopsis
+endif::doctype-manpage[]
diff --git a/doc/www/netatalk-relnotes.conf b/doc/www/netatalk-relnotes.conf
new file mode 100644 (file)
index 0000000..594ee2d
--- /dev/null
@@ -0,0 +1,285 @@
+#\r
+# netatalk.conf\r
+#\r
+# Asciidoc global configuration file.\r
+# css backend, generates XHTML 1.0 conformant markup.\r
+#\r
+# Included in css-embedded.conf\r
+#\r
+\r
+# Start with the html backend configuration.\r
+# include::html.conf[]\r
+\r
+[titles]\r
+underlines="--","==","~~","^^","++"\r
+\r
+[glossary]\r
+basebackend=css\r
+basebackend-css=\r
+basebackend-html\r
+dtddecl=PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"\r
+\r
+[tags]\r
+# Add title class.\r
+ilist={title?<p class="listtitle"><b>{title}</b></p>}<ul>|</ul>\r
+olist={title?<p class="listtitle"><b>{title}</b></p>}<ol>|</ol>\r
+vlist={title?<p class="listtitle"><b>{title}</b></p>}<dl>|</dl>\r
+qlist={title?<p class="listtitle"><b>{title}</b></p>}<ol>|</ol>\r
+\r
+[under-construction-blockmacro]\r
+<p class="under-construction">\r
+This page is currently under construction.<br/>\r
+Please return soon.\r
+</p>\r
+\r
+[image-inlinemacro]\r
+<a class="imagelink" href="{link}">\r
+# border="0" so broken IE6 does not put border round linked image.\r
+  <img src="{target}" alt="{1={target}}"{1? title="{1}"}{width? width="{width}"}{height? height="{height}"} border="0"/>\r
+{link#}</a>\r
+\r
+[image-blockmacro]\r
+<div class="image">\r
+  <p>{link?<a class="imagelink" href="{link}">}\r
+# border="0" so broken IE6 does not put border round linked image.\r
+    <img src="{target}" alt="{1={target}}"{1? title="{1}"}{width? width="{width}"}{height? height="{height}"} border="0"/>\r
+  {link?</a>}</p>\r
+  <p class="imagetitle"><b>Figure:</b> {title}</p>\r
+</div>\r
+\r
+# DEPRECATED.\r
+[graphic]\r
+<div class="graphic">\r
+  <p><img src="{target}" alt="{caption={target}}"/></p>\r
+  <p class="graphictitle"><b>Figure:</b> {title}</p>\r
+</div>\r
+\r
+# Paragraph substitution.\r
+[indentedparagraph]\r
+<p class="blocktitle"><b>Example:</b> {title}</p>\r
+#<div class="indentedparagraph"><pre>|</pre></div>\r
+&nbsp;&nbsp;&nbsp;<a href="|">|</a>\r
+\r
+# Delimited block substitution.\r
+[indentedblock]\r
+<p class="blocktitle"><b>Example:</b> {title}</p>\r
+<div class="indentedblock"><pre>\r
+|\r
+</pre></div>\r
+\r
+[verbatimblock]\r
+<p class="blocktitle"><b>Example:</b> {title}</p>\r
+<div class="verbatimblock"><pre>\r
+|\r
+</pre></div>\r
+\r
+[sidebarblock]\r
+<div class="sidebarblock">\r
+<p class="sidebartitle">{title}</p>\r
+|\r
+</div>\r
+\r
+[customblock]\r
+|\r
+\r
+[table]\r
+# Table captions not used because IE6 is broken.\r
+<p class="tabletitle"><b>Table:</b> {title}</p>\r
+# If you want styled table borders in IE use the following table tag:\r
+# 1. Border style specified here rather than in CSS because IE6 is broken.\r
+# 2. bordercolor attribute is IE specific and not valid XHTML 1.0.\r
+#<table rules="groups" border="2" bordercolor="green" frame="hsides"\r
+#      cellspacing="0" cellpadding="4">\r
+#\r
+# Use this in preference to be strictly XHTML 1.0 conformant.\r
+<table rules="groups" frame="{noborders?void}{noborders!hsides}" cellspacing="0" cellpadding="4">\r
+{headrows#}<thead{noborders? style="border-width: 0;"}>\r
+{headrows}\r
+{headrows#}</thead>\r
+{footrows#}<tfoot{noborders? style="border-width: 0;"}>\r
+{footrows}\r
+{footrows#}</tfoot>\r
+<tbody{noborders? style="border-width: 0;"}>\r
+{bodyrows}\r
+</tbody>\r
+</table>\r
+\r
+#-------------------------\r
+# article and book document types\r
+# Both use the article.css stylesheet\r
+#-------------------------\r
+ifndef::doctype-manpage[]\r
+\r
+[header]\r
+<!DOCTYPE html {dtddecl}>\r
+<html>\r
+<head>\r
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\r
+<meta name="description" content="Netatalk - Unix file and print services for Apple clients" />\r
+<meta name="keywords" content="Netatalk, AFP, AFP Server, File Server, PAP, Print Server, Appletalk, Mac, OSX, OS X, OS9, OS 9" />\r
+<meta name="language" content="EN" />\r
+<meta name="publisher" content="netatalk.sourceforge.net" />\r
+<meta name="robots" content="Follow" />\r
+<link rel="stylesheet" type="text/css" charset="iso-8859-1" href="/css/site.css" />\r
+<link rel="stylesheet" type="text/css" charset="iso-8859-1" href="/css/printer.css" media="print" />\r
+<link rel="alternate stylesheet" type="text/css" charset="iso-8859-1" href="/css/printer.css" title="Printer" />\r
+<link rel="copyright" title="GNU General Public License" href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt" />\r
+<link rel="author" title="The Netatalk Development Team" href="http://netatalk.sf.net" />\r
+<link rel="home" href="index.php" title="Netatalk Home" />\r
+<link rel="home" href="http://www.sourceforge.net/projects/netatalk" title="Netatalk Sourceforge" />\r
+<link rel="bookmark" href="http://sourceforge.net/project/showfiles.php?group_id=8642" title="Downloads" />\r
+\r
+<title>Netatalk Release Notes</title>\r
+</head>\r
+<body>\r
+<div id="header">\r
+<div id="logo"></div>\r
+<div id="menlinks">\r
+        <a href="/" title="Return to Netatalk home">[main]</a>\r
+        <a href="https://sourceforge.net/apps/mediawiki/netatalk/index.php?title=Main_Page" title="Netatalk Wiki">[wiki]</a>\r
+        <a href="/3.0/htmldocs" title="Netatalk Manual">[documentation]</a>\r
+        <a href="http://sourceforge.net/project/showfiles.php?group_id=8642" title="Download Netatalk from sourceforge">[downloads]</a>\r
+        <a href="/support.php" title="Support">[support]</a>\r
+        <a href="/links.php" title="Netatalk related links">[links]</a>\r
+        <img src="/gfx/end.gif" alt="" width="125" height="7" />\r
+</div>\r
+</div>\r
+<div id="header-print">\r
+<h1>netatalk.sourceforge.net</h1>\r
+</div>\r
+<div class="search">\r
+<h4> search netatalk.sf.net</h4>\r
+<form method="get" action="http://www.google.com/search">\r
+<p>\r
+<input type="text" name="q" size="10" maxlength="255" value="" />\r
+<input type="hidden" name="hl" value="de" />\r
+<input type="hidden" name="sitesearch" value="netatalk.sourceforge.net" />\r
+<input type="submit" name="btnG" value="Go" />\r
+</p>\r
+</form>\r
+<span class="italic">powered by Google</span>\r
+</div>\r
+<div id="content">\r
+<h1>{doctitle}</h1>\r
+\r
+[footer]\r
+</div>\r
+<div class="footer">\r
+<span class="italic">webspace sponsored by</span><br />\r
+<!-- use a table for now -->\r
+<table>\r
+<tr>\r
+<td><a href="http://www.sf.net"><img src="http://sourceforge.net/sflogo.php?group_id=8642&amp;type=1" style="border:0;width:88px;height:31px" width="88" height="31" alt="SourceForge.net Logo" /></a></td>\r
+<td><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></td>\r
+<td><a href="http://jigsaw.w3.org/css-validator/"><img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" /></a></td>\r
+</tr>\r
+</table>\r
+</div>\r
+</body>\r
+</html>\r
+\r
+[preamble]\r
+# Untitled elements between header and first section title.\r
+<div id="body">\r
+|\r
+</div>\r
+\r
+[sect0]\r
+<h2 class="sect0">{1?<a name="{1}"></a>}{title}</h2>\r
+|\r
+\r
+[sect1]\r
+<h2>{1?<a name="{1}"></a>}{section-numbers?{sectnum} }{title}</h2>\r
+|\r
+\r
+[sect2]\r
+<h3>{1?<a name="{1}"></a>}{section-numbers?{sectnum} }{title}</h3>\r
+|\r
+\r
+[sect3]\r
+<h4>{1?<a name="{1}"></a>}{section-numbers?{sectnum} }{title}</h4>\r
+|\r
+\r
+[sect4]\r
+<h5>{1?<a name="{1}"></a>}{title}</h5>\r
+|\r
+\r
+endif::doctype-manpage[]\r
+\r
+#-------------------------\r
+# manpage document type\r
+#-------------------------\r
+ifdef::doctype-manpage[]\r
+\r
+[header]\r
+<!DOCTYPE html {dtddecl}>\r
+<html>\r
+<head>\r
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />\r
+<meta name="generator" content="AsciiDoc {asciidoc-version}" />\r
+<meta name="author" content="{author}" />\r
+<meta name="author-email" content="{email}" />\r
+<link rel="stylesheet" href="manpage.css" type="text/css" />\r
+<title>{mantitle}</title>\r
+</head>\r
+<body>\r
+<div id="content">\r
+<h1>{doctitle} Manual Page</h1>\r
+<h2>NAME</h2>\r
+<p>{manname} -\r
+   {manpurpose}\r
+</p>\r
+\r
+[footer]\r
+<div id="footer">\r
+<p>\r
+Version {revision}<br/>\r
+Last updated {localdate} {localtime}\r
+</p>\r
+<p><span class="ahem">This document might look funny (or very plain) to you, since you're not using a browser which (correctly) supports CSS.</span></p>\r
+<div id="badges">\r
+<table border="0" cellpadding="8" summary="Badges">\r
+<tr>\r
+<td><a href="http://validator.w3.org/check/referer"><img\r
+# Source badge locally.\r
+#src="http://www.w3.org/Icons/valid-xhtml10"\r
+src="valid-xhtml10.png"\r
+alt="Valid XHTML 1.0" height="31" width="88" /></a></td>\r
+\r
+<td><a href="http://jigsaw.w3.org/css-validator/"> <img border="0"\r
+# Source badge locally.\r
+#src="http://jigsaw.w3.org/css-validator/images/vcss"\r
+src="vcss.png"\r
+alt="Valid CSS" width="88" height="31" /></a></td>\r
+</tr>\r
+</table>\r
+</div>\r
+</div>\r
+</div>\r
+</body>\r
+</html>\r
+\r
+# Section macros\r
+[sect-synopsis]\r
+<div id="synopsis">\r
+<h2>SYNOPSIS</h2>\r
+|\r
+</div>\r
+\r
+[sect1]\r
+<h2>{1?<a name="{1}"></a>}{title}</h2>\r
+|\r
+\r
+[sect2]\r
+<h3>{1?<a name="{1}"></a>}{title}</h3>\r
+|\r
+\r
+[sect3]\r
+<h4>{1?<a name="{1}"></a>}{title}</h4>\r
+|\r
+\r
+[sect4]\r
+<h5>{1?<a name="{1}"></a>}{title}</h5>\r
+|\r
+\r
+endif::doctype-manpage[]\r
diff --git a/doc/www/stylesheets/asciidoc.css b/doc/www/stylesheets/asciidoc.css
new file mode 100644 (file)
index 0000000..1475be7
--- /dev/null
@@ -0,0 +1,508 @@
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+  font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+  font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+  margin: 1em 5% 1em 5%;
+}
+
+a {
+  color: blue;
+  text-decoration: underline;
+}
+a:visited {
+  color: fuchsia;
+}
+
+em {
+  font-style: italic;
+  color: navy;
+}
+
+strong {
+  font-weight: bold;
+  color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  color: #527bbd;
+  margin-top: 1.2em;
+  margin-bottom: 0.5em;
+  line-height: 1.3;
+}
+
+h1, h2, h3 {
+  border-bottom: 2px solid silver;
+}
+h2 {
+  padding-top: 0.5em;
+}
+h3 {
+  float: left;
+}
+h3 + * {
+  clear: left;
+}
+h5 {
+  font-size: 1.0em;
+}
+
+div.sectionbody {
+  margin-left: 0;
+}
+
+hr {
+  border: 1px solid silver;
+}
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+  margin-top: 0;
+}
+ul > li     { color: #aaa; }
+ul > li > * { color: black; }
+
+pre {
+  padding: 0;
+  margin: 0;
+}
+
+#author {
+  color: #527bbd;
+  font-weight: bold;
+  font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+  font-size: small;
+  border-top: 2px solid silver;
+  padding-top: 0.5em;
+  margin-top: 4.0em;
+}
+#footer-text {
+  float: left;
+  padding-bottom: 0.5em;
+}
+#footer-badges {
+  float: right;
+  padding-bottom: 0.5em;
+}
+
+#preamble {
+  margin-top: 1.5em;
+  margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.admonitionblock {
+  margin-top: 2.0em;
+  margin-bottom: 2.0em;
+  margin-right: 10%;
+  color: #606060;
+}
+
+div.content { /* Block element content. */
+  padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+  color: #527bbd;
+  font-weight: bold;
+  text-align: left;
+  margin-top: 1.0em;
+  margin-bottom: 0.5em;
+}
+div.title + * {
+  margin-top: 0;
+}
+
+td div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content div.title:first-child {
+  margin-top: 0.0em;
+}
+div.content + div.title {
+  margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+  background: #ffffee;
+  border: 1px solid #dddddd;
+  border-left: 4px solid #f0f0f0;
+  padding: 0.5em;
+}
+
+div.listingblock > div.content {
+  border: 1px solid #dddddd;
+  border-left: 5px solid #f0f0f0;
+  background: #f8f8f8;
+  padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+  padding-left: 1.0em;
+  margin-left: 1.0em;
+  margin-right: 10%;
+  border-left: 5px solid #f0f0f0;
+  color: #777777;
+}
+
+div.quoteblock > div.attribution {
+  padding-top: 0.5em;
+  text-align: right;
+}
+
+div.verseblock > pre.content {
+  font-family: inherit;
+  font-size: inherit;
+}
+div.verseblock > div.attribution {
+  padding-top: 0.75em;
+  text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+  text-align: left;
+}
+
+div.admonitionblock .icon {
+  vertical-align: top;
+  font-size: 1.1em;
+  font-weight: bold;
+  text-decoration: underline;
+  color: #527bbd;
+  padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+  padding-left: 0.5em;
+  border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+  border-left: 3px solid #dddddd;
+  padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; }
+a.image:visited { color: white; }
+
+dl {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+dt {
+  margin-top: 0.5em;
+  margin-bottom: 0;
+  font-style: normal;
+  color: navy;
+}
+dd > *:first-child {
+  margin-top: 0.1em;
+}
+
+ul, ol {
+    list-style-position: outside;
+}
+ol.arabic {
+  list-style-type: decimal;
+}
+ol.loweralpha {
+  list-style-type: lower-alpha;
+}
+ol.upperalpha {
+  list-style-type: upper-alpha;
+}
+ol.lowerroman {
+  list-style-type: lower-roman;
+}
+ol.upperroman {
+  list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+  margin-top: 0.1em;
+  margin-bottom: 0.1em;
+}
+
+tfoot {
+  font-weight: bold;
+}
+td > div.verse {
+  white-space: pre;
+}
+
+div.hdlist {
+  margin-top: 0.8em;
+  margin-bottom: 0.8em;
+}
+div.hdlist tr {
+  padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+  font-weight: bold;
+}
+td.hdlist1 {
+  vertical-align: top;
+  font-style: normal;
+  padding-right: 0.8em;
+  color: navy;
+}
+td.hdlist2 {
+  vertical-align: top;
+}
+div.hdlist.compact tr {
+  margin: 0;
+  padding-bottom: 0;
+}
+
+.comment {
+  background: yellow;
+}
+
+.footnote, .footnoteref {
+  font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+  vertical-align: super;
+}
+
+#footnotes {
+  margin: 20px 0 20px 0;
+  padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+  margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+  border: none;
+  border-top: 1px solid silver;
+  height: 1px;
+  text-align: left;
+  margin-left: 0;
+  width: 20%;
+  min-width: 100px;
+}
+
+div.colist td {
+  padding-right: 0.5em;
+  padding-bottom: 0.3em;
+  vertical-align: top;
+}
+div.colist td img {
+  margin-top: 0.3em;
+}
+
+@media print {
+  #footer-badges { display: none; }
+}
+
+#toc {
+  margin-bottom: 2.5em;
+}
+
+#toctitle {
+  color: #527bbd;
+  font-size: 1.1em;
+  font-weight: bold;
+  margin-top: 1.0em;
+  margin-bottom: 0.1em;
+}
+
+div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+div.toclevel2 {
+  margin-left: 2em;
+  font-size: 0.9em;
+}
+div.toclevel3 {
+  margin-left: 4em;
+  font-size: 0.9em;
+}
+div.toclevel4 {
+  margin-left: 6em;
+  font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+tt {
+  font-family: monospace;
+  font-size: inherit;
+  color: navy;
+}
+
+div.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+div.tableblock > table {
+  border: 3px solid #527bbd;
+}
+thead, p.table.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.table {
+  margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+  border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+  border-left-style: none;
+  border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+  border-top-style: none;
+  border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+.monospaced {
+  font-family: monospace;
+  font-size: inherit;
+  color: navy;
+}
+
+table.tableblock {
+  margin-top: 1.0em;
+  margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+  font-weight: bold;
+  color: #527bbd;
+}
+p.tableblock {
+  margin-top: 0;
+}
+table.tableblock {
+  border-width: 3px;
+  border-spacing: 0px;
+  border-style: solid;
+  border-color: #527bbd;
+  border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+  border-width: 1px;
+  padding: 4px;
+  border-style: solid;
+  border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+  border-left-style: hidden;
+  border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+  border-top-style: hidden;
+  border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+  border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+  text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+  text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+  text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+  vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+  vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+  vertical-align: bottom;
+}
index a0d4a82d4ae6da700f4f79a11401ae815d358fd5..dc868ddc9878ab04611ae8aa713ed6b2bb6dc864 100644 (file)
@@ -1,5 +1,47 @@
 dnl Kitchen sink for configuration macros
 
+dnl Check for docbook
+AC_DEFUN(AX_CHECK_DOCBOOK, [
+  # It's just rude to go over the net to build
+  XSLTPROC_FLAGS=--nonet
+  DOCBOOK_ROOT=
+  XSLTPROC_WORKS=no
+
+  AC_ARG_WITH(docbook,
+    AS_HELP_STRING(
+      [--with-docbook],
+      [Path to Docbook XSL directory]
+    ),
+    [DOCBOOK_ROOT=$withval]
+  )
+
+  if test -n "$DOCBOOK_ROOT" ; then
+    AC_CHECK_PROG(XSLTPROC,xsltproc,xsltproc,)
+    if test -n "$XSLTPROC"; then
+      AC_MSG_CHECKING([whether xsltproc works])
+      DB_FILE="$DOCBOOK_ROOT/html/docbook.xsl"
+      $XSLTPROC $XSLTPROC_FLAGS $DB_FILE >/dev/null 2&>&1 << END
+<?xml version="1.0" encoding='ISO-8859-1'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+<book id="test">
+</book>
+END
+      if test "$?" = 0; then
+        XSLTPROC_WORKS=yes
+      fi
+      AC_MSG_RESULT($XSLTPROC_WORKS)
+    fi
+  fi
+
+  AC_MSG_CHECKING([whether to build Docbook documentation])
+  AC_MSG_RESULT($XSLTPROC_WORKS)
+
+  AM_CONDITIONAL(HAVE_XSLTPROC, test x"$XSLTPROC_WORKS" = x"yes")
+  AC_SUBST(XSLTPROC_FLAGS)
+  AC_SUBST(DOCBOOK_ROOT)
+  AC_SUBST(XSLTPROC)
+])
+
 dnl Check for dtrace
 AC_DEFUN([AC_NETATALK_DTRACE], [
   AC_ARG_WITH(dtrace,
index 80ce5afd76ded0ee30b7acb96f79ce37151641b4..520e1e0f0af83cacda87715d3117955d42bbddf1 100644 (file)
@@ -75,6 +75,8 @@ dnl   AC_MSG_RESULT([         Samba sharemode interop: $neta_cv_have_smbshmd])
                AC_MSG_WARN([ You can also re-run configure and specify --without-pam to disable PAM support.])
           fi
        fi
+       AC_MSG_RESULT([    Documentation:])
+       AC_MSG_RESULT([         Docbook:                 $XSLTPROC_WORKS])
 ])
 
 
index 895a5e778b39b68094b7bf7771c67cf63c08dec9..8f1b0d992ec94e80ad60fd4ba1688d5d9900b917 100644 (file)
@@ -1,4 +1,3 @@
 Makefile
 Makefile.in
-.gitignore
 *.o
index 39ffeb2f2ab35efa674130aced3b2d0edbecff89..0ac9461e8a4ab22a449d068e52155a4879735fd3 100644 (file)
@@ -1,11 +1,3 @@
 Makefile
 Makefile.in
-apple_cp.1
-apple_dump.1
-apple_mv.1
-apple_rm.1
-asip-status.pl.1
-afpldaptest.1
-afpstats.1
-uniconv.1
-*.o
+*.1
index 20dede4e188c4629aeb35982499a9bf8c5fba648..07f4f9a71dd061aace628bc2598b0847403aef19 100644 (file)
@@ -1,27 +1,15 @@
 # Makefile.am for man/man1/
 
-pkgconfdir = @PKGCONFDIR@
-
-SUFFIXES= .tmpl .
-
-.tmpl:
-       sed -e s@:SBINDIR:@${sbindir}@ \
-           -e s@:BINDIR:@${bindir}@ \
-           -e s@:ETCDIR:@${pkgconfdir}@ \
-           -e s@:LIBDIR:@${libdir}@ \
-           -e s@:DEFAULT_CNID_SCHEME:@${DEFAULT_CNID_SCHEME}@ \
-           <$< >$@
-
-GENERATED_MANS = uniconv.1 asip-status.pl.1 afpldaptest.1 afpstats.1
-TEMPLATE_FILES = uniconv.1.tmpl asip-status.pl.1.tmpl afpldaptest.1.tmpl afpstats.1.tmpl
-
-NONGENERATED_MANS      =       ad.1 \
-                               afppasswd.1 \
-                               apple_dump.1 \
-                               dbd.1 \
-                               macusers.1 \
-                               netatalk-config.1
-
-man_MANS = $(GENERATED_MANS) $(NONGENERATED_MANS)
-CLEANFILES = $(GENERATED_MANS)
-EXTRA_DIST = $(TEMPLATE_FILES) $(NONGENERATED_MANS)
+man_MANS = \
+       ad.1 \
+       afpldaptest.1 \
+       afppasswd.1 \
+       afpstats.1 \
+       apple_dump.1 \
+       asip-status.pl.1 \
+       dbd.1 \
+       macusers.1 \
+       netatalk-config.1 \
+       uniconv.1
+
+DISTCLEANFILES = $(man_MANS)
diff --git a/man/man1/ad.1 b/man/man1/ad.1
deleted file mode 100644 (file)
index 20b1436..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-'\" t
-.\"     Title: ad
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 02 Sep 2011
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-ad \- Netatalk compatible UNIX file utility suite\&.
-.SH "SYNOPSIS"
-.HP \w'\fBad\fR\ 'u
-\fBad\fR {ls\ |\ cp\ |\ mv\ |\ rm} [\&.\&.\&.]
-.HP \w'\fBad\fR\ 'u
-\fBad\fR {\-v\ |\ \-\-version}
-.SH "DESCRIPTION"
-.PP
-\fBad\fR
-is a UNIX file utility suite with Netatalk compatibility\&. AppleDouble
-files in
-\&.AppleDouble
-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\ [\&.\&.\&.]}
-.PP
-List files and directories\&.
-.HP \w'\fBad\ cp\fR\ 'u
-\fBad cp\fR [\-aipvf] {src_file} {dst_file}
-.HP \w'\fBad\ cp\ \-R\fR\ 'u
-\fBad cp \-R\fR [\-aipvf] {src_file|src_directory\ \&.\&.\&.} {dst_directory}
-.PP
-Copy files and directories\&.
-.HP \w'\fBad\ mv\fR\ 'u
-\fBad mv\fR [\-finv] {src_file} {dst_file}
-.HP \w'\fBad\ mv\fR\ 'u
-\fBad mv\fR [\-finv] {src_file|src_directory\ \&.\&.\&.} {dst_directory}
-.PP
-Move files and directories\&.
-.HP \w'\fBad\ rm\fR\ 'u
-\fBad rm\fR [\-Rv] {file|directory}
-.HP \w'\fBad\ \-v|\-\-version\fR\ 'u
-\fBad \-v|\-\-version\fR
-.PP
-Show version\&.
-.SH "AD LS"
-.PP
-List files and directories\&. Options:
-.PP
-\-d
-.RS 4
-Directories are listed as plain files
-.RE
-.PP
-\-R
-.RS 4
-list subdirectories recursively
-.RE
-.PP
-\-l
-.RS 4
-Long output, list AFP info
-.RE
-.PP
-\-u
-.RS 4
-List UNIX info
-.RE
-.PP
-\fILong output description\fR
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-<unixinfo> <FinderFlags> <AFP Attributes> <Color> <Type> <Creator> <CNID from AppleDouble> <name>
-
-FinderFlags (valid for (f)iles and/or (d)irectories):
-
-  d = On Desktop                      (f/d)
-  e = Hidden extension                (f/d)
-  m = Shared (can run multiple times) (f)
-  n = No INIT resources               (f)
-  i = Inited                          (f/d)
-  c = Custom icon                     (f/d)
-  t = Stationery                      (f)
-  s = Name locked                     (f/d)
-  b = Bundle                          (f/d)
-  v = Invisible                       (f/d)
-  a = Alias file                      (f/d)
-
-AFP Attributes:
-
-  y = System                          (f/d)
-  w = No write                        (f)
-  p = Needs backup                    (f/d)
-  r = No rename                       (f/d)
-  l = No delete                       (f/d)
-  o = No copy                         (f)
-
-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
-.\}
-.SH "AD CP"
-.PP
-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 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
-\-a
-.RS 4
-Archive mode\&. Same as \-Rp\&.
-.RE
-.PP
-\-f
-.RS 4
-For each existing destination pathname, remove it and create a new file, without prompting for confirmation regardless of its permis\- sions\&. (The \-f option overrides any previous \-i or \-n options\&.)
-.RE
-.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 \*(Aqy\*(Aq or \*(AqY\*(Aq, the file copy is attempted\&. (The \-i option overrides any pre\- vious \-f or \-n options\&.)
-.RE
-.PP
-\-n
-.RS 4
-Do not overwrite an existing file\&. (The \-n option overrides any previous \-f or \-i options\&.)
-.RE
-.PP
-\-p
-.RS 4
-Cause cp to preserve the following attributes of each source file in the copy: modification time, access time, file flags, file mode, user ID, and group ID, as allowed by permissions\&. If the user ID and group ID cannot be preserved, no error message is displayed and the exit value is not altered\&.
-.RE
-.PP
-\-R
-.RS 4
-If source_file designates a directory, cp copies the directory and the entire subtree connected at that point\&.If the source_file ends in a /, the contents of the directory are copied rather than the directory itself\&.
-.RE
-.PP
-\-v
-.RS 4
-Cause cp to be verbose, showing files as they are copied\&.
-.RE
-.PP
-\-x
-.RS 4
-File system mount points are not traversed\&.
-.RE
-.SH "AD MV"
-.PP
-Move files and directories\&.
-.PP
-Move files around within an AFP volume, updating the CNID database as needed\&. If either:
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-source or destination is not an AFP volume
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-source AFP volume != destination AFP volume
-.RE
-.sp
-the files are copied and removed from the source\&.
-.PP
-Options:
-.PP
-\-f
-.RS 4
-Do not prompt for confirmation before overwriting the destination path\&. (The \-f option overrides any previous \-i or \-n options\&.)
-.RE
-.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\*(Aq or `Y\*(Aq, the move is attempted\&. (The \-i option overrides any previous \-f or \-n options\&.)
-.RE
-.PP
-\-n
-.RS 4
-Do not overwrite an existing file\&. (The \-n option overrides any previous \-f or \-i options\&.)
-.RE
-.PP
-\-v
-.RS 4
-Cause mv to be verbose, showing files after they are moved\&.
-.RE
-.SH "AD RM"
-.PP
-Remove files and directories\&.
-.PP
-The rm utility attempts to remove the non\-directory type files specified on the command line\&. If the files and directories reside on an AFP volume, the corresponding CNIDs are deleted from the volumes database\&.
-.PP
-The options are as follows:
-.PP
-\-R
-.RS 4
-Attempt to remove the file hierarchy rooted in each file argument\&.
-.RE
-.PP
-\-v
-.RS 4
-Be verbose when deleting files, showing them as they are removed\&.
-.RE
-.SH "REPORTING BUGS"
-.PP
-Report bugs to the Netatalk\-devel list <netatalk\-devel@lists\&.sourceforge\&.net>\&.
-.SH "SEE ALSO"
-.PP
-\fBdbd\fR(1),
-\fBapple_dump\fR(1)\&.
diff --git a/man/man1/ad.1.in b/man/man1/ad.1.in
new file mode 100644 (file)
index 0000000..1a807cf
--- /dev/null
@@ -0,0 +1,250 @@
+'\" t
+.\"     Title: ad
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 02 Sep 2011
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "AD" "1" "02 Sep 2011" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+ad \- Netatalk compatible UNIX file utility suite\&.
+.SH "SYNOPSIS"
+.HP \w'\fBad\fR\ 'u
+\fBad\fR {ls\ |\ cp\ |\ mv\ |\ rm} [\&.\&.\&.]
+.HP \w'\fBad\fR\ 'u
+\fBad\fR {\-v\ |\ \-\-version}
+.SH "DESCRIPTION"
+.PP
+\fBad\fR
+is a UNIX file utility suite with Netatalk compatibility\&. AppleDouble
+files in
+\&.AppleDouble
+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\ [\&.\&.\&.]}
+.PP
+List files and directories\&.
+.HP \w'\fBad\ cp\fR\ 'u
+\fBad cp\fR [\-aipvf] {src_file} {dst_file}
+.HP \w'\fBad\ cp\ \-R\fR\ 'u
+\fBad cp \-R\fR [\-aipvf] {src_file|src_directory\ \&.\&.\&.} {dst_directory}
+.PP
+Copy files and directories\&.
+.HP \w'\fBad\ mv\fR\ 'u
+\fBad mv\fR [\-finv] {src_file} {dst_file}
+.HP \w'\fBad\ mv\fR\ 'u
+\fBad mv\fR [\-finv] {src_file|src_directory\ \&.\&.\&.} {dst_directory}
+.PP
+Move files and directories\&.
+.HP \w'\fBad\ rm\fR\ 'u
+\fBad rm\fR [\-Rv] {file|directory}
+.HP \w'\fBad\ \-v|\-\-version\fR\ 'u
+\fBad \-v|\-\-version\fR
+.PP
+Show version\&.
+.SH "AD LS"
+.PP
+List files and directories\&. Options:
+.PP
+\-d
+.RS 4
+Directories are listed as plain files
+.RE
+.PP
+\-R
+.RS 4
+list subdirectories recursively
+.RE
+.PP
+\-l
+.RS 4
+Long output, list AFP info
+.RE
+.PP
+\-u
+.RS 4
+List UNIX info
+.RE
+.PP
+\fILong output description\fR
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+<unixinfo> <FinderFlags> <AFP Attributes> <Color> <Type> <Creator> <CNID from AppleDouble> <name>
+
+FinderFlags (valid for (f)iles and/or (d)irectories):
+
+  d = On Desktop                      (f/d)
+  e = Hidden extension                (f/d)
+  m = Shared (can run multiple times) (f)
+  n = No INIT resources               (f)
+  i = Inited                          (f/d)
+  c = Custom icon                     (f/d)
+  t = Stationery                      (f)
+  s = Name locked                     (f/d)
+  b = Bundle                          (f/d)
+  v = Invisible                       (f/d)
+  a = Alias file                      (f/d)
+
+AFP Attributes:
+
+  y = System                          (f/d)
+  w = No write                        (f)
+  p = Needs backup                    (f/d)
+  r = No rename                       (f/d)
+  l = No delete                       (f/d)
+  o = No copy                         (f)
+
+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
+.\}
+.SH "AD CP"
+.PP
+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 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
+\-a
+.RS 4
+Archive mode\&. Same as \-Rp\&.
+.RE
+.PP
+\-f
+.RS 4
+For each existing destination pathname, remove it and create a new file, without prompting for confirmation regardless of its permis\- sions\&. (The \-f option overrides any previous \-i or \-n options\&.)
+.RE
+.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 \*(Aqy\*(Aq or \*(AqY\*(Aq, the file copy is attempted\&. (The \-i option overrides any pre\- vious \-f or \-n options\&.)
+.RE
+.PP
+\-n
+.RS 4
+Do not overwrite an existing file\&. (The \-n option overrides any previous \-f or \-i options\&.)
+.RE
+.PP
+\-p
+.RS 4
+Cause cp to preserve the following attributes of each source file in the copy: modification time, access time, file flags, file mode, user ID, and group ID, as allowed by permissions\&. If the user ID and group ID cannot be preserved, no error message is displayed and the exit value is not altered\&.
+.RE
+.PP
+\-R
+.RS 4
+If source_file designates a directory, cp copies the directory and the entire subtree connected at that point\&.If the source_file ends in a /, the contents of the directory are copied rather than the directory itself\&.
+.RE
+.PP
+\-v
+.RS 4
+Cause cp to be verbose, showing files as they are copied\&.
+.RE
+.PP
+\-x
+.RS 4
+File system mount points are not traversed\&.
+.RE
+.SH "AD MV"
+.PP
+Move files and directories\&.
+.PP
+Move files around within an AFP volume, updating the CNID database as needed\&. If either:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+source or destination is not an AFP volume
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+source AFP volume != destination AFP volume
+.RE
+.sp
+the files are copied and removed from the source\&.
+.PP
+Options:
+.PP
+\-f
+.RS 4
+Do not prompt for confirmation before overwriting the destination path\&. (The \-f option overrides any previous \-i or \-n options\&.)
+.RE
+.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\*(Aq or `Y\*(Aq, the move is attempted\&. (The \-i option overrides any previous \-f or \-n options\&.)
+.RE
+.PP
+\-n
+.RS 4
+Do not overwrite an existing file\&. (The \-n option overrides any previous \-f or \-i options\&.)
+.RE
+.PP
+\-v
+.RS 4
+Cause mv to be verbose, showing files after they are moved\&.
+.RE
+.SH "AD RM"
+.PP
+Remove files and directories\&.
+.PP
+The rm utility attempts to remove the non\-directory type files specified on the command line\&. If the files and directories reside on an AFP volume, the corresponding CNIDs are deleted from the volumes database\&.
+.PP
+The options are as follows:
+.PP
+\-R
+.RS 4
+Attempt to remove the file hierarchy rooted in each file argument\&.
+.RE
+.PP
+\-v
+.RS 4
+Be verbose when deleting files, showing them as they are removed\&.
+.RE
+.SH "REPORTING BUGS"
+.PP
+Report bugs to the Netatalk\-devel list <netatalk\-devel@lists\&.sourceforge\&.net>\&.
+.SH "SEE ALSO"
+.PP
+\fBdbd\fR(1),
+\fBapple_dump\fR(1)\&.
diff --git a/man/man1/afpldaptest.1.in b/man/man1/afpldaptest.1.in
new file mode 100644 (file)
index 0000000..94d6bd5
--- /dev/null
@@ -0,0 +1,67 @@
+'\" t
+.\"     Title: afpldaptest
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 22 Mar 2012
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "AFPLDAPTEST" "1" "22 Mar 2012" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+afpldaptest \- Syntactically check ldap parameters in afp\&.conf
+.SH "SYNOPSIS"
+.HP \w'\fBafpldaptest\fR\fB\fR\fBafpldaptest\fR\fB\fR\ 'u
+\fBafpldaptest\fR\fB\fR {\-u\ \fIUSER\fR | \-g\ \fIGROUP\fR | \-i\ \fIUUID\fR}
+.br
+\fBafpldaptest\fR\fB\fR {\-h | \-? | \-:}
+.SH "DESCRIPTION"
+.PP
+\fBafpldaptest\fR
+is a simple command to syntactically check ldap parameters in @pkgconfdir@/afp\&.conf\&.
+.SH "OPTIONS"
+.PP
+\fB\-u\fR \fIUSER\fR
+.RS 4
+Show uuid for
+\fIUSER\fR\&.
+.RE
+.PP
+\fB\-g\fR \fIGROUP\fR
+.RS 4
+Show uuid for
+\fIGROUP\fR\&.
+.RE
+.PP
+\fB\-i\fR \fIUUID\fR
+.RS 4
+Show user, group or local\-uuid for
+\fIUUID\fR\&.
+.RE
+.PP
+\fB\-h, \-?, \-:\fR
+.RS 4
+Show the help and exit\&.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBafp.conf\fR(5)
diff --git a/man/man1/afpldaptest.1.tmpl b/man/man1/afpldaptest.1.tmpl
deleted file mode 100644 (file)
index 5c4c67f..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-'\" t
-.\"     Title: afpldaptest
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 22 Mar 2012
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-afpldaptest \- Syntactically check ldap parameters in afp\&.conf
-.SH "SYNOPSIS"
-.HP \w'\fBafpldaptest\fR\fB\fR\fBafpldaptest\fR\fB\fR\ 'u
-\fBafpldaptest\fR\fB\fR {\-u\ \fIUSER\fR | \-g\ \fIGROUP\fR | \-i\ \fIUUID\fR}
-.br
-\fBafpldaptest\fR\fB\fR {\-h | \-? | \-:}
-.SH "DESCRIPTION"
-.PP
-\fBafpldaptest\fR
-is a simple command to syntactically check ldap parameters in :ETCDIR:/afp\&.conf\&.
-.SH "OPTIONS"
-.PP
-\fB\-u\fR \fIUSER\fR
-.RS 4
-Show uuid for
-\fIUSER\fR\&.
-.RE
-.PP
-\fB\-g\fR \fIGROUP\fR
-.RS 4
-Show uuid for
-\fIGROUP\fR\&.
-.RE
-.PP
-\fB\-i\fR \fIUUID\fR
-.RS 4
-Show user, group or local\-uuid for
-\fIUUID\fR\&.
-.RE
-.PP
-\fB\-h, \-?, \-:\fR
-.RS 4
-Show the help and exit\&.
-.RE
-.SH "SEE ALSO"
-.PP
-\fBafp.conf\fR(5)
diff --git a/man/man1/afppasswd.1 b/man/man1/afppasswd.1
deleted file mode 100644 (file)
index 60d640c..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-'\" t
-.\"     Title: afppasswd
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 22 Mar 2012
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-afppasswd \- netatalk password maintenance utility
-.SH "SYNOPSIS"
-.HP \w'\fBafppasswd\fR\fB\fR\fB\fR\ 'u
-\fBafppasswd\fR\fB\fR\fB\fR [\-acfn] [\-p\ \fIpasswd\fR\ \fIfile\fR] [\-u\ \fIminimum\fR\ \fIuid\fR]
-.SH "DESCRIPTION"
-.PP
-\fBafppasswd\fR
-allows the maintenance of afppasswd files created by netatalk for use by the uams_randnum\&.so UAM (providing the "Randnum exchange" and "2\-Way Randnum exchange" User Authentication Modules)\&.
-.PP
-\fBafppasswd\fR
-can either be called by root with parameters, or can be called by local system users with no parameters to change their AFP passwords\&.
-.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
-.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\*(Aqs documentation\&.
-.sp .5v
-.RE
-.SH "EXAMPLE"
-.PP
-Local user changing their own password:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-example% \fBafppasswd\fR
-Enter NEW AFP password: \fB(hidden)\fR
-Enter NEW AFP password again: \fB(hidden)\fR
-afppasswd: updated password\&.
-.fi
-.if n \{\
-.RE
-.\}
-.SH "OPTIONS"
-.PP
-\fB\-a\fR
-.RS 4
-Add a new user to the
-\fBafppasswd\fR
-file\&.
-.RE
-.PP
-\fB\-c\fR
-.RS 4
-Create and/or initialize
-\fBafppasswd\fR
-file or specific user\&.
-.RE
-.PP
-\fB\-f\fR
-.RS 4
-Force the current action\&.
-.RE
-.PP
-\fB\-p\fR\fI path\fR
-.RS 4
-Path to
-\fBafppasswd\fR
-file\&.
-.RE
-.PP
-\fB\-n\fR
-.RS 4
-If cracklib support is built into
-\fBnetatalk\fR
-this option will cause cracklib checking to be disabled, if the superuser does not want to have the password run against the cracklib dictionary\&.
-.RE
-.PP
-\fB\-u\fR\fI minimum uid\fR
-.RS 4
-This is the minimum
-\fIuser id\fR
-(uid) that
-\fBafppasswd\fR
-will use when creating users\&.
-.RE
-.SH "SEE ALSO"
-.PP
-\fBafpd\fR(8),
-\fBafp.conf\fR(5)\&.
diff --git a/man/man1/afppasswd.1.in b/man/man1/afppasswd.1.in
new file mode 100644 (file)
index 0000000..6acce22
--- /dev/null
@@ -0,0 +1,122 @@
+'\" t
+.\"     Title: afppasswd
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 22 Mar 2012
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "AFPPASSWD" "1" "22 Mar 2012" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+afppasswd \- netatalk password maintenance utility
+.SH "SYNOPSIS"
+.HP \w'\fBafppasswd\fR\fB\fR\fB\fR\ 'u
+\fBafppasswd\fR\fB\fR\fB\fR [\-acfn] [\-p\ \fIpasswd\fR\ \fIfile\fR] [\-u\ \fIminimum\fR\ \fIuid\fR]
+.SH "DESCRIPTION"
+.PP
+\fBafppasswd\fR
+allows the maintenance of afppasswd files created by netatalk for use by the uams_randnum\&.so UAM (providing the "Randnum exchange" and "2\-Way Randnum exchange" User Authentication Modules)\&.
+.PP
+\fBafppasswd\fR
+can either be called by root with parameters, or can be called by local system users with no parameters to change their AFP passwords\&.
+.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
+.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\*(Aqs documentation\&.
+.sp .5v
+.RE
+.SH "EXAMPLE"
+.PP
+Local user changing their own password:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+example% \fBafppasswd\fR
+Enter NEW AFP password: \fB(hidden)\fR
+Enter NEW AFP password again: \fB(hidden)\fR
+afppasswd: updated password\&.
+.fi
+.if n \{\
+.RE
+.\}
+.SH "OPTIONS"
+.PP
+\fB\-a\fR
+.RS 4
+Add a new user to the
+\fBafppasswd\fR
+file\&.
+.RE
+.PP
+\fB\-c\fR
+.RS 4
+Create and/or initialize
+\fBafppasswd\fR
+file or specific user\&.
+.RE
+.PP
+\fB\-f\fR
+.RS 4
+Force the current action\&.
+.RE
+.PP
+\fB\-p\fR\fI path\fR
+.RS 4
+Path to
+\fBafppasswd\fR
+file\&.
+.RE
+.PP
+\fB\-n\fR
+.RS 4
+If cracklib support is built into
+\fBnetatalk\fR
+this option will cause cracklib checking to be disabled, if the superuser does not want to have the password run against the cracklib dictionary\&.
+.RE
+.PP
+\fB\-u\fR\fI minimum uid\fR
+.RS 4
+This is the minimum
+\fIuser id\fR
+(uid) that
+\fBafppasswd\fR
+will use when creating users\&.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBafpd\fR(8),
+\fBafp.conf\fR(5)\&.
diff --git a/man/man1/afpstats.1.in b/man/man1/afpstats.1.in
new file mode 100644 (file)
index 0000000..16dc0b1
--- /dev/null
@@ -0,0 +1,50 @@
+'\" t
+.\"     Title: afpstats
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 24 Mar 2013
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "AFPSTATS" "1" "24 Mar 2013" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+afpstats \- List AFP statistics
+.SH "SYNOPSIS"
+.HP \w'\fBafpstats\fR\fB\fR\ 'u
+\fBafpstats\fR\fB\fR
+.SH "DESCRIPTION"
+.PP
+\fBafpstats\fR
+list AFP statistics via D\-Bus IPC\&.
+.SH "NOTE"
+.PP
+\fBafpd\fR
+must support D\-Bus\&. Check it by "\fBafpd \-V\fR"\&.
+.PP
+"\fBafpstats = yes\fR" must be set in
+@pkgconfdir@/afp\&.conf\&.
+.SH "SEE ALSO"
+.PP
+\fBafpd\fR(8),
+\fBafp.conf\fR(5),
+\fBdbus-daemon\fR(1)
diff --git a/man/man1/afpstats.1.tmpl b/man/man1/afpstats.1.tmpl
deleted file mode 100644 (file)
index b798099..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-'\" t
-.\"     Title: afpstats
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 24 Mar 2013
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.TH "AFPSTATS" "1" "24 Mar 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"
-afpstats \- List AFP statistics
-.SH "SYNOPSIS"
-.HP \w'\fBafpstats\fR\fB\fR\ 'u
-\fBafpstats\fR\fB\fR
-.SH "DESCRIPTION"
-.PP
-\fBafpstats\fR
-list AFP statistics via D\-Bus IPC\&.
-.SH "NOTE"
-.PP
-\fBafpd\fR
-must support D\-Bus\&. Check it by "\fBafpd \-V\fR"\&.
-.PP
-"\fBafpstats = yes\fR" must be set in
-:ETCDIR:/afp\&.conf\&.
-.SH "SEE ALSO"
-.PP
-\fBafpd\fR(8),
-\fBafp.conf\fR(5),
-\fBdbus-daemon\fR(1)
diff --git a/man/man1/apple_dump.1 b/man/man1/apple_dump.1
deleted file mode 100644 (file)
index f8676fd..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-'\" t
-.\"     Title: apple_dump
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 16 Jul 2012
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-apple_dump \- Dump AppleSingle/AppleDouble format data
-.SH "SYNOPSIS"
-.HP \w'\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\ 'u
-\fBapple_dump\fR\fB\fR [\-a] [\fIFILE\fR | \fIDIR\fR]
-.br
-\fBapple_dump\fR\fB\fR \-e \fIFILE\fR | \fIDIR\fR 
-.br
-\fBapple_dump\fR\fB\fR \-f [\fIFILE\fR]
-.br
-\fBapple_dump\fR\fB\fR \-d [\fIFILE\fR]
-.br
-\fBapple_dump\fR\fB\fR \-h | \-help | \-\-help 
-.br
-\fBapple_dump\fR\fB\fR \-v | \-version | \-\-version 
-.SH "DESCRIPTION"
-.PP
-\fBapple_dump\fR
-is a perl script to dump AppleSingle/AppleDouble format data\&.
-.PP
-This script can dump various AppleSingle/AppleDouble data created by mailer, archiver, Mac OS X, Netatalk and so on\&.
-.PP
-With no
-\fIFILE\fR|\fIDIR\fR, or when
-\fIFILE\fR|\fIDIR\fR
-is \-, read standard input\&.
-.SH "OPTIONS"
-.PP
-\fB\-a\fR [\fIFILE\fR|\fIDIR\fR]
-.RS 4
-This is default\&. Dump a AppleSingle/AppleDouble file for
-\fIFILE\fR
-or
-\fIDIR\fR
-automatically\&. If FILE is not AppleSingle/AppleDouble format, look for extended attribute,
-\fI\&.AppleDouble/FILE\fR
-and
-\fI\&._FILE\fR\&. If
-\fIDIR\fR, look for extended attribute,
-\fIDIR/\&.AppleDouble/\&.Parent\fR
-and
-\fI\&._DIR\fR\&.
-.RE
-.PP
-\fB\-e\fR \fIFILE\fR|\fIDIR\fR
-.RS 4
-Dump extended attribute of\fIFILE\fR
-or
-\fIDIR\fR\&.
-.RE
-.PP
-\fB\-f\fR [\fIFILE\fR]
-.RS 4
-Dump
-\fIFILE\fR\&. Assume FinderInfo to be FileInfo\&.
-.RE
-.PP
-\fB\-d\fR [\fIFILE\fR]
-.RS 4
-Dump
-\fIFILE\fR\&. Assume FinderInfo to be DirInfo\&.
-.RE
-.PP
-\fB\-h, \-help, \-\-help\fR
-.RS 4
-Display the help and exit
-.RE
-.PP
-\fB\-v, \-version, \-\-version\fR
-.RS 4
-Show version and exit
-.RE
-.SH "NOTE"
-.PP
-There is no way to detect whether FinderInfo is FileInfo or DirInfo\&. By default, apple_dump 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\*(Aqt look for another file\&.
-.SH "SEE ALSO"
-.PP
-\fBad\fR(1),
-\fBgetfattr\fR(1),
-\fBattr\fR(1),
-\fBrunat\fR(1),
-\fBgetextattr\fR(8),
-\fBlsextattr\fR(8)
diff --git a/man/man1/apple_dump.1.in b/man/man1/apple_dump.1.in
new file mode 100644 (file)
index 0000000..c9d7ff6
--- /dev/null
@@ -0,0 +1,114 @@
+'\" t
+.\"     Title: apple_dump
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 16 Jul 2012
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "APPLE_DUMP" "1" "16 Jul 2012" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+apple_dump \- Dump AppleSingle/AppleDouble format data
+.SH "SYNOPSIS"
+.HP \w'\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\fBapple_dump\fR\fB\fR\ 'u
+\fBapple_dump\fR\fB\fR [\-a] [\fIFILE\fR | \fIDIR\fR]
+.br
+\fBapple_dump\fR\fB\fR \-e \fIFILE\fR | \fIDIR\fR 
+.br
+\fBapple_dump\fR\fB\fR \-f [\fIFILE\fR]
+.br
+\fBapple_dump\fR\fB\fR \-d [\fIFILE\fR]
+.br
+\fBapple_dump\fR\fB\fR \-h | \-help | \-\-help 
+.br
+\fBapple_dump\fR\fB\fR \-v | \-version | \-\-version 
+.SH "DESCRIPTION"
+.PP
+\fBapple_dump\fR
+is a perl script to dump AppleSingle/AppleDouble format data\&.
+.PP
+This script can dump various AppleSingle/AppleDouble data created by mailer, archiver, Mac OS X, Netatalk and so on\&.
+.PP
+With no
+\fIFILE\fR|\fIDIR\fR, or when
+\fIFILE\fR|\fIDIR\fR
+is \-, read standard input\&.
+.SH "OPTIONS"
+.PP
+\fB\-a\fR [\fIFILE\fR|\fIDIR\fR]
+.RS 4
+This is default\&. Dump a AppleSingle/AppleDouble file for
+\fIFILE\fR
+or
+\fIDIR\fR
+automatically\&. If FILE is not AppleSingle/AppleDouble format, look for extended attribute,
+\fI\&.AppleDouble/FILE\fR
+and
+\fI\&._FILE\fR\&. If
+\fIDIR\fR, look for extended attribute,
+\fIDIR/\&.AppleDouble/\&.Parent\fR
+and
+\fI\&._DIR\fR\&.
+.RE
+.PP
+\fB\-e\fR \fIFILE\fR|\fIDIR\fR
+.RS 4
+Dump extended attribute of\fIFILE\fR
+or
+\fIDIR\fR\&.
+.RE
+.PP
+\fB\-f\fR [\fIFILE\fR]
+.RS 4
+Dump
+\fIFILE\fR\&. Assume FinderInfo to be FileInfo\&.
+.RE
+.PP
+\fB\-d\fR [\fIFILE\fR]
+.RS 4
+Dump
+\fIFILE\fR\&. Assume FinderInfo to be DirInfo\&.
+.RE
+.PP
+\fB\-h, \-help, \-\-help\fR
+.RS 4
+Display the help and exit
+.RE
+.PP
+\fB\-v, \-version, \-\-version\fR
+.RS 4
+Show version and exit
+.RE
+.SH "NOTE"
+.PP
+There is no way to detect whether FinderInfo is FileInfo or DirInfo\&. By default, apple_dump 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\*(Aqt look for another file\&.
+.SH "SEE ALSO"
+.PP
+\fBad\fR(1),
+\fBgetfattr\fR(1),
+\fBattr\fR(1),
+\fBrunat\fR(1),
+\fBgetextattr\fR(8),
+\fBlsextattr\fR(8)
diff --git a/man/man1/asip-status.pl.1.in b/man/man1/asip-status.pl.1.in
new file mode 100644 (file)
index 0000000..2963617
--- /dev/null
@@ -0,0 +1,135 @@
+'\" t
+.\"     Title: asip-status.pl
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 24 Jul 2012
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "ASIP\-STATUS\&.PL" "1" "24 Jul 2012" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+asip-status.pl \- Queries AFP servers for their capabilities
+.SH "SYNOPSIS"
+.HP \w'\fBasip\-status\&.pl\fR\fB\fR\ 'u
+\fBasip\-status\&.pl\fR\fB\fR [\-d] [\-i] [\-x] HOSTNAME[:PORT]
+
+.br
+.HP \w'\fBasip\-status\&.pl\fR\fB\fR\ 'u
+\fBasip\-status\&.pl\fR\fB\fR \-v | \-version | \-\-version 
+.SH "DESCRIPTION"
+.PP
+\fBasip\-status\&.pl\fR
+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\*(Aqt supply :PORT, then the default AFP port, 548, will be used\&.
+.SH "OPTIONS"
+.PP
+\fB\-d\fR
+.RS 4
+Enable debug output\&.
+.RE
+.PP
+\fB\-i\fR
+.RS 4
+Show icon if it exists\&.
+.RE
+.PP
+\fB\-x\fR
+.RS 4
+Enable hex dump output\&.
+.RE
+.PP
+\fB\-v, \-version, \-\-version\fR
+.RS 4
+Show version\&.
+.RE
+.SH "EXAMPLES"
+.PP
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBasip\-status\&.pl\fR 192\&.168\&.1\&.15
+AFP reply from 192\&.168\&.1\&.15:548
+Flags: 1  Cmd: 3  ID: 57005
+Reply: DSIGetStatus
+Request ID: 57005
+Machine type: Macintosh
+AFP versions: AFPVersion 1\&.1,AFPVersion 2\&.0,AFPVersion 2\&.1,AFP2\&.2
+UAMs: Cleartxt passwrd,Randnum exchange,2\-Way Randnum exchange
+Volume Icon & Mask: Yes
+Flags: 
+    SupportsCopyFile
+    SupportsChgPwd
+    SupportsServerMessages
+    SupportsServerSignature
+    SupportsTCP/IP
+    SupportsSuperClient
+Server name: bookchan
+Signature:
+04 1d 65 23 04 1d 65 23 04 1d 65 23 04 1d 65 23  \&.\&.e#\&.\&.e#\&.\&.e#\&.\&.e#
+                                                  
+Network address: 192\&.168\&.1\&.15:548 (TCP/IP address and port)
+Network address: 65280\&.128 (ddp address)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBasip\-status\&.pl\fR myserver:10548
+AFP reply from myserver:10548
+Flags: 1  Cmd: 3  ID: 57005
+Reply: DSIGetStatus
+Request ID: 57005
+Machine type: Netatalk3\&.0
+AFP versions: AFP2\&.2,AFPX03,AFP3\&.1,AFP3\&.2,AFP3\&.3
+UAMs: DHX2,DHCAST128
+Volume Icon & Mask: Yes
+Flags: 
+    SupportsCopyFile
+    SupportsServerMessages
+    SupportsServerSignature
+    SupportsTCP/IP
+    SupportsSrvrNotifications
+    SupportsOpenDirectory
+    SupportsUTF8Servername
+    SupportsUUIDs
+    SupportsExtSleep
+    SupportsSuperClient
+Server name: myserver
+Signature:
+8a c6 12 3a 0e d9 95 3e 6f 31 e3 a9 17 f5 70 f6  \&.\&.\&.:\&.\&.\&.>o1\&.\&.\&.\&.p\&.
+                                                  
+Network address: 192\&.168\&.1\&.154:10548 (TCP/IP address and port)
+UTF8 Servername: myserver
+.fi
+.if n \{\
+.RE
+.\}
+.SH "REPORTING BUGS"
+.PP
+Report bugs to the Netatalk\-devel list <netatalk\-devel@lists\&.sourceforge\&.net>\&.
diff --git a/man/man1/asip-status.pl.1.tmpl b/man/man1/asip-status.pl.1.tmpl
deleted file mode 100644 (file)
index 735f8eb..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-'\" t
-.\"     Title: asip-status.pl
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 24 Jul 2012
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-asip-status.pl \- Queries AFP servers for their capabilities
-.SH "SYNOPSIS"
-.HP \w'\fBasip\-status\&.pl\fR\fB\fR\ 'u
-\fBasip\-status\&.pl\fR\fB\fR [\-d] [\-i] [\-x] HOSTNAME[:PORT]
-
-.br
-.HP \w'\fBasip\-status\&.pl\fR\fB\fR\ 'u
-\fBasip\-status\&.pl\fR\fB\fR \-v | \-version | \-\-version 
-.SH "DESCRIPTION"
-.PP
-\fBasip\-status\&.pl\fR
-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\*(Aqt supply :PORT, then the default AFP port, 548, will be used\&.
-.SH "OPTIONS"
-.PP
-\fB\-d\fR
-.RS 4
-Enable debug output\&.
-.RE
-.PP
-\fB\-i\fR
-.RS 4
-Show icon if it exists\&.
-.RE
-.PP
-\fB\-x\fR
-.RS 4
-Enable hex dump output\&.
-.RE
-.PP
-\fB\-v, \-version, \-\-version\fR
-.RS 4
-Show version\&.
-.RE
-.SH "EXAMPLES"
-.PP
-.if n \{\
-.RS 4
-.\}
-.nf
-\fBasip\-status\&.pl\fR 192\&.168\&.1\&.15
-AFP reply from 192\&.168\&.1\&.15:548
-Flags: 1  Cmd: 3  ID: 57005
-Reply: DSIGetStatus
-Request ID: 57005
-Machine type: Macintosh
-AFP versions: AFPVersion 1\&.1,AFPVersion 2\&.0,AFPVersion 2\&.1,AFP2\&.2
-UAMs: Cleartxt passwrd,Randnum exchange,2\-Way Randnum exchange
-Volume Icon & Mask: Yes
-Flags: 
-    SupportsCopyFile
-    SupportsChgPwd
-    SupportsServerMessages
-    SupportsServerSignature
-    SupportsTCP/IP
-    SupportsSuperClient
-Server name: bookchan
-Signature:
-04 1d 65 23 04 1d 65 23 04 1d 65 23 04 1d 65 23  \&.\&.e#\&.\&.e#\&.\&.e#\&.\&.e#
-                                                  
-Network address: 192\&.168\&.1\&.15:548 (TCP/IP address and port)
-Network address: 65280\&.128 (ddp address)
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-.if n \{\
-.RS 4
-.\}
-.nf
-\fBasip\-status\&.pl\fR myserver:10548
-AFP reply from myserver:10548
-Flags: 1  Cmd: 3  ID: 57005
-Reply: DSIGetStatus
-Request ID: 57005
-Machine type: Netatalk3\&.0
-AFP versions: AFP2\&.2,AFPX03,AFP3\&.1,AFP3\&.2,AFP3\&.3
-UAMs: DHX2,DHCAST128
-Volume Icon & Mask: Yes
-Flags: 
-    SupportsCopyFile
-    SupportsServerMessages
-    SupportsServerSignature
-    SupportsTCP/IP
-    SupportsSrvrNotifications
-    SupportsOpenDirectory
-    SupportsUTF8Servername
-    SupportsUUIDs
-    SupportsExtSleep
-    SupportsSuperClient
-Server name: myserver
-Signature:
-8a c6 12 3a 0e d9 95 3e 6f 31 e3 a9 17 f5 70 f6  \&.\&.\&.:\&.\&.\&.>o1\&.\&.\&.\&.p\&.
-                                                  
-Network address: 192\&.168\&.1\&.154:10548 (TCP/IP address and port)
-UTF8 Servername: myserver
-.fi
-.if n \{\
-.RE
-.\}
-.SH "REPORTING BUGS"
-.PP
-Report bugs to the Netatalk\-devel list <netatalk\-devel@lists\&.sourceforge\&.net>\&.
diff --git a/man/man1/dbd.1 b/man/man1/dbd.1
deleted file mode 100644 (file)
index 214b31d..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-'\" t
-.\"     Title: dbd
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" 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" "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
-.\" -----------------------------------------------------------------
-.\" disable hyphenation
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-dbd \- CNID database maintenance
-.SH "SYNOPSIS"
-.HP \w'\fBdbd\fR\fB\fR\ 'u
-\fBdbd\fR\fB\fR [\-fsv] \fIvolumepath\fR
-.SH "DESCRIPTION"
-.PP
-\fBdbd\fR
-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
-convert from adouble:v2 to adouble:ea
-.RE
-.PP
-\-f
-.RS 4
-delete and recreate CNID database
-.RE
-.PP
-\-F
-.RS 4
-location of the afp\&.conf config file
-.RE
-.PP
-\-s
-.RS 4
-scan volume: treat the volume as read only and don\*(Aqt perform any filesystem modifications
-.RE
-.PP
-\-t
-.RS 4
-show statistics while running
-.RE
-.PP
-\-v
-.RS 4
-verbose
-.RE
-.PP
-\-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 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),
-\fBcnid_dbd\fR(8)
diff --git a/man/man1/dbd.1.in b/man/man1/dbd.1.in
new file mode 100644 (file)
index 0000000..ad233a9
--- /dev/null
@@ -0,0 +1,81 @@
+'\" t
+.\"     Title: dbd
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 28 Dec 2012
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "DBD" "1" "28 Dec 2012" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+dbd \- CNID database maintenance
+.SH "SYNOPSIS"
+.HP \w'\fBdbd\fR\fB\fR\ 'u
+\fBdbd\fR\fB\fR [\-fsv] \fIvolumepath\fR
+.SH "DESCRIPTION"
+.PP
+\fBdbd\fR
+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
+convert from adouble:v2 to adouble:ea
+.RE
+.PP
+\-f
+.RS 4
+delete and recreate CNID database
+.RE
+.PP
+\-F
+.RS 4
+location of the afp\&.conf config file
+.RE
+.PP
+\-s
+.RS 4
+scan volume: treat the volume as read only and don\*(Aqt perform any filesystem modifications
+.RE
+.PP
+\-t
+.RS 4
+show statistics while running
+.RE
+.PP
+\-v
+.RS 4
+verbose
+.RE
+.PP
+\-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 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),
+\fBcnid_dbd\fR(8)
diff --git a/man/man1/macusers.1 b/man/man1/macusers.1
deleted file mode 100644 (file)
index 6da607b..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-'\" t
-.\"     Title: macusers
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 13 Oct 2011
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-macusers \- List the users connecting via AFP
-.SH "SYNOPSIS"
-.HP \w'\fBmacusers\fR\fB\fR\ 'u
-\fBmacusers\fR\fB\fR
-.HP \w'\fBmacusers\fR\fB\fR\ 'u
-\fBmacusers\fR\fB\fR \-v | \-version | \-\-version | \-h | \-help | \-\-help 
-.SH "DESCRIPTION"
-.PP
-\fBmacusers\fR
-list the users connecting via AFP\&.
-.SH "OPTIONS"
-.PP
-\fB\-v, \-version, \-\-version\fR
-.RS 4
-Show version and exit
-.RE
-.PP
-\fB\-h, \-help, \-\-help\fR
-.RS 4
-Display the help and exit
-.RE
-.SH "SEE ALSO"
-.PP
-\fBafpd\fR(8)
diff --git a/man/man1/macusers.1.in b/man/man1/macusers.1.in
new file mode 100644 (file)
index 0000000..ed948b2
--- /dev/null
@@ -0,0 +1,54 @@
+'\" t
+.\"     Title: macusers
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 13 Oct 2011
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "MACUSERS" "1" "13 Oct 2011" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+macusers \- List the users connecting via AFP
+.SH "SYNOPSIS"
+.HP \w'\fBmacusers\fR\fB\fR\ 'u
+\fBmacusers\fR\fB\fR
+.HP \w'\fBmacusers\fR\fB\fR\ 'u
+\fBmacusers\fR\fB\fR \-v | \-version | \-\-version | \-h | \-help | \-\-help 
+.SH "DESCRIPTION"
+.PP
+\fBmacusers\fR
+list the users connecting via AFP\&.
+.SH "OPTIONS"
+.PP
+\fB\-v, \-version, \-\-version\fR
+.RS 4
+Show version and exit
+.RE
+.PP
+\fB\-h, \-help, \-\-help\fR
+.RS 4
+Display the help and exit
+.RE
+.SH "SEE ALSO"
+.PP
+\fBafpd\fR(8)
diff --git a/man/man1/megatron.1 b/man/man1/megatron.1
deleted file mode 100644 (file)
index 300bd4f..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-'\" t
-.\"     Title: megatron
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 02 Sep 2011
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-megatron, unhex, unbin, unsingle, hqx2bin, single2bin, macbinary \- Macintosh file format transformer
-.SH "SYNOPSIS"
-.HP \w'\fBmegatron\fR\fB\fR\fBunbin\fR\fB\fR\fBunhex\fR\fB\fR\fBunsingle\fR\fB\fR\fBhqx2bin\fR\fB\fR\fBsingle2bin\fR\fB\fR\fBmacbinary\fR\fB\fR\ 'u
-\fBmegatron\fR\fB\fR [\fIsourcefile\fR...]
-.br
-\fBunbin\fR\fB\fR [\fIsourcefile\fR...]
-.br
-\fBunhex\fR\fB\fR [\fIsourcefile\fR...]
-.br
-\fBunsingle\fR\fB\fR [\fIsourcefile\fR...]
-.br
-\fBhqx2bin\fR\fB\fR [\fIsourcefile\fR...]
-.br
-\fBsingle2bin\fR\fB\fR [\fIsourcefile\fR...]
-.br
-\fBmacbinary\fR\fB\fR [\fIsourcefile\fR...]
-.SH "DESCRIPTION"
-.PP
-\fBmegatron\fR
-is used to transform files from BinHex, MacBinary, AppleSingle, or
-\fBnetatalk\fR
-style AppleDouble formats into MacBinary or
-\fBnetatalk\fR
-style AppleDouble formats\&. The
-\fBnetatalk\fR
-style AppleDouble format is the file format used by
-\fBafpd,\fR
-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 transformation is being asked of it\&.
-.PP
-If
-\fBmegatron\fR
-is called as
-\fBunhex\fR
-,
-\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\*(Aqt have a standard filename extension\&.
-.PP
-If
-\fBmegatron\fR
-is called as
-\fBhqx2bin\fR,
-\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\*(Aqt copy them from the server using a Macintosh for some reason\&.
-.PP
-If
-\fBmegatron\fR
-is called with any other name, it uses the default translation, namely
-\fBunhex\fR\&.
-.PP
-If no source file is given, or if
-\fIsourcefile\fR
-is `\fB\-\fR\*(Aq, and if the conversion is from a BinHex or MacBinary file,
-\fBmegatron\fR
-will read from standard input\&.
-.PP
-The filename used to store any output file is the filename that is encoded in the source file\&. MacBinary files are created with a "\&.bin" extension\&. In the case of conflicts, the old file is overwritten!
-.SH "OPTIONS"
-.PP
-\fB\-v, \-\-version\fR
-.RS 4
-Show version\&.
-.RE
-.SH "SEE ALSO"
-.PP
-\fBafpd\fR(8)
diff --git a/man/man1/megatron.1.in b/man/man1/megatron.1.in
new file mode 100644 (file)
index 0000000..9b47c22
--- /dev/null
@@ -0,0 +1,102 @@
+'\" t
+.\"     Title: megatron
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 02 Sep 2011
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "MEGATRON" "1" "02 Sep 2011" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+megatron, unhex, unbin, unsingle, hqx2bin, single2bin, macbinary \- Macintosh file format transformer
+.SH "SYNOPSIS"
+.HP \w'\fBmegatron\fR\fB\fR\fBunbin\fR\fB\fR\fBunhex\fR\fB\fR\fBunsingle\fR\fB\fR\fBhqx2bin\fR\fB\fR\fBsingle2bin\fR\fB\fR\fBmacbinary\fR\fB\fR\ 'u
+\fBmegatron\fR\fB\fR [\fIsourcefile\fR...]
+.br
+\fBunbin\fR\fB\fR [\fIsourcefile\fR...]
+.br
+\fBunhex\fR\fB\fR [\fIsourcefile\fR...]
+.br
+\fBunsingle\fR\fB\fR [\fIsourcefile\fR...]
+.br
+\fBhqx2bin\fR\fB\fR [\fIsourcefile\fR...]
+.br
+\fBsingle2bin\fR\fB\fR [\fIsourcefile\fR...]
+.br
+\fBmacbinary\fR\fB\fR [\fIsourcefile\fR...]
+.SH "DESCRIPTION"
+.PP
+\fBmegatron\fR
+is used to transform files from BinHex, MacBinary, AppleSingle, or
+\fBnetatalk\fR
+style AppleDouble formats into MacBinary or
+\fBnetatalk\fR
+style AppleDouble formats\&. The
+\fBnetatalk\fR
+style AppleDouble format is the file format used by
+\fBafpd,\fR
+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 transformation is being asked of it\&.
+.PP
+If
+\fBmegatron\fR
+is called as
+\fBunhex\fR
+,
+\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\*(Aqt have a standard filename extension\&.
+.PP
+If
+\fBmegatron\fR
+is called as
+\fBhqx2bin\fR,
+\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\*(Aqt copy them from the server using a Macintosh for some reason\&.
+.PP
+If
+\fBmegatron\fR
+is called with any other name, it uses the default translation, namely
+\fBunhex\fR\&.
+.PP
+If no source file is given, or if
+\fIsourcefile\fR
+is `\fB\-\fR\*(Aq, and if the conversion is from a BinHex or MacBinary file,
+\fBmegatron\fR
+will read from standard input\&.
+.PP
+The filename used to store any output file is the filename that is encoded in the source file\&. MacBinary files are created with a "\&.bin" extension\&. In the case of conflicts, the old file is overwritten!
+.SH "OPTIONS"
+.PP
+\fB\-v, \-\-version\fR
+.RS 4
+Show version\&.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBafpd\fR(8)
diff --git a/man/man1/netatalk-config.1 b/man/man1/netatalk-config.1
deleted file mode 100644 (file)
index 7208ce2..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-'\" t
-.\"     Title: netatalk-config
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 09 June 2001
-.\"    Manual: The Netatalk Project
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-netatalk-config \- script to get information about the installed version of netatalk
-.SH "SYNOPSIS"
-.HP \w'\fBnetatalk\-config\fR\fB\fR\ 'u
-\fBnetatalk\-config\fR\fB\fR [\-\-prefix\ [\fI=DIR\fR]] [\-\-exec_prefix\ [\fI=DIR\fR]] [\-\-help] [\-\-version] [\-\-libs] [\-\-libs\-dirs] [\-\-libs\-names] [\-\-cflags] [\-\-macros]
-.SH "DESCRIPTION"
-.PP
-\fBnetatalk\-config\fR
-is a tool that is used to determine the compiler and linker flags that should be used to compile and link programs that use the
-\fInetatalk\fR
-run\-time libraries\&.
-.SH "OPTIONS"
-.PP
-\fBnetatalk\-config\fR
-accepts the following options:
-.PP
-\fB\-\-help\fR
-.RS 4
-Print a short help for this command and exit\&.
-.RE
-.PP
-\fB\-\-version\fR
-.RS 4
-Print the currently installed version of
-\fInetatalk\fR
-on the standard output\&.
-.RE
-.PP
-\fB\-\-libs\fR
-.RS 4
-Print the linker flags that are necessary to link against the
-\fInetatalk\fR
-run\-time libraries\&.
-.RE
-.PP
-\fB\-\-libs\-dirs\fR
-.RS 4
-Print only the \-l/\-R part of \-\-libs\&.
-.RE
-.PP
-\fB\-\-libs\-names\fR
-.RS 4
-Print only the \-l part of \-\-libs\&.
-.RE
-.PP
-\fB\-\-cflags\fR
-.RS 4
-Print the compiler flags that are necessary to compile a program linked against the
-\fInetatalk\fR
-run\-time libraries\&.
-.RE
-.PP
-\fB\-\-macros\fR
-.RS 4
-Print the
-\fInetatalk\fR
-m4 directory\&.
-.RE
-.PP
-\fB\-\-prefix=PREFIX\fR
-.RS 4
-If specified, use PREFIX instead of the installation prefix that
-\fInetatalk\fR
-was built with when computing the output for the \-\-cflags and \-\-libs options\&. This option is also used for the exec prefix if \-\-exec\-prefix was not specified\&. This option must be specified before any \-\-libs or \-\-cflags options\&.
-.RE
-.PP
-\fB\-\-exec\e_prefix=PREFIX\fR
-.RS 4
-If specified, use PREFIX instead of the installation exec prefix that
-\fInetatalk\fR
-was built with when computing the output for the \-\-cflags and \-\-libs options\&. This option must be specified before any \-\-libs or \-\-cflags options\&.
-.RE
-.SH "COPYRIGHT"
-.PP
-Copyright \(co 1998 Owen Taylor
-.PP
-Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation\&.
-.PP
-Man page adapted for
-\fBnetatalk\-config\fR
-by Sebastian Rittau in 2001\&.
diff --git a/man/man1/netatalk-config.1.in b/man/man1/netatalk-config.1.in
new file mode 100644 (file)
index 0000000..f4947fa
--- /dev/null
@@ -0,0 +1,110 @@
+'\" t
+.\"     Title: netatalk-config
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 09 June 2001
+.\"    Manual: The Netatalk Project
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "NETATALK\-CONFIG" "1" "09 June 2001" "@NETATALK_VERSION@" "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
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+netatalk-config \- script to get information about the installed version of netatalk
+.SH "SYNOPSIS"
+.HP \w'\fBnetatalk\-config\fR\fB\fR\ 'u
+\fBnetatalk\-config\fR\fB\fR [\-\-prefix\ [\fI=DIR\fR]] [\-\-exec_prefix\ [\fI=DIR\fR]] [\-\-help] [\-\-version] [\-\-libs] [\-\-libs\-dirs] [\-\-libs\-names] [\-\-cflags] [\-\-macros]
+.SH "DESCRIPTION"
+.PP
+\fBnetatalk\-config\fR
+is a tool that is used to determine the compiler and linker flags that should be used to compile and link programs that use the
+\fInetatalk\fR
+run\-time libraries\&.
+.SH "OPTIONS"
+.PP
+\fBnetatalk\-config\fR
+accepts the following options:
+.PP
+\fB\-\-help\fR
+.RS 4
+Print a short help for this command and exit\&.
+.RE
+.PP
+\fB\-\-version\fR
+.RS 4
+Print the currently installed version of
+\fInetatalk\fR
+on the standard output\&.
+.RE
+.PP
+\fB\-\-libs\fR
+.RS 4
+Print the linker flags that are necessary to link against the
+\fInetatalk\fR
+run\-time libraries\&.
+.RE
+.PP
+\fB\-\-libs\-dirs\fR
+.RS 4
+Print only the \-l/\-R part of \-\-libs\&.
+.RE
+.PP
+\fB\-\-libs\-names\fR
+.RS 4
+Print only the \-l part of \-\-libs\&.
+.RE
+.PP
+\fB\-\-cflags\fR
+.RS 4
+Print the compiler flags that are necessary to compile a program linked against the
+\fInetatalk\fR
+run\-time libraries\&.
+.RE
+.PP
+\fB\-\-macros\fR
+.RS 4
+Print the
+\fInetatalk\fR
+m4 directory\&.
+.RE
+.PP
+\fB\-\-prefix=PREFIX\fR
+.RS 4
+If specified, use PREFIX instead of the installation prefix that
+\fInetatalk\fR
+was built with when computing the output for the \-\-cflags and \-\-libs options\&. This option is also used for the exec prefix if \-\-exec\-prefix was not specified\&. This option must be specified before any \-\-libs or \-\-cflags options\&.
+.RE
+.PP
+\fB\-\-exec\e_prefix=PREFIX\fR
+.RS 4
+If specified, use PREFIX instead of the installation exec prefix that
+\fInetatalk\fR
+was built with when computing the output for the \-\-cflags and \-\-libs options\&. This option must be specified before any \-\-libs or \-\-cflags options\&.
+.RE
+.SH "COPYRIGHT"
+.PP
+Copyright \(co 1998 Owen Taylor
+.PP
+Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation\&.
+.PP
+Man page adapted for
+\fBnetatalk\-config\fR
+by Sebastian Rittau in 2001\&.
diff --git a/man/man1/uniconv.1.in b/man/man1/uniconv.1.in
new file mode 100644 (file)
index 0000000..1ec2779
--- /dev/null
@@ -0,0 +1,203 @@
+'\" t
+.\"     Title: uniconv
+.\"    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_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "UNICONV" "1" "19 Jan 2013" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+uniconv \- convert Netatalk volume encoding
+.SH "SYNOPSIS"
+.HP \w'\fBuniconv\fR\fB\fR\ 'u
+\fBuniconv\fR\fB\fR [\-ndv] \-c\ \fIcnidbackend\fR \-f\ \fIfromcode\fR \-t\ \fItocode\fR [\-m\ \fImaccode\fR] \fIvolumepath\fR
+.SH "DESCRIPTION"
+.PP
+\fBuniconv\fR
+converts the volume encoding of
+\fIvolumepath\fR
+from the
+\fIfromcode\fR
+to the
+\fItocode\fR
+encoding\&.
+.SH "OPTIONS"
+.PP
+\-c
+.RS 4
+CNID backend used on this volume, usually cdb or dbd\&. Should match the backend selected with afpd for this volume\&. If not specified, the default CNID backend "@DEFAULT_CNID_SCHEME@" is used
+.RE
+.PP
+\-d
+.RS 4
+don\*(Aqt HEX encode leading dots (:2e), equivalent to
+\fBuse dots = yes\fR
+in
+\fBafp.conf\fR(5)
+.RE
+.PP
+\-f
+.RS 4
+encoding to convert from, use ASCII for HEX encoded volumes
+.RE
+.PP
+\-h
+.RS 4
+display help
+.RE
+.PP
+\-m
+.RS 4
+Macintosh client codepage, required for HEX encoded volumes\&. Defaults to "MAC_ROMAN"
+.RE
+.PP
+\-n
+.RS 4
+"dry run", don\*(Aqt do any real changes
+.RE
+.PP
+\-t
+.RS 4
+volume encoding to convert to, e\&.g\&. UTF8
+.RE
+.PP
+\-v
+.RS 4
+verbose output, use twice for maximum logging\&.
+.RE
+.PP
+\-V
+.RS 4
+print version and exit
+.RE
+.PP
+.SH "WARNING"
+.PP
+Setting the wrong options might render your data unusable!!! Make sure you know what you are doing\&. Always backup your data first\&.
+.PP
+It is
+\fB*strongly*\fR
+recommended to do a "dry run" first and to check the output for conversion errors\&.
+.PP
+\fBafpd\fR(8)
+should
+\fInot\fR
+be running while you change the volume encoding\&. Remember to change
+\fBunix charset\fR
+or
+\fBvol charset\fR
+in
+\fBafp.conf\fR(5)
+to the new codepage, before restarting afpd\&.
+.PP
+In case of
+\fBMacChineseTraditional\fR,
+\fBMacJapanese\fR
+or
+\fBMacKorean\fR, uniconv cannot be used\&.
+.PP
+\fBUSE AT YOUR OWN RISK!!!\fR
+.SH "SELECTABLE CHARSETS"
+.PP
+Netatalk provides internal support for UTF\-8 (pre\- and decomposed) and HEX\&. If you want to use other charsets, they must be provided by
+\fBiconv\fR(1)
+.PP
+\fBuniconv\fR
+also knows iso\-8859\&.adapted, an old style 1\&.x NLS widely used\&. This is only intended for upgrading old volumes,
+\fBafpd\fR(8)
+cannot handle iso\-8859\&.adapted anymore\&.
+.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, 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\*(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
+use
+\fBuniconv\fR
+with cdb and
+\fBafpd\fR
+with dbd later\&.
+.PP
+\fBWarning\fR: There must not be two processes opening the CNID database using different backends at once! If a volume is still opened with dbd (cnid_metad/cnid_dbd) and you start
+\fBuniconv\fR
+with cdb, the result will be a corrupted CNID database, as the two backends use different locking schemes\&. You might run into additional problems, e\&.g\&. if dbd is compiled with transactions, cdb will not update the transaction logs\&.
+.PP
+In general, it is recommended to use the same backend for
+\fBuniconv\fR
+you are using with
+\fBafpd\fR(8)\&.
+.SH "EXAMPLES"
+.PP
+convert 1\&.x CAP encoded volume to UTF\-8, clients used MacRoman codepage, cnidscheme is dbd:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+example%\fB uniconv \-c dbd \-f ASCII \-t UTF8 \-m MAC_ROMAN /path/to/share\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+convert iso8859\-1 volume to UTF\-8, cnidscheme is cdb:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+example%\fB uniconv \-c cdb \-f ISO\-8859\-1 \-t UTF8 \-m MAC_ROMAN /path/to/share\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+convert 1\&.x volume using iso8859\-1 adapted NLS to HEX encoding:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+example%\fB uniconv \-f ISO\-8859\-ADAPTED \-t ASCII \-m MAC_ROMAN/path/to/share\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+convert UTF\-8 volume to HEX, for MacCyrillic clients:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+example%\fB uniconv \-f UTF8 \-t ASCII \-m MAC_CYRILLIC /path/to/share\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBafp.conf\fR(5),\fBafpd\fR(8),\fBiconv\fR(1),\fBcnid_metad\fR(8),\fBcnid_dbd\fR(8)
diff --git a/man/man1/uniconv.1.tmpl b/man/man1/uniconv.1.tmpl
deleted file mode 100644 (file)
index fabf30c..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-'\" t
-.\"     Title: uniconv
-.\"    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 "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
-.\" -----------------------------------------------------------------
-.\" disable hyphenation
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-uniconv \- convert Netatalk volume encoding
-.SH "SYNOPSIS"
-.HP \w'\fBuniconv\fR\fB\fR\ 'u
-\fBuniconv\fR\fB\fR [\-ndv] \-c\ \fIcnidbackend\fR \-f\ \fIfromcode\fR \-t\ \fItocode\fR [\-m\ \fImaccode\fR] \fIvolumepath\fR
-.SH "DESCRIPTION"
-.PP
-\fBuniconv\fR
-converts the volume encoding of
-\fIvolumepath\fR
-from the
-\fIfromcode\fR
-to the
-\fItocode\fR
-encoding\&.
-.SH "OPTIONS"
-.PP
-\-c
-.RS 4
-CNID backend used on this volume, usually cdb or dbd\&. Should match the backend selected with afpd for this volume\&. If not specified, the default CNID backend ":DEFAULT_CNID_SCHEME:" is used
-.RE
-.PP
-\-d
-.RS 4
-don\*(Aqt HEX encode leading dots (:2e), equivalent to
-\fBuse dots = yes\fR
-in
-\fBafp.conf\fR(5)
-.RE
-.PP
-\-f
-.RS 4
-encoding to convert from, use ASCII for HEX encoded volumes
-.RE
-.PP
-\-h
-.RS 4
-display help
-.RE
-.PP
-\-m
-.RS 4
-Macintosh client codepage, required for HEX encoded volumes\&. Defaults to "MAC_ROMAN"
-.RE
-.PP
-\-n
-.RS 4
-"dry run", don\*(Aqt do any real changes
-.RE
-.PP
-\-t
-.RS 4
-volume encoding to convert to, e\&.g\&. UTF8
-.RE
-.PP
-\-v
-.RS 4
-verbose output, use twice for maximum logging\&.
-.RE
-.PP
-\-V
-.RS 4
-print version and exit
-.RE
-.PP
-.SH "WARNING"
-.PP
-Setting the wrong options might render your data unusable!!! Make sure you know what you are doing\&. Always backup your data first\&.
-.PP
-It is
-\fB*strongly*\fR
-recommended to do a "dry run" first and to check the output for conversion errors\&.
-.PP
-\fBafpd\fR(8)
-should
-\fInot\fR
-be running while you change the volume encoding\&. Remember to change
-\fBunix charset\fR
-or
-\fBvol charset\fR
-in
-\fBafp.conf\fR(5)
-to the new codepage, before restarting afpd\&.
-.PP
-In case of
-\fBMacChineseTraditional\fR,
-\fBMacJapanese\fR
-or
-\fBMacKorean\fR, uniconv cannot be used\&.
-.PP
-\fBUSE AT YOUR OWN RISK!!!\fR
-.SH "SELECTABLE CHARSETS"
-.PP
-Netatalk provides internal support for UTF\-8 (pre\- and decomposed) and HEX\&. If you want to use other charsets, they must be provided by
-\fBiconv\fR(1)
-.PP
-\fBuniconv\fR
-also knows iso\-8859\&.adapted, an old style 1\&.x NLS widely used\&. This is only intended for upgrading old volumes,
-\fBafpd\fR(8)
-cannot handle iso\-8859\&.adapted anymore\&.
-.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, 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\*(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
-use
-\fBuniconv\fR
-with cdb and
-\fBafpd\fR
-with dbd later\&.
-.PP
-\fBWarning\fR: There must not be two processes opening the CNID database using different backends at once! If a volume is still opened with dbd (cnid_metad/cnid_dbd) and you start
-\fBuniconv\fR
-with cdb, the result will be a corrupted CNID database, as the two backends use different locking schemes\&. You might run into additional problems, e\&.g\&. if dbd is compiled with transactions, cdb will not update the transaction logs\&.
-.PP
-In general, it is recommended to use the same backend for
-\fBuniconv\fR
-you are using with
-\fBafpd\fR(8)\&.
-.SH "EXAMPLES"
-.PP
-convert 1\&.x CAP encoded volume to UTF\-8, clients used MacRoman codepage, cnidscheme is dbd:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-example%\fB uniconv \-c dbd \-f ASCII \-t UTF8 \-m MAC_ROMAN /path/to/share\fR
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-convert iso8859\-1 volume to UTF\-8, cnidscheme is cdb:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-example%\fB uniconv \-c cdb \-f ISO\-8859\-1 \-t UTF8 \-m MAC_ROMAN /path/to/share\fR
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-convert 1\&.x volume using iso8859\-1 adapted NLS to HEX encoding:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-example%\fB uniconv \-f ISO\-8859\-ADAPTED \-t ASCII \-m MAC_ROMAN/path/to/share\fR
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-convert UTF\-8 volume to HEX, for MacCyrillic clients:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-example%\fB uniconv \-f UTF8 \-t ASCII \-m MAC_CYRILLIC /path/to/share\fR
-.fi
-.if n \{\
-.RE
-.\}
-.SH "SEE ALSO"
-.PP
-\fBafp.conf\fR(5),\fBafpd\fR(8),\fBiconv\fR(1),\fBcnid_metad\fR(8),\fBcnid_dbd\fR(8)
index ba10eeb069f64c047345d71684667225ae54657d..999046039f04554512659561961af530f7e05c69 100644 (file)
@@ -1,4 +1,3 @@
 Makefile
 Makefile.in
 *.5
-*.o
index e9066c8bf8c851f080af69b4a24cc9b20d2ca34f..0453a03c3311f50aefdbbfdc339dd72d122f4fa8 100644 (file)
@@ -1,25 +1,9 @@
 # Makefile.am for man/man5/
 
-pkgconfdir = @PKGCONFDIR@
+man_MANS = \
+       afp.conf.5 \
+       afp_signature.conf.5 \
+       afp_voluuid.conf.5 \
+       extmap.conf.5
 
-SUFFIXES = .tmpl .
-
-.tmpl:
-       sed -e "s@:SBINDIR:@${sbindir}@g" \
-           -e "s@:BINDIR:@${bindir}@g" \
-           -e "s@:ETCDIR:@${pkgconfdir}@g" \
-           -e "s@:LIBDIR:@${libdir}@g" \
-           -e "s@:STATEDIR:@${localstatedir}@g" \
-           -e "s@:DEFAULT_CNID_SCHEME:@${DEFAULT_CNID_SCHEME}@g" \
-           -e "s@:COMPILED_BACKENDS:@${compiled_backends}@g" \
-           <$< >$@
-
-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)
-
-CLEANFILES = $(GENERATED_MANS)
-
-EXTRA_DIST = $(TEMPLATE_FILES) $(NONGENERATED_MANS)
+DISTCLEANFILES = $(man_MANS)
diff --git a/man/man5/afp.conf.5.in b/man/man5/afp.conf.5.in
new file mode 100644 (file)
index 0000000..a650d5f
--- /dev/null
@@ -0,0 +1,1182 @@
+'\" t
+.\"     Title: afp.conf
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 30 Apr 2013
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "AFP\&.CONF" "5" "30 Apr 2013" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+afp.conf \- Netatalk configuration file
+.SH "SYNOPSIS"
+.PP
+The
+afp\&.conf
+file is the configuration file for the
+\fBNetatalk\fR
+AFP file server\&.
+.PP
+All AFP specific configuration and AFP volume definitions are done via this file\&.
+.SH "FILE FORMAT"
+.PP
+The file consists of sections and parameters\&. A section begins with the name of the section in square brackets and continues until the next section begins\&. Sections contain parameters of the form:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+    \fIname\fR = \fIvalue \fR
+    
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+The file is line\-based \- that is, each newline\-terminated line represents either a comment, a section name or a parameter\&.
+.PP
+Section and parameter names are case sensitive\&.
+.PP
+Only the first equals sign in a parameter is significant\&. Whitespace before or after the first equals sign is discarded\&. Leading, trailing and internal whitespace in section and parameter names is irrelevant\&. Leading and trailing whitespace in a parameter value is discarded\&. Internal whitespace within a parameter value is retained verbatim\&.
+.PP
+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
+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\&.
+.PP
+The parameter
+\fBinclude = \fR\fB\fIpath\fR\fR
+allows you to include one config file inside another\&. The file is included literally, as though typed in place\&. Nested includes are not supported\&.
+.SH "SECTION DESCRIPTIONS"
+.PP
+Each section in the configuration file (except for the [Global] section) describes a shared resource (known as a
+\(lqvolume\(rq)\&. The section name is the name of the volume and the parameters within the section define the volume attributes and options\&.
+.PP
+There are two special sections, [Global] and [Homes], which are described under
+\fIspecial sections\fR\&. The following notes apply to ordinary section descriptions\&.
+.PP
+A volume consists of a directory to which access is being given plus a description of the access rights which are granted to the user of the service\&. For volumes the
+\fBpath\fR
+option must specify the directory to share\&.
+.PP
+Any volume section without
+\fBpath\fR
+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 specified both in a preset
+\fIand\fR
+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
+The following sample section defines an AFP volume\&. The user has full access to the path
+/foo/bar\&. The share is accessed via the share name
+baz:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ [baz]
+    path = /foo/bar 
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SPECIAL SECTIONS"
+.SS "The [Global] section"
+.PP
+Parameters in this section apply to the server as a whole\&. Parameters denoted by a (G) below are must be set in this section\&.
+.SS "The [Homes] section"
+.PP
+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 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\*(Aqs home\fR
+by default\&. See below under VARIABLE SUBSTITUTIONS\&.
+.PP
+The following example illustrates this\&. Given all user home directories are stored under
+/home:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ [Homes]
+      path = afp\-data
+      basedir regex = /home
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+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\&.
+.PP
+Some parameters are specific to the [Global] section (e\&.g\&.,
+\fIlog type\fR)\&. All others are permissible only in volume sections\&. The letter
+\fIG\fR
+in parentheses indicates that a parameter is specific to the [Global] section\&. The letter
+\fIV\fR
+indicates that a parameter can be specified in a volume specific section\&.
+.SH "VARIABLE SUBSTITUTIONS"
+.PP
+You can use variables in volume names\&. The use of variables in paths is not supported for now\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP "  1." 4.2
+.\}
+if you specify an unknown variable, it will not get converted\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP "  2." 4.2
+.\}
+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:
+.PP
+$b
+.RS 4
+basename
+.RE
+.PP
+$c
+.RS 4
+client\*(Aqs ip address
+.RE
+.PP
+$d
+.RS 4
+volume pathname on server
+.RE
+.PP
+$f
+.RS 4
+full name (contents of the gecos field in the passwd file)
+.RE
+.PP
+$g
+.RS 4
+group name
+.RE
+.PP
+$h
+.RS 4
+hostname
+.RE
+.PP
+$i
+.RS 4
+client\*(Aqs ip, without port
+.RE
+.PP
+$s
+.RS 4
+server name (this can be the hostname)
+.RE
+.PP
+$u
+.RS 4
+user name (if guest, it is the user that guest is running as)
+.RE
+.PP
+$v
+.RS 4
+volume name
+.RE
+.PP
+$$
+.RS 4
+prints dollar sign ($)
+.RE
+.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
+\fBadmin auth user\fR\&. If this succeeds, a normal session is created for the original connecting user\&. Said differently: if you know the password of
+\fBadmin auth user\fR, you can authenticate as any other user\&.
+.RE
+.PP
+k5 keytab = \fIpath\fR \fB(G)\fR, k5 service = \fIservice\fR \fB(G)\fR, k5 realm = \fIrealm\fR \fB(G)\fR
+.RS 4
+These are required if the server supports the Kerberos 5 authentication UAM\&.
+.RE
+.PP
+nt domain = \fIDOMAIN\fR \fB(G)\fR, nt separator = \fISEPARATOR\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 available and active UAM authentication modules\&.
+.RE
+.PP
+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
+set password = \fIBOOLEAN\fR (default: \fIno\fR) \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
+uam list = \fIuam list\fR \fB(G)\fR
+.RS 4
+Space or comma separated list of UAMs\&. (The default is "uams_dhx\&.so uams_dhx2\&.so")\&.
+.sp
+The most commonly used UAMs are:
+.PP
+uams_guest\&.so
+.RS 4
+allows guest logins
+.RE
+.PP
+uams_clrtxt\&.so
+.RS 4
+(uams_pam\&.so or uams_passwd\&.so) Allow logins with passwords transmitted in the clear\&. (legacy)
+.RE
+.PP
+uams_randum\&.so
+.RS 4
+allows Random Number and Two\-Way Random Number Exchange for authentication (requires a separate file containing the passwords, either @pkgconfdir@/afppasswd file or the one specified via "\fBpasswd file\fR"\&. See
+\fBafppasswd\fR(1)
+for details\&. (legacy)
+.RE
+.PP
+uams_dhx\&.so
+.RS 4
+(uams_dhx_pam\&.so or uams_dhx_passwd\&.so) Allow Diffie\-Hellman eXchange (DHX) for authentication\&.
+.RE
+.PP
+uams_dhx2\&.so
+.RS 4
+(uams_dhx2_pam\&.so or uams_dhx2_passwd\&.so) Allow Diffie\-Hellman eXchange 2 (DHX2) for authentication\&.
+.RE
+.PP
+uam_gss\&.so
+.RS 4
+Allow Kerberos V for authentication (optional)
+.RE
+.RE
+.PP
+uam path = \fIpath\fR \fB(G)\fR
+.RS 4
+Sets the default path for UAMs for this server (default is @libdir@/netatalk)\&.
+.RE
+.SS "Charset Options"
+.PP
+With OS X Apple introduced the AFP3 protocol\&. One of the big changes was, that AFP3 uses Unicode names encoded as Decomposed UTF\-8 (UTF8\-MAC)\&. Previous AFP/OS versions used charsets like MacRoman, MacCentralEurope, etc\&.
+.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\*(Aqs no way,
+\fBafpd\fR
+can detect the codepage a pre AFP3 client uses, you have to specify it using the
+\fBmac charset\fR
+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\*(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\*(Aqre using extended characters in the configuration files for
+\fBafpd\fR, make sure your terminal matches the
+\fBunix charset\fR\&.
+.PP
+mac charset = \fICHARSET\fR \fB(G)/(V)\fR
+.RS 4
+Specifies the Mac clients charset, e\&.g\&.
+\fIMAC_ROMAN\fR\&. This is used to convert strings and filenames to the clients codepage for OS9 and Classic, i\&.e\&. for authentication and AFP messages (SIGUSR2 messaging)\&. This will also be the default for the volumes
+\fBmac charset\fR\&. Defaults to
+\fIMAC_ROMAN\fR\&.
+.RE
+.PP
+unix charset = \fICHARSET\fR \fB(G)\fR
+.RS 4
+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 authentication, server messages and volume names\&. If
+\fILOCALE\fR
+is set, the systems locale is used\&. Defaults to
+\fIUTF8\fR\&.
+.RE
+.PP
+vol charset = \fICHARSET\fR \fB(G)/(V)\fR
+.RS 4
+Specifies the encoding of the volumes filesystem\&. By default, it is the same as
+\fBunix charset\fR\&.
+.RE
+.SS "Password Options"
+.PP
+passwd file = \fIpath\fR \fB(G)\fR
+.RS 4
+Sets the path to the Randnum UAM passwd file for this server (default is @pkgconfdir@/afppasswd)\&.
+.RE
+.PP
+passwd minlen = \fInumber\fR \fB(G)\fR
+.RS 4
+Sets the minimum password length, if supported by the UAM
+.RE
+.SS "Network Options"
+.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\*(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 \{\
+.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\*(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 address[: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
+afp port = \fIport number\fR \fB(G)\fR
+.RS 4
+Allows a different TCP port to be used for AFP\&. The default is 548\&. Also sets the default port applied when none specified in an
+\fBafp listen\fR
+option\&.
+.RE
+.PP
+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\&.
+.RE
+.PP
+disconnect time = \fInumber\fR \fB(G)\fR
+.RS 4
+Keep disconnected AFP sessions for
+\fInumber\fR
+hours before dropping them\&. Default is 24 hours\&.
+.RE
+.PP
+dsireadbuf = \fInumber\fR \fB(G)\fR
+.RS 4
+Scale factor that determines the size of the DSI/TCP readahead buffer, default is 12\&. This is multiplies with the DSI server quantum (default ~300k) to give the size of the buffer\&. Increasing this value might increase throughput in fast local networks for volume to volume copies\&.
+\fINote\fR: This buffer is allocated per afpd child process, so specifying large values will eat up large amount of memory (buffer size * number of clients)\&.
+.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\&.
+.RE
+.PP
+hostname = \fIname\fR \fB(G)\fR
+.RS 4
+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
+max connections = \fInumber\fR \fB(G)\fR
+.RS 4
+Sets the maximum number of clients that can simultaneously connect to the server (default is 200)\&.
+.RE
+.PP
+server quantum = \fInumber\fR \fB(G)\fR
+.RS 4
+This specifies the DSI server quantum\&. The default value is 1 MB\&. 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
+.RS 4
+Keep sleeping AFP sessions for
+\fInumber\fR
+hours before disconnecting clients in sleep mode\&. Default is 10 hours\&.
+.RE
+.PP
+tcprcvbuf = \fInumber\fR \fB(G)\fR
+.RS 4
+Try to set TCP receive buffer using setsockpt()\&. Often OSes impose restrictions on the applications ability to set this value\&.
+.RE
+.PP
+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
+use sendfile = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
+.RS 4
+Whether to use sendfile
+syscall for sending file data to clients\&.
+.RE
+.PP
+zeroconf = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
+.RS 4
+Whether to use automatic Zeroconf
+service registration if Avahi or mDNSResponder were compiled in\&.
+.RE
+.SS "Miscellaneous Options"
+.PP
+admin group = \fIgroup\fR \fB(G)\fR
+.RS 4
+Allows users of a certain group to be seen as the superuser when they log in\&. This option is disabled by default\&.
+.RE
+.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\*(Aqs not really in line with UNIX semantics and is a performance hug\&.
+.RE
+.PP
+afpstats = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
+.RS 4
+Whether to provide AFP runtime statistics (connected users, open volumes) via dbus\&.
+.RE
+.PP
+basedir regex = \fIregex\fR \fB(H)\fR
+.RS 4
+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\*(Aqre removed from the configuration and the configuration is reloaded\&.
+.RE
+.PP
+cnid server = \fIipaddress[:port]\fR \fB(G)/(V)\fR
+.RS 4
+Specifies the IP address and port of a cnid_metad server, required for CNID dbd backend\&. Defaults to localhost:4700\&. The network address may be specified either in dotted\-decimal format for IPv4 or in hexadecimal format for IPv6\&.\-
+.RE
+.PP
+dircachesize = \fInumber\fR \fB(G)\fR
+.RS 4
+Maximum possible entries in the directory cache\&. The cache stores directories and files\&. It is used to cache the full path to directories and CNIDs which considerably speeds up directory enumeration\&.
+.sp
+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
+extmap file = \fIpath\fR \fB(G)\fR
+.RS 4
+Sets the path to the file which defines file extension type/creator mappings\&. (default is @pkgconfdir@/extmap\&.conf)\&.
+.RE
+.PP
+guest account = \fIname\fR \fB(G)\fR
+.RS 4
+Specifies the user that guests should use (default is "nobody")\&. The name should be quoted\&.
+.RE
+.PP
+home name = \fIname\fR \fB(H)\fR
+.RS 4
+AFP user home volume name\&. The default is
+\fIuser\*(Aqs home\fR\&.
+.RE
+.PP
+login message = \fImessage\fR \fB(G)/(V)\fR
+.RS 4
+Sets a message to be displayed when clients logon to the server\&. The message should be in
+\fBunix charset\fR
+and should be quoted\&. Extended characters are allowed\&.
+.RE
+.PP
+mimic model = \fImodel\fR \fB(G)\fR
+.RS 4
+Specifies the icon model that appears on clients\&. Defaults to off\&. Note that afpd must support Zeroconf\&. Examples: RackMac (same as Xserve), PowerBook, PowerMac, Macmini, iMac, MacBook, MacBookPro, MacBookAir, MacPro, AppleTV1,1, AirPort\&.
+.RE
+.PP
+signature = <text> \fB(G)\fR
+.RS 4
+Specify a server signature\&. The maximum length is 16 characters\&. This option is useful for clustered environments, to provide fault isolation etc\&. By default, afpd generate signature and saving it to
+@localstatedir@/netatalk/afp_signature\&.conf
+automatically (based on random number)\&. See also asip\-status\&.pl(1)\&.
+.RE
+.PP
+solaris share reservations = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
+.RS 4
+Use share reservations on Solaris\&. Solaris CIFS server uses this too, so this makes a lock coherent multi protocol server\&.
+.RE
+.PP
+vol dbpath = \fIpath\fR \fB(G)\fR
+.RS 4
+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
+@localstatedir@/netatalk/CNID/\&.
+.RE
+.PP
+volnamelen = \fInumber\fR \fB(G)\fR
+.RS 4
+Max length of UTF8\-MAC volume name for Mac OS X\&. Note that Hangul is especially sensitive to this\&.
+.sp
+.if n \{\
+.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
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+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\*(Aqs section)\&.
+.RE
+.SS "Logging Options"
+.PP
+log file = \fIlogfile\fR \fB(G)\fR
+.RS 4
+If not specified Netatalk logs to syslogs daemon facility\&. Otherwise it logs to
+\fBlogfile\fR\&.
+.RE
+.PP
+log level = \fItype:level [type:level \&.\&.\&.]\fR \fB(G)\fR, log level = \fItype:level,[type:level, \&.\&.\&.]\fR \fB(G)\fR
+.RS 4
+Specify that any message of a loglevel up to the given
+\fBlog level\fR
+should be logged\&.
+.sp
+By default afpd logs to syslog with a default logging setup equivalent to
+\fBdefault:note\fR
+.sp
+logtypes: default, afpdaemon, logger, uamsdaemon
+.sp
+loglevels: severe, error, warn, note, info, debug, debug6, debug7, debug8, debug9, maxdebug
+.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
+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\&.
+.PP
+tickleval = \fInumber\fR \fB(G)\fR
+.RS 4
+Sets the tickle timeout interval (in seconds)\&. Defaults to 30\&.
+.RE
+.PP
+timeout = \fInumber\fR \fB(G)\fR
+.RS 4
+Specify the number of tickles to send before timing out a connection\&. The default is 4, therefore a connection will timeout after 2 minutes\&.
+.RE
+.PP
+client polling = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
+.RS 4
+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
+By default, the effective permission of the authenticated user are only mapped to the mentioned UARights permission structure, not the UNIX mode\&. You can adjust this behaviour with the configuration option
+\fBmac acls\fR:
+.PP
+map acls = \fInone|rights|mode\fR \fB(G)\fR
+.RS 4
+.PP
+none
+.RS 4
+no mapping of ACLs
+.RE
+.PP
+rights
+.RS 4
+effective permissions are mapped to UARights structure\&. This is the default\&.
+.RE
+.PP
+mode
+.RS 4
+ACLs are additionally mapped to the UNIX mode of the filesystem object\&.
+.RE
+.RE
+.PP
+If you want to be able to display ACLs on the client, you must setup both client and server as part on a authentication domain (directory service, eg LDAP, Open Directory, Active Directory)\&. The reason is, in OS X ACLs are bound to UUIDs, not just uid\*(Aqs or gid\*(Aqs\&. Therefor Netatalk 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\&.
+.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\&. 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
+.RS 4
+The path name must be a fully qualified path name\&.
+.RE
+.PP
+appledouble = \fIea|v2\fR \fB(V)\fR
+.RS 4
+Specify the format of the metadata files, which are used for saving Mac resource fork as well\&. Earlier versions used AppleDouble v2, the new default format is
+\fBea\fR\&.
+.RE
+.PP
+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 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 = \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\&. 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
+.RS 4
+The deny option specifies users and groups who are not allowed access to the share\&. It follows the same format as the "valid users" option\&.
+.RE
+.PP
+hosts allow = \fIIP host address/IP netmask bits [ \&.\&.\&. ]\fR \fB(V)\fR
+.RS 4
+Only listed hosts and networks are allowed, all others are rejected\&. The network address may be specified either in dotted\-decimal format for IPv4 or in hexadecimal format for IPv6\&.
+.sp
+Example: hosts allow = 10\&.1\&.0\&.0/16 10\&.2\&.1\&.100 2001:0db8:1234::/48
+.RE
+.PP
+hosts deny = \fIIP host address/IP netmask bits [ \&.\&.\&. ]\fR \fB(V)\fR
+.RS 4
+Listed hosts and nets are rejected, all others are allowed\&.
+.sp
+Example: hosts deny = 192\&.168\&.100/24 10\&.1\&.1\&.1 2001:db8::1428:57ab
+.RE
+.PP
+cnid scheme = \fIbackend\fR \fB(V)\fR
+.RS 4
+set the CNID backend to be used for the volume, default is [@DEFAULT_CNID_SCHEME@] available schemes: [@compiled_backends@]
+.RE
+.PP
+ea = \fInone|auto|sys|ad\fR \fB(V)\fR
+.RS 4
+Specify how Extended Attributes
+are stored\&.
+\fBauto\fR
+is the default\&.
+.PP
+auto
+.RS 4
+Try
+\fBsys\fR
+(by setting an EA on the shared directory itself), fallback to
+\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 appropriate\&.
+.RE
+.PP
+sys
+.RS 4
+Use filesystem Extended Attributes\&.
+.RE
+.PP
+ad
+.RS 4
+Use files in
+\fI\&.AppleDouble\fR
+directories\&.
+.RE
+.PP
+none
+.RS 4
+No Extended Attributes support\&.
+.RE
+.RE
+.PP
+mac charset = \fICHARSET\fR \fB(V)\fR
+.RS 4
+specifies the Mac client charset for this Volume, e\&.g\&.
+\fIMAC_ROMAN\fR,
+\fIMAC_CYRILLIC\fR\&. If not specified the global setting is applied\&. This setting is only required if you need volumes, where the Mac charset differs from the one globally set in the [Global] section\&.
+.RE
+.PP
+casefold = \fBoption\fR \fB(V)\fR
+.RS 4
+The casefold option handles, if the case of filenames should be changed\&. The available options are:
+.sp
+\fBtolower\fR
+\- Lowercases names in both directions\&.
+.sp
+\fBtoupper\fR
+\- Uppercases names in both directions\&.
+.sp
+\fBxlatelower\fR
+\- Client sees lowercase, server sees uppercase\&.
+.sp
+\fBxlateupper\fR
+\- Client sees uppercase, server sees lowercase\&.
+.RE
+.PP
+password = \fIpassword\fR \fB(V)\fR
+.RS 4
+This option allows you to set a volume password, which can be a maximum of 8 characters long (using ASCII strongly recommended at the time of this writing)\&.
+.RE
+.PP
+file perm = \fImode\fR \fB(V)\fR, directory perm = \fImode\fR \fB(V)\fR
+.RS 4
+Add(or) with the client requested permissions:
+\fBfile perm\fR
+is for files only,
+\fBdirectory perm\fR
+is for directories only\&. Don\*(Aqt use with "\fBunix priv = no\fR"\&.
+.PP
+\fBExample.\ \&Volume for a collaborative workgroup\fR
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+file perm = 0660 directory perm =
+              0770
+.fi
+.if n \{\
+.RE
+.\}
+
+.RE
+.PP
+umask = \fImode\fR \fB(V)\fR
+.RS 4
+set perm mask\&. Don\*(Aqt use with "\fBunix priv = no\fR"\&.
+.RE
+.PP
+preexec = \fIcommand\fR \fB(V)\fR
+.RS 4
+command to be run when the volume is mounted, ignored for user defined volumes
+.RE
+.PP
+postexec = \fIcommand\fR \fB(V)\fR
+.RS 4
+command to be run when the volume is closed, ignored for user defined volumes
+.RE
+.PP
+root preexec = \fIcommand\fR \fB(V)\fR
+.RS 4
+command to be run as root when the volume is mounted, ignored for user defined volumes
+.RE
+.PP
+root postexec = \fIcommand\fR \fB(V)\fR
+.RS 4
+command to be run as root when the volume is closed, ignored for user defined volumes
+.RE
+.PP
+rolist = \fBusers/groups\fR \fB(V)\fR
+.RS 4
+Allows certain users and groups to have read\-only access to a share\&. This follows the allow option format\&.
+.RE
+.PP
+rwlist = \fIusers/groups\fR \fB(V)\fR
+.RS 4
+Allows certain users and groups to have read/write access to a share\&. This follows the allow option format\&.
+.RE
+.PP
+veto files = \fIvetoed names\fR \fB(V)\fR
+.RS 4
+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
+Boolean volume options\&.
+.PP
+acls = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
+.RS 4
+Whether to flag volumes as supporting ACLs\&. If ACL support is compiled in, this is yes by default\&.
+.RE
+.PP
+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
+convert appledouble = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
+.RS 4
+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\*(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\&. WARNING: enabling this option will lead to unwanted sideeffects were OS X applications when saving files to a temporary file starting with a dot first, then renaming the temp file to its final name, result in the saved file being invisible\&. The only thing this option is useful for is making files that start with a dot invisible on Mac OS 9\&. It\*(Aqs completely useless on Mac OS X, as both in Finder and in Terminal files starting with a dot are hidden anyway\&.
+.RE
+.PP
+network ids = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
+.RS 4
+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 = \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\&.
+.RE
+.PP
+read only = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
+.RS 4
+Specifies the share as being read only for all users\&. Overwrites
+\fBea = auto\fR
+with
+\fBea = none\fR
+.RE
+.PP
+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\&.
+.RE
+.PP
+search db = \fIBOOLEAN\fR (default: \fIno\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\&.
+.RE
+.PP
+stat vol = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
+.RS 4
+Whether to stat volume path when enumerating volumes list, useful for automounting or volumes created by a preexec script\&.
+.RE
+.PP
+time machine = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
+.RS 4
+Whether to enable Time Machine support for this volume\&.
+.RE
+.PP
+unix priv = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
+.RS 4
+Whether to use AFP3 UNIX privileges\&. This should be set for OS X clients\&. See also:
+\fBfile perm\fR,
+\fBdirectory perm\fR
+and
+\fBumask\fR\&.
+.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\*(Aqs in a persistent way, to achieve this several different CNID backends are available\&. The CNID Databases are by default located in the
+@localstatedir@/netatalk/CNID/(volumename)/\&.AppleDB/
+directory\&.
+.PP
+cdb
+.RS 4
+"Concurrent database", backend is based on Oracle Berkley DB\&. With this backend several
+\fBafpd\fR
+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
+process might corrupt the database\&.
+.RE
+.PP
+dbd
+.RS 4
+Access to the CNID database is restricted to the
+\fBcnid_metad\fR
+daemon process\&.
+\fBafpd\fR
+processes communicate with the daemon for database reads and updates\&. If built with Berkeley DB transactions the probability for database corruption is practically zero, but performance can be slower than with
+\fBcdb\fR
+.RE
+.PP
+last
+.RS 4
+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
+automatically\&.
+.sp
+\fBWarning\fR: It is
+\fINOT\fR
+recommended to use this backend for volumes anymore, as
+\fBafpd\fR
+now relies heavily on a persistent ID database\&. Aliases will likely not work and filename mangling is not supported\&.
+.RE
+.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\*(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\&. \*(Aq/\*(Aq will be encoded to
+:2f, if
+\fBusedots\fR
+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\&. \*(Aq/\*(Aq will be converted to \*(Aq:\*(Aq\&.
+.PP
+The
+\fBvol charset\fR
+option will allow you to select another volume encoding\&. E\&.g\&. for western users another useful setting could be vol charset ISO\-8859\-15\&.
+\fBafpd\fR
+will accept any
+\fBiconv\fR(1)
+provided charset\&. If a character cannot be converted from the
+\fBmac charset\fR
+to the selected
+\fBvol charset\fR, afpd will save it as a CAP encoded character\&. For AFP3 clients,
+\fBafpd\fR
+will convert the UTF\-8
+character to
+\fBmac charset\fR
+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"
+.PP
+\fBafpd\fR(8),
+\fBafppasswd\fR(5),
+\fBafp_signature.conf\fR(5),
+\fBextmap.conf\fR(5),
+\fBcnid_metad\fR(8)
diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl
deleted file mode 100644 (file)
index 60ec8d0..0000000
+++ /dev/null
@@ -1,1171 +0,0 @@
-'\" t
-.\"     Title: afp.conf
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 19 Feb 2013
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.TH "AFP\&.CONF" "5" "19 Feb 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"
-afp.conf \- Netatalk configuration file
-.SH "SYNOPSIS"
-.PP
-The
-afp\&.conf
-file is the configuration file for the
-\fBNetatalk\fR
-AFP file server\&.
-.PP
-All AFP specific configuration and AFP volume definitions are done via this file\&.
-.SH "FILE FORMAT"
-.PP
-The file consists of sections and parameters\&. A section begins with the name of the section in square brackets and continues until the next section begins\&. Sections contain parameters of the form:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-    \fIname\fR = \fIvalue \fR
-    
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-The file is line\-based \- that is, each newline\-terminated line represents either a comment, a section name or a parameter\&.
-.PP
-Section and parameter names are case sensitive\&.
-.PP
-Only the first equals sign in a parameter is significant\&. Whitespace before or after the first equals sign is discarded\&. Leading, trailing and internal whitespace in section and parameter names is irrelevant\&. Leading and trailing whitespace in a parameter value is discarded\&. Internal whitespace within a parameter value is retained verbatim\&.
-.PP
-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
-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\&.
-.PP
-The parameter
-\fBinclude = \fR\fB\fIpath\fR\fR
-allows you to include one config file inside another\&. The file is included literally, as though typed in place\&. Nested includes are not supported\&.
-.SH "SECTION DESCRIPTIONS"
-.PP
-Each section in the configuration file (except for the [Global] section) describes a shared resource (known as a
-\(lqvolume\(rq)\&. The section name is the name of the volume and the parameters within the section define the volume attributes and options\&.
-.PP
-There are two special sections, [Global] and [Homes], which are described under
-\fIspecial sections\fR\&. The following notes apply to ordinary section descriptions\&.
-.PP
-A volume consists of a directory to which access is being given plus a description of the access rights which are granted to the user of the service\&. For volumes the
-\fBpath\fR
-option must specify the directory to share\&.
-.PP
-Any volume section without
-\fBpath\fR
-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 specified both in a preset
-\fIand\fR
-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
-The following sample section defines an AFP volume\&. The user has full access to the path
-/foo/bar\&. The share is accessed via the share name
-baz:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
- [baz]
-    path = /foo/bar 
-.fi
-.if n \{\
-.RE
-.\}
-.SH "SPECIAL SECTIONS"
-.SS "The [Global] section"
-.PP
-Parameters in this section apply to the server as a whole\&. Parameters denoted by a (G) below are must be set in this section\&.
-.SS "The [Homes] section"
-.PP
-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 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\*(Aqs home\fR
-by default\&. See below under VARIABLE SUBSTITUTIONS\&.
-.PP
-The following example illustrates this\&. Given all user home directories are stored under
-/home:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
- [Homes]
-      path = afp\-data
-      basedir regex = /home
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-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\&.
-.PP
-Some parameters are specific to the [Global] section (e\&.g\&.,
-\fIlog type\fR)\&. All others are permissible only in volume sections\&. The letter
-\fIG\fR
-in parentheses indicates that a parameter is specific to the [Global] section\&. The letter
-\fIV\fR
-indicates that a parameter can be specified in a volume specific section\&.
-.SH "VARIABLE SUBSTITUTIONS"
-.PP
-You can use variables in volume names\&. The use of variables in paths is not supported for now\&.
-.sp
-.RS 4
-.ie n \{\
-\h'-04' 1.\h'+01'\c
-.\}
-.el \{\
-.sp -1
-.IP "  1." 4.2
-.\}
-if you specify an unknown variable, it will not get converted\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04' 2.\h'+01'\c
-.\}
-.el \{\
-.sp -1
-.IP "  2." 4.2
-.\}
-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:
-.PP
-$b
-.RS 4
-basename
-.RE
-.PP
-$c
-.RS 4
-client\*(Aqs ip address
-.RE
-.PP
-$d
-.RS 4
-volume pathname on server
-.RE
-.PP
-$f
-.RS 4
-full name (contents of the gecos field in the passwd file)
-.RE
-.PP
-$g
-.RS 4
-group name
-.RE
-.PP
-$h
-.RS 4
-hostname
-.RE
-.PP
-$i
-.RS 4
-client\*(Aqs ip, without port
-.RE
-.PP
-$s
-.RS 4
-server name (this can be the hostname)
-.RE
-.PP
-$u
-.RS 4
-user name (if guest, it is the user that guest is running as)
-.RE
-.PP
-$v
-.RS 4
-volume name
-.RE
-.PP
-$$
-.RS 4
-prints dollar sign ($)
-.RE
-.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
-\fBadmin auth user\fR\&. If this succeeds, a normal session is created for the original connecting user\&. Said differently: if you know the password of
-\fBadmin auth user\fR, you can authenticate as any other user\&.
-.RE
-.PP
-k5 keytab = \fIpath\fR \fB(G)\fR, k5 service = \fIservice\fR \fB(G)\fR, k5 realm = \fIrealm\fR \fB(G)\fR
-.RS 4
-These are required if the server supports the Kerberos 5 authentication UAM\&.
-.RE
-.PP
-nt domain = \fIDOMAIN\fR \fB(G)\fR, nt separator = \fISEPARATOR\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 available and active UAM authentication modules\&.
-.RE
-.PP
-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
-set password = \fIBOOLEAN\fR (default: \fIno\fR) \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
-uam list = \fIuam list\fR \fB(G)\fR
-.RS 4
-Space or comma separated list of UAMs\&. (The default is "uams_dhx\&.so uams_dhx2\&.so")\&.
-.sp
-The most commonly used UAMs are:
-.PP
-uams_guest\&.so
-.RS 4
-allows guest logins
-.RE
-.PP
-uams_clrtxt\&.so
-.RS 4
-(uams_pam\&.so or uams_passwd\&.so) Allow logins with passwords transmitted in the clear\&. (legacy)
-.RE
-.PP
-uams_randum\&.so
-.RS 4
-allows Random Number and Two\-Way Random Number Exchange for authentication (requires a separate file containing the passwords, either :ETCDIR:/afppasswd file or the one specified via "\fBpasswd file\fR"\&. See
-\fBafppasswd\fR(1)
-for details\&. (legacy)
-.RE
-.PP
-uams_dhx\&.so
-.RS 4
-(uams_dhx_pam\&.so or uams_dhx_passwd\&.so) Allow Diffie\-Hellman eXchange (DHX) for authentication\&.
-.RE
-.PP
-uams_dhx2\&.so
-.RS 4
-(uams_dhx2_pam\&.so or uams_dhx2_passwd\&.so) Allow Diffie\-Hellman eXchange 2 (DHX2) for authentication\&.
-.RE
-.PP
-uam_gss\&.so
-.RS 4
-Allow Kerberos V for authentication (optional)
-.RE
-.RE
-.PP
-uam path = \fIpath\fR \fB(G)\fR
-.RS 4
-Sets the default path for UAMs for this server (default is :LIBDIR:/netatalk)\&.
-.RE
-.SS "Charset Options"
-.PP
-With OS X Apple introduced the AFP3 protocol\&. One of the big changes was, that AFP3 uses Unicode names encoded as Decomposed UTF\-8 (UTF8\-MAC)\&. Previous AFP/OS versions used charsets like MacRoman, MacCentralEurope, etc\&.
-.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\*(Aqs no way,
-\fBafpd\fR
-can detect the codepage a pre AFP3 client uses, you have to specify it using the
-\fBmac charset\fR
-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\*(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\*(Aqre using extended characters in the configuration files for
-\fBafpd\fR, make sure your terminal matches the
-\fBunix charset\fR\&.
-.PP
-mac charset = \fICHARSET\fR \fB(G)/(V)\fR
-.RS 4
-Specifies the Mac clients charset, e\&.g\&.
-\fIMAC_ROMAN\fR\&. This is used to convert strings and filenames to the clients codepage for OS9 and Classic, i\&.e\&. for authentication and AFP messages (SIGUSR2 messaging)\&. This will also be the default for the volumes
-\fBmac charset\fR\&. Defaults to
-\fIMAC_ROMAN\fR\&.
-.RE
-.PP
-unix charset = \fICHARSET\fR \fB(G)\fR
-.RS 4
-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 authentication, server messages and volume names\&. If
-\fILOCALE\fR
-is set, the systems locale is used\&. Defaults to
-\fIUTF8\fR\&.
-.RE
-.PP
-vol charset = \fICHARSET\fR \fB(G)/(V)\fR
-.RS 4
-Specifies the encoding of the volumes filesystem\&. By default, it is the same as
-\fBunix charset\fR\&.
-.RE
-.SS "Password Options"
-.PP
-passwd file = \fIpath\fR \fB(G)\fR
-.RS 4
-Sets the path to the Randnum UAM passwd file for this server (default is :ETCDIR:/afppasswd)\&.
-.RE
-.PP
-passwd minlen = \fInumber\fR \fB(G)\fR
-.RS 4
-Sets the minimum password length, if supported by the UAM
-.RE
-.SS "Network Options"
-.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\*(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 \{\
-.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\*(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 address[: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
-afp port = \fIport number\fR \fB(G)\fR
-.RS 4
-Allows a different TCP port to be used for AFP\&. The default is 548\&. Also sets the default port applied when none specified in an
-\fBafp listen\fR
-option\&.
-.RE
-.PP
-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\&.
-.RE
-.PP
-disconnect time = \fInumber\fR \fB(G)\fR
-.RS 4
-Keep disconnected AFP sessions for
-\fInumber\fR
-hours before dropping them\&. Default is 24 hours\&.
-.RE
-.PP
-dsireadbuf = \fInumber\fR \fB(G)\fR
-.RS 4
-Scale factor that determines the size of the DSI/TCP readahead buffer, default is 12\&. This is multiplies with the DSI server quantum (default ~300k) to give the size of the buffer\&. Increasing this value might increase throughput in fast local networks for volume to volume copies\&.
-\fINote\fR: This buffer is allocated per afpd child process, so specifying large values will eat up large amount of memory (buffer size * number of clients)\&.
-.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\&.
-.RE
-.PP
-hostname = \fIname\fR \fB(G)\fR
-.RS 4
-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
-max connections = \fInumber\fR \fB(G)\fR
-.RS 4
-Sets the maximum number of clients that can simultaneously connect to the server (default is 200)\&.
-.RE
-.PP
-server quantum = \fInumber\fR \fB(G)\fR
-.RS 4
-This specifies the DSI server quantum\&. The default value is 1 MB\&. 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
-.RS 4
-Keep sleeping AFP sessions for
-\fInumber\fR
-hours before disconnecting clients in sleep mode\&. Default is 10 hours\&.
-.RE
-.PP
-tcprcvbuf = \fInumber\fR \fB(G)\fR
-.RS 4
-Try to set TCP receive buffer using setsockpt()\&. Often OSes impose restrictions on the applications ability to set this value\&.
-.RE
-.PP
-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
-use sendfile = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
-.RS 4
-Whether to use sendfile
-syscall for sending file data to clients\&.
-.RE
-.PP
-zeroconf = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
-.RS 4
-Whether to use automatic Zeroconf
-service registration if Avahi or mDNSResponder were compiled in\&.
-.RE
-.SS "Miscellaneous Options"
-.PP
-admin group = \fIgroup\fR \fB(G)\fR
-.RS 4
-Allows users of a certain group to be seen as the superuser when they log in\&. This option is disabled by default\&.
-.RE
-.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\*(Aqs not really in line with UNIX semantics and is a performance hug\&.
-.RE
-.PP
-afpstats = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
-.RS 4
-Whether to provide AFP runtime statistics (connected users, open volumes) via dbus\&.
-.RE
-.PP
-basedir regex = \fIregex\fR \fB(H)\fR
-.RS 4
-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\*(Aqre removed from the configuration and the configuration is reloaded\&.
-.RE
-.PP
-cnid server = \fIipaddress[:port]\fR \fB(G)/(V)\fR
-.RS 4
-Specifies the IP address and port of a cnid_metad server, required for CNID dbd backend\&. Defaults to localhost:4700\&. The network address may be specified either in dotted\-decimal format for IPv4 or in hexadecimal format for IPv6\&.\-
-.RE
-.PP
-dircachesize = \fInumber\fR \fB(G)\fR
-.RS 4
-Maximum possible entries in the directory cache\&. The cache stores directories and files\&. It is used to cache the full path to directories and CNIDs which considerably speeds up directory enumeration\&.
-.sp
-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
-extmap file = \fIpath\fR \fB(G)\fR
-.RS 4
-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
-.RS 4
-Specifies the user that guests should use (default is "nobody")\&. The name should be quoted\&.
-.RE
-.PP
-home name = \fIname\fR \fB(H)\fR
-.RS 4
-AFP user home volume name\&. The default is
-\fIuser\*(Aqs home\fR\&.
-.RE
-.PP
-login message = \fImessage\fR \fB(G)/(V)\fR
-.RS 4
-Sets a message to be displayed when clients logon to the server\&. The message should be in
-\fBunix charset\fR
-and should be quoted\&. Extended characters are allowed\&.
-.RE
-.PP
-map acls = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
-.RS 4
-Whether to map filesystem ACLs to effective permissions\&.
-.RE
-.PP
-mimic model = \fImodel\fR \fB(G)\fR
-.RS 4
-Specifies the icon model that appears on clients\&. Defaults to off\&. Examples: RackMac (same as Xserve), PowerBook, PowerMac, Macmini, iMac, MacBook, MacBookPro, MacBookAir, MacPro, AppleTV1,1, AirPort\&.
-.RE
-.PP
-signature = <text> \fB(G)\fR
-.RS 4
-Specify a server signature\&. The maximum length is 16 characters\&. This option is useful for clustered environments, to provide fault isolation etc\&. By default, afpd generate signature and saving it to
-:STATEDIR:/netatalk/afp_signature\&.conf
-automatically (based on random number)\&. See also asip\-status\&.pl(1)\&.
-.RE
-.PP
-solaris share reservations = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR
-.RS 4
-Use share reservations on Solaris\&. Solaris CIFS server uses this too, so this makes a lock coherent multi protocol server\&.
-.RE
-.PP
-vol dbpath = \fIpath\fR \fB(G)\fR
-.RS 4
-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
-volnamelen = \fInumber\fR \fB(G)\fR
-.RS 4
-Max length of UTF8\-MAC volume name for Mac OS X\&. Note that Hangul is especially sensitive to this\&.
-.sp
-.if n \{\
-.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
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-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\*(Aqs section)\&.
-.RE
-.SS "Logging Options"
-.PP
-log file = \fIlogfile\fR \fB(G)\fR
-.RS 4
-If not specified Netatalk logs to syslogs daemon facility\&. Otherwise it logs to
-\fBlogfile\fR\&.
-.RE
-.PP
-log level = \fItype:level [type:level \&.\&.\&.]\fR \fB(G)\fR, log level = \fItype:level,[type:level, \&.\&.\&.]\fR \fB(G)\fR
-.RS 4
-Specify that any message of a loglevel up to the given
-\fBlog level\fR
-should be logged\&.
-.sp
-By default afpd logs to syslog with a default logging setup equivalent to
-\fBdefault:note\fR
-.sp
-logtypes: default, afpdaemon, logger, uamsdaemon
-.sp
-loglevels: severe, error, warn, note, info, debug, debug6, debug7, debug8, debug9, maxdebug
-.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
-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\&.
-.PP
-tickleval = \fInumber\fR \fB(G)\fR
-.RS 4
-Sets the tickle timeout interval (in seconds)\&. Defaults to 30\&.
-.RE
-.PP
-timeout = \fInumber\fR \fB(G)\fR
-.RS 4
-Specify the number of tickles to send before timing out a connection\&. The default is 4, therefore a connection will timeout after 2 minutes\&.
-.RE
-.PP
-client polling = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
-.RS 4
-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
-.RS 4
-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
-appledouble = \fIea|v2\fR \fB(V)\fR
-.RS 4
-Specify the format of the metadata files, which are used for saving Mac resource fork as well\&. Earlier versions used AppleDouble v2, the new default format is
-\fBea\fR\&.
-.RE
-.PP
-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 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 = \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\&. 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
-.RS 4
-The deny option specifies users and groups who are not allowed access to the share\&. It follows the same format as the "valid users" option\&.
-.RE
-.PP
-hosts allow = \fIIP host address/IP netmask bits [ \&.\&.\&. ]\fR \fB(V)\fR
-.RS 4
-Only listed hosts and networks are allowed, all others are rejected\&. The network address may be specified either in dotted\-decimal format for IPv4 or in hexadecimal format for IPv6\&.
-.sp
-Example: hosts allow = 10\&.1\&.0\&.0/16 10\&.2\&.1\&.100 2001:0db8:1234::/48
-.RE
-.PP
-hosts deny = \fIIP host address/IP netmask bits [ \&.\&.\&. ]\fR \fB(V)\fR
-.RS 4
-Listed hosts and nets are rejected, all others are allowed\&.
-.sp
-Example: hosts deny = 192\&.168\&.100/24 10\&.1\&.1\&.1 2001:db8::1428:57ab
-.RE
-.PP
-cnid scheme = \fIbackend\fR \fB(V)\fR
-.RS 4
-set the CNID backend to be used for the volume, default is [:DEFAULT_CNID_SCHEME:] available schemes: [:COMPILED_BACKENDS:]
-.RE
-.PP
-ea = \fInone|auto|sys|ad\fR \fB(V)\fR
-.RS 4
-Specify how Extended Attributes
-are stored\&.
-\fBauto\fR
-is the default\&.
-.PP
-auto
-.RS 4
-Try
-\fBsys\fR
-(by setting an EA on the shared directory itself), fallback to
-\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 appropriate\&.
-.RE
-.PP
-sys
-.RS 4
-Use filesystem Extended Attributes\&.
-.RE
-.PP
-ad
-.RS 4
-Use files in
-\fI\&.AppleDouble\fR
-directories\&.
-.RE
-.PP
-none
-.RS 4
-No Extended Attributes support\&.
-.RE
-.RE
-.PP
-mac charset = \fICHARSET\fR \fB(V)\fR
-.RS 4
-specifies the Mac client charset for this Volume, e\&.g\&.
-\fIMAC_ROMAN\fR,
-\fIMAC_CYRILLIC\fR\&. If not specified the global setting is applied\&. This setting is only required if you need volumes, where the Mac charset differs from the one globally set in the [Global] section\&.
-.RE
-.PP
-casefold = \fBoption\fR \fB(V)\fR
-.RS 4
-The casefold option handles, if the case of filenames should be changed\&. The available options are:
-.sp
-\fBtolower\fR
-\- Lowercases names in both directions\&.
-.sp
-\fBtoupper\fR
-\- Uppercases names in both directions\&.
-.sp
-\fBxlatelower\fR
-\- Client sees lowercase, server sees uppercase\&.
-.sp
-\fBxlateupper\fR
-\- Client sees uppercase, server sees lowercase\&.
-.RE
-.PP
-password = \fIpassword\fR \fB(V)\fR
-.RS 4
-This option allows you to set a volume password, which can be a maximum of 8 characters long (using ASCII strongly recommended at the time of this writing)\&.
-.RE
-.PP
-file perm = \fImode\fR \fB(V)\fR, directory perm = \fImode\fR \fB(V)\fR
-.RS 4
-Add(or) with the client requested permissions:
-\fBfile perm\fR
-is for files only,
-\fBdirectory perm\fR
-is for directories only\&. Don\*(Aqt use with "\fBunix priv = no\fR"\&.
-.PP
-\fBExample.\ \&Volume for a collaborative workgroup\fR
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-file perm = 0660 directory perm =
-              0770
-.fi
-.if n \{\
-.RE
-.\}
-
-.RE
-.PP
-umask = \fImode\fR \fB(V)\fR
-.RS 4
-set perm mask\&. Don\*(Aqt use with "\fBunix priv = no\fR"\&.
-.RE
-.PP
-preexec = \fIcommand\fR \fB(V)\fR
-.RS 4
-command to be run when the volume is mounted, ignored for user defined volumes
-.RE
-.PP
-postexec = \fIcommand\fR \fB(V)\fR
-.RS 4
-command to be run when the volume is closed, ignored for user defined volumes
-.RE
-.PP
-root preexec = \fIcommand\fR \fB(V)\fR
-.RS 4
-command to be run as root when the volume is mounted, ignored for user defined volumes
-.RE
-.PP
-root postexec = \fIcommand\fR \fB(V)\fR
-.RS 4
-command to be run as root when the volume is closed, ignored for user defined volumes
-.RE
-.PP
-rolist = \fBusers/groups\fR \fB(V)\fR
-.RS 4
-Allows certain users and groups to have read\-only access to a share\&. This follows the allow option format\&.
-.RE
-.PP
-rwlist = \fIusers/groups\fR \fB(V)\fR
-.RS 4
-Allows certain users and groups to have read/write access to a share\&. This follows the allow option format\&.
-.RE
-.PP
-veto files = \fIvetoed names\fR \fB(V)\fR
-.RS 4
-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
-Boolean volume options\&.
-.PP
-acls = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
-.RS 4
-Whether to flag volumes as supporting ACLs\&. If ACL support is compiled in, this is yes by default\&.
-.RE
-.PP
-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
-convert appledouble = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
-.RS 4
-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\*(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\&. WARNING: enabling this option will lead to unwanted sideeffects were OS X applications when saving files to a temporary file starting with a dot first, then renaming the temp file to its final name, result in the saved file being invisible\&. The only thing this option is useful for is making files that start with a dot invisible on Mac OS 9\&. It\*(Aqs completely useless on Mac OS X, as both in Finder and in Terminal files starting with a dot are hidden anyway\&.
-.RE
-.PP
-network ids = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
-.RS 4
-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 = \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\&.
-.RE
-.PP
-read only = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
-.RS 4
-Specifies the share as being read only for all users\&. Overwrites
-\fBea = auto\fR
-with
-\fBea = none\fR
-.RE
-.PP
-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\&.
-.RE
-.PP
-search db = \fIBOOLEAN\fR (default: \fIno\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\&.
-.RE
-.PP
-stat vol = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
-.RS 4
-Whether to stat volume path when enumerating volumes list, useful for automounting or volumes created by a preexec script\&.
-.RE
-.PP
-time machine = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR
-.RS 4
-Whether to enable Time Machine support for this volume\&.
-.RE
-.PP
-unix priv = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR
-.RS 4
-Whether to use AFP3 UNIX privileges\&. This should be set for OS X clients\&. See also:
-\fBfile perm\fR,
-\fBdirectory perm\fR
-and
-\fBumask\fR\&.
-.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\*(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 Berkley DB\&. With this backend several
-\fBafpd\fR
-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
-process might corrupt the database\&.
-.RE
-.PP
-dbd
-.RS 4
-Access to the CNID database is restricted to the
-\fBcnid_metad\fR
-daemon process\&.
-\fBafpd\fR
-processes communicate with the daemon for database reads and updates\&. If built with Berkeley DB transactions the probability for database corruption is practically zero, but performance can be slower than with
-\fBcdb\fR
-.RE
-.PP
-last
-.RS 4
-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
-automatically\&.
-.sp
-\fBWarning\fR: It is
-\fINOT\fR
-recommended to use this backend for volumes anymore, as
-\fBafpd\fR
-now relies heavily on a persistent ID database\&. Aliases will likely not work and filename mangling is not supported\&.
-.RE
-.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\*(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\&. \*(Aq/\*(Aq will be encoded to
-:2f, if
-\fBusedots\fR
-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\&. \*(Aq/\*(Aq will be converted to \*(Aq:\*(Aq\&.
-.PP
-The
-\fBvol charset\fR
-option will allow you to select another volume encoding\&. E\&.g\&. for western users another useful setting could be vol charset ISO\-8859\-15\&.
-\fBafpd\fR
-will accept any
-\fBiconv\fR(1)
-provided charset\&. If a character cannot be converted from the
-\fBmac charset\fR
-to the selected
-\fBvol charset\fR, afpd will save it as a CAP encoded character\&. For AFP3 clients,
-\fBafpd\fR
-will convert the UTF\-8
-character to
-\fBmac charset\fR
-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"
-.PP
-\fBafpd\fR(8),
-\fBafppasswd\fR(5),
-\fBafp_signature.conf\fR(5),
-\fBextmap.conf\fR(5),
-\fBcnid_metad\fR(8)
diff --git a/man/man5/afp_signature.conf.5.in b/man/man5/afp_signature.conf.5.in
new file mode 100644 (file)
index 0000000..c620ef0
--- /dev/null
@@ -0,0 +1,86 @@
+'\" t
+.\"     Title: afp_signature.conf
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 23 Mar 2012
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "AFP_SIGNATURE\&.CONF" "5" "23 Mar 2012" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+afp_signature.conf \- Configuration file used by afpd(8) to specify server signature
+.SH "DESCRIPTION"
+.PP
+@localstatedir@/netatalk/afp_signature\&.conf
+is the configuration file used by
+\fBafpd\fR
+to specify server signature automagically\&. The configuration lines are composed like:
+.PP
+\fI"server name"\fR
+\fIhexa\-string\fR
+.PP
+The first field is server name\&. Server names must be quoted if they contain spaces\&. The second field is the hexadecimal string of 32 characters for 16\-bytes server signature\&.
+.PP
+The leading spaces and tabs are ignored\&. Blank lines are ignored\&. The lines prefixed with # are ignored\&. The illegal lines are ignored\&.
+.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
+.PP
+Server Signature is unique 16\-bytes identifier used to prevent logging on to the same server twice\&.
+.PP
+Netatalk 2\&.0 and earlier generated server signature by using gethostid()\&. There was a problem that another servers have the same signature because the hostid is not unique enough\&.
+.PP
+Current netatalk generates the signature from random numbers and saves it into afp_signature\&.conf\&. When starting next time, it is read from this file\&.
+.PP
+This file should not be thoughtlessly edited and be copied onto another server\&. If it wants to set the signature intentionally, use the option "signature =" in afp\&.conf\&. In this case, afp_signature\&.conf is not used\&.
+.sp .5v
+.RE
+.PP
+.SH "EXAMPLES"
+.PP
+\fBExample.\ \&afp_signature.conf\fR
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# This is a comment\&.
+"My Server" 74A0BB94EC8C13988B2E75042347E528
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBafpd\fR(8),
+\fBafp.conf\fR(5),
+\fBasip-status.pl\fR(1)
diff --git a/man/man5/afp_signature.conf.5.tmpl b/man/man5/afp_signature.conf.5.tmpl
deleted file mode 100644 (file)
index 2f5fe40..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-'\" t
-.\"     Title: afp_signature.conf
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 23 Mar 2012
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-afp_signature.conf \- Configuration file used by afpd(8) to specify server signature
-.SH "DESCRIPTION"
-.PP
-:STATEDIR:/netatalk/afp_signature\&.conf
-is the configuration file used by
-\fBafpd\fR
-to specify server signature automagically\&. The configuration lines are composed like:
-.PP
-\fI"server name"\fR
-\fIhexa\-string\fR
-.PP
-The first field is server name\&. Server names must be quoted if they contain spaces\&. The second field is the hexadecimal string of 32 characters for 16\-bytes server signature\&.
-.PP
-The leading spaces and tabs are ignored\&. Blank lines are ignored\&. The lines prefixed with # are ignored\&. The illegal lines are ignored\&.
-.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
-.PP
-Server Signature is unique 16\-bytes identifier used to prevent logging on to the same server twice\&.
-.PP
-Netatalk 2\&.0 and earlier generated server signature by using gethostid()\&. There was a problem that another servers have the same signature because the hostid is not unique enough\&.
-.PP
-Current netatalk generates the signature from random numbers and saves it into afp_signature\&.conf\&. When starting next time, it is read from this file\&.
-.PP
-This file should not be thoughtlessly edited and be copied onto another server\&. If it wants to set the signature intentionally, use the option "signature =" in afp\&.conf\&. In this case, afp_signature\&.conf is not used\&.
-.sp .5v
-.RE
-.PP
-.SH "EXAMPLES"
-.PP
-\fBExample.\ \&afp_signature.conf\fR
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-# This is a comment\&.
-"My Server" 74A0BB94EC8C13988B2E75042347E528
-.fi
-.if n \{\
-.RE
-.\}
-.SH "SEE ALSO"
-.PP
-\fBafpd\fR(8),
-\fBafp.conf\fR(5),
-\fBasip-status.pl\fR(1)
diff --git a/man/man5/afp_voluuid.conf.5.in b/man/man5/afp_voluuid.conf.5.in
new file mode 100644 (file)
index 0000000..21612dd
--- /dev/null
@@ -0,0 +1,87 @@
+'\" t
+.\"     Title: afp_voluuid.conf
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 23 Mar 2012
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "AFP_VOLUUID\&.CONF" "5" "23 Mar 2012" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+afp_voluuid.conf \- Configuration file used by afpd(8) to specify UUID for Time Machine volume
+.SH "DESCRIPTION"
+.PP
+@localstatedir@/netatalk/afp_voluuid\&.conf
+is the configuration file used by
+\fBafpd\fR
+to specify UUID of Time Machine volume automagically\&. The configuration lines are composed like:
+.PP
+\fI"volume name"\fR
+\fIuuid\-string\fR
+.PP
+The first field is volume name\&. Volume names must be quoted if they contain spaces\&. The second field is the 36 character hexadecimal ASCII string representation of a UUID\&.
+.PP
+The leading spaces and tabs are ignored\&. Blank lines are ignored\&. The lines prefixed with # are ignored\&. The illegal lines are ignored\&.
+.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
+.PP
+This UUID is advertised by Zeroconf in order to provide robust disambiguation of Time Machine volume\&.
+.PP
+The afpd generates the UUID from random numbers and saves it into afp_voluuid\&.conf, only when setting "time machine = yes" option in afp\&.conf\&.
+.PP
+This file should not be thoughtlessly edited and be copied onto another server\&.
+.sp .5v
+.RE
+.PP
+.SH "EXAMPLES"
+.PP
+\fBExample.\ \&afp_voluuid.conf three TM volumes on one netatalk\fR
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# This is a comment\&.
+"Backup for John Smith" 1573974F\-0ABD\-69CC\-C40A\-8519B681A0E1
+"bob" 39A487F4\-55AA\-8240\-E584\-69AA01800FE9
+mary 6331E2D1\-446C\-B68C\-3066\-D685AADBE911
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBafpd\fR(8),
+\fBafp.conf\fR(5),
+\fBavahi-daemon\fR(8),
+\fBmDNSResponder\fR(8)
diff --git a/man/man5/afp_voluuid.conf.5.tmpl b/man/man5/afp_voluuid.conf.5.tmpl
deleted file mode 100644 (file)
index a9fb2dd..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-'\" t
-.\"     Title: afp_voluuid.conf
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 23 Mar 2012
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-afp_voluuid.conf \- Configuration file used by afpd(8) to specify UUID for Time Machine volume
-.SH "DESCRIPTION"
-.PP
-:STATEDIR:/netatalk/afp_voluuid\&.conf
-is the configuration file used by
-\fBafpd\fR
-to specify UUID of Time Machine volume automagically\&. The configuration lines are composed like:
-.PP
-\fI"volume name"\fR
-\fIuuid\-string\fR
-.PP
-The first field is volume name\&. Volume names must be quoted if they contain spaces\&. The second field is the 36 character hexadecimal ASCII string representation of a UUID\&.
-.PP
-The leading spaces and tabs are ignored\&. Blank lines are ignored\&. The lines prefixed with # are ignored\&. The illegal lines are ignored\&.
-.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
-.PP
-This UUID is advertised by Zeroconf in order to provide robust disambiguation of Time Machine volume\&.
-.PP
-The afpd generates the UUID from random numbers and saves it into afp_voluuid\&.conf, only when setting "time machine = yes" option in afp\&.conf\&.
-.PP
-This file should not be thoughtlessly edited and be copied onto another server\&.
-.sp .5v
-.RE
-.PP
-.SH "EXAMPLES"
-.PP
-\fBExample.\ \&afp_voluuid.conf three TM volumes on one netatalk\fR
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-# This is a comment\&.
-"Backup for John Smith" 1573974F\-0ABD\-69CC\-C40A\-8519B681A0E1
-"bob" 39A487F4\-55AA\-8240\-E584\-69AA01800FE9
-mary 6331E2D1\-446C\-B68C\-3066\-D685AADBE911
-.fi
-.if n \{\
-.RE
-.\}
-.SH "SEE ALSO"
-.PP
-\fBafpd\fR(8),
-\fBafp.conf\fR(5),
-\fBavahi-daemon\fR(8),
-\fBmDNSResponder\fR(8)
diff --git a/man/man5/extmap.conf.5.in b/man/man5/extmap.conf.5.in
new file mode 100644 (file)
index 0000000..9e0abfa
--- /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_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "EXTMAP\&.CONF" "5" "19 Jan 2013" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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@pkgconfdir@/extmap\&.conf\fR\fB\fR\ 'u
+\fB@pkgconfdir@/extmap\&.conf\fR\fB\fR
+.SH "DESCRIPTION"
+.PP
+
+@pkgconfdir@/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)
diff --git a/man/man5/extmap.conf.5.tmpl b/man/man5/extmap.conf.5.tmpl
deleted file mode 100644 (file)
index 9c6679f..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-'\" 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 711b8c366feeaa990bf572e2d9538b5f97a361d0..29043a09f888f3ffa7478bd8196c7134074373b5 100644 (file)
@@ -1,12 +1,3 @@
 Makefile
 Makefile.in
-afpd.8
-afp_acls.8
-atalkd.8
-cnid_dbd.8
-cnid_metad.8
-netatalk.8
-papd.8
-papstatus.8
-psf.8
-*.o
+*.8
index eb112ab3d7445ee15c824cea5b2df46e1d74d485..fdc6eaf190cfbcb2ec46753500fcfcde09ebf6cb 100644 (file)
@@ -1,24 +1,9 @@
 ## Makefile.am for man/man8/
 
-pkgconfdir = @PKGCONFDIR@
+man_MANS = \
+       afpd.8 \
+       cnid_dbd.8 \
+       cnid_metad.8 \
+       netatalk.8
 
-SUFFIXES = .tmpl .
-
-.tmpl:
-       sed -e s@:SBINDIR:@${sbindir}@ \
-           -e s@:BINDIR:@${bindir}@ \
-           -e s@:ETCDIR:@${pkgconfdir}@ \
-           -e s@:LIBDIR:@${libdir}@ \
-           -e s@:LIBEXECDIR:@${libexecdir}@ \
-           -e "s@:STATEDIR:@${localstatedir}@g" \
-           -e s@:NETATALK_VERSION:@${NETATALK_VERSION}@ \
-           <$< >$@
-
-GENERATED_MANS    = afpd.8 cnid_dbd.8 cnid_metad.8 netatalk.8
-TEMPLATE_FILES    = afpd.8.tmpl cnid_dbd.8.tmpl cnid_metad.8.tmpl netatalk.8.tmpl
-
-man_MANS = $(GENERATED_MANS)
-
-CLEANFILES = $(GENERATED_MANS)
-
-EXTRA_DIST = $(TEMPLATE_FILES)
+DISTCLEANFILES = $(man_MANS)
diff --git a/man/man8/afpd.8.in b/man/man8/afpd.8.in
new file mode 100644 (file)
index 0000000..ab40fa3
--- /dev/null
@@ -0,0 +1,171 @@
+'\" t
+.\"     Title: afpd
+.\"    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_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "AFPD" "8" "19 Jan 2013" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+afpd \- Apple Filing Protocol daemon
+.SH "SYNOPSIS"
+.HP \w'\fBafpd\fR\fB\fR\fBafpd\fR\fB\fR\ 'u
+\fBafpd\fR\fB\fR [\-d] [\-F\ \fIconfigfile\fR]
+.br
+\fBafpd\fR\fB\fR \-v | \-V | \-h 
+.SH "DESCRIPTION"
+.PP
+\fBafpd\fR
+provides an Apple Filing Protocol (AFP) interface to the Unix file system\&. It is normally started at boot time by
+\fBnetatalk\fR(8)\&.
+.PP
+@pkgconfdir@/afp\&.conf
+is the configuration file used by
+\fBafpd\fR
+to determine the behavior and configuration of a file server\&.
+.SH "OPTIONS"
+.PP
+\-d
+.RS 4
+Specifies that the daemon should not fork\&.
+.RE
+.PP
+\-v
+.RS 4
+Print version information and exit\&.
+.RE
+.PP
+\-V
+.RS 4
+Print verbose information and exit\&.
+.RE
+.PP
+\-h
+.RS 4
+Print help and exit\&.
+.RE
+.PP
+\-F \fIconfigfile\fR
+.RS 4
+Specifies the configuration file to use\&. (Defaults to
+@pkgconfdir@/afp\&.conf\&.)
+.RE
+.SH "SIGNALS"
+.PP
+To shut down a user\*(Aqs
+\fBafpd\fR
+process it is recommended that
+\fBSIGKILL (\-9)\fR
+\fINOT\fR
+be used, except as a last resort, as this may leave the CNID database in an inconsistent state\&. The safe way to terminate an
+\fBafpd\fR
+is to send it a
+\fBSIGTERM (\-15)\fR
+signal and wait for it to die on its own\&.
+.PP
+SIGTERM and SIGUSR1 signals that are sent to the main
+\fBafpd\fR
+process are propagated to the children, so all will be affected\&.
+.PP
+SIGTERM
+.RS 4
+Clean exit\&. Propagates from master to childs\&.
+.RE
+.PP
+SIGQUIT
+.RS 4
+Send this to the master
+\fBafpd\fR, it will exit leaving all children running! Can be used to implement AFP service without downtime\&.
+.RE
+.PP
+SIGHUP
+.RS 4
+Sending a
+\fBSIGHUP\fR
+to afpd will cause it to reload its configuration files\&.
+.RE
+.PP
+SIGINT
+.RS 4
+Sending a
+\fBSIGINT\fR
+to a child
+\fBafpd\fR
+enables
+\fImax_debug\fR
+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\&.
+.RE
+.PP
+SIGUSR1
+.RS 4
+The
+\fBafpd\fR
+process will send the message "The server is going down for maintenance\&." to the client and shut itself down in 5 minutes\&. New connections are not allowed\&. If this is sent to a child afpd, the other children are not affected\&. However, the main process will still exit, disabling all new connections\&.
+.RE
+.PP
+SIGUSR2
+.RS 4
+The
+\fBafpd\fR
+process will look in the message directory configured at build time for a file named message\&.pid\&. For each one found, a the contents will be sent as a message to the associated AFP client\&. The file is removed after the message is sent\&. This should only be sent to a child
+\fBafpd\fR\&.
+.RE
+.SH "FILES"
+.PP
+@pkgconfdir@/afp\&.conf
+.RS 4
+configuration file used by afpd
+.RE
+.PP
+@localstatedir@/netatalk/afp_signature\&.conf
+.RS 4
+list of server signature
+.RE
+.PP
+@localstatedir@/netatalk/afp_voluuid\&.conf
+.RS 4
+list of UUID for Time Machine volume
+.RE
+.PP
+@pkgconfdir@/extmap\&.conf
+.RS 4
+file name extension mapping
+.RE
+.PP
+@pkgconfdir@/msg/message\&.pid
+.RS 4
+contains messages to be sent to users\&.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBnetatalk\fR(8),
+\fBhosts_access\fR(5),
+\fBafp.conf\fR(5),
+\fBafp_signature.conf\fR(5),
+\fBafp_voluuid.conf\fR(5),
+\fBextmap.conf\fR(5),
+\fBdbd\fR(1)\&.
diff --git a/man/man8/afpd.8.tmpl b/man/man8/afpd.8.tmpl
deleted file mode 100644 (file)
index 9f09a64..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-'\" t
-.\"     Title: afpd
-.\"    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 "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
-.\" -----------------------------------------------------------------
-.\" disable hyphenation
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-afpd \- Apple Filing Protocol daemon
-.SH "SYNOPSIS"
-.HP \w'\fBafpd\fR\fB\fR\fBafpd\fR\fB\fR\ 'u
-\fBafpd\fR\fB\fR [\-d] [\-F\ \fIconfigfile\fR]
-.br
-\fBafpd\fR\fB\fR \-v | \-V | \-h 
-.SH "DESCRIPTION"
-.PP
-\fBafpd\fR
-provides an Apple Filing Protocol (AFP) interface to the Unix file system\&. It is normally started at boot time by
-\fBnetatalk\fR(8)\&.
-.PP
-:ETCDIR:/afp\&.conf
-is the configuration file used by
-\fBafpd\fR
-to determine the behavior and configuration of a file server\&.
-.SH "OPTIONS"
-.PP
-\-d
-.RS 4
-Specifies that the daemon should not fork\&.
-.RE
-.PP
-\-v
-.RS 4
-Print version information and exit\&.
-.RE
-.PP
-\-V
-.RS 4
-Print verbose information and exit\&.
-.RE
-.PP
-\-h
-.RS 4
-Print help and exit\&.
-.RE
-.PP
-\-F \fIconfigfile\fR
-.RS 4
-Specifies the configuration file to use\&. (Defaults to
-:ETCDIR:/afp\&.conf\&.)
-.RE
-.SH "SIGNALS"
-.PP
-To shut down a user\*(Aqs
-\fBafpd\fR
-process it is recommended that
-\fBSIGKILL (\-9)\fR
-\fINOT\fR
-be used, except as a last resort, as this may leave the CNID database in an inconsistent state\&. The safe way to terminate an
-\fBafpd\fR
-is to send it a
-\fBSIGTERM (\-15)\fR
-signal and wait for it to die on its own\&.
-.PP
-SIGTERM and SIGUSR1 signals that are sent to the main
-\fBafpd\fR
-process are propagated to the children, so all will be affected\&.
-.PP
-SIGTERM
-.RS 4
-Clean exit\&. Propagates from master to childs\&.
-.RE
-.PP
-SIGQUIT
-.RS 4
-Send this to the master
-\fBafpd\fR, it will exit leaving all children running! Can be used to implement AFP service without downtime\&.
-.RE
-.PP
-SIGHUP
-.RS 4
-Sending a
-\fBSIGHUP\fR
-to afpd will cause it to reload its configuration files\&.
-.RE
-.PP
-SIGINT
-.RS 4
-Sending a
-\fBSIGINT\fR
-to a child
-\fBafpd\fR
-enables
-\fImax_debug\fR
-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\&.
-.RE
-.PP
-SIGUSR1
-.RS 4
-The
-\fBafpd\fR
-process will send the message "The server is going down for maintenance\&." to the client and shut itself down in 5 minutes\&. New connections are not allowed\&. If this is sent to a child afpd, the other children are not affected\&. However, the main process will still exit, disabling all new connections\&.
-.RE
-.PP
-SIGUSR2
-.RS 4
-The
-\fBafpd\fR
-process will look in the message directory configured at build time for a file named message\&.pid\&. For each one found, a the contents will be sent as a message to the associated AFP client\&. The file is removed after the message is sent\&. This should only be sent to a child
-\fBafpd\fR\&.
-.RE
-.SH "FILES"
-.PP
-:ETCDIR:/afp\&.conf
-.RS 4
-configuration file used by afpd
-.RE
-.PP
-:STATEDIR:/netatalk/afp_signature\&.conf
-.RS 4
-list of server signature
-.RE
-.PP
-:STATEDIR:/netatalk/afp_voluuid\&.conf
-.RS 4
-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\&.
-.RE
-.SH "SEE ALSO"
-.PP
-\fBnetatalk\fR(8),
-\fBhosts_access\fR(5),
-\fBafp.conf\fR(5),
-\fBafp_signature.conf\fR(5),
-\fBafp_voluuid.conf\fR(5),
-\fBextmap.conf\fR(5),
-\fBdbd\fR(1)\&.
diff --git a/man/man8/cnid_dbd.8.in b/man/man8/cnid_dbd.8.in
new file mode 100644 (file)
index 0000000..3b5b68a
--- /dev/null
@@ -0,0 +1,249 @@
+'\" t
+.\"     Title: cnid_dbd
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 01 Jan 2012
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "CNID_DBD" "8" "01 Jan 2012" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+cnid_dbd \- implement access to CNID databases through a dedicated daemon process
+.SH "SYNOPSIS"
+.HP \w'\fBcnid_dbd\fR\fB\fR\fB\fR\fB\fR\fBcnid_dbd\fR\fB\fR\ 'u
+\fBcnid_dbd\fR\fB\fR\fB\fR\fB\fR
+.br
+\fBcnid_dbd\fR\fB\fR \-v | \-V 
+.SH "DESCRIPTION"
+.PP
+\fBcnid_dbd\fR
+provides an interface for storage and retrieval of catalog node IDs (CNIDs) and related information to the
+\fBafpd\fR
+daemon\&. CNIDs are a component of Macintosh based file systems with semantics that map not easily onto Unix file systems\&. This makes separate storage in a database necessary\&.
+\fBcnid_dbd\fR
+is part of the
+\fBCNID backend\fR
+framework of
+\fBafpd\fR
+and implements the
+\fBdbd\fR
+backend\&.
+.PP
+\fBcnid_dbd\fR
+is never started via the command line or system startup scripts but only by the
+\fBcnid_metad\fR
+daemon\&. There is one instance of
+\fBcnid_dbd\fR
+per netatalk volume\&.
+.PP
+\fBcnid_dbd\fR
+uses the
+\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\&.
+.PP
+\fBcnid_dbd\fR
+inherits the effective userid and groupid from
+\fBcnid_metad\fR
+on startup, which is normally caused by
+\fBafpd\fR
+serving a netatalk volume to a client\&. It changes to the
+\fBBerkeley DB\fR
+database home directory
+\fIdbdir\fR
+that is associated with the volume\&. If the userid inherited from
+\fBcnid_metad\fR
+is 0 (root),
+\fBcnid_dbd\fR
+will change userid and groupid to the owner and group of the database home directory\&. Otherwise, it will continue to use the inherited values\&.
+\fBcnid_dbd\fR
+will then attempt to open the database and start serving requests using filedescriptor
+\fIclntfd\fR\&. Subsequent instances of
+\fBafpd\fR
+that want to access the same volume are redirected to the running
+\fBcnid_dbd\fR
+process by
+\fBcnid_metad\fR
+via the filedescriptor
+\fIctrlfd\fR\&.
+.PP
+\fBcnid_dbd\fR
+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
+\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
+\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 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)\&.
+.SH "OPTIONS"
+.PP
+\fB\-v, \-V\fR
+.RS 4
+Show version and exit\&.
+.RE
+.SH "CONFIGURATION"
+.PP
+\fBcnid_dbd\fR
+reads configuration information from the file
+\fIdb_param\fR
+in the database directory
+\fIdbdir\fR
+on startup\&. If the file does not exist or a parameter is not listed, suitable default values are used\&. The format for a single parameter is the parameter name, followed by one or more spaces, followed by the parameter value, followed by a newline\&. The following parameters are currently recognized:
+.PP
+\fBlogfile_autoremove\fR
+.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 regular basis\&. Default: 1\&.
+.RE
+.PP
+\fBcachesize\fR
+.RS 4
+Determines the size of the Berkeley DB cache in kilobytes\&. Default: 8192\&. Each
+\fBcnid_dbd\fR
+process grabs that much memory on top of its normal memory footprint\&. It can be used to tune database performance\&. The
+\fBdb_stat\fR
+utility with the
+\fB\-m\fR
+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
+that gives more detailed information\&.
+.RE
+.PP
+\fBflush_frequency\fR, \fBflush_interval\fR
+.RS 4
+\fIflush_frequency\fR
+(Default: 1000) and
+\fIflush_interval\fR
+(Default: 1800) control how often changes to the database are checkpointed\&. Both of these operations are performed if either i) more than
+\fIflush_frequency\fR
+requests have been received or ii) more than
+\fIflush_interval\fR
+seconds have elapsed since the last save/checkpoint\&. Be careful to check your harddisk configuration for on disk cache settings\&. Many IDE disks just cache writes as the default behaviour, so even flushing database files to disk will not have the desired effect\&.
+.RE
+.PP
+\fBfd_table_size\fR
+.RS 4
+is the maximum number of connections (filedescriptors) that can be open for
+\fBafpd\fR
+client processes in
+\fBcnid_dbd\&.\fR
+Default: 512\&. If this number is exceeded, one of the existing connections is closed and reused\&. The affected
+\fBafpd\fR
+process will transparently reconnect later, which causes slight overhead\&. On the other hand, setting this parameter too high could affect performance in
+\fBcnid_dbd\fR
+since all descriptors have to be checked in a
+\fBselect()\fR
+system call, or worse, you might exceed the per process limit of open file descriptors on your system\&. It is safe to set the value to 1 on volumes where only one
+\fBafpd\fR
+client process is expected to run, e\&.g\&. home directories\&.
+.RE
+.PP
+\fBidle_timeout\fR
+.RS 4
+is the number of seconds of inactivity before an idle
+\fBcnid_dbd\fR
+exits\&. Default: 600\&. Set this to 0 to disable the timeout\&.
+.RE
+.SH "UPDATING"
+.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\*(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
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Stop the to be upgraded old version of Netatalk
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Using the old BerkeleyDB utilities run
+\fBdb_recover \-h <path to \&.AppleDB>\fR
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Using the new BerkeleyDB utilities run
+\fBdb_upgrade \-v \-h <path to \&.AppleDB> \-f cnid2\&.db\fR
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Again using the new BerkeleyDB utilities run
+\fBdb_checkpoint \-1 \-h <path to \&.AppleDB>\fR
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Start the the new version of Netatalk
+.RE
+.SH "SEE ALSO"
+.PP
+\fBcnid_metad\fR(8),
+\fBafpd\fR(8),
+\fBdbd\fR(1)
diff --git a/man/man8/cnid_dbd.8.tmpl b/man/man8/cnid_dbd.8.tmpl
deleted file mode 100644 (file)
index b5d8bc5..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-'\" t
-.\"     Title: cnid_dbd
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 01 Jan 2012
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-cnid_dbd \- implement access to CNID databases through a dedicated daemon process
-.SH "SYNOPSIS"
-.HP \w'\fBcnid_dbd\fR\fB\fR\fB\fR\fB\fR\fBcnid_dbd\fR\fB\fR\ 'u
-\fBcnid_dbd\fR\fB\fR\fB\fR\fB\fR
-.br
-\fBcnid_dbd\fR\fB\fR \-v | \-V 
-.SH "DESCRIPTION"
-.PP
-\fBcnid_dbd\fR
-provides an interface for storage and retrieval of catalog node IDs (CNIDs) and related information to the
-\fBafpd\fR
-daemon\&. CNIDs are a component of Macintosh based file systems with semantics that map not easily onto Unix file systems\&. This makes separate storage in a database necessary\&.
-\fBcnid_dbd\fR
-is part of the
-\fBCNID backend\fR
-framework of
-\fBafpd\fR
-and implements the
-\fBdbd\fR
-backend\&.
-.PP
-\fBcnid_dbd\fR
-is never started via the command line or system startup scripts but only by the
-\fBcnid_metad\fR
-daemon\&. There is one instance of
-\fBcnid_dbd\fR
-per netatalk volume\&.
-.PP
-\fBcnid_dbd\fR
-uses the
-\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\&.
-.PP
-\fBcnid_dbd\fR
-inherits the effective userid and groupid from
-\fBcnid_metad\fR
-on startup, which is normally caused by
-\fBafpd\fR
-serving a netatalk volume to a client\&. It changes to the
-\fBBerkeley DB\fR
-database home directory
-\fIdbdir\fR
-that is associated with the volume\&. If the userid inherited from
-\fBcnid_metad\fR
-is 0 (root),
-\fBcnid_dbd\fR
-will change userid and groupid to the owner and group of the database home directory\&. Otherwise, it will continue to use the inherited values\&.
-\fBcnid_dbd\fR
-will then attempt to open the database and start serving requests using filedescriptor
-\fIclntfd\fR\&. Subsequent instances of
-\fBafpd\fR
-that want to access the same volume are redirected to the running
-\fBcnid_dbd\fR
-process by
-\fBcnid_metad\fR
-via the filedescriptor
-\fIctrlfd\fR\&.
-.PP
-\fBcnid_dbd\fR
-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
-\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
-\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 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)\&.
-.SH "OPTIONS"
-.PP
-\fB\-v, \-V\fR
-.RS 4
-Show version and exit\&.
-.RE
-.SH "CONFIGURATION"
-.PP
-\fBcnid_dbd\fR
-reads configuration information from the file
-\fIdb_param\fR
-in the database directory
-\fIdbdir\fR
-on startup\&. If the file does not exist or a parameter is not listed, suitable default values are used\&. The format for a single parameter is the parameter name, followed by one or more spaces, followed by the parameter value, followed by a newline\&. The following parameters are currently recognized:
-.PP
-\fBlogfile_autoremove\fR
-.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 regular basis\&. Default: 1\&.
-.RE
-.PP
-\fBcachesize\fR
-.RS 4
-Determines the size of the Berkeley DB cache in kilobytes\&. Default: 8192\&. Each
-\fBcnid_dbd\fR
-process grabs that much memory on top of its normal memory footprint\&. It can be used to tune database performance\&. The
-\fBdb_stat\fR
-utility with the
-\fB\-m\fR
-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
-that gives more detailed information\&.
-.RE
-.PP
-\fBflush_frequency\fR, \fBflush_interval\fR
-.RS 4
-\fIflush_frequency\fR
-(Default: 1000) and
-\fIflush_interval\fR
-(Default: 1800) control how often changes to the database are checkpointed\&. Both of these operations are performed if either i) more than
-\fIflush_frequency\fR
-requests have been received or ii) more than
-\fIflush_interval\fR
-seconds have elapsed since the last save/checkpoint\&. Be careful to check your harddisk configuration for on disk cache settings\&. Many IDE disks just cache writes as the default behaviour, so even flushing database files to disk will not have the desired effect\&.
-.RE
-.PP
-\fBfd_table_size\fR
-.RS 4
-is the maximum number of connections (filedescriptors) that can be open for
-\fBafpd\fR
-client processes in
-\fBcnid_dbd\&.\fR
-Default: 512\&. If this number is exceeded, one of the existing connections is closed and reused\&. The affected
-\fBafpd\fR
-process will transparently reconnect later, which causes slight overhead\&. On the other hand, setting this parameter too high could affect performance in
-\fBcnid_dbd\fR
-since all descriptors have to be checked in a
-\fBselect()\fR
-system call, or worse, you might exceed the per process limit of open file descriptors on your system\&. It is safe to set the value to 1 on volumes where only one
-\fBafpd\fR
-client process is expected to run, e\&.g\&. home directories\&.
-.RE
-.PP
-\fBidle_timeout\fR
-.RS 4
-is the number of seconds of inactivity before an idle
-\fBcnid_dbd\fR
-exits\&. Default: 600\&. Set this to 0 to disable the timeout\&.
-.RE
-.SH "UPDATING"
-.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\*(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
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Stop the to be upgraded old version of Netatalk
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Using the old BerkeleyDB utilities run
-\fBdb_recover \-h <path to \&.AppleDB>\fR
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Using the new BerkeleyDB utilities run
-\fBdb_upgrade \-v \-h <path to \&.AppleDB> \-f cnid2\&.db\fR
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Again using the new BerkeleyDB utilities run
-\fBdb_checkpoint \-1 \-h <path to \&.AppleDB>\fR
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Start the the new version of Netatalk
-.RE
-.SH "SEE ALSO"
-.PP
-\fBcnid_metad\fR(8),
-\fBafpd\fR(8),
-\fBdbd\fR(1)
diff --git a/man/man8/cnid_metad.8.in b/man/man8/cnid_metad.8.in
new file mode 100644 (file)
index 0000000..0a0d559
--- /dev/null
@@ -0,0 +1,90 @@
+'\" t
+.\"     Title: cnid_metad
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 23 Mar 2012
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "CNID_METAD" "8" "23 Mar 2012" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+cnid_metad \- start cnid_dbd daemons on request
+.SH "SYNOPSIS"
+.HP \w'\fBcnid_metad\fR\fB\fR\fBcnid_metad\fR\fB\fR\ 'u
+\fBcnid_metad\fR\fB\fR [\-d] [\-F\ \fIconfiguration\ file\fR]
+.br
+\fBcnid_metad\fR\fB\fR \-v | \-V 
+.SH "DESCRIPTION"
+.PP
+\fBcnid_metad\fR
+waits for requests from
+\fBafpd\fR
+to start up instances of the
+\fBcnid_dbd\fR
+daemon\&. It keeps track of the status of a
+\fBcnid_dbd\fR
+instance once started and will restart it if necessary\&.
+\fBcnid_metad\fR
+is normally started at boot time by
+\fBnetatalk\fR(8) and runs until shutdown\&.
+.SH "OPTIONS"
+.PP
+\fB\-d\fR
+.RS 4
+\fBcnid_metad will remain in the foreground and\fR
+will also leave the standard input, standard output and standard error file descriptors open\&. Useful for debugging\&.
+.RE
+.PP
+\fB\-F\fR \fIconfiguration file\fR
+.RS 4
+Use
+\fIconfiguration file\fR
+as the configuration file\&. The default is
+\fI@pkgconfdir@/afp\&.conf\fR\&.
+.RE
+.PP
+\fB\-v, \-V\fR
+.RS 4
+Show version and exit\&.
+.RE
+.SH "CAVEATS"
+.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\*(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
+\fBcnid_metad\fR
+this is desired behaviour\&. As soon as
+\fBcnid_metad\fR
+is restarted
+\fBafpd\fR
+processes will transparently reconnect\&.
+.SH "SEE ALSO"
+.PP
+\fBnetatalk\fR(8),
+\fBcnid_dbd\fR(8),
+\fBafpd\fR(8),
+\fBdbd\fR(1),
+\fBafp.conf\fR(5)
diff --git a/man/man8/cnid_metad.8.tmpl b/man/man8/cnid_metad.8.tmpl
deleted file mode 100644 (file)
index 4007a7c..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-'\" t
-.\"     Title: cnid_metad
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 23 Mar 2012
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-cnid_metad \- start cnid_dbd daemons on request
-.SH "SYNOPSIS"
-.HP \w'\fBcnid_metad\fR\fB\fR\fBcnid_metad\fR\fB\fR\ 'u
-\fBcnid_metad\fR\fB\fR [\-d] [\-F\ \fIconfiguration\ file\fR]
-.br
-\fBcnid_metad\fR\fB\fR \-v | \-V 
-.SH "DESCRIPTION"
-.PP
-\fBcnid_metad\fR
-waits for requests from
-\fBafpd\fR
-to start up instances of the
-\fBcnid_dbd\fR
-daemon\&. It keeps track of the status of a
-\fBcnid_dbd\fR
-instance once started and will restart it if necessary\&.
-\fBcnid_metad\fR
-is normally started at boot time by
-\fBnetatalk\fR(8) and runs until shutdown\&.
-.SH "OPTIONS"
-.PP
-\fB\-d\fR
-.RS 4
-\fBcnid_metad will remain in the foreground and\fR
-will also leave the standard input, standard output and standard error file descriptors open\&. Useful for debugging\&.
-.RE
-.PP
-\fB\-F\fR \fIconfiguration file\fR
-.RS 4
-Use
-\fIconfiguration file\fR
-as the configuration file\&. The default is
-\fI:ETCDIR:/afp\&.conf\fR\&.
-.RE
-.PP
-\fB\-v, \-V\fR
-.RS 4
-Show version and exit\&.
-.RE
-.SH "CAVEATS"
-.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\*(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
-\fBcnid_metad\fR
-this is desired behaviour\&. As soon as
-\fBcnid_metad\fR
-is restarted
-\fBafpd\fR
-processes will transparently reconnect\&.
-.SH "SEE ALSO"
-.PP
-\fBnetatalk\fR(8),
-\fBcnid_dbd\fR(8),
-\fBafpd\fR(8),
-\fBdbd\fR(1),
-\fBafp.conf\fR(5)
diff --git a/man/man8/netatalk.8.in b/man/man8/netatalk.8.in
new file mode 100644 (file)
index 0000000..39790ff
--- /dev/null
@@ -0,0 +1,67 @@
+'\" t
+.\"     Title: netatalk
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
+.\"      Date: 22 Mar 2012
+.\"    Manual: @NETATALK_VERSION@
+.\"    Source: @NETATALK_VERSION@
+.\"  Language: English
+.\"
+.TH "NETATALK" "8" "22 Mar 2012" "@NETATALK_VERSION@" "@NETATALK_VERSION@"
+.\" -----------------------------------------------------------------
+.\" * 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"
+netatalk \- Netatalk AFP server service controller daemon
+.SH "SYNOPSIS"
+.HP \w'\fBnetatalk\fR\fB\fR\fBnetatalk\fR\fB\fR\ 'u
+\fBnetatalk\fR\fB\fR
+.br
+\fBnetatalk\fR\fB\fR
+.SH "DESCRIPTION"
+.PP
+\fBnetatalk\fR
+is the service controller daemon responsible for starting and restarting the AFP daemon
+\fBafpd\fR
+and the CNID daemon
+\fBcnid_metad\fR\&. It is normally started at boot time from /etc/rc\&.
+.SH "SIGNALS"
+.PP
+SIGTERM
+.RS 4
+Stop Netatalk service, AFP and CNID daemons
+.RE
+.PP
+SIGHUP
+.RS 4
+Sending a
+\fBSIGHUP\fR
+will cause the AFP daemon reload its configuration file\&.
+.RE
+.SH "FILES"
+.PP
+@pkgconfdir@/afp\&.conf
+.RS 4
+configuration file used by afpd and cnid_metad
+.RE
+.SH "SEE ALSO"
+.PP
+\fBafpd\fR(8),
+\fBcnid_metad\fR(8),
+\fBafp.conf\fR(5)\&.
diff --git a/man/man8/netatalk.8.tmpl b/man/man8/netatalk.8.tmpl
deleted file mode 100644 (file)
index 06878da..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-'\" t
-.\"     Title: netatalk
-.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\"      Date: 22 Mar 2012
-.\"    Manual: Netatalk 3.0
-.\"    Source: Netatalk 3.0
-.\"  Language: English
-.\"
-.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
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.SH "NAME"
-netatalk \- Netatalk AFP server service controller daemon
-.SH "SYNOPSIS"
-.HP \w'\fBnetatalk\fR\fB\fR\fBnetatalk\fR\fB\fR\ 'u
-\fBnetatalk\fR\fB\fR
-.br
-\fBnetatalk\fR\fB\fR
-.SH "DESCRIPTION"
-.PP
-\fBnetatalk\fR
-is the service controller daemon responsible for starting and restarting the AFP daemon
-\fBafpd\fR
-and the CNID daemon
-\fBcnid_metad\fR\&. It is normally started at boot time from /etc/rc\&.
-.SH "SIGNALS"
-.PP
-SIGTERM
-.RS 4
-Stop Netatalk service, AFP and CNID daemons
-.RE
-.PP
-SIGHUP
-.RS 4
-Sending a
-\fBSIGHUP\fR
-will cause the AFP daemon reload its configuration file\&.
-.RE
-.SH "FILES"
-.PP
-:ETCDIR:/afp\&.conf
-.RS 4
-configuration file used by afpd and cnid_metad
-.RE
-.SH "SEE ALSO"
-.PP
-\fBafpd\fR(8),
-\fBcnid_metad\fR(8),
-\fBafp.conf\fR(5)\&.