xref: /aosp_15_r20/external/libcups/monitor/bcp.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   ppd_file_t	*ppd;			/* PPD file */
39*5e7646d2SAndroid Build Coastguard Worker 
40*5e7646d2SAndroid Build Coastguard Worker 
41*5e7646d2SAndroid Build Coastguard Worker  /*
42*5e7646d2SAndroid Build Coastguard Worker   * Check command-line...
43*5e7646d2SAndroid Build Coastguard Worker   */
44*5e7646d2SAndroid Build Coastguard Worker 
45*5e7646d2SAndroid Build Coastguard Worker   if (argc < 6 || argc > 7)
46*5e7646d2SAndroid Build Coastguard Worker   {
47*5e7646d2SAndroid Build Coastguard Worker     _cupsLangPrintf(stderr,
48*5e7646d2SAndroid Build Coastguard Worker                     _("Usage: %s job-id user title copies options [file]"),
49*5e7646d2SAndroid Build Coastguard Worker 		    argv[0]);
50*5e7646d2SAndroid Build Coastguard Worker     return (1);
51*5e7646d2SAndroid Build Coastguard Worker   }
52*5e7646d2SAndroid Build Coastguard Worker 
53*5e7646d2SAndroid Build Coastguard Worker   if (argc == 6)
54*5e7646d2SAndroid Build Coastguard Worker   {
55*5e7646d2SAndroid Build Coastguard Worker     copies = 1;
56*5e7646d2SAndroid Build Coastguard Worker     fp     = stdin;
57*5e7646d2SAndroid Build Coastguard Worker   }
58*5e7646d2SAndroid Build Coastguard Worker   else
59*5e7646d2SAndroid Build Coastguard Worker   {
60*5e7646d2SAndroid Build Coastguard Worker     copies = atoi(argv[4]);
61*5e7646d2SAndroid Build Coastguard Worker     fp     = fopen(argv[6], "rb");
62*5e7646d2SAndroid Build Coastguard Worker 
63*5e7646d2SAndroid Build Coastguard Worker     if (!fp)
64*5e7646d2SAndroid Build Coastguard Worker     {
65*5e7646d2SAndroid Build Coastguard Worker       perror(argv[6]);
66*5e7646d2SAndroid Build Coastguard Worker       return (1);
67*5e7646d2SAndroid Build Coastguard Worker     }
68*5e7646d2SAndroid Build Coastguard Worker   }
69*5e7646d2SAndroid Build Coastguard Worker 
70*5e7646d2SAndroid Build Coastguard Worker  /*
71*5e7646d2SAndroid Build Coastguard Worker   * Open the PPD file as needed...
72*5e7646d2SAndroid Build Coastguard Worker   */
73*5e7646d2SAndroid Build Coastguard Worker 
74*5e7646d2SAndroid Build Coastguard Worker   ppd = ppdOpenFile(getenv("PPD"));
75*5e7646d2SAndroid Build Coastguard Worker 
76*5e7646d2SAndroid Build Coastguard Worker  /*
77*5e7646d2SAndroid Build Coastguard Worker   * Copy the print file to stdout...
78*5e7646d2SAndroid Build Coastguard Worker   */
79*5e7646d2SAndroid Build Coastguard Worker 
80*5e7646d2SAndroid Build Coastguard Worker   while (copies > 0)
81*5e7646d2SAndroid Build Coastguard Worker   {
82*5e7646d2SAndroid Build Coastguard Worker     copies --;
83*5e7646d2SAndroid Build Coastguard Worker 
84*5e7646d2SAndroid Build Coastguard Worker     if (ppd && ppd->jcl_begin)
85*5e7646d2SAndroid Build Coastguard Worker       fputs(ppd->jcl_begin, stdout);
86*5e7646d2SAndroid Build Coastguard Worker     if (ppd && ppd->jcl_ps)
87*5e7646d2SAndroid Build Coastguard Worker       fputs(ppd->jcl_ps, stdout);
88*5e7646d2SAndroid Build Coastguard Worker 
89*5e7646d2SAndroid Build Coastguard Worker     if (!ppd || ppd->language_level == 1)
90*5e7646d2SAndroid Build Coastguard Worker     {
91*5e7646d2SAndroid Build Coastguard Worker      /*
92*5e7646d2SAndroid Build Coastguard Worker       * Use setsoftwareiomode for BCP mode...
93*5e7646d2SAndroid Build Coastguard Worker       */
94*5e7646d2SAndroid Build Coastguard Worker 
95*5e7646d2SAndroid Build Coastguard Worker       puts("%!PS-Adobe-3.0 ExitServer");
96*5e7646d2SAndroid Build Coastguard Worker       puts("%%Title: (BCP - Level 1)");
97*5e7646d2SAndroid Build Coastguard Worker       puts("%%EndComments");
98*5e7646d2SAndroid Build Coastguard Worker       puts("%%BeginExitServer: 0");
99*5e7646d2SAndroid Build Coastguard Worker       puts("serverdict begin 0 exitserver");
100*5e7646d2SAndroid Build Coastguard Worker       puts("%%EndExitServer");
101*5e7646d2SAndroid Build Coastguard Worker       puts("statusdict begin");
102*5e7646d2SAndroid Build Coastguard Worker       puts("/setsoftwareiomode known {100 setsoftwareiomode}");
103*5e7646d2SAndroid Build Coastguard Worker       puts("end");
104*5e7646d2SAndroid Build Coastguard Worker       puts("%EOF");
105*5e7646d2SAndroid Build Coastguard Worker     }
106*5e7646d2SAndroid Build Coastguard Worker     else
107*5e7646d2SAndroid Build Coastguard Worker     {
108*5e7646d2SAndroid Build Coastguard Worker      /*
109*5e7646d2SAndroid Build Coastguard Worker       * Use setdevparams for BCP mode...
110*5e7646d2SAndroid Build Coastguard Worker       */
111*5e7646d2SAndroid Build Coastguard Worker 
112*5e7646d2SAndroid Build Coastguard Worker       puts("%!PS-Adobe-3.0");
113*5e7646d2SAndroid Build Coastguard Worker       puts("%%Title: (BCP - Level 2)");
114*5e7646d2SAndroid Build Coastguard Worker       puts("%%EndComments");
115*5e7646d2SAndroid Build Coastguard Worker       puts("currentsysparams");
116*5e7646d2SAndroid Build Coastguard Worker       puts("/CurInputDevice 2 copy known {");
117*5e7646d2SAndroid Build Coastguard Worker       puts("get");
118*5e7646d2SAndroid Build Coastguard Worker       puts("<</Protocol /Binary>> setdevparams");
119*5e7646d2SAndroid Build Coastguard Worker       puts("}{");
120*5e7646d2SAndroid Build Coastguard Worker       puts("pop pop");
121*5e7646d2SAndroid Build Coastguard Worker       puts("} ifelse");
122*5e7646d2SAndroid Build Coastguard Worker       puts("%EOF");
123*5e7646d2SAndroid Build Coastguard Worker     }
124*5e7646d2SAndroid Build Coastguard Worker 
125*5e7646d2SAndroid Build Coastguard Worker     if (ppd && ppd->jcl_end)
126*5e7646d2SAndroid Build Coastguard Worker       fputs(ppd->jcl_end, stdout);
127*5e7646d2SAndroid Build Coastguard Worker     else if (!ppd || ppd->num_filters == 0)
128*5e7646d2SAndroid Build Coastguard Worker       putchar(0x04);
129*5e7646d2SAndroid Build Coastguard Worker 
130*5e7646d2SAndroid Build Coastguard Worker    /*
131*5e7646d2SAndroid Build Coastguard Worker     * Loop until we see end-of-file...
132*5e7646d2SAndroid Build Coastguard Worker     */
133*5e7646d2SAndroid Build Coastguard Worker 
134*5e7646d2SAndroid Build Coastguard Worker     do
135*5e7646d2SAndroid Build Coastguard Worker     {
136*5e7646d2SAndroid Build Coastguard Worker       linelen = sizeof(line);
137*5e7646d2SAndroid Build Coastguard Worker       if (psgets(line, &linelen, fp) == NULL)
138*5e7646d2SAndroid Build Coastguard Worker 	break;
139*5e7646d2SAndroid Build Coastguard Worker     }
140*5e7646d2SAndroid Build Coastguard Worker     while (pswrite(line, linelen) > 0);
141*5e7646d2SAndroid Build Coastguard Worker 
142*5e7646d2SAndroid Build Coastguard Worker     fflush(stdout);
143*5e7646d2SAndroid Build Coastguard Worker   }
144*5e7646d2SAndroid Build Coastguard Worker 
145*5e7646d2SAndroid Build Coastguard Worker   return (0);
146*5e7646d2SAndroid Build Coastguard Worker }
147*5e7646d2SAndroid Build Coastguard Worker 
148*5e7646d2SAndroid Build Coastguard Worker 
149*5e7646d2SAndroid Build Coastguard Worker /*
150*5e7646d2SAndroid Build Coastguard Worker  * 'psgets()' - Get a line from a file.
151*5e7646d2SAndroid Build Coastguard Worker  *
152*5e7646d2SAndroid Build Coastguard Worker  * Note:
153*5e7646d2SAndroid Build Coastguard Worker  *
154*5e7646d2SAndroid Build Coastguard Worker  *   This function differs from the gets() function in that it
155*5e7646d2SAndroid Build Coastguard Worker  *   handles any combination of CR, LF, or CR LF to end input
156*5e7646d2SAndroid Build Coastguard Worker  *   lines.
157*5e7646d2SAndroid Build Coastguard Worker  */
158*5e7646d2SAndroid Build Coastguard Worker 
159*5e7646d2SAndroid Build Coastguard Worker static char *				/* O  - String or NULL if EOF */
psgets(char * buf,size_t * bytes,FILE * fp)160*5e7646d2SAndroid Build Coastguard Worker psgets(char   *buf,			/* I  - Buffer to read into */
161*5e7646d2SAndroid Build Coastguard Worker        size_t *bytes,			/* IO - Length of buffer */
162*5e7646d2SAndroid Build Coastguard Worker        FILE   *fp)			/* I  - File to read from */
163*5e7646d2SAndroid Build Coastguard Worker {
164*5e7646d2SAndroid Build Coastguard Worker   char		*bufptr;		/* Pointer into buffer */
165*5e7646d2SAndroid Build Coastguard Worker   int		ch;			/* Character from file */
166*5e7646d2SAndroid Build Coastguard Worker   size_t	len;			/* Max length of string */
167*5e7646d2SAndroid Build Coastguard Worker 
168*5e7646d2SAndroid Build Coastguard Worker 
169*5e7646d2SAndroid Build Coastguard Worker   len    = *bytes - 1;
170*5e7646d2SAndroid Build Coastguard Worker   bufptr = buf;
171*5e7646d2SAndroid Build Coastguard Worker   ch     = EOF;
172*5e7646d2SAndroid Build Coastguard Worker 
173*5e7646d2SAndroid Build Coastguard Worker   while ((size_t)(bufptr - buf) < len)
174*5e7646d2SAndroid Build Coastguard Worker   {
175*5e7646d2SAndroid Build Coastguard Worker     if ((ch = getc(fp)) == EOF)
176*5e7646d2SAndroid Build Coastguard Worker       break;
177*5e7646d2SAndroid Build Coastguard Worker 
178*5e7646d2SAndroid Build Coastguard Worker     if (ch == '\r')
179*5e7646d2SAndroid Build Coastguard Worker     {
180*5e7646d2SAndroid Build Coastguard Worker      /*
181*5e7646d2SAndroid Build Coastguard Worker       * Got a CR; see if there is a LF as well...
182*5e7646d2SAndroid Build Coastguard Worker       */
183*5e7646d2SAndroid Build Coastguard Worker 
184*5e7646d2SAndroid Build Coastguard Worker       ch = getc(fp);
185*5e7646d2SAndroid Build Coastguard Worker 
186*5e7646d2SAndroid Build Coastguard Worker       if (ch != EOF && ch != '\n')
187*5e7646d2SAndroid Build Coastguard Worker       {
188*5e7646d2SAndroid Build Coastguard Worker         ungetc(ch, fp);	/* Nope, save it for later... */
189*5e7646d2SAndroid Build Coastguard Worker         ch = '\r';
190*5e7646d2SAndroid Build Coastguard Worker       }
191*5e7646d2SAndroid Build Coastguard Worker       else
192*5e7646d2SAndroid Build Coastguard Worker         *bufptr++ = '\r';
193*5e7646d2SAndroid Build Coastguard Worker       break;
194*5e7646d2SAndroid Build Coastguard Worker     }
195*5e7646d2SAndroid Build Coastguard Worker     else if (ch == '\n')
196*5e7646d2SAndroid Build Coastguard Worker       break;
197*5e7646d2SAndroid Build Coastguard Worker     else
198*5e7646d2SAndroid Build Coastguard Worker       *bufptr++ = (char)ch;
199*5e7646d2SAndroid Build Coastguard Worker   }
200*5e7646d2SAndroid Build Coastguard Worker 
201*5e7646d2SAndroid Build Coastguard Worker  /*
202*5e7646d2SAndroid Build Coastguard Worker   * Add a trailing newline if it is there...
203*5e7646d2SAndroid Build Coastguard Worker   */
204*5e7646d2SAndroid Build Coastguard Worker 
205*5e7646d2SAndroid Build Coastguard Worker   if (ch == '\n' || ch == '\r')
206*5e7646d2SAndroid Build Coastguard Worker   {
207*5e7646d2SAndroid Build Coastguard Worker     if ((size_t)(bufptr - buf) < len)
208*5e7646d2SAndroid Build Coastguard Worker       *bufptr++ = (char)ch;
209*5e7646d2SAndroid Build Coastguard Worker     else
210*5e7646d2SAndroid Build Coastguard Worker       ungetc(ch, fp);
211*5e7646d2SAndroid Build Coastguard Worker   }
212*5e7646d2SAndroid Build Coastguard Worker 
213*5e7646d2SAndroid Build Coastguard Worker  /*
214*5e7646d2SAndroid Build Coastguard Worker   * Nul-terminate the string and return it (or NULL for EOF).
215*5e7646d2SAndroid Build Coastguard Worker   */
216*5e7646d2SAndroid Build Coastguard Worker 
217*5e7646d2SAndroid Build Coastguard Worker   *bufptr = '\0';
218*5e7646d2SAndroid Build Coastguard Worker   *bytes  = (size_t)(bufptr - buf);
219*5e7646d2SAndroid Build Coastguard Worker 
220*5e7646d2SAndroid Build Coastguard Worker   if (ch == EOF && bufptr == buf)
221*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
222*5e7646d2SAndroid Build Coastguard Worker   else
223*5e7646d2SAndroid Build Coastguard Worker     return (buf);
224*5e7646d2SAndroid Build Coastguard Worker }
225*5e7646d2SAndroid Build Coastguard Worker 
226*5e7646d2SAndroid Build Coastguard Worker 
227*5e7646d2SAndroid Build Coastguard Worker /*
228*5e7646d2SAndroid Build Coastguard Worker  * 'pswrite()' - Write data from a file.
229*5e7646d2SAndroid Build Coastguard Worker  */
230*5e7646d2SAndroid Build Coastguard Worker 
231*5e7646d2SAndroid Build Coastguard Worker static ssize_t				/* O - Number of bytes written */
pswrite(const char * buf,size_t bytes)232*5e7646d2SAndroid Build Coastguard Worker pswrite(const char *buf,		/* I - Buffer to write */
233*5e7646d2SAndroid Build Coastguard Worker         size_t     bytes)		/* I - Bytes to write */
234*5e7646d2SAndroid Build Coastguard Worker {
235*5e7646d2SAndroid Build Coastguard Worker   size_t	count;			/* Remaining bytes */
236*5e7646d2SAndroid Build Coastguard Worker 
237*5e7646d2SAndroid Build Coastguard Worker 
238*5e7646d2SAndroid Build Coastguard Worker   for (count = bytes; count > 0; count --, buf ++)
239*5e7646d2SAndroid Build Coastguard Worker     switch (*buf)
240*5e7646d2SAndroid Build Coastguard Worker     {
241*5e7646d2SAndroid Build Coastguard Worker       case 0x04 : /* CTRL-D */
242*5e7646d2SAndroid Build Coastguard Worker           if (bytes == 1)
243*5e7646d2SAndroid Build Coastguard Worker 	  {
244*5e7646d2SAndroid Build Coastguard Worker 	   /*
245*5e7646d2SAndroid Build Coastguard Worker 	    * Don't quote the last CTRL-D...
246*5e7646d2SAndroid Build Coastguard Worker 	    */
247*5e7646d2SAndroid Build Coastguard Worker 
248*5e7646d2SAndroid Build Coastguard Worker 	    putchar(0x04);
249*5e7646d2SAndroid Build Coastguard Worker 	    break;
250*5e7646d2SAndroid Build Coastguard Worker 	  }
251*5e7646d2SAndroid Build Coastguard Worker 
252*5e7646d2SAndroid Build Coastguard Worker       case 0x01 : /* CTRL-A */
253*5e7646d2SAndroid Build Coastguard Worker       case 0x03 : /* CTRL-C */
254*5e7646d2SAndroid Build Coastguard Worker       case 0x05 : /* CTRL-E */
255*5e7646d2SAndroid Build Coastguard Worker       case 0x11 : /* CTRL-Q */
256*5e7646d2SAndroid Build Coastguard Worker       case 0x13 : /* CTRL-S */
257*5e7646d2SAndroid Build Coastguard Worker       case 0x14 : /* CTRL-T */
258*5e7646d2SAndroid Build Coastguard Worker       case 0x1c : /* CTRL-\ */
259*5e7646d2SAndroid Build Coastguard Worker 	  if (putchar(0x01) < 0)
260*5e7646d2SAndroid Build Coastguard Worker 	    return (-1);
261*5e7646d2SAndroid Build Coastguard Worker 	  if (putchar(*buf ^ 0x40) < 0)
262*5e7646d2SAndroid Build Coastguard Worker 	    return (-1);
263*5e7646d2SAndroid Build Coastguard Worker 	  break;
264*5e7646d2SAndroid Build Coastguard Worker 
265*5e7646d2SAndroid Build Coastguard Worker       default :
266*5e7646d2SAndroid Build Coastguard Worker 	  if (putchar(*buf) < 0)
267*5e7646d2SAndroid Build Coastguard Worker 	    return (-1);
268*5e7646d2SAndroid Build Coastguard Worker 	  break;
269*5e7646d2SAndroid Build Coastguard Worker     }
270*5e7646d2SAndroid Build Coastguard Worker 
271*5e7646d2SAndroid Build Coastguard Worker   return ((ssize_t)bytes);
272*5e7646d2SAndroid Build Coastguard Worker }
273