]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/testlpd.c
2 * "$Id: testlpd.c 6789 2007-08-13 19:52:43Z mike $"
4 * cups-lpd test program for the Common UNIX Printing System (CUPS).
6 * Copyright 2007 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 * main() - Simulate an LPD client.
18 * do_command() - Send the LPD command and wait for a response.
19 * print_job() - Submit a file for printing.
20 * print_waiting() - Print waiting jobs.
21 * remove_job() - Cancel a print job.
22 * status_long() - Show the long printer status.
23 * status_short() - Show the short printer status.
24 * usage() - Show program usage...
28 * Include necessary headers...
31 #include <cups/cups.h>
32 #include <cups/string.h>
46 static int do_command(int outfd
, int infd
, const char *command
);
47 static int print_job(int outfd
, int infd
, char *dest
, char **args
);
48 static int print_waiting(int outfd
, int infd
, char *dest
);
49 static int remove_job(int outfd
, int infd
, char *dest
, char **args
);
50 static int status_long(int outfd
, int infd
, char *dest
, char **args
);
51 static int status_short(int outfd
, int infd
, char *dest
, char **args
);
52 static void usage(void);
56 * 'main()' - Simulate an LPD client.
59 int /* O - Exit status */
60 main(int argc
, /* I - Number of command-line arguments */
61 char *argv
[]) /* I - Command-line arguments */
63 int i
; /* Looping var */
64 int status
; /* Test status */
65 char *op
, /* Operation to test */
66 **opargs
, /* Remaining arguments */
67 *dest
; /* Destination */
68 int cupslpd_argc
; /* Argument count for cups-lpd */
69 char *cupslpd_argv
[1000]; /* Arguments for cups-lpd */
70 int cupslpd_stdin
[2], /* Standard input for cups-lpd */
71 cupslpd_stdout
[2], /* Standard output for cups-lpd */
72 cupslpd_pid
, /* Process ID for cups-lpd */
73 cupslpd_status
; /* Status of cups-lpd process */
77 * Collect command-line arguments...
84 cupslpd_argv
[0] = (char *)"cups-lpd";
86 for (i
= 1; i
< argc
; i
++)
87 if (!strncmp(argv
[i
], "-o", 2))
89 cupslpd_argv
[cupslpd_argc
++] = argv
[i
];
98 cupslpd_argv
[cupslpd_argc
++] = argv
[i
];
101 else if (argv
[i
][0] == '-')
114 (!strcmp(op
, "print-job") && (!dest
|| !opargs
)) ||
115 (!strcmp(op
, "remove-job") && (!dest
|| !opargs
)) ||
116 (strcmp(op
, "print-job") && strcmp(op
, "print-waiting") &&
117 strcmp(op
, "remove-job") && strcmp(op
, "status-long") &&
118 strcmp(op
, "status-short")))
120 printf("op=\"%s\", dest=\"%s\", opargs=%p\n", op
, dest
, opargs
);
125 * Run the cups-lpd program using pipes...
128 cupslpd_argv
[cupslpd_argc
] = NULL
;
131 pipe(cupslpd_stdout
);
133 if ((cupslpd_pid
= fork()) < 0)
139 perror("testlpd: Unable to fork");
142 else if (cupslpd_pid
== 0)
148 dup2(cupslpd_stdin
[0], 0);
149 close(cupslpd_stdin
[0]);
150 close(cupslpd_stdin
[1]);
152 dup2(cupslpd_stdout
[1], 1);
153 close(cupslpd_stdout
[0]);
154 close(cupslpd_stdout
[1]);
156 execv("./cups-lpd", cupslpd_argv
);
158 perror("testlpd: Unable to exec ./cups-lpd");
163 close(cupslpd_stdin
[0]);
164 close(cupslpd_stdout
[1]);
168 * Do the operation test...
171 if (!strcmp(op
, "print-job"))
172 status
= print_job(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
173 else if (!strcmp(op
, "print-waiting"))
174 status
= print_waiting(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
);
175 else if (!strcmp(op
, "remove-job"))
176 status
= remove_job(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
177 else if (!strcmp(op
, "status-long"))
178 status
= status_long(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
179 else if (!strcmp(op
, "status-short"))
180 status
= status_short(cupslpd_stdin
[1], cupslpd_stdout
[0], dest
, opargs
);
183 printf("Unknown operation \"%s\"!\n", op
);
188 * Kill the test program...
191 close(cupslpd_stdin
[1]);
192 close(cupslpd_stdout
[0]);
194 while (wait(&cupslpd_status
) != cupslpd_pid
);
196 printf("cups-lpd exit status was %d...\n", cupslpd_status
);
199 * Return the test status...
207 * 'do_command()' - Send the LPD command and wait for a response.
210 static int /* O - Status from cups-lpd */
211 do_command(int outfd
, /* I - Command file descriptor */
212 int infd
, /* I - Response file descriptor */
213 const char *command
) /* I - Command line to send */
215 int len
; /* Length of command line */
216 char status
; /* Status byte */
219 printf("COMMAND: %02X %s", command
[0], command
+ 1);
221 len
= strlen(command
);
223 if (write(outfd
, command
, len
) < len
)
225 puts(" Write failed!");
229 if (read(infd
, &status
, 1) < 1)
230 puts("STATUS: ERROR");
232 printf("STATUS: %d\n", status
);
239 * 'print_job()' - Submit a file for printing.
242 static int /* O - Status from cups-lpd */
243 print_job(int outfd
, /* I - Command file descriptor */
244 int infd
, /* I - Response file descriptor */
245 char *dest
, /* I - Destination */
246 char **args
) /* I - Arguments */
248 int fd
; /* Print file descriptor */
249 char command
[1024], /* Command buffer */
250 control
[1024], /* Control file */
251 buffer
[8192]; /* Print buffer */
252 int status
; /* Status of command */
253 struct stat fileinfo
; /* File information */
254 char *jobname
; /* Job name */
255 int sequence
; /* Sequence number */
256 int bytes
; /* Bytes read/written */
260 * Check the print file...
263 if (stat(args
[0], &fileinfo
))
269 if ((fd
= open(args
[0], O_RDONLY
)) < 0)
276 * Send the "receive print job" command...
279 snprintf(command
, sizeof(command
), "\002%s\n", dest
);
280 if ((status
= do_command(outfd
, infd
, command
)) != 0)
287 * Format a control file string that will be used to submit the job...
290 if ((jobname
= strrchr(args
[0], '/')) != NULL
)
295 sequence
= (int)getpid() % 1000;
297 snprintf(control
, sizeof(control
),
301 "ldfA%03dlocalhost\n"
302 "UdfA%03dlocalhost\n"
304 cupsUser(), jobname
, sequence
, sequence
, jobname
);
307 * Send the control file...
310 bytes
= strlen(control
);
312 snprintf(command
, sizeof(command
), "\002%d cfA%03dlocalhost\n",
315 if ((status
= do_command(outfd
, infd
, command
)) != 0)
323 if (write(outfd
, control
, bytes
) < bytes
)
325 printf("CONTROL: Unable to write %d bytes!\n", bytes
);
330 printf("CONTROL: Wrote %d bytes.\n", bytes
);
332 if (read(infd
, command
, 1) < 1)
334 puts("STATUS: ERROR");
342 printf("STATUS: %d\n", status
);
346 * Send the data file...
349 snprintf(command
, sizeof(command
), "\003%d dfA%03dlocalhost\n",
350 (int)fileinfo
.st_size
, sequence
);
352 if ((status
= do_command(outfd
, infd
, command
)) != 0)
358 while ((bytes
= read(fd
, buffer
, sizeof(buffer
))) > 0)
360 if (write(outfd
, buffer
, bytes
) < bytes
)
362 printf("DATA: Unable to write %d bytes!\n", bytes
);
372 printf("DATA: Wrote %d bytes.\n", (int)fileinfo
.st_size
);
374 if (read(infd
, command
, 1) < 1)
376 puts("STATUS: ERROR");
384 printf("STATUS: %d\n", status
);
392 * 'print_waiting()' - Print waiting jobs.
395 static int /* O - Status from cups-lpd */
396 print_waiting(int outfd
, /* I - Command file descriptor */
397 int infd
, /* I - Response file descriptor */
398 char *dest
) /* I - Destination */
400 char command
[1024]; /* Command buffer */
404 * Send the "print waiting jobs" command...
407 snprintf(command
, sizeof(command
), "\001%s\n", dest
);
409 return (do_command(outfd
, infd
, command
));
414 * 'remove_job()' - Cancel a print job.
417 static int /* O - Status from cups-lpd */
418 remove_job(int outfd
, /* I - Command file descriptor */
419 int infd
, /* I - Response file descriptor */
420 char *dest
, /* I - Destination */
421 char **args
) /* I - Arguments */
423 int i
; /* Looping var */
424 char command
[1024]; /* Command buffer */
427 * Send the "remove jobs" command...
430 snprintf(command
, sizeof(command
), "\005%s", dest
);
432 for (i
= 0; args
[i
]; i
++)
434 strlcat(command
, " ", sizeof(command
));
435 strlcat(command
, args
[i
], sizeof(command
));
438 strlcat(command
, "\n", sizeof(command
));
440 return (do_command(outfd
, infd
, command
));
445 * 'status_long()' - Show the long printer status.
448 static int /* O - Status from cups-lpd */
449 status_long(int outfd
, /* I - Command file descriptor */
450 int infd
, /* I - Response file descriptor */
451 char *dest
, /* I - Destination */
452 char **args
) /* I - Arguments */
454 char command
[1024], /* Command buffer */
455 buffer
[8192]; /* Status buffer */
456 int bytes
; /* Bytes read/written */
460 * Send the "send short status" command...
464 snprintf(command
, sizeof(command
), "\004%s %s\n", dest
, args
[0]);
466 snprintf(command
, sizeof(command
), "\004%s\n", dest
);
468 bytes
= strlen(command
);
470 if (write(outfd
, command
, bytes
) < bytes
)
474 * Read the status back...
477 while ((bytes
= read(infd
, buffer
, sizeof(buffer
))) > 0)
479 fwrite(buffer
, 1, bytes
, stdout
);
488 * 'status_short()' - Show the short printer status.
491 static int /* O - Status from cups-lpd */
492 status_short(int outfd
, /* I - Command file descriptor */
493 int infd
, /* I - Response file descriptor */
494 char *dest
, /* I - Destination */
495 char **args
) /* I - Arguments */
497 char command
[1024], /* Command buffer */
498 buffer
[8192]; /* Status buffer */
499 int bytes
; /* Bytes read/written */
503 * Send the "send short status" command...
507 snprintf(command
, sizeof(command
), "\003%s %s\n", dest
, args
[0]);
509 snprintf(command
, sizeof(command
), "\003%s\n", dest
);
511 bytes
= strlen(command
);
513 if (write(outfd
, command
, bytes
) < bytes
)
517 * Read the status back...
520 while ((bytes
= read(infd
, buffer
, sizeof(buffer
))) > 0)
522 fwrite(buffer
, 1, bytes
, stdout
);
531 * 'usage()' - Show program usage...
537 puts("Usage: testlpd [options] print-job printer filename [... filename]");
538 puts(" testlpd [options] print-waiting [printer or user]");
539 puts(" testlpd [options] remove-job printer [user [job-id]]");
540 puts(" testlpd [options] status-long [printer or user]");
541 puts(" testlpd [options] status-short [printer or user]");
544 puts(" -o name=value");
551 * End of "$Id: testlpd.c 6789 2007-08-13 19:52:43Z mike $".