xref: /aosp_15_r20/external/libcups/backend/testbackend.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * Backend test program for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2007-2014 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 1997-2005 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker  * information.
9*5e7646d2SAndroid Build Coastguard Worker  */
10*5e7646d2SAndroid Build Coastguard Worker 
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers.
13*5e7646d2SAndroid Build Coastguard Worker  */
14*5e7646d2SAndroid Build Coastguard Worker 
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/string-private.h>
16*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <cups/sidechannel.h>
18*5e7646d2SAndroid Build Coastguard Worker #include <unistd.h>
19*5e7646d2SAndroid Build Coastguard Worker #include <fcntl.h>
20*5e7646d2SAndroid Build Coastguard Worker #include <sys/wait.h>
21*5e7646d2SAndroid Build Coastguard Worker #include <signal.h>
22*5e7646d2SAndroid Build Coastguard Worker #include "backend-private.h"
23*5e7646d2SAndroid Build Coastguard Worker 
24*5e7646d2SAndroid Build Coastguard Worker 
25*5e7646d2SAndroid Build Coastguard Worker /*
26*5e7646d2SAndroid Build Coastguard Worker  * Local globals...
27*5e7646d2SAndroid Build Coastguard Worker  */
28*5e7646d2SAndroid Build Coastguard Worker 
29*5e7646d2SAndroid Build Coastguard Worker static int	job_canceled = 0;
30*5e7646d2SAndroid Build Coastguard Worker 
31*5e7646d2SAndroid Build Coastguard Worker 
32*5e7646d2SAndroid Build Coastguard Worker /*
33*5e7646d2SAndroid Build Coastguard Worker  * Local functions...
34*5e7646d2SAndroid Build Coastguard Worker  */
35*5e7646d2SAndroid Build Coastguard Worker 
36*5e7646d2SAndroid Build Coastguard Worker static void	sigterm_handler(int sig);
37*5e7646d2SAndroid Build Coastguard Worker static void	usage(void) _CUPS_NORETURN;
38*5e7646d2SAndroid Build Coastguard Worker static void	walk_cb(const char *oid, const char *data, int datalen,
39*5e7646d2SAndroid Build Coastguard Worker 		        void *context);
40*5e7646d2SAndroid Build Coastguard Worker 
41*5e7646d2SAndroid Build Coastguard Worker 
42*5e7646d2SAndroid Build Coastguard Worker /*
43*5e7646d2SAndroid Build Coastguard Worker  * 'main()' - Run the named backend.
44*5e7646d2SAndroid Build Coastguard Worker  *
45*5e7646d2SAndroid Build Coastguard Worker  * Usage:
46*5e7646d2SAndroid Build Coastguard Worker  *
47*5e7646d2SAndroid Build Coastguard Worker  *    testbackend [-s] [-t] device-uri job-id user title copies options [file]
48*5e7646d2SAndroid Build Coastguard Worker  */
49*5e7646d2SAndroid Build Coastguard Worker 
50*5e7646d2SAndroid Build Coastguard Worker int					/* O - Exit status */
main(int argc,char * argv[])51*5e7646d2SAndroid Build Coastguard Worker main(int  argc,				/* I - Number of command-line args */
52*5e7646d2SAndroid Build Coastguard Worker      char *argv[])			/* I - Command-line arguments */
53*5e7646d2SAndroid Build Coastguard Worker {
54*5e7646d2SAndroid Build Coastguard Worker   int		first_arg,		/* First argument for backend */
55*5e7646d2SAndroid Build Coastguard Worker 		do_cancel = 0,		/* Simulate a cancel-job via SIGTERM */
56*5e7646d2SAndroid Build Coastguard Worker 		do_ps = 0,		/* Do PostScript query+test? */
57*5e7646d2SAndroid Build Coastguard Worker 		do_pcl = 0,		/* Do PCL query+test? */
58*5e7646d2SAndroid Build Coastguard Worker 		do_side_tests = 0,	/* Test side-channel ops? */
59*5e7646d2SAndroid Build Coastguard Worker 		do_trickle = 0,		/* Trickle data to backend */
60*5e7646d2SAndroid Build Coastguard Worker 		do_walk = 0,		/* Do OID lookup (0) or walking (1) */
61*5e7646d2SAndroid Build Coastguard Worker 		show_log = 0;		/* Show log messages from backends? */
62*5e7646d2SAndroid Build Coastguard Worker   const char	*oid = ".1.3.6.1.2.1.43.10.2.1.4.1.1";
63*5e7646d2SAndroid Build Coastguard Worker   					/* OID to lookup or walk */
64*5e7646d2SAndroid Build Coastguard Worker   char		scheme[255],		/* Scheme in URI == backend */
65*5e7646d2SAndroid Build Coastguard Worker 		backend[1024],		/* Backend path */
66*5e7646d2SAndroid Build Coastguard Worker 		libpath[1024],		/* Path for libcups */
67*5e7646d2SAndroid Build Coastguard Worker 		*ptr;			/* Pointer into path */
68*5e7646d2SAndroid Build Coastguard Worker   const char	*serverbin;		/* CUPS_SERVERBIN environment variable */
69*5e7646d2SAndroid Build Coastguard Worker   int		fd,			/* Temporary file descriptor */
70*5e7646d2SAndroid Build Coastguard Worker 		back_fds[2],		/* Back-channel pipe */
71*5e7646d2SAndroid Build Coastguard Worker 		side_fds[2],		/* Side-channel socket */
72*5e7646d2SAndroid Build Coastguard Worker 		data_fds[2],		/* Data pipe */
73*5e7646d2SAndroid Build Coastguard Worker 		back_pid = -1,		/* Backend process ID */
74*5e7646d2SAndroid Build Coastguard Worker 		data_pid = -1,		/* Trickle process ID */
75*5e7646d2SAndroid Build Coastguard Worker 		pid,			/* Process ID */
76*5e7646d2SAndroid Build Coastguard Worker 		status;			/* Exit status */
77*5e7646d2SAndroid Build Coastguard Worker 
78*5e7646d2SAndroid Build Coastguard Worker 
79*5e7646d2SAndroid Build Coastguard Worker  /*
80*5e7646d2SAndroid Build Coastguard Worker   * Get the current directory and point the run-time linker at the "cups"
81*5e7646d2SAndroid Build Coastguard Worker   * subdirectory...
82*5e7646d2SAndroid Build Coastguard Worker   */
83*5e7646d2SAndroid Build Coastguard Worker 
84*5e7646d2SAndroid Build Coastguard Worker   if (getcwd(libpath, sizeof(libpath)) &&
85*5e7646d2SAndroid Build Coastguard Worker       (ptr = strrchr(libpath, '/')) != NULL && !strcmp(ptr, "/backend"))
86*5e7646d2SAndroid Build Coastguard Worker   {
87*5e7646d2SAndroid Build Coastguard Worker     strlcpy(ptr, "/cups", sizeof(libpath) - (size_t)(ptr - libpath));
88*5e7646d2SAndroid Build Coastguard Worker     if (!access(libpath, 0))
89*5e7646d2SAndroid Build Coastguard Worker     {
90*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
91*5e7646d2SAndroid Build Coastguard Worker       fprintf(stderr, "Setting DYLD_LIBRARY_PATH to \"%s\".\n", libpath);
92*5e7646d2SAndroid Build Coastguard Worker       setenv("DYLD_LIBRARY_PATH", libpath, 1);
93*5e7646d2SAndroid Build Coastguard Worker #else
94*5e7646d2SAndroid Build Coastguard Worker       fprintf(stderr, "Setting LD_LIBRARY_PATH to \"%s\".\n", libpath);
95*5e7646d2SAndroid Build Coastguard Worker       setenv("LD_LIBRARY_PATH", libpath, 1);
96*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
97*5e7646d2SAndroid Build Coastguard Worker     }
98*5e7646d2SAndroid Build Coastguard Worker     else
99*5e7646d2SAndroid Build Coastguard Worker       perror(libpath);
100*5e7646d2SAndroid Build Coastguard Worker   }
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker  /*
103*5e7646d2SAndroid Build Coastguard Worker   * See if we have side-channel tests to do...
104*5e7646d2SAndroid Build Coastguard Worker   */
105*5e7646d2SAndroid Build Coastguard Worker 
106*5e7646d2SAndroid Build Coastguard Worker   for (first_arg = 1;
107*5e7646d2SAndroid Build Coastguard Worker        argv[first_arg] && argv[first_arg][0] == '-';
108*5e7646d2SAndroid Build Coastguard Worker        first_arg ++)
109*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(argv[first_arg], "-d"))
110*5e7646d2SAndroid Build Coastguard Worker       show_log = 1;
111*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(argv[first_arg], "-cancel"))
112*5e7646d2SAndroid Build Coastguard Worker       do_cancel = 1;
113*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(argv[first_arg], "-pcl"))
114*5e7646d2SAndroid Build Coastguard Worker       do_pcl = 1;
115*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(argv[first_arg], "-ps"))
116*5e7646d2SAndroid Build Coastguard Worker       do_ps = 1;
117*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(argv[first_arg], "-s"))
118*5e7646d2SAndroid Build Coastguard Worker       do_side_tests = 1;
119*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(argv[first_arg], "-t"))
120*5e7646d2SAndroid Build Coastguard Worker       do_trickle = 1;
121*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(argv[first_arg], "-get") && (first_arg + 1) < argc)
122*5e7646d2SAndroid Build Coastguard Worker     {
123*5e7646d2SAndroid Build Coastguard Worker       first_arg ++;
124*5e7646d2SAndroid Build Coastguard Worker 
125*5e7646d2SAndroid Build Coastguard Worker       do_side_tests = 1;
126*5e7646d2SAndroid Build Coastguard Worker       oid           = argv[first_arg];
127*5e7646d2SAndroid Build Coastguard Worker     }
128*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(argv[first_arg], "-walk") && (first_arg + 1) < argc)
129*5e7646d2SAndroid Build Coastguard Worker     {
130*5e7646d2SAndroid Build Coastguard Worker       first_arg ++;
131*5e7646d2SAndroid Build Coastguard Worker 
132*5e7646d2SAndroid Build Coastguard Worker       do_side_tests = 1;
133*5e7646d2SAndroid Build Coastguard Worker       do_walk       = 1;
134*5e7646d2SAndroid Build Coastguard Worker       oid           = argv[first_arg];
135*5e7646d2SAndroid Build Coastguard Worker     }
136*5e7646d2SAndroid Build Coastguard Worker     else
137*5e7646d2SAndroid Build Coastguard Worker       usage();
138*5e7646d2SAndroid Build Coastguard Worker 
139*5e7646d2SAndroid Build Coastguard Worker   argc -= first_arg;
140*5e7646d2SAndroid Build Coastguard Worker   if (argc < 6 || argc > 7 || (argc == 7 && do_trickle))
141*5e7646d2SAndroid Build Coastguard Worker     usage();
142*5e7646d2SAndroid Build Coastguard Worker 
143*5e7646d2SAndroid Build Coastguard Worker  /*
144*5e7646d2SAndroid Build Coastguard Worker   * Extract the scheme from the device-uri - that's the program we want to
145*5e7646d2SAndroid Build Coastguard Worker   * execute.
146*5e7646d2SAndroid Build Coastguard Worker   */
147*5e7646d2SAndroid Build Coastguard Worker 
148*5e7646d2SAndroid Build Coastguard Worker   if (sscanf(argv[first_arg], "%254[^:]", scheme) != 1)
149*5e7646d2SAndroid Build Coastguard Worker   {
150*5e7646d2SAndroid Build Coastguard Worker     fputs("testbackend: Bad device-uri - no colon!\n", stderr);
151*5e7646d2SAndroid Build Coastguard Worker     return (1);
152*5e7646d2SAndroid Build Coastguard Worker   }
153*5e7646d2SAndroid Build Coastguard Worker 
154*5e7646d2SAndroid Build Coastguard Worker   if (!access(scheme, X_OK))
155*5e7646d2SAndroid Build Coastguard Worker     strlcpy(backend, scheme, sizeof(backend));
156*5e7646d2SAndroid Build Coastguard Worker   else
157*5e7646d2SAndroid Build Coastguard Worker   {
158*5e7646d2SAndroid Build Coastguard Worker     if ((serverbin = getenv("CUPS_SERVERBIN")) == NULL)
159*5e7646d2SAndroid Build Coastguard Worker       serverbin = CUPS_SERVERBIN;
160*5e7646d2SAndroid Build Coastguard Worker 
161*5e7646d2SAndroid Build Coastguard Worker     snprintf(backend, sizeof(backend), "%s/backend/%s", serverbin, scheme);
162*5e7646d2SAndroid Build Coastguard Worker     if (access(backend, X_OK))
163*5e7646d2SAndroid Build Coastguard Worker     {
164*5e7646d2SAndroid Build Coastguard Worker       fprintf(stderr, "testbackend: Unknown device scheme \"%s\"!\n", scheme);
165*5e7646d2SAndroid Build Coastguard Worker       return (1);
166*5e7646d2SAndroid Build Coastguard Worker     }
167*5e7646d2SAndroid Build Coastguard Worker   }
168*5e7646d2SAndroid Build Coastguard Worker 
169*5e7646d2SAndroid Build Coastguard Worker  /*
170*5e7646d2SAndroid Build Coastguard Worker   * Create the back-channel pipe and side-channel socket...
171*5e7646d2SAndroid Build Coastguard Worker   */
172*5e7646d2SAndroid Build Coastguard Worker 
173*5e7646d2SAndroid Build Coastguard Worker   open("/dev/null", O_WRONLY);		/* Make sure fd 3 and 4 are used */
174*5e7646d2SAndroid Build Coastguard Worker   open("/dev/null", O_WRONLY);
175*5e7646d2SAndroid Build Coastguard Worker 
176*5e7646d2SAndroid Build Coastguard Worker   pipe(back_fds);
177*5e7646d2SAndroid Build Coastguard Worker   fcntl(back_fds[0], F_SETFL, fcntl(back_fds[0], F_GETFL) | O_NONBLOCK);
178*5e7646d2SAndroid Build Coastguard Worker   fcntl(back_fds[1], F_SETFL, fcntl(back_fds[1], F_GETFL) | O_NONBLOCK);
179*5e7646d2SAndroid Build Coastguard Worker 
180*5e7646d2SAndroid Build Coastguard Worker   socketpair(AF_LOCAL, SOCK_STREAM, 0, side_fds);
181*5e7646d2SAndroid Build Coastguard Worker   fcntl(side_fds[0], F_SETFL, fcntl(side_fds[0], F_GETFL) | O_NONBLOCK);
182*5e7646d2SAndroid Build Coastguard Worker   fcntl(side_fds[1], F_SETFL, fcntl(side_fds[1], F_GETFL) | O_NONBLOCK);
183*5e7646d2SAndroid Build Coastguard Worker 
184*5e7646d2SAndroid Build Coastguard Worker  /*
185*5e7646d2SAndroid Build Coastguard Worker   * Execute the trickle process as needed...
186*5e7646d2SAndroid Build Coastguard Worker   */
187*5e7646d2SAndroid Build Coastguard Worker 
188*5e7646d2SAndroid Build Coastguard Worker   if (do_trickle || do_pcl || do_ps || do_cancel)
189*5e7646d2SAndroid Build Coastguard Worker   {
190*5e7646d2SAndroid Build Coastguard Worker     pipe(data_fds);
191*5e7646d2SAndroid Build Coastguard Worker 
192*5e7646d2SAndroid Build Coastguard Worker     signal(SIGTERM, sigterm_handler);
193*5e7646d2SAndroid Build Coastguard Worker 
194*5e7646d2SAndroid Build Coastguard Worker     if ((data_pid = fork()) == 0)
195*5e7646d2SAndroid Build Coastguard Worker     {
196*5e7646d2SAndroid Build Coastguard Worker      /*
197*5e7646d2SAndroid Build Coastguard Worker       * Trickle/query child comes here.  Rearrange file descriptors so that
198*5e7646d2SAndroid Build Coastguard Worker       * FD 1, 3, and 4 point to the backend...
199*5e7646d2SAndroid Build Coastguard Worker       */
200*5e7646d2SAndroid Build Coastguard Worker 
201*5e7646d2SAndroid Build Coastguard Worker       if ((fd = open("/dev/null", O_RDONLY)) != 0)
202*5e7646d2SAndroid Build Coastguard Worker       {
203*5e7646d2SAndroid Build Coastguard Worker         dup2(fd, 0);
204*5e7646d2SAndroid Build Coastguard Worker 	close(fd);
205*5e7646d2SAndroid Build Coastguard Worker       }
206*5e7646d2SAndroid Build Coastguard Worker 
207*5e7646d2SAndroid Build Coastguard Worker       if (data_fds[1] != 1)
208*5e7646d2SAndroid Build Coastguard Worker       {
209*5e7646d2SAndroid Build Coastguard Worker         dup2(data_fds[1], 1);
210*5e7646d2SAndroid Build Coastguard Worker 	close(data_fds[1]);
211*5e7646d2SAndroid Build Coastguard Worker       }
212*5e7646d2SAndroid Build Coastguard Worker       close(data_fds[0]);
213*5e7646d2SAndroid Build Coastguard Worker 
214*5e7646d2SAndroid Build Coastguard Worker       if (back_fds[0] != 3)
215*5e7646d2SAndroid Build Coastguard Worker       {
216*5e7646d2SAndroid Build Coastguard Worker         dup2(back_fds[0], 3);
217*5e7646d2SAndroid Build Coastguard Worker         close(back_fds[0]);
218*5e7646d2SAndroid Build Coastguard Worker       }
219*5e7646d2SAndroid Build Coastguard Worker       close(back_fds[1]);
220*5e7646d2SAndroid Build Coastguard Worker 
221*5e7646d2SAndroid Build Coastguard Worker       if (side_fds[0] != 4)
222*5e7646d2SAndroid Build Coastguard Worker       {
223*5e7646d2SAndroid Build Coastguard Worker         dup2(side_fds[0], 4);
224*5e7646d2SAndroid Build Coastguard Worker         close(side_fds[0]);
225*5e7646d2SAndroid Build Coastguard Worker       }
226*5e7646d2SAndroid Build Coastguard Worker       close(side_fds[1]);
227*5e7646d2SAndroid Build Coastguard Worker 
228*5e7646d2SAndroid Build Coastguard Worker       if (do_trickle)
229*5e7646d2SAndroid Build Coastguard Worker       {
230*5e7646d2SAndroid Build Coastguard Worker        /*
231*5e7646d2SAndroid Build Coastguard Worker 	* Write 10 spaces, 1 per second...
232*5e7646d2SAndroid Build Coastguard Worker 	*/
233*5e7646d2SAndroid Build Coastguard Worker 
234*5e7646d2SAndroid Build Coastguard Worker 	int i;				/* Looping var */
235*5e7646d2SAndroid Build Coastguard Worker 
236*5e7646d2SAndroid Build Coastguard Worker 	for (i = 0; i < 10; i ++)
237*5e7646d2SAndroid Build Coastguard Worker 	{
238*5e7646d2SAndroid Build Coastguard Worker 	  write(1, " ", 1);
239*5e7646d2SAndroid Build Coastguard Worker 	  sleep(1);
240*5e7646d2SAndroid Build Coastguard Worker 	}
241*5e7646d2SAndroid Build Coastguard Worker       }
242*5e7646d2SAndroid Build Coastguard Worker       else if (do_cancel)
243*5e7646d2SAndroid Build Coastguard Worker       {
244*5e7646d2SAndroid Build Coastguard Worker        /*
245*5e7646d2SAndroid Build Coastguard Worker         * Write PS or PCL lines until we see SIGTERM...
246*5e7646d2SAndroid Build Coastguard Worker 	*/
247*5e7646d2SAndroid Build Coastguard Worker 
248*5e7646d2SAndroid Build Coastguard Worker         int	line = 0, page = 0;	/* Current line and page */
249*5e7646d2SAndroid Build Coastguard Worker 	ssize_t	bytes;			/* Number of bytes of response data */
250*5e7646d2SAndroid Build Coastguard Worker 	char	buffer[1024];		/* Output buffer */
251*5e7646d2SAndroid Build Coastguard Worker 
252*5e7646d2SAndroid Build Coastguard Worker 
253*5e7646d2SAndroid Build Coastguard Worker         if (do_pcl)
254*5e7646d2SAndroid Build Coastguard Worker 	  write(1, "\033E", 2);
255*5e7646d2SAndroid Build Coastguard Worker 	else
256*5e7646d2SAndroid Build Coastguard Worker 	  write(1, "%!\n/Courier findfont 12 scalefont setfont 0 setgray\n", 52);
257*5e7646d2SAndroid Build Coastguard Worker 
258*5e7646d2SAndroid Build Coastguard Worker         while (!job_canceled)
259*5e7646d2SAndroid Build Coastguard Worker 	{
260*5e7646d2SAndroid Build Coastguard Worker 	  if (line == 0)
261*5e7646d2SAndroid Build Coastguard Worker 	  {
262*5e7646d2SAndroid Build Coastguard Worker 	    page ++;
263*5e7646d2SAndroid Build Coastguard Worker 
264*5e7646d2SAndroid Build Coastguard Worker 	    if (do_pcl)
265*5e7646d2SAndroid Build Coastguard Worker 	      snprintf(buffer, sizeof(buffer), "PCL Page %d\r\n\r\n", page);
266*5e7646d2SAndroid Build Coastguard Worker 	    else
267*5e7646d2SAndroid Build Coastguard Worker 	      snprintf(buffer, sizeof(buffer),
268*5e7646d2SAndroid Build Coastguard Worker 	               "18 732 moveto (PS Page %d) show\n", page);
269*5e7646d2SAndroid Build Coastguard Worker 
270*5e7646d2SAndroid Build Coastguard Worker 	    write(1, buffer, strlen(buffer));
271*5e7646d2SAndroid Build Coastguard Worker 	  }
272*5e7646d2SAndroid Build Coastguard Worker 
273*5e7646d2SAndroid Build Coastguard Worker           line ++;
274*5e7646d2SAndroid Build Coastguard Worker 
275*5e7646d2SAndroid Build Coastguard Worker 	  if (do_pcl)
276*5e7646d2SAndroid Build Coastguard Worker 	    snprintf(buffer, sizeof(buffer), "Line %d\r\n", line);
277*5e7646d2SAndroid Build Coastguard Worker 	  else
278*5e7646d2SAndroid Build Coastguard Worker 	    snprintf(buffer, sizeof(buffer), "18 %d moveto (Line %d) show\n",
279*5e7646d2SAndroid Build Coastguard Worker 		     720 - line * 12, line);
280*5e7646d2SAndroid Build Coastguard Worker 
281*5e7646d2SAndroid Build Coastguard Worker 	  write(1, buffer, strlen(buffer));
282*5e7646d2SAndroid Build Coastguard Worker 
283*5e7646d2SAndroid Build Coastguard Worker           if (line >= 55)
284*5e7646d2SAndroid Build Coastguard Worker 	  {
285*5e7646d2SAndroid Build Coastguard Worker 	   /*
286*5e7646d2SAndroid Build Coastguard Worker 	    * Eject after 55 lines...
287*5e7646d2SAndroid Build Coastguard Worker 	    */
288*5e7646d2SAndroid Build Coastguard Worker 
289*5e7646d2SAndroid Build Coastguard Worker 	    line = 0;
290*5e7646d2SAndroid Build Coastguard Worker 	    if (do_pcl)
291*5e7646d2SAndroid Build Coastguard Worker 	      write(1, "\014", 1);
292*5e7646d2SAndroid Build Coastguard Worker 	    else
293*5e7646d2SAndroid Build Coastguard Worker 	      write(1, "showpage\n", 9);
294*5e7646d2SAndroid Build Coastguard Worker 	  }
295*5e7646d2SAndroid Build Coastguard Worker 
296*5e7646d2SAndroid Build Coastguard Worker 	 /*
297*5e7646d2SAndroid Build Coastguard Worker 	  * Check for back-channel data...
298*5e7646d2SAndroid Build Coastguard Worker 	  */
299*5e7646d2SAndroid Build Coastguard Worker 
300*5e7646d2SAndroid Build Coastguard Worker 	  if ((bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0)) > 0)
301*5e7646d2SAndroid Build Coastguard Worker 	    write(2, buffer, (size_t)bytes);
302*5e7646d2SAndroid Build Coastguard Worker 
303*5e7646d2SAndroid Build Coastguard Worker 	 /*
304*5e7646d2SAndroid Build Coastguard Worker 	  * Throttle output to ~100hz...
305*5e7646d2SAndroid Build Coastguard Worker 	  */
306*5e7646d2SAndroid Build Coastguard Worker 
307*5e7646d2SAndroid Build Coastguard Worker 	  usleep(10000);
308*5e7646d2SAndroid Build Coastguard Worker 	}
309*5e7646d2SAndroid Build Coastguard Worker 
310*5e7646d2SAndroid Build Coastguard Worker        /*
311*5e7646d2SAndroid Build Coastguard Worker         * Eject current page with info...
312*5e7646d2SAndroid Build Coastguard Worker 	*/
313*5e7646d2SAndroid Build Coastguard Worker 
314*5e7646d2SAndroid Build Coastguard Worker         if (do_pcl)
315*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(buffer, sizeof(buffer),
316*5e7646d2SAndroid Build Coastguard Worker 		   "Canceled on line %d of page %d\r\n\014\033E", line, page);
317*5e7646d2SAndroid Build Coastguard Worker 	else
318*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(buffer, sizeof(buffer),
319*5e7646d2SAndroid Build Coastguard Worker 	           "\n18 %d moveto (Canceled on line %d of page %d)\nshowpage\n",
320*5e7646d2SAndroid Build Coastguard Worker 		   720 - line * 12, line, page);
321*5e7646d2SAndroid Build Coastguard Worker 
322*5e7646d2SAndroid Build Coastguard Worker 	write(1, buffer, strlen(buffer));
323*5e7646d2SAndroid Build Coastguard Worker 
324*5e7646d2SAndroid Build Coastguard Worker        /*
325*5e7646d2SAndroid Build Coastguard Worker         * See if we get any back-channel data...
326*5e7646d2SAndroid Build Coastguard Worker 	*/
327*5e7646d2SAndroid Build Coastguard Worker 
328*5e7646d2SAndroid Build Coastguard Worker         while ((bytes = cupsBackChannelRead(buffer, sizeof(buffer), 5.0)) > 0)
329*5e7646d2SAndroid Build Coastguard Worker 	  write(2, buffer, (size_t)bytes);
330*5e7646d2SAndroid Build Coastguard Worker 
331*5e7646d2SAndroid Build Coastguard Worker 	exit(0);
332*5e7646d2SAndroid Build Coastguard Worker       }
333*5e7646d2SAndroid Build Coastguard Worker       else
334*5e7646d2SAndroid Build Coastguard Worker       {
335*5e7646d2SAndroid Build Coastguard Worker        /*
336*5e7646d2SAndroid Build Coastguard Worker         * Do PS or PCL query + test pages.
337*5e7646d2SAndroid Build Coastguard Worker 	*/
338*5e7646d2SAndroid Build Coastguard Worker 
339*5e7646d2SAndroid Build Coastguard Worker         char		buffer[1024];	/* Buffer for response data */
340*5e7646d2SAndroid Build Coastguard Worker 	ssize_t		bytes;		/* Number of bytes of response data */
341*5e7646d2SAndroid Build Coastguard Worker 	double		timeout;	/* Timeout */
342*5e7646d2SAndroid Build Coastguard Worker 	const char	*data;		/* Data to send */
343*5e7646d2SAndroid Build Coastguard Worker         static const char *pcl_data =	/* PCL data */
344*5e7646d2SAndroid Build Coastguard Worker 		"\033%-12345X@PJL\r\n"
345*5e7646d2SAndroid Build Coastguard Worker 		"@PJL JOB NAME = \"Hello, World!\"\r\n"
346*5e7646d2SAndroid Build Coastguard Worker 		"@PJL INFO USTATUS\r\n"
347*5e7646d2SAndroid Build Coastguard Worker 		"@PJL ENTER LANGUAGE = PCL\r\n"
348*5e7646d2SAndroid Build Coastguard Worker 		"\033E"
349*5e7646d2SAndroid Build Coastguard Worker 		"Hello, World!\n"
350*5e7646d2SAndroid Build Coastguard Worker 		"\014"
351*5e7646d2SAndroid Build Coastguard Worker 		"\033%-12345X@PJL\r\n"
352*5e7646d2SAndroid Build Coastguard Worker 		"@PJL EOJ NAME=\"Hello, World!\"\r\n"
353*5e7646d2SAndroid Build Coastguard Worker 		"\033%-12345X";
354*5e7646d2SAndroid Build Coastguard Worker         static const char *ps_data =	/* PostScript data */
355*5e7646d2SAndroid Build Coastguard Worker 		"%!\n"
356*5e7646d2SAndroid Build Coastguard Worker 		"save\n"
357*5e7646d2SAndroid Build Coastguard Worker 		"product = flush\n"
358*5e7646d2SAndroid Build Coastguard Worker 		"currentpagedevice /PageSize get aload pop\n"
359*5e7646d2SAndroid Build Coastguard Worker 		"2 copy gt {exch} if\n"
360*5e7646d2SAndroid Build Coastguard Worker 		"(Unknown)\n"
361*5e7646d2SAndroid Build Coastguard Worker 		"19 dict\n"
362*5e7646d2SAndroid Build Coastguard Worker 		"dup [612 792] (Letter) put\n"
363*5e7646d2SAndroid Build Coastguard Worker 		"dup [612 1008] (Legal) put\n"
364*5e7646d2SAndroid Build Coastguard Worker 		"dup [612 935] (w612h935) put\n"
365*5e7646d2SAndroid Build Coastguard Worker 		"dup [522 756] (Executive) put\n"
366*5e7646d2SAndroid Build Coastguard Worker 		"dup [595 842] (A4) put\n"
367*5e7646d2SAndroid Build Coastguard Worker 		"dup [420 595] (A5) put\n"
368*5e7646d2SAndroid Build Coastguard Worker 		"dup [499 709] (ISOB5) put\n"
369*5e7646d2SAndroid Build Coastguard Worker 		"dup [516 728] (B5) put\n"
370*5e7646d2SAndroid Build Coastguard Worker 		"dup [612 936] (w612h936) put\n"
371*5e7646d2SAndroid Build Coastguard Worker 		"dup [284 419] (Postcard) put\n"
372*5e7646d2SAndroid Build Coastguard Worker 		"dup [419.5 567] (DoublePostcard) put\n"
373*5e7646d2SAndroid Build Coastguard Worker 		"dup [558 774] (w558h774) put\n"
374*5e7646d2SAndroid Build Coastguard Worker 		"dup [553 765] (w553h765) put\n"
375*5e7646d2SAndroid Build Coastguard Worker 		"dup [522 737] (w522h737) put\n"
376*5e7646d2SAndroid Build Coastguard Worker 		"dup [499 709] (EnvISOB5) put\n"
377*5e7646d2SAndroid Build Coastguard Worker 		"dup [297 684] (Env10) put\n"
378*5e7646d2SAndroid Build Coastguard Worker 		"dup [459 649] (EnvC5) put\n"
379*5e7646d2SAndroid Build Coastguard Worker 		"dup [312 624] (EnvDL) put\n"
380*5e7646d2SAndroid Build Coastguard Worker 		"dup [279 540] (EnvMonarch) put\n"
381*5e7646d2SAndroid Build Coastguard Worker 		"{ exch aload pop 4 index sub abs 5 le exch\n"
382*5e7646d2SAndroid Build Coastguard Worker 		"  5 index sub abs 5 le and\n"
383*5e7646d2SAndroid Build Coastguard Worker 		"  {exch pop exit} {pop} ifelse\n"
384*5e7646d2SAndroid Build Coastguard Worker 		"} bind forall\n"
385*5e7646d2SAndroid Build Coastguard Worker 		"= flush pop pop\n"
386*5e7646d2SAndroid Build Coastguard Worker 		"/Courier findfont 12 scalefont setfont\n"
387*5e7646d2SAndroid Build Coastguard Worker 		"0 setgray 36 720 moveto (Hello, ) show product show (!) show\n"
388*5e7646d2SAndroid Build Coastguard Worker 		"showpage\n"
389*5e7646d2SAndroid Build Coastguard Worker 		"restore\n"
390*5e7646d2SAndroid Build Coastguard Worker 		"\004";
391*5e7646d2SAndroid Build Coastguard Worker 
392*5e7646d2SAndroid Build Coastguard Worker 
393*5e7646d2SAndroid Build Coastguard Worker 	if (do_pcl)
394*5e7646d2SAndroid Build Coastguard Worker 	  data = pcl_data;
395*5e7646d2SAndroid Build Coastguard Worker 	else
396*5e7646d2SAndroid Build Coastguard Worker 	  data = ps_data;
397*5e7646d2SAndroid Build Coastguard Worker 
398*5e7646d2SAndroid Build Coastguard Worker         write(1, data, strlen(data));
399*5e7646d2SAndroid Build Coastguard Worker 	backendMessage("DEBUG: START\n");
400*5e7646d2SAndroid Build Coastguard Worker 	timeout = 60.0;
401*5e7646d2SAndroid Build Coastguard Worker         while ((bytes = cupsBackChannelRead(buffer, sizeof(buffer),
402*5e7646d2SAndroid Build Coastguard Worker 	                                    timeout)) > 0)
403*5e7646d2SAndroid Build Coastguard Worker 	{
404*5e7646d2SAndroid Build Coastguard Worker 	  write(2, buffer, (size_t)bytes);
405*5e7646d2SAndroid Build Coastguard Worker 	  timeout = 5.0;
406*5e7646d2SAndroid Build Coastguard Worker 	}
407*5e7646d2SAndroid Build Coastguard Worker 	backendMessage("\nDEBUG: END\n");
408*5e7646d2SAndroid Build Coastguard Worker       }
409*5e7646d2SAndroid Build Coastguard Worker 
410*5e7646d2SAndroid Build Coastguard Worker       exit(0);
411*5e7646d2SAndroid Build Coastguard Worker     }
412*5e7646d2SAndroid Build Coastguard Worker     else if (data_pid < 0)
413*5e7646d2SAndroid Build Coastguard Worker     {
414*5e7646d2SAndroid Build Coastguard Worker       perror("testbackend: Unable to fork");
415*5e7646d2SAndroid Build Coastguard Worker       return (1);
416*5e7646d2SAndroid Build Coastguard Worker     }
417*5e7646d2SAndroid Build Coastguard Worker   }
418*5e7646d2SAndroid Build Coastguard Worker   else
419*5e7646d2SAndroid Build Coastguard Worker     data_fds[0] = data_fds[1] = -1;
420*5e7646d2SAndroid Build Coastguard Worker 
421*5e7646d2SAndroid Build Coastguard Worker  /*
422*5e7646d2SAndroid Build Coastguard Worker   * Execute the backend...
423*5e7646d2SAndroid Build Coastguard Worker   */
424*5e7646d2SAndroid Build Coastguard Worker 
425*5e7646d2SAndroid Build Coastguard Worker   if ((back_pid = fork()) == 0)
426*5e7646d2SAndroid Build Coastguard Worker   {
427*5e7646d2SAndroid Build Coastguard Worker    /*
428*5e7646d2SAndroid Build Coastguard Worker     * Child comes here...
429*5e7646d2SAndroid Build Coastguard Worker     */
430*5e7646d2SAndroid Build Coastguard Worker 
431*5e7646d2SAndroid Build Coastguard Worker     if (do_trickle || do_ps || do_pcl || do_cancel)
432*5e7646d2SAndroid Build Coastguard Worker     {
433*5e7646d2SAndroid Build Coastguard Worker       if (data_fds[0] != 0)
434*5e7646d2SAndroid Build Coastguard Worker       {
435*5e7646d2SAndroid Build Coastguard Worker         dup2(data_fds[0], 0);
436*5e7646d2SAndroid Build Coastguard Worker         close(data_fds[0]);
437*5e7646d2SAndroid Build Coastguard Worker       }
438*5e7646d2SAndroid Build Coastguard Worker       close(data_fds[1]);
439*5e7646d2SAndroid Build Coastguard Worker     }
440*5e7646d2SAndroid Build Coastguard Worker 
441*5e7646d2SAndroid Build Coastguard Worker     if (!show_log)
442*5e7646d2SAndroid Build Coastguard Worker     {
443*5e7646d2SAndroid Build Coastguard Worker       if ((fd = open("/dev/null", O_WRONLY)) != 2)
444*5e7646d2SAndroid Build Coastguard Worker       {
445*5e7646d2SAndroid Build Coastguard Worker         dup2(fd, 2);
446*5e7646d2SAndroid Build Coastguard Worker 	close(fd);
447*5e7646d2SAndroid Build Coastguard Worker       }
448*5e7646d2SAndroid Build Coastguard Worker     }
449*5e7646d2SAndroid Build Coastguard Worker 
450*5e7646d2SAndroid Build Coastguard Worker     if (back_fds[1] != 3)
451*5e7646d2SAndroid Build Coastguard Worker     {
452*5e7646d2SAndroid Build Coastguard Worker       dup2(back_fds[1], 3);
453*5e7646d2SAndroid Build Coastguard Worker       close(back_fds[0]);
454*5e7646d2SAndroid Build Coastguard Worker     }
455*5e7646d2SAndroid Build Coastguard Worker     close(back_fds[1]);
456*5e7646d2SAndroid Build Coastguard Worker 
457*5e7646d2SAndroid Build Coastguard Worker     if (side_fds[1] != 4)
458*5e7646d2SAndroid Build Coastguard Worker     {
459*5e7646d2SAndroid Build Coastguard Worker       dup2(side_fds[1], 4);
460*5e7646d2SAndroid Build Coastguard Worker       close(side_fds[0]);
461*5e7646d2SAndroid Build Coastguard Worker     }
462*5e7646d2SAndroid Build Coastguard Worker     close(side_fds[1]);
463*5e7646d2SAndroid Build Coastguard Worker 
464*5e7646d2SAndroid Build Coastguard Worker     execv(backend, argv + first_arg);
465*5e7646d2SAndroid Build Coastguard Worker     fprintf(stderr, "testbackend: Unable to execute \"%s\": %s\n", backend,
466*5e7646d2SAndroid Build Coastguard Worker             strerror(errno));
467*5e7646d2SAndroid Build Coastguard Worker     return (errno);
468*5e7646d2SAndroid Build Coastguard Worker   }
469*5e7646d2SAndroid Build Coastguard Worker   else if (back_pid < 0)
470*5e7646d2SAndroid Build Coastguard Worker   {
471*5e7646d2SAndroid Build Coastguard Worker     perror("testbackend: Unable to fork");
472*5e7646d2SAndroid Build Coastguard Worker     return (1);
473*5e7646d2SAndroid Build Coastguard Worker   }
474*5e7646d2SAndroid Build Coastguard Worker 
475*5e7646d2SAndroid Build Coastguard Worker  /*
476*5e7646d2SAndroid Build Coastguard Worker   * Parent comes here, setup back and side channel file descriptors...
477*5e7646d2SAndroid Build Coastguard Worker   */
478*5e7646d2SAndroid Build Coastguard Worker 
479*5e7646d2SAndroid Build Coastguard Worker   if (do_trickle || do_ps || do_pcl || do_cancel)
480*5e7646d2SAndroid Build Coastguard Worker   {
481*5e7646d2SAndroid Build Coastguard Worker     close(data_fds[0]);
482*5e7646d2SAndroid Build Coastguard Worker     close(data_fds[1]);
483*5e7646d2SAndroid Build Coastguard Worker   }
484*5e7646d2SAndroid Build Coastguard Worker 
485*5e7646d2SAndroid Build Coastguard Worker   if (back_fds[0] != 3)
486*5e7646d2SAndroid Build Coastguard Worker   {
487*5e7646d2SAndroid Build Coastguard Worker     dup2(back_fds[0], 3);
488*5e7646d2SAndroid Build Coastguard Worker     close(back_fds[0]);
489*5e7646d2SAndroid Build Coastguard Worker   }
490*5e7646d2SAndroid Build Coastguard Worker   close(back_fds[1]);
491*5e7646d2SAndroid Build Coastguard Worker 
492*5e7646d2SAndroid Build Coastguard Worker   if (side_fds[0] != 4)
493*5e7646d2SAndroid Build Coastguard Worker   {
494*5e7646d2SAndroid Build Coastguard Worker     dup2(side_fds[0], 4);
495*5e7646d2SAndroid Build Coastguard Worker     close(side_fds[0]);
496*5e7646d2SAndroid Build Coastguard Worker   }
497*5e7646d2SAndroid Build Coastguard Worker   close(side_fds[1]);
498*5e7646d2SAndroid Build Coastguard Worker 
499*5e7646d2SAndroid Build Coastguard Worker  /*
500*5e7646d2SAndroid Build Coastguard Worker   * Do side-channel tests as needed, then wait for the backend...
501*5e7646d2SAndroid Build Coastguard Worker   */
502*5e7646d2SAndroid Build Coastguard Worker 
503*5e7646d2SAndroid Build Coastguard Worker   if (do_side_tests)
504*5e7646d2SAndroid Build Coastguard Worker   {
505*5e7646d2SAndroid Build Coastguard Worker     int			length;		/* Length of buffer */
506*5e7646d2SAndroid Build Coastguard Worker     char		buffer[2049];	/* Buffer for reponse */
507*5e7646d2SAndroid Build Coastguard Worker     cups_sc_status_t	scstatus;	/* Status of side-channel command */
508*5e7646d2SAndroid Build Coastguard Worker     static const char * const statuses[] =
509*5e7646d2SAndroid Build Coastguard Worker     {
510*5e7646d2SAndroid Build Coastguard Worker       "CUPS_SC_STATUS_NONE",		/* No status */
511*5e7646d2SAndroid Build Coastguard Worker       "CUPS_SC_STATUS_OK",		/* Operation succeeded */
512*5e7646d2SAndroid Build Coastguard Worker       "CUPS_SC_STATUS_IO_ERROR",	/* An I/O error occurred */
513*5e7646d2SAndroid Build Coastguard Worker       "CUPS_SC_STATUS_TIMEOUT",		/* The backend did not respond */
514*5e7646d2SAndroid Build Coastguard Worker       "CUPS_SC_STATUS_NO_RESPONSE",	/* The device did not respond */
515*5e7646d2SAndroid Build Coastguard Worker       "CUPS_SC_STATUS_BAD_MESSAGE",	/* The command/response message was invalid */
516*5e7646d2SAndroid Build Coastguard Worker       "CUPS_SC_STATUS_TOO_BIG",		/* Response too big */
517*5e7646d2SAndroid Build Coastguard Worker       "CUPS_SC_STATUS_NOT_IMPLEMENTED"	/* Command not implemented */
518*5e7646d2SAndroid Build Coastguard Worker     };
519*5e7646d2SAndroid Build Coastguard Worker 
520*5e7646d2SAndroid Build Coastguard Worker 
521*5e7646d2SAndroid Build Coastguard Worker     sleep(2);
522*5e7646d2SAndroid Build Coastguard Worker 
523*5e7646d2SAndroid Build Coastguard Worker     length   = 0;
524*5e7646d2SAndroid Build Coastguard Worker     scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_DRAIN_OUTPUT, buffer,
525*5e7646d2SAndroid Build Coastguard Worker                                         &length, 60.0);
526*5e7646d2SAndroid Build Coastguard Worker     printf("CUPS_SC_CMD_DRAIN_OUTPUT returned %s\n", statuses[scstatus]);
527*5e7646d2SAndroid Build Coastguard Worker 
528*5e7646d2SAndroid Build Coastguard Worker     length   = 1;
529*5e7646d2SAndroid Build Coastguard Worker     scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, buffer,
530*5e7646d2SAndroid Build Coastguard Worker                                         &length, 5.0);
531*5e7646d2SAndroid Build Coastguard Worker     printf("CUPS_SC_CMD_GET_BIDI returned %s, %d\n", statuses[scstatus], buffer[0]);
532*5e7646d2SAndroid Build Coastguard Worker 
533*5e7646d2SAndroid Build Coastguard Worker     length   = sizeof(buffer) - 1;
534*5e7646d2SAndroid Build Coastguard Worker     scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, buffer,
535*5e7646d2SAndroid Build Coastguard Worker                                         &length, 5.0);
536*5e7646d2SAndroid Build Coastguard Worker     buffer[length] = '\0';
537*5e7646d2SAndroid Build Coastguard Worker     printf("CUPS_SC_CMD_GET_DEVICE_ID returned %s, \"%s\"\n",
538*5e7646d2SAndroid Build Coastguard Worker            statuses[scstatus], buffer);
539*5e7646d2SAndroid Build Coastguard Worker 
540*5e7646d2SAndroid Build Coastguard Worker     length   = 1;
541*5e7646d2SAndroid Build Coastguard Worker     scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE, buffer,
542*5e7646d2SAndroid Build Coastguard Worker                                         &length, 5.0);
543*5e7646d2SAndroid Build Coastguard Worker     printf("CUPS_SC_CMD_GET_STATE returned %s, %02X\n", statuses[scstatus],
544*5e7646d2SAndroid Build Coastguard Worker            buffer[0] & 255);
545*5e7646d2SAndroid Build Coastguard Worker 
546*5e7646d2SAndroid Build Coastguard Worker     if (do_walk)
547*5e7646d2SAndroid Build Coastguard Worker     {
548*5e7646d2SAndroid Build Coastguard Worker      /*
549*5e7646d2SAndroid Build Coastguard Worker       * Walk the OID tree...
550*5e7646d2SAndroid Build Coastguard Worker       */
551*5e7646d2SAndroid Build Coastguard Worker 
552*5e7646d2SAndroid Build Coastguard Worker       scstatus = cupsSideChannelSNMPWalk(oid, 5.0, walk_cb, NULL);
553*5e7646d2SAndroid Build Coastguard Worker       printf("CUPS_SC_CMD_SNMP_WALK returned %s\n", statuses[scstatus]);
554*5e7646d2SAndroid Build Coastguard Worker     }
555*5e7646d2SAndroid Build Coastguard Worker     else
556*5e7646d2SAndroid Build Coastguard Worker     {
557*5e7646d2SAndroid Build Coastguard Worker      /*
558*5e7646d2SAndroid Build Coastguard Worker       * Lookup the same OID twice...
559*5e7646d2SAndroid Build Coastguard Worker       */
560*5e7646d2SAndroid Build Coastguard Worker 
561*5e7646d2SAndroid Build Coastguard Worker       length   = sizeof(buffer);
562*5e7646d2SAndroid Build Coastguard Worker       scstatus = cupsSideChannelSNMPGet(oid, buffer, &length, 5.0);
563*5e7646d2SAndroid Build Coastguard Worker       printf("CUPS_SC_CMD_SNMP_GET %s returned %s, %d bytes (%s)\n", oid,
564*5e7646d2SAndroid Build Coastguard Worker 	     statuses[scstatus], (int)length, buffer);
565*5e7646d2SAndroid Build Coastguard Worker 
566*5e7646d2SAndroid Build Coastguard Worker       length   = sizeof(buffer);
567*5e7646d2SAndroid Build Coastguard Worker       scstatus = cupsSideChannelSNMPGet(oid, buffer, &length, 5.0);
568*5e7646d2SAndroid Build Coastguard Worker       printf("CUPS_SC_CMD_SNMP_GET %s returned %s, %d bytes (%s)\n", oid,
569*5e7646d2SAndroid Build Coastguard Worker 	     statuses[scstatus], (int)length, buffer);
570*5e7646d2SAndroid Build Coastguard Worker     }
571*5e7646d2SAndroid Build Coastguard Worker 
572*5e7646d2SAndroid Build Coastguard Worker     length   = 0;
573*5e7646d2SAndroid Build Coastguard Worker     scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_SOFT_RESET, buffer,
574*5e7646d2SAndroid Build Coastguard Worker                                         &length, 5.0);
575*5e7646d2SAndroid Build Coastguard Worker     printf("CUPS_SC_CMD_SOFT_RESET returned %s\n", statuses[scstatus]);
576*5e7646d2SAndroid Build Coastguard Worker   }
577*5e7646d2SAndroid Build Coastguard Worker 
578*5e7646d2SAndroid Build Coastguard Worker   if (do_cancel)
579*5e7646d2SAndroid Build Coastguard Worker   {
580*5e7646d2SAndroid Build Coastguard Worker     sleep(1);
581*5e7646d2SAndroid Build Coastguard Worker     kill(data_pid, SIGTERM);
582*5e7646d2SAndroid Build Coastguard Worker     kill(back_pid, SIGTERM);
583*5e7646d2SAndroid Build Coastguard Worker   }
584*5e7646d2SAndroid Build Coastguard Worker 
585*5e7646d2SAndroid Build Coastguard Worker   while ((pid = wait(&status)) > 0)
586*5e7646d2SAndroid Build Coastguard Worker   {
587*5e7646d2SAndroid Build Coastguard Worker     if (status)
588*5e7646d2SAndroid Build Coastguard Worker     {
589*5e7646d2SAndroid Build Coastguard Worker       if (WIFEXITED(status))
590*5e7646d2SAndroid Build Coastguard Worker 	printf("%s exited with status %d!\n",
591*5e7646d2SAndroid Build Coastguard Worker 	       pid == back_pid ? backend : "test",
592*5e7646d2SAndroid Build Coastguard Worker 	       WEXITSTATUS(status));
593*5e7646d2SAndroid Build Coastguard Worker       else
594*5e7646d2SAndroid Build Coastguard Worker 	printf("%s crashed with signal %d!\n",
595*5e7646d2SAndroid Build Coastguard Worker 	       pid == back_pid ? backend : "test",
596*5e7646d2SAndroid Build Coastguard Worker 	       WTERMSIG(status));
597*5e7646d2SAndroid Build Coastguard Worker     }
598*5e7646d2SAndroid Build Coastguard Worker   }
599*5e7646d2SAndroid Build Coastguard Worker 
600*5e7646d2SAndroid Build Coastguard Worker  /*
601*5e7646d2SAndroid Build Coastguard Worker   * Exit accordingly...
602*5e7646d2SAndroid Build Coastguard Worker   */
603*5e7646d2SAndroid Build Coastguard Worker 
604*5e7646d2SAndroid Build Coastguard Worker   return (status != 0);
605*5e7646d2SAndroid Build Coastguard Worker }
606*5e7646d2SAndroid Build Coastguard Worker 
607*5e7646d2SAndroid Build Coastguard Worker 
608*5e7646d2SAndroid Build Coastguard Worker /*
609*5e7646d2SAndroid Build Coastguard Worker  * 'sigterm_handler()' - Flag when we get SIGTERM.
610*5e7646d2SAndroid Build Coastguard Worker  */
611*5e7646d2SAndroid Build Coastguard Worker 
612*5e7646d2SAndroid Build Coastguard Worker static void
sigterm_handler(int sig)613*5e7646d2SAndroid Build Coastguard Worker sigterm_handler(int sig)		/* I - Signal */
614*5e7646d2SAndroid Build Coastguard Worker {
615*5e7646d2SAndroid Build Coastguard Worker   (void)sig;
616*5e7646d2SAndroid Build Coastguard Worker 
617*5e7646d2SAndroid Build Coastguard Worker   job_canceled = 1;
618*5e7646d2SAndroid Build Coastguard Worker }
619*5e7646d2SAndroid Build Coastguard Worker 
620*5e7646d2SAndroid Build Coastguard Worker 
621*5e7646d2SAndroid Build Coastguard Worker /*
622*5e7646d2SAndroid Build Coastguard Worker  * 'usage()' - Show usage information.
623*5e7646d2SAndroid Build Coastguard Worker  */
624*5e7646d2SAndroid Build Coastguard Worker 
625*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)626*5e7646d2SAndroid Build Coastguard Worker usage(void)
627*5e7646d2SAndroid Build Coastguard Worker {
628*5e7646d2SAndroid Build Coastguard Worker   puts("Usage: testbackend [-cancel] [-d] [-ps | -pcl] [-s [-get OID] "
629*5e7646d2SAndroid Build Coastguard Worker        "[-walk OID]] [-t] device-uri job-id user title copies options [file]");
630*5e7646d2SAndroid Build Coastguard Worker   puts("");
631*5e7646d2SAndroid Build Coastguard Worker   puts("Options:");
632*5e7646d2SAndroid Build Coastguard Worker   puts("  -cancel     Simulate a canceled print job after 2 seconds.");
633*5e7646d2SAndroid Build Coastguard Worker   puts("  -d          Show log messages from backend.");
634*5e7646d2SAndroid Build Coastguard Worker   puts("  -get OID    Lookup the specified SNMP OID.");
635*5e7646d2SAndroid Build Coastguard Worker   puts("              (.1.3.6.1.2.1.43.10.2.1.4.1.1 is a good one for printers)");
636*5e7646d2SAndroid Build Coastguard Worker   puts("  -pcl        Send PCL+PJL query and test page to backend.");
637*5e7646d2SAndroid Build Coastguard Worker   puts("  -ps         Send PostScript query and test page to backend.");
638*5e7646d2SAndroid Build Coastguard Worker   puts("  -s          Do side-channel + SNMP tests.");
639*5e7646d2SAndroid Build Coastguard Worker   puts("  -t          Send spaces slowly to backend ('trickle').");
640*5e7646d2SAndroid Build Coastguard Worker   puts("  -walk OID   Walk the specified SNMP OID.");
641*5e7646d2SAndroid Build Coastguard Worker   puts("              (.1.3.6.1.2.1.43 is a good one for printers)");
642*5e7646d2SAndroid Build Coastguard Worker 
643*5e7646d2SAndroid Build Coastguard Worker   exit(1);
644*5e7646d2SAndroid Build Coastguard Worker }
645*5e7646d2SAndroid Build Coastguard Worker 
646*5e7646d2SAndroid Build Coastguard Worker 
647*5e7646d2SAndroid Build Coastguard Worker /*
648*5e7646d2SAndroid Build Coastguard Worker  * 'walk_cb()' - Show results of cupsSideChannelSNMPWalk...
649*5e7646d2SAndroid Build Coastguard Worker  */
650*5e7646d2SAndroid Build Coastguard Worker 
651*5e7646d2SAndroid Build Coastguard Worker static void
walk_cb(const char * oid,const char * data,int datalen,void * context)652*5e7646d2SAndroid Build Coastguard Worker walk_cb(const char *oid,		/* I - OID */
653*5e7646d2SAndroid Build Coastguard Worker         const char *data,		/* I - Data */
654*5e7646d2SAndroid Build Coastguard Worker 	int        datalen,		/* I - Length of data */
655*5e7646d2SAndroid Build Coastguard Worker 	void       *context)		/* I - Context (unused) */
656*5e7646d2SAndroid Build Coastguard Worker {
657*5e7646d2SAndroid Build Coastguard Worker   char temp[80];
658*5e7646d2SAndroid Build Coastguard Worker 
659*5e7646d2SAndroid Build Coastguard Worker   (void)context;
660*5e7646d2SAndroid Build Coastguard Worker 
661*5e7646d2SAndroid Build Coastguard Worker   if ((size_t)datalen > (sizeof(temp) - 1))
662*5e7646d2SAndroid Build Coastguard Worker   {
663*5e7646d2SAndroid Build Coastguard Worker     memcpy(temp, data, sizeof(temp) - 1);
664*5e7646d2SAndroid Build Coastguard Worker     temp[sizeof(temp) - 1] = '\0';
665*5e7646d2SAndroid Build Coastguard Worker   }
666*5e7646d2SAndroid Build Coastguard Worker   else
667*5e7646d2SAndroid Build Coastguard Worker   {
668*5e7646d2SAndroid Build Coastguard Worker     memcpy(temp, data, (size_t)datalen);
669*5e7646d2SAndroid Build Coastguard Worker     temp[datalen] = '\0';
670*5e7646d2SAndroid Build Coastguard Worker   }
671*5e7646d2SAndroid Build Coastguard Worker 
672*5e7646d2SAndroid Build Coastguard Worker   printf("CUPS_SC_CMD_SNMP_WALK %s, %d bytes (%s)\n", oid, datalen, temp);
673*5e7646d2SAndroid Build Coastguard Worker }
674