]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cgi-bin/admin.c
Load cups into easysw/current.
[thirdparty/cups.git] / cgi-bin / admin.c
index 01252ba5cf65b356d87b803da37bb9fdbd9c7a28..e50a20797ef8b6914488e5d02ac99dbb76325660 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: admin.c 4943 2006-01-18 20:30:42Z mike $"
+ * "$Id: admin.c 5290 2006-03-14 21:43:57Z mike $"
  *
  *   Administration CGI for the Common UNIX Printing System (CUPS).
  *
@@ -43,6 +43,7 @@
  */
 
 #include "cgi-private.h"
+#include <cups/adminutil.h>
 #include <cups/file.h>
 #include <errno.h>
 #include <unistd.h>
@@ -85,8 +86,21 @@ main(int  argc,                              /* I - Number of command-line arguments */
   * Connect to the HTTP server...
   */
 
+  fputs("DEBUG: admin.cgi started...\n", stderr);
+
   http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
 
+  if (!http)
+  {
+    perror("ERROR: Unable to connect to cupsd");
+    fprintf(stderr, "DEBUG: cupsServer()=\"%s\"\n", cupsServer());
+    fprintf(stderr, "DEBUG: ippPort()=%d\n", ippPort());
+    fprintf(stderr, "DEBUG: cupsEncryption()=%d\n", cupsEncryption());
+    exit(1);
+  }
+
+  fprintf(stderr, "DEBUG: http=%p\n", http);
+
  /*
   * Set the web interface section...
   */
@@ -103,6 +117,8 @@ main(int  argc,                             /* I - Number of command-line arguments */
     * Nope, send the administration menu...
     */
 
+    fputs("DEBUG: No form data, showing main menu...\n", stderr);
+
     do_menu(http);
   }
   else if ((op = cgiGetVariable("OP")) != NULL)
@@ -111,6 +127,8 @@ main(int  argc,                             /* I - Number of command-line arguments */
     * Do the operation...
     */
 
+    fprintf(stderr, "DEBUG: op=\"%s\"...\n", op);
+
     if (!strcmp(op, "redirect"))
     {
       const char *url;                 /* Redirection URL... */
@@ -303,8 +321,8 @@ do_am_class(http_t *http,           /* I - HTTP connection */
 
       request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
 
-      httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                       "/classes/%s", name);
+      httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                       "localhost", 0, "/classes/%s", name);
       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                    NULL, uri);
 
@@ -319,7 +337,8 @@ do_am_class(http_t *http,           /* I - HTTP connection */
 
       if ((response = cupsDoRequest(http, request, "/")) != NULL)
       {
-       if ((attr = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) != NULL)
+       if ((attr = ippFindAttribute(response, "member-names",
+                                    IPP_TAG_NAME)) != NULL)
        {
         /*
           * Mark any current members in the class...
@@ -408,8 +427,9 @@ do_am_class(http_t *http,           /* I - HTTP connection */
 
   request = ippNewRequest(CUPS_ADD_CLASS);
 
-  httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                   "/classes/%s", cgiGetVariable("PRINTER_NAME"));
+  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                   "localhost", 0, "/classes/%s",
+                  cgiGetVariable("PRINTER_NAME"));
   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                NULL, uri);
 
@@ -526,8 +546,9 @@ do_am_printer(http_t *http,         /* I - HTTP connection */
 
     request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
 
-    httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                     "/printers/%s", cgiGetVariable("PRINTER_NAME"));
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                     "localhost", 0, "/printers/%s",
+                    cgiGetVariable("PRINTER_NAME"));
     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                  NULL, uri);
 
@@ -611,6 +632,8 @@ do_am_printer(http_t *http,         /* I - HTTP connection */
     *    printer-uri
     */
 
+    fputs("DEBUG: Getting list of devices...\n", stderr);
+
     request = ippNewRequest(CUPS_GET_DEVICES);
 
     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
@@ -620,11 +643,19 @@ do_am_printer(http_t *http,               /* I - HTTP connection */
     * Do the request and get back a response...
     */
 
+    fprintf(stderr, "DEBUG: http=%p (%s)\n", http, http->hostname);
+
     if ((response = cupsDoRequest(http, request, "/")) != NULL)
     {
+      fputs("DEBUG: Got device list!\n", stderr);
+
       cgiSetIPPVars(response, NULL, NULL, NULL, 0);
       ippDelete(response);
     }
+    else
+      fprintf(stderr,
+              "ERROR: CUPS-Get-Devices request failed with status %x: %s\n",
+             cupsLastError(), cupsLastErrorString());
 
    /*
     * Let the user choose...
@@ -705,6 +736,7 @@ do_am_printer(http_t *http,         /* I - HTTP connection */
       http_status_t    get_status;     /* Status of GET */
 
 
+      /* TODO: Use cupsGetFile() API... */
       snprintf(uri, sizeof(uri), "/printers/%s.ppd", name);
 
       if (httpGet(http, uri))
@@ -719,7 +751,7 @@ do_am_printer(http_t *http,         /* I - HTTP connection */
       }
       else if ((fd = cupsTempFd(filename, sizeof(filename))) >= 0)
       {
-       while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
+       while ((bytes = httpRead2(http, buffer, sizeof(buffer))) > 0)
           write(fd, buffer, bytes);
 
        close(fd);
@@ -921,8 +953,9 @@ do_am_printer(http_t *http,         /* I - HTTP connection */
 
     request = ippNewRequest(CUPS_ADD_PRINTER);
 
-    httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                     "/printers/%s", cgiGetVariable("PRINTER_NAME"));
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                     "localhost", 0, "/printers/%s",
+                    cgiGetVariable("PRINTER_NAME"));
     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                  NULL, uri);
 
@@ -1050,13 +1083,15 @@ do_config_printer(http_t *http)         /* I - HTTP connection */
 
   title = cgiText(_("Set Printer Options"));
 
+  fprintf(stderr, "DEBUG: do_config_printer(http=%p)\n", http);
+
  /*
   * Get the printer name...
   */
 
   if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
-    httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                     "/printers/%s", printer);
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                     "localhost", 0, "/printers/%s", printer);
   else
   {
     cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
@@ -1066,18 +1101,24 @@ do_config_printer(http_t *http)         /* I - HTTP connection */
     return;
   }
 
+  fprintf(stderr, "DEBUG: printer=\"%s\", uri=\"%s\"...\n", printer, uri);
+
  /*
   * Get the PPD file...
   */
 
-  if ((filename = cupsGetPPD(printer)) == NULL)
+  if ((filename = cupsGetPPD2(http, printer)) == NULL)
   {
+    fputs("DEBUG: No PPD file!?!\n", stderr);
+
     cgiStartHTML(title);
     cgiShowIPPError(_("Unable to get PPD file!"));
     cgiEndHTML();
     return;
   }
 
+  fprintf(stderr, "DEBUG: Got PPD file: \"%s\"\n", filename);
+
   if ((ppd = ppdOpenFile(filename)) == NULL)
   {
     cgiSetVariable("ERROR", ppdErrorString(ppdLastError(&i)));
@@ -1103,7 +1144,9 @@ do_config_printer(http_t *http)           /* I - HTTP connection */
   {
     DEBUG_printf(("<LI>%s<UL>\n", group->text));
 
-    for (j = group->num_options, option = group->options; j > 0; j --, option ++)
+    for (j = group->num_options, option = group->options;
+         j > 0;
+        j --, option ++)
       if ((var = cgiGetVariable(option->keyword)) != NULL)
       {
         DEBUG_printf(("<LI>%s = \"%s\"</LI>\n", option->keyword, var));
@@ -1127,6 +1170,8 @@ do_config_printer(http_t *http)           /* I - HTTP connection */
     * Show the options to the user...
     */
 
+    fputs("DEBUG: Showing options...\n", stderr);
+
     ppdLocalize(ppd);
 
     cgiStartHTML("Set Printer Options");
@@ -1134,8 +1179,12 @@ do_config_printer(http_t *http)          /* I - HTTP connection */
 
     if (ppdConflicts(ppd))
     {
-      for (i = ppd->num_groups, k = 0, group = ppd->groups; i > 0; i --, group ++)
-       for (j = group->num_options, option = group->options; j > 0; j --, option ++)
+      for (i = ppd->num_groups, k = 0, group = ppd->groups;
+           i > 0;
+          i --, group ++)
+       for (j = group->num_options, option = group->options;
+            j > 0;
+            j --, option ++)
           if (option->conflicted)
          {
            cgiSetArray("ckeyword", k, option->keyword);
@@ -1220,8 +1269,8 @@ do_config_printer(http_t *http)           /* I - HTTP connection */
 
     request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
 
-    httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                     "/printers/%s", printer);
+    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);
 
@@ -1386,6 +1435,8 @@ do_config_printer(http_t *http)           /* I - HTTP connection */
     * Set default options...
     */
 
+    fputs("DEBUG: Setting options...\n", stderr);
+
     out = cupsTempFile2(tempfile, sizeof(tempfile));
     in  = cupsFileOpen(filename, "r");
 
@@ -1460,8 +1511,9 @@ do_config_printer(http_t *http)           /* I - HTTP connection */
 
     request = ippNewRequest(CUPS_ADD_PRINTER);
 
-    httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                     "/printers/%s", cgiGetVariable("PRINTER_NAME"));
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                     "localhost", 0, "/printers/%s",
+                    cgiGetVariable("PRINTER_NAME"));
     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                  NULL, uri);
 
@@ -1499,8 +1551,8 @@ do_config_printer(http_t *http)           /* I - HTTP connection */
 
 
       cgiFormEncode(uri, printer, sizeof(uri));
-      snprintf(refresh, sizeof(refresh), "5;/admin/?OP=redirect&URL=/printers/%s",
-               uri);
+      snprintf(refresh, sizeof(refresh),
+               "5;/admin/?OP=redirect&URL=/printers/%s", uri);
       cgiSetVariable("refresh_page", refresh);
 
       cgiStartHTML(title);
@@ -1530,586 +1582,46 @@ do_config_server(http_t *http)         /* I - HTTP connection */
     * Save basic setting changes...
     */
 
-    http_status_t status;              /* PUT status */
-    cups_file_t        *cupsd;                 /* cupsd.conf file */
-    char       tempfile[1024];         /* Temporary new cupsd.conf */
-    int                tempfd;                 /* Temporary file descriptor */
-    cups_file_t        *temp;                  /* Temporary file */
-    char       line[1024],             /* Line from cupsd.conf file */
-               *value;                 /* Value on line */
-    const char *server_root;           /* Location of config files */
-    int                linenum,                /* Line number in file */
-               in_policy,              /* In a policy section? */
-               in_cancel_job,          /* In a cancel-job section? */
-               in_admin_location,      /* In the /admin location? */
-               in_conf_location,       /* In the /admin/conf location? */
-               in_root_location;       /* In the / location? */
-    int                remote_printers,        /* Show remote printers */
-               share_printers,         /* Share local printers */
-               remote_admin,           /* Remote administration allowed? */
-               user_cancel_any,        /* Cancel-job policy set? */
-               debug_logging;          /* LogLevel debug set? */
-    int                wrote_port_listen,      /* Wrote the port/listen lines? */
-               wrote_browsing,         /* Wrote the browsing lines? */
-               wrote_policy,           /* Wrote the policy? */
-               wrote_loglevel,         /* Wrote the LogLevel line? */
-               wrote_admin_location,   /* Wrote the /admin location? */
-               wrote_conf_location,    /* Wrote the /admin/conf location? */
-               wrote_root_location;    /* Wrote the / location? */
-    int                indent;                 /* Indentation */
-
-
-   /*
-    * Get form variables...
-    */
-
-    remote_printers = cgiGetVariable("REMOTE_PRINTERS") != NULL;
-    share_printers  = cgiGetVariable("SHARE_PRINTERS") != NULL;
-    remote_admin    = cgiGetVariable("REMOTE_ADMIN") != NULL;
-    user_cancel_any = cgiGetVariable("USER_CANCEL_ANY") != NULL;
-    debug_logging   = cgiGetVariable("DEBUG_LOGGING") != NULL;
-
-   /*
-    * Locate the cupsd.conf file...
-    */
-
-    if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
-      server_root = CUPS_SERVERROOT;
-
-    snprintf(line, sizeof(line), "%s/cupsd.conf", server_root);
-
-   /*
-    * Open the cupsd.conf file...
-    */
-
-    if ((cupsd = cupsFileOpen(line, "r")) == NULL)
+    int                        num_settings;   /* Number of server settings */
+    cups_option_t      *settings;      /* Server settings */
+
+
+    num_settings = 0;
+    num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING,
+                                 cgiGetVariable("DEBUG_LOGGING") ? "1" : "0",
+                                num_settings, &settings);
+    num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN,
+                                 cgiGetVariable("REMOTE_ADMIN") ? "1" : "0",
+                                num_settings, &settings);
+    num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS,
+                                 cgiGetVariable("REMOTE_PRINTERS") ? "1" : "0",
+                                num_settings, &settings);
+    num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS,
+                                 cgiGetVariable("SHARE_PRINTERS") ? "1" : "0",
+                                num_settings, &settings);
+    num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY,
+                                 cgiGetVariable("USER_CANCEL_ANY") ? "1" : "0",
+                                num_settings, &settings);
+
+
+    if (!_cupsAdminSetServerSettings(http, num_settings, settings))
     {
-     /*
-      * Unable to open - log an error...
-      */
-
-      cgiStartHTML(cgiText(_("Change Settings")));
-      cgiSetVariable("MESSAGE", cgiText(_("Unable to change server settings:")));
-      cgiSetVariable("ERROR", strerror(errno));
-      cgiCopyTemplateLang("error.tmpl");
-      cgiEndHTML();
-      
-      perror(line);
-      return;
-    }
-
-   /*
-    * Create a temporary file for the new cupsd.conf file...
-    */
-
-    if ((tempfd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
-    {
-      cgiStartHTML(cgiText(_("Change Settings")));
-      cgiSetVariable("MESSAGE", cgiText(_("Unable to change server settings:")));
-      cgiSetVariable("ERROR", strerror(errno));
-      cgiCopyTemplateLang("error.tmpl");
-      cgiEndHTML();
-      
-      perror(tempfile);
-      cupsFileClose(cupsd);
-      return;
-    }
-
-    if ((temp = cupsFileOpenFd(tempfd, "w")) == NULL)
-    {
-      cgiStartHTML(cgiText(_("Change Settings")));
-      cgiSetVariable("MESSAGE", cgiText(_("Unable to change server settings:")));
-      cgiSetVariable("ERROR", strerror(errno));
-      cgiCopyTemplateLang("error.tmpl");
-      cgiEndHTML();
-      
-      perror(tempfile);
-      close(tempfd);
-      unlink(tempfile);
-      cupsFileClose(cupsd);
-      return;
-    }
-
-   /*
-    * Copy the old file to the new, making changes along the way...
-    */
-
-    in_admin_location    = 0;
-    in_cancel_job        = 0;
-    in_conf_location     = 0;
-    in_policy            = 0;
-    in_root_location     = 0;
-    linenum              = 0;
-    wrote_admin_location = 0;
-    wrote_browsing       = 0;
-    wrote_conf_location  = 0;
-    wrote_loglevel       = 0;
-    wrote_policy         = 0;
-    wrote_port_listen    = 0;
-    wrote_root_location  = 0;
-    indent               = 0;
-
-    while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum))
-    {
-      if (!strcasecmp(line, "Port") || !strcasecmp(line, "Listen"))
-      {
-       if (!wrote_port_listen)
-       {
-          wrote_port_listen = 1;
-
-         if (share_printers || remote_admin)
-         {
-           cupsFilePuts(temp, "# Allow remote access\n");
-           cupsFilePrintf(temp, "Listen *:%d\n", ippPort());
-         }
-         else
-         {
-           cupsFilePuts(temp, "# Only listen for connections from the local machine.\n");
-           cupsFilePrintf(temp, "Listen localhost:%d\n", ippPort());
-         }
-
-#ifdef CUPS_DEFAULT_DOMAINSOCKET
-          cupsFilePuts(temp, "Listen " CUPS_DEFAULT_DOMAINSOCKET "\n");
-#endif /* CUPS_DEFAULT_DOMAINSOCKET */
-       }
-      }
-      else if (!strcasecmp(line, "Browsing") ||
-               !strcasecmp(line, "BrowseAddress") ||
-               !strcasecmp(line, "BrowseAllow") ||
-               !strcasecmp(line, "BrowseDeny") ||
-               !strcasecmp(line, "BrowseOrder"))
-      {
-       if (!wrote_browsing)
-       {
-          wrote_browsing = 1;
-
-          if (remote_printers || share_printers)
-         {
-           if (remote_printers && share_printers)
-             cupsFilePuts(temp, "# Enable printer sharing and shared printers.\n");
-           else if (remote_printers)
-             cupsFilePuts(temp, "# Show shared printers on the local network.\n");
-           else
-             cupsFilePuts(temp, "# Share local printers on the local network.\n");
-
-           cupsFilePuts(temp, "Browsing On\n");
-           cupsFilePuts(temp, "BrowseOrder allow,deny\n");
-
-           if (remote_printers)
-             cupsFilePuts(temp, "BrowseAllow @LOCAL\n");
-
-           if (share_printers)
-             cupsFilePuts(temp, "BrowseAddress @LOCAL\n");
-          }
-         else
-         {
-           cupsFilePuts(temp, "# Disable printer sharing and shared printers.\n");
-           cupsFilePuts(temp, "Browsing Off\n");
-         }
-       }
-      }
-      else if (!strcasecmp(line, "LogLevel"))
-      {
-        wrote_loglevel = 1;
-
-       if (debug_logging)
-       {
-          cupsFilePuts(temp, "# Show troubleshooting information in error_log.\n");
-         cupsFilePuts(temp, "LogLevel debug\n");
-       }
-       else
-       {
-          cupsFilePuts(temp, "# Show general information in error_log.\n");
-         cupsFilePuts(temp, "LogLevel info\n");
-       }
-      }
-      else if (!strcasecmp(line, "<Policy") && !strcasecmp(value, "default"))
-      {
-       in_policy = 1;
-
-       cupsFilePrintf(temp, "%s %s>\n", line, value);
-       indent += 2;
-      }
-      else if (!strcasecmp(line, "</Policy>"))
-      {
-       indent -= 2;
-        if (!wrote_policy)
-       {
-         wrote_policy = 1;
-
-          if (!user_cancel_any)
-           cupsFilePuts(temp, "  # Only the owner or an administrator can cancel a job...\n"
-                              "  <Limit Cancel-Job>\n"
-                              "    Order deny,allow\n"
-                              "    Allow @SYSTEM\n"
-                              "    Allow @OWNER\n"
-                              "  </Limit>\n");
-        }
-
-       in_policy = 0;
-
-       cupsFilePuts(temp, "</Policy>\n");
-      }
-      else if (!strcasecmp(line, "<Location"))
-      {
-       indent += 2;
-        if (!strcmp(value, "/admin"))
-         in_admin_location = 1;
-        if (!strcmp(value, "/admin/conf"))
-         in_conf_location = 1;
-       else if (!strcmp(value, "/"))
-         in_root_location = 1;
-
-       cupsFilePrintf(temp, "%s %s>\n", line, value);
-      }
-      else if (!strcasecmp(line, "</Location>"))
-      {
-       indent -= 2;
-        if (in_admin_location)
-       {
-         wrote_admin_location = 1;
-
-         if (remote_admin)
-            cupsFilePuts(temp, "  # Allow remote administration...\n");
-         else
-            cupsFilePuts(temp, "  # Restrict access to the admin pages...\n");
-
-          cupsFilePuts(temp, "  Order allow,deny\n");
-
-         if (remote_admin)
-           cupsFilePuts(temp, "  Allow @LOCAL\n");
-         else
-           cupsFilePuts(temp, "  Allow localhost\n");
-       }
-        else if (in_conf_location)
-       {
-         wrote_conf_location = 1;
-
-         if (remote_admin)
-            cupsFilePuts(temp, "  # Allow remote access to the configuration files...\n");
-         else
-            cupsFilePuts(temp, "  # Restrict access to the configuration files...\n");
-
-          cupsFilePuts(temp, "  Order allow,deny\n");
-
-         if (remote_admin)
-           cupsFilePuts(temp, "  Allow @LOCAL\n");
-         else
-           cupsFilePuts(temp, "  Allow localhost\n");
-       }
-       else if (in_root_location)
-       {
-         wrote_root_location = 1;
-
-         if (remote_admin && share_printers)
-            cupsFilePuts(temp, "  # Allow shared printing and remote administration...\n");
-         else if (remote_admin)
-            cupsFilePuts(temp, "  # Allow remote administration...\n");
-         else if (share_printers)
-            cupsFilePuts(temp, "  # Allow shared printing...\n");
-         else
-            cupsFilePuts(temp, "  # Restrict access to the server...\n");
-
-          cupsFilePuts(temp, "  Order allow,deny\n");
-
-         if (remote_admin || share_printers)
-           cupsFilePuts(temp, "  Allow @LOCAL\n");
-         else
-           cupsFilePuts(temp, "  Allow localhost\n");
-       }
-
-       in_admin_location = 0;
-       in_conf_location  = 0;
-        in_root_location  = 0;
-
-       cupsFilePuts(temp, "</Location>\n");
-      }
-      else if (!strcasecmp(line, "<Limit") && in_policy)
-      {
-       /*
-       * See if the policy limit is for the Cancel-Job operation...
-       */
-
-       char    *valptr;                /* Pointer into value */
-
-
-       indent += 2;
-
-        if (!strcasecmp(value, "cancel-job"))
-       {
-        /*
-         * Don't write anything for this limit section...
-         */
-
-         in_cancel_job = 2;
-       }
-       else
-       {
-         cupsFilePrintf(temp, "  %s", line);
-
-         while (*value)
-         {
-           for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++);
-
-           if (*valptr)
-             *valptr++ = '\0';
-
-            if (!strcasecmp(value, "cancel-job"))
-           {
-            /*
-             * Write everything except for this definition...
-             */
-
-             in_cancel_job = 1;
-           }
-           else
-             cupsFilePrintf(temp, " %s", value);
-
-            for (value = valptr; isspace(*value & 255); value ++);
-         }
-
-         cupsFilePuts(temp, ">\n");
-        }
-      }
-      else if (!strcasecmp(line, "</Limit>") && in_cancel_job)
-      {
-       indent -= 2;
-
-        if (in_cancel_job == 1)
-          cupsFilePuts(temp, "  </Limit>\n");
-
-        wrote_policy = 1;
-
-        if (!user_cancel_any)
-         cupsFilePuts(temp, "  # Only the owner or an administrator can cancel a job...\n"
-                            "  <Limit Cancel-Job>\n"
-                            "    Order deny,allow\n"
-                            "    Require user @OWNER @SYSTEM\n"
-                            "  </Limit>\n");
-
-       in_cancel_job = 0;
-      }
-      else if ((in_admin_location || in_conf_location || in_root_location) &&
-               (!strcasecmp(line, "Allow") || !strcasecmp(line, "Deny") ||
-               !strcasecmp(line, "Order")))
-       continue;
-      else if (in_cancel_job == 2)
-        continue;
-      else if (!strcasecmp(line, "<Limit")  && value)
-       cupsFilePrintf(temp, "  %s %s>\n", line, value);
-      else if (line[0] == '<')
-      {
-        if (value)
-       {
-          cupsFilePrintf(temp, "%*s%s %s>\n", indent, "", line, value);
-         indent += 2;
-       }
-       else
-       {
-         if (line[1] == '/')
-           indent -= 2;
-
-         cupsFilePrintf(temp, "%*s%s\n", indent, "", line);
-       }
-      }
-      else if (value)
-       cupsFilePrintf(temp, "%*s%s %s\n", indent, "", line, value);
-      else
-       cupsFilePrintf(temp, "%*s%s\n", indent, "", line);
-    }
-
-   /*
-    * Write any missing info...
-    */
-
-    if (!wrote_browsing)
-    {
-      if (remote_printers || share_printers)
-      {
-       if (remote_printers && share_printers)
-         cupsFilePuts(temp, "# Enable printer sharing and shared printers.\n");
-       else if (remote_printers)
-         cupsFilePuts(temp, "# Show shared printers on the local network.\n");
-       else
-         cupsFilePuts(temp, "# Share local printers on the local network.\n");
-
-       cupsFilePuts(temp, "Browsing On\n");
-       cupsFilePuts(temp, "BrowseOrder allow,deny\n");
-
-       if (remote_printers)
-         cupsFilePuts(temp, "BrowseAllow @LOCAL\n");
-
-       if (share_printers)
-         cupsFilePuts(temp, "BrowseAddress @LOCAL\n");
-      }
-      else
-      {
-       cupsFilePuts(temp, "# Disable printer sharing and shared printers.\n");
-       cupsFilePuts(temp, "Browsing Off\n");
-      }
-    }
-
-    if (!wrote_loglevel)
-    {
-      if (debug_logging)
-      {
-        cupsFilePuts(temp, "# Show troubleshooting information in error_log.\n");
-       cupsFilePuts(temp, "LogLevel debug\n");
-      }
-      else
-      {
-        cupsFilePuts(temp, "# Show general information in error_log.\n");
-       cupsFilePuts(temp, "LogLevel info\n");
-      }
-    }
-
-    if (!wrote_port_listen)
-    {
-      if (share_printers || remote_admin)
-      {
-       cupsFilePuts(temp, "# Allow remote access\n");
-       cupsFilePrintf(temp, "Listen *:%d\n", ippPort());
-      }
-      else
-      {
-       cupsFilePuts(temp, "# Only listen for connections from the local machine.\n");
-       cupsFilePrintf(temp, "Listen localhost:%d\n", ippPort());
-      }
-
-#ifdef CUPS_DEFAULT_DOMAINSOCKET
-      cupsFilePuts(temp, "Listen " CUPS_DEFAULT_DOMAINSOCKET "\n");
-#endif /* CUPS_DEFAULT_DOMAINSOCKET */
-    }
-
-    if (!wrote_root_location)
-    {
-      if (remote_admin && share_printers)
-        cupsFilePuts(temp, "# Allow shared printing and remote administration...\n");
-      else if (remote_admin)
-        cupsFilePuts(temp, "# Allow remote administration...\n");
-      else if (share_printers)
-        cupsFilePuts(temp, "# Allow shared printing...\n");
-      else
-        cupsFilePuts(temp, "# Restrict access to the server...\n");
-
-      cupsFilePuts(temp, "<Location />\n"
-                         "  Order allow,deny\n");
-
-      if (remote_admin || share_printers)
-       cupsFilePuts(temp, "  Allow @LOCAL\n");
-      else
-       cupsFilePuts(temp, "  Allow localhost\n");
-
-      cupsFilePuts(temp, "</Location>\n");
-    }
-
-    if (!wrote_admin_location)
-    {
-      if (remote_admin)
-        cupsFilePuts(temp, "# Allow remote administration...\n");
-      else
-        cupsFilePuts(temp, "# Restrict access to the admin pages...\n");
-
-      cupsFilePuts(temp, "<Location /admin>\n"
-                         "  Order allow,deny\n");
-
-      if (remote_admin)
-       cupsFilePuts(temp, "  Allow @LOCAL\n");
-      else
-       cupsFilePuts(temp, "  Allow localhost\n");
-
-      cupsFilePuts(temp, "</Location>\n");
-    }
-
-    if (!wrote_conf_location)
-    {
-      if (remote_admin)
-        cupsFilePuts(temp, "# Allow remote access to the configuration files...\n");
-      else
-        cupsFilePuts(temp, "# Restrict access to the configuration files...\n");
-
-      cupsFilePuts(temp, "<Location /admin/conf>\n"
-                         "  AuthType Basic\n"
-                         "  Require user @SYSTEM\n"
-                         "  Order allow,deny\n");
-
-      if (remote_admin)
-       cupsFilePuts(temp, "  Allow @LOCAL\n");
-      else
-       cupsFilePuts(temp, "  Allow localhost\n");
-
-      cupsFilePuts(temp, "</Location>\n");
-    }
-
-    if (!wrote_policy)
-    {
-      cupsFilePuts(temp, "<Policy default>\n"
-                         "  # Job-related operations must be done by the owner or an adminstrator...\n"
-                         "  <Limit Send-Document Send-URI Hold-Job Release-Job "
-                        "Restart-Job Purge-Jobs Set-Job-Attributes "
-                        "Create-Job-Subscription Renew-Subscription "
-                        "Cancel-Subscription Get-Notifications Reprocess-Job "
-                        "Cancel-Current-Job Suspend-Current-Job Resume-Job "
-                        "CUPS-Move-Job>\n"
-                         "    Require user @OWNER @SYSTEM\n"
-                         "    Order deny,allow\n"
-                         "  </Limit>\n"
-                         "  # All administration operations require an adminstrator to authenticate...\n"
-                        "  <Limit Pause-Printer Resume-Printer "
-                         "Set-Printer-Attributes Enable-Printer "
-                        "Disable-Printer Pause-Printer-After-Current-Job "
-                        "Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer "
-                        "Activate-Printer Restart-Printer Shutdown-Printer "
-                        "Startup-Printer Promote-Job Schedule-Job-After "
-                        "CUPS-Add-Printer CUPS-Delete-Printer "
-                        "CUPS-Add-Class CUPS-Delete-Class "
-                        "CUPS-Accept-Jobs CUPS-Reject-Jobs "
-                        "CUPS-Set-Default CUPS-Add-Device CUPS-Delete-Device>\n"
-                         "    AuthType Basic\n"
-                        "    Require user @SYSTEM\n"
-                         "    Order deny,allow\n"
-                         "</Limit>\n");
-
-      if (!user_cancel_any)
-       cupsFilePuts(temp, "  # Only the owner or an administrator can cancel a job...\n"
-                          "  <Limit Cancel-Job>\n"
-                          "    Require user @OWNER @SYSTEM\n"
-                          "    Order deny,allow\n"
-                          "  </Limit>\n");
-
-      cupsFilePuts(temp, "  <Limit All>\n"
-                         "  Order deny,allow\n"
-                         "  </Limit>\n"
-                        "</Policy>\n");
-    }
-
-    cupsFileClose(cupsd);
-    cupsFileClose(temp);
-
-   /*
-    * Upload the configuration file to the server...
-    */
-
-    status = cupsPutFile(http, "/admin/conf/cupsd.conf", tempfile);
-
-    if (status != HTTP_CREATED)
-    {
-      cgiSetVariable("MESSAGE", cgiText(_("Unable to upload cupsd.conf file:")));
-      cgiSetVariable("ERROR", httpStatus(status));
       cgiStartHTML(cgiText(_("Change Settings")));
+      cgiSetVariable("MESSAGE",
+                     cgiText(_("Unable to change server settings:")));
+      cgiSetVariable("ERROR", cupsLastErrorString());
       cgiCopyTemplateLang("error.tmpl");
     }
     else
     {
       cgiSetVariable("refresh_page", "5;/admin/?OP=redirect");
-
       cgiStartHTML(cgiText(_("Change Settings")));
       cgiCopyTemplateLang("restart.tmpl");
     }
 
-    cgiEndHTML();
+    cupsFreeOptions(num_settings, settings);
 
-    unlink(tempfile);
+    cgiEndHTML();
   }
   else if (cgiIsPOST())
   {
@@ -2187,7 +1699,8 @@ do_config_server(http_t *http)            /* I - HTTP connection */
 
     if (status != HTTP_CREATED)
     {
-      cgiSetVariable("MESSAGE", cgiText(_("Unable to upload cupsd.conf file:")));
+      cgiSetVariable("MESSAGE",
+                     cgiText(_("Unable to upload cupsd.conf file:")));
       cgiSetVariable("ERROR", httpStatus(status));
 
       cgiStartHTML(cgiText(_("Edit Configuration File")));
@@ -2230,7 +1743,8 @@ do_config_server(http_t *http)            /* I - HTTP connection */
     if (stat(filename, &info))
     {
       cgiStartHTML(cgiText(_("Edit Configuration File")));
-      cgiSetVariable("MESSAGE", cgiText(_("Unable to access cupsd.conf file:")));
+      cgiSetVariable("MESSAGE",
+                     cgiText(_("Unable to access cupsd.conf file:")));
       cgiSetVariable("ERROR", strerror(errno));
       cgiCopyTemplateLang("error.tmpl");
       cgiEndHTML();
@@ -2242,7 +1756,8 @@ do_config_server(http_t *http)            /* I - HTTP connection */
     if (info.st_size > (1024 * 1024))
     {
       cgiStartHTML(cgiText(_("Edit Configuration File")));
-      cgiSetVariable("MESSAGE", cgiText(_("Unable to access cupsd.conf file:")));
+      cgiSetVariable("MESSAGE",
+                     cgiText(_("Unable to access cupsd.conf file:")));
       cgiSetVariable("ERROR",
                      cgiText(_("Unable to edit cupsd.conf files larger than "
                               "1MB!")));
@@ -2265,7 +1780,8 @@ do_config_server(http_t *http)            /* I - HTTP connection */
       */
 
       cgiStartHTML(cgiText(_("Edit Configuration File")));
-      cgiSetVariable("MESSAGE", cgiText(_("Unable to access cupsd.conf file:")));
+      cgiSetVariable("MESSAGE",
+                     cgiText(_("Unable to access cupsd.conf file:")));
       cgiSetVariable("ERROR", strerror(errno));
       cgiCopyTemplateLang("error.tmpl");
       cgiEndHTML();
@@ -2323,8 +1839,8 @@ do_delete_class(http_t *http)             /* I - HTTP connection */
   }
 
   if ((pclass = cgiGetVariable("PRINTER_NAME")) != NULL)
-    httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                     "/classes/%s", pclass);
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                     "localhost", 0, "/classes/%s", pclass);
   else
   {
     cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
@@ -2384,8 +1900,8 @@ do_delete_printer(http_t *http)           /* I - HTTP connection */
   }
 
   if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
-    httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                     "/printers/%s", printer);
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                     "localhost", 0, "/printers/%s", printer);
   else
   {
     cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
@@ -2438,14 +1954,11 @@ do_export(http_t *http)                 /* I - HTTP connection */
                *export_all;            /* Export all printers? */
   int          export_count,           /* Number of printers to export */
                printer_count;          /* Number of available printers */
+  const char   *name,                  /* What name to pull */
+               *dest;                  /* Current destination */
+  char         ppd[1024];              /* PPD file */
 
 
- /*
-  * Show header...
-  */
-
-  cgiStartHTML(cgiText(_("Export Printers to Samba")));
-
  /*
   * Get form data...
   */
@@ -2455,163 +1968,6 @@ do_export(http_t *http)                 /* I - HTTP connection */
   export_all   = cgiGetVariable("EXPORT_ALL");
   export_count = cgiGetSize("EXPORT_NAME");
 
-  if (username && *username && password && *password && export_count <= 1000)
-  {
-   /*
-    * Do export...
-    */
-
-    char       userpass[1024],         /* Username%password */
-               *argv[1005];            /* Arguments */
-    int                argc;                   /* Number of arguments */
-    int                pid;                    /* Process ID of child */
-    int                status;                 /* Status of command */
-
-
-    fputs("DEBUG: Export printers...\n", stderr);
-
-   /*
-    * Create the command-line for cupsaddsmb...
-    */
-
-    snprintf(userpass, sizeof(userpass), "%s%%%s", username, password);
-
-    argv[0] = "cupsaddsmb";
-    argv[1] = "-v";
-    argv[2] = "-U";
-    argv[3] = userpass;
-    argc    = 4;
-
-    if (export_all)
-      argv[argc ++] = "-a";
-    else
-    {
-      for (i = 0; i < export_count; i ++)
-        argv[argc ++] = (char *)cgiGetArray("EXPORT_NAME", i);
-    }
-
-    argv[argc] = NULL; 
-
-   /*
-    * Run the command...
-    */
-
-    if ((pid = fork()) == 0)
-    {
-     /*
-      * Child goes here...
-      */
-
-      close(0);
-      open("/dev/null", O_RDONLY);
-      close(1);
-      dup(2);
-
-      execvp("cupsaddsmb", argv);
-      perror("ERROR: Unable to execute cupsaddsmb");
-      exit(20);
-    }
-    else if (pid < 0)
-      cgiSetVariable("ERROR", cgiText(_("Unable to fork process!")));
-    else
-    {
-     /*
-      * Parent goes here, wait for child to finish...
-      */
-
-      while (wait(&status) < 0);
-
-      if (status)
-      {
-        char   message[1024];          /* Error message */
-
-
-       if (WIFEXITED(status))
-       {
-         switch (WEXITSTATUS(status))
-         {
-           case 1 :
-               cgiSetVariable("ERROR", cgiText(_("Unable to connect to server!")));
-                break;
-
-           case 2 :
-               cgiSetVariable("ERROR", cgiText(_("Unable to get printer "
-                                                 "attributes!")));
-                break;
-
-           case 3 :
-               cgiSetVariable("ERROR", cgiText(_("Unable to convert PPD file!")));
-                break;
-
-           case 4 :
-               cgiSetVariable("ERROR", cgiText(_("Unable to copy Windows 2000 "
-                                                 "printer driver files!")));
-                break;
-
-           case 5 :
-               cgiSetVariable("ERROR", cgiText(_("Unable to install Windows "
-                                                 "2000 printer driver files!")));
-                break;
-
-           case 6 :
-               cgiSetVariable("ERROR", cgiText(_("Unable to copy Windows 9x "
-                                                 "printer driver files!")));
-                break;
-
-           case 7 :
-               cgiSetVariable("ERROR", cgiText(_("Unable to install Windows "
-                                                 "9x printer driver files!")));
-                break;
-
-           case 8 :
-               cgiSetVariable("ERROR", cgiText(_("Unable to set Windows "
-                                                 "printer driver!")));
-                break;
-
-           case 9 :
-               cgiSetVariable("ERROR", cgiText(_("No printer drivers found!")));
-                break;
-
-           case 20 :
-               cgiSetVariable("ERROR", cgiText(_("Unable to execute "
-                                                 "cupsaddsmb command!")));
-                break;
-
-           default :
-               snprintf(message, sizeof(message),
-                         cgiText(_("cupsaddsmb failed with status %d")),
-                        WEXITSTATUS(status));
-
-                cgiSetVariable("ERROR", message);
-               break;
-          }
-       }
-        else
-       {
-          snprintf(message, sizeof(message),
-                   cgiText(_("cupsaddsmb crashed on signal %d")),
-                  WTERMSIG(status));
-
-          cgiSetVariable("ERROR", message);
-       }
-      }
-      else
-      {
-        cgiCopyTemplateLang("samba-exported");
-       cgiEndHTML();
-       return;
-      }
-    }
-  }
-  else if (username && !*username)
-    cgiSetVariable("ERROR",
-                   cgiText(_("A Samba username is required to export "
-                            "printer drivers!")));
-  else if (username && (!password || !*password))
-    cgiSetVariable("ERROR",
-                   cgiText(_("A Samba password is required to export "
-                            "printer drivers!")));
-
  /*
   * Get list of available printers...
   */
@@ -2642,9 +1998,10 @@ do_export(http_t *http)                  /* I - HTTP connection */
 
       for (i = 0; i < printer_count; i ++)
       {
+        dest = cgiGetArray("PRINTER_NAME", i);
+
         for (j = 0; j < export_count; j ++)
-         if (!strcasecmp(cgiGetArray("PRINTER_NAME", i),
-                         cgiGetArray("EXPORT_NAME", j)))
+         if (!strcasecmp(dest, cgiGetArray("EXPORT_NAME", j)))
             break;
 
         cgiSetArray("PRINTER_EXPORT", i, j < export_count ? "Y" : "");
@@ -2652,10 +2009,67 @@ do_export(http_t *http)                 /* I - HTTP connection */
     }
   }
 
+ /*
+  * Export or get the printers to export...
+  */
+
+  if (username && *username && password && *password &&
+      (export_all || export_count > 0))
+  {
+   /*
+    * Do export...
+    */
+
+    fputs("DEBUG: Export printers...\n", stderr);
+
+    if (export_all)
+    {
+      name         = "PRINTER_NAME";
+      export_count = cgiGetSize("PRINTER_NAME");
+    }
+    else
+      name = "EXPORT_NAME";
+
+    for (i = 0; i < export_count; i ++)
+    {
+      dest = cgiGetArray(name, i);
+
+      if (!cupsAdminCreateWindowsPPD(http, dest, ppd, sizeof(ppd)))
+        break;
+
+      j = cupsAdminExportSamba(dest, ppd, "localhost", username, password,
+                               stderr);
+
+      unlink(ppd);
+
+      if (!j)
+        break;
+    }
+
+    if (i < export_count)
+      cgiSetVariable("ERROR", cupsLastErrorString());
+    else
+    {
+      cgiStartHTML(cgiText(_("Export Printers to Samba")));
+      cgiCopyTemplateLang("samba-exported.tmpl");
+      cgiEndHTML();
+      return;
+    }
+  }
+  else if (username && !*username)
+    cgiSetVariable("ERROR",
+                   cgiText(_("A Samba username is required to export "
+                            "printer drivers!")));
+  else if (username && (!password || !*password))
+    cgiSetVariable("ERROR",
+                   cgiText(_("A Samba password is required to export "
+                            "printer drivers!")));
+
  /*
   * Show form...
   */
 
+  cgiStartHTML(cgiText(_("Export Printers to Samba")));
   cgiCopyTemplateLang("samba-export.tmpl");
   cgiEndHTML();
 }
@@ -2668,10 +2082,10 @@ do_export(http_t *http)                 /* I - HTTP connection */
 static void
 do_menu(http_t *http)                  /* I - HTTP connection */
 {
-  cups_file_t  *cupsd;                 /* cupsd.conf file */
-  char         line[1024],             /* Line from cupsd.conf file */
-               *value;                 /* Value on line */
-  const char   *server_root;           /* Location of config files */
+  int          num_settings;           /* Number of server settings */
+  cups_option_t        *settings;              /* Server settings */
+  const char   *val;                   /* Setting value */
+  char         filename[1024];         /* Temporary filename */
   const char   *datadir;               /* Location of data files */
   ipp_t                *request,               /* IPP request */
                *response;              /* IPP response */
@@ -2679,165 +2093,37 @@ do_menu(http_t *http)                  /* I - HTTP connection */
 
 
  /*
-  * Locate the cupsd.conf file...
+  * Get the current server settings...
   */
 
-  if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
-    server_root = CUPS_SERVERROOT;
-
-  snprintf(line, sizeof(line), "%s/cupsd.conf", server_root);
-
-  cgiStartHTML(cgiText(_("Administration")));
-
-  printf("<!-- \"%s\" -->\n", line);
-
- /*
-  * Open the cupsd.conf file...
-  */
-
-  if ((cupsd = cupsFileOpen(line, "r")) == NULL)
+  if (!_cupsAdminGetServerSettings(http, &num_settings, &settings))
   {
-   /*
-    * Unable to open - log an error...
-    */
-
-    cgiSetVariable("MESSAGE", cgiText(_("Unable to open cupsd.conf file:")));
-    cgiSetVariable("ERROR", strerror(errno));
-    cgiCopyTemplateLang("error.tmpl");
-    cgiEndHTML();
-
-    perror(line);
+    cgiSetVariable("SETTINGS_MESSAGE",
+                   cgiText(_("Unable to open cupsd.conf file:")));
+    cgiSetVariable("SETTINGS_ERROR", cupsLastErrorString());
   }
-  else
-  {
-   /*
-    * Read the file, keeping track of what settings are enabled...
-    */
 
-    int                remote_access = 0,      /* Remote access allowed? */
-               remote_admin = 0,       /* Remote administration allowed? */
-               browsing = 1,           /* Browsing enabled? */
-               browse_allow = 1,       /* Browse address set? */
-               browse_address = 0,     /* Browse address set? */
-               cancel_policy = 1,      /* Cancel-job policy set? */
-               debug_logging = 0;      /* LogLevel debug set? */
-    int                linenum = 0,            /* Line number in file */
-               in_policy = 0,          /* In a policy section? */
-               in_cancel_job = 0,      /* In a cancel-job section? */
-               in_admin_location = 0;  /* In the /admin location? */
+  if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, num_settings,
+                           settings)) != NULL && atoi(val))
+    cgiSetVariable("DEBUG_LOGGING", "CHECKED");
 
+  if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings,
+                           settings)) != NULL && atoi(val))
+    cgiSetVariable("REMOTE_ADMIN", "CHECKED");
 
-    while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum))
-    {
-      if (!strcasecmp(line, "Port"))
-      {
-        remote_access = 1;
-      }
-      else if (!strcasecmp(line, "Listen"))
-      {
-        char   *port;                  /* Pointer to port number, if any */
-
-
-       if ((port = strrchr(value, ':')) != NULL)
-         *port = '\0';
-
-        if (strcasecmp(value, "localhost") && strcmp(value, "127.0.0.1"))
-         remote_access = 1;
-      }
-      else if (!strcasecmp(line, "Browsing"))
-      {
-        browsing = !strcasecmp(value, "yes") || !strcasecmp(value, "on") ||
-                  !strcasecmp(value, "true");
-      }
-      else if (!strcasecmp(line, "BrowseAddress"))
-      {
-        browse_address = 1;
-      }
-      else if (!strcasecmp(line, "BrowseAllow"))
-      {
-        browse_allow = 1;
-      }
-      else if (!strcasecmp(line, "BrowseOrder"))
-      {
-        browse_allow = !strncasecmp(value, "deny,", 5);
-      }
-      else if (!strcasecmp(line, "LogLevel"))
-      {
-        debug_logging = !strncasecmp(value, "debug", 5);
-      }
-      else if (!strcasecmp(line, "<Policy") && !strcasecmp(value, "default"))
-      {
-        in_policy = 1;
-      }
-      else if (!strcasecmp(line, "</Policy>"))
-      {
-        in_policy = 0;
-      }
-      else if (!strcasecmp(line, "<Limit") && in_policy)
-      {
-       /*
-        * See if the policy limit is for the Cancel-Job operation...
-       */
+  if ((val = cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS, num_settings,
+                           settings)) != NULL && atoi(val))
+    cgiSetVariable("REMOTE_PRINTERS", "CHECKED");
 
-        char   *valptr;                /* Pointer into value */
+  if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, num_settings,
+                           settings)) != NULL && atoi(val))
+    cgiSetVariable("SHARE_PRINTERS", "CHECKED");
 
+  if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, num_settings,
+                           settings)) != NULL && atoi(val))
+    cgiSetVariable("USER_CANCEL_ANY", "CHECKED");
 
-        while (*value)
-       {
-         for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++);
-
-         if (*valptr)
-           *valptr++ = '\0';
-
-          if (!strcasecmp(value, "cancel-job") || !strcasecmp(value, "all"))
-         {
-           in_cancel_job = 1;
-           break;
-         }
-
-          for (value = valptr; isspace(*value & 255); value ++);
-        }
-      }
-      else if (!strcasecmp(line, "</Limit>"))
-      {
-        in_cancel_job = 0;
-      }
-      else if (!strcasecmp(line, "Require") && in_cancel_job)
-      {
-        cancel_policy = 0;
-      }
-      else if (!strcasecmp(line, "<Location") && !strcasecmp(value, "/admin"))
-      {
-        in_admin_location = 1;
-      }
-      else if (!strcasecmp(line, "</Location>"))
-      {
-        in_admin_location = 0;
-      }
-      else if (!strcasecmp(line, "Allow") && in_admin_location &&
-               strcasecmp(value, "localhost") && strcasecmp(value, "127.0.0.1"))
-      {
-        remote_admin = 1;
-      }
-    }
-
-    cupsFileClose(cupsd);
-
-    if (browsing && browse_allow)
-      cgiSetVariable("REMOTE_PRINTERS", "CHECKED");
-
-    if (remote_access && browsing && browse_address)
-      cgiSetVariable("SHARE_PRINTERS", "CHECKED");
-
-    if (remote_access && remote_admin)
-      cgiSetVariable("REMOTE_ADMIN", "CHECKED");
-
-    if (cancel_policy)
-      cgiSetVariable("USER_CANCEL_ANY", "CHECKED");
-
-    if (debug_logging)
-      cgiSetVariable("DEBUG_LOGGING", "CHECKED");
-  }
+  cupsFreeOptions(num_settings, settings);
 
  /*
   * Get the list of printers and their devices...
@@ -2978,7 +2264,8 @@ do_menu(http_t *http)                     /* I - HTTP connection */
            for (;
                 options_ptr < (options + sizeof(options) - 1) && *ptr;
                 ptr ++)
-             if (isalnum(*ptr & 255) || *ptr == '_' || *ptr == '-' || *ptr == '.')
+             if (isalnum(*ptr & 255) || *ptr == '_' || *ptr == '-' ||
+                 *ptr == '.')
                *options_ptr++ = *ptr;
              else if ((*ptr == ' ' || *ptr == '/') && options_ptr[-1] != '_')
                *options_ptr++ = '_';
@@ -3056,33 +2343,39 @@ do_menu(http_t *http)                   /* I - HTTP connection */
   if ((datadir = getenv("CUPS_DATADIR")) == NULL)
     datadir = CUPS_DATADIR;
 
-  snprintf(line, sizeof(line), "%s/drivers/pscript5.dll", datadir);
-  if (!access(line, 0))
+  snprintf(filename, sizeof(filename), "%s/drivers/pscript5.dll", datadir);
+  if (!access(filename, R_OK))
   {
    /*
     * Found Windows 2000 driver file, see if we have smbclient and
     * rpcclient...
     */
 
-    if (cupsFileFind("smbclient", getenv("PATH"), line, sizeof(line)) &&
-        cupsFileFind("rpcclient", getenv("PATH"), line, sizeof(line)))
+    if (cupsFileFind("smbclient", getenv("PATH"), 1, filename,
+                     sizeof(filename)) &&
+        cupsFileFind("rpcclient", getenv("PATH"), 1, filename,
+                    sizeof(filename)))
       cgiSetVariable("HAVE_SAMBA", "Y");
     else
     {
-      if (!cupsFileFind("smbclient", getenv("PATH"), line, sizeof(line)))
+      if (!cupsFileFind("smbclient", getenv("PATH"), 1, filename,
+                        sizeof(filename)))
         fputs("ERROR: smbclient not found!\n", stderr);
 
-      if (!cupsFileFind("rpcclient", getenv("PATH"), line, sizeof(line)))
+      if (!cupsFileFind("rpcclient", getenv("PATH"), 1, filename,
+                        sizeof(filename)))
         fputs("ERROR: rpcclient not found!\n", stderr);
     }
   }
   else
-    perror(line);
+    perror(filename);
 
  /*
   * Finally, show the main menu template...
   */
 
+  cgiStartHTML(cgiText(_("Administration")));
+
   cgiCopyTemplateLang("admin.tmpl");
 
   cgiEndHTML();
@@ -3127,8 +2420,9 @@ do_printer_op(http_t      *http,  /* I - HTTP connection */
 
   request = ippNewRequest(op);
 
-  httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                   is_class ? "/classes/%s" : "/printers/%s", printer);
+  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                   "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
+                  printer);
   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                NULL, uri);
 
@@ -3236,8 +2530,9 @@ do_set_allowed_users(http_t *http)        /* I - HTTP connection */
 
     request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
 
-    httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                     is_class ? "/classes/%s" : "/printers/%s", printer);
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                     "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
+                    printer);
     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                 NULL, uri);
 
@@ -3322,17 +2617,18 @@ do_set_allowed_users(http_t *http)      /* I - HTTP connection */
 
     request = ippNewRequest(is_class ? CUPS_ADD_CLASS : CUPS_ADD_PRINTER);
 
-    httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                     is_class ? "/classes/%s" : "/printers/%s", printer);
+    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                     "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
+                    printer);
     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                 NULL, uri);
 
     if (num_users == 0)
-      ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+      ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
                    "requesting-user-name-allowed", NULL, "all");
     else
     {
-      attr = ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+      attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
                            type, num_users, NULL, NULL);
 
       for (i = 0, ptr = (char *)users; *ptr; i ++)
@@ -3465,8 +2761,9 @@ do_set_sharing(http_t *http)              /* I - HTTP connection */
 
   request = ippNewRequest(is_class ? CUPS_ADD_CLASS : CUPS_ADD_PRINTER);
 
-  httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
-                   is_class ? "/classes/%s" : "/printers/%s", printer);
+  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+                   "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
+                  printer);
   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                NULL, uri);
 
@@ -3562,5 +2859,5 @@ match_string(const char *a,               /* I - First string */
 
     
 /*
- * End of "$Id: admin.c 4943 2006-01-18 20:30:42Z mike $".
+ * End of "$Id: admin.c 5290 2006-03-14 21:43:57Z mike $".
  */