]> git.ipfire.org Git - thirdparty/cups.git/blame - backend/testbackend.c
Remove old files.
[thirdparty/cups.git] / backend / testbackend.c
CommitLineData
568fa3fa
MS
1/*
2 * "$Id$"
3 *
4 * Backend test program for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 2007-2008 by Apple Inc.
7 * Copyright 1997-2005 by Easy Software Products, all rights reserved.
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 * "LICENSE" which should have been included with this file. If this
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() - Run the named backend.
20 * usage() - Show usage information.
21 */
22
23/*
24 * Include necessary headers.
25 */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <cups/string.h>
30#include <cups/cups.h>
31#include <cups/sidechannel.h>
32#include <unistd.h>
33#include <fcntl.h>
34#include <errno.h>
35#include <sys/wait.h>
36
37
38/*
39 * Local functions...
40 */
41
42static void usage(void);
43
44
45/*
46 * 'main()' - Run the named backend.
47 *
48 * Usage:
49 *
50 * betest [-s] [-t] device-uri job-id user title copies options [file]
51 */
52
53int /* O - Exit status */
54main(int argc, /* I - Number of command-line args */
55 char *argv[]) /* I - Command-line arguments */
56{
57 int first_arg, /* First argument for backend */
634763e8 58 do_query = 0, /* Do PostScript query? */
568fa3fa
MS
59 do_side_tests = 0, /* Test side-channel ops? */
60 do_trickle = 0; /* Trickle data to backend */
61 char scheme[255], /* Scheme in URI == backend */
62 backend[1024]; /* Backend path */
63 const char *serverbin; /* CUPS_SERVERBIN environment variable */
64 int back_fds[2], /* Back-channel pipe */
65 side_fds[2], /* Side-channel socket */
66 data_fds[2], /* Data pipe */
67 pid, /* Process ID */
68 status; /* Exit status */
69
70
71 /*
72 * See if we have side-channel tests to do...
73 */
74
75 for (first_arg = 1;
76 argv[first_arg] && argv[first_arg][0] == '-';
77 first_arg ++)
634763e8
MS
78 if (!strcmp(argv[first_arg], "-ps"))
79 do_query = 1;
80 else if (!strcmp(argv[first_arg], "-s"))
568fa3fa
MS
81 do_side_tests = 1;
82 else if (!strcmp(argv[first_arg], "-t"))
83 do_trickle = 1;
84 else
85 usage();
86
87 argc -= first_arg;
88 if (argc < 6 || argc > 7 || (argc == 7 && do_trickle))
89 usage();
90
91 /*
92 * Extract the scheme from the device-uri - that's the program we want to
93 * execute.
94 */
95
96 if (sscanf(argv[first_arg], "%254[^:]", scheme) != 1)
97 {
98 fputs("testbackend: Bad device-uri - no colon!\n", stderr);
99 return (1);
100 }
101
102 if (!access(scheme, X_OK))
103 strlcpy(backend, scheme, sizeof(backend));
104 else
105 {
106 if ((serverbin = getenv("CUPS_SERVERBIN")) == NULL)
107 serverbin = CUPS_SERVERBIN;
108
109 snprintf(backend, sizeof(backend), "%s/backend/%s", serverbin, scheme);
110 if (access(backend, X_OK))
111 {
112 fprintf(stderr, "testbackend: Unknown device scheme \"%s\"!\n", scheme);
113 return (1);
114 }
115 }
116
117 /*
118 * Create the back-channel pipe and side-channel socket...
119 */
120
121 open("/dev/null", O_WRONLY); /* Make sure fd 3 and 4 are used */
122 open("/dev/null", O_WRONLY);
123
124 pipe(back_fds);
125 fcntl(back_fds[0], F_SETFL, fcntl(back_fds[0], F_GETFL) | O_NONBLOCK);
126 fcntl(back_fds[1], F_SETFL, fcntl(back_fds[1], F_GETFL) | O_NONBLOCK);
127
128 socketpair(AF_LOCAL, SOCK_STREAM, 0, side_fds);
129 fcntl(side_fds[0], F_SETFL, fcntl(side_fds[0], F_GETFL) | O_NONBLOCK);
130 fcntl(side_fds[1], F_SETFL, fcntl(side_fds[1], F_GETFL) | O_NONBLOCK);
131
132 /*
133 * Execute the trickle process as needed...
134 */
135
634763e8 136 if (do_trickle || do_query)
568fa3fa
MS
137 {
138 pipe(data_fds);
139
140 if ((pid = fork()) == 0)
141 {
142 /*
634763e8
MS
143 * Trickle/query child comes here... Rearrange file descriptors so that
144 * FD
568fa3fa
MS
145 */
146
634763e8
MS
147 close(0);
148 open("/dev/null", O_RDONLY);
568fa3fa 149
634763e8
MS
150 close(1);
151 dup(data_fds[1]);
568fa3fa 152 close(data_fds[0]);
634763e8
MS
153 close(data_fds[1]);
154
155 close(3);
156 dup(back_fds[0]);
157 close(back_fds[0]);
158 close(back_fds[1]);
159
160 close(4);
161 dup(side_fds[0]);
162 close(side_fds[0]);
163 close(side_fds[1]);
164
165 if (do_trickle)
166 {
167 /*
168 * Write 10 spaces, 1 per second...
169 */
170
171 int i; /* Looping var */
172
173 for (i = 0; i < 10; i ++)
174 {
175 write(1, " ", 1);
176 sleep(1);
177 }
178 }
179 else
568fa3fa
MS
180 {
181 /*
634763e8 182 * Do a simple PostScript query job to get the default page size.
568fa3fa
MS
183 */
184
634763e8
MS
185 char buffer[1024]; /* Buffer for response data */
186 ssize_t bytes; /* Number of bytes of response data */
187 static const char *ps_query = /* PostScript query file */
188 "%!\n"
189 "save\n"
190 "currentpagedevice /PageSize get aload pop\n"
191 "2 copy gt {exch} if\n"
192 "(Unknown)\n"
193 "19 dict\n"
194 "dup [612 792] (Letter) put\n"
195 "dup [612 1008] (Legal) put\n"
196 "dup [612 935] (w612h935) put\n"
197 "dup [522 756] (Executive) put\n"
198 "dup [595 842] (A4) put\n"
199 "dup [420 595] (A5) put\n"
200 "dup [499 709] (ISOB5) put\n"
201 "dup [516 728] (B5) put\n"
202 "dup [612 936] (w612h936) put\n"
203 "dup [284 419] (Postcard) put\n"
204 "dup [419.5 567] (DoublePostcard) put\n"
205 "dup [558 774] (w558h774) put\n"
206 "dup [553 765] (w553h765) put\n"
207 "dup [522 737] (w522h737) put\n"
208 "dup [499 709] (EnvISOB5) put\n"
209 "dup [297 684] (Env10) put\n"
210 "dup [459 649] (EnvC5) put\n"
211 "dup [312 624] (EnvDL) put\n"
212 "dup [279 540] (EnvMonarch) put\n"
213 "{ exch aload pop 4 index sub abs 5 le exch\n"
214 " 5 index sub abs 5 le and\n"
215 " {exch pop exit} {pop} ifelse\n"
216 "} bind forall\n"
217 "= flush pop pop\n"
218 "restore\n"
219 "\004";
220
221
222 write(1, ps_query, strlen(ps_query));
223 write(2, "DEBUG: START\n", 13);
224 while ((bytes = cupsBackChannelRead(buffer, sizeof(buffer), 30.0)) > 0)
225 write(2, buffer, bytes);
226 write(2, "\nDEBUG: END\n", 12);
568fa3fa
MS
227 }
228
229 exit(0);
230 }
231 else if (pid < 0)
232 {
233 perror("testbackend: Unable to fork");
234 return (1);
235 }
236 }
237 else
238 data_fds[0] = data_fds[1] = -1;
239
240 /*
241 * Execute the backend...
242 */
243
244 if ((pid = fork()) == 0)
245 {
246 /*
247 * Child comes here...
248 */
249
634763e8 250 if (do_trickle || do_query)
568fa3fa
MS
251 {
252 close(0);
253 dup(data_fds[0]);
254 close(data_fds[0]);
255 close(data_fds[1]);
256 }
257
258 close(3);
259 dup(back_fds[1]);
260 close(back_fds[0]);
261 close(back_fds[1]);
262
263 close(4);
264 dup(side_fds[1]);
265 close(side_fds[0]);
266 close(side_fds[1]);
267
268 execv(backend, argv + first_arg);
269 fprintf(stderr, "textbackend: Unable to execute \"%s\": %s\n", backend,
270 strerror(errno));
271 return (errno);
272 }
273 else if (pid < 0)
274 {
275 perror("testbackend: Unable to fork");
276 return (1);
277 }
278
279 /*
280 * Parent comes here, setup back and side channel file descriptors...
281 */
282
634763e8 283 if (do_trickle || do_query)
568fa3fa
MS
284 {
285 close(data_fds[0]);
286 close(data_fds[1]);
287 }
288
289 close(3);
290 dup(back_fds[0]);
291 close(back_fds[0]);
292 close(back_fds[1]);
293
294 close(4);
295 dup(side_fds[0]);
296 close(side_fds[0]);
297 close(side_fds[1]);
298
299 /*
300 * Do side-channel tests as needed, then wait for the backend...
301 */
302
303 if (do_side_tests)
304 {
305 int length; /* Length of buffer */
306 char buffer[2049]; /* Buffer for reponse */
307 cups_sc_status_t scstatus; /* Status of side-channel command */
308 static const char * const statuses[] =
309 {
310 "CUPS_SC_STATUS_NONE", /* No status */
311 "CUPS_SC_STATUS_OK", /* Operation succeeded */
312 "CUPS_SC_STATUS_IO_ERROR", /* An I/O error occurred */
313 "CUPS_SC_STATUS_TIMEOUT", /* The backend did not respond */
314 "CUPS_SC_STATUS_NO_RESPONSE", /* The device did not respond */
315 "CUPS_SC_STATUS_BAD_MESSAGE", /* The command/response message was invalid */
316 "CUPS_SC_STATUS_TOO_BIG", /* Response too big */
317 "CUPS_SC_STATUS_NOT_IMPLEMENTED" /* Command not implemented */
318 };
319
320
321 length = 0;
322 scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_DRAIN_OUTPUT, buffer,
323 &length, 5.0);
324 printf("CUPS_SC_CMD_DRAIN_OUTPUT returned %s\n", statuses[scstatus]);
325
326 length = 1;
327 scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, buffer,
328 &length, 5.0);
329 printf("CUPS_SC_CMD_GET_BIDI returned %s, %d\n", statuses[scstatus], buffer[0]);
330
331 length = sizeof(buffer) - 1;
332 scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, buffer,
333 &length, 5.0);
334 buffer[length] = '\0';
335 printf("CUPS_SC_CMD_GET_DEVICE_ID returned %s, \"%s\"\n",
336 statuses[scstatus], buffer);
337
338 length = 1;
339 scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE, buffer,
340 &length, 5.0);
341 printf("CUPS_SC_CMD_GET_STATE returned %s, %02X\n", statuses[scstatus],
342 buffer[0] & 255);
343
344 length = 0;
345 scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_SOFT_RESET, buffer,
346 &length, 5.0);
347 printf("CUPS_SC_CMD_SOFT_RESET returned %s\n", statuses[scstatus]);
348 }
349
350 while (wait(&status) != pid);
351
352 if (status)
353 {
354 if (WIFEXITED(status))
355 printf("%s exited with status %d!\n", backend, WEXITSTATUS(status));
356 else
357 printf("%s crashed with signal %d!\n", backend, WTERMSIG(status));
358 }
359
360 /*
361 * Exit accordingly...
362 */
363
364 return (status != 0);
365}
366
367
368/*
369 * 'usage()' - Show usage information.
370 */
371
372static void
373usage(void)
374{
634763e8
MS
375 fputs("Usage: betest [-ps] [-s] [-t] device-uri job-id user title copies "
376 "options [file]\n", stderr);
568fa3fa
MS
377 exit(1);
378}
379
380
381/*
382 * End of "$Id$".
383 */