]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - systemv/lpoptions.c
Full sweep of all Clang warnings, plus some bug fixes for incorrect memcpy usage.
[thirdparty/cups.git] / systemv / lpoptions.c
index 582213204dfd5487647ed74e05997f67749c8952..36d98998606c50be6f771a3f758b018484a142ad 100644 (file)
@@ -1,52 +1,32 @@
 /*
- * "$Id: lpoptions.c 6347 2007-03-18 03:21:36Z mike $"
+ * "$Id$"
  *
- *   Printer option program for the Common UNIX Printing System (CUPS).
+ * Printer option program for CUPS.
  *
- *   Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
  *
- *   These coded instructions, statements, and computer programs are the
- *   property of Easy Software Products and are protected by Federal
- *   copyright law.  Distribution and use rights are outlined in the file
- *   "LICENSE.txt" which should have been included with this file.  If this
- *   file is missing or damaged please contact Easy Software Products
- *   at:
- *
- *       Attn: CUPS Licensing Information
- *       Easy Software Products
- *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636 USA
- *
- *       Voice: (301) 373-9600
- *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
- *
- * Contents:
- *
- *   main()         - Main entry.
- *   list_group()   - List printer-specific options from the PPD group.
- *   list_options() - List printer-specific options from the PPD file.
- *   usage()        - Show program usage and exit.
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file.  If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
  */
 
 /*
  * Include necessary headers...
  */
 
-#include <cups/string.h>
-#include <cups/cups.h>
-#include <cups/i18n.h>
-#include <stdlib.h>
-#include <errno.h>
+#include <cups/cups-private.h>
 
 
 /*
  * Local functions...
  */
 
-void   list_group(ppd_group_t *group);
-void   list_options(cups_dest_t *dest);
-void   usage(void);
+static void    list_group(ppd_file_t *ppd, ppd_group_t *group);
+static void    list_options(cups_dest_t *dest);
+static void    usage(void) __attribute__((noreturn));
 
 
 /*
@@ -65,7 +45,7 @@ main(int  argc,                               /* I - Number of command-line arguments */
   cups_dest_t  *dests;                 /* Destinations */
   cups_dest_t  *dest;                  /* Current destination */
   char         *printer,               /* Printer name */
-               *instance,              /* Instance name */ 
+               *instance,              /* Instance name */
                *option;                /* Current option */
 
 
@@ -105,10 +85,11 @@ main(int  argc,                            /* I - Number of command-line arguments */
            if (num_dests == 0)
              num_dests = cupsGetDests(&dests);
 
-            if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
+            if (num_dests == 0 || !dests ||
+               (dest = cupsGetDest(printer, instance, num_dests,
+                                   dests)) == NULL)
            {
-             _cupsLangPuts(stderr,
-                           _("lpoptions: Unknown printer or class!\n"));
+             _cupsLangPuts(stderr, _("lpoptions: Unknown printer or class."));
              return (1);
            }
 
@@ -124,7 +105,8 @@ main(int  argc,                             /* I - Number of command-line arguments */
            cupsSetDests(num_dests, dests);
 
            for (j = 0; j < dest->num_options; j ++)
-             if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+             if (cupsGetOption(dest->options[j].name, num_options,
+                               options) == NULL)
                num_options = cupsAddOption(dest->options[j].name,
                                            dest->options[j].value,
                                            num_options, &options);
@@ -158,7 +140,7 @@ main(int  argc,                             /* I - Number of command-line arguments */
            }
 
             if (dest == NULL)
-             _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n"));
+             _cupsLangPuts(stderr, _("lpoptions: No printers."));
            else
              list_options(dest);
 
@@ -176,7 +158,7 @@ main(int  argc,                             /* I - Number of command-line arguments */
 
              if (dest == NULL)
               {
-               _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n"));
+               _cupsLangPuts(stderr, _("lpoptions: No printers."));
                 return (1);
               }
 
@@ -228,7 +210,7 @@ main(int  argc,                             /* I - Number of command-line arguments */
              {
                _cupsLangPrintf(stderr,
                                _("lpoptions: Unable to add printer or "
-                                 "instance: %s\n"),
+                                 "instance: %s"),
                                strerror(errno));
                return (1);
              }
@@ -252,12 +234,13 @@ main(int  argc,                           /* I - Number of command-line arguments */
 
              if (dest == NULL)
               {
-               _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n"));
+               _cupsLangPuts(stderr, _("lpoptions: No printers."));
                 return (1);
               }
 
              for (j = 0; j < dest->num_options; j ++)
-               if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+               if (cupsGetOption(dest->options[j].name, num_options,
+                                 options) == NULL)
                  num_options = cupsAddOption(dest->options[j].name,
                                              dest->options[j].value,
                                              num_options, &options);
@@ -275,7 +258,7 @@ main(int  argc,                             /* I - Number of command-line arguments */
            }
 
             for (j = 0; j < num_options; j ++)
-             if (!strcasecmp(options[j].name, option))
+             if (!_cups_strcasecmp(options[j].name, option))
              {
               /*
                * Remove this option...
@@ -284,8 +267,7 @@ main(int  argc,                             /* I - Number of command-line arguments */
                num_options --;
 
                if (j < num_options)
-                 memcpy(options + j, options + j + 1,
-                        sizeof(cups_option_t) * (num_options - j));
+                 memmove(options + j, options + j + 1, sizeof(cups_option_t) * (size_t)(num_options - j));
                break;
               }
 
@@ -310,7 +292,8 @@ main(int  argc,                             /* I - Number of command-line arguments */
            if (num_dests == 0)
              num_dests = cupsGetDests(&dests);
 
-            if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL)
+            if ((dest = cupsGetDest(printer, instance, num_dests,
+                                   dests)) != NULL)
            {
               cupsFreeOptions(dest->num_options, dest->options);
 
@@ -331,7 +314,7 @@ main(int  argc,                             /* I - Number of command-line arguments */
 
                j = dest - dests;
                if (j < num_dests)
-                 memcpy(dest, dest + 1, (num_dests - j) * sizeof(cups_dest_t));
+                 memmove(dest, dest + 1, (size_t)(num_dests - j) * sizeof(cups_dest_t));
              }
            }
 
@@ -380,26 +363,31 @@ main(int  argc,                           /* I - Number of command-line arguments */
   }
   else if (changes == 0)
   {
+    char       buffer[10240],          /* String for options */
+               *ptr;                   /* Pointer into string */
+
     num_options = dest->num_options;
     options     = dest->options;
 
-    for (i = 0; i < num_options; i ++)
+    for (i = 0, ptr = buffer;
+         ptr < (buffer + sizeof(buffer) - 1) && i < num_options;
+        i ++)
     {
       if (i)
-        _cupsLangPuts(stdout, " ");
+        *ptr++ = ' ';
 
       if (!options[i].value[0])
-        _cupsLangPrintf(stdout, "%s", options[i].name);
+        strlcpy(ptr, options[i].name, sizeof(buffer) - (size_t)(ptr - buffer));
       else if (strchr(options[i].value, ' ') != NULL ||
                strchr(options[i].value, '\t') != NULL)
-       _cupsLangPrintf(stdout, "%s=\'%s\'", options[i].name,
-                       options[i].value);
+       snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), "%s=\'%s\'", options[i].name, options[i].value);
       else
-       _cupsLangPrintf(stdout, "%s=%s", options[i].name,
-                       options[i].value);
+       snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), "%s=%s", options[i].name, options[i].value);
+
+      ptr += strlen(ptr);
     }
 
-    _cupsLangPuts(stdout, "\n");
+    _cupsLangPuts(stdout, buffer);
   }
 
   return (0);
@@ -409,30 +397,95 @@ main(int  argc,                           /* I - Number of command-line arguments */
  * 'list_group()' - List printer-specific options from the PPD group.
  */
 
-void
-list_group(ppd_group_t *group) /* I - Group to show */
+static void
+list_group(ppd_file_t  *ppd,           /* I - PPD file */
+           ppd_group_t *group)         /* I - Group to show */
 {
-  int          i, j;           /* Looping vars */
-  ppd_option_t *option;        /* Current option */
-  ppd_choice_t *choice;        /* Current choice */
-  ppd_group_t  *subgroup;      /* Current subgroup */
+  int          i, j;                   /* Looping vars */
+  ppd_option_t *option;                /* Current option */
+  ppd_choice_t *choice;                /* Current choice */
+  ppd_group_t  *subgroup;              /* Current subgroup */
+  char         buffer[10240],          /* Option string buffer */
+               *ptr;                   /* Pointer into option string */
 
 
   for (i = group->num_options, option = group->options; i > 0; i --, option ++)
   {
-    _cupsLangPrintf(stdout, "%s/%s:", option->keyword, option->text);
+    if (!_cups_strcasecmp(option->keyword, "PageRegion"))
+      continue;
+
+    snprintf(buffer, sizeof(buffer), "%s/%s:", option->keyword, option->text);
 
-    for (j = option->num_choices, choice = option->choices; j > 0; j --, choice ++)
-      if (choice->marked)
-        _cupsLangPrintf(stdout, " *%s", choice->choice);
+    for (j = option->num_choices, choice = option->choices,
+             ptr = buffer + strlen(buffer);
+         j > 0 && ptr < (buffer + sizeof(buffer) - 1);
+        j --, choice ++)
+    {
+      if (!_cups_strcasecmp(choice->choice, "Custom"))
+      {
+        ppd_coption_t  *coption;       /* Custom option */
+        ppd_cparam_t   *cparam;        /* Custom parameter */
+       static const char * const types[] =
+       {                               /* Parameter types */
+         "CURVE",
+         "INTEGER",
+         "INVCURVE",
+         "PASSCODE",
+         "PASSWORD",
+         "POINTS",
+         "REAL",
+         "STRING"
+       };
+
+
+        if ((coption = ppdFindCustomOption(ppd, option->keyword)) == NULL ||
+           cupsArrayCount(coption->params) == 0)
+         snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " %sCustom", choice->marked ? "*" : "");
+        else if (!_cups_strcasecmp(option->keyword, "PageSize") ||
+                !_cups_strcasecmp(option->keyword, "PageRegion"))
+         snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " %sCustom.WIDTHxHEIGHT", choice->marked ? "*" : "");
+        else
+       {
+         cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
+
+         if (cupsArrayCount(coption->params) == 1)
+           snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " %sCustom.%s", choice->marked ? "*" : "", types[cparam->type]);
+         else
+         {
+           const char  *prefix;        /* Prefix string */
+
+
+            if (choice->marked)
+             prefix = " *{";
+           else
+             prefix = " {";
+
+           while (cparam)
+           {
+             snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), "%s%s=%s", prefix, cparam->name, types[cparam->type]);
+             cparam = (ppd_cparam_t *)cupsArrayNext(coption->params);
+             prefix = " ";
+             ptr += strlen(ptr);
+           }
+
+            if (ptr < (buffer + sizeof(buffer) - 1))
+             strlcpy(ptr, "}", sizeof(buffer) - (size_t)(ptr - buffer));
+         }
+       }
+      }
+      else if (choice->marked)
+        snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " *%s", choice->choice);
       else
-        _cupsLangPrintf(stdout, " %s", choice->choice);
+        snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " %s", choice->choice);
+
+      ptr += strlen(ptr);
+    }
 
-    _cupsLangPuts(stdout, "\n");
+    _cupsLangPuts(stdout, buffer);
   }
 
   for (i = group->num_subgroups, subgroup = group->subgroups; i > 0; i --, subgroup ++)
-    list_group(subgroup);
+    list_group(ppd, subgroup);
 }
 
 
@@ -440,19 +493,18 @@ list_group(ppd_group_t *group)    /* I - Group to show */
  * 'list_options()' - List printer-specific options from the PPD file.
  */
 
-void
-list_options(cups_dest_t *dest)        /* I - Destination to list */
+static void
+list_options(cups_dest_t *dest)                /* I - Destination to list */
 {
-  int          i;              /* Looping var */
-  const char   *filename;      /* PPD filename */
-  ppd_file_t   *ppd;           /* PPD data */
-  ppd_group_t  *group;         /* Current group */
+  int          i;                      /* Looping var */
+  const char   *filename;              /* PPD filename */
+  ppd_file_t   *ppd;                   /* PPD data */
+  ppd_group_t  *group;                 /* Current group */
 
 
   if ((filename = cupsGetPPD(dest->name)) == NULL)
   {
-    _cupsLangPrintf(stderr,
-                    _("lpoptions: Unable to get PPD file for %s: %s\n"),
+    _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"),
                    dest->name, cupsLastErrorString());
     return;
   }
@@ -460,8 +512,7 @@ list_options(cups_dest_t *dest)     /* I - Destination to list */
   if ((ppd = ppdOpenFile(filename)) == NULL)
   {
     unlink(filename);
-    _cupsLangPrintf(stderr,
-                    _("lpoptions: Unable to open PPD file for %s!\n"),
+    _cupsLangPrintf(stderr, _("lpoptions: Unable to open PPD file for %s."),
                    dest->name);
     return;
   }
@@ -470,7 +521,7 @@ list_options(cups_dest_t *dest)     /* I - Destination to list */
   cupsMarkOptions(ppd, dest->num_options, dest->options);
 
   for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
-    list_group(group);
+    list_group(ppd, group);
 
   ppdClose(ppd);
   unlink(filename);
@@ -481,7 +532,7 @@ list_options(cups_dest_t *dest)     /* I - Destination to list */
  * 'usage()' - Show program usage and exit.
  */
 
-void
+static void
 usage(void)
 {
   _cupsLangPuts(stdout,
@@ -489,12 +540,12 @@ usage(void)
                  "       lpoptions [-h server] [-E] [-p printer] -l\n"
                  "       lpoptions [-h server] [-E] -p printer -o "
                  "option[=value] ...\n"
-                 "       lpoptions [-h server] [-E] -x printer\n"));
+                 "       lpoptions [-h server] [-E] -x printer"));
 
   exit(1);
 }
 
 
 /*
- * End of "$Id: lpoptions.c 6347 2007-03-18 03:21:36Z mike $".
+ * End of "$Id$".
  */