]>
git.ipfire.org Git - thirdparty/cups.git/blob - systemv/lpoptions.c
df7c2d63d078d264368ec1e29e5350f038b9f0b3
4 * Printer option program for CUPS.
6 * Copyright 2007-2015 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 * Include necessary headers...
20 #include <cups/cups-private.h>
21 #include <cups/ppd-private.h>
28 static void list_group(ppd_file_t
*ppd
, ppd_group_t
*group
);
29 static void list_options(cups_dest_t
*dest
);
30 static void usage(void) __attribute__((noreturn
));
34 * 'main()' - Main entry.
37 int /* O - Exit status */
38 main(int argc
, /* I - Number of command-line arguments */
39 char *argv
[]) /* I - Command-line arguments */
41 int i
, j
; /* Looping vars */
42 int changes
; /* Did we make changes? */
43 int num_options
; /* Number of options */
44 cups_option_t
*options
; /* Options */
45 int num_dests
; /* Number of destinations */
46 cups_dest_t
*dests
; /* Destinations */
47 cups_dest_t
*dest
; /* Current destination */
48 char *printer
, /* Printer name */
49 *instance
, /* Instance name */
50 *option
; /* Current option */
56 * Loop through the command-line arguments...
66 for (i
= 1; i
< argc
; i
++)
67 if (argv
[i
][0] == '-')
71 case 'd' : /* -d printer */
73 printer
= argv
[i
] + 2;
83 if ((instance
= strrchr(printer
, '/')) != NULL
)
87 num_dests
= cupsGetDests(&dests
);
89 if (num_dests
== 0 || !dests
||
90 (dest
= cupsGetDest(printer
, instance
, num_dests
,
93 _cupsLangPuts(stderr
, _("lpoptions: Unknown printer or class."));
98 * Set the default destination...
101 for (j
= 0; j
< num_dests
; j
++)
102 dests
[j
].is_default
= 0;
104 dest
->is_default
= 1;
106 cupsSetDests(num_dests
, dests
);
108 for (j
= 0; j
< dest
->num_options
; j
++)
109 if (cupsGetOption(dest
->options
[j
].name
, num_options
,
111 num_options
= cupsAddOption(dest
->options
[j
].name
,
112 dest
->options
[j
].value
,
113 num_options
, &options
);
116 case 'h' : /* -h server */
118 cupsSetServer(argv
[i
] + 2);
125 cupsSetServer(argv
[i
]);
129 case 'E' : /* Encrypt connection */
130 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED
);
133 case 'l' : /* -l (list options) */
137 num_dests
= cupsGetDests(&dests
);
139 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) == NULL
)
144 _cupsLangPuts(stderr
, _("lpoptions: No printers."));
151 case 'o' : /* -o option[=value] */
155 num_dests
= cupsGetDests(&dests
);
157 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) == NULL
)
162 _cupsLangPuts(stderr
, _("lpoptions: No printers."));
166 for (j
= 0; j
< dest
->num_options
; j
++)
167 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
168 num_options
= cupsAddOption(dest
->options
[j
].name
,
169 dest
->options
[j
].value
,
170 num_options
, &options
);
174 num_options
= cupsParseOptions(argv
[i
] + 2, num_options
, &options
);
181 num_options
= cupsParseOptions(argv
[i
], num_options
, &options
);
187 case 'p' : /* -p printer */
189 printer
= argv
[i
] + 2;
199 if ((instance
= strrchr(printer
, '/')) != NULL
)
203 num_dests
= cupsGetDests(&dests
);
205 if ((dest
= cupsGetDest(printer
, instance
, num_dests
, dests
)) == NULL
)
207 num_dests
= cupsAddDest(printer
, instance
, num_dests
, &dests
);
208 dest
= cupsGetDest(printer
, instance
, num_dests
, dests
);
212 _cupsLangPrintf(stderr
,
213 _("lpoptions: Unable to add printer or "
220 for (j
= 0; j
< dest
->num_options
; j
++)
221 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
222 num_options
= cupsAddOption(dest
->options
[j
].name
,
223 dest
->options
[j
].value
,
224 num_options
, &options
);
227 case 'r' : /* -r option (remove) */
231 num_dests
= cupsGetDests(&dests
);
233 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) == NULL
)
238 _cupsLangPuts(stderr
, _("lpoptions: No printers."));
242 for (j
= 0; j
< dest
->num_options
; j
++)
243 if (cupsGetOption(dest
->options
[j
].name
, num_options
,
245 num_options
= cupsAddOption(dest
->options
[j
].name
,
246 dest
->options
[j
].value
,
247 num_options
, &options
);
251 option
= argv
[i
] + 2;
261 for (j
= 0; j
< num_options
; j
++)
262 if (!_cups_strcasecmp(options
[j
].name
, option
))
265 * Remove this option...
271 memmove(options
+ j
, options
+ j
+ 1, sizeof(cups_option_t
) * (size_t)(num_options
- j
));
278 case 'x' : /* -x printer */
280 printer
= argv
[i
] + 2;
290 if ((instance
= strrchr(printer
, '/')) != NULL
)
294 num_dests
= cupsGetDests(&dests
);
296 if ((dest
= cupsGetDest(printer
, instance
, num_dests
,
299 cupsFreeOptions(dest
->num_options
, dest
->options
);
302 * If we are "deleting" the default printer, then just set the
303 * number of options to 0; if it is also the system default
304 * then cupsSetDests() will remove it for us...
307 if (dest
->is_default
)
309 dest
->num_options
= 0;
310 dest
->options
= NULL
;
318 memmove(dest
, dest
+ 1, (size_t)(num_dests
- j
) * sizeof(cups_dest_t
));
322 cupsSetDests(num_dests
, dests
);
335 num_dests
= cupsGetDests(&dests
);
339 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) != NULL
)
341 for (j
= 0; j
< dest
->num_options
; j
++)
342 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
343 num_options
= cupsAddOption(dest
->options
[j
].name
,
344 dest
->options
[j
].value
,
345 num_options
, &options
);
355 * Set printer options...
358 cupsFreeOptions(dest
->num_options
, dest
->options
);
360 dest
->num_options
= num_options
;
361 dest
->options
= options
;
363 cupsSetDests(num_dests
, dests
);
365 else if (changes
== 0)
367 char buffer
[10240], /* String for options */
368 *ptr
; /* Pointer into string */
370 num_options
= dest
->num_options
;
371 options
= dest
->options
;
373 for (i
= 0, ptr
= buffer
;
374 ptr
< (buffer
+ sizeof(buffer
) - 1) && i
< num_options
;
380 if (!options
[i
].value
[0])
381 strlcpy(ptr
, options
[i
].name
, sizeof(buffer
) - (size_t)(ptr
- buffer
));
382 else if (strchr(options
[i
].value
, ' ') != NULL
||
383 strchr(options
[i
].value
, '\t') != NULL
)
384 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), "%s=\'%s\'", options
[i
].name
, options
[i
].value
);
386 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), "%s=%s", options
[i
].name
, options
[i
].value
);
391 _cupsLangPuts(stdout
, buffer
);
398 * 'list_group()' - List printer-specific options from the PPD group.
402 list_group(ppd_file_t
*ppd
, /* I - PPD file */
403 ppd_group_t
*group
) /* I - Group to show */
405 int i
, j
; /* Looping vars */
406 ppd_option_t
*option
; /* Current option */
407 ppd_choice_t
*choice
; /* Current choice */
408 ppd_group_t
*subgroup
; /* Current subgroup */
409 char buffer
[10240], /* Option string buffer */
410 *ptr
; /* Pointer into option string */
413 for (i
= group
->num_options
, option
= group
->options
; i
> 0; i
--, option
++)
415 if (!_cups_strcasecmp(option
->keyword
, "PageRegion"))
418 snprintf(buffer
, sizeof(buffer
), "%s/%s:", option
->keyword
, option
->text
);
420 for (j
= option
->num_choices
, choice
= option
->choices
,
421 ptr
= buffer
+ strlen(buffer
);
422 j
> 0 && ptr
< (buffer
+ sizeof(buffer
) - 1);
425 if (!_cups_strcasecmp(choice
->choice
, "Custom"))
427 ppd_coption_t
*coption
; /* Custom option */
428 ppd_cparam_t
*cparam
; /* Custom parameter */
429 static const char * const types
[] =
430 { /* Parameter types */
442 if ((coption
= ppdFindCustomOption(ppd
, option
->keyword
)) == NULL
||
443 cupsArrayCount(coption
->params
) == 0)
444 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %sCustom", choice
->marked
? "*" : "");
445 else if (!_cups_strcasecmp(option
->keyword
, "PageSize") ||
446 !_cups_strcasecmp(option
->keyword
, "PageRegion"))
447 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %sCustom.WIDTHxHEIGHT", choice
->marked
? "*" : "");
450 cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
);
452 if (cupsArrayCount(coption
->params
) == 1)
453 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %sCustom.%s", choice
->marked
? "*" : "", types
[cparam
->type
]);
456 const char *prefix
; /* Prefix string */
466 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), "%s%s=%s", prefix
, cparam
->name
, types
[cparam
->type
]);
467 cparam
= (ppd_cparam_t
*)cupsArrayNext(coption
->params
);
472 if (ptr
< (buffer
+ sizeof(buffer
) - 1))
473 strlcpy(ptr
, "}", sizeof(buffer
) - (size_t)(ptr
- buffer
));
477 else if (choice
->marked
)
478 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " *%s", choice
->choice
);
480 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %s", choice
->choice
);
485 _cupsLangPuts(stdout
, buffer
);
488 for (i
= group
->num_subgroups
, subgroup
= group
->subgroups
; i
> 0; i
--, subgroup
++)
489 list_group(ppd
, subgroup
);
494 * 'list_options()' - List printer-specific options from the PPD file.
498 list_options(cups_dest_t
*dest
) /* I - Destination to list */
500 int i
; /* Looping var */
501 const char *filename
; /* PPD filename */
502 ppd_file_t
*ppd
; /* PPD data */
503 ppd_group_t
*group
; /* Current group */
506 if ((filename
= cupsGetPPD(dest
->name
)) == NULL
)
508 _cupsLangPrintf(stderr
, _("lpoptions: Unable to get PPD file for %s: %s"),
509 dest
->name
, cupsLastErrorString());
513 if ((ppd
= ppdOpenFile(filename
)) == NULL
)
516 _cupsLangPrintf(stderr
, _("lpoptions: Unable to open PPD file for %s."),
521 ppdMarkDefaults(ppd
);
522 cupsMarkOptions(ppd
, dest
->num_options
, dest
->options
);
524 for (i
= ppd
->num_groups
, group
= ppd
->groups
; i
> 0; i
--, group
++)
525 list_group(ppd
, group
);
533 * 'usage()' - Show program usage and exit.
539 _cupsLangPuts(stdout
,
540 _("Usage: lpoptions [-h server] [-E] -d printer\n"
541 " lpoptions [-h server] [-E] [-p printer] -l\n"
542 " lpoptions [-h server] [-E] -p printer -o "
543 "option[=value] ...\n"
544 " lpoptions [-h server] [-E] -x printer"));