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/os/zfiopl.c | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'unix/os/zfiopl.c')
-rw-r--r-- | unix/os/zfiopl.c | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/unix/os/zfiopl.c b/unix/os/zfiopl.c new file mode 100644 index 00000000..26468834 --- /dev/null +++ b/unix/os/zfiopl.c @@ -0,0 +1,279 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <ctype.h> + +#define import_kernel +#define import_knames +#define import_zfstat +#define import_prtype +#define import_spp +#include <iraf.h> + +/* + * ZFIOPL -- IRAF FIO interface to plotter devices. A plotter + * is opened as a streaming type (no seeks) write-only binary device. + * FIO writes NCAR metacode to the plotter. This metacode is spooled + * in a temporary file and then disposed of to the plotter by calling + * an OS metacode translator to process the file. The spoolfile is then + * deleted. + * + * The system and device dependent information necessary to perform these + * functions is contained in three strings passed as the "device" parameter + * to ZOPNPL. The strings come from the GRAPHCAP entry for the device. + * The format of such a string is + * + * device D spoolfile D dispose_cmd EOS + * + * where DEVICE is the logical device name (not used herein), D is the field + * delimiter character (the first nonalphnumeric character encountered after + * the device field), SPOOLFILE is a UNIX pathname to be passed to MKTEMP + * to create the spoolfile pathname, and DISPOSE_CMD is a fill-in-the-blanks + * template for a UNIX shell command which will dispose of the spoolfile to + * the plotter device. + */ + +extern int save_prtype; + +#define SZ_OSCMD 512 /* buffer for dispose cmd */ +#define SZ_PLSTR 256 /* zopnpl plotter argument */ + +struct dplotter { + char *name; /* logical gdevice name */ + char *spoolfile; /* spoolfile string */ + char *dispose; /* dispose format string */ +}; + +struct oplotter { + long wbytes; /* nbytes written to device */ + struct dplotter *pl; /* device code as above */ + int status; /* status of last write */ + char spoolfile[SZ_PATHNAME+1]; +}; + +struct dplotter dpltr; /* machdep plotter info */ +struct oplotter pltr; /* open plotter descriptor */ +char plstr[SZ_PLSTR+1]; /* save zopnpl argument */ +int pltr_inuse = NO; /* set if plotter is open */ + + +extern int ZOPNBF (), ZCLSBF (), ZOSCMD (), ZFDELE (), ZARDBF (); +extern int ZAWRBF (), ZAWTBF (), ZSTTBF (); + + + +/* ZOPNPL -- Open a plotter device for binary file i/o. If we can talk + * directly to the plotter, do so, otherwise open a spoolfile which is + * to be sent to the plotter when ZCLSPL is later called. + */ +int +ZOPNPL ( + PKCHAR *plotter, /* plotter device descriptor */ + XINT *mode, /* file access mode */ + XINT *chan /* UNIX file number (output) */ +) +{ + register char *ip; + static char delim; + int fd; + + /* We do not see a need to have more than one plotter open at + * a time, and it makes things simpler. We can easily generalize + * to multiple open plotter devices in the future if justified. + */ + if (pltr_inuse == YES) { + *chan = XERR; + return (XERR); + } else + pltr_inuse = YES; + + /* Parse the plotter string into the name, spoolfile, and dispose + * strings. + */ + strncpy (plstr, (char *)plotter, SZ_PLSTR); + + /* Locate NAME field. */ + dpltr.name = plstr; + for (ip=plstr; isalnum(*ip); ip++) + ; + delim = *ip; + *ip++ = EOS; + + /* Locate SPOOLFILE field. */ + for (dpltr.spoolfile=ip; *ip && *ip != delim; ip++) + ; + *ip++ = EOS; + + /* Locate DISPOSE field. */ + for (dpltr.dispose=ip; *ip && *ip != delim; ip++) + ; + *ip++ = EOS; + + /* Initialize the open plotter descriptor. + */ + pltr.wbytes = 0L; + pltr.pl = &dpltr; + strcpy (pltr.spoolfile, dpltr.spoolfile); + if (dpltr.dispose[0] != EOS) + if ((fd = mkstemp (pltr.spoolfile)) >= 0) { + fchmod (fd, 0644); + close (fd); + } + + return ZOPNBF ((PKCHAR *)pltr.spoolfile, mode, chan); +} + + +/* ZCLSPL -- To close a plotter we merely close the "spoolfile", and then + * dispose of the spoolfile to the OS if so indicated. + */ +int +ZCLSPL (XINT *chan, XINT *status) +{ + static PKCHAR xnullstr[1] = { EOS }; + register char *ip, *op, *f; + PKCHAR cmd[(SZ_OSCMD+1) / sizeof(PKCHAR)]; + XINT junk; + + ZCLSBF (chan, status); + pltr_inuse = NO; + + /* Dispose of the output file if so indicated. Do not bother to + * check the status return, since we cannot return status to FIO + * from here anyhow. Do not dispose of the file if it is empty. + * If the file is disposed of by the OS, we assume that it is also + * deleted after printing. If file is not disposed to the OS, we + * delete it ourselves. + */ + if (*(pltr.pl->dispose) != EOS) { + if (pltr.wbytes > 0) { + PKCHAR out[SZ_FNAME+1]; + + /* Build up command line by substituting the spoolfile name + * everywhere the macro "$F" appears in the "dispose" text. + */ + op = (char *)cmd; + for (ip=pltr.pl->dispose; (*op = *ip++) != EOS; op++) + if (*op == '$' && *ip == 'F') { + for (f=pltr.spoolfile; (*op = *f++) != EOS; op++) + ; + /* Overwrite EOS, skip over 'F' */ + --op, ip++; + } + strcpy ((char *)out, + save_prtype == PR_CONNECTED ? "/dev/tty" : ""); + ZOSCMD (cmd, xnullstr, out, out, &junk); + } else + ZFDELE ((PKCHAR *)pltr.spoolfile, &junk); + } + + return (*status); +} + + +/* ZARDPL -- For UNIX, the read and write routines are just the binary file + * i/o routines. Note that packing of chars into bytes, mapping of escape + * sequences, etc. is done by the high level code; our function is merely to + * move the data to the device. The read primitive is not likely to be needed + * for a plotter, but you never know... + */ +int +ZARDPL ( + XINT *chan, + XCHAR *buf, + XINT *maxbytes, + XLONG *offset +) +{ + return ZARDBF (chan, buf, maxbytes, offset); +} + + +/* ZAWRPL -- Write a metafile record to the plotter spoolfile. We are always + * called to write metacode; zfiopl is not used to send device codes to the + * plotter. Our job is to make the NSPP metacode record passed on to us by + * WRITEB look like whatever the system metacode translators expect. On the + * KPNO system, the metacode translators are Fortran programs, expecting an + * unformatted binary metacode file as input. We simulate this file by + * adding the integer byte count of the record to the beginning and end of + * each record. + * + * N.B.: We ASSUME that the FIO buffer has been set to the size of a metafile + * record, i.e., 1440 bytes or 720 chars on the VAX. + */ +int +ZAWRPL ( + XINT *chan, + XCHAR *buf, + XINT *nbytes, + XLONG *offset /* not used */ +) +{ + static XINT hdrlen=sizeof(int); + static XLONG noffset=0L; + XINT status; + int reclen; + + /* Write out the integer record header. Set the file offset to zero + * since the file is sequential, and the offsets do not include the + * record headers anyhow so are wrong. + */ + reclen = *nbytes; + ZAWRBF (chan, (XCHAR *)&reclen, &hdrlen, &noffset); + ZAWTBF (chan, &status); + + /* Write the metacode data. + */ + pltr.wbytes += *nbytes; + ZAWRBF (chan, buf, nbytes, &noffset); + ZAWTBF (chan, &pltr.status); + + /* Write out the integer record trailer. Set the file offset to zero + * since the file is sequential, and the offsets do not include the + * record headers anyhow so are wrong. + */ + reclen = *nbytes; + ZAWRBF (chan, (XCHAR *)&reclen, &hdrlen, &noffset); + ZAWTBF (chan, &status); + + return (status); +} + + +/* ZAWTPL -- Return the status of the write (we do not read metafiles with + * the plotter interface). The status byte count does not include the + * record header, since that was written with a separate write unbeknownst + * to FIO, so the status value returned refers only to the metacode data. + */ +int +ZAWTPL (XINT *chan, XINT *status) +{ + ZAWTBF (chan, status); + if (*status > 0) + *status = pltr.status; + + return (*status); +} + + +/* ZSTTPL -- Get status for the plotter output file. Plotter output is + * strictly sequential due to the way metacode records are packaged in + * ZAWRPL. Hence we must always return blksize=0 to indicate that the + * device is a streaming file, regardless of whether or not the output + * is spooled. + */ +int +ZSTTPL (XINT *chan, XINT *param, XLONG *lvalue) +{ + switch (*param) { + case FSTT_BLKSIZE: + *lvalue = 0L; + break; + default: + return ZSTTBF (chan, param, lvalue); + } + return (XOK); +} |