1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Printer option program for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2006 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups-private.h>
16*5e7646d2SAndroid Build Coastguard Worker #include <cups/ppd-private.h>
17*5e7646d2SAndroid Build Coastguard Worker
18*5e7646d2SAndroid Build Coastguard Worker
19*5e7646d2SAndroid Build Coastguard Worker /*
20*5e7646d2SAndroid Build Coastguard Worker * Local functions...
21*5e7646d2SAndroid Build Coastguard Worker */
22*5e7646d2SAndroid Build Coastguard Worker
23*5e7646d2SAndroid Build Coastguard Worker static void list_group(ppd_file_t *ppd, ppd_group_t *group);
24*5e7646d2SAndroid Build Coastguard Worker static void list_options(cups_dest_t *dest);
25*5e7646d2SAndroid Build Coastguard Worker static void usage(void) _CUPS_NORETURN;
26*5e7646d2SAndroid Build Coastguard Worker
27*5e7646d2SAndroid Build Coastguard Worker
28*5e7646d2SAndroid Build Coastguard Worker /*
29*5e7646d2SAndroid Build Coastguard Worker * 'main()' - Main entry.
30*5e7646d2SAndroid Build Coastguard Worker */
31*5e7646d2SAndroid Build Coastguard Worker
32*5e7646d2SAndroid Build Coastguard Worker int /* O - Exit status */
main(int argc,char * argv[])33*5e7646d2SAndroid Build Coastguard Worker main(int argc, /* I - Number of command-line arguments */
34*5e7646d2SAndroid Build Coastguard Worker char *argv[]) /* I - Command-line arguments */
35*5e7646d2SAndroid Build Coastguard Worker {
36*5e7646d2SAndroid Build Coastguard Worker int i, j; /* Looping vars */
37*5e7646d2SAndroid Build Coastguard Worker int changes; /* Did we make changes? */
38*5e7646d2SAndroid Build Coastguard Worker int num_options; /* Number of options */
39*5e7646d2SAndroid Build Coastguard Worker cups_option_t *options; /* Options */
40*5e7646d2SAndroid Build Coastguard Worker int num_dests; /* Number of destinations */
41*5e7646d2SAndroid Build Coastguard Worker cups_dest_t *dests; /* Destinations */
42*5e7646d2SAndroid Build Coastguard Worker cups_dest_t *dest; /* Current destination */
43*5e7646d2SAndroid Build Coastguard Worker char *opt, /* Option pointer */
44*5e7646d2SAndroid Build Coastguard Worker *printer, /* Printer name */
45*5e7646d2SAndroid Build Coastguard Worker *instance, /* Instance name */
46*5e7646d2SAndroid Build Coastguard Worker *option; /* Current option */
47*5e7646d2SAndroid Build Coastguard Worker
48*5e7646d2SAndroid Build Coastguard Worker
49*5e7646d2SAndroid Build Coastguard Worker _cupsSetLocale(argv);
50*5e7646d2SAndroid Build Coastguard Worker
51*5e7646d2SAndroid Build Coastguard Worker /*
52*5e7646d2SAndroid Build Coastguard Worker * Loop through the command-line arguments...
53*5e7646d2SAndroid Build Coastguard Worker */
54*5e7646d2SAndroid Build Coastguard Worker
55*5e7646d2SAndroid Build Coastguard Worker dest = NULL;
56*5e7646d2SAndroid Build Coastguard Worker num_dests = 0;
57*5e7646d2SAndroid Build Coastguard Worker dests = NULL;
58*5e7646d2SAndroid Build Coastguard Worker num_options = 0;
59*5e7646d2SAndroid Build Coastguard Worker options = NULL;
60*5e7646d2SAndroid Build Coastguard Worker changes = 0;
61*5e7646d2SAndroid Build Coastguard Worker
62*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i < argc; i ++)
63*5e7646d2SAndroid Build Coastguard Worker {
64*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(argv[i], "--help"))
65*5e7646d2SAndroid Build Coastguard Worker usage();
66*5e7646d2SAndroid Build Coastguard Worker else if (argv[i][0] == '-')
67*5e7646d2SAndroid Build Coastguard Worker {
68*5e7646d2SAndroid Build Coastguard Worker for (opt = argv[i] + 1; *opt; opt ++)
69*5e7646d2SAndroid Build Coastguard Worker {
70*5e7646d2SAndroid Build Coastguard Worker switch (*opt)
71*5e7646d2SAndroid Build Coastguard Worker {
72*5e7646d2SAndroid Build Coastguard Worker case 'd' : /* -d printer */
73*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
74*5e7646d2SAndroid Build Coastguard Worker {
75*5e7646d2SAndroid Build Coastguard Worker printer = opt + 1;
76*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
77*5e7646d2SAndroid Build Coastguard Worker }
78*5e7646d2SAndroid Build Coastguard Worker else
79*5e7646d2SAndroid Build Coastguard Worker {
80*5e7646d2SAndroid Build Coastguard Worker i ++;
81*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
82*5e7646d2SAndroid Build Coastguard Worker usage();
83*5e7646d2SAndroid Build Coastguard Worker
84*5e7646d2SAndroid Build Coastguard Worker printer = argv[i];
85*5e7646d2SAndroid Build Coastguard Worker }
86*5e7646d2SAndroid Build Coastguard Worker
87*5e7646d2SAndroid Build Coastguard Worker if ((instance = strrchr(printer, '/')) != NULL)
88*5e7646d2SAndroid Build Coastguard Worker *instance++ = '\0';
89*5e7646d2SAndroid Build Coastguard Worker
90*5e7646d2SAndroid Build Coastguard Worker if (num_dests == 0)
91*5e7646d2SAndroid Build Coastguard Worker num_dests = cupsGetDests(&dests);
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker if (num_dests == 0 || !dests || (dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
94*5e7646d2SAndroid Build Coastguard Worker {
95*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("lpoptions: Unknown printer or class."));
96*5e7646d2SAndroid Build Coastguard Worker return (1);
97*5e7646d2SAndroid Build Coastguard Worker }
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker /*
100*5e7646d2SAndroid Build Coastguard Worker * Set the default destination...
101*5e7646d2SAndroid Build Coastguard Worker */
102*5e7646d2SAndroid Build Coastguard Worker
103*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < num_dests; j ++)
104*5e7646d2SAndroid Build Coastguard Worker dests[j].is_default = 0;
105*5e7646d2SAndroid Build Coastguard Worker
106*5e7646d2SAndroid Build Coastguard Worker dest->is_default = 1;
107*5e7646d2SAndroid Build Coastguard Worker
108*5e7646d2SAndroid Build Coastguard Worker cupsSetDests(num_dests, dests);
109*5e7646d2SAndroid Build Coastguard Worker
110*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < dest->num_options; j ++)
111*5e7646d2SAndroid Build Coastguard Worker if (cupsGetOption(dest->options[j].name, num_options,
112*5e7646d2SAndroid Build Coastguard Worker options) == NULL)
113*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(dest->options[j].name,
114*5e7646d2SAndroid Build Coastguard Worker dest->options[j].value,
115*5e7646d2SAndroid Build Coastguard Worker num_options, &options);
116*5e7646d2SAndroid Build Coastguard Worker break;
117*5e7646d2SAndroid Build Coastguard Worker
118*5e7646d2SAndroid Build Coastguard Worker case 'h' : /* -h server */
119*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
120*5e7646d2SAndroid Build Coastguard Worker {
121*5e7646d2SAndroid Build Coastguard Worker cupsSetServer(opt + 1);
122*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
123*5e7646d2SAndroid Build Coastguard Worker }
124*5e7646d2SAndroid Build Coastguard Worker else
125*5e7646d2SAndroid Build Coastguard Worker {
126*5e7646d2SAndroid Build Coastguard Worker i ++;
127*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
128*5e7646d2SAndroid Build Coastguard Worker usage();
129*5e7646d2SAndroid Build Coastguard Worker
130*5e7646d2SAndroid Build Coastguard Worker cupsSetServer(argv[i]);
131*5e7646d2SAndroid Build Coastguard Worker }
132*5e7646d2SAndroid Build Coastguard Worker break;
133*5e7646d2SAndroid Build Coastguard Worker
134*5e7646d2SAndroid Build Coastguard Worker case 'E' : /* Encrypt connection */
135*5e7646d2SAndroid Build Coastguard Worker cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
136*5e7646d2SAndroid Build Coastguard Worker break;
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker case 'l' : /* -l (list options) */
139*5e7646d2SAndroid Build Coastguard Worker if (dest == NULL)
140*5e7646d2SAndroid Build Coastguard Worker {
141*5e7646d2SAndroid Build Coastguard Worker if (num_dests == 0)
142*5e7646d2SAndroid Build Coastguard Worker num_dests = cupsGetDests(&dests);
143*5e7646d2SAndroid Build Coastguard Worker
144*5e7646d2SAndroid Build Coastguard Worker if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
145*5e7646d2SAndroid Build Coastguard Worker dest = dests;
146*5e7646d2SAndroid Build Coastguard Worker }
147*5e7646d2SAndroid Build Coastguard Worker
148*5e7646d2SAndroid Build Coastguard Worker if (dest == NULL)
149*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("lpoptions: No printers."));
150*5e7646d2SAndroid Build Coastguard Worker else
151*5e7646d2SAndroid Build Coastguard Worker list_options(dest);
152*5e7646d2SAndroid Build Coastguard Worker
153*5e7646d2SAndroid Build Coastguard Worker changes = -1;
154*5e7646d2SAndroid Build Coastguard Worker break;
155*5e7646d2SAndroid Build Coastguard Worker
156*5e7646d2SAndroid Build Coastguard Worker case 'o' : /* -o option[=value] */
157*5e7646d2SAndroid Build Coastguard Worker if (dest == NULL)
158*5e7646d2SAndroid Build Coastguard Worker {
159*5e7646d2SAndroid Build Coastguard Worker if (num_dests == 0)
160*5e7646d2SAndroid Build Coastguard Worker num_dests = cupsGetDests(&dests);
161*5e7646d2SAndroid Build Coastguard Worker
162*5e7646d2SAndroid Build Coastguard Worker if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
163*5e7646d2SAndroid Build Coastguard Worker dest = dests;
164*5e7646d2SAndroid Build Coastguard Worker
165*5e7646d2SAndroid Build Coastguard Worker if (dest == NULL)
166*5e7646d2SAndroid Build Coastguard Worker {
167*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("lpoptions: No printers."));
168*5e7646d2SAndroid Build Coastguard Worker return (1);
169*5e7646d2SAndroid Build Coastguard Worker }
170*5e7646d2SAndroid Build Coastguard Worker
171*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < dest->num_options; j ++)
172*5e7646d2SAndroid Build Coastguard Worker if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
173*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(dest->options[j].name,
174*5e7646d2SAndroid Build Coastguard Worker dest->options[j].value,
175*5e7646d2SAndroid Build Coastguard Worker num_options, &options);
176*5e7646d2SAndroid Build Coastguard Worker }
177*5e7646d2SAndroid Build Coastguard Worker
178*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
179*5e7646d2SAndroid Build Coastguard Worker {
180*5e7646d2SAndroid Build Coastguard Worker num_options = cupsParseOptions(opt + 1, num_options, &options);
181*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
182*5e7646d2SAndroid Build Coastguard Worker }
183*5e7646d2SAndroid Build Coastguard Worker else
184*5e7646d2SAndroid Build Coastguard Worker {
185*5e7646d2SAndroid Build Coastguard Worker i ++;
186*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
187*5e7646d2SAndroid Build Coastguard Worker usage();
188*5e7646d2SAndroid Build Coastguard Worker
189*5e7646d2SAndroid Build Coastguard Worker num_options = cupsParseOptions(argv[i], num_options, &options);
190*5e7646d2SAndroid Build Coastguard Worker }
191*5e7646d2SAndroid Build Coastguard Worker
192*5e7646d2SAndroid Build Coastguard Worker changes = 1;
193*5e7646d2SAndroid Build Coastguard Worker break;
194*5e7646d2SAndroid Build Coastguard Worker
195*5e7646d2SAndroid Build Coastguard Worker case 'p' : /* -p printer */
196*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
197*5e7646d2SAndroid Build Coastguard Worker {
198*5e7646d2SAndroid Build Coastguard Worker printer = opt + 1;
199*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
200*5e7646d2SAndroid Build Coastguard Worker }
201*5e7646d2SAndroid Build Coastguard Worker else
202*5e7646d2SAndroid Build Coastguard Worker {
203*5e7646d2SAndroid Build Coastguard Worker i ++;
204*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
205*5e7646d2SAndroid Build Coastguard Worker usage();
206*5e7646d2SAndroid Build Coastguard Worker
207*5e7646d2SAndroid Build Coastguard Worker printer = argv[i];
208*5e7646d2SAndroid Build Coastguard Worker }
209*5e7646d2SAndroid Build Coastguard Worker
210*5e7646d2SAndroid Build Coastguard Worker if ((instance = strrchr(printer, '/')) != NULL)
211*5e7646d2SAndroid Build Coastguard Worker *instance++ = '\0';
212*5e7646d2SAndroid Build Coastguard Worker
213*5e7646d2SAndroid Build Coastguard Worker if (num_dests == 0)
214*5e7646d2SAndroid Build Coastguard Worker num_dests = cupsGetDests(&dests);
215*5e7646d2SAndroid Build Coastguard Worker
216*5e7646d2SAndroid Build Coastguard Worker if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
217*5e7646d2SAndroid Build Coastguard Worker {
218*5e7646d2SAndroid Build Coastguard Worker num_dests = cupsAddDest(printer, instance, num_dests, &dests);
219*5e7646d2SAndroid Build Coastguard Worker dest = cupsGetDest(printer, instance, num_dests, dests);
220*5e7646d2SAndroid Build Coastguard Worker
221*5e7646d2SAndroid Build Coastguard Worker if (dest == NULL)
222*5e7646d2SAndroid Build Coastguard Worker {
223*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("lpoptions: Unable to add printer or instance: %s"), strerror(errno));
224*5e7646d2SAndroid Build Coastguard Worker return (1);
225*5e7646d2SAndroid Build Coastguard Worker }
226*5e7646d2SAndroid Build Coastguard Worker }
227*5e7646d2SAndroid Build Coastguard Worker
228*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < dest->num_options; j ++)
229*5e7646d2SAndroid Build Coastguard Worker if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
230*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(dest->options[j].name,
231*5e7646d2SAndroid Build Coastguard Worker dest->options[j].value,
232*5e7646d2SAndroid Build Coastguard Worker num_options, &options);
233*5e7646d2SAndroid Build Coastguard Worker break;
234*5e7646d2SAndroid Build Coastguard Worker
235*5e7646d2SAndroid Build Coastguard Worker case 'r' : /* -r option (remove) */
236*5e7646d2SAndroid Build Coastguard Worker if (dest == NULL)
237*5e7646d2SAndroid Build Coastguard Worker {
238*5e7646d2SAndroid Build Coastguard Worker if (num_dests == 0)
239*5e7646d2SAndroid Build Coastguard Worker num_dests = cupsGetDests(&dests);
240*5e7646d2SAndroid Build Coastguard Worker
241*5e7646d2SAndroid Build Coastguard Worker if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
242*5e7646d2SAndroid Build Coastguard Worker dest = dests;
243*5e7646d2SAndroid Build Coastguard Worker
244*5e7646d2SAndroid Build Coastguard Worker if (dest == NULL)
245*5e7646d2SAndroid Build Coastguard Worker {
246*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stderr, _("lpoptions: No printers."));
247*5e7646d2SAndroid Build Coastguard Worker return (1);
248*5e7646d2SAndroid Build Coastguard Worker }
249*5e7646d2SAndroid Build Coastguard Worker
250*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < dest->num_options; j ++)
251*5e7646d2SAndroid Build Coastguard Worker if (cupsGetOption(dest->options[j].name, num_options,
252*5e7646d2SAndroid Build Coastguard Worker options) == NULL)
253*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(dest->options[j].name,
254*5e7646d2SAndroid Build Coastguard Worker dest->options[j].value,
255*5e7646d2SAndroid Build Coastguard Worker num_options, &options);
256*5e7646d2SAndroid Build Coastguard Worker }
257*5e7646d2SAndroid Build Coastguard Worker
258*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
259*5e7646d2SAndroid Build Coastguard Worker {
260*5e7646d2SAndroid Build Coastguard Worker option = opt + 1;
261*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
262*5e7646d2SAndroid Build Coastguard Worker }
263*5e7646d2SAndroid Build Coastguard Worker else
264*5e7646d2SAndroid Build Coastguard Worker {
265*5e7646d2SAndroid Build Coastguard Worker i ++;
266*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
267*5e7646d2SAndroid Build Coastguard Worker usage();
268*5e7646d2SAndroid Build Coastguard Worker
269*5e7646d2SAndroid Build Coastguard Worker option = argv[i];
270*5e7646d2SAndroid Build Coastguard Worker }
271*5e7646d2SAndroid Build Coastguard Worker
272*5e7646d2SAndroid Build Coastguard Worker num_options = cupsRemoveOption(option, num_options, &options);
273*5e7646d2SAndroid Build Coastguard Worker
274*5e7646d2SAndroid Build Coastguard Worker changes = 1;
275*5e7646d2SAndroid Build Coastguard Worker break;
276*5e7646d2SAndroid Build Coastguard Worker
277*5e7646d2SAndroid Build Coastguard Worker case 'x' : /* -x printer */
278*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
279*5e7646d2SAndroid Build Coastguard Worker {
280*5e7646d2SAndroid Build Coastguard Worker printer = opt + 1;
281*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
282*5e7646d2SAndroid Build Coastguard Worker }
283*5e7646d2SAndroid Build Coastguard Worker else
284*5e7646d2SAndroid Build Coastguard Worker {
285*5e7646d2SAndroid Build Coastguard Worker i ++;
286*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
287*5e7646d2SAndroid Build Coastguard Worker usage();
288*5e7646d2SAndroid Build Coastguard Worker
289*5e7646d2SAndroid Build Coastguard Worker printer = argv[i];
290*5e7646d2SAndroid Build Coastguard Worker }
291*5e7646d2SAndroid Build Coastguard Worker
292*5e7646d2SAndroid Build Coastguard Worker if ((instance = strrchr(printer, '/')) != NULL)
293*5e7646d2SAndroid Build Coastguard Worker *instance++ = '\0';
294*5e7646d2SAndroid Build Coastguard Worker
295*5e7646d2SAndroid Build Coastguard Worker if (num_dests == 0)
296*5e7646d2SAndroid Build Coastguard Worker num_dests = cupsGetDests(&dests);
297*5e7646d2SAndroid Build Coastguard Worker
298*5e7646d2SAndroid Build Coastguard Worker num_dests = cupsRemoveDest(printer, instance, num_dests, &dests);
299*5e7646d2SAndroid Build Coastguard Worker
300*5e7646d2SAndroid Build Coastguard Worker cupsSetDests(num_dests, dests);
301*5e7646d2SAndroid Build Coastguard Worker dest = NULL;
302*5e7646d2SAndroid Build Coastguard Worker changes = -1;
303*5e7646d2SAndroid Build Coastguard Worker break;
304*5e7646d2SAndroid Build Coastguard Worker
305*5e7646d2SAndroid Build Coastguard Worker default :
306*5e7646d2SAndroid Build Coastguard Worker usage();
307*5e7646d2SAndroid Build Coastguard Worker }
308*5e7646d2SAndroid Build Coastguard Worker }
309*5e7646d2SAndroid Build Coastguard Worker }
310*5e7646d2SAndroid Build Coastguard Worker else
311*5e7646d2SAndroid Build Coastguard Worker {
312*5e7646d2SAndroid Build Coastguard Worker usage();
313*5e7646d2SAndroid Build Coastguard Worker }
314*5e7646d2SAndroid Build Coastguard Worker }
315*5e7646d2SAndroid Build Coastguard Worker
316*5e7646d2SAndroid Build Coastguard Worker if (num_dests == 0)
317*5e7646d2SAndroid Build Coastguard Worker num_dests = cupsGetDests(&dests);
318*5e7646d2SAndroid Build Coastguard Worker
319*5e7646d2SAndroid Build Coastguard Worker if (dest == NULL)
320*5e7646d2SAndroid Build Coastguard Worker {
321*5e7646d2SAndroid Build Coastguard Worker if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL)
322*5e7646d2SAndroid Build Coastguard Worker {
323*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < dest->num_options; j ++)
324*5e7646d2SAndroid Build Coastguard Worker if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
325*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(dest->options[j].name,
326*5e7646d2SAndroid Build Coastguard Worker dest->options[j].value,
327*5e7646d2SAndroid Build Coastguard Worker num_options, &options);
328*5e7646d2SAndroid Build Coastguard Worker }
329*5e7646d2SAndroid Build Coastguard Worker }
330*5e7646d2SAndroid Build Coastguard Worker
331*5e7646d2SAndroid Build Coastguard Worker if (dest == NULL)
332*5e7646d2SAndroid Build Coastguard Worker return (0);
333*5e7646d2SAndroid Build Coastguard Worker
334*5e7646d2SAndroid Build Coastguard Worker if (changes > 0)
335*5e7646d2SAndroid Build Coastguard Worker {
336*5e7646d2SAndroid Build Coastguard Worker /*
337*5e7646d2SAndroid Build Coastguard Worker * Set printer options...
338*5e7646d2SAndroid Build Coastguard Worker */
339*5e7646d2SAndroid Build Coastguard Worker
340*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(dest->num_options, dest->options);
341*5e7646d2SAndroid Build Coastguard Worker
342*5e7646d2SAndroid Build Coastguard Worker dest->num_options = num_options;
343*5e7646d2SAndroid Build Coastguard Worker dest->options = options;
344*5e7646d2SAndroid Build Coastguard Worker
345*5e7646d2SAndroid Build Coastguard Worker cupsSetDests(num_dests, dests);
346*5e7646d2SAndroid Build Coastguard Worker }
347*5e7646d2SAndroid Build Coastguard Worker else if (changes == 0)
348*5e7646d2SAndroid Build Coastguard Worker {
349*5e7646d2SAndroid Build Coastguard Worker char buffer[10240], /* String for options */
350*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer into string */
351*5e7646d2SAndroid Build Coastguard Worker
352*5e7646d2SAndroid Build Coastguard Worker num_options = dest->num_options;
353*5e7646d2SAndroid Build Coastguard Worker options = dest->options;
354*5e7646d2SAndroid Build Coastguard Worker
355*5e7646d2SAndroid Build Coastguard Worker for (i = 0, ptr = buffer;
356*5e7646d2SAndroid Build Coastguard Worker ptr < (buffer + sizeof(buffer) - 1) && i < num_options;
357*5e7646d2SAndroid Build Coastguard Worker i ++)
358*5e7646d2SAndroid Build Coastguard Worker {
359*5e7646d2SAndroid Build Coastguard Worker if (i)
360*5e7646d2SAndroid Build Coastguard Worker *ptr++ = ' ';
361*5e7646d2SAndroid Build Coastguard Worker
362*5e7646d2SAndroid Build Coastguard Worker if (!options[i].value[0])
363*5e7646d2SAndroid Build Coastguard Worker strlcpy(ptr, options[i].name, sizeof(buffer) - (size_t)(ptr - buffer));
364*5e7646d2SAndroid Build Coastguard Worker else if (strchr(options[i].value, ' ') != NULL ||
365*5e7646d2SAndroid Build Coastguard Worker strchr(options[i].value, '\t') != NULL)
366*5e7646d2SAndroid Build Coastguard Worker snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), "%s=\'%s\'", options[i].name, options[i].value);
367*5e7646d2SAndroid Build Coastguard Worker else
368*5e7646d2SAndroid Build Coastguard Worker snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), "%s=%s", options[i].name, options[i].value);
369*5e7646d2SAndroid Build Coastguard Worker
370*5e7646d2SAndroid Build Coastguard Worker ptr += strlen(ptr);
371*5e7646d2SAndroid Build Coastguard Worker }
372*5e7646d2SAndroid Build Coastguard Worker
373*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, buffer);
374*5e7646d2SAndroid Build Coastguard Worker }
375*5e7646d2SAndroid Build Coastguard Worker
376*5e7646d2SAndroid Build Coastguard Worker return (0);
377*5e7646d2SAndroid Build Coastguard Worker }
378*5e7646d2SAndroid Build Coastguard Worker
379*5e7646d2SAndroid Build Coastguard Worker /*
380*5e7646d2SAndroid Build Coastguard Worker * 'list_group()' - List printer-specific options from the PPD group.
381*5e7646d2SAndroid Build Coastguard Worker */
382*5e7646d2SAndroid Build Coastguard Worker
383*5e7646d2SAndroid Build Coastguard Worker static void
list_group(ppd_file_t * ppd,ppd_group_t * group)384*5e7646d2SAndroid Build Coastguard Worker list_group(ppd_file_t *ppd, /* I - PPD file */
385*5e7646d2SAndroid Build Coastguard Worker ppd_group_t *group) /* I - Group to show */
386*5e7646d2SAndroid Build Coastguard Worker {
387*5e7646d2SAndroid Build Coastguard Worker int i, j; /* Looping vars */
388*5e7646d2SAndroid Build Coastguard Worker ppd_option_t *option; /* Current option */
389*5e7646d2SAndroid Build Coastguard Worker ppd_choice_t *choice; /* Current choice */
390*5e7646d2SAndroid Build Coastguard Worker ppd_group_t *subgroup; /* Current subgroup */
391*5e7646d2SAndroid Build Coastguard Worker char buffer[10240], /* Option string buffer */
392*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer into option string */
393*5e7646d2SAndroid Build Coastguard Worker
394*5e7646d2SAndroid Build Coastguard Worker
395*5e7646d2SAndroid Build Coastguard Worker for (i = group->num_options, option = group->options; i > 0; i --, option ++)
396*5e7646d2SAndroid Build Coastguard Worker {
397*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(option->keyword, "PageRegion"))
398*5e7646d2SAndroid Build Coastguard Worker continue;
399*5e7646d2SAndroid Build Coastguard Worker
400*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%s/%s:", option->keyword, option->text);
401*5e7646d2SAndroid Build Coastguard Worker
402*5e7646d2SAndroid Build Coastguard Worker for (j = option->num_choices, choice = option->choices,
403*5e7646d2SAndroid Build Coastguard Worker ptr = buffer + strlen(buffer);
404*5e7646d2SAndroid Build Coastguard Worker j > 0 && ptr < (buffer + sizeof(buffer) - 1);
405*5e7646d2SAndroid Build Coastguard Worker j --, choice ++)
406*5e7646d2SAndroid Build Coastguard Worker {
407*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(choice->choice, "Custom"))
408*5e7646d2SAndroid Build Coastguard Worker {
409*5e7646d2SAndroid Build Coastguard Worker ppd_coption_t *coption; /* Custom option */
410*5e7646d2SAndroid Build Coastguard Worker ppd_cparam_t *cparam; /* Custom parameter */
411*5e7646d2SAndroid Build Coastguard Worker static const char * const types[] =
412*5e7646d2SAndroid Build Coastguard Worker { /* Parameter types */
413*5e7646d2SAndroid Build Coastguard Worker "CURVE",
414*5e7646d2SAndroid Build Coastguard Worker "INTEGER",
415*5e7646d2SAndroid Build Coastguard Worker "INVCURVE",
416*5e7646d2SAndroid Build Coastguard Worker "PASSCODE",
417*5e7646d2SAndroid Build Coastguard Worker "PASSWORD",
418*5e7646d2SAndroid Build Coastguard Worker "POINTS",
419*5e7646d2SAndroid Build Coastguard Worker "REAL",
420*5e7646d2SAndroid Build Coastguard Worker "STRING"
421*5e7646d2SAndroid Build Coastguard Worker };
422*5e7646d2SAndroid Build Coastguard Worker
423*5e7646d2SAndroid Build Coastguard Worker
424*5e7646d2SAndroid Build Coastguard Worker if ((coption = ppdFindCustomOption(ppd, option->keyword)) == NULL ||
425*5e7646d2SAndroid Build Coastguard Worker cupsArrayCount(coption->params) == 0)
426*5e7646d2SAndroid Build Coastguard Worker snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " %sCustom", choice->marked ? "*" : "");
427*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strcasecmp(option->keyword, "PageSize") ||
428*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(option->keyword, "PageRegion"))
429*5e7646d2SAndroid Build Coastguard Worker snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " %sCustom.WIDTHxHEIGHT", choice->marked ? "*" : "");
430*5e7646d2SAndroid Build Coastguard Worker else
431*5e7646d2SAndroid Build Coastguard Worker {
432*5e7646d2SAndroid Build Coastguard Worker cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
433*5e7646d2SAndroid Build Coastguard Worker
434*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayCount(coption->params) == 1)
435*5e7646d2SAndroid Build Coastguard Worker snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " %sCustom.%s", choice->marked ? "*" : "", types[cparam->type]);
436*5e7646d2SAndroid Build Coastguard Worker else
437*5e7646d2SAndroid Build Coastguard Worker {
438*5e7646d2SAndroid Build Coastguard Worker const char *prefix; /* Prefix string */
439*5e7646d2SAndroid Build Coastguard Worker
440*5e7646d2SAndroid Build Coastguard Worker
441*5e7646d2SAndroid Build Coastguard Worker if (choice->marked)
442*5e7646d2SAndroid Build Coastguard Worker prefix = " *{";
443*5e7646d2SAndroid Build Coastguard Worker else
444*5e7646d2SAndroid Build Coastguard Worker prefix = " {";
445*5e7646d2SAndroid Build Coastguard Worker
446*5e7646d2SAndroid Build Coastguard Worker while (cparam)
447*5e7646d2SAndroid Build Coastguard Worker {
448*5e7646d2SAndroid Build Coastguard Worker snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), "%s%s=%s", prefix, cparam->name, types[cparam->type]);
449*5e7646d2SAndroid Build Coastguard Worker cparam = (ppd_cparam_t *)cupsArrayNext(coption->params);
450*5e7646d2SAndroid Build Coastguard Worker prefix = " ";
451*5e7646d2SAndroid Build Coastguard Worker ptr += strlen(ptr);
452*5e7646d2SAndroid Build Coastguard Worker }
453*5e7646d2SAndroid Build Coastguard Worker
454*5e7646d2SAndroid Build Coastguard Worker if (ptr < (buffer + sizeof(buffer) - 1))
455*5e7646d2SAndroid Build Coastguard Worker strlcpy(ptr, "}", sizeof(buffer) - (size_t)(ptr - buffer));
456*5e7646d2SAndroid Build Coastguard Worker }
457*5e7646d2SAndroid Build Coastguard Worker }
458*5e7646d2SAndroid Build Coastguard Worker }
459*5e7646d2SAndroid Build Coastguard Worker else if (choice->marked)
460*5e7646d2SAndroid Build Coastguard Worker snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " *%s", choice->choice);
461*5e7646d2SAndroid Build Coastguard Worker else
462*5e7646d2SAndroid Build Coastguard Worker snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " %s", choice->choice);
463*5e7646d2SAndroid Build Coastguard Worker
464*5e7646d2SAndroid Build Coastguard Worker ptr += strlen(ptr);
465*5e7646d2SAndroid Build Coastguard Worker }
466*5e7646d2SAndroid Build Coastguard Worker
467*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, buffer);
468*5e7646d2SAndroid Build Coastguard Worker }
469*5e7646d2SAndroid Build Coastguard Worker
470*5e7646d2SAndroid Build Coastguard Worker for (i = group->num_subgroups, subgroup = group->subgroups; i > 0; i --, subgroup ++)
471*5e7646d2SAndroid Build Coastguard Worker list_group(ppd, subgroup);
472*5e7646d2SAndroid Build Coastguard Worker }
473*5e7646d2SAndroid Build Coastguard Worker
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker /*
476*5e7646d2SAndroid Build Coastguard Worker * 'list_options()' - List printer-specific options from the PPD file.
477*5e7646d2SAndroid Build Coastguard Worker */
478*5e7646d2SAndroid Build Coastguard Worker
479*5e7646d2SAndroid Build Coastguard Worker static void
list_options(cups_dest_t * dest)480*5e7646d2SAndroid Build Coastguard Worker list_options(cups_dest_t *dest) /* I - Destination to list */
481*5e7646d2SAndroid Build Coastguard Worker {
482*5e7646d2SAndroid Build Coastguard Worker http_t *http; /* Connection to destination */
483*5e7646d2SAndroid Build Coastguard Worker char resource[1024]; /* Resource path */
484*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
485*5e7646d2SAndroid Build Coastguard Worker const char *filename; /* PPD filename */
486*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd; /* PPD data */
487*5e7646d2SAndroid Build Coastguard Worker ppd_group_t *group; /* Current group */
488*5e7646d2SAndroid Build Coastguard Worker
489*5e7646d2SAndroid Build Coastguard Worker
490*5e7646d2SAndroid Build Coastguard Worker if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, resource, sizeof(resource), NULL, NULL)) == NULL)
491*5e7646d2SAndroid Build Coastguard Worker {
492*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"),
493*5e7646d2SAndroid Build Coastguard Worker dest->name, cupsLastErrorString());
494*5e7646d2SAndroid Build Coastguard Worker return;
495*5e7646d2SAndroid Build Coastguard Worker }
496*5e7646d2SAndroid Build Coastguard Worker
497*5e7646d2SAndroid Build Coastguard Worker if ((filename = cupsGetPPD2(http, dest->name)) == NULL)
498*5e7646d2SAndroid Build Coastguard Worker {
499*5e7646d2SAndroid Build Coastguard Worker httpClose(http);
500*5e7646d2SAndroid Build Coastguard Worker
501*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"),
502*5e7646d2SAndroid Build Coastguard Worker dest->name, cupsLastErrorString());
503*5e7646d2SAndroid Build Coastguard Worker return;
504*5e7646d2SAndroid Build Coastguard Worker }
505*5e7646d2SAndroid Build Coastguard Worker
506*5e7646d2SAndroid Build Coastguard Worker httpClose(http);
507*5e7646d2SAndroid Build Coastguard Worker
508*5e7646d2SAndroid Build Coastguard Worker if ((ppd = ppdOpenFile(filename)) == NULL)
509*5e7646d2SAndroid Build Coastguard Worker {
510*5e7646d2SAndroid Build Coastguard Worker unlink(filename);
511*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("lpoptions: Unable to open PPD file for %s."),
512*5e7646d2SAndroid Build Coastguard Worker dest->name);
513*5e7646d2SAndroid Build Coastguard Worker return;
514*5e7646d2SAndroid Build Coastguard Worker }
515*5e7646d2SAndroid Build Coastguard Worker
516*5e7646d2SAndroid Build Coastguard Worker ppdMarkDefaults(ppd);
517*5e7646d2SAndroid Build Coastguard Worker cupsMarkOptions(ppd, dest->num_options, dest->options);
518*5e7646d2SAndroid Build Coastguard Worker
519*5e7646d2SAndroid Build Coastguard Worker for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
520*5e7646d2SAndroid Build Coastguard Worker list_group(ppd, group);
521*5e7646d2SAndroid Build Coastguard Worker
522*5e7646d2SAndroid Build Coastguard Worker ppdClose(ppd);
523*5e7646d2SAndroid Build Coastguard Worker unlink(filename);
524*5e7646d2SAndroid Build Coastguard Worker }
525*5e7646d2SAndroid Build Coastguard Worker
526*5e7646d2SAndroid Build Coastguard Worker
527*5e7646d2SAndroid Build Coastguard Worker /*
528*5e7646d2SAndroid Build Coastguard Worker * 'usage()' - Show program usage and exit.
529*5e7646d2SAndroid Build Coastguard Worker */
530*5e7646d2SAndroid Build Coastguard Worker
531*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)532*5e7646d2SAndroid Build Coastguard Worker usage(void)
533*5e7646d2SAndroid Build Coastguard Worker {
534*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("Usage: lpoptions [options] -d destination\n"
535*5e7646d2SAndroid Build Coastguard Worker " lpoptions [options] [-p destination] [-l]\n"
536*5e7646d2SAndroid Build Coastguard Worker " lpoptions [options] [-p destination] -o option[=value]\n"
537*5e7646d2SAndroid Build Coastguard Worker " lpoptions [options] -x destination"));
538*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("Options:"));
539*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-d destination Set default destination"));
540*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-E Encrypt the connection to the server"));
541*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-h server[:port] Connect to the named server and port"));
542*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-l Show supported options and values"));
543*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-o name[=value] Set default option and value"));
544*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-p destination Specify a destination"));
545*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-U username Specify the username to use for authentication"));
546*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-x destination Remove default options for destination"));
547*5e7646d2SAndroid Build Coastguard Worker
548*5e7646d2SAndroid Build Coastguard Worker exit(1);
549*5e7646d2SAndroid Build Coastguard Worker }
550