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