]> git.ipfire.org Git - thirdparty/cups.git/blame - monitor/tbcp.c
Full sweep of all Clang warnings, plus some bug fixes for incorrect memcpy usage.
[thirdparty/cups.git] / monitor / tbcp.c
CommitLineData
bd7854cb 1/*
f2d18633 2 * "$Id$"
bd7854cb 3 *
7e86f2f6 4 * TBCP port monitor for CUPS.
bd7854cb 5 *
7e86f2f6
MS
6 * Copyright 2007-2014 by Apple Inc.
7 * Copyright 1993-2006 by Easy Software Products.
bd7854cb 8 *
7e86f2f6
MS
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/".
bd7854cb 14 *
7e86f2f6 15 * This file is subject to the Apple OS-Developed Software exception.
bd7854cb 16 */
17
18/*
19 * Include necessary headers...
20 */
21
0837b7e8 22#include <cups/cups-private.h>
aaf19ab0 23#include <cups/ppd.h>
bd7854cb 24
25
26/*
27 * Local functions...
28 */
29
30static char *psgets(char *buf, size_t *bytes, FILE *fp);
7e86f2f6 31static ssize_t pswrite(const char *buf, size_t bytes);
bd7854cb 32
33
34/*
35 * 'main()' - Main entry...
36 */
37
38int /* O - Exit status */
39main(int argc, /* I - Number of command-line args */
40 char *argv[]) /* I - Command-line arguments */
41{
42 FILE *fp; /* File to print */
43 int copies; /* Number of copies left */
44 char line[1024]; /* Line/buffer from stream/file */
45 size_t linelen; /* Length of line */
46
47
48 /*
49 * Check command-line...
50 */
51
52 if (argc < 6 || argc > 7)
53 {
0837b7e8
MS
54 _cupsLangPrintf(stderr,
55 _("Usage: %s job-id user title copies options [file]"),
56 argv[0]);
bd7854cb 57 return (1);
58 }
59
60 if (argc == 6)
61 {
62 copies = 1;
63 fp = stdin;
64 }
65 else
66 {
67 copies = atoi(argv[4]);
68 fp = fopen(argv[6], "rb");
69
70 if (!fp)
71 {
72 perror(argv[6]);
73 return (1);
74 }
75 }
76
77 /*
78 * Copy the print file to stdout...
79 */
80
81 while (copies > 0)
82 {
83 copies --;
84
85 /*
86 * Read the first line...
87 */
88
89 linelen = sizeof(line);
a469f8a5
MS
90 if (!psgets(line, &linelen, fp))
91 break;
bd7854cb 92
93 /*
94 * Handle leading PJL fun...
95 */
96
97 if (!strncmp(line, "\033%-12345X", 9) || !strncmp(line, "@PJL ", 5))
98 {
99 /*
100 * Yup, we have leading PJL fun, so copy it until we hit a line
101 * with "ENTER LANGUAGE"...
102 */
103
104 while (strstr(line, "ENTER LANGUAGE") == NULL)
105 {
106 fwrite(line, 1, linelen, stdout);
107
108 linelen = sizeof(line);
109 if (psgets(line, &linelen, fp) == NULL)
110 break;
111 }
112 }
113 else
114 {
115 /*
db1f069b 116 * No PJL stuff, just add the UEL...
bd7854cb 117 */
118
db1f069b 119 fputs("\033%-12345X", stdout);
bd7854cb 120 }
121
122 /*
123 * Switch to TBCP mode...
124 */
125
126 fputs("\001M", stdout);
127
128 /*
129 * Loop until we see end-of-file...
130 */
131
7e86f2f6 132 while (pswrite(line, linelen) > 0)
bd7854cb 133 {
134 linelen = sizeof(line);
135 if (psgets(line, &linelen, fp) == NULL)
136 break;
137 }
138
139 fflush(stdout);
140 }
141
142 return (0);
143}
144
145
146/*
147 * 'psgets()' - Get a line from a file.
148 *
149 * Note:
150 *
151 * This function differs from the gets() function in that it
152 * handles any combination of CR, LF, or CR LF to end input
153 * lines.
154 */
155
156static char * /* O - String or NULL if EOF */
157psgets(char *buf, /* I - Buffer to read into */
158 size_t *bytes, /* IO - Length of buffer */
159 FILE *fp) /* I - File to read from */
160{
161 char *bufptr; /* Pointer into buffer */
162 int ch; /* Character from file */
163 size_t len; /* Max length of string */
164
165
166 len = *bytes - 1;
167 bufptr = buf;
168 ch = EOF;
169
7e86f2f6 170 while ((size_t)(bufptr - buf) < len)
bd7854cb 171 {
172 if ((ch = getc(fp)) == EOF)
173 break;
174
175 if (ch == '\r')
176 {
177 /*
178 * Got a CR; see if there is a LF as well...
179 */
180
181 ch = getc(fp);
182
183 if (ch != EOF && ch != '\n')
184 {
185 ungetc(ch, fp); /* Nope, save it for later... */
186 ch = '\r';
187 }
188 else
189 *bufptr++ = '\r';
190 break;
191 }
192 else if (ch == '\n')
193 break;
194 else
7e86f2f6 195 *bufptr++ = (char)ch;
bd7854cb 196 }
197
198 /*
199 * Add a trailing newline if it is there...
200 */
201
202 if (ch == '\n' || ch == '\r')
203 {
7e86f2f6
MS
204 if ((size_t)(bufptr - buf) < len)
205 *bufptr++ = (char)ch;
bd7854cb 206 else
207 ungetc(ch, fp);
208 }
209
210 /*
211 * Nul-terminate the string and return it (or NULL for EOF).
212 */
213
214 *bufptr = '\0';
7e86f2f6 215 *bytes = (size_t)(bufptr - buf);
bd7854cb 216
217 if (ch == EOF && bufptr == buf)
218 return (NULL);
219 else
220 return (buf);
221}
222
223
224/*
225 * 'pswrite()' - Write data from a file.
226 */
227
7e86f2f6 228static ssize_t /* O - Number of bytes written */
bd7854cb 229pswrite(const char *buf, /* I - Buffer to write */
7e86f2f6 230 size_t bytes) /* I - Bytes to write */
bd7854cb 231{
232 size_t count; /* Remaining bytes */
233
234
235 for (count = bytes; count > 0; count --, buf ++)
236 switch (*buf)
237 {
db1f069b
MS
238 case 0x04 : /* CTRL-D */
239 if (bytes == 1)
240 {
241 /*
242 * Don't quote the last CTRL-D...
243 */
244
245 putchar(0x04);
246 break;
247 }
248
bd7854cb 249 case 0x01 : /* CTRL-A */
250 case 0x03 : /* CTRL-C */
bd7854cb 251 case 0x05 : /* CTRL-E */
252 case 0x11 : /* CTRL-Q */
253 case 0x13 : /* CTRL-S */
254 case 0x14 : /* CTRL-T */
255 case 0x1b : /* CTRL-[ (aka ESC) */
256 case 0x1c : /* CTRL-\ */
257 if (putchar(0x01) < 0)
258 return (-1);
259 if (putchar(*buf ^ 0x40) < 0)
260 return (-1);
261 break;
262
263 default :
264 if (putchar(*buf) < 0)
265 return (-1);
266 break;
267 }
268
7e86f2f6 269 return ((ssize_t)bytes);
bd7854cb 270}
271
272
273/*
f2d18633 274 * End of "$Id$".
bd7854cb 275 */