]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - systemv/lpoptions.c
License change: Apache License, Version 2.0.
[thirdparty/cups.git] / systemv / lpoptions.c
index 06a1762c6f5a148f6821360232b80f6edb88924a..ca148cd63f24fc7d5384db53c5c7e65c53f5819a 100644 (file)
@@ -1,23 +1,10 @@
 /*
- * "$Id: lpoptions.c 7720 2008-07-11 22:46:21Z mike $"
+ * Printer option program for CUPS.
  *
- *   Printer option program for CUPS.
+ * Copyright 2007-2016 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
  *
- *   Copyright 2007-2011 by Apple Inc.
- *   Copyright 1997-2006 by Easy Software Products.
- *
- *   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/".
- *
- * 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.
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
  */
 
 /*
@@ -25,6 +12,7 @@
  */
 
 #include <cups/cups-private.h>
+#include <cups/ppd-private.h>
 
 
 /*
@@ -51,7 +39,8 @@ main(int  argc,                               /* I - Number of command-line arguments */
   int          num_dests;              /* Number of destinations */
   cups_dest_t  *dests;                 /* Destinations */
   cups_dest_t  *dest;                  /* Current destination */
-  char         *printer,               /* Printer name */
+  char         *opt,                   /* Option pointer */
+               *printer,               /* Printer name */
                *instance,              /* Instance name */
                *option;                /* Current option */
 
@@ -70,273 +59,256 @@ main(int  argc,                           /* I - Number of command-line arguments */
   changes     = 0;
 
   for (i = 1; i < argc; i ++)
+  {
     if (argv[i][0] == '-')
     {
-      switch (argv[i][1])
+      for (opt = argv[i] + 1; *opt; opt ++)
       {
-        case 'd' : /* -d printer */
-           if (argv[i][2])
-             printer = argv[i] + 2;
-           else
-           {
-             i ++;
-             if (i >= argc)
-               usage();
-
-             printer = argv[i];
-           }
-
-            if ((instance = strrchr(printer, '/')) != NULL)
-             *instance++ = '\0';
-
-           if (num_dests == 0)
-             num_dests = cupsGetDests(&dests);
-
-            if (num_dests == 0 || !dests ||
-               (dest = cupsGetDest(printer, instance, num_dests,
-                                   dests)) == NULL)
-           {
-             _cupsLangPuts(stderr, _("lpoptions: Unknown printer or class."));
-             return (1);
-           }
+       switch (*opt)
+       {
+         case 'd' : /* -d printer */
+             if (opt[1] != '\0')
+             {
+               printer = opt + 1;
+               opt += strlen(opt) - 1;
+             }
+             else
+             {
+               i ++;
+               if (i >= argc)
+                 usage();
 
-          /*
-           * Set the default destination...
-           */
+               printer = argv[i];
+             }
 
-           for (j = 0; j < num_dests; j ++)
-             dests[j].is_default = 0;
+             if ((instance = strrchr(printer, '/')) != NULL)
+               *instance++ = '\0';
 
-           dest->is_default = 1;
+             if (num_dests == 0)
+               num_dests = cupsGetDests(&dests);
 
-           cupsSetDests(num_dests, dests);
+             if (num_dests == 0 || !dests || (dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
+             {
+               _cupsLangPuts(stderr, _("lpoptions: Unknown printer or class."));
+               return (1);
+             }
 
-           for (j = 0; j < dest->num_options; j ++)
-             if (cupsGetOption(dest->options[j].name, num_options,
-                               options) == NULL)
-               num_options = cupsAddOption(dest->options[j].name,
-                                           dest->options[j].value,
-                                           num_options, &options);
-           break;
+            /*
+             * Set the default destination...
+             */
 
-       case 'h' : /* -h server */
-           if (argv[i][2])
-             cupsSetServer(argv[i] + 2);
-           else
-           {
-             i ++;
-             if (i >= argc)
-               usage();
+             for (j = 0; j < num_dests; j ++)
+               dests[j].is_default = 0;
 
-             cupsSetServer(argv[i]);
-           }
-           break;
+             dest->is_default = 1;
 
-        case 'E' : /* Encrypt connection */
-           cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
-           break;
+             cupsSetDests(num_dests, dests);
 
-       case 'l' : /* -l (list options) */
-            if (dest == NULL)
-           {
-             if (num_dests == 0)
-               num_dests = cupsGetDests(&dests);
+             for (j = 0; j < dest->num_options; j ++)
+               if (cupsGetOption(dest->options[j].name, num_options,
+                                 options) == NULL)
+                 num_options = cupsAddOption(dest->options[j].name,
+                                             dest->options[j].value,
+                                             num_options, &options);
+             break;
 
-             if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
-               dest = dests;
-           }
+         case 'h' : /* -h server */
+             if (opt[1] != '\0')
+             {
+               cupsSetServer(opt + 1);
+               opt += strlen(opt) - 1;
+             }
+             else
+             {
+               i ++;
+               if (i >= argc)
+                 usage();
 
-            if (dest == NULL)
-             _cupsLangPuts(stderr, _("lpoptions: No printers."));
-           else
-             list_options(dest);
+               cupsSetServer(argv[i]);
+             }
+             break;
 
-            changes = -1;
-           break;
+         case 'E' : /* Encrypt connection */
+             cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+             break;
 
-       case 'o' : /* -o option[=value] */
-            if (dest == NULL)
-           {
-             if (num_dests == 0)
-               num_dests = cupsGetDests(&dests);
+         case 'l' : /* -l (list options) */
+             if (dest == NULL)
+             {
+               if (num_dests == 0)
+                 num_dests = cupsGetDests(&dests);
 
-             if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
-               dest = dests;
+               if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
+                 dest = dests;
+             }
 
              if (dest == NULL)
-              {
                _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)
-                 num_options = cupsAddOption(dest->options[j].name,
-                                             dest->options[j].value,
-                                             num_options, &options);
-           }
-
-           if (argv[i][2])
-             num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
-           else
-           {
-             i ++;
-             if (i >= argc)
-               usage();
-
-             num_options = cupsParseOptions(argv[i], num_options, &options);
-           }
-
-           changes = 1;
-           break;
+             else
+               list_options(dest);
 
-       case 'p' : /* -p printer */
-           if (argv[i][2])
-             printer = argv[i] + 2;
-           else
-           {
-             i ++;
-             if (i >= argc)
-               usage();
+             changes = -1;
+             break;
 
-             printer = argv[i];
-           }
+         case 'o' : /* -o option[=value] */
+             if (dest == NULL)
+             {
+               if (num_dests == 0)
+                 num_dests = cupsGetDests(&dests);
+
+               if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
+                 dest = dests;
+
+               if (dest == NULL)
+               {
+                 _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)
+                   num_options = cupsAddOption(dest->options[j].name,
+                                               dest->options[j].value,
+                                               num_options, &options);
+             }
 
-            if ((instance = strrchr(printer, '/')) != NULL)
-             *instance++ = '\0';
+             if (opt[1] != '\0')
+             {
+               num_options = cupsParseOptions(opt + 1, num_options, &options);
+               opt += strlen(opt) - 1;
+             }
+             else
+             {
+               i ++;
+               if (i >= argc)
+                 usage();
 
-           if (num_dests == 0)
-             num_dests = cupsGetDests(&dests);
+               num_options = cupsParseOptions(argv[i], num_options, &options);
+             }
 
-            if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
-           {
-             num_dests = cupsAddDest(printer, instance, num_dests, &dests);
-             dest      = cupsGetDest(printer, instance, num_dests, dests);
+             changes = 1;
+             break;
 
-              if (dest == NULL)
+         case 'p' : /* -p printer */
+             if (opt[1] != '\0')
              {
-               _cupsLangPrintf(stderr,
-                               _("lpoptions: Unable to add printer or "
-                                 "instance: %s"),
-                               strerror(errno));
-               return (1);
+               printer = opt + 1;
+               opt += strlen(opt) - 1;
              }
-           }
+             else
+             {
+               i ++;
+               if (i >= argc)
+                 usage();
 
-           for (j = 0; j < dest->num_options; j ++)
-             if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
-               num_options = cupsAddOption(dest->options[j].name,
-                                           dest->options[j].value,
-                                           num_options, &options);
-           break;
+               printer = argv[i];
+             }
+
+             if ((instance = strrchr(printer, '/')) != NULL)
+               *instance++ = '\0';
 
-       case 'r' : /* -r option (remove) */
-            if (dest == NULL)
-           {
              if (num_dests == 0)
                num_dests = cupsGetDests(&dests);
 
-             if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
-               dest = dests;
-
-             if (dest == NULL)
-              {
-               _cupsLangPuts(stderr, _("lpoptions: No printers."));
-                return (1);
-              }
+             if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
+             {
+               num_dests = cupsAddDest(printer, instance, num_dests, &dests);
+               dest      = cupsGetDest(printer, instance, num_dests, dests);
+
+               if (dest == NULL)
+               {
+                 _cupsLangPrintf(stderr, _("lpoptions: Unable to add printer or instance: %s"), strerror(errno));
+                 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);
-           }
-
-           if (argv[i][2])
-             option = argv[i] + 2;
-           else
-           {
-             i ++;
-             if (i >= argc)
-               usage();
+                                             dest->options[j].value,
+                                             num_options, &options);
+             break;
 
-             option = argv[i];
-           }
-
-            for (j = 0; j < num_options; j ++)
-             if (!_cups_strcasecmp(options[j].name, option))
+         case 'r' : /* -r option (remove) */
+             if (dest == NULL)
              {
-              /*
-               * Remove this option...
-               */
-
-               num_options --;
-
-               if (j < num_options)
-                 memcpy(options + j, options + j + 1,
-                        sizeof(cups_option_t) * (num_options - j));
-               break;
-              }
-
-           changes = 1;
-           break;
-
-        case 'x' : /* -x printer */
-           if (argv[i][2])
-             printer = argv[i] + 2;
-           else
-           {
-             i ++;
-             if (i >= argc)
-               usage();
-
-             printer = argv[i];
-           }
+               if (num_dests == 0)
+                 num_dests = cupsGetDests(&dests);
+
+               if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
+                 dest = dests;
+
+               if (dest == NULL)
+               {
+                 _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)
+                   num_options = cupsAddOption(dest->options[j].name,
+                                               dest->options[j].value,
+                                               num_options, &options);
+             }
 
-            if ((instance = strrchr(printer, '/')) != NULL)
-             *instance++ = '\0';
+             if (opt[1] != '\0')
+             {
+               option = opt + 1;
+               opt += strlen(opt) - 1;
+             }
+             else
+             {
+               i ++;
+               if (i >= argc)
+                 usage();
 
-           if (num_dests == 0)
-             num_dests = cupsGetDests(&dests);
+               option = argv[i];
+             }
 
-            if ((dest = cupsGetDest(printer, instance, num_dests,
-                                   dests)) != NULL)
-           {
-              cupsFreeOptions(dest->num_options, dest->options);
+              num_options = cupsRemoveOption(option, num_options, &options);
 
-             /*
-             * If we are "deleting" the default printer, then just set the
-             * number of options to 0; if it is also the system default
-             * then cupsSetDests() will remove it for us...
-             */
+             changes = 1;
+             break;
 
-             if (dest->is_default)
+         case 'x' : /* -x printer */
+             if (opt[1] != '\0')
              {
-               dest->num_options = 0;
-               dest->options     = NULL;
+               printer = opt + 1;
+               opt += strlen(opt) - 1;
              }
              else
              {
-               num_dests --;
+               i ++;
+               if (i >= argc)
+                 usage();
 
-               j = dest - dests;
-               if (j < num_dests)
-                 memcpy(dest, dest + 1, (num_dests - j) * sizeof(cups_dest_t));
+               printer = argv[i];
              }
-           }
 
-           cupsSetDests(num_dests, dests);
-           dest    = NULL;
-           changes = -1;
-           break;
+             if ((instance = strrchr(printer, '/')) != NULL)
+               *instance++ = '\0';
+
+             if (num_dests == 0)
+               num_dests = cupsGetDests(&dests);
+
+              num_dests = cupsRemoveDest(printer, instance, num_dests, &dests);
 
-       default :
-           usage();
+             cupsSetDests(num_dests, dests);
+             dest    = NULL;
+             changes = -1;
+             break;
+
+         default :
+             usage();
+       }
       }
     }
     else
+    {
       usage();
+    }
+  }
 
   if (num_dests == 0)
     num_dests = cupsGetDests(&dests);
@@ -385,14 +357,12 @@ main(int  argc,                           /* I - Number of command-line arguments */
         *ptr++ = ' ';
 
       if (!options[i].value[0])
-        strlcpy(ptr, options[i].name, sizeof(buffer) - (ptr - buffer));
+        strlcpy(ptr, options[i].name, sizeof(buffer) - (size_t)(ptr - buffer));
       else if (strchr(options[i].value, ' ') != NULL ||
                strchr(options[i].value, '\t') != NULL)
-       snprintf(ptr, sizeof(buffer) - (ptr - buffer), "%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
-       snprintf(ptr, sizeof(buffer) - (ptr - buffer), "%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);
     }
@@ -450,19 +420,16 @@ list_group(ppd_file_t  *ppd,              /* I - PPD file */
 
         if ((coption = ppdFindCustomOption(ppd, option->keyword)) == NULL ||
            cupsArrayCount(coption->params) == 0)
-         snprintf(ptr, sizeof(buffer) - (ptr - buffer), " %sCustom",
-                  choice->marked ? "*" : "");
+         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) - (ptr - buffer),
-                  " %sCustom.WIDTHxHEIGHT", choice->marked ? "*" : "");
+         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) - (ptr - buffer), " %sCustom.%s",
-                    choice->marked ? "*" : "", types[cparam->type]);
+           snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " %sCustom.%s", choice->marked ? "*" : "", types[cparam->type]);
          else
          {
            const char  *prefix;        /* Prefix string */
@@ -475,22 +442,21 @@ list_group(ppd_file_t  *ppd,              /* I - PPD file */
 
            while (cparam)
            {
-             snprintf(ptr, sizeof(buffer) - (ptr - buffer), "%s%s=%s", prefix,
-                      cparam->name, types[cparam->type]);
+             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) - (ptr - buffer));
+             strlcpy(ptr, "}", sizeof(buffer) - (size_t)(ptr - buffer));
          }
        }
       }
       else if (choice->marked)
-        snprintf(ptr, sizeof(buffer) - (ptr - buffer), " *%s", choice->choice);
+        snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " *%s", choice->choice);
       else
-        snprintf(ptr, sizeof(buffer) - (ptr - buffer), " %s", choice->choice);
+        snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), " %s", choice->choice);
 
       ptr += strlen(ptr);
     }
@@ -558,8 +524,3 @@ usage(void)
 
   exit(1);
 }
-
-
-/*
- * End of "$Id: lpoptions.c 7720 2008-07-11 22:46:21Z mike $".
- */