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