                        MaraDNS' coding style

   MaraDNS is a divergent body of code that has been developed, in
   some form or other, for nearly a decade. While some changes have
   been made to that code during this time period, notably the tab
   and bracing style, some other things about the code have stayed
   the same. These coding style guidelines have always been in mind
   as I was writing MaraDNS code. Now that MaraDNS is becoming
   popular enough that other people are starting to contribute to
   it, I am documenting these guidelines so that people can make
   patches that I will accept.

   Please note that the only patches I will accept for MaraDNS 1.4
   and MaraDNS 2.0 are patches that fix bugs and do not add any
   features to the code. MaraDNS is open-source and people
   interesting in adding features to the code are free to make
   their own MaraDNS fork. Please do not name any such fork
   "MaraDNS".

   So, without further ado:

All indexed writes must be protected against overflows

   In other words, all code that writes to arrays must be checked,
   before a write is made, to verify that the write in question is
   within the bounds of the array. For example, this code violates
   MaraDNS coding styles:

         c = &some_array;
         while(*c != 0) {
                 if(*c > 'A' && *c < 'Z')
                         *c += 32;
                 c++;
         }

   In order for this kind of code to be accepted in to MaraDNS
   code, it must be revised to look like this:

         c = &some_array;
         limit = size_of_array;
         while(*c != 0 && limit > 0) {
                 if(*c > 'A' && *c < 'Z')
                         *c += 32;
                 c++;
                 limit--;
         }

All arrays must be at least one byte bigger than they should be

   All arrays must be at least one byte bigger than they should be,
   and should ideally be about three bytes bigger than they should
   be. In other words, let us suppose we have a character array
   that is MAX_BYTES long, where the bounds checking makes sure we
   don't write past MAX_BYTES. Then we declare the array in this
   form:

         char s[MAX_BYTES + 3];

   The reason for this 3-byte cushion is to prevent off-by-one
   errors. An off-by-one error can be very dangerous. This kind of
   error is why OpenBSD had a remote code execution exploit with
   its FTP daemon. In MaraDNS' code, there was once a potential
   buffer overflow that was only stopped because I always have
   these cushions at the end of arrays.

No old MaraDNS configuration file should be broken

   Unless there is a compelling reason to do so, no changes that
   break or change how an old mararc file or zone file is parsed
   should be done. For example, there is a mararc variable entitled
   default_rrany_set that does nothing in MaraDNS 1.2; we still
   support this variable (and have it do nothing) since people
   using MaraDNS since 1.0 might have this variable set.

   As another example, when I changed the zone file format in
   MaraDNS 1.3, I went to a good deal of effort to make sure over
   99% of MaraDNS 1.2 zone files work completely unchanged in
   MaraDNS 1.3, and that a MaraDNS user can set a single mararc
   variable, csv2_tilde_handling in order to make MaraDNS 1.4 100%
   compatible with MaraDNS 1.2 zone files.

   Indeed, MaraDNS 1.4 still supports MaraDNS 1.0 zone files, even
   though I am encouraging people to upgrade to the newer zone file
   format, and even though I have a Perl script that converts a
   MaraDNS 1.0 zone file in to a MaraDNS 1.2+ zone file.

   I have sometimes sometimes made old configuration files not
   compatible with newer versions of MaraDNS. These changes are
   only done when:

     * There is a compelling reason to make the change in question
     * The change in question impacts the minimum number of MaraDNS
       users
     * The change in question is fully documented in MaraDNS'
       upgrade document.

   For example, MaraDNS 1.0 had a bug where it would silently
   ignore a misspelled mararc parameter. In MaraDNS 1.2, I changed
   this behavior to one where MaraDNS will exit with a fatal error
   should there be a misspelled mararc variable. I made this change
   to make life easier for system administrators who are wondering
   why a change isn't working in MaraDNS because they made a typo
   in their mararc. This change, of course, is fully documented in
   the MaraDNS update document.

   The reason for this is because MaraDNS users have better things
   to do in their life than to follow every single change made to
   MaraDNS; it's difficult enough for people to adjust to MaraDNS.
   There is no good reason why we should force users to adjust to
   each new version just because we have some silly idea about what
   makes MaraDNS' configuration files neater. This is a problem
   Linux and X11 developers have; I have had to change my custom
   keyboard mapping file that allows me to type Spanish letters and
   accents on a US keyboard no less than twice in the last few
   years.

   There's also the issue, with French users of MaraDNS, of the
   French documentation not being updated since the 1.0 days of
   MaraDNS.

   Note that MaraDNS 2.0 will break many configurations, since the
   same IP will be unable to be both a recursive and authoritative
   DNS server. This is why I will continue to support MaraDNS 1.4
   for the foreseeable future even though MaraDNS 2.0 has been
   released.

Brace and tab style

   MaraDNS' tabbing and brace style has changed over the years. The
   current style is to not have tabs in the code at all; a script
   converts all tabs in to spaces every time MaraDNS is updated.
   When contributing new code to MaraDNS, keep this in mind:

     * When making a change to already existing code, try to
       maintain the bracing and spacing style of that code.
     * For new code, there is a somewhat informal bracing style.

   Here is the bracing and tab style for new code in MaraDNS:

 int main() {
         int a;
         for(a = 0; a < 100; a++ ) {
                 printf("a is %c\n",a);
         }
 }

Licensing and copyright issues

   Contributions made to MaraDNS can not be accepted unless you are
   willing to license your contributions under the conditions of
   MaraDNS' license, which is a BSD license as follows:

     Copyright (c) 2002-2010 Sam Trenholme and others

     TERMS

     Redistribution and use in source and binary forms, with or
     without modification, are permitted provided that the
     following conditions are met:

      1. Redistributions of source code must retain the above
         copyright notice, this list of conditions and the
         following disclaimer.
      2. Redistributions in binary form must reproduce the above
         copyright notice, this list of conditions and the
         following disclaimer in the documentation and/or other
         materials provided with the distribution.

     This software is provided 'as is' with no guarantees of
     correctness or fitness for purpose.

Contributed code must not break anything in MaraDNS

   Any contributed code, before it is accepted, must not break
   anything in MaraDNS. This means the following:

     * The patched code must compile with no warnings nor errors
       when compiling MaraDNS with -Wall set (the default when
       compiling MaraDNS).
     * The patched code must pass all tests in the sqa/regressions
       directory. To perform this test, first compile the patched
       MaraDNS. Next, enter the sqa/regressions directory. Next,
       become root. Finally sh ./do.tests

Finally, thank you for your interest in MaraDNS

   Finally, I would like to thank you for your interest in MaraDNS,
   and really appreciate the time you take to make patches for it.
   I hope these coding style guidelines are not too bothersome;
   they make MaraDNS' code a more secure, reliable DNS server.
