]>
git.ipfire.org Git - thirdparty/cups.git/blob - systemv/lpoptions.c
2 * Printer option program for CUPS.
4 * Copyright 2007-2016 by Apple Inc.
5 * Copyright 1997-2006 by Easy Software Products.
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
10 * which should have been included with this file. If this file is
11 * missing or damaged, see the license at "http://www.cups.org/".
15 * Include necessary headers...
18 #include <cups/cups-private.h>
19 #include <cups/ppd-private.h>
26 static void list_group(ppd_file_t
*ppd
, ppd_group_t
*group
);
27 static void list_options(cups_dest_t
*dest
);
28 static void usage(void) __attribute__((noreturn
));
32 * 'main()' - Main entry.
35 int /* O - Exit status */
36 main(int argc
, /* I - Number of command-line arguments */
37 char *argv
[]) /* I - Command-line arguments */
39 int i
, j
; /* Looping vars */
40 int changes
; /* Did we make changes? */
41 int num_options
; /* Number of options */
42 cups_option_t
*options
; /* Options */
43 int num_dests
; /* Number of destinations */
44 cups_dest_t
*dests
; /* Destinations */
45 cups_dest_t
*dest
; /* Current destination */
46 char *opt
, /* Option pointer */
47 *printer
, /* Printer name */
48 *instance
, /* Instance name */
49 *option
; /* Current option */
55 * Loop through the command-line arguments...
65 for (i
= 1; i
< argc
; i
++)
67 if (argv
[i
][0] == '-')
69 for (opt
= argv
[i
] + 1; *opt
; opt
++)
73 case 'd' : /* -d printer */
77 opt
+= strlen(opt
) - 1;
88 if ((instance
= strrchr(printer
, '/')) != NULL
)
92 num_dests
= cupsGetDests(&dests
);
94 if (num_dests
== 0 || !dests
|| (dest
= cupsGetDest(printer
, instance
, num_dests
, dests
)) == NULL
)
96 _cupsLangPuts(stderr
, _("lpoptions: Unknown printer or class."));
101 * Set the default destination...
104 for (j
= 0; j
< num_dests
; j
++)
105 dests
[j
].is_default
= 0;
107 dest
->is_default
= 1;
109 cupsSetDests(num_dests
, dests
);
111 for (j
= 0; j
< dest
->num_options
; j
++)
112 if (cupsGetOption(dest
->options
[j
].name
, num_options
,
114 num_options
= cupsAddOption(dest
->options
[j
].name
,
115 dest
->options
[j
].value
,
116 num_options
, &options
);
119 case 'h' : /* -h server */
122 cupsSetServer(opt
+ 1);
123 opt
+= strlen(opt
) - 1;
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
);
181 num_options
= cupsParseOptions(opt
+ 1, num_options
, &options
);
182 opt
+= strlen(opt
) - 1;
190 num_options
= cupsParseOptions(argv
[i
], num_options
, &options
);
196 case 'p' : /* -p printer */
200 opt
+= strlen(opt
) - 1;
211 if ((instance
= strrchr(printer
, '/')) != NULL
)
215 num_dests
= cupsGetDests(&dests
);
217 if ((dest
= cupsGetDest(printer
, instance
, num_dests
, dests
)) == NULL
)
219 num_dests
= cupsAddDest(printer
, instance
, num_dests
, &dests
);
220 dest
= cupsGetDest(printer
, instance
, num_dests
, dests
);
224 _cupsLangPrintf(stderr
, _("lpoptions: Unable to add printer or instance: %s"), strerror(errno
));
229 for (j
= 0; j
< dest
->num_options
; j
++)
230 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
231 num_options
= cupsAddOption(dest
->options
[j
].name
,
232 dest
->options
[j
].value
,
233 num_options
, &options
);
236 case 'r' : /* -r option (remove) */
240 num_dests
= cupsGetDests(&dests
);
242 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) == NULL
)
247 _cupsLangPuts(stderr
, _("lpoptions: No printers."));
251 for (j
= 0; j
< dest
->num_options
; j
++)
252 if (cupsGetOption(dest
->options
[j
].name
, num_options
,
254 num_options
= cupsAddOption(dest
->options
[j
].name
,
255 dest
->options
[j
].value
,
256 num_options
, &options
);
262 opt
+= strlen(opt
) - 1;
273 num_options
= cupsRemoveOption(option
, num_options
, &options
);
278 case 'x' : /* -x printer */
282 opt
+= strlen(opt
) - 1;
293 if ((instance
= strrchr(printer
, '/')) != NULL
)
297 num_dests
= cupsGetDests(&dests
);
299 num_dests
= cupsRemoveDest(printer
, instance
, num_dests
, &dests
);
301 cupsSetDests(num_dests
, dests
);
318 num_dests
= cupsGetDests(&dests
);
322 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) != NULL
)
324 for (j
= 0; j
< dest
->num_options
; j
++)
325 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
326 num_options
= cupsAddOption(dest
->options
[j
].name
,
327 dest
->options
[j
].value
,
328 num_options
, &options
);
338 * Set printer options...
341 cupsFreeOptions(dest
->num_options
, dest
->options
);
343 dest
->num_options
= num_options
;
344 dest
->options
= options
;
346 cupsSetDests(num_dests
, dests
);
348 else if (changes
== 0)
350 char buffer
[10240], /* String for options */
351 *ptr
; /* Pointer into string */
353 num_options
= dest
->num_options
;
354 options
= dest
->options
;
356 for (i
= 0, ptr
= buffer
;
357 ptr
< (buffer
+ sizeof(buffer
) - 1) && i
< num_options
;
363 if (!options
[i
].value
[0])
364 strlcpy(ptr
, options
[i
].name
, sizeof(buffer
) - (size_t)(ptr
- buffer
));
365 else if (strchr(options
[i
].value
, ' ') != NULL
||
366 strchr(options
[i
].value
, '\t') != NULL
)
367 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), "%s=\'%s\'", options
[i
].name
, options
[i
].value
);
369 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), "%s=%s", options
[i
].name
, options
[i
].value
);
374 _cupsLangPuts(stdout
, buffer
);
381 * 'list_group()' - List printer-specific options from the PPD group.
385 list_group(ppd_file_t
*ppd
, /* I - PPD file */
386 ppd_group_t
*group
) /* I - Group to show */
388 int i
, j
; /* Looping vars */
389 ppd_option_t
*option
; /* Current option */
390 ppd_choice_t
*choice
; /* Current choice */
391 ppd_group_t
*subgroup
; /* Current subgroup */
392 char buffer
[10240], /* Option string buffer */
393 *ptr
; /* Pointer into option string */
396 for (i
= group
->num_options
, option
= group
->options
; i
> 0; i
--, option
++)
398 if (!_cups_strcasecmp(option
->keyword
, "PageRegion"))
401 snprintf(buffer
, sizeof(buffer
), "%s/%s:", option
->keyword
, option
->text
);
403 for (j
= option
->num_choices
, choice
= option
->choices
,
404 ptr
= buffer
+ strlen(buffer
);
405 j
> 0 && ptr
< (buffer
+ sizeof(buffer
) - 1);
408 if (!_cups_strcasecmp(choice
->choice
, "Custom"))
410 ppd_coption_t
*coption
; /* Custom option */
411 ppd_cparam_t
*cparam
; /* Custom parameter */
412 static const char * const types
[] =
413 { /* Parameter types */
425 if ((coption
= ppdFindCustomOption(ppd
, option
->keyword
)) == NULL
||
426 cupsArrayCount(coption
->params
) == 0)
427 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %sCustom", choice
->marked
? "*" : "");
428 else if (!_cups_strcasecmp(option
->keyword
, "PageSize") ||
429 !_cups_strcasecmp(option
->keyword
, "PageRegion"))
430 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %sCustom.WIDTHxHEIGHT", choice
->marked
? "*" : "");
433 cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
);
435 if (cupsArrayCount(coption
->params
) == 1)
436 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %sCustom.%s", choice
->marked
? "*" : "", types
[cparam
->type
]);
439 const char *prefix
; /* Prefix string */
449 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), "%s%s=%s", prefix
, cparam
->name
, types
[cparam
->type
]);
450 cparam
= (ppd_cparam_t
*)cupsArrayNext(coption
->params
);
455 if (ptr
< (buffer
+ sizeof(buffer
) - 1))
456 strlcpy(ptr
, "}", sizeof(buffer
) - (size_t)(ptr
- buffer
));
460 else if (choice
->marked
)
461 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " *%s", choice
->choice
);
463 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %s", choice
->choice
);
468 _cupsLangPuts(stdout
, buffer
);
471 for (i
= group
->num_subgroups
, subgroup
= group
->subgroups
; i
> 0; i
--, subgroup
++)
472 list_group(ppd
, subgroup
);
477 * 'list_options()' - List printer-specific options from the PPD file.
481 list_options(cups_dest_t
*dest
) /* I - Destination to list */
483 int i
; /* Looping var */
484 const char *filename
; /* PPD filename */
485 ppd_file_t
*ppd
; /* PPD data */
486 ppd_group_t
*group
; /* Current group */
489 if ((filename
= cupsGetPPD(dest
->name
)) == NULL
)
491 _cupsLangPrintf(stderr
, _("lpoptions: Unable to get PPD file for %s: %s"),
492 dest
->name
, cupsLastErrorString());
496 if ((ppd
= ppdOpenFile(filename
)) == NULL
)
499 _cupsLangPrintf(stderr
, _("lpoptions: Unable to open PPD file for %s."),
504 ppdMarkDefaults(ppd
);
505 cupsMarkOptions(ppd
, dest
->num_options
, dest
->options
);
507 for (i
= ppd
->num_groups
, group
= ppd
->groups
; i
> 0; i
--, group
++)
508 list_group(ppd
, group
);
516 * 'usage()' - Show program usage and exit.
522 _cupsLangPuts(stdout
,
523 _("Usage: lpoptions [-h server] [-E] -d printer\n"
524 " lpoptions [-h server] [-E] [-p printer] -l\n"
525 " lpoptions [-h server] [-E] -p printer -o "
526 "option[=value] ...\n"
527 " lpoptions [-h server] [-E] -x printer"));