/*- ****************************************************************************** ****************************************************************************** ** ** ARCHIVE HEADER INFORMATION ** ** @C-file{ ** FILENAME = "vveparse.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 ** ** chk_skipfrom [tbs] ** getv_characterset - ** getv_decodeversion - ** getv_format - ** getv_mode - ** getv_operatingsystem - ** getv_reclen - ** getv_timestamp - ** parse_begin_header - ** rd_next_line - ** ** 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$"; /*- **---------------------------------------------------------------------------- ** Standard include files **---------------------------------------------------------------------------- */ #include /*- **---------------------------------------------------------------------------- ** Include files **---------------------------------------------------------------------------- */ #include "checkos.h" #include "machine.h" #include "local.h" #include "globals.h" #include "specific.h" #include "vvutils.h" #include "vveparse.h" /*- **============================================================================ ** ** FUNCTION ** ** chk_skipfrom ** ** DESCRIPTION ** ** [tbs] ** ** INPUT PARAMETERS ** ** [tbs] ** ** OUTPUT PARAMETERS ** ** [tbs] ** ** RETURN VALUE ** ** [tbs] ** **============================================================================ */ #if (ANSI_SYNTAX) Boolean chk_skipfrom (CONST char *line_ptr, CONST Int16 part_needed, CONST char *hdr_file_spec, CONST Header_Struct *skipfrom_hdr, File_Info *ip_file) #else /* NOT (ANSI_SYNTAX) */ Boolean chk_skipfrom (line_ptr, part_needed, hdr_file_spec, skipfrom_hdr, ip_file) CONST char *line_ptr; CONST Int16 part_needed; CONST char *hdr_file_spec; CONST Header_Struct *skipfrom_hdr; File_Info *ip_file; #endif /* (ANSI_SYNTAX) */ { char pt_file_spec[MAX_IP_LINE_LEN + 1]; Int16 pt_no; int fields_read; strcpy (pt_file_spec, ""); /*- **------------------------------------------------------------------------ ** Header syntax: skipfrom part-no file-spec ** ** The file-spec parameter may include whitespace, but leading or trailing ** whitespace will be ignored. The Unix file "one two three" would be ** supported with a skipfrom header like: ** ** skipfrom 1 one two three **------------------------------------------------------------------------ */ fields_read = sscanf (line_ptr, "%*s %hd %[^\n]", &pt_no, pt_file_spec); if (fields_read < 2) { FATALMSG_1 ("error parsing `%s' header value", skipfrom_hdr->h_string); show_file_context (ip_file, line_ptr); vv_exit (); } vstrtrws (pt_file_spec); /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ if ((pt_no == part_needed) && (STRCMP (hdr_file_spec, pt_file_spec) == 0)) { return (TRUE); } return (FALSE); } /* chk_skipfrom */ /*- **============================================================================ ** ** FUNCTION ** ** getv_characterset ** ** DESCRIPTION ** ** [tbs] ** ** INPUT PARAMETERS ** ** [tbs] ** ** OUTPUT PARAMETERS ** ** [tbs] ** ** RETURN VALUE ** ** [tbs] ** **============================================================================ */ #if (ANSI_SYNTAX) void getv_characterset ( CONST Header_Struct *characterset_hdr, char **character_set) #else /* NOT (ANSI_SYNTAX) */ void getv_characterset (characterset_hdr, character_set) CONST Header_Struct *characterset_hdr; char **character_set; #endif /* (ANSI_SYNTAX) */ { /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ if (characterset_hdr->present != TRUE) { *character_set = STRDUP (VV_CHARACTERSET); LOGMSG ("VVE character set: not recorded"); WARNMSG ("VVE file character set was not recorded"); INFOMSG_1 ("local character set `%s' assumed", VV_CHARACTERSET); } else { *character_set = STRDUP (characterset_hdr->value); LOGMSG_1 ("VVE character set: %s", *character_set); } } /* getv_characterset*/ /*- **============================================================================ ** ** FUNCTION ** ** getv_decodeversion ** ** DESCRIPTION ** ** [tbs] ** ** INPUT PARAMETERS ** ** [tbs] ** ** OUTPUT PARAMETERS ** ** [tbs] ** ** RETURN VALUE ** ** [tbs] ** **============================================================================ */ #if (ANSI_SYNTAX) void getv_decodeversion ( CONST Header_Struct *decodeversion_hdr, Int16 *decode_version) #else /* NOT (ANSI_SYNTAX) */ void getv_decodeversion (decodeversion_hdr, decode_version) CONST Header_Struct *decodeversion_hdr; Int16 *decode_version; #endif /* (ANSI_SYNTAX) */ { int fields_read; /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ *decode_version = 0; if (decodeversion_hdr->present != TRUE) { LOGMSG ("VVE minimum decode version: not recorded"); return; } fields_read = sscanf (decodeversion_hdr->value, "%hd", decode_version); if (fields_read != 1) { ERRORMSG_2 ("Error parsing `%s' header value: `%s'", decodeversion_hdr->h_string, decodeversion_hdr->value); } else { LOGMSG_1 ("VVE minimum decode version: %d.0", *decode_version); } } /* getv_decodeversion */ /*- **============================================================================ ** ** FUNCTION ** ** getv_format ** ** DESCRIPTION ** ** [tbs] ** ** INPUT PARAMETERS ** ** [tbs] ** ** OUTPUT PARAMETERS ** ** [tbs] ** ** RETURN VALUE ** ** [tbs] ** **============================================================================ */ #if (ANSI_SYNTAX) void getv_format (CONST Header_Struct *format_hdr, CONST char *format_str_array[], File_Info *vve_file) #else /* NOT (ANSI_SYNTAX) */ void getv_format (format_hdr, format_str_array, vve_file) CONST Header_Struct *format_hdr; CONST char *format_str_array[]; File_Info *vve_file; #endif /* (ANSI_SYNTAX) */ { Int16 format_no; /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ vve_file->format = INV_FORMAT; if (format_hdr->present != TRUE) { LOGMSG ("VVE format: not recorded"); return; } /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ format_no = lookup_key (format_str_array, format_hdr->value, NO_ABBREVIATIONS, CASE_INSENSITIVE); switch (format_no) { case FMT_FIXED: case FMT_STREAM: case FMT_VARIABLE: LOGMSG_1 ("VVE format: %s", format_str_array[format_no]); vve_file->format = format_no; break; default: ERRORMSG_2 ("invalid `%s' header value: `%s'", format_hdr->h_string, format_hdr->value); break; } return; } /* getv_format */ /*- **============================================================================ ** ** FUNCTION ** ** getv_mode ** ** DESCRIPTION ** ** [tbs] ** ** INPUT PARAMETERS ** ** [tbs] ** ** OUTPUT PARAMETERS ** ** [tbs] ** ** RETURN VALUE ** ** [tbs] ** **============================================================================ */ #if (ANSI_SYNTAX) void getv_mode (CONST Header_Struct *mode_hdr, CONST char *mode_str_array[], File_Info *vve_file) #else /* NOT (ANSI_SYNTAX) */ void getv_mode (mode_hdr, mode_str_array, vve_file) CONST Header_Struct *mode_hdr; CONST char *mode_str_array[]; File_Info *vve_file; #endif /* (ANSI_SYNTAX) */ { Int16 mode_no; /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ vve_file->mode = INV_MODE; if (mode_hdr->present != TRUE) { LOGMSG ("\nVVE mode: not recorded"); return; } /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ mode_no = lookup_key (mode_str_array, mode_hdr->value, NO_ABBREVIATIONS, CASE_INSENSITIVE); switch (mode_no) { case MODE_BINARY: case MODE_TEXT: LOGMSG_1 ("\nVVE mode: %s", mode_str_array[mode_no]); vve_file->mode = mode_no; break; default: ERRORMSG_2 ("invalid `%s' header value: `%s'", mode_hdr->h_string, mode_hdr->value); break; } return; } /* getv_mode */ /*- **============================================================================ ** ** FUNCTION ** ** getv_operatingsystem ** ** DESCRIPTION ** ** [tbs] ** ** INPUT PARAMETERS ** ** [tbs] ** ** OUTPUT PARAMETERS ** ** [tbs] ** ** RETURN VALUE ** ** [tbs] ** **============================================================================ */ #if (ANSI_SYNTAX) void getv_operatingsystem ( CONST Header_Struct *operatingsystem_hdr, char **operating_system) #else /* NOT (ANSI_SYNTAX) */ void getv_operatingsystem (operatingsystem_hdr, operating_system) CONST Header_Struct *operatingsystem_hdr; char **operating_system; #endif /* (ANSI_SYNTAX) */ { /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ if (operatingsystem_hdr->present != TRUE) { *operating_system = STRDUP (VV_OPERATING_SYSTEM); LOGMSG ("VVE operating system: not recorded"); WARNMSG ("VVE file operating system was not recorded"); INFOMSG_1 ("local operating system `%s' assumed", VV_OPERATING_SYSTEM); } else { *operating_system = STRDUP (operatingsystem_hdr->value); LOGMSG_1 ("VVE operating system: %s", *operating_system); } } /* getv_operatingsystem */ /*- **============================================================================ ** ** FUNCTION ** ** getv_reclen ** ** DESCRIPTION ** ** [tbs] ** ** NOTE: define record length meanings ** ** INPUT PARAMETERS ** ** [tbs] ** ** OUTPUT PARAMETERS ** ** [tbs] ** ** RETURN VALUE ** ** [tbs] ** **============================================================================ */ #if (ANSI_SYNTAX) void getv_reclen (CONST Header_Struct *reclen_hdr, File_Info *vve_file) #else /* NOT (ANSI_SYNTAX) */ void getv_reclen (reclen_hdr, vve_file) CONST Header_Struct *reclen_hdr; File_Info *vve_file; #endif /* (ANSI_SYNTAX) */ { int no_values; char dummy1[MAX_IP_LINE_LEN + 1]; char dummy2[MAX_IP_LINE_LEN + 1]; int status; /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ vve_file->max_rec_len = INV_RECORD_LEN; vve_file->lng_rec_len = INV_RECORD_LEN; if (reclen_hdr->present != TRUE) { LOGMSG ("VVE longest record length: not recorded"); LOGMSG ("VVE maximum record length: not recorded"); return; } /*- **------------------------------------------------------------------------ ** Check how many values are with the recordlength header. There should ** be one or two. **------------------------------------------------------------------------ */ no_values = sscanf (reclen_hdr->value, "%s %s", dummy1, dummy2); switch (no_values) { /*- **-------------------------------------------------------------------- ** **-------------------------------------------------------------------- */ case 2: status = sscanf (dummy2, "%ld", &vve_file->lng_rec_len); if ((status != 1) || (vve_file->lng_rec_len < 0) || (vve_file->lng_rec_len > MAX_VV_RECORD_LEN)) { vve_file->lng_rec_len = INV_RECORD_LEN; ERRORMSG_2 ("Invalid second value of `%s' header: `%s'", reclen_hdr->h_string, reclen_hdr->value); } else { LOGMSG_1 ("VVE longest record length: %ld", vve_file->lng_rec_len); } break; /*- **-------------------------------------------------------------------- ** **-------------------------------------------------------------------- */ case 1: status = sscanf (dummy1, "%ld", &vve_file->max_rec_len); if ((status != 1) || (vve_file->max_rec_len < 0) || (vve_file->max_rec_len > MAX_VV_RECORD_LEN)) { vve_file->max_rec_len = INV_RECORD_LEN; ERRORMSG_2 ("Invalid first value of `%s' header: `%s'", reclen_hdr->h_string, reclen_hdr->value); } else { LOGMSG_1 ("VVE maximum record length: %ld", vve_file->max_rec_len); } break; /*- **-------------------------------------------------------------------- ** **-------------------------------------------------------------------- */ default: ERRORMSG_2 ("Error parsing `%s' header value: `%s'", reclen_hdr->h_string, reclen_hdr->value); break; } } /* getv_reclen */ /*- **============================================================================ ** ** FUNCTION ** ** getv_timestamp ** ** DESCRIPTION ** ** [tbs] ** ** INPUT PARAMETERS ** ** [tbs] ** ** OUTPUT PARAMETERS ** ** [tbs] ** ** RETURN VALUE ** ** [tbs] ** **============================================================================ */ #if (ANSI_SYNTAX) void getv_timestamp (CONST Header_Struct *timestamp_hdr, File_Info *vve_file) #else /* NOT (ANSI_SYNTAX) */ void getv_timestamp (timestamp_hdr, vve_file) CONST Header_Struct *timestamp_hdr; File_Info *vve_file; #endif /* (ANSI_SYNTAX) */ { TIME_T timestamp; /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ vve_file->mod_time = INV_TIMESTAMP; if (timestamp_hdr->present != TRUE) { LOGMSG ("VVE timestamp: not recorded"); return; } /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ timestamp = pars_time (timestamp_hdr->value); if (timestamp != INV_TIMESTAMP) { vve_file->mod_time = timestamp; LOGMSG_1 ("VVE timestamp: %s", vv_timestamp (vve_file->mod_time)); } else { ERRORMSG_2 ("invalid `%s' header value: `%s'", timestamp_hdr->h_string, timestamp_hdr->value); } } /* getv_timestamp */ /*- **============================================================================ ** ** FUNCTION ** ** parse_begin_header ** ** DESCRIPTION ** ** [tbs] ** ** INPUT PARAMETERS ** ** [tbs] ** ** OUTPUT PARAMETERS ** ** [tbs] ** ** RETURN VALUE ** ** [tbs] ** **============================================================================ */ #if (ANSI_SYNTAX) void parse_begin_header (CONST char *line_ptr, CONST File_Info *ip_file, CONST Int16 decoding_type, Header_Struct *hdr_struct, char **hdr_file_spec) #else /* NOT (ANSI_SYNTAX) */ void parse_begin_header (line_ptr, ip_file, decoding_type, hdr_struct, hdr_file_spec) CONST char *line_ptr; CONST File_Info *ip_file; CONST Int16 decoding_type; Header_Struct *hdr_struct; char **hdr_file_spec; #endif /* (ANSI_SYNTAX) */ { char *begin_value_buffer; int fields_read; *hdr_file_spec = NULL; begin_value_buffer = allocate_buffer ((MAX_IP_LINE_LEN + 1), "begin_value_buffer"); /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ if (decoding_type == VV_DECODING) { fields_read = sscanf (line_ptr, "%*s %[^\n]", begin_value_buffer); /*- **-------------------------------------------------------------------- ** **-------------------------------------------------------------------- */ if (fields_read == 1) { *hdr_file_spec = STRDUP (begin_value_buffer); } else { FATALMSG_1 ("error parsing value of `%s' header", hdr_struct->h_string); show_file_context (ip_file, line_ptr); vv_exit (); } } /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ else { fields_read = sscanf (line_ptr, "%*s %*s %[^\n]", begin_value_buffer); if (fields_read == 1) { *hdr_file_spec = STRDUP (begin_value_buffer); } else { FATALMSG_1 ("error parsing value of UU/XXcode `%s' header", hdr_struct->h_string); show_file_context (ip_file, line_ptr); vv_exit (); } } vstrtrws (*hdr_file_spec); hdr_struct->present = TRUE; free (begin_value_buffer); } /* parse_begin_header */ /*- **============================================================================ ** ** FUNCTION ** ** rd_next_line ** ** DESCRIPTION ** ** [tbs] ** ** INPUT PARAMETERS ** ** [tbs] ** ** OUTPUT PARAMETERS ** ** [tbs] ** ** RETURN VALUE ** ** [tbs] ** **============================================================================ */ #if (ANSI_SYNTAX) char *rd_next_line (CONST Int32 max_chars, CONST char *vve_line_prefix, char *buffer, File_Info *ip_file, Int32 *byte_count) #else /* NOT (ANSI_SYNTAX) */ char *rd_next_line (max_chars, vve_line_prefix, buffer, ip_file, byte_count) CONST Int32 max_chars; CONST char *vve_line_prefix; char *buffer; File_Info *ip_file; Int32 *byte_count; #endif /* (ANSI_SYNTAX) */ { char *eol_ptr; Int32 status; int pfx_len; /*- **------------------------------------------------------------------------ ** **------------------------------------------------------------------------ */ for (;;) { status = read_line (max_chars, buffer, ip_file); buffer[(SIZE_T) max_chars - 1] = '\0'; if (status < 0) { return (NULL); } /*- **-------------------------------------------------------------------- ** **-------------------------------------------------------------------- */ *byte_count += strlen (buffer); eol_ptr = STRRCHR (buffer, '\n'); if (eol_ptr != NULL) { *eol_ptr = '\0'; } else { eol_ptr = &buffer[(SIZE_T) (max_chars - 1)]; } ip_file->line_no++; /*- **-------------------------------------------------------------------- ** If there's a line prefix, check that it's here. **-------------------------------------------------------------------- */ if ((vve_line_prefix == NULL) || (*vve_line_prefix == '\0')) { break; } else { pfx_len = strlen (vve_line_prefix); if (STRNCMPI (buffer, vve_line_prefix, (Int16) pfx_len) == 0) { buffer += pfx_len; break; } } } return (buffer); } /* rd_next_line */