PageRenderTime 32ms CodeModel.GetById 26ms app.highlight 2ms RepoModel.GetById 2ms app.codeStats 0ms

/vp_plugins/sptsd/samples/lpoptions.c.smp

http://cupsfilter.googlecode.com/
Unknown | 552 lines | 448 code | 104 blank | 0 comment | 0 complexity | be265e4b44be4892d5054093436fc5dd MD5 | raw file
  1/*
  2 * "$Id: lpoptions.c 7720 2008-07-11 22:46:21Z mike $"
  3 *
  4 *   Printer option program for the Common UNIX Printing System (CUPS).
  5 *
  6 *   Copyright 2007-2008 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
 38static void	list_group(ppd_file_t *ppd, ppd_group_t *group);
 39static void	list_options(cups_dest_t *dest);
 40static void	usage(void);
 41
 42
 43/*
 44 * 'main()' - Main entry.
 45 */
 46
 47int					/* O - Exit status */
 48main(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 (num_dests == 0 || !dests ||
100	        (dest = cupsGetDest(printer, instance, num_dests,
101		                    dests)) == NULL)
102	    {
103	      _cupsLangPuts(stderr,
104	                    _("lpoptions: Unknown printer or class!\n"));
105	      return (1);
106	    }
107
108	   /*
109	    * Set the default destination...
110	    */
111
112	    for (j = 0; j < num_dests; j ++)
113	      dests[j].is_default = 0;
114
115	    dest->is_default = 1;
116
117	    cupsSetDests(num_dests, dests);
118
119	    for (j = 0; j < dest->num_options; j ++)
120	      if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
121		num_options = cupsAddOption(dest->options[j].name,
122	                                    dest->options[j].value,
123	                                    num_options, &options);
124	    break;
125
126	case 'h' : /* -h server */
127	    if (argv[i][2])
128	      cupsSetServer(argv[i] + 2);
129	    else
130	    {
131	      i ++;
132	      if (i >= argc)
133	        usage();
134
135	      cupsSetServer(argv[i]);
136	    }
137	    break;
138
139        case 'E' : /* Encrypt connection */
140	    cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
141	    break;
142
143	case 'l' : /* -l (list options) */
144            if (dest == NULL)
145	    {
146	      if (num_dests == 0)
147		num_dests = cupsGetDests(&dests);
148
149	      if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
150	        dest = dests;
151	    }
152
153            if (dest == NULL)
154	      _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n"));
155	    else
156	      list_options(dest);
157
158            changes = -1;
159	    break;
160
161	case 'o' : /* -o option[=value] */
162            if (dest == NULL)
163	    {
164	      if (num_dests == 0)
165		num_dests = cupsGetDests(&dests);
166
167	      if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
168	        dest = dests;
169
170	      if (dest == NULL)
171              {
172		_cupsLangPuts(stderr, _("lpoptions: No printers!?!\n"));
173                return (1);
174              }
175
176	      for (j = 0; j < dest->num_options; j ++)
177		if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
178		  num_options = cupsAddOption(dest->options[j].name,
179	                                      dest->options[j].value,
180	                                      num_options, &options);
181	    }
182
183	    if (argv[i][2])
184	      num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
185	    else
186	    {
187	      i ++;
188	      if (i >= argc)
189	        usage();
190
191	      num_options = cupsParseOptions(argv[i], num_options, &options);
192	    }
193
194	    changes = 1;
195	    break;
196
197	case 'p' : /* -p printer */
198	    if (argv[i][2])
199	      printer = argv[i] + 2;
200	    else
201	    {
202	      i ++;
203	      if (i >= argc)
204	        usage();
205
206	      printer = argv[i];
207	    }
208
209            if ((instance = strrchr(printer, '/')) != NULL)
210	      *instance++ = '\0';
211
212	    if (num_dests == 0)
213	      num_dests = cupsGetDests(&dests);
214
215            if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
216	    {
217	      num_dests = cupsAddDest(printer, instance, num_dests, &dests);
218	      dest      = cupsGetDest(printer, instance, num_dests, dests);
219
220              if (dest == NULL)
221	      {
222	        _cupsLangPrintf(stderr,
223		                _("lpoptions: Unable to add printer or "
224				  "instance: %s\n"),
225				strerror(errno));
226		return (1);
227	      }
228	    }
229
230	    for (j = 0; j < dest->num_options; j ++)
231	      if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
232		num_options = cupsAddOption(dest->options[j].name,
233	                                    dest->options[j].value,
234	                                    num_options, &options);
235	    break;
236
237	case 'r' : /* -r option (remove) */
238            if (dest == NULL)
239	    {
240	      if (num_dests == 0)
241		num_dests = cupsGetDests(&dests);
242
243	      if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
244	        dest = dests;
245
246	      if (dest == NULL)
247              {
248		_cupsLangPuts(stderr, _("lpoptions: No printers!?!\n"));
249                return (1);
250              }
251
252	      for (j = 0; j < dest->num_options; j ++)
253		if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
254		  num_options = cupsAddOption(dest->options[j].name,
255	                                      dest->options[j].value,
256	                                      num_options, &options);
257	    }
258
259	    if (argv[i][2])
260	      option = argv[i] + 2;
261	    else
262	    {
263	      i ++;
264	      if (i >= argc)
265	        usage();
266
267	      option = argv[i];
268	    }
269
270            for (j = 0; j < num_options; j ++)
271	      if (!strcasecmp(options[j].name, option))
272	      {
273	       /*
274	        * Remove this option...
275		*/
276
277	        num_options --;
278
279		if (j < num_options)
280		  memcpy(options + j, options + j + 1,
281		         sizeof(cups_option_t) * (num_options - j));
282		break;
283              }
284
285	    changes = 1;
286	    break;
287
288        case 'x' : /* -x printer */
289	    if (argv[i][2])
290	      printer = argv[i] + 2;
291	    else
292	    {
293	      i ++;
294	      if (i >= argc)
295	        usage();
296
297	      printer = argv[i];
298	    }
299
300            if ((instance = strrchr(printer, '/')) != NULL)
301	      *instance++ = '\0';
302
303	    if (num_dests == 0)
304	      num_dests = cupsGetDests(&dests);
305
306            if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL)
307	    {
308              cupsFreeOptions(dest->num_options, dest->options);
309
310             /*
311	      * If we are "deleting" the default printer, then just set the
312	      * number of options to 0; if it is also the system default
313	      * then cupsSetDests() will remove it for us...
314	      */
315
316	      if (dest->is_default)
317	      {
318		dest->num_options = 0;
319		dest->options     = NULL;
320	      }
321	      else
322	      {
323		num_dests --;
324
325		j = dest - dests;
326		if (j < num_dests)
327		  memcpy(dest, dest + 1, (num_dests - j) * sizeof(cups_dest_t));
328	      }
329	    }
330
331	    cupsSetDests(num_dests, dests);
332	    dest    = NULL;
333	    changes = -1;
334	    break;
335
336	default :
337	    usage();
338      }
339    }
340    else
341      usage();
342
343  if (num_dests == 0)
344    num_dests = cupsGetDests(&dests);
345
346  if (dest == NULL)
347  {
348    if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL)
349    {
350      for (j = 0; j < dest->num_options; j ++)
351	if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
352	  num_options = cupsAddOption(dest->options[j].name,
353	                              dest->options[j].value,
354	                              num_options, &options);
355    }
356  }
357
358  if (dest == NULL)
359    return (0);
360
361  if (changes > 0)
362  {
363   /*
364    * Set printer options...
365    */
366
367    cupsFreeOptions(dest->num_options, dest->options);
368
369    dest->num_options = num_options;
370    dest->options     = options;
371
372    cupsSetDests(num_dests, dests);
373  }
374  else if (changes == 0)
375  {
376    num_options = dest->num_options;
377    options     = dest->options;
378
379    for (i = 0; i < num_options; i ++)
380    {
381      if (i)
382        _cupsLangPuts(stdout, " ");
383
384      if (!options[i].value[0])
385        _cupsLangPrintf(stdout, "%s", options[i].name);
386      else if (strchr(options[i].value, ' ') != NULL ||
387               strchr(options[i].value, '\t') != NULL)
388	_cupsLangPrintf(stdout, "%s=\'%s\'", options[i].name,
389	                options[i].value);
390      else
391	_cupsLangPrintf(stdout, "%s=%s", options[i].name,
392	                options[i].value);
393    }
394
395    _cupsLangPuts(stdout, "\n");
396  }
397
398  return (0);
399}
400
401/*
402 * 'list_group()' - List printer-specific options from the PPD group.
403 */
404
405static void
406list_group(ppd_file_t  *ppd,		/* I - PPD file */
407           ppd_group_t *group)		/* I - Group to show */
408{
409  int		i, j;			/* Looping vars */
410  ppd_option_t	*option;		/* Current option */
411  ppd_choice_t	*choice;		/* Current choice */
412  ppd_group_t	*subgroup;		/* Current subgroup */
413
414
415  for (i = group->num_options, option = group->options; i > 0; i --, option ++)
416  {
417    if (!strcasecmp(option->keyword, "PageRegion"))
418      continue;
419
420    _cupsLangPrintf(stdout, "%s/%s:", option->keyword, option->text);
421
422    for (j = option->num_choices, choice = option->choices;
423         j > 0;
424	 j --, choice ++)
425      if (!strcasecmp(choice->choice, "Custom"))
426      {
427        ppd_coption_t	*coption;	/* Custom option */
428        ppd_cparam_t	*cparam;	/* Custom parameter */
429	static const char * const types[] =
430	{				/* Parameter types */
431	  "CURVE",
432	  "INTEGER",
433	  "INVCURVE",
434	  "PASSCODE",
435	  "PASSWORD",
436	  "POINTS",
437	  "REAL",
438	  "STRING"
439	};
440
441
442        if ((coption = ppdFindCustomOption(ppd, option->keyword)) == NULL ||
443	    cupsArrayCount(coption->params) == 0)
444	  _cupsLangPrintf(stdout, " %sCustom", choice->marked ? "*" : "");
445        else if (!strcasecmp(option->keyword, "PageSize") ||
446	        !strcasecmp(option->keyword, "PageRegion"))
447	  _cupsLangPrintf(stdout, " %sCustom.WIDTHxHEIGHT",
448	                  choice->marked ? "*" : "");
449        else
450	{
451	  cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
452
453	  if (cupsArrayCount(coption->params) == 1)
454	    _cupsLangPrintf(stdout, " %sCustom.%s", choice->marked ? "*" : "",
455	                    types[cparam->type]);
456	  else
457	  {
458	    const char	*prefix;	/* Prefix string */
459
460
461            if (choice->marked)
462	      prefix = " *{";
463	    else
464	      prefix = " {";
465
466	    while (cparam)
467	    {
468	      _cupsLangPrintf(stdout, "%s%s=%s", prefix, cparam->name,
469	                      types[cparam->type]);
470	      cparam = (ppd_cparam_t *)cupsArrayNext(coption->params);
471	      prefix = " ";
472	    }
473
474	    _cupsLangPuts(stdout, "}");
475	  }
476	}
477      }
478      else if (choice->marked)
479        _cupsLangPrintf(stdout, " *%s", choice->choice);
480      else
481        _cupsLangPrintf(stdout, " %s", choice->choice);
482
483    _cupsLangPuts(stdout, "\n");
484  }
485
486  for (i = group->num_subgroups, subgroup = group->subgroups; i > 0; i --, subgroup ++)
487    list_group(ppd, subgroup);
488}
489
490
491/*
492 * 'list_options()' - List printer-specific options from the PPD file.
493 */
494
495static void
496list_options(cups_dest_t *dest)		/* I - Destination to list */
497{
498  int		i;			/* Looping var */
499  const char	*filename;		/* PPD filename */
500  ppd_file_t	*ppd;			/* PPD data */
501  ppd_group_t	*group;			/* Current group */
502
503
504  if ((filename = cupsGetPPD(dest->name)) == NULL)
505  {
506    _cupsLangPrintf(stderr,
507                    _("lpoptions: Unable to get PPD file for %s: %s\n"),
508		    dest->name, cupsLastErrorString());
509    return;
510  }
511
512  if ((ppd = ppdOpenFile(filename)) == NULL)
513  {
514    unlink(filename);
515    _cupsLangPrintf(stderr,
516                    _("lpoptions: Unable to open PPD file for %s!\n"),
517		    dest->name);
518    return;
519  }
520
521  ppdMarkDefaults(ppd);
522  cupsMarkOptions(ppd, dest->num_options, dest->options);
523
524  for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
525    list_group(ppd, group);
526
527  ppdClose(ppd);
528  unlink(filename);
529}
530
531
532/*
533 * 'usage()' - Show program usage and exit.
534 */
535
536static void
537usage(void)
538{
539  _cupsLangPuts(stdout,
540                _("Usage: lpoptions [-h server] [-E] -d printer\n"
541		  "       lpoptions [-h server] [-E] [-p printer] -l\n"
542		  "       lpoptions [-h server] [-E] -p printer -o "
543		  "option[=value] ...\n"
544		  "       lpoptions [-h server] [-E] -x printer\n"));
545
546  exit(1);
547}
548
549
550/*
551 * End of "$Id: lpoptions.c 7720 2008-07-11 22:46:21Z mike $".
552 */