]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/util.c
Fixed the IPP tag enumerations to match the final IPP/1.0 and /1.1
[thirdparty/cups.git] / cups / util.c
CommitLineData
3b960317 1/*
fafbba4f 2 * "$Id: util.c,v 1.27 1999/07/15 14:05:02 mike Exp $"
3b960317 3 *
4 * Printing utilities for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-1999 by Easy Software Products.
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.txt" 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
3b960317 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 *
3270670b 26 * cupsCancelJob() - Cancel a print job.
018b8ca8 27 * cupsDoFileRequest() - Do an IPP request...
3270670b 28 * cupsGetClasses() - Get a list of printer classes.
29 * cupsGetDefault() - Get the default printer or class.
30 * cupsGetPPD() - Get the PPD file for a printer.
31 * cupsGetPrinters() - Get a list of printers.
32 * cupsPrintFile() - Print a file to a printer or class.
33 * cups_connect() - Connect to the specified host...
3b960317 34 */
35
36/*
37 * Include necessary headers...
38 */
39
40#include "cups.h"
4a73831b 41#include "ipp.h"
42#include "language.h"
43#include "string.h"
44#include "debug.h"
aeabf506 45#include <stdlib.h>
46#include <ctype.h>
4a73831b 47#include <errno.h>
48#include <sys/stat.h>
d23a857a 49#if defined(WIN32) || defined(__EMX__)
50# include <io.h>
51#else
52# include <unistd.h>
53#endif /* WIN32 || __EMX__ */
3b960317 54
55
113aba7a 56/*
57 * Local globals...
58 */
59
d23a857a 60static http_t *cups_server = NULL;
61
62
63/*
64 * Local functions...
65 */
66
063e1ac7 67static char *cups_connect(const char *name, char *printer, char *hostname);
113aba7a 68
69
8431231f 70/*
71 * 'cupsCancelJob()' - Cancel a print job.
72 */
73
d23a857a 74int /* O - 1 on success, 0 on failure */
063e1ac7 75cupsCancelJob(const char *name, /* I - Name of printer or class */
76 int job) /* I - Job ID */
3b960317 77{
d23a857a 78 char printer[HTTP_MAX_URI], /* Printer name */
79 hostname[HTTP_MAX_URI], /* Hostname */
80 uri[HTTP_MAX_URI]; /* Printer URI */
81 ipp_t *request, /* IPP request */
82 *response; /* IPP response */
83 cups_lang_t *language; /* Language info */
84
85
86 /*
87 * See if we can connect to the server...
88 */
89
90 if (!cups_connect(name, printer, hostname))
2bffb563 91 return (0);
d23a857a 92
93 /*
94 * Build an IPP_CANCEL_JOB request, which requires the following
95 * attributes:
96 *
97 * attributes-charset
98 * attributes-natural-language
99 * printer-uri
100 * job-id
101 */
102
103 request = ippNew();
104
105 request->request.op.operation_id = IPP_CANCEL_JOB;
106 request->request.op.request_id = 1;
107
108 language = cupsLangDefault();
109
110 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
111 "attributes-charset", NULL, cupsLangEncoding(language));
112
113 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
114 "attributes-natural-language", NULL,
115 language != NULL ? language->language : "C");
116
117 sprintf(uri, "ipp://%s:%d/printers/%s", hostname, ippPort(), printer);
118 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
119 NULL, uri);
120
121 ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job);
122
123 /*
124 * Do the request...
125 */
126
127 if ((response = cupsDoRequest(cups_server, request, "/jobs/")) == NULL)
128 return (0);
129
130 ippDelete(response);
131 return (1);
3b960317 132}
133
134
113aba7a 135/*
3270670b 136 * 'cupsDoFileRequest()' - Do an IPP request...
113aba7a 137 */
138
3270670b 139ipp_t * /* O - Response data */
063e1ac7 140cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
141 ipp_t *request, /* I - IPP request */
142 const char *resource, /* I - HTTP resource for POST */
143 const char *filename) /* I - File to send or NULL */
113aba7a 144{
145 ipp_t *response; /* IPP response data */
146 char length[255]; /* Content-Length field */
cc389bfb 147 http_status_t status; /* Status of HTTP request */
3270670b 148 FILE *file; /* File to send */
149 struct stat fileinfo; /* File information */
150 int bytes; /* Number of bytes read/written */
151 char buffer[8192]; /* Output buffer */
063e1ac7 152 const char *password; /* Password string */
153 char plain[255], /* Plaintext username:password */
d23a857a 154 encode[255]; /* Encoded username:password */
d23a857a 155 static char authstring[255] = "";
156 /* Authorization string */
113aba7a 157
158
3270670b 159 DEBUG_printf(("cupsDoFileRequest(%08x, %08s, \'%s\', \'%s\')\n",
160 http, request, resource, filename ? filename : "(null)"));
113aba7a 161
162 /*
3270670b 163 * See if we have a file to send...
113aba7a 164 */
165
3270670b 166 if (filename != NULL)
167 {
168 if (stat(filename, &fileinfo))
169 {
170 /*
171 * Can't get file information!
172 */
113aba7a 173
3270670b 174 ippDelete(request);
175 return (NULL);
176 }
113aba7a 177
3270670b 178 if ((file = fopen(filename, "rb")) == NULL)
877378d9 179 {
3270670b 180 /*
181 * Can't open file!
182 */
183
877378d9 184 ippDelete(request);
185 return (NULL);
186 }
3270670b 187 }
113aba7a 188
189 /*
3270670b 190 * Loop until we can send the request without authorization problems.
113aba7a 191 */
192
3270670b 193 response = NULL;
d23a857a 194
3270670b 195 while (response == NULL)
d23a857a 196 {
3270670b 197 DEBUG_puts("cupsDoFileRequest: setup...");
198
d23a857a 199 /*
3270670b 200 * Setup the HTTP variables needed...
d23a857a 201 */
202
3270670b 203 if (filename != NULL)
6b67a15e 204 sprintf(length, "%u", ippLength(request) + (size_t)fileinfo.st_size);
3270670b 205 else
206 sprintf(length, "%u", ippLength(request));
d23a857a 207
3270670b 208 httpClearFields(http);
209 httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length);
210 httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
211 httpSetField(http, HTTP_FIELD_AUTHORIZATION, authstring);
212
213 /*
214 * Try the request...
215 */
216
217 DEBUG_puts("cupsDoFileRequest: post...");
218
219 if (httpPost(http, resource))
220 if (httpPost(http, resource))
221 break;
222
223 /*
224 * Send the IPP data and wait for the response...
225 */
226
227 DEBUG_puts("cupsDoFileRequest: ipp write...");
228
229 request->state = IPP_IDLE;
018b8ca8 230 if (ippWrite(http, request) != IPP_ERROR)
231 if (filename != NULL)
232 {
233 DEBUG_puts("cupsDoFileRequest: file write...");
d23a857a 234
018b8ca8 235 /*
236 * Send the file...
237 */
d23a857a 238
018b8ca8 239 rewind(file);
d23a857a 240
018b8ca8 241 while ((bytes = fread(buffer, 1, sizeof(buffer), file)) > 0)
242 if (httpWrite(http, buffer, bytes) < bytes)
243 break;
244 }
d23a857a 245
d23a857a 246 /*
3270670b 247 * Get the server's return status...
d23a857a 248 */
249
3270670b 250 DEBUG_puts("cupsDoFileRequest: update...");
d23a857a 251
018b8ca8 252 while ((status = httpUpdate(http)) == HTTP_CONTINUE);
253
018b8ca8 254 if (status == HTTP_UNAUTHORIZED)
3270670b 255 {
256 DEBUG_puts("cupsDoFileRequest: unauthorized...");
113aba7a 257
3270670b 258 /*
259 * Flush any error message...
260 */
261
262 httpFlush(http);
263
6b67a15e 264 if ((password = cupsGetPassword("Password:")) != NULL)
3270670b 265 {
266 /*
267 * Got a password; send it to the server...
268 */
113aba7a 269
018b8ca8 270 if (!password[0])
271 break;
6b67a15e 272 sprintf(plain, "%s:%s", cupsUser(), password);
3270670b 273 httpEncode64(encode, plain);
274 sprintf(authstring, "Basic %s", encode);
275
276 continue;
277 }
3da4463c 278 else
279 break;
3270670b 280 }
3270670b 281
282 if (status != HTTP_OK)
113aba7a 283 {
3270670b 284 DEBUG_printf(("cupsDoFileRequest: error %d...\n", status));
d23a857a 285
286 /*
3270670b 287 * Flush any error message...
d23a857a 288 */
289
69ee1496 290 httpFlush(http);
3270670b 291 break;
292 }
293 else
294 {
295 /*
296 * Read the response...
297 */
298
299 DEBUG_puts("cupsDoFileRequest: response...");
300
301 response = ippNew();
302
303 if (ippRead(http, response) == IPP_ERROR)
304 {
305 /*
306 * Delete the response...
307 */
308
309 ippDelete(response);
310 response = NULL;
311
312 /*
313 * Flush any remaining data...
314 */
315
316 httpFlush(http);
317 break;
318 }
113aba7a 319 }
320 }
321
3270670b 322 /*
323 * Close the file if needed...
324 */
325
326 if (filename != NULL)
327 fclose(file);
328
113aba7a 329 /*
330 * Delete the original request and return the response...
331 */
332
333 ippDelete(request);
334
335 return (response);
336}
337
338
8431231f 339/*
340 * 'cupsGetClasses()' - Get a list of printer classes.
341 */
342
d23a857a 343int /* O - Number of classes */
344cupsGetClasses(char ***classes) /* O - Classes */
3b960317 345{
d23a857a 346 int n; /* Number of classes */
347 ipp_t *request, /* IPP Request */
348 *response; /* IPP Response */
349 ipp_attribute_t *attr; /* Current attribute */
350 cups_lang_t *language; /* Default language */
351
352
353 /*
354 * Try to connect to the server...
355 */
356
357 if (!cups_connect("default", NULL, NULL))
2bffb563 358 return (0);
d23a857a 359
360 /*
361 * Build a CUPS_GET_CLASSES request, which requires the following
362 * attributes:
363 *
364 * attributes-charset
365 * attributes-natural-language
366 */
367
368 request = ippNew();
369
370 request->request.op.operation_id = CUPS_GET_CLASSES;
371 request->request.op.request_id = 1;
372
373 language = cupsLangDefault();
374
375 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
376 "attributes-charset", NULL, cupsLangEncoding(language));
377
378 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
379 "attributes-natural-language", NULL, language->language);
380
381 /*
382 * Do the request and get back a response...
383 */
384
385 n = 0;
386 *classes = NULL;
387
388 if ((response = cupsDoRequest(cups_server, request, "/classes/")) != NULL)
389 {
390 for (attr = response->attrs; attr != NULL; attr = attr->next)
391 if (strcmp(attr->name, "printer-name") == 0 &&
392 attr->value_tag == IPP_TAG_NAME)
393 {
394 if (n == 0)
395 *classes = malloc(sizeof(char *));
396 else
397 *classes = realloc(*classes, sizeof(char *) * (n + 1));
398
399 if (*classes == NULL)
400 {
401 ippDelete(response);
402 return (0);
403 }
404
405 (*classes)[n] = strdup(attr->values[0].string.text);
406 n ++;
407 }
408
409 ippDelete(response);
410 }
411
412 return (n);
3b960317 413}
414
415
8431231f 416/*
417 * 'cupsGetDefault()' - Get the default printer or class.
418 */
419
063e1ac7 420const char * /* O - Default printer or NULL */
4a73831b 421cupsGetDefault(void)
422{
113aba7a 423 ipp_t *request, /* IPP Request */
424 *response; /* IPP Response */
425 ipp_attribute_t *attr; /* Current attribute */
426 cups_lang_t *language; /* Default language */
427 static char def_printer[64];/* Default printer */
428
429
430 /*
431 * First see if the LPDEST or PRINTER environment variables are
432 * set...
433 */
434
435 if (getenv("LPDEST") != NULL)
436 return (getenv("LPDEST"));
437 else if (getenv("PRINTER") != NULL)
438 return (getenv("PRINTER"));
439
440 /*
441 * Try to connect to the server...
442 */
443
d23a857a 444 if (!cups_connect("default", NULL, NULL))
445 return (NULL);
113aba7a 446
447 /*
448 * Build a CUPS_GET_DEFAULT request, which requires the following
449 * attributes:
450 *
451 * attributes-charset
452 * attributes-natural-language
453 */
454
455 request = ippNew();
456
457 request->request.op.operation_id = CUPS_GET_DEFAULT;
458 request->request.op.request_id = 1;
459
460 language = cupsLangDefault();
461
d23a857a 462 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
463 "attributes-charset", NULL, cupsLangEncoding(language));
113aba7a 464
d23a857a 465 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
466 "attributes-natural-language", NULL, language->language);
113aba7a 467
468 /*
469 * Do the request and get back a response...
470 */
471
d23a857a 472 if ((response = cupsDoRequest(cups_server, request, "/printers/")) != NULL)
113aba7a 473 {
474 if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
475 {
476 strcpy(def_printer, attr->values[0].string.text);
477 ippDelete(response);
478 return (def_printer);
479 }
480
481 ippDelete(response);
482 }
483
484 return (NULL);
4a73831b 485}
486
487
8431231f 488/*
489 * 'cupsGetPPD()' - Get the PPD file for a printer.
490 */
491
063e1ac7 492const char * /* O - Filename for PPD file */
493cupsGetPPD(const char *name) /* I - Printer name */
3b960317 494{
d23a857a 495 FILE *fp; /* PPD file */
496 int bytes; /* Number of bytes read */
497 char buffer[8192]; /* Buffer for file */
498 char printer[HTTP_MAX_URI], /* Printer name */
499 hostname[HTTP_MAX_URI], /* Hostname */
500 resource[HTTP_MAX_URI]; /* Resource name */
501 static char filename[HTTP_MAX_URI]; /* Local filename */
502 char *tempdir; /* Temporary file directory */
503 struct stat fileinfo; /* File information */
504
505
506 /*
507 * See if we can connect to the server...
508 */
509
510 if (!cups_connect(name, printer, hostname))
511 return (NULL);
512
513 /*
514 * Then check for the cache file...
515 */
516
517#if defined(WIN32) || defined(__EMX__)
518 tempdir = "C:/WINDOWS/TEMP";
519#else
520 if ((tempdir = getenv("TMPDIR")) == NULL)
521 tempdir = "/tmp";
522#endif /* WIN32 || __EMX__ */
523
524 sprintf(filename, "%s/%s.ppd", tempdir, printer);
525 if (stat(filename, &fileinfo))
526 memset(&fileinfo, 0, sizeof(fileinfo));
527
528 /*
529 * And send a request to the HTTP server using "if-modified-since"...
530 */
531
532 sprintf(resource, "/printers/%s.ppd", printer);
533
534 httpClearFields(cups_server);
535 httpSetField(cups_server, HTTP_FIELD_HOST, hostname);
536 httpSetField(cups_server, HTTP_FIELD_IF_MODIFIED_SINCE,
537 httpGetDateString(fileinfo.st_mtime));
538 httpGet(cups_server, resource);
539
540 switch (httpUpdate(cups_server))
541 {
542 case HTTP_OK : /* New file - get it! */
543 break;
544 case HTTP_NOT_MODIFIED : /* File hasn't been modified; use the current copy */
545 return (filename);
546 default :
547 return (NULL);
548 }
549
550 /*
551 * OK, we need to copy the file; open the file and copy it...
552 */
553
554 unlink(filename);
555 if ((fp = fopen(filename, "w")) == NULL)
556 {
557 /*
558 * Can't open file; close the server connection and return NULL...
559 */
560
561 httpClose(cups_server);
562 cups_server = NULL;
563 return (NULL);
564 }
565
566 while ((bytes = httpRead(cups_server, buffer, sizeof(buffer))) > 0)
567 fwrite(buffer, bytes, 1, fp);
568
569 fclose(fp);
570
571 return (filename);
3b960317 572}
573
574
8431231f 575/*
576 * 'cupsGetPrinters()' - Get a list of printers.
577 */
578
d23a857a 579int /* O - Number of printers */
580cupsGetPrinters(char ***printers) /* O - Printers */
3b960317 581{
d23a857a 582 int n; /* Number of printers */
583 ipp_t *request, /* IPP Request */
584 *response; /* IPP Response */
585 ipp_attribute_t *attr; /* Current attribute */
586 cups_lang_t *language; /* Default language */
587
588
589 /*
590 * Try to connect to the server...
591 */
592
593 if (!cups_connect("default", NULL, NULL))
2bffb563 594 return (0);
d23a857a 595
596 /*
597 * Build a CUPS_GET_PRINTERS request, which requires the following
598 * attributes:
599 *
600 * attributes-charset
601 * attributes-natural-language
602 */
603
604 request = ippNew();
605
606 request->request.op.operation_id = CUPS_GET_PRINTERS;
607 request->request.op.request_id = 1;
608
609 language = cupsLangDefault();
610
611 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
612 "attributes-charset", NULL, cupsLangEncoding(language));
613
614 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
615 "attributes-natural-language", NULL, language->language);
616
617 /*
618 * Do the request and get back a response...
619 */
620
621 n = 0;
622 *printers = NULL;
623
624 if ((response = cupsDoRequest(cups_server, request, "/printers/")) != NULL)
625 {
626 for (attr = response->attrs; attr != NULL; attr = attr->next)
627 if (strcmp(attr->name, "printer-name") == 0 &&
628 attr->value_tag == IPP_TAG_NAME)
629 {
630 if (n == 0)
631 *printers = malloc(sizeof(char *));
632 else
633 *printers = realloc(*printers, sizeof(char *) * (n + 1));
634
635 if (*printers == NULL)
636 {
637 ippDelete(response);
638 return (0);
639 }
640
641 (*printers)[n] = strdup(attr->values[0].string.text);
642 n ++;
643 }
644
645 ippDelete(response);
646 }
647
648 return (n);
3b960317 649}
650
651
4a73831b 652/*
653 * 'cupsPrintFile()' - Print a file to a printer or class.
654 */
655
656int /* O - Job ID */
063e1ac7 657cupsPrintFile(const char *name, /* I - Printer or class name */
658 const char *filename, /* I - File to print */
659 const char *title, /* I - Title of job */
4a73831b 660 int num_options,/* I - Number of options */
661 cups_option_t *options) /* I - Options */
3b960317 662{
d23a857a 663 int i; /* Looping var */
664 int n, n2; /* Attribute values */
665 char *option, /* Name of option */
666 *val, /* Pointer to option value */
667 *s; /* Pointer into option value */
668 ipp_t *request; /* IPP request */
669 ipp_t *response; /* IPP response */
670 ipp_attribute_t *attr; /* IPP job-id attribute */
671 char hostname[HTTP_MAX_URI], /* Hostname */
672 printer[HTTP_MAX_URI], /* Printer or class name */
673 uri[HTTP_MAX_URI]; /* Printer URI */
674 cups_lang_t *language; /* Language to use */
d23a857a 675 int jobid; /* New job ID */
676
4a73831b 677
678 DEBUG_printf(("cupsPrintFile(\'%s\', \'%s\', %d, %08x)\n",
679 printer, filename, num_options, options));
680
d23a857a 681 if (name == NULL || filename == NULL)
4a73831b 682 return (0);
683
4a73831b 684 /*
685 * Setup a connection and request data...
686 */
687
688 if ((request = ippNew()) == NULL)
4a73831b 689 return (0);
4a73831b 690
d23a857a 691 if (!cups_connect(name, printer, hostname))
692 {
693 DEBUG_printf(("cupsPrintFile: Unable to open connection - %s.\n",
694 strerror(errno)));
d23a857a 695 ippDelete(request);
696 return (0);
697 }
4a73831b 698
699 /*
700 * Build a standard CUPS URI for the printer and fill the standard IPP
701 * attributes...
702 */
703
704 request->request.op.operation_id = IPP_PRINT_JOB;
705 request->request.op.request_id = 1;
706
d23a857a 707 sprintf(uri, "ipp://%s:%d/printers/%s", hostname, ippPort(), printer);
4a73831b 708
709 language = cupsLangDefault();
710
d23a857a 711 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
712 "attributes-charset", NULL, cupsLangEncoding(language));
4a73831b 713
d23a857a 714 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
715 "attributes-natural-language", NULL,
716 language != NULL ? language->language : "C");
4a73831b 717
d23a857a 718 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
719 NULL, uri);
4a73831b 720
877378d9 721 /*
722 * Handle raw print files...
723 */
724
725 if (cupsGetOption("raw", num_options, options))
726 ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
727 NULL, "application/vnd.cups-raw");
728 else
729 ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
730 NULL, "application/octet-stream");
5081f753 731
d23a857a 732 ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "requesting-user-name",
ac4c1450 733 NULL, cupsUser());
4a73831b 734
d23a857a 735 if (title)
736 ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, title);
737
4a73831b 738 /*
739 * Then add all options on the command-line...
740 */
741
4a73831b 742 for (i = 0; i < num_options; i ++)
743 {
877378d9 744 /*
745 * Skip the "raw" option - handled above...
746 */
747
748 if (strcmp(options[i].name, "raw") == 0)
749 continue;
750
e8fda7b9 751 /*
752 * See what the option value is; for compatibility with older interface
5356dc5a 753 * scripts, we have to support single-argument options as well as
aeabf506 754 * option=value, option=low-high, and option=MxN.
e8fda7b9 755 */
756
d23a857a 757 option = options[i].name;
758 val = options[i].value;
e8fda7b9 759
5356dc5a 760 if (*val == '\0')
761 val = NULL;
e8fda7b9 762
763 if (val != NULL)
764 {
765 if (strcasecmp(val, "true") == 0 ||
766 strcasecmp(val, "on") == 0 ||
767 strcasecmp(val, "yes") == 0)
768 {
769 /*
770 * Boolean value - true...
771 */
772
773 n = 1;
774 val = "";
775 }
776 else if (strcasecmp(val, "false") == 0 ||
777 strcasecmp(val, "off") == 0 ||
778 strcasecmp(val, "no") == 0)
779 {
780 /*
781 * Boolean value - false...
782 */
783
784 n = 0;
785 val = "";
786 }
787
788 n = strtol(val, &s, 0);
789 }
790 else
791 {
d23a857a 792 if (strncmp(option, "no", 2) == 0)
e8fda7b9 793 {
d23a857a 794 option += 2;
795 n = 0;
e8fda7b9 796 }
797 else
798 n = 1;
799
800 s = "";
801 }
802
aeabf506 803 if (*s != '\0' && *s != '-' && (*s != 'x' || s == val))
e8fda7b9 804 {
805 /*
806 * String value(s)...
807 */
808
4b666281 809 DEBUG_printf(("cupsPrintFile: Adding string option \'%s\' with value \'%s\'...\n",
d23a857a 810 option, val));
aeabf506 811
d23a857a 812 ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, option, NULL, val);
e8fda7b9 813 }
814 else if (val != NULL)
815 {
816 /*
aeabf506 817 * Numeric value, range, or resolution...
e8fda7b9 818 */
819
820 if (*s == '-')
821 {
d23a857a 822 n2 = strtol(s + 1, NULL, 0);
823 ippAddRange(request, IPP_TAG_JOB, option, n, n2);
aeabf506 824
4b666281 825 DEBUG_printf(("cupsPrintFile: Adding range option \'%s\' with value %d-%d...\n",
d23a857a 826 option, n, n2));
aeabf506 827 }
828 else if (*s == 'x')
829 {
830 n2 = strtol(s + 1, &s, 0);
831
5356dc5a 832 if (strcmp(s, "dpc") == 0)
d23a857a 833 ippAddResolution(request, IPP_TAG_JOB, option, IPP_RES_PER_CM, n, n2);
5356dc5a 834 else if (strcmp(s, "dpi") == 0)
d23a857a 835 ippAddResolution(request, IPP_TAG_JOB, option, IPP_RES_PER_INCH, n, n2);
aeabf506 836 else
d23a857a 837 ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, option, NULL, val);
aeabf506 838
4b666281 839 DEBUG_printf(("cupsPrintFile: Adding resolution option \'%s\' with value %s...\n",
d23a857a 840 option, val));
e8fda7b9 841 }
842 else
aeabf506 843 {
d23a857a 844 ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, option, n);
aeabf506 845
4b666281 846 DEBUG_printf(("cupsPrintFile: Adding integer option \'%s\' with value %d...\n",
d23a857a 847 option, n));
aeabf506 848 }
e8fda7b9 849 }
850 else
851 {
852 /*
853 * Boolean value...
854 */
855
4b666281 856 DEBUG_printf(("cupsPrintFile: Adding boolean option \'%s\' with value %d...\n",
d23a857a 857 option, n));
858 ippAddBoolean(request, IPP_TAG_JOB, option, (char)n);
e8fda7b9 859 }
4a73831b 860 }
4a73831b 861
862 /*
3270670b 863 * Try printing the file...
4a73831b 864 */
865
866 sprintf(uri, "/printers/%s", printer);
867
3270670b 868 if ((response = cupsDoFileRequest(cups_server, request, uri, filename)) == NULL)
869 jobid = 0;
870 else if (response->request.status.status_code > IPP_OK_CONFLICT)
4a73831b 871 {
3270670b 872 DEBUG_printf(("IPP response code was 0x%x!\n",
873 response->request.status.status_code));
4a73831b 874 jobid = 0;
875 }
3270670b 876 else if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL)
4a73831b 877 {
3270670b 878 DEBUG_puts("No job ID!");
4a73831b 879 jobid = 0;
880 }
881 else
3270670b 882 jobid = attr->values[0].integer;
4a73831b 883
3270670b 884 if (response != NULL)
885 ippDelete(response);
4a73831b 886
887 return (jobid);
3b960317 888}
889
890
891/*
d23a857a 892 * 'cups_connect()' - Connect to the specified host...
893 */
894
063e1ac7 895static char * /* I - Printer name or NULL */
896cups_connect(const char *name, /* I - Destination (printer[@host]) */
897 char *printer, /* O - Printer name */
898 char *hostname) /* O - Hostname */
d23a857a 899{
900 char hostbuf[HTTP_MAX_URI];
901 /* Name of host */
902 static char printerbuf[HTTP_MAX_URI];
903 /* Name of printer or class */
904
905
906 if (name == NULL)
907 return (NULL);
908
909 if (sscanf(name, "%[^@]@%s", printerbuf, hostbuf) == 1)
396faf38 910 strcpy(hostbuf, cupsServer());
d23a857a 911
912 if (hostname != NULL)
913 strcpy(hostname, hostbuf);
914 else
915 hostname = hostbuf;
916
917 if (printer != NULL)
918 strcpy(printer, printerbuf);
919 else
920 printer = printerbuf;
921
922 if (cups_server != NULL)
923 {
924 if (strcasecmp(cups_server->hostname, hostname) == 0)
925 return (printer);
926
927 httpClose(cups_server);
928 }
929
930 if ((cups_server = httpConnect(hostname, ippPort())) == NULL)
931 return (NULL);
932 else
933 return (printer);
934}
935
936
937/*
fafbba4f 938 * End of "$Id: util.c,v 1.27 1999/07/15 14:05:02 mike Exp $".
3b960317 939 */