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