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