xref: /aosp_15_r20/external/libcups/systemv/lpoptions.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
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