summaryrefslogtreecommitdiff
path: root/support/vvcode/vvutils.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/vvcode/vvutils.c
Initial commit
Diffstat (limited to 'support/vvcode/vvutils.c')
-rw-r--r--support/vvcode/vvutils.c2729
1 files changed, 2729 insertions, 0 deletions
diff --git a/support/vvcode/vvutils.c b/support/vvcode/vvutils.c
new file mode 100644
index 0000000000..3cd59777af
--- /dev/null
+++ b/support/vvcode/vvutils.c
@@ -0,0 +1,2729 @@
+/*-
+******************************************************************************
+******************************************************************************
+**
+** ARCHIVE HEADER INFORMATION
+**
+** @C-file{
+** FILENAME = "vvutils.c",
+** VERSION = "1.00",
+** DATE = "",
+** TIME = "",
+**
+** AUTHOR = "Niel Kempson",
+** ADDRESS = "25 Whitethorn Drive, Cheltenham, GL52 5LL, England",
+** TELEPHONE = "+44-242 579105",
+** EMAIL = "kempson@tex.ac.uk (Internet)",
+**
+** SUPPORTED = "yes",
+** ARCHIVED = "tex.ac.uk, ftp.tex.ac.uk",
+** KEYWORDS = "VVcode",
+**
+** CODETABLE = "ISO/ASCII",
+** CHECKSUM = "51492 1481 5732 57976",
+**
+** DOCSTRING = { This file is part of VVcode.
+** }
+** }
+**
+** MODULE CONTENTS
+**
+** allocate_buffer Allocate memory for a buffer.
+** display_comment Display a VVE file comment.
+** f_close Close a file.
+** getc_format Get the format specified on the command line.
+** getc_mode Get the mode specified on the command line.
+** getc_reclen Get the maximum record length specified on
+** the command line.
+** getc_timestamp Get the timestamp specified on the command
+** line.
+** header_type Look for a header string in a list of headers.
+** init_crc32_table Initialize the 32 bit CRC table.
+** lookup_key Look for a string in a list of keywords.
+** make_time Convert a 'tm' structure into a Unix style
+** time_t value.
+** open_log_file Open the log file for writing.
+** parse_header Extract the value of a VVE/XLT header line.
+** pars_time Parse a string in VVcode timestamp format and
+** convert it to a Unix style time_t value.
+** pars_xlt_tbl Parse a character set translation table.
+** rd_enc_tbl Read and check an encoding table from a
+** specified file.
+** rd_xlt_tbl Read and check a character set translation
+** table from a specified file.
+** set_dec_tbl Invert an encoding table to form a decoding
+** table.
+** set_xlt_tbl Setup the character set translation table.
+** show_file_context Show the context in which a file processing
+** error occurred.
+** vstrchr Search a string for the first occurrence of a
+** specified character.
+** vstricmp Compare two strings ignoring case differences.
+** vstrnicmp Compare at most 'n' characters of two strings
+** ignoring case differences.
+** vstrrchr Search a string for the last occurrence of a
+** specified character.
+** vstrrstr Search a string for the last occurrence of
+** any of a list of specified characters.
+** vstrstr Search a string for the first occurrence of
+** any of a list of specified characters.
+** vv_timestamp Convert a Unix style time_t value into a
+** VVcode format timestamp string.
+** vstrdup Duplicate a string, allocating memory for the
+** copy.
+** vstrtrws Strip trailing whitespace from a string.
+**
+** COPYRIGHT
+**
+** Copyright (c) 1991-1993 by Niel Kempson <kempson@tex.ac.uk>
+**
+** 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 1, 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.
+**
+** In other words, you are welcome to use, share and improve this
+** program. You are forbidden to forbid anyone else to use, share
+** and improve what you give them. Help stamp out software-hoarding!
+**
+** CHANGE LOG
+**
+******************************************************************************
+******************************************************************************
+*/
+static char rcsid[] = "$Id$";
+
+
+#define VVUTILS 1
+
+
+/*-
+**----------------------------------------------------------------------------
+** Standard include files
+**----------------------------------------------------------------------------
+*/
+#include <stdio.h>
+
+
+/*-
+**----------------------------------------------------------------------------
+** Include files
+**----------------------------------------------------------------------------
+*/
+#include "checkos.h"
+#include "machine.h"
+#include "local.h"
+#include "globals.h"
+#include "specific.h"
+#include "vvutils.h"
+
+
+/*-
+**----------------------------------------------------------------------------
+**
+**----------------------------------------------------------------------------
+*/
+static int month_days[12] =
+ {
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+ };
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** allocate_buffer
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ char *allocate_buffer (CONST SIZE_T buf_len,
+ CONST char *buf_name)
+#else /* NOT (ANSI_SYNTAX) */
+ char *allocate_buffer (buf_len, buf_name)
+ CONST SIZE_T buf_len;
+ CONST char *buf_name;
+#endif /* (ANSI_SYNTAX) */
+{
+ SIZE_T bytes_required;
+
+ char *buf_ptr;
+
+ bytes_required = buf_len * sizeof (char);
+ buf_ptr = (char *) malloc (bytes_required);
+
+ if (buf_ptr == NULL)
+ {
+ FATALMSG_2 ("error allocating %ld bytes for buffer `%s'",
+ (Int32) bytes_required, buf_name);
+ vv_exit ();
+ }
+ else
+ {
+ DEBUG_2 ("allocate_buffer: allocated %ld bytes for buffer `%s'",
+ (Int32) bytes_required, buf_name);
+ }
+ return (buf_ptr);
+} /* allocate_buffer */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** display_comment
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ void display_comment (CONST File_Info *ip_file,
+ CONST char *line_ptr,
+ Header_Struct *hdr_struct)
+#else /* NOT (ANSI_SYNTAX) */
+ void display_comment (ip_file, line_ptr, hdr_struct)
+ CONST File_Info *ip_file;
+ CONST char *line_ptr;
+ Header_Struct *hdr_struct;
+#endif /* (ANSI_SYNTAX) */
+{
+ char *comment_str_buffer;
+ int fields_read;
+
+ hdr_struct->present = FALSE;
+ hdr_struct->value = NULL;
+ comment_str_buffer = allocate_buffer ((MAX_IP_LINE_LEN + 1),
+ "comment_str_buffer");
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ fields_read = sscanf (line_ptr, "%*s %[^\n]", comment_str_buffer);
+ if (fields_read == 1)
+ {
+ LOGMSG_1 ("VVE file comment: %s", comment_str_buffer);
+ }
+ else
+ {
+ ERRORMSG_1 ("error parsing value of `%s' header", hdr_struct->h_string);
+ show_file_context (ip_file, line_ptr);
+ }
+ free (comment_str_buffer);
+} /* display_comment */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** f_close
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ void f_close (File_Info *target_file)
+#else /* NOT (ANSI_SYNTAX) */
+ void f_close (target_file)
+ File_Info *target_file;
+#endif /* (ANSI_SYNTAX) */
+{
+ int status;
+
+ if (target_file->file_ptr != (FILE *) NULL)
+ {
+ status = fclose (target_file->file_ptr);
+
+ if (status != 0)
+ {
+ ERRORMSG_1 ("error closing file `%s'", target_file->file_spec);
+ explain_error ();
+ }
+ }
+} /* f_close */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** getc_format
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ Int16 getc_format (CONST Qualifier_Struct *qual_format,
+ CONST char *fmt_str_array[])
+#else /* NOT (ANSI_SYNTAX) */
+ Int16 getc_format (qual_format, fmt_str_array)
+ CONST Qualifier_Struct *qual_format;
+ CONST char *fmt_str_array[];
+#endif /* (ANSI_SYNTAX) */
+{
+ Int16 format_no;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if (qual_format->present != TRUE)
+ {
+ DEBUG ("getc_format: format not specified on the command line");
+ return (INV_FORMAT);
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ format_no = lookup_key (fmt_str_array, qual_format->value,
+ ALLOW_ABBREVIATIONS, CASE_INSENSITIVE);
+
+ switch (format_no)
+ {
+
+ /*-
+ **----------------------------------------------------------------
+ **
+ **----------------------------------------------------------------
+ */
+ case FMT_FIXED:
+
+#if (SUPPORT_FIXED_FMT)
+ break;
+#else /* NOT (SUPPORT_FIXED_FMT) */
+ USAGE_1 ("format `%s' is not supported by this implementation",
+ fmt_str_array[format_no]);
+ break;
+#endif /* (SUPPORT_FIXED_FMT) */
+
+ /*-
+ **----------------------------------------------------------------
+ **
+ **----------------------------------------------------------------
+ */
+ case FMT_STREAM:
+
+#if (SUPPORT_STREAM_FMT)
+ break;
+#else /* NOT (SUPPORT_STREAM_FMT) */
+ USAGE_1 ("format `%s' is not supported by this implementation",
+ fmt_str_array[format_no]);
+ break;
+#endif /* (SUPPORT_STREAM_FMT) */
+
+ /*-
+ **----------------------------------------------------------------
+ **
+ **----------------------------------------------------------------
+ */
+ case FMT_VARIABLE:
+
+#if SUPPORT_VARIABLE_FMT
+ break;
+#else /* NOT (SUPPORT_VARIABLE_FMT) */
+ USAGE_1 ("format `%s' is not supported by this implementation",
+ fmt_str_array[format_no]);
+ break;
+#endif /* (SUPPORT_VARIABLE_FMT) */
+
+ /*-
+ **----------------------------------------------------------------
+ **
+ **----------------------------------------------------------------
+ */
+ case FMT_DEFAULT:
+ break;
+
+ /*-
+ **----------------------------------------------------------------
+ **
+ **----------------------------------------------------------------
+ */
+ default:
+ USAGE_1 ("invalid format `%s'", qual_format->value);
+ }
+
+ DEBUG_1 ("getc_format: command line specifies format `%s'",
+ fmt_str_array[format_no]);
+ return (format_no);
+} /* getc_format */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** getc_mode
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ Int16 getc_mode (CONST Qualifier_Struct *qual_mode,
+ CONST char *mode_str_array[])
+#else /* NOT (ANSI_SYNTAX) */
+ Int16 getc_mode (qual_mode, mode_str_array)
+ CONST Qualifier_Struct *qual_mode;
+ CONST char *mode_str_array[];
+#endif /* (ANSI_SYNTAX) */
+{
+ Int16 mode_no;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if (qual_mode->present != TRUE)
+ {
+ DEBUG ("getc_mode: mode not specified on the command line");
+ return (INV_MODE);
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ mode_no = lookup_key (mode_str_array, qual_mode->value,
+ ALLOW_ABBREVIATIONS, CASE_INSENSITIVE);
+
+ switch (mode_no)
+ {
+ case MODE_BINARY:
+ case MODE_TEXT:
+ break;
+ default:
+ USAGE_1 ("invalid mode `%s'", qual_mode->value);
+ }
+
+ DEBUG_1 ("getc_mode: command line specifies mode `%s'",
+ mode_str_array[mode_no]);
+ return (mode_no);
+} /* getc_mode */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** getc_reclen
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ Int32 getc_reclen (CONST Qualifier_Struct *qual_reclen,
+ CONST File_Info *ip_file)
+#else /* NOT (ANSI_SYNTAX) */
+ Int32 getc_reclen (qual_reclen, ip_file)
+ CONST Qualifier_Struct *qual_reclen;
+ CONST File_Info *ip_file;
+#endif /* (ANSI_SYNTAX) */
+{
+ Int32 record_len;
+ int status;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if (qual_reclen->present != TRUE)
+ {
+ DEBUG ("getc_reclen: record length not specified on the command line");
+ return (INV_RECORD_LEN);
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ record_len = INV_RECORD_LEN;
+ status = sscanf (qual_reclen->value, "%ld", &record_len);
+
+ if (status != 1)
+ {
+ USAGE_1 ("invalid record length specified `%s'", qual_reclen->value);
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if (ip_file->format == FMT_VARIABLE)
+ {
+ if ((record_len < (Int32) MIN_VARIABLE_RECORD_LEN)
+ || (record_len > (Int32) MAX_VARIABLE_RECORD_LEN))
+ {
+ USAGE_3 ("record length must be in the range %ld-%ld (not %ld)",
+ (Int32) MIN_VARIABLE_RECORD_LEN,
+ (Int32) MAX_VARIABLE_RECORD_LEN, record_len);
+ }
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ else
+ if (ip_file->format == FMT_FIXED)
+ {
+ if ((record_len < (Int32) MIN_FIXED_RECORD_LEN)
+ || (record_len > (Int32) MAX_FIXED_RECORD_LEN))
+ {
+ USAGE_3 ("record length must be in the range %ld-%ld (not %ld)",
+ (Int32) MIN_FIXED_RECORD_LEN,
+ (Int32) MAX_FIXED_RECORD_LEN, record_len);
+ }
+ }
+
+ DEBUG_1 ("getc_reclen: command line specifies maximum record length `%ld'",
+ record_len);
+ return (record_len);
+} /* getc_reclen */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** getc_timestamp
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ TIME_T getc_timestamp (CONST Qualifier_Struct *qual_timestamp)
+#else /* NOT (ANSI_SYNTAX) */
+ TIME_T getc_timestamp (qual_timestamp)
+ CONST Qualifier_Struct *qual_timestamp;
+#endif /* (ANSI_SYNTAX) */
+{
+ TIME_T cmd_timestamp;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if (qual_timestamp->present != TRUE)
+ {
+ DEBUG ("getc_timestamp: timestamp not specified on the command line");
+ return (INV_TIMESTAMP);
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if ((qual_timestamp->value == NULL) || (*qual_timestamp->value == '\0'))
+ {
+ (void) time (&cmd_timestamp);
+ }
+ else
+ {
+ cmd_timestamp = pars_time (qual_timestamp->value);
+
+ if (cmd_timestamp == INV_TIMESTAMP)
+ {
+ USAGE_1 ("invalid timestamp string specified `%s'",
+ qual_timestamp->value);
+ }
+ }
+ return (cmd_timestamp);
+} /* getc_timestamp */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** header_type
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ Int16 header_type (CONST File_Info *ip_file,
+ CONST char *line_ptr,
+ CONST Header_Struct *hdr_array)
+#else /* NOT (ANSI_SYNTAX) */
+ Int16 header_type (ip_file, line_ptr, hdr_array)
+ CONST File_Info *ip_file;
+ CONST char *line_ptr;
+ CONST Header_Struct *hdr_array;
+#endif /* (ANSI_SYNTAX) */
+{
+ int cmp_len;
+ Int16 hdr_found;
+ Int16 hdr_no;
+
+
+ /*-
+ **------------------------------------------------------------------------
+ ** If the string to be tested is NULL treat it as ambiguous and return.
+ **------------------------------------------------------------------------
+ */
+ if ((line_ptr == NULL) || (line_ptr[0] == '\0'))
+ {
+ return (HDR_UNKNOWN);
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ ** Search the VVE header structure array for this string.
+ **------------------------------------------------------------------------
+ */
+ hdr_found = -1;
+
+ for (hdr_no = 0; hdr_array[hdr_no].h_string != NULL; hdr_no++)
+ {
+ cmp_len = strlen (hdr_array[hdr_no].h_string);
+
+ if (STRNCMPI (hdr_array[hdr_no].h_string, line_ptr, cmp_len) == 0)
+ {
+ DEBUG_1 ("header_type: VVE line matches header: `%s'",
+ hdr_array[hdr_no].h_string);
+
+ if (hdr_found < 0)
+ {
+ hdr_found = hdr_no;
+ }
+ else
+ {
+ ERRORMSG ("ambiguous header ignored");
+ show_file_context (ip_file, line_ptr);
+ return (HDR_UNKNOWN);
+ }
+ }
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ ** If the header string is unknown, return that status.
+ **------------------------------------------------------------------------
+ */
+ if (hdr_found < 0)
+ {
+ DEBUG_1 ("header_type: ignored unknown VVE header line: `%s'",
+ line_ptr);
+ return (HDR_UNKNOWN);
+ }
+ else
+ {
+ return (hdr_found);
+ }
+} /* header_type */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** init_crc32_table
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ void init_crc32_table (CONST Int16 crc_table_size,
+ CONST Unsigned32 crc_polynomial,
+ Unsigned32 *crc_table)
+#else /* NOT (ANSI_SYNTAX) */
+ void init_crc32_table (crc_table_size, crc_polynomial,
+ crc_table)
+ CONST Int16 crc_table_size;
+ CONST Unsigned32 crc_polynomial;
+ Unsigned32 *crc_table;
+#endif /* (ANSI_SYNTAX) */
+{
+ Unsigned16 idx;
+ Unsigned16 j;
+ Unsigned32 r;
+
+ for (idx = 0; idx < (Unsigned16) crc_table_size; idx++)
+ {
+ r = idx;
+ for (j = 0; j < 8; j++)
+ {
+ if (r & 1)
+ {
+ r = (r >> 1) ^ crc_polynomial;
+ }
+ else
+ {
+ r >>= 1;
+ }
+ }
+ crc_table[idx] = r;
+ }
+} /* init_crc32_table */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** lookup_key
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ Int16 lookup_key (CONST char *key_list[],
+ CONST char *string,
+ CONST Int16 allow_abbrevs,
+ CONST Int16 case_sensitivity)
+#else /* NOT (ANSI_SYNTAX) */
+ Int16 lookup_key (key_list, string, allow_abbrevs,
+ case_sensitivity)
+ CONST char *key_list[];
+ CONST char *string;
+ CONST Int16 allow_abbrevs;
+ CONST Int16 case_sensitivity;
+#endif /* (ANSI_SYNTAX) */
+{
+ Int16 key_no;
+ int cmp_len;
+ Int16 look_status;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if ((string == NULL) || (*string == '\0'))
+ {
+ return (LOOKUP_AMBIGUOUS);
+ }
+ cmp_len = strlen (string);
+ look_status = LOOKUP_UNKNOWN;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ for (key_no = 0; key_list[key_no] != NULL; key_no++)
+ {
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ if (allow_abbrevs == NO_ABBREVIATIONS)
+ {
+ cmp_len = strlen (key_list[key_no]);
+ }
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ if (case_sensitivity == CASE_INSENSITIVE)
+ {
+ if (STRNCMPI (key_list[key_no], string, cmp_len) == 0)
+ {
+ if (look_status == LOOKUP_UNKNOWN)
+ {
+ look_status = key_no;
+ }
+ else
+ {
+ look_status = LOOKUP_AMBIGUOUS;
+ }
+ }
+ }
+ else
+ {
+ if (STRNCMP (key_list[key_no], string, cmp_len) == 0)
+ {
+ if (look_status == LOOKUP_UNKNOWN)
+ {
+ look_status = key_no;
+ }
+ else
+ {
+ look_status = LOOKUP_AMBIGUOUS;
+ }
+ }
+ }
+ }
+
+ return (look_status);
+} /* lookup_key */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** make_time
+**
+** DESCRIPTION
+**
+** Convert the 'tm' structure (in GMT) to a standard 'TIME_T' value of
+** the number of seconds since 1-Jan-1970 00:00:00 GMT.
+**
+** NOTE: the structure time is assumed to be GMT and only the fields
+** tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec are used.
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ TIME_T make_time (CONST struct tm *t_struct)
+#else /* NOT (ANSI_SYNTAX) */
+ TIME_T make_time (t_struct)
+ CONST struct tm *t_struct;
+#endif /* (ANSI_SYNTAX) */
+{
+ TIME_T total_days;
+ TIME_T total_secs;
+ int i;
+
+ DEBUG_3 ("make_time: date provided = %04d/%02d/%02d",
+ t_struct->tm_year, t_struct->tm_mon, t_struct->tm_mday);
+ DEBUG_3 ("make_time: time provided = %02d:%02d:%02d",
+ t_struct->tm_hour, t_struct->tm_min, t_struct->tm_sec);
+
+ /*-
+ **------------------------------------------------------------------------
+ ** Calculate the number of days since 1 January 1970, but do not return a
+ ** negative number.
+ **------------------------------------------------------------------------
+ */
+ if (t_struct->tm_year < 70)
+ {
+ return (0L);
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ total_days = (TIME_T) 0;
+ for (i = 1970; i < (1900 + t_struct->tm_year); i++)
+ {
+ total_days += (TIME_T) 365;
+ if (LEAPYEAR (i) == TRUE)
+ {
+ ++total_days;
+ }
+ }
+
+ for (i = 0; i < t_struct->tm_mon; i++)
+ {
+ total_days += month_days[i];
+ if ((i == 1) && (LEAPYEAR (1900 + t_struct->tm_year) == TRUE))
+ {
+ ++total_days;
+ }
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ total_days += (TIME_T) (t_struct->tm_mday - 1);
+
+ total_secs = ((TIME_T) total_days * 86400L)
+ + ((TIME_T) t_struct->tm_hour * 3600L)
+ + ((TIME_T) t_struct->tm_min * 60L)
+ + (TIME_T) t_struct->tm_sec;
+
+ DEBUG_1 ("make_time: time_t value returned = %ld", total_secs);
+ return (total_secs);
+} /* make_time */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** open_log_file
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ void open_log_file (CONST Qualifier_Struct *log_qualifier,
+ CONST char *def_file_name,
+ CONST Int16 overwrite_flag,
+ File_Info *log_file)
+#else /* NOT (ANSI_SYNTAX) */
+ void open_log_file (log_qualifier, def_file_name,
+ overwrite_flag, log_file)
+ CONST Qualifier_Struct *log_qualifier;
+ CONST char *def_file_name;
+ CONST Int16 overwrite_flag;
+ File_Info *log_file;
+#endif /* (ANSI_SYNTAX) */
+{
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ log_file->file_ptr = (FILE *) NULL;
+ log_file->mode = MODE_TEXT;
+ log_file->format = DEF_TEXT_FMT;
+ log_file->max_rec_len = INV_RECORD_LEN;
+ log_file->lng_rec_len = INV_RECORD_LEN;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if (log_qualifier->present != TRUE)
+ {
+ DEBUG ("open_log_file: log file not specified on the command line");
+ return;
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if (log_qualifier->value != NULL)
+ {
+ strcpy (log_file->file_spec, log_qualifier->value);
+
+ /*-
+ **--------------------------------------------------------------------
+ ** If a file spec was given for the log file, use the default log
+ ** file extension if one was not provided.
+ **--------------------------------------------------------------------
+ */
+#if (STICKY_DEFAULTS)
+ apply_defaults (def_file_name, DEF_LOG_EXT, log_file->file_spec);
+#endif /* (STICKY_DEFAULTS) */
+
+ DEBUG_1 ("open_log_file: opening log file `%s'", log_file->file_spec);
+ log_file->file_ptr = f_open_out (overwrite_flag, log_file);
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ else
+ {
+ strcpy (log_file->file_spec, "stderr");
+ log_file->file_ptr = stderr;
+ log_file->pipe_flag = TRUE;
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if (log_file->file_ptr == (FILE *) NULL)
+ {
+ FATALMSG_1 ("error opening log file `%s'", log_file->file_spec);
+ vv_exit ();
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if ((log_file->pipe_flag == TRUE) || (is_a_file (log_file) == FALSE))
+ {
+ DEBUG_1 ("open_log_file: `%s' is not a regular file",
+ log_file->file_spec);
+ log_file->pipe_flag = TRUE;
+ set_pipe_mode (log_file);
+ }
+} /* open_log_file */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** parse_header
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ void parse_header (CONST File_Info *ip_file,
+ CONST char *line_ptr,
+ Header_Struct *hdr_struct)
+#else /* NOT (ANSI_SYNTAX) */
+ void parse_header (ip_file, line_ptr, hdr_struct)
+ CONST File_Info *ip_file;
+ CONST char *line_ptr;
+ Header_Struct *hdr_struct;
+#endif /* (ANSI_SYNTAX) */
+{
+ char *dummy;
+ int fields_read;
+
+ hdr_struct->present = FALSE;
+ hdr_struct->value = NULL;
+ dummy = allocate_buffer ((MAX_IP_LINE_LEN + 1), "dummy");
+ fields_read = sscanf (line_ptr, "%*s %s", dummy);
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if (fields_read == 1)
+ {
+ hdr_struct->value = STRDUP (dummy);
+ hdr_struct->present = TRUE;
+ }
+ else
+ {
+ ERRORMSG_1 ("error parsing value of `%s' header", hdr_struct->h_string);
+ show_file_context (ip_file, line_ptr);
+ }
+ free (dummy);
+} /* parse_header */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** pars_time
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ TIME_T pars_time (CONST char *time_str)
+#else /* NOT (ANSI_SYNTAX) */
+ TIME_T pars_time (time_str)
+ CONST char *time_str;
+#endif /* (ANSI_SYNTAX) */
+{
+ int args;
+ TIME_T time_val;
+ struct tm tm_struct;
+
+ /*-
+ **------------------------------------------------------------------------
+ ** If the time string is empty or null, return an error.
+ **------------------------------------------------------------------------
+ */
+ time_val = INV_TIMESTAMP;
+
+ if ((time_str == NULL) || (*time_str == '\0'))
+ {
+ return (INV_TIMESTAMP);
+ }
+
+ DEBUG_1 ("pars_time: VVE timestamp string provided = `%s'", time_str);
+
+ /*-
+ **------------------------------------------------------------------------
+ ** Initialize the time structure to 1970.01.01-00:00:00 GMT
+ **------------------------------------------------------------------------
+ */
+ tm_struct.tm_year = 1970;
+ tm_struct.tm_mon = 1;
+ tm_struct.tm_mday = 1;
+ tm_struct.tm_hour = 0;
+ tm_struct.tm_min = 0;
+ tm_struct.tm_sec = 0;
+
+ args = sscanf (time_str, VV_TIMESTAMP_FORMAT,
+ &tm_struct.tm_year, &tm_struct.tm_mon, &tm_struct.tm_mday,
+ &tm_struct.tm_hour, &tm_struct.tm_min, &tm_struct.tm_sec);
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if ((args < 1) || (args > 6))
+ {
+ ERRORMSG_1 ("error parsing timestamp string `%s'", time_str);
+ return (INV_TIMESTAMP);
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if ((tm_struct.tm_year < 1970) || (tm_struct.tm_year > 2037))
+ {
+ ERRORMSG_1 ("year (YYYY) must be in the range 1970-2037 (not %d)\n",
+ tm_struct.tm_year);
+ return (INV_TIMESTAMP);
+ }
+ (tm_struct.tm_year) -= 1900;
+
+ if ((tm_struct.tm_mon < 1) || (tm_struct.tm_mon > 12))
+ {
+ ERRORMSG_1 ("month (MM) must be in the range 1-12 (not %d)\n",
+ tm_struct.tm_mon);
+ return (INV_TIMESTAMP);
+ }
+ --(tm_struct.tm_mon);
+
+ if ((tm_struct.tm_mday < 1) || (tm_struct.tm_mday > 31))
+ {
+ ERRORMSG_1 ("day (DD) must be in the range 1-31 (not %d)\n",
+ tm_struct.tm_mday);
+ return (INV_TIMESTAMP);
+ }
+
+ if ((tm_struct.tm_hour < 0) || (tm_struct.tm_hour > 23))
+ {
+ ERRORMSG_1 ("hours (HH) must be in the range 0-23 (not %d)\n",
+ tm_struct.tm_hour);
+ return (INV_TIMESTAMP);
+ }
+
+ if ((tm_struct.tm_min < 0) || (tm_struct.tm_min > 59))
+ {
+ ERRORMSG_1 ("minutes (MM) must be in the range 0-59 (not %d)\n",
+ tm_struct.tm_min);
+ return (INV_TIMESTAMP);
+ }
+
+ if ((tm_struct.tm_sec < 0) || (tm_struct.tm_sec > 59))
+ {
+ ERRORMSG_1 ("seconds (SS) must be in the range 0-59 (not %d)\n",
+ tm_struct.tm_sec);
+ return (INV_TIMESTAMP);
+ }
+
+ tm_struct.tm_wday = 0;
+ tm_struct.tm_yday = 0;
+ tm_struct.tm_isdst = 0;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ time_val = make_time (&tm_struct);
+ DEBUG_1 ("pars_time: time_t value returned = %ld", time_val);
+
+ return (time_val);
+} /* pars_time */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** pars_xlt_tbl
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ Boolean pars_xlt_tbl (CONST char *xlt_buffer,
+ Xlt_Struct *xlt_tbl_struct,
+ Int16 subst_char)
+#else /* NOT (ANSI_SYNTAX) */
+ Boolean pars_xlt_tbl (xlt_buffer, xlt_tbl_struct,
+ subst_char)
+ CONST char *xlt_buffer;
+ Xlt_Struct *xlt_tbl_struct;
+ Int16 subst_char;
+#endif /* (ANSI_SYNTAX) */
+{
+ char *curr_ptr;
+ int fields_read;
+ char *item_end;
+ int item_num;
+ SIZE_T item_len;
+ char *item_start;
+ char *item_str;
+ Boolean status;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ status = TRUE;
+ item_str = allocate_buffer (XLT_BUFFER_SIZE, "item_str");
+ curr_ptr = (char *) xlt_buffer;
+
+ for (item_num = 0;; item_num++)
+ {
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ while ((*curr_ptr != '\0') && isspace (*curr_ptr))
+ {
+ ++curr_ptr;
+ }
+ if (*curr_ptr == '\0')
+ {
+ break;
+ }
+ else
+ {
+ item_start = curr_ptr;
+ }
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ while ((*curr_ptr != '\0') && (!isspace (*curr_ptr)))
+ {
+ ++curr_ptr;
+ }
+ item_end = curr_ptr;
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ item_len = (SIZE_T) (item_end - item_start) + 1;
+ strncpy (item_str, item_start, item_len);
+ item_str[item_len] = '\0';
+
+ fields_read = sscanf (item_str, "%hd",
+ &(xlt_tbl_struct->xlt_tbl[item_num]));
+ if (fields_read != 1)
+ {
+ ERRORMSG_2 ("error parsing item %d (`%s') in translation file",
+ (item_num + 1), item_str);
+ status = FALSE;
+ }
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ if ((xlt_tbl_struct->xlt_tbl[item_num] < -1)
+ || (xlt_tbl_struct->xlt_tbl[item_num] > 255))
+ {
+ ERRORMSG_2 ("invalid value (%d) of item %d in translation file",
+ xlt_tbl_struct->xlt_tbl[item_num], (item_num + 1));
+ status = FALSE;
+ }
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ if (xlt_tbl_struct->xlt_tbl[item_num] == -1)
+ {
+ xlt_tbl_struct->xlt_tbl[item_num] = subst_char;
+ }
+ } /* end-for */
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if ((status == TRUE) && (item_num != XLT_TABLE_LEN))
+ {
+ ERRORMSG_1 ("wrong number of values in translation file: %d",
+ item_num);
+ status = FALSE;
+ }
+ free (item_str);
+ return (status);
+} /* pars_xlt_tbl */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** rd_enc_tbl
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ Boolean rd_enc_tbl (File_Info *enc_file,
+ CONST Int16 enc_tbl_len,
+ char *encode_table)
+#else /* NOT (ANSI_SYNTAX) */
+ Boolean rd_enc_tbl (enc_file, enc_tbl_len, encode_table)
+ File_Info *enc_file;
+ CONST Int16 enc_tbl_len;
+ char *encode_table;
+#endif /* (ANSI_SYNTAX) */
+{
+ char *buffer;
+ char *end_of_line;
+ int chars_read;
+ Boolean ret_status;
+ Int32 read_status;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ buffer = allocate_buffer ((MAX_IP_LINE_LEN + 1), "buffer");
+ enc_file->mode = MODE_TEXT;
+ enc_file->format = DEF_TEXT_FMT;
+ enc_file->max_rec_len = INV_RECORD_LEN;
+ enc_file->lng_rec_len = INV_RECORD_LEN;
+ enc_file->line_no = 0;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ enc_file->file_ptr = f_open_in (enc_file);
+
+ if (enc_file->file_ptr == (FILE *) NULL)
+ {
+ ERRORMSG_1 ("error opening encoding table file `%s'",
+ enc_file->file_spec);
+ vv_exit ();
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ encode_table[0] = '\0';
+ ret_status = TRUE;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ for (;;)
+ {
+ chars_read = strlen ((char *) encode_table);
+ enc_file->line_no++;
+
+ read_status = read_line ((Int32) MAX_IP_LINE_LEN, buffer, enc_file);
+
+ if (read_status < 0L)
+ {
+ if (feof (enc_file->file_ptr) != 0)
+ {
+ break;
+ }
+
+ ERRORMSG ("error reading encoding table file");
+ show_file_context (enc_file, NULL);
+ explain_error ();
+ ret_status = FALSE;
+ break;
+ }
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ buffer[MAX_IP_LINE_LEN - 1] = (char) '\0';
+ end_of_line = STRCHR (buffer, '\n');
+
+ if (end_of_line != NULL)
+ {
+ *end_of_line = '\0';
+ }
+ chars_read += strlen (buffer);
+
+ if (chars_read <= enc_tbl_len)
+ {
+ strcat ((char *) encode_table, buffer);
+ }
+ else
+ {
+ ERRORMSG_1 ("too many characters in encoding table file: %d",
+ chars_read);
+ show_file_context (enc_file, buffer);
+ ret_status = FALSE;
+ break;
+ }
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ if (chars_read < enc_tbl_len)
+ {
+ ERRORMSG_1 ("not enough characters in encoding table file: %d",
+ chars_read);
+ ret_status = FALSE;
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ f_close (enc_file);
+ free (buffer);
+ return (ret_status);
+} /* rd_enc_tbl */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** rd_xlt_tbl
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ Int16 rd_xlt_tbl (Header_Struct *xlt_hdr_array,
+ File_Info *xlt_file,
+ Xlt_Struct *xlt_tbl_struct)
+#else /* NOT (ANSI_SYNTAX) */
+ Int16 rd_xlt_tbl (xlt_hdr_array, xlt_file, xlt_tbl_struct)
+ Header_Struct *xlt_hdr_array;
+ File_Info *xlt_file;
+ Xlt_Struct *xlt_tbl_struct;
+#endif /* (ANSI_SYNTAX) */
+{
+ char buffer[MAX_IP_LINE_LEN + 1];
+ Int32 bytes_read;
+ int chars_read;
+ char *comment;
+ char *end_of_line;
+ int fields_read;
+ Int16 hdr_no;
+ Boolean ret_status;
+ Int16 subst_char;
+ char *xlt_buffer;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ xlt_file->mode = MODE_TEXT;
+ xlt_file->format = DEF_TEXT_FMT;
+ xlt_file->max_rec_len = INV_RECORD_LEN;
+ xlt_file->lng_rec_len = INV_RECORD_LEN;
+ xlt_file->line_no = 0;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ xlt_file->file_ptr = f_open_in (xlt_file);
+
+ if (xlt_file->file_ptr == (FILE *) NULL)
+ {
+ FATALMSG_1 ("error opening translation file `%s'",
+ xlt_file->file_spec);
+ vv_exit ();
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ xlt_buffer = allocate_buffer (XLT_BUFFER_SIZE, "xlt_buffer");
+ xlt_buffer[0] = 0;
+ ret_status = TRUE;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ while (ret_status == TRUE)
+ {
+ chars_read = strlen (xlt_buffer);
+ xlt_file->line_no++;
+ bytes_read = read_line ((Int32) MAX_IP_LINE_LEN, buffer, xlt_file);
+
+ if (bytes_read < 0)
+ {
+ if (feof (xlt_file->file_ptr) != 0)
+ {
+ break;
+ }
+ ERRORMSG ("error reading translation file");
+ show_file_context (xlt_file, NULL);
+ explain_error ();
+ ret_status = FALSE;
+ continue;
+ }
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ buffer[MAX_IP_LINE_LEN - 2] = (char) '\n';
+ buffer[MAX_IP_LINE_LEN - 1] = (char) '\0';
+ comment = STRCHR (buffer, XLT_COMMENT_CHAR);
+
+ if (comment != NULL)
+ {
+ *comment = '\n';
+ *(++comment) = '\0';
+ }
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ end_of_line = STRCHR (buffer, '\n');
+
+ if (end_of_line != NULL)
+ {
+ *end_of_line = ' ';
+ }
+ chars_read += strlen (buffer);
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ if ((xlt_hdr_array[HDR_XLT_FROM].present != TRUE)
+ || (xlt_hdr_array[HDR_XLT_SUBSTCHAR].present != TRUE)
+ || (xlt_hdr_array[HDR_XLT_TO].present != TRUE))
+ {
+ hdr_no = header_type (xlt_file, buffer, xlt_hdr_array);
+
+ switch (hdr_no)
+ {
+ case HDR_UNKNOWN:
+ break;
+ case HDR_XLT_FROM:
+ case HDR_XLT_SUBSTCHAR:
+ case HDR_XLT_TO:
+ if (xlt_hdr_array[hdr_no].present == TRUE)
+ {
+ ERRORMSG_1 ("header `%s' repeated in translation file",
+ xlt_hdr_array[hdr_no].h_string);
+ show_file_context (xlt_file, buffer);
+ ret_status = FALSE;
+ }
+ else
+ {
+ parse_header (xlt_file, buffer, &xlt_hdr_array[hdr_no]);
+ }
+ break;
+ default:
+ INTERNAL_ERROR ("rd_xlt_file");
+ break;
+ }
+ continue;
+ }
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ fields_read = sscanf (xlt_hdr_array[HDR_XLT_SUBSTCHAR].value, "%hd",
+ &subst_char);
+ if ((fields_read != 1) || (subst_char < 0) || (subst_char > 255))
+ {
+ ERRORMSG_2 ("invalid `%s' header value in translation file: `%s'",
+ xlt_hdr_array[HDR_XLT_SUBSTCHAR].h_string,
+ xlt_hdr_array[HDR_XLT_SUBSTCHAR].value);
+ ret_status = FALSE;
+ break;
+ }
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ if (chars_read <= XLT_BUFFER_SIZE)
+ {
+ strcat ((char *) xlt_buffer, buffer);
+ }
+ else
+ {
+ ERRORMSG_1 ("too many characters in translation file: %d",
+ chars_read);
+ show_file_context (xlt_file, buffer);
+ ret_status = FALSE;
+ break;
+ }
+ }
+ f_close (xlt_file);
+
+ /*-
+ **------------------------------------------------------------------------
+ ** The contents of the translation file have been read, now parse them to
+ ** create the translation table.
+ **------------------------------------------------------------------------
+ */
+ if (xlt_hdr_array[HDR_XLT_FROM].present != TRUE)
+ {
+ ERRORMSG_1 ("header `%s' not found in translation file",
+ xlt_hdr_array[HDR_XLT_FROM].h_string);
+ ret_status = FALSE;
+ }
+ else if (xlt_hdr_array[HDR_XLT_SUBSTCHAR].present != TRUE)
+ {
+ ERRORMSG_1 ("header `%s' not found in translation file",
+ xlt_hdr_array[HDR_XLT_SUBSTCHAR].h_string);
+ ret_status = FALSE;
+ }
+ else if (xlt_hdr_array[HDR_XLT_TO].present != TRUE)
+ {
+ ERRORMSG_1 ("header `%s' not found in translation file",
+ xlt_hdr_array[HDR_XLT_TO].h_string);
+ ret_status = FALSE;
+ }
+ else
+ {
+ xlt_tbl_struct->xlt_from = STRDUP (xlt_hdr_array[HDR_XLT_FROM].value);
+ xlt_tbl_struct->xlt_to = STRDUP (xlt_hdr_array[HDR_XLT_TO].value);
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ ** The contents of the translation file have been read, now parse them to
+ ** create the translation table.
+ **------------------------------------------------------------------------
+ */
+ if (ret_status == TRUE)
+ {
+ ret_status = pars_xlt_tbl (xlt_buffer, xlt_tbl_struct, subst_char);
+ }
+
+ free (xlt_buffer);
+ return (ret_status);
+} /* rd_xlt_tbl */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** set_dec_tbl
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ void set_dec_tbl (CONST Int16 enc_tbl_len,
+ CONST char *encode_table,
+ CONST Int16 dec_tbl_len,
+ Int16 *decode_table)
+#else /* NOT (ANSI_SYNTAX) */
+ void set_dec_tbl (enc_tbl_len, encode_table,
+ dec_tbl_len, decode_table)
+ CONST Int16 enc_tbl_len;
+ CONST char *encode_table;
+ CONST Int16 dec_tbl_len;
+ Int16 *decode_table;
+#endif /* (ANSI_SYNTAX) */
+{
+ Int16 i;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ for (i = 0; i < dec_tbl_len; i++)
+ {
+ decode_table[i] = INV_TABLE_ENTRY;
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ for (i = 0; i < enc_tbl_len; i++)
+ {
+ if (decode_table[encode_table[i]] == INV_TABLE_ENTRY)
+ {
+ decode_table[encode_table[i]] = i;
+ }
+ else
+ {
+ ERRORMSG_1 ("invalid encoding table - character 0x%02X duplicated",
+ encode_table[i]);
+ vv_exit ();
+ }
+ }
+} /* set_dec_tbl */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** set_xlt_tbl
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ void set_xlt_tbl (File_Info *xlt_file,
+ Xlt_Struct *xlt_table,
+ Header_Struct *xlt_hdr_array)
+#else /* NOT (ANSI_SYNTAX) */
+ void set_xlt_tbl (xlt_file, xlt_table, xlt_hdr_array)
+ File_Info *xlt_file;
+ Xlt_Struct *xlt_table;
+ Header_Struct *xlt_hdr_array;
+#endif /* (ANSI_SYNTAX) */
+{
+ Int16 status;
+
+ /*-
+ **------------------------------------------------------------------------
+ ** If an extension has not been provided, use the default extension
+ ** for translation table files.
+ **------------------------------------------------------------------------
+ */
+#if (STICKY_DEFAULTS)
+ apply_defaults (NULL, DEF_XLT_EXT, xlt_file->file_spec);
+#endif /* (STICKY_DEFAULTS) */
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ xlt_table->xlt_from = NULL;
+ xlt_table->xlt_to = NULL;
+ status = rd_xlt_tbl (xlt_hdr_array, xlt_file, xlt_table);
+
+ if (status < 0)
+ {
+ FATALMSG_1 ("error reading translation table file `%s'",
+ xlt_file->file_spec);
+ vv_exit ();
+ }
+
+ LOGMSG_1 ("\nTranslation table source: %s", xlt_file->file_spec);
+ LOGMSG_2 ("Translation performed: `%s' to `%s'",
+ xlt_table->xlt_from, xlt_table->xlt_to);
+
+} /* set_xlt_tbl */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** show_file_context
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ void show_file_context (CONST File_Info *file,
+ CONST char *file_text)
+#else /* NOT (ANSI_SYNTAX) */
+ void show_file_context (file, file_text)
+ CONST File_Info *file;
+ CONST char *file_text;
+#endif /* (ANSI_SYNTAX) */
+{
+ if (file_text != NULL)
+ {
+ INFOMSG_2 ("context: line %ld of file `%s'",
+ file->line_no, file->file_spec);
+ INFOMSG_1 ("text: `%s'", file_text);
+ }
+ else
+ {
+ INFOMSG_2 ("context: line %ld of file `%s'",
+ file->line_no, file->file_spec);
+ }
+} /* show_file_context */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** vstrchr
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ char *vstrchr (CONST char *str, CONST int ch)
+#else /* NOT (ANSI_SYNTAX) */
+ char *vstrchr (str, ch)
+ CONST char *str;
+ CONST int ch;
+#endif /* (ANSI_SYNTAX) */
+{
+ int i;
+
+ for (i = 0; str[i] != '\0'; i++)
+ {
+ if (str[i] == (char) ch)
+ {
+ return ((char *) &str[i]);
+ }
+ }
+ return (NULL);
+} /* vstrchr */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** vstricmp
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ int vstricmp (CONST char *str1, CONST char *str2)
+#else /* NOT (ANSI_SYNTAX) */
+ int vstricmp (str1, str2)
+ CONST char *str1;
+ CONST char *str2;
+#endif /* (ANSI_SYNTAX) */
+{
+ int i;
+ int u1;
+ int u2;
+
+ i = 0;
+ while (((str1[i] != '\0') || (str2[i] != '\0')))
+ {
+ u1 = (int) TOUPPER (str1[i]);
+ u2 = (int) TOUPPER (str2[i]);
+ if (u1 != u2)
+ {
+ return (u1 - u2);
+ }
+ i++;
+ }
+ return (0);
+} /* vstricmp */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** vstrncmp
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ int vstrncmp (CONST char *str1, CONST char *str2,
+ CONST int max_chars)
+#else /* NOT (ANSI_SYNTAX) */
+ int vstrncmp (str1, str2, max_chars)
+ CONST char *str1;
+ CONST char *str2;
+ CONST int max_chars;
+#endif /* (ANSI_SYNTAX) */
+{
+ int i;
+
+ i = 0;
+ while ((i < max_chars) && ((str1[i] != '\0') || (str2[i] != '\0')))
+ {
+ if (str1[i] != str2[i])
+ {
+ return ((int) (str1[i] != str2[i]));
+ }
+ i++;
+ }
+ return (0);
+} /* vstrncmp */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** vstrnicmp
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ int vstrnicmp (CONST char *str1, CONST char *str2,
+ CONST int max_chars)
+#else /* NOT (ANSI_SYNTAX) */
+ int vstrnicmp (str1, str2, max_chars)
+ CONST char *str1;
+ CONST char *str2;
+ CONST int max_chars;
+#endif /* (ANSI_SYNTAX) */
+{
+ int i;
+ int u1;
+ int u2;
+
+ i = 0;
+ while ((i < max_chars) && ((str1[i] != '\0') || (str2[i] != '\0')))
+ {
+ u1 = (int) TOUPPER (str1[i]);
+ u2 = (int) TOUPPER (str2[i]);
+ if (u1 != u2)
+ {
+ return (u1 - u2);
+ }
+ i++;
+ }
+ return (0);
+} /* vstrnicmp */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** vstrrchr
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ char *vstrrchr (CONST char *str, CONST int ch)
+#else /* NOT (ANSI_SYNTAX) */
+ char *vstrrchr (str, ch)
+ CONST char *str;
+ CONST int ch;
+#endif /* (ANSI_SYNTAX) */
+{
+ int i;
+ int length;
+
+ length = strlen (str);
+
+ for (i = (length - 1); i >= 0; i--)
+ {
+ if (str[i] == (char) ch)
+ {
+ return ((char *) &str[i]);
+ }
+ }
+ return (NULL);
+} /* vstrrchr */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** vstrrstr
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ char *vstrrstr (CONST char *str, CONST char *search_str)
+#else /* NOT (ANSI_SYNTAX) */
+ char *vstrrstr (str, search_str)
+ CONST char *str;
+ CONST char *search_str;
+#endif /* (ANSI_SYNTAX) */
+{
+ int i;
+ int length;
+
+ length = strlen (str);
+
+ for (i = (length - 1); i >= 0; i--)
+ {
+ if (vstrchr (search_str, str[i]) != NULL)
+ {
+ return ((char *) &str[i]);
+ }
+ }
+ return (NULL);
+} /* vstrrstr */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** vstrstr
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ char *vstrstr (CONST char *str, CONST char *search_str)
+#else /* NOT (ANSI_SYNTAX) */
+ char *vstrstr (str, search_str)
+ CONST char *str;
+ CONST char *search_str;
+#endif /* (ANSI_SYNTAX) */
+{
+ int idx;
+
+ for (idx = 0; str[idx] != '\0'; idx++)
+ {
+ if (vstrchr (search_str, str[idx]) != NULL)
+ {
+ return ((char *) &str[idx]);
+ }
+ }
+ return (NULL);
+} /* vstrstr */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** vv_timestamp
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ char *vv_timestamp (TIME_T time_val)
+#else /* NOT (ANSI_SYNTAX) */
+ char *vv_timestamp (time_val)
+ TIME_T time_val;
+#endif /* (ANSI_SYNTAX) */
+{
+ static char time_string[32]; /* YYYY-MM-DD-HH:MM:SS GMT */
+ int year;
+ int month;
+ int mday;
+ int hours;
+ int mins;
+ int secs;
+ TIME_T day_secs;
+ TIME_T days_this_month;
+ TIME_T year_secs;
+ TIME_T leap_year_secs;
+ TIME_T this_year_secs;
+
+ /*-
+ **------------------------------------------------------------------------
+ ** We can't cope with times before 1-Jan-1970 00:00:00.
+ **------------------------------------------------------------------------
+ */
+ DEBUG_1 ("vv_timestamp: time_t value provided = %ld", time_val);
+
+ if (time_val < 0)
+ {
+ WARNMSG_1 ("time_t value < 0 (%ld) - converted to 0\n", time_val);
+ time_val = 0;
+ }
+
+ day_secs = 86400L;
+ year_secs = 365L * 86400L;
+ leap_year_secs = year_secs + 86400L;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ for (year = 1970;; year++)
+ {
+
+ if (LEAPYEAR (year))
+ {
+ this_year_secs = leap_year_secs;
+ }
+ else
+ {
+ this_year_secs = year_secs;
+ }
+
+ /*-
+ **--------------------------------------------------------------------
+ **
+ **--------------------------------------------------------------------
+ */
+ if (time_val >= this_year_secs)
+ {
+ time_val -= this_year_secs;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ for (month = 0;; month++)
+ {
+ days_this_month = month_days[month];
+
+ if ((month == 1) && (LEAPYEAR (year)))
+ {
+ ++days_this_month;
+ }
+
+ if (time_val >= (day_secs * days_this_month))
+ {
+ time_val -= day_secs * days_this_month;
+ }
+ else
+ {
+ break;
+ }
+ }
+ ++month;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ mday = (int) (time_val / day_secs);
+ ++mday;
+ time_val = time_val % day_secs;
+
+ hours = (int) (time_val / 3600L);
+ time_val = time_val % 3600L;
+
+ mins = (int) (time_val / 60L);
+ time_val = time_val % 60L;
+
+ secs = (int) time_val;
+
+ /*-
+ **------------------------------------------------------------------------
+ **
+ **------------------------------------------------------------------------
+ */
+ sprintf (time_string, VV_TIMESTAMP_FORMAT,
+ year, month, mday, hours, mins, secs);
+ strcat (time_string, " GMT");
+ DEBUG_1 ("vv_timestamp: VVE timestamp string return value = `%s'\n",
+ time_string);
+ return (time_string);
+} /* vv_timestamp */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** vstrdup
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ char *vstrdup (CONST char *str)
+#else /* NOT (ANSI_SYNTAX) */
+ char *vstrdup (str)
+ CONST char *str;
+#endif /* (ANSI_SYNTAX) */
+{
+ char *tmp_ptr;
+ SIZE_T no_bytes;
+
+ no_bytes = (SIZE_T) (strlen (str) + 1) * sizeof (char);
+ tmp_ptr = (char *) malloc (no_bytes);
+
+ if (tmp_ptr == NULL)
+ {
+ FATALMSG_2 ("couldn't allocate %d bytes to copy string `%s'",
+ no_bytes, str);
+ vv_exit ();
+ }
+ strcpy (tmp_ptr, str);
+ return (tmp_ptr);
+} /* vstrdup */
+
+
+
+/*-
+**============================================================================
+**
+** FUNCTION
+**
+** vstrtrws
+**
+** DESCRIPTION
+**
+** [tbs]
+**
+** INPUT PARAMETERS
+**
+** [tbs]
+**
+** OUTPUT PARAMETERS
+**
+** [tbs]
+**
+** RETURN VALUE
+**
+** [tbs]
+**
+**============================================================================
+*/
+#if (ANSI_SYNTAX)
+ char *vstrtrws (char *str)
+#else /* NOT (ANSI_SYNTAX) */
+ char *vstrtrws (str)
+ char *str;
+#endif /* (ANSI_SYNTAX) */
+{
+ char *end_ptr;
+ int length;
+
+ if ((str == NULL) || (*str == '\0'))
+ {
+ return (str);
+ }
+
+ length = strlen (str);
+ end_ptr = str + length - 1;
+
+ while ((end_ptr >= str) && (isspace (*end_ptr)))
+ {
+ *end_ptr = '\0';
+ --end_ptr;
+ }
+ return (str);
+} /* vstrtrws */