"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "inn-2.4.5/HACKING" of archive inn-2.4.5.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 Hacking INN
    2 
    3     This file is for people who are interested in making modifications to
    4     INN.  Normal users can safely skip reading it.  It is intended primarily
    5     as a guide, resource, and accumulation of tips for maintainers and
    6     contributors, and secondarily as documentation of some of INN's
    7     internals.
    8 
    9     This is $Revision: 7736 $ dated $Date: 2006-04-15 04:52:06 +0200 (Sat,
   10     15 Apr 2006) $.
   11 
   12     First of all, if you plan on working on INN source, please start from
   13     the current development tree.  There may be significant changes from the
   14     previous full release, so starting from development sources will make it
   15     considerably easier to integrate your work.  You can get nightly
   16     snapshots of the current development source from ftp.isc.org in
   17     /isc/inn/snapshots (the snapshots named inn-CURRENT-*.tar.gz), or you
   18     can get the current CVS tree by using CVSup (see "Using CVSup").
   19 
   20 Configuring and Portability
   21 
   22     All INN code should be written expecting ANSI C and POSIX.  There is no
   23     need to attempt to support pre-ANSI compilers, and ANSI-only features
   24     such as <stdarg.h>, string concatenation, #elif, and token pasting may
   25     be used freely.  So far as possible, INN is written to attempt to be
   26     portable to any system new enough that someone is likely to want to run
   27     a news server on it, but whenever possible this portability should be
   28     provided by checking for standard behavior in configure and supplying
   29     replacements for standard functions that are missing.
   30 
   31     When there is a conflict between ANSI C and C99, INN code should be
   32     written expecting C99 and autoconf used to patch up the differences.
   33 
   34     Try to avoid using #ifdef and the like in the middle of code as much as
   35     possible.  Instead, try to isolate the necessary portability bits and
   36     include them in libinn or at least in conditional macros separate from
   37     the code.  Trying to read code littered with conditional compilation
   38     directives is much more difficult.
   39 
   40     The shell script configure at the top level of the source tree is
   41     generated by autoconf from configure.in, and include/config.h.in is
   42     generated by autoheader from configure.in and include/acconfig.h.  At
   43     configure time, configure generates include/config.h and several other
   44     files based on options it was given and what it discovers about the
   45     target system.
   46 
   47     All modifications to configure should instead be made to configure.in. 
   48     Similarly, modifications to include/config.h.in should instead be made
   49     to include/acconfig.h.  The autoconf manual (available using info
   50     autoconf if you have autoconf and the GNU info utilities installed on
   51     your system) is a valuable reference when making any modifications.
   52 
   53     To regenerate configure, just run "autoconf".  To regenerate
   54     include/config.h.in, run:
   55 
   56         autoheader -l include
   57 
   58     to tell it where to find acconfig.h.  Please don't include patches to
   59     either configure or include/config.h.in when sending patches to INN;
   60     instead, note in your patch that those files must be regenerated.
   61 
   62     The generated files are checked into the CVS repository so that people
   63     working on INN don't have to have autoconf on their system, and to make
   64     packaging easier.
   65 
   66     At the time of this writing, autoconf 2.13 is required.
   67 
   68     The supporting files for autoconf are in the support subdirectory,
   69     including the files config.guess and config.sub to determine the system
   70     name and and ltmain.sh for libtool support.  The latter file comes from
   71     the libtool distribution; the canonical version of the former two are
   72     available from ftp.gnu.org in /gnu/config.  In addition, m4/libtool.m4
   73     is just a copy of libtool.m4 from the libtool distribution.  (Using
   74     libtool without using automake requires a few odd hacks.)  These files
   75     used to be on a separate vendor branch so that we could make local
   76     modifications, but local modifications have not been necessary for some
   77     time.  Now, new versions can just be checked in like any other file
   78     modifications.
   79 
   80     INN should not compile with libtool by default, only when requested,
   81     since otherwise normal compilations are quite slow.  (Using libtool is
   82     not without some cost.)  Basic compilation with libtool works fine as of
   83     this writing, with both static and shared compiles, but the dependencies
   84     aren't quite right for make -j using libtool.
   85 
   86 Documentation
   87 
   88     INN's documentation is currently somewhat in a state of flux.  The vast
   89     majority is still in the form of man pages written directly in nroff. 
   90     Some parts of the documentation have been rewritten in POD; that
   91     documentation can be found in doc/pod.  The canonical source for README,
   92     INSTALL, NEWS, doc/hook-perl, doc/hook-python, and this file are also in
   93     POD.
   94 
   95     If you're modifying some part of INN's documentation and see that it has
   96     a POD version in doc/pod, it's preferred if you can make the
   97     modifications to the POD source and then regenerate the derived files. 
   98     For a quick introduction to POD, see the perlpod(1) man page on your
   99     system (it should be installed if you have Perl installed).
  100 
  101     When writing new documentation, write in whatever format you care to; if
  102     necessary, we can always convert it to POD or whatever else we want to
  103     use.  Having the documentation exist in *some* form is more important
  104     than what language you write it in.  If you really don't have any
  105     particular preference, there's a slight preference currently for POD.
  106 
  107     If you use POD or regenerate POD documentation, please install something
  108     close to the latest versions of the POD processing utilities to avoid
  109     changes to the documentation depending on who generated it last.  You
  110     can find the latest version on CPAN (ftp.perl.org or another mirror) in
  111     modules/by-module/Pod.  You'll need PodParser (for versions of Perl
  112     before 5.6.1; 5.6.1 and later come with a recent enough version) and the
  113     latest version of podlators.  For versions of Perl earlier than 5.005,
  114     you'll also need File::Spec in modules/by-module/File.
  115 
  116     podlators 1.25 or later will build INN's documentation without
  117     significant changes from the versions that are checked into the
  118     repository.
  119 
  120     There are Makefile rules in doc/pod/Makefile to build all of the
  121     documentation whose master form is POD; if you add additional
  122     documentation, please add a rule there as well.  Documentation should be
  123     generated by cd'ing to doc/pod and typing "make file" where "file" is
  124     the relative path to the documentation file.  This will get all of the
  125     various flags right for pod2text or pod2man.
  126 
  127 Error Handling
  128 
  129     INN has a set of generic error handling routines that should be used as
  130     much as possible so that the same syntax can be used for reporting
  131     errors everywhere in INN.  The four basic functions are warn, syswarn,
  132     die, and sysdie; warn prints or logs a warning, and die does the same
  133     and then exits the current program.  The sys* versions add a colon, a
  134     space, and the value of strerror(errno) to the end of the message, and
  135     should be used to report failing system calls.
  136 
  137     All of the actual error reporting is done via error handlers, and a
  138     program can register its own handlers in addition to or instead of the
  139     default one.  The default error handler (error_log_stderr) prints to
  140     stderr, prepending the value of error_program_name if it's set to
  141     something other than NULL.  Three other error handlers are available,
  142     error_log_syslog_crit, error_log_syslog_err, and
  143     error_log_syslog_warning, which log the message to syslog at LOG_CRIT,
  144     LOG_ERR, or LOG_WARNING priority, respectively.
  145 
  146     There is a different set of error handlers for warn/syswarn and
  147     die/sysdie.  To set them, make calls like:
  148 
  149         warn_set_handlers(2, error_log_stderr, error_log_syslog_warning);
  150         die_set_handlers(2, error_log_stderr, error_log_syslog_err);
  151 
  152     The first argument is the number of handlers, and the remaining
  153     arguments are pointers to functions taking an int (the length of the
  154     formatted message), a const char * (the format), a va_list (the
  155     arguments), and an int that's 0 if warn or die was called and equal to
  156     the value of errno if syswarn or sysdie was called.  The length of the
  157     formatted message is obtained by calling vsnprintf with the provided
  158     format and arguments, and therefore is reliable to use as the size of a
  159     buffer to malloc to hold the result of formatting the message provided
  160     that vsnprintf is used to format it (warning: the system vsprintf may
  161     produce more output under some circumstances, so always use vsnprintf).
  162 
  163     The error handler can do anything it wishes; each error handler is
  164     called in the sequence given.  Error handlers shouldn't call warn or die
  165     unless great caution is taken to prevent infinite recursion.  Also be
  166     aware that sysdie is called if malloc fails in xmalloc, so if the error
  167     handler needs to allocate memory, it must not use xmalloc or a related
  168     function to do so and it shouldn't call die to report failure.  The
  169     default syslog handlers report memory allocation failure to stderr and
  170     exit.
  171 
  172     Finally, die and sysdie support an additional handler that's called
  173     immediate before exiting, takes no arguments, and returns an int which
  174     is used as the argument for exit.  It can do any necessary global
  175     cleanup, call abort instead to generate a core dump or the like.
  176 
  177     The advantage of using this system everywhere in INN is that library
  178     code can use warn and die to report errors and each calling program can
  179     set up the error handlers as appropriate to make sure the errors go to
  180     the right place.  The default handler is fine for interactive programs;
  181     for programs that run from interactive scripts, adding something like:
  182 
  183         error_program_name = "program";
  184 
  185     to the beginning of main (where program is the name of the program) will
  186     make it easier to figure out which program the script calls is failing. 
  187     For programs that may also be called non-interactively, like inndstart,
  188     one may want to set up handlers like:
  189 
  190         warn_set_handlers(2, error_log_stderr, error_log_syslog_warning);
  191         die_set_handlers(2, error_log_stderr, error_log_syslog_err);
  192 
  193     Finally, for daemons and other non-interactive programs, one may want to
  194     do:
  195 
  196         warn_set_handlers(1, error_log_syslog_warning);
  197         die_set_handlers(1, error_log_syslog_err);
  198 
  199     to report errors only via syslog.  (Note that if you use syslog error
  200     handlers, the program should call openlog first thing to make sure they
  201     are logged with the right facility.)
  202 
  203     For historical reasons, error messages that are fatal to the news
  204     subsystem are logged at the LOG_CRIT priority, and therefore die in innd
  205     should use error_log_syslog_crit.
  206 
  207 Test Suite
  208 
  209     The test suite for INN is located in the tests directory and is just
  210     getting started.  The test suite consists of a set of programs listed in
  211     tests/TESTS and the scaffolding in the runtests program.
  212 
  213     Adding new tests is very straightforward and very flexible.  Just write
  214     a program that tests some part of INN, put it in a directory under tests
  215     named after the part of INN it's testing (all the tests so far are in
  216     lib because they're testing libinn routines), and have it output first a
  217     line containing the count of test cases in that file, and then for each
  218     test a line saying "ok n" or "not ok n" where n is the test case number.
  219     (If a test is skipped for some reason, such as a test of an optional
  220     feature that wasn't compiled into INN, the test program should output
  221     "ok n # skip".)  Add any rules necessary to build the test to
  222     tests/Makefile (note that for simplicity it doesn't recurse into
  223     subdirectories) and make sure it creates an executable ending in .t. 
  224     Then add the name of the test to tests/TESTS, without the .t ending.
  225 
  226     One naming convention:  to distinguish more easily between e.g. 
  227     lib/error.c (the implementation) and tests/lib/error-t.c (the test
  228     suite), we add -t to the end of the test file names.  So
  229     tests/lib/error-t.c is the source that compiles into an executable
  230     tests/lib/error.t which is run by putting a line in tests/TESTS of just
  231     "lib/error".
  232 
  233     Note that tests don't have to be written in C; in fact, lib/xmalloc.t is
  234     just a shell script (that calls a supporting C program).  Tests can be
  235     written in shell or Perl (but other languages should be avoided because
  236     someone who wants to run the test suite may not have it) and just have
  237     to follow the above output conventions.
  238 
  239     Additions to the test suite, no matter how simple, are very welcome.
  240 
  241 Makefiles
  242 
  243     All INN makefiles include Makefile.global at the top level, and only
  244     that makefile is a configure substitution target.  This has the
  245     disadvantage that configure's normal support for building in a tree
  246     outside of the source tree doesn't work, but it has the significant
  247     advantage of making configure run much faster and allowing one to run
  248     make in any subdirectory and pick up all the definitions and settings
  249     from the top level configuration.
  250 
  251     All INN makefiles should also set $(top) to be the path to the top of
  252     the build directory (usually relative).  This path is used to find
  253     various programs like fixscript and libtool so that the same macros (set
  254     in Makefile.global) can be used all over INN.
  255 
  256     The format of INN's makefiles is mostly standardized; the best examples
  257     of the format are probably frontends/Makefile and backends/Makefile, at
  258     least for directories with lots of separate programs.  The ALL variable
  259     holds all the files that should be generated, EXTRA those additional
  260     files that were generated by configure, and SOURCES the C source files
  261     for generating tag information.
  262 
  263     There are a set of standard installation commands defined in make
  264     variables by Makefile.global, and these should be used for all file
  265     installations.  See the comment blocks in Makefile.global.in for
  266     information on what commands are available and when they should be used.
  267     There are also variables set for each of the installation directories
  268     that INN uses, for use in building the list of installed paths to files.
  269 
  270     Each subdirectory makefile should have the targets all (the default),
  271     clean, clobber, install, tags, and profiled.  The tags target generates
  272     vi tags files, and the profiled target generates a profiling version of
  273     the programs (although this hasn't been tested much recently).  These
  274     rules should be present and empty in those directories where they don't
  275     apply.
  276 
  277     Be sure to test compiling with both static and dynamic libraries and
  278     make sure that all the libtool support works correctly.  All linking
  279     steps, and the compile steps for all library source, should be done
  280     through $(LIBTOOL) (which will be set to empty in Makefile.global if
  281     libtool support isn't desired).
  282 
  283 Scripts
  284 
  285     INN comes with and installs a large number of different scripts, both
  286     Bourne shell and Perl, and also comes with support for Tcl scripts
  287     (although it doesn't come with any).  Shell variables containing both
  288     configure-time information and configuration information from inn.conf
  289     are set by the innshellvars support libraries, so the only
  290     system-specific configuration that should have to be done is fixing the
  291     right path to the interpretor and adding a line to load the appropriate
  292     innshellvars.
  293 
  294     support/fixscript, built by configure, does this.  It takes a .in file
  295     and generates the final script (removing the .in) by fixing the path to
  296     the interpretor on the first line and replacing the second line,
  297     whatever it is, with code to load the innshellvars appropriate for that
  298     interpretor.  (If invoked with -i, it just fixes the interpretor path.)
  299 
  300     Scripts should use innshellvars (via fixscript) to get the right path
  301     and the right variables whenever possible, rather than having configure
  302     substitute values in them.  Any values needed at run-time should instead
  303     be available from all of the different innshellvars.
  304 
  305     See the existing scripts for examples of how this is done.
  306 
  307 Include Files
  308 
  309     Include files relevant to all of INN, or relevant to the two libraries
  310     built as part of INN (the utility libinn library and the libstorage
  311     library that contains all storage and overview functions) are found in
  312     the include directory; other include files relevant only to a portion of
  313     INN are found in the relevant directory.
  314 
  315     Practically all INN source files will start with:
  316 
  317         #include "config.h"
  318         #include "clibrary.h"
  319 
  320     The first picks up all defines generated by autoconf and is necessary
  321     for types that may not be present on all systems (uid_t, pid_t, size_t,
  322     int32_t, and the like).  It therefore should be included before any
  323     other headers that use those types, as well as to get general
  324     configuration information.
  325 
  326     The second is portably equivalent to:
  327 
  328         #include <sys/types.h>
  329         #include <stdarg.h>
  330         #include <stdio.h>
  331         #include <stdlib.h>
  332         #include <stddef.h>
  333         #include <stdint.h>
  334         #include <string.h>
  335         #include <unistd.h>
  336 
  337     except that it doesn't include headers that are missing on a given
  338     system, replaces functions not found on the system with the INN
  339     equivalents, provides macros that INN assumes are available but which
  340     weren't found, and defines some additional portability things.  Even if
  341     this is more headers than the source file actually needs, it's generally
  342     better to just include clibrary.h rather than trying to duplicate the
  343     autoconf-driven hackery that it does to do things portably.  The primary
  344     exception is for source files in lib that only define a single function
  345     and are used for portability; those may want to include only config.h so
  346     that they can be easily used in other projects that use autoconf. 
  347     config.h is a fairly standard header name for this purpose.
  348 
  349     clibrary.h does also include config.h, but it's somewhat poor form to
  350     rely on this; it's better to explicitly list the header dependencies for
  351     the benefit of someone else reading the code.
  352 
  353     There are portable wrappers around several header files that have known
  354     portability traps or that need some fixing up on some platforms.  Look
  355     in include/portable and familiarize yourself with them and use them
  356     where appropriate.
  357 
  358     Another frequently included header file is libinn.h, which among other
  359     things defines xmalloc(), xrealloc(), xstrdup(), and xcalloc(), which
  360     are checked versions of the standard memory allocation routines that
  361     terminate the program if the memory allocation fails.  These should
  362     generally always be used instead of the regular C versions.  libinn.h
  363     also provides various other utility functions that are frequently used.
  364 
  365     paths.h includes a wide variety of paths determined at configure time,
  366     both default paths to various parts of INN and paths to programs.  Don't
  367     just use the default paths, though, if they're also configurable in
  368     inn.conf; instead, call ReadInnConf() and use the global innconf
  369     structure.
  370 
  371     Other files in include are interfaces to particular bits of INN library
  372     functionality or are used for other purposes; see the comments in each
  373     file.
  374 
  375     Eventually, the header files will be separated into installed header
  376     files and uninstalled header files; the latter are those headers that
  377     are used only for compiling INN and aren't useful for users of INN's
  378     libraries (such as clibrary.h).  All of the installed headers will live
  379     in include/inn and be installed in a subdirectory named inn in the
  380     configured include directory.  This conversion is still in progress.
  381 
  382     When writing header files, remember that C reserves all identifiers
  383     beginning with two underscores and all identifiers beginning with an
  384     underscore and a capital letter for the use of the implementation; don't
  385     use any identifiers with names like that.  Additionally, any identifier
  386     beginning with an underscore and a lower-case letter is reserved in file
  387     scope, which means that such identifiers can only be used by INN for the
  388     name of structure members or function arguments in function prototypes.
  389 
  390     Try to pay attention to the impact of a header file on the program
  391     namespace, particularly for installed header files in include/inn.  All
  392     symbols defined by a header file should ideally begin with INN_, inn_,
  393     or some other unique prefix indicating the subsystem that symbol is part
  394     of, to avoid accidental conflicts with symbols defined by the program
  395     that uses that header file.
  396 
  397 Coding Style
  398 
  399     INN has quite a variety of coding styles intermixed.  As with all
  400     programs, it's preferrable when making minor modifications to keep the
  401     coding style of the code you're modifying.  In INN, that will vary by
  402     file.  (Over time we're trying to standardize on one coding style, so
  403     changing the region you worked on to fit the general coding style is
  404     also acceptable).
  405 
  406     If you're writing a substantial new piece of code, the prevailing
  407     "standard" INN coding style appears to be something like the following:
  408 
  409     *  Write in regular ANSI C whenever possible.  Use the normal ANSI and
  410        POSIX constructs and use autoconf or portability wrappers to fix
  411        things up beforehand so that the code itself can read like regular
  412        ANSI or POSIX code.  Code should be written so that it works as
  413        expected on a modern platform and is fixed up with portability tricks
  414        for older platforms, not the other way around.  You may assume an
  415        ANSI C compiler.
  416 
  417        Try to use const wherever appropriate.  Don't use register; modern
  418        compilers will do as good of a job as you will in choosing what to
  419        put into a register.  Don't bother with restrict (at least yet).
  420 
  421     *  Use string handling functions that take counts for the size of the
  422        buffer whenever possible.  This means using snprintf in preference to
  423        sprintf and using strlcpy and strlcat in preference to strcpy and
  424        strcat.  Also, use strlcpy and strlcat instead of strncpy and strncat
  425        unless the behavior of the latter is specifically required, as it is
  426        much easier to audit uses of the former than the latter.  (strlcpy is
  427        like strncpy except that it always nul-terminates and doesn't fill
  428        the rest of the buffer with nuls, making it more efficient.  strlcat
  429        is like strncat except that it always nul-terminates and it takes the
  430        total size of the buffer as its third argument rather than just the
  431        amount of space left.)  All of these functions are guaranteed to be
  432        available; there are replacements in lib for systems that don't have
  433        them.
  434 
  435     *  Avoid #ifdef and friends whenever possible.  Particularly avoid using
  436        them in the middle of code blocks.  Try to hide all portability
  437        preprocessor magic in header files or in portability code in lib. 
  438        When something just has to be done two completely different ways
  439        depending on the platform or compile options or the like, try to
  440        abstract that functionality out into a generic function and provide
  441        two separate implementations using #ifdef; then the main code can
  442        just call that function.
  443 
  444        If you do have to use preprocessor defines, note that if you always
  445        define them to either 0 or 1 (never use #define without a second
  446        argument), you can use the preprocessor define in a regular if
  447        statement rather than using #if or #ifdef.  Make use of this instead
  448        of #ifdef when possible, since that way the compiler will still
  449        syntax-check the other branch for you and it makes it far easier to
  450        convert the code to use a run-time check if necessary. 
  451        (Unfortunately, this trick can't be used if one branch may call
  452        functions unavailable on a particular platform.)
  453 
  454     *  Avoid uses of fixed-width buffers except in performance-critical
  455        code, as it's harder to be sure that such code is correct and it
  456        tends to be less flexible later on.  If you need a reusable,
  457        resizable memory buffer, one is provided in lib/buffer.c.
  458 
  459     *  Avoid uses of static variables whenever possible, particularly in
  460        libraries, because it interferes with making the code re-entrant down
  461        the road and makes it harder to follow what's going on.  Similarly,
  462        avoid using global variables whenever possible, and if they are
  463        required, try to wrap them into structures that could later be
  464        changed into arguments to the affected functions.
  465 
  466     *  Roughly BSD style but with four-space indents.  This means no space
  467        before the parens around function arguments, open brace on the same
  468        line as if/while/for, and close and open brace on the same line as
  469        else).
  470 
  471     *  Introductory comments for functions or files are generally written
  472        as:
  473 
  474            /*
  475            **  Introductory comment.
  476            */
  477 
  478        Other multiline comments in the source are generally written as:
  479 
  480            /* This is a
  481               multiline comment. */
  482 
  483        Comments before functions saying what they do are nice to have.  In
  484        general, the RCS/CVS Id tag is on the first line of each source file
  485        since it's useful to know when a file was last modified.
  486 
  487     *  Checks for NULL pointers are preferrably written out explicitly; in
  488        other words, use:
  489 
  490            if (p != NULL)
  491 
  492        rather than:
  493 
  494            if (p)
  495 
  496        to make it clearer what the code is assuming.
  497 
  498     *  It's better to always put the body of an if statement on a separate
  499        line, even if it's only a single line.  In other words, write:
  500 
  501            if (p != NULL)
  502                return p;
  503 
  504        and not:
  505 
  506            if (p != NULL) return p;
  507 
  508        This is in part for a practical reason:  some code coverage analysis
  509        tools like purecov will count the second example above as a single
  510        line and won't notice if the condition always evaluates the same way.
  511 
  512     *  Plain structs make perfectly reasonable abstract data types; it's not
  513        necessary to typedef the struct to something else.  Structs are
  514        actually very useful for opaque data structures, since you can
  515        predeclare them and then manipulate pointers to them without ever
  516        having to know what the contents look like.  Please try to avoid
  517        typedefs except for function pointers or other extremely confusing
  518        data types, or for data types where we really gain some significant
  519        data abstraction from hiding the underlying data type.  Also avoid
  520        using the _t suffix for any type; all types ending in _t are reserved
  521        by POSIX.  For typedefs of function pointer types, a suffix of _func
  522        usually works.
  523 
  524        This style point is currently widely violated inside of INN itself;
  525        INN originally made extensive use of typedefs.
  526 
  527     *  When noting something that should be improved later, add a comment
  528        containing "FIXME:" so that one can easily grep for such comments.
  529 
  530     INN's indentation style roughly corresponds to that produced by GNU
  531     indent 2.2.6 with the following options:
  532 
  533         -bad -bap -nsob -fca -lc78 -cd41 -cp1 -br -ce -cdw -cli0 -ss -npcs
  534         -ncs -di1 -nbc -psl -brs -i4 -ci4 -lp -ts8 -nut -ip5 -lps -l78 -bbo
  535         -hnl
  536 
  537     Unfortunately, indent currently doesn't get everything right (it has
  538     problems with spacing around struct pointer arguments in functions,
  539     wants to put in a space between a dereference of a function pointer and
  540     the arguments to the called function, misidentifies some macro calls as
  541     being type declarations, and fouls up long but simple case statements). 
  542     It would be excellent if someday we could just run all of INN's code
  543     through indent routinely to enforce a consistant coding style, but
  544     indent isn't quite ready for that.
  545 
  546     For users of emacs cc-mode, use the "bsd" style but with:
  547 
  548         (setq c-basic-offset 4)
  549 
  550     Finally, if possible, please don't use tabs in source files, since they
  551     can expand differently in different environments.  In particular, please
  552     try not to use the mix of tabs and spaces that is the default in emacs. 
  553     If you use emacs to edit INN code, you may want to put:
  554 
  555         ; Use only spaces when indenting or centering, no tabs.
  556         (setq-default indent-tabs-mode nil)
  557 
  558     in your ~/.emacs file.
  559 
  560     Note that this is only a rough guideline and the maintainers aren't
  561     style nazis; we're more interested in your code contribution than in how
  562     you write it.
  563 
  564 Using CVSup
  565 
  566     If you want to get updated INN source more easily or more quickly than
  567     by downloading nightly snapshots, or if you want to see the full CVS
  568     history, you may want to use CVSup to download the source.  CVSup is a
  569     client and server designed for replicating CVS repositories between
  570     sites.
  571 
  572     Unfortunately, CVSup is written in Modula-3, so getting a working binary
  573     can be somewhat difficult.  Binaries are available in the *BSD ports
  574     collection or (for a wide variety of different platforms) available from
  575     <ftp://ftp.freebsd.org/pub/FreeBSD/CVSup/binaries/> and its mirrors. 
  576     Alternately, you can get a compiler from <http://m3.polymtl.ca/m3/>
  577     (this is more actively maintained than the DEC Modula-3 compiler) and
  578     the source from <ftp://ftp.freebsd.org/pub/FreeBSD/CVSup/>.
  579 
  580     After you have the CVSup client, you need to have space to download the
  581     INN repository and space for CVSup to store its data files.  You also
  582     need to write a configuration file (a supfile) for CVSup.  The following
  583     supfile will download the latest versions from the mainline source:
  584 
  585         *default host=inn-cvs.isc.org
  586         *default base=<data-location>
  587         *default prefix=<download-location>
  588         *default release=cvs
  589         *default tag=.
  590         *default delete use-rel-suffix
  591         inn
  592 
  593     where <data-location> should be a directory where CVSup can put its data
  594     files and <download-location> is where the downloaded source will go (it
  595     will be put into a subdirectory named inn).  If you want to pull down
  596     the entire CVS repository instead (warning: this is much larger than
  597     just the latest versions of the source), delete the "*default tag=."
  598     line.  The best way to download the CVS repository is to download it
  599     into a portion of a locally-created CVS repository, so that then you can
  600     perform standard CVS operations (like cvs log) against the downloaded
  601     repository.  Creating your own local CVS repository is outside the scope
  602     of this document.
  603 
  604     Note that only multiplexed mode is supported (this mode should be the
  605     default).
  606 
  607     For more general information on using CVSup, see the FreeBSD page on it
  608     at <http://www.freebsd.org/handbook/mirrors-cvsup.html>.
  609 
  610 Making a Release
  611 
  612     This is a checklist that INN maintainers should go through when
  613     preparing a new release of INN.
  614 
  615     1.  If making a major release, branch the source tree and create a new
  616         STABLE branch tag.  This branch will be used for minor releases
  617         based on that major release and can be done a little while before
  618         the .0 release of that major release.  At the same time as the
  619         branch is cut, tag the trunk with a STABLE-<version>-branch marker
  620         tag so that it's easy to refer to the trunk at the time of the
  621         branch.
  622 
  623     2.  Update doc/pod/news.pod and regenerate NEWS.  Be more detailed for a
  624         minor release than for a major release.  For a major release, also
  625         add information on how to upgrade from the last major release,
  626         including anything special to be aware of.  (Minor releases
  627         shouldn't require any special care when upgrading.)
  628 
  629     3.  Make sure that support/config.sub and support/config.guess are the
  630         latest versions (from <ftp://ftp.gnu.org/gnu/config/>).  See the
  631         instructions in "Configuring and Portability" for details on how to
  632         update these files.
  633 
  634     4.  Make sure that samples/control.ctl is in sync with the master
  635         version at <ftp://ftp.isc.org/pub/usenet/CONFIG/control.ctl>.
  636 
  637     5.  Check out a copy of the release branch.  It's currently necessary to
  638         run configure to generate Makefile.global.  Then run "make
  639         check-manifest".  The only differences should be files that are
  640         generated by configure; if there are any other differences, fix the
  641         MANIFEST.
  642 
  643     6.  Run "make release".  Note that you need to have a copy of svn2cl
  644         from <http://ch.tudelft.nl/~arthur/svn2cl/> to do this; at least
  645         version 0.7 is required.  Start the ChangeLog at the time of the
  646         previous release.  (Eventually, the script will be smart enough to
  647         do this for you.)
  648 
  649     7.  Make the resulting tar file available for testing in a non-listable
  650         directory on ftp.isc.org and announce its availability on
  651         inn-workers.  Install it on at least one system and make sure that
  652         system runs fine for at least a few days.  This is also a good time
  653         to send out a draft of the release announcement to inn-workers for
  654         proof-reading.
  655 
  656     8.  Generate a diff between this release and the previous release if
  657         feasible (always for minor releases, possibly not a good idea due to
  658         the length of the diff for major releases).
  659 
  660     9.  Move the release into the public area of the ftp site and update the
  661         inn.tar.gz link.  Make an MD5 checksum of the release tarball and
  662         put it on the ftp site as well, and update the inn.tar.gz.md5 link. 
  663         Put the diff up on the ftp site as well.  Contact the ISC folks to
  664         get the release PGP-signed.  Possibly move older releases off into
  665         the OLD directory.
  666 
  667     10. Announce the new release on inn-announce and in news.software.nntp.
  668 
  669     11. Tag the checked-out tree that was used for generating the release
  670         with a release tag (INN-<version>).
  671 
  672     12. Bump the revision number in Makefile.global.in.
  673 
  674 References
  675 
  676     Some additional references that may be hard to find and may be of use to
  677     people working on INN:
  678 
  679     <http://www.eyrie.org/~eagle/nntp/>
  680         The home page for the IETF NNTP standardization effort, including
  681         links to the IETF NNTP working group archives and copies of the
  682         latest drafts of the new NNTP standard.  The old archived mailing
  683         list traffic contains a lot of interesting discussion of why NNTP is
  684         the way it is.
  685 
  686     <http://www.imc.org/ietf-usefor/>
  687         The archives for the USEFOR IETF working group, the working group
  688         for the RFC 1036 replacement (the format of Usenet articles).  Also
  689         contains a lot of references to other relevant work, such as the RFC
  690         822 replacement work.
  691 
  692     <http://www.mibsoftware.com/userkt/inn/dev/>
  693         Forrest Cavalier provides several tools for following INN
  694         development at this page and elsewhere in the Usenet RKT.  Under
  695         here is a web-accessible checked-out copy of the current INN source
  696         tree and pointers to how to use CVSup.
  697 
  698     <http://www.sas.com/standards/large.file/>
  699         The standards for large file support on Unix that are being
  700         generally implemented by vendors.  INN sort of partially uses these,
  701         but a good full audit of the code to check them should really be
  702         done and there are occasional problems.
  703 
  704     <http://v6web.litech.org/ipv6primer/>
  705         A primer on IPv6 with pointers to the appropriate places for more
  706         technical details as needed, useful when working on IPv6 support in
  707         INN.
  708