1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * TBCP port monitor for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2014 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 1993-2006 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker */
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker */
13*5e7646d2SAndroid Build Coastguard Worker
14*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups-private.h>
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/ppd.h>
16*5e7646d2SAndroid Build Coastguard Worker
17*5e7646d2SAndroid Build Coastguard Worker
18*5e7646d2SAndroid Build Coastguard Worker /*
19*5e7646d2SAndroid Build Coastguard Worker * Local functions...
20*5e7646d2SAndroid Build Coastguard Worker */
21*5e7646d2SAndroid Build Coastguard Worker
22*5e7646d2SAndroid Build Coastguard Worker static char *psgets(char *buf, size_t *bytes, FILE *fp);
23*5e7646d2SAndroid Build Coastguard Worker static ssize_t pswrite(const char *buf, size_t bytes);
24*5e7646d2SAndroid Build Coastguard Worker
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker /*
27*5e7646d2SAndroid Build Coastguard Worker * 'main()' - Main entry...
28*5e7646d2SAndroid Build Coastguard Worker */
29*5e7646d2SAndroid Build Coastguard Worker
30*5e7646d2SAndroid Build Coastguard Worker int /* O - Exit status */
main(int argc,char * argv[])31*5e7646d2SAndroid Build Coastguard Worker main(int argc, /* I - Number of command-line args */
32*5e7646d2SAndroid Build Coastguard Worker char *argv[]) /* I - Command-line arguments */
33*5e7646d2SAndroid Build Coastguard Worker {
34*5e7646d2SAndroid Build Coastguard Worker FILE *fp; /* File to print */
35*5e7646d2SAndroid Build Coastguard Worker int copies; /* Number of copies left */
36*5e7646d2SAndroid Build Coastguard Worker char line[1024]; /* Line/buffer from stream/file */
37*5e7646d2SAndroid Build Coastguard Worker size_t linelen; /* Length of line */
38*5e7646d2SAndroid Build Coastguard Worker
39*5e7646d2SAndroid Build Coastguard Worker
40*5e7646d2SAndroid Build Coastguard Worker /*
41*5e7646d2SAndroid Build Coastguard Worker * Check command-line...
42*5e7646d2SAndroid Build Coastguard Worker */
43*5e7646d2SAndroid Build Coastguard Worker
44*5e7646d2SAndroid Build Coastguard Worker if (argc < 6 || argc > 7)
45*5e7646d2SAndroid Build Coastguard Worker {
46*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
47*5e7646d2SAndroid Build Coastguard Worker _("Usage: %s job-id user title copies options [file]"),
48*5e7646d2SAndroid Build Coastguard Worker argv[0]);
49*5e7646d2SAndroid Build Coastguard Worker return (1);
50*5e7646d2SAndroid Build Coastguard Worker }
51*5e7646d2SAndroid Build Coastguard Worker
52*5e7646d2SAndroid Build Coastguard Worker if (argc == 6)
53*5e7646d2SAndroid Build Coastguard Worker {
54*5e7646d2SAndroid Build Coastguard Worker copies = 1;
55*5e7646d2SAndroid Build Coastguard Worker fp = stdin;
56*5e7646d2SAndroid Build Coastguard Worker }
57*5e7646d2SAndroid Build Coastguard Worker else
58*5e7646d2SAndroid Build Coastguard Worker {
59*5e7646d2SAndroid Build Coastguard Worker copies = atoi(argv[4]);
60*5e7646d2SAndroid Build Coastguard Worker fp = fopen(argv[6], "rb");
61*5e7646d2SAndroid Build Coastguard Worker
62*5e7646d2SAndroid Build Coastguard Worker if (!fp)
63*5e7646d2SAndroid Build Coastguard Worker {
64*5e7646d2SAndroid Build Coastguard Worker perror(argv[6]);
65*5e7646d2SAndroid Build Coastguard Worker return (1);
66*5e7646d2SAndroid Build Coastguard Worker }
67*5e7646d2SAndroid Build Coastguard Worker }
68*5e7646d2SAndroid Build Coastguard Worker
69*5e7646d2SAndroid Build Coastguard Worker /*
70*5e7646d2SAndroid Build Coastguard Worker * Copy the print file to stdout...
71*5e7646d2SAndroid Build Coastguard Worker */
72*5e7646d2SAndroid Build Coastguard Worker
73*5e7646d2SAndroid Build Coastguard Worker while (copies > 0)
74*5e7646d2SAndroid Build Coastguard Worker {
75*5e7646d2SAndroid Build Coastguard Worker copies --;
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker /*
78*5e7646d2SAndroid Build Coastguard Worker * Read the first line...
79*5e7646d2SAndroid Build Coastguard Worker */
80*5e7646d2SAndroid Build Coastguard Worker
81*5e7646d2SAndroid Build Coastguard Worker linelen = sizeof(line);
82*5e7646d2SAndroid Build Coastguard Worker if (!psgets(line, &linelen, fp))
83*5e7646d2SAndroid Build Coastguard Worker break;
84*5e7646d2SAndroid Build Coastguard Worker
85*5e7646d2SAndroid Build Coastguard Worker /*
86*5e7646d2SAndroid Build Coastguard Worker * Handle leading PJL fun...
87*5e7646d2SAndroid Build Coastguard Worker */
88*5e7646d2SAndroid Build Coastguard Worker
89*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(line, "\033%-12345X", 9) || !strncmp(line, "@PJL ", 5))
90*5e7646d2SAndroid Build Coastguard Worker {
91*5e7646d2SAndroid Build Coastguard Worker /*
92*5e7646d2SAndroid Build Coastguard Worker * Yup, we have leading PJL fun, so copy it until we hit a line
93*5e7646d2SAndroid Build Coastguard Worker * with "ENTER LANGUAGE"...
94*5e7646d2SAndroid Build Coastguard Worker */
95*5e7646d2SAndroid Build Coastguard Worker
96*5e7646d2SAndroid Build Coastguard Worker while (strstr(line, "ENTER LANGUAGE") == NULL)
97*5e7646d2SAndroid Build Coastguard Worker {
98*5e7646d2SAndroid Build Coastguard Worker fwrite(line, 1, linelen, stdout);
99*5e7646d2SAndroid Build Coastguard Worker
100*5e7646d2SAndroid Build Coastguard Worker linelen = sizeof(line);
101*5e7646d2SAndroid Build Coastguard Worker if (psgets(line, &linelen, fp) == NULL)
102*5e7646d2SAndroid Build Coastguard Worker break;
103*5e7646d2SAndroid Build Coastguard Worker }
104*5e7646d2SAndroid Build Coastguard Worker }
105*5e7646d2SAndroid Build Coastguard Worker else
106*5e7646d2SAndroid Build Coastguard Worker {
107*5e7646d2SAndroid Build Coastguard Worker /*
108*5e7646d2SAndroid Build Coastguard Worker * No PJL stuff, just add the UEL...
109*5e7646d2SAndroid Build Coastguard Worker */
110*5e7646d2SAndroid Build Coastguard Worker
111*5e7646d2SAndroid Build Coastguard Worker fputs("\033%-12345X", stdout);
112*5e7646d2SAndroid Build Coastguard Worker }
113*5e7646d2SAndroid Build Coastguard Worker
114*5e7646d2SAndroid Build Coastguard Worker /*
115*5e7646d2SAndroid Build Coastguard Worker * Switch to TBCP mode...
116*5e7646d2SAndroid Build Coastguard Worker */
117*5e7646d2SAndroid Build Coastguard Worker
118*5e7646d2SAndroid Build Coastguard Worker fputs("\001M", stdout);
119*5e7646d2SAndroid Build Coastguard Worker
120*5e7646d2SAndroid Build Coastguard Worker /*
121*5e7646d2SAndroid Build Coastguard Worker * Loop until we see end-of-file...
122*5e7646d2SAndroid Build Coastguard Worker */
123*5e7646d2SAndroid Build Coastguard Worker
124*5e7646d2SAndroid Build Coastguard Worker while (pswrite(line, linelen) > 0)
125*5e7646d2SAndroid Build Coastguard Worker {
126*5e7646d2SAndroid Build Coastguard Worker linelen = sizeof(line);
127*5e7646d2SAndroid Build Coastguard Worker if (psgets(line, &linelen, fp) == NULL)
128*5e7646d2SAndroid Build Coastguard Worker break;
129*5e7646d2SAndroid Build Coastguard Worker }
130*5e7646d2SAndroid Build Coastguard Worker
131*5e7646d2SAndroid Build Coastguard Worker fflush(stdout);
132*5e7646d2SAndroid Build Coastguard Worker }
133*5e7646d2SAndroid Build Coastguard Worker
134*5e7646d2SAndroid Build Coastguard Worker return (0);
135*5e7646d2SAndroid Build Coastguard Worker }
136*5e7646d2SAndroid Build Coastguard Worker
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker /*
139*5e7646d2SAndroid Build Coastguard Worker * 'psgets()' - Get a line from a file.
140*5e7646d2SAndroid Build Coastguard Worker *
141*5e7646d2SAndroid Build Coastguard Worker * Note:
142*5e7646d2SAndroid Build Coastguard Worker *
143*5e7646d2SAndroid Build Coastguard Worker * This function differs from the gets() function in that it
144*5e7646d2SAndroid Build Coastguard Worker * handles any combination of CR, LF, or CR LF to end input
145*5e7646d2SAndroid Build Coastguard Worker * lines.
146*5e7646d2SAndroid Build Coastguard Worker */
147*5e7646d2SAndroid Build Coastguard Worker
148*5e7646d2SAndroid Build Coastguard Worker static char * /* O - String or NULL if EOF */
psgets(char * buf,size_t * bytes,FILE * fp)149*5e7646d2SAndroid Build Coastguard Worker psgets(char *buf, /* I - Buffer to read into */
150*5e7646d2SAndroid Build Coastguard Worker size_t *bytes, /* IO - Length of buffer */
151*5e7646d2SAndroid Build Coastguard Worker FILE *fp) /* I - File to read from */
152*5e7646d2SAndroid Build Coastguard Worker {
153*5e7646d2SAndroid Build Coastguard Worker char *bufptr; /* Pointer into buffer */
154*5e7646d2SAndroid Build Coastguard Worker int ch; /* Character from file */
155*5e7646d2SAndroid Build Coastguard Worker size_t len; /* Max length of string */
156*5e7646d2SAndroid Build Coastguard Worker
157*5e7646d2SAndroid Build Coastguard Worker
158*5e7646d2SAndroid Build Coastguard Worker len = *bytes - 1;
159*5e7646d2SAndroid Build Coastguard Worker bufptr = buf;
160*5e7646d2SAndroid Build Coastguard Worker ch = EOF;
161*5e7646d2SAndroid Build Coastguard Worker
162*5e7646d2SAndroid Build Coastguard Worker while ((size_t)(bufptr - buf) < len)
163*5e7646d2SAndroid Build Coastguard Worker {
164*5e7646d2SAndroid Build Coastguard Worker if ((ch = getc(fp)) == EOF)
165*5e7646d2SAndroid Build Coastguard Worker break;
166*5e7646d2SAndroid Build Coastguard Worker
167*5e7646d2SAndroid Build Coastguard Worker if (ch == '\r')
168*5e7646d2SAndroid Build Coastguard Worker {
169*5e7646d2SAndroid Build Coastguard Worker /*
170*5e7646d2SAndroid Build Coastguard Worker * Got a CR; see if there is a LF as well...
171*5e7646d2SAndroid Build Coastguard Worker */
172*5e7646d2SAndroid Build Coastguard Worker
173*5e7646d2SAndroid Build Coastguard Worker ch = getc(fp);
174*5e7646d2SAndroid Build Coastguard Worker
175*5e7646d2SAndroid Build Coastguard Worker if (ch != EOF && ch != '\n')
176*5e7646d2SAndroid Build Coastguard Worker {
177*5e7646d2SAndroid Build Coastguard Worker ungetc(ch, fp); /* Nope, save it for later... */
178*5e7646d2SAndroid Build Coastguard Worker ch = '\r';
179*5e7646d2SAndroid Build Coastguard Worker }
180*5e7646d2SAndroid Build Coastguard Worker else
181*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\r';
182*5e7646d2SAndroid Build Coastguard Worker break;
183*5e7646d2SAndroid Build Coastguard Worker }
184*5e7646d2SAndroid Build Coastguard Worker else if (ch == '\n')
185*5e7646d2SAndroid Build Coastguard Worker break;
186*5e7646d2SAndroid Build Coastguard Worker else
187*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (char)ch;
188*5e7646d2SAndroid Build Coastguard Worker }
189*5e7646d2SAndroid Build Coastguard Worker
190*5e7646d2SAndroid Build Coastguard Worker /*
191*5e7646d2SAndroid Build Coastguard Worker * Add a trailing newline if it is there...
192*5e7646d2SAndroid Build Coastguard Worker */
193*5e7646d2SAndroid Build Coastguard Worker
194*5e7646d2SAndroid Build Coastguard Worker if (ch == '\n' || ch == '\r')
195*5e7646d2SAndroid Build Coastguard Worker {
196*5e7646d2SAndroid Build Coastguard Worker if ((size_t)(bufptr - buf) < len)
197*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (char)ch;
198*5e7646d2SAndroid Build Coastguard Worker else
199*5e7646d2SAndroid Build Coastguard Worker ungetc(ch, fp);
200*5e7646d2SAndroid Build Coastguard Worker }
201*5e7646d2SAndroid Build Coastguard Worker
202*5e7646d2SAndroid Build Coastguard Worker /*
203*5e7646d2SAndroid Build Coastguard Worker * Nul-terminate the string and return it (or NULL for EOF).
204*5e7646d2SAndroid Build Coastguard Worker */
205*5e7646d2SAndroid Build Coastguard Worker
206*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
207*5e7646d2SAndroid Build Coastguard Worker *bytes = (size_t)(bufptr - buf);
208*5e7646d2SAndroid Build Coastguard Worker
209*5e7646d2SAndroid Build Coastguard Worker if (ch == EOF && bufptr == buf)
210*5e7646d2SAndroid Build Coastguard Worker return (NULL);
211*5e7646d2SAndroid Build Coastguard Worker else
212*5e7646d2SAndroid Build Coastguard Worker return (buf);
213*5e7646d2SAndroid Build Coastguard Worker }
214*5e7646d2SAndroid Build Coastguard Worker
215*5e7646d2SAndroid Build Coastguard Worker
216*5e7646d2SAndroid Build Coastguard Worker /*
217*5e7646d2SAndroid Build Coastguard Worker * 'pswrite()' - Write data from a file.
218*5e7646d2SAndroid Build Coastguard Worker */
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Number of bytes written */
pswrite(const char * buf,size_t bytes)221*5e7646d2SAndroid Build Coastguard Worker pswrite(const char *buf, /* I - Buffer to write */
222*5e7646d2SAndroid Build Coastguard Worker size_t bytes) /* I - Bytes to write */
223*5e7646d2SAndroid Build Coastguard Worker {
224*5e7646d2SAndroid Build Coastguard Worker size_t count; /* Remaining bytes */
225*5e7646d2SAndroid Build Coastguard Worker
226*5e7646d2SAndroid Build Coastguard Worker
227*5e7646d2SAndroid Build Coastguard Worker for (count = bytes; count > 0; count --, buf ++)
228*5e7646d2SAndroid Build Coastguard Worker switch (*buf)
229*5e7646d2SAndroid Build Coastguard Worker {
230*5e7646d2SAndroid Build Coastguard Worker case 0x04 : /* CTRL-D */
231*5e7646d2SAndroid Build Coastguard Worker if (bytes == 1)
232*5e7646d2SAndroid Build Coastguard Worker {
233*5e7646d2SAndroid Build Coastguard Worker /*
234*5e7646d2SAndroid Build Coastguard Worker * Don't quote the last CTRL-D...
235*5e7646d2SAndroid Build Coastguard Worker */
236*5e7646d2SAndroid Build Coastguard Worker
237*5e7646d2SAndroid Build Coastguard Worker putchar(0x04);
238*5e7646d2SAndroid Build Coastguard Worker break;
239*5e7646d2SAndroid Build Coastguard Worker }
240*5e7646d2SAndroid Build Coastguard Worker
241*5e7646d2SAndroid Build Coastguard Worker case 0x01 : /* CTRL-A */
242*5e7646d2SAndroid Build Coastguard Worker case 0x03 : /* CTRL-C */
243*5e7646d2SAndroid Build Coastguard Worker case 0x05 : /* CTRL-E */
244*5e7646d2SAndroid Build Coastguard Worker case 0x11 : /* CTRL-Q */
245*5e7646d2SAndroid Build Coastguard Worker case 0x13 : /* CTRL-S */
246*5e7646d2SAndroid Build Coastguard Worker case 0x14 : /* CTRL-T */
247*5e7646d2SAndroid Build Coastguard Worker case 0x1b : /* CTRL-[ (aka ESC) */
248*5e7646d2SAndroid Build Coastguard Worker case 0x1c : /* CTRL-\ */
249*5e7646d2SAndroid Build Coastguard Worker if (putchar(0x01) < 0)
250*5e7646d2SAndroid Build Coastguard Worker return (-1);
251*5e7646d2SAndroid Build Coastguard Worker if (putchar(*buf ^ 0x40) < 0)
252*5e7646d2SAndroid Build Coastguard Worker return (-1);
253*5e7646d2SAndroid Build Coastguard Worker break;
254*5e7646d2SAndroid Build Coastguard Worker
255*5e7646d2SAndroid Build Coastguard Worker default :
256*5e7646d2SAndroid Build Coastguard Worker if (putchar(*buf) < 0)
257*5e7646d2SAndroid Build Coastguard Worker return (-1);
258*5e7646d2SAndroid Build Coastguard Worker break;
259*5e7646d2SAndroid Build Coastguard Worker }
260*5e7646d2SAndroid Build Coastguard Worker
261*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)bytes);
262*5e7646d2SAndroid Build Coastguard Worker }
263