]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/adminutil.c
Merge changes from CUPS 1.4svn-r7696.
[thirdparty/cups.git] / cups / adminutil.c
index 2bd6caf5fc389e2babe9a6a72d6dd1a4150d2759..95393afd060b98a1682c962ba4e4cb14b6f7c42d 100644 (file)
@@ -1,26 +1,17 @@
 /*
- * "$Id: adminutil.c 6378 2007-03-21 07:18:18Z mike $"
+ * "$Id: adminutil.c 7576 2008-05-15 21:05:14Z mike $"
  *
  *   Administration utility API definitions for the Common UNIX Printing
  *   System (CUPS).
  *
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 2001-2007 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/".
  *
  *   This file is subject to the Apple OS-Developed Software exception.
  *
@@ -88,7 +79,7 @@ static void           write_option(cups_file_t *dstfp, int order,
 
 char *                                 /* O - PPD file or NULL */
 cupsAdminCreateWindowsPPD(
-    http_t     *http,                  /* I - Connection to server */
+    http_t     *http,                  /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
     const char *dest,                  /* I - Printer or class */
     char       *buffer,                        /* I - Filename buffer */
     int        bufsize)                        /* I - Size of filename buffer */
@@ -108,6 +99,7 @@ cupsAdminCreateWindowsPPD(
                        option[41],     /* Option */
                        choice[41];     /* Choice */
   int                  jcloption,      /* In a JCL option? */
+                       jclorder,       /* Next JCL order dependency */
                        linenum;        /* Current line number */
   time_t               curtime;        /* Current time */
   struct tm            *curdate;       /* Current date */
@@ -129,6 +121,9 @@ cupsAdminCreateWindowsPPD(
   if (buffer)
     *buffer = '\0';
 
+  if (!http)
+    http = _cupsConnect();
+
   if (!http || !dest || !buffer || bufsize < 2)
     return (NULL);
 
@@ -205,6 +200,7 @@ cupsAdminCreateWindowsPPD(
   */
 
   jcloption = 0;
+  jclorder  = 0;
   linenum   = 0;
   language  = cupsLangDefault();
 
@@ -243,10 +239,23 @@ cupsAdminCreateWindowsPPD(
       jcloption = 0;
       cupsFilePrintf(dstfp, "%s\n", line);
     }
+    else if (jcloption && !strncmp(line, "*OrderDependency:", 17))
+    {
+      for (ptr = line + 17; *ptr && isspace(*ptr & 255); ptr ++);
+
+      ptr = strchr(ptr, ' ');
+
+      if (ptr)
+      {
+       cupsFilePrintf(dstfp, "*OrderDependency: %d%s\n", jclorder, ptr);
+       jclorder ++;
+      }
+      else
+        cupsFilePrintf(dstfp, "%s\n", line);
+    }
     else if (jcloption &&
              strncmp(line, "*End", 4) &&
-             strncmp(line, "*Default", 8) &&
-             strncmp(line, "*OrderDependency", 16))
+             strncmp(line, "*Default", 8))
     {
       if ((ptr = strchr(line, ':')) == NULL)
       {
@@ -285,7 +294,7 @@ cupsAdminCreateWindowsPPD(
        return (NULL);
       }
 
-      if (sscanf(line, "*%40s%*[ \t]%40[^/]", option, choice) != 2)
+      if (sscanf(line, "*%40s%*[ \t]%40[^:/]", option, choice) != 2)
       {
         snprintf(line, sizeof(line),
                 _cupsLangString(language,
@@ -363,24 +372,24 @@ cupsAdminCreateWindowsPPD(
                                   IPP_TAG_ZERO)) != NULL &&
       (suppattr = ippFindAttribute(response, "job-hold-until-supported",
                                    IPP_TAG_ZERO)) != NULL)
-    write_option(dstfp, 10, "cupsJobHoldUntil", "Hold Until", "job-hold-until",
-                 suppattr, defattr, 0, 1);
+    write_option(dstfp, jclorder ++, "cupsJobHoldUntil", "Hold Until",
+                 "job-hold-until", suppattr, defattr, 0, 1);
 
   if ((defattr = ippFindAttribute(response, "job-priority-default",
                                   IPP_TAG_INTEGER)) != NULL &&
       (suppattr = ippFindAttribute(response, "job-priority-supported",
                                    IPP_TAG_RANGE)) != NULL)
-    write_option(dstfp, 11, "cupsJobPriority", "Priority", "job-priority",
-                 suppattr, defattr, 0, 1);
+    write_option(dstfp, jclorder ++, "cupsJobPriority", "Priority",
+                 "job-priority", suppattr, defattr, 0, 1);
 
   if ((defattr = ippFindAttribute(response, "job-sheets-default",
                                   IPP_TAG_ZERO)) != NULL &&
       (suppattr = ippFindAttribute(response, "job-sheets-supported",
                                    IPP_TAG_ZERO)) != NULL)
   {
-    write_option(dstfp, 20, "cupsJobSheetsStart", "Start Banner",
+    write_option(dstfp, jclorder ++, "cupsJobSheetsStart", "Start Banner",
                  "job-sheets", suppattr, defattr, 0, 2);
-    write_option(dstfp, 21, "cupsJobSheetsEnd", "End Banner",
+    write_option(dstfp, jclorder ++, "cupsJobSheetsEnd", "End Banner",
                  "job-sheets", suppattr, defattr, 1, 2);
   }
 
@@ -577,6 +586,10 @@ cupsAdminExportSamba(
     }
   }
 
+ /*
+  * See if we have the Win9x PS driver...
+  */
+
   snprintf(file, sizeof(file), "%s/drivers/ADOBEPS4.DRV", cg->cups_datadir);
   if (!access(file, 0))
   {
@@ -647,6 +660,136 @@ cupsAdminExportSamba(
     }
   }
 
+ /*
+  * See if we have the 64-bit Windows PS driver...
+  *
+  * Files:
+  *
+  *     x64/ps5ui.dll
+  *     x64/pscript.hlp
+  *     x64/pscript.ntf
+  *     x64/pscript5.dll
+  */
+
+  snprintf(file, sizeof(file), "%s/drivers/x64/pscript5.dll", cg->cups_datadir);
+  if (!access(file, 0))
+  {
+    have_drivers |= 4;
+
+   /*
+    * 64-bit Windows driver is installed; do the smbclient commands needed
+    * to copy the Win64 drivers over...
+    */
+
+    snprintf(address, sizeof(address), "//%s/print$", samba_server);
+
+    snprintf(subcmd, sizeof(subcmd),
+             "mkdir x64;"
+            "put %s x64/%s.ppd;"
+            "put %s/drivers/x64/ps5ui.dll x64/ps5ui.dll;"
+            "put %s/drivers/x64/pscript.hlp x64/pscript.hlp;"
+            "put %s/drivers/x64/pscript.ntf x64/pscript.ntf;"
+            "put %s/drivers/x64/pscript5.dll x64/pscript5.dll",
+            ppd, dest, cg->cups_datadir, cg->cups_datadir,
+            cg->cups_datadir, cg->cups_datadir);
+
+    if ((status = do_samba_command("smbclient", address, subcmd,
+                                   authfile, logfile)) != 0)
+    {
+      snprintf(message, sizeof(message),
+               _cupsLangString(language,
+                              _("Unable to copy 64-bit Windows printer "
+                                "driver files (%d)!")), status);
+
+      _cupsSetError(IPP_INTERNAL_ERROR, message);
+
+      if (logfile)
+       _cupsLangPrintf(logfile, "%s\n", message);
+
+      unlink(authfile);
+
+      return (0);
+    }
+
+   /*
+    * See if we also have the CUPS driver files; if so, use them!
+    */
+
+    snprintf(file, sizeof(file), "%s/drivers/x64/cupsps6.dll", cg->cups_datadir);
+    if (!access(file, 0))
+    {
+     /*
+      * Copy the CUPS driver files over...
+      */
+
+      snprintf(subcmd, sizeof(subcmd),
+               "put %s/drivers/x64/cups6.ini x64/cups6.ini;"
+               "put %s/drivers/x64/cupsps6.dll x64/cupsps6.dll;"
+              "put %s/drivers/x64/cupsui6.dll x64/cupsui6.dll",
+              cg->cups_datadir, cg->cups_datadir, cg->cups_datadir);
+
+      if ((status = do_samba_command("smbclient", address, subcmd,
+                                     authfile, logfile)) != 0)
+      {
+       snprintf(message, sizeof(message),
+                _cupsLangString(language,
+                                _("Unable to copy 64-bit CUPS printer driver "
+                                  "files (%d)!")), status);
+
+       _cupsSetError(IPP_INTERNAL_ERROR, message);
+
+       if (logfile)
+         _cupsLangPrintf(logfile, "%s\n", message);
+
+        unlink(authfile);
+
+       return (0);
+      }
+      
+     /*
+      * Do the rpcclient command needed for the CUPS drivers...
+      */
+
+      snprintf(subcmd, sizeof(subcmd),
+               "adddriver \"Windows x64\" \"%s:"
+              "pscript5.dll:%s.ppd:ps5ui.dll:pscript.hlp:NULL:RAW:"
+              "pscript5.dll,%s.ppd,ps5ui.dll,pscript.hlp,pscript.ntf,"
+              "cups6.ini,cupsps6.dll,cupsui6.dll\"",
+              dest, dest, dest);
+    }
+    else
+    {
+     /*
+      * Don't have the CUPS drivers, so just use the standard Windows
+      * drivers...
+      */
+
+      snprintf(subcmd, sizeof(subcmd),
+               "adddriver \"Windows x64\" \"%s:"
+              "pscript5.dll:%s.ppd:ps5ui.dll:pscript.hlp:NULL:RAW:"
+              "pscript5.dll,%s.ppd,ps5ui.dll,pscript.hlp,pscript.ntf\"",
+              dest, dest, dest);
+    }
+
+    if ((status = do_samba_command("rpcclient", samba_server, subcmd,
+                                   authfile, logfile)) != 0)
+    {
+      snprintf(message, sizeof(message),
+               _cupsLangString(language,
+                              _("Unable to install Windows 2000 printer "
+                                "driver files (%d)!")), status);
+
+      _cupsSetError(IPP_INTERNAL_ERROR, message);
+
+      if (logfile)
+       _cupsLangPrintf(logfile, "%s\n", message);
+
+      unlink(authfile);
+
+      return (0);
+    }
+  }
+
   if (logfile && !(have_drivers & 1))
   {
     if (!have_drivers)
@@ -661,12 +804,18 @@ cupsAdminExportSamba(
                                "are installed!")),
               sizeof(message));
 
-    _cupsSetError(IPP_INTERNAL_ERROR, message);
+    _cupsSetError(IPP_NOT_FOUND, message);
     _cupsLangPrintf(logfile, "%s\n", message);
   }
 
   if (have_drivers == 0)
+  {
+    _cupsSetError(IPP_NOT_FOUND, message);
+
+    unlink(authfile);
+
     return (0);
+  }
 
  /*
   * Finally, associate the drivers we just added with the queue...
@@ -709,7 +858,7 @@ cupsAdminExportSamba(
 
 int                                    /* O - 1 on success, 0 on failure */
 cupsAdminGetServerSettings(
-    http_t        *http,               /* I - Connection to server */
+    http_t        *http,               /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
     int           *num_settings,       /* O - Number of settings */
     cups_option_t **settings)          /* O - Settings */
 {
@@ -728,7 +877,7 @@ cupsAdminGetServerSettings(
 
 int                                    /* O - 1 on success, 0 on failure */
 _cupsAdminGetServerSettings(
-    http_t        *http,               /* I - Connection to server */
+    http_t        *http,               /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
     int           *num_settings,       /* O - Number of settings */
     cups_option_t **settings)          /* O - Settings */
 {
@@ -747,6 +896,9 @@ _cupsAdminGetServerSettings(
   * Range check input...
   */
 
+  if (!http)
+    http = _cupsConnect();
+
   if (!http || !num_settings || !settings)
   {
     _cupsSetError(IPP_INTERNAL_ERROR, NULL);
@@ -812,8 +964,8 @@ _cupsAdminGetServerSettings(
 
     while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum))
     {
-      if (!value)
-        continue;
+      if (!value && strncmp(line, "</", 2))
+        value = line + strlen(line);
 
       if (!strcasecmp(line, "Port") || !strcasecmp(line, "Listen"))
       {
@@ -914,7 +1066,7 @@ _cupsAdminGetServerSettings(
        in_admin_location = 0;
        in_location       = 0;
       }
-      else if (!strcasecmp(line, "Allow") && in_admin_location &&
+      else if (!strcasecmp(line, "Allow") &&
                strcasecmp(value, "localhost") && strcasecmp(value, "127.0.0.1")
 #ifdef AF_LOCAL
               && *value != '/'
@@ -924,9 +1076,9 @@ _cupsAdminGetServerSettings(
 #endif /* AF_INET6 */
               )
       {
-       remote_admin = 1;
-
-       if (!strcasecmp(value, "all"))
+        if (in_admin_location)
+         remote_admin = 1;
+        else if (!strcasecmp(value, "all"))
          remote_any = 1;
       }
       else if (line[0] != '<' && !in_location && !in_policy)
@@ -998,7 +1150,7 @@ _cupsAdminGetServerSettings(
 
 int                                    /* O - 1 on success, 0 on failure */
 cupsAdminSetServerSettings(
-    http_t        *http,               /* I - Connection to server */
+    http_t        *http,               /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
     int           num_settings,                /* I - Number of settings */
     cups_option_t *settings)           /* I - Settings */
 {
@@ -1014,7 +1166,7 @@ cupsAdminSetServerSettings(
 
 int                                    /* O - 1 on success, 0 on failure */
 _cupsAdminSetServerSettings(
-    http_t        *http,               /* I - Connection to server */
+    http_t        *http,               /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
     int           num_settings,                /* I - Number of settings */
     cups_option_t *settings)           /* I - Settings */
 {
@@ -1067,6 +1219,9 @@ _cupsAdminSetServerSettings(
   * Range check input...
   */
 
+  if (!http)
+    http = _cupsConnect();
+
   if (!http || !num_settings || !settings)
   {
     _cupsSetError(IPP_INTERNAL_ERROR, NULL);
@@ -1315,19 +1470,41 @@ _cupsAdminSetServerSettings(
               !strcasecmp(line, "BrowseAddress") ||
               !strcasecmp(line, "BrowseAllow") ||
               !strcasecmp(line, "BrowseDeny") ||
+              !strcasecmp(line, "BrowseLocalProtocols") ||
+              !strcasecmp(line, "BrowseRemoteProtocols") ||
               !strcasecmp(line, "BrowseOrder")) &&
             (remote_printers >= 0 || share_printers >= 0))
     {
       if (!wrote_browsing)
       {
+       int new_remote_printers = (remote_printers > 0 ||
+                                  (remote_printers == -1 &&
+                                   old_remote_printers > 0));
+       int new_share_printers = (share_printers > 0 ||
+                                 (share_printers == -1 &&
+                                  old_share_printers > 0));
+
         wrote_browsing = 1;
 
-        if (remote_printers > 0 || share_printers > 0)
+        if (new_remote_printers || new_share_printers)
        {
-         if (remote_printers > 0 && share_printers > 0)
+         const char *localp = cupsGetOption("BrowseLocalProtocols",
+                                            num_settings, settings);
+         const char *remotep = cupsGetOption("BrowseRemoteProtocols",
+                                             num_settings, settings);
+
+          if (!localp)
+           localp = cupsGetOption("BrowseLocalProtocols", cupsd_num_settings,
+                                  cupsd_settings);
+
+          if (!remotep)
+           remotep = cupsGetOption("BrowseRemoteProtocols", cupsd_num_settings,
+                                   cupsd_settings);
+
+         if (new_remote_printers && new_share_printers)
            cupsFilePuts(temp,
                         "# Enable printer sharing and shared printers.\n");
-         else if (remote_printers > 0)
+         else if (new_remote_printers)
            cupsFilePuts(temp,
                         "# Show shared printers on the local network.\n");
          else
@@ -1337,11 +1514,31 @@ _cupsAdminSetServerSettings(
          cupsFilePuts(temp, "Browsing On\n");
          cupsFilePuts(temp, "BrowseOrder allow,deny\n");
 
-         if (remote_printers > 0)
+         if (new_remote_printers)
+         {
            cupsFilePuts(temp, "BrowseAllow all\n");
 
-         if (share_printers > 0)
+           if (!remotep || !*remotep)
+             cupsFilePuts(temp, "BrowseRemoteProtocols "
+                                CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS "\n");
+            else if (remotep)
+             cupsFilePrintf(temp, "BrowseRemoteProtocols %s\n", remotep);
+          }
+         else
+           cupsFilePuts(temp, "BrowseRemoteProtocols\n");
+
+         if (new_share_printers)
+         {
            cupsFilePuts(temp, "BrowseAddress @LOCAL\n");
+
+           if (!localp || !*localp)
+             cupsFilePuts(temp, "BrowseLocalProtocols "
+                                CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS "\n");
+            else if (localp)
+             cupsFilePrintf(temp, "BrowseLocalProtocols %s\n", localp);
+         }
+         else
+           cupsFilePuts(temp, "BrowseLocalProtocols\n");
         }
        else
        {
@@ -1387,8 +1584,8 @@ _cupsAdminSetServerSettings(
                             "cancel a job...\n"
                             "  <Limit Cancel-Job>\n"
                             "    Order deny,allow\n"
-                            "    Allow @SYSTEM\n"
-                            "    Allow @OWNER\n"
+                            "    Require user @OWNER "
+                            CUPS_DEFAULT_PRINTADMIN_AUTH "\n"
                             "  </Limit>\n");
       }
 
@@ -1428,8 +1625,6 @@ _cupsAdminSetServerSettings(
        if (remote_admin)
          cupsFilePrintf(temp, "  Allow %s\n",
                         remote_any > 0 ? "all" : "@LOCAL");
-       else
-         cupsFilePuts(temp, "  Allow localhost\n");
       }
       else if (in_conf_location && remote_admin >= 0)
       {
@@ -1447,8 +1642,6 @@ _cupsAdminSetServerSettings(
        if (remote_admin)
          cupsFilePrintf(temp, "  Allow %s\n",
                         remote_any > 0 ? "all" : "@LOCAL");
-       else
-         cupsFilePuts(temp, "  Allow localhost\n");
       }
       else if (in_root_location && (remote_admin >= 0 || share_printers >= 0))
       {
@@ -1469,8 +1662,6 @@ _cupsAdminSetServerSettings(
        if (remote_admin > 0 || share_printers > 0)
          cupsFilePrintf(temp, "  Allow %s\n",
                         remote_any > 0 ? "all" : "@LOCAL");
-       else
-         cupsFilePuts(temp, "  Allow localhost\n");
       }
 
       in_admin_location = 0;
@@ -1540,7 +1731,8 @@ _cupsAdminSetServerSettings(
                           "a job...\n"
                           "  <Limit Cancel-Job>\n"
                           "    Order deny,allow\n"
-                          "    Require user @OWNER @SYSTEM\n"
+                          "    Require user @OWNER "
+                          CUPS_DEFAULT_PRINTADMIN_AUTH "\n"
                           "  </Limit>\n");
 
       in_cancel_job = 0;
@@ -1548,7 +1740,8 @@ _cupsAdminSetServerSettings(
     else if ((((in_admin_location || in_conf_location || in_root_location) &&
                remote_admin >= 0) ||
               (in_root_location && share_printers >= 0)) &&
-             (!strcasecmp(line, "Allow") || !strcasecmp(line, "Deny") ||
+             (((!strcasecmp(line, "Allow") || !strcasecmp(line, "Deny")) &&
+              !strcasecmp(value, "@LOCAL")) ||
              !strcasecmp(line, "Order")))
       continue;
     else if (in_cancel_job == 2)
@@ -1689,8 +1882,6 @@ _cupsAdminSetServerSettings(
 
     if (remote_admin > 0 || share_printers > 0)
       cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
-    else
-      cupsFilePuts(temp, "  Allow localhost\n");
 
     cupsFilePuts(temp, "</Location>\n");
   }
@@ -1707,8 +1898,6 @@ _cupsAdminSetServerSettings(
 
     if (remote_admin)
       cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
-    else
-      cupsFilePuts(temp, "  Allow localhost\n");
 
     cupsFilePuts(temp, "</Location>\n");
   }
@@ -1722,14 +1911,12 @@ _cupsAdminSetServerSettings(
       cupsFilePuts(temp, "# Restrict access to the configuration files...\n");
 
     cupsFilePuts(temp, "<Location /admin/conf>\n"
-                       "  AuthType Basic\n"
+                       "  AuthType Default\n"
                        "  Require user @SYSTEM\n"
                        "  Order allow,deny\n");
 
     if (remote_admin)
       cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
-    else
-      cupsFilePuts(temp, "  Allow localhost\n");
 
     cupsFilePuts(temp, "</Location>\n");
   }
@@ -1738,7 +1925,7 @@ _cupsAdminSetServerSettings(
   {
     cupsFilePuts(temp, "<Policy default>\n"
                        "  # Job-related operations must be done by the owner "
-                      "or an adminstrator...\n"
+                      "or an administrator...\n"
                        "  <Limit Send-Document Send-URI Hold-Job Release-Job "
                       "Restart-Job Purge-Jobs Set-Job-Attributes "
                       "Create-Job-Subscription Renew-Subscription "
@@ -1749,7 +1936,7 @@ _cupsAdminSetServerSettings(
                        "    Order deny,allow\n"
                        "  </Limit>\n"
                        "  # All administration operations require an "
-                      "adminstrator to authenticate...\n"
+                      "administrator to authenticate...\n"
                       "  <Limit Pause-Printer Resume-Printer "
                        "Set-Printer-Attributes Enable-Printer "
                       "Disable-Printer Pause-Printer-After-Current-Job "
@@ -1760,7 +1947,7 @@ _cupsAdminSetServerSettings(
                       "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"
+                       "    AuthType Default\n"
                       "    Require user @SYSTEM\n"
                        "    Order deny,allow\n"
                        "</Limit>\n");
@@ -1769,8 +1956,9 @@ _cupsAdminSetServerSettings(
       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"
+                        "    Require user @OWNER "
+                        CUPS_DEFAULT_PRINTADMIN_AUTH "\n"
                         "  </Limit>\n");
 
     cupsFilePuts(temp, "  <Limit All>\n"
@@ -2194,5 +2382,5 @@ write_option(cups_file_t     *dstfp,      /* I - PPD file */
 
 
 /*
- * End of "$Id: adminutil.c 6378 2007-03-21 07:18:18Z mike $".
+ * End of "$Id: adminutil.c 7576 2008-05-15 21:05:14Z mike $".
  */