aboutsummaryrefslogtreecommitdiff
path: root/unix/os/zfiopl.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /unix/os/zfiopl.c
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'unix/os/zfiopl.c')
-rw-r--r--unix/os/zfiopl.c279
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);
+}