]>
git.ipfire.org Git - thirdparty/cups.git/blob - systemv/lpoptions.c
2 * Printer option program for CUPS.
4 * Copyright © 2007-2018 by Apple Inc.
5 * Copyright © 1997-2006 by Easy Software Products.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
12 * Include necessary headers...
15 #include <cups/cups-private.h>
16 #include <cups/ppd-private.h>
23 static void list_group(ppd_file_t
*ppd
, ppd_group_t
*group
);
24 static void list_options(cups_dest_t
*dest
);
25 static void usage(void) _CUPS_NORETURN
;
29 * 'main()' - Main entry.
32 int /* O - Exit status */
33 main(int argc
, /* I - Number of command-line arguments */
34 char *argv
[]) /* I - Command-line arguments */
36 int i
, j
; /* Looping vars */
37 int changes
; /* Did we make changes? */
38 int num_options
; /* Number of options */
39 cups_option_t
*options
; /* Options */
40 int num_dests
; /* Number of destinations */
41 cups_dest_t
*dests
; /* Destinations */
42 cups_dest_t
*dest
; /* Current destination */
43 char *opt
, /* Option pointer */
44 *printer
, /* Printer name */
45 *instance
, /* Instance name */
46 *option
; /* Current option */
52 * Loop through the command-line arguments...
62 for (i
= 1; i
< argc
; i
++)
64 if (!strcmp(argv
[i
], "--help"))
66 else if (argv
[i
][0] == '-')
68 for (opt
= argv
[i
] + 1; *opt
; opt
++)
72 case 'd' : /* -d printer */
76 opt
+= strlen(opt
) - 1;
87 if ((instance
= strrchr(printer
, '/')) != NULL
)
91 num_dests
= cupsGetDests(&dests
);
93 if (num_dests
== 0 || !dests
|| (dest
= cupsGetDest(printer
, instance
, num_dests
, dests
)) == NULL
)
95 _cupsLangPuts(stderr
, _("lpoptions: Unknown printer or class."));
100 * Set the default destination...
103 for (j
= 0; j
< num_dests
; j
++)
104 dests
[j
].is_default
= 0;
106 dest
->is_default
= 1;
108 cupsSetDests(num_dests
, dests
);
110 for (j
= 0; j
< dest
->num_options
; j
++)
111 if (cupsGetOption(dest
->options
[j
].name
, num_options
,
113 num_options
= cupsAddOption(dest
->options
[j
].name
,
114 dest
->options
[j
].value
,
115 num_options
, &options
);
118 case 'h' : /* -h server */
121 cupsSetServer(opt
+ 1);
122 opt
+= strlen(opt
) - 1;
130 cupsSetServer(argv
[i
]);
134 case 'E' : /* Encrypt connection */
135 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED
);
138 case 'l' : /* -l (list options) */
142 num_dests
= cupsGetDests(&dests
);
144 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) == NULL
)
149 _cupsLangPuts(stderr
, _("lpoptions: No printers."));
156 case 'o' : /* -o option[=value] */
160 num_dests
= cupsGetDests(&dests
);
162 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) == NULL
)
167 _cupsLangPuts(stderr
, _("lpoptions: No printers."));
171 for (j
= 0; j
< dest
->num_options
; j
++)
172 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
173 num_options
= cupsAddOption(dest
->options
[j
].name
,
174 dest
->options
[j
].value
,
175 num_options
, &options
);
180 num_options
= cupsParseOptions(opt
+ 1, num_options
, &options
);
181 opt
+= strlen(opt
) - 1;
189 num_options
= cupsParseOptions(argv
[i
], num_options
, &options
);
195 case 'p' : /* -p printer */
199 opt
+= strlen(opt
) - 1;
210 if ((instance
= strrchr(printer
, '/')) != NULL
)
214 num_dests
= cupsGetDests(&dests
);
216 if ((dest
= cupsGetDest(printer
, instance
, num_dests
, dests
)) == NULL
)
218 num_dests
= cupsAddDest(printer
, instance
, num_dests
, &dests
);
219 dest
= cupsGetDest(printer
, instance
, num_dests
, dests
);
223 _cupsLangPrintf(stderr
, _("lpoptions: Unable to add printer or instance: %s"), strerror(errno
));
228 for (j
= 0; j
< dest
->num_options
; j
++)
229 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
230 num_options
= cupsAddOption(dest
->options
[j
].name
,
231 dest
->options
[j
].value
,
232 num_options
, &options
);
235 case 'r' : /* -r option (remove) */
239 num_dests
= cupsGetDests(&dests
);
241 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) == NULL
)
246 _cupsLangPuts(stderr
, _("lpoptions: No printers."));
250 for (j
= 0; j
< dest
->num_options
; j
++)
251 if (cupsGetOption(dest
->options
[j
].name
, num_options
,
253 num_options
= cupsAddOption(dest
->options
[j
].name
,
254 dest
->options
[j
].value
,
255 num_options
, &options
);
261 opt
+= strlen(opt
) - 1;
272 num_options
= cupsRemoveOption(option
, num_options
, &options
);
277 case 'x' : /* -x printer */
281 opt
+= strlen(opt
) - 1;
292 if ((instance
= strrchr(printer
, '/')) != NULL
)
296 num_dests
= cupsGetDests(&dests
);
298 num_dests
= cupsRemoveDest(printer
, instance
, num_dests
, &dests
);
300 cupsSetDests(num_dests
, dests
);
317 num_dests
= cupsGetDests(&dests
);
321 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) != NULL
)
323 for (j
= 0; j
< dest
->num_options
; j
++)
324 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
325 num_options
= cupsAddOption(dest
->options
[j
].name
,
326 dest
->options
[j
].value
,
327 num_options
, &options
);
337 * Set printer options...
340 cupsFreeOptions(dest
->num_options
, dest
->options
);
342 dest
->num_options
= num_options
;
343 dest
->options
= options
;
345 cupsSetDests(num_dests
, dests
);
347 else if (changes
== 0)
349 char buffer
[10240], /* String for options */
350 *ptr
; /* Pointer into string */
352 num_options
= dest
->num_options
;
353 options
= dest
->options
;
355 for (i
= 0, ptr
= buffer
;
356 ptr
< (buffer
+ sizeof(buffer
) - 1) && i
< num_options
;
362 if (!options
[i
].value
[0])
363 strlcpy(ptr
, options
[i
].name
, sizeof(buffer
) - (size_t)(ptr
- buffer
));
364 else if (strchr(options
[i
].value
, ' ') != NULL
||
365 strchr(options
[i
].value
, '\t') != NULL
)
366 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), "%s=\'%s\'", options
[i
].name
, options
[i
].value
);
368 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), "%s=%s", options
[i
].name
, options
[i
].value
);
373 _cupsLangPuts(stdout
, buffer
);
380 * 'list_group()' - List printer-specific options from the PPD group.
384 list_group(ppd_file_t
*ppd
, /* I - PPD file */
385 ppd_group_t
*group
) /* I - Group to show */
387 int i
, j
; /* Looping vars */
388 ppd_option_t
*option
; /* Current option */
389 ppd_choice_t
*choice
; /* Current choice */
390 ppd_group_t
*subgroup
; /* Current subgroup */
391 char buffer
[10240], /* Option string buffer */
392 *ptr
; /* Pointer into option string */
395 for (i
= group
->num_options
, option
= group
->options
; i
> 0; i
--, option
++)
397 if (!_cups_strcasecmp(option
->keyword
, "PageRegion"))
400 snprintf(buffer
, sizeof(buffer
), "%s/%s:", option
->keyword
, option
->text
);
402 for (j
= option
->num_choices
, choice
= option
->choices
,
403 ptr
= buffer
+ strlen(buffer
);
404 j
> 0 && ptr
< (buffer
+ sizeof(buffer
) - 1);
407 if (!_cups_strcasecmp(choice
->choice
, "Custom"))
409 ppd_coption_t
*coption
; /* Custom option */
410 ppd_cparam_t
*cparam
; /* Custom parameter */
411 static const char * const types
[] =
412 { /* Parameter types */
424 if ((coption
= ppdFindCustomOption(ppd
, option
->keyword
)) == NULL
||
425 cupsArrayCount(coption
->params
) == 0)
426 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %sCustom", choice
->marked
? "*" : "");
427 else if (!_cups_strcasecmp(option
->keyword
, "PageSize") ||
428 !_cups_strcasecmp(option
->keyword
, "PageRegion"))
429 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %sCustom.WIDTHxHEIGHT", choice
->marked
? "*" : "");
432 cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
);
434 if (cupsArrayCount(coption
->params
) == 1)
435 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %sCustom.%s", choice
->marked
? "*" : "", types
[cparam
->type
]);
438 const char *prefix
; /* Prefix string */
448 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), "%s%s=%s", prefix
, cparam
->name
, types
[cparam
->type
]);
449 cparam
= (ppd_cparam_t
*)cupsArrayNext(coption
->params
);
454 if (ptr
< (buffer
+ sizeof(buffer
) - 1))
455 strlcpy(ptr
, "}", sizeof(buffer
) - (size_t)(ptr
- buffer
));
459 else if (choice
->marked
)
460 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " *%s", choice
->choice
);
462 snprintf(ptr
, sizeof(buffer
) - (size_t)(ptr
- buffer
), " %s", choice
->choice
);
467 _cupsLangPuts(stdout
, buffer
);
470 for (i
= group
->num_subgroups
, subgroup
= group
->subgroups
; i
> 0; i
--, subgroup
++)
471 list_group(ppd
, subgroup
);
476 * 'list_options()' - List printer-specific options from the PPD file.
480 list_options(cups_dest_t
*dest
) /* I - Destination to list */
482 http_t
*http
; /* Connection to destination */
483 char resource
[1024]; /* Resource path */
484 int i
; /* Looping var */
485 const char *filename
; /* PPD filename */
486 ppd_file_t
*ppd
; /* PPD data */
487 ppd_group_t
*group
; /* Current group */
490 if ((http
= cupsConnectDest(dest
, CUPS_DEST_FLAGS_NONE
, 30000, NULL
, resource
, sizeof(resource
), NULL
, NULL
)) == NULL
)
492 _cupsLangPrintf(stderr
, _("lpoptions: Unable to get PPD file for %s: %s"),
493 dest
->name
, cupsLastErrorString());
497 if ((filename
= cupsGetPPD2(http
, dest
->name
)) == NULL
)
501 _cupsLangPrintf(stderr
, _("lpoptions: Unable to get PPD file for %s: %s"),
502 dest
->name
, cupsLastErrorString());
508 if ((ppd
= ppdOpenFile(filename
)) == NULL
)
511 _cupsLangPrintf(stderr
, _("lpoptions: Unable to open PPD file for %s."),
516 ppdMarkDefaults(ppd
);
517 cupsMarkOptions(ppd
, dest
->num_options
, dest
->options
);
519 for (i
= ppd
->num_groups
, group
= ppd
->groups
; i
> 0; i
--, group
++)
520 list_group(ppd
, group
);
528 * 'usage()' - Show program usage and exit.
534 _cupsLangPuts(stdout
, _("Usage: lpoptions [options] -d destination\n"
535 " lpoptions [options] [-p destination] [-l]\n"
536 " lpoptions [options] [-p destination] -o option[=value]\n"
537 " lpoptions [options] -x destination"));
538 _cupsLangPuts(stdout
, _("Options:"));
539 _cupsLangPuts(stdout
, _("-d destination Set default destination"));
540 _cupsLangPuts(stdout
, _("-E Encrypt the connection to the server"));
541 _cupsLangPuts(stdout
, _("-h server[:port] Connect to the named server and port"));
542 _cupsLangPuts(stdout
, _("-l Show supported options and values"));
543 _cupsLangPuts(stdout
, _("-o name[=value] Set default option and value"));
544 _cupsLangPuts(stdout
, _("-p destination Specify a destination"));
545 _cupsLangPuts(stdout
, _("-U username Specify the username to use for authentication"));
546 _cupsLangPuts(stdout
, _("-x destination Remove default options for destination"));