From 40e5a5811c6ffce9b0974e93cdd927cbcf60c157 Mon Sep 17 00:00:00 2001 From: Joe Hunkeler Date: Tue, 11 Aug 2015 16:51:37 -0400 Subject: Repatch (from linux) of OSX IRAF --- unix/boot/rtar/README | 5 + unix/boot/rtar/mkpkg.sh | 6 + unix/boot/rtar/rtar.c | 863 ++++++++++++++++++++++++++++++++++++++++++++++++ unix/boot/rtar/rtar.hlp | 165 +++++++++ unix/boot/rtar/rtar.ms | 125 +++++++ 5 files changed, 1164 insertions(+) create mode 100644 unix/boot/rtar/README create mode 100644 unix/boot/rtar/mkpkg.sh create mode 100644 unix/boot/rtar/rtar.c create mode 100644 unix/boot/rtar/rtar.hlp create mode 100644 unix/boot/rtar/rtar.ms (limited to 'unix/boot/rtar') diff --git a/unix/boot/rtar/README b/unix/boot/rtar/README new file mode 100644 index 00000000..61e45d80 --- /dev/null +++ b/unix/boot/rtar/README @@ -0,0 +1,5 @@ +RTAR -- Read tar format file or tape. This is a portable, non-UNIX, non- + proprietary program for reading tar format files on a variety of + systems. The TAR format is an excellent choice for transporting + files between different machines because of its simplicity, efficiency, + and machine independence. diff --git a/unix/boot/rtar/mkpkg.sh b/unix/boot/rtar/mkpkg.sh new file mode 100644 index 00000000..ec801f5f --- /dev/null +++ b/unix/boot/rtar/mkpkg.sh @@ -0,0 +1,6 @@ +# Bootstrap RTAR. + +$CC -c $HSI_CF rtar.c +$CC $HSI_LF rtar.o $HSI_LIBS -o rtar.e +mv rtar.e ../../hlib +rm -f rtar.o diff --git a/unix/boot/rtar/rtar.c b/unix/boot/rtar/rtar.c new file mode 100644 index 00000000..6ef2e37e --- /dev/null +++ b/unix/boot/rtar/rtar.c @@ -0,0 +1,863 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + */ + +#include +#include +#include +#include +#include + +#define NOKNET +#define import_spp +#define import_knames +#include + +#include "../bootProto.h" + + +/* + * RTAR -- Read a UNIX tar format tape containing files with legal IRAF + * virtual filenames. Map tape filenames to host system filenames using + * IRAF filename mapping if the tape does not contain legal host system + * filenames. + * + * Switches: + * a advance to first file in filelist before doing + * anything. useful for restarting an aborted + * operation. first file is not otherwise used. + * b generate only C style binary byte stream output + * files (default is to write a text file when + * the input stream is text). + * d print debug messages + * e exclude, rather than include, listed files + * f read from named file rather than stdin + * l do not try to resolve links by a file copy + * m do not restore file modify times + * n do not strip tailing blank lines from text files + * o omit binary files (e.g. when foreign host has + * incompatible binary file format) + * p omit the given pathname prefix when creating files + * r replace existing file at extraction + * t print name of each file matched + * u do not attempt to restore user id + * v verbose; print full description of each file + * x extract files (extract everything if no files + * listed or if -e is set) + * + * Switches must be given in a group, in any order, e.g.: + * + * rtar -xetvf tarfile sys/osb sys/os lib/config.h$ + * + * would extract all files from tarfile with names not beginning with sys/os + * or sys/osb or with names not equal to lib/config.h, printing a verbose + * description of each file extracted. If an exclude filename does not end + * with a $ all files with the given string as a prefix are excluded. + */ + +#define TBLOCK 512 +#define NBLOCK 20 +#define NAMSIZ 100 +#define MAXERR 20 +#define MAXTRYS 100 +#define MAXLINELEN 256 +#define SZ_TAPEBUFFER (TBLOCK * NBLOCK) +#define EOS '\0' +#define ERR (-1) +#define OK 0 +#define RWXR_XR_X 0755 +#define SZ_PADBUF 8196 +#define ctrlcode(c) ((c) >= '\007' && (c) <= '\017') + +#define LF_LINK 1 +#define LF_SYMLINK 2 +#define LF_DIR 5 + +/* File header structure. One of these precedes each file on the tape. + * Each file occupies an integral number of TBLOCK size logical blocks + * on the tape. The number of logical blocks per physical block is variable, + * with at most NBLOCK logical blocks per physical tape block. Two zero + * blocks mark the end of the tar file. + */ +union hblock { + char dummy[TBLOCK]; + struct header { + char name[NAMSIZ]; /* NULL delimited */ + char mode[8]; /* octal, ascii */ + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char linkflag; + char linkname[NAMSIZ]; + } dbuf; +}; + + +/* Decoded file header. + */ +struct fheader { + char name[NAMSIZ]; + int mode; + int uid; + int gid; + int isdir; + long size; + long mtime; + long chksum; + int linkflag; + char linkname[NAMSIZ]; +}; + + +static int advance; /* Advance to named file */ +static int stripblanks; /* strip blank padding at end of file */ +static int debug; /* Print debugging messages */ +static int binaryout; /* make only binary byte stream files */ +static int omitbinary; /* omit binary files (do not write) */ +static int extract; /* Extract files from the tape */ +static int replace; /* Replace existing files */ +static int exclude; /* Excluded named files */ +static int printfnames; /* Print file names */ +static int verbose; /* Print everything */ +static int links; /* Defeat copy to resolve link */ +static int setmtime; /* Restore file modify times */ +static int rsetuid; /* Restore file user id */ + +static char *pathprefix = NULL; +static int len_pathprefix = 0; +static struct fheader *curfil; +static int eof; +static int nerrs; +static char *first_file; +static char tapeblock[SZ_TAPEBUFFER]; +static char *nextblock; +static int nblocks; + +extern int ZZSTRT (void); +extern int ZZSTOP (void); + +extern int tape_open (char *fname, int mode); +extern int tape_close (int fd); +extern int tape_read (int fd, char *buf, int nbytes); + +static int matchfile (char *fname, register char **files); +static int getheader (int in, register struct fheader *fh); +static int cchksum (register char *p, register int nbyte); +static void printheader (FILE *out, register struct fheader *fh, int verbose); +static int filetype (int in, struct fheader *fh); +static int newfile (char *fname, int mode, int uid, int gid, int type); +static int checkdir (register char *path, int mode, int uid, int gid); +static void copyfile (int in, int out, struct fheader *fh, int ftype); +static void strip_blanks (int in, int out, long nbytes); +static void skipfile (int in, struct fheader *fh); +static char *getblock (int in); + + + + +char *getblock(); + + +/* MAIN -- "rtar [xtvlef] [names]". The default operation is to extract all + * files from the tar format standard input in quiet mode. + */ +int main (int argc, char *argv[]) +{ + struct fheader fh; + char **argp; + char *ip; + int in = 0, out; + int ftype; + int ch; + + ZZSTRT(); /* initialize the IRAF kernel */ + + advance = 0; + debug = 0; + binaryout = 0; + omitbinary = 0; + extract = 0; + replace = 0; + exclude = 0; + printfnames = 0; + verbose = 0; + links = 0; + setmtime = 1; + rsetuid = 1; + stripblanks = 1; /* strip blanks at end of file by default */ + + /* Get parameters. Argp is left pointing at the list of files to be + * extracted (default all if no files named). + */ + argp = &argv[1]; + if (argc <= 1) + extract++; + else { + while (*argp && **argp == '-') { + ip = *argp++ + 1; + while ((ch = *ip++) != EOS) { + switch (ch) { + case 'a': + advance++; + break; + case 'n': + stripblanks = 0; + break; + case 'x': + extract++; + break; + case 'b': + binaryout++; + break; + case 'd': + debug++; + break; + case 'e': + exclude++; + break; + case 'r': + replace++; + break; + case 't': + printfnames++; + break; + case 'v': + printfnames++; + verbose++; + break; + case 'l': + links++; + break; + case 'm': + setmtime = 0; + break; + case 'u': + rsetuid = 0; + break; + case 'o': + omitbinary++; + break; + case 'p': + if (*argp != NULL) { + pathprefix = *argp++; + len_pathprefix = strlen (pathprefix); + } + break; + case 'f': + if (*argp == NULL) { + fprintf (stderr, "missing filename argument\n"); + exit (OSOK+1); + } + in = tape_open (*argp, 0); + if (in == ERR) { + fprintf (stderr, "cannot open `%s'\n", *argp); + ZZSTOP(); + exit (OSOK+1); + } + argp++; + break; + default: + fprintf (stderr, "Warning: unknown switch `%c'\n", ch); + fflush (stderr); + break; + } + } + } + } + + /* If advancing to a file get the name of the file. This file name + * occurs at the beginning of the file list but is not part of the list. + * Only full filenames are permitted here. + */ + if (advance) + first_file = *argp++; + + /* Step along through the tar format file. Read file header and if + * file is in list and extraction is enabled, extract file. + */ + while (getheader (in, &fh) != EOF) { + curfil = &fh; + if (advance) { + if (strcmp (fh.name, first_file) == 0) { + if (debug) + fprintf (stderr, "match\n"); + advance = 0; + } else { + if (debug) + printheader (stderr, &fh, verbose); + skipfile (in, &fh); + continue; + } + } + + if (matchfile (fh.name, argp) == exclude) { + if (debug) + fprintf (stderr, "skip file `%s'\n", fh.name); + skipfile (in, &fh); + continue; + } + + if (printfnames) { + printheader (stdout, &fh, verbose); + fflush (stdout); + } + + if (fh.linkflag == LF_SYMLINK || fh.linkflag == LF_LINK) { + /* No file follows header if file is a link. Try to resolve + * the link by copying the original file, assuming it has been + * read from the tape. + */ + if (extract) { + if (fh.linkflag == LF_SYMLINK) { + if (replace) + os_delete (fh.name); + if (symlink (fh.linkname, fh.name) != 0) { + fprintf (stderr, + "Cannot make symbolic link %s -> %s\n", + fh.name, fh.linkname); + } + } else if (fh.linkflag == LF_LINK && !links) { + if (replace) + os_delete (fh.name); + if (os_fcopy (fh.linkname, fh.name) == ERR) { + fprintf (stderr, "Copy `%s' to `%s' fails\n", + fh.linkname, fh.name); + } else { + os_setfmode (fh.name, fh.mode); + if (rsetuid) + os_setowner (fh.name, fh.uid, fh.gid); + if (setmtime) + os_setmtime (fh.name, fh.mtime); + } + } else { + fprintf (stderr, + "Warning: cannot make link `%s' to `%s'\n", + fh.name, fh.linkname); + } + } + continue; + } + + if (extract) { + ftype = filetype (in, &fh); + if (fh.size > 0 && ftype == BINARY_FILE && omitbinary) { + if (printfnames) + fprintf (stderr, "omit binary file `%s'\n", fh.name); + skipfile (in, &fh); + continue; + } + out = newfile (fh.name, fh.mode, fh.uid, fh.gid, ftype); + if (out == ERR) { + fprintf (stderr, "cannot create file `%s'\n", fh.name); + skipfile (in, &fh); + continue; + } + if (!fh.isdir) { + copyfile (in, out, &fh, ftype); + os_close (out); + } + os_setfmode (fh.name, fh.mode); + if (rsetuid) + os_setowner (fh.name, fh.uid, fh.gid); + if (setmtime) + os_setmtime (fh.name, fh.mtime); + } else + skipfile (in, &fh); + } + + /* End of TAR file normally occurs when a zero tape block is read; + * this is not the same as the physical end of file, leading to + * problems when reading from sequential devices (e.g. pipes and + * magtape). Advance to the physical end of file before exiting. + */ + if (!eof) + while (tape_read (in, tapeblock, SZ_TAPEBUFFER) > 0) + ; + if (in) + tape_close (in); + + ZZSTOP(); + exit (OSOK); + + return (0); +} + + +/* MATCHFILE -- Search the filelist for the named file. If the file list + * is empty anything is a match. If the list element ends with a $ an + * exact match is required (excluding the $), otherwise we have a match if + * the list element is a prefix of the filename. + */ +static int +matchfile ( + char *fname, /* filename to be compared to list */ + register char **files /* pointer to array of fname pointers */ +) +{ + register char *fn, *ln; + register int firstchar; + + if (*files == NULL) + return (1); + + firstchar = *fname; + do { + if (**files++ == firstchar) { + for (fn=fname, ln = *(files-1); *ln && *ln == *fn++; ) + ln++; + if (*ln == EOS) + return (1); + else if (*ln == '$' && *(fn-1) == EOS) + return (1); + } + } while (*files); + + return (0); +} + + +/* GETHEADER -- Read the next file block and attempt to interpret it as a + * file header. A checksum error on the file header is fatal and usually + * indicates that the tape is not positioned to the beginning of a file. + * If we have a legal header, decode the character valued fields into binary. + */ +static int +getheader ( + int in, /* input file */ + register struct fheader *fh /* decoded file header (output) */ +) +{ + register char *ip, *op; + register int n; + union hblock *hb; + int tape_checksum, ntrys; + + for (ntrys=0; ; ntrys++) { + if ((hb = (union hblock *)getblock (in)) == NULL) + return (EOF); + + /* Decode the checksum value saved in the file header and then + * overwrite the field with blanks, as the field was blank when + * the checksum was originally computed. Compute the actual + * checksum as the sum of all bytes in the header block. If the + * sum is zero this indicates the end of the tar file, otherwise + * the checksums must match. + */ + if (*hb->dbuf.chksum == '\0' && cchksum ((char *)hb, TBLOCK) == 0) + return (EOF); + else + sscanf (hb->dbuf.chksum, "%o", &tape_checksum); + + for (ip=hb->dbuf.chksum, n=8; --n >= 0; ) + *ip++ = ' '; + if (cchksum ((char *)hb, TBLOCK) != tape_checksum) { + /* If a checksum error occurs try to advance to the next + * header block. + */ + if (ntrys == 0) { + fprintf (stderr, + "rtar: file header checksum error %o != %o\n", + cchksum ((char *)hb, TBLOCK), tape_checksum); + } else if (ntrys >= MAXTRYS) { + fprintf (stderr, "cannot recover from checksum error\n"); + exit (OSOK+1); + } + } else + break; + } + + if (ntrys > 1) + fprintf (stderr, "found next file following checksum error\n"); + + /* Decode the ascii header fields into the output file header + * structure. + */ + for (ip=hb->dbuf.name, op=fh->name; (*op++ = *ip++); ) + ; + fh->isdir = (*(op-2) == '/'); + + sscanf (hb->dbuf.mode, "%o", &fh->mode); + sscanf (hb->dbuf.uid, "%o", &fh->uid); + sscanf (hb->dbuf.gid, "%o", &fh->gid); + sscanf (hb->dbuf.size, "%lo", &fh->size); + sscanf (hb->dbuf.mtime, "%lo", &fh->mtime); + + n = hb->dbuf.linkflag; + if (n >= '0' && n <= '9') + fh->linkflag = n - '0'; + else + fh->linkflag = 0; + + if (fh->linkflag) + strcpy (fh->linkname, hb->dbuf.linkname); + + return (TBLOCK); +} + + +/* CCHKSUM -- Compute the checksum of a byte array. + */ +static int +cchksum ( + register char *p, + register int nbytes +) +{ + register int sum; + + for (sum=0; --nbytes >= 0; ) + sum += *p++; + + return (sum); +} + + +struct _modebits { + int code; + char ch; +} modebits[] = { + { 040000, 'd' }, + { 0400, 'r' }, + { 0200, 'w' }, + { 0100, 'x' }, + { 040, 'r' }, + { 020, 'w' }, + { 010, 'x' }, + { 04, 'r' }, + { 02, 'w' }, + { 01, 'x' }, + { 0, 0 } +}; + + +/* PRINTHEADER -- Print the file header in either short or long (verbose) + * format, e.g.: + * drwxr-xr-x 9 tody 1024 Nov 3 17:53 . + */ +static void +printheader ( + FILE *out, /* output file */ + register struct fheader *fh, /* file header struct */ + int verbose /* long format output */ +) +{ + register struct _modebits *mp; + char *tp, *ctime(); + + if (!verbose) { + fprintf (out, "%s\n", fh->name); + return; + } + + for (mp=modebits; mp->code; mp++) + fprintf (out, "%c", mp->code & fh->mode ? mp->ch : '-'); + + tp = ctime (&fh->mtime); + fprintf (out, "%3d %4d %2d %8ld %-12.12s %-4.4s %s", + fh->linkflag, + fh->uid, + fh->gid, + fh->size, + tp + 4, tp + 20, + fh->name); + + if (fh->linkflag && *fh->linkname) + fprintf (out, " -> %s\n", fh->linkname); + else + fprintf (out, "\n"); +} + + +/* FILETYPE -- Determine the file type (text, binary, or directory) of the + * next file on the input stream. Directory files are easy; the tar format + * identifies directories unambiguously. Discriminating between text and + * binary files is not possible in general because UNIX does not make such + * a distinction, but in practice we can apply a heuristic which will work + * in nearly all cases. This can be overriden, producing only binary byte + * stream files as output, by a command line switch. + */ +static int +filetype ( + int in, /* input file */ + struct fheader *fh /* decoded file header */ +) +{ + register char *cp; + register int n, ch; + int newline_seen, nchars; + + /* Easy cases first. + */ + if (fh->isdir) + return (DIRECTORY_FILE); + else if (fh->size == 0 || binaryout) + return (BINARY_FILE); + + /* Get a pointer to the first block of the input file and set the + * input pointers back so that the block is returned by the next + * call to getblock. + */ + if ((cp = getblock (in)) == NULL) + return (BINARY_FILE); + nextblock -= TBLOCK; + nblocks++; + + /* Examine the data to see if it is text. The simple heuristic + * used requires that all characters be either printable ascii + * or common control codes. + */ + n = nchars = (fh->size < TBLOCK) ? fh->size : TBLOCK; + for (newline_seen=0; --n >= 0; ) { + ch = *cp++; + if (ch == '\n') + newline_seen++; + else if (!isprint(ch) && !isspace(ch) && !ctrlcode(ch)) + break; + } + + if (n >= 0 || (nchars > MAXLINELEN && !newline_seen)) + return (BINARY_FILE); + else + return (TEXT_FILE); +} + + +/* NEWFILE -- Try to open a new file for writing, creating the new file + * with the mode bits given. Create all directories leading to the file if + * necessary (and possible). + */ +static int +newfile ( + char *fname, /* pathname of file */ + int mode, /* file mode bits */ + int uid, int gid, /* file owner, group codes */ + int type /* text, binary, directory */ +) +{ + int fd; + char *cp; + char *rindex(); + + if (len_pathprefix && strncmp(fname,pathprefix,len_pathprefix) == 0) + fname += len_pathprefix; + + if (debug) + fprintf (stderr, "newfile `%s':\n", fname); + + if (checkdir (fname, mode, uid, gid) == ERR) + return (ERR); + + if (type == DIRECTORY_FILE) { + cp = rindex (fname, '/'); + if (cp && *(cp+1) == EOS) + *cp = EOS; + fd = os_createdir (fname, mode); + + /* Ignore any error creating directory, as this may just mean + * that the directory already exists. If the directory does + * not exist and cannot be created, there will be plenty of + * other errors when we try to write files into it. + */ + fd = OK; + + } else { + if (replace) + os_delete (fname); + fd = os_createfile (fname, mode, type); + } + + return (fd); +} + + +/* CHECKDIR -- Verify that all the directories in the pathname of a file + * exist. If they do not exist, try to create them. + */ +static int +checkdir ( + register char *path, + int mode, + int uid, int gid +) +{ + register char *cp; + char *rindex(); + + /* Quick check to see if the directory exists. + */ + if ((cp = rindex (path, '/')) == NULL) + return (OK); + + *cp = EOS; + if (os_access (path, 0, DIRECTORY_FILE) == YES) { + *cp = '/'; + return (OK); + } + *cp = '/'; + + /* The directory cannot be accessed. Try to make all directories + * in the pathname. If the file is itself a directory leave its + * creation until later. + */ + for (cp=path; *cp; cp++) { + if (*cp != '/') + continue; + if (*(cp+1) == EOS) + return (OK); + + *cp = EOS; + if (os_access (path, 0, DIRECTORY_FILE) == NO) { + if (os_createdir (path, RWXR_XR_X) == ERR) { + fprintf (stderr, "cannot create directory `%s'\n", path); + *cp = '/'; + return (ERR); + } else + os_setowner (path, uid, gid); + } + *cp = '/'; + } + + return (OK); +} + + +/* COPYFILE -- Copy bytes from the input (tar) file to the output file. + * Each file consists of a integral number of TBLOCK size blocks on the + * input file. + */ +static void +copyfile ( + int in, /* input file */ + int out, /* output file */ + struct fheader *fh, /* file header structure */ + int ftype /* text or binary file */ +) +{ + long nbytes = fh->size; + int nblocks = 0, maxpad; + char *bp; + + + /* Link files are zero length on the tape. */ + if (fh->linkflag) + return; + + if (ftype == BINARY_FILE || !stripblanks) + maxpad = 0; + else + maxpad = SZ_PADBUF; + + /* Copy all but the last MAXPAD characters if the file is a text file + * and stripping is enabled. + */ + while (nbytes > maxpad && (bp = getblock (in)) != NULL) + if (os_write (out, bp, nbytesname); + if (nerrs++ > MAXERR) { + fprintf (stderr, "Too many errors\n"); + exit (OSOK+1); + } + } else { + nbytes -= TBLOCK; + nblocks++; + } + + /* Strip whitespace at end of file added by WTAR when the archive was + * created. + */ + if (nbytes > 0) + strip_blanks (in, out, nbytes); + + if (debug) + fprintf (stderr, "%d blocks written\n", nblocks); +} + + +/* STRIP_BLANKS -- Read the remaining file data into the pad buffer. + * Write out the remaining data, minus any extra blanks or empty blank lines + * at the end of the file. Some versions of WTAR (e.g., VMS) do not know + * the actual size of a text file and have to pad with blanks at the end to + * make the file the size noted in the file header. + */ +static void +strip_blanks (int in, int out, long nbytes) +{ + register char *ip, *op; + char padbuf[SZ_PADBUF+10]; + char *lastnl; + int n; + + /* Fill buffer. + */ + op = padbuf; + while (nbytes > 0 && (ip = getblock (in)) != NULL) { + n = nbytes < TBLOCK ? (int)nbytes : TBLOCK; + os_amovb (ip, op, n + sizeof(XCHAR)-1); + nbytes -= n; + op += n; + } + + /* Backspace from the end of the buffer until the last nonblank line + * is found. + */ + lastnl = op - 1; + for (ip=lastnl; ip > padbuf; --ip) + if (*ip == '\n') + lastnl = ip; + else if (*ip != ' ') + break; + + /* Write out everything up to and including the newline at the end of + * the last line containing anything but blanks. + */ + os_write (out, padbuf, lastnl - padbuf + 1); +} + + +/* SKIPFILE -- Skip the indicated number of bytes on the input (tar) file. + */ +static void +skipfile ( + int in, /* input file */ + struct fheader *fh /* file header */ +) +{ + register long nbytes = fh->size; + + /* Link files are zero length on the tape. */ + if (fh->linkflag) + return; + + while (nbytes > 0 && getblock (in) != NULL) + nbytes -= TBLOCK; +} + + +/* GETBLOCK -- Return a pointer to the next file block of size TBLOCK bytes + * in the input file. + */ +static char * +getblock (int in) +{ + char *bp; + int nbytes; + + for (;;) { + if (eof) + return (NULL); + else if (--nblocks >= 0) { + bp = nextblock; + nextblock += TBLOCK; + return (bp); + } + + if ((nbytes = tape_read (in, tapeblock, SZ_TAPEBUFFER)) < TBLOCK) + eof++; + else { + nblocks = (nbytes + TBLOCK-1) / TBLOCK; + nextblock = tapeblock; + } + } +} diff --git a/unix/boot/rtar/rtar.hlp b/unix/boot/rtar/rtar.hlp new file mode 100644 index 00000000..843add6f --- /dev/null +++ b/unix/boot/rtar/rtar.hlp @@ -0,0 +1,165 @@ +.help rtar Oct92 softools +.IH +NAME +rtar -- read TAR format archive file +.IH +USAGE +rtar [ flags ] [ archive ] [ after ] [ files ] +.IH +PARAMETERS +.ls 4 -a +Advance to the archive file named by the \fIafter\fR argument before +performing the main operation. The extract or list operation will begin with +the file \fIafter\fR and continue to the end of the archive. +.le +.ls 4 -b +Output only binary byte stream files. By default, \fIrtar\fR outputs text +files in the host system textfile format. The conversion from the byte stream +\fItar\fR format to host textfile format may involve modification of the +file, e.g., conversion from ASCII to EBCDIC. A binary extraction copies +the file to disk without modification. +.le +.ls 4 -d +Print detailed information about what \fIrtar\fR is doing. +.le +.ls 4 -e +Extract the entire contents of the tape \fIexcluding\fR the files or directories +listed in \fIfiles\fR. +.le +.ls 4 -f filename +\fIRtar\fR uses the first filename argument as the host filename of the +archive instead of reading from \fIstdin\fR. Magtape devices should be +specified using the host device name, e.g., "/dev/nrmt8" or "MSA0". +Since \fIrtar\fR is a host level program and does not read the IRAF tapecap +file, IRAF device names such as "mta" cannot be used. +.le +.ls 4 -l +Do not try to resolve file links by a disk to disk file copy. By default, +if file A appears in the archive as a link to file B, +\fIrtar\fR trys to resolve the link by performing a disk to disk copy of +file B to A. This is valid providing file B was present in the archive and +has already been extracted. If the \fBl\fR flag is present linked files +will not be extracted. +.le +.ls 4 -m +Do not restore the file modify time. +.le +.ls 4 -n +Do not strip trailing blank lines from text files read from the tape. +The default is to strip any blank lines at the ends of files. +This is necessary when the file was written by \fIwtar\fR on a system +like VMS, where the size of the file is not known before it has been +read. The \fIwtar\fR utility must guess at the final size and pad the +file at the end with spaces to ensure that the size of the file actually +written agrees with the file header. +.le +.ls 4 -o +Omit binary files when performing the extraction. A binary file is any +file containing ASCII values other than 040 through 0176 (the printable +ASCII characters), tab, or newline in the first 512 byte block of the file. +.le +.ls 4 -p pathprefix +When creating directories and files from the pathnames recorded in the archive, +omit the given path prefix if it matches the pathname given in the archive. +This feature is used to relocate directories, or to read tar archives +containing absolute pathnames. For example, given "-p /usr/", the archive +pathname "/usr/me/file" would be written to the file "me/file". +.le +.ls 4 -r +The extracted file replaces any existing file of the same name, i.e., +\fIrtar\fR performs a delete before creating the extracted file. +.le +.ls 4 -t +The names of the specified files are listed each time they occur on +the tape. If no \fIfiles\fR argument is given, all of the names on the tape +are listed. +.le +.ls 4 -u +Do not attempt to restore the owner and group identification of each file. +.le +.ls 4 -v +Print more information about the tape entries than just their names. +The verbose file list format gives the file permissions, the link flag +(zero if there were no links to the file), the owner and group identification +numbers of the file on the system that wrote the archive, the file size in +bytes, the date of last modification of the file, and the file name. +.le +.ls 4 -x +The named files are extracted from the tape. If the named file +matches a directory whose contents had been written onto the tape, this +directory is (recursively) extracted. The owner, modification time, and mode +are restored (if possible). If no file argument is given, the entire content +of the tape is extracted. Note that if multiple entries specifying the same +file are on the tape, the last one overwrites all earlier. +.le +.IH +DESCRIPTION +\fIRtar\fR reads multiple files from a UNIX \fItar\fR format file, +restoring the files to disk on the local host machine. +Output filenames are mapped according to the IRAF filenaming conventions +of the local host operating system. + +\fIRtar\fR's actions are controlled by the \fIflags\fR argument. +\fIFlags\fR consists of a minus sign followed by a string of characters +containing any combination of the function flags described below. +Other arguments to \fIrtar\fR are the name of the archive file to be read, +the name of the file on the archive at which reading is to begin, +and the names of the files or directories to be read or to be excluded +from the read. In all cases, appearance of a directory name refers to +the files and (recursively) subdirectories of that directory. + +All \fIrtar\fR filename arguments are IRAF virtual filenames (or host +filenames), except the prefix strings, which pertain to the tape format and +hence are UNIX pathnames. Magtape devices must be specified using a host +physical or logical device name (i.e., IRAF device names like "mta" will not +work). + +If the input archive file is a tape the blocksize must be a multiple +of 512 bytes, with a maximum blocksize of 10240 bytes. Each archived file +occupies an integral number of 512 byte blocks in the archive (this is +required by the \fItar\fR format). + +Filenames appearing in the file list are interpreted as prefix strings, +i.e., a match occurs if the given string is a prefix of an actual filename +in the archive. If the last character in the \fIfiles\fR filename is +a \fB$\fR then an exact match is required (excluding the $ meta-character). +.IH +DIAGNOSTICS +A file read error occurring while reading the archive file is fatal unless +caught and corrected by the host system. +File header checksum errors result in skipping of the archive file +currently being read, with execution continuing with the next archive +file if possible. +File write errors on the output file are reported but do not cause +termination of \fIrtar\fR. The output file being written will be corrupted. +.ih +EXAMPLES +Since \fIrtar\fR is a bootstrap utility implemented as a foreign task in +the CL, it may be called either from within the CL (as in the examples), +or at the host system level. The command syntax is identical on both cases. + +1. List the contents of the disk archive file "foo.tar". + + cl> rtar -tvf foo.tar + +2. Unpack the tape archive on unix device /dev/nrmt8 in the current +directory. + + cl> rtar -xf /dev/nrmt8 + +3. Unpack the tape archive on the VMS device MSA0: in the current +directory. + + cl> rtar -xf msa0 + +When working within the CL, commands such as \fIrewind\fR may be used +with \fIrtar\fR, but switching between IRAF and host device names may be +confusing. +.IH +BUGS +The current limit on file name length is 100 characters (this restriction +is imposed by the standard UNIX \fItar\fR format). +File links are not recreated. +.ih +SEE ALSO +wtar, rmbin diff --git a/unix/boot/rtar/rtar.ms b/unix/boot/rtar/rtar.ms new file mode 100644 index 00000000..43746400 --- /dev/null +++ b/unix/boot/rtar/rtar.ms @@ -0,0 +1,125 @@ +.TH RTAR 1 "14 November 1984" +.SH NAME +rtar \- read tape archive format file +.SH SYNOPSIS +.B rtar +[ flags ] [ archive ] [ after ] [ files ] +.SH DESCRIPTION +.PP +.I Rtar +reads multiple files from a UNIX \fItar\fR format file, restoring the files +to disk on the local host machine. Output filenames are mapped according to +the IRAF filenaming conventions of the local host operating system. +.IR Rtar 's +actions are controlled by the +.I flags +argument. +.I Flags +consists of an \fB-\fR followed by +a string of characters containing any combination of the function flags +described below. +Other arguments to +.I rtar +are the name of the archive file to be read, +the name of the file on the archive at which reading is to begin, +and the names of the files or directories to be read or to be excluded +from the read. +In all cases, appearance of a directory name refers to +the files and (recursively) subdirectories of that directory. +All +.I rtar +filename arguments are UNIX pathnames except +.I archive, +which is a host system filename. +.PP +The default action of \fIrtar\fR is to unpack all files from the \fItar\fR +format standard input. The following flag characters may be used to further +control the function of \fIrtar\fR: +.TP 8 +.B x +The named files are extracted from the tape. If the named file +matches a directory whose contents had been written onto the tape, this +directory is (recursively) extracted. The owner, modification time, and mode +are restored (if possible). If no file argument is given, the entire content +of the tape is extracted. Note that if multiple entries specifying the same +file are on the tape, the last one overwrites all earlier. +.TP 8 +.B r +The extracted file replaces any existing file of the same name, i.e., +.I rtar +performs a delete before creating the extracted file. +.TP 8 +.B e +Extract the entire contents of the tape \fIexcluding\fR the files or directories +listed in \fIfiles\fR. +.TP 8 +.B a +Advance to the archive file named by the \fIafter\fR argument before +performing the main operation. The extract or list operation will begin with +the file \fIafter\fR and continue to the end of the archive. +.TP 8 +.B t +The names of the specified files are listed each time they occur on +the tape. If no \fIfiles\fR argument is given, all of the names on the tape +are listed. +.TP 8 +.B v +Print more information about the tape entries than just their names. +The verbose file list format gives the file permissions, the link flag +(zero if there were no links to the file), the owner and group identification +numbers of the file on the system that wrote the archive, the file size in +bytes, the date of last modification of the file, and the file name. +.TP 8 +.B d +Print detailed information about what \fIrtar\fR is doing. +.TP 8 +.B f +.I Rtar +uses the first filename argument as the host filename of the archive +instead of reading from \fIstdin\fR. +.TP 8 +.B l +Do not try to resolve file links by a disk to disk file copy. By default, +if file A appears in the archive as a link to file B, +\fIrtar\fR trys to resolve the link by performing a disk to disk copy of +file B to A. This is valid providing file B was present in the archive and +has already been extracted. If the \fBl\fR flag is present linked files +will not be extracted. +.TP 8 +.B o +Omit binary files when performing the extraction. A binary file is any +file containing ASCII values other than 040 through 0176 (the printable +ASCII characters), tab, or newline in the first 512 byte block of the file. +.TP 8 +.B b +Output only binary byte stream files. By default, \fIrtar\fR outputs text +files in the host system textfile format. The conversion from the byte stream +\fItar\fR format to host textfile format may involve modification of the +file, e.g., conversion from ASCII to EBCDIC. A binary extraction copies +the file to disk without modification. +.PP +If the input archive file is a tape the blocksize must be a multiple +of 512 bytes, with a maximum blocksize of 10240 bytes. Each archived file +occupies an integral number of 512 byte blocks in the archive. +.PP +Filenames appearing in the file list are interpreted as prefix strings, +i.e., a match occurs if the given string is a prefix of an actual filename +in the archive. If the last character in the \fIfiles\fR filename is +a \fB$\fR then an exact match is required (excluding the $ metacharacter). +.SH DIAGNOSTICS +.br +A file read error occurring while reading the archive file is fatal unless +caught and corrected by the host system. +.br +File header checksum errors result in skipping of the archive file +currently being read, with execution continuing with the next archive +file if possible. +.br +File write errors on the output file are reported but do not cause +termination of \fIrtar\fR. The output file being written will be corrupted. +.SH BUGS +.br +The current limit on file name length is 100 characters (this restriction +is imposed by the standard UNIX \fItar\fR format). +.br +File links are not recreated. -- cgit