From: CSBVAX::MRGATE!montnaro@sprite@SMTP 20-MAR-1987 23:13 To: MODSRC Subj: ansitape.2 Received: by sprite.steinmetz (3.2/1.1x Steinmetz) id AA07109; Fri, 20 Mar 87 22:54:57 EST Date: Fri, 20 Mar 87 22:54:57 EST From: Skip Montanaro Posted-Date: Fri, 20 Mar 87 22:54:57 EST Message-Id: <8703210354.AA07109@sprite.steinmetz> To: modsrc@arisia.decnet Subject: ansitape.2 Path: seismo!rutgers!mit-eddie!mirror!sources-request From: sources-request@mirror.TMC.COM Newsgroups: mod.sources Subject: v08i100: ANSI tape program, Part02/02 Message-ID: <2061@mirror.TMC.COM> Date: 3 Mar 87 22:28:20 GMT Sender: rs@mirror.TMC.COM Lines: 1036 Approved: mirror!rs Submitted by: David S. Hayes Mod.sources: Volume 8, Issue 100 Archive-name: ansitape/Part02 This is the second part of Ansitape. It contains the makefile, the manual pages, and miscellaneous small files. The program itself is contained in the first message. [ I left this in its original wrapper because it wouldn't fit in one piece, so I didn't tamper... --r$ ] #!/bin/sh # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # Makefile ansitape.h tables.c ansitape.1 ansitape.5.tbl echo x - Makefile cat > "Makefile" << '//E*O*F Makefile//' # Makefile for ANSITAPE # # This program creates, reads, writes, and takes directory listings of # ANSI-formatted tapes. # # This program was developed at # # HQDA Army Artificial Intelligence Center # Pentagon Attn: DACS-DMA # Washington, DC 20310-0200 # # Phone: (202) 694-6900 # E-mail: # Arpa: merlin%hqda-ai.uucp@smoke.brl.arpa # alternate dshayes@smoke.brl.arpa # UUCP: ...!seismo!sundc!hqda-ai!merlin # # Support? You want support? What do I look like, a software house? # Mail me your gripes, comments, and bugs, and I'll try to keep # up with them. # # THIS PROGRAM IS IN THE PUBLIC DOMAIN. # Define AT MOST ONE of the following # Define this if you want debugging. #CCOPT = -g # Define this if you want compiler optimizations. CCOPT = -O # Define this if you want to handle IBM EBCDIC tapes. IBM = -DEBCDIC # Define this to be the maximum size of a file you are willing to # read to determine the record length. Files smaller than this # are read twice: once to find the max record length, and the second # time when writing the tape. Files larger than this just assume # that the recordlength == blocklength. Probably not a great # assumption, but we have to assume something. # # If this is not defined, the ansitape.c uses 100K by default. #READMAX = 100000 # This is the directory where ansitape will go. BIN = /usr/local/bin # This is the directory where you put your # unformatted manual pages for commands. CMDMAN = /usr/man/man1 # This is the directory where you put your # unformatted manual pages for file formats. FILEMAN = /usr/man/man5 # This is the directory where you put your # FORMATTED manual pages for file formats. # Define this to be /tmp if you don't keep # formatted copies of the file format manual pages. # Cron should clean it out eventually. FILECAT = /usr/man/cat5 all: ansitape man ansitape: ansitape.c ansitape.h tables.o cc ${CCOPT} -o ansitape ${IBM} ${READMAX} ansitape.c tables.o mv ansitape ${BIN} tables.o: tables.c man: man1 man5 man1: ansitape.1 cp ansitape.1 ${CMDMAN} man5: ansitape.5.tbl tbl ansitape.5.tbl > ${FILEMAN}/ansitape.5 tbl ansitape.5.tbl | nroff -man | colcrt > ${FILECAT}/ansitape.5 //E*O*F Makefile// echo x - ansitape.h cat > "ansitape.h" << '//E*O*F ansitape.h//' /* * This file contains the definitions of the tape control records. This * is to be used when developing a program to work with ANSI standard * labelled tapes. */ /* * Actually, these should be upper case. The ansitape program doesn't * convert things to upper case until the headers are made -- the tape * control block has everything in lower case. For the sake of easy * comparisons, we define them here as lower case. */ #define NOPROTECT ' ' /* space if no protection */ #define REC_FIXED 'f' /* Records are all fixed length */ #define REC_VARIABLE 'd' /* Records are preceeded by a 4-digit * zero-filled count of their length, * including the 4 digits themselves */ #define IBM_VARIABLE 'v' /* IBM's version of ANSI D format */ #define CC_FORTRAN 'a' /* First char of rec is f-77 carriage * control */ #define CC_EMBEDDED 'm' /* Carriage control is part of the data * contained in each record */ #define CC_IMPLIED ' ' /* Each record goes on a separate line * when printed */ /* * VOLUME 1 Describes the owner of and access to the volume. */ struct ansi_vol1 { char header[4]; /* VOL1 */ char label[6]; /* volume name, A-Z0-9 */ char access; /* access code */ char __ignored1[20]; /* reserved, space fill */ char __ignored2[6]; /* reserved, space fill */ char owner[14]; /* user name */ char __ignored3[28]; /* reserved, space fill */ char ansi_level; /* ansi standard level, always 3 */ }; /* * VOLUME 2 optional, ignored by this software. */ /* * HEADER 1 Begins basic description of a tape file. */ struct ansi_hdr1 { char header[4]; /* HDR1 */ char name[17]; /* rightmost 17 characters of filename */ char fileset[6]; /* should be same as volume id of 1st * tape */ char volume_num[4]; /* number of volume in set */ char file_num[4];/* number of file on tape */ char gen[4]; /* generation number */ char genver[2]; /* generation version number */ char created[6]; /* date of creation, "bYYDDD" */ char expires[6]; /* expiration date "bYYDDD" */ char access; /* protection, space = unprotected */ char blockcount[6]; /* zero in header */ char tapesys[13];/* name of software creating tape */ char __ignored[7]; /* reserved, space fill */ }; /* * HEADER 2 Record format, record size, block size. */ struct ansi_hdr2 { char header[4]; /* HDR2 */ char recfmt; /* record format */ char blocklen[5];/* file tape block length */ char reclen[5]; /* file logical record length */ char density; /* density/recording mode. Should be 2 * for 800 bpi, 3 for 1600 bpi. */ char vol_switch; /* 0, or 1 if this file was continued */ char job[17]; /* job name (8), /, job step (8) of * creator */ char recording[2]; /* parity/conversion, space * fill */ char carriage_control; char alignment; /* reserved, space fill */ char blocked_records; /* 'B' if records are blocked */ char __ignored2[11]; char block_offset[2]; /* ingore 1st n char of each * block */ char __ignored3[28]; }; /* * HEADER 3 This contains a bunch of rms-dependent data. We will * ignore it for now, and hope that it doesnt screw up VMS too badly. */ struct ansi_hdr3 { char header[4]; /* HDR3 */ char os_reserved[76]; /* reserved to OS, space fill */ }; /* * HEADER 4 This is the rest of the filename if its longer than 17 * characters. We should have no trouble fitting UNIX filenames into * this. */ struct ansi_hdr4 { char header[4]; /* HDR4 */ char name2[63]; /* leftmost char, if name is more than * 17 characters long. */ char unknown[2]; /* fill with 00 */ char __ignored[11]; }; /* * FORMAT NOTES * * 1. The tape always starts with a VOL1 record. Other volume records * are optional. We ignore them, and do not generate them on output. * * 2. Each file starts with a set of HDRn records. The headers are * followed by a tape mark. * * 3. The data is written to the tape in fixed-length blocks. Valid ANSI * block lengths are 18 to 2048 bytes, although VMS will support longer * blocks. The block does not have to be full. If the block is not * completely filled, the remainder of the block is padded with * circumflex (^) characters. The file is followed by a tape mark. * * 4. Trailing records are written. Either EOF or EOV records may be * used. The record formats are the same as the HDR records, expect: * * a. the "HDR" is replaced by "EOF" or "EOV". * * b. the blockcount field in EOF1/EOV1 contains the actual number of * physical tape blocks written in the preceding file section. In the * HDR1 record, the blockcount is 000000. * * 5. A tape file may extend across a volume boundary. If it does, EOV * labels are used, indicating that another tape must be read. If the * file ends here, an EOF label is used. * * 6. After the EOF records, a tape mark is written. This separates the * trailers from the headers for the next file. At the end of the * tape, two tape marks are written. */ //E*O*F ansitape.h// echo x - tables.c cat > "tables.c" << '//E*O*F tables.c//' /* Mapping of EBCDIC codes to ASCII equivalents. */ static char to_ascii_table[256] = { '\000', '\001', '\002', '\003', '\234', '\011', '\206', '\177', '\227', '\215', '\216', '\013', '\014', '\015', '\016', '\017', '\020', '\021', '\022', '\023', '\235', '\205', '\010', '\207', '\030', '\031', '\222', '\217', '\034', '\035', '\036', '\037', '\200', '\201', '\202', '\203', '\204', '\012', '\027', '\033', '\210', '\211', '\212', '\213', '\214', '\005', '\006', '\007', '\220', '\221', '\026', '\223', '\224', '\225', '\226', '\004', '\230', '\231', '\232', '\233', '\024', '\025', '\236', '\032', '\040', '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\133', '\056', '\074', '\050', '\053', '\041', '\046', '\251', '\252', '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\135', '\044', '\052', '\051', '\073', '\136', '\055', '\057', '\262', '\263', '\264', '\265', '\266', '\267', '\270', '\271', '\174', '\054', '\045', '\137', '\076', '\077', '\272', '\273', '\274', '\275', '\276', '\277', '\300', '\301', '\302', '\140', '\072', '\043', '\100', '\047', '\075', '\042', '\303', '\141', '\142', '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\304', '\305', '\306', '\307', '\310', '\311', '\312', '\152', '\153', '\154', '\155', '\156', '\157', '\160', '\161', '\162', '\313', '\314', '\315', '\316', '\317', '\320', '\321', '\176', '\163', '\164', '\165', '\166', '\167', '\170', '\171', '\172', '\322', '\323', '\324', '\325', '\326', '\327', '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\173', '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\110', '\111', '\350', '\351', '\352', '\353', '\354', '\355', '\175', '\112', '\113', '\114', '\115', '\116', '\117', '\120', '\121', '\122', '\356', '\357', '\360', '\361', '\362', '\363', '\134', '\237', '\123', '\124', '\125', '\126', '\127', '\130', '\131', '\132', '\364', '\365', '\366', '\367', '\370', '\371', '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', '\070', '\071', '\372', '\373', '\374', '\375', '\376', '\377' }; /* Mapping of ASCII codes to EBCDIC equivalents. */ static char to_ebcdic_table[256] = { '\000', '\001', '\002', '\003', '\067', '\055', '\056', '\057', '\026', '\005', '\045', '\013', '\014', '\015', '\016', '\017', '\020', '\021', '\022', '\023', '\074', '\075', '\062', '\046', '\030', '\031', '\077', '\047', '\034', '\035', '\036', '\037', '\100', '\117', '\177', '\173', '\133', '\154', '\120', '\175', '\115', '\135', '\134', '\116', '\153', '\140', '\113', '\141', '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\172', '\136', '\114', '\176', '\156', '\157', '\174', '\301', '\302', '\303', '\304', '\305', '\306', '\307', '\310', '\311', '\321', '\322', '\323', '\324', '\325', '\326', '\327', '\330', '\331', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351', '\112', '\340', '\132', '\137', '\155', '\171', '\201', '\202', '\203', '\204', '\205', '\206', '\207', '\210', '\211', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\230', '\231', '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\251', '\300', '\152', '\320', '\241', '\007', '\040', '\041', '\042', '\043', '\044', '\025', '\006', '\027', '\050', '\051', '\052', '\053', '\054', '\011', '\012', '\033', '\060', '\061', '\032', '\063', '\064', '\065', '\066', '\010', '\070', '\071', '\072', '\073', '\004', '\024', '\076', '\341', '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\110', '\111', '\121', '\122', '\123', '\124', '\125', '\126', '\127', '\130', '\131', '\142', '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\200', '\212', '\213', '\214', '\215', '\216', '\217', '\220', '\232', '\233', '\234', '\235', '\236', '\237', '\240', '\252', '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', '\312', '\313', '\314', '\315', '\316', '\317', '\332', '\333', '\334', '\335', '\336', '\337', '\352', '\353', '\354', '\355', '\356', '\357', '\372', '\373', '\374', '\375', '\376', '\377' }; to_ebcdic(source, dest, count) char *source, *dest; int count; { for (; count--;) *(dest++) = to_ebcdic_table[0377 & *(source++)]; } to_ascii(source, dest, count) char *source, *dest; int count; { for (; count--;) *(dest++) = to_ascii_table[0377 & *(source++)]; } //E*O*F tables.c// echo x - ansitape.1 cat > "ansitape.1" << '//E*O*F ansitape.1//' ..TH ANSITAPE 1 "23 June 1986" AICenter Merlin ..\"@(#)ansitape.1 2.0 86/07/08 AICenter; by David S. Hayes ..SH NAME ansitape \- ANSI-standard magtape label program ..SH SYNOPSIS \fIansitape \fPtxrc\[vqfaei3\] \[\mt=\fIdevice\fP\] ..RS +0.5i ..br \[vo=\fIvolume-name\fP\] \[rs=\[ r | \fIrecordsize\fP \]\] \[bs=\fIblocksize\fP] ..br \[rf=\[ v | f \]\] \[cc=\[ i | f | e \]\] ..br \fIfilename1 filename2\fR . . . ..RE -0.5i ..SH DESCRIPTION ..LP \fIAnsitape\fP reads, writes, and creates magtapes conforming to the ANSI standard for magtape labelling. Primarily, this is useful to exchange tapes with VAX/VMS, which makes this kind of tape by default. ..LP \fIAnsitape\fP is controlled by a function key letter ..BR "(t, x, c, or r)" . Various options modify the format of the output tape. ..SH "Writing ANSI Tapes" ..PP The list of files on the command line is written to the tape. A full Unix pathname may be specified, however, only the last pathname component (everything after the last /) is used as the filename on the tape. ..PP Normally, regular text files are to be exchanged. ..I ansitape reads the files one line at a time and transfers them to the tape. The newline character at the end of each line is removed, and the file is written in a variable-length record format. Variable-format files have the length of the longest record specified in a file header. Therefore, ..I ansitape will read each input file from disk before it goes on to tape, to determine the maximum record size. The read is skipped if the file is more than 100,000 bytes long. The default carriage control (implied) instructs the other host to restore the newline character before printing the record. ..PP If \fIansitape\fP thinks that the input file is a Unix text file (Fortran or implied carriage control), it will automatically strip the the Unix newline from the end of each record. No strip is done with embedded carriage control files, or with any file using a fixed-length record format. ..PP For binary files, fixed-length records should be used. VAX/VMS normally uses a record length of 512 bytes for things like directories and executable files, but data files may have any record length. Binary files should be flagged for embedded (\fIrf=e\fP) carriage control. ..sp ..SH "Reading ANSI Tapes" ..PP When reading, the input file list is presumed to be the names of files to be extracted from the tape. The shell wildcard characters asterisk (*) and question-mark (?) may be used. Of course, they must be quoted to prevent the shell from interpreting them before ..I ansitape sees them. ..PP None of the options for record format or carriage control need be specified when reading files. ..I Ansitape will automatically pick up this information from the header records on the tape, and do the right thing. If you can't get just what you want from ..IR ansitape , the resulting files may be run through ..IR dd(1) . ..sp ..SH "FUNCTION LETTERS" ..PP These function letters describe the overall operation desired. One of them must be specified in the first argument to ..IR ansitape . For lexically rigorous Unix fans, a minus sign (-) is allowed, but optional, to introduce the first keyword option set. ..TP 6 ..I r Write the named files on the end of the tape. This requires that the tape have been previously initialized with an ANSI volume header. ..TP 6 ..I c Create a new magtape. The tape is initialized with a new ANSI volume header. All files previously on the tape are destroyed. This option implies \fIr\fP. ..TP 6 ..I x Extract all files from the tape. Files are placed in the current directory. Protection is r/w to everyone, modified by the current \fIumask(2)\fP. ..TP 6 ..I t List all of the names on the tape. ..sp ..SH "MODIFIER KEY LETTERS" ..PP These key letters are part of the first argument to ..IR ansitape . ..TP 6 ..I v Normally \fIansitape\fP does its work silently; the \fIv\fP (verbose) option displays the name of each file \fIansitape\fP treats, preceded by the function letter. It also displays the volume name of each tape as it is mounted. When used with the \fIt\fP option, \fIansitape\fP displays the number of tape blocks used by each file, the record format, and the carriage control option. ..TP 6 ..I q Query before writing anything. On write (c or r options), this causes \fIansitape\fP to ask before writing to the tape. On extract operations, \fIansitape\fP displays the Unix pathname, and asks if it should extract the file. Any response starting with a 'y' or 'Y' means yes, any other response (including an empty line) means no. ..TP 6 ..I f File I/O is done to standard i/o instead. For example, when writing a tape file that is to contain a lint listing, we could specify ..sp lint xyz.c | ansitape rf xyz.lint ..sp instead of ..sp lint xyz.c > /tmp/xyz.lint ..br ansitape r /tmp/xyz.lint ..br rm /tmp/xyz.lint ..sp When reading, this option causes the extracted files to be sent to stdout instead of a disk file. ..TP 6 ..I a The tape should be read or written with the ASCII character set. This is the default. ..TP 6 ..I e The tape should be written with the EBCDIC character set. The mapping is the same one used by the ..I dd(1) program with ..IR conv=ebcdic . This option is automatically enabled if IBM-format labels are selected. ..TP 6 ..I i Use IBM-format tape labels. The IBM format is very similar, but not identical, to the ANSI standard. The major difference is that the tape will contain no HDR3 or HDR4 records, thus restricting the name of the files on the tape to 17 characters. This option automatically selects the EBCDIC character set for output. To make an IBM-format label on a tape using the ASCII character set (why?), use the option sequence ..IR ia . ..TP 6 ..I 3 Do not write HDR3 or HDR4 labels. The HDR3 label is reserved for the use of the operating system that created the file. HDR4 is for overflow of filenames that are longer than the 17 characters allocated in the HDR1 label. Not all systems process these labels correctly, or even ignore them correctly. This switch suppresses the HDR3 and HDR4 labels when the tape is to be transfered to a system that would choke on them. ..SH "FUNCTION MODIFIERS" ..PP Each of these options should be given as a separate argument to ..IR ansitape . Multiple options may be specified. They must appear as after the key-letter options above, and before any filename arguments. ..TP 6 ..IR mt= device Select an alternate drive on which the tape is mounted. The default is ..IR /dev/rmt8 . ..TP 6 ..IR vo= volume-name Specify the name of the output volume. Normally, this defaults to the first six characters of your login name. The string 'UNIX' is used as the default if \fIansitape\fP cannot determine your login name. ..TP 6 ..IR rs= recordsize Specify the output recordsize in bytes. This is the maximum size in the case of variable-format files. This option also turns on the fixed-record-format option. Thus, if you want to have variable record sizes with a smaller maximum, you must specify ..sp ..ce ..IR rs= "recordsize " rf=v ..sp When the recordsize is manually given, ..I ansitape does not read disk files to determine the maximum record length. ..TP 6 ..I rs=r This is a variant of the ..I rs= option. This causes ..I ansitape to read all disk files for recordsize, regardless of their size. Normally, files larger than 100K bytes are not scanned for recordsize. Using this option also implies variable-length records. ..TP 6 ..IR bs= blocksize Specify the output blocksize, in bytes. As many records as will fit are crammed into each physical tape block. ANSI standards limit this to 2048 bytes (the default), but you may specify more or less. Be advised that specifying more may prevent some systems from reading the tape. ..TP 6 ..I rf=v Record format is variable-length. In other words, they are text files. This is the default, and should be left alone unless you really know what you're doing. ..TP 6 ..I rf=f Record format is fixed-length. This is usually a bad choice, and should be reserved for binary files. This also turns off the newline strip usually done for Unix text files. ..TP 6 ..I cc=i Carriage control implied (default). Unlike Unix text files, where records are delimited by a newline character, ANSI files do not normally include the newline as part of the record. Instead, a newline is automatically added to the record whenever it is sent to a printing device. ..TP 6 ..I cc=f Carriage control Fortran. Each line is expected to start with a Fortran carriage-control character. \fIAnsitape\fP does not insert these characters automatically, it merely marks the file as having them. This is of limited usefulness. (Good opportunity for another ambitious hacker.) ..TP 6 ..I cc=e Carriage control is embedded. Carriage control characters (if any) are a part of the data records. This is usually used in the case of binary data files. ..TP 6 ..SH FILES /dev/rmt? half-inch magnetic tape interface ..br /dev/rar? quarter-inch magnetic tape interface ..br /dev/rst? SCSI tape interface ..SH "SEE ALSO" dd(1), umask(2), mtio(4), tp(5) ..SH AUTHOR David S. Hayes, Site Manager, US Army Artificial Intelligence Center. Originally developed June 1986. Revised August 1986. This software is in the public domain. ..SH BUGS ..LP The ..I r (write) option cannot be used with quarter-inch archive tapes, since these tape drives cannot backspace. ..LP There is no way to ask for the ..IR n -th occurrence of a file. ..LP Tape errors are handled ungracefully. ..LP Files with names longer than 80 characters have the name truncated. This is a limitation of the ANSI labelling standard. If the tape is made without HDR3 and HDR4 labels (\fI3\fP or \fIi\fP switch), the name is limited to 17 characters. ..LP Multi-volume tape sets cannot yet be generated. ..I ansitape will read them just fine, but it won't write them. Unix provides no device-independent way to detect a physical end-of-tape. It was decided that a 2400-foot limitation was preferrable to device-dependence. ..TP 6 Note to Systems Programmers: ..I ansitape uses a boolean function ..I (eot) to determine when the tape drive has hit the end of file. It is called every time a block of data is written to the tape. If this function ever returns TRUE (a defined constant), an automatic volume switch occurs. The pertinent device registers are obtained by a MTIOCGET ioctl system call. The registers are described in ..I /sys/sundev/tmreg.h (Sun system with TapeMaster controller). If you have a VAX, the filename will be slightly different. Sun Microsystems supplies this file even with binary-only distributions. //E*O*F ansitape.1// echo x - ansitape.5.tbl cat > "ansitape.5.tbl" << '//E*O*F ansitape.5.tbl//' ..TH ANSITAPE 5 "8 August 1986" ..SH NAME ansitape - ANSI standard magtape labels ..SH DESCRIPTION ..PP An ANSI-labelled tape starts with a volume header. This header specifies the volume name and protection, the owner of the volume, and the ANSI label standard level that the tape conforms to. ..PP Every file on the tape has a header, some data blocks, and a trailer. A tape mark follows each of these elements. At the end of the tape, two tape marks follow the trailer, to indicate logical end-of-tape. ..PP If a file is too large to be copied onto one tape, it may be continued on another tape by modifying the trailer section. ..sp ..SH "VOLUME HEADER" ..TS expand allbox; c c c c l n c l . Field Width Example Use VOL1 4 VOL1 T{ Indicates this is a volume header. T} Label 6 VAX1 T{ The name of the volume. T} Access 1 space T{ Volume protection. Space means unprotected. T} IGN1 20 << ignored >> IGN2 6 << ignored >> Owner 14 Joe User T{ The name of the user. T} IGN3 28 << ignored >> Level 1 3 ANSI standard level. ..TE ..sp ..TP 10 Owner The owner field is 14 characters in ANSI labels. IBM labels cut the owner field to 10 characters. The IGN2 field is 10 characters on IBM-format tapes. ..bp ..SH "FILE HEADERS" ..LP ..TS expand allbox; c c c c l n c l . Field Width Example Use HDR1 4 HDR1 T{ Identifies first file header. T} Name 17 FILE.DAT T{ Leftmost 17 characters of filename. T} Set 6 VAX1 T{ Name of volume set this file is part of. T} Vol Num 4 0001 T{ Number of this volume within volume set. T} File Num 4 0001 T{ Number of file on this tape. T} Generation 4 0001 T{ Like a major release number. T} Gen Version 2 00 T{ Version of a file within a release. T} Created 6 b86001 T{ The date of file creation. T} Expires 6 b86365 T{ Date file expires. T} Access 1 space T{ File protection. Space means unprotected. T} Blockcount 6 000000 T{ Number of blocks in the file. T} System 13 OS360 T{ The name of the software system that created the tape. T} IGN 7 << ignored >> ..TE ..sp ..TP 1i Name The filename may be up to 17 characters in IBM labels, and ANSI labels before standard level 3. On ANSI level 3 and after, the HDR4 record provides overflow storage for up to 63 more characters of filename. ..TP Set Name On multi-reel tape sets, a name identifying the set as a whole. Normally, this is just the volume name of the first reel in the set. ..TP Generation Like a major release number. The version field is a version within a generation. On VAX/VMS systems, these two fields are mathematically related to the (single) version number of disk files. ..TP Created The date the file was created. This is a six character field, where the first character is always a space. The next two are the year. The final 3 are the day within the year, counting January 1st as day 1. ..TP Blocks The number of blocks in the file. In HDR1 records, this is always zero. The corresponding EOF1 or EOV1 contains the number of tape blocks written in the file on the current reel. ..bp ..LP ..TS expand allbox; c c c c l n c l . Field Width Example Use HDR2 4 HDR2 T{ Second file header. T} Rec Format 1 D Record format. Blk Length 5 02048 Tape block size. Rec Length 5 00080 Record size. Density 1 3 Recording density code. Vol Switch 1 0 T{ 1 if this is a continuation of a file from a previous reel. T} Job 17 user/program See following notes. Recording 2 space Unused in 9-track tapes. Car Control 1 space See following notes. Blocking 1 B See following notes. IGN 11 << ignored >> Offset 2 00 T{ Bytes to skip at front of each block. T} ..TE ..TP Rec Format A single character indicating what type of records are provided. The codes are ..sp ..TS center allbox; c c c l . Code Meaning F Fixed-length D Variable up to rec length V IBM code for variable U Unknown ..TE ..TP Job The name of the job (username in Unix) right-padded to 8 characters, a slash (/), and the job step (program name in Unix) right-padded to 8 characters. This identifies where the JCL was when this file was created. ..TP Carriage Control Normally a space, indicating that the records do not contain carriage control information. When printed, each record is placed on a separate line. If an 'A' is used, the first character of each record is presumed to be a Fortran carriage-control character. VAX/VMS also uses 'M' to indicate that carriage-control is embedded as part of the data. This is usually used in the case of binary files. ..TP Blocking The B indicates that as many records as will fit are placed in a physical tape block. Records do not cross block boundaries. A space indicates only one record per physical tape block. ..bp ..LP The HDR3 and HDR4 labels are not written on IBM tapes. ANSI allows, but does not require, these labels. ..sp ..TS expand allbox; c c c c l n c l . Field Width Example Use HDR3 4 HDR3 Third file header. OS 76 Operating-system dependent. ..TE ..TP OS This field is reserved for the use of the operating system that created the file. Other operating systems are supposed to disregard HDR3 records. On VAX/VMS, this record contains the RMS file description. ..sp ..LP ..TS expand allbox; c c c c l n c l . Field Width Example Use HDR4 4 HDR4 Fourth file header. Name 2 63 Name continuation from HDR1. Unknown 2 00 Unknown, fill with 00. IGN 11 << ignored >> ..TE ..TP Name 2 On ANSI tapes, if the filename is longer than 17 characters, the first 17 are placed in the HDR1 record. The next 63 are put in HDR4. Filenames longer than 80 characters are truncated. Note that it is not required to have a HDR3 record in order to have a HDR4. ..sp ..SH "FILE TRAILING LABELS" ..PP These labels are written after a tape file. For every label written at the head of the file, there will be a corresponding label at the tail. Except for the ..I "block count" field in HDR1, the only difference is in the name of the label. If we have reached the logical end of the file, the characters ..I HDR in the headers are replaced by the characters ..I EOF in the trailing labels. If we are not at the logical end of the file, but are merely pausing at the physical end of tape before continuing on another reel, the ..I HDR characters are replaced by ..I EOV (end-of-volume). ..PP The ..I "block count" field of HDR1 was initially recorded as 000000. When the trailers are written, the block count is changed to indicate the number of tape data blocks written. A file that is continued over several volumes maintains separate counts for each reel. ..SH "RECORD FORMATS" ..PP The two basic record formats are fixed and variable. ..PP Fixed format uses records that are all constant length. This is the case with VAX/VMS executable images (record length = 512). It is also used by IBM systems for text files, with a record length of 80 (card images). The record size field of HDR2 tells how long each record is. ..PP With fixed-length records, the blocksize is usually selected to be some multiple of the recordsize. As many records as will fit are placed in each block. Since records do not (normally) span physical tape blocks, extra space at the end of a block is wasted. ..PP Variable-length records are used by VAX/VMS for text files. The Unix program ..I ansitape(1) also turns Unix text files into variable-length tape files. With this format, the record length specified in HDR2 is an upper limit. ..PP Each record is preceeded by a 4-digit (zero-filled) byte count. The count included the digits themselves, so the minimum valid number is 0004. These four digits specify how long the record is. The data follows the digits, and is in turn followed by the digits for the next record. ..PP When writing, ..I ansitape checks to make sure that there is enough room in the tape block for the next record. If the record (including its length digits) won't fit, the current block is sent to the tape, and a new block is started. Unused space at the end of the tape block is filled with circumflex (^) characters. //E*O*F ansitape.5.tbl// echo Possible errors detected by \'wc\' [hopefully none]: temp=/tmp/shar$$ trap "rm -f $temp; exit" 0 1 2 3 15 cat > $temp <<\!!! 83 363 2185 Makefile 149 881 5555 ansitape.h 156 578 5687 tables.c 302 1797 10559 ansitape.1 290 1477 7890 ansitape.5.tbl 980 5096 31876 total !!! wc Makefile ansitape.h tables.c ansitape.1 ansitape.5.tbl | sed 's=[^ ]*/==' | diff -b $temp - exit 0 -- David S. Hayes, The Merlin of Avalon PhoneNet: (202) 694-6900 ARPA: merlin%hqda-ai.uucp@brl-smoke UUCP: ...!seismo!sundc!hqda-ai!merlin