Article 2678 of comp.sources.unix:
Path: nntpd.lkg.dec.com!crl.dec.com!crl.dec.com!caen!usenet.cis.ufl.edu!usenet.eel.ufl.edu!news.mathworks.com!uunet!in2.uu.net!news1.digital.com!vixie!vixie!not-for-mail
From: nmm1@cus.cam.ac.uk (Nick Maclaren)
Newsgroups: comp.sources.unix
Subject: v29i020: mvstape - suite of utilities for handling IBM MVS tapes, Part01/09
Date: 4 Aug 1995 15:04:01 -0700
Organization: Vixie Enterprises
Lines: 1674
Sender: vixie@vix.com
Approved: vixie@gw.home.vix.com
Message-ID: <1.807573809.16947@gw.home.vix.com>
NNTP-Posting-Host: gw.home.vix.com

Submitted-By: nmm1@cus.cam.ac.uk (Nick Maclaren)
Posting-Number: Volume 29, Issue 20
Archive-Name: mvstape/part01

From READ_ME...

This suite of programs will read IBM MVS tapes and others with related
formats, with a variety of options for scanning their contents and
extracting their files.  It will handle both IBM Standard Label and
unlabelled tapes (including leading tape mark format), but not ANSI Labelled
tapes, CMS dump tapes etc.

There is also a library of auxiliary functions for unpicking 370 architecture
data formats, which can be used separately from the tape utilities.

It will handle sequential files in almost all MVS formats (i.e. not RECFM=D!),
PDSs in TLS and IEBCOPY formats and simple direct access files in TLS format,
but not IEHMOVE unloaded files, VSAM unloaded files etc.  [TLS is the
University of Cambridge Computing Service Tape Library System format that is
based on IBM Standard Label tapes.]

...
	Nick Maclaren,
	University of Cambridge Computer Laboratory,
	New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
	Email:  nmm1@cam.ac.uk
	Tel.:  +44 1223 334761    Fax:  +44 1223 334679

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 9)."
# Contents:  check.1 check.c command.h control.h ebcdic.h globals.h
#   ibmconv.3c ibmconv.3f ibmconv.h iebcopy.h labels.h loadtape.1
#   loadtape.h mvstape.1 mvstape.h system.h tarpit.h tlsdict.h
#   tlspds.h version.h
# Wrapped by nmm1@ursa.cus.cam.ac.uk on Fri Aug  4 15:43:56 1995
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'check.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'check.1'\"
else
echo shar: Extracting \"'check.1'\" \(644 characters\)
sed "s/^X//" >'check.1' <<'END_OF_FILE'
X.TH CHECK 1L
X.SH NAME
Xcheck \- display the blocks in a `diskized' tape file
X.SH SYNOPSIS
X.BI check " file"
X.SH DESCRIPTION
XThe
X.I check
Xcommand is a debugging utility for the
X.I mvstape
Xsuite of programs.  It prints out the block numbers, lengths and initial
Xcontents (in both text and hexadecimal) for each physical block image in a
X`diskized' tape file.  It is not intended to be installed for use other than by
Xthe person responsible for maintaining the
X.I mvstape
Xsuite.
X.SH AUTHOR
X.I check
Xwas developed by N.M. Maclaren of the University of Cambridge Computing
XService.
X.SH SEE ALSO
Xloadtape(1L), mvstape(1L), readtape(1L), scantape(1L).
END_OF_FILE
if test 644 -ne `wc -c <'check.1'`; then
    echo shar: \"'check.1'\" unpacked with wrong size!
fi
# end of 'check.1'
fi
if test -f 'check.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'check.c'\"
else
echo shar: Extracting \"'check.c'\" \(2870 characters\)
sed "s/^X//" >'check.c' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xcheck.c  -  an auxiliary that prints out a map of a 'diskized' tape file
Xfor debugging purposes. */
X
X
X
X/* WARNING:  the whole program assumes that CHAR_BIT == 8, sizeof(short) >= 2
Xand sizeof(int) >= 4.  There is no point in putting the effort into dealing
Xwith this, given the expected lifetime of this program and the foulness of the
Xjob. */
X
X
X
X#include <ctype.h>
X#include <stdio.h>
X#include <stdlib.h>
X#ifndef EXIT_SUCCESS
X#define EXIT_SUCCESS 0    /* Avoid Sun's broken library */
X#define EXIT_FAILURE 1    /* Avoid Sun's broken library */
X#endif
X#include <string.h>
X
X#include "ebcdic.h"
X
X#define STATIC static           /* Because local symbols may be stripped! */
X
X
X
X#define constant_64K 65536      /* The maximum size of tape blocks */
X
X
X
Xstatic FILE *file;
Xstatic int eof = 0;
X
X
X
XSTATIC void get_string (char *target, const char *data, int length) {
X    int i, k;
X    char *ptr;
X
X    for (i = 0; i < length; ++i) if (data[i] != EBCDIC_SPACE) break;
X    k = 0;
X    for ( ; i < length; ++i) target[k++] = EBCDIC_to_ASCII(data[i]);
X    target[k] = '\0';
X    for (i = 0; i < k; ++i) if (!isprint(target[i])) target[i] = '?';
X    if ((ptr = strchr(target,' ')) != NULL) *ptr = '\0';
X}
X
X
X
XSTATIC int read_block (char *buffer) {
X    int n;
X    BE_int length;
X
X    if ((n = fread(length,1,sizeof(length),file)) == 0 && feof(file)) {
X        eof = 1;
X        return 0;
X    } else if (n != sizeof(length) || n > constant_64K) {
X        fprintf(stderr,"Invalid length field\n");
X        exit(EXIT_FAILURE);
X    }
X    if ((n = get_BE_int(length)) <= 0)
X        return n;
X    else if (fread(buffer,1,n,file) != n) {
X        fprintf(stderr,"Invalid data\n");
X        exit(EXIT_FAILURE);
X    } else
X        return n;
X}
X
X
X
Xint main (int argc, char *argv[]) {
X    int i, k, n;
X    char *buffer, temp[70];
X
X    if (argc != 2) {
X        fprintf(stderr,"Invalid number of arguments\n");
X        exit(EXIT_FAILURE);
X    } else if ((file = fopen(argv[1],"rb")) == NULL) {
X        fprintf(stderr,"Unable to open file\n");
X        exit(EXIT_FAILURE);
X    } else if ((buffer = malloc(constant_64K)) == NULL) {
X        fprintf(stderr,"Unable to get buffer\n");
X        exit(EXIT_FAILURE);
X    }
X    initialize_code_pages();
X
X    for (k = 1; ; ++k) {
X        n = read_block(buffer);
X        if (eof) break;
X        get_string(temp,buffer,(n < 64 ? n : 64));
X        printf("%d (%d): %s\n",k,n,temp);
X        printf("        ");
X        for (i = 0; i < (n < 32 ? n : 32); ++i) {
X            if (i != 0 && i%4 == 0) putchar(' ');
X            printf("%.2x",(unsigned char)buffer[i]);
X        }
X        putchar('\n');
X    }
X    if (fclose(file)) {
X        fprintf(stderr,"Unable to close file\n");
X        exit(EXIT_FAILURE);
X    }
X    return EXIT_SUCCESS;
X}
END_OF_FILE
if test 2870 -ne `wc -c <'check.c'`; then
    echo shar: \"'check.c'\" unpacked with wrong size!
fi
# end of 'check.c'
fi
if test -f 'command.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'command.h'\"
else
echo shar: Extracting \"'command.h'\" \(2444 characters\)
sed "s/^X//" >'command.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xcommand.h  -  everything relating to command decoding and interpretation,
Xexcept the following:  command_args and command_flags, which are needed by
Xmvstape.c that otherwise does not need this header; system-dependent code, 
Xwhich is in system.h and headers called from it. */
X
X
X
X/* The command structure definition and its operand definitions, which includes
Xthe PREFIX, CD, CODE and FORMAT commands in effect for this command. */
X
Xtypedef struct COMMAND {
X    struct COMMAND *command_next;         /* Pointer to next on chain */
X    int command_type,                     /* COPY, APPEND or SKIP */
X        command_opt,                      /* STREAM, LINES or whatever */
X        command_flags;                    /* SKIP and IGNORECC */
X    CODE_PAGE *code_page;                 /* The effective code page */
X    int recfm, lrecl;                     /* Defaults for unlabelled tapes */
X    int seq_from, seq_to;                 /* Non-zero if by sequence number */
X    int prefix_len, dir_len;              /* Used for building default names */
X    char MVSname[MVSnamesize];            /* The MVS name for matching */
X    char UNIXname[UNIXnamesize];          /* The effective 'AS' name */
X} command;
X
X#define command_copy              1
X#define command_append            2
X#define command_skip              3
X
X#define command_opt_stream        1
X#define command_opt_lines         2
X#define command_opt_records       3
X#define command_opt_blocks        4
X#define command_opt_text          11      /* Used only in command.c */
X#define command_opt_binary        12      /* Used only in command.c */
X#define command_opt_data          13      /* Used only in command.c */
X
X#define command_flags_trans       0x01
X#define command_flags_strip       0x02
X#define command_flags_transcc     0x04    /* Not both transcc and ignorecc */
X#define command_flags_ignorecc    0x08    /* Not both transcc and ignorecc */
X#define command_flags_range       0x10    /* I.e. COPY 5-6 or even 5-5 */
X
X
X
X/* The command chain is accessed from both command.c and control.c. */
X
Xextern command *command_chain; /* The chain of matching commands */
X
X
X
X/* External functions that rely upon definitions in this header. */
X
X/* unpick.c external functions. */
X
Xextern int copy_file (int fileno, const command *cmdptr, int block_in_hand);
END_OF_FILE
if test 2444 -ne `wc -c <'command.h'`; then
    echo shar: \"'command.h'\" unpacked with wrong size!
fi
# end of 'command.h'
fi
if test -f 'control.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'control.h'\"
else
echo shar: Extracting \"'control.h'\" \(2621 characters\)
sed "s/^X//" >'control.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xcommand.h  -  everything needed for dataset matching and conversion control
Xexcept the system-dependent code, which is in system.h and headers called from
Xit. */
X
X
X
X#include <setjmp.h>
X
X
X
X/* The PDS structure used for most of the processing, and a temporary one used
Xfor changing from EBCDIC to ASCII order. */
X
Xtypedef struct {
X    char name[PDSnamesize];     /* The name of the member, as a C string */
X    char flags;                 /* Is this is an alias and/or a load module? */
X    int next_entry;             /* The index of the next entry (circular) */
X    int next_offset;            /* For decoding TLS's disgusting format */
X} PDS_STRUCT;
X
X#define PDS_flags_head  0x01    /* It is the head of an alias chain */
X#define PDS_flags_ttrs  0x02    /* It has user TTRs (i.e. is a load module) */
X
Xtypedef struct {
X    char name[PDSnamesize];     /* The name of the member, as a C string */
X    int this_offset;            /* For decoding TLS's disgusting format */
X} PDS_WORK_STRUCT;
X
X
X
X/* Global variables, to avoid them being passed through multiple levels of
Xfunction call. */
X
Xextern int IO_jump_set;         /* Whether IO_error_jump is set */
Xextern jmp_buf IO_error_jump;   /* What to do on ERR_skip */
X
Xextern int following_EOF,       /* Used for diagnostics and recovery */
X    block_length;               /* For I/O communication */
X
Xextern char dataset_name[];     /* "" for anonymous files - important */
Xextern char dataset_date[];     /* In character form, because of < 1970 */
Xextern int dataset_int_date[3]; /* E.g. {1993,7,13} */
Xextern int dataset_seqno,       /* Always set first - uses MVS counting */
X    dataset_recfm, dataset_lrecl, /* May be set by matching */
X    dataset_blksize;            /* Used mainly for messages */
Xextern char dataset_comments[comment_size]; /* Used for messages only */
Xextern int dataset_dsorg, dataset_keylen, /* Used for checking */
X    dataset_KB, dataset_dir_blks, /* Used mainly for messages */
X    dataset_deleted;            /* Deleted or replaced on a TLS tape */
X
Xextern int PDS_member_max,      /* An array is simpler to sort than a chain */
X    PDS_member_count;
Xextern PDS_STRUCT *PDS_member_list; /* This is reused, while still adequate */
Xextern PDS_WORK_STRUCT *PDS_work_list; /* This is also reused */
X
Xextern char UNIX_filename[];    /* The UNIX filename it is being copied to */
X
Xextern char *TLS_next_segment;  /* The next disk block in a tape block */
Xextern char *IEB_next_segment;  /* Similar for IEBCOPY */
END_OF_FILE
if test 2621 -ne `wc -c <'control.h'`; then
    echo shar: \"'control.h'\" unpacked with wrong size!
fi
# end of 'control.h'
fi
if test -f 'ebcdic.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ebcdic.h'\"
else
echo shar: Extracting \"'ebcdic.h'\" \(3281 characters\)
sed "s/^X//" >'ebcdic.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xebcdic.h  -  everything to do with EBCDIC to ASCII conversion.  Warning:
Xthis is used by check, loadtape and mvstape as well as the IBM conversion
Xlibrary. */
X
X
X
X/* Kludge the routines to handle 16-bit ints, after a fashion.  These will not
Xwork with MVStape, but are supported by the conversion library.  This whole
Xareas is revolting, but then it follows C in this respect. */
X
X#include <limits.h>
X#if INT_MAX >= 2147483647
X#define UINT unsigned int
X#else
X#define UINT unsigned long
X#endif
X
X
X
X/* Workspace and functions must be local for the library and global for the
Xmain program.  Other definitions for the program do not matter when imported
Xinto the library, because they are not reexported.  The INTERN kludge is needed
Xto bypass a gratuitous and perverse misreading of the ANSI standard by Sun's
XSolaris 2 compiler. */
X
X#ifdef CONVERSION_LIBRARY
X#define EXTERN static
X#define INTERN static
X#else
X#define EXTERN extern
X#define INTERN
X#endif
X
X
X
X/* Define some EBCDIC characters that are used in unpick.c. */
X
X#define EBCDIC_SPACE    0x40    /* ANSI control characters - what else? */
X#define EBCDIC_PLUS     0x4e
X#define EBCDIC_ONE      0xf1
X#define EBCDIC_ZERO     0xf0
X#define EBCDIC_MINUS    0x60
X
X
X
X/* Define a macro to translate EBCDIC, for efficiency.  Note that it uses -1 as
Xthe invalid character. */
X
X#define EBCDIC_to_ASCII(x) (ebcdic_to_ascii[(unsigned char)(x)])
Xextern short (EBCDIC_to_ASCII) (int character);
X
X
X
X/* Define the code page lookup table format. */
X
Xtypedef struct {
X    const char *name;                 /* The name of the code page */
X    const short *table;               /* The address of the lookup table */
X} CODE_PAGE;
X
X
X
X/* Define the external function and arrays in ebcdic.c.  The kludge for the
Xconversion library is needed to bypass a fairly common compiler bug, which is 
Xpresent in IBM's CSet/2. */
X
XEXTERN void initialize_code_pages (void);
X
XEXTERN CODE_PAGE *select_code_page (const char *name);
X
X#ifndef CONVERSION_LIBRARY
XEXTERN CODE_PAGE code_pages[];         /* The code page lookup table */
X#endif
XEXTERN const short *ebcdic_to_ascii;   /* The translation table in use */
X
X
X
X/* Define types and macros for handling big-endian shorts and ints on any type
Xof architecture.  This has been tested mainly on big-endian machines. */
X
Xtypedef unsigned char BE_short[2];    /* Big-endian short */
Xtypedef unsigned char BE_int[4];      /* Big-endian int */
Xtypedef unsigned char *BE_ptr;        /* Yuck, C */
X
X#define get_BE_short(x) (((const BE_ptr)(x))[1]+\
X    ((unsigned int)((const BE_ptr)(x))[0]<<8))
Xextern unsigned int (get_BE_short) (const BE_ptr);
X
X#define get_BE_int(x) \
X    (((const BE_ptr)(x))[3]+((((const BE_ptr)(x))[2]+((((const BE_ptr)(x))[1]+\
X    ((UINT)((const BE_ptr)(x))[0]<<8))<<8))<<8))
Xextern UINT (get_BE_int) (const BE_ptr);
X
X#define put_BE_short(x,y) \
X    (((BE_ptr)(x))[0] = (y)>>8, ((BE_ptr)(x))[1] = (y)&0xff)
Xextern void (put_BE_short) (BE_short, unsigned int);
X
X#define put_BE_int(x,y) \
X    (((BE_ptr)(x))[0] = (y)>>24, ((BE_ptr)(x))[1] = ((y)>>16)&0xff, \
X    ((BE_ptr)(x))[2] = ((y)>>8)&0xff, ((BE_ptr)(x))[3] = (y)&0xff)
Xextern void (put_BE_int) (BE_int, UINT);
X
X
X
END_OF_FILE
if test 3281 -ne `wc -c <'ebcdic.h'`; then
    echo shar: \"'ebcdic.h'\" unpacked with wrong size!
fi
# end of 'ebcdic.h'
fi
if test -f 'globals.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'globals.h'\"
else
echo shar: Extracting \"'globals.h'\" \(3465 characters\)
sed "s/^X//" >'globals.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xglobals.h  -  the global variables that are needed almost everywhere, or in
Xotherwise unrelated modules.  They are centralised for clarity rather than
Xefficiency or structuring. */
X
X
X
Xextern const char *command_name; /* 'readtape', 'scantape' or 'mvstape' */
Xextern int command_mode,       /* coded form of command_name */
X    return_code;               /* Set to EXIT_FAILURE on soft errors */
X#define mode_reading     1     /* It is command 'readtape' */
X#define mode_scanning    2     /* It is command 'scantape' */
X
Xextern int tape_fileno,        /* Raw UNIX I/O is used on the tape */
X    tape_file_count,           /* Used for messages only */
X    block_number;              /* Used for diagnostics only */
X
Xextern char tape_name[],       /* For messages only - set from VOL1 label */
X    tape_owner[],              /* Not much relevance at Cambridge */
X    tape_date[];               /* In character form, because of < 1970 */
X
Xextern int tape_type, tape_marks, /* Options set from the arguments */
X    tape_mark_count;           /* The actual count of tape marks passed */
X#define type_none    0
X#define type_TLS     1         /* Note that the order of these is important */
X#define type_SL      2
X#define type_NL      3
Xextern const char *type_names[]; /* For diagnostics only */
X
Xextern char vol1_label[], hdr1_label[]; /* For checking and disk dictionary */
X
Xextern int TLS_version,        /* The TLS version number, if TLS */
X    TLS_dict_fileno,           /* Raw UNIX I/O for the TLS dictionary, too */
X    TLS_dict_length,           /* Used when writing the dictionary only */
X    TLS_dict_updateable,       /* Whether the dictionary is updateable */
X    stop_on_EOF;               /* Scanning should stop only on real EOF */
Xextern void *TLS_dictionary;   /* The store copy of the TLS dictionary */
X
Xextern int IO_error_limit, disk_IO_error_limit, /* Set from the arguments */
X    IO_error_count, disk_IO_errors; /* The actual error counts */
XCODE_PAGE *default_code_page;  /* The code page set from the arguments */
X
Xextern int (*read_actual_block)(void), /* read_X_block(), X = disk or tape */
X    (*read_basic_block)(void); /* read_X_block(), X = simple or TLS */
Xextern char *actual_block_buffer, /* Not usually accessed directly */
X    *block_buffer;             /* Used for all I/O communication */
X
Xextern FILE *command_file, *listing_file, /* Files set from the arguments */
X    *IO_error_file;
Xextern int tar_fileno;
X
Xextern int debug, verification, allow_errors, /* More options from arguments */
X    print_lines, renaming_option, /* Not relevant to both modes */
X    no_name_check;             /* Currently MS-DOS etc. only */
X#define verify_matched     0x01
X#define verify_all         0x02
X#define verify_details     0x04
X
Xextern char *command_args;     /* For communication with command.c */
Xextern int command_flags,      /* For diagnostics only - set by command.c */
X    max_seqno_matched;         /* To reduce wasted time, mainly */
X#define match_by_number    0x01
X#define match_by_name      0x02
X#define format_specified   0x04
X
Xextern int temp_tar_fileno;    /* Used for creating tar files */
Xextern char temp_tar_filename[]; /* The name of the temporary file */
X
Xextern int temp_VBS_fileno;    /* Used for copying VBS files */
Xextern char temp_VBS_filename[]; /* The name of the temporary file */
END_OF_FILE
if test 3465 -ne `wc -c <'globals.h'`; then
    echo shar: \"'globals.h'\" unpacked with wrong size!
fi
# end of 'globals.h'
fi
if test -f 'ibmconv.3c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ibmconv.3c'\"
else
echo shar: Extracting \"'ibmconv.3c'\" \(3219 characters\)
sed "s/^X//" >'ibmconv.3c' <<'END_OF_FILE'
X.TH IBMCONV 3C
X.SH NAME
Xibm_code_page, ibm_chars, ibm_shorts, ibm_ints, ibm_longs, ibm_floats,
Xibm_doubles, ibm_long_doubles \- convert IBM 370 architecture data to local
Xformat
X.SH SYNOPSIS
X.B #include \&"ibmconv.h"
X.PP
X.B "int ibm_code_page (const char *code_page);"
X.PP
X.B "int ibm_chars (const void *input, char *output, int count);"
X.PP
X.B "int ibm_shorts (const void *input, short *output, int count);"
X.PP
X.B "int ibm_ints (const void *input, int *output, int count);"
X.PP
X.B "int ibm_longs (const void *input, long *output, int count);"
X.PP
X.B "int ibm_floats (const void *input, float *output, int count);"
X.PP
X.B "int ibm_doubles (const void *input, double *output, int count);"
X.PP
X.B "int ibm_long_doubles (const void *input, long double *output, int count);"
X.SH DESCRIPTION
XThese functions convert IBM 370 architecture data to local format.  As ANSI
XC specifies that
X.BR short ,
X.BR long ,
X.B float
Xand
X.B double
Xare at least as accurate as IBM 370 architecture, only
X.B ibm_ints
Xand
X.B ibm_long_doubles
Xmay lose much accuracy on any system.  Even these will be reasonably accurate
Xprovided that
X.B int
Xhas at least 32 bits and
X.B "long double"
Xhas at least 128, but neither property can be relied upon.
X.PP
X.B ibm_code_page
Xsets up a code page for use by
X.BR ibm_chars .
XThis may be one of
X.B phx
X(the one used in Phoenix, and the default),
X.B phx8
X(the 8-bit Phoenix one),
X.B phxmvt
X(the one used when Phoenix ran under MVT),
X.B ibmmvs
X(`standard' IBM MVS),
X.B ibm037
X(IBM code page 37) or
X.B ibm500
X(IBM code page 500).  The case of the code page name is ignored.  The
X.IR phx ,
X.I phxmvt
Xand
X.I ibmmvs
Xcode pages map EBCDIC to 7-bit ASCII with both EBCDIC
X.I NL
Xand
X.I LF
Xand EBCDIC
X.I NUL
Xmapped to ASCII
X.I SUB
X(to avoid confusing UNIX utilities); the first two also map pound sterling to
XISO Latin 1.  The remainder map all 256 EBCDIC characters to ISO Latin 1.
X.PP
XAll of the other functions convert arrays of the appropriate IBM 370 data type,
Xwhich is one of the following:
X.TP 20
X.B ibm_chars
Xsingle-byte (8-bit) EBCDIC characters
X.TP
X.B ibm_shorts
X16-bit integers or INTEGER*2
X.TP
X.B ibm_ints
X32-bit integers or INTEGER*4
X.TP
X.B ibm_longs
X32-bit integers or INTEGER*4
X.TP
X.B ibm_floats
X32-bit floating point or REAL*4
X.TP
X.B ibm_doubles
X64-bit floating point or REAL*8
X.TP
X.B ibm_long_doubles
X128-bit floating point or REAL*16
X.PD
X.SH RETURN VALUE
XAll these functions return 0 for success and -1 for failure (i.e. code page
Xnot found or negative item count).  If they succeed, but some conversions fail,
Xthey will return 1 and will set
X.B errno
Xto
X.B EDOM
Xfor untranslatable characters or to
X.B ERANGE
Xfor overflow.
X.SH BUGS
XFloating point conversion is not always completely accurate and inaccuracies
Xare not diagnosed, but the maximum error is no larger than ordinary rounding
Xerror.
X.PP
XFloating point underflow and unnormalized numbers are not diagnosed; the former
Xare converted to zero, and the latter to their normalized form.
X.SH AUTHOR
X.BR ibm_code_page ,
X.BR ibm_chars ,
X.BR ibm_shorts ,
X.BR ibm_ints ,
X.BR ibm_longs ,
X.BR ibm_floats ,
X.B ibm_doubles
Xand
X.B ibm_long_doubles
Xwere developed by N.M. Maclaren of the University of Cambridge Computing
XService.
X.SH SEE ALSO
Xibmconv(3f).
END_OF_FILE
if test 3219 -ne `wc -c <'ibmconv.3c'`; then
    echo shar: \"'ibmconv.3c'\" unpacked with wrong size!
fi
# end of 'ibmconv.3c'
fi
if test -f 'ibmconv.3f' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ibmconv.3f'\"
else
echo shar: Extracting \"'ibmconv.3f'\" \(3590 characters\)
sed "s/^X//" >'ibmconv.3f' <<'END_OF_FILE'
X.TH IBMCONV 3F
X.SH NAME
XIBMCODEPAGE, IBMCHARS, IBMINT2S, IBMINT4S, IBMREAL4S, IBMREAL8S, IBMREAL16S \-
Xconvert IBM 370 architecture data to local format
X.SH SYNOPSIS
X.PD 0
X.B "INTEGER FUNCTION IBMCODEPAGE (CODEPAGE)"
X.PP
X.B "CHARACTER CODEPAGE(*)"
X.PD
X.PP
X.PD 0
X.B "INTEGER FUNCTION IBMCHARS (INPUT, OUTPUT, COUNT)"
X.PP
X.B "CHARACTER INPUT(*), OUTPUT(*)"
X.PP
X.B "INTEGER COUNT"
X.PD
X.PP
X.PD 0
X.B "INTEGER FUNCTION IBMINT2S (INPUT, OUTPUT, COUNT)"
X.PP
X.B "CHARACTER INPUT(*)"
X.PP
X.B "INTEGER*2 OUTPUT(*)"
X.PP
X.B "INTEGER COUNT"
X.PD
X.PP
X.PD 0
X.B "INTEGER FUNCTION IBMINT4S (INPUT, OUTPUT, COUNT)"
X.PP
X.B "CHARACTER INPUT(*)"
X.PP
X.B "INTEGER*4 OUTPUT(*)"
X.PP
X.B "INTEGER COUNT"
X.PD
X.PP
X.PD 0
X.B "INTEGER FUNCTION IBMREAL4S (INPUT, OUTPUT, COUNT)"
X.PP
X.B "CHARACTER INPUT(*)"
X.PP
X.B "REAL*4 OUTPUT(*)"
X.PP
X.B "INTEGER COUNT"
X.PD
X.PP
X.PD 0
X.B "INTEGER FUNCTION IBMREAL8S (INPUT, OUTPUT, COUNT)"
X.PP
X.B "CHARACTER INPUT(*)"
X.PP
X.B "REAL*8 OUTPUT(*)"
X.PP
X.B "INTEGER COUNT"
X.PD
X.PP
X.PD 0
X.B "INTEGER FUNCTION IBMREAL16S (INPUT, OUTPUT, COUNT)"
X.PP
X.B "CHARACTER INPUT(*)"
X.PP
X.B "REAL*16 OUTPUT(*)"
X.PP
X.B "INTEGER COUNT"
X.PD
X.SH DESCRIPTION
XThese functions convert IBM 370 architecture data to local format.  As Fortran
Xdoes not specify any minimum precision for its data types, no guarantees can be
Xgiven about accuracy loss.  However, there will usually be very little in cases
Xwhere the target data types are at least as large as the 370 equivalents.
X.PP
X.B IBMCODEPAGE
Xsets up a code page for use by
X.BR IBMCHARS .
XThis may be one of
X.B phx
X(the one used in Phoenix, and the default),
X.B phx8
X(the 8-bit Phoenix one),
X.B phxmvt
X(the one used when Phoenix ran under MVT),
X.B ibmmvs
X(`standard' IBM MVS),
X.B ibm037
X(IBM code page 37) or
X.B ibm500
X(IBM code page 500).  The case of the code page name is ignored, but the string 
Xmust be null-terminated.  The
X.IR phx ,
X.I phxmvt
Xand
X.I ibmmvs
Xcode pages map EBCDIC to 7-bit ASCII with both EBCDIC
X.I NL
Xand
X.I LF
Xand EBCDIC
X.I NUL
Xmapped to ASCII
X.I SUB
X(to avoid confusing UNIX utilities); the first two also map pound sterling to
XISO Latin 1.  The remainder map all 256 EBCDIC characters to ISO Latin 1.
X.PP
XAll of the other functions convert arrays of the appropriate IBM 370 data type,
Xwhich is one of the following:
X.TP 20
X.B IBMCHARS
Xsingle-byte (8-bit) EBCDIC characters
X.TP
X.B IBMINT2S
X16-bit integers or INTEGER*2
X.TP
X.B IBMINT4S
X32-bit integers or INTEGER*4
X.TP
X.B IBMREAL4S
X32-bit floating point or REAL*4
X.TP
X.B IBMREAL8S
X64-bit floating point or REAL*8
X.TP
X.B IBMREAL16S
X128-bit floating point or REAL*16
X.PD
X.SH RETURN VALUE
XAll these functions return 0 for success and -1 for failure (i.e. code page
Xnot found or negative item count).  If they succeed, but some conversions fail,
Xthey will return 1 and will set
X.B errno
Xto
X.B EDOM
Xfor untranslatable characters or to
X.B ERANGE
Xfor overflow.
X.SH BUGS
XThese functions cannot be implemented portably, and may not be available for
Xall systems.
X.B IBMREAL16S
Xis especially likely not to be available, and may issue an error message and
Xabort.
X.PP
XFloating point conversion is not always completely accurate and inaccuracies
Xare not diagnosed, but the maximum error is no larger than ordinary rounding
Xerror.
X.PP
XFloating point underflow and unnormalized numbers are not diagnosed; the former
Xare converted to zero, and the latter to their normalized form.
X.SH AUTHOR
X.BR IBMCODEPAGE ,
X.BR IBMCHARS ,
X.BR IBMINT2S ,
X.BR IBMINT4S ,
X.BR IBMREAL4S ,
X.B IBMREAL8S
Xand
X.B IBMREAL16S
Xwere developed by N.M. Maclaren of the University of Cambridge Computing
XService.
X.SH SEE ALSO
Xibmconv(3c).
END_OF_FILE
if test 3590 -ne `wc -c <'ibmconv.3f'`; then
    echo shar: \"'ibmconv.3f'\" unpacked with wrong size!
fi
# end of 'ibmconv.3f'
fi
if test -f 'ibmconv.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ibmconv.h'\"
else
echo shar: Extracting \"'ibmconv.h'\" \(803 characters\)
sed "s/^X//" >'ibmconv.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1994, 1995
X   (C) Copyright the University of Cambridge 1994, 1995
X   ALL RIGHTS RESERVED
X
Xibmconv.h  -  headers for some library functions to do data conversion. */
X
X
X
X#ifndef _IBMCONV_
X#define _IBMCONV_
X
Xextern int ibm_code_page (const char *code_page);
Xextern int ibm_chars (const void *input, char *output, int count);
Xextern int ibm_shorts (const void *input, short *output, int count);
Xextern int ibm_ints (const void *input, int *output, int count);
Xextern int ibm_longs (const void *input, long *output, int count);
Xextern int ibm_floats (const void *input, float *output, int count);
Xextern int ibm_doubles (const void *input, double *output, int count);
Xextern int ibm_long_doubles (const void *input, long double *output, int count);
X
X#endif    /* _IBMCONV_ */
END_OF_FILE
if test 803 -ne `wc -c <'ibmconv.h'`; then
    echo shar: \"'ibmconv.h'\" unpacked with wrong size!
fi
# end of 'ibmconv.h'
fi
if test -f 'iebcopy.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'iebcopy.h'\"
else
echo shar: Extracting \"'iebcopy.h'\" \(2966 characters\)
sed "s/^X//" >'iebcopy.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xiebcopy.h  -  constants and control blocks for decoding IEBCOPY unloaded
XPDSs.  It assumes horrible things about the way the C compiler lays out
Xstructures but, then, so do most UNIX programs!
X
XNote that IEBCOPY format is not public, and so this may not work for all
Xversions of IEBCOPY.  If it does not, it will need modifying. */
X
X
X
X/* The first IEBCOPY file header block, that gives the DCB characteristics. */
X
Xtypedef struct {
X    unsigned char indicators;     /* Bit X'80' indicates a corrupted file */
X    char identifier[3];           /* This is defined to be X'CA6D0F' */
X    char dsorg[2];                /* Only X'0200' (plain PO) is supported */
X    BE_short blksize, lrecl;      /* The block size and record length */
X    unsigned char recfm,          /* The record format */
X        keylen;                   /* This must be X'00' - i.e. no keys */
X    char ignored1[2];             /* OPTCD and reserved */
X    BE_short tape_blksize;        /* The block size on tape */
X    char ignored2[10];            /* Ignorable DEVTYPE output */
X    BE_short trks_per_cyl;        /* The number of tracks in a cylinder */
X    char ignored3[8];             /* Ignorable DEVTYPE output */
X                                  /* Plus 16 bytes reserved, apparently */
X} IEB_FIRST_BLOCK;
X
X#define indicate_corrupted 0x80   /* Unloading the PDS failed somehow */
X#define IEBCOPY_identifier "\xca\x6d\x0f" /* For checking */
X
X
X
X/* The second IEBCOPY file header block, that gives the extent list. */
X
Xtypedef struct {
X    char ignored[6];              /* File mask, UCB address and bin number! */
X    unsigned char lower_cchh[4],  /* The lower CCHH of the extent */
X        upper_cchh[4];            /* The upper CCHH of the extent */
X    BE_short tracks;              /* The number of tracks in the extent */
X} IEB_EXTENT;
X
Xtypedef struct {
X    unsigned char num_extents;    /* The number of extents (1 to 16) */
X    char ignored1[15];            /* Last 15 bytes of basic section of DEB */
X    IEB_EXTENT extents[16];       /* The extent list from the DEB */
X    char ignored2[4];             /* Reserved */
X} IEB_SECOND_BLOCK;
X
X
X
X/* The IEBCOPY data blocks. */
X
Xtypedef struct {
X    char ignored[4];              /* Probably always X'00000000' */
X    unsigned char cchhr[5];       /* The CCHHR of this block */
X    unsigned char keylen;         /* The key length (always 0) */
X    BE_short datalen;             /* The length of the data */
X    char data[1];                 /* The data starting with the key, if any */
X} IEB_DATA_BLOCK;
X
X
X
X/* The RECFM=VS headers of all unloaded blocks. */
X
Xtypedef struct {
X    BE_short b_length, b_pad,     /* The block descriptor word */
X        r_length, r_pad;          /* The record descriptor word */
X    char data[1];                 /* Whatever kind of data are included */
X} IEB_TAPE_BLOCK;
END_OF_FILE
if test 2966 -ne `wc -c <'iebcopy.h'`; then
    echo shar: \"'iebcopy.h'\" unpacked with wrong size!
fi
# end of 'iebcopy.h'
fi
if test -f 'labels.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'labels.h'\"
else
echo shar: Extracting \"'labels.h'\" \(2480 characters\)
sed "s/^X//" >'labels.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xlabels.h  -  IBM SL control blocks and related constants.  This assumes
Xhorrible things about the way the C compiler lays out structures but, then, so
Xdo most UNIX programs!  Warning:  this is used by both loadtape and mvstape. */
X
X
X
X/* Define IBM Standard Label volume, header and trailer labels.  This does not
Xdefine most of the fields, as they make little sense under UNIX and are not
Xeven much use for checking. */
X
Xtypedef struct {
X    char labelid[4],           /* 'VOL1' in EBCDIC */
X        tapename[6],           /* Tape name in EBCDIC */
X        _reserved1[31],        /* Reserved */
X        owner[10],             /* The owner's name and address (!) */
X        _reserved2[29];        /* Reserved */
X} VOL1_LABEL;
X
Xtypedef struct {
X    char labelid[4],           /* 'HDR1' or 'EOF1' in EBCDIC */
X        dataset_name[17],      /* The dataset name in EBCDIC */
X        _ignored1[10],         /* Unused MVT/MVS information */
X        sequence_number[4],    /* The sequence number in EBCDIC */
X        _ignored2[6],          /* Unused MVT/MVS information */
X        creation_date[6],      /* The creation date in IBM form */
X        _ignored3[7],          /* Unused MVT/MVS information */
X        block_count[6],        /* The block count, in the trailer label */
X        _ignored4[20];         /* Unused MVT/MVS information and reserved */
X} HDR1_LABEL;
X
Xtypedef struct {
X    char labelid[4],           /* 'HDR2' or 'EOF2' in EBCDIC */
X        recfm1,                /* The record format 'F', 'V' or 'U' */
X        blksize[5],            /* The BLKSIZE in EBCDIC */
X        lrecl[5],              /* The LRECL in EBCDIC */
X        _ignored1[2],          /* Unused MVT/MVS information */
X        job_step_id[17],       /* Jobname/stepname, where these are set */
X        _ignored2[2],          /* Unused MVT/MVS information */
X        recfm2,                /* The record format 'A', 'M' or ' ' */
X        _reserved1,            /* Reserved */
X        recfm3,                /* The record format 'B', 'S', 'R' or ' ' */
X        _reserved2[41];        /* Reserved */
X} HDR2_LABEL;
X
X/* Note that an lrecl value of '99999' means X and a recfm3 value of 'R' means
X'BS'. */
X
Xtypedef struct {
X    char labelid[4],           /* 'UTLn', n = 1...4, in EBCDIC */
X        TLS_dict_entry[76];    /* A copy of the TLS dictionary entry */
X} UTL_LABEL;
END_OF_FILE
if test 2480 -ne `wc -c <'labels.h'`; then
    echo shar: \"'labels.h'\" unpacked with wrong size!
fi
# end of 'labels.h'
fi
if test -f 'loadtape.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'loadtape.1'\"
else
echo shar: Extracting \"'loadtape.1'\" \(3199 characters\)
sed "s/^X//" >'loadtape.1' <<'END_OF_FILE'
X.TH LOADTAPE 1L
X.SH NAME
Xloadtape \- read a 1/2" magnetic tape onto disk, preserving its structure
X.SH SYNOPSIS
X.B loadtape
X.BI \-t " tape"
X.BI \-d " disk"
X[
X.BI \-m " EOFs"
X]
X[
X.B \-v
X]
X[
X.BI \-X " errors"
X]
X.SH DESCRIPTION
XThe
X.I loadtape
Xcommand is used to create a `diskized' copy of a complete tape.  The output
Xfile may be used by the utilities
X.I readtape
Xand
X.I scantape.
XThere is some recovery from I/O errors, but the command is not designed for
Xdecoding badly corrupted tapes.
X.SS Options
X.I loadtape
Xrecognises the following arguments:
X.TP
X.B \-d
Xspecifies the disk file to receive a `diskized' copy of the tape (compulsory).
X.TP
X.B \-m
Xspecifies which double tape mark means end of tape (minimum 1, maximum 1000).
XThe default is 1 for unlabelled tapes, and the standard algorithm for labelled
Xtapes.
X.TP
X.B \-t
Xspecifies the tape device file on which the magnetic tape is mounted
X(compulsory).
X.TP
X.B \-v
Xwrites the byte count, block count, I/O error count, maximum block size, minimum
Xblock size and whether the last block is the only short one on
X.I stdout.
X.TP
X.B \-D
Xprint debugging information on
X.I stderr
X(not useful for most users).
X.TP
X.B \-X
Xspecifies how many I/O errors occur before the command stops (default 10,
Xmaximum 10000).
X.SH FILE FORMAT
XA `diskized' tape file is a stream of binary data that can be unpicked to
Xrecreate the block structure of the magnetic tape.  Tape labels, I/O errors and
Xfilemarks are all preserved, and are treated like data records.  Each physical
Xblock on the magnetic tape is written to the disk file as a 4-byte length in
Xbig-endian order, followed by its data.  File marks are indicated by a length
Xof zero and I/O errors by a negative length; neither are followed by any data.
XThe end of tape is indicated by the end of the file.
X.PP
XThis file format is the same as the one produced by the Phoenix command DISCTLS,
Xwhich will read and write a disk file as if it were a TLS tape.  Such a Phoenix
Xfile may be transferred to UNIX in stream binary mode, and this will give
Xexactly the same effect as writing a 1/2" tape with the Phoenix command
X.TLS
Xfollowed by reading it under UNIX with the
X.I loadtape
Xcommand.  [TLS is the Tape Library System using IBM standard labelled tapes
Xthat was developed as part of the Phoenix user-friendly front end to MVS by the
XUniversity of Cambridge Computing Service.]
X.PP
XAn unreadable TLS dictionary is replaced by a block of length 65536 whose
Xcontents start with the string "This space left intentionally blank"; this space
Xis used by the
X.I readtape
Xand
X.I scantape
Xcommands when recovering the TLS dictionary from the trailer labels.
X.SH BUGS
XThe handling of I/O errors is crude, and the actual error type is lost, but this
Xis as much a restriction of UNIX as the program.
X.PP
XBlocks up to 65535 can be handled, provided the device driver and tape deck
Xhandle them correctly, but longer ones are rejected.
X.PP
XThe tape device must be a raw device, on systems that support both raw and
Xblock magnetic tape devices, though this is not checked.
X.SH AUTHOR
X.I loadtape
Xwas developed by N.M. Maclaren of the University of Cambridge Computing
XService.
X.SH SEE ALSO
Xmvstape(1L), readtape(1L), scantape(1L).
END_OF_FILE
if test 3199 -ne `wc -c <'loadtape.1'`; then
    echo shar: \"'loadtape.1'\" unpacked with wrong size!
fi
# end of 'loadtape.1'
fi
if test -f 'loadtape.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'loadtape.h'\"
else
echo shar: Extracting \"'loadtape.h'\" \(1369 characters\)
sed "s/^X//" >'loadtape.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xloadtape.h  -  the only header for the tape 'diskizing' utility. */
X
X
X
X/* The following are all the external headers.  Note that system.h includes
Xseveral others, and must come first both for POSIX compliance and in case the
Xsystem's headers are sick (as under Solaris 2). */
X
X#include "system.h"
X
X#include <ctype.h>
X#include <stdarg.h>
X
X
X
X/* Miscellaneous global definitions, with obvious interpretations. */
X
X#define constant_64K      65536    /* This is in the hardware etc. */
X#define TAPE_LABEL_SIZE   80       /* This is defined by the specification */
X#define max_tape_marks    1000     /* For checking only (could be INT_MAX) */
X#define max_IO_errors     10000    /* For checking only (could be INT_MAX) */
X#define label_fieldsize   20       /* Enough for any tape label field */
X
X#define STATIC static              /* Because local symbols may be stripped! */
X
X
X
X/* See system.h for the error flags. */
X
X
X
X/* loadtape.c external functions. */
X
Xextern int main (int argc, char *argv[]);
X/* extern void fatal (const char *message, int errtype, ...);    in system.h */
X/* extern void warn (const char *message, int errtype, ...);     in system.h */
X/* extern void comment (const char *message, ...);               in system.h */
END_OF_FILE
if test 1369 -ne `wc -c <'loadtape.h'`; then
    echo shar: \"'loadtape.h'\" unpacked with wrong size!
fi
# end of 'loadtape.h'
fi
if test -f 'mvstape.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mvstape.1'\"
else
echo shar: Extracting \"'mvstape.1'\" \(755 characters\)
sed "s/^X//" >'mvstape.1' <<'END_OF_FILE'
X.TH MVSTAPE 1L
X.SH NAME
Xmvstape \- read or scan a 1/2" magnetic tape or `diskized' tape file
X.SH DESCRIPTION
XThe
X.I mvstape
Xprogram is the same one as the
X.I readtape
Xand
X.I scantape
Xcommands, and is not normally called by the name
X.I mvstape.
XIf it is, it will accept any argument of either
X.I readtape
Xor
X.I scantape,
Xswitching into reading mode if either the
X.B \-e
Xor
X.B \-f
Xarguments are present; otherwise it will switch into scanning mode.  It will
Xthen diagnose any options that are incompatible with the mode actually used.
XSee the
X.I readtape
Xand
X.I scantape
Xpages for more information.
X.SH AUTHOR
X.I mvstape
Xwas developed by N.M. Maclaren of the University of Cambridge Computing
XService.
X.SH SEE ALSO
Xloadtape(1L), readtape(1L), scantape(1L).
END_OF_FILE
if test 755 -ne `wc -c <'mvstape.1'`; then
    echo shar: \"'mvstape.1'\" unpacked with wrong size!
fi
# end of 'mvstape.1'
fi
if test -f 'mvstape.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mvstape.h'\"
else
echo shar: Extracting \"'mvstape.h'\" \(2791 characters\)
sed "s/^X//" >'mvstape.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xmvstape.h  -  the main header, including all constants that are needed
Xalmost everywhere or in otherwise unrelated modules. */
X
X
X
X/* The following headers are so ubiquitous that we include them globally.  Note
Xthat system.h includes several others, and must come first both for POSIX
Xcompliance and in case the system's headers are sick (as under Solaris 2). */
X
X#include "system.h"
X#include "ebcdic.h"
X#include "globals.h"
X#include "externs.h"
X
X
X
X/* Miscellaneous global definitions, with obvious interpretations. */
X
X#define TAPEnamesize      10       /* Yes, I know that it is 6 + 1 */
X#define TAPEownersize     15       /* Yes, I know that it is 10 + 1 */
X#define MVSnamesize       55       /* Including a PDS member name */
X#define PDSnamesize       10       /* Yes, I know that it is 8 + 1 */
X#define date_charsize     15       /* As in "29 Feb 1968" */
X#define comment_size      30       /* Expanded TLS comments or job/step id */
X#define UNIXnamesize      260      /* POSIX requires at least 256 */
X#define constant_64K      65536    /* This is in the hardware etc. */
X#define TAPE_LABEL_SIZE   80       /* This is defined by the specification */
X#define reading_name      "readtape" /* The name that indicates reading */
X#define scanning_name     "scantape" /* The name that indicates scanning */
X#define default_name      "mvstape" /* The default command name */
X
X#define STATIC static              /* Because local symbols may be stripped! */
X
X
X
X/* Error flags, to clarify the error-handling code somewhat.  These are
Xarguments to IO_error().   See system.h for the standard error flags, which
Xare also passed to fatal() and warn(). */
X
X#define ERR_ignore     1           /* Ignoring the I/O error is permitted */
X#define ERR_skip       2           /* Skipping the file is the only option */
X
X
X
X/* The flags for the file organisation and record formats supported by this
Xprogram - note that they are NOT the same as the ones MVS uses.  They are here,
Xbecause otherwise almost all modules would have to import control.h. */
X
X#define dsorg_PS       1           /* Sequential - always for non-TLS tapes */
X#define dsorg_PO       2           /* Partitioned (PDSs) */
X#define dsorg_DA       3           /* Direct-access (only RECFM=F, unkeyed) */
X
X#define recfm_V        0x01        /* Variable */
X#define recfm_F        0x02        /* Fixed */
X#define recfm_U        0x04        /* Undefined */
X#define recfm_B        0x08        /* Blocked */
X#define recfm_S        0x10        /* Spanned (ignored with fixed) */
X#define recfm_A        0x20        /* ANSI carriage controls */
X#define recfm_M        0x40        /* Machine code carriage controls */
END_OF_FILE
if test 2791 -ne `wc -c <'mvstape.h'`; then
    echo shar: \"'mvstape.h'\" unpacked with wrong size!
fi
# end of 'mvstape.h'
fi
if test -f 'system.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'system.h'\"
else
echo shar: Extracting \"'system.h'\" \(2862 characters\)
sed "s/^X//" >'system.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1994
X   (C) Copyright the University of Cambridge 1994
X   ALL RIGHTS RESERVED
X
Xsystem.h - the header to determine which kind of system, and include the UNIX
Xmacros or emulation headers.  It includes some definitions that are needed from 
Xeverywhere (and not just the mvstape program).  This header is included from
Xmvstape.h, loadtape.h and <opsys>.c. */
X
X
X
X/* Check the system type, and default to UNIX if it looks possible.  There is
Xno clean way to test whether a system is reasonably POSIX compatible or
XUNIX-like, still less whether it is MS-DOS-like! */
X
X#define UNIX    123456789
X#define MSDOS   456789012
X#define MACOS   789012345
X#if !defined(SYSTEM) &&                                                \
X    (defined(unix) || defined(__unix) || defined(__unix__) ||          \
X    defined(_POSIX_VERSION) || defined(_POSIX_SOURCE))
X#define SYSTEM UNIX
X#endif
X
X/* Note that the position of _POSIX_SOURCE is rather important, because it must
Xbe set before any system header is included.  Unfortunately, some systems have
Xcompletely broken headers when this is set, and so it is practical to set only
Xin the makefile. */
X
X#if SYSTEM == UNIX
X/* #define _POSIX_SOURCE */
X#include "uniextra.h"
X#elif SYSTEM == MSDOS || SYSTEM == MACOS
X#include "unifudge.h"
X    #if SYSTEM == MACOS
X    #error MacOS support has not yet been implemented
X    #endif
X#else
X#error "Unknown value of SYSTEM preprocessor definition"
X#endif
X
X
X
X/* The following headers are so ubiquitous that we include them globally. */
X
X#include <errno.h>
X#include <stdio.h>
X#include <stddef.h>
X#include <stdlib.h>
X#ifndef EXIT_SUCCESS
X#define EXIT_SUCCESS 0    /* Avoid Sun's broken library */
X#define EXIT_FAILURE 1    /* Avoid Sun's broken library */
X#endif
X#include <string.h>
X
X
X
X/* Definitions and external functions for error handling.  These are the only
Xexternal functions that may be called from the POSIX emulation functions, which
Xis why they are here. */
X
X#define ERR_private    1           /* errno is not useful */
X#define ERR_system     2           /* Information in errno */
X#define ERR_tapeio     3           /* Information in errno on a tape problem */
X
Xextern void fatal (const char *message, int errtype, ...);
Xextern void warn (const char *message, int errtype, ...);
Xextern void comment (const char *message, ...);
X
X
X
X/* tapeio.c external functions, which are in <opsys.c> for non-UNIX systems.
XThese are here because they are includes from tapeio.c and <opsys.c>. */
X
Xextern int basic_tape_open (const char *name);
Xextern int basic_tape_close (int fileno);
Xextern int basic_tape_rewind (int fileno);
Xextern const char * basic_tape_status (int fileno);
Xextern int basic_tape_skip (int fileno, int labels, int data);
Xextern int basic_tape_read (int fileno, char *buffer, int length);
Xextern void basic_tape_signal (void (*receiver)(const char *));
END_OF_FILE
if test 2862 -ne `wc -c <'system.h'`; then
    echo shar: \"'system.h'\" unpacked with wrong size!
fi
# end of 'system.h'
fi
if test -f 'tarpit.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tarpit.h'\"
else
echo shar: Extracting \"'tarpit.h'\" \(1648 characters\)
sed "s/^X//" >'tarpit.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993
X   (C) Copyright the University of Cambridge 1993
X   ALL RIGHTS RESERVED
X
Xtarpit.h  -  the format of a basic tar header.  For some perverse reason,
Xthe tar.h on most UNIX systems gives only the flag settings.  Also, remember
Xthat the format is not entirely standard, and that the man page is
Xtraditionally wrong anyway (though POSIX is somewhat better).  Most versions of
Xtar ignore all spaces and nulls within these fields, in whatever order, because
Xthat is the only way to accept foreign tar tapes.  Yuck. */
X
X
X
X/* Define the minimum tar format, ignoring all extensions, for portability. */
X
X#define TAR_BLKSIZE     512      /* This is fixed */
X#define TAR_NAMESIZE    100      /* So is this */
X
Xtypedef struct {
X     char name[TAR_NAMESIZE];    /* The UNIX name */
X     char mode[8];               /* The file's mode, as text */
X     char uid[8];                /* The file's uid, as text */
X     char gid[8];                /* The file's guid, as text */
X     char size[12];              /* The file's size, as text */
X     char mtime[12];             /* The file's creation time, as text */
X     char chksum[8];             /* An almost useless check sum, as text */
X     char linkflag;              /* Whether this is a file or link */
X     char linkname[TAR_NAMESIZE]; /* The link name, if it is a link */
X     char _unused[TAR_BLKSIZE-2*TAR_NAMESIZE-57]; /* Pad to the correct size */
X} tar_header;
X
X#define TAR_REGTYPE     '\0'     /* Regular File - documented as '0' (ugh) */
X#define TAR_LINKTYPE    '1'      /* Hard Link */
X
X#define TAR_FIELDSIZE   20       /* Longer than any of the octal fields */
END_OF_FILE
if test 1648 -ne `wc -c <'tarpit.h'`; then
    echo shar: \"'tarpit.h'\" unpacked with wrong size!
fi
# end of 'tarpit.h'
fi
if test -f 'tlsdict.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tlsdict.h'\"
else
echo shar: Extracting \"'tlsdict.h'\" \(3539 characters\)
sed "s/^X//" >'tlsdict.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xtlsdict.h  -  TLS dictionary formats and related constants.  This assumes
Xhorrible things about the way the C compiler lays out structures but, then, so
Xdo most UNIX programs!  Warning:  this is used by both loadtape and mvstape. */
X
X
X
X/* Define the MVS DSORG and RECFM flags, as far as we need them. */
X
X#define MVS_DSORG_PS    0x40    /* These are bits, but never set together */
X#define MVS_DSORG_DA    0x20
X#define MVS_DSORG_PO    0x02
X
X#define MVS_RECFM_F     0x80    /* Just define the bits we use */
X#define MVS_RECFM_V     0x40
X#define MVS_RECFM_U     0xC0    /* Watch out - this is RECFM_F|RECFM_V */
X#define MVS_RECFM_B     0x10
X#define MVS_RECFM_S     0x08
X#define MVS_RECFM_A     0x04
X#define MVS_RECFM_M     0x02
X
X
X
X/* Define the formats of version 3 and 4 TLS dictionary entries.  The only
Xfield used out of the first dictionary entry (which is different) is the number
Xof last entry used, and even that is not critical. */
X
X#define TLS_dictionary_name "TLS.DICTIONARY" /* The name of the first file */
X
Xtypedef struct {
X    char dataset_name[26];      /* Remember MVT? */
X    BE_short entry_num,         /* Label number less one (for checking) */
X        fwd_ptr, back_ptr,      /* Alphabetic file chain */
X        tape_date, disk_date,   /* The dates in compressed form */
X        blksize, lrecl;         /* The disk BLKSIZE and LRECL */
X    unsigned char dsorg, recfm, /* The disk DSORG and RECFM */
X        keylen,                 /* The key length (checked to be zero) */
X        flags;                  /* The TLS flags (only one used here) */
X    BE_short tracks, dir_blks;  /* Size in 3330 tracks and no. of dir. blocks */
X    char _ignored2[4];          /* Unused MVS-specific information */
X    unsigned char comments[18]; /* User comment field */
X} TLS_V3_DICT;
X
X#define TLS_V3_DICT_SIZE  70    /* It had better be sizeof(TLS_V3_DICT)! */
X
X#define tracksize_3330    12    /* The 3330 nominal track size in kilobytes */
X
Xtypedef struct {
X    char dataset_name[44];      /* The MVS dataset name */
X    BE_short entry_num;         /* Label number less one (for checking) */
X    unsigned char version;      /* '4' in EBCDIC - distinguishes versions */
X    char _unused1;              /* Padding (i.e. unused) */
X    BE_short fwd_ptr, back_ptr; /* Alphabetic file chain */
X    BE_int tape_date, disk_date; /* The dates in compressed form */
X    BE_short blksize, lrecl;    /* The disk BLKSIZE and LRECL */
X    unsigned char dsorg, recfm, /* The disk DSORG and RECFM */
X        keylen,                 /* The key length (checked to be zero) */
X        flags;                  /* The TLS flags (only one used here) */
X    BE_int size_KB;             /* Size in nominal kilobytes */
X    BE_short dir_blks;          /* Number of directory blocks */
X    char _ignored2[3];          /* Unused MVS-specific information */
X    unsigned char comments[18]; /* User comment field */
X    char _unused2[5];           /* Unused */
X} TLS_V4_DICT;
X
X#define TLS_V4_DICT_SIZE 100    /* It had better be sizeof(TLS_V4_DICT)! */
X
X#define tls_flags_deleted 0x80 /* Whether this file or version is deleted */
X#define tls_dict_version(x) ((x)->dsorg) /* Version dependent! */
X#define tls_dict_last_entry(x) ((x)->blksize) /* ditto */
X
X
X
X/* Marker set by loadtape utility to mark the place where the dictionary should
Xbe, if it could be read. */
X
X#define TLS_dict_marker "This space left intentionally blank"
END_OF_FILE
if test 3539 -ne `wc -c <'tlsdict.h'`; then
    echo shar: \"'tlsdict.h'\" unpacked with wrong size!
fi
# end of 'tlsdict.h'
fi
if test -f 'tlspds.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tlspds.h'\"
else
echo shar: Extracting \"'tlspds.h'\" \(2783 characters\)
sed "s/^X//" >'tlspds.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xtlspds.h  -  constants and control blocks for PDS decoding.  Much of this is
XTLS-specific, but some applies to all PDS formats.  This assumes horrible
Xthings about the way the C compiler lays out structures but, then, so do most
XUNIX programs! */
X
X
X
X/* TLS disk block headers, which are packed into tape records. */
X
Xtypedef struct {
X    char flags,                   /* Various flags */
X        ttr[3],cchhr[5];          /* TTR of record and 5 bytes of junk */
X    unsigned char keylen;         /* The key length (almost always 0) */
X    BE_short datalen;             /* The length of the data */
X    char data[1];                 /* The data starting with the key, if any */
X} TLS_BLOCK_HDR;
X
X#define TLS_PREFIX_LENGTH 12      /* Must be offsetof(TLS_BLOCK_HDR *,data)! */
X
X#define tls_last_block    0x80    /* The last disk block in the segment */
X#define tls_more_dirs     0x01    /* There are yet more directory segments */
X
X
X
X/* TLS PDS member marker records. */
X
Xtypedef struct {
X    char marker[12],              /* The text to check against */
X        member[8];                /* The member name in the first one */
X} PDS_MARKER;
X
X#define pds_marker_size    20     /* Big enough for the text, plus one */
X
X#define tls_member_marker_1 "TLS**MARK1**" /* Used for locating members */
X#define tls_member_marker_2 "TLS**MARK2**" /* Skip these, except for recovery */
X
X
X
X/* Define the format of a PDS directory on tape and its entries. */
X
X#define PDS_key_length     8      /* This is fixed for all time */
X#define PDS_data_length    256    /* This is fixed for all time */
X
Xtypedef struct {
X    char flags,                   /* Various flags */
X        mbbcchhr[8];              /* Full FDAD or TTR, depending on use */
X    unsigned char keylen;         /* The key length (always 8) */
X    BE_short datalen;             /* The length of the data (always 256) */
X    char key[PDS_key_length];     /* The last member in the block */
X    BE_short bytes_used;          /* The number of bytes used */
X    char data[PDS_data_length-2];  /* The entries, in alphabetical order */
X} PDS_DIRECTORY;
X
Xtypedef struct {
X    char name[8];                 /* The name of the member */
X    unsigned char ttr[3],         /* The 'TTR' of the member */
X        flags;                    /* The alias flag, TTR count and length */
X    char user_data[1];            /* The user data, if any */
X} PDS_ENTRY;
X
X#define pds_end_of_chain 0x800000 /* TLS's amazing end of chain marker */
X#define pds_alias_flag   0x80     /* The alias flag bit */
X#define pds_ttr_bits     0x60     /* The TTR count mask */
X#define pds_length_bits  0x1f     /* The halfword length mask */
END_OF_FILE
if test 2783 -ne `wc -c <'tlspds.h'`; then
    echo shar: \"'tlspds.h'\" unpacked with wrong size!
fi
# end of 'tlspds.h'
fi
if test -f 'version.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'version.h'\"
else
echo shar: Extracting \"'version.h'\" \(918 characters\)
sed "s/^X//" >'version.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xversion.h - specify the version number.  Warning: this is used by loadtape and
Xmvstape.  History:
X
X1.0    -    first beta release; stable but tested mainly by the author
X1.1    -    added partial support for other systems (initially OS/2), some
X            support for MTS and other illegal tapes, plus other improvements
X1.1.1  -    improved portability (in many respects)
X1.1.2  -    allow 'diskized' tapes to be piped in
X1.1.3  -    allow dynamic code pages and fix bugs
X1.1.4  -    make most tape mark counting automatic
X*/
X
X
Xextern char VERSION[];    /* To silence GCC and some other compilers */
X
Xchar VERSION[] = "\
X(C) Copyright N.M. Maclaren 1993, 1994, 1995\n\
X(C) Copyright the University of Cambridge 1993, 1994, 1995\n\
XALL RIGHTS RESERVED\n\
XMVSTAPE version 1.1.4\n\
X";
END_OF_FILE
if test 918 -ne `wc -c <'version.h'`; then
    echo shar: \"'version.h'\" unpacked with wrong size!
fi
# end of 'version.h'
fi
echo shar: End of archive 1 \(of 9\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 9 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0


