]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/testlpd.c
79b0ab02018ee3da1de069a339eaef42fcc78de0
2 * cups-lpd test program for CUPS.
4 * Copyright 2007-2015 by Apple Inc.
5 * Copyright 2006 by Easy Software Products, all rights reserved.
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
10 * which should have been included with this file. If this file is
11 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * Include necessary headers...
18 #include <cups/cups.h>
19 #include <cups/string-private.h>
31 static int do_command(int outfd
, int infd
, const char *command
);
32 static int print_job(int outfd
, int infd
, char *dest
, char **args
) __attribute__((nonnull(4)));
33 static int print_waiting(int outfd
, int infd
, char *dest
);
34 static int remove_job(int outfd
, int infd
, char *dest
, char **args
) __attribute__((nonnull(4)));
35 static int status_long(int outfd
, int infd
, char *dest
, char **args
) __attribute__((nonnull(4)));
36 static int status_short(int outfd
, int infd
, char *dest
, char **args
) __attribute__((nonnull(4)));
37 static void usage(void) __attribute__((noreturn
));
41 * 'main()' - Simulate an LPD client.
44 int /* O - Exit status */
45 main(int argc
, /* I - Number of command-line arguments */
46 char *argv
[]) /* I - Command-line arguments */
48 int i
; /* Looping var */
49 int status
; /* Test status */
50 char *op
, /* Operation to test */
51 **opargs
, /* Remaining arguments */
52 *dest
; /* Destination */
53 int cupslpd_argc
; /* Argument count for cups-lpd */
54 char *cupslpd_argv
[1000]; /* Arguments for cups-lpd */
55 int cupslpd_stdin
[2], /* Standard input for cups-lpd */
56 cupslpd_stdout
[2], /* Standard output for cups-lpd */
57 cupslpd_pid
, /* Process ID for cups-lpd */
58 cupslpd_status
; /* Status of cups-lpd process */
62 * Collect command-line arguments...
69 cupslpd_argv
[0] = (char *)"cups-lpd";
71 for (i
= 1; i
< argc
; i
++)
72 if (!strncmp(argv
[i
], "-o", 2))
74 cupslpd_argv
[cupslpd_argc
++] = argv
[i
];
83 cupslpd_argv
[cupslpd_argc
++] = argv
[i
];
86 else if (argv
[i
][0] == '-')
99 (!strcmp(op
, "print-job") && (!dest
|| !opargs
)) ||
100 (!strcmp(op
, "remove-job") && (!dest
|| !opargs
)) ||
101 (strcmp(op
, "print-job") && strcmp(op
, "print-waiting") &&
102 strcmp(op
, "remove-job") && strcmp(op
, "status-long") &&
103 strcmp(op
, "status-short")))
105 printf("op=\"%s\", dest=\"%s\", opargs=%p\n", op
, dest
, opargs
);
110 * Run the cups-lpd program using pipes...
113 cupslpd_argv
[cupslpd_argc
] = NULL
;
116 pipe(cupslpd_stdout
);
118 if ((cupslpd_pid
= fork()) < 0)
124 perror("testlpd: Unable to fork");
127 else if (cupslpd_pid
== 0)
133 dup2(cupslpd_stdin
[0], 0);
134 close(cupslpd_stdin
[0]);
135 close(cupslpd_stdin
[1]);
137 dup2(cupslpd_stdout
[1], 1);
138 close(cupslpd_stdout
[0]);
139 close(cupslpd_stdout
[1]);
141 execv("./cups-lpd", cupslpd_argv
);
143 perror("testlpd: Unable to exec ./cups-lpd");
148 close(cupslpd_stdin
[0]);
149 close(cupslpd_stdout
[1]);
153 * Do the operation test...
156 if (!strcmp(op
, "print-job"))
157 status
= print_job(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
158 else if (!strcmp(op
, "print-waiting"))
159 status
= print_waiting(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
);
160 else if (!strcmp(op
, "remove-job"))
161 status
= remove_job(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
162 else if (!strcmp(op
, "status-long"))
163 status
= status_long(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
164 else if (!strcmp(op
, "status-short"))
165 status
= status_short(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
168 printf("Unknown operation \"%s\"!\n", op
);
173 * Kill the test program...
176 close(cupslpd_stdin
[1]);
177 close(cupslpd_stdout
[0]);
179 while (wait(&cupslpd_status
) != cupslpd_pid
);
181 printf("cups-lpd exit status was %d...\n", cupslpd_status
);
184 * Return the test status...
192 * 'do_command()' - Send the LPD command and wait for a response.
195 static int /* O - Status from cups-lpd */
196 do_command(int outfd
, /* I - Command file descriptor */
197 int infd
, /* I - Response file descriptor */
198 const char *command
) /* I - Command line to send */
200 size_t len
; /* Length of command line */
201 char status
; /* Status byte */
204 printf("COMMAND: %02X %s", command
[0], command
+ 1);
206 len
= strlen(command
);
208 if ((size_t)write(outfd
, command
, len
) < len
)
210 puts(" Write failed!");
214 if (read(infd
, &status
, 1) < 1)
215 puts("STATUS: ERROR");
217 printf("STATUS: %d\n", status
);
224 * 'print_job()' - Submit a file for printing.
227 static int /* O - Status from cups-lpd */
228 print_job(int outfd
, /* I - Command file descriptor */
229 int infd
, /* I - Response file descriptor */
230 char *dest
, /* I - Destination */
231 char **args
) /* I - Arguments */
233 int fd
; /* Print file descriptor */
234 char command
[1024], /* Command buffer */
235 control
[1024], /* Control file */
236 buffer
[8192]; /* Print buffer */
237 int status
; /* Status of command */
238 struct stat fileinfo
; /* File information */
239 char *jobname
; /* Job name */
240 int sequence
; /* Sequence number */
241 ssize_t bytes
; /* Bytes read/written */
245 * Check the print file...
248 if (stat(args
[0], &fileinfo
))
254 if ((fd
= open(args
[0], O_RDONLY
)) < 0)
261 * Send the "receive print job" command...
264 snprintf(command
, sizeof(command
), "\002%s\n", dest
);
265 if ((status
= do_command(outfd
, infd
, command
)) != 0)
272 * Format a control file string that will be used to submit the job...
275 if ((jobname
= strrchr(args
[0], '/')) != NULL
)
280 sequence
= (int)getpid() % 1000;
282 snprintf(control
, sizeof(control
),
286 "ldfA%03dlocalhost\n"
287 "UdfA%03dlocalhost\n"
289 cupsUser(), jobname
, sequence
, sequence
, jobname
);
292 * Send the control file...
295 bytes
= (ssize_t
)strlen(control
);
297 snprintf(command
, sizeof(command
), "\002%d cfA%03dlocalhost\n",
298 (int)bytes
, sequence
);
300 if ((status
= do_command(outfd
, infd
, command
)) != 0)
308 if (write(outfd
, control
, (size_t)bytes
) < bytes
)
310 printf("CONTROL: Unable to write %d bytes!\n", (int)bytes
);
315 printf("CONTROL: Wrote %d bytes.\n", (int)bytes
);
317 if (read(infd
, command
, 1) < 1)
319 puts("STATUS: ERROR");
327 printf("STATUS: %d\n", status
);
331 * Send the data file...
334 snprintf(command
, sizeof(command
), "\003%d dfA%03dlocalhost\n",
335 (int)fileinfo
.st_size
, sequence
);
337 if ((status
= do_command(outfd
, infd
, command
)) != 0)
343 while ((bytes
= read(fd
, buffer
, sizeof(buffer
))) > 0)
345 if (write(outfd
, buffer
, (size_t)bytes
) < bytes
)
347 printf("DATA: Unable to write %d bytes!\n", (int)bytes
);
357 printf("DATA: Wrote %d bytes.\n", (int)fileinfo
.st_size
);
359 if (read(infd
, command
, 1) < 1)
361 puts("STATUS: ERROR");
369 printf("STATUS: %d\n", status
);
377 * 'print_waiting()' - Print waiting jobs.
380 static int /* O - Status from cups-lpd */
381 print_waiting(int outfd
, /* I - Command file descriptor */
382 int infd
, /* I - Response file descriptor */
383 char *dest
) /* I - Destination */
385 char command
[1024]; /* Command buffer */
389 * Send the "print waiting jobs" command...
392 snprintf(command
, sizeof(command
), "\001%s\n", dest
);
394 return (do_command(outfd
, infd
, command
));
399 * 'remove_job()' - Cancel a print job.
402 static int /* O - Status from cups-lpd */
403 remove_job(int outfd
, /* I - Command file descriptor */
404 int infd
, /* I - Response file descriptor */
405 char *dest
, /* I - Destination */
406 char **args
) /* I - Arguments */
408 int i
; /* Looping var */
409 char command
[1024]; /* Command buffer */
412 * Send the "remove jobs" command...
415 snprintf(command
, sizeof(command
), "\005%s", dest
);
417 for (i
= 0; args
[i
]; i
++)
419 strlcat(command
, " ", sizeof(command
));
420 strlcat(command
, args
[i
], sizeof(command
));
423 strlcat(command
, "\n", sizeof(command
));
425 return (do_command(outfd
, infd
, command
));
430 * 'status_long()' - Show the long printer status.
433 static int /* O - Status from cups-lpd */
434 status_long(int outfd
, /* I - Command file descriptor */
435 int infd
, /* I - Response file descriptor */
436 char *dest
, /* I - Destination */
437 char **args
) /* I - Arguments */
439 char command
[1024], /* Command buffer */
440 buffer
[8192]; /* Status buffer */
441 ssize_t bytes
; /* Bytes read/written */
445 * Send the "send short status" command...
449 snprintf(command
, sizeof(command
), "\004%s %s\n", dest
, args
[0]);
451 snprintf(command
, sizeof(command
), "\004%s\n", dest
);
453 bytes
= (ssize_t
)strlen(command
);
455 if (write(outfd
, command
, (size_t)bytes
) < bytes
)
459 * Read the status back...
462 while ((bytes
= read(infd
, buffer
, sizeof(buffer
))) > 0)
464 fwrite(buffer
, 1, (size_t)bytes
, stdout
);
473 * 'status_short()' - Show the short printer status.
476 static int /* O - Status from cups-lpd */
477 status_short(int outfd
, /* I - Command file descriptor */
478 int infd
, /* I - Response file descriptor */
479 char *dest
, /* I - Destination */
480 char **args
) /* I - Arguments */
482 char command
[1024], /* Command buffer */
483 buffer
[8192]; /* Status buffer */
484 ssize_t bytes
; /* Bytes read/written */
488 * Send the "send short status" command...
492 snprintf(command
, sizeof(command
), "\003%s %s\n", dest
, args
[0]);
494 snprintf(command
, sizeof(command
), "\003%s\n", dest
);
496 bytes
= (ssize_t
)strlen(command
);
498 if (write(outfd
, command
, (size_t)bytes
) < bytes
)
502 * Read the status back...
505 while ((bytes
= read(infd
, buffer
, sizeof(buffer
))) > 0)
507 fwrite(buffer
, 1, (size_t)bytes
, stdout
);
516 * 'usage()' - Show program usage...
522 puts("Usage: testlpd [options] print-job printer filename [... filename]");
523 puts(" testlpd [options] print-waiting [printer or user]");
524 puts(" testlpd [options] remove-job printer [user [job-id]]");
525 puts(" testlpd [options] status-long [printer or user]");
526 puts(" testlpd [options] status-short [printer or user]");
529 puts(" -o name=value");