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