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