]>
Commit | Line | Data |
---|---|---|
c8f9565c | 1 | /* |
d2935a0f | 2 | * "$Id: ipp.c,v 1.34 2001/01/22 15:03:19 mike Exp $" |
c8f9565c | 3 | * |
4 | * IPP backend for the Common UNIX Printing System (CUPS). | |
5 | * | |
d2935a0f | 6 | * Copyright 1997-2001 by Easy Software Products, all rights reserved. |
c8f9565c | 7 | * |
8 | * These coded instructions, statements, and computer programs are the | |
9 | * property of Easy Software Products and are protected by Federal | |
10 | * copyright law. Distribution and use rights are outlined in the file | |
11 | * "LICENSE" which should have been included with this file. If this | |
12 | * file is missing or damaged please contact Easy Software Products | |
13 | * at: | |
14 | * | |
15 | * Attn: CUPS Licensing Information | |
16 | * Easy Software Products | |
8784b6a6 | 17 | * 44141 Airport View Drive, Suite 204 |
c8f9565c | 18 | * Hollywood, Maryland 20636-3111 USA |
19 | * | |
20 | * Voice: (301) 373-9603 | |
21 | * EMail: cups-info@cups.org | |
22 | * WWW: http://www.cups.org | |
23 | * | |
24 | * Contents: | |
25 | * | |
6d0582d2 | 26 | * main() - Send a file to the printer or server. |
c8f9565c | 27 | */ |
28 | ||
29 | /* | |
30 | * Include necessary headers. | |
31 | */ | |
32 | ||
33 | #include <stdio.h> | |
34 | #include <stdlib.h> | |
35 | #include <errno.h> | |
36 | #include <sys/types.h> | |
37 | #include <sys/stat.h> | |
38 | #include <cups/cups.h> | |
39 | #include <cups/language.h> | |
40 | #include <cups/string.h> | |
4ff40357 | 41 | #include <signal.h> |
c8f9565c | 42 | |
43 | ||
44 | /* | |
45 | * 'main()' - Send a file to the printer or server. | |
46 | * | |
47 | * Usage: | |
48 | * | |
49 | * printer-uri job-id user title copies options [file] | |
50 | */ | |
51 | ||
52 | int /* O - Exit status */ | |
53 | main(int argc, /* I - Number of command-line arguments (6 or 7) */ | |
54 | char *argv[]) /* I - Command-line arguments */ | |
55 | { | |
25512894 | 56 | int i; /* Looping var */ |
c8f9565c | 57 | int num_options; /* Number of printer options */ |
3079988e | 58 | cups_option_t *options; /* Printer options */ |
c8f9565c | 59 | char method[255], /* Method in URI */ |
60 | hostname[1024], /* Hostname */ | |
61 | username[255], /* Username info */ | |
62 | resource[1024], /* Resource info (printer name) */ | |
63 | filename[1024]; /* File to print */ | |
64 | int port; /* Port number (not used) */ | |
65 | char password[255], /* Password info */ | |
66 | uri[HTTP_MAX_URI];/* Updated URI without user/pass */ | |
67 | http_status_t status; /* Status of HTTP job */ | |
97fcaf92 | 68 | ipp_status_t ipp_status; /* Status of IPP request */ |
c8f9565c | 69 | FILE *fp; /* File to print */ |
70 | http_t *http; /* HTTP connection */ | |
71 | ipp_t *request, /* IPP request */ | |
72 | *response; /* IPP response */ | |
73 | ipp_attribute_t *job_id; /* job-id attribute */ | |
97fcaf92 | 74 | ipp_attribute_t *copies_sup; /* copies-supported attribute */ |
25512894 | 75 | ipp_attribute_t *charset_sup; /* charset-supported attribute */ |
36aa99bb | 76 | ipp_attribute_t *format_sup; /* document-format-supported attribute */ |
25512894 | 77 | const char *charset; /* Character set to use */ |
c8f9565c | 78 | cups_lang_t *language; /* Default language */ |
79 | struct stat fileinfo; /* File statistics */ | |
80 | size_t nbytes, /* Number of bytes written */ | |
81 | tbytes; /* Total bytes written */ | |
82 | char buffer[8192]; /* Output buffer */ | |
97fcaf92 | 83 | int copies; /* Number of copies remaining */ |
0a3944d6 | 84 | const char *content_type; /* CONTENT_TYPE environment variable */ |
4ff40357 | 85 | #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) |
86 | struct sigaction action; /* Actions for POSIX signals */ | |
87 | #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ | |
5a2c7855 | 88 | int version; /* IPP version */ |
c8f9565c | 89 | |
90 | ||
68edc300 | 91 | if (argc == 1) |
92 | { | |
183914a3 | 93 | char *s; |
94 | ||
d4c438d4 | 95 | if ((s = strrchr(argv[0], '/')) != NULL) |
96 | s ++; | |
97 | else | |
98 | s = argv[0]; | |
99 | ||
100 | printf("network %s \"Unknown\" \"Internet Printing Protocol\"\n", s); | |
68edc300 | 101 | return (0); |
102 | } | |
103 | else if (argc < 6 || argc > 7) | |
c8f9565c | 104 | { |
105 | fprintf(stderr, "Usage: %s job-id user title copies options [file]\n", | |
106 | argv[0]); | |
107 | return (1); | |
108 | } | |
109 | ||
110 | /* | |
111 | * If we have 7 arguments, print the file named on the command-line. | |
97fcaf92 | 112 | * Otherwise, copy stdin to a temporary file and print the temporary |
113 | * file. | |
c8f9565c | 114 | */ |
115 | ||
116 | if (argc == 6) | |
97fcaf92 | 117 | { |
118 | /* | |
119 | * Copy stdin to a temporary file... | |
120 | */ | |
121 | ||
122 | FILE *fp; /* Temporary file */ | |
123 | char buffer[8192]; /* Buffer for copying */ | |
124 | int bytes; /* Number of bytes read */ | |
125 | ||
126 | ||
127 | if ((fp = fopen(cupsTempFile(filename, sizeof(filename)), "w")) == NULL) | |
128 | { | |
129 | perror("ERROR: unable to create temporary file"); | |
130 | return (1); | |
131 | } | |
132 | ||
133 | while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) | |
134 | if (fwrite(buffer, 1, bytes, fp) < bytes) | |
135 | { | |
136 | perror("ERROR: unable to write to temporary file"); | |
137 | fclose(fp); | |
138 | unlink(filename); | |
139 | return (1); | |
140 | } | |
141 | ||
142 | fclose(fp); | |
143 | } | |
144 | else | |
145 | { | |
146 | strncpy(filename, argv[6], sizeof(filename) - 1); | |
147 | filename[sizeof(filename) - 1] = '\0'; | |
148 | } | |
149 | ||
150 | /* | |
151 | * Open the print file... | |
152 | */ | |
153 | ||
154 | if ((fp = fopen(filename, "rb")) == NULL) | |
c8f9565c | 155 | { |
156 | perror("ERROR: Unable to open print file"); | |
157 | return (1); | |
158 | } | |
159 | else | |
97fcaf92 | 160 | stat(filename, &fileinfo); |
c8f9565c | 161 | |
162 | /* | |
163 | * Extract the hostname and printer name from the URI... | |
164 | */ | |
165 | ||
166 | httpSeparate(argv[0], method, username, hostname, &port, resource); | |
167 | ||
168 | /* | |
169 | * Try connecting to the remote server... | |
170 | */ | |
171 | ||
97fcaf92 | 172 | do |
c8f9565c | 173 | { |
97fcaf92 | 174 | fprintf(stderr, "INFO: Connecting to %s...\n", hostname); |
c8f9565c | 175 | |
97fcaf92 | 176 | if ((http = httpConnect(hostname, port)) == NULL) |
d21a7597 | 177 | { |
97fcaf92 | 178 | if (errno == ECONNREFUSED) |
179 | { | |
180 | fprintf(stderr, "INFO: Network host \'%s\' is busy; will retry in 30 seconds...", | |
181 | hostname); | |
182 | sleep(30); | |
183 | } | |
184 | else | |
185 | { | |
186 | perror("ERROR: Unable to connect to IPP host"); | |
2cc18dd2 | 187 | sleep(30); |
97fcaf92 | 188 | } |
d21a7597 | 189 | } |
c8f9565c | 190 | } |
97fcaf92 | 191 | while (http == NULL); |
c8f9565c | 192 | |
193 | /* | |
194 | * Build a URI for the printer and fill the standard IPP attributes for | |
8ce7c000 | 195 | * an IPP_PRINT_FILE request. We can't use the URI in argv[0] because it |
196 | * might contain username:password information... | |
c8f9565c | 197 | */ |
198 | ||
3f9cb6c6 | 199 | snprintf(uri, sizeof(uri), "%s://%s:%d%s", method, hostname, port, resource); |
c8f9565c | 200 | |
201 | /* | |
97fcaf92 | 202 | * First validate the destination and see if the device supports multiple |
203 | * copies. We have to do this because some IPP servers (e.g. HP JetDirect) | |
204 | * don't support the copies attribute... | |
c8f9565c | 205 | */ |
206 | ||
25512894 | 207 | language = cupsLangDefault(); |
208 | charset_sup = NULL; | |
209 | copies_sup = NULL; | |
210 | version = 1; | |
c8f9565c | 211 | |
97fcaf92 | 212 | do |
c8f9565c | 213 | { |
214 | /* | |
97fcaf92 | 215 | * Build the IPP request... |
c8f9565c | 216 | */ |
217 | ||
97fcaf92 | 218 | request = ippNew(); |
5a2c7855 | 219 | request->request.op.version[1] = version; |
97fcaf92 | 220 | request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; |
221 | request->request.op.request_id = 1; | |
c8f9565c | 222 | |
97fcaf92 | 223 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, |
67436e05 | 224 | "attributes-charset", NULL, "utf-8"); |
97fcaf92 | 225 | |
226 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, | |
227 | "attributes-natural-language", NULL, | |
67436e05 | 228 | language != NULL ? language->language : "en"); |
c8f9565c | 229 | |
97fcaf92 | 230 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", |
231 | NULL, uri); | |
c8f9565c | 232 | |
97fcaf92 | 233 | /* |
234 | * Now fill in the HTTP request stuff... | |
235 | */ | |
c8f9565c | 236 | |
97fcaf92 | 237 | httpClearFields(http); |
238 | httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp"); | |
239 | if (username[0]) | |
c8f9565c | 240 | { |
97fcaf92 | 241 | httpEncode64(password, username); |
242 | httpSetField(http, HTTP_FIELD_AUTHORIZATION, password); | |
243 | } | |
c8f9565c | 244 | |
97fcaf92 | 245 | sprintf(buffer, "%u", ippLength(request)); |
246 | httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, buffer); | |
c8f9565c | 247 | |
97fcaf92 | 248 | /* |
249 | * Do the request... | |
250 | */ | |
c8f9565c | 251 | |
36aa99bb | 252 | for (response = NULL, ipp_status = IPP_BAD_REQUEST;;) |
c8f9565c | 253 | { |
97fcaf92 | 254 | /* |
255 | * POST the request, retrying as needed... | |
256 | */ | |
257 | ||
258 | if (httpPost(http, resource)) | |
c8f9565c | 259 | { |
97fcaf92 | 260 | fputs("INFO: Unable to POST get-printer-attributes request; retrying...\n", stderr); |
261 | sleep(10); | |
262 | httpReconnect(http); | |
263 | continue; | |
c8f9565c | 264 | } |
c8f9565c | 265 | |
97fcaf92 | 266 | fputs("INFO: POST successful, sending IPP request...\n", stderr); |
c8f9565c | 267 | |
c8f9565c | 268 | /* |
97fcaf92 | 269 | * Send the IPP request... |
c8f9565c | 270 | */ |
97fcaf92 | 271 | |
272 | request->state = IPP_IDLE; | |
273 | ||
274 | if (ippWrite(http, request) == IPP_ERROR) | |
275 | { | |
276 | fputs("ERROR: Unable to send IPP request!\n", stderr); | |
277 | status = HTTP_ERROR; | |
278 | break; | |
279 | } | |
280 | ||
281 | fputs("INFO: IPP request sent, getting status...\n", stderr); | |
282 | ||
c8f9565c | 283 | /* |
97fcaf92 | 284 | * Finally, check the status from the HTTP server... |
c8f9565c | 285 | */ |
286 | ||
97fcaf92 | 287 | while ((status = httpUpdate(http)) == HTTP_CONTINUE); |
288 | ||
289 | if (status == HTTP_OK) | |
c8f9565c | 290 | { |
97fcaf92 | 291 | response = ippNew(); |
292 | ippRead(http, response); | |
293 | ||
294 | ipp_status = response->request.status.status_code; | |
d21a7597 | 295 | |
97fcaf92 | 296 | if (ipp_status > IPP_OK_CONFLICT) |
297 | { | |
298 | if (ipp_status == IPP_PRINTER_BUSY || | |
299 | ipp_status == IPP_SERVICE_UNAVAILABLE) | |
300 | { | |
301 | fputs("INFO: Printer busy; will retry in 10 seconds...\n", stderr); | |
302 | sleep(10); | |
303 | } | |
5a2c7855 | 304 | else if (ipp_status == IPP_BAD_REQUEST && version == 1) |
305 | { | |
306 | /* | |
307 | * Switch to IPP/1.0... | |
308 | */ | |
309 | ||
310 | fputs("INFO: Printer does not support IPP/1.1, trying IPP/1.0...\n", stderr); | |
311 | version = 0; | |
312 | } | |
97fcaf92 | 313 | else |
314 | { | |
315 | fprintf(stderr, "ERROR: Printer will not accept print file (%x)!\n", | |
316 | ipp_status); | |
5a2c7855 | 317 | fprintf(stderr, "ERROR: %s\n", ippErrorString(ipp_status)); |
97fcaf92 | 318 | status = HTTP_ERROR; |
319 | } | |
320 | } | |
321 | else if ((copies_sup = ippFindAttribute(response, "copies-supported", | |
322 | IPP_TAG_RANGE)) != NULL) | |
323 | { | |
324 | /* | |
325 | * Has the "copies-supported" attribute - does it have an upper | |
326 | * bound > 1? | |
327 | */ | |
328 | ||
329 | if (copies_sup->values[0].range.upper <= 1) | |
330 | copies_sup = NULL; /* No */ | |
331 | } | |
332 | ||
25512894 | 333 | charset_sup = ippFindAttribute(response, "charset-supported", |
334 | IPP_TAG_CHARSET); | |
36aa99bb | 335 | format_sup = ippFindAttribute(response, "document-format-supported", |
336 | IPP_TAG_MIMETYPE); | |
c8f9565c | 337 | } |
97fcaf92 | 338 | else |
c8f9565c | 339 | { |
d21a7597 | 340 | response = NULL; |
341 | ||
97fcaf92 | 342 | if (status == HTTP_ERROR) |
343 | { | |
344 | fprintf(stderr, "WARNING: Did not receive the IPP response (%d)\n", | |
345 | errno); | |
346 | status = HTTP_OK; | |
347 | ipp_status = IPP_PRINTER_BUSY; | |
348 | } | |
349 | else | |
d21a7597 | 350 | { |
5a2c7855 | 351 | fprintf(stderr, "ERROR: Validate request was not accepted (%d)!\n", |
352 | status); | |
d21a7597 | 353 | ipp_status = IPP_FORBIDDEN; |
354 | } | |
c8f9565c | 355 | } |
97fcaf92 | 356 | |
357 | httpFlush(http); | |
358 | ||
359 | break; | |
360 | } | |
361 | ||
362 | if (status != HTTP_OK) | |
363 | { | |
364 | if (fp != stdin) | |
365 | fclose(fp); | |
366 | ||
367 | httpClose(http); | |
368 | ||
369 | return (1); | |
c8f9565c | 370 | } |
5a2c7855 | 371 | else if (ipp_status > IPP_OK_CONFLICT) |
372 | httpReconnect(http); | |
c8f9565c | 373 | } |
97fcaf92 | 374 | while (ipp_status > IPP_OK_CONFLICT); |
c8f9565c | 375 | |
4ff40357 | 376 | /* |
377 | * Now that we are "connected" to the port, ignore SIGTERM so that we | |
378 | * can finish out any page data the driver sends (e.g. to eject the | |
379 | * current page... | |
380 | */ | |
381 | ||
382 | #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ | |
383 | sigset(SIGTERM, SIG_IGN); | |
384 | #elif defined(HAVE_SIGACTION) | |
385 | memset(&action, 0, sizeof(action)); | |
386 | ||
387 | sigemptyset(&action.sa_mask); | |
388 | action.sa_handler = SIG_IGN; | |
389 | sigaction(SIGTERM, &action, NULL); | |
390 | #else | |
391 | signal(SIGTERM, SIG_IGN); | |
392 | #endif /* HAVE_SIGSET */ | |
393 | ||
c8f9565c | 394 | /* |
97fcaf92 | 395 | * See if the printer supports multiple copies... |
c8f9565c | 396 | */ |
397 | ||
97fcaf92 | 398 | if (copies_sup) |
399 | copies = 1; | |
0c5b0932 | 400 | else |
97fcaf92 | 401 | copies = atoi(argv[4]); |
0c5b0932 | 402 | |
25512894 | 403 | /* |
404 | * Figure out the character set to use... | |
405 | */ | |
406 | ||
407 | charset = language ? cupsLangEncoding(language) : "us-ascii"; | |
408 | ||
409 | if (charset_sup) | |
410 | { | |
411 | /* | |
412 | * See if IPP server supports the requested character set... | |
413 | */ | |
414 | ||
415 | for (i = 0; i < charset_sup->num_values; i ++) | |
416 | if (strcasecmp(charset, charset_sup->values[i].string.text) == 0) | |
417 | break; | |
418 | ||
419 | /* | |
420 | * If not, choose us-ascii or utf-8... | |
421 | */ | |
422 | ||
423 | if (i >= charset_sup->num_values) | |
424 | { | |
425 | /* | |
426 | * See if us-ascii is supported... | |
427 | */ | |
428 | ||
429 | for (i = 0; i < charset_sup->num_values; i ++) | |
430 | if (strcasecmp("us-ascii", charset_sup->values[i].string.text) == 0) | |
431 | break; | |
432 | ||
433 | if (i < charset_sup->num_values) | |
434 | charset = "us-ascii"; | |
435 | else | |
436 | charset = "utf-8"; | |
437 | } | |
438 | } | |
439 | ||
440 | if (response) | |
441 | ippDelete(response); | |
442 | ||
c8f9565c | 443 | /* |
97fcaf92 | 444 | * Then issue the print-job request... |
c8f9565c | 445 | */ |
446 | ||
97fcaf92 | 447 | while (copies > 0) |
c8f9565c | 448 | { |
449 | /* | |
97fcaf92 | 450 | * Build the IPP request... |
c8f9565c | 451 | */ |
452 | ||
97fcaf92 | 453 | request = ippNew(); |
5a2c7855 | 454 | request->request.op.version[1] = version; |
97fcaf92 | 455 | request->request.op.operation_id = IPP_PRINT_JOB; |
456 | request->request.op.request_id = 1; | |
c8f9565c | 457 | |
97fcaf92 | 458 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, |
25512894 | 459 | "attributes-charset", NULL, charset); |
8ce7c000 | 460 | |
97fcaf92 | 461 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, |
462 | "attributes-natural-language", NULL, | |
67436e05 | 463 | language != NULL ? language->language : "en"); |
c8f9565c | 464 | |
97fcaf92 | 465 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", |
466 | NULL, uri); | |
c8f9565c | 467 | |
97fcaf92 | 468 | fprintf(stderr, "DEBUG: printer-uri = \"%s\"\n", uri); |
469 | ||
470 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", | |
471 | NULL, argv[2]); | |
472 | ||
473 | fprintf(stderr, "DEBUG: requesting-user-name = \"%s\"\n", argv[2]); | |
474 | ||
475 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, | |
476 | argv[3]); | |
c8f9565c | 477 | |
97fcaf92 | 478 | fprintf(stderr, "DEBUG: job-name = \"%s\"\n", argv[3]); |
8ce7c000 | 479 | |
c8f9565c | 480 | /* |
97fcaf92 | 481 | * Handle options on the command-line... |
c8f9565c | 482 | */ |
483 | ||
97fcaf92 | 484 | options = NULL; |
485 | num_options = cupsParseOptions(argv[5], 0, &options); | |
486 | ||
36aa99bb | 487 | if ((content_type = getenv("CONTENT_TYPE")) != NULL && format_sup != NULL) |
488 | { | |
489 | for (i = 0; i < format_sup->num_values; i ++) | |
490 | if (strcasecmp(content_type, format_sup->values[i].string.text) == 0) | |
491 | break; | |
492 | ||
493 | if (i < format_sup->num_values) | |
494 | num_options = cupsAddOption("document-format", content_type, | |
495 | num_options, &options); | |
496 | } | |
97fcaf92 | 497 | |
183914a3 | 498 | cupsEncodeOptions(request, num_options, options); |
499 | cupsFreeOptions(num_options, options); | |
c8f9565c | 500 | |
168c50b6 | 501 | if (copies_sup) |
502 | ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies", atoi(argv[4])); | |
503 | ||
cb555bcf | 504 | /* |
97fcaf92 | 505 | * Now fill in the HTTP request stuff... |
cb555bcf | 506 | */ |
507 | ||
97fcaf92 | 508 | httpClearFields(http); |
509 | httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp"); | |
510 | if (username[0]) | |
511 | { | |
512 | httpEncode64(password, username); | |
513 | httpSetField(http, HTTP_FIELD_AUTHORIZATION, password); | |
514 | } | |
cb555bcf | 515 | |
97fcaf92 | 516 | sprintf(buffer, "%u", ippLength(request) + (size_t)fileinfo.st_size); |
517 | httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, buffer); | |
8ce7c000 | 518 | |
c8f9565c | 519 | /* |
97fcaf92 | 520 | * Do the request... |
c8f9565c | 521 | */ |
522 | ||
97fcaf92 | 523 | for (;;) |
c8f9565c | 524 | { |
97fcaf92 | 525 | /* |
526 | * POST the request, retrying as needed... | |
527 | */ | |
528 | ||
529 | httpReconnect(http); | |
c8f9565c | 530 | |
97fcaf92 | 531 | if (httpPost(http, resource)) |
3f9cb6c6 | 532 | { |
97fcaf92 | 533 | fputs("INFO: Unable to POST print request; retrying...\n", stderr); |
534 | sleep(10); | |
535 | continue; | |
536 | } | |
537 | ||
538 | fputs("INFO: POST successful, sending IPP request...\n", stderr); | |
3f9cb6c6 | 539 | |
97fcaf92 | 540 | /* |
541 | * Send the IPP request... | |
542 | */ | |
543 | ||
544 | request->state = IPP_IDLE; | |
3f9cb6c6 | 545 | |
97fcaf92 | 546 | if (ippWrite(http, request) == IPP_ERROR) |
547 | { | |
548 | fputs("ERROR: Unable to send IPP request!\n", stderr); | |
549 | status = HTTP_ERROR; | |
550 | break; | |
3f9cb6c6 | 551 | } |
c8f9565c | 552 | |
97fcaf92 | 553 | fputs("INFO: IPP request sent, sending print file...\n", stderr); |
554 | ||
555 | /* | |
556 | * Then send the file... | |
557 | */ | |
558 | ||
559 | rewind(fp); | |
560 | ||
561 | tbytes = 0; | |
562 | while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) | |
563 | { | |
564 | tbytes += nbytes; | |
565 | fprintf(stderr, "INFO: Sending print file, %uk...\n", tbytes / 1024); | |
566 | ||
567 | if (httpWrite(http, buffer, nbytes) < nbytes) | |
568 | { | |
569 | perror("ERROR: Unable to send print file to printer"); | |
570 | status = HTTP_ERROR; | |
571 | break; | |
572 | } | |
573 | } | |
574 | ||
575 | fputs("INFO: Print file sent; checking status...\n", stderr); | |
576 | ||
577 | /* | |
578 | * Finally, check the status from the HTTP server... | |
579 | */ | |
580 | ||
581 | while ((status = httpUpdate(http)) == HTTP_CONTINUE); | |
582 | ||
583 | if (status == HTTP_OK) | |
6a536282 | 584 | { |
97fcaf92 | 585 | response = ippNew(); |
586 | ippRead(http, response); | |
587 | ||
588 | if ((ipp_status = response->request.status.status_code) > IPP_OK_CONFLICT) | |
589 | { | |
590 | if (ipp_status == IPP_SERVICE_UNAVAILABLE || | |
591 | ipp_status == IPP_PRINTER_BUSY) | |
592 | { | |
593 | fputs("INFO: Printer is busy; retrying print job...\n", stderr); | |
594 | sleep(10); | |
595 | } | |
596 | else | |
5a2c7855 | 597 | { |
97fcaf92 | 598 | fprintf(stderr, "ERROR: Print file was not accepted (%04x)!\n", |
599 | response->request.status.status_code); | |
5a2c7855 | 600 | fprintf(stderr, "ERROR: %s\n", ippErrorString(ipp_status)); |
601 | } | |
97fcaf92 | 602 | } |
603 | else if ((job_id = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL) | |
604 | fputs("INFO: Print file accepted - job ID unknown.\n", stderr); | |
605 | else | |
606 | fprintf(stderr, "INFO: Print file accepted - job ID %d.\n", | |
607 | job_id->values[0].integer); | |
6a536282 | 608 | } |
609 | else | |
97fcaf92 | 610 | { |
611 | response = NULL; | |
612 | ipp_status = IPP_PRINTER_BUSY; | |
613 | ||
614 | if (status == HTTP_ERROR) | |
615 | { | |
616 | fprintf(stderr, "WARNING: Did not receive the IPP response (%d)\n", | |
617 | errno); | |
618 | status = HTTP_OK; | |
619 | } | |
620 | else | |
621 | fprintf(stderr, "ERROR: Print request was not accepted (%d)!\n", status); | |
622 | } | |
623 | ||
624 | httpFlush(http); | |
625 | ||
626 | break; | |
c8f9565c | 627 | } |
628 | ||
97fcaf92 | 629 | if (request != NULL) |
630 | ippDelete(request); | |
631 | if (response != NULL) | |
632 | ippDelete(response); | |
633 | ||
634 | if (ipp_status <= IPP_OK_CONFLICT) | |
635 | { | |
636 | fprintf(stderr, "PAGE: 1 %d\n", copies_sup ? atoi(argv[4]) : 1); | |
637 | copies --; | |
638 | } | |
48419d23 | 639 | else if (ipp_status != IPP_SERVICE_UNAVAILABLE && |
640 | ipp_status != IPP_PRINTER_BUSY) | |
641 | break; | |
c8f9565c | 642 | } |
643 | ||
644 | /* | |
645 | * Free memory... | |
646 | */ | |
647 | ||
648 | httpClose(http); | |
c8f9565c | 649 | |
650 | /* | |
97fcaf92 | 651 | * Close and remove the temporary file if necessary... |
c8f9565c | 652 | */ |
653 | ||
97fcaf92 | 654 | fclose(fp); |
3f9cb6c6 | 655 | |
97fcaf92 | 656 | if (argc < 7) |
657 | unlink(filename); | |
c8f9565c | 658 | |
659 | /* | |
660 | * Return the queue status... | |
661 | */ | |
662 | ||
663 | return (status != HTTP_OK); | |
664 | } | |
665 | ||
666 | ||
667 | /* | |
d2935a0f | 668 | * End of "$Id: ipp.c,v 1.34 2001/01/22 15:03:19 mike Exp $". |
c8f9565c | 669 | */ |