xref: /aosp_15_r20/external/libcups/monitor/tbcp.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
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