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