diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /rfc822/rfc822.sgml | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'rfc822/rfc822.sgml')
| -rw-r--r-- | rfc822/rfc822.sgml | 625 | 
1 files changed, 625 insertions, 0 deletions
| diff --git a/rfc822/rfc822.sgml b/rfc822/rfc822.sgml new file mode 100644 index 0000000..f0d7c93 --- /dev/null +++ b/rfc822/rfc822.sgml @@ -0,0 +1,625 @@ +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"> +<!-- Copyright 2001-2007 Double Precision, Inc.  See COPYING for --> +<!-- distribution information. --> +<refentry> +  <info><author><firstname>Sam</firstname><surname>Varshavchik</surname><contrib>Author</contrib></author><productname>Courier Mail Server</productname></info> + +  <refmeta> +    <refentrytitle>rfc822</refentrytitle> +    <manvolnum>3</manvolnum> +    <refmiscinfo class='manual'>Double Precision, Inc.</refmiscinfo> +  </refmeta> + +  <refnamediv> +    <refname>rfc822</refname> +    <refpurpose>RFC 822 parsing library</refpurpose> +  </refnamediv> + +  <refsynopsisdiv> + +    <informalexample> +      <programlisting format="linespecific"> +#include <rfc822.h> + +#include <rfc2047.h> + +cc ... -lrfc822 +</programlisting> +    </informalexample> +  </refsynopsisdiv> + +  <refsect1> +    <title>DESCRIPTION</title> + +    <para> +The rfc822 library provides functions for parsing E-mail headers in the RFC +822 format. This library also includes some functions to help with encoding +and decoding 8-bit text, as defined by RFC 2047.</para> + +    <para> +The format used by E-mail headers to encode sender and recipient +information is defined by +<ulink url="http://www.rfc-editor.org/rfc/rfc822.txt">RFC 822</ulink> +(and its successor, +<ulink url="http://www.rfc-editor.org/rfc/rfc2822.txt">RFC 2822</ulink>). +The format allows the actual E-mail +address and the sender/recipient name to be expressed together, for example: +<literal moreinfo="none">John Smith <jsmith@example.com></literal></para> + +    <para> +The main purposes of the rfc822 library is to:</para> + +    <para> +1) Parse a text string containing a list of RFC 822-formatted address into +its logical components: names and E-mail addresses.</para> + +    <para> +2) Access those individual components.</para> + +    <para> +3) Allow some limited modifications of the parsed structure, and then +convert it back into a text string.</para> + +    <refsect2> +      <title>Tokenizing an E-mail header</title> + +      <informalexample> +	<programlisting format="linespecific"> +struct rfc822t *tokens=rfc822t_alloc_new(const char *header, +                void (*err_func)(const char *, int, void *), +                void *func_arg); + +void rfc822t_free(tokens); +</programlisting> +      </informalexample> + +      <para> +The <function moreinfo="none">rfc822t_alloc_new</function>() function (superceeds +<function moreinfo="none">rfc822t_alloc</function>(), which is now +obsolete) accepts an E-mail <parameter moreinfo="none">header</parameter>, and parses it into +individual tokens. This function allocates and returns a pointer to an +<structname>rfc822t</structname> +structure, which is later used by +<function moreinfo="none">rfc822a_alloc</function>() to extract +individual addresses from these tokens.</para> + +      <para> +If <parameter moreinfo="none">err_func</parameter> argument, if not NULL, is a pointer +to a callback +function.  The function is called in the event that the E-mail header is +corrupted to the point that it cannot even be parsed.  This is a rare instance +-- most forms of corruption are still valid at least on the lexical level.  +The only time this error is reported is in the event of mismatched +parenthesis, angle brackets, or quotes.  The callback function receives the +<parameter moreinfo="none">header</parameter> pointer, an index to the syntax error in the +header string, and the <parameter moreinfo="none">func_arg</parameter> argument.</para> + +      <para> +The semantics of <parameter moreinfo="none">err_func</parameter> are subject to change.  It is recommended +to leave this argument as NULL in the current version of the library.</para> + +      <para> +<function moreinfo="none">rfc822t_alloc</function>() returns a pointer to a +dynamically-allocated <structname>rfc822t</structname> +structure. A NULL pointer is returned if there's insufficient memory to +allocate this structure. The <function moreinfo="none">rfc822t_free</function>() function +destroys +<structname>rfc822t</structname> structure and frees all +dynamically allocated memory.</para> + +      <note> +	<para> +Until <function moreinfo="none">rfc822t_free</function>() is called, the contents of +<parameter moreinfo="none">header</parameter> MUST +NOT be destroyed or altered in any way. The contents of +<parameter moreinfo="none">header</parameter> are not +modified by <function moreinfo="none">rfc822t_alloc</function>(), however the +<structname>rfc822t</structname> structure contains +pointers to portions of the supplied <parameter moreinfo="none">header</parameter>, +and they must remain valid.</para> +      </note> +    </refsect2> + +    <refsect2> +      <title>Extracting E-mail addresses</title> + +      <informalexample> +	<programlisting format="linespecific"> +struct rfc822a *addrs=rfc822a_alloc(struct rfc822t *tokens); + +void rfc822a_free(addrs); +</programlisting> +      </informalexample> + +      <para> +The <function moreinfo="none">rfc822a_alloc</function>() function returns a +dynamically-allocated <structname>rfc822a</structname> +structure, that contains individual addresses that were logically parsed +from a <structname>rfc822t</structname> structure.  The +<function moreinfo="none">rfc822a_alloc</function>() function returns NULL if +there was insufficient memory to allocate the <structname>rfc822a</structname> structure. The +<function moreinfo="none">rfc822a_free</function>() function destroys the <structname>rfc822a</structname> function, and frees all +associated dynamically-allocated memory. The <structname>rfc822t</structname> structure passed +to <function moreinfo="none">rfc822a_alloc</function>() must not be destroyed before <function moreinfo="none">rfc822a_free</function>() destroys the +<structname>rfc822a</structname> structure.</para> + +      <para> +The <structname>rfc822a</structname> structure has the following fields:</para> +      <informalexample> +	<programlisting format="linespecific"> +struct rfc822a { +        struct rfc822addr *addrs; +        int     naddrs; +} ; +</programlisting> +      </informalexample> + +      <para> +The <structfield>naddrs</structfield> field gives the number of +<structname>rfc822addr</structname> structures +that are pointed to by <structfield>addrs</structfield>, which is an array. +Each <structname>rfc822addr</structname> +structure represents either an address found in the original E-mail header, +<emphasis>or the contents of some legacy "syntactical sugar"</emphasis>. +For example, the +following is a valid E-mail header:</para> + +      <informalexample> +	<programlisting format="linespecific"> +To: recipient-list: tom@example.com, john@example.com; +</programlisting> +      </informalexample> + +      <para>Typically, all of this, except for "<literal moreinfo="none">To:</literal>", +is tokenized by <function moreinfo="none">rfc822t_alloc</function>(), then parsed by +<function moreinfo="none">rfc822a_alloc</function>(). +"<literal moreinfo="none">recipient-list:</literal>" and +the trailing semicolon is a legacy mailing list specification that is no +longer in widespread use, but must still must be accounted for. The resulting +<structname>rfc822a</structname> structure will have four +<structname>rfc822addr</structname> structures: one for +"<literal moreinfo="none">recipient-list:</literal>"; +one for each address; and one for the trailing semicolon. +Each <structname>rfc822a</structname> structure has the following +fields:</para> +      <informalexample> +	<programlisting format="linespecific"> +struct rfc822addr { +        struct rfc822token *tokens; +        struct rfc822token *name; +} ; +</programlisting> +      </informalexample> + +      <para> +If <structfield>tokens</structfield> is a null pointer, this structure +represents some +non-address portion of the original header, such as +"<literal moreinfo="none">recipient-list:</literal>" or a +semicolon.  Otherwise it points to a structure that represents the E-mail +address in tokenized form.</para> + +      <para> +<structfield>name</structfield> either points to the tokenized form of a +non-address portion of +the original header, or to a tokenized form of the recipient's name. +<structfield>name</structfield> will be NULL if the recipient name was not provided. For the +following address: +<literal moreinfo="none">Tom Jones <tjones@example.com></literal> - the +<structfield>tokens</structfield> field points to the tokenized form of +"<literal moreinfo="none">tjones@example.com</literal>", +and <structfield>name</structfield> points to the tokenized form of +"<literal moreinfo="none">Tom Jones</literal>".</para> + +      <para> +Each <structname>rfc822token</structname> structure contains the following +fields:</para> +      <informalexample> +	<programlisting format="linespecific"> +struct rfc822token { +        struct rfc822token *next; +        int token; +        const char *ptr; +        int len; +} ; +</programlisting> +      </informalexample> + +      <para> +The <structfield>next</structfield> pointer builds a linked list of all +tokens in this name or +address.  The possible values for the <structfield>token</structfield> field +are:</para> + +      <variablelist> +	<varlistentry> +	  <term>0x00</term> +	  <listitem> +	    <para> +This is a simple atom - a sequence of non-special characters that +is delimited by whitespace or special characters (see below).</para> +	  </listitem> +	</varlistentry> +	<varlistentry> +	  <term>0x22</term> +	  <listitem> +	    <para> +The value of the ascii quote - this is a quoted string.</para> +	  </listitem> +	</varlistentry> +	<varlistentry> +	  <term>Open parenthesis: '('</term> +	  <listitem> +	    <para> +This is an old style comment.  A deprecated form of E-mail +addressing uses - for example - +"<literal moreinfo="none">john@example.com (John Smith)</literal>" instead of +"<literal moreinfo="none">John Smith <john@example.com></literal>". +This old-style notation defined +parenthesized content as arbitrary comments. +The <structname>rfc822token</structname> with +<structfield>token</structfield> set to '(' is created for the contents of +the entire comment.</para> +	  </listitem> +	</varlistentry> +	<varlistentry> +	  <term>Symbols: '<', '>', '@', and many others</term> +	  <listitem> +	    <para> +The remaining possible values of <structfield>token</structfield> include all +the characters in RFC 822 headers that have special significance.</para> +	  </listitem> +	</varlistentry> +      </variablelist> + +      <para> +When a <structname>rfc822token</structname> structure does not represent a +special character, the <structfield>ptr</structfield> field points to a text +string giving its contents. +The contents are NOT null-terminated, the <structfield>len</structfield> +field contains the number of characters included. +The macro rfc822_is_atom(token) indicates whether +<structfield>ptr</structfield> and <structfield>len</structfield> are used for +the given <structfield>token</structfield>. +Currently <function moreinfo="none">rfc822_is_atom</function>() returns true if +<structfield>token</structfield> is a zero byte, '<literal moreinfo="none">"</literal>', or +'<literal moreinfo="none">(</literal>'.</para> + +      <para> +Note that it's possible that <structfield>len</structfield> might be zero. +This happens with null addresses used as return addresses for delivery status +notifications.</para> +    </refsect2> + +    <refsect2> +      <title>Working with E-mail addresses</title> +      <informalexample> +	<programlisting format="linespecific"> +void rfc822_deladdr(struct rfc822a *addrs, int index); + +void rfc822tok_print(const struct rfc822token *list, +        void (*func)(char, void *), void *func_arg); + +void rfc822_print(const struct rfc822a *addrs, +        void (*print_func)(char, void *), +        void (*print_separator)(const char *, void *), void *callback_arg); +  +void rfc822_addrlist(const struct rfc822a *addrs, +                void (*print_func)(char, void *), +                void *callback_arg); +  +void rfc822_namelist(const struct rfc822a *addrs, +                void (*print_func)(char, void *), +                void *callback_arg); + +void rfc822_praddr(const struct rfc822a *addrs, +                int index, +                void (*print_func)(char, void *), +                void *callback_arg); + +void rfc822_prname(const struct rfc822a *addrs, +                int index, +                void (*print_func)(char, void *), +                void *callback_arg); + +void rfc822_prname_orlist(const struct rfc822a *addrs, +                int index, +                void (*print_func)(char, void *), +                void *callback_arg); + +char *rfc822_gettok(const struct rfc822token *list); +char *rfc822_getaddrs(const struct rfc822a *addrs); +char *rfc822_getaddr(const struct rfc822a *addrs, int index); +char *rfc822_getname(const struct rfc822a *addrs, int index); +char *rfc822_getname_orlist(const struct rfc822a *addrs, int index); + +char *rfc822_getaddrs_wrap(const struct rfc822a *, int); +</programlisting> +      </informalexample> + +      <para> +These functions are used to work with individual addresses that are parsed +by <function moreinfo="none">rfc822a_alloc</function>().</para> + +      <para> +<function moreinfo="none">rfc822_deladdr</function>() removes a single +<structname>rfc822addr</structname> structure, whose +<parameter moreinfo="none">index</parameter> is given, from the address array in +<structname>rfc822addr</structname>. +<structfield>naddrs</structfield> is decremented by one.</para> + +      <para> +<function moreinfo="none">rfc822tok_print</function>() converts a tokenized +<parameter moreinfo="none">list</parameter> of <structname>rfc822token</structname> +objects into a text string. The callback function, +<parameter moreinfo="none">func</parameter>, is called one +character at a time, for every character in the tokenized objects. An +arbitrary pointer, <parameter moreinfo="none">func_arg</parameter>, is passed unchanged as +the additional argument to the callback function. +<function moreinfo="none">rfc822tok_print</function>() is not usually the most +convenient and efficient function, but it has its uses.</para> + +      <para> +<function moreinfo="none">rfc822_print</function>() takes an entire +<structname>rfc822a</structname> structure, and uses the +callback functions to print the contained addresses, in their original form, +separated by commas. The function pointed to by +<parameter moreinfo="none">print_func</parameter> is used to +print each individual address, one character at a time.  Between the +addresses, the <parameter moreinfo="none">print_separator</parameter> function is called to +print the address separator, usually the string ", ". +The <parameter moreinfo="none">callback_arg</parameter> argument is passed +along unchanged, as an additional argument to these functions.</para> + +      <para> +The functions <function moreinfo="none">rfc822_addrlist</function>() and +<function moreinfo="none">rfc822_namelist</function>() also print the +contents of the entire <structname>rfc822a</structname> structure, but in a +different way. +<function moreinfo="none">rfc822_addrlist</function>() prints just the actual E-mail +addresses, not the recipient +names or comments.  Each E-mail address is followed by a newline character. +<function moreinfo="none">rfc822_namelist</function>() prints just the names or comments, +followed by newlines.</para> + +      <para> +The functions <function moreinfo="none">rfc822_praddr</function>() and +<function moreinfo="none">rfc822_prname</function>() are just like +<function moreinfo="none">rfc822_addrlist</function>() and +<function moreinfo="none">rfc822_namelist</function>(), except that they print a single name +or address in the <structname>rfc822a</structname> structure, given its +<parameter moreinfo="none">index</parameter>. The +functions <function moreinfo="none">rfc822_gettok</function>(), +<function moreinfo="none">rfc822_getaddrs</function>(), <function moreinfo="none">rfc822_getaddr</function>(), +and <function moreinfo="none">rfc822_getname</function>() are equivalent to +<function moreinfo="none">rfc822tok_print</function>(), <function moreinfo="none">rfc822_print</function>(), +<function moreinfo="none">rfc822_praddr</function>() and <function moreinfo="none">rfc822_prname</function>(), +but, instead of using a callback function +pointer, these functions write the output into a dynamically allocated buffer. +That buffer must be destroyed by <function moreinfo="none">free</function>(3) after use. +These functions will +return a null pointer in the event of a failure to allocate memory for the +buffer.</para> + +      <para> +<function moreinfo="none">rfc822_prname_orlist</function>() is similar to +<function moreinfo="none">rfc822_prname</function>(), except that it will +also print the legacy RFC822 group list syntax (which are also parsed by +<function moreinfo="none">rfc822a_alloc</function>()).  <function moreinfo="none">rfc822_praddr</function>() +will print an empty string for an index +that corresponds to a group list name (or terminated semicolon). +<function moreinfo="none">rfc822_prname</function>() will also print an empty string. +<function moreinfo="none">rfc822_prname_orlist</function>() will +instead print either the name of the group list, or a single string ";". +<function moreinfo="none">rfc822_getname_orlist</function>() will instead save it into a +dynamically allocated buffer.</para> + +      <para> +The function <function moreinfo="none">rfc822_getaddrs_wrap</function>() is similar to +<function moreinfo="none">rfc822_getaddrs</function>(), except +that the generated text is wrapped on or about the 73rd column, using +newline characters.</para> + +    </refsect2> + +    <refsect2> +      <title>Working with dates</title> +      <informalexample> +	<programlisting format="linespecific"> +time_t timestamp=rfc822_parsedt(const char *datestr) +const char *datestr=rfc822_mkdate(time_t timestamp); +void rfc822_mkdate_buf(time_t timestamp, char *buffer); +</programlisting> +      </informalexample> + +      <para> +These functions convert between timestamps and dates expressed in the +<literal moreinfo="none">Date:</literal> E-mail header format.</para> + +      <para> +<function moreinfo="none">rfc822_parsedt</function>() returns the timestamp corresponding to +the given date string (0 if there was a syntax error).</para> + +      <para> +<function moreinfo="none">rfc822_mkdate</function>() returns a date string corresponding to +the given timestamp. +<function moreinfo="none">rfc822_mkdate_buf</function>() writes the date string into the +given buffer instead, +which must be big enough to accommodate it.</para> + +    </refsect2> + +    <refsect2> +      <title>Working with 8-bit MIME-encoded headers</title> + +      <informalexample> +	<programlisting format="linespecific"> +int error=rfc2047_decode(const char *text, +                int (*callback_func)(const char *, int, const char *, void *), +                void *callback_arg); +  +extern char *str=rfc2047_decode_simple(const char *text); +  +extern char *str=rfc2047_decode_enhanced(const char *text, +                const char *charset); +  +void rfc2047_print(const struct rfc822a *a, +        const char *charset, +        void (*print_func)(char, void *), +        void (*print_separator)(const char *, void *), void *); + +  +char *buffer=rfc2047_encode_str(const char *string, +                const char *charset); +  +int error=rfc2047_encode_callback(const char *string, +        const char *charset, +        int (*func)(const char *, size_t, void *), +        void *callback_arg); +  +char *buffer=rfc2047_encode_header(const struct rfc822a *a, +        const char *charset); +</programlisting> +      </informalexample> + +      <para> +These functions provide additional logic to encode or decode 8-bit content +in 7-bit RFC 822 headers, as specified in RFC 2047.</para> + +      <para> +<function moreinfo="none">rfc2047_decode</function>() is a basic RFC 2047 decoding function. +It receives a +pointer to some 7bit RFC 2047-encoded text, and a callback function.  The +callback function is repeatedly called. Each time it's called it receives a +piece of decoded text. The arguments are: a pointer to a text fragment, number +of bytes in the text fragment, followed by a pointer to the character set of +the text fragment. The character set pointer is NULL for portions of the +original text that are not RFC 2047-encoded.</para> + +      <para> +The callback function also receives <parameter moreinfo="none">callback_arg</parameter>, as +its last +argument. If the callback function returns a non-zero value, +<function moreinfo="none">rfc2047_decode</function>() +terminates, returning that value.  Otherwise, +<function moreinfo="none">rfc2047_decode</function>() returns 0 after +a successful decoding. <function moreinfo="none">rfc2047_decode</function>() returns -1 if it +was unable to allocate sufficient memory.</para> + +      <para> +<function moreinfo="none">rfc2047_decode_simple</function>() and +<function moreinfo="none">rfc2047_decode_enhanced</function>() are alternatives to +<function moreinfo="none">rfc2047_decode</function>() which forego a callback function, and +return the decoded text +in a dynamically-allocated memory buffer. The buffer must be +<function moreinfo="none">free</function>(3)-ed after +use. <function moreinfo="none">rfc2047_decode_simple</function>() discards all character set +specifications, and +merely decodes any 8-bit text. <function moreinfo="none">rfc2047_decode_enhanced</function>() +is a compromise to +discarding all character set information.  The local character set being used +is specified as the second argument to +<function moreinfo="none">rfc2047_decode_enhanced</function>().  Any RFC +2047-encoded text in a different character set will be prefixed by the name of +the character set, in brackets, in the resulting output.</para> + +      <para> +<function moreinfo="none">rfc2047_decode_simple</function>() and +<function moreinfo="none">rfc2047_decode_enhanced</function>() return a null pointer +if they are unable to allocate sufficient memory.</para> + +      <para> +The <function moreinfo="none">rfc2047_print</function>() function is equivalent to +<function moreinfo="none">rfc822_print</function>(), followed by +<function moreinfo="none">rfc2047_decode_enhanced</function>() on the result.  The callback +functions are used in +an identical fashion, except that they receive text that's already +decoded.</para> + +      <para> +The function <function moreinfo="none">rfc2047_encode_str</function>() takes a +<parameter moreinfo="none">string</parameter> and <parameter moreinfo="none">charset</parameter> +being the name of the local character set, then encodes any 8-bit portions of +<parameter moreinfo="none">string</parameter> using RFC 2047 encoding. +<function moreinfo="none">rfc2047_encode_str</function>() returns a +dynamically-allocated buffer with the result, which must be +<function moreinfo="none">free</function>(3)-ed after +use, or NULL if there was insufficient memory to allocate the buffer.</para> + +      <para> +The function <function moreinfo="none">rfc2047_encode_callback</function>() is similar to +<function moreinfo="none">rfc2047_encode_str</function>() +except that the callback function is repeatedly called to received the +encoding string.  Each invocation of the callback function receives a pointer +to a portion of the encoded text, the number of characters in this portion, +and <parameter moreinfo="none">callback_arg</parameter>.</para> + +      <para> +The function <function moreinfo="none">rfc2047_encode_header</function>() is basically +equivalent to <function moreinfo="none">rfc822_getaddrs</function>(), followed by +<function moreinfo="none">rfc2047_encode_str</function>();</para> + +    </refsect2> + +    <refsect2> + +      <title>Working with subjects</title> + +      <informalexample> +	<programlisting format="linespecific"> +char *basesubj=rfc822_coresubj(const char *subj); + +char *basesubj=rfc822_coresubj_nouc(const char *subj); +</programlisting> +      </informalexample> + +      <para> +This function takes the contents of the subject header, and returns the +"core" subject header that's used in the specification of the IMAP THREAD +function. This function is designed to strip all subject line artifacts that +might've been added in the process of forwarding or replying to a message. +Currently, <function moreinfo="none">rfc822_coresubj</function>() performs the following transformations:</para> +      <variablelist> +	<varlistentry> +	  <term>Whitespace</term> +	  <listitem> +	    <para>Leading and trailing whitespace is removed.  Consecutive +whitespace characters are collapsed into a single whitespace character. +All whitespace characters are replaced by a space.</para> +	  </listitem> +	</varlistentry> +	<varlistentry> +	  <term>Re:, (fwd) [foo]</term> +	  <listitem> +	    <para> +These artifacts (and several others) are removed from +the subject line.</para> +	  </listitem> +	</varlistentry> +      </variablelist> + +      <para>Note that this function does NOT do MIME decoding.  In order to +implement IMAP THREAD, it is necessary to call something like +<function moreinfo="none">rfc2047_decode</function>() before +calling <function moreinfo="none">rfc822_coresubj</function>().</para> + +      <para> +This function returns a pointer to a dynamically-allocated buffer, which +must be <function moreinfo="none">free</function>(3)-ed after use.</para> + +      <para> +<function moreinfo="none">rfc822_coresubj_nouc</function>() is like +<function moreinfo="none">rfc822_coresubj</function>(), except that the subject +is not converted to uppercase.</para> +    </refsect2> +  </refsect1> + +  <refsect1> +    <title>SEE ALSO</title> + +    <para> +<ulink url="rfc2045.html"><citerefentry><refentrytitle>rfc2045</refentrytitle><manvolnum>3</manvolnum></citerefentry></ulink>, +<ulink url="reformail.html"><citerefentry><refentrytitle>reformail</refentrytitle><manvolnum>1</manvolnum></citerefentry></ulink>, +<ulink url="reformime.html"><citerefentry><refentrytitle>reformime</refentrytitle><manvolnum>1</manvolnum></citerefentry></ulink>.</para> +  </refsect1> +</refentry> | 
