]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/testdest.c
Greatly simplify the man page handling.
[thirdparty/cups.git] / cups / testdest.c
index c940d3b1a6eef5d034866decbc16273396433f9f..a65e09960d84cd1219e8c1f010331595f023a2d0 100644 (file)
@@ -1,15 +1,9 @@
 /*
  * CUPS destination API test program for CUPS.
  *
- * Copyright 2016 by Apple Inc.
+ * Copyright © 2012-2018 by Apple Inc.
  *
- * 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/".
- *
- * This file is subject to the Apple OS-Developed Software exception.
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
  */
 
 /*
@@ -17,6 +11,7 @@
  */
 
 #include <stdio.h>
+#include <errno.h>
 #include "cups.h"
 
 
@@ -31,7 +26,7 @@ static void   show_conflicts(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo,
 static void    show_default(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option);
 static void    show_media(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags, const char *name);
 static void    show_supported(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
-static void    usage(const char *arg) __attribute__((noreturn));
+static void    usage(const char *arg) _CUPS_NORETURN;
 
 
 /*
@@ -42,17 +37,31 @@ int                                 /* O - Exit status */
 main(int  argc,                                /* I - Number of command-line arguments */
      char *argv[])                     /* I - Command-line arguments */
 {
+  int          i;                      /* Looping var */
   http_t       *http;                  /* Connection to destination */
   cups_dest_t  *dest = NULL;           /* Destination */
   cups_dinfo_t *dinfo;                 /* Destination info */
+  unsigned     dflags = CUPS_DEST_FLAGS_NONE;
+                                       /* Destination flags */
 
 
   if (argc < 2)
-    usage(NULL);
+    return (0);
+
+  if (!strcmp(argv[1], "--get"))
+  {
+    cups_dest_t        *dests;                 /* Destinations */
+    int                num_dests = cupsGetDests2(CUPS_HTTP_DEFAULT, &dests);
+                                       /* Number of destinations */
 
-  if (!strcmp(argv[1], "--enum"))
+    for (i = 0; i < num_dests; i ++)
+      enum_cb(NULL, 0, dests + i);
+
+    cupsFreeDests(num_dests, dests);
+    return (0);
+  }
+  else if (!strcmp(argv[1], "--enum"))
   {
-    int                        i;              /* Looping var */
     cups_ptype_t       type = 0,       /* Printer type filter */
                        mask = 0;       /* Printer type mask */
 
@@ -102,65 +111,91 @@ main(int  argc,                           /* I - Number of command-line arguments */
 
     return (0);
   }
-  else if (!strncmp(argv[1], "ipp://", 6) || !strncmp(argv[1], "ipps://", 7))
-    dest = cupsGetDestWithURI(NULL, argv[1]);
+
+  i = 1;
+  if (!strcmp(argv[i], "--device"))
+  {
+    dflags = CUPS_DEST_FLAGS_DEVICE;
+    i ++;
+  }
+
+  if (!strncmp(argv[i], "ipp://", 6) || !strncmp(argv[i], "ipps://", 7))
+    dest = cupsGetDestWithURI(NULL, argv[i]);
+  else if (!strcmp(argv[i], "default"))
+  {
+    dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL);
+    if (dest && dest->instance)
+      printf("default is \"%s/%s\".\n", dest->name, dest->instance);
+    else if (dest)
+      printf("default is \"%s\".\n", dest->name);
+    else
+      puts("no default destination.");
+  }
   else
-    dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[1], NULL);
+    dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[i], NULL);
 
   if (!dest)
   {
-    printf("testdest: Unable to get destination \"%s\": %s\n", argv[1], cupsLastErrorString());
+    printf("testdest: Unable to get destination \"%s\": %s\n", argv[i], cupsLastErrorString());
     return (1);
   }
 
-  if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)
+  i ++;
+
+  if ((http = cupsConnectDest(dest, dflags, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)
   {
-    printf("testdest: Unable to connect to destination \"%s\": %s\n", argv[1], cupsLastErrorString());
+    printf("testdest: Unable to connect to destination \"%s\": %s\n", dest->name, cupsLastErrorString());
     return (1);
   }
 
   if ((dinfo = cupsCopyDestInfo(http, dest)) == NULL)
   {
-    printf("testdest: Unable to get information for destination \"%s\": %s\n", argv[1], cupsLastErrorString());
+    printf("testdest: Unable to get information for destination \"%s\": %s\n", dest->name, cupsLastErrorString());
     return (1);
   }
 
-  if (argc == 2 || (!strcmp(argv[2], "supported") && argc < 6))
+  if (i == argc || !strcmp(argv[i], "supported"))
   {
-    if (argc > 3)
-      show_supported(http, dest, dinfo, argv[3], argv[4]);
+    i ++;
+
+    if ((i + 1) < argc)
+      show_supported(http, dest, dinfo, argv[i], argv[i + 1]);
     else if (argc > 2)
-      show_supported(http, dest, dinfo, argv[3], NULL);
+      show_supported(http, dest, dinfo, argv[i], NULL);
     else
       show_supported(http, dest, dinfo, NULL, NULL);
   }
-  else if (!strcmp(argv[2], "conflicts") && argc > 3)
+  else if (!strcmp(argv[i], "conflicts") && (i + 1) < argc)
   {
-    int                        i,              /* Looping var */
-                       num_options = 0;/* Number of options */
+    int                        num_options = 0;/* Number of options */
     cups_option_t      *options = NULL;/* Options */
 
-    for (i = 3; i < argc; i ++)
+    for (i ++; i < argc; i ++)
       num_options = cupsParseOptions(argv[i], num_options, &options);
 
     show_conflicts(http, dest, dinfo, num_options, options);
   }
-  else if (!strcmp(argv[2], "default") && argc == 4)
+  else if (!strcmp(argv[i], "default") && (i + 1) < argc)
   {
-    show_default(http, dest, dinfo, argv[3]);
+    show_default(http, dest, dinfo, argv[i + 1]);
   }
-  else if (!strcmp(argv[2], "localize") && argc > 3 && argc < 6)
+  else if (!strcmp(argv[i], "localize"))
   {
-    localize(http, dest, dinfo, argv[3], argv[4]);
+    i ++;
+    if ((i + 1) < argc)
+      localize(http, dest, dinfo, argv[i], argv[i + 1]);
+    else if (argc > 2)
+      localize(http, dest, dinfo, argv[i], NULL);
+    else
+      localize(http, dest, dinfo, NULL, NULL);
   }
-  else if (!strcmp(argv[2], "media"))
+  else if (!strcmp(argv[i], "media"))
   {
-    int                i;                      /* Looping var */
     const char *name = NULL;           /* Media name, if any */
     unsigned   flags = CUPS_MEDIA_FLAGS_DEFAULT;
                                        /* Media selection flags */
 
-    for (i = 3; i < argc; i ++)
+    for (i ++; i < argc; i ++)
     {
       if (!strcmp(argv[i], "borderless"))
        flags = CUPS_MEDIA_FLAGS_BORDERLESS;
@@ -178,19 +213,19 @@ main(int  argc,                           /* I - Number of command-line arguments */
 
     show_media(http, dest, dinfo, flags, name);
   }
-  else if (!strcmp(argv[2], "print") && argc > 3)
+  else if (!strcmp(argv[i], "print") && (i + 1) < argc)
   {
-    int                        i,              /* Looping var */
-                       num_options = 0;/* Number of options */
+    int                        num_options = 0;/* Number of options */
     cups_option_t      *options = NULL;/* Options */
+    const char         *filename = argv[i + 1];
 
-    for (i = 4; i < argc; i ++)
+    for (i += 2; i < argc; i ++)
       num_options = cupsParseOptions(argv[i], num_options, &options);
 
-    print_file(http, dest, dinfo, argv[3], num_options, options);
+    print_file(http, dest, dinfo, filename, num_options, options);
   }
   else
-    usage(argv[2]);
+    usage(argv[i]);
 
   return (0);
 }
@@ -212,13 +247,15 @@ enum_cb(void        *user_data,           /* I - User data (unused) */
   (void)flags;
 
   if (dest->instance)
-    printf("%s/%s:\n", dest->name, dest->instance);
+    printf("%s%s/%s%s:\n", (flags & CUPS_DEST_FLAGS_REMOVED) ? "REMOVE " : "", dest->name, dest->instance, dest->is_default ? " (Default)" : "");
   else
-    printf("%s:\n", dest->name);
+    printf("%s%s%s:\n", (flags & CUPS_DEST_FLAGS_REMOVED) ? "REMOVE " : "", dest->name, dest->is_default ? " (Default)" : "");
 
   for (i = 0; i < dest->num_options; i ++)
     printf("    %s=\"%s\"\n", dest->options[i].name, dest->options[i].value);
 
+  puts("");
+
   return (1);
 }
 
@@ -234,11 +271,128 @@ localize(http_t       *http,             /* I - Connection to destination */
          const char   *option,         /* I - Option */
         const char   *value)           /* I - Value, if any */
 {
-  (void)http;
-  (void)dest;
-  (void)dinfo;
-  (void)option;
-  (void)value;
+  ipp_attribute_t      *attr;          /* Attribute */
+  int                  i,              /* Looping var */
+                       count;          /* Number of values */
+
+
+  if (!option)
+  {
+    attr = cupsFindDestSupported(http, dest, dinfo, "job-creation-attributes");
+    if (attr)
+    {
+      count = ippGetCount(attr);
+      for (i = 0; i < count; i ++)
+        localize(http, dest, dinfo, ippGetString(attr, i, NULL), NULL);
+    }
+    else
+    {
+      static const char * const options[] =
+      {                                        /* List of standard options */
+        CUPS_COPIES,
+       CUPS_FINISHINGS,
+       CUPS_MEDIA,
+       CUPS_NUMBER_UP,
+       CUPS_ORIENTATION,
+       CUPS_PRINT_COLOR_MODE,
+       CUPS_PRINT_QUALITY,
+       CUPS_SIDES
+      };
+
+      puts("No job-creation-attributes-supported attribute, probing instead.");
+
+      for (i = 0; i < (int)(sizeof(options) / sizeof(options[0])); i ++)
+        if (cupsCheckDestSupported(http, dest, dinfo, options[i], NULL))
+         localize(http, dest, dinfo, options[i], NULL);
+    }
+  }
+  else if (!value)
+  {
+    printf("%s (%s)\n", option, cupsLocalizeDestOption(http, dest, dinfo, option));
+
+    if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL)
+    {
+      count = ippGetCount(attr);
+
+      switch (ippGetValueTag(attr))
+      {
+        case IPP_TAG_INTEGER :
+           for (i = 0; i < count; i ++)
+              printf("  %d\n", ippGetInteger(attr, i));
+           break;
+
+        case IPP_TAG_ENUM :
+           for (i = 0; i < count; i ++)
+              printf("  %s\n", ippEnumString(option, ippGetInteger(attr, i)));
+           break;
+
+        case IPP_TAG_RANGE :
+           for (i = 0; i < count; i ++)
+           {
+             int upper, lower = ippGetRange(attr, i, &upper);
+
+              printf("  %d-%d\n", lower, upper);
+           }
+           break;
+
+        case IPP_TAG_RESOLUTION :
+           for (i = 0; i < count; i ++)
+           {
+             int xres, yres;
+             ipp_res_t units;
+             xres = ippGetResolution(attr, i, &yres, &units);
+
+              if (xres == yres)
+                printf("  %d%s\n", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
+             else
+                printf("  %dx%d%s\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
+           }
+           break;
+
+       case IPP_TAG_TEXTLANG :
+       case IPP_TAG_NAMELANG :
+       case IPP_TAG_TEXT :
+       case IPP_TAG_NAME :
+       case IPP_TAG_KEYWORD :
+       case IPP_TAG_URI :
+       case IPP_TAG_URISCHEME :
+       case IPP_TAG_CHARSET :
+       case IPP_TAG_LANGUAGE :
+       case IPP_TAG_MIMETYPE :
+           for (i = 0; i < count; i ++)
+              printf("  %s (%s)\n", ippGetString(attr, i, NULL), cupsLocalizeDestValue(http, dest, dinfo, option, ippGetString(attr, i, NULL)));
+           break;
+
+        case IPP_TAG_STRING :
+           for (i = 0; i < count; i ++)
+           {
+             int j, len;
+             unsigned char *data = ippGetOctetString(attr, i, &len);
+
+              fputs("  ", stdout);
+             for (j = 0; j < len; j ++)
+             {
+               if (data[j] < ' ' || data[j] >= 0x7f)
+                 printf("<%02X>", data[j]);
+               else
+                 putchar(data[j]);
+              }
+              putchar('\n');
+           }
+           break;
+
+        case IPP_TAG_BOOLEAN :
+           break;
+
+        default :
+           printf("  %s\n", ippTagString(ippGetValueTag(attr)));
+           break;
+      }
+    }
+
+  }
+  else
+    puts(cupsLocalizeDestValue(http, dest, dinfo, option, value));
 }
 
 
@@ -254,12 +408,59 @@ print_file(http_t        *http,           /* I - Connection to destination */
           int           num_options,   /* I - Number of options */
           cups_option_t *options)      /* I - Options */
 {
-  (void)http;
-  (void)dest;
-  (void)dinfo;
-  (void)filename;
-  (void)num_options;
-  (void)options;
+  cups_file_t  *fp;                    /* File to print */
+  int          job_id;                 /* Job ID */
+  ipp_status_t status;                 /* Submission status */
+  const char   *title;                 /* Title of job */
+  char         buffer[32768];          /* File buffer */
+  ssize_t      bytes;                  /* Bytes read/to write */
+
+
+  if ((fp = cupsFileOpen(filename, "r")) == NULL)
+  {
+    printf("Unable to open \"%s\": %s\n", filename, strerror(errno));
+    return;
+  }
+
+  if ((title = strrchr(filename, '/')) != NULL)
+    title ++;
+  else
+    title = filename;
+
+  if ((status = cupsCreateDestJob(http, dest, dinfo, &job_id, title, num_options, options)) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
+  {
+    printf("Unable to create job: %s\n", cupsLastErrorString());
+    cupsFileClose(fp);
+    return;
+  }
+
+  printf("Created job ID: %d\n", job_id);
+
+  if (cupsStartDestDocument(http, dest, dinfo, job_id, title, CUPS_FORMAT_AUTO, 0, NULL, 1) != HTTP_STATUS_CONTINUE)
+  {
+    printf("Unable to send document: %s\n", cupsLastErrorString());
+    cupsFileClose(fp);
+    return;
+  }
+
+  while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
+  {
+    if (cupsWriteRequestData(http, buffer, (size_t)bytes) != HTTP_STATUS_CONTINUE)
+    {
+      printf("Unable to write document data: %s\n", cupsLastErrorString());
+      break;
+    }
+  }
+
+  cupsFileClose(fp);
+
+  if ((status = cupsFinishDestDocument(http, dest, dinfo)) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
+  {
+    printf("Unable to send document: %s\n", cupsLastErrorString());
+    return;
+  }
+
+  puts("Job queued.");
 }
 
 
@@ -293,10 +494,37 @@ show_default(http_t       *http,  /* I - Connection to destination */
             cups_dinfo_t *dinfo,       /* I - Destination information */
             const char  *option)       /* I - Option */
 {
-  (void)http;
-  (void)dest;
-  (void)dinfo;
-  (void)option;
+  if (!strcmp(option, "media"))
+  {
+   /*
+    * Show default media option...
+    */
+
+    cups_size_t size;                   /* Media size information */
+
+    if (cupsGetDestMediaDefault(http, dest, dinfo, CUPS_MEDIA_FLAGS_DEFAULT, &size))
+      printf("%s (%.2fx%.2fmm, margins=[%.2f %.2f %.2f %.2f])\n", size.media, size.width * 0.01, size.length * 0.01, size.left * 0.01, size.bottom * 0.01, size.right * 0.01, size.top * 0.01);
+     else
+       puts("FAILED");
+  }
+  else
+  {
+   /*
+    * Show default other option...
+    */
+
+    ipp_attribute_t *defattr;           /* Default attribute */
+
+    if ((defattr = cupsFindDestDefault(http, dest, dinfo, option)) != NULL)
+    {
+      char value[1024];                 /* Value of default attribute */
+
+      ippAttributeString(defattr, value, sizeof(value));
+      puts(value);
+    }
+    else
+      puts("FAILED");
+  }
 }
 
 
@@ -424,7 +652,8 @@ show_supported(http_t       *http,  /* I - Connection to destination */
   }
   else if (!value)
   {
-    puts(option);
+    printf("%s (%s - %s)\n", option, cupsLocalizeDestOption(http, dest, dinfo, option), cupsCheckDestSupported(http, dest, dinfo, option, NULL) ? "supported" : "not-supported");
+
     if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL)
     {
       count = ippGetCount(attr);
@@ -438,7 +667,13 @@ show_supported(http_t       *http, /* I - Connection to destination */
 
         case IPP_TAG_ENUM :
            for (i = 0; i < count; i ++)
-              printf("  %s\n", ippEnumString(option, ippGetInteger(attr, i)));
+           {
+             int val = ippGetInteger(attr, i);
+             char valstr[256];
+
+              snprintf(valstr, sizeof(valstr), "%d", val);
+              printf("  %s (%s)\n", ippEnumString(option, ippGetInteger(attr, i)), cupsLocalizeDestValue(http, dest, dinfo, option, valstr));
+            }
            break;
 
         case IPP_TAG_RANGE :
@@ -450,11 +685,29 @@ show_supported(http_t       *http,        /* I - Connection to destination */
            }
            break;
 
+        case IPP_TAG_RESOLUTION :
+           for (i = 0; i < count; i ++)
+           {
+             int xres, yres;
+             ipp_res_t units;
+             xres = ippGetResolution(attr, i, &yres, &units);
+
+              if (xres == yres)
+                printf("  %d%s\n", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
+             else
+                printf("  %dx%d%s\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
+           }
+           break;
+
+       case IPP_TAG_KEYWORD :
+           for (i = 0; i < count; i ++)
+              printf("  %s (%s)\n", ippGetString(attr, i, NULL), cupsLocalizeDestValue(http, dest, dinfo, option, ippGetString(attr, i, NULL)));
+           break;
+
        case IPP_TAG_TEXTLANG :
        case IPP_TAG_NAMELANG :
        case IPP_TAG_TEXT :
        case IPP_TAG_NAME :
-       case IPP_TAG_KEYWORD :
        case IPP_TAG_URI :
        case IPP_TAG_URISCHEME :
        case IPP_TAG_CHARSET :
@@ -490,13 +743,12 @@ show_supported(http_t       *http,        /* I - Connection to destination */
            break;
       }
     }
-    
+
   }
   else if (cupsCheckDestSupported(http, dest, dinfo, option, value))
     puts("YES");
   else
     puts("NO");
-
 }
 
 
@@ -511,9 +763,10 @@ usage(const char *arg)                     /* I - Argument for usage message */
     printf("testdest: Unknown option \"%s\".\n", arg);
 
   puts("Usage:");
-  puts("  ./testdest name [operation ...]");
-  puts("  ./testdest ipp://... [operation ...]");
-  puts("  ./testdest ipps://... [operation ...]");
+  puts("  ./testdest [--device] name [operation ...]");
+  puts("  ./testdest [--device] ipp://... [operation ...]");
+  puts("  ./testdest [--device] ipps://... [operation ...]");
+  puts("  ./testdest --get");
   puts("  ./testdest --enum [grayscale] [color] [duplex] [staple] [small]\n"
        "                    [medium] [large]");
   puts("");
@@ -527,8 +780,3 @@ usage(const char *arg)                      /* I - Argument for usage message */
 
   exit(arg != NULL);
 }
-
-
-/*
- * End of "$Id$".
- */