summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES-1.3.txt4
-rw-r--r--CHANGES.txt12
-rw-r--r--backend/usb-darwin.c18
-rw-r--r--cgi-bin/admin.c294
-rw-r--r--config-scripts/cups-defaults.m43
-rw-r--r--cups/adminutil.c26
-rw-r--r--cups/api-filter.shtml4
-rw-r--r--doc/cups.css2
-rw-r--r--doc/help/ref-cupsd-conf.html.in12
-rw-r--r--filter/pstops.c205
-rw-r--r--man/cupsd.conf.man.in2
-rw-r--r--man/filter.man13
-rw-r--r--scheduler/classes.c63
-rw-r--r--scheduler/classes.h3
-rw-r--r--scheduler/client.c126
-rw-r--r--scheduler/conf.c312
-rw-r--r--scheduler/conf.h1
-rw-r--r--scheduler/cupsd.h2
-rw-r--r--scheduler/dirsvc.c54
-rw-r--r--scheduler/ipp.c37
-rw-r--r--scheduler/job.c10
-rw-r--r--scheduler/main.c22
-rw-r--r--scheduler/printers.c381
-rw-r--r--scheduler/printers.h2
-rw-r--r--templates/add-class.tmpl18
-rw-r--r--templates/add-printer.tmpl13
-rw-r--r--templates/admin.tmpl33
-rw-r--r--templates/choose-device.tmpl24
-rw-r--r--templates/choose-make.tmpl18
-rw-r--r--templates/choose-model.tmpl21
-rw-r--r--templates/choose-serial.tmpl6
-rw-r--r--templates/choose-uri.tmpl8
-rw-r--r--templates/class-added.tmpl4
-rw-r--r--templates/class-confirm.tmpl4
-rw-r--r--templates/class-deleted.tmpl4
-rw-r--r--templates/class-modified.tmpl4
-rw-r--r--templates/error-op.tmpl4
-rw-r--r--templates/error.tmpl4
-rw-r--r--templates/list-available-printers.tmpl4
-rw-r--r--templates/maintenance.tmpl4
-rw-r--r--templates/modify-class.tmpl14
-rw-r--r--templates/modify-printer.tmpl18
-rw-r--r--templates/printer-accept.tmpl4
-rw-r--r--templates/printer-added.tmpl4
-rw-r--r--templates/printer-configured.tmpl4
-rw-r--r--templates/printer-confirm.tmpl4
-rw-r--r--templates/printer-default.tmpl4
-rw-r--r--templates/printer-deleted.tmpl4
-rw-r--r--templates/printer-modified.tmpl4
-rw-r--r--templates/printer-purge.tmpl4
-rw-r--r--templates/printer-reject.tmpl4
-rw-r--r--templates/printer-start.tmpl4
-rw-r--r--templates/printer-stop.tmpl4
-rw-r--r--templates/printer.tmpl2
-rw-r--r--templates/set-printer-options-header.tmpl2
-rw-r--r--templates/set-printer-options-trailer.tmpl2
-rw-r--r--templates/subscription-added.tmpl4
-rw-r--r--templates/subscription-canceled.tmpl4
-rw-r--r--templates/users.tmpl3
59 files changed, 1206 insertions, 668 deletions
diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt
index 320e6ea30..a80d10f73 100644
--- a/CHANGES-1.3.txt
+++ b/CHANGES-1.3.txt
@@ -4,6 +4,10 @@ CHANGES-1.3.txt
CHANGES IN CUPS V1.3.9
- Documentation updates (STR #2904, STR #2944)
+ - The PostScript filter did not work with Adobe applications
+ using custom page sizes.
+ - The Mac OS X USB backend did not work with some printers
+ that reported a bad 1284 device ID.
- The scheduler incorrectly resolved the client connection
address when HostNameLookups was set to Off (STR #2946)
- The IPP backend incorrectly stopped the local queue if
diff --git a/CHANGES.txt b/CHANGES.txt
index bf0a6a733..db5c885bf 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,9 +1,19 @@
-CHANGES.txt - 2008-09-10
+CHANGES.txt - 2008-09-20
------------------------
CHANGES IN CUPS V1.4b1
- Documentation updates (STR #2567)
+ - The web interface now provides an advanced server settings
+ form.
+ - The web interface's "modify printer" pages now make it
+ easier to change just one setting (STR #1919)
+ - The scheduler now supports a plist PrintcapFormat.
+ - The scheduler now supports multiple addresses in Allow and
+ Deny lines, just like Apache (STR #2947)
+ - Added CUPS_JOBTYPE environment variable for job filters so
+ they know whether they are printing a banner or document
+ file (STR #2799)
- Added support for printer filtering by the cupsfilter
command (STR #2562)
- Added a SSLOptions directive to allow Windows clients to
diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c
index 73c3e4c57..ea2f92b1d 100644
--- a/backend/usb-darwin.c
+++ b/backend/usb-darwin.c
@@ -1036,11 +1036,13 @@ static Boolean list_device_cb(void *refcon,
modelstr[0] = '/';
- if (!CFStringGetCString(make, makestr, sizeof(makestr),
+ if (!make ||
+ !CFStringGetCString(make, makestr, sizeof(makestr),
kCFStringEncodingUTF8))
strcpy(makestr, "Unknown");
- if (!CFStringGetCString(model, &modelstr[1], sizeof(modelstr)-1,
+ if (!model ||
+ !CFStringGetCString(model, &modelstr[1], sizeof(modelstr)-1,
kCFStringEncodingUTF8))
strcpy(modelstr + 1, "Printer");
@@ -1193,18 +1195,10 @@ static void copy_deviceinfo(CFStringRef deviceIDString,
CFStringRef serialKeys[] = { CFSTR("SN:"), CFSTR("SERN:"), NULL };
if (make != NULL)
- {
- if ((*make = copy_value_for_key(deviceIDString, makeKeys)) == NULL)
- *make = CFStringCreateWithCString(kCFAllocatorDefault, "Unknown",
- kCFStringEncodingUTF8);
- }
+ *make = copy_value_for_key(deviceIDString, makeKeys);
if (model != NULL)
- {
- if ((*model = copy_value_for_key(deviceIDString, modelKeys)) == NULL)
- *model = CFStringCreateWithCString(kCFAllocatorDefault, "Printer",
- kCFStringEncodingUTF8);
- }
+ *model = copy_value_for_key(deviceIDString, modelKeys);
if (serial != NULL)
*serial = copy_value_for_key(deviceIDString, serialKeys);
diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c
index 206b6dda8..3dea06ded 100644
--- a/cgi-bin/admin.c
+++ b/cgi-bin/admin.c
@@ -115,7 +115,7 @@ main(int argc, /* I - Number of command-line arguments */
* See if we have form data...
*/
- if (!cgiInitialize())
+ if (!cgiInitialize() || !cgiGetVariable("OP"))
{
/*
* Nope, send the administration menu...
@@ -204,6 +204,8 @@ main(int argc, /* I - Number of command-line arguments */
snprintf(prefix, sizeof(prefix), "http://%s:%s",
getenv("SERVER_NAME"), getenv("SERVER_PORT"));
+ fprintf(stderr, "DEBUG: redirecting with prefix %s!\n", prefix);
+
if ((url = cgiGetVariable("URL")) != NULL)
printf("Location: %s%s\n\n", prefix, url);
else
@@ -1201,8 +1203,12 @@ do_am_printer(http_t *http, /* I - HTTP connection */
NULL, cgiGetVariable("PRINTER_INFO"));
if (!file)
- ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name",
- NULL, cgiGetVariable("PPD_NAME"));
+ {
+ var = cgiGetVariable("PPD_NAME");
+ if (strcmp(var, "__no_change__"))
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name",
+ NULL, var);
+ }
strlcpy(uri, cgiGetVariable("DEVICE_URI"), sizeof(uri));
@@ -1396,14 +1402,28 @@ do_config_server(http_t *http) /* I - HTTP connection */
int num_settings; /* Number of server settings */
cups_option_t *settings; /* Server settings */
+ int advanced, /* Advanced settings shown? */
+ changed; /* Have settings changed? */
const char *debug_logging, /* DEBUG_LOGGING value */
*remote_admin, /* REMOTE_ADMIN value */
*remote_any, /* REMOTE_ANY value */
*remote_printers,
/* REMOTE_PRINTERS value */
*share_printers,/* SHARE_PRINTERS value */
- *user_cancel_any;
+ *user_cancel_any,
/* USER_CANCEL_ANY value */
+ *browse_web_if, /* BrowseWebIF value */
+ *preserve_job_history,
+ /* PreserveJobHistory value */
+ *preserve_job_files,
+ /* PreserveJobFiles value */
+ *max_jobs, /* MaxJobs value */
+ *max_log_size, /* MaxLogSize value */
+ *val; /* Value for other setting */
+ char local_protocols[255],
+ /* BrowseLocalProtocols */
+ remote_protocols[255];
+ /* BrowseRemoteProtocols */
#ifdef HAVE_GSSAPI
char default_auth_type[255];
/* DefaultAuthType value */
@@ -1414,12 +1434,92 @@ do_config_server(http_t *http) /* I - HTTP connection */
* Get the checkbox values from the form...
*/
- debug_logging = cgiGetVariable("DEBUG_LOGGING") ? "1" : "0";
- remote_admin = cgiGetVariable("REMOTE_ADMIN") ? "1" : "0";
- remote_any = cgiGetVariable("REMOTE_ANY") ? "1" : "0";
- remote_printers = cgiGetVariable("REMOTE_PRINTERS") ? "1" : "0";
- share_printers = cgiGetVariable("SHARE_PRINTERS") ? "1" : "0";
- user_cancel_any = cgiGetVariable("USER_CANCEL_ANY") ? "1" : "0";
+ debug_logging = cgiGetVariable("DEBUG_LOGGING") ? "1" : "0";
+ remote_admin = cgiGetVariable("REMOTE_ADMIN") ? "1" : "0";
+ remote_any = cgiGetVariable("REMOTE_ANY") ? "1" : "0";
+ remote_printers = cgiGetVariable("REMOTE_PRINTERS") ? "1" : "0";
+ share_printers = cgiGetVariable("SHARE_PRINTERS") ? "1" : "0";
+ user_cancel_any = cgiGetVariable("USER_CANCEL_ANY") ? "1" : "0";
+
+ advanced = cgiGetVariable("ADVANCEDSETTINGS") != NULL;
+ if (advanced)
+ {
+ /*
+ * Get advanced settings...
+ */
+
+ browse_web_if = cgiGetVariable("BROWSE_WEB_IF") ? "Yes" : "No";
+ preserve_job_history = cgiGetVariable("PRESERVE_JOB_HISTORY") ? "Yes" : "No";
+ preserve_job_files = cgiGetVariable("PRESERVE_JOB_FILES") ? "Yes" : "No";
+ max_jobs = cgiGetVariable("MAX_JOBS");
+ max_log_size = cgiGetVariable("MAX_LOG_SIZE");
+
+ if (!max_jobs || atoi(max_jobs) <= 0)
+ max_jobs = "500";
+
+ if (!max_log_size || atof(max_log_size) <= 0.0)
+ max_log_size = "1m";
+
+ if (cgiGetVariable("BROWSE_LOCAL_CUPS"))
+ strcpy(local_protocols, "cups");
+ else
+ local_protocols[0] = '\0';
+
+#ifdef HAVE_DNSSD
+ if (cgiGetVariable("BROWSE_LOCAL_DNSSD"))
+ {
+ if (local_protocols[0])
+ strcat(local_protocols, " dnssd");
+ else
+ strcat(local_protocols, "dnssd");
+ }
+#endif /* HAVE_DNSSD */
+
+#ifdef HAVE_LDAP
+ if (cgiGetVariable("BROWSE_LOCAL_LDAP"))
+ {
+ if (local_protocols[0])
+ strcat(local_protocols, " ldap");
+ else
+ strcat(local_protocols, "ldap");
+ }
+#endif /* HAVE_LDAP */
+
+#ifdef HAVE_LIBSLP
+ if (cgiGetVariable("BROWSE_LOCAL_SLP"))
+ {
+ if (local_protocols[0])
+ strcat(local_protocols, " slp");
+ else
+ strcat(local_protocols, "slp");
+ }
+#endif /* HAVE_SLP */
+
+ if (cgiGetVariable("BROWSE_REMOTE_CUPS"))
+ strcpy(remote_protocols, "cups");
+ else
+ remote_protocols[0] = '\0';
+
+#ifdef HAVE_LDAP
+ if (cgiGetVariable("BROWSE_REMOTE_LDAP"))
+ {
+ if (remote_protocols[0])
+ strcat(remote_protocols, " ldap");
+ else
+ strcat(remote_protocols, "ldap");
+ }
+#endif /* HAVE_LDAP */
+
+#ifdef HAVE_LIBSLP
+ if (cgiGetVariable("BROWSE_REMOTE_SLP"))
+ {
+ if (remote_protocols[0])
+ strcat(remote_protocols, " slp");
+ else
+ strcat(remote_protocols, "slp");
+ }
+#endif /* HAVE_SLP */
+ }
/*
* Get the current server settings...
@@ -1445,8 +1545,7 @@ do_config_server(http_t *http) /* I - HTTP connection */
strlcpy(default_auth_type, "Negotiate", sizeof(default_auth_type));
else
{
- const char *val = cupsGetOption("DefaultAuthType", num_settings,
- settings);
+ val = cupsGetOption("DefaultAuthType", num_settings, settings);
if (val && !strcasecmp(val, "Negotiate"))
strlcpy(default_auth_type, "Basic", sizeof(default_auth_type));
@@ -1461,23 +1560,44 @@ do_config_server(http_t *http) /* I - HTTP connection */
* See if the settings have changed...
*/
- if (strcmp(debug_logging, cupsGetOption(CUPS_SERVER_DEBUG_LOGGING,
- num_settings, settings)) ||
- strcmp(remote_admin, cupsGetOption(CUPS_SERVER_REMOTE_ADMIN,
- num_settings, settings)) ||
- strcmp(remote_any, cupsGetOption(CUPS_SERVER_REMOTE_ANY,
- num_settings, settings)) ||
- strcmp(remote_printers, cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS,
- num_settings, settings)) ||
- strcmp(share_printers, cupsGetOption(CUPS_SERVER_SHARE_PRINTERS,
- num_settings, settings)) ||
+ changed = strcmp(debug_logging, cupsGetOption(CUPS_SERVER_DEBUG_LOGGING,
+ num_settings, settings)) ||
+ strcmp(remote_admin, cupsGetOption(CUPS_SERVER_REMOTE_ADMIN,
+ num_settings, settings)) ||
+ strcmp(remote_any, cupsGetOption(CUPS_SERVER_REMOTE_ANY,
+ num_settings, settings)) ||
+ strcmp(remote_printers, cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS,
+ num_settings, settings)) ||
+ strcmp(share_printers, cupsGetOption(CUPS_SERVER_SHARE_PRINTERS,
+ num_settings, settings)) ||
#ifdef HAVE_GSSAPI
- !cupsGetOption("DefaultAuthType", num_settings, settings) ||
- strcmp(default_auth_type, cupsGetOption("DefaultAuthType",
- num_settings, settings)) ||
+ !cupsGetOption("DefaultAuthType", num_settings, settings) ||
+ strcmp(default_auth_type, cupsGetOption("DefaultAuthType",
+ num_settings, settings)) ||
#endif /* HAVE_GSSAPI */
- strcmp(user_cancel_any, cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY,
- num_settings, settings)))
+ strcmp(user_cancel_any, cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY,
+ num_settings, settings));
+
+ if (advanced && !changed)
+ changed = cupsGetOption("BrowseLocalProtocols", num_settings, settings) ||
+ strcasecmp(local_protocols,
+ CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS) ||
+ cupsGetOption("BrowseRemoteProtocols", num_settings,
+ settings) ||
+ strcasecmp(remote_protocols,
+ CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS) ||
+ cupsGetOption("BrowseWebIF", num_settings, settings) ||
+ strcasecmp(browse_web_if, "No") ||
+ cupsGetOption("PreserveJobHistory", num_settings, settings) ||
+ strcasecmp(preserve_job_history, "Yes") ||
+ cupsGetOption("PreserveJobFiles", num_settings, settings) ||
+ strcasecmp(preserve_job_files, "No") ||
+ cupsGetOption("MaxJobs", num_settings, settings) ||
+ strcasecmp(max_jobs, "500") ||
+ cupsGetOption("MaxLogSize", num_settings, settings) ||
+ strcasecmp(max_log_size, "1m");
+
+ if (changed)
{
/*
* Settings *have* changed, so save the changes...
@@ -1503,6 +1623,43 @@ do_config_server(http_t *http) /* I - HTTP connection */
num_settings, &settings);
#endif /* HAVE_GSSAPI */
+ if (advanced)
+ {
+ /*
+ * Add advanced settings...
+ */
+
+ if (cupsGetOption("BrowseLocalProtocols", num_settings, settings) ||
+ strcasecmp(local_protocols, CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS))
+ num_settings = cupsAddOption("BrowseLocalProtocols", local_protocols,
+ num_settings, &settings);
+ if (cupsGetOption("BrowseRemoteProtocols", num_settings, settings) ||
+ strcasecmp(remote_protocols, CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS))
+ num_settings = cupsAddOption("BrowseRemoteProtocols", remote_protocols,
+ num_settings, &settings);
+ if (cupsGetOption("BrowseWebIF", num_settings, settings) ||
+ strcasecmp(browse_web_if, "No"))
+ num_settings = cupsAddOption("BrowseWebIF", browse_web_if,
+ num_settings, &settings);
+ if (cupsGetOption("PreserveJobHistory", num_settings, settings) ||
+ strcasecmp(preserve_job_history, "Yes"))
+ num_settings = cupsAddOption("PreserveJobHistory",
+ preserve_job_history, num_settings,
+ &settings);
+ if (cupsGetOption("PreserveJobFiles", num_settings, settings) ||
+ strcasecmp(preserve_job_files, "No"))
+ num_settings = cupsAddOption("PreserveJobFiles", preserve_job_files,
+ num_settings, &settings);
+ if (cupsGetOption("MaxJobs", num_settings, settings) ||
+ strcasecmp(max_jobs, "500"))
+ num_settings = cupsAddOption("MaxJobs", max_jobs, num_settings,
+ &settings);
+ if (cupsGetOption("MaxLogSize", num_settings, settings) ||
+ strcasecmp(max_log_size, "1m"))
+ num_settings = cupsAddOption("MaxLogSize", max_log_size, num_settings,
+ &settings);
+ }
+
if (!cupsAdminSetServerSettings(http, num_settings, settings))
{
if (cupsLastError() == IPP_NOT_AUTHORIZED)
@@ -2354,6 +2511,89 @@ do_menu(http_t *http) /* I - HTTP connection */
cgiSetVariable("KERBEROS", "CHECKED");
#endif /* HAVE_GSSAPI */
+#ifdef HAVE_DNSSD
+ cgiSetVariable("HAVE_DNSSD", "1");
+#endif /* HAVE_DNSSD */
+
+#ifdef HAVE_LDAP
+ cgiSetVariable("HAVE_LDAP", "1");
+#endif /* HAVE_LDAP */
+
+#ifdef HAVE_LIBSLP
+ cgiSetVariable("HAVE_LIBSLP", "1");
+#endif /* HAVE_LIBSLP */
+
+ if ((val = cupsGetOption("BrowseRemoteProtocols", num_settings,
+ settings)) == NULL)
+ if ((val = cupsGetOption("BrowseProtocols", num_settings,
+ settings)) == NULL)
+ val = CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS;
+
+ if (strstr(val, "cups") || strstr(val, "CUPS"))
+ cgiSetVariable("BROWSE_REMOTE_CUPS", "CHECKED");
+
+ if (strstr(val, "ldap") || strstr(val, "LDAP"))
+ cgiSetVariable("BROWSE_REMOTE_LDAP", "CHECKED");
+
+ if (strstr(val, "slp") || strstr(val, "SLP"))
+ cgiSetVariable("BROWSE_REMOTE_SLP", "CHECKED");
+
+ if ((val = cupsGetOption("BrowseLocalProtocols", num_settings,
+ settings)) == NULL)
+ if ((val = cupsGetOption("BrowseProtocols", num_settings,
+ settings)) == NULL)
+ val = CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS;
+
+ if (strstr(val, "cups") || strstr(val, "CUPS"))
+ cgiSetVariable("BROWSE_LOCAL_CUPS", "CHECKED");
+
+ if (strstr(val, "dnssd") || strstr(val, "DNSSD") ||
+ strstr(val, "dns-sd") || strstr(val, "DNS-SD") ||
+ strstr(val, "bonjour") || strstr(val, "BONJOUR"))
+ cgiSetVariable("BROWSE_LOCAL_DNSSD", "CHECKED");
+
+ if (strstr(val, "ldap") || strstr(val, "LDAP"))
+ cgiSetVariable("BROWSE_LOCAL_LDAP", "CHECKED");
+
+ if (strstr(val, "slp") || strstr(val, "SLP"))
+ cgiSetVariable("BROWSE_LOCAL_SLP", "CHECKED");
+
+ if ((val = cupsGetOption("BrowseWebIF", num_settings,
+ settings)) == NULL)
+ val = "No";
+
+ if (!strcasecmp(val, "yes") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "true"))
+ cgiSetVariable("BROWSE_WEB_IF", "CHECKED");
+
+ if ((val = cupsGetOption("PreserveJobHistory", num_settings,
+ settings)) == NULL)
+ val = "Yes";
+
+ if (!strcasecmp(val, "yes") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "true"))
+ {
+ cgiSetVariable("PRESERVE_JOB_HISTORY", "CHECKED");
+
+ if ((val = cupsGetOption("PreserveJobFiles", num_settings,
+ settings)) == NULL)
+ val = "No";
+
+ if (!strcasecmp(val, "yes") || !strcasecmp(val, "on") ||
+ !strcasecmp(val, "true"))
+ cgiSetVariable("PRESERVE_JOB_FILES", "CHECKED");
+ }
+
+ if ((val = cupsGetOption("MaxJobs", num_settings, settings)) == NULL)
+ val = "500";
+
+ cgiSetVariable("MAX_JOBS", val);
+
+ if ((val = cupsGetOption("MaxLogSize", num_settings, settings)) == NULL)
+ val = "1m";
+
+ cgiSetVariable("MAX_LOG_SIZE", val);
+
cupsFreeOptions(num_settings, settings);
/*
diff --git a/config-scripts/cups-defaults.m4 b/config-scripts/cups-defaults.m4
index b07231da5..7efd78363 100644
--- a/config-scripts/cups-defaults.m4
+++ b/config-scripts/cups-defaults.m4
@@ -286,7 +286,7 @@ if test x$default_printcap != xno; then
case $uname in
Darwin*)
if test $uversion -ge 90; then
- CUPS_DEFAULT_PRINTCAP=""
+ CUPS_DEFAULT_PRINTCAP="/Library/Preferences/org.cups.printers.plist"
else
CUPS_DEFAULT_PRINTCAP="/etc/printcap"
fi
@@ -305,6 +305,7 @@ else
CUPS_DEFAULT_PRINTCAP=""
fi
+AC_SUBST(CUPS_DEFAULT_PRINTCAP)
AC_DEFINE_UNQUOTED(CUPS_DEFAULT_PRINTCAP, "$CUPS_DEFAULT_PRINTCAP")
dnl Default LPD config file...
diff --git a/cups/adminutil.c b/cups/adminutil.c
index fd7aa6e95..dc62951ad 100644
--- a/cups/adminutil.c
+++ b/cups/adminutil.c
@@ -1566,27 +1566,33 @@ _cupsAdminSetServerSettings(
{
cupsFilePuts(temp, "BrowseAllow all\n");
- if (!remotep || !*remotep)
- cupsFilePuts(temp, "BrowseRemoteProtocols "
- CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS "\n");
- else if (remotep)
- cupsFilePrintf(temp, "BrowseRemoteProtocols %s\n", remotep);
+ if (!remotep)
+ remotep = CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS;
+
+ cupsFilePrintf(temp, "BrowseRemoteProtocols %s\n", remotep);
}
else
cupsFilePuts(temp, "BrowseRemoteProtocols\n");
+ cupsd_num_settings = cupsAddOption("BrowseRemoteProtocols", remotep,
+ cupsd_num_settings,
+ &cupsd_settings);
+
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);
+ if (!localp)
+ localp = CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS;
+
+ cupsFilePrintf(temp, "BrowseLocalProtocols %s\n", localp);
}
else
cupsFilePuts(temp, "BrowseLocalProtocols\n");
+
+ cupsd_num_settings = cupsAddOption("BrowseLocalProtocols", localp,
+ cupsd_num_settings,
+ &cupsd_settings);
}
else
{
diff --git a/cups/api-filter.shtml b/cups/api-filter.shtml
index 90d86342d..7d2b46973 100644
--- a/cups/api-filter.shtml
+++ b/cups/api-filter.shtml
@@ -131,6 +131,10 @@ when running print filters and backends:</p>
<dt>CUPS_DATADIR</dt>
<dd>The directory where (read-only) CUPS data files can be found.</dd>
+ <dt>CUPS_FILETYPE</dt>
+ <dd>The type of file being printed: "job-sheet" for a banner page and
+ "document" for a regular print file.</dd>
+
<dt>CUPS_SERVERROOT</dt>
<dd>The root directory of the server.</dd>
diff --git a/doc/cups.css b/doc/cups.css
index 8a17c2255..5ceddf2af 100644
--- a/doc/cups.css
+++ b/doc/cups.css
@@ -200,13 +200,11 @@ DIV.figure CAPTION {
}
TH.label {
- padding-top: 5pt;
text-align: right;
vertical-align: top;
}
TH.sublabel {
- padding-top: 0pt;
text-align: right;
font-weight: normal;
}
diff --git a/doc/help/ref-cupsd-conf.html.in b/doc/help/ref-cupsd-conf.html.in
index d55119c86..06111e646 100644
--- a/doc/help/ref-cupsd-conf.html.in
+++ b/doc/help/ref-cupsd-conf.html.in
@@ -2446,6 +2446,7 @@ files as soon as each job is completed, canceled, or aborted.</P>
Printcap
Printcap /etc/printcap
Printcap /etc/printers.conf
+Printcap /Library/Preferences/org.cups.printers.plist
</PRE>
<H3>Description</H3>
@@ -2454,9 +2455,9 @@ Printcap /etc/printers.conf
printcap file is automatically generated and updated with a list
of available printers. If specified with no value, then no
printcap file will be generated. The default is to generate a
-file named <VAR>/etc/printcap</VAR>.</P>
+file named <VAR>@CUPS_DEFAUL_PRINTCAP@</VAR>.</P>
-<P>When a filename is specified (e.g. <VAR>/etc/printcap</VAR>),
+<P>When a filename is specified (e.g. <VAR>@CUPS_DEFAULT_PRINTCAP@</VAR>),
the printcap file is written whenever a printer is added or
removed. The printcap file can then be used by applications that
are hardcoded to look at the printcap file for the available
@@ -2470,13 +2471,14 @@ printers.</P>
<PRE CLASS="command">
PrintcapFormat BSD
PrintcapFormat Solaris
+PrintcapFormat plist
</PRE>
<H3>Description</H3>
-<P>The <CODE>PrintcapFormat</CODE> directive controls the output
-format of the printcap file. The default is to generate a BSD
-printcap file.</P>
+<P>The <CODE>PrintcapFormat</CODE> directive controls the output format of the
+printcap file. The default is to generate the plist format on Mac OS X, the
+Solaris format on Solaris, and the BSD format on other operating systems.</P>
<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.1.13</SPAN><A NAME="PrintcapGUI">PrintcapGUI</A></H2>
diff --git a/filter/pstops.c b/filter/pstops.c
index 98767d0ae..0e8ac48d0 100644
--- a/filter/pstops.c
+++ b/filter/pstops.c
@@ -1,5 +1,5 @@
/*
- * "$Id: pstops.c 7886 2008-08-29 01:51:57Z mike $"
+ * "$Id: pstops.c 7977 2008-09-23 23:44:33Z mike $"
*
* PostScript filter for the Common UNIX Printing System (CUPS).
*
@@ -16,32 +16,36 @@
*
* Contents:
*
- * main() - Main entry...
- * add_page() - Add a page to the pages array...
+ * main() - Main entry.
+ * add_page() - Add a page to the pages array.
* cancel_job() - Flag the job as canceled.
* check_range() - Check to see if the current page is selected for
- * copy_bytes() - Copy bytes from the input file to stdout...
- * copy_comments() - Copy all of the comments section...
- * copy_dsc() - Copy a DSC-conforming document...
- * copy_non_dsc() - Copy a document that does not conform to the DSC...
- * copy_page() - Copy a page description...
- * copy_prolog() - Copy the document prolog section...
- * copy_setup() - Copy the document setup section...
- * copy_trailer() - Copy the document trailer...
- * do_prolog() - Send the necessary document prolog commands...
- * do_setup() - Send the necessary document setup commands...
+ * printing.
+ * copy_bytes() - Copy bytes from the input file to stdout.
+ * copy_comments() - Copy all of the comments section.
+ * copy_dsc() - Copy a DSC-conforming document.
+ * copy_non_dsc() - Copy a document that does not conform to the DSC.
+ * copy_page() - Copy a page description.
+ * copy_prolog() - Copy the document prolog section.
+ * copy_setup() - Copy the document setup section.
+ * copy_trailer() - Copy the document trailer.
+ * do_prolog() - Send the necessary document prolog commands.
+ * do_setup() - Send the necessary document setup commands.
* doc_printf() - Send a formatted string to stdout and/or the temp
* file.
* doc_puts() - Send a nul-terminated string to stdout and/or the
* temp file.
* doc_write() - Send data to stdout and/or the temp file.
- * end_nup() - End processing for N-up printing...
+ * end_nup() - End processing for N-up printing.
* include_feature() - Include a printer option/feature command.
- * parse_text() - Parse a text value in a comment...
- * set_pstops_options() - Set pstops options...
- * skip_page() - Skip past a page that won't be printed...
- * start_nup() - Start processing for N-up printing...
+ * parse_text() - Parse a text value in a comment.
+ * set_pstops_options() - Set pstops options.
+ * skip_page() - Skip past a page that won't be printed.
+ * start_nup() - Start processing for N-up printing.
+ * write_label_prolog() - Write the prolog with the classification and page
+ * label.
* write_labels() - Write the actual page labels.
+ * write_options() - Write options provided via %%IncludeFeature.
*/
/*
@@ -211,10 +215,12 @@ static void write_label_prolog(pstops_doc_t *doc, const char *label,
float bottom, float top,
float width);
static void write_labels(pstops_doc_t *doc, int orient);
+static void write_options(pstops_doc_t *doc, ppd_file_t *ppd,
+ int num_options, cups_option_t *options);
/*
- * 'main()' - Main entry...
+ * 'main()' - Main entry.
*/
int /* O - Exit status */
@@ -412,7 +418,7 @@ main(int argc, /* I - Number of command-line args */
/*
- * 'add_page()' - Add a page to the pages array...
+ * 'add_page()' - Add a page to the pages array.
*/
static pstops_page_t * /* O - New page info object */
@@ -530,7 +536,7 @@ check_range(pstops_doc_t *doc, /* I - Document information */
/*
- * 'copy_bytes()' - Copy bytes from the input file to stdout...
+ * 'copy_bytes()' - Copy bytes from the input file to stdout.
*/
static void
@@ -575,7 +581,7 @@ copy_bytes(cups_file_t *fp, /* I - File to read from */
/*
- * 'copy_comments()' - Copy all of the comments section...
+ * 'copy_comments()' - Copy all of the comments section.
*
* This function expects "line" to be filled with a comment line.
* On return, "line" will contain the next line in the file, if any.
@@ -799,7 +805,7 @@ copy_comments(cups_file_t *fp, /* I - File to read from */
/*
- * 'copy_dsc()' - Copy a DSC-conforming document...
+ * 'copy_dsc()' - Copy a DSC-conforming document.
*
* This function expects "line" to be filled with the %!PS-Adobe comment line.
*/
@@ -1059,7 +1065,7 @@ copy_dsc(cups_file_t *fp, /* I - File to read from */
/*
- * 'copy_non_dsc()' - Copy a document that does not conform to the DSC...
+ * 'copy_non_dsc()' - Copy a document that does not conform to the DSC.
*
* This function expects "line" to be filled with the %! comment line.
*/
@@ -1239,7 +1245,7 @@ copy_non_dsc(cups_file_t *fp, /* I - File to read from */
/*
- * 'copy_page()' - Copy a page description...
+ * 'copy_page()' - Copy a page description.
*
* This function expects "line" to be filled with a %%Page comment line.
* On return, "line" will contain the next line in the file, if any.
@@ -1565,53 +1571,7 @@ copy_page(cups_file_t *fp, /* I - File to read from */
if (pageinfo->num_options > 0)
- {
- int i; /* Looping var */
- ppd_option_t *option; /* PPD option */
- int min_order; /* Minimum OrderDependency value */
- char *doc_setup, /* DocumentSetup commands to send */
- *any_setup; /* AnySetup commands to send */
-
-
- /*
- * Yes, figure out the minimum OrderDependency value...
- */
-
- if ((option = ppdFindOption(ppd, "PageRegion")) != NULL)
- min_order = option->order;
- else
- min_order = 999.0f;
-
- for (i = 0; i < pageinfo->num_options; i ++)
- if ((option = ppdFindOption(ppd, pageinfo->options[i].name)) != NULL &&
- option->order < min_order)
- min_order = option->order;
-
- /*
- * Mark and extract them...
- */
-
- cupsMarkOptions(ppd, pageinfo->num_options, pageinfo->options);
-
- doc_setup = ppdEmitString(ppd, PPD_ORDER_DOCUMENT, min_order);
- any_setup = ppdEmitString(ppd, PPD_ORDER_ANY, min_order);
-
- /*
- * Then send them out...
- */
-
- if (doc_setup)
- {
- doc_puts(doc, doc_setup);
- free(doc_setup);
- }
-
- if (any_setup)
- {
- doc_puts(doc, any_setup);
- free(any_setup);
- }
- }
+ write_options(doc, ppd, pageinfo->num_options, pageinfo->options);
/*
* Output commands for the current page...
@@ -1757,7 +1717,7 @@ copy_page(cups_file_t *fp, /* I - File to read from */
/*
- * 'copy_prolog()' - Copy the document prolog section...
+ * 'copy_prolog()' - Copy the document prolog section.
*
* This function expects "line" to be filled with a %%BeginProlog comment line.
* On return, "line" will contain the next line in the file, if any.
@@ -1811,7 +1771,7 @@ copy_prolog(cups_file_t *fp, /* I - File to read from */
/*
- * 'copy_setup()' - Copy the document setup section...
+ * 'copy_setup()' - Copy the document setup section.
*
* This function expects "line" to be filled with a %%BeginSetup comment line.
* On return, "line" will contain the next line in the file, if any.
@@ -1825,6 +1785,10 @@ copy_setup(cups_file_t *fp, /* I - File to read from */
ssize_t linelen, /* I - Length of initial line */
size_t linesize) /* I - Size of line buffer */
{
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+
+
while (strncmp(line, "%%BeginSetup", 12))
{
if (!strncmp(line, "%%Page:", 7))
@@ -1838,6 +1802,11 @@ copy_setup(cups_file_t *fp, /* I - File to read from */
doc_puts(doc, "%%BeginSetup\n");
+ do_setup(doc, ppd);
+
+ num_options = 0;
+ options = NULL;
+
if (!strncmp(line, "%%BeginSetup", 12))
{
while (strncmp(line, "%%EndSetup", 10))
@@ -1851,8 +1820,7 @@ copy_setup(cups_file_t *fp, /* I - File to read from */
*/
if (doc->number_up == 1 && !doc->fitplot)
- doc->num_options = include_feature(ppd, line, doc->num_options,
- &(doc->options));
+ num_options = include_feature(ppd, line, num_options, &options);
}
else if (strncmp(line, "%%BeginSetup", 12))
doc_write(doc, line, linelen);
@@ -1867,7 +1835,11 @@ copy_setup(cups_file_t *fp, /* I - File to read from */
fputs(_("ERROR: Missing %%EndSetup!\n"), stderr);
}
- do_setup(doc, ppd);
+ if (num_options > 0)
+ {
+ write_options(doc, ppd, num_options, options);
+ cupsFreeOptions(num_options, options);
+ }
doc_puts(doc, "%%EndSetup\n");
@@ -1876,7 +1848,7 @@ copy_setup(cups_file_t *fp, /* I - File to read from */
/*
- * 'copy_trailer()' - Copy the document trailer...
+ * 'copy_trailer()' - Copy the document trailer.
*
* This function expects "line" to be filled with a %%Trailer comment line.
* On return, "line" will contain the next line in the file, if any.
@@ -1925,7 +1897,7 @@ copy_trailer(cups_file_t *fp, /* I - File to read from */
/*
- * 'do_prolog()' - Send the necessary document prolog commands...
+ * 'do_prolog()' - Send the necessary document prolog commands.
*/
static void
@@ -1964,7 +1936,7 @@ do_prolog(pstops_doc_t *doc, /* I - Document information */
/*
- * 'do_setup()' - Send the necessary document setup commands...
+ * 'do_setup()' - Send the necessary document setup commands.
*/
static void
@@ -1983,7 +1955,7 @@ do_setup(pstops_doc_t *doc, /* I - Document information */
doc_puts(doc, "userdict dup(\\004)cvn{}put (\\004\\004)cvn{}put\n");
/*
- * Mark any options from %%IncludeFeature: comments...
+ * Mark job options...
*/
cupsMarkOptions(ppd, doc->num_options, doc->options);
@@ -2147,7 +2119,7 @@ doc_write(pstops_doc_t *doc, /* I - Document information */
/*
- * 'end_nup()' - End processing for N-up printing...
+ * 'end_nup()' - End processing for N-up printing.
*/
static void
@@ -2273,7 +2245,7 @@ include_feature(
/*
- * 'parse_text()' - Parse a text value in a comment...
+ * 'parse_text()' - Parse a text value in a comment.
*
* This function parses a DSC text value as defined on page 36 of the
* DSC specification. Text values are either surrounded by parenthesis
@@ -2362,7 +2334,7 @@ parse_text(const char *start, /* I - Start of text value */
/*
- * 'set_pstops_options()' - Set pstops options...
+ * 'set_pstops_options()' - Set pstops options.
*/
static void
@@ -2757,7 +2729,7 @@ set_pstops_options(
/*
- * 'skip_page()' - Skip past a page that won't be printed...
+ * 'skip_page()' - Skip past a page that won't be printed.
*/
static ssize_t /* O - Length of next line */
@@ -2819,7 +2791,7 @@ skip_page(cups_file_t *fp, /* I - File to read from */
/*
- * 'start_nup()' - Start processing for N-up printing...
+ * 'start_nup()' - Start processing for N-up printing.
*/
static void
@@ -3411,5 +3383,64 @@ write_labels(pstops_doc_t *doc, /* I - Document information */
/*
- * End of "$Id: pstops.c 7886 2008-08-29 01:51:57Z mike $".
+ * 'write_options()' - Write options provided via %%IncludeFeature.
+ */
+
+static void
+write_options(
+ pstops_doc_t *doc, /* I - Document */
+ ppd_file_t *ppd, /* I - PPD file */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ int i; /* Looping var */
+ ppd_option_t *option; /* PPD option */
+ int min_order; /* Minimum OrderDependency value */
+ char *doc_setup, /* DocumentSetup commands to send */
+ *any_setup; /* AnySetup commands to send */
+
+
+ /*
+ * Figure out the minimum OrderDependency value...
+ */
+
+ if ((option = ppdFindOption(ppd, "PageRegion")) != NULL)
+ min_order = option->order;
+ else
+ min_order = 999.0f;
+
+ for (i = 0; i < num_options; i ++)
+ if ((option = ppdFindOption(ppd, options[i].name)) != NULL &&
+ option->order < min_order)
+ min_order = option->order;
+
+ /*
+ * Mark and extract them...
+ */
+
+ cupsMarkOptions(ppd, num_options, options);
+
+ doc_setup = ppdEmitString(ppd, PPD_ORDER_DOCUMENT, min_order);
+ any_setup = ppdEmitString(ppd, PPD_ORDER_ANY, min_order);
+
+ /*
+ * Then send them out...
+ */
+
+ if (doc_setup)
+ {
+ doc_puts(doc, doc_setup);
+ free(doc_setup);
+ }
+
+ if (any_setup)
+ {
+ doc_puts(doc, any_setup);
+ free(any_setup);
+ }
+}
+
+
+/*
+ * End of "$Id: pstops.c 7977 2008-09-23 23:44:33Z mike $".
*/
diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in
index 06f3ccdaf..e218fd096 100644
--- a/man/cupsd.conf.man.in
+++ b/man/cupsd.conf.man.in
@@ -545,6 +545,8 @@ disables printcap generation.
.TP 5
PrintcapFormat bsd
.TP 5
+PrintcapFormat plist
+.TP 5
PrintcapFormat solaris
.br
Specifies the format of the printcap file.
diff --git a/man/filter.man b/man/filter.man
index 049e378f3..9abb21dc0 100644
--- a/man/filter.man
+++ b/man/filter.man
@@ -12,7 +12,7 @@
.\" 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/".
.\"
-.TH filter 7 "Common UNIX Printing System" "14 May 2008" "Apple Inc."
+.TH filter 7 "Common UNIX Printing System" "18 September 2008" "Apple Inc."
.SH NAME
filter \- cups file conversion filter interface
.SH SYNOPSIS
@@ -148,11 +148,22 @@ The MIME type associated with the file (e.g.
application/postscript).
.TP 5
+CUPS_CACHEDIR
+.br
+The directory for semi-persistent cache files can be found.
+
+.TP 5
CUPS_DATADIR
.br
The directory where data files can be found.
.TP 5
+CUPS_FILETYPE
+.br
+The type of file being printed: "job-sheet" for a banner page and "document"
+for a regular print file.
+
+.TP 5
CUPS_SERVERROOT
.br
The root directory of the server.
diff --git a/scheduler/classes.c b/scheduler/classes.c
index 1d5ecf096..07190018a 100644
--- a/scheduler/classes.c
+++ b/scheduler/classes.c
@@ -3,7 +3,7 @@
*
* Printer class routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -18,7 +18,6 @@
* cupsdAddPrinterToClass() - Add a printer to a class...
* cupsdDeletePrinterFromClass() - Delete a printer from a class.
* cupsdDeletePrinterFromClasses() - Delete a printer from all classes.
- * cupsdDeleteAllClasses() - Remove all classes from the system.
* cupsdFindAvailablePrinter() - Find an available printer in a class.
* cupsdFindClass() - Find the named class.
* cupsdLoadAllClasses() - Load classes from the classes.conf file.
@@ -218,24 +217,6 @@ cupsdDeletePrinterFromClasses(
/*
- * 'cupsdDeleteAllClasses()' - Remove all classes from the system.
- */
-
-void
-cupsdDeleteAllClasses(void)
-{
- cupsd_printer_t *c; /* Pointer to current printer/class */
-
-
- for (c = (cupsd_printer_t *)cupsArrayFirst(Printers);
- c;
- c = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (c->type & CUPS_PRINTER_CLASS)
- cupsdDeletePrinter(c, 0);
-}
-
-
-/*
* 'cupsdFindAvailablePrinter()' - Find an available printer in a class.
*/
@@ -391,11 +372,8 @@ cupsdLoadAllClasses(void)
DefaultPrinter = p;
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "</Class>"))
{
@@ -405,17 +383,13 @@ cupsdLoadAllClasses(void)
p = NULL;
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
- }
}
else if (!p)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
}
else if (!strcasecmp(line, "AuthInfoRequired"))
{
@@ -459,7 +433,7 @@ cupsdLoadAllClasses(void)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
+ continue;
}
else if ((temp = cupsdFindPrinter(value)) == NULL)
{
@@ -501,12 +475,9 @@ cupsdLoadAllClasses(void)
else if (!strcasecmp(value, "stopped"))
p->state = IPP_PRINTER_STOPPED;
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.",
linenum);
- break;
- }
}
else if (!strcasecmp(line, "StateMessage"))
{
@@ -543,12 +514,9 @@ cupsdLoadAllClasses(void)
!strcasecmp(value, "false")))
p->accepting = 0;
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.",
linenum);
- break;
- }
}
else if (!strcasecmp(line, "Shared"))
{
@@ -567,12 +535,9 @@ cupsdLoadAllClasses(void)
!strcasecmp(value, "false")))
p->shared = 0;
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.",
linenum);
- break;
- }
}
else if (!strcasecmp(line, "JobSheets"))
{
@@ -607,11 +572,8 @@ cupsdLoadAllClasses(void)
}
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "AllowUser"))
{
@@ -621,11 +583,8 @@ cupsdLoadAllClasses(void)
cupsdAddPrinterUser(p, value);
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "DenyUser"))
{
@@ -635,44 +594,32 @@ cupsdLoadAllClasses(void)
cupsdAddPrinterUser(p, value);
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "QuotaPeriod"))
{
if (value)
p->quota_period = atoi(value);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "PageLimit"))
{
if (value)
p->page_limit = atoi(value);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "KLimit"))
{
if (value)
p->k_limit = atoi(value);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "OpPolicy"))
{
@@ -692,22 +639,16 @@ cupsdLoadAllClasses(void)
value, linenum);
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "ErrorPolicy"))
{
if (value)
cupsdSetString(&p->error_policy, value);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
- break;
- }
}
else
{
diff --git a/scheduler/classes.h b/scheduler/classes.h
index 3c67c0290..68288f69b 100644
--- a/scheduler/classes.h
+++ b/scheduler/classes.h
@@ -3,7 +3,7 @@
*
* Printer class definitions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -24,7 +24,6 @@ extern void cupsdAddPrinterToClass(cupsd_printer_t *c,
extern void cupsdDeletePrinterFromClass(cupsd_printer_t *c,
cupsd_printer_t *p);
extern void cupsdDeletePrinterFromClasses(cupsd_printer_t *p);
-extern void cupsdDeleteAllClasses(void);
extern cupsd_printer_t *cupsdFindAvailablePrinter(const char *name);
extern cupsd_printer_t *cupsdFindClass(const char *name);
extern void cupsdLoadAllClasses(void);
diff --git a/scheduler/client.c b/scheduler/client.c
index 8e9d84bbe..f2dd9007d 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -439,6 +439,8 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
{
if (HostNameLookups)
httpAddrLookup(&temp, con->servername, sizeof(con->servername));
+ else if (httpAddrLocalhost(&temp))
+ strlcpy(con->servername, "localhost", sizeof(con->servername));
else
httpAddrString(&temp, con->servername, sizeof(con->servername));
@@ -450,6 +452,8 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
{
if (HostNameLookups)
httpAddrLookup(&temp, con->servername, sizeof(con->servername));
+ else if (httpAddrLocalhost(&temp))
+ strlcpy(con->servername, "localhost", sizeof(con->servername));
else
httpAddrString(&temp, con->servername, sizeof(con->servername));
@@ -4691,6 +4695,22 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
{
# endif /* __APPLE__ */
+ if (!KerberosInitialized)
+ {
+ /*
+ * Setup a Kerberos context for the scheduler to use...
+ */
+
+ KerberosInitialized = 1;
+
+ if (krb5_init_context(&KerberosContext))
+ {
+ KerberosContext = NULL;
+
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize Kerberos context");
+ }
+ }
+
/*
* We MUST create a file-based cache because memory-based caches are
* only valid for the current process/address space.
@@ -4703,70 +4723,73 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
* are removed when we have successfully printed a job.
*/
+ if (KerberosContext)
+ {
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
- if ((error = krb5_cc_new_unique(KerberosContext, "FILE", NULL,
- &ccache)) != 0)
+ if ((error = krb5_cc_new_unique(KerberosContext, "FILE", NULL,
+ &ccache)) != 0)
# else /* HAVE_HEIMDAL */
- if ((error = krb5_cc_gen_new(KerberosContext, &krb5_fcc_ops,
- &ccache)) != 0)
+ if ((error = krb5_cc_gen_new(KerberosContext, &krb5_fcc_ops,
+ &ccache)) != 0)
# endif /* HAVE_KRB5_CC_NEW_UNIQUE */
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create new credentials cache (%d/%s)",
- error, strerror(errno));
- ccache = NULL;
- }
- else if ((error = krb5_parse_name(KerberosContext, con->username,
- &principal)) != 0)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to parse kerberos username (%d/%s)", error,
- strerror(errno));
- krb5_cc_destroy(KerberosContext, ccache);
- ccache = NULL;
- }
- else if ((error = krb5_cc_initialize(KerberosContext, ccache,
- principal)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to initialize credentials cache (%d/%s)", error,
- strerror(errno));
- krb5_cc_destroy(KerberosContext, ccache);
- krb5_free_principal(KerberosContext, principal);
- ccache = NULL;
- }
- else
- {
- krb5_free_principal(KerberosContext, principal);
-
- /*
- * Copy the user's credentials to the new cache file...
- */
-
- major_status = gss_krb5_copy_ccache(&minor_status,
- con->gss_delegated_cred, ccache);
-
- if (GSS_ERROR(major_status))
{
- cupsdLogGSSMessage(CUPSD_LOG_ERROR, major_status, minor_status,
- "Unable to import client credentials cache");
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to create new credentials cache (%d/%s)",
+ error, strerror(errno));
+ ccache = NULL;
+ }
+ else if ((error = krb5_parse_name(KerberosContext, con->username,
+ &principal)) != 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to parse kerberos username (%d/%s)", error,
+ strerror(errno));
+ krb5_cc_destroy(KerberosContext, ccache);
+ ccache = NULL;
+ }
+ else if ((error = krb5_cc_initialize(KerberosContext, ccache,
+ principal)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to initialize credentials cache (%d/%s)", error,
+ strerror(errno));
krb5_cc_destroy(KerberosContext, ccache);
+ krb5_free_principal(KerberosContext, principal);
ccache = NULL;
}
else
{
+ krb5_free_principal(KerberosContext, principal);
+
/*
- * Add the KRB5CCNAME environment variable to the job so that the
- * backend can use the credentials when printing.
+ * Copy the user's credentials to the new cache file...
*/
- snprintf(krb5ccname, sizeof(krb5ccname), "KRB5CCNAME=FILE:%s",
- krb5_cc_get_name(KerberosContext, ccache));
- envp[envc++] = krb5ccname;
+ major_status = gss_krb5_copy_ccache(&minor_status,
+ con->gss_delegated_cred, ccache);
- if (!RunUser)
- chown(krb5_cc_get_name(KerberosContext, ccache), User, Group);
- }
+ if (GSS_ERROR(major_status))
+ {
+ cupsdLogGSSMessage(CUPSD_LOG_ERROR, major_status, minor_status,
+ "Unable to import client credentials cache");
+ krb5_cc_destroy(KerberosContext, ccache);
+ ccache = NULL;
+ }
+ else
+ {
+ /*
+ * Add the KRB5CCNAME environment variable to the job so that the
+ * backend can use the credentials when printing.
+ */
+
+ snprintf(krb5ccname, sizeof(krb5ccname), "KRB5CCNAME=FILE:%s",
+ krb5_cc_get_name(KerberosContext, ccache));
+ envp[envc++] = krb5ccname;
+
+ if (!RunUser)
+ chown(krb5_cc_get_name(KerberosContext, ccache), User, Group);
+ }
+ }
}
# ifdef __APPLE__
}
@@ -4774,7 +4797,6 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
# endif /* HAVE_KRB5_CC_NEW_UNIQUE || HAVE_HEIMDAL */
}
#endif /* HAVE_GSSAPI */
-
}
if (con->http.version == HTTP_1_1)
diff --git a/scheduler/conf.c b/scheduler/conf.c
index e640a2101..0161762fe 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -454,6 +454,9 @@ cupsdReadConfiguration(void)
if (!strcmp(CUPS_DEFAULT_PRINTCAP, "/etc/printers.conf"))
PrintcapFormat = PRINTCAP_SOLARIS;
+ else if (!strcmp(CUPS_DEFAULT_PRINTCAP,
+ "/Library/Preferences/org.cups.printers.plist"))
+ PrintcapFormat = PRINTCAP_PLIST;
else
PrintcapFormat = PRINTCAP_BSD;
@@ -1165,7 +1168,6 @@ cupsdReadConfiguration(void)
cupsdDeleteAllSubscriptions();
cupsdFreeAllJobs();
- cupsdDeleteAllClasses();
cupsdDeleteAllPrinters();
DefaultPrinter = NULL;
@@ -1690,92 +1692,113 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
* Deny [From] host/ip...
*/
- if (!strncasecmp(value, "from", 4))
+ while (*value)
{
- /*
- * Strip leading "from"...
- */
+ if (!strncasecmp(value, "from", 4))
+ {
+ /*
+ * Strip leading "from"...
+ */
- value += 4;
+ value += 4;
- while (isspace(*value & 255))
- value ++;
- }
+ while (isspace(*value & 255))
+ value ++;
- /*
- * Figure out what form the allow/deny address takes:
- *
- * All
- * None
- * *.domain.com
- * .domain.com
- * host.domain.com
- * nnn.*
- * nnn.nnn.*
- * nnn.nnn.nnn.*
- * nnn.nnn.nnn.nnn
- * nnn.nnn.nnn.nnn/mm
- * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
- */
+ if (!*value)
+ break;
+ }
- if (!strcasecmp(value, "all"))
- {
/*
- * All hosts...
+ * Find the end of the value...
*/
- if (!strcasecmp(line, "Allow"))
- cupsdAllowIP(loc, zeros, zeros);
- else
- cupsdDenyIP(loc, zeros, zeros);
- }
- else if (!strcasecmp(value, "none"))
- {
+ for (valptr = value; *valptr && !isspace(*valptr & 255); valptr ++);
+
+ while (isspace(*valptr & 255))
+ *valptr++ = '\0';
+
/*
- * No hosts...
+ * Figure out what form the allow/deny address takes:
+ *
+ * All
+ * None
+ * *.domain.com
+ * .domain.com
+ * host.domain.com
+ * nnn.*
+ * nnn.nnn.*
+ * nnn.nnn.nnn.*
+ * nnn.nnn.nnn.nnn
+ * nnn.nnn.nnn.nnn/mm
+ * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
*/
- if (!strcasecmp(line, "Allow"))
- cupsdAllowIP(loc, ones, zeros);
- else
- cupsdDenyIP(loc, ones, zeros);
- }
+ if (!strcasecmp(value, "all"))
+ {
+ /*
+ * All hosts...
+ */
+
+ if (!strcasecmp(line, "Allow"))
+ cupsdAllowIP(loc, zeros, zeros);
+ else
+ cupsdDenyIP(loc, zeros, zeros);
+ }
+ else if (!strcasecmp(value, "none"))
+ {
+ /*
+ * No hosts...
+ */
+
+ if (!strcasecmp(line, "Allow"))
+ cupsdAllowIP(loc, ones, zeros);
+ else
+ cupsdDenyIP(loc, ones, zeros);
+ }
#ifdef AF_INET6
- else if (value[0] == '*' || value[0] == '.' ||
- (!isdigit(value[0] & 255) && value[0] != '['))
+ else if (value[0] == '*' || value[0] == '.' ||
+ (!isdigit(value[0] & 255) && value[0] != '['))
#else
- else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
+ else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
#endif /* AF_INET6 */
- {
- /*
- * Host or domain name...
- */
+ {
+ /*
+ * Host or domain name...
+ */
- if (value[0] == '*')
- value ++;
+ if (value[0] == '*')
+ value ++;
- if (!strcasecmp(line, "Allow"))
- cupsdAllowHost(loc, value);
+ if (!strcasecmp(line, "Allow"))
+ cupsdAllowHost(loc, value);
+ else
+ cupsdDenyHost(loc, value);
+ }
else
- cupsdDenyHost(loc, value);
- }
- else
- {
- /*
- * One of many IP address forms...
- */
-
- if (!get_addr_and_mask(value, ip, mask))
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
- value, linenum);
- return (0);
+ /*
+ * One of many IP address forms...
+ */
+
+ if (!get_addr_and_mask(value, ip, mask))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
+ value, linenum);
+ return (0);
+ }
+
+ if (!strcasecmp(line, "Allow"))
+ cupsdAllowIP(loc, ip, mask);
+ else
+ cupsdDenyIP(loc, ip, mask);
}
- if (!strcasecmp(line, "Allow"))
- cupsdAllowIP(loc, ip, mask);
- else
- cupsdDenyIP(loc, ip, mask);
+ /*
+ * Advance to next value...
+ */
+
+ value = valptr;
}
}
else if (!strcasecmp(line, "AuthType"))
@@ -2579,92 +2602,113 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
"Unable to initialize browse access control list!");
else
{
- if (!strncasecmp(value, "from ", 5))
+ while (*value)
{
- /*
- * Strip leading "from"...
- */
+ if (!strncasecmp(value, "from", 4))
+ {
+ /*
+ * Strip leading "from"...
+ */
- value += 5;
+ value += 4;
- while (isspace(*value))
- value ++;
- }
+ while (isspace(*value & 255))
+ value ++;
- /*
- * Figure out what form the allow/deny address takes:
- *
- * All
- * None
- * *.domain.com
- * .domain.com
- * host.domain.com
- * nnn.*
- * nnn.nnn.*
- * nnn.nnn.nnn.*
- * nnn.nnn.nnn.nnn
- * nnn.nnn.nnn.nnn/mm
- * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
- */
+ if (!*value)
+ break;
+ }
- if (!strcasecmp(value, "all"))
- {
/*
- * All hosts...
+ * Find the end of the value...
*/
- if (!strcasecmp(line, "BrowseAllow"))
- cupsdAllowIP(location, zeros, zeros);
- else
- cupsdDenyIP(location, zeros, zeros);
- }
- else if (!strcasecmp(value, "none"))
- {
+ for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
+
+ while (isspace(*valueptr & 255))
+ *valueptr++ = '\0';
+
/*
- * No hosts...
+ * Figure out what form the allow/deny address takes:
+ *
+ * All
+ * None
+ * *.domain.com
+ * .domain.com
+ * host.domain.com
+ * nnn.*
+ * nnn.nnn.*
+ * nnn.nnn.nnn.*
+ * nnn.nnn.nnn.nnn
+ * nnn.nnn.nnn.nnn/mm
+ * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
*/
- if (!strcasecmp(line, "BrowseAllow"))
- cupsdAllowIP(location, ones, zeros);
- else
- cupsdDenyIP(location, ones, zeros);
- }
+ if (!strcasecmp(value, "all"))
+ {
+ /*
+ * All hosts...
+ */
+
+ if (!strcasecmp(line, "BrowseAllow"))
+ cupsdAllowIP(location, zeros, zeros);
+ else
+ cupsdDenyIP(location, zeros, zeros);
+ }
+ else if (!strcasecmp(value, "none"))
+ {
+ /*
+ * No hosts...
+ */
+
+ if (!strcasecmp(line, "BrowseAllow"))
+ cupsdAllowIP(location, ones, zeros);
+ else
+ cupsdDenyIP(location, ones, zeros);
+ }
#ifdef AF_INET6
- else if (value[0] == '*' || value[0] == '.' ||
- (!isdigit(value[0] & 255) && value[0] != '['))
+ else if (value[0] == '*' || value[0] == '.' ||
+ (!isdigit(value[0] & 255) && value[0] != '['))
#else
- else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
+ else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
#endif /* AF_INET6 */
- {
- /*
- * Host or domain name...
- */
+ {
+ /*
+ * Host or domain name...
+ */
- if (value[0] == '*')
- value ++;
+ if (value[0] == '*')
+ value ++;
- if (!strcasecmp(line, "BrowseAllow"))
- cupsdAllowHost(location, value);
+ if (!strcasecmp(line, "BrowseAllow"))
+ cupsdAllowHost(location, value);
+ else
+ cupsdDenyHost(location, value);
+ }
else
- cupsdDenyHost(location, value);
- }
- else
- {
- /*
- * One of many IP address forms...
- */
-
- if (!get_addr_and_mask(value, ip, mask))
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
- value, linenum);
- break;
+ /*
+ * One of many IP address forms...
+ */
+
+ if (!get_addr_and_mask(value, ip, mask))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
+ value, linenum);
+ break;
+ }
+
+ if (!strcasecmp(line, "BrowseAllow"))
+ cupsdAllowIP(location, ip, mask);
+ else
+ cupsdDenyIP(location, ip, mask);
}
- if (!strcasecmp(line, "BrowseAllow"))
- cupsdAllowIP(location, ip, mask);
- else
- cupsdDenyIP(location, ip, mask);
+ /*
+ * Advance to next value...
+ */
+
+ value = valueptr;
}
}
}
@@ -3116,6 +3160,8 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
if (!strcasecmp(value, "bsd"))
PrintcapFormat = PRINTCAP_BSD;
+ else if (!strcasecmp(value, "plist"))
+ PrintcapFormat = PRINTCAP_PLIST;
else if (!strcasecmp(value, "solaris"))
PrintcapFormat = PRINTCAP_SOLARIS;
else
diff --git a/scheduler/conf.h b/scheduler/conf.h
index e53f13f44..1d534fbca 100644
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -64,6 +64,7 @@ typedef enum
#define PRINTCAP_BSD 0 /* Berkeley LPD format */
#define PRINTCAP_SOLARIS 1 /* Solaris lpsched format */
+#define PRINTCAP_PLIST 2 /* Mac OS X plist format */
/*
diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h
index 4c26cd8d9..88f914607 100644
--- a/scheduler/cupsd.h
+++ b/scheduler/cupsd.h
@@ -165,6 +165,8 @@ VAR void *DefaultProfile VALUE(0);
/* Default security profile */
#ifdef HAVE_GSSAPI
+VAR int KerberosInitialized VALUE(0);
+ /* Has Kerberos been initialized? */
VAR krb5_context KerberosContext VALUE(NULL);
/* Kerberos context for credentials */
#endif /* HAVE_GSSAPI */
diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c
index 172df5778..0d841741a 100644
--- a/scheduler/dirsvc.c
+++ b/scheduler/dirsvc.c
@@ -436,17 +436,13 @@ cupsdLoadRemoteCache(void)
p = NULL;
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of remote.cache.", linenum);
- break;
- }
}
else if (!p)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of remote.cache.", linenum);
- break;
}
else if (!strcasecmp(line, "Info"))
{
@@ -473,14 +469,11 @@ cupsdLoadRemoteCache(void)
cupsdSetString(&p->hostname, host);
cupsdSetString(&p->uri, value);
- cupsdSetString(&p->device_uri, value);
+ cupsdSetDeviceURI(p, value);
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of remote.cache.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "Option") && value)
{
@@ -501,6 +494,18 @@ cupsdLoadRemoteCache(void)
&(p->options));
}
}
+ else if (!strcasecmp(line, "Reason"))
+ {
+ if (value &&
+ p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
+ {
+ p->reasons[p->num_reasons] = _cupsStrAlloc(value);
+ p->num_reasons ++;
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Syntax error on line %d of remote.cache.", linenum);
+ }
else if (!strcasecmp(line, "State"))
{
/*
@@ -512,11 +517,8 @@ cupsdLoadRemoteCache(void)
else if (value && !strcasecmp(value, "stopped"))
p->state = IPP_PRINTER_STOPPED;
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of remote.cache.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "StateMessage"))
{
@@ -544,22 +546,16 @@ cupsdLoadRemoteCache(void)
!strcasecmp(value, "false")))
p->accepting = 0;
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of remote.cache.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "Type"))
{
if (value)
p->type = atoi(value);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of remote.cache.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "BrowseTime"))
{
@@ -571,11 +567,8 @@ cupsdLoadRemoteCache(void)
p->browse_expire = t;
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of remote.cache.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "JobSheets"))
{
@@ -606,11 +599,8 @@ cupsdLoadRemoteCache(void)
}
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of remote.cache.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "AllowUser"))
{
@@ -620,11 +610,8 @@ cupsdLoadRemoteCache(void)
cupsdAddPrinterUser(p, value);
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of remote.cache.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "DenyUser"))
{
@@ -634,11 +621,8 @@ cupsdLoadRemoteCache(void)
cupsdAddPrinterUser(p, value);
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of remote.cache.", linenum);
- break;
- }
}
else
{
@@ -794,8 +778,7 @@ cupsdSaveRemoteCache(void)
if (printer->location)
cupsFilePrintf(fp, "Location %s\n", printer->location);
- if (printer->device_uri)
- cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri);
+ cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri);
if (printer->state == IPP_PRINTER_STOPPED)
{
@@ -805,6 +788,9 @@ cupsdSaveRemoteCache(void)
else
cupsFilePuts(fp, "State Idle\n");
+ for (i = 0; i < printer->num_reasons; i ++)
+ cupsFilePrintf(fp, "Reason %s\n", printer->reasons[i]);
+
if (printer->accepting)
cupsFilePuts(fp, "Accepting Yes\n");
else
@@ -3113,6 +3099,9 @@ process_browse_data(
else
p = cupsdAddPrinter(name);
+ if (!p)
+ return;
+
cupsdClearString(&(p->hostname));
cupsdLogMessage(CUPSD_LOG_DEBUG, "Added remote %s \"%s\"...",
@@ -3132,9 +3121,6 @@ process_browse_data(
cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
}
- if (!p)
- return;
-
if (!p->hostname)
{
/*
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index 936a43d1f..be1835629 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -2448,7 +2448,9 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
* Do we have a valid device URI?
*/
- http_uri_status_t uri_status; /* URI separation status */
+ http_uri_status_t uri_status; /* URI separation status */
+ char old_device_uri[1024];
+ /* Old device URI */
need_restart_job = 1;
@@ -2508,15 +2510,19 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
}
}
+ if (printer->sanitized_device_uri)
+ strlcpy(old_device_uri, printer->sanitized_device_uri,
+ sizeof(old_device_uri));
+ else
+ old_device_uri[0] = '\0';
+
+ cupsdSetDeviceURI(printer, attr->values[0].string.text);
+
cupsdLogMessage(CUPSD_LOG_INFO,
"Setting %s device-uri to \"%s\" (was \"%s\".)",
- printer->name,
- cupsdSanitizeURI(attr->values[0].string.text, line,
- sizeof(line)),
- cupsdSanitizeURI(printer->device_uri, resource,
- sizeof(resource)));
+ printer->name, printer->sanitized_device_uri,
+ old_device_uri);
- cupsdSetString(&printer->device_uri, attr->values[0].string.text);
set_device_uri = 1;
}
@@ -9258,6 +9264,23 @@ save_krb5_creds(cupsd_client_t *con, /* I - Client connection */
return;
# endif /* __APPLE__ */
+ if (!KerberosInitialized)
+ {
+ /*
+ * Setup a Kerberos context for the scheduler to use...
+ */
+
+ KerberosInitialized = 1;
+
+ if (krb5_init_context(&KerberosContext))
+ {
+ KerberosContext = NULL;
+
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize Kerberos context");
+ return;
+ }
+ }
+
/*
* We MUST create a file-based cache because memory-based caches are
* only valid for the current process/address space.
diff --git a/scheduler/job.c b/scheduler/job.c
index 8f453d980..e11fc5db0 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -2477,14 +2477,13 @@ start_job(cupsd_job_t *job, /* I - Job ID */
int filterfds[2][2];/* Pipes used between filters */
int envc; /* Number of environment variables */
char **argv, /* Filter command-line arguments */
- sani_uri[1024], /* Sanitized DEVICE_URI env var */
filename[1024], /* Job filename */
command[1024], /* Full path to command */
jobid[255], /* Job ID string */
title[IPP_MAX_NAME],
/* Job title string */
copies[255], /* # copies string */
- *envp[MAX_ENV + 16],
+ *envp[MAX_ENV + 17],
/* Environment variables */
charset[255], /* CHARSET env variable */
class_name[255],/* CLASS env variable */
@@ -3124,7 +3123,6 @@ start_job(cupsd_job_t *job, /* I - Job ID */
job->filetypes[job->current_file]->type);
snprintf(device_uri, sizeof(device_uri), "DEVICE_URI=%s",
printer->device_uri);
- cupsdSanitizeURI(printer->device_uri, sani_uri, sizeof(sani_uri));
snprintf(ppd, sizeof(ppd), "PPD=%s/ppd/%s.ppd", ServerRoot, printer->name);
snprintf(printer_name, sizeof(printer_name), "PRINTER=%s", printer->name);
snprintf(rip_max_cache, sizeof(rip_max_cache), "RIP_MAX_CACHE=%s", RIPCache);
@@ -3141,6 +3139,8 @@ start_job(cupsd_job_t *job, /* I - Job ID */
envp[envc ++] = content_type;
envp[envc ++] = device_uri;
envp[envc ++] = printer_name;
+ envp[envc ++] = banner_page ? "CUPS_FILETYPE=job-sheet" :
+ "CUPS_FILETYPE=document";
if (!printer->remote && !printer->raw)
{
@@ -3203,7 +3203,7 @@ start_job(cupsd_job_t *job, /* I - Job ID */
cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"%s\"", i, envp[i]);
else
cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"DEVICE_URI=%s\"", i,
- sani_uri);
+ printer->sanitized_device_uri);
if (printer->remote)
job->current_file = job->num_files;
@@ -3415,7 +3415,7 @@ start_job(cupsd_job_t *job, /* I - Job ID */
else
backroot = !(backinfo.st_mode & (S_IRWXG | S_IRWXO));
- argv[0] = sani_uri;
+ argv[0] = printer->sanitized_device_uri;
filterfds[slot][0] = -1;
filterfds[slot][1] = -1;
diff --git a/scheduler/main.c b/scheduler/main.c
index d38045e49..bdc46bc59 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -528,28 +528,6 @@ main(int argc, /* I - Number of command-line args */
PSQUpdateQuotaProc = dlsym(PSQLibRef, PSQLibFuncName);
#endif /* __APPLE__ && HAVE_DLFCN_H */
-#ifdef HAVE_GSSAPI
-# ifdef __APPLE__
- /*
- * If the weak-linked GSSAPI/Kerberos library is not present, don't try
- * to use it...
- */
-
- if (krb5_init_context != NULL)
-# endif /* __APPLE__ */
-
- /*
- * Setup a Kerberos context for the scheduler to use...
- */
-
- if (krb5_init_context(&KerberosContext))
- {
- KerberosContext = NULL;
-
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize Kerberos context");
- }
-#endif /* HAVE_GSSAPI */
-
/*
* Startup the server...
*/
diff --git a/scheduler/printers.c b/scheduler/printers.c
index 25d820f8a..5016951c2 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -1,5 +1,5 @@
/*
- * "$Id: printers.c 7879 2008-08-28 00:08:56Z mike $"
+ * "$Id: printers.c 7968 2008-09-19 23:03:01Z mike $"
*
* Printer routines for the Common UNIX Printing System (CUPS).
*
@@ -27,6 +27,7 @@
* cupsdSaveAllPrinters() - Save all printer definitions to the
* printers.conf file.
* cupsdSetAuthInfoRequired() - Set the required authentication info.
+ * cupsdSetDeviceURI() - Set the device URI for a printer.
* cupsdSetPrinterAttr() - Set a printer attribute.
* cupsdSetPrinterAttrs() - Set printer attributes based upon the PPD
* file.
@@ -37,7 +38,6 @@
* cupsdValidateDest() - Validate a printer/class destination.
* cupsdWritePrintcap() - Write a pseudo-printcap file for older
* applications that need it...
- * cupsdSanitizeURI() - Sanitize a device URI...
* add_printer_defaults() - Add name-default attributes to the printer
* attributes.
* add_printer_filter() - Add a MIME filter for a printer.
@@ -49,6 +49,7 @@
* desktop tools.
* write_irix_state() - Update the status files used by IRIX
* printing desktop tools.
+ * write_xml_string() - Write a string with XML escaping.
*/
/*
@@ -73,6 +74,7 @@ static void delete_printer_filters(cupsd_printer_t *p);
static void write_irix_config(cupsd_printer_t *p);
static void write_irix_state(cupsd_printer_t *p);
#endif /* __sgi */
+static void write_xml_string(cups_file_t *fp, const char *s);
/*
@@ -107,7 +109,7 @@ cupsdAddPrinter(const char *name) /* I - Name of printer */
cupsdSetString(&p->hostname, ServerName);
cupsdSetStringf(&p->uri, "ipp://%s:%d/printers/%s", ServerName, LocalPort, name);
- cupsdSetStringf(&p->device_uri, "file:/dev/null");
+ cupsdSetDeviceURI(p, "file:/dev/null");
p->state = IPP_PRINTER_STOPPED;
p->state_time = time(NULL);
@@ -594,8 +596,7 @@ cupsdDeleteAllPrinters(void)
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & CUPS_PRINTER_CLASS))
- cupsdDeletePrinter(p, 0);
+ cupsdDeletePrinter(p, 0);
}
@@ -760,6 +761,7 @@ cupsdDeletePrinter(
cupsdClearString(&p->job_sheets[0]);
cupsdClearString(&p->job_sheets[1]);
cupsdClearString(&p->device_uri);
+ cupsdClearString(&p->sanitized_device_uri);
cupsdClearString(&p->port_monitor);
cupsdClearString(&p->op_policy);
cupsdClearString(&p->error_policy);
@@ -917,11 +919,8 @@ cupsdLoadAllPrinters(void)
DefaultPrinter = p;
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "</Printer>"))
{
@@ -934,7 +933,7 @@ cupsdLoadAllPrinters(void)
cupsdSetPrinterAttrs(p);
cupsdAddPrinterHistory(p);
- if (p->device_uri && strncmp(p->device_uri, "file:", 5) &&
+ if (strncmp(p->device_uri, "file:", 5) &&
p->state != IPP_PRINTER_STOPPED)
{
/*
@@ -962,17 +961,13 @@ cupsdLoadAllPrinters(void)
p = NULL;
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!p)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
}
else if (!strcasecmp(line, "AuthInfoRequired"))
{
@@ -994,13 +989,10 @@ cupsdLoadAllPrinters(void)
else if (!strcasecmp(line, "DeviceURI"))
{
if (value)
- cupsdSetString(&p->device_uri, value);
+ cupsdSetDeviceURI(p, value);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "Option") && value)
{
@@ -1028,11 +1020,20 @@ cupsdLoadAllPrinters(void)
else if (value)
cupsdClearString(&p->port_monitor);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
+ }
+ else if (!strcasecmp(line, "Reason"))
+ {
+ if (value &&
+ p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
+ {
+ p->reasons[p->num_reasons] = _cupsStrAlloc(value);
+ p->num_reasons ++;
}
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Syntax error on line %d of printers.conf.", linenum);
}
else if (!strcasecmp(line, "State"))
{
@@ -1045,11 +1046,8 @@ cupsdLoadAllPrinters(void)
else if (value && !strcasecmp(value, "stopped"))
p->state = IPP_PRINTER_STOPPED;
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "StateMessage"))
{
@@ -1086,11 +1084,8 @@ cupsdLoadAllPrinters(void)
!strcasecmp(value, "false")))
p->accepting = 0;
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "Shared"))
{
@@ -1109,11 +1104,8 @@ cupsdLoadAllPrinters(void)
!strcasecmp(value, "false")))
p->shared = 0;
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "JobSheets"))
{
@@ -1144,11 +1136,8 @@ cupsdLoadAllPrinters(void)
}
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "AllowUser"))
{
@@ -1158,11 +1147,8 @@ cupsdLoadAllPrinters(void)
cupsdAddPrinterUser(p, value);
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "DenyUser"))
{
@@ -1172,44 +1158,32 @@ cupsdLoadAllPrinters(void)
cupsdAddPrinterUser(p, value);
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "QuotaPeriod"))
{
if (value)
p->quota_period = atoi(value);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "PageLimit"))
{
if (value)
p->page_limit = atoi(value);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "KLimit"))
{
if (value)
p->k_limit = atoi(value);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "OpPolicy"))
{
@@ -1229,22 +1203,16 @@ cupsdLoadAllPrinters(void)
value, linenum);
}
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "ErrorPolicy"))
{
if (value)
cupsdSetString(&p->error_policy, value);
else
- {
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
- break;
- }
}
else if (!strcasecmp(line, "Attribute") && value)
{
@@ -1481,8 +1449,7 @@ cupsdSaveAllPrinters(void)
else
cupsFilePrintf(fp, "Location %s\n", printer->location);
}
- if (printer->device_uri)
- cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri);
+ cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri);
if (printer->port_monitor)
cupsFilePrintf(fp, "PortMonitor %s\n", printer->port_monitor);
@@ -1497,6 +1464,9 @@ cupsdSaveAllPrinters(void)
cupsFilePrintf(fp, "StateTime %d\n", (int)printer->state_time);
+ for (i = 0; i < printer->num_reasons; i ++)
+ cupsFilePrintf(fp, "Reason %s\n", printer->reasons[i]);
+
if (printer->accepting)
cupsFilePuts(fp, "Accepting Yes\n");
else
@@ -1828,6 +1798,74 @@ cupsdSetAuthInfoRequired(
/*
+ * 'cupsdSetDeviceURI()' - Set the device URI for a printer.
+ */
+
+void
+cupsdSetDeviceURI(cupsd_printer_t *p, /* I - Printer */
+ const char *uri) /* I - Device URI */
+{
+ char buffer[1024], /* URI buffer */
+ *start, /* Start of data after scheme */
+ *slash, /* First slash after scheme:// */
+ *ptr; /* Pointer into user@host:port part */
+
+
+ /*
+ * Set the full device URI..
+ */
+
+ cupsdSetString(&(p->device_uri), uri);
+
+ /*
+ * Copy the device URI to a temporary buffer so we can sanitize any auth
+ * info in it...
+ */
+
+ strlcpy(buffer, uri, sizeof(buffer));
+
+ /*
+ * Find the end of the scheme:// part...
+ */
+
+ if ((ptr = strchr(buffer, ':')) != NULL)
+ {
+ for (start = ptr + 1; *start; start ++)
+ if (*start != '/')
+ break;
+
+ /*
+ * Find the next slash (/) in the URI...
+ */
+
+ if ((slash = strchr(start, '/')) == NULL)
+ slash = start + strlen(start); /* No slash, point to the end */
+
+ /*
+ * Check for an @ sign before the slash...
+ */
+
+ if ((ptr = strchr(start, '@')) != NULL && ptr < slash)
+ {
+ /*
+ * Found an @ sign and it is before the resource part, so we have
+ * an authentication string. Copy the remaining URI over the
+ * authentication string...
+ */
+
+ _cups_strcpy(start, ptr + 1);
+ }
+ }
+
+ /*
+ * Save the sanitized URI...
+ */
+
+ cupsdSetString(&(p->sanitized_device_uri), buffer);
+}
+
+
+/*
* 'cupsdSetPrinterAttr()' - Set a printer attribute.
*/
@@ -1958,7 +1996,6 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
{
int i, /* Looping var */
length; /* Length of browse attributes */
- char uri[HTTP_MAX_URI]; /* URI for printer */
char resource[HTTP_MAX_URI]; /* Resource portion of URI */
char filename[1024]; /* Name of PPD file */
int num_air; /* Number of auth-info-required values */
@@ -2229,31 +2266,11 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
else
{
/*
- * Add printer-specific attributes... Start by sanitizing the device
- * URI so it doesn't have a username or password in it...
+ * Add printer-specific attributes...
*/
- if (!p->device_uri)
- strcpy(uri, "file:/dev/null");
- else if (strstr(p->device_uri, "://") != NULL)
- {
- /*
- * http://..., ipp://..., etc.
- */
-
- cupsdSanitizeURI(p->device_uri, uri, sizeof(uri));
- }
- else
- {
- /*
- * file:..., serial:..., etc.
- */
-
- strlcpy(uri, p->device_uri, sizeof(uri));
- }
-
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
- uri);
+ p->sanitized_device_uri);
/*
* Assign additional attributes from the PPD file (if any)...
@@ -2707,8 +2724,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
ServerRoot, p->name);
add_printer_filter(p, p->filetype, filename);
}
- else if (p->device_uri &&
- !strncmp(p->device_uri, "ipp://", 6) &&
+ else if (!strncmp(p->device_uri, "ipp://", 6) &&
(strstr(p->device_uri, "/printers/") != NULL ||
strstr(p->device_uri, "/classes/") != NULL))
{
@@ -3008,9 +3024,12 @@ cupsdSetPrinterReasons(
sptr = s;
for (i = 0; i < p->num_reasons; i ++)
- free(p->reasons[i]);
+ _cupsStrFree(p->reasons[i]);
p->num_reasons = 0;
+
+ if (PrintcapFormat == PRINTCAP_PLIST)
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
}
if (!strcmp(s, "none"))
@@ -3062,6 +3081,9 @@ cupsdSetPrinterReasons(
if (!strcmp(reason, "paused") && p->state == IPP_PRINTER_STOPPED)
cupsdSetPrinterState(p, IPP_PRINTER_IDLE, 1);
+
+ if (PrintcapFormat == PRINTCAP_PLIST)
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
}
}
else if (p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
@@ -3076,11 +3098,14 @@ cupsdSetPrinterReasons(
if (i >= p->num_reasons)
{
- p->reasons[i] = strdup(reason);
+ p->reasons[i] = _cupsStrAlloc(reason);
p->num_reasons ++;
if (!strcmp(reason, "paused") && p->state != IPP_PRINTER_STOPPED)
cupsdSetPrinterState(p, IPP_PRINTER_STOPPED, 1);
+
+ if (PrintcapFormat == PRINTCAP_PLIST)
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
}
}
}
@@ -3111,6 +3136,9 @@ cupsdSetPrinterState(
* Set the new state...
*/
+ if (PrintcapFormat == PRINTCAP_PLIST)
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
+
old_state = p->state;
p->state = s;
@@ -3542,7 +3570,8 @@ cupsdValidateDest(
void
cupsdWritePrintcap(void)
{
- cups_file_t *fp; /* printcap file */
+ int i; /* Looping var */
+ cups_file_t *fp; /* Printcap file */
cupsd_printer_t *p; /* Current printer */
@@ -3575,11 +3604,11 @@ cupsdWritePrintcap(void)
* data has come from...
*/
- cupsFilePuts(fp,
- "# This file was automatically generated by cupsd(8) from the\n");
- cupsFilePrintf(fp, "# %s/printers.conf file. All changes to this file\n",
- ServerRoot);
- cupsFilePuts(fp, "# will be lost.\n");
+ if (PrintcapFormat != PRINTCAP_PLIST)
+ cupsFilePrintf(fp, "# This file was automatically generated by cupsd(8) "
+ "from the\n"
+ "# %s/printers.conf file. All changes to this file\n"
+ "# will be lost.\n", ServerRoot);
if (Printers)
{
@@ -3589,7 +3618,7 @@ cupsdWritePrintcap(void)
switch (PrintcapFormat)
{
- case PRINTCAP_BSD:
+ case PRINTCAP_BSD :
/*
* Each printer is put in the file as:
*
@@ -3613,7 +3642,68 @@ cupsdWritePrintcap(void)
ServerName, p->name);
break;
- case PRINTCAP_SOLARIS:
+ case PRINTCAP_PLIST :
+ /*
+ * Each printer is written as a dictionary in a plist file.
+ * Currently the printer-name, printer-info, printer-is-accepting-jobs,
+ * printer-location, printer-make-and-model, printer-state,
+ * printer-state-reasons, printer-type, and (sanitized) device-uri.
+ */
+
+ cupsFilePuts(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD "
+ "PLIST 1.0//EN\" \"http://www.apple.com/DTDs/"
+ "PropertyList-1.0.dtd\">\n"
+ "<plist version=\"1.0\">\n"
+ "<array>\n");
+
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
+ p;
+ p = (cupsd_printer_t *)cupsArrayNext(Printers))
+ {
+ cupsFilePuts(fp, "\t<dict>\n"
+ "\t\t<key>printer-name</key>\n"
+ "\t\t<string>");
+ write_xml_string(fp, p->name);
+ cupsFilePuts(fp, "</string>\n"
+ "\t\t<key>printer-info</key>\n"
+ "\t\t<string>");
+ write_xml_string(fp, p->info);
+ cupsFilePrintf(fp, "</string>\n"
+ "\t\t<key>printer-is-accepting-jobs</key>\n"
+ "\t\t<%s/>\n"
+ "\t\t<key>printer-location</key>\n"
+ "\t\t<string>", p->accepting ? "true" : "false");
+ write_xml_string(fp, p->location);
+ cupsFilePuts(fp, "</string>\n"
+ "\t\t<key>printer-make-and-model</key>\n"
+ "\t\t<string>");
+ write_xml_string(fp, p->make_model);
+ cupsFilePrintf(fp, "</string>\n"
+ "\t\t<key>printer-state</key>\n"
+ "\t\t<integer>%d</integer>\n"
+ "\t\t<key>printer-state-reasons</key>\n"
+ "\t\t<array>\n", p->state);
+ for (i = 0; i < p->num_reasons; i ++)
+ {
+ cupsFilePuts(fp, "\t\t\t<string>");
+ write_xml_string(fp, p->reasons[i]);
+ cupsFilePuts(fp, "</string>\n");
+ }
+ cupsFilePrintf(fp, "\t\t</array>\n"
+ "\t\t<key>printer-type</key>\n"
+ "\t\t<integer>%d</integer>\n"
+ "\t\t<key>device-uri</key>\n"
+ "\t\t<string>", p->type);
+ write_xml_string(fp, p->sanitized_device_uri);
+ cupsFilePuts(fp, "</string>\n"
+ "\t</dict>\n");
+ }
+ cupsFilePuts(fp, "</array>\n"
+ "</plist>\n");
+ break;
+
+ case PRINTCAP_SOLARIS :
/*
* Each printer is put in the file as:
*
@@ -3665,74 +3755,6 @@ cupsdWritePrintcap(void)
/*
- * 'cupsdSanitizeURI()' - Sanitize a device URI...
- */
-
-char * /* O - New device URI */
-cupsdSanitizeURI(const char *uri, /* I - Original device URI */
- char *buffer, /* O - New device URI */
- int buflen) /* I - Size of new device URI buffer */
-{
- char *start, /* Start of data after scheme */
- *slash, /* First slash after scheme:// */
- *ptr; /* Pointer into user@host:port part */
-
-
- /*
- * Range check input...
- */
-
- if (!uri || !buffer || buflen < 2)
- return (NULL);
-
- /*
- * Copy the device URI to the new buffer...
- */
-
- strlcpy(buffer, uri, buflen);
-
- /*
- * Find the end of the scheme:// part...
- */
-
- if ((ptr = strchr(buffer, ':')) == NULL)
- return (buffer); /* No scheme: part... */
-
- for (start = ptr + 1; *start; start ++)
- if (*start != '/')
- break;
-
- /*
- * Find the next slash (/) in the URI...
- */
-
- if ((slash = strchr(start, '/')) == NULL)
- slash = start + strlen(start); /* No slash, point to the end */
-
- /*
- * Check for an @ sign before the slash...
- */
-
- if ((ptr = strchr(start, '@')) != NULL && ptr < slash)
- {
- /*
- * Found an @ sign and it is before the resource part, so we have
- * an authentication string. Copy the remaining URI over the
- * authentication string...
- */
-
- _cups_strcpy(start, ptr + 1);
- }
-
- /*
- * Return the new device URI...
- */
-
- return (buffer);
-}
-
-
-/*
* 'add_printer_defaults()' - Add name-default attributes to the printer attributes.
*/
@@ -4224,7 +4246,7 @@ write_irix_config(cupsd_printer_t *p) /* I - Printer to update */
cupsFilePrintf(fp, "Printer Model | %s\n", p->make_model ? p->make_model : "");
cupsFilePrintf(fp, "Location Code | %s\n", p->location ? p->location : "");
cupsFilePrintf(fp, "Physical Location | %s\n", p->info ? p->info : "");
- cupsFilePrintf(fp, "Port Path | %s\n", p->device_uri ? p->device_uri : "");
+ cupsFilePrintf(fp, "Port Path | %s\n", p->device_uri);
cupsFilePrintf(fp, "Config Path | /var/spool/lp/pod/%s.config\n", p->name);
cupsFilePrintf(fp, "Active Status Path | /var/spool/lp/pod/%s.status\n", p->name);
cupsFilePuts(fp, "Status Update Wait | 10 seconds\n");
@@ -4269,7 +4291,7 @@ write_irix_state(cupsd_printer_t *p) /* I - Printer to update */
"Faulted");
cupsFilePrintf(fp, "Information | 01 00 00 | %s\n", CUPS_SVERSION);
cupsFilePrintf(fp, "Information | 02 00 00 | Device URI: %s\n",
- p->device_uri ? p->device_uri : "");
+ p->device_uri);
cupsFilePrintf(fp, "Information | 03 00 00 | %s jobs\n",
p->accepting ? "Accepting" : "Not accepting");
cupsFilePrintf(fp, "Information | 04 00 00 | %s\n", p->state_message);
@@ -4367,5 +4389,44 @@ write_irix_state(cupsd_printer_t *p) /* I - Printer to update */
/*
- * End of "$Id: printers.c 7879 2008-08-28 00:08:56Z mike $".
+ * 'write_xml_string()' - Write a string with XML escaping.
+ */
+
+static void
+write_xml_string(cups_file_t *fp, /* I - File to write to */
+ const char *s) /* I - String to write */
+{
+ const char *start; /* Start of current sequence */
+
+
+ if (!s)
+ return;
+
+ for (start = s; *s; s ++)
+ {
+ if (*s == '&')
+ {
+ if (s > start)
+ cupsFileWrite(fp, start, s - start);
+
+ cupsFilePuts(fp, "&amp;");
+ start = s + 1;
+ }
+ else if (*s == '<')
+ {
+ if (s > start)
+ cupsFileWrite(fp, start, s - start);
+
+ cupsFilePuts(fp, "&lt;");
+ start = s + 1;
+ }
+ }
+
+ if (s > start)
+ cupsFilePuts(fp, start);
+}
+
+
+/*
+ * End of "$Id: printers.c 7968 2008-09-19 23:03:01Z mike $".
*/
diff --git a/scheduler/printers.h b/scheduler/printers.h
index 0853b2eda..21353025a 100644
--- a/scheduler/printers.h
+++ b/scheduler/printers.h
@@ -59,6 +59,7 @@ typedef struct cupsd_printer_s
time_t browse_expire; /* Expiration time for printer */
time_t browse_time; /* Last time update was sent/received */
char *device_uri; /* Device URI */
+ char *sanitized_device_uri; /* Sanitized device URI */
char *port_monitor; /* Port monitor */
int raw; /* Raw queue? */
int remote; /* Remote queue? */
@@ -153,6 +154,7 @@ extern void cupsdSaveAllPrinters(void);
extern int cupsdSetAuthInfoRequired(cupsd_printer_t *p,
const char *values,
ipp_attribute_t *attr);
+extern void cupsdSetDeviceURI(cupsd_printer_t *p, const char *uri);
extern void cupsdSetPrinterAttr(cupsd_printer_t *p,
const char *name, char *value);
extern void cupsdSetPrinterAttrs(cupsd_printer_t *p);
diff --git a/templates/add-class.tmpl b/templates/add-class.tmpl
index 6cec19910..0bb15f18d 100644
--- a/templates/add-class.tmpl
+++ b/templates/add-class.tmpl
@@ -1,18 +1,25 @@
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Add Class</H2>
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
<TABLE>
<TR>
<TH CLASS="label">Name:</TH>
-<TD><INPUT TYPE="TEXT" NAME="PRINTER_NAME" SIZE="40" MAXLENGTH="127"></TD>
+<TD><INPUT TYPE="TEXT" NAME="PRINTER_NAME" SIZE="40" MAXLENGTH="127"><BR>
+<SMALL>(May contain any printable characters except "/", "#", and space)</SMALL></TD>
</TR>
<TR>
-<TH CLASS="label">Location:</TH>
-<TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" SIZE="40" MAXLENGTH="127"></TD>
+<TH CLASS="label">Description:</TH>
+<TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" SIZE="40" MAXLENGTH="127"><BR>
+<SMALL>(Human-readable description such as "HP LaserJet with Duplexer")</SMALL></TD>
</TR>
<TR>
-<TH CLASS="label">Description:</TH>
-<TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" SIZE="40" MAXLENGTH="127"></TD>
+<TH CLASS="label">Location:</TH>
+<TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" SIZE="40" MAXLENGTH="127"><BR>
+<SMALL>(Human-readable location such as "Lab 1")</SMALL></TD>
</TR>
<TR>
<TH CLASS="label">Members:</TH>
@@ -29,3 +36,4 @@
</TABLE>
</FORM>
+</DIV> \ No newline at end of file
diff --git a/templates/add-printer.tmpl b/templates/add-printer.tmpl
index 804e18921..bf100f0c0 100644
--- a/templates/add-printer.tmpl
+++ b/templates/add-printer.tmpl
@@ -1,3 +1,7 @@
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Add Printer</H2>
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
{?current_make!?<INPUT TYPE="HIDDEN" NAME="CURRENT_MAKE" VALUE="{current_make}">:}
@@ -5,10 +9,6 @@
<TABLE>
<TR>
-<TH CLASS="label">Connection:</TH>
-<TD><INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">{device_uri}</TD>
-</TR>
-<TR>
<TH CLASS="label">Name:</TH>
<TD><INPUT TYPE="TEXT" NAME="PRINTER_NAME" SIZE="40" MAXLENGTH="127" VALUE="{?template_name}"><BR>
<SMALL>(May contain any printable characters except "/", "#", and space)</SMALL></TD>
@@ -24,6 +24,10 @@
<SMALL>(Human-readable location such as "Lab 1")</SMALL></TD>
</TR>
<TR>
+<TH CLASS="label">Connection:</TH>
+<TD><INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">{device_uri}</TD>
+</TR>
+<TR>
<TH CLASS="label">Sharing:</TH>
<TD><INPUT TYPE="CHECKBOX" NAME="PRINTER_IS_SHARED" {PRINTER_IS_SHARED=1?CHECKED:}">
Share This Printer</TD>
@@ -35,3 +39,4 @@ Share This Printer</TD>
</TABLE>
</FORM>
+</DIV> \ No newline at end of file
diff --git a/templates/admin.tmpl b/templates/admin.tmpl
index 2e27facd7..78a2ddba6 100644
--- a/templates/admin.tmpl
+++ b/templates/admin.tmpl
@@ -39,7 +39,37 @@
<FORM METHOD="POST" ACTION="/admin">
-<P><B>Basic Server Settings:</B></P>
+{ADVANCEDSETTINGS?<P><B>Advanced Server Settings\:</B>
+(<A HREF="/admin/">Show Basic Settings</A>)</P>
+
+<P><INPUT TYPE="HIDDEN" NAME="OP" VALUE="config-server">
+<INPUT TYPE="HIDDEN" NAME="ADVANCEDSETTINGS" VALUE="YES">
+<INPUT TYPE="CHECKBOX" NAME="REMOTE_PRINTERS" {?remote_printers}> Show printers shared by other systems<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Protocols\:
+<INPUT TYPE="CHECKBOX" NAME="BROWSE_REMOTE_CUPS" {?browse_remote_cups}> CUPS
+{HAVE_LDAP?<INPUT TYPE="CHECKBOX" NAME="BROWSE_REMOTE_LDAP" {?browse_remote_ldap}> LDAP:}
+{HAVE_LIBSLP?<INPUT TYPE="CHECKBOX" NAME="BROWSE_REMOTE_SLP" {?browse_remote_slp}> SLP:}<BR>
+<INPUT TYPE="CHECKBOX" NAME="SHARE_PRINTERS" {?share_printers}> Share printers connected to this system<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Protocols\:
+<INPUT TYPE="CHECKBOX" NAME="BROWSE_LOCAL_CUPS" {?browse_local_cups}> CUPS
+{HAVE_DNSSD?<INPUT TYPE="CHECKBOX" NAME="BROWSE_LOCAL_DNSSD" {?browse_local_dnssd}> DNS-SD:}
+{HAVE_LDAP?<INPUT TYPE="CHECKBOX" NAME="BROWSE_LOCAL_LDAP" {?browse_local_ldap}> LDAP:}
+{HAVE_LIBSLP?<INPUT TYPE="CHECKBOX" NAME="BROWSE_LOCAL_SLP" {?browse_local_slp}> SLP:}<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<INPUT TYPE="CHECKBOX" NAME="REMOTE_ANY" {?remote_any}> Allow printing from the Internet<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<INPUT TYPE="CHECKBOX" NAME="BROWSE_WEB_IF" {?browse_web_if}> Advertise web interface<BR>
+<INPUT TYPE="CHECKBOX" NAME="REMOTE_ADMIN" {?remote_admin}> Allow remote administration<BR>
+{have_gssapi?<INPUT TYPE="CHECKBOX" NAME="KERBEROS" {?kerberos}> Use Kerberos authentication (<A HREF="/help/kerberos.html?TOPIC=Getting+Started">FAQ</A>)<BR>:}
+<INPUT TYPE="CHECKBOX" NAME="USER_CANCEL_ANY" {?user_cancel_any}> Allow users to cancel any job (not just their own)<BR>
+<INPUT TYPE="CHECKBOX" NAME="PRESERVE_JOB_HISTORY" {?preserve_job_history}> Preserve job history<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Number of jobs\:
+<INPUT TYPE="TEXT" NAME="MAX_JOBS" VALUE="{?max_jobs}" SIZE="6"><BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<INPUT TYPE="CHECKBOX" NAME="PRESERVE_JOB_FILES" {?preserve_job_files}> Preserve job print files<BR>
+<INPUT TYPE="CHECKBOX" NAME="DEBUG_LOGGING" {?debug_logging}> Save debugging information for troubleshooting<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Max log file size\:
+<INPUT TYPE="TEXT" NAME="MAX_LOG_SIZE" VALUE="{?max_log_size}" SIZE="6"></P>
+
+:<P><B>Basic Server Settings:</B>
+(<A HREF="/admin/?ADVANCEDSETTINGS=YES">Show Advanced Settings</A>)</P>
<P><INPUT TYPE="HIDDEN" NAME="OP" VALUE="config-server">
<INPUT TYPE="CHECKBOX" NAME="REMOTE_PRINTERS" {?remote_printers}> Show printers shared by other systems<BR>
@@ -50,6 +80,7 @@
<INPUT TYPE="CHECKBOX" NAME="USER_CANCEL_ANY" {?user_cancel_any}> Allow users to cancel any job (not just their own)<BR>
<INPUT TYPE="CHECKBOX" NAME="DEBUG_LOGGING" {?debug_logging}> Save debugging information for troubleshooting</P>
+}
<P><INPUT TYPE="SUBMIT" NAME="CHANGESETTINGS" VALUE="Change Settings"></P>
</FORM>}
diff --git a/templates/choose-device.tmpl b/templates/choose-device.tmpl
index 52e89e557..17e0ac011 100644
--- a/templates/choose-device.tmpl
+++ b/templates/choose-device.tmpl
@@ -1,11 +1,22 @@
+<DIV CLASS="indent">
+
+<H2 CLASS="title">{op=modify-printer?Modify {printer_name}:Add Printer}</H2>
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+{printer_name?<INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{printer_name}">:}
<TABLE>
+{op=add-printer?:<TR>
+<TH CLASS="label">Current Connection:</TH>
+<TD><INPUT TYPE="RADIO" NAME="DEVICE_URI" VALUE="{current_device_uri}" CHECKED>
+{current_device_uri}</TD>
+</TR>:}
+<TR>
<TH CLASS="label">Local Printers:</TH>
<TD>
-{[device_uri]{device_class!network?<INPUT TYPE="radio" NAME="DEVICE_URI"
-VALUE="{device_uri}{?device_make_and_model!Unknown?|{device_make_and_model}:}" {?current_device_uri={device_uri}?CHECKED:{current_device_scheme={device_uri}?CHECKED:}}>
+{[device_uri]{device_class!network?<INPUT TYPE="RADIO" NAME="DEVICE_URI"
+VALUE="{device_uri}{?device_make_and_model!Unknown?|{device_make_and_model}:}">
{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}<BR>
:}}
</TD>
@@ -13,8 +24,8 @@ VALUE="{device_uri}{?device_make_and_model!Unknown?|{device_make_and_model}:}" {
<TR>
<TH CLASS="label">Discovered Network Printers:</TH>
<TD>
-{[device_uri]{device_class=network?{device_uri~[a-z]+://?<INPUT TYPE="radio" NAME="DEVICE_URI"
-VALUE="{device_uri}{?device_make_and_model!Unknown?|{device_make_and_model}:}" {?current_device_uri={device_uri}?CHECKED:{current_device_scheme={device_uri}?CHECKED:}}>
+{[device_uri]{device_class=network?{device_uri~[a-z]+://?<INPUT TYPE="RADIO" NAME="DEVICE_URI"
+VALUE="{device_uri}{?device_make_and_model!Unknown?|{device_make_and_model}:}">
{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}<BR>
:}:}}
</TD>
@@ -23,8 +34,8 @@ VALUE="{device_uri}{?device_make_and_model!Unknown?|{device_make_and_model}:}" {
<TR>
<TH CLASS="label">Other Network Printers:</TH>
<TD>
-{[device_uri]{device_class=network?{device_uri~[a-z]+://?:<INPUT TYPE="radio" NAME="DEVICE_URI"
-VALUE="{device_uri}{?device_make_and_model!Unknown?|{device_make_and_model}:}" {?current_device_uri={device_uri}?CHECKED:{current_device_scheme={device_uri}?CHECKED:}}>
+{[device_uri]{device_class=network?{device_uri~[a-z]+://?:<INPUT TYPE="RADIO" NAME="DEVICE_URI"
+VALUE="{device_uri}{?device_make_and_model!Unknown?|{device_make_and_model}:}">
{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}<BR>
}:}}
</TD>
@@ -36,3 +47,4 @@ VALUE="{device_uri}{?device_make_and_model!Unknown?|{device_make_and_model}:}" {
</TABLE>
</FORM>
+</DIV> \ No newline at end of file
diff --git a/templates/choose-make.tmpl b/templates/choose-make.tmpl
index 2d5a1fac4..e2731dea3 100644
--- a/templates/choose-make.tmpl
+++ b/templates/choose-make.tmpl
@@ -1,19 +1,20 @@
+<DIV CLASS="indent">
+
+<H2 CLASS="title">{op=modify-printer?Modify {printer_name}:Add Printer}</H2>
+
<FORM METHOD="POST" ACTION="/admin" ENCTYPE="multipart/form-data">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+{printer_name?<INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{printer_name}">:}
<INPUT TYPE="HIDDEN" NAME="BAUDRATE" VALUE="{?baudrate}">
<INPUT TYPE="HIDDEN" NAME="BITS" VALUE="{?bits}">
<INPUT TYPE="HIDDEN" NAME="PARITY" VALUE="{?parity}">
<INPUT TYPE="HIDDEN" NAME="FLOW" VALUE="{?flow}">
<TABLE>
-<TR>
-<TH CLASS="label">Connection:</TH>
-<TD><INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">{device_uri}</TD>
-</TR>
-<TR>
+{op=modify-printer?:<TR>
<TH CLASS="label">Name:</TH>
<TD><INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">{printer_name}</TD>
-</TR>
+</TR>}
<TR>
<TH CLASS="label">Description:</TH>
<TD><INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{printer_info}">{printer_info}</TD>
@@ -23,6 +24,10 @@
<TD><INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{printer_location}">{printer_location}</TD>
</TR>
<TR>
+<TH CLASS="label">Connection:</TH>
+<TD><INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">{device_uri}</TD>
+</TR>
+<TR>
<TH CLASS="label">Sharing:</TH>
<TD><INPUT TYPE="HIDDEN" NAME="PRINTER_IS_SHARED" VALUE="{?printer_is_shared}">
{?printer_is_shared=?Do Not:{?printer_is_shared=0?Do Not:}} Share This Printer</TD>
@@ -55,3 +60,4 @@ TYPE="FILE" NAME="PPD_FILE"></TD>
</TABLE>
</FORM>
+</DIV> \ No newline at end of file
diff --git a/templates/choose-model.tmpl b/templates/choose-model.tmpl
index e49d7cf39..33282fb15 100644
--- a/templates/choose-model.tmpl
+++ b/templates/choose-model.tmpl
@@ -1,18 +1,19 @@
+<DIV CLASS="indent">
+
+<H2 CLASS="title">{op=modify-printer?Modify {printer_name}:Add Printer}</H2>
+
<FORM METHOD="POST" ACTION="/admin" ENCTYPE="multipart/form-data">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+{printer_name?<INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{printer_name}">:}
<INPUT TYPE="HIDDEN" NAME="BAUDRATE" VALUE="{?baudrate}">
<INPUT TYPE="HIDDEN" NAME="BITS" VALUE="{?bits}">
<INPUT TYPE="HIDDEN" NAME="PARITY" VALUE="{?parity}">
<INPUT TYPE="HIDDEN" NAME="FLOW" VALUE="{?flow}">
<TABLE>
-<TR>
-<TH CLASS="label">Connection:</TH>
-<TD><INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">{device_uri}</TD>
-</TR>
-<TR>
+{op=modify-printer?:<TR>
<TH CLASS="label">Name:</TH>
<TD><INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">{printer_name}</TD>
-</TR>
+</TR>}
<TR>
<TH CLASS="label">Description:</TH>
<TD><INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{printer_info}">{printer_info}</TD>
@@ -22,6 +23,10 @@
<TD><INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{printer_location}">{printer_location}</TD>
</TR>
<TR>
+<TH CLASS="label">Connection:</TH>
+<TD><INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">{device_uri}</TD>
+</TR>
+<TR>
<TH CLASS="label">Sharing:</TH>
<TD><INPUT TYPE="HIDDEN" NAME="PRINTER_IS_SHARED" VALUE="{?printer_is_shared}">
{?printer_is_shared=?Do Not:{?printer_is_shared=0?Do Not:}} Share This Printer</TD>
@@ -34,7 +39,8 @@
<TH CLASS="label">Model:</TH>
<TD>
<SELECT NAME="PPD_NAME" SIZE="10">
-{[ppd_name]<OPTION VALUE="{ppd_name}" {?current_make_and_model={ppd_make_and_model}?SELECTED:}>{ppd_make_and_model} ({ppd_natural_language})
+{op=add-printer?:<OPTION VALUE="__no_change__" SELECTED>Current Driver - {current_make_and_model}</OPTION>:}
+{[ppd_name]<OPTION VALUE="{ppd_name}" {op=modify-printer?:{?current_make_and_model={ppd_make_and_model}?SELECTED:}}>{ppd_make_and_model} ({ppd_natural_language})
}</SELECT>
</TD>
</TR>
@@ -50,3 +56,4 @@ TYPE="FILE" NAME="PPD_FILE"></TD>
</TABLE>
</FORM>
+</DIV> \ No newline at end of file
diff --git a/templates/choose-serial.tmpl b/templates/choose-serial.tmpl
index 25a4931fb..d714779b3 100644
--- a/templates/choose-serial.tmpl
+++ b/templates/choose-serial.tmpl
@@ -1,5 +1,10 @@
+<DIV CLASS="indent">
+
+<H2 CLASS="title">{op=modify-printer?Modify {printer_name}:Add Printer}</H2>
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+{printer_name?<INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{printer_name}">:}
<TABLE>
<TR>
@@ -43,3 +48,4 @@
</TABLE>
</FORM>
+</DIV> \ No newline at end of file
diff --git a/templates/choose-uri.tmpl b/templates/choose-uri.tmpl
index 765a32e15..8b4f4a851 100644
--- a/templates/choose-uri.tmpl
+++ b/templates/choose-uri.tmpl
@@ -1,11 +1,16 @@
+<DIV CLASS="indent">
+
+<H2 CLASS="title">{op=modify-printer?Modify {printer_name}:Add Printer}</H2>
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+{printer_name?<INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{printer_name}">:}
<INPUT TYPE="HIDDEN" NAME="CURRENT_MAKE_AND_MODEL" VALUE="{?current_make_and_model}">
<TABLE>
<TR>
<TH CLASS="label">Connection:</TH>
-<TD><INPUT TYPE="TEXT" SIZE="60" MAXLENGTH="1024" NAME="DEVICE_URI" VALUE="{device_uri}"></TD>
+<TD><INPUT TYPE="TEXT" SIZE="60" MAXLENGTH="1024" NAME="DEVICE_URI" VALUE="{current_device_uri?{current_device_uri}:{device_uri}}"></TD>
</TR>
<TR>
<TD></TD>
@@ -35,3 +40,4 @@ Printers"</A> for the correct URI to use with your printer.</P>
</TABLE>
</FORM>
+</DIV> \ No newline at end of file
diff --git a/templates/class-added.tmpl b/templates/class-added.tmpl
index f740581ad..64de61a18 100644
--- a/templates/class-added.tmpl
+++ b/templates/class-added.tmpl
@@ -1,2 +1,6 @@
+<DIV CLASS="indent">
+
<P>Class <A HREF="/classes/{printer_name}">{printer_name}</A> has been added
successfully.
+
+</DIV>
diff --git a/templates/class-confirm.tmpl b/templates/class-confirm.tmpl
index 77debf12a..d5641498c 100644
--- a/templates/class-confirm.tmpl
+++ b/templates/class-confirm.tmpl
@@ -1,4 +1,8 @@
+<DIV CLASS="indent">
+
<P><B>Warning:</B> Are you sure you want to delete class
{printer_name}?</P>
<P ALIGN="CENTER"><FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="op" VALUE="delete-class"><INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{printer_name}"><INPUT TYPE="SUBMIT" NAME="confirm" VALUE="Delete Class"></FORM></P>
+
+</DIV>
diff --git a/templates/class-deleted.tmpl b/templates/class-deleted.tmpl
index 269ddd87a..f2bb4d610 100644
--- a/templates/class-deleted.tmpl
+++ b/templates/class-deleted.tmpl
@@ -1 +1,5 @@
+<DIV CLASS="indent">
+
<P>Class {printer_name} has been deleted successfully.
+
+</DIV> \ No newline at end of file
diff --git a/templates/class-modified.tmpl b/templates/class-modified.tmpl
index 861790732..ddbbbc019 100644
--- a/templates/class-modified.tmpl
+++ b/templates/class-modified.tmpl
@@ -1,2 +1,6 @@
+<DIV CLASS="indent">
+
<P>Class <A HREF="/classes/{printer_name}">{printer_name}</A> has been
modified successfully.
+
+</DIV> \ No newline at end of file
diff --git a/templates/error-op.tmpl b/templates/error-op.tmpl
index 6950831a0..5cba90123 100644
--- a/templates/error-op.tmpl
+++ b/templates/error-op.tmpl
@@ -1,3 +1,7 @@
+<DIV CLASS="indent">
+
<P>Error:</P>
<BLOCKQUOTE>Unknown operation "{op}"!</BLOCKQUOTE>
+
+</DIV>
diff --git a/templates/error.tmpl b/templates/error.tmpl
index bf0530cbd..0d29665b9 100644
--- a/templates/error.tmpl
+++ b/templates/error.tmpl
@@ -1,3 +1,7 @@
+<DIV CLASS="indent">
+
<P>{?message?{message}:Error:}</P>
<BLOCKQUOTE>{error}</BLOCKQUOTE>
+
+</DIV>
diff --git a/templates/list-available-printers.tmpl b/templates/list-available-printers.tmpl
index 4ff6d0e3d..8b325fdac 100644
--- a/templates/list-available-printers.tmpl
+++ b/templates/list-available-printers.tmpl
@@ -1,3 +1,5 @@
+<DIV CLASS="indent">
+
<H2 CLASS="title">Available Printers</H2>
{#device_uri=0?<P>No printers found.</P>
@@ -5,3 +7,5 @@
<LI><FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="add-printer"><INPUT TYPE="HIDDEN" NAME="TEMPLATE_NAME" VALUE="{template_name}"><INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="Local Printer"><INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{device_make_and_model}"><INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}"><INPUT TYPE="SUBMIT" VALUE="Add This Printer"></FORM>
{device_make_and_model} ({device_info})</LI>
}</UL>}
+
+</DIV>
diff --git a/templates/maintenance.tmpl b/templates/maintenance.tmpl
index ab57fb108..379c001cb 100644
--- a/templates/maintenance.tmpl
+++ b/templates/maintenance.tmpl
@@ -1,2 +1,6 @@
+<DIV CLASS="indent">
+
<P>Maintenance commands sent; job ID is <A HREF="/printers/{printer_name}">
{printer_name}-{job_id}</A>.</P>
+
+</DIV>
diff --git a/templates/modify-class.tmpl b/templates/modify-class.tmpl
index 2255b2bb4..e36bb6b49 100644
--- a/templates/modify-class.tmpl
+++ b/templates/modify-class.tmpl
@@ -1,21 +1,20 @@
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Modify Class {printer_name}</H2>
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
<TABLE>
<TR>
-<TH CLASS="label">Name:</TH>
-<TD><INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
-{printer_name}</TD>
+<TH CLASS="label">Description:</TH>
+<TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" VALUE="{?printer_info}" SIZE="40" MAXLENGTH="127"></TD>
</TR>
<TR>
<TH CLASS="label">Location:</TH>
<TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" VALUE="{?printer_location}" SIZE="40" MAXLENGTH="127"></TD>
</TR>
<TR>
-<TH CLASS="label">Description:</TH>
-<TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" VALUE="{?printer_info}" SIZE="40" MAXLENGTH="127"></TD>
-</TR>
-<TR>
<TH CLASS="label">Members:</TH>
<TD>
<SELECT NAME="MEMBER_URIS" SIZE="10" MULTIPLE>
@@ -30,3 +29,4 @@
</TABLE>
</FORM>
+</DIV> \ No newline at end of file
diff --git a/templates/modify-printer.tmpl b/templates/modify-printer.tmpl
index c670ca7a0..924d0ee57 100644
--- a/templates/modify-printer.tmpl
+++ b/templates/modify-printer.tmpl
@@ -1,16 +1,13 @@
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Modify {printer_name}</H2>
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
-{?printer_make_and_model=?{?current_make_and_model!?<INPUT TYPE="HIDDEN" NAME="CURRENT_MAKE_AND_MODEL" VALUE="{current_make_and_model}">:}:<INPUT TYPE="HIDDEN" NAME="CURRENT_MAKE_AND_MODEL" VALUE="{printer_make_and_model}">}
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
<TABLE>
<TR>
-<TH CLASS="label">Connection:</TH>
-<TD><INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">{device_uri}</TD>
-</TR>
-<TR>
-<TH CLASS="label">Name:</TH>
-<TD><INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">{printer_name}</TD>
-</TR>
<TH CLASS="label">Description:</TH>
<TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" VALUE="{?printer_info}" SIZE="40" MAXLENGTH="127"><BR>
<SMALL>(Human-readable description such as "HP LaserJet with Duplexer")</SMALL></TD>
@@ -21,6 +18,10 @@
<SMALL>(Human-readable location such as "Lab 1")</SMALL></TD>
</TR>
<TR>
+<TH CLASS="label">Connection:</TH>
+<TD><INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">{device_uri}</TD>
+</TR>
+<TR>
<TH CLASS="label">Sharing:</TH>
<TD><INPUT TYPE="CHECKBOX" NAME="PRINTER_IS_SHARED" {PRINTER_IS_SHARED=1?CHECKED:}">
Share This Printer</TD>
@@ -33,3 +34,4 @@ Share This Printer</TD>
</TABLE>
</FORM>
+</DIV>
diff --git a/templates/printer-accept.tmpl b/templates/printer-accept.tmpl
index 15e8b15ff..7aa91f3dd 100644
--- a/templates/printer-accept.tmpl
+++ b/templates/printer-accept.tmpl
@@ -1,3 +1,7 @@
+<DIV CLASS="indent">
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
is now accepting jobs.</P>
+
+</DIV>
diff --git a/templates/printer-added.tmpl b/templates/printer-added.tmpl
index ba5f550c2..2b819954f 100644
--- a/templates/printer-added.tmpl
+++ b/templates/printer-added.tmpl
@@ -1,2 +1,6 @@
+<DIV CLASS="indent">
+
<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> has been added
successfully.
+
+</DIV>
diff --git a/templates/printer-configured.tmpl b/templates/printer-configured.tmpl
index 3f6b08b70..b80db4569 100644
--- a/templates/printer-configured.tmpl
+++ b/templates/printer-configured.tmpl
@@ -1,2 +1,6 @@
+<DIV CLASS="indent">
+
<P>{OP=set-class-options?Class <A HREF="/classes/{printer_name}">:Printer <A HREF="/printers/{printer_name}">}{printer_name}</A> has
been configured successfully.
+
+</DIV>
diff --git a/templates/printer-confirm.tmpl b/templates/printer-confirm.tmpl
index 516aeea38..4cac6c366 100644
--- a/templates/printer-confirm.tmpl
+++ b/templates/printer-confirm.tmpl
@@ -1,4 +1,8 @@
+<DIV CLASS="indent">
+
<P><B>Warning:</B> Are you sure you want to delete printer
{printer_name}?</P>
<P ALIGN="CENTER"><FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="delete-printer"><INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{printer_name}"><INPUT TYPE="SUBMIT" NAME="confirm" VALUE="Delete Printer"></FORM></P>
+
+</DIV>
diff --git a/templates/printer-default.tmpl b/templates/printer-default.tmpl
index 7bb6bc41d..b18e45047 100644
--- a/templates/printer-default.tmpl
+++ b/templates/printer-default.tmpl
@@ -1,3 +1,5 @@
+<DIV CLASS="indent">
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
has been made the default printer on the server.</P>
@@ -5,3 +7,5 @@ has been made the default printer on the server.</P>
<BLOCKQUOTE><B>Note:</B> Any user default that has been set via
the <TT>lpoptions</TT> command will override this default
setting.</BLOCKQUOTE>
+
+</DIV>
diff --git a/templates/printer-deleted.tmpl b/templates/printer-deleted.tmpl
index f1336b037..0928955e2 100644
--- a/templates/printer-deleted.tmpl
+++ b/templates/printer-deleted.tmpl
@@ -1 +1,5 @@
+<DIV CLASS="indent">
+
<P>Printer {printer_name} has been deleted successfully.
+
+</DIV>
diff --git a/templates/printer-modified.tmpl b/templates/printer-modified.tmpl
index a16abd169..f6fb6e2a1 100644
--- a/templates/printer-modified.tmpl
+++ b/templates/printer-modified.tmpl
@@ -1,2 +1,6 @@
+<DIV CLASS="indent">
+
<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> has been
modified successfully.
+
+</DIV> \ No newline at end of file
diff --git a/templates/printer-purge.tmpl b/templates/printer-purge.tmpl
index 8226d6040..4cba910e2 100644
--- a/templates/printer-purge.tmpl
+++ b/templates/printer-purge.tmpl
@@ -1,3 +1,7 @@
+<DIV CLASS="indent">
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
has been purged of all jobs.</P>
+
+</DIV> \ No newline at end of file
diff --git a/templates/printer-reject.tmpl b/templates/printer-reject.tmpl
index aca24a576..4a52c24c6 100644
--- a/templates/printer-reject.tmpl
+++ b/templates/printer-reject.tmpl
@@ -1,3 +1,7 @@
+<DIV CLASS="indent">
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
is no longer accepting jobs.</P>
+
+</DIV>
diff --git a/templates/printer-start.tmpl b/templates/printer-start.tmpl
index d3b95d3df..d89d89c05 100644
--- a/templates/printer-start.tmpl
+++ b/templates/printer-start.tmpl
@@ -1,3 +1,7 @@
+<DIV CLASS="indent">
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
has been started.</P>
+
+</DIV> \ No newline at end of file
diff --git a/templates/printer-stop.tmpl b/templates/printer-stop.tmpl
index bdccd88f8..75ad8ac16 100644
--- a/templates/printer-stop.tmpl
+++ b/templates/printer-stop.tmpl
@@ -1,3 +1,7 @@
+<DIV CLASS="indent">
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
has been stopped.</P>
+
+</DIV> \ No newline at end of file
diff --git a/templates/printer.tmpl b/templates/printer.tmpl
index 14f107d13..f069b8513 100644
--- a/templates/printer.tmpl
+++ b/templates/printer.tmpl
@@ -35,7 +35,7 @@
<TR><TH ALIGN="RIGHT" VALIGN="TOP">Description:</TH><TD>{printer_info}</TD></TR>
<TR><TH ALIGN="RIGHT" VALIGN="TOP">Location:</TH><TD>{printer_location}</TD></TR>
<TR><TH ALIGN="RIGHT" VALIGN="TOP">Driver:</TH><TD>{printer_make_and_model} ({color_supported=1?color:grayscale}{sides_supported?, 2-sided printing:})<BR>
-<TR><TH ALIGN="RIGHT" VALIGN="TOP">URI:</TH><TD>{device_uri}</TD></TR>
+<TR><TH ALIGN="RIGHT" VALIGN="TOP">Connection:</TH><TD>{device_uri}</TD></TR>
<TR><TH ALIGN="RIGHT" VALIGN="TOP">Defaults:</TH><TD>job-sheets={job_sheets_default}
media={media_default?{media_default}:unknown}
{sides_default?sides={sides_default}:}</TD></TR>
diff --git a/templates/set-printer-options-header.tmpl b/templates/set-printer-options-header.tmpl
index 56d2bb766..fb59e65d4 100644
--- a/templates/set-printer-options-header.tmpl
+++ b/templates/set-printer-options-header.tmpl
@@ -1,3 +1,5 @@
+<DIV CLASS="indent">
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
diff --git a/templates/set-printer-options-trailer.tmpl b/templates/set-printer-options-trailer.tmpl
index ac07cc9e1..f52d8947f 100644
--- a/templates/set-printer-options-trailer.tmpl
+++ b/templates/set-printer-options-trailer.tmpl
@@ -10,3 +10,5 @@ for (var i = 0; i < paramtables.length; i++)
}
--></SCRIPT>
</FORM>
+
+</DIV>
diff --git a/templates/subscription-added.tmpl b/templates/subscription-added.tmpl
index 6153d7950..c288b3649 100644
--- a/templates/subscription-added.tmpl
+++ b/templates/subscription-added.tmpl
@@ -1 +1,5 @@
+<DIV CLASS="indent">
+
<P>Subscription {subscription_name} has been added successfully.</P>
+
+</DIV>
diff --git a/templates/subscription-canceled.tmpl b/templates/subscription-canceled.tmpl
index 46662ccdb..86f2c1069 100644
--- a/templates/subscription-canceled.tmpl
+++ b/templates/subscription-canceled.tmpl
@@ -1 +1,5 @@
+<DIV CLASS="indent">
+
<P>Subscription #{notify_subscription_id} has been canceled.</P>
+
+</DIV>
diff --git a/templates/users.tmpl b/templates/users.tmpl
index 369e30b11..5f9f71f8d 100644
--- a/templates/users.tmpl
+++ b/templates/users.tmpl
@@ -1,3 +1,5 @@
+<DIV CLASS="indent">
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{OP}">
<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
@@ -24,3 +26,4 @@
</TABLE>
</FORM>
+</DIV>