Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
srohatgi01
GitHub Repository: srohatgi01/cups
Path: blob/master/monitor/bcp.c
1090 views
1
/*
2
* TBCP port monitor for CUPS.
3
*
4
* Copyright 2007-2014 by Apple Inc.
5
* Copyright 1993-2006 by Easy Software Products.
6
*
7
* Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8
*/
9
10
/*
11
* Include necessary headers...
12
*/
13
14
#include <cups/cups-private.h>
15
#include <cups/ppd.h>
16
17
18
/*
19
* Local functions...
20
*/
21
22
static char *psgets(char *buf, size_t *bytes, FILE *fp);
23
static ssize_t pswrite(const char *buf, size_t bytes);
24
25
26
/*
27
* 'main()' - Main entry...
28
*/
29
30
int /* O - Exit status */
31
main(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
{
47
_cupsLangPrintf(stderr,
48
_("Usage: %s job-id user title copies options [file]"),
49
argv[0]);
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
}
140
while (pswrite(line, linelen) > 0);
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
159
static char * /* O - String or NULL if EOF */
160
psgets(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
173
while ((size_t)(bufptr - buf) < len)
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
198
*bufptr++ = (char)ch;
199
}
200
201
/*
202
* Add a trailing newline if it is there...
203
*/
204
205
if (ch == '\n' || ch == '\r')
206
{
207
if ((size_t)(bufptr - buf) < len)
208
*bufptr++ = (char)ch;
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';
218
*bytes = (size_t)(bufptr - buf);
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
231
static ssize_t /* O - Number of bytes written */
232
pswrite(const char *buf, /* I - Buffer to write */
233
size_t bytes) /* I - Bytes to write */
234
{
235
size_t count; /* Remaining bytes */
236
237
238
for (count = bytes; count > 0; count --, buf ++)
239
switch (*buf)
240
{
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
252
case 0x01 : /* CTRL-A */
253
case 0x03 : /* CTRL-C */
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
271
return ((ssize_t)bytes);
272
}
273
274