From fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 8 Jul 2015 20:46:52 -0400 Subject: Initial commit --- unix/os/zfiolp.c | 239 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 unix/os/zfiolp.c (limited to 'unix/os/zfiolp.c') 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 +#include +#include +#include + +#define import_kernel +#define import_knames +#define import_zfstat +#define import_prtype +#define import_spp +#include + +/* + * 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); +} -- cgit