2 * "$Id: lpoptions.c 9793 2011-05-20 03:49:49Z mike $"
4 * Printer option program for CUPS.
6 * Copyright 2007-2011 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
17 * main() - Main entry.
18 * list_group() - List printer-specific options from the PPD group.
19 * list_options() - List printer-specific options from the PPD file.
20 * usage() - Show program usage and exit.
24 * Include necessary headers...
27 #include <cups/cups-private.h>
34 static void list_group(ppd_file_t *ppd, ppd_group_t *group);
35 static void list_options(cups_dest_t *dest);
36 static void usage(void);
40 * 'main()' - Main entry.
43 int /* O - Exit status */
44 main(int argc, /* I - Number of command-line arguments */
45 char *argv[]) /* I - Command-line arguments */
47 int i, j; /* Looping vars */
48 int changes; /* Did we make changes? */
49 int num_options; /* Number of options */
50 cups_option_t *options; /* Options */
51 int num_dests; /* Number of destinations */
52 cups_dest_t *dests; /* Destinations */
53 cups_dest_t *dest; /* Current destination */
54 char *printer, /* Printer name */
55 *instance, /* Instance name */
56 *option; /* Current option */
62 * Loop through the command-line arguments...
72 for (i = 1; i < argc; i ++)
73 if (argv[i][0] == '-')
77 case 'd' : /* -d printer */
79 printer = argv[i] + 2;
89 if ((instance = strrchr(printer, '/')) != NULL)
93 num_dests = cupsGetDests(&dests);
95 if (num_dests == 0 || !dests ||
96 (dest = cupsGetDest(printer, instance, num_dests,
99 _cupsLangPuts(stderr, _("lpoptions: Unknown printer or class."));
104 * Set the default destination...
107 for (j = 0; j < num_dests; j ++)
108 dests[j].is_default = 0;
110 dest->is_default = 1;
112 cupsSetDests(num_dests, dests);
114 for (j = 0; j < dest->num_options; j ++)
115 if (cupsGetOption(dest->options[j].name, num_options,
117 num_options = cupsAddOption(dest->options[j].name,
118 dest->options[j].value,
119 num_options, &options);
122 case 'h' : /* -h server */
124 cupsSetServer(argv[i] + 2);
131 cupsSetServer(argv[i]);
135 case 'E' : /* Encrypt connection */
136 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
139 case 'l' : /* -l (list options) */
143 num_dests = cupsGetDests(&dests);
145 if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
150 _cupsLangPuts(stderr, _("lpoptions: No printers."));
157 case 'o' : /* -o option[=value] */
161 num_dests = cupsGetDests(&dests);
163 if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
168 _cupsLangPuts(stderr, _("lpoptions: No printers."));
172 for (j = 0; j < dest->num_options; j ++)
173 if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
174 num_options = cupsAddOption(dest->options[j].name,
175 dest->options[j].value,
176 num_options, &options);
180 num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
187 num_options = cupsParseOptions(argv[i], num_options, &options);
193 case 'p' : /* -p printer */
195 printer = argv[i] + 2;
205 if ((instance = strrchr(printer, '/')) != NULL)
209 num_dests = cupsGetDests(&dests);
211 if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
213 num_dests = cupsAddDest(printer, instance, num_dests, &dests);
214 dest = cupsGetDest(printer, instance, num_dests, dests);
218 _cupsLangPrintf(stderr,
219 _("lpoptions: Unable to add printer or "
226 for (j = 0; j < dest->num_options; j ++)
227 if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
228 num_options = cupsAddOption(dest->options[j].name,
229 dest->options[j].value,
230 num_options, &options);
233 case 'r' : /* -r option (remove) */
237 num_dests = cupsGetDests(&dests);
239 if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
244 _cupsLangPuts(stderr, _("lpoptions: No printers."));
248 for (j = 0; j < dest->num_options; j ++)
249 if (cupsGetOption(dest->options[j].name, num_options,
251 num_options = cupsAddOption(dest->options[j].name,
252 dest->options[j].value,
253 num_options, &options);
257 option = argv[i] + 2;
267 for (j = 0; j < num_options; j ++)
268 if (!_cups_strcasecmp(options[j].name, option))
271 * Remove this option...
277 memcpy(options + j, options + j + 1,
278 sizeof(cups_option_t) * (num_options - j));
285 case 'x' : /* -x printer */
287 printer = argv[i] + 2;
297 if ((instance = strrchr(printer, '/')) != NULL)
301 num_dests = cupsGetDests(&dests);
303 if ((dest = cupsGetDest(printer, instance, num_dests,
306 cupsFreeOptions(dest->num_options, dest->options);
309 * If we are "deleting" the default printer, then just set the
310 * number of options to 0; if it is also the system default
311 * then cupsSetDests() will remove it for us...
314 if (dest->is_default)
316 dest->num_options = 0;
317 dest->options = NULL;
325 memcpy(dest, dest + 1, (num_dests - j) * sizeof(cups_dest_t));
329 cupsSetDests(num_dests, dests);
342 num_dests = cupsGetDests(&dests);
346 if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL)
348 for (j = 0; j < dest->num_options; j ++)
349 if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
350 num_options = cupsAddOption(dest->options[j].name,
351 dest->options[j].value,
352 num_options, &options);
362 * Set printer options...
365 cupsFreeOptions(dest->num_options, dest->options);
367 dest->num_options = num_options;
368 dest->options = options;
370 cupsSetDests(num_dests, dests);
372 else if (changes == 0)
374 char buffer[10240], /* String for options */
375 *ptr; /* Pointer into string */
377 num_options = dest->num_options;
378 options = dest->options;
380 for (i = 0, ptr = buffer;
381 ptr < (buffer + sizeof(buffer) - 1) && i < num_options;
387 if (!options[i].value[0])
388 strlcpy(ptr, options[i].name, sizeof(buffer) - (ptr - buffer));
389 else if (strchr(options[i].value, ' ') != NULL ||
390 strchr(options[i].value, '\t') != NULL)
391 snprintf(ptr, sizeof(buffer) - (ptr - buffer), "%s=\'%s\'",
392 options[i].name, options[i].value);
394 snprintf(ptr, sizeof(buffer) - (ptr - buffer), "%s=%s",
395 options[i].name, options[i].value);
400 _cupsLangPuts(stdout, buffer);
407 * 'list_group()' - List printer-specific options from the PPD group.
411 list_group(ppd_file_t *ppd, /* I - PPD file */
412 ppd_group_t *group) /* I - Group to show */
414 int i, j; /* Looping vars */
415 ppd_option_t *option; /* Current option */
416 ppd_choice_t *choice; /* Current choice */
417 ppd_group_t *subgroup; /* Current subgroup */
418 char buffer[10240], /* Option string buffer */
419 *ptr; /* Pointer into option string */
422 for (i = group->num_options, option = group->options; i > 0; i --, option ++)
424 if (!_cups_strcasecmp(option->keyword, "PageRegion"))
427 snprintf(buffer, sizeof(buffer), "%s/%s:", option->keyword, option->text);
429 for (j = option->num_choices, choice = option->choices,
430 ptr = buffer + strlen(buffer);
431 j > 0 && ptr < (buffer + sizeof(buffer) - 1);
434 if (!_cups_strcasecmp(choice->choice, "Custom"))
436 ppd_coption_t *coption; /* Custom option */
437 ppd_cparam_t *cparam; /* Custom parameter */
438 static const char * const types[] =
439 { /* Parameter types */
451 if ((coption = ppdFindCustomOption(ppd, option->keyword)) == NULL ||
452 cupsArrayCount(coption->params) == 0)
453 snprintf(ptr, sizeof(buffer) - (ptr - buffer), " %sCustom",
454 choice->marked ? "*" : "");
455 else if (!_cups_strcasecmp(option->keyword, "PageSize") ||
456 !_cups_strcasecmp(option->keyword, "PageRegion"))
457 snprintf(ptr, sizeof(buffer) - (ptr - buffer),
458 " %sCustom.WIDTHxHEIGHT", choice->marked ? "*" : "");
461 cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
463 if (cupsArrayCount(coption->params) == 1)
464 snprintf(ptr, sizeof(buffer) - (ptr - buffer), " %sCustom.%s",
465 choice->marked ? "*" : "", types[cparam->type]);
468 const char *prefix; /* Prefix string */
478 snprintf(ptr, sizeof(buffer) - (ptr - buffer), "%s%s=%s", prefix,
479 cparam->name, types[cparam->type]);
480 cparam = (ppd_cparam_t *)cupsArrayNext(coption->params);
485 if (ptr < (buffer + sizeof(buffer) - 1))
486 strlcpy(ptr, "}", sizeof(buffer) - (ptr - buffer));
490 else if (choice->marked)
491 snprintf(ptr, sizeof(buffer) - (ptr - buffer), " *%s", choice->choice);
493 snprintf(ptr, sizeof(buffer) - (ptr - buffer), " %s", choice->choice);
498 _cupsLangPuts(stdout, buffer);
501 for (i = group->num_subgroups, subgroup = group->subgroups; i > 0; i --, subgroup ++)
502 list_group(ppd, subgroup);
507 * 'list_options()' - List printer-specific options from the PPD file.
511 list_options(cups_dest_t *dest) /* I - Destination to list */
513 int i; /* Looping var */
514 const char *filename; /* PPD filename */
515 ppd_file_t *ppd; /* PPD data */
516 ppd_group_t *group; /* Current group */
519 if ((filename = cupsGetPPD(dest->name)) == NULL)
521 _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"),
522 dest->name, cupsLastErrorString());
526 if ((ppd = ppdOpenFile(filename)) == NULL)
529 _cupsLangPrintf(stderr, _("lpoptions: Unable to open PPD file for %s."),
534 ppdMarkDefaults(ppd);
535 cupsMarkOptions(ppd, dest->num_options, dest->options);
537 for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
538 list_group(ppd, group);
546 * 'usage()' - Show program usage and exit.
552 _cupsLangPuts(stdout,
553 _("Usage: lpoptions [-h server] [-E] -d printer\n"
554 " lpoptions [-h server] [-E] [-p printer] -l\n"
555 " lpoptions [-h server] [-E] -p printer -o "
556 "option[=value] ...\n"
557 " lpoptions [-h server] [-E] -x printer"));
564 * End of "$Id: lpoptions.c 9793 2011-05-20 03:49:49Z mike $".