]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/testlpd.c
2 * "$Id: testlpd.c 13138 2016-03-15 14:59:54Z msweet $"
4 * cups-lpd test program for CUPS.
6 * Copyright 2007-2015 by Apple Inc.
7 * Copyright 2006 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 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
17 * Include necessary headers...
20 #include <cups/cups.h>
21 #include <cups/string-private.h>
33 static int do_command(int outfd
, int infd
, const char *command
);
34 static int print_job(int outfd
, int infd
, char *dest
, char **args
) __attribute__((nonnull(4)));
35 static int print_waiting(int outfd
, int infd
, char *dest
);
36 static int remove_job(int outfd
, int infd
, char *dest
, char **args
) __attribute__((nonnull(4)));
37 static int status_long(int outfd
, int infd
, char *dest
, char **args
) __attribute__((nonnull(4)));
38 static int status_short(int outfd
, int infd
, char *dest
, char **args
) __attribute__((nonnull(4)));
39 static void usage(void) __attribute__((noreturn
));
43 * 'main()' - Simulate an LPD client.
46 int /* O - Exit status */
47 main(int argc
, /* I - Number of command-line arguments */
48 char *argv
[]) /* I - Command-line arguments */
50 int i
; /* Looping var */
51 int status
; /* Test status */
52 char *op
, /* Operation to test */
53 **opargs
, /* Remaining arguments */
54 *dest
; /* Destination */
55 int cupslpd_argc
; /* Argument count for cups-lpd */
56 char *cupslpd_argv
[1000]; /* Arguments for cups-lpd */
57 int cupslpd_stdin
[2], /* Standard input for cups-lpd */
58 cupslpd_stdout
[2], /* Standard output for cups-lpd */
59 cupslpd_pid
, /* Process ID for cups-lpd */
60 cupslpd_status
; /* Status of cups-lpd process */
64 * Collect command-line arguments...
71 cupslpd_argv
[0] = (char *)"cups-lpd";
73 for (i
= 1; i
< argc
; i
++)
74 if (!strncmp(argv
[i
], "-o", 2))
76 cupslpd_argv
[cupslpd_argc
++] = argv
[i
];
85 cupslpd_argv
[cupslpd_argc
++] = argv
[i
];
88 else if (argv
[i
][0] == '-')
101 (!strcmp(op
, "print-job") && (!dest
|| !opargs
)) ||
102 (!strcmp(op
, "remove-job") && (!dest
|| !opargs
)) ||
103 (strcmp(op
, "print-job") && strcmp(op
, "print-waiting") &&
104 strcmp(op
, "remove-job") && strcmp(op
, "status-long") &&
105 strcmp(op
, "status-short")))
107 printf("op=\"%s\", dest=\"%s\", opargs=%p\n", op
, dest
, opargs
);
112 * Run the cups-lpd program using pipes...
115 cupslpd_argv
[cupslpd_argc
] = NULL
;
118 pipe(cupslpd_stdout
);
120 if ((cupslpd_pid
= fork()) < 0)
126 perror("testlpd: Unable to fork");
129 else if (cupslpd_pid
== 0)
135 dup2(cupslpd_stdin
[0], 0);
136 close(cupslpd_stdin
[0]);
137 close(cupslpd_stdin
[1]);
139 dup2(cupslpd_stdout
[1], 1);
140 close(cupslpd_stdout
[0]);
141 close(cupslpd_stdout
[1]);
143 execv("./cups-lpd", cupslpd_argv
);
145 perror("testlpd: Unable to exec ./cups-lpd");
150 close(cupslpd_stdin
[0]);
151 close(cupslpd_stdout
[1]);
155 * Do the operation test...
158 if (!strcmp(op
, "print-job"))
159 status
= print_job(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
160 else if (!strcmp(op
, "print-waiting"))
161 status
= print_waiting(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
);
162 else if (!strcmp(op
, "remove-job"))
163 status
= remove_job(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
164 else if (!strcmp(op
, "status-long"))
165 status
= status_long(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
166 else if (!strcmp(op
, "status-short"))
167 status
= status_short(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
170 printf("Unknown operation \"%s\"!\n", op
);
175 * Kill the test program...
178 close(cupslpd_stdin
[1]);
179 close(cupslpd_stdout
[0]);
181 while (wait(&cupslpd_status
) != cupslpd_pid
);
183 printf("cups-lpd exit status was %d...\n", cupslpd_status
);
186 * Return the test status...
194 * 'do_command()' - Send the LPD command and wait for a response.
197 static int /* O - Status from cups-lpd */
198 do_command(int outfd
, /* I - Command file descriptor */
199 int infd
, /* I - Response file descriptor */
200 const char *command
) /* I - Command line to send */
202 size_t len
; /* Length of command line */
203 char status
; /* Status byte */
206 printf("COMMAND: %02X %s", command
[0], command
+ 1);
208 len
= strlen(command
);
210 if ((size_t)write(outfd
, command
, len
) < len
)
212 puts(" Write failed!");
216 if (read(infd
, &status
, 1) < 1)
217 puts("STATUS: ERROR");
219 printf("STATUS: %d\n", status
);
226 * 'print_job()' - Submit a file for printing.
229 static int /* O - Status from cups-lpd */
230 print_job(int outfd
, /* I - Command file descriptor */
231 int infd
, /* I - Response file descriptor */
232 char *dest
, /* I - Destination */
233 char **args
) /* I - Arguments */
235 int fd
; /* Print file descriptor */
236 char command
[1024], /* Command buffer */
237 control
[1024], /* Control file */
238 buffer
[8192]; /* Print buffer */
239 int status
; /* Status of command */
240 struct stat fileinfo
; /* File information */
241 char *jobname
; /* Job name */
242 int sequence
; /* Sequence number */
243 ssize_t bytes
; /* Bytes read/written */
247 * Check the print file...
250 if (stat(args
[0], &fileinfo
))
256 if ((fd
= open(args
[0], O_RDONLY
)) < 0)
263 * Send the "receive print job" command...
266 snprintf(command
, sizeof(command
), "\002%s\n", dest
);
267 if ((status
= do_command(outfd
, infd
, command
)) != 0)
274 * Format a control file string that will be used to submit the job...
277 if ((jobname
= strrchr(args
[0], '/')) != NULL
)
282 sequence
= (int)getpid() % 1000;
284 snprintf(control
, sizeof(control
),
288 "ldfA%03dlocalhost\n"
289 "UdfA%03dlocalhost\n"
291 cupsUser(), jobname
, sequence
, sequence
, jobname
);
294 * Send the control file...
297 bytes
= (ssize_t
)strlen(control
);
299 snprintf(command
, sizeof(command
), "\002%d cfA%03dlocalhost\n",
300 (int)bytes
, sequence
);
302 if ((status
= do_command(outfd
, infd
, command
)) != 0)
310 if (write(outfd
, control
, (size_t)bytes
) < bytes
)
312 printf("CONTROL: Unable to write %d bytes!\n", (int)bytes
);
317 printf("CONTROL: Wrote %d bytes.\n", (int)bytes
);
319 if (read(infd
, command
, 1) < 1)
321 puts("STATUS: ERROR");
329 printf("STATUS: %d\n", status
);
333 * Send the data file...
336 snprintf(command
, sizeof(command
), "\003%d dfA%03dlocalhost\n",
337 (int)fileinfo
.st_size
, sequence
);
339 if ((status
= do_command(outfd
, infd
, command
)) != 0)
345 while ((bytes
= read(fd
, buffer
, sizeof(buffer
))) > 0)
347 if (write(outfd
, buffer
, (size_t)bytes
) < bytes
)
349 printf("DATA: Unable to write %d bytes!\n", (int)bytes
);
359 printf("DATA: Wrote %d bytes.\n", (int)fileinfo
.st_size
);
361 if (read(infd
, command
, 1) < 1)
363 puts("STATUS: ERROR");
371 printf("STATUS: %d\n", status
);
379 * 'print_waiting()' - Print waiting jobs.
382 static int /* O - Status from cups-lpd */
383 print_waiting(int outfd
, /* I - Command file descriptor */
384 int infd
, /* I - Response file descriptor */
385 char *dest
) /* I - Destination */
387 char command
[1024]; /* Command buffer */
391 * Send the "print waiting jobs" command...
394 snprintf(command
, sizeof(command
), "\001%s\n", dest
);
396 return (do_command(outfd
, infd
, command
));
401 * 'remove_job()' - Cancel a print job.
404 static int /* O - Status from cups-lpd */
405 remove_job(int outfd
, /* I - Command file descriptor */
406 int infd
, /* I - Response file descriptor */
407 char *dest
, /* I - Destination */
408 char **args
) /* I - Arguments */
410 int i
; /* Looping var */
411 char command
[1024]; /* Command buffer */
414 * Send the "remove jobs" command...
417 snprintf(command
, sizeof(command
), "\005%s", dest
);
419 for (i
= 0; args
[i
]; i
++)
421 strlcat(command
, " ", sizeof(command
));
422 strlcat(command
, args
[i
], sizeof(command
));
425 strlcat(command
, "\n", sizeof(command
));
427 return (do_command(outfd
, infd
, command
));
432 * 'status_long()' - Show the long printer status.
435 static int /* O - Status from cups-lpd */
436 status_long(int outfd
, /* I - Command file descriptor */
437 int infd
, /* I - Response file descriptor */
438 char *dest
, /* I - Destination */
439 char **args
) /* I - Arguments */
441 char command
[1024], /* Command buffer */
442 buffer
[8192]; /* Status buffer */
443 ssize_t bytes
; /* Bytes read/written */
447 * Send the "send short status" command...
451 snprintf(command
, sizeof(command
), "\004%s %s\n", dest
, args
[0]);
453 snprintf(command
, sizeof(command
), "\004%s\n", dest
);
455 bytes
= (ssize_t
)strlen(command
);
457 if (write(outfd
, command
, (size_t)bytes
) < bytes
)
461 * Read the status back...
464 while ((bytes
= read(infd
, buffer
, sizeof(buffer
))) > 0)
466 fwrite(buffer
, 1, (size_t)bytes
, stdout
);
475 * 'status_short()' - Show the short printer status.
478 static int /* O - Status from cups-lpd */
479 status_short(int outfd
, /* I - Command file descriptor */
480 int infd
, /* I - Response file descriptor */
481 char *dest
, /* I - Destination */
482 char **args
) /* I - Arguments */
484 char command
[1024], /* Command buffer */
485 buffer
[8192]; /* Status buffer */
486 ssize_t bytes
; /* Bytes read/written */
490 * Send the "send short status" command...
494 snprintf(command
, sizeof(command
), "\003%s %s\n", dest
, args
[0]);
496 snprintf(command
, sizeof(command
), "\003%s\n", dest
);
498 bytes
= (ssize_t
)strlen(command
);
500 if (write(outfd
, command
, (size_t)bytes
) < bytes
)
504 * Read the status back...
507 while ((bytes
= read(infd
, buffer
, sizeof(buffer
))) > 0)
509 fwrite(buffer
, 1, (size_t)bytes
, stdout
);
518 * 'usage()' - Show program usage...
524 puts("Usage: testlpd [options] print-job printer filename [... filename]");
525 puts(" testlpd [options] print-waiting [printer or user]");
526 puts(" testlpd [options] remove-job printer [user [job-id]]");
527 puts(" testlpd [options] status-long [printer or user]");
528 puts(" testlpd [options] status-short [printer or user]");
531 puts(" -o name=value");
538 * End of "$Id: testlpd.c 13138 2016-03-15 14:59:54Z msweet $".