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