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