diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /unix/boot/bootlib/tape.c | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'unix/boot/bootlib/tape.c')
-rw-r--r-- | unix/boot/bootlib/tape.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/unix/boot/bootlib/tape.c b/unix/boot/bootlib/tape.c new file mode 100644 index 00000000..6d949f72 --- /dev/null +++ b/unix/boot/bootlib/tape.c @@ -0,0 +1,271 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + */ + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <ctype.h> + +#define NOKNET +#define import_spp +#define import_finfo +#define import_knames +#include <iraf.h> + +/* + * TAPE.C -- Generalized binary file i/o to a tape drive or other devices. + * + * fd = tape_open (fname, mode) + * tape_close (fd) + * nb = tape_read (fd, buf, maxbytes) + * nb = tape_write (fd, buf, nbytes) + * + * Only one "tape" file can be open at a time (unless all open files are of + * the same type). Since we call ZZRDMT and ZZWRMT directly, only blocked + * output is permitted (there is no internal buffering). Only sequential + * output is permitted to disk (there is no seek entry point). + * + * NOTE - For the IRAF V2.10 version of this utility, only host device names + * are permitted. The IRAF device names "mta", "mtb", etc are not supported + * as the tapefile file is not read. + */ + +#define TF_STDIN 0 +#define TF_STDOUT 1 +#define TF_BINARY 2 +#define TF_TAPE 3 + +#define R 0 +#define W 1 +#define RW 2 + +/* Tape position structure (V2.10). */ +struct mtpos { + int filno; /* current file (1=first) */ + int recno; /* current record (1=first) */ + int nfiles; /* number of files on tape */ + int tapeused; /* total tape used (Kb) */ + int pflags; /* i/o status bitflags (output) */ +}; + +/* MTPOS bitflags. */ +#define MF_ERR 0001 /* i/o error occurred in last operation */ +#define MF_EOF 0002 /* a tape mark was seen in the last operation */ +#define MF_EOT 0004 /* end of tape seen in the last operation */ +#define MF_EOR 0010 /* a record advance occurred in the last operation */ + +static int ftype; +static XINT acmode; +static int ateof; +static XLONG offset = 0; + +static int os_mtname (char *fname, char *osdev); + +extern int ZZOPMT(), ZOPNBF(), ZCLSBF(), ZZCLMT(); +extern int ZARDBF(), ZAWTBF(), ZZRDMT(), ZZWTMT(), ZAWRBF(), ZZWRMT(); + + + +/* TAPE_OPEN -- Open the named file, which need not actually be a tape device. + */ +int +tape_open ( + char *fname, /* file or device to be opened */ + int mode /* access mode */ +) +{ + PKCHAR osfn[SZ_PATHNAME+1]; + XINT chan; + extern char *vfn2osfn(); + + + if (strcmp (fname, "stdin") == 0) { + ftype = TF_STDIN; + if (mode != R) + chan = ERR; + else + chan = 1; /* arbitrary */ + + } else if (strcmp (fname, "stdout") == 0) { + ftype = TF_STDOUT; + if (mode != W) + chan = ERR; + else + chan = 1; /* arbitrary */ + + } else if (os_mtname (fname, (char *)osfn)) { + /* Open a magtape device. Only host device names are permitted. + * Try to open without moving the tape (newfile=0). + */ + register int *op; + struct mtpos devpos; + int nwords = sizeof(devpos) / sizeof(int); + XINT newfile = 0; + char *tapecap = ":np"; + + for (op = (int *)&devpos; --nwords >= 0; ) + *op++ = 0; + ftype = TF_TAPE; + if (mode == R) + acmode = READ_ONLY; + else + acmode = WRITE_ONLY; + + ZZOPMT (osfn, &acmode, (PKCHAR *)tapecap, (XINT *)&devpos, + &newfile, &chan); + + } else { + /* Open a binary disk file. + */ + ftype = TF_BINARY; + offset = 1; + + strcpy ((char *)osfn, vfn2osfn (fname, 0)); + if (mode == R) + acmode = READ_ONLY; + else if (mode == W) + acmode = NEW_FILE; + else + acmode = READ_WRITE; + + ZOPNBF (osfn, &acmode, &chan); + } + + ateof = 0; + + return (chan == XERR ? ERR : chan); +} + + +/* TAPE_CLOSE -- Close a file opened with tape_open. + */ +int +tape_close (int fd) +{ + struct mtpos devpos; + XINT x_fd=fd, status; + + if (ftype == TF_BINARY) + ZCLSBF (&x_fd, &status); + else if (ftype == TF_TAPE) + ZZCLMT (&x_fd, (XINT *)&devpos, &status); + else + status = XOK; + + return (status == XERR ? ERR : OK); +} + + +/* TAPE_READ -- Read from a file opened with tape_open. + */ +int +tape_read ( + int fd, /* input file */ + char *buf, /* output buffer */ + int maxbytes /* max bytes to read */ +) +{ + struct mtpos devpos; + XINT x_fd=fd, x_maxbytes=maxbytes, status; + + if (ateof) + return (0); + + if (ftype == TF_STDIN) { + status = read (0, buf, maxbytes); + } else if (ftype == TF_BINARY) { + ZARDBF (&x_fd, (XCHAR *)buf, &x_maxbytes, &offset); + ZAWTBF (&x_fd, &status); + if (status > 0) + offset += status; + } else if (ftype == TF_TAPE){ + ZZRDMT (&x_fd, (XCHAR *)buf, &x_maxbytes, &offset); + ZZWTMT (&x_fd, (XINT *)&devpos, &status); + if (devpos.pflags & MF_EOF) + ateof++; + } else + status = XERR; + + return (status == XERR ? ERR : status); +} + + +/* TAPE_WRITE -- Write to a file opened with tape_open. + */ +int +tape_write ( + int fd, /* output file */ + char *buf, /* input bufferr */ + int nbytes /* nbytes to write */ +) +{ + struct mtpos devpos; + XINT x_fd=fd, x_nbytes=nbytes, status; + + if (ftype == TF_STDOUT) { + status = write (1, buf, nbytes); + } else if (ftype == TF_BINARY) { + ZAWRBF (&x_fd, (XCHAR *)buf, &x_nbytes, &offset); + ZAWTBF (&x_fd, &status); + if (status > 0) + offset += status; + } else if (ftype == TF_TAPE) { + ZZWRMT (&x_fd, (XCHAR *)buf, &x_nbytes, &offset); + ZZWTMT (&x_fd, (XINT *)&devpos, &status); + } else + status = XERR; + + return (status == XERR ? ERR : status); +} + + +/* OS_MTNAME -- Parse a filename to determine if the file is a magtape + * device or something else. A nonzero return indicates that the device + * is a tape. + */ +static int +os_mtname ( + char *fname, /* filename e.g., "foo.tar" or "mua0:". */ + char *osdev /* receives host system drive name */ +) +{ +#ifdef VMS + register char *ip; + char drive[SZ_FNAME+1]; +#endif + + /* Ignore any "mt." prefix. This is for backwards compatibility, + * to permit old-style names like "mt.MUA0:". + */ + if (!strncmp (fname, "mt.", 3) || !strncmp (fname, "MT.", 3)) + fname += 3; + +#ifdef VMS + /* Resolve a possible logical device name. */ + if (strchr (fname, '[')) + strcpy (drive, fname); + else + _tranlog (fname, drive); + + /* If the resolved name ends with a colon it is a device name, + * which we assume to be a tape device. + */ + for (ip=drive; *ip; ip++) + ; + if (*(ip-1) == ':') { + strcpy (osdev, drive); + return (1); + } +#else + /* For unix systems we assume anything beginning with /dev is a + * tape device. + */ + if (strncmp (fname, "/dev/", 5) == 0) { + strcpy (osdev, fname); + return (1); + } +#endif + + strcpy (osdev, fname); + return (0); +} |