4 * Backend test program for the Common UNIX Printing System (CUPS).
6 * Copyright 2007-2008 by Apple Inc.
7 * Copyright 1997-2005 by Easy Software Products, all rights reserved.
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/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * main() - Run the named backend.
20 * usage() - Show usage information.
24 * Include necessary headers.
29 #include <cups/string.h>
30 #include <cups/cups.h>
31 #include <cups/sidechannel.h>
42 static void usage(void);
46 * 'main()' - Run the named backend.
50 * betest [-s] [-t] device-uri job-id user title copies options [file]
53 int /* O - Exit status */
54 main(int argc
, /* I - Number of command-line args */
55 char *argv
[]) /* I - Command-line arguments */
57 int first_arg
, /* First argument for backend */
58 do_side_tests
= 0, /* Test side-channel ops? */
59 do_trickle
= 0; /* Trickle data to backend */
60 char scheme
[255], /* Scheme in URI == backend */
61 backend
[1024]; /* Backend path */
62 const char *serverbin
; /* CUPS_SERVERBIN environment variable */
63 int back_fds
[2], /* Back-channel pipe */
64 side_fds
[2], /* Side-channel socket */
65 data_fds
[2], /* Data pipe */
67 status
; /* Exit status */
71 * See if we have side-channel tests to do...
75 argv
[first_arg
] && argv
[first_arg
][0] == '-';
77 if (!strcmp(argv
[first_arg
], "-s"))
79 else if (!strcmp(argv
[first_arg
], "-t"))
85 if (argc
< 6 || argc
> 7 || (argc
== 7 && do_trickle
))
89 * Extract the scheme from the device-uri - that's the program we want to
93 if (sscanf(argv
[first_arg
], "%254[^:]", scheme
) != 1)
95 fputs("testbackend: Bad device-uri - no colon!\n", stderr
);
99 if (!access(scheme
, X_OK
))
100 strlcpy(backend
, scheme
, sizeof(backend
));
103 if ((serverbin
= getenv("CUPS_SERVERBIN")) == NULL
)
104 serverbin
= CUPS_SERVERBIN
;
106 snprintf(backend
, sizeof(backend
), "%s/backend/%s", serverbin
, scheme
);
107 if (access(backend
, X_OK
))
109 fprintf(stderr
, "testbackend: Unknown device scheme \"%s\"!\n", scheme
);
115 * Create the back-channel pipe and side-channel socket...
118 open("/dev/null", O_WRONLY
); /* Make sure fd 3 and 4 are used */
119 open("/dev/null", O_WRONLY
);
122 fcntl(back_fds
[0], F_SETFL
, fcntl(back_fds
[0], F_GETFL
) | O_NONBLOCK
);
123 fcntl(back_fds
[1], F_SETFL
, fcntl(back_fds
[1], F_GETFL
) | O_NONBLOCK
);
125 socketpair(AF_LOCAL
, SOCK_STREAM
, 0, side_fds
);
126 fcntl(side_fds
[0], F_SETFL
, fcntl(side_fds
[0], F_GETFL
) | O_NONBLOCK
);
127 fcntl(side_fds
[1], F_SETFL
, fcntl(side_fds
[1], F_GETFL
) | O_NONBLOCK
);
130 * Execute the trickle process as needed...
137 if ((pid
= fork()) == 0)
140 * Trickle child comes here...
143 int i
; /* Looping var */
146 for (i
= 0; i
< 10; i
++)
149 * Write 10 spaces, 1 per second...
152 write(data_fds
[1], " ", 1);
160 perror("testbackend: Unable to fork");
165 data_fds
[0] = data_fds
[1] = -1;
168 * Execute the backend...
171 if ((pid
= fork()) == 0)
174 * Child comes here...
195 execv(backend
, argv
+ first_arg
);
196 fprintf(stderr
, "textbackend: Unable to execute \"%s\": %s\n", backend
,
202 perror("testbackend: Unable to fork");
207 * Parent comes here, setup back and side channel file descriptors...
227 * Do side-channel tests as needed, then wait for the backend...
232 int length
; /* Length of buffer */
233 char buffer
[2049]; /* Buffer for reponse */
234 cups_sc_status_t scstatus
; /* Status of side-channel command */
235 static const char * const statuses
[] =
237 "CUPS_SC_STATUS_NONE", /* No status */
238 "CUPS_SC_STATUS_OK", /* Operation succeeded */
239 "CUPS_SC_STATUS_IO_ERROR", /* An I/O error occurred */
240 "CUPS_SC_STATUS_TIMEOUT", /* The backend did not respond */
241 "CUPS_SC_STATUS_NO_RESPONSE", /* The device did not respond */
242 "CUPS_SC_STATUS_BAD_MESSAGE", /* The command/response message was invalid */
243 "CUPS_SC_STATUS_TOO_BIG", /* Response too big */
244 "CUPS_SC_STATUS_NOT_IMPLEMENTED" /* Command not implemented */
249 scstatus
= cupsSideChannelDoRequest(CUPS_SC_CMD_DRAIN_OUTPUT
, buffer
,
251 printf("CUPS_SC_CMD_DRAIN_OUTPUT returned %s\n", statuses
[scstatus
]);
254 scstatus
= cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI
, buffer
,
256 printf("CUPS_SC_CMD_GET_BIDI returned %s, %d\n", statuses
[scstatus
], buffer
[0]);
258 length
= sizeof(buffer
) - 1;
259 scstatus
= cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID
, buffer
,
261 buffer
[length
] = '\0';
262 printf("CUPS_SC_CMD_GET_DEVICE_ID returned %s, \"%s\"\n",
263 statuses
[scstatus
], buffer
);
266 scstatus
= cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE
, buffer
,
268 printf("CUPS_SC_CMD_GET_STATE returned %s, %02X\n", statuses
[scstatus
],
272 scstatus
= cupsSideChannelDoRequest(CUPS_SC_CMD_SOFT_RESET
, buffer
,
274 printf("CUPS_SC_CMD_SOFT_RESET returned %s\n", statuses
[scstatus
]);
277 while (wait(&status
) != pid
);
281 if (WIFEXITED(status
))
282 printf("%s exited with status %d!\n", backend
, WEXITSTATUS(status
));
284 printf("%s crashed with signal %d!\n", backend
, WTERMSIG(status
));
288 * Exit accordingly...
291 return (status
!= 0);
296 * 'usage()' - Show usage information.
302 fputs("Usage: betest [-s] [-t] device-uri job-id user title copies options "