1*7dd7cddfSDavid du Colombier /* 2*7dd7cddfSDavid du Colombier * 3*7dd7cddfSDavid du Colombier * POSTBEGIN, if it's not NULL, is some PostScript code that's sent to the printer 4*7dd7cddfSDavid du Colombier * before any of the input files. It's not terribly important since the same thing 5*7dd7cddfSDavid du Colombier * can be accomplished in other ways, but this approach is convenient. POSTBEGIN 6*7dd7cddfSDavid du Colombier * is initialized so as to disable job timeouts. The string can also be set on the 7*7dd7cddfSDavid du Colombier * command line using the -P option. 8*7dd7cddfSDavid du Colombier * 9*7dd7cddfSDavid du Colombier */ 10*7dd7cddfSDavid du Colombier 11*7dd7cddfSDavid du Colombier #define POSTBEGIN "statusdict /waittimeout 0 put\n" 12*7dd7cddfSDavid du Colombier 13*7dd7cddfSDavid du Colombier /* 14*7dd7cddfSDavid du Colombier * 15*7dd7cddfSDavid du Colombier * The following help determine where postio is when it's running - either in the 16*7dd7cddfSDavid du Colombier * START, SEND, or DONE states. Primarily controls what's done in getstatus(). 17*7dd7cddfSDavid du Colombier * RADIAN occasionally had problems with two way conversations. Anyway this stuff 18*7dd7cddfSDavid du Colombier * can be used to prevent status queries while we're transmitting a job. Enabled 19*7dd7cddfSDavid du Colombier * by the -q option. 20*7dd7cddfSDavid du Colombier * 21*7dd7cddfSDavid du Colombier */ 22*7dd7cddfSDavid du Colombier 23*7dd7cddfSDavid du Colombier #define NOTCONNECTED 0 24*7dd7cddfSDavid du Colombier #define START 1 25*7dd7cddfSDavid du Colombier #define SEND 2 26*7dd7cddfSDavid du Colombier #define DONE 3 27*7dd7cddfSDavid du Colombier 28*7dd7cddfSDavid du Colombier /* 29*7dd7cddfSDavid du Colombier * 30*7dd7cddfSDavid du Colombier * Previous versions of postio only ran as a single process. That was (and still 31*7dd7cddfSDavid du Colombier * is) convenient, but meant we could only flow control one direction. Data coming 32*7dd7cddfSDavid du Colombier * back from the printer occasionally got lost, but that didn't often hurt (except 33*7dd7cddfSDavid du Colombier * for lost error messages). Anyway I've added code that lets you split the program 34*7dd7cddfSDavid du Colombier * into separate read and write processes, thereby helping to prevent data loss in 35*7dd7cddfSDavid du Colombier * both directions. It should be particularly useful when you're sending a job that 36*7dd7cddfSDavid du Colombier * you expect will be returning useful data over the communications line. 37*7dd7cddfSDavid du Colombier * 38*7dd7cddfSDavid du Colombier * The next three definitions control what's done with data on communications line. 39*7dd7cddfSDavid du Colombier * The READ flag means the line can be read, while the WRITE flag means it can be 40*7dd7cddfSDavid du Colombier * written. When we're running as a single process both flags are set. I tried to 41*7dd7cddfSDavid du Colombier * overlay the separate read/write process code on what was there and working for 42*7dd7cddfSDavid du Colombier * one process. The implementation isn't as good as it could be, but should be 43*7dd7cddfSDavid du Colombier * safe. The single process version still works, and remains the default. 44*7dd7cddfSDavid du Colombier * 45*7dd7cddfSDavid du Colombier */ 46*7dd7cddfSDavid du Colombier 47*7dd7cddfSDavid du Colombier #define READ 1 48*7dd7cddfSDavid du Colombier #define WRITE 2 49*7dd7cddfSDavid du Colombier #define READWRITE 3 50*7dd7cddfSDavid du Colombier 51*7dd7cddfSDavid du Colombier /* 52*7dd7cddfSDavid du Colombier * 53*7dd7cddfSDavid du Colombier * Messages generated on the printer and returned over the communications line 54*7dd7cddfSDavid du Colombier * look like, 55*7dd7cddfSDavid du Colombier * 56*7dd7cddfSDavid du Colombier * %%[ status: idle; source: serial 25 ]%% 57*7dd7cddfSDavid du Colombier * %%[ status: waiting; source: serial 25 ]%% 58*7dd7cddfSDavid du Colombier * %%[ status: initializing; source: serial 25 ]%% 59*7dd7cddfSDavid du Colombier * %%[ status: busy; source: serial 25 ]%% 60*7dd7cddfSDavid du Colombier * %%[ status: printing; source: serial 25 ]%% 61*7dd7cddfSDavid du Colombier * %%[ status: PrinterError: out of paper; source: serial 25 ]%% 62*7dd7cddfSDavid du Colombier * %%[ status: PrinterError: no paper tray; source: serial 25 ]%% 63*7dd7cddfSDavid du Colombier * 64*7dd7cddfSDavid du Colombier * %%[ PrinterError: out of paper; source: serial 25 ]%% 65*7dd7cddfSDavid du Colombier * %%[ PrinterError: no paper tray; source: serial 25 ]%% 66*7dd7cddfSDavid du Colombier * 67*7dd7cddfSDavid du Colombier * %%[ Error: undefined; OffendingCommand: xxx ]%% 68*7dd7cddfSDavid du Colombier * %%[ Flushing: rest of job (to end-of-file) will be ignored ]%% 69*7dd7cddfSDavid du Colombier * 70*7dd7cddfSDavid du Colombier * although the list isn't meant to be complete. 71*7dd7cddfSDavid du Colombier * 72*7dd7cddfSDavid du Colombier * The following constants are used to classify the recognized printer states. 73*7dd7cddfSDavid du Colombier * readline() reads complete lines from ttyi and stores them in array mesg[]. 74*7dd7cddfSDavid du Colombier * getstatus() looks for the "%%[ " and " ]%%" delimiters that bracket printer 75*7dd7cddfSDavid du Colombier * messages and if found it tries to parse the enclosed message. After the lookup 76*7dd7cddfSDavid du Colombier * one of the following numbers is returned as an indication of the existence or 77*7dd7cddfSDavid du Colombier * content of the printer message. The return value is used in start(), send(), 78*7dd7cddfSDavid du Colombier * and done() to figure out what's happening and what can be done next. 79*7dd7cddfSDavid du Colombier * 80*7dd7cddfSDavid du Colombier */ 81*7dd7cddfSDavid du Colombier 82*7dd7cddfSDavid du Colombier #define BUSY 0 /* processing data already sent */ 83*7dd7cddfSDavid du Colombier #define WAITING 1 /* printer wants more data */ 84*7dd7cddfSDavid du Colombier #define PRINTING 2 /* printing a page */ 85*7dd7cddfSDavid du Colombier #define IDLE 3 /* ready to start the next job */ 86*7dd7cddfSDavid du Colombier #define ENDOFJOB 4 /* readline() builds this up on EOF */ 87*7dd7cddfSDavid du Colombier #define PRINTERERROR 5 /* PrinterError - eg. out of paper */ 88*7dd7cddfSDavid du Colombier #define ERROR 6 /* some kind of PostScript error */ 89*7dd7cddfSDavid du Colombier #define FLUSHING 7 /* throwing out the rest of the job */ 90*7dd7cddfSDavid du Colombier #define INITIALIZING 8 /* printer is booting */ 91*7dd7cddfSDavid du Colombier #define DISCONNECT 9 /* from Datakit! */ 92*7dd7cddfSDavid du Colombier #define UNKNOWN 10 /* in case we missed anything */ 93*7dd7cddfSDavid du Colombier #define NOSTATUS 11 /* no response from the printer */ 94*7dd7cddfSDavid du Colombier 95*7dd7cddfSDavid du Colombier #define WRITEPROCESS 12 /* dummy states for write process */ 96*7dd7cddfSDavid du Colombier #define INTERACTIVE 13 /* and interactive mode */ 97*7dd7cddfSDavid du Colombier 98*7dd7cddfSDavid du Colombier /* 99*7dd7cddfSDavid du Colombier * 100*7dd7cddfSDavid du Colombier * An array of type Status is used, in getstatus(), to figure out the printer's 101*7dd7cddfSDavid du Colombier * current state. Just helps convert strings representing the current state into 102*7dd7cddfSDavid du Colombier * integer codes that other routines use. 103*7dd7cddfSDavid du Colombier * 104*7dd7cddfSDavid du Colombier */ 105*7dd7cddfSDavid du Colombier 106*7dd7cddfSDavid du Colombier typedef struct { 107*7dd7cddfSDavid du Colombier char *state; /* printer's current status */ 108*7dd7cddfSDavid du Colombier int val; /* value returned by getstatus() */ 109*7dd7cddfSDavid du Colombier } Status; 110*7dd7cddfSDavid du Colombier 111*7dd7cddfSDavid du Colombier /* 112*7dd7cddfSDavid du Colombier * 113*7dd7cddfSDavid du Colombier * STATUS is used to initialize an array of type Status that translates the ASCII 114*7dd7cddfSDavid du Colombier * strings returned by the printer into appropriate codes that can be used later 115*7dd7cddfSDavid du Colombier * on in the program. getstatus() converts characters to lower case, so if you 116*7dd7cddfSDavid du Colombier * add any entries make them lower case and put them in before the UNKNOWN entry. 117*7dd7cddfSDavid du Colombier * The lookup terminates when we get a match or when an entry with a NULL state 118*7dd7cddfSDavid du Colombier * is found. 119*7dd7cddfSDavid du Colombier * 120*7dd7cddfSDavid du Colombier */ 121*7dd7cddfSDavid du Colombier 122*7dd7cddfSDavid du Colombier #define STATUS \ 123*7dd7cddfSDavid du Colombier \ 124*7dd7cddfSDavid du Colombier { \ 125*7dd7cddfSDavid du Colombier "busy", BUSY, \ 126*7dd7cddfSDavid du Colombier "waiting", WAITING, \ 127*7dd7cddfSDavid du Colombier "printing", PRINTING, \ 128*7dd7cddfSDavid du Colombier "idle", IDLE, \ 129*7dd7cddfSDavid du Colombier "endofjob", ENDOFJOB, \ 130*7dd7cddfSDavid du Colombier "printererror", PRINTERERROR, \ 131*7dd7cddfSDavid du Colombier "error", ERROR, \ 132*7dd7cddfSDavid du Colombier "flushing", FLUSHING, \ 133*7dd7cddfSDavid du Colombier "initializing", INITIALIZING, \ 134*7dd7cddfSDavid du Colombier NULL, UNKNOWN \ 135*7dd7cddfSDavid du Colombier } 136*7dd7cddfSDavid du Colombier 137*7dd7cddfSDavid du Colombier /* 138*7dd7cddfSDavid du Colombier * 139*7dd7cddfSDavid du Colombier * The baud rate can be set on the command line using the -b option. If you omit 140*7dd7cddfSDavid du Colombier * it BAUDRATE will be used. 141*7dd7cddfSDavid du Colombier * 142*7dd7cddfSDavid du Colombier */ 143*7dd7cddfSDavid du Colombier 144*7dd7cddfSDavid du Colombier #define BAUDRATE B9600 145*7dd7cddfSDavid du Colombier 146*7dd7cddfSDavid du Colombier /* 147*7dd7cddfSDavid du Colombier * 148*7dd7cddfSDavid du Colombier * An array of type Baud is used, in routine getbaud(), to translate ASCII strings 149*7dd7cddfSDavid du Colombier * into termio values that represent the requested baud rate. 150*7dd7cddfSDavid du Colombier * 151*7dd7cddfSDavid du Colombier */ 152*7dd7cddfSDavid du Colombier 153*7dd7cddfSDavid du Colombier typedef struct { 154*7dd7cddfSDavid du Colombier char *rate; /* string identifying the baud rate */ 155*7dd7cddfSDavid du Colombier short val; /* and its termio.h value */ 156*7dd7cddfSDavid du Colombier } Baud; 157*7dd7cddfSDavid du Colombier 158*7dd7cddfSDavid du Colombier /* 159*7dd7cddfSDavid du Colombier * 160*7dd7cddfSDavid du Colombier * BAUDTABLE initializes the array that's used to translate baud rate requests 161*7dd7cddfSDavid du Colombier * into termio values. It needs to end with an entry that has NULL assigned to 162*7dd7cddfSDavid du Colombier * the rate field. 163*7dd7cddfSDavid du Colombier * 164*7dd7cddfSDavid du Colombier */ 165*7dd7cddfSDavid du Colombier 166*7dd7cddfSDavid du Colombier #define BAUDTABLE \ 167*7dd7cddfSDavid du Colombier \ 168*7dd7cddfSDavid du Colombier { \ 169*7dd7cddfSDavid du Colombier "9600", B9600, \ 170*7dd7cddfSDavid du Colombier "B9600", B9600, \ 171*7dd7cddfSDavid du Colombier "19200", EXTA, \ 172*7dd7cddfSDavid du Colombier "19.2", EXTA, \ 173*7dd7cddfSDavid du Colombier "B19200", EXTA, \ 174*7dd7cddfSDavid du Colombier "EXTA", EXTA, \ 175*7dd7cddfSDavid du Colombier "1200", B1200, \ 176*7dd7cddfSDavid du Colombier "B1200", B1200, \ 177*7dd7cddfSDavid du Colombier "2400", B2400, \ 178*7dd7cddfSDavid du Colombier "B2400", B2400, \ 179*7dd7cddfSDavid du Colombier "B4800", B4800, \ 180*7dd7cddfSDavid du Colombier "4800", B4800, \ 181*7dd7cddfSDavid du Colombier "38400", EXTB, \ 182*7dd7cddfSDavid du Colombier "38.4", EXTB, \ 183*7dd7cddfSDavid du Colombier "B38400", EXTB, \ 184*7dd7cddfSDavid du Colombier "EXTB", EXTB, \ 185*7dd7cddfSDavid du Colombier NULL, B9600 \ 186*7dd7cddfSDavid du Colombier } 187*7dd7cddfSDavid du Colombier 188*7dd7cddfSDavid du Colombier /* 189*7dd7cddfSDavid du Colombier * 190*7dd7cddfSDavid du Colombier * A few miscellaneous definitions. BLOCKSIZE is the default size of the buffer 191*7dd7cddfSDavid du Colombier * used for reading the input files (changed with the -B option). MESGSIZE is the 192*7dd7cddfSDavid du Colombier * size of the character array used to store printer status lines - don't make it 193*7dd7cddfSDavid du Colombier * too small! 194*7dd7cddfSDavid du Colombier * 195*7dd7cddfSDavid du Colombier */ 196*7dd7cddfSDavid du Colombier 197*7dd7cddfSDavid du Colombier #define BLOCKSIZE 2048 198*7dd7cddfSDavid du Colombier #define MESGSIZE 512 199*7dd7cddfSDavid du Colombier 200*7dd7cddfSDavid du Colombier /* 201*7dd7cddfSDavid du Colombier * 202*7dd7cddfSDavid du Colombier * Some of the non-integer valued functions used in postio.c. 203*7dd7cddfSDavid du Colombier * 204*7dd7cddfSDavid du Colombier */ 205*7dd7cddfSDavid du Colombier 206*7dd7cddfSDavid du Colombier char *find(); 207*7dd7cddfSDavid du Colombier 208*7dd7cddfSDavid du Colombier char *malloc(); 209*7dd7cddfSDavid du Colombier char *strtok(); 210