diff options
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, "&"); + start = s + 1; + } + else if (*s == '<') + { + if (s > start) + cupsFileWrite(fp, start, s - start); + + cupsFilePuts(fp, "<"); + 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> + 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> + 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> + <INPUT TYPE="CHECKBOX" NAME="REMOTE_ANY" {?remote_any}> Allow printing from the Internet<BR> + <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> + Number of jobs\: +<INPUT TYPE="TEXT" NAME="MAX_JOBS" VALUE="{?max_jobs}" SIZE="6"><BR> + <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> + 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> |