/*
 *  eval_input_alda.c - Part of AFD, an automatic file distribution program.
 *  Copyright (c) 2007 - 2025 Holger Kiehl <Holger.Kiehl@dwd.de>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "afddefs.h"

DESCR__S_M3
/*
 ** NAME
 **   eval_input_alda - checks syntax of input for process alda
 **
 ** SYNOPSIS
 **   void eval_input_alda(int *argc, char *argv[])
 **
 ** DESCRIPTION
 **   This module checks whether the syntax is correct. The syntax is as
 **   follows:
 **           alda [options] <file name pattern>
 **
 **   Mode options
 **           -c                           continuous
 **           -C                           continuous daemon
 **           -l                           local log data
 **           -r                           remote log data
 **           -b                           back trace data
 **           -f                           forward trace data
 **   Range parameters
 **           -s <AFD host name/alias/ID>  Starting AFD hostname/alias/ID.
 **           -e <AFD host name/alias/ID>  Ending AFD hostname/alias/ID.
 **           -t <start>[-<end>]           Time frame at starting point.
 **           -T <start>[-<end>]           Time frame at end point.
 **           -L <log type>                Search only in given log type.
 **                                        Log type can be:
 **                                          I - Input Log
 **                                          U - Distribution Log
 **                                          P - Production Log
 **                                          C - Output Log confirmed
 **                                          R - Output Log retrieved
 **                                          O - Output Log delivered
 **                                          D - Delete Log
 **                                        Default: IUPOD
 **           -g <time in seconds>         Maximum time to search for
 **                                        a single file before giving up.
 **           -G <time in minutes>         Maximum time we may search for
 **                                        all files.
 **   Format parameter
 **           -o <format>                  Specifies the output format.
 **                                        Possible format parameters
 **                                        are as listed:
 **              -- Input log data --
 **              %[Z]IT<time char>      - input time
 **              %[Y]IF                 - input file name
 **              %[X]IS<size char>      - input file size
 **              %[Z]II                 - input source ID
 **              %[Y]IN                 - full source name
 **              %[Z]IU                 - unique number
 **              -- Distribution log data --
 **              %[Z]Ut<time char>      - distribution time
 **              %[Z]UT<time char>      - input time
 **              %[Y]UF                 - input file name
 **              %[X]US<size char>      - input file size
 **              %[Z]UI                 - input source ID
 **              %[Z]UU                 - unique number
 **              %[Z]Un                 - number of jobs distributed
 **              %[Z]Uj<separator char> - list of job ID's
 **              %[Z]Uc<separator char> - list of number of pre-processing
 **              %[Z]UY                 - distribution type
 **              -- Production log data --
 **              %[Z]Pt<time char>      - time when production starts
 **              %[Z]PT<time char>      - time when production finished
 **              %[X]PD<duration char>  - production time (duration)
 **              %[X]Pu<duration char>  - CPU usage
 **              %[Z]Pb                 - ratio relationship 1
 **              %[Z]PB                 - ratio relationship 2
 **              %[Z]PJ                 - job ID
 **              %[Z]PZ<time char>      - job creation time
 **              %[Z]PU                 - unique number
 **              %[Z]PL                 - split job number
 **              %[Y]Pf                 - input file name
 **              %[X]Ps<size char>      - input file size
 **              %[Y]PF                 - produced file name
 **              %[X]PS<size char>      - produced file size
 **              %[Y]PC                 - command executed
 **              %[Z]PR                 - return code of command executed
 **              -- Output log data --
 **              %[Z]Ot<time char>      - time when sending starts
 **              %[Z]OT<time char>      - time when file is transmitted
 **              %[X]OD<duration char>  - time taken to transmit file
 **              %[Y]Of                 - local output file name
 **              %[Y]OF                 - remote output file name/directory
 **              %[Y]OE                 - final output file name/directory
 **              %[Z]Op                 - protocol ID used for transmission
 **              %[Y]OP                 - protocol used for transmission
 **              %[X]OS<size char>      - output file size
 **              %[Z]OJ                 - job ID
 **              %[Z]Oe                 - number of retries
 **              %[Y]OA                 - archive directory
 **              %[Z]OZ<time char>      - job creation time
 **              %[Z]OU                 - unique number
 **              %[Z]OL                 - split job number
 **              %[Y]OM                 - mail queue ID
 **              %[Y]Oh                 - target real hostname/IP
 **              %[Y]OH                 - target alias name
 **              %[Y]OR                 - Recipient of job
 **              %[Z]Oo                 - output type ID
 **              %[Y]OO                 - output type string
 **              -- Delete log data --
 **              %[Z]Dt<time char>      - time when job was created
 **              %[Z]DT<time char>      - time when file was deleted
 **              %[Z]Dr                 - delete reason ID
 **              %[Y]DR                 - delete reason string
 **              %[Y]DW                 - user/program causing deletion
 **              %[Y]DA                 - additional reason
 **              %[Z]DZ<time char>      - job creation time
 **              %[Z]DU                 - unique number
 **              %[Z]DL                 - split job number
 **              %[Y]DF                 - file name of deleted file
 **              %[X]DS<size char>      - file size of deleted file
 **              %[Z]DJ                 - job ID of deleted file
 **              %[Z]DI                 - input source ID
 **              %[Y]DN                 - full source name
 **              %[Y]DH                 - target alias name
 **              -- AFD information --
 **              %[Y]Ah                 - AFD real hostname/IP
 **              %[Y]AH                 - AFD alias name
 **              %[Y]AV                 - AFD version
 **
 **               [X] -> [-][0]#[.#]] or [-][0]#[d|o|x]
 **               [Y] -> [-]# or [<individual character positions>]
 **               [Z] -> [-][0]#[d|o|x]
 **
 **            (used second chars: AbBcCDeEfFhHIJjLNnpOoPrRsStTuUWYZ)
 **
 **            Time character (t,T):
 **                 a - Abbreviated weekday name: Tue
 **                 A - Full weekday name: Tuesday
 **                 b - Abbreviated month name: Jan
 **                 B - Full month name: January
 **                 c - Date and time: Tue Jan 19 16:24:50 1999
 **                 d - Day of the month [01 - 31]: 19
 **                 H - Hour of the 24-hour day [00 - 23]: 16
 **                 I - Hour of the 24-hour day [00 - 12]: 04
 **                 j - Day of the year [001 - 366]: 19
 **                 m - Month [01 - 12]: 01
 **                 M - Minute [00 - 59]: 24
 **                 p - AM/PM: PM
 **                 S - Second [00 - 61]: 50
 **             (*) u - Unix time: 916759490
 **                 U - Sunday week number [00 - 53]: 02
 **                 w - Weekday [0 - 6] (0=Sunday): 2
 **                 W - Monday week number [00 - 53]: 02
 **                 X - Time: 16:24:50
 **                 y - Year without centry [00 - 99]: 99
 **                 Y - Year with centry: 1999
 **                 Z - Time zone name: CET
 **            Duration character (D,u):
 **                 A - Automatic shortes format: 4d
 **                             d - days
 **                             h - hours
 **                             m - minutes
 **                             s - seconds
 **             (*) D - Days only : 4
 **             (*) H - Hours only : 102
 **             (*) M - Minutes only: 6144
 **             (*) S - Seconds only: 368652
 **                 X - Time (h:mm:ss): 102:24:12
 **                 Y - Time (d:hh:mm): 4:06:24
 **            Size character (S):
 **             (#) a - Automatic shortes format: 1 GB
 **                             B  - byte
 **                             KB - kilobyte (10^3)
 **                             MB - megabyte (10^6)
 **                             GB - gigabyte (10^9)
 **                             TB - terabyte (10^12)
 **                             PB - petabyte (10^15)
 **                             EB - exabyte  (10^18)
 **             (#) A - Automatic shortes format: 1 GiB
 **                             B   - byte
 **                             KiB - kibibyte (2^10)
 **                             MiB - mebibyte (2^20)
 **                             GiB - gibibyte (2^30)
 **                             TiB - tebibyte (2^40)
 **                             PiB - pebibyte (2^50)
 **                             EiB - exbibyte (2^60)
 **             (#) B - Bytes only: 1884907510
 **             (#) e - Exabyte only : 0
 **             (#) E - Exbibyte only: 0
 **             (#) g - Gigabyte only: 1
 **             (#) G - Gibibyte only: 1
 **             (#) k - Kilobyte only: 1884907
 **             (#) K - Kibibyte only: 1840729
 **             (#) m - Megabyte only: 1884
 **             (#) M - Mebibyte only: 1797
 **             (#) p - Petabyte only: 0
 **             (#) P - Pebibyte only: 0
 **             (#) t - Terabyte only: 0
 **             (#) T - Tebibyte only: 0
 **
 **            (*) Can be printed as decimal (d), octal (o) or hexadecimal (x)
 **            (#) Can be printed as numeric string with decimal point
 **                                      OR
 **                Can be printed as decimal (d), octal (o) or hexadecimal (x)
 **   Search parameters
 **           -d <directory name/alias/ID> Directory name, alias or ID.
 **           -h <host name/alias/ID>      Host name, alias or ID.
 **           -j <job ID>                  Job identifier.
 **           -u <unique number>           Unique number.
 **           -z <size>                    Original file size in byte.
 **                                        (Production log only!)
 **           -S[I|U|P|O|D] <size>         File size in byte.
 **           -D[P|O] <time>               Duration in seconds.
 **           -p <protocol>                Protocol used for transport.
 **   Other parameters
 **           -F <file name>               Footer to add to output.
 **           -R <x>                       Rotate log x times.
 **           -H <file name>               Header to add to output.
 **           -O <file name>               File where to write output.
 **           -v[v[v[v[v[v]]]]]            Verbose mode.
 **           -w <work dir>                Working directory of the AFD.
 **           --header_line=<line>         Add the given header line to
 **                                        output. The following
 **                                        % parameters can be used to
 **                                        insert additional system
 **                                        infomation:
 **                                          %I - inode number of the log file
 **                                          %H - host ID
 **
 **   To be able to differentiate between name, alias and ID:
 **       alias - must always begin with %
 **       ID    - must always begin with #
 **       name  - just the name without extra identifier
 **
 ** RETURN VALUES
 **   If any of the above parameters have been specified it returns
 **   them in the appropriate variable.
 **
 ** AUTHOR
 **   H.Kiehl
 **
 ** HISTORY
 **   15.04.2007 H.Kiehl Created
 **   04.05.2024 H.Kiehl Setup umask so we do not create log files wih
 **                      mode 666.
 **   19.03.2025 H.Kiehl Add --header_line=<line> parameter to add
 **                      a header line with additional system information.
 **
 */
DESCR__E_M3

#include <stdio.h>          /* stderr, fprintf(), fopen()                */
#include <string.h>         /* strerror(), strcpy()                      */
#include <stdlib.h>         /* exit()                                    */
#include <time.h>           /* time()                                    */
#include <ctype.h>          /* isdigit()                                 */
#include <sys/stat.h>       /* umask()                                   */
#include <unistd.h>         /* access()                                  */
#include <errno.h>
#include "aldadefs.h"
#ifdef WITH_AFD_MON
# include "mondefs.h"
#endif

#define START_HOST_TYPE  1
#define END_HOST_TYPE    2
#define SEARCH_DIR_TYPE  3
#define SEARCH_HOST_TYPE 4
#define ALIAS_TYPE       5
#define ID_TYPE          6
#define NAME_TYPE        7
#define START_TIME_TYPE  8
#define END_TIME_TYPE    9

#define ADDITIONAL_EXTRA_LENGTH 16


/* External global variables. */
extern unsigned int end_alias_counter,
                    *end_id,
                    end_id_counter,
                    end_name_counter,
                    file_pattern_counter,
                    mode,
                    protocols,
                    search_dir_alias_counter,
                    *search_dir_id,
                    search_dir_id_counter,
                    search_dir_name_counter,
                    search_duration_flag,
                    search_file_size_flag,
                    search_orig_file_size_flag,
                    search_host_alias_counter,
                    *search_host_id,
                    search_host_id_counter,
                    search_host_name_counter,
                    search_job_id,
                    search_unique_number,
                    search_log_type,
#ifdef _OUTPUT_LOG
                    show_output_type,
#endif
                    start_alias_counter,
                    *start_id,
                    start_id_counter,
                    start_name_counter;
extern int          gt_lt_sign,
                    gt_lt_sign_duration,
                    gt_lt_sign_orig,
                    no_of_header_lines,
                    rotate_limit,
                    trace_mode,
                    verbose;
extern time_t       end_time_end,
                    end_time_start,
                    max_diff_time,
                    max_search_time,
                    start_time_end,
                    start_time_start;
extern off_t        search_file_size,
                    search_orig_file_size;
extern double       search_duration;
extern char         **end_alias,
                    **end_name,
                    **file_pattern,
                    footer_filename[],
                    *format_str,
                    header_filename[],
                    **header_line,
                    output_filename[],
                    **search_dir_alias,
                    **search_dir_name,
                    **search_host_alias,
                    **search_host_name,
                    **start_alias,
                    **start_name;
extern FILE         *output_fp;

/* Local function prototypes. */
static int          eval_time(char *, int, time_t),
                    get_time_value(char *, char **, time_t),
                    insert_line(char ***, const char *, size_t),
                    store_protocols(char *);
static void         store_name_alias_id(char *, int),
                    usage(char *);


/*########################## eval_input_alda() ##########################*/
void
eval_input_alda(int *argc, char *argv[])
{
   int    correct = YES;               /* Was input/syntax correct?      */
   time_t now;
   char   *progname;

   progname = argv[0];
   now = time(NULL);
   max_search_time = 0L;
   max_diff_time = DEFAULT_MAX_DIFF_TIME;
   start_time_start = 0;
   start_time_end = 0;
   end_time_start = 0;
   end_time_end = 0;
   protocols = 0;
   mode = 0;
   output_filename[0] = '\0';
   rotate_limit = DEFAULT_ROTATE_LIMIT;
   header_filename[0] = '\0';
   footer_filename[0] = '\0';
   verbose = 0;

   argv++;
   (*argc)--;
   if ((*argc > 0) && (argv[0][0] == '-'))
   {
      while ((*argc > 0) && ((*argv)[0] == '-'))
      {
         switch (*(argv[0] + 1))
         {
            /*
             * Mode parameters
             * ===============
             */
            case 'c' : /* Continuous mode. */
               mode |= ALDA_CONTINUOUS_MODE;
               (*argc)--;
               argv++;
               break;

            case 'C' : /* Continuous daemon mode. */
               mode |= ALDA_CONTINUOUS_DAEMON_MODE;
               (*argc)--;
               argv++;
               break;

            case 'l' : /* Local mode. */
               mode |= ALDA_LOCAL_MODE;
               (*argc)--;
               argv++;
               break;

            case 'r' : /* Remote mode. */
#ifdef WITH_AFD_MON
               mode |= ALDA_REMOTE_MODE;
#else
               (void)fprintf(stderr,
                             "ERROR  : This code has not been compiled for remote mode.\n");
               (void)fprintf(stderr,
                             "         Please configure with --enable-afd_mon or\n");
               (void)fprintf(stderr,
                             "         --enable-compile_afd_mon_only and recompile.\n");
               correct = NO;
#endif
               (*argc)--;
               argv++;
               break;

            case 'b' : /* Back trace data. */
               mode |= ALDA_BACKWARD_MODE;
               (*argc)--;
               argv++;
               break;

            case 'f' : /* Forward trace data. */
               mode |= ALDA_FORWARD_MODE;
               (*argc)--;
               argv++;
               break;

            /*
             * Range parameters
             * ================
             */
            case 's' : /* Starting AFD hostname/alias/ID. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No starting AFD hostname/alias/ID specified for parameter -s.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  store_name_alias_id(*(argv + 1), START_HOST_TYPE);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'e' : /* Ending AFD hostname/alias/ID. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No ending AFD hostname/alias/ID specified for parameter -s.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  store_name_alias_id(*(argv + 1), END_HOST_TYPE);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 't' : /* Time frame at starting point. */
               if ((*argc == 1) ||
                   ((*(argv + 1)[0] == '-') &&
                    ((isdigit((int)(*((argv + 1)[0] + 1))) == 0) ||
                     (*((argv + 1)[0] + 2) == '\0'))))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No time frame specified for parameter -t.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  if (eval_time(*(argv + 1), START_TIME_TYPE, now) != SUCCESS)
                  {
                     correct = NO;
                  }
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'T' : /* Time frame at ending point. */
               if ((*argc == 1) ||
                   ((*(argv + 1)[0] == '-') &&
                    ((isdigit((int)(*((argv + 1)[0] + 1))) == 0) ||
                     (*((argv + 1)[0] + 2) == '\0'))))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No time frame specified for parameter -T.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  if (eval_time(*(argv + 1), END_TIME_TYPE, now) != SUCCESS)
                  {
                     correct = NO;
                  }
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'L' : /* Search only in given log type. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No log type specified for parameter -L.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  int i;

                  search_log_type = 0;
#ifdef _OUTPUT_LOG
                  show_output_type = 0;
#endif
                  i = 0;
                  do
                  {
                     switch ((*(argv + 1))[i])
                     {
#ifdef _INPUT_LOG
                        case 'I' : /* Input log. */
                           search_log_type |= SEARCH_INPUT_LOG;
                           break;
#endif
#ifdef _DISTRIBUTION_LOG
                        case 'U' : /* Distribution log. */
                           search_log_type |= SEARCH_DISTRIBUTION_LOG;
                           break;
#endif
#ifdef _PRODUCTION_LOG
                        case 'P' : /* Production log. */
                           search_log_type |= SEARCH_PRODUCTION_LOG;
                           break;
#endif
#ifdef _OUTPUT_LOG
# if defined(_WITH_DE_MAIL_SUPPORT) && !defined(_CONFIRMATION_LOG)
                        case 'C' : /* Output log confirmation. */
                           search_log_type |= SEARCH_OUTPUT_LOG;
                           show_output_type |= SHOW_CONF_OF_DISPATCH;
                           show_output_type |= SHOW_CONF_OF_RECEIPT;
                           show_output_type |= SHOW_CONF_OF_RETRIEVE;
                           show_output_type |= SHOW_CONF_TIMEUP;
                           break;

# endif
                        case 'R' : /* Output log retrieve. */
                           search_log_type |= SEARCH_OUTPUT_LOG;
                           show_output_type |= SHOW_NORMAL_RECEIVED;
                           break;

                        case 'O' : /* Output log delivered. */
                           search_log_type |= SEARCH_OUTPUT_LOG;
                           show_output_type |= SHOW_NORMAL_DELIVERED;
                           break;
#endif
#ifdef _DELETE_LOG
                        case 'D' : /* Delete log. */
                           search_log_type |= SEARCH_DELETE_LOG;
                           break;
#endif
                     }
                     i++;
                  } while ((*(argv + 1))[i] != '\0');
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'g' : /* Maximum time to search for a single file */
                       /* before giving up.                        */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No seconds specified for parameter -g.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  max_diff_time = (time_t)(str2timet(*(argv + 1), NULL, 10));
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'G' : /* Maximum time we may search for all files. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No minutes specified for parameter -G.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  max_search_time = (time_t)(str2timet(*(argv + 1), NULL, 10) * 60);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            /*
             * Format parameters
             * =================
             */
            case 'o' : /* Specifies the output format. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No output format specified for parameter -o.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  int  length = 0;
                  char *ptr = (argv + 1)[0];

                  if (format_str != NULL)
                  {
                     free(format_str);
                     format_str = NULL;
                  }
                  while (*(ptr + length) != '\0')
                  {
                     length++;
                  }
                  if ((format_str = malloc(length + 1)) == NULL)
                  {
                     (void)fprintf(stderr,
                                      "ERROR  : Failed to malloc() %d bytes for format string : %s (%s %d)\n",
                                   length + 1, strerror(errno),
                                   __FILE__, __LINE__);
                     correct = NO;
                  }
                  else
                  {
                     length = 0;
                     ptr = (argv + 1)[0];

                     while (*ptr != '\0')
                     {
                        format_str[length] = *ptr;
                        length++; ptr++;
                     }
                     format_str[length] = '\0';
                  }
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            /*
             * Search parameters
             * =================
             */
            case 'd' : /* Directory name/alias/ID. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No directory name/alias/ID specified for parameter -d.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  store_name_alias_id(*(argv + 1), SEARCH_DIR_TYPE);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'h' : /* Host name/alias/ID. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No host name/alias/ID specified for parameter -h.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  store_name_alias_id(*(argv + 1), SEARCH_HOST_TYPE);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'j' : /* Job identifier. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No job ID specified for parameter -j.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  search_job_id = (unsigned int)strtoul(*(argv + 1), NULL, 16);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'u' : /* Unique number. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No unique number specified for parameter -u.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  search_unique_number = (unsigned int)strtoul(*(argv + 1), NULL, 16);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'z' : /* Original file size (production only!) in byte. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No size specified for parameter -s.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  char *ptr;

                  search_orig_file_size_flag = SEARCH_PRODUCTION_LOG;
                  ptr = *(argv + 1);
                  if (*ptr == '<')
                  {
                     gt_lt_sign_orig = LESS_THEN_SIGN;
                     ptr++;
                  }
                  else if (*ptr == '>')
                       {
                          gt_lt_sign_orig = GREATER_THEN_SIGN;
                          ptr++;
                       }
                  else if (*ptr == '!')
                       {
                          gt_lt_sign_orig = NOT_SIGN;
                          ptr++;
                       }
                       else
                       {
                          gt_lt_sign_orig = EQUAL_SIGN;
                          if (*ptr == '=')
                          {
                             ptr++;
                          }
                       }
                  search_orig_file_size = (unsigned int)strtoul(ptr, NULL, 10);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'S' : /* File size in byte. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No size specified for parameter -S.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  char *ptr;

                  switch (*(argv[0] + 2))
                  {
#ifdef _INPUT_LOG
                     case 'I' : /* Input */
                        search_file_size_flag = SEARCH_INPUT_LOG;
                        break;
#endif
#ifdef _DISTRIBUTION_LOG
                     case 'U' : /* Distribution */
                        search_file_size_flag = SEARCH_DISTRIBUTION_LOG;
                        break;
#endif
#ifdef _PRODUCTION_LOG
                     case 'P' : /* Production */
                        search_file_size_flag = SEARCH_PRODUCTION_LOG;
                        break;
#endif
#ifdef _OUTPUT_LOG
                     case 'O' : /* Output */
                        search_file_size_flag = SEARCH_OUTPUT_LOG;
                        break;
#endif
#ifdef _DELETE_LOG
                     case 'D' : /* Delete */
                        search_file_size_flag = SEARCH_DELETE_LOG;
                        break;
#endif
                     default : /* All */
                        search_file_size_flag = SEARCH_ALL_LOGS;
                        break;
                  }

                  ptr = *(argv + 1);
                  if (*ptr == '<')
                  {
                     gt_lt_sign = LESS_THEN_SIGN;
                     ptr++;
                  }
                  else if (*ptr == '>')
                       {
                          gt_lt_sign = GREATER_THEN_SIGN;
                          ptr++;
                       }
                       else
                       {
                          gt_lt_sign = EQUAL_SIGN;
                          if (*ptr == '=')
                          {
                             ptr++;
                          }
                       }
                  search_file_size = (unsigned int)strtoul(ptr, NULL, 10);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'D' : /* Duration in seconds. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No duration specified for parameter -D.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  char *ptr;

                  switch (*(argv[0] + 2))
                  {
#ifdef _PRODUCTION_LOG
                     case 'P' : /* Production */
                        search_duration_flag = SEARCH_PRODUCTION_LOG;
                        break;
#endif
#ifdef _OUTPUT_LOG
                     case 'O' : /* Output */
                        search_duration_flag = SEARCH_OUTPUT_LOG;
                        break;
#endif
                     default : /* All */
                        search_duration_flag = SEARCH_ALL_LOGS;
                        break;
                  }

                  ptr = *(argv + 1);
                  if (*ptr == '<')
                  {
                     gt_lt_sign_duration = LESS_THEN_SIGN;
                     ptr++;
                  }
                  else if (*ptr == '>')
                       {
                          gt_lt_sign_duration = GREATER_THEN_SIGN;
                          ptr++;
                       }
                  else if (*ptr == '!')
                       {
                          gt_lt_sign_duration = NOT_SIGN;
                          ptr++;
                       }
                       else
                       {
                          gt_lt_sign_duration = EQUAL_SIGN;
                          if (*ptr == '=')
                          {
                             ptr++;
                          }
                       }
                  search_duration = strtod(ptr, NULL);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'p' : /* Protocol used for transport. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No protocol specified for parameter -p.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  if (store_protocols(*(argv + 1)) == INCORRECT)
                  {
                     correct = NO;
                  }
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            /*
             * Other parameters
             * ================
             */
            case 'F' : /* Footer to add to output. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No filename specified for parameter -F.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  if (access(*(argv + 1), R_OK) == 0)
                  {
                     (void)my_strncpy(footer_filename, *(argv + 1),
                                      MAX_PATH_LENGTH);
                  }
                  else
                  {
                     (void)fprintf(stderr,
                                   "ERROR  : Failed to access() %s : %s\n",
                                   *(argv + 1), strerror(errno));
                     correct = NO;
                  }
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'H' : /* Header to add to output. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No filename specified for parameter -H.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  if (access(*(argv + 1), R_OK) == 0)
                  {
                     (void)my_strncpy(header_filename, *(argv + 1), MAX_PATH_LENGTH);
                  }
                  else
                  {
                     (void)fprintf(stderr,
                                   "ERROR  : Failed to access() %s : %s\n",
                                   *(argv + 1), strerror(errno));
                     correct = NO;
                  }
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'O' : /* File where to write output. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No filename specified for parameter -O.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  (void)my_strncpy(output_filename, *(argv + 1),
                                   MAX_PATH_LENGTH);
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'R' : /* Number of times the log should be rotated. */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "ERROR  : No rotate limit specified for parameter -R.\n");
                  correct = NO;
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  rotate_limit = atoi(*(argv + 1));
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case 'v' : /* Verbose mode. */
               while (*(argv[0] + 1 + verbose) == 'v')
               {
                  verbose++;
               }
               if (*(argv[0] + 1 + verbose) != '\0')
               {
                   /* Unknown parameter. */
                   (void)fprintf(stderr,
                                 "ERROR  : Unknown parameter %c. (%s %d)\n",
                                 *(argv[0] + 1), __FILE__, __LINE__);
                   correct = NO;
               }
               (*argc)--;
               argv++;
               break;

            /*
             * NOTE: AFD_WORK_DIR is handled by function get_afd_path()
             *       much earlier. That function cuts away the -w argument
             *       so if we hit it here again it is a second -w argument!
             *       Do not bail out, just give a warning, since it is
             *       common error that users using aldad specify the
             *       working directory as an argument.
             */
            case 'w' : /* Second working directory argument is wrong! */
               if ((*argc == 1) || (*(argv + 1)[0] == '-'))
               {
                  (void)fprintf(stderr,
                                "WARNING: Working directory already set and no working directory specified for parameter -w.\n");
                  (*argc) -= 1;
                  argv += 1;
               }
               else
               {
                  (void)fprintf(stderr,
                                "WARNING: Working directory already set. Ignoring.\n");
                  (*argc) -= 2;
                  argv += 2;
               }
               break;

            case '-' : /* Other parameters starting with --. */
               {
                  char *p_name = &argv[0][2];

                  /* --header_line= */
                  if (strcmp(p_name, "header_line=") != 0)
                  {
                     if (insert_line(&header_line, &argv[0][14],
                                     no_of_header_lines))
                     {
                        no_of_header_lines++;
                     }
                  }
                  (*argc)--;
                  argv++;
                  break;
               }

            default : /* Unknown parameter. */
               (void)fprintf(stderr,
                             "ERROR  : Unknown parameter `%s' [argc=%d] (%s %d)\n",
                             argv[0], *argc, __FILE__, __LINE__);
               (*argc)--;
               argv++;
               correct = NO;
               break;
         }
      }
   }

   if ((correct == NO) ||
       (((mode & ALDA_BACKWARD_MODE) == 0) &&
        ((mode & ALDA_FORWARD_MODE) == 0)))
   {
      usage(progname);
      exit(INCORRECT);
   }

   /* Store file name pattern(s). */
   if (*argc > 0)
   {
      int i,
          length,
          max_length;

      max_length = 0;
      for (i = 0; i < *argc; i++)
      {
        length = 0;
        while (argv[i][length] != '\0')
        {
           length++;
        }
        if (length > max_length)
        {
           max_length = length;
        }
      }
      RT_ARRAY(file_pattern, *argc, (max_length + 1), char);
      for (i = 0; i < *argc; i++)
      {
        length = 0;
        while (argv[i][length] != '\0')
        {
           file_pattern[i][length] = argv[i][length];
           length++;
        }
        file_pattern[i][length] = '\0';
      }
      file_pattern_counter = *argc;
   }
   else
   {
      RT_ARRAY(file_pattern, 1, 2, char);
      file_pattern[0][0] = '*';
      file_pattern[0][1] = '\0';
      file_pattern_counter = 1;
   }

   /* Set default output string if not set. */
   if (format_str == NULL)
   {
      if ((format_str = malloc(DEFAULT_OUTPUT_ALL_FORMAT_LENGTH + 3)) == NULL)
      {
         (void)fprintf(stderr,
                       "ERROR  : Failed to malloc() %d bytes for format string : %s (%s %d)\n",
                       (int)(DEFAULT_OUTPUT_ALL_FORMAT_LENGTH + 3),
                       strerror(errno), __FILE__, __LINE__);
         exit(INCORRECT);
      }
      if (search_log_type == SEARCH_ALL_LOGS)
      {
         (void)strcpy(format_str, DEFAULT_OUTPUT_ALL_FORMAT);
         trace_mode = ON;
      }
#ifdef _INPUT_LOG
      else if (search_log_type == SEARCH_INPUT_LOG)
           {
              (void)strcpy(format_str, DEFAULT_OUTPUT_INPUT_FORMAT);
              trace_mode = OFF;
           }
#endif
#ifdef _DISTRIBUTION_LOG
      else if (search_log_type == SEARCH_DISTRIBUTION_LOG)
           {
              (void)strcpy(format_str, DEFAULT_OUTPUT_DISTRIBUTION_FORMAT);
              trace_mode = OFF;
           }
#endif
#ifdef _PRODUCTION_LOG
      else if (search_log_type == SEARCH_PRODUCTION_LOG)
           {
              (void)strcpy(format_str, DEFAULT_OUTPUT_PRODUCTION_FORMAT);
              trace_mode = OFF;
           }
#endif
#ifdef _OUTPUT_LOG
      else if (search_log_type == SEARCH_OUTPUT_LOG)
           {
              (void)strcpy(format_str, DEFAULT_OUTPUT_OUTPUT_FORMAT);
              trace_mode = OFF;
           }
#endif
#ifdef _DELETE_LOG
      else if (search_log_type == SEARCH_DELETE_LOG)
           {
              (void)strcpy(format_str, DEFAULT_OUTPUT_DELETE_FORMAT);
              trace_mode = OFF;
           }
#endif
           else
           {
              (void)strcpy(format_str, DEFAULT_OUTPUT_ALL_FORMAT);
              trace_mode = ON;
           }
   }
   else
   {
      if (search_log_type == SEARCH_ALL_LOGS)
      {
         trace_mode = ON;
      }
#ifdef _INPUT_LOG
      else if (search_log_type == SEARCH_INPUT_LOG)
           {
              trace_mode = OFF;
           }
#endif
#ifdef _DISTRIBUTION_LOG
      else if (search_log_type == SEARCH_DISTRIBUTION_LOG)
           {
              trace_mode = OFF;
           }
#endif
#ifdef _PRODUCTION_LOG
      else if (search_log_type == SEARCH_PRODUCTION_LOG)
           {
              trace_mode = OFF;
           }
#endif
#ifdef _OUTPUT_LOG
      else if (search_log_type == SEARCH_OUTPUT_LOG)
           {
              trace_mode = OFF;
           }
#endif
#ifdef _DELETE_LOG
      else if (search_log_type == SEARCH_DELETE_LOG)
           {
              trace_mode = OFF;
           }
#endif
           else
           {
              trace_mode = ON;
           }
   }

   /* If no protocol is set, assume we want all protocols. */
   if (protocols == 0)
   {
      protocols = ~0u;
   }

   /* Check if all neccessary mode flags have been set, otherwise set them. */
   if (((mode & ALDA_LOCAL_MODE) == 0) && ((mode & ALDA_REMOTE_MODE) == 0))
   {
      mode |= ALDA_LOCAL_MODE;
   }
   if (((mode & ALDA_BACKWARD_MODE) == 0) && ((mode & ALDA_FORWARD_MODE) == 0))
   {
      mode |= ALDA_FORWARD_MODE;
   }

   /* Check if the time values are initilized. */
   if (end_time_start == 0)
   {
      end_time_start = now;
   }
   if (end_time_end == 0)
   {
      end_time_end = now;
   }

   if (output_filename[0] == '\0')
   {
      output_fp = stdout;
   }
   else
   {
      /*
       * Set umask so that all log files have the permission 644.
       * If we do not set this here fopen() will create files with
       * permission 666 according to POSIX.1.
       */
#ifdef GROUP_CAN_WRITE
      (void)umask(S_IWOTH);
#else
      (void)umask(S_IWGRP | S_IWOTH);
#endif

      if ((output_fp = fopen(output_filename, "a")) == NULL)
      {
         (void)fprintf(stderr, "Failed to fopen() `%s' : %s (%s %d)\n",
                       output_filename, strerror(errno), __FILE__, __LINE__);
         exit(INCORRECT);
      }
   }

   return;
}


/*++++++++++++++++++++++++ store_name_alias_id() ++++++++++++++++++++++++*/
static void
store_name_alias_id(char *input, int dir_host_type)
{
   unsigned int *p_alias_counter = NULL,
                **p_id = NULL, /* Silence compiler. */
                *p_id_counter = NULL,
                *p_name_counter = NULL;
   int          length,
                max_length = 0,
                max_alias_length = 0,
                max_id_length = 0,
                max_name_length = 0,
                type = NAME_TYPE;
   char         ***p_alias = NULL, /* Silence compiler. */
                ***p_name = NULL,  /* Silence compiler. */
                *ptr;

   /* Count number of parameters. */
   ptr = input;
   do
   {
      if (*ptr == '%')
      {
         ptr++;
         if (p_alias_counter == NULL)
         {
            if (dir_host_type == START_HOST_TYPE)
            {
               max_length = MAX_AFDNAME_LENGTH + 1;
               p_alias = &start_alias;
               p_alias_counter = &start_alias_counter;
            }
            else if (dir_host_type == END_HOST_TYPE)
                 {
                    max_length = MAX_AFDNAME_LENGTH + 1;
                    p_alias = &end_alias;
                    p_alias_counter = &end_alias_counter;
                 }
            else if (dir_host_type == SEARCH_HOST_TYPE)
                 {
                    max_length = MAX_HOSTNAME_LENGTH + ADDITIONAL_EXTRA_LENGTH + 1;
                    p_alias = &search_host_alias;
                    p_alias_counter = &search_host_alias_counter;
                 }
                 else
                 {
                    max_length = MAX_DIR_ALIAS_LENGTH + ADDITIONAL_EXTRA_LENGTH + 1;
                    p_alias = &search_dir_alias;
                    p_alias_counter = &search_dir_alias_counter;
                 }
            *p_alias_counter = 0;
            max_alias_length = 0;
            type = ALIAS_TYPE;
         }
      }
      else if (*ptr == '#')
           {
              ptr++;
              if (p_id_counter == NULL)
              {
                 if (dir_host_type == START_HOST_TYPE)
                 {
                    p_id = &start_id;
                    p_id_counter = &start_id_counter;
                 }
                 else if (dir_host_type == END_HOST_TYPE)
                      {
                         p_id = &end_id;
                         p_id_counter = &end_id_counter;
                      }
                 else if (dir_host_type == SEARCH_HOST_TYPE)
                      {
                         p_id = &search_host_id;
                         p_id_counter = &search_host_id_counter;
                      }
                      else
                      {
                         p_id = &search_dir_id;
                         p_id_counter = &search_dir_id_counter;
                      }
                 *p_id_counter = 0;
                 max_length = MAX_INT_LENGTH;
                 max_id_length = 0;
                 type = ID_TYPE;
              }
           }
           else
           {
              if (*ptr == '\\')
              {
                 ptr++;
              }
              if (p_name_counter == NULL)
              {
                 if (dir_host_type == START_HOST_TYPE)
                 {
                    max_length = MAX_REAL_HOSTNAME_LENGTH;
                    p_name = &start_name;
                    p_name_counter = &start_name_counter;
                 }
                 else if (dir_host_type == END_HOST_TYPE)
                      {
                         max_length = MAX_REAL_HOSTNAME_LENGTH;
                         p_name = &end_name;
                         p_name_counter = &end_name_counter;
                      }
                 else if (dir_host_type == SEARCH_HOST_TYPE)
                      {
                         max_length = MAX_REAL_HOSTNAME_LENGTH;
                         p_name = &search_host_name;
                         p_name_counter = &search_host_name_counter;
                      }
                      else
                      {
                         max_length = MAX_PATH_LENGTH;
                         p_name = &search_dir_name;
                         p_name_counter = &search_dir_name_counter;
                      }
                 *p_name_counter = 0;
                 max_name_length = 0;
                 type = NAME_TYPE;
              }
           }

      length = 0;
      do
      {
         if (*(ptr + length) == '\\')
         {
            ptr++;
         }
         length++;
      } while ((length < max_length) &&
               (*(ptr + length) != ',') && (*(ptr + length)  != '\0'));

      ptr += length;
      if (length >= max_length)
      {
         char *p_start = ptr - length,
              *tmp_ptr;

         while ((p_start >= input) && (*p_start != ',') &&
                ((p_start - 1) >= input) && (*(p_start - 1) != '\\'))
         {
            if (p_start == input)
            {
               break;
            }
            p_start--;
         }
         while ((*ptr != ',') && (*ptr != '\0'))
         {
            if (*ptr == '\\')
            {
               ptr++;
            }
            ptr++;
         }
         if (*ptr == ',')
         {
            *ptr = '\0';
            tmp_ptr = ptr;
         }
         else
         {
            tmp_ptr = NULL;
         }
         (void)fprintf(stderr,
                       "WARNING: Ignoring %s since it may only be %d bytes long.\n",
                       p_start, max_length);
         if (tmp_ptr != NULL)
         {
            *tmp_ptr = ',';
         }
      }
      else
      {
         if (type == ALIAS_TYPE)
         {
            if (length > max_alias_length)
            {
               max_alias_length = length;
            }
            (*p_alias_counter)++;
         }
         else if (type == ID_TYPE)
              {
                 if (length > max_id_length)
                 {
                    max_id_length = length;
                 }
                 (*p_id_counter)++;
              }
              else
              {
                 if (length > max_name_length)
                 {
                    max_name_length = length;
                 }
                 (*p_name_counter)++;
              }
      }
      if (*ptr == ',')
      {
         ptr++;
         length = 0;
      }
   } while (*ptr != '\0');

   /* ALlocate the necessary memory. */
   if (p_alias_counter != NULL)
   {
      RT_ARRAY(*p_alias, (*p_alias_counter), (max_alias_length + 1), char);
      *p_alias_counter = 0;
   }
   if (p_id_counter != NULL)
   {
      if ((*p_id = malloc((*p_id_counter) * sizeof(unsigned int))) == NULL)
      {
         (void)fprintf(stderr,
                       "ERROR  : Failed to malloc() %lu bytes.\n",
                       (long unsigned int)((*p_id_counter) * sizeof(unsigned int)));
      }
      *p_id_counter = 0;
   }
   if (p_name_counter != NULL)
   {
      RT_ARRAY(*p_name, (*p_name_counter), (max_name_length + 1), char);
      *p_name_counter = 0;
   }

   /* Lets store the input in the allocated area. */
   ptr = input;
   do
   {
       if (*ptr == '%')
       {
          ptr++;
       }
       else if (*ptr == '#')
            {
               ptr++;
            }
            else
            {
               if (*ptr == '\\')
               {
                  ptr++;
               }
            }

      length = 0;
      if (type == ALIAS_TYPE)
      {
         do
         {
            if (*(ptr + length) == '\\')
            {
               ptr++;
            }
            (*p_alias)[(*p_alias_counter)][length] = *(ptr + length);
            length++;
         } while ((*(ptr + length) != ',') && (*(ptr + length)  != '\0'));
         (*p_alias)[(*p_alias_counter)][length] = '\0';
         (*p_alias_counter)++;
      }
      else if (type == ID_TYPE)
           {
              char *tmp_ptr;

              do
              {
                 length++;
              } while ((*(ptr + length) != ',') && (*(ptr + length)  != '\0'));
              if (*(ptr + length) == ',')
              {
                 tmp_ptr = ptr + length;
                 *tmp_ptr = '\0';
              }
              else
              {
                 tmp_ptr = NULL;
              }
              *p_id[(*p_id_counter)] = (unsigned int)strtoul(ptr, NULL, 16);
              if (tmp_ptr != NULL)
              {
                 *tmp_ptr = ',';
              }
              (*p_id_counter)++;
           }
           else
           {
              do
              {
                 if (*(ptr + length) == '\\')
                 {
                    ptr++;
                 }
                 (*p_name)[(*p_name_counter)][length] = *(ptr + length);
                 length++;
              } while ((*(ptr + length) != ',') && (*(ptr + length)  != '\0'));
              (*p_name)[(*p_name_counter)][length] = '\0';
              (*p_name_counter)++;
           }

      ptr += length;
      if (*ptr == ',')
      {
         ptr++;
         length = 0;
      }
   } while (*ptr != '\0');

   return;
}


/*++++++++++++++++++++++++++ store_protocols() ++++++++++++++++++++++++++*/
static int
store_protocols(char *str_protocols)
{
   int  ret;
   char *p_start,
        *ptr;

   p_start = ptr = str_protocols;
   do
   {
      while ((*ptr != ',') && (*ptr != '\0'))
      {
         ptr++;
      }
      if (*ptr == ',')
      {
         *ptr = '\0';
         ptr++;
      }
      if (my_strcmp(p_start, ALDA_FTP_SHEME) == 0)
      {
         protocols |= ALDA_FTP_FLAG;
      }
      else if (my_strcmp(p_start, ALDA_LOC_SHEME) == 0)
           {
              protocols |= ALDA_LOC_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_EXEC_SHEME) == 0)
           {
              protocols |= ALDA_EXEC_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_SMTP_SHEME) == 0)
           {
              protocols |= ALDA_SMTP_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_DEMAIL_SHEME) == 0)
           {
              protocols |= ALDA_DE_MAIL_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_SFTP_SHEME) == 0)
           {
              protocols |= ALDA_SFTP_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_SCP_SHEME) == 0)
           {
              protocols |= ALDA_SCP_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_HTTP_SHEME) == 0)
           {
              protocols |= ALDA_HTTP_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_HTTPS_SHEME) == 0)
           {
              protocols |= ALDA_HTTPS_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_FTPS_SHEME) == 0)
           {
              protocols |= ALDA_FTPS_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_WMO_SHEME) == 0)
           {
              protocols |= ALDA_WMO_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_MAP_SHEME) == 0)
           {
              protocols |= ALDA_MAP_FLAG;
           }
      else if (my_strcmp(p_start, ALDA_DFAX_SHEME) == 0)
           {
              protocols |= ALDA_DFAX_FLAG;
           }
           else
           {
              (void)fprintf(stderr, "Unknown protocol `%s'.\n", p_start);
              return(INCORRECT);
           }
      p_start = ptr;
   } while (*ptr != '\0');

   if (protocols)
   {
      ret = SUCCESS;
   }
   else
   {
      ret = INCORRECT;
      (void)fprintf(stderr, "No protocol specified. (%s %d)\n",
                    __FILE__, __LINE__);
   }

   return(ret);
}


/*++++++++++++++++++++++++++++ insert_line() +++++++++++++++++++++++++++*/
/*                             -------------                            */
/* Taken from a stackoverflow awnser:                                   */
/*    https://stackoverflow.com/questions/61941666                      */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int
insert_line(char ***root, const char str[], size_t i)
{
   char *p = malloc(strlen(str) + 1);
   int  success = p != NULL;

   if (success)
   {
      char **tmp = realloc(*root, (i + 1) * sizeof(char *));

      if (success)
      {
         (void)strcpy(p, str);
         tmp[i] = p;
         *root = tmp;
      }
      else
      {
         free(p);
      }
   }

   return(success);
}


/*++++++++++++++++++++++++++++ eval_time() ++++++++++++++++++++++++++++++*/
/*                             -----------                               */
/* Syntax is as follows: <start time>[-<end time>]                       */
/* Accepted time formats for <start time> and <end time> are as follows: */
/*     Absolute: MMDDhhmm                                                */
/*               DDhhmm                                                  */
/*               hhmm                                                    */
/*     Relative: -DDhhmm                                                 */
/*               -hhmm                                                   */
/*               -mm                                                     */
/* Where MMDDhhmmss have the following meaning:                          */
/*        MM - The month as a decimal number (range 01 to 12).           */
/*        DD - The day of the month as a decimal number (range 01 to 31).*/
/*        hh - The hour as a decimal number using a 24-hour clock (range */
/*             00 to 23).                                                */
/*        mm - The minute as a decimal number (range 00 to 59).          */
/*        ss - The second as a decimal number (range 00 to 61).          */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static int
eval_time(char *input, int type, time_t now)
{
   time_t value;
   char   *ptr;

   ptr = input;
   value = get_time_value(input, &ptr, now);
   switch (value)
   {
      case INCORRECT : /* Syntax is incorrect. */
         (void)fprintf(stderr, "Time syntax incorrect.\n");
         return(INCORRECT);

      case SUCCESS   : /* No time value, take current time. */
         value = now;
         break;

      default        : /* Some time value is set. */
         break;
   }
   if (type == START_TIME_TYPE)
   {
      start_time_start = value;
   }
   else if (type == END_TIME_TYPE)
        {
           end_time_start = value;
        }

   if (*ptr != '\0')
   {
      value = get_time_value(ptr, NULL, now);
      switch (value)
      {
         case INCORRECT : /* Syntax is incorrect. */
            (void)fprintf(stderr, "Time syntax incorrect.\n");
            return(INCORRECT);

         case SUCCESS   : /* No time value, take current time. */
            value = now;
            break;

         default        : /* Some time value is set. */
            break;
      }
      if (type == START_TIME_TYPE)
      {
         if (value >= start_time_start)
         {
            start_time_end = value;
         }
         else
         {
            (void)fprintf(stderr, "End value must be >= start time.\n");
            return(INCORRECT);
         }
      }
      else if (type == END_TIME_TYPE)
           {
              if (value >= end_time_start)
              {
                 end_time_end = value;
              }
              else
              {
                 (void)fprintf(stderr, "End value must be >= start time.\n");
                 return(INCORRECT);
              }
           }
   }

   return(SUCCESS);
}


/*-------------------------- get_time_value() ---------------------------*/
static int
get_time_value(char *input, char **ret_ptr, time_t now)
{
   int    length,
          max_length;
   time_t value = SUCCESS;
   char   *ptr;

   ptr = input;
   length = 0;
   if (*ptr == '-')
   {
      max_length = 6;
      ptr++;
   }
   else
   {
      max_length = 10;
   }
   while ((*(ptr + length) != '\0') && (*(ptr + length) != '-') &&
          (length < max_length))
   {
      length++;
   }
   if ((length > 0) && (length <= max_length))
   {
      char tmp_char;

      if (*(ptr + length) == '-')
      {
         tmp_char = '-';
         *(ptr + length) = '\0';
      }
      else
      {
         tmp_char = '\0';
      }
      if (max_length == 6)
      {
         if ((!isdigit((int)(*ptr))) || (!isdigit((int)(*(ptr + 1)))))
         {
            *(ptr + length) = tmp_char;
            return(INCORRECT);
         }

         if (length == 2) /* -mm */
         {
            int min;

            min = atoi(ptr);
            if ((min < 0) || (min > 99))
            {
               *(ptr + length) = tmp_char;
               return(INCORRECT);
            }

            value = now - (min * 60);
         }
         else if (length == 4) /* -hhmm */
              {
                 if ((!isdigit((int)(*(ptr + 2)))) ||
                     (!isdigit((int)(*(ptr + 3)))))
                 {
                    *(ptr + length) = tmp_char;
                    return(INCORRECT);
                 }
                 else
                 {
                    int  hour,
                         min;
                    char tmp_char2;

                    tmp_char2 = *(ptr + 2);
                    *(ptr + 2) = '\0';
                    hour = atoi(ptr);
                    *(ptr + 2) = tmp_char2;
                    if ((hour < 0) || (hour > 99))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    min = atoi((ptr + 2));
                    if ((min < 0) || (min > 59))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }

                    value = now - (min * 60) - (hour * 3600);
                 }
              }
         else if (length == 6) /* -DDhhmm */
              {
                 if ((!isdigit((int)(*(ptr + 2)))) ||
                     (!isdigit((int)(*(ptr + 3)))) ||
                     (!isdigit((int)(*(ptr + 4)))) ||
                     (!isdigit((int)(*(ptr + 5)))))
                 {
                    *(ptr + length) = tmp_char;
                    return(INCORRECT);
                 }
                 else
                 {
                    int  day,
                         hour,
                         min;
                    char tmp_char2;

                    tmp_char2 = *(ptr + 2);
                    *(ptr + 2) = '\0';
                    day = atoi(ptr);
                    *(ptr + 2) = tmp_char2;
                    if ((day < 0) || (day > 99))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    tmp_char2 = *(ptr + 4);
                    *(ptr + 4) = '\0';
                    hour = atoi((ptr + 2));
                    *(ptr + 4) = tmp_char2;
                    if ((hour < 0) || (hour > 23))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    min = atoi((ptr + 4));
                    if ((min < 0) || (min > 59))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }

                    value = now - (min * 60) - (hour * 3600) - (day * 86400);
                 }
              }
              else
              {
                 *(ptr + length) = tmp_char;
                 return(INCORRECT);
              }
      }
      else
      {
         if ((!isdigit((int)(*ptr))) || (!isdigit((int)(*(ptr + 1)))) ||
             (!isdigit((int)(*(ptr + 2)))) || (!isdigit((int)(*(ptr + 3)))))
         {
            *(ptr + length) = tmp_char;
            return(INCORRECT);
         }

         if (length == 4) /* hhmm */
         {
            int       hour,
                      min;
            char      tmp_char2;
            struct tm *bd_time;     /* Broken-down time. */

            tmp_char2 = *(ptr + 2);
            *(ptr + 2) = '\0';
            hour = atoi(ptr);
            *(ptr + 2) = tmp_char2;
            if ((hour < 0) || (hour > 23))
            {
               *(ptr + length) = tmp_char;
               return(INCORRECT);
            }
            min = atoi((ptr + 2));
            if ((min < 0) || (min > 59))
            {
               *(ptr + length) = tmp_char;
               return(INCORRECT);
            }
            if ((bd_time = localtime(&now)) == NULL)
            {
               (void)fprintf(stderr, "Failed to determine localtime() : %s (%s %d)\n",
                             strerror(errno), __FILE__, __LINE__);
               *(ptr + length) = tmp_char;
               return(INCORRECT);
            }
            bd_time->tm_sec  = 0;
            bd_time->tm_min  = min;
            bd_time->tm_hour = hour;

            value = mktime(bd_time);
         }
         else if (length == 6) /* DDhhmm */
              {
                 if ((!isdigit((int)(*(ptr + 4)))) ||
                     (!isdigit((int)(*(ptr + 5)))))
                 {
                    *(ptr + length) = tmp_char;
                    return(INCORRECT);
                 }
                 else
                 {
                    int       day,
                              hour,
                              min;
                    char      tmp_char2;
                    struct tm *bd_time;     /* Broken-down time. */

                    tmp_char2 = *(ptr + 2);
                    *(ptr + 2) = '\0';
                    day = atoi(ptr);
                    *(ptr + 2) = tmp_char2;
                    if ((day < 0) || (day > 31))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    tmp_char2 = *(ptr + 4);
                    *(ptr + 4) = '\0';
                    hour = atoi((ptr + 2));
                    *(ptr + 4) = tmp_char2;
                    if ((hour < 0) || (hour > 23))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    min = atoi((ptr + 4));
                    if ((min < 0) || (min > 59))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    if ((bd_time = localtime(&now)) == NULL)
                    {
                       (void)fprintf(stderr, "Failed to determine localtime() : %s (%s %d)\n",
                                     strerror(errno), __FILE__, __LINE__);
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    bd_time->tm_sec  = 0;
                    bd_time->tm_min  = min;
                    bd_time->tm_hour = hour;
                    bd_time->tm_mday = day;

                    value = mktime(bd_time);
                 }
              }
         else if (length == 8) /* MMDDhhmm */
              {
                 if ((!isdigit((int)(*(ptr + 4)))) ||
                     (!isdigit((int)(*(ptr + 5)))) ||
                     (!isdigit((int)(*(ptr + 6)))) ||
                     (!isdigit((int)(*(ptr + 7)))))
                 {
                    *(ptr + length) = tmp_char;
                    return(INCORRECT);
                 }
                 else
                 {
                    int       day,
                              hour,
                              min,
                              month;
                    char      tmp_char2;
                    struct tm *bd_time;     /* Broken-down time. */

                    tmp_char2 = *(ptr + 2);
                    *(ptr + 2) = '\0';
                    month = atoi(ptr);
                    *(ptr + 2) = tmp_char2;
                    if ((month < 0) || (month > 12))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    tmp_char2 = *(ptr + 4);
                    *(ptr + 4) = '\0';
                    day = atoi(ptr + 2);
                    *(ptr + 4) = tmp_char2;
                    if ((day < 0) || (day > 31))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    tmp_char2 = *(ptr + 6);
                    *(ptr + 6) = '\0';
                    hour = atoi((ptr + 4));
                    *(ptr + 6) = tmp_char2;
                    if ((hour < 0) || (hour > 23))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    min = atoi((ptr + 6));
                    if ((min < 0) || (min > 59))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    if ((bd_time = localtime(&now)) == NULL)
                    {
                       (void)fprintf(stderr, "Failed to determine localtime() : %s (%s %d)\n",
                                     strerror(errno), __FILE__, __LINE__);
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    bd_time->tm_sec  = 0;
                    bd_time->tm_min  = min;
                    bd_time->tm_hour = hour;
                    bd_time->tm_mday = day;
                    if ((bd_time->tm_mon == 0) && (month == 12))
                    {
                       bd_time->tm_year -= 1;
                    }
                    bd_time->tm_mon  = month - 1;

                    value = mktime(bd_time);
                 }
              }
         else if (length == 10) /* MMDDhhmmss */
              {
                 if ((!isdigit((int)(*(ptr + 4)))) ||
                     (!isdigit((int)(*(ptr + 5)))) ||
                     (!isdigit((int)(*(ptr + 6)))) ||
                     (!isdigit((int)(*(ptr + 7)))) ||
                     (!isdigit((int)(*(ptr + 8)))) ||
                     (!isdigit((int)(*(ptr + 9)))))
                 {
                    *(ptr + length) = tmp_char;
                    return(INCORRECT);
                 }
                 else
                 {
                    int       day,
                              hour,
                              min,
                              month,
                              second;
                    char      tmp_char2;
                    struct tm *bd_time;     /* Broken-down time. */

                    tmp_char2 = *(ptr + 2);
                    *(ptr + 2) = '\0';
                    month = atoi(ptr);
                    *(ptr + 2) = tmp_char2;
                    if ((month < 0) || (month > 12))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    tmp_char2 = *(ptr + 4);
                    *(ptr + 4) = '\0';
                    day = atoi(ptr + 2);
                    *(ptr + 4) = tmp_char2;
                    if ((day < 0) || (day > 31))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    tmp_char2 = *(ptr + 6);
                    *(ptr + 6) = '\0';
                    hour = atoi((ptr + 4));
                    *(ptr + 6) = tmp_char2;
                    if ((hour < 0) || (hour > 23))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    tmp_char2 = *(ptr + 8);
                    *(ptr + 8) = '\0';
                    min = atoi((ptr + 6));
                    *(ptr + 8) = tmp_char2;
                    if ((min < 0) || (min > 59))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    second = atoi((ptr + 8));
                    if ((second < 0) || (second > 61))
                    {
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    if ((bd_time = localtime(&now)) == NULL)
                    {
                       (void)fprintf(stderr, "Failed to determine localtime() : %s (%s %d)\n",
                                     strerror(errno), __FILE__, __LINE__);
                       *(ptr + length) = tmp_char;
                       return(INCORRECT);
                    }
                    bd_time->tm_sec  = second;
                    bd_time->tm_min  = min;
                    bd_time->tm_hour = hour;
                    bd_time->tm_mday = day;
                    if ((bd_time->tm_mon == 0) && (month == 12))
                    {
                       bd_time->tm_year -= 1;
                    }
                    bd_time->tm_mon  = month - 1;

                    value = mktime(bd_time);
                 }
              }
              else
              {
                 *(ptr + length) = tmp_char;
                 return(INCORRECT);
              }
      }

      ptr += length;
      *ptr = tmp_char;
      if (ret_ptr != NULL)
      {
         if (*ptr == '\0')
         {
            *ret_ptr = ptr;
         }
         else
         {
            *ret_ptr = ptr + 1;
         }
      }
   }
   else
   {
      value = INCORRECT;
   }

   return(value);
}


/*+++++++++++++++++++++++++++++ usage() +++++++++++++++++++++++++++++++++*/
static void
usage(char *progname)
{
   (void)fprintf(stderr, "Usage: %s [options] <file name pattern>\n", progname);
   (void)fprintf(stderr, "\n    Mode options\n");
   (void)fprintf(stderr, "           -c                           continuous\n");
   (void)fprintf(stderr, "           -C                           continuous daemon\n");
   (void)fprintf(stderr, "           -l                           local log data (default)\n");
   (void)fprintf(stderr, "           -r                           remote log data\n");
   (void)fprintf(stderr, "           -b                           back trace data\n");
   (void)fprintf(stderr, "           -f                           forward trace data\n");
   (void)fprintf(stderr, "    Range parameters\n");
   (void)fprintf(stderr, "           -s <AFD host name/alias/ID>  Starting AFD hostname/alias/ID.\n");
   (void)fprintf(stderr, "           -e <AFD host name/alias/ID>  Ending AFD hostname/alias/ID.\n");
   (void)fprintf(stderr, "           -t <start>[-<end>]           Time frame at starting point.\n");
   (void)fprintf(stderr, "              Time is specified as follows:\n");
   (void)fprintf(stderr, "                 Absolute: MMDDhhmmss, MMDDhhmm, DDhhmm or hhmm\n");
   (void)fprintf(stderr, "                 Relative: -DDhhmm, -hhmm or -mm\n");
   (void)fprintf(stderr, "              Where MMDDhhmmss have the following meaning:\n");
   (void)fprintf(stderr, "                 MM - The month as a decimal number (range 01 to 12).\n");
   (void)fprintf(stderr, "                 DD - The day of the month as a decimal number (range 01 to 31).\n");
   (void)fprintf(stderr, "                 hh - The hour as a decimal number using a 24-hour clock (range\n");
   (void)fprintf(stderr, "                      00 to 23).\n");
   (void)fprintf(stderr, "                 mm - The minute as a decimal number (range 00 to 59).\n");
   (void)fprintf(stderr, "                 ss - The second as a decimal number (range 00 to 61).\n");
   (void)fprintf(stderr, "           -T <start>[-<end>]           Time frame at end point.\n");
   (void)fprintf(stderr, "           -L <log type>                Search only in given log type.\n");
   (void)fprintf(stderr, "                                        Log type can be:\n");
#ifdef _INPUT_LOG
   (void)fprintf(stderr, "                                          I - Input Log\n");
#endif
#ifdef _DISTRIBUTION_LOG
   (void)fprintf(stderr, "                                          U - Distribution Log\n");
#endif
#ifdef _PRODUCTION_LOG
   (void)fprintf(stderr, "                                          P - Production Log\n");
#endif
#ifdef _OUTPUT_LOG
# if defined(_WITH_DE_MAIL_SUPPORT) && !defined(_CONFIRMATION_LOG)
   (void)fprintf(stderr, "                                          C - Output Log confirmed\n");
# endif
   (void)fprintf(stderr, "                                          R - Output Log retrieved\n");
   (void)fprintf(stderr, "                                          O - Output Log delivered\n");
#endif
#ifdef _DELETE_LOG
   (void)fprintf(stderr, "                                          D - Delete Log\n");
#endif
   (void)fprintf(stderr, "                                        Default: IUPOD\n");
   (void)fprintf(stderr, "           -g <time in seconds>         Maximum time to search for\n");
   (void)fprintf(stderr, "                                        a single file before giving up.\n");
   (void)fprintf(stderr, "           -G <time in minutes>         Maximum time we may search\n");
   (void)fprintf(stderr, "                                        for all files.\n");
   (void)fprintf(stderr, "    Format parameters\n");
   (void)fprintf(stderr, "           -o <format>                  Specifies the output format.\n");
   (void)fprintf(stderr, "                                        Possible format parameters\n");
   (void)fprintf(stderr, "                                        are as listed:\n");
#ifdef _INPUT_LOG
   (void)fprintf(stderr, "              -- Input log data --\n");
   (void)fprintf(stderr, "              %%[Z]IT<time char>      - input time\n");
   (void)fprintf(stderr, "              %%[Y]IF                 - input file name\n");
   (void)fprintf(stderr, "              %%[X]IS<size char>      - input file size\n");
   (void)fprintf(stderr, "              %%[Z]II                 - input source ID\n");
   (void)fprintf(stderr, "              %%[Y]IN                 - full source name\n");
   (void)fprintf(stderr, "              %%[Z]IU                 - unique number\n");
#endif
#ifdef _DISTRIBUTION_LOG
   (void)fprintf(stderr, "              -- Distribution log data --\n");
   (void)fprintf(stderr, "              %%[Z]Ut<time char>      - distribution time\n");
   (void)fprintf(stderr, "              %%[Z]UT<time char>      - input time\n");
   (void)fprintf(stderr, "              %%[Y]UF                 - input file name\n");
   (void)fprintf(stderr, "              %%[X]US<size char>      - input file size\n");
   (void)fprintf(stderr, "              %%[Z]UI                 - input source ID\n");
# ifndef _INPUT_LOG
   (void)fprintf(stderr, "              %%[Y]UN                 - full source name\n");
# endif
   (void)fprintf(stderr, "              %%[Z]UU                 - unique number\n");
   (void)fprintf(stderr, "              %%[Z]Un                 - number of jobs distributed\n");
   (void)fprintf(stderr, "              %%[Z]Uj<separator char> - list of job ID's\n");
   (void)fprintf(stderr, "              %%[Z]Uc<separator char> - list of number of pre-processing\n");
   (void)fprintf(stderr, "              %%[Z]UY                 - distribution type\n");
#endif
#ifdef _PRODUCTION_LOG
   (void)fprintf(stderr, "              -- Production log data --\n");
   (void)fprintf(stderr, "              %%[Z]Pt<time char>      - time when production starts\n");
   (void)fprintf(stderr, "              %%[Z]PT<time char>      - time when production finished\n");
   (void)fprintf(stderr, "              %%[X]PD<duration char>  - production time (duration)\n");
   (void)fprintf(stderr, "              %%[X]Pu<duration char>  - CPU usage\n");
   (void)fprintf(stderr, "              %%[Z]Pb                 - ratio relationship 1\n");
   (void)fprintf(stderr, "              %%[Z]PB                 - ratio relationship 2\n");
   (void)fprintf(stderr, "              %%[Z]PJ                 - job ID\n");
   (void)fprintf(stderr, "              %%[Z]PZ<time char>      - job creation time\n");
   (void)fprintf(stderr, "              %%[Z]PU                 - unique number\n");
   (void)fprintf(stderr, "              %%[Z]PL                 - split job number\n");
   (void)fprintf(stderr, "              %%[Y]Pf                 - input file name\n");
   (void)fprintf(stderr, "              %%[X]Ps<size char>      - input file size\n");
   (void)fprintf(stderr, "              %%[Y]PF                 - produced file name\n");
   (void)fprintf(stderr, "              %%[X]PS<size char>      - produced file size\n");
   (void)fprintf(stderr, "              %%[Y]PC                 - command executed\n");
   (void)fprintf(stderr, "              %%[Z]PR                 - return code of command executed\n");
#endif
#ifdef _OUTPUT_LOG
   (void)fprintf(stderr, "              -- Output log data --\n");
   (void)fprintf(stderr, "              %%[Z]Ot<time char>      - time when sending starts\n");
   (void)fprintf(stderr, "              %%[Z]OT<time char>      - time when file is transmitted\n");
   (void)fprintf(stderr, "              %%[X]OD<duration char>  - time taken to transmit file\n");
   (void)fprintf(stderr, "              %%[Y]Of                 - local output file name\n");
   (void)fprintf(stderr, "              %%[Y]OF                 - remote output file name/directory\n");
   (void)fprintf(stderr, "              %%[Y]OE                 - final output file name/directory\n");
   (void)fprintf(stderr, "              %%[Z]Op                 - protocol ID used for transmission\n");
   (void)fprintf(stderr, "              %%[Y]OP                 - protocol used for transmission\n");
   (void)fprintf(stderr, "              %%[X]OS<size char>      - output file size\n");
   (void)fprintf(stderr, "              %%[Z]OJ                 - job ID\n");
   (void)fprintf(stderr, "              %%[Z]Oe                 - number of retries\n");
   (void)fprintf(stderr, "              %%[Y]OA                 - archive directory\n");
   (void)fprintf(stderr, "              %%[Z]OZ<time char>      - job creation time\n");
   (void)fprintf(stderr, "              %%[Z]OU                 - unique number\n");
   (void)fprintf(stderr, "              %%[Z]OL                 - split job number\n");
   (void)fprintf(stderr, "              %%[Y]OM                 - mail queue ID\n");
   (void)fprintf(stderr, "              %%[Y]Oh                 - target real hostname/IP\n");
   (void)fprintf(stderr, "              %%[Y]OH                 - target alias name\n");
   (void)fprintf(stderr, "              %%[Y]OR                 - Recipient of job\n");
   (void)fprintf(stderr, "              %%[Z]Oo                 - output type ID\n");
   (void)fprintf(stderr, "              %%[Y]OO                 - output type string\n");
#endif
#ifdef _DELETE_LOG
   (void)fprintf(stderr, "              -- Delete log data --\n");
   (void)fprintf(stderr, "              %%[Z]Dt<time char>      - time when job was created\n");
   (void)fprintf(stderr, "              %%[Z]DT<time char>      - time when file was deleted\n");
   (void)fprintf(stderr, "              %%[Z]Dr                 - delete reason ID\n");
   (void)fprintf(stderr, "              %%[Y]DR                 - delete reason string\n");
   (void)fprintf(stderr, "              %%[Y]DW                 - user/program causing deletion\n");
   (void)fprintf(stderr, "              %%[Y]DA                 - additional reason\n");
   (void)fprintf(stderr, "              %%[Z]DZ<time char>      - job creation time\n");
   (void)fprintf(stderr, "              %%[Z]DU                 - unique number\n");
   (void)fprintf(stderr, "              %%[Z]DL                 - split job number\n");
   (void)fprintf(stderr, "              %%[Y]DF                 - file name of deleted file\n");
   (void)fprintf(stderr, "              %%[X]DS<size char>      - file size of deleted file\n");
   (void)fprintf(stderr, "              %%[Z]DJ                 - job ID of deleted file\n");
   (void)fprintf(stderr, "              %%[Z]DI                 - input source ID\n");
   (void)fprintf(stderr, "              %%[Y]DN                 - full source name\n");
   (void)fprintf(stderr, "              %%[Y]DH                 - target alias name\n");
#endif
   (void)fprintf(stderr, "              -- AFD information --\n");
   (void)fprintf(stderr, "              %%[Y]Ah                 - AFD real hostname/IP\n");
   (void)fprintf(stderr, "              %%[Y]AH                 - AFD alias name\n");
   (void)fprintf(stderr, "              %%[Y]AV                 - AFD version\n");
   (void)fprintf(stderr, "\n               [X] -> [-][0]#[.#]] or [-][0]#[d|o|x]\n");
   (void)fprintf(stderr, "               [Y] -> [-]# or [<individual character positions>]\n");
   (void)fprintf(stderr, "               [Z] -> [-][0]#[d|o|x]\n");
   (void)fprintf(stderr, "\n            Time character (t,T):\n");
   (void)fprintf(stderr, "                 a - Abbreviated weekday name: Tue\n");
   (void)fprintf(stderr, "                 A - Full weekday name: Tuesday\n");
   (void)fprintf(stderr, "                 b - Abbreviated month name: Jan\n");
   (void)fprintf(stderr, "                 B - Full month name: January\n");
   (void)fprintf(stderr, "                 c - Date and time: Tue Jan 19 16:24:50 1999\n");
   (void)fprintf(stderr, "                 d - Day of the month [01 - 31]: 19\n");
   (void)fprintf(stderr, "                 H - Hour of the 24-hour day [00 - 23]: 16\n");
   (void)fprintf(stderr, "                 I - Hour of the 24-hour day [00 - 12]: 04\n");
   (void)fprintf(stderr, "                 j - Day of the year [001 - 366]: 19\n");
   (void)fprintf(stderr, "                 m - Month [01 - 12]: 01\n");
   (void)fprintf(stderr, "                 M - Minute [00 - 59]: 24\n");
   (void)fprintf(stderr, "                 p - AM/PM: PM\n");
   (void)fprintf(stderr, "                 S - Second [00 - 61]: 50\n");
   (void)fprintf(stderr, "             (*) u - Unix time: 916759490\n");
   (void)fprintf(stderr, "                 U - Sunday week number [00 - 53]: 02\n");
   (void)fprintf(stderr, "                 w - Weekday [0 - 6] (0=Sunday): 2\n");
   (void)fprintf(stderr, "                 W - Monday week number [00 - 53]: 02\n");
   (void)fprintf(stderr, "                 X - Time: 16:24:50\n");
   (void)fprintf(stderr, "                 y - Year without century [00 - 99]: 99\n");
   (void)fprintf(stderr, "                 Y - Year with century: 1999\n");
   (void)fprintf(stderr, "                 Z - Time zone name: CET\n");
   (void)fprintf(stderr, "            Duration character (D,u):\n");
   (void)fprintf(stderr, "                 A - Automatic shortest format: 4d\n");
   (void)fprintf(stderr, "                             d - days\n");
   (void)fprintf(stderr, "                             h - hours\n");
   (void)fprintf(stderr, "                             m - minutes\n");
   (void)fprintf(stderr, "                             s - seconds\n");
   (void)fprintf(stderr, "             (*) D - Days only : 4\n");
   (void)fprintf(stderr, "             (*) H - Hours only : 102\n");
   (void)fprintf(stderr, "             (*) M - Minutes only: 6144\n");
   (void)fprintf(stderr, "             (*) S - Seconds only: 368652\n");
   (void)fprintf(stderr, "                 X - Time (h:mm:ss): 102:24:12\n");
   (void)fprintf(stderr, "                 Y - Time (d:hh:mm): 4:06:24\n");
   (void)fprintf(stderr, "            Size character (S):\n");
   (void)fprintf(stderr, "             (#) a - Automatic shortest format: 1 GB\n");
   (void)fprintf(stderr, "                             B  - byte\n");
   (void)fprintf(stderr, "                             KB - kilobyte (10^3)\n");
   (void)fprintf(stderr, "                             MB - megabyte (10^6)\n");
   (void)fprintf(stderr, "                             GB - gigabyte (10^9)\n");
   (void)fprintf(stderr, "                             TB - terabyte (10^12)\n");
   (void)fprintf(stderr, "                             PB - petabyte (10^15)\n");
   (void)fprintf(stderr, "                             EB - exabyte  (10^18)\n");
   (void)fprintf(stderr, "             (#) A - Automatic shortest format: 1 GiB\n");
   (void)fprintf(stderr, "                             B   - byte\n");
   (void)fprintf(stderr, "                             KiB - kibibyte (2^10)\n");
   (void)fprintf(stderr, "                             MiB - mebibyte (2^20)\n");
   (void)fprintf(stderr, "                             GiB - gibibyte (2^30)\n");
   (void)fprintf(stderr, "                             TiB - tebibyte (2^40)\n");
   (void)fprintf(stderr, "                             PiB - pebibyte (2^50)\n");
   (void)fprintf(stderr, "                             EiB - exbibyte (2^60)\n");
   (void)fprintf(stderr, "             (#) B - Bytes only: 1884907510\n");
   (void)fprintf(stderr, "             (#) e - Exabyte only : 0\n");
   (void)fprintf(stderr, "             (#) E - Exbibyte only: 0\n");
   (void)fprintf(stderr, "             (#) g - Gigabyte only: 1\n");
   (void)fprintf(stderr, "             (#) G - Gibibyte only: 1\n");
   (void)fprintf(stderr, "             (#) k - Kilobyte only: 1884907\n");
   (void)fprintf(stderr, "             (#) K - Kibibyte only: 1840729\n");
   (void)fprintf(stderr, "             (#) m - Megabyte only: 1884\n");
   (void)fprintf(stderr, "             (#) M - Mebibyte only: 1797\n");
   (void)fprintf(stderr, "             (#) p - Petabyte only: 0\n");
   (void)fprintf(stderr, "             (#) P - Pebibyte only: 0\n");
   (void)fprintf(stderr, "             (#) t - Terabyte only: 0\n");
   (void)fprintf(stderr, "             (#) T - Tebibyte only: 0\n");
   (void)fprintf(stderr, "\n            (*) Can be printed as decimal (d), octal (o) or hexadecimal (x)\n");
   (void)fprintf(stderr, "            (#) Can be printed as numeric string with decimal point\n");
   (void)fprintf(stderr, "                                      OR\n");
   (void)fprintf(stderr, "                Can be printed as decimal (d), octal (o) or hexadecimal (x)\n");
   (void)fprintf(stderr, "    Search parameters\n");
   (void)fprintf(stderr, "            -d <directory name/alias/ID> Directory name, alias or ID.\n");
   (void)fprintf(stderr, "                                            dir name no prefix\n");
   (void)fprintf(stderr, "                                            dir alias use prefix %%\n");
   (void)fprintf(stderr, "                                            dir ID use prefix #\n");
   (void)fprintf(stderr, "            -h <host name/alias/ID>      Host name, alias or ID.\n");
   (void)fprintf(stderr, "                                            host name no prefix\n");
   (void)fprintf(stderr, "                                            host alias use prefix %%\n");
   (void)fprintf(stderr, "                                            host ID use prefix #\n");
   (void)fprintf(stderr, "            -j <job ID>                  Job identifier.\n");
   (void)fprintf(stderr, "            -u <unique number>           Unique number.\n");
   (void)fprintf(stderr, "            -z <size>                    Original file size in byte.\n");
   (void)fprintf(stderr, "                                         (Production log only!)\n");
   (void)fprintf(stderr, "            -S[I|U|P|O|D] <size>         File size in byte.\n");
   (void)fprintf(stderr, "            -D[P|O] <time>               Duration in seconds.\n");
   (void)fprintf(stderr, "            -p <protocol>                Protocol used for transport:\n");
   (void)fprintf(stderr, "                                          %s\n", ALDA_FTP_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_LOC_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_EXEC_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_SMTP_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_DEMAIL_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_SFTP_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_SCP_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_HTTP_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_HTTPS_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_FTPS_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_WMO_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_MAP_SHEME);
   (void)fprintf(stderr, "                                          %s\n", ALDA_DFAX_SHEME);
   (void)fprintf(stderr, "    Other parameters\n");
   (void)fprintf(stderr, "            -F <file name>               Footer to add to output.\n");
   (void)fprintf(stderr, "            -R <x>                       Rotate log x times.\n");
   (void)fprintf(stderr, "            -H <file name>               Header to add to output.\n");
   (void)fprintf(stderr, "            -O <file name>               File where to write output.\n");
   (void)fprintf(stderr, "            -v[v[v[v[v[v]]]]]            Verbose mode.\n");
   (void)fprintf(stderr, "            -w <work dir>                Working directory of the AFD.\n");
   (void)fprintf(stderr, "            --header_line=<line>         Add the given header line to\n");
   (void)fprintf(stderr, "                                         output. The following\n");
   (void)fprintf(stderr, "                                         %% parameters can be used to\n");
   (void)fprintf(stderr, "                                         insert additional system\n");
   (void)fprintf(stderr, "                                         infomation:\n");
   (void)fprintf(stderr, "                                           %%I - inode number of the log file\n");
#ifdef HAVE_GETHOSTID
   (void)fprintf(stderr, "                                           %%H - host ID\n");
#endif
   (void)fprintf(stderr, "    To be able to differentiate between name, alias and ID:\n");
   (void)fprintf(stderr, "        alias - must always begin with %%\n");
   (void)fprintf(stderr, "        ID    - must always begin with #\n");
   (void)fprintf(stderr, "        name  - just the name without extra identifier\n");

   return;
}