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