aboutsummaryrefslogtreecommitdiff
path: root/unix/os/zfiolp.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/os/zfiolp.c')
-rw-r--r--unix/os/zfiolp.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/unix/os/zfiolp.c b/unix/os/zfiolp.c
new file mode 100644
index 00000000..e07571a2
--- /dev/null
+++ b/unix/os/zfiolp.c
@@ -0,0 +1,239 @@
+/* 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>
+
+/*
+ * ZFIOLP -- IRAF FIO interface to the line printer device. The line printer
+ * is opened as a streaming type (no seeks) write-only binary device.
+ * On systems like UNIX in which the line printer is just another file,
+ * the interface is trivial; we just call the FIOBF routines. On other
+ * systems it might be necessary to spool the output to a binary file
+ * and dispose of the file to a queue when the printer file is closed,
+ * or some such thing.
+ *
+ * Currently, the CL-callable LPRINT program is the only thing in IRAF which
+ * writes to the printer. Most programs are intended to write to their
+ * standard output or a file, which is subsequently copied to the printer
+ * by the user or by a CL level script. LPRINT uses "dev$*.tty" descriptors
+ * and the TTY interface to learn the characteristics of the printer (eject
+ * is considered equivalent to a tty clear, for example).
+ *
+ * The system and device dependent information necessary to perform these
+ * functions is contained in three strings passed as the "printer" parameter
+ * to ZOPNLP. The strings come from the TERMCAP 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 printer device.
+ */
+
+extern int save_prtype;
+
+#define SZ_OSCMD 512 /* buffer for dispose cmd */
+#define SZ_LPSTR 256 /* zopnlp plotter argument */
+
+struct lprinter {
+ char *name; /* logical gdevice name */
+ char *spoolfile; /* spoolfile string */
+ char *dispose; /* dispose format string */
+};
+
+struct oprinter {
+ struct lprinter *lp; /* device code as above */
+ long wbytes; /* nbytes written to device */
+ char spoolfile[SZ_PATHNAME+1];
+};
+
+struct lprinter dpr; /* device table */
+struct oprinter lpr; /* printer descriptor */
+int lpr_inuse = NO; /* set if printer is open */
+char lpstr[SZ_LPSTR+1]; /* save zopnlp argument */
+
+
+extern int ZOPNBF (), ZCLSBF (), ZOSCMD (), ZFDELE (), ZARDBF ();
+extern int ZAWRBF (), ZAWTBF (), ZSTTBF ();
+
+
+/* ZOPNLP -- Open a printer device for binary file i/o. If we can talk
+ * directly to the printer, do so, otherwise open a spoolfile which is
+ * to be sent to the printer when ZCLSLP is later called.
+ */
+int
+ZOPNLP (
+ PKCHAR *printer, /* logical name of printer device */
+ 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 printer open at
+ * a time, and it makes things simpler. We can easily generalize
+ * to multiple open printer devices in the future if justified.
+ */
+ if (lpr_inuse == YES) {
+ *chan = XERR;
+ return (XERR);
+ } else
+ lpr_inuse = YES;
+
+ /* Parse the printer string into the name, spoolfile, and dispose
+ * strings.
+ */
+ strncpy (lpstr, (char *)printer, SZ_LPSTR);
+ lpstr[SZ_LPSTR] = EOS;
+
+ /* Locate NAME field. */
+ dpr.name = lpstr;
+ for (ip=lpstr; isalnum(*ip); ip++)
+ ;
+ delim = *ip;
+ *ip++ = EOS;
+
+ /* Locate SPOOLFILE field. */
+ for (dpr.spoolfile=ip; *ip && *ip != delim; ip++)
+ ;
+ *ip++ = EOS;
+
+ /* Locate DISPOSE field. */
+ for (dpr.dispose=ip; *ip && *ip != delim; ip++)
+ ;
+ *ip++ = EOS;
+
+ /* Initialize the open printer descriptor.
+ */
+ lpr.wbytes = 0L;
+ lpr.lp = &dpr;
+ strcpy (lpr.spoolfile, dpr.spoolfile);
+ if (dpr.dispose[0] != EOS)
+ if ((fd = mkstemp (lpr.spoolfile)) >= 0) {
+ fchmod (fd, 0644);
+ close (fd);
+ }
+
+ return ZOPNBF ((PKCHAR *)lpr.spoolfile, mode, chan);
+}
+
+
+/* ZCLSLP -- To close a printer we merely close the "spoolfile", and then
+ * dispose of the spoolfile to the OS if so indicated.
+ */
+int
+ZCLSLP (XINT *chan, XINT *status)
+{
+ static PKCHAR xnullstr[1] = { XEOS };
+ register char *ip, *op, *f;
+ PKCHAR cmd[(SZ_LINE+1) / sizeof(PKCHAR)];
+ XINT junk;
+
+ ZCLSBF (chan, status);
+ lpr_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 (*(lpr.lp->dispose) != EOS) {
+ if (lpr.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=lpr.lp->dispose; (*op = *ip++) != EOS; op++)
+ if (*op == '$' && *ip == 'F') {
+ for (f=lpr.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 *)lpr.spoolfile, &junk);
+ }
+
+ return (*status);
+}
+
+
+/* ZARDLP -- Initiate a read from the line printer device. 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 printer, but you never know...
+ */
+int
+ZARDLP (XINT *chan, XCHAR *buf, XINT *maxbytes, XLONG *offset)
+{
+ XLONG dummy_offset = 0;
+
+ return ZARDBF (chan, buf, maxbytes, &dummy_offset);
+}
+
+
+/* ZAWRLP -- Initiate a write to the line printer. Keep track of the number
+ * of bytes written so we know whether or not to dispose of the spoolfile
+ * at close time.
+ */
+int
+ZAWRLP (XINT *chan, XCHAR *buf, XINT *nbytes, XLONG *offset)
+{
+ XLONG dummy_offset = 0;
+
+ lpr.wbytes += *nbytes;
+ return ZAWRBF (chan, buf, nbytes, &dummy_offset);
+}
+
+
+/* ZAWTLP -- Wait for i/o and return the status of the channel, i.e., the
+ * number of bytes read or written or XERR.
+ */
+int
+ZAWTLP (XINT *chan, XINT *status)
+{
+ return ZAWTBF (chan, status);
+}
+
+
+/* ZSTTLP -- Get status for the line printer output file. We call ZSTTBF since
+ * the output file was opened by ZOPNBF. The actual output file may be either
+ * a blocked or streaming file depending on whether the output is spooled.
+ */
+int
+ZSTTLP (XINT *chan, XINT *param, XLONG *lvalue)
+{
+ switch (*param) {
+ case FSTT_BLKSIZE:
+ *lvalue = 0L; /* streaming device */
+ break;
+ default:
+ return ZSTTBF (chan, param, lvalue);
+ }
+ return (*lvalue);
+}