summaryrefslogtreecommitdiff
path: root/backend/testbackend.c
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-02-28 23:00:58 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-02-28 23:00:58 +0000
commit568fa3faf16f8694653600d87955473941cc03c1 (patch)
tree7cb02898e83751848e3fa61a7821bb651ec361ae /backend/testbackend.c
parentd6943d1d3132205deeb6f9ad49ca54091ab3dfe5 (diff)
downloadcups-568fa3faf16f8694653600d87955473941cc03c1.tar.gz
Import CUPS 1.4svn-r7356.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@647 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'backend/testbackend.c')
-rw-r--r--backend/testbackend.c310
1 files changed, 310 insertions, 0 deletions
diff --git a/backend/testbackend.c b/backend/testbackend.c
new file mode 100644
index 000000000..4835ac6f6
--- /dev/null
+++ b/backend/testbackend.c
@@ -0,0 +1,310 @@
+/*
+ * "$Id$"
+ *
+ * Backend test program for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 2007-2008 by Apple Inc.
+ * Copyright 1997-2005 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Run the named backend.
+ * usage() - Show usage information.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cups/string.h>
+#include <cups/cups.h>
+#include <cups/sidechannel.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+
+/*
+ * Local functions...
+ */
+
+static void usage(void);
+
+
+/*
+ * 'main()' - Run the named backend.
+ *
+ * Usage:
+ *
+ * betest [-s] [-t] device-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line args */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int first_arg, /* First argument for backend */
+ do_side_tests = 0, /* Test side-channel ops? */
+ do_trickle = 0; /* Trickle data to backend */
+ char scheme[255], /* Scheme in URI == backend */
+ backend[1024]; /* Backend path */
+ const char *serverbin; /* CUPS_SERVERBIN environment variable */
+ int back_fds[2], /* Back-channel pipe */
+ side_fds[2], /* Side-channel socket */
+ data_fds[2], /* Data pipe */
+ pid, /* Process ID */
+ status; /* Exit status */
+
+
+ /*
+ * See if we have side-channel tests to do...
+ */
+
+ for (first_arg = 1;
+ argv[first_arg] && argv[first_arg][0] == '-';
+ first_arg ++)
+ if (!strcmp(argv[first_arg], "-s"))
+ do_side_tests = 1;
+ else if (!strcmp(argv[first_arg], "-t"))
+ do_trickle = 1;
+ else
+ usage();
+
+ argc -= first_arg;
+ if (argc < 6 || argc > 7 || (argc == 7 && do_trickle))
+ usage();
+
+ /*
+ * Extract the scheme from the device-uri - that's the program we want to
+ * execute.
+ */
+
+ if (sscanf(argv[first_arg], "%254[^:]", scheme) != 1)
+ {
+ fputs("testbackend: Bad device-uri - no colon!\n", stderr);
+ return (1);
+ }
+
+ if (!access(scheme, X_OK))
+ strlcpy(backend, scheme, sizeof(backend));
+ else
+ {
+ if ((serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ serverbin = CUPS_SERVERBIN;
+
+ snprintf(backend, sizeof(backend), "%s/backend/%s", serverbin, scheme);
+ if (access(backend, X_OK))
+ {
+ fprintf(stderr, "testbackend: Unknown device scheme \"%s\"!\n", scheme);
+ return (1);
+ }
+ }
+
+ /*
+ * Create the back-channel pipe and side-channel socket...
+ */
+
+ open("/dev/null", O_WRONLY); /* Make sure fd 3 and 4 are used */
+ open("/dev/null", O_WRONLY);
+
+ pipe(back_fds);
+ fcntl(back_fds[0], F_SETFL, fcntl(back_fds[0], F_GETFL) | O_NONBLOCK);
+ fcntl(back_fds[1], F_SETFL, fcntl(back_fds[1], F_GETFL) | O_NONBLOCK);
+
+ socketpair(AF_LOCAL, SOCK_STREAM, 0, side_fds);
+ fcntl(side_fds[0], F_SETFL, fcntl(side_fds[0], F_GETFL) | O_NONBLOCK);
+ fcntl(side_fds[1], F_SETFL, fcntl(side_fds[1], F_GETFL) | O_NONBLOCK);
+
+ /*
+ * Execute the trickle process as needed...
+ */
+
+ if (do_trickle)
+ {
+ pipe(data_fds);
+
+ if ((pid = fork()) == 0)
+ {
+ /*
+ * Trickle child comes here...
+ */
+
+ int i; /* Looping var */
+
+ close(data_fds[0]);
+ for (i = 0; i < 10; i ++)
+ {
+ /*
+ * Write 10 spaces, 1 per second...
+ */
+
+ write(data_fds[1], " ", 1);
+ sleep(1);
+ }
+
+ exit(0);
+ }
+ else if (pid < 0)
+ {
+ perror("testbackend: Unable to fork");
+ return (1);
+ }
+ }
+ else
+ data_fds[0] = data_fds[1] = -1;
+
+ /*
+ * Execute the backend...
+ */
+
+ if ((pid = fork()) == 0)
+ {
+ /*
+ * Child comes here...
+ */
+
+ if (do_trickle)
+ {
+ close(0);
+ dup(data_fds[0]);
+ close(data_fds[0]);
+ close(data_fds[1]);
+ }
+
+ close(3);
+ dup(back_fds[1]);
+ close(back_fds[0]);
+ close(back_fds[1]);
+
+ close(4);
+ dup(side_fds[1]);
+ close(side_fds[0]);
+ close(side_fds[1]);
+
+ execv(backend, argv + first_arg);
+ fprintf(stderr, "textbackend: Unable to execute \"%s\": %s\n", backend,
+ strerror(errno));
+ return (errno);
+ }
+ else if (pid < 0)
+ {
+ perror("testbackend: Unable to fork");
+ return (1);
+ }
+
+ /*
+ * Parent comes here, setup back and side channel file descriptors...
+ */
+
+ if (do_trickle)
+ {
+ close(data_fds[0]);
+ close(data_fds[1]);
+ }
+
+ close(3);
+ dup(back_fds[0]);
+ close(back_fds[0]);
+ close(back_fds[1]);
+
+ close(4);
+ dup(side_fds[0]);
+ close(side_fds[0]);
+ close(side_fds[1]);
+
+ /*
+ * Do side-channel tests as needed, then wait for the backend...
+ */
+
+ if (do_side_tests)
+ {
+ int length; /* Length of buffer */
+ char buffer[2049]; /* Buffer for reponse */
+ cups_sc_status_t scstatus; /* Status of side-channel command */
+ static const char * const statuses[] =
+ {
+ "CUPS_SC_STATUS_NONE", /* No status */
+ "CUPS_SC_STATUS_OK", /* Operation succeeded */
+ "CUPS_SC_STATUS_IO_ERROR", /* An I/O error occurred */
+ "CUPS_SC_STATUS_TIMEOUT", /* The backend did not respond */
+ "CUPS_SC_STATUS_NO_RESPONSE", /* The device did not respond */
+ "CUPS_SC_STATUS_BAD_MESSAGE", /* The command/response message was invalid */
+ "CUPS_SC_STATUS_TOO_BIG", /* Response too big */
+ "CUPS_SC_STATUS_NOT_IMPLEMENTED" /* Command not implemented */
+ };
+
+
+ length = 0;
+ scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_DRAIN_OUTPUT, buffer,
+ &length, 5.0);
+ printf("CUPS_SC_CMD_DRAIN_OUTPUT returned %s\n", statuses[scstatus]);
+
+ length = 1;
+ scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, buffer,
+ &length, 5.0);
+ printf("CUPS_SC_CMD_GET_BIDI returned %s, %d\n", statuses[scstatus], buffer[0]);
+
+ length = sizeof(buffer) - 1;
+ scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, buffer,
+ &length, 5.0);
+ buffer[length] = '\0';
+ printf("CUPS_SC_CMD_GET_DEVICE_ID returned %s, \"%s\"\n",
+ statuses[scstatus], buffer);
+
+ length = 1;
+ scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE, buffer,
+ &length, 5.0);
+ printf("CUPS_SC_CMD_GET_STATE returned %s, %02X\n", statuses[scstatus],
+ buffer[0] & 255);
+
+ length = 0;
+ scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_SOFT_RESET, buffer,
+ &length, 5.0);
+ printf("CUPS_SC_CMD_SOFT_RESET returned %s\n", statuses[scstatus]);
+ }
+
+ while (wait(&status) != pid);
+
+ if (status)
+ {
+ if (WIFEXITED(status))
+ printf("%s exited with status %d!\n", backend, WEXITSTATUS(status));
+ else
+ printf("%s crashed with signal %d!\n", backend, WTERMSIG(status));
+ }
+
+ /*
+ * Exit accordingly...
+ */
+
+ return (status != 0);
+}
+
+
+/*
+ * 'usage()' - Show usage information.
+ */
+
+static void
+usage(void)
+{
+ fputs("Usage: betest [-s] [-t] device-uri job-id user title copies options "
+ "[file]\n", stderr);
+ exit(1);
+}
+
+
+/*
+ * End of "$Id$".
+ */