/*- ****************************************************************************** ****************************************************************************** ** ** 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 ** ** 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 /*- **---------------------------------------------------------------------------- ** 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 */