]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cgi-bin/printers.c
Merge changes from CUPS 1.4svn-r7696.
[thirdparty/cups.git] / cgi-bin / printers.c
index 25bb7ea70ef6087785bdc2bd430e1b6ffbbd319f..f90632866a04e6a2827ce873e17c6d80e6280798 100644 (file)
@@ -1,29 +1,23 @@
 /*
- * "$Id: printers.c 4921 2006-01-12 21:26:26Z mike $"
+ * "$Id: printers.c 7301 2008-02-13 00:27:52Z mike $"
  *
  *   Printer status CGI for the Common UNIX Printing System (CUPS).
  *
+ *   Copyright 2007-2008 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
+ *   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 for CGI.
+ *   main()              - Main entry for CGI.
+ *   print_command()     - Send a print command to the printer.
+ *   show_all_printers() - Show all printers...
+ *   show_printer()      - Show a single printer.
  */
 
 /*
  */
 
 #include "cgi-private.h"
+#include <errno.h>
+
+
+/*
+ * Local functions...
+ */
+
+void   print_command(http_t *http, const char *printer, const char *command);
+void   show_all_printers(http_t *http, const char *username);
+void   show_printer(http_t *http, const char *printer);
 
 
 /*
@@ -41,17 +45,13 @@ int                                 /* O - Exit status */
 main(int  argc,                                /* I - Number of command-line arguments */
      char *argv[])                     /* I - Command-line arguments */
 {
-  cups_lang_t  *language;              /* Language information */
-  char         *printer;               /* Printer name */
+  const char   *printer;               /* Printer name */
+  const char   *user;                  /* Username */
   http_t       *http;                  /* Connection to the server */
   ipp_t                *request,               /* IPP request */
                *response;              /* IPP response */
   ipp_attribute_t *attr;               /* IPP attribute */
-  ipp_status_t status;                 /* Operation status... */
-  char         uri[HTTP_MAX_URI];      /* Printer URI */
-  const char   *which_jobs;            /* Which jobs to show */
   const char   *op;                    /* Operation to perform, if any */
-  char         refresh[1024];          /* Refresh URL */
   static const char *def_attrs[] =     /* Attributes for default printer */
                {
                  "printer-name",
@@ -64,13 +64,8 @@ main(int  argc,                              /* I - Number of command-line arguments */
   */
 
   cgiInitialize();
-  op = cgiGetVariable("OP");
 
- /*
-  * Get the request language...
-  */
-
-  language = cupsLangDefault();
+  op = cgiGetVariable("OP");
 
  /*
   * Set the web interface section...
@@ -79,48 +74,40 @@ main(int  argc,                             /* I - Number of command-line arguments */
   cgiSetVariable("SECTION", "printers");
 
  /*
-  * Connect to the HTTP server...
+  * See if we are displaying a printer or all printers...
   */
 
-  http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+  if ((printer = getenv("PATH_INFO")) != NULL)
+  {
+    printer ++;
+
+    if (!*printer)
+      printer = NULL;
+  }
 
  /*
-  * Tell the client to expect UTF-8 encoded HTML...
+  * See who is logged in...
   */
 
-  puts("Content-Type: text/html;charset=utf-8\n");
+  user = getenv("REMOTE_USER");
 
  /*
-  * See if we need to show a list of printers or the status of a
-  * single printer...
+  * Connect to the HTTP server...
   */
 
-  cgiSetServerVersion();
+  http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
 
-  printer = argv[0];
-  if (strcmp(printer, "/") == 0 || strstr(printer, "printers.cgi") != NULL)
-  {
-    printer = NULL;
-    cgiSetVariable("TITLE", _cupsLangString(language, _("Printer")));
-  }
-  else
-    cgiSetVariable("TITLE", printer);
+ /*
+  * Get the default printer...
+  */
 
-  if (op == NULL || strcasecmp(op, "print-test-page") != 0)
+  if (!op || !cgiIsPOST())
   {
    /*
     * Get the default destination...
     */
 
-    request = ippNew();
-    request->request.op.operation_id = CUPS_GET_DEFAULT;
-    request->request.op.request_id   = 1;
-
-    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                "attributes-charset", NULL, cupsLangEncoding(language));
-
-    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
-                "attributes-natural-language", NULL, language->language);
+    request = ippNewRequest(CUPS_GET_DEFAULT);
 
     ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                   "requested-attributes",
@@ -145,290 +132,485 @@ main(int  argc,                         /* I - Number of command-line arguments */
     }
 
    /*
-    * Get the printer info...
+    * See if we need to show a list of printers or the status of a
+    * single printer...
     */
 
-    request = ippNew();
+    if (!printer)
+      show_all_printers(http, user);
+    else
+      show_printer(http, printer);
+  }
+  else if (!strcasecmp(op, "print-self-test-page") && printer)
+    print_command(http, printer, "PrintSelfTestPage");
+  else if (!strcasecmp(op, "clean-print-heads") && printer)
+    print_command(http, printer, "Clean all");
+  else if (!strcasecmp(op, "print-test-page") && printer)
+    cgiPrintTestPage(http, printer);
+  else if (!strcasecmp(op, "move-jobs") && printer)
+    cgiMoveJobs(http, printer, 0);
+  else
+  {
+   /*
+    * Unknown/bad operation...
+    */
+
+    if (printer)
+      cgiStartHTML(printer);
+    else
+      cgiStartHTML(cgiText(_("Printers")));
 
-    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                "attributes-charset", NULL, cupsLangEncoding(language));
+    cgiCopyTemplateLang("error-op.tmpl");
+    cgiEndHTML();
+  }
 
-    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
-                "attributes-natural-language", NULL, language->language);
+ /*
+  * Close the HTTP server connection...
+  */
 
-    if (printer == NULL)
-    {
-     /*
-      * Build a CUPS_GET_PRINTERS request, which requires the following
-      * attributes:
-      *
-      *    attributes-charset
-      *    attributes-natural-language
-      */
+  httpClose(http);
 
-      request->request.op.operation_id = CUPS_GET_PRINTERS;
-      request->request.op.request_id   = 1;
+ /*
+  * Return with no errors...
+  */
 
-      ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
-                    "printer-type", 0);
-      ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
-                    "printer-type-mask", CUPS_PRINTER_CLASS);
+  return (0);
+}
 
-      if (getenv("REMOTE_USER") != NULL)
-       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                     NULL, getenv("REMOTE_USER"));
-    }
-    else
-    {
-     /*
-      * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
-      * attributes:
-      *
-      *    attributes-charset
-      *    attributes-natural-language
-      *    printer-uri
-      */
 
-      request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
-      request->request.op.request_id   = 1;
+/*
+ * 'print_command()' - Send a print command to the printer.
+ */
 
-      httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                       "/printers/%s", printer);
-      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
-                   uri);
-    }
+void
+print_command(http_t     *http,                /* I - Connection to server */
+              const char *printer,     /* I - Printer */
+             const char *command)      /* I - Command to send */
+{
+  cups_file_t  *fp;                    /* File pointer */
+  char         filename[1024];         /* Temporary file */
+  ipp_t                *request,               /* IPP request */
+               *response;              /* IPP response */
+  char         uri[HTTP_MAX_URI],      /* Printer URI */
+               resource[1024],         /* POST resource path */
+               refresh[1024];          /* Refresh URL */
+  const char   *user;                  /* Username */
 
-    cgiGetAttributes(request, "printers.tmpl");
 
  /*
-    * Do the request and get back a response...
-    */
+ /*
+  * See who is logged in...
+  */
 
-    if ((response = cupsDoRequest(http, request, "/")) != NULL)
-    {
-     /*
-      * Got the result; set the CGI variables and check the status of a
-      * single-queue request...
-      */
+  if ((user = getenv("REMOTE_USER")) == NULL)
+    user = "guest";
 
-      cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+ /*
+  * Create the CUPS command file to print...
+  */
 
-      if (printer && (attr = ippFindAttribute(response, "printer-state",
-                                              IPP_TAG_ENUM)) != NULL &&
-          attr->values[0].integer == IPP_PRINTER_PROCESSING)
-      {
-       /*
-        * Printer is processing - automatically refresh the page until we
-       * are done printing...
-       */
-
-       cgiFormEncode(uri, printer, sizeof(uri));
-       snprintf(refresh, sizeof(refresh), "10;/printers/%s", uri);
-       cgiSetVariable("refresh_page", refresh);
-      }
+  if ((fp = cupsTempFile2(filename, sizeof(filename))) == NULL)
+  {
+    cgiStartHTML(cgiText(_("Printer Maintenance")));
+    cgiSetVariable("MESSAGE", _("Unable to create temporary file:"));
+    cgiSetVariable("ERROR", strerror(errno));
+    cgiCopyTemplateLang("error.tmpl");
+    cgiEndHTML();
+    return;
+  }
 
-     /*
-      * Delete the response...
-      */
+  cupsFilePuts(fp, "#CUPS-COMMAND\n");
+  cupsFilePrintf(fp, "%s\n", command);
+  cupsFileClose(fp);
 
-      ippDelete(response);
-    }
-    else if (printer)
-      fprintf(stderr, "ERROR: Get-Printer-Attributes request failed - %s (%x)\n",
-              ippErrorString(cupsLastError()), cupsLastError());
-    else
-      fprintf(stderr, "ERROR: CUPS-Get-Printers request failed - %s (%x)\n",
-              ippErrorString(cupsLastError()), cupsLastError());
+ /*
+  * Point to the printer...
+  */
+
+  snprintf(resource, sizeof(resource), "/printers/%s", printer);
+
+  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                   "localhost", ippPort(), "/printers/%s", printer);
+
+ /*
+  * Build an IPP_PRINT_JOB request, which requires the following
+  * attributes:
+  *
+  *    attributes-charset
+  *    attributes-natural-language
+  *    printer-uri
+  *    requesting-user-name
+  *    document-format
+  */
 
+  request = ippNewRequest(IPP_PRINT_JOB);
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+               NULL, uri);
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+               "requesting-user-name", NULL, user);
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+               NULL, "Printer Maintenance");
+
+  ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
+               NULL, "application/postscript");
+
+ /*
+  * Do the request and get back a response...
+  */
+
+  if ((response = cupsDoFileRequest(http, request, resource,
+                                    filename)) != NULL)
+  {
+    cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+
+    ippDelete(response);
+  }
+
+  unlink(filename);
+
+  if (cupsLastError() <= IPP_OK_CONFLICT)
+  {
    /*
-    * Show the standard header...
+    * Automatically reload the printer status page...
     */
 
-    cgiCopyTemplateLang("header.tmpl");
+    cgiFormEncode(uri, resource, sizeof(uri));
+    snprintf(refresh, sizeof(refresh), "2;URL=%s", uri);
+    cgiSetVariable("refresh_page", refresh);
+  }
+  else if (cupsLastError() == IPP_NOT_AUTHORIZED)
+  {
+    puts("Status: 401\n");
+    exit(0);
+  }
+
+  cgiStartHTML(cgiText(_("Printer Maintenance")));
+
+  if (cupsLastError() > IPP_OK_CONFLICT)
+    cgiShowIPPError(_("Unable to send maintenance job:"));
+  else
+  {
+    cgiSetVariable("PRINTER_NAME", printer);
+
+    cgiCopyTemplateLang("maintenance.tmpl");
+  }
+
+  cgiEndHTML();
+}
+
+
+/*
+ * 'show_all_printers()' - Show all printers...
+ */
+
+void
+show_all_printers(http_t     *http,    /* I - Connection to server */
+                  const char *user)    /* I - Username */
+{
+  int                  i;              /* Looping var */
+  ipp_t                        *request,       /* IPP request */
+                       *response;      /* IPP response */
+  cups_array_t         *printers;      /* Array of printer objects */
+  ipp_attribute_t      *printer,       /* Printer object */
+                       *attr;          /* Current attribute */
+  int                  ascending,      /* Order of printers (0 = descending) */
+                       first,          /* First printer to show */
+                       count;          /* Number of printers */
+  const char           *var;           /* Form variable */
+  void                 *search;        /* Search data */
+  char                 val[1024];      /* Form variable */
+
+
+  fprintf(stderr, "DEBUG: show_all_printers(http=%p, user=\"%s\")\n",
+          http, user ? user : "(null)");
+
+ /*
+  * Show the standard header...
+  */
+
+  cgiStartHTML(cgiText(_("Printers")));
+
+ /*
+  * Build a CUPS_GET_PRINTERS request, which requires the following
+  * attributes:
+  *
+  *    attributes-charset
+  *    attributes-natural-language
+  *    printer-type
+  *    printer-type-mask
+  *    requesting-user-name
+  */
+
+  request = ippNewRequest(CUPS_GET_PRINTERS);
+
+  ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
+                "printer-type", 0);
+  ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
+                "printer-type-mask", CUPS_PRINTER_CLASS);
 
+  if (user)
+    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+                "requesting-user-name", NULL, user);
+
+  cgiGetAttributes(request, "printers.tmpl");
+
+ /*
+  * Do the request and get back a response...
+  */
+
+  if ((response = cupsDoRequest(http, request, "/")) != NULL)
+  {
    /*
-    * Write the report...
+    * Get a list of matching job objects.
     */
 
-    cgiCopyTemplateLang("printers.tmpl");
+    if ((var = cgiGetVariable("QUERY")) != NULL &&
+        !cgiGetVariable("CLEAR"))
+      search = cgiCompileSearch(var);
+    else
+      search = NULL;
+
+    printers  = cgiGetIPPObjects(response, search);
+    count     = cupsArrayCount(printers);
+
+    if (search)
+      cgiFreeSearch(search);
 
    /*
-    * Get jobs for the specified printer if a printer has been chosen...
+    * Figure out which printers to display...
     */
 
-    if (printer != NULL)
-    {
-     /*
-      * Build an IPP_GET_JOBS request, which requires the following
-      * attributes:
-      *
-      *    attributes-charset
-      *    attributes-natural-language
-      *    printer-uri
-      */
-
-      request = ippNew();
+    if ((var = cgiGetVariable("FIRST")) != NULL)
+      first = atoi(var);
+    else
+      first = 0;
 
-      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                  "attributes-charset", NULL, cupsLangEncoding(language));
+    if (first >= count)
+      first = count - CUPS_PAGE_MAX;
 
-      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
-                  "attributes-natural-language", NULL, language->language);
+    first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX;
 
-      request->request.op.operation_id = IPP_GET_JOBS;
-      request->request.op.request_id   = 1;
+    if (first < 0)
+      first = 0;
 
-      httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                       "/printers/%s", printer);
-      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
-                   uri);
+    sprintf(val, "%d", count);
+    cgiSetVariable("TOTAL", val);
 
-      if ((which_jobs = cgiGetVariable("which_jobs")) != NULL)
-       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs",
-                     NULL, which_jobs);
+    if ((var = cgiGetVariable("ORDER")) != NULL)
+      ascending = !strcasecmp(var, "asc");
+    else
+      ascending = 1;
 
-      if (getenv("REMOTE_USER") != NULL)
+    if (ascending)
+    {
+      for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, first);
+          i < CUPS_PAGE_MAX && printer;
+          i ++, printer = (ipp_attribute_t *)cupsArrayNext(printers))
       {
-       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                     NULL, getenv("REMOTE_USER"));
-
-       if (strcmp(getenv("REMOTE_USER"), "root"))
-         ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
+        cgiSetIPPObjectVars(printer, NULL, i);
+
+        cgiSetArray("cupscommand", i, "0");
+
+       for (attr = printer; attr; attr = attr->next)
+         if (attr->group_tag != IPP_TAG_PRINTER || !attr->name)
+           break;
+         else if (!strcmp(attr->name, "printer-type"))
+         {
+            if (attr->values[0].integer & CUPS_PRINTER_COMMANDS)
+             cgiSetArray("cupscommand", i, "1");
+           break;
+         }
+      }
+    }
+    else
+    {
+      for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, count - first - 1);
+          i < CUPS_PAGE_MAX && printer;
+          i ++, printer = (ipp_attribute_t *)cupsArrayPrev(printers))
+      {
+        cgiSetIPPObjectVars(printer, NULL, i);
+
+        cgiSetArray("cupscommand", i, "0");
+
+       for (attr = printer; attr; attr = attr->next)
+         if (attr->group_tag == IPP_TAG_ZERO || !attr->name)
+           break;
+         else if (!strcmp(attr->name, "printer-type"))
+         {
+            if (attr->values[0].integer & CUPS_PRINTER_COMMANDS)
+             cgiSetArray("cupscommand", i, "1");
+           break;
+         }
       }
-      else
-       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                     NULL, "unknown");
+    }
 
-      cgiGetAttributes(request, "jobs.tmpl");
+   /*
+    * Save navigation URLs...
+    */
 
-     /*
-      * Do the request and get back a response...
-      */
+    cgiSetVariable("THISURL", "/printers/");
 
-      if ((response = cupsDoRequest(http, request, "/")) != NULL)
-      {
-       cgiSetIPPVars(response, NULL, NULL, NULL, 0);
-       ippDelete(response);
+    if (first > 0)
+    {
+      sprintf(val, "%d", first - CUPS_PAGE_MAX);
+      cgiSetVariable("PREV", val);
+    }
 
-       cgiCopyTemplateLang("jobs.tmpl");
-      }
-      else
-       fprintf(stderr, "ERROR: Get-Jobs request failed - %s (%x)\n",
-               ippErrorString(cupsLastError()), cupsLastError());
+    if ((first + CUPS_PAGE_MAX) < count)
+    {
+      sprintf(val, "%d", first + CUPS_PAGE_MAX);
+      cgiSetVariable("NEXT", val);
     }
-  }
-  else
-  {
+
    /*
-    * Print a test page...
+    * Then show everything...
     */
 
-    char       filename[1024];         /* Test page filename */
-    const char *datadir;               /* CUPS_DATADIR env var */
+    cgiCopyTemplateLang("search.tmpl");
 
+    cgiCopyTemplateLang("printers-header.tmpl");
 
-    cgiFormEncode(uri, printer, sizeof(uri));
-    snprintf(refresh, sizeof(refresh), "2;/printers/%s", uri);
-    cgiSetVariable("refresh_page", refresh);
+    if (count > 0)
+      cgiCopyTemplateLang("pager.tmpl");
 
-    if ((datadir = getenv("CUPS_DATADIR")) == NULL)
-      datadir = CUPS_DATADIR;
+    cgiCopyTemplateLang("printers.tmpl");
 
-    snprintf(filename, sizeof(filename), "%s/data/testprint.ps", datadir);
-    httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                     "/printers/%s", printer);
+    if (count > 0)
+      cgiCopyTemplateLang("pager.tmpl");
+
+   /*
+    * Delete the response...
+    */
 
+    cupsArrayDelete(printers);
+    ippDelete(response);
+  }
+  else
+  {
    /*
-    * Build an IPP_PRINT_JOB request, which requires the following
-    * attributes:
-    *
-    *    attributes-charset
-    *    attributes-natural-language
-    *    printer-uri
-    *    requesting-user-name
-    *    document-format
+    * Show the error...
     */
 
-    request = ippNew();
+    cgiShowIPPError(_("Unable to get printer list:"));
+  }
 
-    request->request.op.operation_id = IPP_PRINT_JOB;
-    request->request.op.request_id   = 1;
+   cgiEndHTML();
+}
 
-    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                "attributes-charset", NULL, cupsLangEncoding(language));
 
-    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
-                "attributes-natural-language", NULL, language->language);
+/*
+ * 'show_printer()' - Show a single printer.
+ */
 
-    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
-                NULL, uri);
+void
+show_printer(http_t     *http,         /* I - Connection to server */
+             const char *printer)      /* I - Name of printer */
+{
+  ipp_t                *request,               /* IPP request */
+               *response;              /* IPP response */
+  ipp_attribute_t *attr;               /* IPP attribute */
+  char         uri[HTTP_MAX_URI];      /* Printer URI */
+  char         refresh[1024];          /* Refresh URL */
 
-    if (getenv("REMOTE_USER") != NULL)
-      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                   NULL, getenv("REMOTE_USER"));
-    else
-      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                   NULL, "root");
 
-    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
-                NULL, "Test Page");
+  fprintf(stderr, "DEBUG: show_printer(http=%p, printer=\"%s\")\n",
+          http, printer ? printer : "(null)");
 
-    ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
-                NULL, "application/postscript");
+ /*
+  * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
+  * attributes:
+  *
+  *    attributes-charset
+  *    attributes-natural-language
+  *    printer-uri
+  */
+
+  request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
+
+  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                   "localhost", 0, "/printers/%s", printer);
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+               uri);
+
+  cgiGetAttributes(request, "printers.tmpl");
+
+ /*
+  * Do the request and get back a response...
+  */
 
+  if ((response = cupsDoRequest(http, request, "/")) != NULL)
+  {
    /*
-    * Do the request and get back a response...
+    * Got the result; set the CGI variables and check the status of a
+    * single-queue request...
     */
 
-    if ((response = cupsDoFileRequest(http, request, uri + 15,
-                                      filename)) != NULL)
+    cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+
+    if ((attr = ippFindAttribute(response, "printer-type",
+                                 IPP_TAG_ENUM)) != NULL)
     {
-      status = response->request.status.status_code;
-      cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+      cgiSetVariable("cupscommand",
+                     (attr->values[0].integer & CUPS_PRINTER_COMMANDS) ?
+                        "1" : "0");
+    }
 
-      ippDelete(response);
+    if (printer && (attr = ippFindAttribute(response, "printer-state",
+                                            IPP_TAG_ENUM)) != NULL &&
+        attr->values[0].integer == IPP_PRINTER_PROCESSING)
+    {
+     /*
+      * Printer is processing - automatically refresh the page until we
+      * are done printing...
+      */
+
+      cgiFormEncode(uri, printer, sizeof(uri));
+      snprintf(refresh, sizeof(refresh), "10;URL=/printers/%s", uri);
+      cgiSetVariable("refresh_page", refresh);
     }
-    else
-      status = cupsLastError();
 
-    cgiSetVariable("PRINTER_NAME", printer);
+   /*
+    * Delete the response...
+    */
+
+    ippDelete(response);
 
    /*
     * Show the standard header...
     */
 
-    cgiCopyTemplateLang("header.tmpl");
+    cgiStartHTML(printer);
 
    /*
-    * Show the result...
+    * Show the printer status...
     */
 
-    if (status > IPP_OK_CONFLICT)
-    {
-      cgiSetVariable("ERROR", ippErrorString(status));
-      cgiCopyTemplateLang("error.tmpl");
-    }
-    else
-      cgiCopyTemplateLang("test-page.tmpl");
-  }
-
-  cgiCopyTemplateLang("trailer.tmpl");
+    cgiSetVariable("_SINGLE_DEST", "1");
+    cgiCopyTemplateLang("printers.tmpl");
 
- /*
-  * Close the HTTP server connection...
-  */
  /*
+    * Show jobs for the specified printer...
+    */
 
-  httpClose(http);
-  cupsLangFree(language);
+    cgiCopyTemplateLang("printer-jobs-header.tmpl");
+    cgiShowJobs(http, printer);
+  }
+  else
+  {
+   /*
+    * Show the IPP error...
+    */
 
- /*
-  * Return with no errors...
-  */
+    cgiStartHTML(printer);
+    cgiShowIPPError(_("Unable to get printer status:"));
+  }
 
-  return (0);
+   cgiEndHTML();
 }
 
 
 /*
- * End of "$Id: printers.c 4921 2006-01-12 21:26:26Z mike $".
+ * End of "$Id: printers.c 7301 2008-02-13 00:27:52Z mike $".
  */