webserver.c


/*
 *
 * Code to implement a multithreaded midrange web server on Linux.
 *
 * This program was written by
 * Stephan K.H. Seidl <stephan.seidl@stfmc.de> in 2020,
 * no copyright is claimed.
 * It is offered as-is, without any warranty.
 * This program is in the public domain; do with it what you wish.
 *
 * This web server is stateful. Up to 256 clients are served in parallel.
 * Within a limited period of time, each individual client initiates
 * a synchronous handshake sequence, consisting of reserving a slot,
 * exchanging certain information, asking a series of questions that the
 * server must answer as quickly as possible, and finally releasing
 * the server slot reserved before.
 *
 * In terms of the algorithms, the big guns have been rolled out here.
 *
 * The idea for this code came up in 2017. It was then written in March 2020
 * and tested and stressed during the following months during the coronavirus
 * pandemic. Since May 2020, the code has been operating under production
 * conditions and, since July 2020, it has been doing what it has to do. The
 * latter will of course not say that there are no more errors to be found.
 * Anyway, feel free now. If you want, read the code below, understand it,
 * and copy whatever you would like to have from there.
 *
 * @(#)webserver.c 1.28 - 2020-09-28 skhs
 *
 */

/****************************************************************************/

#if (!defined (_GNU_SOURCE))
#define _GNU_SOURCE
#endif

#if (defined (_POSIX_C_SOURCE))
#undef _POSIX_C_SOURCE
#endif

#if (!defined (_FILE_OFFSET_BITS))
#define _FILE_OFFSET_BITS 64
#endif

/* This is for `size_t', according to ANSI. */
#include <stddef.h>
/* This is for `ssize_t', according to POSIX. */
#include <sys/types.h>

#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <pthread.h>
#include <signal.h>
#if (defined (c_plusplus) || defined (__cplusplus))
/* Just to allow the compilation with g++. */
typedef sig_atomic_t atomic_uint;
#else
#include <stdatomic.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/utsname.h>
#include <time.h>
#include <unistd.h>

/****************************************************************************/

#if (0)
#define MYWEBSERVER_PRODUCTION_VERSION 1
#endif

/****************************************************************************/

#define MYWEBSERVER_APPLICATION_NAME            "MY-NICE-APP"
#define MYWEBSERVER_MINIMUM_APPLICATION_VERSION "9.8.7"
#define MYWEBSERVER_FDEI_VERSION                "1.28.1"

/****************************************************************************/

#define MYWEBSERVER_FAVICON_URL "https://my-company.com/icons/favicon.ico"

/****************************************************************************/

#if (defined (MYWEBSERVER_PRODUCTION_VERSION))
#define MYWEBSERVER_ACCOUNTING_FILE_NAME_STEM "/some-directory/fdei/acc-"
#else
#define MYWEBSERVER_ACCOUNTING_FILE_NAME_STEM "/tmp/acc-"
#endif

/****************************************************************************/

#if (defined (MYWEBSERVER_PRODUCTION_VERSION))
#define MYWEBSERVER_DEFAULT_DEBUG                       1
#define MYWEBSERVER_DEFAULT_DEFENDER_EXPONENT           4
#define MYWEBSERVER_DEFAULT_KBYTES_DISK_OUT_BUFFER   8192
#define MYWEBSERVER_DEFAULT_KBYTES_PER_SLOT           256
#define MYWEBSERVER_DEFAULT_KBYTES_THREAD_STACKSIZE   256
#define MYWEBSERVER_DEFAULT_MILLISECS_TO_BE_SLEPT      20
#define MYWEBSERVER_DEFAULT_PORT                       80
#define MYWEBSERVER_DEFAULT_SLOT_NUMBER               256
#define MYWEBSERVER_DEFAULT_STATELOCATOR_LIFETIME      60
#else
#define MYWEBSERVER_DEFAULT_DEBUG                       2
#define MYWEBSERVER_DEFAULT_DEFENDER_EXPONENT           4
#define MYWEBSERVER_DEFAULT_KBYTES_DISK_OUT_BUFFER   8192
#define MYWEBSERVER_DEFAULT_KBYTES_PER_SLOT           256
#define MYWEBSERVER_DEFAULT_KBYTES_THREAD_STACKSIZE   256
#define MYWEBSERVER_DEFAULT_MILLISECS_TO_BE_SLEPT      20
#define MYWEBSERVER_DEFAULT_PORT                    12913
#define MYWEBSERVER_DEFAULT_SLOT_NUMBER               256
#define MYWEBSERVER_DEFAULT_STATELOCATOR_LIFETIME      60
#endif

/****************************************************************************/

#define MYWEBSERVER_MYSTRERRBUFDIM 4097

/****************************************************************************/

#if (defined (MYWEBSERVER_PRODUCTION_VERSION))
#else
#define MYWEBSERVER_IMPLEMENT_A_CRUNCHER_STUB 1
#endif

/****************************************************************************/

#define MYWEBSERVER_MUCO_OPC_CHCK           (0x32)
#define MYWEBSERVER_MUCO_OPC_HELO           (0x34)
#define MYWEBSERVER_MUCO_RC_SUCCESS         (0x00)
#define MYWEBSERVER_MUCO_RC_REQUESTREJECTED (0x52)
#define MYWEBSERVER_MUCO_RC_RESOURCEBUSY    (0x53)

/****************************************************************************/

#define MYWEBSERVER_STRINGIFY_AUX(a) #a
#define MYWEBSERVER_STRINGIFY(a)     MYWEBSERVER_STRINGIFY_AUX (a)

/****************************************************************************/

#if (defined (c_plusplus) || defined (__cplusplus))
extern "C" {
#endif

/****************************************************************************/

typedef struct {
  struct sockaddr_storage sas;
  socklen_t               addrlen;
  char                    numericcliaddrstr [46 + 1 + 20];
  char                    numericcliportstr [21];
  } sau_t;

typedef struct iacn {
  struct iacn   *left;
  struct iacn   *right;
  struct iacn   *up;
  struct iacn   *padding;
  int           bal;
  unsigned int  cnt;
  sau_t         sau;
  unsigned char calisep [128];
  } iacn_t;

typedef struct job {
  struct job    *left;
  struct job    *right;
  unsigned char *pbuf1;
  unsigned char *pbuf2;
  unsigned char *pbuf3;
  unsigned char *ppadding;
  unsigned int  bufdim;
  unsigned int  buflvl1;
  unsigned int  buflvl2;
  unsigned int  buflvl3;
  unsigned int  rank;
  unsigned int  slot;
  int           sfd;
  int           ipadding;
  sau_t         sau;
  unsigned char calisep [128];
  } job_t;

typedef struct ctn {
  struct ctn     *left;
  struct ctn     *right;
  struct ctn     *up;
  struct ctn     *padding;
  int            bal;
  unsigned int   slot;
  struct timeval creatim;
  sau_t          sau;
  unsigned char  calisep [128];
  } ctn_t;

typedef struct {
  unsigned int  bufferlevel;
  unsigned int  bitlen [2];
  unsigned int  state [8];
  unsigned char buffer [64];
  } sha256context_t;

#if (0)
typedef void (*mysighandler_t) (int);
#endif

/****************************************************************************/

static unsigned char *largebuffer          = 0;
static ctn_t         *cretimnodebaseaddr   = 0;
static unsigned char *diskoutbuffer0       = 0;
static unsigned char *diskoutbuffer1       = 0;
static iacn_t        *iacnodebaseaddr1     = 0;
static iacn_t        *iacnodebaseaddr2     = 0;
static job_t         *jobbaseaddr          = 0;
static unsigned char *randomblockbaseaddr  = 0;
static unsigned char *statelocatorbaseaddr = 0;
static unsigned int  *threadrankbaseaddr   = 0;

static pthread_barrier_t barrier2;
static pthread_barrier_t barrierall;
static pthread_barrier_t barrierallminus1;

/* Fast non-recursive mutexes. */
static pthread_mutex_t mutexcounternodes1 = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mutexdiskoutbuffer = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mutexexclusivecode = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mutexfreejobchain  = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mutexjobstobedone  = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mutexstalocliftim  = PTHREAD_MUTEX_INITIALIZER;

static job_t *pfreejobchainfirst = 0;
static job_t *pfreejobchainlast  = 0;
static job_t *pjobstobedonefirst = 0;
static job_t *pjobstobedonelast  = 0;

static iacn_t *pfreeiacnodechainfirst1 = 0;
static iacn_t *pfreeiacnodechainlast1  = 0;
static iacn_t *piacnodetree1           = 0;

static iacn_t *pfreeiacnodechainfirst2 = 0;
static iacn_t *pfreeiacnodechainlast2  = 0;
static iacn_t *piacnodetree2           = 0;

static ctn_t *pfreecretimnodechainfirst = 0;
static ctn_t *pfreecretimnodechainlast  = 0;
static ctn_t *pcretimnodetree           = 0;

static volatile unsigned int diskoutbuflvl0     = 0;
static volatile unsigned int diskoutbuflvl1     = 0;
static volatile unsigned int diskoutbufwhichone = 0;

static volatile int sfdbase = -1;

static unsigned int debugglobal                 = 0;
static unsigned int defenderexponentglobal      = 0;
static unsigned int kbytesdiskoutbufferglobal   = 0;
static unsigned int kbytesthreadstacksizeglobal = 0;
static unsigned int millisecstobesleptglobal    = 0;
static unsigned int numslotsglobal              = 0;
static unsigned int statelocatorlifetimeglobal  = 0;

static char          accfilenamestem [4097]            = { 0 };
static char          canhostnam [4097]                 = { 0 };
static char          executorurl [4097]                = { 0 };
static char          faviconurl [4097]                 = { 0 };
static unsigned char hiddenstatelocatorbase [32]       = { 0 };
static char          numericserverportstr [21]         = { 0 };
static unsigned char universalrejectionresponse [4097] = { 0 };

static size_t universalrejectionresponsesize = 0;

/****************************************************************************/

/* Variable for controlling the program sequence with the following values.
   0: Normal program flow, executing infinite loops.
   1: Caught SIGINT or SIGTERM. Leave the infinite loops, flush the accounting
      record buffers, go through all critical regions such as mutex-armored
      sections and barriers, and exit the program cleanly so that Valgrind
      does not show errors related to our code.
   2: Internal server error. Leave the infinite loops, go through all critical
      regions such as mutex-armored sections and barriers, and exit the
      program in such a manner that the only error message we need to see
      does not get lost. */
static volatile atomic_uint terminateexecution = 0;

/****************************************************************************/

static volatile atomic_uint writeoutaccrecstofile = 0;

/****************************************************************************/

int main (int, char **);
#if (defined (c_plusplus) || defined (__cplusplus))
/* Just to allow the compilation with g++. */
static int atomic_compare_exchange_weak (volatile atomic_uint *,
  atomic_uint *, atomic_uint);
static atomic_uint atomic_load (volatile atomic_uint *);
static void atomic_store (volatile atomic_uint *, atomic_uint);
#endif
static volatile unsigned int atomicallyLoadsTerminateExecution (void);
static volatile unsigned int atomicallyLoadsWriteoutAccRecsToFile (void);
static void atomicallyStoresOneToWriteoutAccRecsToFile (void);
static void atomicallyStoresTwoToTerminateExecution (void);
static void atomicallyStoresZeroToWriteoutAccRecsToFile (void);
static void canonicalizeIpAddr (char *);
static unsigned int checkAccountingFileNameStem (char *);
static unsigned int checkAndLowerHostname (char *);
static unsigned int checkAvlTreeAddressCounterNodes1 (iacn_t *);
static unsigned int checkAvlTreeAddressCounterNodes2 (iacn_t *);
static unsigned int checkAvlTreeCreationTimeNodes (ctn_t *);
static unsigned int checkChangedIpAddress (job_t *);
static unsigned int checkExecutorUrlChars (char *);
static unsigned int checkFaviconUrlChars (char *);
static void checkForPendingSignals (char *);
static void crc16 (unsigned int, unsigned char *, unsigned char *);
static void createHiddenStateLocatorBase (void);
static void createStateLocator (unsigned int, unsigned int, unsigned char *);
static void createUniversalRejectionResponse (void);
#if (defined (MYWEBSERVER_IMPLEMENT_A_CRUNCHER_STUB))
static void cruncher (unsigned char, unsigned char *);
#else
extern void cruncher (unsigned char, unsigned char *);
#endif
static void destroyTheBarriers (char *);
static void doAsciiArmoring (const unsigned char *, unsigned int,
  unsigned char *);
static void enforceStateLocatorLifeTimeRule (struct timeval *, char *);
static void executeAcceptLoop (char *);
static void fileAnAccessRecord (const char *, char *);
static unsigned int findFreeSlot (sau_t *, struct timeval *, unsigned int *);
static void flushOutStreams (void);
static void getCanonicalHostname (char *, unsigned int);
static int getListenBacklog (void);
static void getRandomBytes32 (unsigned int, unsigned int, unsigned char *);
static unsigned int gotTheCompleteHttpRequest (unsigned char *, unsigned int);
#if (0)
static void handleSigintSigusr1Sigterm (int);
#endif
static void httpServer (job_t *, char *);
static void inetServer (const char *, unsigned int, unsigned int,
  unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
  unsigned int);
static unsigned int insertAddressCounterNode1 (iacn_t *);
static unsigned int insertAddressCounterNode2 (iacn_t *);
static unsigned int insertCreationTimeNode (ctn_t *);
#if (0)
static void installSigintSigusr1Sigterm (void);
#endif
static void installSignalMask (char *);
static void installWorkspace (unsigned int);
static unsigned int isValidStateLocator (const unsigned char *, char *);
static unsigned int isValidUint (unsigned long);
#if (0)
static mysighandler_t myBsdStyleSignal (int, mysighandler_t);
#endif
static char * myStrError (int, char *);
static char * padWithLeadingZeros (char *, unsigned int, char *, size_t);
static void * passP (void *);
static unsigned int passU (unsigned int);
static unsigned int perAddrConnLimitExceeded (sau_t *, unsigned int, char *);
static void persuadeAcceptToReturn (char *);
static void prepareAcceptLoop (const char *);
static unsigned int registerIpAddress1 (sau_t *, unsigned int);
static unsigned int registerIpAddress2 (sau_t *, unsigned int);
static unsigned int removeAddressCounterNode1 (iacn_t *);
static unsigned int removeAddressCounterNode2 (iacn_t *);
static unsigned int removeCreationTimeNode (ctn_t *);
static void removeStateLocatorAndIpAddress2 (unsigned char *, char *);
static int sauCmp (const sau_t *, const sau_t *);
static void scatterThreads (unsigned int, char *);
static void sha256 (unsigned int, const unsigned char *, unsigned char *);
static void sha256Final (sha256context_t *, unsigned char *);
static void sha256Init (sha256context_t *);
static void sha256Transform (sha256context_t *);
static void sha256Update (sha256context_t *, unsigned int,
  const unsigned char *);
static void sleepMilliSecs (unsigned int, char *);
static void startOneMainLoadWorkerThread (unsigned int, char *);
static void startThreads (char *);
static int tvCmp (const struct timeval *, const struct timeval *,
  const ctn_t *, const ctn_t *);
static void undoAsciiArmoring (const unsigned char *, unsigned char *,
  char *);
static void unregisterIpAddress1 (sau_t *);
static void unregisterIpAddress2 (sau_t *);
static unsigned char * w (unsigned char *, unsigned char *, const char *);
static void * workerCleanupStateLocators (void *);
static void * workerDiskOutput (void *);
static void * workerMainLoad (void *);
static void writeoutBufferToDisk (unsigned char *, unsigned int);
static void writeoutUniversalRejectionResponse (int);

/****************************************************************************/

#if (defined (c_plusplus) || defined (__cplusplus))
}
#endif

/****************************************************************************/

int
main (int argc, char **argv)
{
  unsigned int kbytesdiskoutbufferlocal, debuglocal, defenderexponentlocal,
    kbytesperslot, statelocatorlifetimelocal, millisecstobesleptlocal,
    numslotslocal, kbytesthreadstacksizelocal, dimindent, i;
  unsigned long uli;
  int opt, rc;
  char *pdup, *pbasename, *pindent, *endptr;
  size_t numbytes;
  unsigned char *pw, *bw;

  (void) strcpy (&accfilenamestem[0], MYWEBSERVER_ACCOUNTING_FILE_NAME_STEM);
  kbytesdiskoutbufferlocal = MYWEBSERVER_DEFAULT_KBYTES_DISK_OUT_BUFFER;
  debuglocal = MYWEBSERVER_DEFAULT_DEBUG;
  defenderexponentlocal = MYWEBSERVER_DEFAULT_DEFENDER_EXPONENT;
  (void) strcpy (&faviconurl[0], MYWEBSERVER_FAVICON_URL);
  (void) getCanonicalHostname (&canhostnam[0],
    (unsigned int) (sizeof (canhostnam) / sizeof (canhostnam[0])));
  kbytesperslot = MYWEBSERVER_DEFAULT_KBYTES_PER_SLOT;
  statelocatorlifetimelocal = MYWEBSERVER_DEFAULT_STATELOCATOR_LIFETIME;
  millisecstobesleptlocal = MYWEBSERVER_DEFAULT_MILLISECS_TO_BE_SLEPT;
  numslotslocal = MYWEBSERVER_DEFAULT_SLOT_NUMBER;
  (void) strcpy (&numericserverportstr[0],
                  MYWEBSERVER_STRINGIFY (MYWEBSERVER_DEFAULT_PORT));
  kbytesthreadstacksizelocal = MYWEBSERVER_DEFAULT_KBYTES_THREAD_STACKSIZE;
  uli = 0;
  while ((opt = getopt (argc, argv, "a:b:d:e:f:h:k:l:m:n:p:s:x:")) != -1) {
    switch (opt) {
      case 'a':
        (void) strncpy (&accfilenamestem[0], optarg,
                         sizeof (accfilenamestem) /
                         sizeof (accfilenamestem[0]));
        accfilenamestem[sizeof (accfilenamestem) /
                        sizeof (accfilenamestem[0]) - 1] = '\0';
        if (strlen (&accfilenamestem[0]) == sizeof (accfilenamestem) /
                                            sizeof (accfilenamestem[0]) - 1) {
          (void) fprintf (stderr, "main: strncpy (accfilenamestem): "
                           "Internal buffer overflow.\n");
          return (1);
          }
        if (checkAccountingFileNameStem (&accfilenamestem[0]) != 0) {
          /***** LABEL *****/ label_usage:
          pdup = strdup (*(argv + 0));
          if (pdup == 0) {
            (void) fprintf (stderr, "main: strdup: No more memory.\n");
            return (1);
            }
          pbasename = strrchr (pdup, '/');
          if (pbasename == 0)
              pbasename = pdup;
            else
              pbasename++;
          dimindent = (unsigned int) strlen (pbasename) + 8;
          numbytes = (size_t) (dimindent + 1) * sizeof (char);
          pindent = (char *) malloc (numbytes);
          if (pindent == 0) {
            (void) fprintf (stderr, "main: malloc: No more memory.\n");
            return (1);
            }
          for (i = 0; i < dimindent; i++)
            *(pindent + i) = ' ';
          *(pindent + dimindent) = '\0';
          (void) fprintf (stderr, "Usage: %s "
                           "[-a <accfilenamestem>] "
                           "[-b <kbytesdiskoutbuffer>] \\\n%s"
                           "[-d <debuglevel>] "
                           "[-e <defenderexponent>]         \\\n%s"
                           "[-f <faviconurl>] "
                           "[-h <hostname>]                 \\\n%s"
                           "[-k <kbytesperslot>] "
                           "[-l <statelocatorlifetime>]  \\\n%s"
                           "[-m <millisecstobeslept>] "
                           "[-n <numslots>]         \\\n%s"
                           "[-p <portnumber>] "
                           "[-s <kbytesthreadstacksize>]    \\\n%s"
                           "[-x <executorurl>]\n",
                           pbasename, pindent, pindent, pindent,
                           pindent, pindent, pindent);
          (void) free (pindent);
          (void) free (pdup);
          return (1);
          }
        break;
      case 'b':
        uli = strtoul (optarg, &endptr, 10);
        if (endptr == 0 || endptr == optarg || isValidUint (uli) == 0) {
          /***** LABEL *****/ label_error:
          if (endptr == 0 || endptr == optarg)
            goto label_usage;
          if (isValidUint (uli) == 0) {
            (void) fprintf (stderr, "main: Excessive argument values.\n");
            goto label_usage;
            }
          }
        kbytesdiskoutbufferlocal = (unsigned int) uli;
        break;
      case 'd':
        uli = strtoul (optarg, &endptr, 10);
        if (endptr == 0 || endptr == optarg || isValidUint (uli) == 0)
          goto label_error;
        debuglocal = (unsigned int) uli;
        break;
      case 'e':
        uli = strtoul (optarg, &endptr, 10);
        if (endptr == 0 || endptr == optarg || isValidUint (uli) == 0)
          goto label_error;
        defenderexponentlocal = (unsigned int) uli;
        break;
      case 'f':
        (void) strncpy (&faviconurl[0], optarg,
                         sizeof (faviconurl) /
                         sizeof (faviconurl[0]));
        faviconurl[sizeof (faviconurl) /
                   sizeof (faviconurl[0]) - 1] = '\0';
        if (strlen (&faviconurl[0]) == sizeof (faviconurl) /
                                       sizeof (faviconurl[0]) - 1) {
          (void) fprintf (stderr, "main: strncpy (faviconurl): "
                           "Internal buffer overflow.\n");
          return (1);
          }
        if (checkFaviconUrlChars (&faviconurl[0]) != 0)
          goto label_usage;
        break;
      case 'h':
        (void) strncpy (&canhostnam[0], optarg,
                         sizeof (canhostnam) /
                         sizeof (canhostnam[0]));
        canhostnam[sizeof (canhostnam) /
                   sizeof (canhostnam[0]) - 1] = '\0';
        if (strlen (&canhostnam[0]) == sizeof (canhostnam) /
                                       sizeof (canhostnam[0]) - 1) {
          (void) fprintf (stderr, "main: strncpy (canhostnam): "
                           "Internal buffer overflow.\n");
          return (1);
          }
        if (checkAndLowerHostname (&canhostnam[0]) != 0)
          goto label_usage;
        break;
      case 'k':
        uli = strtoul (optarg, &endptr, 10);
        if (endptr == 0 || endptr == optarg || isValidUint (uli) == 0)
          goto label_error;
        kbytesperslot = (unsigned int) uli;
        break;
      case 'l':
        uli = strtoul (optarg, &endptr, 10);
        if (endptr == 0 || endptr == optarg || isValidUint (uli) == 0)
          goto label_error;
        statelocatorlifetimelocal = (unsigned int) uli;
        break;
      case 'm':
        uli = strtoul (optarg, &endptr, 10);
        if (endptr == 0 || endptr == optarg || isValidUint (uli) == 0)
          goto label_error;
        millisecstobesleptlocal = (unsigned int) uli;
        break;
      case 'n':
        uli = strtoul (optarg, &endptr, 10);
        if (endptr == 0 || endptr == optarg || isValidUint (uli) == 0)
          goto label_error;
        numslotslocal = (unsigned int) uli;
        break;
      case 'p':
        uli = strtoul (optarg, &endptr, 10);
        if (endptr == 0 || endptr == optarg || isValidUint (uli) == 0)
          goto label_error;
        rc = snprintf (&numericserverportstr[0],
                        sizeof (numericserverportstr), "%lu", uli);
        if (rc >= (int) sizeof (numericserverportstr)) {
          (void) fprintf (stderr, "main: snprintf (numericserverportstr): "
                           "Internal buffer overflow.\n");
          return (1);
          }
        break;
      case 's':
        uli = strtoul (optarg, &endptr, 10);
        if (endptr == 0 || endptr == optarg || isValidUint (uli) == 0)
          goto label_error;
        kbytesthreadstacksizelocal = (unsigned int) uli;
        break;
      case 'x':
        (void) strncpy (&executorurl[0], optarg,
                         sizeof (executorurl) /
                         sizeof (executorurl[0]));
        executorurl[sizeof (executorurl) /
                    sizeof (executorurl[0]) - 1] = '\0';
        if (strlen (&executorurl[0]) == sizeof (executorurl) /
                                        sizeof (executorurl[0]) - 1) {
          (void) fprintf (stderr, "main: strncpy (executorurl): "
                           "Internal buffer overflow.\n");
          return (1);
          }
        if (checkExecutorUrlChars (&executorurl[0]) != 0)
          goto label_usage;
        break;
      default: /* '?' */
        goto label_usage;
      }
    }
  if (optind < argc)
    goto label_usage;
  if (strlen (&executorurl[0]) == 0) {
    pw = (unsigned char *) &executorurl[0];
    bw = pw + sizeof (executorurl) / sizeof (executorurl[0]);
    pw = w (pw, bw, "http://");
    pw = w (pw, bw, &canhostnam[0]);
    pw = w (pw, bw, ":");
    pw = w (pw, bw, &numericserverportstr[0]);
    pw = w (pw, bw, "/");
    *(bw - 1) = '\0';
    if (strlen (&executorurl[0]) == sizeof (executorurl) /
                                    sizeof (executorurl[0]) - 1) {
      (void) fprintf (stderr, "main: w (executorurl): "
                       "Internal buffer overflow.\n");
      return (1);
      }
    }
  if (debuglocal > 0)
    (void) printf ("Hi there, FDEI HTTP server seen on `%s'.\n"
                    "Accounting file name stem is `%s'.\n"
                    "Executor URL in use `%s'.\n"
                    "Favicon URL in use `%s'.\n",
                    &canhostnam[0], &accfilenamestem[0], &executorurl[0],
                    &faviconurl[0]);
  (void) inetServer (&numericserverportstr[0], defenderexponentlocal,
                      kbytesperslot, debuglocal, kbytesdiskoutbufferlocal,
                      kbytesthreadstacksizelocal, millisecstobesleptlocal,
                      numslotslocal, statelocatorlifetimelocal);
  return (0);
  }

/****************************************************************************/

#if (defined (c_plusplus) || defined (__cplusplus))
/* Just to allow the compilation with g++. */
static int
atomic_compare_exchange_weak (volatile atomic_uint *a, atomic_uint *e,
                               atomic_uint v)
{
  if (memcmp ((void *) a, (void *) e, sizeof (atomic_uint)) == 0) {
      (void) memcpy ((void *) a, (void *) &v, sizeof (atomic_uint));
      return (1);
      }
    else {
      (void) memcpy ((void *) e, (void *) a, sizeof (atomic_uint));
      return (0);
      }
  }
#endif

/****************************************************************************/

#if (defined (c_plusplus) || defined (__cplusplus))
/* Just to allow the compilation with g++. */
static atomic_uint
atomic_load (volatile atomic_uint *a)
{
  return (*a);
  }
#endif

/****************************************************************************/

#if (defined (c_plusplus) || defined (__cplusplus))
/* Just to allow the compilation with g++. */
static void
atomic_store (volatile atomic_uint *a, atomic_uint v)
{
  *a = v;
  return;
  }
#endif

/****************************************************************************/

static volatile unsigned int
atomicallyLoadsTerminateExecution (void)
{
  return ((volatile unsigned int) atomic_load (&terminateexecution));
  }

/****************************************************************************/

static volatile unsigned int
atomicallyLoadsWriteoutAccRecsToFile (void)
{
  return ((volatile unsigned int) atomic_load (&writeoutaccrecstofile));
  }

/****************************************************************************/

static void
atomicallyStoresOneToWriteoutAccRecsToFile (void)
{
  /* (void) */ atomic_store (&writeoutaccrecstofile, (atomic_uint) 1);
  return;
  }

/****************************************************************************/

static void
atomicallyStoresTwoToTerminateExecution (void)
{
  /* (void) */ atomic_store (&terminateexecution, (atomic_uint) 2);
  return;
  }

/****************************************************************************/

static void
atomicallyStoresZeroToWriteoutAccRecsToFile (void)
{
  /* (void) */ atomic_store (&writeoutaccrecstofile, (atomic_uint) 0);
  return;
  }

/****************************************************************************/

static void
canonicalizeIpAddr (char *p)
{
  /* Translates `::ffff:127.0.0.1' to `127.0.0.1', for example. */
  if (*(p + 0) == ':')
    if (*(p + 1) == ':')
      if (*(p + 2) == 'f' || *(p + 2) == 'F')
        if (*(p + 3) == 'f' || *(p + 3) == 'F')
          if (*(p + 4) == 'f' || *(p + 4) == 'F')
            if (*(p + 5) == 'f' || *(p + 5) == 'F')
              if (*(p + 6) == ':')
                for (;;) {
                  if ((*(p + 0) = *(p + 7)) == '\0')
                    break;
                  p++;
                  }
  return;
  }

/****************************************************************************/

static unsigned int
checkAccountingFileNameStem (char *p)
{
  size_t n, i;
  int k;

  /* We exercise a certain arbitrariness here. */
  n = strlen (p);
  if (n == 0)
    return (1);
  for (i = 0; i < n; i++) {
    k = (int) *(p + i);
    if (isdigit (k) == 0 &&
        isupper (k) == 0 &&
        islower (k) == 0 &&
        k != '-'         &&
        k != '.'         &&
        k != '/')
      return (1);
    }
  if (strstr (p, "//") != 0)
    return (1);
  return (0);
  }

/****************************************************************************/

static unsigned int
checkAndLowerHostname (char *p)
{
  size_t n, i;
  int k;
  char *p0, *p1;

  n = strlen (p);
  if (n == 0)
    return (1);
  for (i = 0; i < n; i++) {
    *(p + i) = k = tolower (*(p + i));
    if (islower (k) == 0 &&
        isdigit (k) == 0 &&
        k != '-'         &&
        k != '.')
      return (1);
    }
  if (*(p + 0) == '-')
    return (1);
  if (*(p + 0) == '.')
    return (1);
  if (strstr (p, ".-") != 0)
    return (1);
  if (strstr (p, "..") != 0)
    return (1);
  p0 = p;
  while (*p0 != '\0') {
    p1 = strchr (p0, '.');
    if (p1 == 0)
      p1 = strchr (p0, '\0');
    if (p0 + 63 < p1)
      /* Component too long. */
      return (1);
    if (*p1 == '\0')
      break;
    p0 = p1 + 1;
    }
  return (0);
  }

/****************************************************************************/

static unsigned int
checkAvlTreeAddressCounterNodes1 (iacn_t *node)
{
  iacn_t *nodeaux;
  unsigned int levelmaxleft, levelmaxright, levelmax;
  int balancemax;

  /* Pay attention, this function calls itself.
     However, it is only called in debug mode. */
  if (node == 0)
    return (0);
  if (node->left != 0) {
    if (node->left->up != node) {
      /***** LABEL *****/ label_unrecoverable_error:
      (void) fprintf (stderr, "checkAvlTreeAddressCounterNodes1: "
                       "Unrecoverable error.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (0xffffffff);
      }
    nodeaux = node->left;
    if (sauCmp (&nodeaux->sau, &node->sau) >= 0)
      goto label_unrecoverable_error;
    while (nodeaux->right != 0) {
      if (sauCmp (&nodeaux->sau, &nodeaux->right->sau) >= 0)
        goto label_unrecoverable_error;
      nodeaux = nodeaux->right;
      if (sauCmp (&nodeaux->sau, &node->sau) >= 0)
        goto label_unrecoverable_error;
      }
    }
  if (node->right != 0) {
    if (node->right->up != node)
      goto label_unrecoverable_error;
    nodeaux = node->right;
    if (sauCmp (&node->sau, &nodeaux->sau) >= 0)
      goto label_unrecoverable_error;
    while (nodeaux->left != 0) {
      if (sauCmp (&nodeaux->left->sau, &nodeaux->sau) >= 0)
        goto label_unrecoverable_error;
      nodeaux = nodeaux->left;
      if (sauCmp (&node->sau, &nodeaux->sau) >= 0)
        goto label_unrecoverable_error;
      }
    }
  if (node->up != 0) {
    if (node->up->left != node && node->up->right != node)
      goto label_unrecoverable_error;
    }
  levelmaxleft = checkAvlTreeAddressCounterNodes1 (node->left);
  if (levelmaxleft == 0xffffffff)
    return (0xffffffff);
  levelmaxright = checkAvlTreeAddressCounterNodes1 (node->right);
  if (levelmaxright == 0xffffffff)
    return (0xffffffff);
  levelmaxleft++;
  levelmaxright++;
  balancemax = (int) levelmaxleft - (int) levelmaxright;
  if (balancemax < -1 || balancemax > 1 || balancemax != node->bal) {
    (void) fprintf (stderr, "checkAvlTreeAddressCounterNodes1: "
                     "Inconsistent AVL tree.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (0xffffffff);
    }
  levelmax = levelmaxleft > levelmaxright ? levelmaxleft : levelmaxright;
  return (levelmax);
  }

/****************************************************************************/

static unsigned int
checkAvlTreeAddressCounterNodes2 (iacn_t *node)
{
  iacn_t *nodeaux;
  unsigned int levelmaxleft, levelmaxright, levelmax;
  int balancemax;

  /* Pay attention, this function calls itself.
     However, it is only called in debug mode. */
  if (node == 0)
    return (0);
  if (node->left != 0) {
    if (node->left->up != node) {
      /***** LABEL *****/ label_unrecoverable_error:
      (void) fprintf (stderr, "checkAvlTreeAddressCounterNodes2: "
                       "Unrecoverable error.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (0xffffffff);
      }
    nodeaux = node->left;
    if (sauCmp (&nodeaux->sau, &node->sau) >= 0)
      goto label_unrecoverable_error;
    while (nodeaux->right != 0) {
      if (sauCmp (&nodeaux->sau, &nodeaux->right->sau) >= 0)
        goto label_unrecoverable_error;
      nodeaux = nodeaux->right;
      if (sauCmp (&nodeaux->sau, &node->sau) >= 0)
        goto label_unrecoverable_error;
      }
    }
  if (node->right != 0) {
    if (node->right->up != node)
      goto label_unrecoverable_error;
    nodeaux = node->right;
    if (sauCmp (&node->sau, &nodeaux->sau) >= 0)
      goto label_unrecoverable_error;
    while (nodeaux->left != 0) {
      if (sauCmp (&nodeaux->left->sau, &nodeaux->sau) >= 0)
        goto label_unrecoverable_error;
      nodeaux = nodeaux->left;
      if (sauCmp (&node->sau, &nodeaux->sau) >= 0)
        goto label_unrecoverable_error;
      }
    }
  if (node->up != 0) {
    if (node->up->left != node && node->up->right != node)
      goto label_unrecoverable_error;
    }
  levelmaxleft = checkAvlTreeAddressCounterNodes2 (node->left);
  if (levelmaxleft == 0xffffffff)
    return (0xffffffff);
  levelmaxright = checkAvlTreeAddressCounterNodes2 (node->right);
  if (levelmaxright == 0xffffffff)
    return (0xffffffff);
  levelmaxleft++;
  levelmaxright++;
  balancemax = (int) levelmaxleft - (int) levelmaxright;
  if (balancemax < -1 || balancemax > 1 || balancemax != node->bal) {
    (void) fprintf (stderr, "checkAvlTreeAddressCounterNodes2: "
                     "Inconsistent AVL tree.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (0xffffffff);
    }
  levelmax = levelmaxleft > levelmaxright ? levelmaxleft : levelmaxright;
  return (levelmax);
  }

/****************************************************************************/

static unsigned int
checkAvlTreeCreationTimeNodes (ctn_t *node)
{
  ctn_t *nodeaux;
  unsigned int levelmaxleft, levelmaxright, levelmax;
  int balancemax;

  /* Pay attention, this function calls itself.
     However, it is only called in debug mode. */
  if (node == 0)
    return (0);
  if (node->left != 0) {
    if (node->left->up != node) {
      /***** LABEL *****/ label_unrecoverable_error:
      (void) fprintf (stderr, "checkAvlTreeCreationTimeNodes: "
                       "Unrecoverable error.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (0xffffffff);
      }
    nodeaux = node->left;
    if (tvCmp (&nodeaux->creatim, &node->creatim, nodeaux, node) >= 0)
      goto label_unrecoverable_error;
    while (nodeaux->right != 0) {
      if (tvCmp (&nodeaux->creatim, &nodeaux->right->creatim,
                  nodeaux, nodeaux->right) >= 0)
        goto label_unrecoverable_error;
      nodeaux = nodeaux->right;
      if (tvCmp (&nodeaux->creatim, &node->creatim, nodeaux, node) >= 0)
        goto label_unrecoverable_error;
      }
    }
  if (node->right != 0) {
    if (node->right->up != node)
      goto label_unrecoverable_error;
    nodeaux = node->right;
    if (tvCmp (&node->creatim, &nodeaux->creatim, node, nodeaux) >= 0)
      goto label_unrecoverable_error;
    while (nodeaux->left != 0) {
      if (tvCmp (&nodeaux->left->creatim, &nodeaux->creatim,
                  nodeaux->left, nodeaux) >= 0)
        goto label_unrecoverable_error;
      nodeaux = nodeaux->left;
      if (tvCmp (&node->creatim, &nodeaux->creatim, node, nodeaux) >= 0)
        goto label_unrecoverable_error;
      }
    }
  if (node->up != 0) {
    if (node->up->left != node && node->up->right != node)
      goto label_unrecoverable_error;
    }
  levelmaxleft = checkAvlTreeCreationTimeNodes (node->left);
  if (levelmaxleft == 0xffffffff)
    return (0xffffffff);
  levelmaxright = checkAvlTreeCreationTimeNodes (node->right);
  if (levelmaxright == 0xffffffff)
    return (0xffffffff);
  levelmaxleft++;
  levelmaxright++;
  balancemax = (int) levelmaxleft - (int) levelmaxright;
  if (balancemax < -1 || balancemax > 1 || balancemax != node->bal) {
    (void) fprintf (stderr, "checkAvlTreeCreationTimeNodes: "
                     "Inconsistent AVL tree.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (0xffffffff);
    }
  levelmax = levelmaxleft > levelmaxright ? levelmaxleft : levelmaxright;
  return (levelmax);
  }

/****************************************************************************/

static unsigned int
checkChangedIpAddress (job_t *pjob)
{
  char *p1, *p2;

  p1 = &pjob->sau.numericcliaddrstr[0];
  p2 = &(cretimnodebaseaddr + pjob->slot)->sau.numericcliaddrstr[0];
  while (*p1 != '_' && *p1 != '\0' && *p2 != '_' && *p2 != '\0')
    if (*p1++ != *p2++)
      return (1);
  if ((*p1 == '_' || *p1 == '\0') && (*p2 == '_' || *p2 == '\0' ))
    return (0);
  return (1);
  }

/****************************************************************************/

static unsigned int
checkExecutorUrlChars (char *p)
{
  size_t i;
  int k;

  /* We exercise a certain arbitrariness here. */
  for (i = 0; i < strlen (p); i++) {
    k = (int) *(p + i);
    if (isdigit (k) == 0 &&
        isupper (k) == 0 &&
        islower (k) == 0 &&
        k != '-'         &&
        k != '.'         &&
        k != '/'         &&
        k != ':')
      return (1);
    }
  return (0);
  }

/****************************************************************************/

static unsigned int
checkFaviconUrlChars (char *p)
{
  return (checkExecutorUrlChars (p));
  }

/****************************************************************************/

static void
checkForPendingSignals (char *mystrerrbufbase)
{
  sigset_t set;
  struct timespec ts;
  int rc, sig;
  atomic_uint te, desi;

  if (sigfillset (&set) != 0) {
    (void) perror ("checkForPendingSignals: sigfillset");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  ts.tv_sec = 0;
  ts.tv_nsec = 1;
  rc = pthread_mutex_lock (&mutexexclusivecode);
  if (rc != 0) {
    (void) fprintf (stderr, "checkForPendingSignals: pthread_mutex_lock "
                     "(mutexexclusivecode): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  sig = sigtimedwait (&set, 0, &ts);
  rc = pthread_mutex_unlock (&mutexexclusivecode);
  if (rc != 0) {
    (void) fprintf (stderr, "checkForPendingSignals: pthread_mutex_unlock "
                     "(mutexexclusivecode): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    /* We cannot do more than pray. */
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  if (sig < 1)
    return;
  if (sig == SIGINT || sig == SIGTERM) {
    /* Performs `if(terminateexecution==0)terminateexecution=1;'. */
    te = atomic_load (&terminateexecution);
    desi = te == 0 ? 1 : te;
    while (!atomic_compare_exchange_weak (&terminateexecution, &te, desi));
    if (debugglobal > 0) {
      if (sig == SIGINT)
        (void) printf ("Handled signal SIGINT.\n");
      if (sig == SIGTERM)
        (void) printf ("Handled signal SIGTERM.\n");
      }
    return;
    }
  if (sig == SIGUSR1) {
    (void) atomicallyStoresOneToWriteoutAccRecsToFile ();
    if (debugglobal > 0)
      (void) printf ("Handled signal SIGUSR1.\n");
    return;
    }
  if (debugglobal > 0)
    (void) printf ("Caught signal %d, ignored.\n", sig);
  return;
  }

/****************************************************************************/

static void
crc16 (unsigned int n, unsigned char *pbuf, unsigned char *pcrc)
{
  unsigned int crc, i, u, v, j, xnz, k;

  crc = 0xffff;
  for (i = 0; i < n; i++) {
    u = (unsigned int) *(pbuf + i);
    v = 0x0080;
    for (j = 0; j < 8; j++) {
      xnz = crc & (unsigned int) 0x8000;
      crc <<= 1;
      if ((u & v) != 0)
        crc++;
      if (xnz != 0)
        crc ^= (unsigned int) 0x1021;
      v >>= 1;
      }
    }
  for (k = 0; k < 16; k++) {
    if ((crc & (unsigned int) 0x8000) != 0)
        crc = crc << 1 ^ (unsigned int) 0x1021;
      else
        crc <<= 1;
    }
  *(pcrc + 0) = (unsigned char) (crc >> 8 & (unsigned int) 0xff);
  *(pcrc + 1) = (unsigned char) (crc      & (unsigned int) 0xff);
  return;
  }

/****************************************************************************/

static void
createHiddenStateLocatorBase (void)
{
  (void) getRandomBytes32 (0, 32, &hiddenstatelocatorbase[0]);
  return;
  }

/****************************************************************************/

static void
createStateLocator (unsigned int rank, unsigned int slot, unsigned char *buf)
{
  static const char *nostatelocator =
    "0000000000000000000000000000000000000000000000000000000000000000";
  struct {
    unsigned char slot1l;
    unsigned char slot1h;
    unsigned char hiddenbase [32];
    unsigned char slot2h;
    unsigned char slot2l;
    unsigned char publicrand [15];
    unsigned char hash [15];
    unsigned char overrun [17];
    } b;

  b.slot1l = (unsigned char) (slot      & (unsigned int) 0xff);
  b.slot1h = (unsigned char) (slot >> 8 & (unsigned int) 0xff);
  (void) memcpy (&b.hiddenbase[0], &hiddenstatelocatorbase[0], 32);
  b.slot2h = b.slot1h;
  b.slot2l = b.slot1l;
  (void) getRandomBytes32 (rank, 15, &b.publicrand[0]);
  (void) sha256 (51, &b.slot1l, &b.hash[0]);
  (void) doAsciiArmoring (&b.slot2h, 32, buf);
  if (slot == 0)
    if (strcmp (nostatelocator, (char *) buf) == 0)
      (void) createStateLocator (rank, slot, buf);
  return;
  }

/****************************************************************************/

static void
createUniversalRejectionResponse (void)
{
  char buf32 [32];
  unsigned char *p, *b, rcmuco;
  const char *pconst1, *pconst2;
  char *p0, *p1, *p2, *p3;
  unsigned int contentlength;
  int rc;

  /* We create a rejecting response that is constant and that meets all
     possible requests from the peers, in the sense that the peers cannot
     complain about HTTP and HTML. This makes it possible to react quickly
     in all cases of attempted resource overruns or attacks without the need
     of reading possibly transmitted requests, not to mention the need of
     processing them. This constant response also makes it possible to keep
     the TCP/IP protocol polite and to allow the application on the opposite
     side to issue error messages at a high level. */
  p = &universalrejectionresponse[0];
  b = p + sizeof (universalrejectionresponse) /
          sizeof (universalrejectionresponse[0]);
  p = w (p, b, "HTTP/1.1 200 OK\r\n");
  p = w (p, b, "Server: FDEI/" MYWEBSERVER_FDEI_VERSION "\r\n");
  p = w (p, b, "Connection: close\r\n");
  p = w (p, b, "Content-Length: <contentlength></contentlength>\r\n");
  p = w (p, b, "Content-Type: application/xhtml+xml;charset=us-ascii\r\n");
  p = w (p, b, "\r\n");
  p = w (p, b, "<?xml version=\"1.0\" encoding=\"us-ascii\"?>\r\n");
  p = w (p, b, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML Basic 1.1//EN\" ");
  p = w (p, b, "\"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd\">\r\n");
  p = w (p, b, "<html xmlns=\"http://www.w3.org/1999/xhtml\" ");
  p = w (p, b, "lang=\"en\" xml:lang=\"en\">\r\n");
  p = w (p, b, "<head>\r\n");
  if (strlen (&faviconurl[0]) != 0) {
    p = w (p, b, "<link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"");
    p = w (p, b, &faviconurl[0]);
    p = w (p, b, "\"/>\r\n");
    }
  p = w (p, b, "<title>FDEI " MYWEBSERVER_FDEI_VERSION "</title>\r\n");
  p = w (p, b, "</head>\r\n");
  p = w (p, b, "<body>\r\n");
  p = w (p, b, "<div>FDEI Universal Rejection Response</div>\r\n");
  p = w (p, b, "<div>FDEI " MYWEBSERVER_FDEI_VERSION ", suitable for "
                            MYWEBSERVER_APPLICATION_NAME " version "
                            MYWEBSERVER_MINIMUM_APPLICATION_VERSION
                          " and higher</div>\r\n");
  p = w (p, b, "<div>fdeixnum=1</div>\r\n");
  p = w (p, b, "<div>fdeix0=");
  p = w (p, b, &executorurl[0]);
  p = w (p, b, "</div>\r\n");
  p = w (p, b, "<div>sentstatelocator=");
  p = w (p, b, "00000000000000000000000000000000");
  p = w (p, b, "00000000000000000000000000000000");
  p = w (p, b, "</div>\r\n");
  p = w (p, b, "<div>statelocator=");
  p = w (p, b, "00000000000000000000000000000000");
  p = w (p, b, "00000000000000000000000000000000");
  p = w (p, b, "</div>\r\n");
  p = w (p, b, "<div>shutdownrequestacknowledged=1</div>\r\n");
  rcmuco = MYWEBSERVER_MUCO_RC_REQUESTREJECTED;
  p = w (p, b, "<div>returncode=");
  (void) doAsciiArmoring (&rcmuco, 1, (unsigned char *) &buf32[0]);
  p = w (p, b, &buf32[0]);
  p = w (p, b, "</div>\r\n");
  p = w (p, b, "<div>reslinnum=1</div>\r\n");
  p = w (p, b, "<div>reslin0=");
  buf32[0] = 0;
  buf32[1] = 8;
  buf32[2] = (char) rcmuco;
  (void) crc16 (3, (unsigned char *) &buf32[0],
                   (unsigned char *) &buf32[3]);
  buf32[5] = buf32[3] ^ buf32[4];
  (void) crc16 (6, (unsigned char *) &buf32[0],
                   (unsigned char *) &buf32[6]);
  (void) doAsciiArmoring ((unsigned char *) &buf32[0], 8,
                           (unsigned char *) &buf32[8]);
  p = w (p, b, &buf32[8]);
  p = w (p, b, "</div>\r\n");
  p = w (p, b, "<div>endofres=1</div>\r\n");
  p = w (p, b, "</body>\r\n");
  p = w (p, b, "</html>\r\n");
  *(b - 1) = '\0';
  p = &universalrejectionresponse[0];
  if (strlen ((char *) p) == sizeof (universalrejectionresponse) /
                             sizeof (universalrejectionresponse[0]) - 1) {
    (void) fprintf (stderr, "createUniversalRejectionResponse: "
                     "(universalrejectionresponse): "
                     "Internal buffer overflow.\n");
    (void) exit (1);
    }
  pconst1 = "<contentlength></contentlength>";
  pconst2 = "\r\n\r\n";
  p0 = strstr ((char *) &universalrejectionresponse[0], pconst1);
  p1 = p0 + strlen (pconst1);
  p2 = strstr (p1, pconst2) + strlen (pconst2);
  contentlength = (unsigned int) strlen (p2);
  rc = snprintf (&buf32[0], sizeof (buf32), "%u", contentlength);
  if (rc >= (int) sizeof (buf32)) {
    (void) fprintf (stderr, "createUniversalRejectionResponse: "
                     "snprintf: Internal buffer overflow.\n");
    (void) exit (1);
    }
  p3 = &buf32[0];
  if (strlen (p3) > strlen (pconst1)) {
    (void) fprintf (stderr, "createUniversalRejectionResponse: "
                     "Unrecoverable error.\n");
    (void) exit (1);
    }
  while (*p3 != '\0')
    *p0++ = *p3++;
  while (*p1 != '\0')
    *p0++ = *p1++;
  *p0 = *p1;
  p = &universalrejectionresponse[0];
  universalrejectionresponsesize = strlen ((char *) p)
                                 * sizeof (unsigned char);
  return;
  }

/****************************************************************************/

#if (defined (MYWEBSERVER_IMPLEMENT_A_CRUNCHER_STUB))
static void
cruncher (unsigned char slot8, unsigned char *p)
{
  unsigned char crc16char [2];
  unsigned int gothelo;

  slot8 = *&slot8;
  gothelo = 0;
  if (*(p + 0) ==  0 &&
      *(p + 1) == 10 &&
      *(p + 2) == MYWEBSERVER_MUCO_OPC_HELO) {
    if (*(p + 3) == 'H' &&
        *(p + 4) == 'E' &&
        *(p + 5) == 'L' &&
        *(p + 6) == 'O') {
      if (*(p + 7) == '1' ||
          *(p + 7) == '2' ||
          *(p + 7) == '3') {
        (void) crc16 (10, p + 0, &crc16char[0]);
        if (crc16char[0] == 0 &&
            crc16char[1] == 0) {
          gothelo = 1;
          }
        }
      }
    }
  if (gothelo != 0) {
    /* Incomplete but tolerated cruncher response. */
    *(p +  0) = 0;
    *(p +  1) = 15;
    *(p +  2) = 0;
    *(p +  3) = 0;
    *(p +  4) = 0;
    *(p +  5) = 0;
    *(p +  6) = 0;
    *(p +  7) = 0;
    *(p +  8) = 0;
    *(p +  9) = 0;
    *(p + 10) = 0;
    (void) crc16 ( 8, p + 3, p + 11);
    (void) crc16 (13, p + 0, p + 13);
    return;
    }
  /* For the remainder change one byte for debugging and return. */
  *(p + 2) = MYWEBSERVER_MUCO_RC_REQUESTREJECTED;
  return;
  }
#endif

/****************************************************************************/

static void
destroyTheBarriers (char *mystrerrbufbase)
{
  int rc;

  rc = pthread_barrier_destroy (&barrierallminus1);
  if (rc != 0) {
    (void) fprintf (stderr, "destroyTheBarriers: "
                     "pthread_barrier_destroy (barrierallminus1): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  rc = pthread_barrier_destroy (&barrierall);
  if (rc != 0) {
    (void) fprintf (stderr, "destroyTheBarriers: "
                     "pthread_barrier_destroy (barrierall): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  rc = pthread_barrier_destroy (&barrier2);
  if (rc != 0) {
    (void) fprintf (stderr, "destroyTheBarriers: "
                     "pthread_barrier_destroy (barrier2): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  return;
  }

/****************************************************************************/

static void
doAsciiArmoring (const unsigned char *in, unsigned int n, unsigned char *out)
{
  static const char *hexstr = "0123456789ABCDEF";
  unsigned int i, k1, k2;
  unsigned char c;

  for (i = 0; i < n; i++) {
    c = *(in + i);
    k1 = (unsigned int) c >> 4 & (unsigned int) 0xf;
    k2 = (unsigned int) c      & (unsigned int) 0xf;
    *(out + 2 * i + 0) = (unsigned char) *(hexstr + k1);
    *(out + 2 * i + 1) = (unsigned char) *(hexstr + k2);
    }
  *(out + 2 * n + 0) = '\0';
  return;
  }

/****************************************************************************/

static void
enforceStateLocatorLifeTimeRule (struct timeval *currtim,
                                  char *mystrerrbufbase)
{
  unsigned char statelocator [65];
  ctn_t *node;
  struct timeval tv;
  unsigned char *puc;

  /* Due to runtime requirements, the present function
     will remove a maximum of 2 expired state locators. */
  if (atomicallyLoadsTerminateExecution () != 0)
    return;
  if ((node = (ctn_t *) passP (pcretimnodetree)) == 0)
    return;
  while (node->left != 0)
    node = node->left;
  tv.tv_sec  = node->creatim.tv_sec + (time_t) statelocatorlifetimeglobal;
  tv.tv_usec = node->creatim.tv_usec;
  if (tvCmp (currtim, &tv, 0, 0) < 1)
    return;
  puc = statelocatorbaseaddr + node->slot * 193;
  (void) strcpy ((char *) &statelocator[0], (char *) puc);
  (void) removeStateLocatorAndIpAddress2 (&statelocator[0], mystrerrbufbase);
  if ((node = (ctn_t *) passP (pcretimnodetree)) == 0)
    return;
  while (node->left != 0)
    node = node->left;
  tv.tv_sec  = node->creatim.tv_sec + (time_t) statelocatorlifetimeglobal;
  tv.tv_usec = node->creatim.tv_usec;
  if (tvCmp (currtim, &tv, 0, 0) < 1)
    return;
  puc = statelocatorbaseaddr + node->slot * 193;
  (void) strcpy ((char *) &statelocator[0], (char *) puc);
  (void) removeStateLocatorAndIpAddress2 (&statelocator[0], mystrerrbufbase);
  return;
  }

/****************************************************************************/

static void
executeAcceptLoop (char *mystrerrbufbase)
{
  static unsigned int sfdcounter = 0;
  sau_t peeraddr;
  int sfdacc, rc;
  job_t *pjob;
  unsigned char *p, *b;
  unsigned int peraddrconnlimit;

  for (;;) {
    if (atomicallyLoadsTerminateExecution () != 0)
      return;
    (void) memset (&peeraddr, 0, sizeof (peeraddr));
    peeraddr.addrlen = (socklen_t) sizeof (peeraddr.sas);
    sfdacc = accept (sfdbase, (struct sockaddr *) &peeraddr,
                      &peeraddr.addrlen);
    if (sfdacc < 0) {
      /* List taken from Linux accept(2) manual page. */
      if (errno == ENETDOWN     ||
          errno == EPROTO       ||
          errno == ENOPROTOOPT  ||
          errno == EHOSTDOWN    ||
          errno == ENONET       ||
          errno == EHOSTUNREACH ||
          errno == EOPNOTSUPP   ||
          errno == ENETUNREACH) {
        if (atomicallyLoadsTerminateExecution () != 0)
          return;
        continue;
        }
      (void) perror ("executeAcceptLoop: accept");
      (void) exit (1);
      }
    if (atomicallyLoadsTerminateExecution () != 0) {
      /***** LABEL *****/ label_close_and_return:
      if (sfdacc >= 0) {
        if (atomicallyLoadsTerminateExecution () < 2)
          (void) writeoutUniversalRejectionResponse (sfdacc);
        if (close (sfdacc) != 0) {
          (void) perror ("executeAcceptLoop: close 1");
          (void) exit (1);
          }
        }
      return;
      }
    if (debugglobal > 0) {
      if (sfdcounter < 12)
        sfdcounter++;
      if (sfdcounter < 11)
        (void) printf ("Main thread: Got %d as socket file descriptor "
                        "from `accept()'.\n", sfdacc);
      if (sfdcounter == 11)
        (void) printf ("Main thread: ...\n");
      }
    /* We do not accept new connections here until a job template is
       available in the job template chain. A job template will always
       be available after a while. Meanwhile, some kernel queue may fill
       up until the kernel finally starts throwing packets away. Things
       like these happen in the case of an L7-DDos attack, for example. */
    pjob = 0;
    while (pjob == 0) {
      if (atomicallyLoadsTerminateExecution () != 0)
        goto label_close_and_return;
      rc = pthread_mutex_lock (&mutexfreejobchain);
      if (rc != 0) {
        (void) fprintf (stderr, "executeAcceptLoop: pthread_mutex_lock "
                         "(mutexfreejobchain) 1: "
                         "%s.\n", myStrError (rc, mystrerrbufbase));
        (void) exit (1);
        }
      if (pfreejobchainfirst == 0) {
        rc = pthread_mutex_unlock (&mutexfreejobchain);
        if (rc != 0) {
          (void) fprintf (stderr, "executeAcceptLoop: pthread_mutex_unlock "
                           "(mutexfreejobchain) 1: "
                           "%s.\n", myStrError (rc, mystrerrbufbase));
          (void) exit (1);
          }
        (void) sleepMilliSecs (millisecstobesleptglobal, mystrerrbufbase);
        continue;
        }
      /* Begin of non-zero chaining out on the left side. */
      pjob = pfreejobchainfirst;
      if (pfreejobchainfirst->right != 0)
          pfreejobchainfirst->right->left = 0;
        else
          pfreejobchainlast = 0;
      pfreejobchainfirst = pfreejobchainfirst->right;
      /* End of non-zero chaining out on the left side. */
      rc = pthread_mutex_unlock (&mutexfreejobchain);
      if (rc != 0) {
        (void) fprintf (stderr, "executeAcceptLoop: pthread_mutex_unlock "
                         "(mutexfreejobchain) 2: "
                         "%s.\n", myStrError (rc, mystrerrbufbase));
        (void) exit (1);
        }
      }
    if (atomicallyLoadsTerminateExecution () != 0)
      goto label_close_and_return;
    rc = getnameinfo ((struct sockaddr *) &peeraddr, peeraddr.addrlen,
                       &peeraddr.numericcliaddrstr[0],
                       (socklen_t) sizeof (peeraddr.numericcliaddrstr),
                       &peeraddr.numericcliportstr[0],
                       (socklen_t) sizeof (peeraddr.numericcliportstr),
                       NI_NUMERICHOST | NI_NUMERICSERV);
    if (rc != 0) {
      (void) fprintf (stderr, "executeAcceptLoop: getnameinfo: "
                       "%s.\n", gai_strerror (rc));
      (void) exit (1);
      }
    (void) canonicalizeIpAddr (&peeraddr.numericcliaddrstr[0]);
    if (atomicallyLoadsTerminateExecution () < 2 && debugglobal > 3) {
      /* Simulate the situation in which all client addresses differ from
         each other. In this way, it can be tested with the help of only
         one client computer how the present server would behave under
         heavy load or in the event of an L7-DDos attack. */
      p = (unsigned char *) &peeraddr.numericcliaddrstr[0];
      b = p + sizeof (peeraddr.numericcliaddrstr) /
              sizeof (peeraddr.numericcliaddrstr[0]);
      p += strlen ((char *) p);
      p = w (p, b, "_");
      p = w (p, b, &peeraddr.numericcliportstr[0]);
      *(b - 1) = '\0';
      }
    /* We will not allow a single IP address to consume
       more than `numslotsglobal/2^defenderexponentglobal' slots. */
    peraddrconnlimit = numslotsglobal >> defenderexponentglobal;
    if (perAddrConnLimitExceeded (&peeraddr,
                                   peraddrconnlimit,
                                   mystrerrbufbase) != 0) {
      if (atomicallyLoadsTerminateExecution () != 0)
        goto label_close_and_return;
      /* Ignore the request. */
      if (sfdacc >= 0) {
        (void) writeoutUniversalRejectionResponse (sfdacc);
        if (close (sfdacc) != 0) {
          (void) perror ("executeAcceptLoop: close 2");
          (void) exit (1);
          }
        }
      rc = pthread_mutex_lock (&mutexfreejobchain);
      if (rc != 0) {
        (void) fprintf (stderr, "executeAcceptLoop: pthread_mutex_lock "
                         "(mutexfreejobchain) 2: "
                         "%s.\n", myStrError (rc, mystrerrbufbase));
        (void) exit (1);
        }
      /* Begin of chaining in on the left side. */
      pjob->left = 0;
      if (pfreejobchainfirst == 0) {
          pfreejobchainlast = pjob;
          pjob->right = 0;
          }
        else {
          pfreejobchainfirst->left = pjob;
          pjob->right = pfreejobchainfirst;
          }
      pfreejobchainfirst = pjob;
      /* End of chaining in on the left side. */
      rc = pthread_mutex_unlock (&mutexfreejobchain);
      if (rc != 0) {
        (void) fprintf (stderr, "executeAcceptLoop: pthread_mutex_unlock "
                         "(mutexfreejobchain) 3: "
                         "%s.\n", myStrError (rc, mystrerrbufbase));
        (void) exit (1);
        }
      continue;
      }
    if (atomicallyLoadsTerminateExecution () != 0)
      goto label_close_and_return;
    /* The request is generally accepted. It will now be placed in
       a FIFO and will later on be processed by a worker thread. */
    pjob->buflvl1 = 0;
    pjob->buflvl2 = 0;
    pjob->buflvl3 = 0;
    pjob->sfd = sfdacc;
    (void) memcpy (&pjob->sau, &peeraddr, sizeof (sau_t));
    rc = pthread_mutex_lock (&mutexjobstobedone);
    if (rc != 0) {
      (void) fprintf (stderr, "executeAcceptLoop: pthread_mutex_lock "
                       "(mutexjobstobedone): "
                       "%s.\n", myStrError (rc, mystrerrbufbase));
      (void) exit (1);
      }
    /* Begin of chaining in on the right side. */
    pjob->right = 0;
    if (pjobstobedonelast == 0) {
        pjobstobedonefirst = pjob;
        pjob->left = 0;
        }
      else {
        pjobstobedonelast->right = pjob;
        pjob->left = pjobstobedonelast;
        }
    pjobstobedonelast = pjob;
    /* End of chaining in on the right side. */
    rc = pthread_mutex_unlock (&mutexjobstobedone);
    if (rc != 0) {
      (void) fprintf (stderr, "executeAcceptLoop: pthread_mutex_unlock "
                       "(mutexjobstobedone): "
                       "%s.\n", myStrError (rc, mystrerrbufbase));
      (void) exit (1);
      }
    if (atomicallyLoadsTerminateExecution () != 0)
      /* Do not close the file descriptor here. */
      break;
    /* continue */
    }
  return;
  }

/****************************************************************************/

static void
fileAnAccessRecord (const char *p, char *mystrerrbufbase)
{
  unsigned int lenrec, n;
  int rc;

  lenrec = (unsigned int) strlen (p);
  for (;;) {
    if (atomicallyLoadsTerminateExecution () != 0)
      return;
    rc = pthread_mutex_lock (&mutexdiskoutbuffer);
    if (rc != 0) {
      (void) fprintf (stderr, "fileAnAccessRecord: pthread_mutex_lock "
                       "(mutexdiskoutbuffer): "
                       "%s.\n", myStrError (rc, mystrerrbufbase));
      (void) atomicallyStoresTwoToTerminateExecution ();
      return;
      }
    n = diskoutbufwhichone == 0 ? diskoutbuflvl0 : diskoutbuflvl1;
    if (n + lenrec + 1 <= kbytesdiskoutbufferglobal * 1024)
      break;
    /* Output buffer full, wait for `workerDiskOutput()'.
       This should never happen. */
    rc = pthread_mutex_unlock (&mutexdiskoutbuffer);
    if (rc != 0) {
      (void) fprintf (stderr, "fileAnAccessRecord: pthread_mutex_unlock "
                       "(mutexdiskoutbuffer) 1: "
                       "%s.\n", myStrError (rc, mystrerrbufbase));
      /* We cannot do more than pray. */
      (void) atomicallyStoresTwoToTerminateExecution ();
      return;
      }
    if (atomicallyLoadsTerminateExecution () != 0)
      return;
    (void) sleepMilliSecs (millisecstobesleptglobal, mystrerrbufbase);
    }
  if (diskoutbufwhichone == 0) {
      (void) strcpy ((char *) (diskoutbuffer0 + diskoutbuflvl0), p);
      diskoutbuflvl0 += lenrec;
      }
    else {
      (void) strcpy ((char *) (diskoutbuffer1 + diskoutbuflvl1), p);
      diskoutbuflvl1 += lenrec;
      }
  rc = pthread_mutex_unlock (&mutexdiskoutbuffer);
  if (rc != 0) {
    (void) fprintf (stderr, "fileAnAccessRecord: pthread_mutex_unlock "
                     "(mutexdiskoutbuffer) 2: "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    /* We cannot do more than pray. */
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  return;
  }

/****************************************************************************/

static unsigned int
findFreeSlot (sau_t *sau, struct timeval *currtim, unsigned int *slotout)
{
  static const char *uchexstr = "0123456789ABCDEF";
  char buf5 [5];
  unsigned int slot, peraddrconnlimit;
  ctn_t *node;

  if (pfreecretimnodechainfirst == 0)
    /* Resource busy. */
    return (1);
  slot = pfreecretimnodechainfirst->slot;
  buf5[0] = *(uchexstr + (slot >> 12 & (unsigned int) 0xf));
  buf5[1] = *(uchexstr + (slot >>  8 & (unsigned int) 0xf));
  buf5[2] = *(uchexstr + (slot >>  4 & (unsigned int) 0xf));
  buf5[3] = *(uchexstr + (slot       & (unsigned int) 0xf));
  buf5[4] = '\0';
  if (strcmp (&buf5[0], (char *) (statelocatorbaseaddr + slot * 193)) != 0) {
    (void) fprintf (stderr, "findFreeSlot: Unrecoverable error.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    /* Internal server error. */
    return (3);
    }
  peraddrconnlimit = numslotsglobal >> defenderexponentglobal;
  if (registerIpAddress2 (sau, peraddrconnlimit) != 0)
    /* Rejected. */
    return (2);
  /* Begin of non-zero chaining out on the left side. */
  node = pfreecretimnodechainfirst;
  if (pfreecretimnodechainfirst->right != 0)
      pfreecretimnodechainfirst->right->left = 0;
    else
      pfreecretimnodechainlast = 0;
  pfreecretimnodechainfirst = pfreecretimnodechainfirst->right;
  /* End of non-zero chaining out on the left side. */
  (void) memcpy (&node->creatim, currtim, sizeof (struct timeval));
  (void) memcpy (&node->sau, sau, sizeof (sau_t));
  if (atomicallyLoadsTerminateExecution () < 2)
    if (insertCreationTimeNode (node) != 0) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      /* Internal server error. */
      return (3);
      }
  *slotout = slot;
  return (0);
  }

/****************************************************************************/

static void
flushOutStreams (void)
{
  if (fflush (stdout) != 0) {
    (void) perror ("flushOutStreams: fflush (stdout)");
    (void) atomicallyStoresTwoToTerminateExecution ();
    }
  /* Fails when `stdout' points to a terminal,
     but not when it is redirected to a regular file.
     So keep calm. */
  (void) fsync (fileno (stdout));
  if (fflush (stderr) != 0) {
    (void) perror ("flushOutStreams: fflush (stderr)");
    (void) atomicallyStoresTwoToTerminateExecution ();
    }
  /* Fails when `stderr' points to a terminal,
     but not when it is redirected to a regular file.
     So keep calm. */
  (void) fsync (fileno (stderr));
  return;
  }

/****************************************************************************/

static void
getCanonicalHostname (char *buf, unsigned int bufdim)
{
  struct utsname utsn;
  struct addrinfo aihints, *paistart, *pai;
  int rc;
  sau_t sau;

  /* If this function does not provide a publically valid host name, the
     network configuration associated with this host should be examined.
     The `uname' syscall is our first approach here. */
  (void) memset (&utsn, 0, sizeof (utsn));
  if (uname (&utsn) != 0) {
    (void) perror ("getCanonicalHostname: uname");
    (void) exit (1);
    }
  *(utsn.nodename + sizeof (utsn.nodename) /
                    sizeof (utsn.nodename[0]) - 1) = '\0';
  /* Convert to lower case. */
  (void) checkAndLowerHostname (&utsn.nodename[0]);
  /* Next is to use the nodename from `uname' to obtain
     the FQDN as seen from the point of view of the host. */
  (void) memset (&aihints, 0, sizeof (aihints));
  aihints.ai_flags = AI_ADDRCONFIG | AI_CANONNAME;
  aihints.ai_family = AF_UNSPEC;
  aihints.ai_socktype = SOCK_STREAM;
  aihints.ai_protocol = IPPROTO_TCP;
  rc = getaddrinfo (&utsn.nodename[0], 0, &aihints, &paistart);
  if (rc != 0) {
    (void) fprintf (stderr, "getCanonicalHostname: getaddrinfo 1: "
                     "%s.\n", gai_strerror (rc));
    (void) exit (1);
    }
  /* Do not spin through the `addrinfo' structures.
     Consider the first member only. */
  pai = paistart;
  (void) strncpy (buf, pai->ai_canonname, (size_t) bufdim);
  (void) freeaddrinfo (paistart);
  if (bufdim != 0)
    *(buf + bufdim - 1) = '\0';
  /* Convert to lower case. */
  (void) checkAndLowerHostname (buf);
  /* Next is to use the above FQDN to obtain a socket address. */
  rc = getaddrinfo (buf, 0, &aihints, &paistart);
  if (rc != 0) {
    (void) fprintf (stderr, "getCanonicalHostname: getaddrinfo 2: "
                     "%s.\n", gai_strerror (rc));
    (void) exit (1);
    }
  /* Do not spin through the `addrinfo' structures.
     Consider the first member only. */
  pai = paistart;
  (void) memcpy (&sau.sas, pai->ai_addr, pai->ai_addrlen);
  sau.addrlen = pai->ai_addrlen;
  (void) freeaddrinfo (paistart);
  /* Now perform a reverse DNS Lookup using the obtained
     socket address. This should yield the FQDN as seen
     from the point of view of the Internet. */
  rc = getnameinfo ((struct sockaddr *) &sau.sas, sau.addrlen, buf,
                     (socklen_t) bufdim, 0, 0, NI_NAMEREQD);
  if (rc != 0) {
    (void) fprintf (stderr, "getCanonicalHostname: getnameinfo: "
                     "%s.\n", gai_strerror (rc));
    (void) exit (1);
    }
  if (bufdim != 0)
    *(buf + bufdim - 1) = '\0';
  /* Convert to lower case. */
  (void) checkAndLowerHostname (buf);
  return;
  }

/****************************************************************************/

static int
getListenBacklog (void)
{
  static const char *procfile = "/proc/sys/net/core/somaxconn";
  char bufio [33];
  int backlog, fdio, rc;
  unsigned int somaxconn;

  /* A sufficiently large `backlog' value for `listen()' is desirable here
     for two reasons. Firstly, we do not want the peer to be rejected with
     the error code `ECONNRESET', but with a qualified message. Secondly,
     we always have to be able to connect to the server ourselves to shut
     it down properly. */
  backlog = (int) numslotsglobal * 4 + 100;
  fdio = open (procfile, O_RDONLY);
  if (fdio == -1) {
    (void) perror ("getListenBacklog: open");
    (void) exit (1);
    }
  if (read (fdio, &bufio[0], sizeof (bufio)) == -1) {
    (void) perror ("getListenBacklog: read");
    (void) exit (1);
    }
  if (sscanf (&bufio[0], "%u", &somaxconn) != 1) {
    if (errno != 0) {
      (void) perror ("getListenBacklog: sscanf 1");
      (void) exit (1);
      }
    (void) fprintf (stderr, "getListenBacklog: sscanf 2: "
                     "Unrecoverable error.\n");
    (void) exit (1);
    }
  if (close (fdio) != 0) {
    (void) perror ("getListenBacklog: close 1");
    (void) exit (1);
    }
  /* What we have in our hands now with `somaxconn' is an upper bound for
     the argument `backlog' for the `listen()' function. If we find this
     upper bound too small, we should increase it. */
  if (somaxconn < (unsigned int) backlog) {
    /* The value of `somaxconn' is less than we want it to be. So we are
       going to enlarge this upper bound, writing into `/proc/...'.
       To do so, we need to run as root. */
    fdio = open (procfile, O_WRONLY);
    if (fdio != -1) {
      /* We are here, so we run as root. Good. */
      somaxconn = (unsigned int) backlog;
      /* We do not forget the '\n' character here. Otherwise, we
         will get EINVAL from the following `write()' below. */
      rc = snprintf (&bufio[0], sizeof (bufio), "%u\n", somaxconn);
      if (rc >= (int) sizeof (bufio)) {
        (void) fprintf (stderr, "getListenBacklog: snprintf: "
                         "Internal buffer overflow.\n");
        (void) exit (1);
        }
      if (write (fdio, &bufio[0], strlen (&bufio[0])) == -1) {
        (void) perror ("getListenBacklog: write");
        (void) exit (1);
        }
      if (close (fdio) != 0) {
        (void) perror ("getListenBacklog: close 2");
        (void) exit (1);
        }
      }
    }
  if (backlog > (int) somaxconn)
    /* We do not run as root. */
    backlog = (int) somaxconn;
  return (backlog);
  }

/****************************************************************************/

static void
getRandomBytes32 (unsigned int rank, unsigned int n, unsigned char *buf)
{
  struct timeval tv;
  struct {
    unsigned char tv [sizeof (struct timeval) / sizeof (unsigned char)];
    unsigned char crc1 [2];
    unsigned char crc2 [2];
    unsigned char randomblock1 [32];
    unsigned char randomblock2 [32];
    unsigned char hash [32];
    } b;
  unsigned int k, m;
  unsigned char *p;

  if (n > 32) {
    (void) fprintf (stderr, "getRandomBytes32: Excessive requirement.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    }
  /* Everyone has his own paranoia. Good. */
  if (n == 0) {
    (void) memset (&tv, 0, sizeof (tv));
    if (gettimeofday (&tv, 0) != 0) {
      (void) perror ("getRandomBytes32: gettimeofday");
      tv.tv_sec = 0;
      tv.tv_usec = 0;
      (void) atomicallyStoresTwoToTerminateExecution ();
      }
    (void) memcpy (&b.tv[0], &tv, sizeof (tv));
    }
  k = rank;
  (void) crc16 ((unsigned int) sizeof (k), (unsigned char *) &k, &b.crc1[0]);
  k = n;
  (void) crc16 ((unsigned int) sizeof (k), (unsigned char *) &k, &b.crc2[0]);
  (void) memcpy (&b.randomblock1[0], randomblockbaseaddr + rank * 192, 64);
  p = &b.crc1[0];
  m = 68;
  if (n == 0) {
    p -= sizeof (struct timeval) / sizeof (unsigned char);
    m += (unsigned int) (sizeof (struct timeval) / sizeof (unsigned char));
    }
  (void) sha256 (m, p, &b.hash[0]);
  (void) memcpy (randomblockbaseaddr + rank * 192, &b.randomblock2[0], 64);
  if (n == 0)
    return;
  while (n > 32) {
    (void) memcpy (buf, &b.hash[0], 32);
    buf += 32;
    n -= 32;
    }
  (void) memcpy (buf, &b.hash[0], (size_t) n);
  return;
  }

/****************************************************************************/

static unsigned int
gotTheCompleteHttpRequest (unsigned char *buf, unsigned int len)
{
  char buf5 [5];
  const char *pconst;
  char *pcontent, *pcontentlen, *p0;
  unsigned int nchars, i, contentlen, requestlen;

  *(buf + len) = '\0';
  pconst = "\r\n\r\n";
  if ((pcontent = strstr ((char *) buf, pconst)) == 0) {
    pconst = "\n\n";
    if ((pcontent = strstr ((char *) buf, pconst)) == 0)
      return (0);
    pcontent -= 2;
    }
  pcontent += 4;
  if (*pcontent == '\0')
    return (1);
  pconst = "\nContent-Length:";
  if ((pcontentlen = strstr ((char *) buf, pconst)) == 0)
    return (0);
  pcontentlen += strlen (pconst);
  while (*pcontentlen == ' ')
    pcontentlen++;
  if (isdigit (*pcontentlen) == 0)
    return (0);
  p0 = pcontentlen + 1;
  while (isdigit (*p0) != 0)
    p0++;
  if (p0 >= pcontent)
    return (0);
  if ((nchars = passU ((unsigned int) (p0 - pcontentlen))) > 4)
    return (0);
  for (i = 0; i < nchars; i++)
    buf5[i] = *(pcontentlen + i);
  buf5[nchars] = '\0';
  (void) sscanf (&buf5[0], "%u", &contentlen);
  requestlen = passU ((unsigned int) (pcontent - (char *) buf)) + contentlen;
  if (requestlen + 2 == len)
    if (*(buf + requestlen + 0) == 0x0d)
      if (*(buf + requestlen + 1) == 0x0a)
        /* Some clients send the request with an
           appended but not counted ^M-^J sequence. */
        return (1);
  if (requestlen != len)
    return (0);
  return (1);
  }

/****************************************************************************/

#if (0)
static void
handleSigintSigusr1Sigterm (int sig)
{
  atomic_uint te, desi;

  if (sig == SIGINT || sig == SIGTERM) {
    /* Performs `if(terminateexecution==0)terminateexecution=1;'. */
    te = atomic_load (&terminateexecution);
    desi = te == 0 ? 1 : te;
    while (!atomic_compare_exchange_weak (&terminateexecution, &te, desi));
    }
  if (sig == SIGUSR1) {
    (void) atomicallyStoresOneToWriteoutAccRecsToFile ();
    }
  return;
  }
#endif

/****************************************************************************/

static void
httpServer (job_t *pjob, char *mystrerrbufbase)
{
  char timiso8601 [21], buf32 [32], formbuf32 [32], buf151 [151], buf65 [65];
  unsigned char statelocator [65];
  unsigned int get, post, nchars, i, statelocatorequalszero, shutdownreq,
    reqlinnum, k, neednewstatelocator, cliappquali, reslinnum, ncharsrecord,
    contentlength;
  char *p0, *psrccontent, *p1, *psrc, *pdst;
  unsigned char *p, *b, *psetjump, rcmuco;
  struct timeval currtim;
  struct tm tm;
  int rc;
  const char *pconst, *pconst1, *pconst2;

  get = 0;
  p0 = (char *) pjob->pbuf1;
  while (*p0 == ' ' || *p0 == '\t')
    p0++;
  if (*(p0 + 0) == 'G' ||
      *(p0 + 1) == 'E' ||
      *(p0 + 2) == 'T') {
    p0 += 3;
    if (*p0 == ' ' || *p0 == '\t') {
      p0++;
      while (*p0 == ' ' || *p0 == '\t')
        p0++;
      if (*p0 == '/') {
        p0++;
        while (*p0 != ' '  && *p0 != '\t' &&
               *p0 != '\r' && *p0 != '\n' &&
               *p0 != '\0')
          p0++;
        if (*p0 == ' ' || *p0 == '\t') {
          p0++;
          while (*p0 == ' ' || *p0 == '\t')
            p0++;
          if (*(p0 + 0) == 'H' ||
              *(p0 + 1) == 'T' ||
              *(p0 + 2) == 'T' ||
              *(p0 + 3) == 'P' ||
              *(p0 + 4) == '/' ||
              *(p0 + 5) == '1' ||
              *(p0 + 6) == '.' ||
              *(p0 + 7) == '1') {
            p0 += 8;
            while (*p0 == ' ' || *p0 == '\t')
              p0++;
            if (*p0 == '\r')
              p0++;
            if (*p0 == '\n')
              get = 1;
            }
          }
        }
      }
    }
  post = 0;
  p0 = (char *) pjob->pbuf1;
  while (*p0 == ' ' || *p0 == '\t')
    p0++;
  if (*(p0 + 0) == 'P' ||
      *(p0 + 1) == 'O' ||
      *(p0 + 2) == 'S' ||
      *(p0 + 3) == 'T') {
    p0 += 4;
    if (*p0 == ' ' || *p0 == '\t') {
      p0++;
      while (*p0 == ' ' || *p0 == '\t')
        p0++;
      if (*p0 == '/') {
        p0++;
        while (*p0 != ' '  && *p0 != '\t' &&
               *p0 != '\r' && *p0 != '\n' &&
               *p0 != '\0')
          p0++;
        if (*p0 == ' ' || *p0 == '\t') {
          p0++;
          while (*p0 == ' ' || *p0 == '\t')
            p0++;
          if (*(p0 + 0) == 'H' ||
              *(p0 + 1) == 'T' ||
              *(p0 + 2) == 'T' ||
              *(p0 + 3) == 'P' ||
              *(p0 + 4) == '/' ||
              *(p0 + 5) == '1' ||
              *(p0 + 6) == '.' ||
              *(p0 + 7) == '1') {
            p0 += 8;
            while (*p0 == ' ' || *p0 == '\t')
              p0++;
            if (*p0 == '\r')
              p0++;
            if (*p0 == '\n')
              post = 1;
            }
          }
        }
      }
    }
  p = pjob->pbuf2;
  b = pjob->pbuf2 + pjob->bufdim - 1;
  p = w (p, b, "HTTP/1.1 200 OK\r\n");
  p = w (p, b, "Date: ");
  if (gettimeofday (&currtim, 0) != 0) {
    (void) perror ("httpServer: gettimeofday");
    currtim.tv_sec = 0;
    currtim.tv_usec = 0;
    (void) atomicallyStoresTwoToTerminateExecution ();
    }
  if (gmtime_r (&currtim.tv_sec, &tm) != &tm) {
    (void) perror ("httpServer: gmtime_r");
    (void) memset (&tm, 0, sizeof (tm));
    tm.tm_mday = 1;
    tm.tm_year = 70;
    tm.tm_wday = 4;
    (void) atomicallyStoresTwoToTerminateExecution ();
    }
  /* ISO 8601. */
  if (strftime (&timiso8601[0], sizeof (timiso8601),
                 "%Y-%m-%dT%H:%M:%SZ", &tm) != 20) {
    (void) fprintf (stderr, "httpServer: strftime: String length error 1.\n");
    (void) strcpy (&timiso8601[0], "1970-01-01T00:00:00Z");
    (void) atomicallyStoresTwoToTerminateExecution ();
    }
  /* RFC 1123. */
  if (strftime (&buf32[0], sizeof (buf32),
                 "%a, %d %b %Y %H:%M:%S GMT", &tm) != 29) {
    (void) fprintf (stderr, "httpServer: strftime: String length error 2.\n");
    (void) strcpy (&buf32[0], "Thu, 01 Jan 1970 00:00:00 GMT");
    (void) atomicallyStoresTwoToTerminateExecution ();
    }
  p = w (p, b, &buf32[0]);
  p = w (p, b, "\r\n");
  p = w (p, b, "Server: FDEI");
  if (get != 0)
    p = w (p, b, "L");
  if (post != 0)
    p = w (p, b, "X");
  p = w (p, b, "/" MYWEBSERVER_FDEI_VERSION "\r\n");
  p = w (p, b, "Connection: close\r\n");
  p = w (p, b, "Content-Length: <contentlength></contentlength>\r\n");
  p = w (p, b, "Content-Type: application/xhtml+xml;charset=us-ascii\r\n");
  p = w (p, b, "\r\n");
  p = w (p, b, "<?xml version=\"1.0\" encoding=\"us-ascii\"?>\r\n");
  p = w (p, b, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML Basic 1.1//EN\" ");
  p = w (p, b, "\"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd\">\r\n");
  p = w (p, b, "<html xmlns=\"http://www.w3.org/1999/xhtml\" ");
  p = w (p, b, "lang=\"en\" xml:lang=\"en\">\r\n");
  p = w (p, b, "<head>\r\n");
  if (strlen (&faviconurl[0]) != 0) {
    p = w (p, b, "<link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"");
    p = w (p, b, &faviconurl[0]);
    p = w (p, b, "\"/>\r\n");
    }
  p = w (p, b, "<title>FDEI");
  if (get != 0)
    p = w (p, b, "L");
  if (post != 0)
    p = w (p, b, "X");
  p = w (p, b, " " MYWEBSERVER_FDEI_VERSION "</title>\r\n");
  p = w (p, b, "</head>\r\n");
  p = w (p, b, "<body>\r\n");
  p = w (p, b, "<div>FDEI");
  if (get != 0) {
    p = w (p, b, " Locator, referencing FDEI Executables</div>\r\n");
    p = w (p, b, "<div>FDEIL");
    }
  if (post != 0) {
    p = w (p, b, " Executable</div>\r\n");
    p = w (p, b, "<div>FDEIX");
    }
  p = w (p, b, " " MYWEBSERVER_FDEI_VERSION ", suitable for "
                   MYWEBSERVER_APPLICATION_NAME " version "
                   MYWEBSERVER_MINIMUM_APPLICATION_VERSION
               " and higher</div>\r\n");
  p = w (p, b, "<div>youripaddr=");
  p = w (p, b, &pjob->sau.numericcliaddrstr[0]);
  p = w (p, b, "</div>\r\n");
  if (strchr (&pjob->sau.numericcliaddrstr[0], '.') != 0) {
    if (strchr (&pjob->sau.numericcliaddrstr[0], ':') == 0) {
      p = w (p, b, "<div>youripv4addr=");
      p = w (p, b, &pjob->sau.numericcliaddrstr[0]);
      p = w (p, b, "</div>\r\n");
      }
    }
  if (strchr (&pjob->sau.numericcliaddrstr[0], ':') != 0) {
    if (strchr (&pjob->sau.numericcliaddrstr[0], '.') == 0) {
      p = w (p, b, "<div>youripv6addr=");
      p = w (p, b, &pjob->sau.numericcliaddrstr[0]);
      p = w (p, b, "</div>\r\n");
      }
    }
  p = w (p, b, "<div>youripport=");
  p = w (p, b, &pjob->sau.numericcliportstr[0]);
  p = w (p, b, "</div>\r\n");
  p = w (p, b, "<div>servertimestamp=");
  rc = snprintf (&buf32[0], sizeof (buf32), "%lu",
                  (unsigned long) currtim.tv_sec);
  if (rc >= (int) sizeof (buf32)) {
    (void) fprintf (stderr, "httpServer: snprintf 1: "
                     "Internal buffer overflow.\n");
    (void) strcpy (&buf32[0], "0");
    (void) atomicallyStoresTwoToTerminateExecution ();
    }
  p = w (p, b, &buf32[0]);
  p = w (p, b, ".");
  rc = snprintf (&buf32[0], sizeof (buf32), "%06u",
                  (unsigned int) currtim.tv_usec);
  if (rc >= (int) sizeof (buf32)) {
    (void) fprintf (stderr, "httpServer: snprintf 2: "
                     "Internal buffer overflow.\n");
    (void) strcpy (&buf32[0], "000000");
    (void) atomicallyStoresTwoToTerminateExecution ();
    }
  p = w (p, b, &buf32[0]);
  p = w (p, b, "</div>\r\n");
  p = w (p, b, "<div>servertime=");
  p = w (p, b, &timiso8601[0]);
  p = w (p, b, "</div>\r\n");
  psetjump = p;
  if (get != 0) {
    p = w (p, b, "<div>fdeixnum=1</div>\r\n");
    p = w (p, b, "<div>fdeix0=");
    p = w (p, b, &executorurl[0]);
    p = w (p, b, "</div>\r\n");
    p = w (p, b, "<div>endofres=1</div>\r\n");
    goto label_finish_html;
    }
  if (get == 0 && post == 0) {
    /***** LABEL *****/ label_syntax_or_spec_error:
    p = psetjump;
    if (atomicallyLoadsTerminateExecution () < 2)
        p = w (p, b, "<div>FDEI HTTP spoken here</div>\r\n");
      else
        p = w (p, b, "<div>Internal server error</div>\r\n");
    /***** LABEL *****/ label_jump_from_malicious_attack:
    p = w (p, b, "<div>FDEI Universal Rejection Response</div>\r\n");
    p = w (p, b, "<div>fdeixnum=1</div>\r\n");
    p = w (p, b, "<div>fdeix0=");
    p = w (p, b, &executorurl[0]);
    p = w (p, b, "</div>\r\n");
    p = w (p, b, "<div>sentstatelocator=");
    p = w (p, b, "00000000000000000000000000000000");
    p = w (p, b, "00000000000000000000000000000000");
    p = w (p, b, "</div>\r\n");
    p = w (p, b, "<div>statelocator=");
    p = w (p, b, "00000000000000000000000000000000");
    p = w (p, b, "00000000000000000000000000000000");
    p = w (p, b, "</div>\r\n");
    p = w (p, b, "<div>shutdownrequestacknowledged=1</div>\r\n");
    rcmuco = MYWEBSERVER_MUCO_RC_REQUESTREJECTED;
    p = w (p, b, "<div>returncode=");
    (void) doAsciiArmoring (&rcmuco, 1, (unsigned char *) &buf32[0]);
    p = w (p, b, &buf32[0]);
    p = w (p, b, "</div>\r\n");
    p = w (p, b, "<div>reslinnum=1</div>\r\n");
    p = w (p, b, "<div>reslin0=");
    buf32[0] = 0;
    buf32[1] = 8;
    buf32[2] = (char) rcmuco;
    (void) crc16 (3, (unsigned char *) &buf32[0],
                     (unsigned char *) &buf32[3]);
    buf32[5] = buf32[3] ^ buf32[4];
    (void) crc16 (6, (unsigned char *) &buf32[0],
                     (unsigned char *) &buf32[6]);
    (void) doAsciiArmoring ((unsigned char *) &buf32[0], 8,
                             (unsigned char *) &buf32[8]);
    p = w (p, b, &buf32[8]);
    p = w (p, b, "</div>\r\n");
    p = w (p, b, "<div>endofres=1</div>\r\n");
    goto label_finish_html;
    }
  pconst = "\r\n\r\n";
  if ((psrccontent = strstr ((char *) pjob->pbuf1, pconst)) == 0) {
    pconst = "\n\n";
    if ((psrccontent = strstr ((char *) pjob->pbuf1, pconst)) == 0)
      goto label_syntax_or_spec_error;
    psrccontent -= 2;
    }
  *(psrccontent + 3) = '&';
  pconst = "&statelocator=";
  if ((p0 = strstr (psrccontent, pconst)) == 0)
    goto label_syntax_or_spec_error;
  p0 += strlen (pconst);
  if ((p1 = strchr (p0, '&')) == 0)
    goto label_syntax_or_spec_error;
  if ((nchars = passU ((unsigned int) (p1 - p0))) != 64)
    goto label_syntax_or_spec_error;
  for (i = 0; i < nchars; i++) {
    if (isxdigit (*(p0 + i)) == 0)
      goto label_syntax_or_spec_error;
    }
  *p1 = '\0';
  p = w (p, b, "<div>rcvdstatelocator=");
  p = w (p, b, p0);
  p = w (p, b, "</div>\r\n");
  (void) strcpy ((char *) &statelocator[0], p0);
  *p1 = '&';
  statelocatorequalszero = 1;
  for (i = 0; i < nchars; i++) {
    if (*(p0 + i) != '0') {
      statelocatorequalszero = 0;
      break;
      }
    }
  if (statelocatorequalszero == 0) {
    if (isValidStateLocator (&statelocator[0], mystrerrbufbase) == 0) {
      if (atomicallyLoadsTerminateExecution () >= 2)
        goto label_syntax_or_spec_error;
      p = psetjump;
      p = w (p, b, "<div>POST viewed as a malicious attack</div>\r\n");
      goto label_jump_from_malicious_attack;
      }
    }
  shutdownreq = strstr (psrccontent, "&shutdown=1&") == 0 ? 0 : 1;
  if (shutdownreq != 0)
    p = w (p, b, "<div>shutdown=1</div>\r\n");
  pconst = "&reqlinnum=";
  if ((p0 = strstr (psrccontent, pconst)) == 0)
    goto label_syntax_or_spec_error;
  p0 += strlen (pconst);
  if ((p1 = strchr (p0, '&')) == 0)
    goto label_syntax_or_spec_error;
  if ((nchars = passU ((unsigned int) (p1 - p0))) > 4)
    goto label_syntax_or_spec_error;
  for (i = 0; i < nchars; i++) {
    if (isdigit (*(p0 + i)) == 0)
      goto label_syntax_or_spec_error;
    }
  *p1 = '\0';
  if (sscanf (p0, "%u", &reqlinnum) != 1) {
    if (errno != 0)
        (void) perror ("httpServer: sscanf");
      else
        (void) fprintf (stderr, "httpServer: sscanf: Unrecoverable error.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_syntax_or_spec_error;
    }
  p = w (p, b, "<div>reqlinnum=");
  p = w (p, b, p0);
  p = w (p, b, "</div>\r\n");
  *p1 = '&';
  if (reqlinnum > 1024)
    goto label_syntax_or_spec_error;
  pjob->buflvl3 = 0;
  rc = snprintf (&formbuf32[0], sizeof (formbuf32), "%u",
                  reqlinnum == 0 ? 0 : reqlinnum - 1);
  if (rc >= (int) sizeof (formbuf32)) {
    (void) fprintf (stderr, "httpServer: snprintf 3: "
                     "Internal buffer overflow.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_syntax_or_spec_error;
    }
  rc = snprintf (&formbuf32[0], sizeof (formbuf32), "&reqlin%%0%du=", rc);
  if (rc >= (int) sizeof (formbuf32)) {
    (void) fprintf (stderr, "httpServer: snprintf 4: "
                     "Internal buffer overflow.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_syntax_or_spec_error;
    }
  for (k = 0; k < reqlinnum; k++) {
    rc = snprintf (&buf32[0], sizeof (buf32), &formbuf32[0], k);
    if (rc >= (int) sizeof (buf32)) {
      (void) fprintf (stderr, "httpServer: snprintf 5: "
                       "Internal buffer overflow.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_syntax_or_spec_error;
      }
    if ((p0 = strstr (psrccontent, &buf32[0])) == 0)
      goto label_syntax_or_spec_error;
    p0 += strlen (&buf32[0]);
    if ((p1 = strchr (p0, '&')) == 0)
      goto label_syntax_or_spec_error;
    nchars = passU ((unsigned int) (p1 - p0));
    if (k + 1 != reqlinnum) {
        if (nchars != 64)
          goto label_syntax_or_spec_error;
        }
      else {
        if (nchars == 0)
          goto label_syntax_or_spec_error;
        if ((nchars & (unsigned int) 0x1) != 0)
          goto label_syntax_or_spec_error;
        }
    for (i = 0; i < nchars; i++) {
      if (isxdigit (*(p0 + i)) == 0)
        goto label_syntax_or_spec_error;
      }
    *p1 = '\0';
    p = w (p, b, "<div>");
    p = w (p, b, &buf32[1]);
    p = w (p, b, p0);
    p = w (p, b, "</div>\r\n");
    (void) undoAsciiArmoring ((unsigned char *) p0,
                               pjob->pbuf3 + pjob->buflvl3,
                               mystrerrbufbase);
    if (atomicallyLoadsTerminateExecution () >= 2)
      goto label_syntax_or_spec_error;
    pjob->buflvl3 += nchars >> 1;
    *p1 = '&';
    }
  p0 = strstr (psrccontent, "&endofreq=1");
  if (p0 == 0)
    goto label_syntax_or_spec_error;
  p0 += strlen ("&endofreq=1");
  if (*p0 != '\0' && *p0 != '&' && *p0 != '\n' && *p0 != '\r')
    goto label_syntax_or_spec_error;
  p = w (p, b, "<div>endofreq=1</div>\r\n");
  /* Here, input has correctly been read. */
  rc = pthread_mutex_lock (&mutexstalocliftim);
  if (rc != 0) {
    (void) fprintf (stderr, "httpServer: pthread_mutex_lock "
                     "(mutexstalocliftim): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_syntax_or_spec_error;
    }
  /* Due to runtime requirements, the following function
     will remove a maximum of 2 expired state locators. */
  (void) enforceStateLocatorLifeTimeRule (&currtim, mystrerrbufbase);
  pjob->slot = 0xffffffff;
  rcmuco = MYWEBSERVER_MUCO_RC_SUCCESS;
  if (rcmuco == MYWEBSERVER_MUCO_RC_SUCCESS)
    if (shutdownreq != 0 && statelocatorequalszero != 0)
      /* Illogical combination. */
      rcmuco = MYWEBSERVER_MUCO_RC_REQUESTREJECTED;
  if (rcmuco == MYWEBSERVER_MUCO_RC_SUCCESS)
    if (statelocatorequalszero == 0) {
      buf32[0] = (char) statelocator[0];
      buf32[1] = (char) statelocator[1];
      buf32[2] = (char) statelocator[2];
      buf32[3] = (char) statelocator[3];
      buf32[4] = '\0';
      (void) undoAsciiArmoring ((unsigned char *) &buf32[0],
                                 (unsigned char *) &buf32[5],
                                 mystrerrbufbase);
      pjob->slot = ((unsigned int) buf32[5] & (unsigned int) 0xff) << 8
                 | ((unsigned int) buf32[6] & (unsigned int) 0xff);
#if (0)
      /* The following test has already been performed
         with `isValidStateLocator()' above. So we do not
         have a problem inside a critical region. Good. */
      if (pjob->slot >= numslotsglobal) {
        ....
        }
#endif
      if (strcmp ((char *) &statelocator[0],
                   (char *) (statelocatorbaseaddr + pjob->slot * 193)) != 0) {
        /* We received a formally valid non-zero state locator,
           but this state locator is not in our data base.
           Most likely already removed because it expired. */
        rcmuco = MYWEBSERVER_MUCO_RC_REQUESTREJECTED;
        (void) memset (&statelocator[0], '0', 64);
        statelocatorequalszero = 1;
        pjob->slot = 0xffffffff;
        shutdownreq = 0;
        }
      }
  if (rcmuco == MYWEBSERVER_MUCO_RC_SUCCESS)
    if (statelocatorequalszero == 0)
      if (checkChangedIpAddress (pjob) != 0) {
        /* We do not allow a client here to access the same slot on the one
           hand and to appear with different IP addresses on the other. This
           could undermine our defense system. */
        rcmuco = MYWEBSERVER_MUCO_RC_REQUESTREJECTED;
        if (atomicallyLoadsTerminateExecution () < 2)
          (void) removeStateLocatorAndIpAddress2 (&statelocator[0],
                                                   mystrerrbufbase);
        (void) memset (&statelocator[0], '0', 64);
        statelocatorequalszero = 1;
        pjob->slot = 0xffffffff;
        }
  if (rcmuco == MYWEBSERVER_MUCO_RC_SUCCESS)
    if (shutdownreq != 0) {
      /* Accomplish the shutdown request. */
      if (atomicallyLoadsTerminateExecution () < 2)
        (void) removeStateLocatorAndIpAddress2 (&statelocator[0],
                                                 mystrerrbufbase);
      (void) memset (&statelocator[0], '0', 64);
      statelocatorequalszero = 1;
      pjob->slot = 0xffffffff;
      }
  neednewstatelocator = 0;
  if (rcmuco == MYWEBSERVER_MUCO_RC_SUCCESS)
    if (shutdownreq == 0)
      if (statelocatorequalszero != 0) {
        rc = findFreeSlot (&pjob->sau, &currtim, &pjob->slot);
        if (rc == 0) {
            /* This would be the right place here to create a new state
               locator. But creating them is expensive. So we just looked
               for a free slot here and moved the creation of the state
               locator to a relaxed point below where the mutex will have
               been unlocked again. */
            neednewstatelocator = 1;
            }
          else if (rc == 1) {
            rcmuco = MYWEBSERVER_MUCO_RC_RESOURCEBUSY;
            }
          else if (rc == 2) {
            rcmuco = MYWEBSERVER_MUCO_RC_REQUESTREJECTED;
            }
          else {
            (void) atomicallyStoresTwoToTerminateExecution ();
            }
        }
  rc = pthread_mutex_unlock (&mutexstalocliftim);
  if (rc != 0) {
    (void) fprintf (stderr, "httpServer: pthread_mutex_unlock "
                     "(mutexstalocliftim): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    /* We cannot do more than pray. */
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_syntax_or_spec_error;
    }
  /* Make sure `findFreeSlot()' above worked correctly. */
  if (atomicallyLoadsTerminateExecution () >= 2)
    goto label_syntax_or_spec_error;
  if (neednewstatelocator != 0) {
    (void) createStateLocator (pjob->rank, pjob->slot, &statelocator[0]);
    (void) strcpy ((char *) (statelocatorbaseaddr + pjob->slot * 193),
                    (char *) &statelocator[0]);
    statelocatorequalszero = 0;
    }
  if (rcmuco != MYWEBSERVER_MUCO_RC_SUCCESS)
    if (statelocatorequalszero == 0) {
      (void) fprintf (stderr, "httpServer: (logic): Unrecoverable error.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_syntax_or_spec_error;
      }
  p = w (p, b, "<div>sentstatelocator=");
  p = w (p, b, (char *) &statelocator[0]);
  p = w (p, b, "</div>\r\n");
  p = w (p, b, "<div>statelocator=");
  p = w (p, b, (char *) &statelocator[0]);
  p = w (p, b, "</div>\r\n");
  if (shutdownreq != 0 && rcmuco == MYWEBSERVER_MUCO_RC_SUCCESS)
    p = w (p, b, "<div>shutdownrequestacknowledged=1</div>\r\n");
  if (shutdownreq != 0 || rcmuco != MYWEBSERVER_MUCO_RC_SUCCESS) {
    p = w (p, b, "<div>returncode=");
    (void) doAsciiArmoring (&rcmuco, 1, (unsigned char *) &buf32[0]);
    p = w (p, b, &buf32[0]);
    p = w (p, b, "</div>\r\n");
    p = w (p, b, "<div>reslinnum=1</div>\r\n");
    p = w (p, b, "<div>reslin0=");
    buf32[0] = 0;
    buf32[1] = 8;
    buf32[2] = (char) rcmuco;
    (void) crc16 (3, (unsigned char *) &buf32[0],
                     (unsigned char *) &buf32[3]);
    buf32[5] = buf32[3] ^ buf32[4];
    (void) crc16 (6, (unsigned char *) &buf32[0],
                     (unsigned char *) &buf32[6]);
    (void) doAsciiArmoring ((unsigned char *) &buf32[0], 8,
                             (unsigned char *) &buf32[8]);
    p = w (p, b, &buf32[8]);
    p = w (p, b, "</div>\r\n");
    p = w (p, b, "<div>endofres=1</div>\r\n");
    goto label_finish_html;
    }
  if (pjob->slot > 255) {
    (void) fprintf (stderr, "httpServer: "
                     "As a reminder, the currently implemented "
                     "cruncher only has 256 processing slots.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_syntax_or_spec_error;
    }
  cliappquali = 0;
  if (*(pjob->pbuf3 + 2) == MYWEBSERVER_MUCO_OPC_CHCK)
    cliappquali++;
  (void) cruncher ((unsigned char) pjob->slot, pjob->pbuf3);
  if (*(pjob->pbuf3 + 2) == MYWEBSERVER_MUCO_RC_SUCCESS)
    cliappquali++;
  if (cliappquali == 2) {
    /* The client application is sufficiently qualified to successfully
       communicate with the cruncher. So it makes sense to file an access
       record. Another way of speaking here could be that we are facing
       a potential customer who is currently evaluating the trial version
       of our software, and of course we are interested in knowing when,
       how often and from where these tests take place. Or a customer is
       using one of our services offered. */
    rc = snprintf (&buf151[0], sizeof (buf151), "%s %03u %03u %s %s\n",
                    &timiso8601[0], pjob->slot, pjob->rank,
                    padWithLeadingZeros (&pjob->sau.numericcliportstr[0], 5,
                                          &buf32[0], sizeof (buf32)),
                    &pjob->sau.numericcliaddrstr[0]);
    if (rc >= (int) sizeof (buf151)) {
      (void) fprintf (stderr, "httpServer: snprintf 6: "
                       "Internal buffer overflow.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_syntax_or_spec_error;
      }
    (void) fileAnAccessRecord (&buf151[0], mystrerrbufbase);
    }
  p = w (p, b, "<div>returncode=");
  (void) doAsciiArmoring (pjob->pbuf3 + 2, 1, (unsigned char *) &buf32[0]);
  p = w (p, b, &buf32[0]);
  p = w (p, b, "</div>\r\n");
  p = w (p, b, "<div>reslinnum=");
  /* Pay attention, the cruncher stores in big endian mode. */
  nchars = (unsigned int) (*(pjob->pbuf3 + 0) & (unsigned char) 0xff) << 8
         | (unsigned int) (*(pjob->pbuf3 + 1) & (unsigned char) 0xff);
  reslinnum = nchars >> 5;
  if ((nchars & (unsigned int) 0x1f) != 0)
    reslinnum++;
  rc = snprintf (&buf32[0], sizeof (buf32), "%u", reslinnum);
  if (rc >= (int) sizeof (buf32)) {
    (void) fprintf (stderr, "httpServer: snprintf 7: "
                     "Internal buffer overflow.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_syntax_or_spec_error;
    }
  p = w (p, b, &buf32[0]);
  p = w (p, b, "</div>\r\n");
  rc = snprintf (&formbuf32[0], sizeof (formbuf32), "%u",
                  reslinnum == 0 ? 0 : reslinnum - 1);
  if (rc >= (int) sizeof (formbuf32)) {
    (void) fprintf (stderr, "httpServer: snprintf 8: "
                     "Internal buffer overflow.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_syntax_or_spec_error;
    }
  rc = snprintf (&formbuf32[0], sizeof (formbuf32), "<div>reslin%%0%du=", rc);
  if (rc >= (int) sizeof (formbuf32)) {
    (void) fprintf (stderr, "httpServer: snprintf 9: "
                     "Internal buffer overflow.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_syntax_or_spec_error;
    }
  for (k = 0; k < reslinnum; k++) {
    rc = snprintf (&buf32[0], sizeof (buf32), &formbuf32[0], k);
    if (rc >= (int) sizeof (buf32)) {
      (void) fprintf (stderr, "httpServer: snprintf 10: "
                       "Internal buffer overflow.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_syntax_or_spec_error;
      }
    p = w (p, b, &buf32[0]);
    ncharsrecord = k + 1 != reslinnum ? 32 : nchars & (unsigned int) 0x1f;
    (void) doAsciiArmoring (pjob->pbuf3 + k * 32, ncharsrecord,
                             (unsigned char *) &buf65[0]);
    p = w (p, b, &buf65[0]);
    p = w (p, b, "</div>\r\n");
    }
  p = w (p, b, "<div>endofres=1</div>\r\n");
  /***** LABEL *****/ label_finish_html:
  p = w (p, b, "</body>\r\n");
  p = w (p, b, "</html>\r\n");
  *(pjob->pbuf2 + pjob->bufdim - 1) = '\0';
  pconst1 = "<contentlength></contentlength>";
  pconst2 = "\r\n\r\n";
  psrc = strstr ((char *) pjob->pbuf2, pconst1);
  if (psrc == 0) {
    (void) fprintf (stderr, "httpServer: strstr (pconst1): "
                     "Unrecoverable error.\n");
    (void) strcpy ((char *) pjob->pbuf1, "Internal server error");
    pjob->buflvl1 = (unsigned int) strlen ((char *) pjob->pbuf1);
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  *psrc = '\0';
  (void) strcpy ((char *) pjob->pbuf1, (char *) pjob->pbuf2);
  *psrc = '<';
  pdst = (char *) pjob->pbuf1
       + passU ((unsigned int) (psrc - (char *) pjob->pbuf2));
  psrc += strlen (pconst1);
  psrccontent = strstr (psrc, pconst2);
  if (psrccontent == 0) {
    (void) fprintf (stderr, "httpServer: strstr (pconst2): "
                     "Unrecoverable error.\n");
    (void) strcpy ((char *) pjob->pbuf1, "Internal server error");
    pjob->buflvl1 = (unsigned int) strlen ((char *) pjob->pbuf1);
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  psrccontent += strlen (pconst2);
  contentlength = (unsigned int) strlen (psrccontent);
  rc = snprintf (&buf32[0], sizeof (buf32), "%u", contentlength);
  if (rc >= (int) sizeof (buf32)) {
    (void) fprintf (stderr, "httpServer: snprintf 11: "
                     "Internal buffer overflow.\n");
    (void) strcpy ((char *) pjob->pbuf1, "Internal server error");
    pjob->buflvl1 = (unsigned int) strlen ((char *) pjob->pbuf1);
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  (void) strcpy ((char *) pdst, &buf32[0]);
  pdst += strlen (&buf32[0]);
  (void) strcpy ((char *) pdst, (char *) psrc);
  pjob->buflvl1 = (unsigned int) strlen ((char *) pjob->pbuf1);
  return;
  }

/****************************************************************************/

static void
inetServer (const char *port, unsigned int defenderexponentlocal,
             unsigned int kbytesperslot, unsigned int debuglocal,
             unsigned int kbytesdiskoutbufferlocal,
             unsigned int kbytesthreadstacksizelocal,
             unsigned int millisecstobesleptlocal, unsigned int numslotslocal,
             unsigned int statelocatorlifetimelocal)
{
  char mystrerrbuf [MYWEBSERVER_MYSTRERRBUFDIM];
  int rc;
  job_t *pjob;

  if (port == 0) {
    (void) fprintf (stderr, "inetServer: "
                     "Null pointer as a port string.\n");
    (void) exit (1);
    }
  if (defenderexponentlocal == 0) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the defender exponent "
                     "falls below 1.\n",
                     defenderexponentlocal);
    (void) exit (1);
    }
  if (defenderexponentlocal > 4) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the defender exponent "
                     "exceeds 4.\n",
                     defenderexponentlocal);
    (void) exit (1);
    }
  if (kbytesperslot == 0) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the number of kbytes per slot "
                     "falls below 1.\n",
                     kbytesperslot);
    (void) exit (1);
    }
  if (kbytesperslot > 256) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the number of kbytes per slot "
                     "exceeds 256.\n",
                     kbytesperslot);
    (void) exit (1);
    }
  if (kbytesdiskoutbufferlocal == 0) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the number of kbytes per disk output buffer "
                     "falls below 1.\n",
                     kbytesdiskoutbufferlocal);
    (void) exit (1);
    }
  if (kbytesdiskoutbufferlocal > 32768) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the number of kbytes per disk output buffer "
                     "exceeds 32768.\n",
                     kbytesdiskoutbufferlocal);
    (void) exit (1);
    }
  if (kbytesthreadstacksizelocal > 4096) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the number of thread stack kbytes "
                     "exceeds 4096.\n",
                     kbytesthreadstacksizelocal);
    (void) exit (1);
    }
  if (millisecstobesleptlocal == 0) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the number of milliseconds to "
                     "be slept somewhere falls below 1.\n",
                     millisecstobesleptlocal);
    (void) exit (1);
    }
  if (millisecstobesleptlocal > 999) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the number of milliseconds to "
                     "be slept somewhere exceeds 999.\n",
                     millisecstobesleptlocal);
    (void) exit (1);
    }
  if (numslotslocal < (unsigned int) 1 << defenderexponentlocal) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the number of available slots "
                     "falls below 2^defenderexponent.\n",
                     numslotslocal);
    (void) exit (1);
    }
  if (numslotslocal > 256) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the number of available slots "
                     "exceeds 256.\n",
                     numslotslocal);
    (void) exit (1);
    }
  if (statelocatorlifetimelocal == 0) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the state locator lifetime "
                     "falls below 1.\n",
                     statelocatorlifetimelocal);
    (void) exit (1);
    }
  if (statelocatorlifetimelocal > 900) {
    (void) fprintf (stderr, "inetServer: "
                     "%u as the state locator lifetime "
                     "exceeds 900.\n",
                     statelocatorlifetimelocal);
    (void) exit (1);
    }
  debugglobal                 = debuglocal;
  defenderexponentglobal      = defenderexponentlocal;
  kbytesdiskoutbufferglobal   = kbytesdiskoutbufferlocal;
  kbytesthreadstacksizeglobal = kbytesthreadstacksizelocal;
  millisecstobesleptglobal    = millisecstobesleptlocal;
  numslotsglobal              = numslotslocal;
  statelocatorlifetimeglobal  = statelocatorlifetimelocal;
  if (debugglobal > 0)
    (void) printf ("Server started, will listen on TCP port %s.\n"
                    "Will serve a maximum of %u clients in parallel.\n",
                    port, numslotsglobal);
  (void) installWorkspace (kbytesperslot);
  (void) createHiddenStateLocatorBase ();
  (void) createUniversalRejectionResponse ();
  (void) installSignalMask (&mystrerrbuf[0]);
#if (0)
  (void) installSigintSigusr1Sigterm ();
#endif
  (void) startThreads (&mystrerrbuf[0]);
  (void) prepareAcceptLoop (port);
  (void) executeAcceptLoop (&mystrerrbuf[0]);
  if (debugglobal > 0)
    (void) printf ("Main thread: Arrived at `barrier2'.\n");
  (void) flushOutStreams ();
  /* Wait for the disk output worker to be in front of its termination. */
  rc = pthread_barrier_wait (&barrier2);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    (void) fprintf (stderr, "inetServer: pthread_barrier_wait "
                     "(barrier2): "
                     "%s.\n", myStrError (rc, &mystrerrbuf[0]));
    /* This is more or less pure actionism here. If something bad
       happened at this point, we typically got stuck in the barrier. */
    (void) exit (1);
    }
  if (debugglobal > 0)
    (void) printf ("Main thread: Passed `barrier2'.\n");
  (void) flushOutStreams ();
  if (atomicallyLoadsTerminateExecution () < 2) {
    pjob = pjobstobedonefirst;
    while (pjob != 0) {
      if (pjob->sfd >= 0) {
        (void) writeoutUniversalRejectionResponse (pjob->sfd);
        if (close (pjob->sfd) != 0)
          if (debugglobal > 0)
            (void) printf ("Main thread: inetServer: close 1: %s.\n",
                            myStrError (errno, &mystrerrbuf[0]));
        pjob->sfd = -1;
        }
      pjob = pjob->right;
      }
    if (sfdbase >= 0) {
      if (close (sfdbase) != 0)
        if (debugglobal > 0)
          (void) printf ("Main thread: inetServer: close 2: %s.\n",
                          myStrError (errno, &mystrerrbuf[0]));
      sfdbase = -1;
      }
    }
  /* Delay somewhat before the barriers get destroyed.
     This is really important. */
  (void) sleepMilliSecs (millisecstobesleptglobal, &mystrerrbuf[0]);
  (void) destroyTheBarriers (&mystrerrbuf[0]);
  if (threadrankbaseaddr != 0)
    (void) free (threadrankbaseaddr);
  if (statelocatorbaseaddr != 0)
    (void) free (statelocatorbaseaddr);
  if (randomblockbaseaddr != 0)
    (void) free (randomblockbaseaddr);
  if (jobbaseaddr != 0)
    (void) free (jobbaseaddr);
  if (iacnodebaseaddr2 != 0)
    (void) free (iacnodebaseaddr2);
  if (iacnodebaseaddr1 != 0)
    (void) free (iacnodebaseaddr1);
  if (diskoutbuffer1 != 0)
    (void) free (diskoutbuffer1);
  if (diskoutbuffer0 != 0)
    (void) free (diskoutbuffer0);
  if (cretimnodebaseaddr != 0)
    (void) free (cretimnodebaseaddr);
  if (largebuffer != 0)
    (void) free (largebuffer);
  (void) sleepMilliSecs (millisecstobesleptglobal, &mystrerrbuf[0]);
  if (debugglobal > 0) {
    if (atomicallyLoadsTerminateExecution () >= 2)
        (void) printf ("Main thread: Server gracefully stopped "
                        "due to an internal error.\n");
      else
        (void) printf ("Main thread: Server gracefully stopped.\n");
    }
  return;
  }

/****************************************************************************/

static unsigned int
insertAddressCounterNode1 (iacn_t *cell)
{
  iacn_t *tree, *p, *pnext, top, *plast, *plastlast;
  int signedcomp;
  unsigned int increased;

  /* AVL comes from G.M.Adelson-Velsky and E.M.Landis (1962). */
  cell->left = 0;
  cell->right = 0;
  cell->up = 0;
  cell->bal = 0;
  tree = piacnodetree1;
  /* Check for the simple case. */
  if (tree == 0) {
    piacnodetree1 = cell;
    return (0);
    }
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeAddressCounterNodes1 (piacnodetree1) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  /* Walk downwards, looking for the given key in the tree. */
  p = tree;
  for (;;) {
    signedcomp = sauCmp (&p->sau, &cell->sau);
    if (signedcomp == 0) {
        (void) fprintf (stderr, "insertAddressCounterNode1: "
                         "Cell to be inserted already in AVL tree.\n");
        (void) atomicallyStoresTwoToTerminateExecution ();
        return (1);
        }
      else if (signedcomp < 0)
        pnext = p->right;
      else
        pnext = p->left;
    if (pnext == 0)
      break;
    p = pnext;
    }
  /* Initialize a special cell that is only used to
     correctly terminate the tree-rebalancing operation loop. */
  (void) memset (&top, 0, sizeof (top));
  /* Now, link `tree' to be the right subtree under `top'. */
  tree->up = &top;
  top.right = tree;
  /* Insert the new cell. */
  signedcomp = sauCmp (&p->sau, &cell->sau);
  if (signedcomp == 0) {
      /***** LABEL *****/ label_unrecoverable_error:
      (void) fprintf (stderr, "insertAddressCounterNode1: "
                       "Unrecoverable error.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
    else if (signedcomp < 0)
      p->right = cell;
    else
      p->left = cell;
  cell->up = p;
  /* Walk upwards rebalancing the tree. */
  increased = 1;
  plast = cell;
  p = plast->up;
  while (p->up != 0) {
    /* `plastlast->bal' is always valid.
       `plast->bal' is always valid.
       `p->bal' needs to be updated in case of `increased==1',
       where the state `increased==1' itself needs verification. */
    if (increased == 0) {
      plast = p;
      p = plast->up;
      continue;
      }
    /* Check where we have come from. */
    if (plast == p->left) {
        /* We have come from the left. */
        p->bal++;
        if (p->bal <= 0)
          increased = 0;
        if (p->bal <= 1) {
          plast = p;
          p = plast->up;
          continue;
          }
        if (plast->bal == 1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->left == p)
              plast->up->left = plast;
            else
              plast->up->right = plast;
          p->left = plast->right;
          if (p->left != 0)
            p->left->up = p;
          plast->right = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          increased = 0;
          p = plast->up;
          continue;
          }
        if (plast->bal == -1) {
          /* Double rotation. */
          plastlast = plast->right;
          plastlast->up = p->up;
          if (p->up->left == p)
              plastlast->up->left = plastlast;
            else
              plastlast->up->right = plastlast;
          plast->right = plastlast->left;
          if (plast->right != 0)
            plast->right->up = plast;
          p->left = plastlast->right;
          if (p->left != 0)
            p->left->up = p;
          plastlast->left = plast;
          plast->up = plastlast;
          plastlast->right = p;
          p->up = plastlast;
          if (plastlast->bal == -1)
              plast->bal = 1;
            else
              plast->bal = 0;
          if (plastlast->bal == 1)
              p->bal = -1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          increased = 0;
          plast = plastlast;
          p = plast->up;
          continue;
          }
        goto label_unrecoverable_error;
        }
      else {
        /* We have come from the right. */
        p->bal--;
        if (p->bal >= 0)
          increased = 0;
        if (p->bal >= -1) {
          plast = p;
          p = plast->up;
          continue;
          }
        if (plast->bal == -1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->right == p)
              plast->up->right = plast;
            else
              plast->up->left = plast;
          p->right = plast->left;
          if (p->right != 0)
            p->right->up = p;
          plast->left = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          increased = 0;
          p = plast->up;
          continue;
          }
        if (plast->bal == 1) {
          /* Double rotation. */
          plastlast = plast->left;
          plastlast->up = p->up;
          if (p->up->right == p)
              plastlast->up->right = plastlast;
            else
              plastlast->up->left = plastlast;
          plast->left = plastlast->right;
          if (plast->left != 0)
            plast->left->up = plast;
          p->right = plastlast->left;
          if (p->right != 0)
            p->right->up = p;
          plastlast->right = plast;
          plast->up = plastlast;
          plastlast->left = p;
          p->up = plastlast;
          if (plastlast->bal == 1)
              plast->bal = -1;
            else
              plast->bal = 0;
          if (plastlast->bal == -1)
              p->bal = 1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          increased = 0;
          plast = plastlast;
          p = plast->up;
          continue;
          }
        goto label_unrecoverable_error;
        }
    }
  /* Disconnect from `top'. */
  plast->up = 0;
  /* Now, update the tree entry. */
  piacnodetree1 = plast;
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeAddressCounterNodes1 (piacnodetree1) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  return (0);
  }

/****************************************************************************/

static unsigned int
insertAddressCounterNode2 (iacn_t *cell)
{
  iacn_t *tree, *p, *pnext, top, *plast, *plastlast;
  int signedcomp;
  unsigned int increased;

  /* AVL comes from G.M.Adelson-Velsky and E.M.Landis (1962). */
  cell->left = 0;
  cell->right = 0;
  cell->up = 0;
  cell->bal = 0;
  tree = piacnodetree2;
  /* Check for the simple case. */
  if (tree == 0) {
    piacnodetree2 = cell;
    return (0);
    }
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeAddressCounterNodes2 (piacnodetree2) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  /* Walk downwards, looking for the given key in the tree. */
  p = tree;
  for (;;) {
    signedcomp = sauCmp (&p->sau, &cell->sau);
    if (signedcomp == 0) {
        (void) fprintf (stderr, "insertAddressCounterNode2: "
                         "Cell to be inserted already in AVL tree.\n");
        (void) atomicallyStoresTwoToTerminateExecution ();
        return (1);
        }
      else if (signedcomp < 0)
        pnext = p->right;
      else
        pnext = p->left;
    if (pnext == 0)
      break;
    p = pnext;
    }
  /* Initialize a special cell that is only used to
     correctly terminate the tree-rebalancing operation loop. */
  (void) memset (&top, 0, sizeof (top));
  /* Now, link `tree' to be the right subtree under `top'. */
  tree->up = &top;
  top.right = tree;
  /* Insert the new cell. */
  signedcomp = sauCmp (&p->sau, &cell->sau);
  if (signedcomp == 0) {
      /***** LABEL *****/ label_unrecoverable_error:
      (void) fprintf (stderr, "insertAddressCounterNode2: "
                       "Unrecoverable error.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
    else if (signedcomp < 0)
      p->right = cell;
    else
      p->left = cell;
  cell->up = p;
  /* Walk upwards rebalancing the tree. */
  increased = 1;
  plast = cell;
  p = plast->up;
  while (p->up != 0) {
    /* `plastlast->bal' is always valid.
       `plast->bal' is always valid.
       `p->bal' needs to be updated in case of `increased==1',
       where the state `increased==1' itself needs verification. */
    if (increased == 0) {
      plast = p;
      p = plast->up;
      continue;
      }
    /* Check where we have come from. */
    if (plast == p->left) {
        /* We have come from the left. */
        p->bal++;
        if (p->bal <= 0)
          increased = 0;
        if (p->bal <= 1) {
          plast = p;
          p = plast->up;
          continue;
          }
        if (plast->bal == 1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->left == p)
              plast->up->left = plast;
            else
              plast->up->right = plast;
          p->left = plast->right;
          if (p->left != 0)
            p->left->up = p;
          plast->right = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          increased = 0;
          p = plast->up;
          continue;
          }
        if (plast->bal == -1) {
          /* Double rotation. */
          plastlast = plast->right;
          plastlast->up = p->up;
          if (p->up->left == p)
              plastlast->up->left = plastlast;
            else
              plastlast->up->right = plastlast;
          plast->right = plastlast->left;
          if (plast->right != 0)
            plast->right->up = plast;
          p->left = plastlast->right;
          if (p->left != 0)
            p->left->up = p;
          plastlast->left = plast;
          plast->up = plastlast;
          plastlast->right = p;
          p->up = plastlast;
          if (plastlast->bal == -1)
              plast->bal = 1;
            else
              plast->bal = 0;
          if (plastlast->bal == 1)
              p->bal = -1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          increased = 0;
          plast = plastlast;
          p = plast->up;
          continue;
          }
        goto label_unrecoverable_error;
        }
      else {
        /* We have come from the right. */
        p->bal--;
        if (p->bal >= 0)
          increased = 0;
        if (p->bal >= -1) {
          plast = p;
          p = plast->up;
          continue;
          }
        if (plast->bal == -1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->right == p)
              plast->up->right = plast;
            else
              plast->up->left = plast;
          p->right = plast->left;
          if (p->right != 0)
            p->right->up = p;
          plast->left = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          increased = 0;
          p = plast->up;
          continue;
          }
        if (plast->bal == 1) {
          /* Double rotation. */
          plastlast = plast->left;
          plastlast->up = p->up;
          if (p->up->right == p)
              plastlast->up->right = plastlast;
            else
              plastlast->up->left = plastlast;
          plast->left = plastlast->right;
          if (plast->left != 0)
            plast->left->up = plast;
          p->right = plastlast->left;
          if (p->right != 0)
            p->right->up = p;
          plastlast->right = plast;
          plast->up = plastlast;
          plastlast->left = p;
          p->up = plastlast;
          if (plastlast->bal == 1)
              plast->bal = -1;
            else
              plast->bal = 0;
          if (plastlast->bal == -1)
              p->bal = 1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          increased = 0;
          plast = plastlast;
          p = plast->up;
          continue;
          }
        goto label_unrecoverable_error;
        }
    }
  /* Disconnect from `top'. */
  plast->up = 0;
  /* Now, update the tree entry. */
  piacnodetree2 = plast;
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeAddressCounterNodes2 (piacnodetree2) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  return (0);
  }

/****************************************************************************/

static unsigned int
insertCreationTimeNode (ctn_t *cell)
{
  ctn_t *tree, *p, *pnext, top, *plast, *plastlast;
  int signedcomp;
  unsigned int increased;

  /* AVL comes from G.M.Adelson-Velsky and E.M.Landis (1962). */
  cell->left = 0;
  cell->right = 0;
  cell->up = 0;
  cell->bal = 0;
  tree = pcretimnodetree;
  /* Check for the simple case. */
  if (tree == 0) {
    pcretimnodetree = cell;
    return (0);
    }
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeCreationTimeNodes (pcretimnodetree) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  /* Walk downwards, looking for the given key in the tree. */
  p = tree;
  for (;;) {
    signedcomp = tvCmp (&p->creatim, &cell->creatim, p, cell);
    if (signedcomp == 0) {
        (void) fprintf (stderr, "insertCreationTimeNode: "
                         "Cell to be inserted already in AVL tree.\n");
        (void) atomicallyStoresTwoToTerminateExecution ();
        return (1);
        }
      else if (signedcomp < 0)
        pnext = p->right;
      else
        pnext = p->left;
    if (pnext == 0)
      break;
    p = pnext;
    }
  /* Initialize a special cell that is only used to
     correctly terminate the tree-rebalancing operation loop. */
  (void) memset (&top, 0, sizeof (top));
  /* Now, link `tree' to be the right subtree under `top'. */
  tree->up = &top;
  top.right = tree;
  /* Insert the new cell. */
  signedcomp = tvCmp (&p->creatim, &cell->creatim, p, cell);
  if (signedcomp == 0) {
      /***** LABEL *****/ label_unrecoverable_error:
      (void) fprintf (stderr, "insertCreationTimeNode: "
                       "Unrecoverable error.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
    else if (signedcomp < 0)
      p->right = cell;
    else
      p->left = cell;
  cell->up = p;
  /* Walk upwards rebalancing the tree. */
  increased = 1;
  plast = cell;
  p = plast->up;
  while (p->up != 0) {
    /* `plastlast->bal' is always valid.
       `plast->bal' is always valid.
       `p->bal' needs to be updated in case of `increased==1',
       where the state `increased==1' itself needs verification. */
    if (increased == 0) {
      plast = p;
      p = plast->up;
      continue;
      }
    /* Check where we have come from. */
    if (plast == p->left) {
        /* We have come from the left. */
        p->bal++;
        if (p->bal <= 0)
          increased = 0;
        if (p->bal <= 1) {
          plast = p;
          p = plast->up;
          continue;
          }
        if (plast->bal == 1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->left == p)
              plast->up->left = plast;
            else
              plast->up->right = plast;
          p->left = plast->right;
          if (p->left != 0)
            p->left->up = p;
          plast->right = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          increased = 0;
          p = plast->up;
          continue;
          }
        if (plast->bal == -1) {
          /* Double rotation. */
          plastlast = plast->right;
          plastlast->up = p->up;
          if (p->up->left == p)
              plastlast->up->left = plastlast;
            else
              plastlast->up->right = plastlast;
          plast->right = plastlast->left;
          if (plast->right != 0)
            plast->right->up = plast;
          p->left = plastlast->right;
          if (p->left != 0)
            p->left->up = p;
          plastlast->left = plast;
          plast->up = plastlast;
          plastlast->right = p;
          p->up = plastlast;
          if (plastlast->bal == -1)
              plast->bal = 1;
            else
              plast->bal = 0;
          if (plastlast->bal == 1)
              p->bal = -1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          increased = 0;
          plast = plastlast;
          p = plast->up;
          continue;
          }
        goto label_unrecoverable_error;
        }
      else {
        /* We have come from the right. */
        p->bal--;
        if (p->bal >= 0)
          increased = 0;
        if (p->bal >= -1) {
          plast = p;
          p = plast->up;
          continue;
          }
        if (plast->bal == -1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->right == p)
              plast->up->right = plast;
            else
              plast->up->left = plast;
          p->right = plast->left;
          if (p->right != 0)
            p->right->up = p;
          plast->left = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          increased = 0;
          p = plast->up;
          continue;
          }
        if (plast->bal == 1) {
          /* Double rotation. */
          plastlast = plast->left;
          plastlast->up = p->up;
          if (p->up->right == p)
              plastlast->up->right = plastlast;
            else
              plastlast->up->left = plastlast;
          plast->left = plastlast->right;
          if (plast->left != 0)
            plast->left->up = plast;
          p->right = plastlast->left;
          if (p->right != 0)
            p->right->up = p;
          plastlast->right = plast;
          plast->up = plastlast;
          plastlast->left = p;
          p->up = plastlast;
          if (plastlast->bal == 1)
              plast->bal = -1;
            else
              plast->bal = 0;
          if (plastlast->bal == -1)
              p->bal = 1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          increased = 0;
          plast = plastlast;
          p = plast->up;
          continue;
          }
        goto label_unrecoverable_error;
        }
    }
  /* Disconnect from `top'. */
  plast->up = 0;
  /* Now, update the tree entry. */
  pcretimnodetree = plast;
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeCreationTimeNodes (pcretimnodetree) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  return (0);
  }

/****************************************************************************/

#if (0)
static void
installSigintSigusr1Sigterm (void)
{
  mysighandler_t sh;

  sh = myBsdStyleSignal (SIGINT, handleSigintSigusr1Sigterm);
  if (sh == SIG_ERR) {
    (void) perror ("installSigintSigusr1Sigterm: myBsdStyleSignal (SIGINT)");
    (void) exit (1);
    }
  sh = myBsdStyleSignal (SIGUSR1, handleSigintSigusr1Sigterm);
  if (sh == SIG_ERR) {
    (void) perror ("installSigintSigusr1Sigterm: myBsdStyleSignal (SIGUSR1)");
    (void) exit (1);
    }
  sh = myBsdStyleSignal (SIGTERM, handleSigintSigusr1Sigterm);
  if (sh == SIG_ERR) {
    (void) perror ("installSigintSigusr1Sigterm: myBsdStyleSignal (SIGTERM)");
    (void) exit (1);
    }
  return;
  }
#endif

/****************************************************************************/

static void
installSignalMask (char *mystrerrbufbase)
{
  sigset_t set;
  int rc;

  if (sigfillset (&set) != 0) {
    (void) perror ("installSignalMask: sigfillset");
    (void) exit (1);
    }
  rc = pthread_sigmask (SIG_BLOCK, &set, 0);
  if (rc != 0) {
    (void) fprintf (stderr, "installSignalMask: pthread_sigmask: "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  return;
  }

/****************************************************************************/

static void
installWorkspace (unsigned int kbytesperslot)
{
  static const char *uchexstr = "0123456789ABCDEF";
  size_t numbytestotal, numbytes;
  unsigned int i;
  ctn_t *pctn;
  iacn_t *piacn;
  job_t *pjob;
  int fdio;
  unsigned char *puc;

  numbytestotal = 0;
  /* ..... `largebuffer' .................................................. */
  numbytes = 3
           * (size_t) numslotsglobal * (size_t) kbytesperslot * 1024
           * sizeof (unsigned char);
  numbytestotal += numbytes;
  largebuffer = (unsigned char *) malloc (numbytes);
  if (largebuffer == 0) {
    (void) fprintf (stderr, "installWorkspace: "
                     "cannot malloc %lu Bytes for a large buffer.\n",
                     (unsigned long) numbytes);
    (void) exit (1);
    }
  /* First touch rule not applicable, so initialize the memory here. */
  (void) memset (largebuffer, 0, numbytes);
  if (debugglobal > 0)
    (void) printf ("Large buffer of %lu kByte(s) successfully allocated.\n",
                    (unsigned long) numbytes >> 10);
  /* ..... `cretimnodebaseaddr' ........................................... */
  numbytes = (size_t) numslotsglobal * sizeof (ctn_t);
  numbytestotal += numbytes;
  cretimnodebaseaddr = (ctn_t *) malloc (numbytes);
  if (cretimnodebaseaddr == 0) {
    (void) fprintf (stderr, "installWorkspace: "
                     "cannot malloc %lu Bytes for a "
                     "creation time node array.\n",
                     (unsigned long) numbytes);
    (void) exit (1);
    }
  /* First touch rule not applicable, so initialize the memory here. */
  (void) memset (cretimnodebaseaddr, 0, numbytes);
  if (debugglobal > 0)
    (void) printf ("Creation time node array of %lu "
                    "kByte(s) successfully allocated.\n",
                    ((unsigned long) numbytes & (unsigned long) 0x3ff) == 0
                      ? ((unsigned long) numbytes >> 10)
                      : ((unsigned long) numbytes >> 10) + 1);
  for (i = 0; i < numslotsglobal; i++) {
    pctn = cretimnodebaseaddr + i;
    if (i == 0)
        pctn->left = 0;
      else
        pctn->left = pctn - 1;
    if (i + 1 != numslotsglobal)
        pctn->right = pctn + 1;
      else
        pctn->right = 0;
    pctn->slot = i;
    (void) memset (&pctn->creatim, 0xff, sizeof (struct timeval));
    }
  pfreecretimnodechainfirst = cretimnodebaseaddr + 0;
  pfreecretimnodechainlast  = cretimnodebaseaddr + numslotsglobal - 1;
  pcretimnodetree = 0;
  /* ..... `diskoutbuffer0' ............................................... */
  numbytes = (size_t) kbytesdiskoutbufferglobal * 1024
           * sizeof (unsigned char);
  numbytestotal += numbytes;
  diskoutbuffer0 = (unsigned char *) malloc (numbytes);
  if (diskoutbuffer0 == 0) {
    (void) fprintf (stderr, "installWorkspace: "
                     "cannot malloc %lu Bytes for disk output buffer 0.\n",
                     (unsigned long) numbytes);
    (void) exit (1);
    }
  /* First touch rule not applicable, so initialize the memory here. */
  (void) memset (diskoutbuffer0, 0, numbytes);
  if (debugglobal > 0)
    (void) printf ("Disk output buffer 0 of %lu "
                    "kByte(s) successfully allocated.\n",
                    (unsigned long) numbytes >> 10);
  diskoutbuflvl0 = 0;
  diskoutbufwhichone = 0;
  /* ..... `diskoutbuffer1' ............................................... */
  numbytes = (size_t) kbytesdiskoutbufferglobal * 1024
           * sizeof (unsigned char);
  numbytestotal += numbytes;
  diskoutbuffer1 = (unsigned char *) malloc (numbytes);
  if (diskoutbuffer1 == 0) {
    (void) fprintf (stderr, "installWorkspace: "
                     "cannot malloc %lu Bytes for disk output buffer 1.\n",
                     (unsigned long) numbytes);
    (void) exit (1);
    }
  /* First touch rule not applicable, so initialize the memory here. */
  (void) memset (diskoutbuffer1, 0, numbytes);
  if (debugglobal > 0)
    (void) printf ("Disk output buffer 1 of %lu "
                    "kByte(s) successfully allocated.\n",
                    (unsigned long) numbytes >> 10);
  diskoutbuflvl1 = 0;
  diskoutbufwhichone = 0;
  /* ..... `iacnodebaseaddr1' ............................................. */
  numbytes = (size_t) numslotsglobal * sizeof (iacn_t);
  numbytestotal += numbytes;
  iacnodebaseaddr1 = (iacn_t *) malloc (numbytes);
  if (iacnodebaseaddr1 == 0) {
    (void) fprintf (stderr, "installWorkspace: "
                     "cannot malloc %lu Bytes for "
                     "address counter node array 1.\n",
                     (unsigned long) numbytes);
    (void) exit (1);
    }
  /* First touch rule not applicable, so initialize the memory here. */
  (void) memset (iacnodebaseaddr1, 0, numbytes);
  if (debugglobal > 0)
    (void) printf ("Address counter node array 1 of %lu "
                    "kByte(s) successfully allocated.\n",
                    ((unsigned long) numbytes & (unsigned long) 0x3ff) == 0
                      ? ((unsigned long) numbytes >> 10)
                      : ((unsigned long) numbytes >> 10) + 1);
  for (i = 0; i < numslotsglobal; i++) {
    piacn = iacnodebaseaddr1 + i;
    if (i == 0)
        piacn->left = 0;
      else
        piacn->left = piacn - 1;
    if (i + 1 != numslotsglobal)
        piacn->right = piacn + 1;
      else
        piacn->right = 0;
    }
  pfreeiacnodechainfirst1 = iacnodebaseaddr1 + 0;
  pfreeiacnodechainlast1  = iacnodebaseaddr1 + numslotsglobal - 1;
  piacnodetree1 = 0;
  /* ..... `iacnodebaseaddr2' ............................................. */
  numbytes = (size_t) numslotsglobal * sizeof (iacn_t);
  numbytestotal += numbytes;
  iacnodebaseaddr2 = (iacn_t *) malloc (numbytes);
  if (iacnodebaseaddr2 == 0) {
    (void) fprintf (stderr, "installWorkspace: "
                     "cannot malloc %lu Bytes for "
                     "address counter node array 2.\n",
                     (unsigned long) numbytes);
    (void) exit (1);
    }
  /* First touch rule not applicable, so initialize the memory here. */
  (void) memset (iacnodebaseaddr2, 0, numbytes);
  if (debugglobal > 0)
    (void) printf ("Address counter node array 2 of %lu "
                    "kByte(s) successfully allocated.\n",
                    ((unsigned long) numbytes & (unsigned long) 0x3ff) == 0
                      ? ((unsigned long) numbytes >> 10)
                      : ((unsigned long) numbytes >> 10) + 1);
  for (i = 0; i < numslotsglobal; i++) {
    piacn = iacnodebaseaddr2 + i;
    if (i == 0)
        piacn->left = 0;
      else
        piacn->left = piacn - 1;
    if (i + 1 != numslotsglobal)
        piacn->right = piacn + 1;
      else
        piacn->right = 0;
    }
  pfreeiacnodechainfirst2 = iacnodebaseaddr2 + 0;
  pfreeiacnodechainlast2  = iacnodebaseaddr2 + numslotsglobal - 1;
  piacnodetree2 = 0;
  /* ..... `jobbaseaddr' .................................................. */
  numbytes = (size_t) numslotsglobal * sizeof (job_t);
  numbytestotal += numbytes;
  jobbaseaddr = (job_t *) malloc (numbytes);
  if (jobbaseaddr == 0) {
    (void) fprintf (stderr, "installWorkspace: "
                     "cannot malloc %lu Bytes for a job array.\n",
                     (unsigned long) numbytes);
    (void) exit (1);
    }
  /* First touch rule not applicable, so initialize the memory here. */
  (void) memset (jobbaseaddr, 0, numbytes);
  if (debugglobal > 0)
    (void) printf ("Job array of %lu kByte(s) successfully allocated.\n",
                    ((unsigned long) numbytes & (unsigned long) 0x3ff) == 0
                      ? ((unsigned long) numbytes >> 10)
                      : ((unsigned long) numbytes >> 10) + 1);
  for (i = 0; i < numslotsglobal; i++) {
    pjob = jobbaseaddr + i;
    if (i == 0)
        pjob->left = 0;
      else
        pjob->left = pjob - 1;
    if (i + 1 != numslotsglobal)
        pjob->right = pjob + 1;
      else
        pjob->right = 0;
    pjob->pbuf1 = largebuffer + (3 * i + 0) * kbytesperslot * 1024;
    pjob->pbuf2 = largebuffer + (3 * i + 1) * kbytesperslot * 1024;
    pjob->pbuf3 = largebuffer + (3 * i + 2) * kbytesperslot * 1024;
    pjob->bufdim = kbytesperslot * 1024;
    pjob->rank = 0xffffffff;
    pjob->slot = 0xffffffff;
    pjob->sfd = -1;
    }
  pfreejobchainfirst = jobbaseaddr + 0;
  pfreejobchainlast  = jobbaseaddr + numslotsglobal - 1;
  pjobstobedonefirst = 0;
  pjobstobedonelast  = 0;
  /* ..... `randomblockbaseaddr' .......................................... */
  numbytes = (size_t) numslotsglobal * 192 * sizeof (unsigned char);
  numbytestotal += numbytes;
  randomblockbaseaddr = (unsigned char *) malloc (numbytes);
  if (randomblockbaseaddr == 0) {
    (void) fprintf (stderr, "installWorkspace: "
                     "cannot malloc %lu Bytes for a random block array.\n",
                     (unsigned long) numbytes);
    (void) exit (1);
    }
  fdio = open ("/dev/urandom", O_RDONLY);
  if (fdio == -1) {
    (void) perror ("installWorkspace: open");
    (void) exit (1);
    }
  if (read (fdio, randomblockbaseaddr, numbytes) != (ssize_t) numbytes) {
    (void) perror ("installWorkspace: read");
    (void) exit (1);
    }
  if (close (fdio) != 0) {
    (void) perror ("installWorkspace: close");
    (void) exit (1);
    }
  /* The first thread, i.e. the thread in which these lines of code here are
     executed, is the first user of the random block created for a thread
     with rank 0 that is not yet with us. So we are already here pushing
     the rank-0 random data from `/dev/urandom' through. */
  (void) getRandomBytes32 (0, 0, 0);
  (void) getRandomBytes32 (0, 0, 0);
  if (debugglobal > 0)
    (void) printf ("Random block array of %lu kByte(s) "
                      "successfully allocated.\n",
                    ((unsigned long) numbytes & (unsigned long) 0x3ff) == 0
                      ? ((unsigned long) numbytes >> 10)
                      : ((unsigned long) numbytes >> 10) + 1);
  /* ..... `statelocatorbaseaddr' ......................................... */
  numbytes = (size_t) numslotsglobal * 193 * sizeof (unsigned char);
  numbytestotal += numbytes;
  statelocatorbaseaddr = (unsigned char *) malloc (numbytes);
  if (statelocatorbaseaddr == 0) {
    (void) fprintf (stderr, "installWorkspace: "
                     "cannot malloc %lu Bytes for a state locator array.\n",
                     (unsigned long) numbytes);
    (void) exit (1);
    }
  /* First touch rule not applicable, so initialize the memory here. */
  (void) memset (statelocatorbaseaddr, 0xff, numbytes);
  if (debugglobal > 0)
    (void) printf ("State locator array of %lu "
                    "kByte(s) successfully allocated.\n",
                    ((unsigned long) numbytes & (unsigned long) 0x3ff) == 0
                      ? ((unsigned long) numbytes >> 10)
                      : ((unsigned long) numbytes >> 10) + 1);
  puc = statelocatorbaseaddr;
  for (i = 0; i < numslotsglobal; i++) {
    *(puc + i * 193 +  0) = *(uchexstr + (i >> 12 & (unsigned int) 0xf));
    *(puc + i * 193 +  1) = *(uchexstr + (i >>  8 & (unsigned int) 0xf));
    *(puc + i * 193 +  2) = *(uchexstr + (i >>  4 & (unsigned int) 0xf));
    *(puc + i * 193 +  3) = *(uchexstr + (i       & (unsigned int) 0xf));
    *(puc + i * 193 +  4) = '\0';
    *(puc + i * 193 + 64) = '\0';
    }
  /* ..... `threadrankbaseaddr' ........................................... */
  numbytes = (size_t) (numslotsglobal + 2) * sizeof (unsigned int);
  numbytestotal += numbytes;
  threadrankbaseaddr = (unsigned int *) malloc (numbytes);
  if (threadrankbaseaddr == 0) {
    (void) fprintf (stderr, "installWorkspace: "
                     "cannot malloc %lu Bytes for a thread rank array.\n",
                     (unsigned long) numbytes);
    (void) exit (1);
    }
  /* First touch rule not applicable, so initialize the memory here. */
  (void) memset (threadrankbaseaddr, 0, numbytes);
  if (debugglobal > 0)
    (void) printf ("Thread rank array of %lu kByte(s) "
                      "successfully allocated.\n",
                    ((unsigned long) numbytes & (unsigned long) 0x3ff) == 0
                      ? ((unsigned long) numbytes >> 10)
                      : ((unsigned long) numbytes >> 10) + 1);
  for (i = 0; i < numslotsglobal + 2; i++)
    *(threadrankbaseaddr + i) = i;
  if (debugglobal > 0)
    (void) printf ("We have %lu MByte(s) heap size in total.\n",
                    ((unsigned long) numbytestotal &
                     (unsigned long) 0xfffff) == 0
                      ? ((unsigned long) numbytestotal >> 20)
                      : ((unsigned long) numbytestotal >> 20) + 1);
  return;
  }

/****************************************************************************/

static unsigned int
isValidStateLocator (const unsigned char *statelocator, char *mystrerrbufbase)
{
  unsigned char buf32 [32];
  unsigned int slot;
  struct {
    unsigned char slot1l;
    unsigned char slot1h;
    unsigned char hiddenbase [32];
    unsigned char slot2h;
    unsigned char slot2l;
    unsigned char publicrand [15];
    unsigned char hash [15];
    unsigned char overrun [17];
    } b;

  (void) undoAsciiArmoring (statelocator, &buf32[0], mystrerrbufbase);
  if (atomicallyLoadsTerminateExecution () >= 2)
    return (0);
  slot = ((unsigned int) buf32[0] & (unsigned int) 0xff) << 8
       | ((unsigned int) buf32[1] & (unsigned int) 0xff);
  if (slot >= numslotsglobal)
    return (0);
  b.slot1l = buf32[1];
  b.slot1h = buf32[0];
  (void) memcpy (&b.hiddenbase[0], &hiddenstatelocatorbase[0], 32);
  b.slot2h = b.slot1h;
  b.slot2l = b.slot1l;
  (void) memcpy (&b.publicrand[0], &buf32[2], 15);
  (void) sha256 (51, &b.slot1l, &b.hash[0]);
  if (memcmp (&b.hash[0], &buf32[17], 15) == 0)
    return (1);
  return (0);
  }

/****************************************************************************/

static unsigned int
isValidUint (unsigned long uli)
{
  if ((uli & (unsigned long) 0xffffffff) != uli)
    return (0);
  return (1);
  }

/****************************************************************************/

#if (0)
static mysighandler_t
myBsdStyleSignal (int signum, mysighandler_t handler)
{
  struct sigaction act, oldact;

  act.sa_flags = SA_RESTART;
  act.sa_handler = handler;
  if (sigemptyset (&act.sa_mask) != 0)
    return (SIG_ERR);
  if (sigaddset (&act.sa_mask, signum) != 0)
    return (SIG_ERR);
  if (sigaction (signum, &act, &oldact) != 0)
    return (SIG_ERR);
  return (oldact.sa_handler);
  }
#endif

/****************************************************************************/

static char *
myStrError (int errnum, char *mystrerrbufbase)
{
  /* The GNU-specific version. */
  return (strerror_r (errnum, mystrerrbufbase, MYWEBSERVER_MYSTRERRBUFDIM));
  }

/****************************************************************************/

static char *
padWithLeadingZeros (char *str, unsigned int len, char *buf, size_t bufsize)
{
  unsigned int strlenaux, i;

  strlenaux = (unsigned int) strlen (str);
  if (strlenaux >= len)
    return (str);
  if (bufsize < (size_t) (len + 1) * sizeof (char))
    return (str);
  for (i = 0; i < len - strlenaux; i++)
    *(buf + i) = '0';
  (void) strcpy (buf + len - strlenaux, str);
  return (buf);
  }

/****************************************************************************/

static void *
passP (void *p)
{
  return (p);
  }

/****************************************************************************/

static unsigned int
passU (unsigned int u)
{
  return (u);
  }

/****************************************************************************/

static unsigned int
perAddrConnLimitExceeded (sau_t *sau, unsigned int connlimit,
                           char *mystrerrbufbase)
{
  int rc, rcria;

  rc = pthread_mutex_lock (&mutexcounternodes1);
  if (rc != 0) {
    (void) fprintf (stderr, "perAddrConnLimitExceeded: "
                     "pthread_mutex_lock "
                     "(mutexcounternodes1): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  rcria = registerIpAddress1 (sau, connlimit);
  rc = pthread_mutex_unlock (&mutexcounternodes1);
  if (rc != 0) {
    (void) fprintf (stderr, "perAddrConnLimitExceeded: "
                     "pthread_mutex_unlock "
                     "(mutexcounternodes1): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  return (rcria);
  }

/****************************************************************************/

static void
persuadeAcceptToReturn (char *mystrerrbufbase)
{
  struct addrinfo aihints, *paistart, *pai;
  int rc, sfdaret, sfd, o;
  const char *p;
  ssize_t rcwrite;

  (void) memset (&aihints, 0, sizeof (aihints));
  aihints.ai_flags    = 0;
  aihints.ai_family   = AF_UNSPEC;
  aihints.ai_socktype = SOCK_STREAM;
  aihints.ai_protocol = IPPROTO_TCP;
  rc = getaddrinfo ("localhost", &numericserverportstr[0],
                     &aihints, &paistart);
  if (rc != 0) {
    (void) fprintf (stderr, "persuadeAcceptToReturn: getaddrinfo: "
                     "%s.\n", gai_strerror (rc));
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  if (debugglobal > 0)
    (void) printf ("Disk output worker: Function `getaddrinfo()' "
                    "successfully executed.\n");
  sfdaret = -1;
  for (pai = paistart; pai != 0; pai = pai->ai_next) {
    sfd = socket (pai->ai_family, pai->ai_socktype, pai->ai_protocol);
    if (sfd < 0)
      continue;
    o = 1;
    if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, &o, sizeof (o)) != 0) {
      if (close (sfd) != 0) {
        if (debugglobal > 0)
          (void) printf ("Dist output worker: persuadeAcceptToReturn: "
                          "close 1: %s.\n",
                          myStrError (errno, mystrerrbufbase));
        return;
        }
      continue;
      }
    if (connect (sfd, pai->ai_addr, pai->ai_addrlen) == 0) {
      sfdaret = sfd;
      break;
      }
    if (close (sfd) != 0) {
      if (debugglobal > 0)
        (void) printf ("Dist output worker: persuadeAcceptToReturn: close 2: "
                        "%s.\n", myStrError (errno, mystrerrbufbase));
      return;
      }
    }
  (void) freeaddrinfo (paistart);
  if (sfdaret < 0) {
    if (debugglobal > 0)
      (void) printf ("Disk output worker: persuadeAcceptToReturn: "
                      "Connection to `localhost' cannot be established.\n");
    (void) fprintf (stderr, "persuadeAcceptToReturn: "
                     "Connection to `localhost' cannot be established.\n");
    return;
    }
  if (debugglobal > 0)
    (void) printf ("Disk output worker: Functions `socket()', "
                    "`setsockopt()', and `connect()' successfully "
                    "executed.\n");
  p = "Dear function `accept()', please do return now.\r\n";
  rcwrite = send (sfdaret, p, strlen (p) * sizeof (char),
                   MSG_DONTWAIT | MSG_NOSIGNAL);
  if ((size_t) rcwrite > strlen (p) * sizeof (char)) {
    (void) fprintf (stderr, "persuadeAcceptToReturn: Unrecoverable error.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  if (rcwrite < 0) {
      if (debugglobal > 0)
        (void) printf ("Dist output worker: persuadeAcceptToReturn: send: "
                        "%s.\n", myStrError (errno, mystrerrbufbase));
      (void) perror ("persuadeAcceptToReturn: send");
      }
    else if ((size_t) rcwrite != strlen (p) * sizeof (char)) {
      if (debugglobal > 0)
        (void) printf ("Dist output worker: persuadeAcceptToReturn: send: "
                        "Not all bytes have been written.\n");
      (void) fprintf (stderr, "persuadeAcceptToReturn: send: "
                       "Not all bytes have been written.\n");
      }
  if (close (sfdaret) != 0) {
    if (debugglobal > 0)
      (void) printf ("Dist output worker: persuadeAcceptToReturn: close 3: "
                      "%s.\n", myStrError (errno, mystrerrbufbase));
    (void) perror ("persuadeAcceptToReturn: close 3");
    return;
    }
  if ((size_t) rcwrite == strlen (p) * sizeof (char))
    if (debugglobal > 0)
      (void) printf ("Disk output worker: Sent `accept()' return request.\n");
  return;
  }

/****************************************************************************/

static void
prepareAcceptLoop (const char *port)
{
  struct addrinfo aihints, *paistart, *pai;
  int rc, sfdtmp, o, backlog;

  (void) memset (&aihints, 0, sizeof (aihints));
  aihints.ai_flags = AI_PASSIVE;
  aihints.ai_family = AF_UNSPEC;
  aihints.ai_socktype = SOCK_STREAM;
  aihints.ai_protocol = 0;
  rc = getaddrinfo (0, port, &aihints, &paistart);
  if (rc != 0) {
    (void) fprintf (stderr, "prepareAcceptLoop: getaddrinfo: "
                     "%s.\n", gai_strerror (rc));
    (void) exit (1);
    }
  if (debugglobal > 0)
    (void) printf ("Main thread: Function `getaddrinfo()' "
                    "successfully executed.\n");
  /* Spin through the `addrinfo' structures, preferring IPv6. */
  sfdbase = -1;
  for (pai = paistart; pai != 0; pai = pai->ai_next) {
    if (pai->ai_family != AF_INET6)
      continue;
    sfdtmp = socket (pai->ai_family, pai->ai_socktype, pai->ai_protocol);
    if (sfdtmp < 0)
      continue;
    o = 1;
    if (setsockopt (sfdtmp, SOL_SOCKET, SO_REUSEADDR, &o, sizeof (o)) != 0) {
      if (close (sfdtmp) != 0) {
        (void) perror ("prepareAcceptLoop: close 1");
        (void) exit (1);
        }
      continue;
      }
    if (bind (sfdtmp, pai->ai_addr, pai->ai_addrlen) == 0) {
      sfdbase = sfdtmp;
      break;
      }
    if (close (sfdtmp) != 0) {
      (void) perror ("prepareAcceptLoop: close 2");
      (void) exit (1);
      }
    }
  for (pai = paistart; pai != 0; pai = pai->ai_next) {
    if (sfdbase >= 0)
      break;
    if (pai->ai_family != AF_INET)
      continue;
    sfdtmp = socket (pai->ai_family, pai->ai_socktype, pai->ai_protocol);
    if (sfdtmp < 0)
      continue;
    o = 1;
    if (setsockopt (sfdtmp, SOL_SOCKET, SO_REUSEADDR, &o, sizeof (o)) != 0) {
      if (close (sfdtmp) != 0) {
        (void) perror ("prepareAcceptLoop: close 3");
        (void) exit (1);
        }
      continue;
      }
    if (bind (sfdtmp, pai->ai_addr, pai->ai_addrlen) == 0) {
      sfdbase = sfdtmp;
      break;
      }
    if (close (sfdtmp) != 0) {
      (void) perror ("prepareAcceptLoop: close 4");
      (void) exit (1);
      }
    }
  (void) freeaddrinfo (paistart);
  if (sfdbase < 0) {
    (void) fprintf (stderr, "prepareAcceptLoop: "
                     "socket(), setsockopt(), and/or bind() failed.\n");
    (void) exit (1);
    }
  if (debugglobal > 0)
    (void) printf ("Main thread: Functions `socket()', `setsockopt()', "
                    "and `bind()' successfully executed.\n");
  backlog = getListenBacklog ();
  if (listen (sfdbase, backlog) != 0) {
    (void) perror ("prepareAcceptLoop: listen");
    (void) exit (1);
    }
  if (debugglobal > 0)
    (void) printf ("Main thread: Function `listen(%d,%d)' "
                    "successfully executed.\n", sfdbase, backlog);
  return;
  }

/****************************************************************************/

static unsigned int
registerIpAddress1 (sau_t *sau, unsigned int cntlimit)
{
  iacn_t *p, *pnext;
  int signedcomp;
  unsigned int cnt;

  p = piacnodetree1;
  /* Check for the simple case. */
  if (p == 0) {
    /* Begin of non-zero chaining out on the left side. */
    p = pfreeiacnodechainfirst1;
    if (p == 0) {
      (void) fprintf (stderr, "registerIpAddress1: Unrecoverable error 1.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (0);
      }
    if (pfreeiacnodechainfirst1->right != 0)
        pfreeiacnodechainfirst1->right->left = 0;
      else
        pfreeiacnodechainlast1 = 0;
    pfreeiacnodechainfirst1 = pfreeiacnodechainfirst1->right;
    /* End of non-zero chaining out on the left side. */
    piacnodetree1 = p;
    p->left = 0;
    p->right = 0;
    p->up = 0;
    p->bal = 0;
    p->cnt = 1;
    (void) memcpy (&p->sau, sau, sizeof (sau_t));
    return (0);
    }
  /* Walk downwards, looking for the given key in the tree. */
  for (;;) {
    signedcomp = sauCmp (&p->sau, sau);
    if (signedcomp == 0) {
        /* Found. */
        p->cnt++;
        cnt = p->cnt;
        if (p->cnt > cntlimit)
          p->cnt = cntlimit;
        if (cnt > cntlimit)
          return (1);
        return (0);
        }
      else if (signedcomp < 0)
        pnext = p->right;
      else
        pnext = p->left;
    if (pnext == 0)
      break;
    p = pnext;
    }
  /* Begin of non-zero chaining out on the left side. */
  p = pfreeiacnodechainfirst1;
  if (p == 0) {
    (void) fprintf (stderr, "registerIpAddress1: Unrecoverable error 2.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (0);
    }
  if (pfreeiacnodechainfirst1->right != 0)
      pfreeiacnodechainfirst1->right->left = 0;
    else
      pfreeiacnodechainlast1 = 0;
  pfreeiacnodechainfirst1 = pfreeiacnodechainfirst1->right;
  /* End of non-zero chaining out on the left side. */
  p->left = 0;
  p->right = 0;
  p->up = 0;
  p->bal = 0;
  p->cnt = 1;
  (void) memcpy (&p->sau, sau, sizeof (sau_t));
  if (atomicallyLoadsTerminateExecution () < 2)
    if (insertAddressCounterNode1 (p) != 0)
      (void) atomicallyStoresTwoToTerminateExecution ();
  return (0);
  }

/****************************************************************************/

static unsigned int
registerIpAddress2 (sau_t *sau, unsigned int cntlimit)
{
  iacn_t *p, *pnext;
  int signedcomp;
  unsigned int cnt;

  p = piacnodetree2;
  /* Check for the simple case. */
  if (p == 0) {
    /* Begin of non-zero chaining out on the left side. */
    p = pfreeiacnodechainfirst2;
    if (p == 0) {
      (void) fprintf (stderr, "registerIpAddress2: Unrecoverable error 1.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (0);
      }
    if (pfreeiacnodechainfirst2->right != 0)
        pfreeiacnodechainfirst2->right->left = 0;
      else
        pfreeiacnodechainlast2 = 0;
    pfreeiacnodechainfirst2 = pfreeiacnodechainfirst2->right;
    /* End of non-zero chaining out on the left side. */
    piacnodetree2 = p;
    p->left = 0;
    p->right = 0;
    p->up = 0;
    p->bal = 0;
    p->cnt = 1;
    (void) memcpy (&p->sau, sau, sizeof (sau_t));
    return (0);
    }
  /* Walk downwards, looking for the given key in the tree. */
  for (;;) {
    signedcomp = sauCmp (&p->sau, sau);
    if (signedcomp == 0) {
        /* Found. */
        p->cnt++;
        cnt = p->cnt;
        if (p->cnt > cntlimit)
          p->cnt = cntlimit;
        if (cnt > cntlimit)
          return (1);
        return (0);
        }
      else if (signedcomp < 0)
        pnext = p->right;
      else
        pnext = p->left;
    if (pnext == 0)
      break;
    p = pnext;
    }
  /* Begin of non-zero chaining out on the left side. */
  p = pfreeiacnodechainfirst2;
  if (p == 0) {
    (void) fprintf (stderr, "registerIpAddress2: Unrecoverable error 2.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (0);
    }
  if (pfreeiacnodechainfirst2->right != 0)
      pfreeiacnodechainfirst2->right->left = 0;
    else
      pfreeiacnodechainlast2 = 0;
  pfreeiacnodechainfirst2 = pfreeiacnodechainfirst2->right;
  /* End of non-zero chaining out on the left side. */
  p->left = 0;
  p->right = 0;
  p->up = 0;
  p->bal = 0;
  p->cnt = 1;
  (void) memcpy (&p->sau, sau, sizeof (sau_t));
  if (atomicallyLoadsTerminateExecution () < 2)
    if (insertAddressCounterNode2 (p) != 0)
      (void) atomicallyStoresTwoToTerminateExecution ();
  return (0);
  }

/****************************************************************************/

static unsigned int
removeAddressCounterNode1 (iacn_t *cell)
{
  iacn_t *tree, *node, top, *keyneighbor, *p1, *p2, *p, *plast, *plastlast;
  int signedcomp, bal;
  unsigned int decreased;

  /* AVL comes from G.M.Adelson-Velsky and E.M.Landis (1962). */
  tree = piacnodetree1;
  if (tree == 0) {
    /***** LABEL *****/ label_cell_to_be_removed_not_in_avl_tree:
    (void) fprintf (stderr, "removeAddressCounterNode1: "
                     "Cell to be removed not in AVL tree.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (1);
    }
  /* Check whether the cell is in the tree. */
  node = tree;
  while (node != 0) {
    signedcomp = sauCmp (&node->sau, &cell->sau);
    if (signedcomp == 0)
        break;
      else if (signedcomp < 0)
        node = node->right;
      else
        node = node->left;
    }
  if (node == 0)
    goto label_cell_to_be_removed_not_in_avl_tree;
  if (node != cell)
    goto label_cell_to_be_removed_not_in_avl_tree;
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeAddressCounterNodes1 (piacnodetree1) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  /* Initialize a special cell that is only used to
     correctly terminate the tree-rebalancing operation loop. */
  (void) memset (&top, 0, sizeof (top));
  /* Now, link `tree' to be the right subtree under `top'. */
  tree->up = &top;
  top.right = tree;
  /* `cell' points to the cell which has to be deleted.
     In general, if there are cells under `cell' on both sides,
     the deletion of `cell' is difficult because the extension
     of the subtrees under `cell' might be excessive. */
  if (cell->left != 0 && cell->right != 0) {
    /* Yes, on both sides there are cells under `cell'.
       Look for the cell with the greatest key
       being less than the one of `cell'. */
    keyneighbor = cell->left;
    while (keyneighbor->right != 0)
      keyneighbor = keyneighbor->right;
    /* Exchange `cell's and `keyneighbor's location inside the tree.
       Pay attention, the cell addresses themselves do not change.
       Exchange the upper neighbors of `cell' and `keyneighbor'. */
    p1 = cell->up;
    p2 = keyneighbor->up;
    if (p1->left == cell)
        p1->left = keyneighbor;
      else
        p1->right = keyneighbor;
    if (p2->left == keyneighbor)
        p2->left = cell;
      else
        p2->right = cell;
    keyneighbor->up = p1;
    cell->up = p2;
    /* Exchange the left neighbors of `cell' and `keyneighbor'. */
    p1 = cell->left;
    p2 = keyneighbor->left;
    p1->up = keyneighbor;
    if (p2 != 0)
      p2->up = cell;
    keyneighbor->left = p1;
    cell->left = p2;
    /* Exchange the right neighbors of `cell' and `keyneighbor'. */
    p1 = cell->right;
    p2 = keyneighbor->right;
    p1->up = keyneighbor;
    if (p2 != 0)
      p2->up = cell;
    keyneighbor->right = p1;
    cell->right = p2;
    /* Do not exchange the lower neighbors of `cell' and `keyneighbor'.
       The locations of the cells are exchanged now.
       Exchange their balances too. */
    bal = cell->bal;
    cell->bal = keyneighbor->bal;
    keyneighbor->bal = bal;
    /* Now, the tree is violated.
       To repair it, `cell' must be deleted. */
    }
  /* Paranoia check. */
  if (cell->left != 0 && cell->right != 0) {
    /***** LABEL *****/ label_unrecoverable_error:
    (void) fprintf (stderr, "removeAddressCounterNode1: "
                     "Unrecoverable error.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (1);
    }
  /* Remove `cell' from the tree, prepare the rebalancing operation. */
  p = cell->up;
  if (cell->left != 0)
      plast = cell->left;
    else
      plast = cell->right;
  if (p->right == cell) {
      p->right = plast;
      /* We lose height on the right-hand side of `p'. */
      p->bal++;
      }
    else {
      p->left = plast;
      /* We lose height on the left-hand side of `p'. */
      p->bal--;
      }
  /* If we are balanced now, then we have lost height under `p' at all. */
  decreased = p->bal == 0 ? 1 : 0;
  if (plast != 0)
    plast->up = p;
  /* Walk upwards rebalancing the tree. */
  while (p->up != 0) {
    /* `p->bal' is updated here, but, it may be out of range. */
    if (p->bal == -1 || p->bal == 0 || p->bal == 1) {
      plast = p;
      p = plast->up;
      if (decreased != 0) {
        if (plast == p->left)
            p->bal--;
          else
            p->bal++;
        decreased = p->bal == 0 ? 1 : 0;
        }
      continue;
      }
    /* Paranoia check. */
    if (decreased != 0)
      goto label_unrecoverable_error;
    /* Check where we have come from. */
    if (p->bal == -2) {
        /* We have come from the left.
           A tree rebalancing operation is to be done.
           Ensure that we can reuse the insertion rotation codes. */
        plast = p->right;
        /* Yes, we are now able to reuse the insertion rotation codes. */
        if (plast->bal == -1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->right == p)
              plast->up->right = plast;
            else
              plast->up->left = plast;
          p->right = plast->left;
          if (p->right != 0)
            p->right->up = p;
          plast->left = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          p = plast->up;
          if (plast == p->left)
              p->bal--;
            else
              p->bal++;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == 1) {
          /* Double rotation. */
          plastlast = plast->left;
          plastlast->up = p->up;
          if (p->up->right == p)
              plastlast->up->right = plastlast;
            else
              plastlast->up->left = plastlast;
          plast->left = plastlast->right;
          if (plast->left != 0)
            plast->left->up = plast;
          p->right = plastlast->left;
          if (p->right != 0)
            p->right->up = p;
          plastlast->right = plast;
          plast->up = plastlast;
          plastlast->left = p;
          p->up = plastlast;
          if (plastlast->bal == 1)
              plast->bal = -1;
            else
              plast->bal = 0;
          if (plastlast->bal == -1)
              p->bal = 1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          plast = plastlast;
          p = plast->up;
          if (plast == p->left)
              p->bal--;
            else
              p->bal++;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == 0) {
          /* Another double rotation. */
          plastlast = plast->left;
          plastlast->up = p->up;
          if (p->up->right == p)
              plastlast->up->right = plastlast;
            else
              plastlast->up->left = plastlast;
          plast->left = plastlast->right;
          if (plast->left != 0)
            plast->left->up = plast;
          p->right = plastlast->left;
          if (p->right != 0)
            p->right->up = p;
          plastlast->right = plast;
          plast->up = plastlast;
          plastlast->left = p;
          p->up = plastlast;
          if (plastlast->bal == 1)
              plast->bal = -2;
            else
              plast->bal = -1;
          if (plastlast->bal == -1)
              p->bal = 1;
            else
              p->bal = 0;
          plastlast->bal = -1;
          if (plast->bal == -2) {
              /* Repair the problem. */
              p = plast;
              plast = p->left;
              }
            else {
              /* Normal continuation. */
              plast = plastlast;
              p = plast->up;
              }
          continue;
          }
        goto label_unrecoverable_error;
        }
      else if (p->bal == 2) {
        /* We have come from the right.
           A tree rebalancing operation is to be done.
           Ensure that we can reuse the insertion rotation codes. */
        plast = p->left;
        /* Yes, we are now able to reuse the insertion rotation codes. */
        if (plast->bal == 1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->left == p)
              plast->up->left = plast;
            else
              plast->up->right = plast;
          p->left = plast->right;
          if (p->left != 0)
            p->left->up = p;
          plast->right = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          p = plast->up;
          if (plast == p->right)
              p->bal++;
            else
              p->bal--;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == -1) {
          /* Double rotation. */
          plastlast = plast->right;
          plastlast->up = p->up;
          if (p->up->left == p)
              plastlast->up->left = plastlast;
            else
              plastlast->up->right = plastlast;
          plast->right = plastlast->left;
          if (plast->right != 0)
            plast->right->up = plast;
          p->left = plastlast->right;
          if (p->left != 0)
            p->left->up = p;
          plastlast->left = plast;
          plast->up = plastlast;
          plastlast->right = p;
          p->up = plastlast;
          if (plastlast->bal == -1)
              plast->bal = 1;
            else
              plast->bal = 0;
          if (plastlast->bal == 1)
              p->bal = -1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          plast = plastlast;
          p = plast->up;
          if (plast == p->right)
              p->bal++;
            else
              p->bal--;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == 0) {
          /* Another double rotation. */
          plastlast = plast->right;
          plastlast->up = p->up;
          if (p->up->left == p)
              plastlast->up->left = plastlast;
            else
              plastlast->up->right = plastlast;
          plast->right = plastlast->left;
          if (plast->right != 0)
            plast->right->up = plast;
          p->left = plastlast->right;
          if (p->left != 0)
            p->left->up = p;
          plastlast->left = plast;
          plast->up = plastlast;
          plastlast->right = p;
          p->up = plastlast;
          if (plastlast->bal == -1)
              plast->bal = 2;
            else
              plast->bal = 1;
          if (plastlast->bal == 1)
              p->bal = -1;
            else
              p->bal = 0;
          plastlast->bal = 1;
          if (plast->bal == 2) {
              /* Repair the problem. */
              p = plast;
              plast = p->right;
              }
            else {
              /* Normal continuation. */
              plast = plastlast;
              p = plast->up;
              }
          continue;
          }
        goto label_unrecoverable_error;
        }
      else {
        goto label_unrecoverable_error;
        }
    }
  /* Disconnect the tree from `top'. */
  if (top.right != 0)
    top.right->up = 0;
  /* Now, update the tree entry. */
  piacnodetree1 = top.right;
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeAddressCounterNodes1 (piacnodetree1) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  return (0);
  }

/****************************************************************************/

static unsigned int
removeAddressCounterNode2 (iacn_t *cell)
{
  iacn_t *tree, *node, top, *keyneighbor, *p1, *p2, *p, *plast, *plastlast;
  int signedcomp, bal;
  unsigned int decreased;

  /* AVL comes from G.M.Adelson-Velsky and E.M.Landis (1962). */
  tree = piacnodetree2;
  if (tree == 0) {
    /***** LABEL *****/ label_cell_to_be_removed_not_in_avl_tree:
    (void) fprintf (stderr, "removeAddressCounterNode2: "
                     "Cell to be removed not in AVL tree.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (1);
    }
  /* Check whether the cell is in the tree. */
  node = tree;
  while (node != 0) {
    signedcomp = sauCmp (&node->sau, &cell->sau);
    if (signedcomp == 0)
        break;
      else if (signedcomp < 0)
        node = node->right;
      else
        node = node->left;
    }
  if (node == 0)
    goto label_cell_to_be_removed_not_in_avl_tree;
  if (node != cell)
    goto label_cell_to_be_removed_not_in_avl_tree;
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeAddressCounterNodes2 (piacnodetree2) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  /* Initialize a special cell that is only used to
     correctly terminate the tree-rebalancing operation loop. */
  (void) memset (&top, 0, sizeof (top));
  /* Now, link `tree' to be the right subtree under `top'. */
  tree->up = &top;
  top.right = tree;
  /* `cell' points to the cell which has to be deleted.
     In general, if there are cells under `cell' on both sides,
     the deletion of `cell' is difficult because the extension
     of the subtrees under `cell' might be excessive. */
  if (cell->left != 0 && cell->right != 0) {
    /* Yes, on both sides there are cells under `cell'.
       Look for the cell with the greatest key
       being less than the one of `cell'. */
    keyneighbor = cell->left;
    while (keyneighbor->right != 0)
      keyneighbor = keyneighbor->right;
    /* Exchange `cell's and `keyneighbor's location inside the tree.
       Pay attention, the cell addresses themselves do not change.
       Exchange the upper neighbors of `cell' and `keyneighbor'. */
    p1 = cell->up;
    p2 = keyneighbor->up;
    if (p1->left == cell)
        p1->left = keyneighbor;
      else
        p1->right = keyneighbor;
    if (p2->left == keyneighbor)
        p2->left = cell;
      else
        p2->right = cell;
    keyneighbor->up = p1;
    cell->up = p2;
    /* Exchange the left neighbors of `cell' and `keyneighbor'. */
    p1 = cell->left;
    p2 = keyneighbor->left;
    p1->up = keyneighbor;
    if (p2 != 0)
      p2->up = cell;
    keyneighbor->left = p1;
    cell->left = p2;
    /* Exchange the right neighbors of `cell' and `keyneighbor'. */
    p1 = cell->right;
    p2 = keyneighbor->right;
    p1->up = keyneighbor;
    if (p2 != 0)
      p2->up = cell;
    keyneighbor->right = p1;
    cell->right = p2;
    /* Do not exchange the lower neighbors of `cell' and `keyneighbor'.
       The locations of the cells are exchanged now.
       Exchange their balances too. */
    bal = cell->bal;
    cell->bal = keyneighbor->bal;
    keyneighbor->bal = bal;
    /* Now, the tree is violated.
       To repair it, `cell' must be deleted. */
    }
  /* Paranoia check. */
  if (cell->left != 0 && cell->right != 0) {
    /***** LABEL *****/ label_unrecoverable_error:
    (void) fprintf (stderr, "removeAddressCounterNode2: "
                     "Unrecoverable error.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (1);
    }
  /* Remove `cell' from the tree, prepare the rebalancing operation. */
  p = cell->up;
  if (cell->left != 0)
      plast = cell->left;
    else
      plast = cell->right;
  if (p->right == cell) {
      p->right = plast;
      /* We lose height on the right-hand side of `p'. */
      p->bal++;
      }
    else {
      p->left = plast;
      /* We lose height on the left-hand side of `p'. */
      p->bal--;
      }
  /* If we are balanced now, then we have lost height under `p' at all. */
  decreased = p->bal == 0 ? 1 : 0;
  if (plast != 0)
    plast->up = p;
  /* Walk upwards rebalancing the tree. */
  while (p->up != 0) {
    /* `p->bal' is updated here, but, it may be out of range. */
    if (p->bal == -1 || p->bal == 0 || p->bal == 1) {
      plast = p;
      p = plast->up;
      if (decreased != 0) {
        if (plast == p->left)
            p->bal--;
          else
            p->bal++;
        decreased = p->bal == 0 ? 1 : 0;
        }
      continue;
      }
    /* Paranoia check. */
    if (decreased != 0)
      goto label_unrecoverable_error;
    /* Check where we have come from. */
    if (p->bal == -2) {
        /* We have come from the left.
           A tree rebalancing operation is to be done.
           Ensure that we can reuse the insertion rotation codes. */
        plast = p->right;
        /* Yes, we are now able to reuse the insertion rotation codes. */
        if (plast->bal == -1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->right == p)
              plast->up->right = plast;
            else
              plast->up->left = plast;
          p->right = plast->left;
          if (p->right != 0)
            p->right->up = p;
          plast->left = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          p = plast->up;
          if (plast == p->left)
              p->bal--;
            else
              p->bal++;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == 1) {
          /* Double rotation. */
          plastlast = plast->left;
          plastlast->up = p->up;
          if (p->up->right == p)
              plastlast->up->right = plastlast;
            else
              plastlast->up->left = plastlast;
          plast->left = plastlast->right;
          if (plast->left != 0)
            plast->left->up = plast;
          p->right = plastlast->left;
          if (p->right != 0)
            p->right->up = p;
          plastlast->right = plast;
          plast->up = plastlast;
          plastlast->left = p;
          p->up = plastlast;
          if (plastlast->bal == 1)
              plast->bal = -1;
            else
              plast->bal = 0;
          if (plastlast->bal == -1)
              p->bal = 1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          plast = plastlast;
          p = plast->up;
          if (plast == p->left)
              p->bal--;
            else
              p->bal++;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == 0) {
          /* Another double rotation. */
          plastlast = plast->left;
          plastlast->up = p->up;
          if (p->up->right == p)
              plastlast->up->right = plastlast;
            else
              plastlast->up->left = plastlast;
          plast->left = plastlast->right;
          if (plast->left != 0)
            plast->left->up = plast;
          p->right = plastlast->left;
          if (p->right != 0)
            p->right->up = p;
          plastlast->right = plast;
          plast->up = plastlast;
          plastlast->left = p;
          p->up = plastlast;
          if (plastlast->bal == 1)
              plast->bal = -2;
            else
              plast->bal = -1;
          if (plastlast->bal == -1)
              p->bal = 1;
            else
              p->bal = 0;
          plastlast->bal = -1;
          if (plast->bal == -2) {
              /* Repair the problem. */
              p = plast;
              plast = p->left;
              }
            else {
              /* Normal continuation. */
              plast = plastlast;
              p = plast->up;
              }
          continue;
          }
        goto label_unrecoverable_error;
        }
      else if (p->bal == 2) {
        /* We have come from the right.
           A tree rebalancing operation is to be done.
           Ensure that we can reuse the insertion rotation codes. */
        plast = p->left;
        /* Yes, we are now able to reuse the insertion rotation codes. */
        if (plast->bal == 1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->left == p)
              plast->up->left = plast;
            else
              plast->up->right = plast;
          p->left = plast->right;
          if (p->left != 0)
            p->left->up = p;
          plast->right = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          p = plast->up;
          if (plast == p->right)
              p->bal++;
            else
              p->bal--;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == -1) {
          /* Double rotation. */
          plastlast = plast->right;
          plastlast->up = p->up;
          if (p->up->left == p)
              plastlast->up->left = plastlast;
            else
              plastlast->up->right = plastlast;
          plast->right = plastlast->left;
          if (plast->right != 0)
            plast->right->up = plast;
          p->left = plastlast->right;
          if (p->left != 0)
            p->left->up = p;
          plastlast->left = plast;
          plast->up = plastlast;
          plastlast->right = p;
          p->up = plastlast;
          if (plastlast->bal == -1)
              plast->bal = 1;
            else
              plast->bal = 0;
          if (plastlast->bal == 1)
              p->bal = -1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          plast = plastlast;
          p = plast->up;
          if (plast == p->right)
              p->bal++;
            else
              p->bal--;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == 0) {
          /* Another double rotation. */
          plastlast = plast->right;
          plastlast->up = p->up;
          if (p->up->left == p)
              plastlast->up->left = plastlast;
            else
              plastlast->up->right = plastlast;
          plast->right = plastlast->left;
          if (plast->right != 0)
            plast->right->up = plast;
          p->left = plastlast->right;
          if (p->left != 0)
            p->left->up = p;
          plastlast->left = plast;
          plast->up = plastlast;
          plastlast->right = p;
          p->up = plastlast;
          if (plastlast->bal == -1)
              plast->bal = 2;
            else
              plast->bal = 1;
          if (plastlast->bal == 1)
              p->bal = -1;
            else
              p->bal = 0;
          plastlast->bal = 1;
          if (plast->bal == 2) {
              /* Repair the problem. */
              p = plast;
              plast = p->right;
              }
            else {
              /* Normal continuation. */
              plast = plastlast;
              p = plast->up;
              }
          continue;
          }
        goto label_unrecoverable_error;
        }
      else {
        goto label_unrecoverable_error;
        }
    }
  /* Disconnect the tree from `top'. */
  if (top.right != 0)
    top.right->up = 0;
  /* Now, update the tree entry. */
  piacnodetree2 = top.right;
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeAddressCounterNodes2 (piacnodetree2) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  return (0);
  }

/****************************************************************************/

static unsigned int
removeCreationTimeNode (ctn_t *cell)
{
  ctn_t *tree, *node, top, *keyneighbor, *p1, *p2, *p, *plast, *plastlast;
  int signedcomp, bal;
  unsigned int decreased;

  /* AVL comes from G.M.Adelson-Velsky and E.M.Landis (1962). */
  tree = pcretimnodetree;
  if (tree == 0) {
    /***** LABEL *****/ label_cell_to_be_removed_not_in_avl_tree:
    (void) fprintf (stderr, "removeCreationTimeNode: "
                     "Cell to be removed not in AVL tree.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (1);
    }
  /* Check whether the cell is in the tree. */
  node = tree;
  while (node != 0) {
    signedcomp = tvCmp (&node->creatim, &cell->creatim, node, cell);
    if (signedcomp == 0)
        break;
      else if (signedcomp < 0)
        node = node->right;
      else
        node = node->left;
    }
  if (node == 0)
    goto label_cell_to_be_removed_not_in_avl_tree;
  if (node != cell)
    goto label_cell_to_be_removed_not_in_avl_tree;
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeCreationTimeNodes (pcretimnodetree) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  /* Initialize a special cell that is only used to
     correctly terminate the tree-rebalancing operation loop. */
  (void) memset (&top, 0, sizeof (top));
  /* Now, link `tree' to be the right subtree under `top'. */
  tree->up = &top;
  top.right = tree;
  /* `cell' points to the cell which has to be deleted.
     In general, if there are cells under `cell' on both sides,
     the deletion of `cell' is difficult because the extension
     of the subtrees under `cell' might be excessive. */
  if (cell->left != 0 && cell->right != 0) {
    /* Yes, on both sides there are cells under `cell'.
       Look for the cell with the greatest key
       being less than the one of `cell'. */
    keyneighbor = cell->left;
    while (keyneighbor->right != 0)
      keyneighbor = keyneighbor->right;
    /* Exchange `cell's and `keyneighbor's location inside the tree.
       Pay attention, the cell addresses themselves do not change.
       Exchange the upper neighbors of `cell' and `keyneighbor'. */
    p1 = cell->up;
    p2 = keyneighbor->up;
    if (p1->left == cell)
        p1->left = keyneighbor;
      else
        p1->right = keyneighbor;
    if (p2->left == keyneighbor)
        p2->left = cell;
      else
        p2->right = cell;
    keyneighbor->up = p1;
    cell->up = p2;
    /* Exchange the left neighbors of `cell' and `keyneighbor'. */
    p1 = cell->left;
    p2 = keyneighbor->left;
    p1->up = keyneighbor;
    if (p2 != 0)
      p2->up = cell;
    keyneighbor->left = p1;
    cell->left = p2;
    /* Exchange the right neighbors of `cell' and `keyneighbor'. */
    p1 = cell->right;
    p2 = keyneighbor->right;
    p1->up = keyneighbor;
    if (p2 != 0)
      p2->up = cell;
    keyneighbor->right = p1;
    cell->right = p2;
    /* Do not exchange the lower neighbors of `cell' and `keyneighbor'.
       The locations of the cells are exchanged now.
       Exchange their balances too. */
    bal = cell->bal;
    cell->bal = keyneighbor->bal;
    keyneighbor->bal = bal;
    /* Now, the tree is violated.
       To repair it, `cell' must be deleted. */
    }
  /* Paranoia check. */
  if (cell->left != 0 && cell->right != 0) {
    /***** LABEL *****/ label_unrecoverable_error:
    (void) fprintf (stderr, "removeCreationTimeNode: "
                     "Unrecoverable error.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return (1);
    }
  /* Remove `cell' from the tree, prepare the rebalancing operation. */
  p = cell->up;
  if (cell->left != 0)
      plast = cell->left;
    else
      plast = cell->right;
  if (p->right == cell) {
      p->right = plast;
      /* We lose height on the right-hand side of `p'. */
      p->bal++;
      }
    else {
      p->left = plast;
      /* We lose height on the left-hand side of `p'. */
      p->bal--;
      }
  /* If we are balanced now, then we have lost height under `p' at all. */
  decreased = p->bal == 0 ? 1 : 0;
  if (plast != 0)
    plast->up = p;
  /* Walk upwards rebalancing the tree. */
  while (p->up != 0) {
    /* `p->bal' is updated here, but, it may be out of range. */
    if (p->bal == -1 || p->bal == 0 || p->bal == 1) {
      plast = p;
      p = plast->up;
      if (decreased != 0) {
        if (plast == p->left)
            p->bal--;
          else
            p->bal++;
        decreased = p->bal == 0 ? 1 : 0;
        }
      continue;
      }
    /* Paranoia check. */
    if (decreased != 0)
      goto label_unrecoverable_error;
    /* Check where we have come from. */
    if (p->bal == -2) {
        /* We have come from the left.
           A tree rebalancing operation is to be done.
           Ensure that we can reuse the insertion rotation codes. */
        plast = p->right;
        /* Yes, we are now able to reuse the insertion rotation codes. */
        if (plast->bal == -1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->right == p)
              plast->up->right = plast;
            else
              plast->up->left = plast;
          p->right = plast->left;
          if (p->right != 0)
            p->right->up = p;
          plast->left = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          p = plast->up;
          if (plast == p->left)
              p->bal--;
            else
              p->bal++;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == 1) {
          /* Double rotation. */
          plastlast = plast->left;
          plastlast->up = p->up;
          if (p->up->right == p)
              plastlast->up->right = plastlast;
            else
              plastlast->up->left = plastlast;
          plast->left = plastlast->right;
          if (plast->left != 0)
            plast->left->up = plast;
          p->right = plastlast->left;
          if (p->right != 0)
            p->right->up = p;
          plastlast->right = plast;
          plast->up = plastlast;
          plastlast->left = p;
          p->up = plastlast;
          if (plastlast->bal == 1)
              plast->bal = -1;
            else
              plast->bal = 0;
          if (plastlast->bal == -1)
              p->bal = 1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          plast = plastlast;
          p = plast->up;
          if (plast == p->left)
              p->bal--;
            else
              p->bal++;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == 0) {
          /* Another double rotation. */
          plastlast = plast->left;
          plastlast->up = p->up;
          if (p->up->right == p)
              plastlast->up->right = plastlast;
            else
              plastlast->up->left = plastlast;
          plast->left = plastlast->right;
          if (plast->left != 0)
            plast->left->up = plast;
          p->right = plastlast->left;
          if (p->right != 0)
            p->right->up = p;
          plastlast->right = plast;
          plast->up = plastlast;
          plastlast->left = p;
          p->up = plastlast;
          if (plastlast->bal == 1)
              plast->bal = -2;
            else
              plast->bal = -1;
          if (plastlast->bal == -1)
              p->bal = 1;
            else
              p->bal = 0;
          plastlast->bal = -1;
          if (plast->bal == -2) {
              /* Repair the problem. */
              p = plast;
              plast = p->left;
              }
            else {
              /* Normal continuation. */
              plast = plastlast;
              p = plast->up;
              }
          continue;
          }
        goto label_unrecoverable_error;
        }
      else if (p->bal == 2) {
        /* We have come from the right.
           A tree rebalancing operation is to be done.
           Ensure that we can reuse the insertion rotation codes. */
        plast = p->left;
        /* Yes, we are now able to reuse the insertion rotation codes. */
        if (plast->bal == 1) {
          /* Single rotatation. */
          plast->up = p->up;
          if (p->up->left == p)
              plast->up->left = plast;
            else
              plast->up->right = plast;
          p->left = plast->right;
          if (p->left != 0)
            p->left->up = p;
          plast->right = p;
          p->up = plast;
          plast->bal = 0;
          p->bal = 0;
          p = plast->up;
          if (plast == p->right)
              p->bal++;
            else
              p->bal--;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == -1) {
          /* Double rotation. */
          plastlast = plast->right;
          plastlast->up = p->up;
          if (p->up->left == p)
              plastlast->up->left = plastlast;
            else
              plastlast->up->right = plastlast;
          plast->right = plastlast->left;
          if (plast->right != 0)
            plast->right->up = plast;
          p->left = plastlast->right;
          if (p->left != 0)
            p->left->up = p;
          plastlast->left = plast;
          plast->up = plastlast;
          plastlast->right = p;
          p->up = plastlast;
          if (plastlast->bal == -1)
              plast->bal = 1;
            else
              plast->bal = 0;
          if (plastlast->bal == 1)
              p->bal = -1;
            else
              p->bal = 0;
          plastlast->bal = 0;
          plast = plastlast;
          p = plast->up;
          if (plast == p->right)
              p->bal++;
            else
              p->bal--;
          decreased = p->bal == 0 ? 1 : 0;
          continue;
          }
        if (plast->bal == 0) {
          /* Another double rotation. */
          plastlast = plast->right;
          plastlast->up = p->up;
          if (p->up->left == p)
              plastlast->up->left = plastlast;
            else
              plastlast->up->right = plastlast;
          plast->right = plastlast->left;
          if (plast->right != 0)
            plast->right->up = plast;
          p->left = plastlast->right;
          if (p->left != 0)
            p->left->up = p;
          plastlast->left = plast;
          plast->up = plastlast;
          plastlast->right = p;
          p->up = plastlast;
          if (plastlast->bal == -1)
              plast->bal = 2;
            else
              plast->bal = 1;
          if (plastlast->bal == 1)
              p->bal = -1;
            else
              p->bal = 0;
          plastlast->bal = 1;
          if (plast->bal == 2) {
              /* Repair the problem. */
              p = plast;
              plast = p->right;
              }
            else {
              /* Normal continuation. */
              plast = plastlast;
              p = plast->up;
              }
          continue;
          }
        goto label_unrecoverable_error;
        }
      else {
        goto label_unrecoverable_error;
        }
    }
  /* Disconnect the tree from `top'. */
  if (top.right != 0)
    top.right->up = 0;
  /* Now, update the tree entry. */
  pcretimnodetree = top.right;
  if (debugglobal > 1)
    /* Check the AVL tree. */
    if (checkAvlTreeCreationTimeNodes (pcretimnodetree) == 0xffffffff) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return (1);
      }
  return (0);
  }

/****************************************************************************/

static void
removeStateLocatorAndIpAddress2 (unsigned char *statelocator,
                                  char *mystrerrbufbase)
{
  unsigned char buf7 [7];
  unsigned int slot;
  unsigned char *puc;
  ctn_t *node;

  buf7[0] = *(statelocator + 0);
  buf7[1] = *(statelocator + 1);
  buf7[2] = *(statelocator + 2);
  buf7[3] = *(statelocator + 3);
  buf7[4] = '\0';
  (void) undoAsciiArmoring (&buf7[0], &buf7[5], mystrerrbufbase);
  if (atomicallyLoadsTerminateExecution () >= 2)
    return;
  slot = ((unsigned int) buf7[5] & (unsigned int) 0xff) << 8
       | ((unsigned int) buf7[6] & (unsigned int) 0xff);
  if (slot >= numslotsglobal) {
    (void) fprintf (stderr, "removeStateLocatorAndIpAddress2: "
                     "Unrecoverable error.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  puc = statelocatorbaseaddr + slot * 193;
  if (strcmp ((char *) statelocator, (char *) puc) != 0) {
    (void) fprintf (stderr, "removeStateLocatorAndIpAddress2: "
                     "State locator to be removed not found.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  node = cretimnodebaseaddr + slot;
  if (atomicallyLoadsTerminateExecution () < 2) {
    (void) unregisterIpAddress2 (&node->sau);
    if (removeCreationTimeNode (node) != 0) {
      (void) atomicallyStoresTwoToTerminateExecution ();
      return;
      }
    }
  node->up = 0;
  node->bal = 0;
  (void) memset (&node->creatim, 0xff, sizeof (struct timeval));
  (void) memset (&node->sau, 0, sizeof (sau_t));
  *(statelocatorbaseaddr + slot * 193 + 4) = '\0';
  (void) memset (statelocatorbaseaddr + slot * 193 + 5, 0xff, 58);
  /* Begin of chaining in on the left side. */
  node->left = 0;
  if (pfreecretimnodechainfirst == 0) {
      pfreecretimnodechainlast = node;
      node->right = 0;
      }
    else {
      pfreecretimnodechainfirst->left = node;
      node->right = pfreecretimnodechainfirst;
      }
  pfreecretimnodechainfirst = node;
  /* End of chaining in on the left side. */
  return;
  }

/****************************************************************************/

static int
sauCmp (const sau_t *sau1, const sau_t *sau2)
{
  return (strcmp (&sau1->numericcliaddrstr[0], &sau2->numericcliaddrstr[0]));
  }

/****************************************************************************/

static void
scatterThreads (unsigned int rank, char *mystrerrbufbase)
{
  unsigned int size, numrankbits, k, ibit, commbitmask, garbagemask,
    sendrrank, recvrrank;

  /* Some 0-root scattering tree algorithm. */
  size = numslotsglobal;
  numrankbits = 0;
  k = size - 1;
  while (k != 0) {
    k = passU (k >> 1);
    numrankbits++;
    }
  for (ibit = 0; ibit < numrankbits; ibit++) {
    commbitmask = (unsigned int) 0x1 << (numrankbits - (ibit + 1));
    garbagemask = commbitmask - 1;
    if ((rank & garbagemask) != 0)
      continue;
    sendrrank = rank & ~ commbitmask;
    recvrrank = rank |   commbitmask;
    if (recvrrank >= size)
      continue;
    if (rank == sendrrank)
        (void) startOneMainLoadWorkerThread (recvrrank, mystrerrbufbase);
      else if (rank == recvrrank)
        ;
      else {
        (void) fprintf (stderr, "scatterThreads: Unrecoverable error.\n");
        (void) atomicallyStoresTwoToTerminateExecution ();
        return;
        }
    }
  return;
  }

/****************************************************************************/

static void
sha256 (unsigned int n, const unsigned char *pbuf, unsigned char *phash)
{
  sha256context_t context;

  /* https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf . */
  (void) sha256Init (&context);
  (void) sha256Update (&context, n, pbuf);
  (void) sha256Final (&context, phash);
  return;
  }

/****************************************************************************/

static void
sha256Final (sha256context_t *context, unsigned char *phash)
{
  unsigned int am0, am1, am2, am3, i, m;

  am0 = context->bitlen[0]       & (unsigned int) 0xffff;
  am1 = context->bitlen[0] >> 16 & (unsigned int) 0xffff;
  am2 = context->bitlen[1]       & (unsigned int) 0xffff;
  am3 = context->bitlen[1] >> 16 & (unsigned int) 0xffff;
  am0 += context->bufferlevel * 8;
  am1 += am0 >> 16;
  am2 += am1 >> 16;
  am3 += am2 >> 16;
  am0 &= (unsigned int) 0xffff;
  am1 &= (unsigned int) 0xffff;
  am2 &= (unsigned int) 0xffff;
  am3 &= (unsigned int) 0xffff;
  context->bitlen[0] = (am1 << 16) | am0;
  context->bitlen[1] = (am3 << 16) | am2;
  if (context->bufferlevel < 56) {
      context->buffer[context->bufferlevel++] = 0x80;
      while (context->bufferlevel < 56)
        context->buffer[context->bufferlevel++] = 0x00;
      }
    else {
      context->buffer[context->bufferlevel++] = 0x80;
      while (context->bufferlevel < 64)
        context->buffer[context->bufferlevel++] = 0x00;
      (void) sha256Transform (context);
      for (i = 0; i < 56; i++)
        context->buffer[i] = 0;
      }
  m = 0xff;
  context->buffer[56] = (unsigned char) (context->bitlen[1] >> 24 & m);
  context->buffer[57] = (unsigned char) (context->bitlen[1] >> 16 & m);
  context->buffer[58] = (unsigned char) (context->bitlen[1] >>  8 & m);
  context->buffer[59] = (unsigned char) (context->bitlen[1]       & m);
  context->buffer[60] = (unsigned char) (context->bitlen[0] >> 24 & m);
  context->buffer[61] = (unsigned char) (context->bitlen[0] >> 16 & m);
  context->buffer[62] = (unsigned char) (context->bitlen[0] >>  8 & m);
  context->buffer[63] = (unsigned char) (context->bitlen[0]       & m);
  (void) sha256Transform (context);
  *(phash +  0) = (unsigned char) (context->state[0] >> 24 & m);
  *(phash +  1) = (unsigned char) (context->state[0] >> 16 & m);
  *(phash +  2) = (unsigned char) (context->state[0] >>  8 & m);
  *(phash +  3) = (unsigned char) (context->state[0]       & m);
  *(phash +  4) = (unsigned char) (context->state[1] >> 24 & m);
  *(phash +  5) = (unsigned char) (context->state[1] >> 16 & m);
  *(phash +  6) = (unsigned char) (context->state[1] >>  8 & m);
  *(phash +  7) = (unsigned char) (context->state[1]       & m);
  *(phash +  8) = (unsigned char) (context->state[2] >> 24 & m);
  *(phash +  9) = (unsigned char) (context->state[2] >> 16 & m);
  *(phash + 10) = (unsigned char) (context->state[2] >>  8 & m);
  *(phash + 11) = (unsigned char) (context->state[2]       & m);
  *(phash + 12) = (unsigned char) (context->state[3] >> 24 & m);
  *(phash + 13) = (unsigned char) (context->state[3] >> 16 & m);
  *(phash + 14) = (unsigned char) (context->state[3] >>  8 & m);
  *(phash + 15) = (unsigned char) (context->state[3]       & m);
  *(phash + 16) = (unsigned char) (context->state[4] >> 24 & m);
  *(phash + 17) = (unsigned char) (context->state[4] >> 16 & m);
  *(phash + 18) = (unsigned char) (context->state[4] >>  8 & m);
  *(phash + 19) = (unsigned char) (context->state[4]       & m);
  *(phash + 20) = (unsigned char) (context->state[5] >> 24 & m);
  *(phash + 21) = (unsigned char) (context->state[5] >> 16 & m);
  *(phash + 22) = (unsigned char) (context->state[5] >>  8 & m);
  *(phash + 23) = (unsigned char) (context->state[5]       & m);
  *(phash + 24) = (unsigned char) (context->state[6] >> 24 & m);
  *(phash + 25) = (unsigned char) (context->state[6] >> 16 & m);
  *(phash + 26) = (unsigned char) (context->state[6] >>  8 & m);
  *(phash + 27) = (unsigned char) (context->state[6]       & m);
  *(phash + 28) = (unsigned char) (context->state[7] >> 24 & m);
  *(phash + 29) = (unsigned char) (context->state[7] >> 16 & m);
  *(phash + 30) = (unsigned char) (context->state[7] >>  8 & m);
  *(phash + 31) = (unsigned char) (context->state[7]       & m);
  return;
  }

/****************************************************************************/

static void
sha256Init (sha256context_t *context)
{
  context->bufferlevel = 0;
  context->bitlen[0] = 0;
  context->bitlen[1] = 0;
  context->state[0] = (unsigned int) 0x6a09e667;
  context->state[1] = (unsigned int) 0xbb67ae85;
  context->state[2] = (unsigned int) 0x3c6ef372;
  context->state[3] = (unsigned int) 0xa54ff53a;
  context->state[4] = (unsigned int) 0x510e527f;
  context->state[5] = (unsigned int) 0x9b05688c;
  context->state[6] = (unsigned int) 0x1f83d9ab;
  context->state[7] = (unsigned int) 0x5be0cd19;
  return;
  }

/****************************************************************************/

static void
sha256Transform (sha256context_t *context)
{
  static const unsigned int k [64] = {
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
  unsigned int m [64];
  unsigned int i, a, b, c, d, e, f, g, h, u, v;

  for (i = 0; i < 16; i++)
    m[i] = ((unsigned int) context->buffer[(i << 2) + 0] &
            (unsigned int) 0xff) << 24
         | ((unsigned int) context->buffer[(i << 2) + 1] &
            (unsigned int) 0xff) << 16
         | ((unsigned int) context->buffer[(i << 2) + 2] &
            (unsigned int) 0xff) <<  8
         | ((unsigned int) context->buffer[(i << 2) + 3] &
            (unsigned int) 0xff);
  for (i = 16; i < 64; i++)
    m[i] = ( ( (m[i -  2] >> 17 | m[i -  2] << 15) ^
               (m[i -  2] >> 19 | m[i -  2] << 13) ^ m[i -  2] >> 10 ) +
             ( (m[i - 15] >>  7 | m[i - 15] << 25) ^
               (m[i - 15] >> 18 | m[i - 15] << 14) ^ m[i - 15] >>  3 ) +
             m[i -  7]                                                 +
             m[i - 16] ) & (unsigned int) 0xffffffff;
  a = context->state[0];
  b = context->state[1];
  c = context->state[2];
  d = context->state[3];
  e = context->state[4];
  f = context->state[5];
  g = context->state[6];
  h = context->state[7];
  for (i = 0; i < 64; i++) {
    u = ( h                       +
          ( (e >>  6 | e << 26) ^
            (e >> 11 | e << 21) ^
            (e >> 25 | e <<  7) ) +
          ( (e & f) ^ (~e & g) )  +
          k[i]                    +
          m[i] ) & (unsigned int) 0xffffffff;
    v = ( ( (a >>  2 | a << 30) ^
            (a >> 13 | a << 19) ^
            (a >> 22 | a << 10) ) +
          ( (a & b) ^ (a & c) ^ (b & c) ) ) & (unsigned int) 0xffffffff;
    h = g;
    g = f;
    f = e;
    e = (d + u) & (unsigned int) 0xffffffff;
    d = c;
    c = b;
    b = a;
    a = (u + v) & (unsigned int) 0xffffffff;
    }
  context->state[0] = (context->state[0] + a) & (unsigned int) 0xffffffff;
  context->state[1] = (context->state[1] + b) & (unsigned int) 0xffffffff;
  context->state[2] = (context->state[2] + c) & (unsigned int) 0xffffffff;
  context->state[3] = (context->state[3] + d) & (unsigned int) 0xffffffff;
  context->state[4] = (context->state[4] + e) & (unsigned int) 0xffffffff;
  context->state[5] = (context->state[5] + f) & (unsigned int) 0xffffffff;
  context->state[6] = (context->state[6] + g) & (unsigned int) 0xffffffff;
  context->state[7] = (context->state[7] + h) & (unsigned int) 0xffffffff;
  return;
  }

/****************************************************************************/

static void
sha256Update (sha256context_t *context, unsigned int len,
               const unsigned char *pbuf)
{
  unsigned int i, am0, am1, am2, am3;

  for (i = 0; i < len; i++) {
    context->buffer[context->bufferlevel++] = *(pbuf + i);
    if (context->bufferlevel < 64)
      continue;
    context->bufferlevel = 0;
    (void) sha256Transform (context);
    am0 = context->bitlen[0]       & (unsigned int) 0xffff;
    am1 = context->bitlen[0] >> 16 & (unsigned int) 0xffff;
    am2 = context->bitlen[1]       & (unsigned int) 0xffff;
    am3 = context->bitlen[1] >> 16 & (unsigned int) 0xffff;
    am0 += 512;
    am1 += am0 >> 16;
    am2 += am1 >> 16;
    am3 += am2 >> 16;
    am0 &= (unsigned int) 0xffff;
    am1 &= (unsigned int) 0xffff;
    am2 &= (unsigned int) 0xffff;
    am3 &= (unsigned int) 0xffff;
    context->bitlen[0] = (am1 << 16) | am0;
    context->bitlen[1] = (am3 << 16) | am2;
    }
  return;
  }

/****************************************************************************/

static void
sleepMilliSecs (unsigned int millisecstobesleptlocal, char *mystrerrbufbase)
{
#if (0)
  struct timespec ts;

  if (millisecstobesleptlocal == 0)
    return;
  (void) checkForPendingSignals (mystrerrbufbase);
  ts.tv_sec = (time_t) millisecstobesleptlocal / 1000;
  ts.tv_nsec = ((long) millisecstobesleptlocal % 1000) * 1000000;
  /* Do not mess around here to handle an early return
     from the following function call due to an interrupt. */
  (void) nanosleep (&ts, 0);
#elif (0)
  struct timeval tv;

  if (millisecstobesleptlocal == 0)
    return;
  (void) checkForPendingSignals (mystrerrbufbase);
  tv.tv_sec = (time_t) millisecstobesleptlocal / 1000;
  tv.tv_usec = ((suseconds_t) millisecstobesleptlocal % 1000) * 1000;
  /* Do not mess around here to handle an early return
     from the following function call due to an interrupt. */
  (void) select (0, 0, 0, 0, &tv);
#else
  struct timespec ts, tr;
  int rc;

  if (millisecstobesleptlocal == 0)
    return;
  (void) checkForPendingSignals (mystrerrbufbase);
  ts.tv_sec = (time_t) millisecstobesleptlocal / 1000;
  ts.tv_nsec = ((long) millisecstobesleptlocal % 1000) * 1000000;
  /* Yes, mess around here to handle an early return
     from the following function call due to an interrupt. */
  for (;;) {
    rc = nanosleep (&ts, &tr);
    if (rc == 0)
      break;
    if (errno != EINTR) {
      (void) perror ("sleepMilliSecs: nanosleep");
      (void) atomicallyStoresTwoToTerminateExecution ();
      break;
      }
    if (atomicallyLoadsTerminateExecution () != 0)
      break;
    (void) memcpy (&ts, &tr, sizeof (struct timespec));
    }
#endif
  return;
  }

/****************************************************************************/

static void
startOneMainLoadWorkerThread (unsigned int rank, char *mystrerrbufbase)
{
  int rc;
  pthread_attr_t attr;
  size_t numbytes;
  pthread_t thread;

  rc = pthread_attr_init (&attr);
  if (rc != 0) {
    (void) fprintf (stderr, "startOneMainLoadWorkerThread: "
                     "pthread_attr_init: "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  if (kbytesthreadstacksizeglobal != 0) {
    numbytes = (size_t) kbytesthreadstacksizeglobal * 1024;
    rc = pthread_attr_setstacksize (&attr, numbytes);
    if (rc != 0) {
      (void) fprintf (stderr, "startOneMainLoadWorkerThread: "
                       "pthread_attr_setstacksize: "
                       "%s.\n", myStrError (rc, mystrerrbufbase));
      (void) atomicallyStoresTwoToTerminateExecution ();
      return;
      }
    }
  rc = pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
  if (rc != 0) {
    (void) fprintf (stderr, "startOneMainLoadWorkerThread: "
                     "pthread_attr_setdetachstate: "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  rc = pthread_create (&thread, &attr, workerMainLoad,
                        threadrankbaseaddr + rank);
  if (rc != 0) {
    (void) fprintf (stderr, "startOneMainLoadWorkerThread: "
                     "pthread_create: "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  rc = pthread_attr_destroy (&attr);
  if (rc != 0) {
    (void) fprintf (stderr, "startOneMainLoadWorkerThread: "
                     "pthread_attr_destroy: "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  return;
  }

/****************************************************************************/

static void
startThreads (char *mystrerrbufbase)
{
  int rc;
  pthread_attr_t attr;
  size_t numbytes, stacksize;
  pthread_t thread;

  rc = pthread_barrier_init (&barrier2, 0, 2);
  if (rc != 0) {
    (void) fprintf (stderr, "startThreads: pthread_barrier_init "
                     "(barrier2): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  rc = pthread_barrier_init (&barrierall, 0, numslotsglobal + 3);
  if (rc != 0) {
    (void) fprintf (stderr, "startThreads: pthread_barrier_init "
                     "(barrierall): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  rc = pthread_barrier_init (&barrierallminus1, 0, numslotsglobal + 2);
  if (rc != 0) {
    (void) fprintf (stderr, "startThreads: pthread_barrier_init "
                     "(barrierallminus1): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  rc = pthread_attr_init (&attr);
  if (rc != 0) {
    (void) fprintf (stderr, "startThreads: pthread_attr_init: "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  if (kbytesthreadstacksizeglobal != 0) {
    numbytes = (size_t) kbytesthreadstacksizeglobal * 1024;
    rc = pthread_attr_setstacksize (&attr, numbytes);
    if (rc != 0) {
      (void) fprintf (stderr, "startThreads: pthread_attr_setstacksize: "
                       "%s.\n", myStrError (rc, mystrerrbufbase));
      (void) exit (1);
      }
    }
  rc = pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
  if (rc != 0) {
    (void) fprintf (stderr, "startThreads: pthread_attr_setdetachstate: "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  /* Start the disk output worker thread. */
  rc = pthread_create (&thread, &attr, workerDiskOutput,
                        threadrankbaseaddr + numslotsglobal + 1);
  if (rc != 0) {
    (void) fprintf (stderr, "startThreads: pthread_create "
                     "(workerDiskOutput): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  /* Start the state locator cleanup worker thread. */
  rc = pthread_create (&thread, &attr, workerCleanupStateLocators,
                        threadrankbaseaddr + numslotsglobal + 0);
  if (rc != 0) {
    (void) fprintf (stderr, "startThreads: pthread_create "
                     "(workerCleanupStateLocators): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  /* Start the 0-rank main load worker thread. */
  (void) startOneMainLoadWorkerThread (0, mystrerrbufbase);
  (void) flushOutStreams ();
  /* Wait until all those who help are with us. */
  rc = pthread_barrier_wait (&barrierall);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    (void) fprintf (stderr, "startThreads: pthread_barrier_wait "
                     "(barrierall): "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    /* This is more or less pure actionism here. If something bad
       happened at this point, we typically got stuck in the barrier. */
    (void) exit (1);
    }
  if (debugglobal > 0) {
    rc = pthread_attr_getstacksize (&attr, &stacksize);
    if (rc != 0) {
      (void) fprintf (stderr, "startThreads: pthread_attr_getstacksize: "
                       "%s.\n", myStrError (rc, mystrerrbufbase));
      (void) exit (1);
      }
    numbytes = stacksize;
    (void) printf ("Started %u additional threads, each of which with %lu "
                    "kByte(s) stack size.\n",
                    numslotsglobal + 2,
                    ((unsigned long) numbytes & (unsigned long) 0x3ff) == 0
                      ? ((unsigned long) numbytes >> 10)
                      : ((unsigned long) numbytes >> 10) + 1);
    numbytes = stacksize * (size_t) (numslotsglobal + 2);
    (void) printf ("That is %lu MByte(s) stack size in total.\n",
                    ((unsigned long) numbytes &
                     (unsigned long) 0xfffff) == 0
                      ? ((unsigned long) numbytes >> 20)
                      : ((unsigned long) numbytes >> 20) + 1);
    }
  rc = pthread_attr_destroy (&attr);
  if (rc != 0) {
    (void) fprintf (stderr, "startThreads: pthread_attr_destroy: "
                     "%s.\n", myStrError (rc, mystrerrbufbase));
    (void) exit (1);
    }
  return;
  }

/****************************************************************************/

static int
tvCmp (const struct timeval *tv1, const struct timeval *tv2,
        const ctn_t *node1, const ctn_t *node2)
{
  unsigned char *puc1, *puc2;

  if (tv1->tv_sec > tv2->tv_sec)
    return (+1);
  if (tv1->tv_sec < tv2->tv_sec)
    return (-1);
  if (tv1->tv_usec > tv2->tv_usec)
    return (+1);
  if (tv1->tv_usec < tv2->tv_usec)
    return (-1);
  if (node1 == 0 || node2 == 0)
    return (0);
  puc1 = statelocatorbaseaddr + node1->slot * 193;
  puc2 = statelocatorbaseaddr + node2->slot * 193;
  return ((int) strcmp ((char *) puc1, (char *) puc2));
  }

/****************************************************************************/

static void
undoAsciiArmoring (const unsigned char *in, unsigned char *out,
                    char *mystrerrbufbase)
{
  static const char *uchexstr = "0123456789ABCDEF";
  static const char *lchexstr = "0123456789abcdef";
  static unsigned int first = 1;
  static unsigned int table [256];
  int rc;
  unsigned int n, i, j, k;

  if (first != 0) {
    /* Begin of initialization of static variables. */
    rc = pthread_mutex_lock (&mutexexclusivecode);
    if (rc != 0) {
      (void) fprintf (stderr, "undoAsciiArmoring: pthread_mutex_lock "
                       "(mutexexclusivecode): "
                       "%s.\n", myStrError (rc, mystrerrbufbase));
      (void) atomicallyStoresTwoToTerminateExecution ();
      n = (unsigned int) strlen ((const char *) in);
      if ((n & (unsigned int) 0x1) != 0)
        n++;
      n >>= 1;
      if (n != 0)
        (void) memset (out, 0xff, (size_t) n);
      return;
      }
    (void) passP (&first);
    if (first != 0) {
      n = (unsigned int) (sizeof (table) / sizeof (table[0]));
      for (i = 0; i < n; i++)
        table[i] = 0xffff;
      for (i = 0; i < 16; i++) {
        table[(unsigned char) *(uchexstr + i)] = i;
        table[(unsigned char) *(lchexstr + i)] = i;
        }
      first = 0;
      }
    rc = pthread_mutex_unlock (&mutexexclusivecode);
    if (rc != 0) {
      (void) fprintf (stderr, "undoAsciiArmoring: pthread_mutex_unlock "
                       "(mutexexclusivecode): "
                       "%s.\n", myStrError (rc, mystrerrbufbase));
      /* We cannot do more than pray. */
      (void) atomicallyStoresTwoToTerminateExecution ();
      }
    /* End of initialization of static variables. */
    }
  for (j = 0;; j++) {
    if (*(in + j) == '\0')
      break;
    k = table[*(in + j)];
    if (k > 15) {
      if (atomicallyLoadsTerminateExecution () < 2) {
        (void) fprintf (stderr, "undoAsciiArmoring: "
                         "Input not a hex string.\n");
        (void) atomicallyStoresTwoToTerminateExecution ();
        }
      k = 15;
      }
    if ((j & (unsigned int) 0x1) == 0)
        *(out + (j >> 1))  = (unsigned char) (k << 4 & (unsigned int) 0xf0);
      else
        *(out + (j >> 1)) |= (unsigned char) (k << 0 & (unsigned int) 0x0f);
    }
  return;
  }

/****************************************************************************/

static void
unregisterIpAddress1 (sau_t *sau)
{
  iacn_t *p, *pnext;
  int signedcomp;

  if (atomicallyLoadsTerminateExecution () >= 2)
    return;
  /* Walk downwards, looking for the given key in the tree. */
  p = piacnodetree1;
  if (p == 0) {
    (void) fprintf (stderr, "unregisterIpAddress1: Empty tree.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  for (;;) {
    signedcomp = sauCmp (&p->sau, sau);
    if (signedcomp == 0) {
        /* Found. */
        if (p->cnt > 1) {
          p->cnt--;
          return;
          }
        if (p->cnt == 1) {
          if (removeAddressCounterNode1 (p) != 0) {
            (void) atomicallyStoresTwoToTerminateExecution ();
            return;
            }
          p->up = 0;
          p->bal = 0;
          p->cnt = 0;
          (void) memset (&p->sau, 0, sizeof (sau_t));
          /* Begin of chaining in on the left side. */
          p->left = 0;
          if (pfreeiacnodechainfirst1 == 0) {
              pfreeiacnodechainlast1 = p;
              p->right = 0;
              }
            else {
              pfreeiacnodechainfirst1->left = p;
              p->right = pfreeiacnodechainfirst1;
              }
          pfreeiacnodechainfirst1 = p;
          /* End of chaining in on the left side. */
          return;
          }
        (void) fprintf (stderr, "unregisterIpAddress1: Bad counter value.\n");
        (void) atomicallyStoresTwoToTerminateExecution ();
        return;
        }
      else if (signedcomp < 0)
        pnext = p->right;
      else
        pnext = p->left;
    if (pnext == 0) {
      (void) fprintf (stderr, "unregisterIpAddress1: "
                       "IP address not found.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return;
      }
    p = pnext;
    }
  /* Never reached. */
  return;
  }

/****************************************************************************/

static void
unregisterIpAddress2 (sau_t *sau)
{
  iacn_t *p, *pnext;
  int signedcomp;

  if (atomicallyLoadsTerminateExecution () >= 2)
    return;
  /* Walk downwards, looking for the given key in the tree. */
  p = piacnodetree2;
  if (p == 0) {
    (void) fprintf (stderr, "unregisterIpAddress2: Empty tree.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  for (;;) {
    signedcomp = sauCmp (&p->sau, sau);
    if (signedcomp == 0) {
        /* Found. */
        if (p->cnt > 1) {
          p->cnt--;
          return;
          }
        if (p->cnt == 1) {
          if (removeAddressCounterNode2 (p) != 0) {
            (void) atomicallyStoresTwoToTerminateExecution ();
            return;
            }
          p->up = 0;
          p->bal = 0;
          p->cnt = 0;
          (void) memset (&p->sau, 0, sizeof (sau_t));
          /* Begin of chaining in on the left side. */
          p->left = 0;
          if (pfreeiacnodechainfirst2 == 0) {
              pfreeiacnodechainlast2 = p;
              p->right = 0;
              }
            else {
              pfreeiacnodechainfirst2->left = p;
              p->right = pfreeiacnodechainfirst2;
              }
          pfreeiacnodechainfirst2 = p;
          /* End of chaining in on the left side. */
          return;
          }
        (void) fprintf (stderr, "unregisterIpAddress2: Bad counter value.\n");
        (void) atomicallyStoresTwoToTerminateExecution ();
        return;
        }
      else if (signedcomp < 0)
        pnext = p->right;
      else
        pnext = p->left;
    if (pnext == 0) {
      (void) fprintf (stderr, "unregisterIpAddress2: "
                       "IP address not found.\n");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return;
      }
    p = pnext;
    }
  /* Never reached. */
  return;
  }

/****************************************************************************/

static unsigned char *
w (unsigned char *p, unsigned char *pbeyond, const char *txt)
{
  while (p < pbeyond) {
    if ((*p = (unsigned char) *txt++) == '\0')
      return (p);
    p++;
    }
  return (pbeyond);
  }

/****************************************************************************/

static void *
workerCleanupStateLocators (void *arg)
{
  static int rcexit = 0;
  char mystrerrbuf [MYWEBSERVER_MYSTRERRBUFDIM];
  int rc;
  struct timeval currtim;

  arg = *&arg;
  (void) flushOutStreams ();
  /* Wait until all those who help are with us. */
  rc = pthread_barrier_wait (&barrierall);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    (void) fprintf (stderr, "workerCleanupStateLocators: "
                     "pthread_barrier_wait (barrierall): "
                     "%s.\n", myStrError (rc, &mystrerrbuf[0]));
    /* This is more or less pure actionism here. If something bad
       happened at this point, we typically got stuck in the barrier. */
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_barrierallminus1;
    }
  for (;;) {
    if (atomicallyLoadsTerminateExecution () != 0)
      break;
    if (gettimeofday (&currtim, 0) != 0) {
      (void) perror ("workerCleanupStateLocators: gettimeofday");
      currtim.tv_sec = 0;
      currtim.tv_usec = 0;
      (void) atomicallyStoresTwoToTerminateExecution ();
      }
    rc = pthread_mutex_lock (&mutexstalocliftim);
    if (rc != 0) {
      (void) fprintf (stderr, "workerCleanupStateLocators: "
                       "pthread_mutex_lock (mutexstalocliftim): "
                       "%s.\n", myStrError (rc, &mystrerrbuf[0]));
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_barrierallminus1;
      }
    /* Due to runtime requirements, the following function
       will remove a maximum of 2 expired state locators. */
    (void) enforceStateLocatorLifeTimeRule (&currtim, &mystrerrbuf[0]);
    rc = pthread_mutex_unlock (&mutexstalocliftim);
    if (rc != 0) {
      (void) fprintf (stderr, "workerCleanupStateLocators: "
                       "pthread_mutex_unlock (mutexstalocliftim): "
                       "%s.\n", myStrError (rc, &mystrerrbuf[0]));
      /* We cannot do more than pray. */
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_barrierallminus1;
      }
    if (atomicallyLoadsTerminateExecution () != 0)
      break;
    (void) sleepMilliSecs (millisecstobesleptglobal, &mystrerrbuf[0]);
    }
  /***** LABEL *****/ label_barrierallminus1:
  if (debugglobal > 0)
    (void) printf ("State locator cleanup worker: "
                    "Arrived at `barrierallminus1'.\n");
  (void) flushOutStreams ();
  /* Wait for the worker majority to be in front of their termination. */
  rc = pthread_barrier_wait (&barrierallminus1);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    (void) fprintf (stderr, "workerCleanupStateLocators: "
                     "pthread_barrier_wait (barrierallminus1): "
                     "%s.\n", myStrError (rc, &mystrerrbuf[0]));
    /* This is more or less pure actionism here. If something bad
       happened at this point, we typically got stuck in the barrier. */
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_exit;
    }
  if (debugglobal > 0)
    (void) printf ("State locator cleanup worker: "
                    "Passed `barrierallminus1'.\n");
  /***** LABEL *****/ label_exit:
  (void) flushOutStreams ();
  (void) pthread_exit (&rcexit);
  /* Never reached. */
  return (0);
  }

/****************************************************************************/

static void *
workerDiskOutput (void *arg)
{
  static int rcexit = 0;
  char mystrerrbuf [MYWEBSERVER_MYSTRERRBUFDIM];
  int rc;
  unsigned int n, writeout;
  unsigned char *p;

  arg = *&arg;
  diskoutbuflvl0 = 0;
  diskoutbuflvl1 = 0;
  diskoutbufwhichone = 0;
  (void) flushOutStreams ();
  /* Wait until all those who help are with us. */
  rc = pthread_barrier_wait (&barrierall);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    (void) fprintf (stderr, "workerDiskOutput: "
                     "pthread_barrier_wait (barrierall): "
                     "%s.\n", myStrError (rc, &mystrerrbuf[0]));
    /* This is more or less pure actionism here. If something bad
       happened at this point, we typically got stuck in the barrier. */
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_barrierallminus1;
    }
  for (;;) {
    if (atomicallyLoadsTerminateExecution () != 0)
      break;
    rc = pthread_mutex_lock (&mutexdiskoutbuffer);
    if (rc != 0) {
      (void) fprintf (stderr, "workerDiskOutput: "
                       "pthread_mutex_lock (mutexdiskoutbuffer): "
                       "%s.\n", myStrError (rc, &mystrerrbuf[0]));
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_barrierallminus1;
      }
    n = diskoutbufwhichone == 0 ? diskoutbuflvl0 : diskoutbuflvl1;
    writeout = 0;
    if (atomicallyLoadsWriteoutAccRecsToFile () != 0) {
        (void) atomicallyStoresZeroToWriteoutAccRecsToFile ();
        if (n != 0) {
          diskoutbufwhichone = 1 - diskoutbufwhichone;
          writeout = 1;
          }
        }
      else if (n > kbytesdiskoutbufferglobal * 1024 >> 1) {
        diskoutbufwhichone = 1 - diskoutbufwhichone;
        writeout = 1;
        }
    rc = pthread_mutex_unlock (&mutexdiskoutbuffer);
    if (rc != 0) {
      (void) fprintf (stderr, "workerDiskOutput: "
                       "pthread_mutex_unlock (mutexdiskoutbuffer): "
                       "%s.\n", myStrError (rc, &mystrerrbuf[0]));
      /* We cannot do more than pray. */
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_barrierallminus1;
      }
    if (writeout != 0) {
      /* Keep in mind, `diskoutbufwhichone' was toggled. */
      p = diskoutbufwhichone != 0 ? diskoutbuffer0 : diskoutbuffer1;
      (void) writeoutBufferToDisk (p, n);
      if (diskoutbufwhichone != 0)
          diskoutbuflvl0 = 0;
        else
          diskoutbuflvl1 = 0;
      }
    if (atomicallyLoadsTerminateExecution () != 0)
      break;
    (void) sleepMilliSecs (millisecstobesleptglobal, &mystrerrbuf[0]);
    }
  /***** LABEL *****/ label_barrierallminus1:
  if (debugglobal > 0)
    (void) printf ("Dist output worker: Arrived at `barrierallminus1'.\n");
  (void) flushOutStreams ();
  /* Wait for the worker majority to be in front of their termination. */
  rc = pthread_barrier_wait (&barrierallminus1);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    (void) fprintf (stderr, "workerDiskOutput: "
                     "pthread_barrier_wait (barrierallminus1): "
                     "%s.\n", myStrError (rc, &mystrerrbuf[0]));
    /* This is more or less pure actionism here. If something bad
       happened at this point, we typically got stuck in the barrier. */
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_persuadeaccepttoreturn;
    }
  if (debugglobal > 0)
    (void) printf ("Dist output worker: Passed `barrierallminus1'.\n");
  p = diskoutbufwhichone == 0 ? diskoutbuffer0 : diskoutbuffer1;
  n = diskoutbufwhichone == 0 ? diskoutbuflvl0 : diskoutbuflvl1;
  (void) writeoutBufferToDisk (p, n);
  if (diskoutbufwhichone == 0)
      diskoutbuflvl0 = 0;
    else
      diskoutbuflvl1 = 0;
  /***** LABEL *****/ label_persuadeaccepttoreturn:
  (void) flushOutStreams ();
  (void) persuadeAcceptToReturn (&mystrerrbuf[0]);
  (void) sleepMilliSecs (millisecstobesleptglobal, &mystrerrbuf[0]);
  (void) persuadeAcceptToReturn (&mystrerrbuf[0]);
  (void) sleepMilliSecs (millisecstobesleptglobal, &mystrerrbuf[0]);
  (void) persuadeAcceptToReturn (&mystrerrbuf[0]);
  if (debugglobal > 0)
    (void) printf ("Dist output worker: Arrived at `barrier2'.\n");
  (void) flushOutStreams ();
  /* Prevent the main thread from ending before us. */
  rc = pthread_barrier_wait (&barrier2);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    (void) fprintf (stderr, "workerDiskOutput: "
                     "pthread_barrier_wait (barrier2): "
                     "%s.\n", myStrError (rc, &mystrerrbuf[0]));
    /* This is more or less pure actionism here. If something bad
       happened at this point, we typically got stuck in the barrier. */
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_exit;
    }
  if (debugglobal > 0)
    (void) printf ("Dist output worker: Passed `barrier2'.\n");
  /***** LABEL *****/ label_exit:
  (void) flushOutStreams ();
  (void) pthread_exit (&rcexit);
  /* Never reached. */
  return (0);
  }

/****************************************************************************/

static void *
workerMainLoad (void *arg)
{
  static int rcexit = 0;
  char mystrerrbuf [MYWEBSERVER_MYSTRERRBUFDIM];
  unsigned int rank, numtoberead, i, numwritten, numtobewritten;
  int rc;
  job_t *pjob;
  struct timeval tv;
  unsigned char *pinbuf, *poutbuf;
  ssize_t rcread, rcwrite;

  rank = * (unsigned int *) arg;
  if (rank != 0) {
    /* Push the data from `/dev/urandom' through. */
    (void) getRandomBytes32 (rank, 0, 0);
    (void) getRandomBytes32 (rank, 0, 0);
    }
  (void) scatterThreads (rank, &mystrerrbuf[0]);
  (void) flushOutStreams ();
  /* Wait until all those who help are with us. */
  rc = pthread_barrier_wait (&barrierall);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    (void) fprintf (stderr, "workerMainLoad: "
                     "pthread_barrier_wait (barrierall): "
                     "%s.\n", myStrError (rc, &mystrerrbuf[0]));
    /* This is more or less pure actionism here. If something bad
       happened at this point, we typically got stuck in the barrier. */
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_barrierallminus1;
    }
  for (;;) {
    if (atomicallyLoadsTerminateExecution () != 0)
      goto label_barrierallminus1;
    pjob = 0;
    while (pjob == 0) {
      if (atomicallyLoadsTerminateExecution () != 0)
        goto label_barrierallminus1;
      rc = pthread_mutex_lock (&mutexjobstobedone);
      if (rc != 0) {
        (void) fprintf (stderr, "workerMainLoad: pthread_mutex_lock "
                         "(mutexjobstobedone): "
                         "%s.\n", myStrError (rc, &mystrerrbuf[0]));
        (void) atomicallyStoresTwoToTerminateExecution ();
        goto label_barrierallminus1;
        }
      if (pjobstobedonefirst == 0) {
        rc = pthread_mutex_unlock (&mutexjobstobedone);
        if (rc != 0) {
          (void) fprintf (stderr, "workerMainLoad: pthread_mutex_unlock "
                           "(mutexjobstobedone) 1: "
                           "%s.\n", myStrError (rc, &mystrerrbuf[0]));
          /* We cannot do more than pray. */
          (void) atomicallyStoresTwoToTerminateExecution ();
          goto label_barrierallminus1;
          }
        if (atomicallyLoadsTerminateExecution () != 0)
          goto label_barrierallminus1;
        (void) sleepMilliSecs (millisecstobesleptglobal, &mystrerrbuf[0]);
        continue;
        }
      /* Begin of non-zero chaining out on the left side. */
      pjob = pjobstobedonefirst;
      if (pjobstobedonefirst->right != 0)
          pjobstobedonefirst->right->left = 0;
        else
          pjobstobedonelast = 0;
      pjobstobedonefirst = pjobstobedonefirst->right;
      /* End of non-zero chaining out on the left side. */
      rc = pthread_mutex_unlock (&mutexjobstobedone);
      if (rc != 0) {
        (void) fprintf (stderr, "workerMainLoad: pthread_mutex_unlock "
                         "(mutexjobstobedone) 2: "
                         "%s.\n", myStrError (rc, &mystrerrbuf[0]));
        /* We cannot do more than pray. */
        (void) atomicallyStoresTwoToTerminateExecution ();
        goto label_barrierallminus1;
        }
      }
    if (atomicallyLoadsTerminateExecution () != 0) {
      if (atomicallyLoadsTerminateExecution () >= 2)
        goto label_barrierallminus1;
      (void) writeoutUniversalRejectionResponse (pjob->sfd);
      goto label_close_file_descriptor;
      }
    /* Install a timeout for this descriptor. */
    tv.tv_sec = 2;
    tv.tv_usec = 0;
    if (setsockopt (pjob->sfd, SOL_SOCKET, SO_RCVTIMEO, (const char *) &tv,
                     sizeof (tv)) != 0) {
      (void) writeoutUniversalRejectionResponse (pjob->sfd);
      goto label_close_file_descriptor;
      }
    /* We will read now. */
    pjob->buflvl1 = 0;
    pinbuf = pjob->pbuf1;
    numtoberead = pjob->bufdim - 1;
    /* We expect significantly less than 1500 bytes here. */
    for (i = 0; i < 8; i++) {
      if (atomicallyLoadsTerminateExecution () != 0) {
        if (atomicallyLoadsTerminateExecution () >= 2)
          goto label_barrierallminus1;
        (void) writeoutUniversalRejectionResponse (pjob->sfd);
        goto label_close_file_descriptor;
        }
      if (numtoberead == 0)
        break;
      /* No flags. */
      rcread = read (pjob->sfd, pinbuf, (size_t) numtoberead);
      if (rcread > (ssize_t) numtoberead) {
        (void) fprintf (stderr, "workerMainLoad: read: "
                         "Unrecoverable error.\n");
        (void) atomicallyStoresTwoToTerminateExecution ();
        goto label_barrierallminus1;
        }
      if (rcread < 0) {
        if (errno == ECONNRESET) {
          /* Some description from the Internet: `Connection reset by peer'
             is the TCP/IP equivalent of slamming the phone back on the hook.
             It is more polite than merely not replying, leaving one hanging.
             But it is not the FIN-ACK expected of the truly polite TCP/IP
             converseur. For short. The peer closed the connection. Hence,
             we shall not send our nice universal rejection response here. */
          goto label_close_file_descriptor;
          }
        if (errno == EAGAIN || errno == EWOULDBLOCK)
          /* Timeout expired. */
          break;
        if (debugglobal > 0)
          (void) printf ("Main load worker %03u: read: %s.\n",
                          rank, myStrError (errno, &mystrerrbuf[0]));
        break;
        }
      pinbuf += rcread;
      numtoberead -= (unsigned int) rcread;
      pjob->buflvl1 += (unsigned int) rcread;
      if (gotTheCompleteHttpRequest (pjob->pbuf1, pjob->buflvl1) != 0)
        /* This is usually the case. */
        break;
      }
    if (atomicallyLoadsTerminateExecution () != 0) {
      if (atomicallyLoadsTerminateExecution () >= 2)
        goto label_barrierallminus1;
      (void) writeoutUniversalRejectionResponse (pjob->sfd);
      goto label_close_file_descriptor;
      }
    numwritten = 0;
    /* Adequacy test. */
    if (pjob->buflvl1 > 22 && pjob->buflvl1 < pjob->bufdim - 1) {
      /* Less than `GET / HTTP/1.1\nHost: h\n' is not possible.
         So it has actually been read something from the file descriptor
         and the amount of data is not too large.
         Hence, keep going. */
      *(pjob->pbuf1 + pjob->buflvl1) = '\0';
      pjob->rank = rank;
      (void) httpServer (pjob, &mystrerrbuf[0]);
      /* Write now. */
      poutbuf = pjob->pbuf1;
      numtobewritten = pjob->buflvl1;
      while (numtobewritten > 0) {
        rcwrite = send (pjob->sfd, poutbuf, (size_t) numtobewritten,
                         MSG_DONTWAIT | MSG_NOSIGNAL);
        if (rcwrite > (ssize_t) numtobewritten) {
          (void) fprintf (stderr, "workerMainLoad: send: "
                           "Unrecoverable error.\n");
          (void) atomicallyStoresTwoToTerminateExecution ();
          goto label_barrierallminus1;
          }
        if (rcwrite < 0) {
          if (debugglobal > 0)
            (void) printf ("Main load worker %03u: send: %s.\n",
                            rank, myStrError (errno, &mystrerrbuf[0]));
          break;
          }
        if (rcwrite == 0)
          break;
        poutbuf += rcwrite;
        numtobewritten -= (unsigned int) rcwrite;
        numwritten += (unsigned int) rcwrite;
        }
      if (numwritten != pjob->buflvl1)
        if (debugglobal > 0)
          (void) printf ("Main load worker %03u: send: "
                          "Not all bytes have been written.\n", rank);
      }
    if (numwritten == 0)
      /* Nothing written so far. */
      if (atomicallyLoadsTerminateExecution () < 2)
        /* Now yes. */
        (void) writeoutUniversalRejectionResponse (pjob->sfd);
    if (atomicallyLoadsTerminateExecution () == 0 && debugglobal > 2)
      /* The work is done. At this point of full resource occupancy,
         sleep some time to offer the opportunity to study in slow motion
         how the present server would behave under heavy load, where the
         latter, under such conditions, can be be generated by a single
         client computer. */
      (void) sleepMilliSecs (statelocatorlifetimeglobal * 1000 >> 4,
                              &mystrerrbuf[0]);
    if (atomicallyLoadsTerminateExecution () >= 2)
      goto label_barrierallminus1;
    /***** LABEL *****/ label_close_file_descriptor:
    if (pjob->sfd >= 0)
      if (close (pjob->sfd) != 0)
        if (debugglobal > 0)
          (void) printf ("Main load worker %03u: close: %s.\n",
                          rank, myStrError (errno, &mystrerrbuf[0]));
    if (atomicallyLoadsTerminateExecution () >= 2)
      goto label_barrierallminus1;
    rc = pthread_mutex_lock (&mutexcounternodes1);
    if (rc != 0) {
      (void) fprintf (stderr, "workerMainLoad: pthread_mutex_lock "
                       "(mutexcounternodes1): "
                       "%s.\n", myStrError (rc, &mystrerrbuf[0]));
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_barrierallminus1;
      }
    (void) unregisterIpAddress1 (&pjob->sau);
    rc = pthread_mutex_unlock (&mutexcounternodes1);
    if (rc != 0) {
      (void) fprintf (stderr, "workerMainLoad: pthread_mutex_unlock "
                       "(mutexcounternodes1): "
                       "%s.\n", myStrError (rc, &mystrerrbuf[0]));
      /* We cannot do more than pray. */
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_barrierallminus1;
      }
    pjob->buflvl1 = 0;
    pjob->buflvl2 = 0;
    pjob->buflvl3 = 0;
    pjob->rank = 0xffffffff;
    pjob->slot = 0xffffffff;
    pjob->sfd = -1;
    (void) memset (&pjob->sau, 0, sizeof (sau_t));
    if (atomicallyLoadsTerminateExecution () >= 2)
      goto label_barrierallminus1;
    rc = pthread_mutex_lock (&mutexfreejobchain);
    if (rc != 0) {
      (void) fprintf (stderr, "workerMainLoad: pthread_mutex_lock "
                       "(mutexfreejobchain): "
                       "%s.\n", myStrError (rc, &mystrerrbuf[0]));
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_barrierallminus1;
      }
    /* Begin of chaining in on the left side. */
    pjob->left = 0;
    if (pfreejobchainfirst == 0) {
        pfreejobchainlast = pjob;
        pjob->right = 0;
        }
      else {
        pfreejobchainfirst->left = pjob;
        pjob->right = pfreejobchainfirst;
        }
    pfreejobchainfirst = pjob;
    /* End of chaining in on the left side. */
    rc = pthread_mutex_unlock (&mutexfreejobchain);
    if (rc != 0) {
      (void) fprintf (stderr, "workerMainLoad: pthread_mutex_unlock "
                       "(mutexfreejobchain): "
                       "%s.\n", myStrError (rc, &mystrerrbuf[0]));
      /* We cannot do more than pray. */
      (void) atomicallyStoresTwoToTerminateExecution ();
      goto label_barrierallminus1;
      }
    }
  /***** LABEL *****/ label_barrierallminus1:
  if ((debugglobal > 0 && rank == 0) || debugglobal > 1)
    (void) printf ("Main load worker %03u: "
                    "Arrived at `barrierallminus1'.\n", rank);
  (void) flushOutStreams ();
  /* Wait for the worker majority to be in front of their termination. */
  rc = pthread_barrier_wait (&barrierallminus1);
  if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
    (void) fprintf (stderr, "workerMainLoad: "
                     "pthread_barrier_wait (barrierallminus1): "
                     "%s.\n", myStrError (rc, &mystrerrbuf[0]));
    /* This is more or less pure actionism here. If something bad
       happened at this point, we typically got stuck in the barrier. */
    (void) atomicallyStoresTwoToTerminateExecution ();
    goto label_exit;
    }
  if ((debugglobal > 0 && rank == 0) || debugglobal > 1)
    (void) printf ("Main load worker %03u: "
                    "Passed `barrierallminus1'.\n", rank);
  /***** LABEL *****/ label_exit:
  (void) flushOutStreams ();
  (void) pthread_exit (&rcexit);
  /* Never reached. */
  return (0);
  }

/****************************************************************************/

static void
writeoutBufferToDisk (unsigned char *p, unsigned int n)
{
  char accfilename [sizeof (accfilenamestem) /
                    sizeof (accfilenamestem[0]) + 10];
  unsigned char *pw, *bw;
  int fdio;
  ssize_t rcwrite;

  if (n == 0)
    return;
  pw = (unsigned char *) &accfilename[0];
  bw = pw + sizeof (accfilename) / sizeof (accfilename[0]);
  pw = w (pw, bw, &accfilenamestem[0]);
  if (*(p + 10) != 'T') {
    (void) fprintf (stderr, "writeoutBufferToDisk: Unrecoverable error 1.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  *(p + 10) = '\0';
  if ((unsigned char *) strchr ((char *) p, '\0') != p + 10) {
    (void) fprintf (stderr, "writeoutBufferToDisk: Unrecoverable error 2.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  pw = w (pw, bw, (char *) p);
  *(p + 10) = 'T';
  if (pw == bw) {
    (void) fprintf (stderr, "writeoutBufferToDisk: Unrecoverable error 3.\n");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  fdio = open (&accfilename[0], O_WRONLY | O_APPEND | O_CREAT,
                S_IRUSR | S_IWUSR);
  if (fdio == -1) {
    (void) perror ("writeoutBufferToDisk: open");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  while ((rcwrite = write (fdio, p, (size_t) n)) > 0) {
    if (rcwrite > (ssize_t) n) {
      (void) fprintf (stderr, "writeoutBufferToDisk: "
                       "Unrecoverable error 4.\n");
      if (close (fdio) != 0)
        (void) perror ("writeoutBufferToDisk: close 1");
      (void) atomicallyStoresTwoToTerminateExecution ();
      return;
      }
    if (rcwrite == (ssize_t) n)
      break;
    p += rcwrite;
    n -= (unsigned int) rcwrite;
    }
  if (rcwrite < 0) {
    (void) perror ("writeoutBufferToDisk: write");
    if (close (fdio) != 0)
      (void) perror ("writeoutBufferToDisk: close 2");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  if (close (fdio) != 0) {
    (void) perror ("writeoutBufferToDisk: close 3");
    (void) atomicallyStoresTwoToTerminateExecution ();
    return;
    }
  return;
  }

/****************************************************************************/

static void
writeoutUniversalRejectionResponse (int fd)
{
  unsigned char *buf;
  size_t count;

  buf = &universalrejectionresponse[0];
  count = universalrejectionresponsesize;
  /* We ignore the return code here. */
  (void) send (fd, buf, count, MSG_DONTWAIT | MSG_NOSIGNAL);
  return;
  }

/****************************************************************************/


Stephan K.H. Seidl