]> git.ipfire.org Git - thirdparty/cups.git/blob - systemv/lpoptions.c
Load cups into easysw/current.
[thirdparty/cups.git] / systemv / lpoptions.c
1 /*
2 * "$Id: lpoptions.c 6649 2007-07-11 21:46:42Z mike $"
3 *
4 * Printer option program for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
14 *
15 * Contents:
16 *
17 * main() - Main entry.
18 * list_group() - List printer-specific options from the PPD group.
19 * list_options() - List printer-specific options from the PPD file.
20 * usage() - Show program usage and exit.
21 */
22
23 /*
24 * Include necessary headers...
25 */
26
27 #include <cups/string.h>
28 #include <cups/cups.h>
29 #include <cups/i18n.h>
30 #include <stdlib.h>
31 #include <errno.h>
32
33
34 /*
35 * Local functions...
36 */
37
38 void list_group(ppd_group_t *group);
39 void list_options(cups_dest_t *dest);
40 void usage(void);
41
42
43 /*
44 * 'main()' - Main entry.
45 */
46
47 int /* O - Exit status */
48 main(int argc, /* I - Number of command-line arguments */
49 char *argv[]) /* I - Command-line arguments */
50 {
51 int i, j; /* Looping vars */
52 int changes; /* Did we make changes? */
53 int num_options; /* Number of options */
54 cups_option_t *options; /* Options */
55 int num_dests; /* Number of destinations */
56 cups_dest_t *dests; /* Destinations */
57 cups_dest_t *dest; /* Current destination */
58 char *printer, /* Printer name */
59 *instance, /* Instance name */
60 *option; /* Current option */
61
62
63 _cupsSetLocale(argv);
64
65 /*
66 * Loop through the command-line arguments...
67 */
68
69 dest = NULL;
70 num_dests = 0;
71 dests = NULL;
72 num_options = 0;
73 options = NULL;
74 changes = 0;
75
76 for (i = 1; i < argc; i ++)
77 if (argv[i][0] == '-')
78 {
79 switch (argv[i][1])
80 {
81 case 'd' : /* -d printer */
82 if (argv[i][2])
83 printer = argv[i] + 2;
84 else
85 {
86 i ++;
87 if (i >= argc)
88 usage();
89
90 printer = argv[i];
91 }
92
93 if ((instance = strrchr(printer, '/')) != NULL)
94 *instance++ = '\0';
95
96 if (num_dests == 0)
97 num_dests = cupsGetDests(&dests);
98
99 if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
100 {
101 _cupsLangPuts(stderr,
102 _("lpoptions: Unknown printer or class!\n"));
103 return (1);
104 }
105
106 /*
107 * Set the default destination...
108 */
109
110 for (j = 0; j < num_dests; j ++)
111 dests[j].is_default = 0;
112
113 dest->is_default = 1;
114
115 cupsSetDests(num_dests, dests);
116
117 for (j = 0; j < dest->num_options; j ++)
118 if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
119 num_options = cupsAddOption(dest->options[j].name,
120 dest->options[j].value,
121 num_options, &options);
122 break;
123
124 case 'h' : /* -h server */
125 if (argv[i][2])
126 cupsSetServer(argv[i] + 2);
127 else
128 {
129 i ++;
130 if (i >= argc)
131 usage();
132
133 cupsSetServer(argv[i]);
134 }
135 break;
136
137 case 'E' : /* Encrypt connection */
138 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
139 break;
140
141 case 'l' : /* -l (list options) */
142 if (dest == NULL)
143 {
144 if (num_dests == 0)
145 num_dests = cupsGetDests(&dests);
146
147 if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
148 dest = dests;
149 }
150
151 if (dest == NULL)
152 _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n"));
153 else
154 list_options(dest);
155
156 changes = -1;
157 break;
158
159 case 'o' : /* -o option[=value] */
160 if (dest == NULL)
161 {
162 if (num_dests == 0)
163 num_dests = cupsGetDests(&dests);
164
165 if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
166 dest = dests;
167
168 if (dest == NULL)
169 {
170 _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n"));
171 return (1);
172 }
173
174 for (j = 0; j < dest->num_options; j ++)
175 if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
176 num_options = cupsAddOption(dest->options[j].name,
177 dest->options[j].value,
178 num_options, &options);
179 }
180
181 if (argv[i][2])
182 num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
183 else
184 {
185 i ++;
186 if (i >= argc)
187 usage();
188
189 num_options = cupsParseOptions(argv[i], num_options, &options);
190 }
191
192 changes = 1;
193 break;
194
195 case 'p' : /* -p printer */
196 if (argv[i][2])
197 printer = argv[i] + 2;
198 else
199 {
200 i ++;
201 if (i >= argc)
202 usage();
203
204 printer = argv[i];
205 }
206
207 if ((instance = strrchr(printer, '/')) != NULL)
208 *instance++ = '\0';
209
210 if (num_dests == 0)
211 num_dests = cupsGetDests(&dests);
212
213 if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
214 {
215 num_dests = cupsAddDest(printer, instance, num_dests, &dests);
216 dest = cupsGetDest(printer, instance, num_dests, dests);
217
218 if (dest == NULL)
219 {
220 _cupsLangPrintf(stderr,
221 _("lpoptions: Unable to add printer or "
222 "instance: %s\n"),
223 strerror(errno));
224 return (1);
225 }
226 }
227
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);
233 break;
234
235 case 'r' : /* -r option (remove) */
236 if (dest == NULL)
237 {
238 if (num_dests == 0)
239 num_dests = cupsGetDests(&dests);
240
241 if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
242 dest = dests;
243
244 if (dest == NULL)
245 {
246 _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n"));
247 return (1);
248 }
249
250 for (j = 0; j < dest->num_options; j ++)
251 if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
252 num_options = cupsAddOption(dest->options[j].name,
253 dest->options[j].value,
254 num_options, &options);
255 }
256
257 if (argv[i][2])
258 option = argv[i] + 2;
259 else
260 {
261 i ++;
262 if (i >= argc)
263 usage();
264
265 option = argv[i];
266 }
267
268 for (j = 0; j < num_options; j ++)
269 if (!strcasecmp(options[j].name, option))
270 {
271 /*
272 * Remove this option...
273 */
274
275 num_options --;
276
277 if (j < num_options)
278 memcpy(options + j, options + j + 1,
279 sizeof(cups_option_t) * (num_options - j));
280 break;
281 }
282
283 changes = 1;
284 break;
285
286 case 'x' : /* -x printer */
287 if (argv[i][2])
288 printer = argv[i] + 2;
289 else
290 {
291 i ++;
292 if (i >= argc)
293 usage();
294
295 printer = argv[i];
296 }
297
298 if ((instance = strrchr(printer, '/')) != NULL)
299 *instance++ = '\0';
300
301 if (num_dests == 0)
302 num_dests = cupsGetDests(&dests);
303
304 if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL)
305 {
306 cupsFreeOptions(dest->num_options, dest->options);
307
308 /*
309 * If we are "deleting" the default printer, then just set the
310 * number of options to 0; if it is also the system default
311 * then cupsSetDests() will remove it for us...
312 */
313
314 if (dest->is_default)
315 {
316 dest->num_options = 0;
317 dest->options = NULL;
318 }
319 else
320 {
321 num_dests --;
322
323 j = dest - dests;
324 if (j < num_dests)
325 memcpy(dest, dest + 1, (num_dests - j) * sizeof(cups_dest_t));
326 }
327 }
328
329 cupsSetDests(num_dests, dests);
330 dest = NULL;
331 changes = -1;
332 break;
333
334 default :
335 usage();
336 }
337 }
338 else
339 usage();
340
341 if (num_dests == 0)
342 num_dests = cupsGetDests(&dests);
343
344 if (dest == NULL)
345 {
346 if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL)
347 {
348 for (j = 0; j < dest->num_options; j ++)
349 if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
350 num_options = cupsAddOption(dest->options[j].name,
351 dest->options[j].value,
352 num_options, &options);
353 }
354 }
355
356 if (dest == NULL)
357 return (0);
358
359 if (changes > 0)
360 {
361 /*
362 * Set printer options...
363 */
364
365 cupsFreeOptions(dest->num_options, dest->options);
366
367 dest->num_options = num_options;
368 dest->options = options;
369
370 cupsSetDests(num_dests, dests);
371 }
372 else if (changes == 0)
373 {
374 num_options = dest->num_options;
375 options = dest->options;
376
377 for (i = 0; i < num_options; i ++)
378 {
379 if (i)
380 _cupsLangPuts(stdout, " ");
381
382 if (!options[i].value[0])
383 _cupsLangPrintf(stdout, "%s", options[i].name);
384 else if (strchr(options[i].value, ' ') != NULL ||
385 strchr(options[i].value, '\t') != NULL)
386 _cupsLangPrintf(stdout, "%s=\'%s\'", options[i].name,
387 options[i].value);
388 else
389 _cupsLangPrintf(stdout, "%s=%s", options[i].name,
390 options[i].value);
391 }
392
393 _cupsLangPuts(stdout, "\n");
394 }
395
396 return (0);
397 }
398
399 /*
400 * 'list_group()' - List printer-specific options from the PPD group.
401 */
402
403 void
404 list_group(ppd_group_t *group) /* I - Group to show */
405 {
406 int i, j; /* Looping vars */
407 ppd_option_t *option; /* Current option */
408 ppd_choice_t *choice; /* Current choice */
409 ppd_group_t *subgroup; /* Current subgroup */
410
411
412 for (i = group->num_options, option = group->options; i > 0; i --, option ++)
413 {
414 _cupsLangPrintf(stdout, "%s/%s:", option->keyword, option->text);
415
416 for (j = option->num_choices, choice = option->choices; j > 0; j --, choice ++)
417 if (choice->marked)
418 _cupsLangPrintf(stdout, " *%s", choice->choice);
419 else
420 _cupsLangPrintf(stdout, " %s", choice->choice);
421
422 _cupsLangPuts(stdout, "\n");
423 }
424
425 for (i = group->num_subgroups, subgroup = group->subgroups; i > 0; i --, subgroup ++)
426 list_group(subgroup);
427 }
428
429
430 /*
431 * 'list_options()' - List printer-specific options from the PPD file.
432 */
433
434 void
435 list_options(cups_dest_t *dest) /* I - Destination to list */
436 {
437 int i; /* Looping var */
438 const char *filename; /* PPD filename */
439 ppd_file_t *ppd; /* PPD data */
440 ppd_group_t *group; /* Current group */
441
442
443 if ((filename = cupsGetPPD(dest->name)) == NULL)
444 {
445 _cupsLangPrintf(stderr,
446 _("lpoptions: Unable to get PPD file for %s: %s\n"),
447 dest->name, cupsLastErrorString());
448 return;
449 }
450
451 if ((ppd = ppdOpenFile(filename)) == NULL)
452 {
453 unlink(filename);
454 _cupsLangPrintf(stderr,
455 _("lpoptions: Unable to open PPD file for %s!\n"),
456 dest->name);
457 return;
458 }
459
460 ppdMarkDefaults(ppd);
461 cupsMarkOptions(ppd, dest->num_options, dest->options);
462
463 for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
464 list_group(group);
465
466 ppdClose(ppd);
467 unlink(filename);
468 }
469
470
471 /*
472 * 'usage()' - Show program usage and exit.
473 */
474
475 void
476 usage(void)
477 {
478 _cupsLangPuts(stdout,
479 _("Usage: lpoptions [-h server] [-E] -d printer\n"
480 " lpoptions [-h server] [-E] [-p printer] -l\n"
481 " lpoptions [-h server] [-E] -p printer -o "
482 "option[=value] ...\n"
483 " lpoptions [-h server] [-E] -x printer\n"));
484
485 exit(1);
486 }
487
488
489 /*
490 * End of "$Id: lpoptions.c 6649 2007-07-11 21:46:42Z mike $".
491 */