xref: /aosp_15_r20/external/libcups/scheduler/testlpd.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * cups-lpd test program for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2007-2015 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2006 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 information.
8*5e7646d2SAndroid Build Coastguard Worker  */
9*5e7646d2SAndroid Build Coastguard Worker 
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker  */
13*5e7646d2SAndroid Build Coastguard Worker 
14*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups.h>
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/string-private.h>
16*5e7646d2SAndroid Build Coastguard Worker #include <sys/stat.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <sys/wait.h>
18*5e7646d2SAndroid Build Coastguard Worker #include <signal.h>
19*5e7646d2SAndroid Build Coastguard Worker #include <unistd.h>
20*5e7646d2SAndroid Build Coastguard Worker #include <fcntl.h>
21*5e7646d2SAndroid Build Coastguard Worker 
22*5e7646d2SAndroid Build Coastguard Worker 
23*5e7646d2SAndroid Build Coastguard Worker /*
24*5e7646d2SAndroid Build Coastguard Worker  * Local functions...
25*5e7646d2SAndroid Build Coastguard Worker  */
26*5e7646d2SAndroid Build Coastguard Worker 
27*5e7646d2SAndroid Build Coastguard Worker static int	do_command(int outfd, int infd, const char *command);
28*5e7646d2SAndroid Build Coastguard Worker static int	print_job(int outfd, int infd, char *dest, char **args) _CUPS_NONNULL(4);
29*5e7646d2SAndroid Build Coastguard Worker static int	print_waiting(int outfd, int infd, char *dest);
30*5e7646d2SAndroid Build Coastguard Worker static int	remove_job(int outfd, int infd, char *dest, char **args) _CUPS_NONNULL(4);
31*5e7646d2SAndroid Build Coastguard Worker static int	status_long(int outfd, int infd, char *dest, char **args) _CUPS_NONNULL(4);
32*5e7646d2SAndroid Build Coastguard Worker static int	status_short(int outfd, int infd, char *dest, char **args) _CUPS_NONNULL(4);
33*5e7646d2SAndroid Build Coastguard Worker static void	usage(void) _CUPS_NORETURN;
34*5e7646d2SAndroid Build Coastguard Worker 
35*5e7646d2SAndroid Build Coastguard Worker 
36*5e7646d2SAndroid Build Coastguard Worker /*
37*5e7646d2SAndroid Build Coastguard Worker  * 'main()' - Simulate an LPD client.
38*5e7646d2SAndroid Build Coastguard Worker  */
39*5e7646d2SAndroid Build Coastguard Worker 
40*5e7646d2SAndroid Build Coastguard Worker int					/* O - Exit status */
main(int argc,char * argv[])41*5e7646d2SAndroid Build Coastguard Worker main(int  argc,				/* I - Number of command-line arguments */
42*5e7646d2SAndroid Build Coastguard Worker      char *argv[])			/* I - Command-line arguments */
43*5e7646d2SAndroid Build Coastguard Worker {
44*5e7646d2SAndroid Build Coastguard Worker   int	i;				/* Looping var */
45*5e7646d2SAndroid Build Coastguard Worker   int	status;				/* Test status */
46*5e7646d2SAndroid Build Coastguard Worker   char	*op,				/* Operation to test */
47*5e7646d2SAndroid Build Coastguard Worker 	**opargs,			/* Remaining arguments */
48*5e7646d2SAndroid Build Coastguard Worker 	*dest;				/* Destination */
49*5e7646d2SAndroid Build Coastguard Worker   int	cupslpd_argc;			/* Argument count for cups-lpd */
50*5e7646d2SAndroid Build Coastguard Worker   char	*cupslpd_argv[1000];		/* Arguments for cups-lpd */
51*5e7646d2SAndroid Build Coastguard Worker   int	cupslpd_stdin[2],		/* Standard input for cups-lpd */
52*5e7646d2SAndroid Build Coastguard Worker 	cupslpd_stdout[2],		/* Standard output for cups-lpd */
53*5e7646d2SAndroid Build Coastguard Worker 	cupslpd_pid,			/* Process ID for cups-lpd */
54*5e7646d2SAndroid Build Coastguard Worker 	cupslpd_status;			/* Status of cups-lpd process */
55*5e7646d2SAndroid Build Coastguard Worker 
56*5e7646d2SAndroid Build Coastguard Worker 
57*5e7646d2SAndroid Build Coastguard Worker  /*
58*5e7646d2SAndroid Build Coastguard Worker   * Collect command-line arguments...
59*5e7646d2SAndroid Build Coastguard Worker   */
60*5e7646d2SAndroid Build Coastguard Worker 
61*5e7646d2SAndroid Build Coastguard Worker   op              = NULL;
62*5e7646d2SAndroid Build Coastguard Worker   opargs          = argv + argc;
63*5e7646d2SAndroid Build Coastguard Worker   dest            = NULL;
64*5e7646d2SAndroid Build Coastguard Worker   cupslpd_argc    = 1;
65*5e7646d2SAndroid Build Coastguard Worker   cupslpd_argv[0] = (char *)"cups-lpd";
66*5e7646d2SAndroid Build Coastguard Worker 
67*5e7646d2SAndroid Build Coastguard Worker   for (i = 1; i < argc; i ++)
68*5e7646d2SAndroid Build Coastguard Worker     if (!strncmp(argv[i], "-o", 2))
69*5e7646d2SAndroid Build Coastguard Worker     {
70*5e7646d2SAndroid Build Coastguard Worker       cupslpd_argv[cupslpd_argc++] = argv[i];
71*5e7646d2SAndroid Build Coastguard Worker 
72*5e7646d2SAndroid Build Coastguard Worker       if (!argv[i][2])
73*5e7646d2SAndroid Build Coastguard Worker       {
74*5e7646d2SAndroid Build Coastguard Worker         i ++;
75*5e7646d2SAndroid Build Coastguard Worker 
76*5e7646d2SAndroid Build Coastguard Worker 	if (i >= argc)
77*5e7646d2SAndroid Build Coastguard Worker 	  usage();
78*5e7646d2SAndroid Build Coastguard Worker 
79*5e7646d2SAndroid Build Coastguard Worker 	cupslpd_argv[cupslpd_argc++] = argv[i];
80*5e7646d2SAndroid Build Coastguard Worker       }
81*5e7646d2SAndroid Build Coastguard Worker     }
82*5e7646d2SAndroid Build Coastguard Worker     else if (argv[i][0] == '-')
83*5e7646d2SAndroid Build Coastguard Worker       usage();
84*5e7646d2SAndroid Build Coastguard Worker     else if (!op)
85*5e7646d2SAndroid Build Coastguard Worker       op = argv[i];
86*5e7646d2SAndroid Build Coastguard Worker     else if (!dest)
87*5e7646d2SAndroid Build Coastguard Worker       dest = argv[i];
88*5e7646d2SAndroid Build Coastguard Worker     else
89*5e7646d2SAndroid Build Coastguard Worker     {
90*5e7646d2SAndroid Build Coastguard Worker       opargs = argv + i;
91*5e7646d2SAndroid Build Coastguard Worker       break;
92*5e7646d2SAndroid Build Coastguard Worker     }
93*5e7646d2SAndroid Build Coastguard Worker 
94*5e7646d2SAndroid Build Coastguard Worker   if (!op ||
95*5e7646d2SAndroid Build Coastguard Worker       (!strcmp(op, "print-job") && (!dest || !opargs)) ||
96*5e7646d2SAndroid Build Coastguard Worker       (!strcmp(op, "remove-job") && (!dest || !opargs)) ||
97*5e7646d2SAndroid Build Coastguard Worker       (strcmp(op, "print-job") && strcmp(op, "print-waiting") &&
98*5e7646d2SAndroid Build Coastguard Worker        strcmp(op, "remove-job") && strcmp(op, "status-long") &&
99*5e7646d2SAndroid Build Coastguard Worker        strcmp(op, "status-short")))
100*5e7646d2SAndroid Build Coastguard Worker   {
101*5e7646d2SAndroid Build Coastguard Worker     printf("op=\"%s\", dest=\"%s\", opargs=%p\n", op, dest, opargs);
102*5e7646d2SAndroid Build Coastguard Worker     usage();
103*5e7646d2SAndroid Build Coastguard Worker   }
104*5e7646d2SAndroid Build Coastguard Worker 
105*5e7646d2SAndroid Build Coastguard Worker  /*
106*5e7646d2SAndroid Build Coastguard Worker   * Run the cups-lpd program using pipes...
107*5e7646d2SAndroid Build Coastguard Worker   */
108*5e7646d2SAndroid Build Coastguard Worker 
109*5e7646d2SAndroid Build Coastguard Worker   cupslpd_argv[cupslpd_argc] = NULL;
110*5e7646d2SAndroid Build Coastguard Worker 
111*5e7646d2SAndroid Build Coastguard Worker   pipe(cupslpd_stdin);
112*5e7646d2SAndroid Build Coastguard Worker   pipe(cupslpd_stdout);
113*5e7646d2SAndroid Build Coastguard Worker 
114*5e7646d2SAndroid Build Coastguard Worker   if ((cupslpd_pid = fork()) < 0)
115*5e7646d2SAndroid Build Coastguard Worker   {
116*5e7646d2SAndroid Build Coastguard Worker    /*
117*5e7646d2SAndroid Build Coastguard Worker     * Error!
118*5e7646d2SAndroid Build Coastguard Worker     */
119*5e7646d2SAndroid Build Coastguard Worker 
120*5e7646d2SAndroid Build Coastguard Worker     perror("testlpd: Unable to fork");
121*5e7646d2SAndroid Build Coastguard Worker     return (1);
122*5e7646d2SAndroid Build Coastguard Worker   }
123*5e7646d2SAndroid Build Coastguard Worker   else if (cupslpd_pid == 0)
124*5e7646d2SAndroid Build Coastguard Worker   {
125*5e7646d2SAndroid Build Coastguard Worker    /*
126*5e7646d2SAndroid Build Coastguard Worker     * Child goes here...
127*5e7646d2SAndroid Build Coastguard Worker     */
128*5e7646d2SAndroid Build Coastguard Worker 
129*5e7646d2SAndroid Build Coastguard Worker     dup2(cupslpd_stdin[0], 0);
130*5e7646d2SAndroid Build Coastguard Worker     close(cupslpd_stdin[0]);
131*5e7646d2SAndroid Build Coastguard Worker     close(cupslpd_stdin[1]);
132*5e7646d2SAndroid Build Coastguard Worker 
133*5e7646d2SAndroid Build Coastguard Worker     dup2(cupslpd_stdout[1], 1);
134*5e7646d2SAndroid Build Coastguard Worker     close(cupslpd_stdout[0]);
135*5e7646d2SAndroid Build Coastguard Worker     close(cupslpd_stdout[1]);
136*5e7646d2SAndroid Build Coastguard Worker 
137*5e7646d2SAndroid Build Coastguard Worker     execv("./cups-lpd", cupslpd_argv);
138*5e7646d2SAndroid Build Coastguard Worker 
139*5e7646d2SAndroid Build Coastguard Worker     perror("testlpd: Unable to exec ./cups-lpd");
140*5e7646d2SAndroid Build Coastguard Worker     exit(errno);
141*5e7646d2SAndroid Build Coastguard Worker   }
142*5e7646d2SAndroid Build Coastguard Worker   else
143*5e7646d2SAndroid Build Coastguard Worker   {
144*5e7646d2SAndroid Build Coastguard Worker     close(cupslpd_stdin[0]);
145*5e7646d2SAndroid Build Coastguard Worker     close(cupslpd_stdout[1]);
146*5e7646d2SAndroid Build Coastguard Worker   }
147*5e7646d2SAndroid Build Coastguard Worker 
148*5e7646d2SAndroid Build Coastguard Worker  /*
149*5e7646d2SAndroid Build Coastguard Worker   * Do the operation test...
150*5e7646d2SAndroid Build Coastguard Worker   */
151*5e7646d2SAndroid Build Coastguard Worker 
152*5e7646d2SAndroid Build Coastguard Worker   if (!strcmp(op, "print-job"))
153*5e7646d2SAndroid Build Coastguard Worker     status = print_job(cupslpd_stdin[1], cupslpd_stdout[0], dest, opargs);
154*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(op, "print-waiting"))
155*5e7646d2SAndroid Build Coastguard Worker     status = print_waiting(cupslpd_stdin[1], cupslpd_stdout[0], dest);
156*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(op, "remove-job"))
157*5e7646d2SAndroid Build Coastguard Worker     status = remove_job(cupslpd_stdin[1], cupslpd_stdout[0], dest, opargs);
158*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(op, "status-long"))
159*5e7646d2SAndroid Build Coastguard Worker     status = status_long(cupslpd_stdin[1], cupslpd_stdout[0], dest, opargs);
160*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(op, "status-short"))
161*5e7646d2SAndroid Build Coastguard Worker     status = status_short(cupslpd_stdin[1], cupslpd_stdout[0], dest, opargs);
162*5e7646d2SAndroid Build Coastguard Worker   else
163*5e7646d2SAndroid Build Coastguard Worker   {
164*5e7646d2SAndroid Build Coastguard Worker     printf("Unknown operation \"%s\"!\n", op);
165*5e7646d2SAndroid Build Coastguard Worker     status = 1;
166*5e7646d2SAndroid Build Coastguard Worker   }
167*5e7646d2SAndroid Build Coastguard Worker 
168*5e7646d2SAndroid Build Coastguard Worker  /*
169*5e7646d2SAndroid Build Coastguard Worker   * Kill the test program...
170*5e7646d2SAndroid Build Coastguard Worker   */
171*5e7646d2SAndroid Build Coastguard Worker 
172*5e7646d2SAndroid Build Coastguard Worker   close(cupslpd_stdin[1]);
173*5e7646d2SAndroid Build Coastguard Worker   close(cupslpd_stdout[0]);
174*5e7646d2SAndroid Build Coastguard Worker 
175*5e7646d2SAndroid Build Coastguard Worker   while (wait(&cupslpd_status) != cupslpd_pid);
176*5e7646d2SAndroid Build Coastguard Worker 
177*5e7646d2SAndroid Build Coastguard Worker   printf("cups-lpd exit status was %d...\n", cupslpd_status);
178*5e7646d2SAndroid Build Coastguard Worker 
179*5e7646d2SAndroid Build Coastguard Worker  /*
180*5e7646d2SAndroid Build Coastguard Worker   * Return the test status...
181*5e7646d2SAndroid Build Coastguard Worker   */
182*5e7646d2SAndroid Build Coastguard Worker 
183*5e7646d2SAndroid Build Coastguard Worker   return (status);
184*5e7646d2SAndroid Build Coastguard Worker }
185*5e7646d2SAndroid Build Coastguard Worker 
186*5e7646d2SAndroid Build Coastguard Worker 
187*5e7646d2SAndroid Build Coastguard Worker /*
188*5e7646d2SAndroid Build Coastguard Worker  * 'do_command()' - Send the LPD command and wait for a response.
189*5e7646d2SAndroid Build Coastguard Worker  */
190*5e7646d2SAndroid Build Coastguard Worker 
191*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Status from cups-lpd */
do_command(int outfd,int infd,const char * command)192*5e7646d2SAndroid Build Coastguard Worker do_command(int        outfd,		/* I - Command file descriptor */
193*5e7646d2SAndroid Build Coastguard Worker            int        infd,		/* I - Response file descriptor */
194*5e7646d2SAndroid Build Coastguard Worker 	   const char *command)		/* I - Command line to send */
195*5e7646d2SAndroid Build Coastguard Worker {
196*5e7646d2SAndroid Build Coastguard Worker   size_t	len;			/* Length of command line */
197*5e7646d2SAndroid Build Coastguard Worker   char		status;			/* Status byte */
198*5e7646d2SAndroid Build Coastguard Worker 
199*5e7646d2SAndroid Build Coastguard Worker 
200*5e7646d2SAndroid Build Coastguard Worker   printf("COMMAND: %02X %s", command[0], command + 1);
201*5e7646d2SAndroid Build Coastguard Worker 
202*5e7646d2SAndroid Build Coastguard Worker   len = strlen(command);
203*5e7646d2SAndroid Build Coastguard Worker 
204*5e7646d2SAndroid Build Coastguard Worker   if ((size_t)write(outfd, command, len) < len)
205*5e7646d2SAndroid Build Coastguard Worker   {
206*5e7646d2SAndroid Build Coastguard Worker     puts("    Write failed!");
207*5e7646d2SAndroid Build Coastguard Worker     return (-1);
208*5e7646d2SAndroid Build Coastguard Worker   }
209*5e7646d2SAndroid Build Coastguard Worker 
210*5e7646d2SAndroid Build Coastguard Worker   if (read(infd, &status, 1) < 1)
211*5e7646d2SAndroid Build Coastguard Worker     puts("STATUS: ERROR");
212*5e7646d2SAndroid Build Coastguard Worker   else
213*5e7646d2SAndroid Build Coastguard Worker     printf("STATUS: %d\n", status);
214*5e7646d2SAndroid Build Coastguard Worker 
215*5e7646d2SAndroid Build Coastguard Worker   return (status);
216*5e7646d2SAndroid Build Coastguard Worker }
217*5e7646d2SAndroid Build Coastguard Worker 
218*5e7646d2SAndroid Build Coastguard Worker 
219*5e7646d2SAndroid Build Coastguard Worker /*
220*5e7646d2SAndroid Build Coastguard Worker  * 'print_job()' - Submit a file for printing.
221*5e7646d2SAndroid Build Coastguard Worker  */
222*5e7646d2SAndroid Build Coastguard Worker 
223*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Status from cups-lpd */
print_job(int outfd,int infd,char * dest,char ** args)224*5e7646d2SAndroid Build Coastguard Worker print_job(int  outfd,			/* I - Command file descriptor */
225*5e7646d2SAndroid Build Coastguard Worker           int  infd,			/* I - Response file descriptor */
226*5e7646d2SAndroid Build Coastguard Worker 	  char *dest,			/* I - Destination */
227*5e7646d2SAndroid Build Coastguard Worker 	  char **args)			/* I - Arguments */
228*5e7646d2SAndroid Build Coastguard Worker {
229*5e7646d2SAndroid Build Coastguard Worker   int		fd;			/* Print file descriptor */
230*5e7646d2SAndroid Build Coastguard Worker   char		command[1024],		/* Command buffer */
231*5e7646d2SAndroid Build Coastguard Worker 		control[1024],		/* Control file */
232*5e7646d2SAndroid Build Coastguard Worker 		buffer[8192];		/* Print buffer */
233*5e7646d2SAndroid Build Coastguard Worker   int		status;			/* Status of command */
234*5e7646d2SAndroid Build Coastguard Worker   struct stat	fileinfo;		/* File information */
235*5e7646d2SAndroid Build Coastguard Worker   char		*jobname;		/* Job name */
236*5e7646d2SAndroid Build Coastguard Worker   int		sequence;		/* Sequence number */
237*5e7646d2SAndroid Build Coastguard Worker   ssize_t	bytes;			/* Bytes read/written */
238*5e7646d2SAndroid Build Coastguard Worker 
239*5e7646d2SAndroid Build Coastguard Worker 
240*5e7646d2SAndroid Build Coastguard Worker  /*
241*5e7646d2SAndroid Build Coastguard Worker   * Check the print file...
242*5e7646d2SAndroid Build Coastguard Worker   */
243*5e7646d2SAndroid Build Coastguard Worker 
244*5e7646d2SAndroid Build Coastguard Worker   if (stat(args[0], &fileinfo))
245*5e7646d2SAndroid Build Coastguard Worker   {
246*5e7646d2SAndroid Build Coastguard Worker     perror(args[0]);
247*5e7646d2SAndroid Build Coastguard Worker     return (-1);
248*5e7646d2SAndroid Build Coastguard Worker   }
249*5e7646d2SAndroid Build Coastguard Worker 
250*5e7646d2SAndroid Build Coastguard Worker   if ((fd = open(args[0], O_RDONLY)) < 0)
251*5e7646d2SAndroid Build Coastguard Worker   {
252*5e7646d2SAndroid Build Coastguard Worker     perror(args[0]);
253*5e7646d2SAndroid Build Coastguard Worker     return (-1);
254*5e7646d2SAndroid Build Coastguard Worker   }
255*5e7646d2SAndroid Build Coastguard Worker 
256*5e7646d2SAndroid Build Coastguard Worker  /*
257*5e7646d2SAndroid Build Coastguard Worker   * Send the "receive print job" command...
258*5e7646d2SAndroid Build Coastguard Worker   */
259*5e7646d2SAndroid Build Coastguard Worker 
260*5e7646d2SAndroid Build Coastguard Worker   snprintf(command, sizeof(command), "\002%s\n", dest);
261*5e7646d2SAndroid Build Coastguard Worker   if ((status = do_command(outfd, infd, command)) != 0)
262*5e7646d2SAndroid Build Coastguard Worker   {
263*5e7646d2SAndroid Build Coastguard Worker     close(fd);
264*5e7646d2SAndroid Build Coastguard Worker     return (status);
265*5e7646d2SAndroid Build Coastguard Worker   }
266*5e7646d2SAndroid Build Coastguard Worker 
267*5e7646d2SAndroid Build Coastguard Worker  /*
268*5e7646d2SAndroid Build Coastguard Worker   * Format a control file string that will be used to submit the job...
269*5e7646d2SAndroid Build Coastguard Worker   */
270*5e7646d2SAndroid Build Coastguard Worker 
271*5e7646d2SAndroid Build Coastguard Worker   if ((jobname = strrchr(args[0], '/')) != NULL)
272*5e7646d2SAndroid Build Coastguard Worker     jobname ++;
273*5e7646d2SAndroid Build Coastguard Worker   else
274*5e7646d2SAndroid Build Coastguard Worker     jobname = args[0];
275*5e7646d2SAndroid Build Coastguard Worker 
276*5e7646d2SAndroid Build Coastguard Worker   sequence = (int)getpid() % 1000;
277*5e7646d2SAndroid Build Coastguard Worker 
278*5e7646d2SAndroid Build Coastguard Worker   snprintf(control, sizeof(control),
279*5e7646d2SAndroid Build Coastguard Worker            "Hlocalhost\n"
280*5e7646d2SAndroid Build Coastguard Worker            "P%s\n"
281*5e7646d2SAndroid Build Coastguard Worker            "J%s\n"
282*5e7646d2SAndroid Build Coastguard Worker            "ldfA%03dlocalhost\n"
283*5e7646d2SAndroid Build Coastguard Worker            "UdfA%03dlocalhost\n"
284*5e7646d2SAndroid Build Coastguard Worker            "N%s\n",
285*5e7646d2SAndroid Build Coastguard Worker 	   cupsUser(), jobname, sequence, sequence, jobname);
286*5e7646d2SAndroid Build Coastguard Worker 
287*5e7646d2SAndroid Build Coastguard Worker  /*
288*5e7646d2SAndroid Build Coastguard Worker   * Send the control file...
289*5e7646d2SAndroid Build Coastguard Worker   */
290*5e7646d2SAndroid Build Coastguard Worker 
291*5e7646d2SAndroid Build Coastguard Worker   bytes = (ssize_t)strlen(control);
292*5e7646d2SAndroid Build Coastguard Worker 
293*5e7646d2SAndroid Build Coastguard Worker   snprintf(command, sizeof(command), "\002%d cfA%03dlocalhost\n",
294*5e7646d2SAndroid Build Coastguard Worker            (int)bytes, sequence);
295*5e7646d2SAndroid Build Coastguard Worker 
296*5e7646d2SAndroid Build Coastguard Worker   if ((status = do_command(outfd, infd, command)) != 0)
297*5e7646d2SAndroid Build Coastguard Worker   {
298*5e7646d2SAndroid Build Coastguard Worker     close(fd);
299*5e7646d2SAndroid Build Coastguard Worker     return (status);
300*5e7646d2SAndroid Build Coastguard Worker   }
301*5e7646d2SAndroid Build Coastguard Worker 
302*5e7646d2SAndroid Build Coastguard Worker   bytes ++;
303*5e7646d2SAndroid Build Coastguard Worker 
304*5e7646d2SAndroid Build Coastguard Worker   if (write(outfd, control, (size_t)bytes) < bytes)
305*5e7646d2SAndroid Build Coastguard Worker   {
306*5e7646d2SAndroid Build Coastguard Worker     printf("CONTROL: Unable to write %d bytes!\n", (int)bytes);
307*5e7646d2SAndroid Build Coastguard Worker     close(fd);
308*5e7646d2SAndroid Build Coastguard Worker     return (-1);
309*5e7646d2SAndroid Build Coastguard Worker   }
310*5e7646d2SAndroid Build Coastguard Worker 
311*5e7646d2SAndroid Build Coastguard Worker   printf("CONTROL: Wrote %d bytes.\n", (int)bytes);
312*5e7646d2SAndroid Build Coastguard Worker 
313*5e7646d2SAndroid Build Coastguard Worker   if (read(infd, command, 1) < 1)
314*5e7646d2SAndroid Build Coastguard Worker   {
315*5e7646d2SAndroid Build Coastguard Worker     puts("STATUS: ERROR");
316*5e7646d2SAndroid Build Coastguard Worker     close(fd);
317*5e7646d2SAndroid Build Coastguard Worker     return (-1);
318*5e7646d2SAndroid Build Coastguard Worker   }
319*5e7646d2SAndroid Build Coastguard Worker   else
320*5e7646d2SAndroid Build Coastguard Worker   {
321*5e7646d2SAndroid Build Coastguard Worker     status = command[0];
322*5e7646d2SAndroid Build Coastguard Worker 
323*5e7646d2SAndroid Build Coastguard Worker     printf("STATUS: %d\n", status);
324*5e7646d2SAndroid Build Coastguard Worker   }
325*5e7646d2SAndroid Build Coastguard Worker 
326*5e7646d2SAndroid Build Coastguard Worker  /*
327*5e7646d2SAndroid Build Coastguard Worker   * Send the data file...
328*5e7646d2SAndroid Build Coastguard Worker   */
329*5e7646d2SAndroid Build Coastguard Worker 
330*5e7646d2SAndroid Build Coastguard Worker   snprintf(command, sizeof(command), "\003%d dfA%03dlocalhost\n",
331*5e7646d2SAndroid Build Coastguard Worker            (int)fileinfo.st_size, sequence);
332*5e7646d2SAndroid Build Coastguard Worker 
333*5e7646d2SAndroid Build Coastguard Worker   if ((status = do_command(outfd, infd, command)) != 0)
334*5e7646d2SAndroid Build Coastguard Worker   {
335*5e7646d2SAndroid Build Coastguard Worker     close(fd);
336*5e7646d2SAndroid Build Coastguard Worker     return (status);
337*5e7646d2SAndroid Build Coastguard Worker   }
338*5e7646d2SAndroid Build Coastguard Worker 
339*5e7646d2SAndroid Build Coastguard Worker   while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
340*5e7646d2SAndroid Build Coastguard Worker   {
341*5e7646d2SAndroid Build Coastguard Worker     if (write(outfd, buffer, (size_t)bytes) < bytes)
342*5e7646d2SAndroid Build Coastguard Worker     {
343*5e7646d2SAndroid Build Coastguard Worker       printf("DATA: Unable to write %d bytes!\n", (int)bytes);
344*5e7646d2SAndroid Build Coastguard Worker       close(fd);
345*5e7646d2SAndroid Build Coastguard Worker       return (-1);
346*5e7646d2SAndroid Build Coastguard Worker     }
347*5e7646d2SAndroid Build Coastguard Worker   }
348*5e7646d2SAndroid Build Coastguard Worker 
349*5e7646d2SAndroid Build Coastguard Worker   write(outfd, "", 1);
350*5e7646d2SAndroid Build Coastguard Worker 
351*5e7646d2SAndroid Build Coastguard Worker   close(fd);
352*5e7646d2SAndroid Build Coastguard Worker 
353*5e7646d2SAndroid Build Coastguard Worker   printf("DATA: Wrote %d bytes.\n", (int)fileinfo.st_size);
354*5e7646d2SAndroid Build Coastguard Worker 
355*5e7646d2SAndroid Build Coastguard Worker   if (read(infd, command, 1) < 1)
356*5e7646d2SAndroid Build Coastguard Worker   {
357*5e7646d2SAndroid Build Coastguard Worker     puts("STATUS: ERROR");
358*5e7646d2SAndroid Build Coastguard Worker     close(fd);
359*5e7646d2SAndroid Build Coastguard Worker     return (-1);
360*5e7646d2SAndroid Build Coastguard Worker   }
361*5e7646d2SAndroid Build Coastguard Worker   else
362*5e7646d2SAndroid Build Coastguard Worker   {
363*5e7646d2SAndroid Build Coastguard Worker     status = command[0];
364*5e7646d2SAndroid Build Coastguard Worker 
365*5e7646d2SAndroid Build Coastguard Worker     printf("STATUS: %d\n", status);
366*5e7646d2SAndroid Build Coastguard Worker   }
367*5e7646d2SAndroid Build Coastguard Worker 
368*5e7646d2SAndroid Build Coastguard Worker   return (status);
369*5e7646d2SAndroid Build Coastguard Worker }
370*5e7646d2SAndroid Build Coastguard Worker 
371*5e7646d2SAndroid Build Coastguard Worker 
372*5e7646d2SAndroid Build Coastguard Worker /*
373*5e7646d2SAndroid Build Coastguard Worker  * 'print_waiting()' - Print waiting jobs.
374*5e7646d2SAndroid Build Coastguard Worker  */
375*5e7646d2SAndroid Build Coastguard Worker 
376*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Status from cups-lpd */
print_waiting(int outfd,int infd,char * dest)377*5e7646d2SAndroid Build Coastguard Worker print_waiting(int  outfd,		/* I - Command file descriptor */
378*5e7646d2SAndroid Build Coastguard Worker               int  infd,		/* I - Response file descriptor */
379*5e7646d2SAndroid Build Coastguard Worker 	      char *dest)		/* I - Destination */
380*5e7646d2SAndroid Build Coastguard Worker {
381*5e7646d2SAndroid Build Coastguard Worker   char		command[1024];		/* Command buffer */
382*5e7646d2SAndroid Build Coastguard Worker 
383*5e7646d2SAndroid Build Coastguard Worker 
384*5e7646d2SAndroid Build Coastguard Worker  /*
385*5e7646d2SAndroid Build Coastguard Worker   * Send the "print waiting jobs" command...
386*5e7646d2SAndroid Build Coastguard Worker   */
387*5e7646d2SAndroid Build Coastguard Worker 
388*5e7646d2SAndroid Build Coastguard Worker   snprintf(command, sizeof(command), "\001%s\n", dest);
389*5e7646d2SAndroid Build Coastguard Worker 
390*5e7646d2SAndroid Build Coastguard Worker   return (do_command(outfd, infd, command));
391*5e7646d2SAndroid Build Coastguard Worker }
392*5e7646d2SAndroid Build Coastguard Worker 
393*5e7646d2SAndroid Build Coastguard Worker 
394*5e7646d2SAndroid Build Coastguard Worker /*
395*5e7646d2SAndroid Build Coastguard Worker  * 'remove_job()' - Cancel a print job.
396*5e7646d2SAndroid Build Coastguard Worker  */
397*5e7646d2SAndroid Build Coastguard Worker 
398*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Status from cups-lpd */
remove_job(int outfd,int infd,char * dest,char ** args)399*5e7646d2SAndroid Build Coastguard Worker remove_job(int  outfd,			/* I - Command file descriptor */
400*5e7646d2SAndroid Build Coastguard Worker            int  infd,			/* I - Response file descriptor */
401*5e7646d2SAndroid Build Coastguard Worker 	   char *dest,			/* I - Destination */
402*5e7646d2SAndroid Build Coastguard Worker 	   char **args)			/* I - Arguments */
403*5e7646d2SAndroid Build Coastguard Worker {
404*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
405*5e7646d2SAndroid Build Coastguard Worker   char		command[1024];		/* Command buffer */
406*5e7646d2SAndroid Build Coastguard Worker 
407*5e7646d2SAndroid Build Coastguard Worker  /*
408*5e7646d2SAndroid Build Coastguard Worker   * Send the "remove jobs" command...
409*5e7646d2SAndroid Build Coastguard Worker   */
410*5e7646d2SAndroid Build Coastguard Worker 
411*5e7646d2SAndroid Build Coastguard Worker   snprintf(command, sizeof(command), "\005%s", dest);
412*5e7646d2SAndroid Build Coastguard Worker 
413*5e7646d2SAndroid Build Coastguard Worker   for (i = 0; args[i]; i ++)
414*5e7646d2SAndroid Build Coastguard Worker   {
415*5e7646d2SAndroid Build Coastguard Worker     strlcat(command, " ", sizeof(command));
416*5e7646d2SAndroid Build Coastguard Worker     strlcat(command, args[i], sizeof(command));
417*5e7646d2SAndroid Build Coastguard Worker   }
418*5e7646d2SAndroid Build Coastguard Worker 
419*5e7646d2SAndroid Build Coastguard Worker   strlcat(command, "\n", sizeof(command));
420*5e7646d2SAndroid Build Coastguard Worker 
421*5e7646d2SAndroid Build Coastguard Worker   return (do_command(outfd, infd, command));
422*5e7646d2SAndroid Build Coastguard Worker }
423*5e7646d2SAndroid Build Coastguard Worker 
424*5e7646d2SAndroid Build Coastguard Worker 
425*5e7646d2SAndroid Build Coastguard Worker /*
426*5e7646d2SAndroid Build Coastguard Worker  * 'status_long()' - Show the long printer status.
427*5e7646d2SAndroid Build Coastguard Worker  */
428*5e7646d2SAndroid Build Coastguard Worker 
429*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Status from cups-lpd */
status_long(int outfd,int infd,char * dest,char ** args)430*5e7646d2SAndroid Build Coastguard Worker status_long(int  outfd,			/* I - Command file descriptor */
431*5e7646d2SAndroid Build Coastguard Worker             int  infd,			/* I - Response file descriptor */
432*5e7646d2SAndroid Build Coastguard Worker 	    char *dest,			/* I - Destination */
433*5e7646d2SAndroid Build Coastguard Worker 	    char **args)		/* I - Arguments */
434*5e7646d2SAndroid Build Coastguard Worker {
435*5e7646d2SAndroid Build Coastguard Worker   char		command[1024],		/* Command buffer */
436*5e7646d2SAndroid Build Coastguard Worker 		buffer[8192];		/* Status buffer */
437*5e7646d2SAndroid Build Coastguard Worker   ssize_t	bytes;			/* Bytes read/written */
438*5e7646d2SAndroid Build Coastguard Worker 
439*5e7646d2SAndroid Build Coastguard Worker 
440*5e7646d2SAndroid Build Coastguard Worker  /*
441*5e7646d2SAndroid Build Coastguard Worker   * Send the "send short status" command...
442*5e7646d2SAndroid Build Coastguard Worker   */
443*5e7646d2SAndroid Build Coastguard Worker 
444*5e7646d2SAndroid Build Coastguard Worker   if (args[0])
445*5e7646d2SAndroid Build Coastguard Worker     snprintf(command, sizeof(command), "\004%s %s\n", dest, args[0]);
446*5e7646d2SAndroid Build Coastguard Worker   else
447*5e7646d2SAndroid Build Coastguard Worker     snprintf(command, sizeof(command), "\004%s\n", dest);
448*5e7646d2SAndroid Build Coastguard Worker 
449*5e7646d2SAndroid Build Coastguard Worker   bytes = (ssize_t)strlen(command);
450*5e7646d2SAndroid Build Coastguard Worker 
451*5e7646d2SAndroid Build Coastguard Worker   if (write(outfd, command, (size_t)bytes) < bytes)
452*5e7646d2SAndroid Build Coastguard Worker     return (-1);
453*5e7646d2SAndroid Build Coastguard Worker 
454*5e7646d2SAndroid Build Coastguard Worker  /*
455*5e7646d2SAndroid Build Coastguard Worker   * Read the status back...
456*5e7646d2SAndroid Build Coastguard Worker   */
457*5e7646d2SAndroid Build Coastguard Worker 
458*5e7646d2SAndroid Build Coastguard Worker   while ((bytes = read(infd, buffer, sizeof(buffer))) > 0)
459*5e7646d2SAndroid Build Coastguard Worker   {
460*5e7646d2SAndroid Build Coastguard Worker     fwrite(buffer, 1, (size_t)bytes, stdout);
461*5e7646d2SAndroid Build Coastguard Worker     fflush(stdout);
462*5e7646d2SAndroid Build Coastguard Worker   }
463*5e7646d2SAndroid Build Coastguard Worker 
464*5e7646d2SAndroid Build Coastguard Worker   return (0);
465*5e7646d2SAndroid Build Coastguard Worker }
466*5e7646d2SAndroid Build Coastguard Worker 
467*5e7646d2SAndroid Build Coastguard Worker 
468*5e7646d2SAndroid Build Coastguard Worker /*
469*5e7646d2SAndroid Build Coastguard Worker  * 'status_short()' - Show the short printer status.
470*5e7646d2SAndroid Build Coastguard Worker  */
471*5e7646d2SAndroid Build Coastguard Worker 
472*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Status from cups-lpd */
status_short(int outfd,int infd,char * dest,char ** args)473*5e7646d2SAndroid Build Coastguard Worker status_short(int  outfd,		/* I - Command file descriptor */
474*5e7646d2SAndroid Build Coastguard Worker              int  infd,			/* I - Response file descriptor */
475*5e7646d2SAndroid Build Coastguard Worker 	     char *dest,		/* I - Destination */
476*5e7646d2SAndroid Build Coastguard Worker 	     char **args)		/* I - Arguments */
477*5e7646d2SAndroid Build Coastguard Worker {
478*5e7646d2SAndroid Build Coastguard Worker   char		command[1024],		/* Command buffer */
479*5e7646d2SAndroid Build Coastguard Worker 		buffer[8192];		/* Status buffer */
480*5e7646d2SAndroid Build Coastguard Worker   ssize_t	bytes;			/* Bytes read/written */
481*5e7646d2SAndroid Build Coastguard Worker 
482*5e7646d2SAndroid Build Coastguard Worker 
483*5e7646d2SAndroid Build Coastguard Worker  /*
484*5e7646d2SAndroid Build Coastguard Worker   * Send the "send short status" command...
485*5e7646d2SAndroid Build Coastguard Worker   */
486*5e7646d2SAndroid Build Coastguard Worker 
487*5e7646d2SAndroid Build Coastguard Worker   if (args[0])
488*5e7646d2SAndroid Build Coastguard Worker     snprintf(command, sizeof(command), "\003%s %s\n", dest, args[0]);
489*5e7646d2SAndroid Build Coastguard Worker   else
490*5e7646d2SAndroid Build Coastguard Worker     snprintf(command, sizeof(command), "\003%s\n", dest);
491*5e7646d2SAndroid Build Coastguard Worker 
492*5e7646d2SAndroid Build Coastguard Worker   bytes = (ssize_t)strlen(command);
493*5e7646d2SAndroid Build Coastguard Worker 
494*5e7646d2SAndroid Build Coastguard Worker   if (write(outfd, command, (size_t)bytes) < bytes)
495*5e7646d2SAndroid Build Coastguard Worker     return (-1);
496*5e7646d2SAndroid Build Coastguard Worker 
497*5e7646d2SAndroid Build Coastguard Worker  /*
498*5e7646d2SAndroid Build Coastguard Worker   * Read the status back...
499*5e7646d2SAndroid Build Coastguard Worker   */
500*5e7646d2SAndroid Build Coastguard Worker 
501*5e7646d2SAndroid Build Coastguard Worker   while ((bytes = read(infd, buffer, sizeof(buffer))) > 0)
502*5e7646d2SAndroid Build Coastguard Worker   {
503*5e7646d2SAndroid Build Coastguard Worker     fwrite(buffer, 1, (size_t)bytes, stdout);
504*5e7646d2SAndroid Build Coastguard Worker     fflush(stdout);
505*5e7646d2SAndroid Build Coastguard Worker   }
506*5e7646d2SAndroid Build Coastguard Worker 
507*5e7646d2SAndroid Build Coastguard Worker   return (0);
508*5e7646d2SAndroid Build Coastguard Worker }
509*5e7646d2SAndroid Build Coastguard Worker 
510*5e7646d2SAndroid Build Coastguard Worker 
511*5e7646d2SAndroid Build Coastguard Worker /*
512*5e7646d2SAndroid Build Coastguard Worker  * 'usage()' - Show program usage...
513*5e7646d2SAndroid Build Coastguard Worker  */
514*5e7646d2SAndroid Build Coastguard Worker 
515*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)516*5e7646d2SAndroid Build Coastguard Worker usage(void)
517*5e7646d2SAndroid Build Coastguard Worker {
518*5e7646d2SAndroid Build Coastguard Worker   puts("Usage: testlpd [options] print-job printer filename [... filename]");
519*5e7646d2SAndroid Build Coastguard Worker   puts("       testlpd [options] print-waiting [printer or user]");
520*5e7646d2SAndroid Build Coastguard Worker   puts("       testlpd [options] remove-job printer [user [job-id]]");
521*5e7646d2SAndroid Build Coastguard Worker   puts("       testlpd [options] status-long [printer or user]");
522*5e7646d2SAndroid Build Coastguard Worker   puts("       testlpd [options] status-short [printer or user]");
523*5e7646d2SAndroid Build Coastguard Worker   puts("");
524*5e7646d2SAndroid Build Coastguard Worker   puts("Options:");
525*5e7646d2SAndroid Build Coastguard Worker   puts("    -o name=value");
526*5e7646d2SAndroid Build Coastguard Worker 
527*5e7646d2SAndroid Build Coastguard Worker   exit(0);
528*5e7646d2SAndroid Build Coastguard Worker }
529