]>
Commit | Line | Data |
---|---|---|
bf23e338 | 1 | /* |
753453e4 | 2 | * "$Id: dest.c,v 1.18.2.1 2001/12/26 16:52:11 mike Exp $" |
bf23e338 | 3 | * |
4 | * User-defined destination (and option) support for the Common UNIX | |
5 | * Printing System (CUPS). | |
6 | * | |
d2935a0f | 7 | * Copyright 1997-2001 by Easy Software Products. |
bf23e338 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
10 | * property of Easy Software Products and are protected by Federal | |
11 | * copyright law. Distribution and use rights are outlined in the file | |
12 | * "LICENSE.txt" which should have been included with this file. If this | |
13 | * file is missing or damaged please contact Easy Software Products | |
14 | * at: | |
15 | * | |
16 | * Attn: CUPS Licensing Information | |
17 | * Easy Software Products | |
18 | * 44141 Airport View Drive, Suite 204 | |
19 | * Hollywood, Maryland 20636-3111 USA | |
20 | * | |
21 | * Voice: (301) 373-9603 | |
22 | * EMail: cups-info@cups.org | |
23 | * WWW: http://www.cups.org | |
24 | * | |
25 | * Contents: | |
26 | * | |
faee7464 | 27 | * cupsAddDest() - Add a destination to the list of destinations. |
28 | * cupsFreeDests() - Free the memory used by the list of destinations. | |
29 | * cupsGetDest() - Get the named destination from the list. | |
30 | * cupsGetDests() - Get the list of destinations. | |
31 | * cupsSetDests() - Set the list of destinations. | |
32 | * cups_get_dests() - Get destinations from a file. | |
bf23e338 | 33 | */ |
34 | ||
35 | /* | |
36 | * Include necessary headers... | |
37 | */ | |
38 | ||
39 | #include "cups.h" | |
f4671380 | 40 | #include "string.h" |
41 | #include <stdlib.h> | |
8a2c2126 | 42 | #include <ctype.h> |
bf23e338 | 43 | |
44 | ||
45 | /* | |
46 | * Local functions... | |
47 | */ | |
48 | ||
49 | static int cups_get_dests(const char *filename, int num_dests, | |
50 | cups_dest_t **dests); | |
51 | ||
52 | ||
53 | /* | |
54 | * 'cupsAddDest()' - Add a destination to the list of destinations. | |
55 | */ | |
56 | ||
f4671380 | 57 | int /* O - New number of destinations */ |
58 | cupsAddDest(const char *name, /* I - Name of destination */ | |
59 | const char *instance, /* I - Instance of destination */ | |
60 | int num_dests, /* I - Number of destinations */ | |
61 | cups_dest_t **dests) /* IO - Destinations */ | |
bf23e338 | 62 | { |
f4671380 | 63 | int i; /* Looping var */ |
64 | cups_dest_t *dest; /* Destination pointer */ | |
65 | ||
66 | ||
67 | if (name == NULL || dests == NULL) | |
68 | return (0); | |
69 | ||
70 | if ((dest = cupsGetDest(name, instance, num_dests, *dests)) != NULL) | |
71 | return (num_dests); | |
72 | ||
73 | /* | |
74 | * Add new destination... | |
75 | */ | |
76 | ||
77 | if (num_dests == 0) | |
78 | dest = malloc(sizeof(cups_dest_t)); | |
79 | else | |
80 | dest = realloc(*dests, sizeof(cups_dest_t) * (num_dests + 1)); | |
81 | ||
82 | if (dest == NULL) | |
83 | return (num_dests); | |
84 | ||
85 | *dests = dest; | |
86 | ||
87 | for (i = num_dests; i > 0; i --, dest ++) | |
88 | if (strcasecmp(name, dest->name) < 0) | |
89 | break; | |
29134920 | 90 | else if (strcasecmp(name, dest->name) == 0 && |
91 | instance != NULL && dest->instance != NULL && | |
f4671380 | 92 | strcasecmp(instance, dest->instance) < 0) |
93 | break; | |
94 | ||
95 | if (i > 0) | |
96 | memmove(dest + 1, dest, i * sizeof(cups_dest_t)); | |
97 | ||
98 | dest->name = strdup(name); | |
99 | dest->is_default = 0; | |
100 | dest->num_options = 0; | |
101 | dest->options = (cups_option_t *)0; | |
102 | ||
103 | if (instance == NULL) | |
104 | dest->instance = NULL; | |
105 | else | |
106 | dest->instance = strdup(instance); | |
107 | ||
108 | return (num_dests + 1); | |
bf23e338 | 109 | } |
110 | ||
111 | ||
112 | /* | |
113 | * 'cupsFreeDests()' - Free the memory used by the list of destinations. | |
114 | */ | |
115 | ||
116 | void | |
f4671380 | 117 | cupsFreeDests(int num_dests, /* I - Number of destinations */ |
118 | cups_dest_t *dests) /* I - Destinations */ | |
bf23e338 | 119 | { |
f4671380 | 120 | int i; /* Looping var */ |
121 | cups_dest_t *dest; /* Current destination */ | |
122 | ||
123 | ||
124 | if (num_dests == 0 || dests == NULL) | |
125 | return; | |
126 | ||
127 | for (i = num_dests, dest = dests; i > 0; i --, dest ++) | |
128 | { | |
129 | free(dest->name); | |
130 | ||
131 | if (dest->instance) | |
132 | free(dest->instance); | |
133 | ||
134 | cupsFreeOptions(dest->num_options, dest->options); | |
135 | } | |
136 | ||
137 | free(dests); | |
bf23e338 | 138 | } |
139 | ||
140 | ||
141 | /* | |
142 | * 'cupsGetDest()' - Get the named destination from the list. | |
143 | */ | |
144 | ||
f4671380 | 145 | cups_dest_t * /* O - Destination pointer or NULL */ |
146 | cupsGetDest(const char *name, /* I - Name of destination */ | |
147 | const char *instance, /* I - Instance of destination */ | |
148 | int num_dests, /* I - Number of destinations */ | |
149 | cups_dest_t *dests) /* I - Destinations */ | |
bf23e338 | 150 | { |
f4671380 | 151 | int comp; /* Result of comparison */ |
152 | ||
153 | ||
7bfde0bb | 154 | if (num_dests == 0 || dests == NULL) |
f4671380 | 155 | return (NULL); |
156 | ||
7bfde0bb | 157 | if (name == NULL) |
f4671380 | 158 | { |
7bfde0bb | 159 | /* |
160 | * NULL name for default printer. | |
161 | */ | |
162 | ||
163 | while (num_dests > 0) | |
f4671380 | 164 | { |
7bfde0bb | 165 | if (dests->is_default) |
166 | return (dests); | |
167 | ||
168 | num_dests --; | |
169 | dests ++; | |
f4671380 | 170 | } |
7bfde0bb | 171 | } |
172 | else | |
173 | { | |
174 | /* | |
175 | * Lookup name and optionally the instance... | |
176 | */ | |
f4671380 | 177 | |
7bfde0bb | 178 | while (num_dests > 0) |
179 | { | |
180 | if ((comp = strcasecmp(name, dests->name)) < 0) | |
181 | return (NULL); | |
182 | else if (comp == 0) | |
183 | { | |
184 | if ((instance == NULL && dests->instance == NULL) || | |
185 | (instance != NULL && dests->instance != NULL && | |
186 | strcasecmp(instance, dests->instance) == 0)) | |
187 | return (dests); | |
188 | } | |
189 | ||
190 | num_dests --; | |
191 | dests ++; | |
192 | } | |
f4671380 | 193 | } |
194 | ||
195 | return (NULL); | |
bf23e338 | 196 | } |
197 | ||
198 | ||
199 | /* | |
200 | * 'cupsGetDests()' - Get the list of destinations. | |
201 | */ | |
202 | ||
203 | int /* O - Number of destinations */ | |
204 | cupsGetDests(cups_dest_t **dests) /* O - Destinations */ | |
205 | { | |
206 | int i; /* Looping var */ | |
207 | int num_dests; /* Number of destinations */ | |
208 | int count; /* Number of printers/classes */ | |
209 | char **names; /* Printer/class names */ | |
210 | cups_dest_t *dest; /* Destination pointer */ | |
f4671380 | 211 | const char *home; /* HOME environment variable */ |
212 | char filename[1024]; /* Local ~/.lpoptions file */ | |
37ac5c5e | 213 | const char *defprinter; /* Default printer */ |
214 | char name[1024], /* Copy of printer name */ | |
215 | *instance; /* Pointer to instance name */ | |
bf23e338 | 216 | |
217 | ||
218 | /* | |
219 | * Initialize destination array... | |
220 | */ | |
221 | ||
222 | num_dests = 0; | |
223 | *dests = (cups_dest_t *)0; | |
224 | ||
225 | /* | |
226 | * Grab all available printers... | |
227 | */ | |
228 | ||
229 | if ((count = cupsGetPrinters(&names)) > 0) | |
230 | { | |
231 | for (i = 0; i < count; i ++) | |
232 | { | |
f4671380 | 233 | num_dests = cupsAddDest(names[i], NULL, num_dests, dests); |
bf23e338 | 234 | free(names[i]); |
235 | } | |
236 | ||
237 | free(names); | |
238 | } | |
239 | ||
240 | /* | |
241 | * Grab all available classes... | |
242 | */ | |
243 | ||
244 | if ((count = cupsGetClasses(&names)) > 0) | |
245 | { | |
246 | for (i = 0; i < count; i ++) | |
247 | { | |
f4671380 | 248 | num_dests = cupsAddDest(names[i], NULL, num_dests, dests); |
bf23e338 | 249 | free(names[i]); |
250 | } | |
251 | ||
252 | free(names); | |
253 | } | |
254 | ||
255 | /* | |
256 | * Grab the default destination... | |
257 | */ | |
258 | ||
37ac5c5e | 259 | if ((defprinter = cupsGetDefault()) != NULL) |
260 | { | |
261 | /* | |
262 | * Grab printer and instance name... | |
263 | */ | |
264 | ||
265 | strncpy(name, defprinter, sizeof(name) - 1); | |
266 | name[sizeof(name) - 1] = '\0'; | |
267 | ||
268 | if ((instance = strchr(name, '/')) != NULL) | |
269 | *instance++ = '\0'; | |
270 | ||
271 | /* | |
272 | * Lookup the printer and instance and make it the default... | |
273 | */ | |
274 | ||
275 | if ((dest = cupsGetDest(name, instance, num_dests, *dests)) != NULL) | |
276 | dest->is_default = 1; | |
277 | } | |
753453e4 | 278 | else |
279 | { | |
280 | /* | |
281 | * This initialization of "instance" is unnecessary, but avoids a | |
282 | * compiler warning... | |
283 | */ | |
284 | ||
285 | instance = NULL; | |
286 | } | |
bf23e338 | 287 | |
288 | /* | |
289 | * Load the /etc/cups/lpoptions and ~/.lpoptions files... | |
290 | */ | |
291 | ||
3e3712a4 | 292 | if ((home = getenv("CUPS_SERVERROOT")) != NULL) |
293 | { | |
04de52f8 | 294 | snprintf(filename, sizeof(filename), "%s/lpoptions", home); |
3e3712a4 | 295 | num_dests = cups_get_dests(filename, num_dests, dests); |
296 | } | |
297 | else | |
298 | num_dests = cups_get_dests(CUPS_SERVERROOT "/lpoptions", num_dests, dests); | |
f4671380 | 299 | |
300 | if ((home = getenv("HOME")) != NULL) | |
301 | { | |
04de52f8 | 302 | snprintf(filename, sizeof(filename), "%s/.lpoptions", home); |
f4671380 | 303 | num_dests = cups_get_dests(filename, num_dests, dests); |
304 | } | |
bf23e338 | 305 | |
753453e4 | 306 | /* |
307 | * Reset the default destination if the LPDEST or PRINTER environment | |
308 | * variables are set... | |
309 | */ | |
310 | ||
311 | if (getenv("LPDEST") != NULL || getenv("PRINTER") != NULL) | |
312 | { | |
313 | /* | |
314 | * Lookup the printer and instance and make it the default... | |
315 | */ | |
316 | ||
317 | if ((dest = cupsGetDest(name, instance, num_dests, *dests)) != NULL) | |
318 | dest->is_default = 1; | |
319 | } | |
320 | ||
f4671380 | 321 | /* |
322 | * Return the number of destinations... | |
323 | */ | |
324 | ||
325 | return (num_dests); | |
bf23e338 | 326 | } |
327 | ||
328 | ||
329 | /* | |
330 | * 'cupsSetDests()' - Set the list of destinations. | |
331 | */ | |
332 | ||
333 | void | |
f4671380 | 334 | cupsSetDests(int num_dests, /* I - Number of destinations */ |
335 | cups_dest_t *dests) /* I - Destinations */ | |
bf23e338 | 336 | { |
f4671380 | 337 | int i, j; /* Looping vars */ |
338 | cups_dest_t *dest; /* Current destination */ | |
339 | cups_option_t *option; /* Current option */ | |
340 | FILE *fp; /* File pointer */ | |
341 | const char *home; /* HOME environment variable */ | |
342 | char filename[1024]; /* lpoptions file */ | |
343 | ||
344 | ||
345 | /* | |
346 | * Figure out which file to write to... | |
347 | */ | |
348 | ||
7ad5f9ca | 349 | #ifdef WIN32 |
350 | if ((home = getenv("CUPS_SERVERROOT")) == NULL) | |
351 | home = CUPS_SERVERROOT; | |
352 | ||
353 | snprintf(filename, sizeof(filename), "%s/lpoptions", home); | |
354 | #else | |
f4671380 | 355 | if (getuid() == 0) |
3e3712a4 | 356 | { |
a6988fb1 | 357 | if ((home = getenv("CUPS_SERVERROOT")) == NULL) |
358 | home = CUPS_SERVERROOT; | |
359 | ||
360 | snprintf(filename, sizeof(filename), "%s/lpoptions", home); | |
3e3712a4 | 361 | } |
f4671380 | 362 | else if ((home = getenv("HOME")) != NULL) |
04de52f8 | 363 | snprintf(filename, sizeof(filename), "%s/.lpoptions", home); |
f4671380 | 364 | else |
365 | return; | |
7ad5f9ca | 366 | #endif /* WIN32 */ |
f4671380 | 367 | |
368 | /* | |
369 | * Try to open the file... | |
370 | */ | |
371 | ||
372 | if ((fp = fopen(filename, "w")) == NULL) | |
373 | return; | |
374 | ||
375 | /* | |
376 | * Write each printer; each line looks like: | |
377 | * | |
378 | * Dest name[/instance] options | |
379 | * Default name[/instance] options | |
380 | */ | |
381 | ||
382 | for (i = num_dests, dest = dests; i > 0; i --, dest ++) | |
db504ff1 | 383 | if (dest->instance != NULL || dest->num_options != 0 || dest->is_default) |
f4671380 | 384 | { |
385 | fprintf(fp, "%s %s", dest->is_default ? "Default" : "Dest", | |
386 | dest->name); | |
387 | if (dest->instance) | |
388 | fprintf(fp, "/%s", dest->instance); | |
389 | ||
390 | for (j = dest->num_options, option = dest->options; j > 0; j --, option ++) | |
9495a093 | 391 | if (option->value[0]) |
f12f2b91 | 392 | { |
393 | if (strchr(option->value, ' ') != NULL) | |
394 | fprintf(fp, " %s=\"%s\"", option->name, option->value); | |
395 | else | |
396 | fprintf(fp, " %s=%s", option->name, option->value); | |
397 | } | |
9495a093 | 398 | else |
399 | fprintf(fp, " %s", option->name); | |
f4671380 | 400 | |
401 | fputs("\n", fp); | |
402 | } | |
403 | ||
404 | /* | |
405 | * Close the file and return... | |
406 | */ | |
407 | ||
408 | fclose(fp); | |
bf23e338 | 409 | } |
410 | ||
411 | ||
412 | /* | |
413 | * 'cups_get_dests()' - Get destinations from a file. | |
414 | */ | |
415 | ||
416 | static int /* O - Number of destinations */ | |
417 | cups_get_dests(const char *filename, /* I - File to read from */ | |
418 | int num_dests, /* I - Number of destinations */ | |
419 | cups_dest_t **dests) /* IO - Destinations */ | |
420 | { | |
db504ff1 | 421 | int i; /* Looping var */ |
f4671380 | 422 | cups_dest_t *dest; /* Current destination */ |
f4671380 | 423 | FILE *fp; /* File pointer */ |
424 | char line[8192], /* Line from file */ | |
425 | *lineptr, /* Pointer into line */ | |
426 | *name, /* Name of destination/option */ | |
db504ff1 | 427 | *instance; /* Instance of destination */ |
97aa42aa | 428 | const char *printer; /* PRINTER or LPDEST */ |
f4671380 | 429 | |
430 | ||
97aa42aa | 431 | /* |
432 | * Check environment variables... | |
433 | */ | |
434 | ||
435 | if ((printer = getenv("LPDEST")) == NULL) | |
436 | if ((printer = getenv("PRINTER")) != NULL) | |
437 | if (strcmp(printer, "lp") == 0) | |
438 | printer = NULL; | |
439 | ||
f4671380 | 440 | /* |
441 | * Try to open the file... | |
442 | */ | |
443 | ||
444 | if ((fp = fopen(filename, "r")) == NULL) | |
db504ff1 | 445 | return (num_dests); |
f4671380 | 446 | |
447 | /* | |
448 | * Read each printer; each line looks like: | |
449 | * | |
450 | * Dest name[/instance] options | |
451 | * Default name[/instance] options | |
452 | */ | |
453 | ||
454 | while (fgets(line, sizeof(line), fp) != NULL) | |
455 | { | |
456 | /* | |
457 | * See what type of line it is... | |
458 | */ | |
459 | ||
460 | if (strncasecmp(line, "dest", 4) == 0 && isspace(line[4])) | |
461 | lineptr = line + 4; | |
db504ff1 | 462 | else if (strncasecmp(line, "default", 7) == 0 && isspace(line[7])) |
f4671380 | 463 | lineptr = line + 7; |
464 | else | |
465 | continue; | |
466 | ||
467 | /* | |
468 | * Skip leading whitespace... | |
469 | */ | |
470 | ||
471 | while (isspace(*lineptr)) | |
472 | lineptr ++; | |
473 | ||
474 | if (!*lineptr) | |
475 | continue; | |
476 | ||
477 | name = lineptr; | |
478 | ||
479 | /* | |
480 | * Search for an instance... | |
481 | */ | |
482 | ||
483 | while (!isspace(*lineptr) && *lineptr && *lineptr != '/') | |
484 | lineptr ++; | |
485 | ||
486 | if (!*lineptr) | |
487 | continue; | |
488 | ||
489 | if (*lineptr == '/') | |
490 | { | |
491 | /* | |
492 | * Found an instance... | |
493 | */ | |
494 | ||
495 | *lineptr++ = '\0'; | |
496 | instance = lineptr; | |
497 | ||
498 | /* | |
499 | * Search for an instance... | |
500 | */ | |
501 | ||
502 | while (!isspace(*lineptr) && *lineptr) | |
503 | lineptr ++; | |
504 | } | |
505 | else | |
506 | instance = NULL; | |
507 | ||
508 | *lineptr++ = '\0'; | |
509 | ||
510 | /* | |
511 | * Add the destination... | |
512 | */ | |
513 | ||
514 | num_dests = cupsAddDest(name, instance, num_dests, dests); | |
515 | ||
516 | if ((dest = cupsGetDest(name, instance, num_dests, *dests)) == NULL) | |
517 | { | |
518 | /* | |
519 | * Out of memory! | |
520 | */ | |
521 | ||
522 | fclose(fp); | |
db504ff1 | 523 | return (num_dests); |
f4671380 | 524 | } |
525 | ||
526 | /* | |
527 | * Add options until we hit the end of the line... | |
528 | */ | |
529 | ||
faee7464 | 530 | if (dest->num_options) |
531 | { | |
532 | /* | |
533 | * Free old options... | |
534 | */ | |
535 | ||
536 | cupsFreeOptions(dest->num_options, dest->options); | |
537 | ||
538 | dest->num_options = 0; | |
539 | dest->options = (cups_option_t *)0; | |
540 | } | |
541 | ||
db504ff1 | 542 | dest->num_options = cupsParseOptions(lineptr, dest->num_options, |
543 | &(dest->options)); | |
f4671380 | 544 | |
db504ff1 | 545 | /* |
546 | * Set this as default if needed... | |
547 | */ | |
f4671380 | 548 | |
97aa42aa | 549 | if (strncasecmp(line, "default", 7) == 0 && printer == NULL) |
db504ff1 | 550 | { |
551 | for (i = 0; i < num_dests; i ++) | |
552 | (*dests)[i].is_default = 0; | |
f4671380 | 553 | |
db504ff1 | 554 | dest->is_default = 1; |
f4671380 | 555 | } |
556 | } | |
557 | ||
558 | /* | |
559 | * Close the file and return... | |
560 | */ | |
561 | ||
562 | fclose(fp); | |
1e907b5a | 563 | |
564 | return (num_dests); | |
bf23e338 | 565 | } |
566 | ||
567 | ||
568 | /* | |
753453e4 | 569 | * 'cups_get_sdests()' - Get destinations from a server. |
570 | */ | |
571 | ||
572 | static int /* O - Number of destinations */ | |
573 | cups_get_sdests(ipp_op_t op, /* I - get-printers or get-classes */ | |
574 | int num_dests, /* I - Number of destinations */ | |
575 | cups_dest_t **dests) /* IO - Destinations */ | |
576 | { | |
577 | cups_dest_t *dest; /* Current destination */ | |
578 | http_t *http; /* HTTP connection */ | |
579 | ipp_t *request, /* IPP Request */ | |
580 | *response; /* IPP Response */ | |
581 | ipp_attribute_t *attr; /* Current attribute */ | |
582 | cups_lang_t *language; /* Default language */ | |
583 | const char *name; /* printer-name attribute */ | |
584 | char job_sheets[1024]; /* job-sheets option */ | |
585 | static const char *pattrs[] = /* Attributes we're interested in */ | |
586 | { | |
587 | "printer-name", | |
588 | "job-sheets-default" | |
589 | }; | |
590 | ||
591 | ||
592 | /* | |
593 | * Connect to the CUPS server... | |
594 | */ | |
595 | ||
596 | if ((http = httpConnect(cupsServer(), ippPort())) == NULL) | |
597 | return (num_dests); | |
598 | ||
599 | /* | |
600 | * Build a CUPS_GET_PRINTERS or CUPS_GET_CLASSES request, which require | |
601 | * the following attributes: | |
602 | * | |
603 | * attributes-charset | |
604 | * attributes-natural-language | |
605 | */ | |
606 | ||
607 | request = ippNew(); | |
608 | ||
609 | request->request.op.operation_id = op; | |
610 | request->request.op.request_id = 1; | |
611 | ||
612 | language = cupsLangDefault(); | |
613 | ||
614 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, | |
615 | "attributes-charset", NULL, cupsLangEncoding(language)); | |
616 | ||
617 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, | |
618 | "attributes-natural-language", NULL, language->language); | |
619 | ||
620 | ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, | |
621 | "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), | |
622 | NULL, pattrs); | |
623 | ||
624 | /* | |
625 | * Do the request and get back a response... | |
626 | */ | |
627 | ||
628 | if ((response = cupsDoRequest(http, request, "/")) != NULL) | |
629 | { | |
630 | for (attr = response->attrs; attr != NULL; attr = attr->next) | |
631 | { | |
632 | /* | |
633 | * Skip leading attributes until we hit a printer... | |
634 | */ | |
635 | ||
636 | while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) | |
637 | attr = attr->next; | |
638 | ||
639 | if (attr == NULL) | |
640 | break; | |
641 | ||
642 | /* | |
643 | * Pull the needed attributes from this job... | |
644 | */ | |
645 | ||
646 | name = NULL; | |
647 | ||
648 | strcpy(job_sheets, ""); | |
649 | ||
650 | while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) | |
651 | { | |
652 | if (strcmp(attr->name, "printer-name") == 0 && | |
653 | attr->value_tag == IPP_TAG_NAME) | |
654 | name = attr->values[0].string.text; | |
655 | ||
656 | if (strcmp(attr->name, "job-sheets-default") == 0 && | |
657 | (attr->value_tag == IPP_TAG_KEYWORD || | |
658 | attr->value_tag == IPP_TAG_NAME)) | |
659 | { | |
660 | if (attr->num_values == 2) | |
661 | snprintf(job_sheets, sizeof(job_sheets), "%s,%s", | |
662 | attr->values[0].string.text, attr->values[1].string.text); | |
663 | else | |
664 | strcpy(job_sheets, attr->values[0].string.text); | |
665 | } | |
666 | ||
667 | attr = attr->next; | |
668 | } | |
669 | ||
670 | /* | |
671 | * See if we have everything needed... | |
672 | */ | |
673 | ||
674 | if (!name) | |
675 | { | |
676 | if (attr == NULL) | |
677 | break; | |
678 | else | |
679 | continue; | |
680 | } | |
681 | ||
682 | num_dests = cupsAddDest(name, NULL, num_dests, dests); | |
683 | ||
684 | if ((dest = cupsGetDest(name, NULL, num_dests, *dests)) != NULL) | |
685 | if (job_sheets[0]) | |
686 | dest->num_options = cupsAddOption("job-sheets", job_sheets, 0, | |
687 | &(dest->options)); | |
688 | ||
689 | if (attr == NULL) | |
690 | break; | |
691 | } | |
692 | ||
693 | ippDelete(response); | |
694 | } | |
695 | ||
696 | /* | |
697 | * Close the server connection... | |
698 | */ | |
699 | ||
700 | httpClose(http); | |
701 | ||
702 | /* | |
703 | * Return the count... | |
704 | */ | |
705 | ||
706 | return (num_dests); | |
707 | } | |
708 | ||
709 | ||
710 | /* | |
711 | * End of "$Id: dest.c,v 1.18.2.1 2001/12/26 16:52:11 mike Exp $". | |
bf23e338 | 712 | */ |