jeff@cjsa.WA.COM (Jeffery Small) (03/20/89)
# This is a shell archive. Remove anything before this line # then unpack it by saving it in a file and typing "sh file" # (Files unpacked will be owned by you and have default permissions). # This archive contains the following files: # ./README # ./Quantex.c # ./Daisy.c # ./list # ./Remote # if `test ! -s ./README` then echo "extracting ./README ..." sed 's/^X//' > ./README << 'END__of_the__FILE' XI got a number of requests to post the sample printer interface programs Xwhich I mentioned in a previous article - so here they are. X XThese programs are of no immediate use to anyone since they were written Xfor my two specific printers and contain a lot of local idiomatic stuff Xwhich would be "junk" to anyone else. However, I hope they may serve as Xsome kind of guide and starting point for others who are interested in Xtackling the task of writing their own interface. X XWhat you get: X XREADME - This file X XQuantex.c - Interface script for the Quantex Model 7065 Dot Matrix printer X attached to the parallel port. This is a real nice multi-mode X printer with lots of options. Get out your printer manual and X find out what codes you need to send to get your printer to X perform tricks. I can assure you that none of the Quantex codes X will be anything like what your printer wants. X XDaisy.c - Interface script for the Dataproducts DP-20 printer connected to X the serial port. This is a nasty little 20 cps Daisy Wheel X printer which has a lot of personality problems. I included this X script because: (1) It shows control over the serial port which X differs from the parallel port and (2) this printer emulates a X lot of the Diablo630 control codes which many people will find X more familiar - albeit a lot more confusing than the Quantex X codes. X X If you create you own interface script - compile it and install X it in the /usr/spool/lp/interface directory. Make SURE you X set the owner to "lp", the group to "other" and mode to "755". X Xlist - A Bourne shell script which I use to "list" (ie: send listings) X of files to the various printers while setting the printer X options. This script acts as a front-end to the interface X programs above. It assembles print options and filenames, X builds a command string in the proper format and then issues X the lp request. I use this approach because: X X 1: It's easy to modify the script when I want to add an option. X (for example - the option -8ss set everything up to be able X to print Smart Spreadsheet files in compressed pitch on X 8-1/2" wide paper - filtering the spreadsheet through X my DtoU (DOS to UNIX) filter on the way. - Very handy X type of thing to put into the script.) X X 2: It's easier to give the list options then construct the X lp command string. X X 3: I can specify my own desired default behavior. X X 4: lp doesn't give you and informative error messages when it X fails - and I was real sick of that. X X Once again, this script is chock full of local stuff (like X printing on our letterhead) which won't be of any use to you. X Rip this thing apart and reassemble to your heart's content. X XRemote: - In my last posting I also mentioned that remote printing with X the default scripts does not work properly. If you have two X UNIX-PCs attached with a serial or phone cable and configure X one to remote print on the other across the line, lp requests X work OK until you try to send an option string like: X X lp -s -dDaisy -o"lq 12cpi 8lpi" file1 file2 X X The multiple options get lost during the uucp transfer and I X could find no way to quote the string to get them to come X across intact. Thus, I modified the dumb-remote interface X script to transpose option requests into a string like: X X -o lq -o 12cpi -o 8lpi X X which works fine. "Remote" shows the modifications required. X X XHope some of you find this info. helpful. X-- XJeffery Small (206) 485-5596 uw-beaver!uw-nsr!uw-warp XC. Jeffery Small and Associates !cjsa!jeff X19112 152nd Ave NE - Woodinville, WA 98072 uunet!nwnexus END__of_the__FILE if test `wc -c < ./README` -ne 3811 then echo "\tWAIT A MINUTE ... Expecting file size of 3811 bytes" echo "\t but got a file size of `wc -c < ./README` bytes" echo "\tWARNING ......... Suggest you check file contents." fi else echo "will not over write ./README" fi if `test ! -s ./Quantex.c` then echo "extracting ./Quantex.c ..." sed 's/^X//' > ./Quantex.c << 'END__of_the__FILE' X#ifndef lint Xstatic char sccsid[] = "@(#) Quantex.c 1.1 3/19/89"; X#endif lint X X/************************************************************************/ X/* */ X/* SYNOPSIS */ X/* Quantex id spooler title copies options file1 [ file2 ... ] */ X/* */ X/* ARGUMENTS */ X/* id is: spooler_job_ID (assigned by lp spooler) */ X/* spooler is: spooler_name (typically "lp") */ X/* title is: header_title (assigned with lp -t flag) */ X/* copies is: No. of copies (assigned with lp -n flag) */ X/* options is: print_options (assigned with lp -o flag) */ X/* file1 is: file_name (name of file to be printed) */ X/* file2 ... : file_name(s) (additional files for printing) */ X/* */ X/* DESCRIPTION */ X/* This is the line printer interface for the Quantex Model #7065 */ X/* dot matrix printer. Output is directed to "stdout". It is */ X/* left up to the caller (or calling program) to redirect "stdout" */ X/* to the proper printer port as the lp spooler automatically does.*/ X/* Nevertheless, the knowledge that the printer is hardwired to */ X/* the parallel port is hard-coded into this program in setport(), */ X/* so moving the printer will require modifications to this prog. */ X/* For information related to the serial port, see the Daisy */ X/* interface. */ X/* */ X/* NOTES */ X/* * "id" (argv[1]) and "spooler" (argv[2]) are always ignored. */ X/* * Unknown "option" arguments are silently ignored. */ X/* * Command line arguments have been emperically determined by */ X/* looking at the model interface scripts. In particular, it */ X/* is unclear how argument No. 6 "-raw" is ever set using the */ X/* lp spooler. Therefore, we implement our own "raw" argument */ X/* as a -o option. */ X/* */ X/* BUGS */ X/* * The printer and the lp-driver maintain different "ideas" */ X/* about what top & bottom margins and page length mean. This */ X/* results in the need for "pagelen" & "activelines". (UGH). */ X/* */ X/* INSTALLATION (at least on the 3B1) */ X/* cc -c -O Quantex.c */ X/* ld -s Quantex.o $(SHAREDLIB) -o Quantex */ X/* install -o lp -g other -m 755 Quantex /usr/spool/lp/interface */ X/* */ X/************************************************************************/ X X#include <stdio.h> X#include <termio.h> X#include <string.h> X#include <sys/lprio.h> X#include <fcntl.h> X#include <ctype.h> X#include <time.h> X X#define NULLCHR (char) 0 X#define NULLPTR (char *) 0 X X#define OFF 0 X#define ON 1 X X#define PITCH_CNT 5 X X#define PITCH_10 0 X#define PITCH_12 1 X#define PITCH_13 2 X#define PITCH_15 3 X#define PITCH_17 4 X X#define PAPER_CNT 3 X X#define LTRHEAD 0 X#define PAPER_8 1 X#define PAPER_14 2 X Xstatic char *options; /* points to printing options */ Xstatic short formfeed = ON; /* issue formfeed at end of doc.*/ Xstatic short printhdr = OFF; /* print date & filename header */ Xstatic short pitch; /* horizontal pitch indicator */ Xstatic short paper; /* paper size indicator */ Xstatic short tpmargin; /* top margin lines from top */ Xstatic short bmmargin; /* bottom margin lines from bot */ Xstatic short ltmargin; /* left margin column number */ Xstatic short rtmargin; /* right margin column number */ Xstatic short pagelen; /* length of page in lines */ Xstatic short activelines; /* length of page for lp-driver */ X Xstatic short maxcol[PITCH_CNT][PAPER_CNT] = { { 76, 80, 136 }, X { 91, 96, 163 }, X { 100, 106, 180 }, X { 114, 120, 204 }, X { 129, 136, 232 } }; Xmain(argc, argv) X Xint argc; Xchar *argv[]; X{ X short copies, i; X char buf[BUFSIZ], *ctime(), *date, *fgets(), *filename; X long clock, time(); X void do_opts(), exit(), setprinter(); X FILE *fopen(), *source; X X if (argc < 7) { X (void) fprintf(stderr, X "%s: Error in argument count. Nothing to print.\n", argv[0]); X exit(1); X } X X (void) time(&clock); X date = ctime(&clock); X X copies = ( (i = atoi(argv[4])) > 0 ) ? i : 1; X options = argv[5]; X X setprinter(); /* set default printer options */ X X do_opts(); /* set specified print options */ X X if (strlen(argv[3]) > 0) { /* print title page if specified */ X X (void) fputs("\n\n\n\n\n\n", stdout); X (void) fputs("\n\n== Date Printed: =====================", stdout); X (void) fputs("======================================\n\n", stdout); X (void) fputs(date, stdout); X (void) fputs("\n\n======================================", stdout); X (void) fputs("======================================\n\n", stdout); X (void) fputs("\n\n== Title: ============================", stdout); X (void) fputs("======================================\n\n", stdout); X (void) fputs(argv[3], stdout); X (void) fputs("\n\n======================================", stdout); X (void) fputs("======================================\f", stdout); X } X X while (copies--) { /* loop for multiple copies */ X X if (! strcmp(argv[6], "-raw")) { /* just in case it arrives! */ X formfeed = OFF; X i = 7; X } else { X i = 6; X } X X for ( ; i < argc; i++) { /* loop to process each file */ X X if ( (source = fopen(argv[i], "r")) == (FILE *) 0 ) { X (void) fprintf(stderr, "%s: Cannot open file <%s> for reading.\n", X argv[0], argv[i]); X } else { X X /* a nice little four-line file ID header option */ X X if (printhdr) { X if ( (filename = strrchr(argv[i], '/')) == NULLPTR ) { X filename = argv[i]; X } else { X filename++; /* get file basename */ X } X (void) printf("File: %s\nDate: %s\n\n", filename, date); X } X X while ( fgets(buf, BUFSIZ, source) != NULLPTR ) { X (void) fputs(buf, stdout); X } X X if ( (copies == 0) && (i == (argc - 1)) ) { X setprinter(); /* reset default printer options */ X } X X if (formfeed) { X (void) putchar('\f'); /* formfeed at end of each file */ X } X } /* end if-else */ X X (void) fclose(source); X } /* end for loop */ X } /* end while */ X exit(0); X /*NOTREACHED*/ X} /* end main() */ X X/************************************************************************/ X/* void setprinter () */ X/* */ X/* Initialize the printer to the following default settings: */ X/* */ X/* Option Init. string Description */ X/* ------------ ----------------- ------------------------------- */ X/* nlq ^[[2!p near-letter-quality print speed */ X/* 8in ^[[1!z 8" paper width */ X/* 12cpi ^[[2w 12 char/inch horizontal pitch */ X/* 6lpi ^[[1z 6 lines/inch vertical pitch */ X/* nops ^[[0!y proportional spacing off */ X/* pglen 66 ^[[66t set page length to 66 lines */ X/* lm 1 rm 96 ^[[1;96s margin col: left = 1, rt = 96 */ X/* -- ^[[2g clear all horizontal tabs */ X/* -- ^[[9;17;...;...u set new tab stops every 8 sp. */ X/************************************************************************/ X Xvoid setprinter() X{ X extern short activelines, pagelen, paper, pitch; X extern short tpmargin, bmmargin, ltmargin, rtmargin; X extern short maxcol[PITCH_CNT][PAPER_CNT]; X X (void) fputs("\033[2!p\033[1!z\033[2w\033[1z\033[0!y\033[66t\015", stdout); X (void) fputs("\033[1;96s\033[2g\033[9;17;25;33;41;49;57;65;73u\015", stdout); X (void) fputs("\033[81;89;97;105;113;121;129;137;145;153;161u\015", stdout); X (void) fputs("\033[169;177;185;193;201;209;217;225;233;241;249u\015",stdout); X X paper = PAPER_8; /* export current settings */ X pitch = PITCH_12; X tpmargin = 0; X bmmargin = 0; X ltmargin = 1; X rtmargin = 96; X pagelen = activelines = 66; X X return; X} X X/************************************************************************/ X/* void do_opts () */ X/* */ X/* Process all of the options contained in the external *option string */ X/* which was passed to main() as argv[5]. Options are processed in the */ X/* order received so it is up to the caller to insure that the desired */ X/* effect is achieved. (ie: set horiz. pitch prior to setting margins, */ X/* etc.) */ X/************************************************************************/ X Xvoid do_opts() X{ X extern short activelines, pagelen, paper, pitch; X extern short tpmargin, bmmargin, ltmargin, rtmargin; X extern short printhdr, maxcol[PITCH_CNT][PAPER_CNT]; X char *nextarg(), *op; X short temp; X void setport(); X X while ( *(op = nextarg()) != NULLCHR ) { /* quit on NULL option */ X X if (! strcmp(op, "lq")) { /* 2-pass LQ - 40cps */ X (void) fputs("\033[3!p", stdout); X X } else if (! strcmp(op, "nlq")) { /* 1-pass NLQ - 80cps */ X (void) fputs("\033[2!p", stdout); X X } else if (! strcmp(op, "dp")) { /* data-proc. - 250cps */ X (void) fputs("\033[1!p", stdout); X X } else if (! strcmp(op, "draft")) { /* draft mode - 300cps */ X (void) fputs("\033[0!p", stdout); X X } else if (! strcmp(op, "8in")) { /* 8" wide paper */ X paper = PAPER_8; X rtmargin = maxcol[pitch][paper]; X (void) printf("\033[1!z\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "14in")) { /* 13-7/8" wide paper */ X paper = PAPER_14; X rtmargin = maxcol[pitch][paper]; X (void) printf("\033[0!z\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "10cpi")) { /* 10 cpi horiz. pitch */ X pitch = PITCH_10; X rtmargin = maxcol[pitch][paper]; X (void) printf("\033[1w\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "12cpi")) { /* 12 cpi horiz. pitch */ X pitch = PITCH_12; X rtmargin = maxcol[pitch][paper]; X (void) printf("\033[2w\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "13cpi")) { /* 13.3 cpi horiz pitch */ X pitch = PITCH_13; X rtmargin = maxcol[pitch][paper]; X (void) printf("\033[3w\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "15cpi")) { /* 15 cpi horiz. pitch */ X pitch = PITCH_15; X rtmargin = maxcol[pitch][paper]; X (void) printf("\033[5w\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "17cpi")) { /* 17.1 cpi horiz pitch */ X pitch = PITCH_17; X rtmargin = maxcol[pitch][paper]; X (void) printf("\033[4w\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "2lpi")) { /* 2 lpi vert. pitch */ X activelines = pagelen = 22; X (void) printf("\033[4z\033[%dt\015", pagelen); X X } else if (! strcmp(op, "3lpi")) { /* 3 lpi vert. pitch */ X activelines = pagelen = 33; X (void) printf("\033[5z\033[%dt\015", pagelen); X X } else if (! strcmp(op, "4lpi")) { /* 4 lpi vert. pitch */ X activelines = pagelen = 44; X (void) printf("\033[6z\033[%dt\015", pagelen); X X } else if (! strcmp(op, "6lpi")) { /* 6 lpi vert. pitch */ X activelines = pagelen = 66; X (void) printf("\033[1z\033[%dt\015", pagelen); X X } else if (! strcmp(op, "8lpi")) { /* 8 lpi vert. pitch */ X activelines = pagelen = 88; X (void) printf("\033[2z\033[%dt\015", pagelen); X X } else if (! strcmp(op, "12lpi")) { /* 12 lpi vert. pitch */ X activelines = pagelen = 132; X (void) printf("\033[3z\033[%dt\015", pagelen); X X } else if (! strcmp(op, "pglen")) { /* overall page length */ X if ( *(op = nextarg()) != NULLCHR ) { X if ( (temp = atoi(op)) > 0 ) { X tpmargin = 0; /* setting pglen auto. */ X bmmargin = 0; /* resets tm & bm to 0 */ X activelines = pagelen = temp; X (void) printf("\033[%dt\015", pagelen); X } X } X X } else if (! strcmp(op, "tm")) { /* set top margin */ X if ( *(op = nextarg()) != NULLCHR ) { X if ( ((temp = atoi(op)) > 0) && (temp <= activelines) ) { X tpmargin = temp; X (void) printf("\033[%dr\015", tpmargin); X activelines -= (tpmargin - 1); X } X } X X } else if (! strcmp(op, "bm")) { /* set bottom margin */ X if ( *(op = nextarg()) != NULLCHR ) { X if ( ((temp = atoi(op)) > 0) && (temp <= activelines) ) { X bmmargin = temp; X (void) printf("\033[;%dr\015", ((pagelen - bmmargin) + 1)); X activelines -= (bmmargin - 1); X } X } X X } else if (! strcmp(op, "lm")) { /* set left margin & tabs */ X if ( *(op = nextarg()) != NULLCHR ) { X if ( ((temp = atoi(op)) > 0) && (temp < rtmargin) ) { X ltmargin = temp; X (void) printf("\033[%ds\033[2g\015", ltmargin); X X for (temp = (ltmargin + 8); temp < 237; temp += 8) { X (void) printf("\033[%du\015", temp); X } X } X } X X } else if (! strcmp(op, "rm")) { /* set right margin */ X if ( *(op = nextarg()) != NULLCHR ) { X if ( ((temp = atoi(op)) > 0) && (temp > ltmargin) ) { X rtmargin = (temp <= maxcol[pitch][paper]) ? temp : X maxcol[pitch][paper]; X (void) printf("\033[;%ds\015", rtmargin); X } X } X X } else if (! strcmp(op, "cjsa")) { /* set for CJSA ltrhead */ X paper = LTRHEAD; X pitch = PITCH_12; X ltmargin = 17; X rtmargin = maxcol[pitch][paper]; X tpmargin = 12; X (void) printf("\033[2w\033[17s\033[12r\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "cjsa2")) { /* CJSA ltrhd 2nd shts */ X paper = LTRHEAD; X pitch = PITCH_12; X ltmargin = 17; X rtmargin = maxcol[pitch][paper]; X tpmargin = 1; X (void) printf("\033[2w\033[17s\033[1r\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "matrix")) { /* set for Matrix ltrhd */ X paper = LTRHEAD; X pitch = PITCH_12; X ltmargin = 10; X rtmargin = maxcol[pitch][paper]; X tpmargin = 12; X (void) printf("\033[2w\033[10s\033[12r\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "matrix2")) { /* Matrix ltrhd 2nd shts */ X paper = LTRHEAD; X pitch = PITCH_12; X ltmargin = 10; X rtmargin = maxcol[pitch][paper]; X tpmargin = 1; X (void) printf("\033[2w\033[10s\033[1r\033[;%ds\015", rtmargin); X X } else if (! strcmp(op, "ps")) { /* proportional sp. ON */ X (void) fputs("\033[1!y\015", stdout); X X } else if (! strcmp(op, "nops")) { /* proportional sp. OFF */ X (void) fputs("\033[0!y\015", stdout); X X } else if (! strcmp(op, "header")) { /* print file header */ X printhdr = ON; X X } else if (! strcmp(op, "raw")) { /* raw mode: */ X formfeed = OFF; /* do not issue '\f' */ X printhdr = OFF; /* do not print header */ X (void) printf("\033[1;%dr\015", pagelen); X activelines = pagelen; /* tm = 1, bm = pagelen */ X X } /* end if-else */ X } /* end while loop */ X X setport(activelines); /* set ioctl on port */ X X return; X} /* end do_opts(); X X/************************************************************************/ X/* char *nextarg () */ X/* */ X/* Return a pointer to the next option argument located in the static */ X/* *option string. A pointer to a NULL string will indicate the end */ X/* of the options. */ X/************************************************************************/ X Xchar *nextarg() X{ X extern char *options; X static char opbuf[128]; X int i; X X while ( isspace(*options) ) { /* skip white space */ X options++; X } X X i = 0; X while ( (*options != NULLCHR) && (! isspace(*options)) ) { X opbuf[i++] = *(options++); X } X opbuf[i] = NULLCHR; X X return(opbuf); X} X X/************************************************************************/ X/* void setport (lines) */ X/* */ X/* Adjust the parallel printer port (/dev/lp - not /dev/rawlp) to */ X/* perform zero indentation, provide a column width of 237 characters */ X/* maximum (for Quantex printing at 17.1 cpi on 13-7/8" paper), and set */ X/* the number of active lines per page to the value specified in the */ X/* "lines" argument. */ X/* */ X/* Note that you can circumvent this requirement if you use /dev/rawlp, */ X/* but this setup makes the use of /dev/lp possible if you want to */ X/* utilize some element of the driver's post-processing control. */ X/************************************************************************/ X Xvoid setport(lines) X Xshort lines; X{ X struct lprio store; X X store.ind = 0; X store.col = 237; X store.line = lines; X X (void) ioctl(1, LPRSET, &store); X X return; X} END__of_the__FILE if test `wc -c < ./Quantex.c` -ne 16046 then echo "\tWAIT A MINUTE ... Expecting file size of 16046 bytes" echo "\t but got a file size of `wc -c < ./Quantex.c` bytes" echo "\tWARNING ......... Suggest you check file contents." fi else echo "will not over write ./Quantex.c" fi if `test ! -s ./Daisy.c` then echo "extracting ./Daisy.c ..." sed 's/^X//' > ./Daisy.c << 'END__of_the__FILE' X#ifndef lint Xstatic char sccsid[] = "@(#) Daisy.c 1.1 3/19/89"; X#endif lint X X/************************************************************************/ X/* */ X/* SYNOPSIS */ X/* Daisy id spooler title copies options file1 [ file2 ... ] */ X/* */ X/* ARGUMENTS */ X/* id is: spooler_job_ID (assigned by lp spooler) */ X/* spooler is: spooler_name (typically "lp") */ X/* title is: header_title (assigned with lp -t flag) */ X/* copies is: No. of copies (assigned with lp -n flag) */ X/* options is: print_options (assigned with lp -o flag) */ X/* file1 is: file_name (name of file to be printed) */ X/* file2 ... : file_name(s) (additional files for printing) */ X/* */ X/* DESCRIPTION */ X/* This is the line printer interface for the Dataproducts DP-20 */ X/* daisy wheel printer. Output is directed to "stdout". It is */ X/* left up to the caller (or calling program) to redirect "stdout" */ X/* to the proper printer port as the lp spooler automatically does.*/ X/* This interface is for a printer connected to a serial port. */ X/* For information related to the parallel port, see the Quantex */ X/* interface. */ X/* */ X/* NOTES */ X/* * The DP-20 is similar to a Diablo630 in its control codes. */ X/* * "id" (argv[1]), "spooler" (argv[2]) and "title" (argv[3]) */ X/* are always ignored. */ X/* * Unknown "option" arguments are silently ignored. */ X/* * Command line arguments have been emperically determined by */ X/* looking at the model interface scripts. In particular, it */ X/* is unclear how argument No. 6 "-raw" is ever set using the */ X/* lp spooler. */ X/* */ X/* BUGS */ X/* * The title option (argv[3]) is not implemented as this would */ X/* generate a title page on a printer which generally will be */ X/* hand fed single sheets of paper. */ X/* * The "bm" bottom margin option is not implemented since this */ X/* printer requires that you index down to the point in order */ X/* to set the margin - ouch - The "Diablo" interface model */ X/* is a particularly stupid implementation and extremely */ X/* non-intuitive. */ X/* * So, after many months of screwing around, we finally figure */ X/* out that the DP-20 can actually keep up with 300 baud! 450 */ X/* was just a little too fast for its sensitive character. */ X/* Junk the sucker... Oh yeah, watch out ... 300 baud is */ X/* hardwired into this programin setport(). */ X/* */ X/* INSTALLATION (at least on the 3B1) */ X/* cc -c -O Daisy.c */ X/* ld -s Daisy.o $(SHAREDLIB) -o Daisy */ X/* install -o lp -g other -m 755 Daisy /usr/spool/lp/interface */ X/* */ X/************************************************************************/ X X#include <stdio.h> X#include <termio.h> X#include <fcntl.h> X#include <ctype.h> X X#define NULLCHR (char) 0 X#define NULLPTR (char *) 0 X X#define SET(variable, bits) ((variable) |= (bits)) X#define CLEAR(variable, bits) ((variable) &= ~(bits)) X X#define PITCH_CNT 5 X X#define PITCH_10 0 X#define PITCH_12 1 X#define PITCH_13 2 X#define PITCH_15 3 X#define PITCH_17 4 X X#define PAPER_CNT 3 X X#define LTRHEAD 0 X#define PAPER_8 1 X#define PAPER_14 2 X X#define RAW 0 X#define NORMAL 1 X#define SPEED 2 X Xstatic char *options; /* points to printing options */ Xstatic short pitch; /* horizontal pitch indicator */ Xstatic short paper; /* paper size indicator */ Xstatic short rtmargin; /* right margin column number */ X Xstatic short maxcol[PITCH_CNT][PAPER_CNT] = { { 76, 80, 136 }, X { 91, 96, 163 }, X { 100, 106, 180 }, X { 114, 120, 204 }, X { 129, 136, 232 } }; X Xstatic float pval[PITCH_CNT] = { 10.0, 12.0, 13.3, 15.0, 17.1 }; X Xstatic char hmi_n[PITCH_CNT] = { '\015', '\013', '\012', '\011', '\010' }; X Xmain(argc, argv) X Xint argc; Xchar *argv[]; X{ X short copies, i; X char buf[BUFSIZ]; X void do_opts(), exit(), setport(), setprinter(); X FILE *fopen(), *source; X X setport(SPEED); /* set port speed to 300 baud */ X X if (argc < 7) { X (void) fprintf(stderr, X "%s: Error in argument count. Nothing to print.\n", argv[0]); X exit(1); X } X X copies = ( (i = atoi(argv[4])) > 0 ) ? i : 1; X options = argv[5]; X X setport(RAW); /* turn off port output processing */ X X setprinter(); /* set default printer options */ X X do_opts(); /* set specified print options */ X X setport(NORMAL); /* turn on port output processing */ X X while (copies--) { /* loop for multiple copies */ X X for (i = 6 ; i < argc; i++) { /* loop to process each file */ X X if ( (source = fopen(argv[i], "r")) == (FILE *) 0 ) { X (void) fprintf(stderr, "%s: Cannot open file <%s> for reading.\n", X argv[0], argv[i]); X } else { X X (void) putchar('\r'); /* insure carriage is at left margin */ X X while ( fgets(buf, BUFSIZ, source) != NULLPTR ) { X (void) fputs(buf, stdout); X } X (void) putchar('\f'); /* formfeed at end of each file */ X } /* end if-else */ X X (void) fclose(source); X } /* end for loop */ X } /* end while */ X X setport(RAW); /* turn off port output processing */ X setprinter(); /* reset default printer options */ X setport(NORMAL); /* turn on port output processing */ X (void) putchar('\r'); /* leave carriage at left margin */ X X exit(0); X /*NOTREACHED*/ X} /* end main() */ X X/************************************************************************/ X/* void setport (type) */ X/* */ X/* Adjust the serial printer port (stdout set by lp spooler) to the */ X/* appropriate values. If "type" is SPEED, the required 300-baud rate */ X/* is established. If "type" is RAW, then output post-processing is */ X/* disabled so that non-printing control codes can be issued to the */ X/* printer. If "type" is NORMAL, then xon/xoff flow control, tab, */ X/* NL/CR and output post-processing is re-enabled in preparation of */ X/* sending the test file(s) to the printer. */ X/* */ X/* The RAW mode is required while sending control-codes or else the */ X/* embeded tabs '\011' and newlines '\012' will be converted to spaces/ */ X/* carriage-returns and the control functions will not be implemented. */ X/************************************************************************/ X Xvoid setport(type) X Xint type; X{ X struct termio port; X int fd; X X fd = dup(1); X X (void) ioctl(fd, TCGETA, &port); X X switch (type) { X X case SPEED: X CLEAR(port.c_cflag, CBAUD|HUPCL); X SET(port.c_cflag, B300|CLOCAL); X break; X X case RAW: X CLEAR(port.c_oflag, OPOST); X break; X X case NORMAL: X SET(port.c_iflag, IXON); X SET(port.c_oflag, OPOST|ONLCR|TAB3); X break; X } X X (void) ioctl(fd, TCSETAW, &port); X return; X} X X/************************************************************************/ X/* void setprinter () */ X/* */ X/* Initialize the printer to the following default settings: */ X/* */ X/* Option Init. string Description */ X/* ------------ ----------------- ------------------------------- */ X/* -- ^[2 clear all horizontal tabs */ X/* 12cpi ^[^_{11} 12 char/inch horizontal pitch */ X/* lm 1 ^[\t{1}^[9 set left margin to column 1 */ X/* rm 96 ^[\t{96}^[0 set right margin to column 96 */ X/* -- ^[C clear top and bottom margins */ X/************************************************************************/ X Xvoid setprinter() X{ X extern short paper, pitch, rtmargin; X extern short maxcol[PITCH_CNT][PAPER_CNT]; X X (void) fputs("\033\062\033\037\013\033\011\001\033\071", stdout); X (void) fputs("\033\011\140\033\060\033\103", stdout); X X paper = PAPER_8; /* export current settings */ X pitch = PITCH_12; X rtmargin = maxcol[pitch][paper]; X X return; X} X X/************************************************************************/ X/* void do_opts () */ X/* */ X/* Process all of the options contained in the external *option string */ X/* which was passed to main() as argv[5]. Options are processed in the */ X/* order received so it is up to the caller to insure that the desired */ X/* effect is achieved. (ie: set horiz. pitch prior to setting margins, */ X/* etc.) */ X/************************************************************************/ X Xvoid do_opts() X{ X extern short paper, pitch, rtmargin; X extern char hmi_n[PITCH_CNT]; X extern float pval[PITCH_CNT]; X extern short maxcol[PITCH_CNT][PAPER_CNT]; X char Bchar, *nextarg(), *op; X short col, line; X X while ( *(op = nextarg()) != NULLCHR ) { /* quit on NULL option */ X X if (! strcmp(op, "10cpi")) { /* 10 cpi horiz. pitch */ X pitch = PITCH_10; X rtmargin = maxcol[pitch][paper]; X (void) fputs("\033\037\015", stdout); X X } else if (! strcmp(op, "12cpi")) { /* 12 cpi horiz. pitch */ X pitch = PITCH_12; X rtmargin = maxcol[pitch][paper]; X (void) fputs("\033\037\013", stdout); X X } else if (! strcmp(op, "13cpi")) { /* 13.3 cpi horiz pitch */ X pitch = PITCH_13; X rtmargin = maxcol[pitch][paper]; X (void) fputs("\033\037\012", stdout); X X } else if (! strcmp(op, "15cpi")) { /* 15 cpi horiz. pitch */ X pitch = PITCH_15; X rtmargin = maxcol[pitch][paper]; X (void) fputs("\033\037\011", stdout); X X } else if (! strcmp(op, "17cpi")) { /* 17.1 cpi horiz pitch */ X pitch = PITCH_17; X rtmargin = maxcol[pitch][paper]; X (void) fputs("\033\037\010", stdout); X X } else if (! strcmp(op, "tm")) { /* set top margin */ X if ( *(op = nextarg()) != NULLCHR ) { X if ( (line = atoi(op)) > 0 ) { X while ( line-- ) { X (void) putchar('\n'); X } X (void) fputs("\033T", stdout); X } X } X X /* DP-20 can't take ascii val. */ X /* over 126! - hunk of junk! */ X } else if (! strcmp(op, "lm")) { X if ( *(op = nextarg()) != NULLCHR ) { X if ( ((col = atoi(op)) > 0) && (col < rtmargin) X && (col <= 126) ) { X Bchar = (char) col; X (void) fputs("\033\011", stdout); X (void) fwrite(&Bchar, sizeof(Bchar), 1, stdout); X (void) fputs("\033\071", stdout); X } X } X X } else if (! strcmp(op, "rm")) { /* set right margin */ X if ( *(op = nextarg()) != NULLCHR ) { X if ( (col = atoi(op)) > 0 ) { X rtmargin = (col <= maxcol[pitch][paper]) ? col : X maxcol[pitch][paper]; X col = (((rtmargin/pval[pitch]) * 4.0) + 0.85); X Bchar = (char) col; X (void) fputs("\033\037\037\033\011", stdout); X (void) fwrite(&Bchar, sizeof(Bchar), 1, stdout); X (void) fputs("\033\060\033\037", stdout); X (void) fwrite(&hmi_n[pitch], sizeof(hmi_n[pitch]), 1, stdout); X } X } X X } else if ( (! strcmp(op, "cjsa")) || /* set for CJSA ltrhead */ X (! strcmp(op, "cjsa2")) ) { X paper = LTRHEAD; X pitch = PITCH_12; X rtmargin = maxcol[pitch][paper]; X (void) fputs("\033\103\033\037\013", stdout); X (void) fputs("\033\011\014\033\071\033\011\133\033\060", stdout); X X } else if ( (! strcmp(op, "matrix")) || /* set for Matrix ltrhd */ X (! strcmp(op, "matrix2")) ) { X paper = LTRHEAD; X pitch = PITCH_12; X rtmargin = maxcol[pitch][paper]; X (void) fputs("\033\103\033\037\013", stdout); X (void) fputs("\033\011\001\033\071\033\011\133\033\060", stdout); X X } else if (! strcmp(op, "8in")) { /* 8" wide paper */ X paper = PAPER_8; X rtmargin = maxcol[pitch][paper]; X (void) fputs("\033\037\037\033\011\041\033\060\033\037", stdout); X (void) fwrite(&hmi_n[pitch], sizeof(hmi_n[pitch]), 1, stdout); X X } else if (! strcmp(op, "14in")) { /* 13-7/8" wide paper */ X paper = PAPER_14; X rtmargin = maxcol[pitch][paper]; X (void) fputs("\033\037\037\033\011\067\033\060\033\037", stdout); X (void) fwrite(&hmi_n[pitch], sizeof(hmi_n[pitch]), 1, stdout); X X } else if (! strcmp(op, "ps")) { /* proportional sp. ON */ X (void) fputs("\033P", stdout); X X } else if (! strcmp(op, "nops")) { /* proportional sp. OFF */ X (void) fputs("\033Q", stdout); X X } /* end if-else */ X } /* end while loop */ X X return; X} /* end do_opts(); X X/************************************************************************/ X/* char *nextarg () */ X/* */ X/* Return a pointer to the next option argument located in the static */ X/* *option string. A pointer to a NULL string will indicate the end */ X/* of the options. */ X/************************************************************************/ X Xchar *nextarg() X{ X extern char *options; X static char opbuf[128]; X int i; X X while ( isspace(*options) ) { /* skip white space */ X options++; X } X X i = 0; X while ( (*options != NULLCHR) && (! isspace(*options)) ) { X opbuf[i++] = *(options++); X } X opbuf[i] = NULLCHR; X X return(opbuf); X} END__of_the__FILE if test `wc -c < ./Daisy.c` -ne 12876 then echo "\tWAIT A MINUTE ... Expecting file size of 12876 bytes" echo "\t but got a file size of `wc -c < ./Daisy.c` bytes" echo "\tWARNING ......... Suggest you check file contents." fi else echo "will not over write ./Daisy.c" fi if `test ! -s ./list` then echo "extracting ./list ..." sed 's/^X//' > ./list << 'END__of_the__FILE' X#! /bin/sh X# X# sccsid = "@(#) list 1.1 3/19/89" X X######################################################################### X# # X#SYNOPSIS # X# list [-options] file1 [ file2 ... ] # X# # X# DESCRIPTION # X# This Bourne shell script acts as a front end to the printer # X# interface programs written for the Quantex (#7065) and Daisy # X# (Dataproducts DP-20) printers. List makes "listings" of the # X# specified files, setting the appropriate printer interface # X# options in their correct order. Default values have been # X# assigned, all of which may be overridden. # X# # X# OPTIONS # X# See the case statment below. Note that options must be # X# seperated by space including options which require an argument. # X# eg: # X# # X# list -lq -14in -co 2 -15cpi -8lpi -lm 10 -rm 72 /etc/passwd # X# # X# BUGS # X# You could build all this into the printer interface programs # X# but its much easier to keep modifying this script. # X# # X######################################################################### X XTMP=/tmp/LIST$$ X Xtrap "/bin/rm -f $TMP ; trap 0; exit 1" 1 2 3 15 Xtrap "/bin/rm -f $TMP ; exit 0" 0 X XDTOU="" XOPTS="" XFILES="" XPTR="Quantex" XSPEED="nlq" XPAPER="8in" XHPITCH="12cpi" XVPITCH="6lpi" XPROPSP="OFF" XPGLEN="66" XTM="3" XBM="3" XLM="10" XRM="96" XHEADER="OFF" XLTRHEAD="" XCOPIES="1" X Xif [ "$#" = "0" ] Xthen X echo "usage: $0 [-options] file1 [ file2 ... ]" X exit 1 Xfi X Xwhile [ $# -gt 0 ] Xdo X case $1 in X -quantex | -Quantex | -QUANTEX) # Quantex printer X PTR="Quantex";; X -daisy | -Daisy | -DAISY) # Daisy wheel printer X PTR="Daisy" X TM="0";; X -epson | -Epson | -EPSON) # Epson mode - Quantex printer X PTR="Epson";; X -diablo* | -Diablo* | -DIABLO*) # Diablo interface to Daisy X PTR="Diablo630" X TM="0";; X -lq) # 2-pass LQ print X SPEED="lq";; X -nlq) # Single pass NLQ print X SPEED="nlq";; X -dp) # Data-processing print X SPEED="dp";; X -draft) # Draft print (300 cps) X SPEED="draft";; X -8in) # 8" wide paper X RM="136" X PAPER="8in";; X -14in) # 13-7/8" wide paper X RM="232" X PAPER="14in";; X -10cpi) # 10 cpi horizontal pitch X if [ "$PAPER" = "8in" ] ; then X RM=80 X else X RM=136 X fi X HPITCH="10cpi";; X -12cpi) # 12 cpi horizontal pitch X if [ "$PAPER" = "8in" ] ; then X RM=96 X else X RM=163 X fi X HPITCH="12cpi";; X -13cpi) # 13 cpi horizontal pitch X if [ "$PAPER" = "8in" ] ; then X RM=104 X else X RM=176 X fi X HPITCH="13cpi";; X -15cpi) # 15 cpi horizontal pitch X if [ "$PAPER" = "8in" ] ; then X RM=120 X else X RM=204 X fi X HPITCH="15cpi";; X -17cpi) # 17 cpi horizontal pitch X if [ "$PAPER" = "8in" ] ; then X RM=136 X else X RM=232 X fi X HPITCH="17cpi";; X -2lpi) # 2 lpi vertical pitch X PGLEN="22" X VPITCH="2lpi";; X -3lpi) # 3 lpi vertical pitch X PGLEN="33" X VPITCH="3lpi";; X -4lpi) # 4 lpi vertical pitch X PGLEN="44" X VPITCH="4lpi";; X -6lpi) # 6 lpi vertical pitch X PGLEN="66" X VPITCH="6lpi";; X -8lpi) # 8 lpi vertical pitch X PGLEN="88" X VPITCH="8lpi";; X -12lpi) # 12 lpi vertical pitch X PGLEN="132" X VPITCH="12lpi";; X -ps) # Proportional spacing on X PROPSP="ON";; X -pglen) # Set page length X PGLEN="$2" X TM="1" X BM="1" X shift;; X -tm) # Set top margin X TM="$2" X shift;; X -bm) # Set bottom margin X BM="$2" X shift;; X -lm) # Set left margin X LM="$2" X shift;; X -rm) # Set right margin X RM="$2" X shift;; X -h | -header) # Turn header printing on X HEADER="ON";; X -noh | -noheader) # Turn header printing off X HEADER="OFF";; X -noi | -noindent) # Turn indenting off X LM="1";; X -novm) # Turn vert margin off X TM="1" X BM="1";; X -cjsa | -CJSA) # Set for CJSA letterhead X LTRHEAD="cjsa";; X -cjsa2 | -CJSA2) # CJSA letterhead 2nd sheets X LTRHEAD="cjsa2";; X -matrix | -Matrix | -MATRIX) # Set for Matrix letterhead X LTRHEAD="matrix";; X -matrix2 | -Matrix2 | -MATRIX2) # Matrix letterhead 2nd sheets X LTRHEAD="matrix2";; X -copies | -co | -c | -n) # Number of copies to print X COPIES="$2" X shift;; X -raw) # No trailing formfeeds X TM="1" X BM="1" X HEADER="OFF" X LTRHEAD="" X OPTS="${OPTS}raw ";; X -8ss) # Printing Smart Spreadsheet X DTOU="YES" X SPEED="dp" X PAPER="8in" X HPITCH="17cpi" X VPITCH="8lpi" X PGLEN="88" X TM="1" X BM="1" X LM="10" X RM="136" X HEADER="OFF" X PROPSP="OFF" X OPTS="${OPTS}raw ";; X -*) # Bad argument X echo "$0: '"$1"' Unknown argument!" X exit 2;; X *) # Should be a file argument X if test -r "$1" X then X if [ "$DTOU" = "YES" ] X then X DtoU $1 $TMP # DtoU is a DOS to UNIX X if [ "$?" != "0" ] # filter to strip ^Ms & ^Zs X then X echo "$0: Cannot 'DtoU' this file!" X else X mv $TMP $1 X if [ "$?" != "0" ] X then X echo "$0: Cannot 'DtoU' this file!" X fi X fi X fi X X FILES="${FILES}$1 " X else X echo "$0: Can not open file $1" X fi X ;; X esac X shift Xdone X Xif [ "x${FILES}" != "x" ] # Are there files to print? Xthen X X if [ "x${LTRHEAD}" != "x" ] # If letterhead specified ... X then X OPTS="${OPTS}$SPEED $LTRHEAD " # put OPTS in proper order X else X OPTS="${OPTS}$SPEED $PAPER $HPITCH $VPITCH pglen $PGLEN " X OPTS="${OPTS}tm $TM bm $BM lm $LM rm $RM " X X if [ "PROPSP" = "ON" ] X then X OPTS="${OPTS}ps " X fi X X if [ "$HEADER" = "ON" ] X then X OPTS="${OPTS}header " X fi X fi X X lp -s -d$PTR -n$COPIES -o"$OPTS" $FILES # Spool file(s) X X exit 0 Xelse X echo "$0: No file(s) specified for printing." X exit 3 Xfi END__of_the__FILE if test `wc -c < ./list` -ne 5633 then echo "\tWAIT A MINUTE ... Expecting file size of 5633 bytes" echo "\t but got a file size of `wc -c < ./list` bytes" echo "\tWARNING ......... Suggest you check file contents." fi else echo "will not over write ./list" fi if `test ! -s ./Remote` then echo "extracting ./Remote ..." sed 's/^X//' > ./Remote << 'END__of_the__FILE' X#sccs "@(#)lp/model:dumb-remote 1.7" X# X# Modified by Jeffery Small on 09-15-88 to properly handle -o arguments X# X# X# lp interface for printer in remote mode X# X# X. /usr/spool/lp/interface/remote XTITLE=$3 XCOPIES=$4 XOPTS=$5 XRAW=$6 Xshift; shift; shift; shift; shift X Xif [ "$RAW" = "-raw" ] Xthen X PTYPE=${PTYPE}_R X shift X for F in $* X do X cp $F /usr/spool/uucppublic/`basename $F`.g X FILES=$FILES"/usr/spool/uucppublic/`basename $F`.g " X done Xelse X for F in $* X do X cp $F /usr/spool/uucppublic/`basename $F`.: X FILES=$FILES"/usr/spool/uucppublic/`basename $F`.: " X done Xfi X XOPTIONS="" Xfor i in $OPTS Xdo X OPTIONS=$OPTIONS"-o$i " Xdone X Xuux -r -n "$MACHINE!lp -d$PTYPE -t$TITLE $OPTIONS -n$COPIES $FILES" Xuucp $FILES $MACHINE!/usr/spool/uucppublic Xexit 0 END__of_the__FILE if test `wc -c < ./Remote` -ne 754 then echo "\tWAIT A MINUTE ... Expecting file size of 754 bytes" echo "\t but got a file size of `wc -c < ./Remote` bytes" echo "\tWARNING ......... Suggest you check file contents." fi else echo "will not over write ./Remote" fi echo "Finished archive 1 of 1" # if you want to concatenate archives, remove anything after this line exit