-CHANGES.txt - 2008-10-01
+CHANGES.txt - 2008-10-08
------------------------
CHANGES IN CUPS V1.4b1
- Documentation updates (STR #2567)
+ - CUPS-Get-Driver now provides much better driver matching based
+ on the IEEE-1284 device ID and make/model strings (STR #2707)
+ - Now support the cupsSNMPSupplies keyword to control whether
+ the network backends query the SNMP Printer MIB for supply
+ levels.
- Now support and use a new banner file format for better text
support and easier customization (STR #2490)
- The scheduler now sets the PRINTER_INFO and PRINTER_LOCATION
IMGLIBS = @IMGLIBS@
IMGFILTERS = @IMGFILTERS@
LAUNCHDLIBS = @LAUNCHDLIBS@
-LDFLAGS = -L../cups -L../filter @LDARCHFLAGS@ \
+LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc \
+ -L../scheduler @LDARCHFLAGS@ \
@LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
LEGACY_BACKENDS = @LEGACY_BACKENDS@
LIBCUPSORDER = @LIBCUPSORDER@
$(RM) man/cups-lpd.man man/cupsaddsmb.man man/cupsd.man
$(RM) man/cupsd.conf.man man/drv.man man/lpoptions.man
$(RM) packaging/cups.list
+ $(RM) packaging/cups-desc.plist packaging/cups-info.plist
$(RM) templates/header.tmpl
$(RM) desktop/cups.desktop
$(RM) init/cups.xml
-$(RM) doc/*/index.html
-$(RM) templates/*/header.tmpl
- -$(RM) -r autom4te*.cache
+ -$(RM) -r autom4te*.cache clang cups/charmaps cups/locale driver/test
#
usb: usb.o ../cups/$(LIBCUPS) libbackend.a
echo Linking $@...
- $(CC) $(ARCHFLAGS) $(LDFLAGS) -o usb usb.o libbackend.a $(LIBUSB) \
+ $(CC) $(LDFLAGS) -o usb usb.o libbackend.a $(LIBUSB) \
$(BACKLIBS) $(LIBS)
usb.o: usb.c usb-darwin.c usb-libusb.c usb-unix.c
* Announce any devices we've found...
*/
+ DNSServiceErrorType status; /* DNS query status */
cups_device_t *best; /* Best matching device */
char device_uri[1024]; /* Device URI */
int count; /* Number of queries */
fprintf(stderr, "DEBUG: Querying \"%s\"...\n", device->fullName);
- if (DNSServiceQueryRecord(&(device->ref),
- kDNSServiceFlagsShareConnection,
- 0, device->fullName, kDNSServiceType_TXT,
- kDNSServiceClass_IN, query_callback,
- devices) != kDNSServiceErr_NoError)
+ status = DNSServiceQueryRecord(&(device->ref),
+ kDNSServiceFlagsShareConnection,
+ 0, device->fullName,
+ kDNSServiceType_TXT,
+ kDNSServiceClass_IN, query_callback,
+ devices);
+ if (status != kDNSServiceErr_NoError)
+ {
fputs("ERROR: Unable to query for TXT records!\n", stderr);
- else
+ fprintf(stderr, "DEBUG: DNSServiceQueryRecord returned %d\n",
+ status);
+ }
+ else
count ++;
}
}
{
cups_device_t key, /* Search key */
*device; /* Device */
- char fullName[1024]; /* Full name for query */
+ char fullName[kDNSServiceMaxDomainName];
+ /* Full name for query */
/*
* Set the "full name" of this service, which is used for queries...
*/
- snprintf(fullName, sizeof(fullName), "%s.%s%s", serviceName, regtype,
- replyDomain);
+ DNSServiceConstructFullName(fullName, serviceName, regtype, replyDomain);
device->fullName = strdup(fullName);
return (device);
*ptr, /* Pointer into value string */
*name_ptr; /* Pointer into name string */
cups_snmp_t packet; /* SNMP response packet */
+ ppd_file_t *ppd; /* PPD file for this queue */
+ ppd_attr_t *ppdattr; /* cupsSNMPSupplies attribute */
static const char * const types[] = /* Supply types */
{
"other",
memset(supplies, 0, sizeof(supplies));
+ /*
+ * See if we should be getting supply levels via SNMP...
+ */
+
+ if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL &&
+ (ppdattr = ppdFindAttr(ppd, "cupsSNMPSupplies", NULL)) != NULL &&
+ ppdattr->value && strcasecmp(ppdattr->value, "true"))
+ {
+ ppdClose(ppd);
+ return;
+ }
+
+ ppdClose(ppd);
+
/*
* Get the device description...
*/
status = (*g.classdriver)->WritePipe(g.classdriver, (UInt8*)print_ptr, &bytes, 0);
/*
- * Ignore timeout errors...
+ * Ignore timeout errors, but retain the number of bytes written to
+ * avoid sending duplicate data (<rdar://problem/6254911>)...
*/
if (status == kIOUSBTransactionTimeout)
- {
status = 0;
- bytes = 0;
- }
if (status || bytes < 0)
{
}
}
-#ifdef DEBUG
char bundlestr[1024];
CFStringGetCString(bundle, bundlestr, sizeof(bundlestr), kCFStringEncodingUTF8);
fprintf(stderr, "DEBUG: load_classdriver(%s) (kr:0x%08x)\n", bundlestr, (int)kr);
-#endif /* DEBUG */
return kr;
}
struct sigaction action; /* POSIX signal action */
sigset_t newmask, /* New signal mask */
oldmask; /* Old signal mask */
+ char usbpath[1024]; /* Path to USB backend */
+ const char *cups_serverbin;/* Path to CUPS binaries */
+
memset(&action, 0, sizeof(action));
sigaddset(&action.sa_mask, SIGTERM);
* Set up the arguments and call posix_spawn...
*/
+ if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
+ cups_serverbin = CUPS_SERVERBIN;
+ snprintf(usbpath, sizeof(usbpath), "%s/backend/usb", cups_serverbin);
+
for (i = 0; i < argc && i < (sizeof(my_argv) / sizeof(my_argv[0])) - 1; i ++)
my_argv[i] = argv[i];
my_argv[i] = NULL;
- if (posix_spawn(&child_pid, "/usr/libexec/cups/backend/usb", NULL, &attrs,
- my_argv, environ))
+ if (posix_spawn(&child_pid, usbpath, NULL, &attrs, my_argv, environ))
{
- perror("DEBUG: Unable to exec /usr/libexec/cups/backend/usb");
+ fprintf(stderr, "DEBUG: Unable to exec %s: %s\n", usbpath,
+ strerror(errno));
_cupsLangPrintf(stderr, _("Unable to use legacy USB class driver!\n"));
exit(CUPS_BACKEND_STOP);
}
admin.cgi: admin.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSCGI)
echo Linking $@...
- $(CC) $(LDFLAGS) -o $@ admin.o -L. -lcupscgi $(LIBS)
+ $(CC) $(LDFLAGS) -o $@ admin.o -lcupscgi $(LIBS)
#
classes.cgi: classes.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSCGI)
echo Linking $@...
- $(CC) $(LDFLAGS) -o $@ classes.o -L. -lcupscgi $(LIBS)
+ $(CC) $(LDFLAGS) -o $@ classes.o -lcupscgi $(LIBS)
#
help.cgi: help.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSCGI)
echo Linking $@...
- $(CC) $(LDFLAGS) -o $@ help.o -L. -lcupscgi $(LIBS)
+ $(CC) $(LDFLAGS) -o $@ help.o -lcupscgi $(LIBS)
#
jobs.cgi: jobs.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSCGI)
echo Linking $@...
- $(CC) $(LDFLAGS) -o $@ jobs.o -L. -lcupscgi $(LIBS)
+ $(CC) $(LDFLAGS) -o $@ jobs.o -lcupscgi $(LIBS)
#
/*
- * "$Id: admin.c 7888 2008-08-29 21:16:56Z mike $"
+ * "$Id: admin.c 8029 2008-10-08 21:07:45Z mike $"
*
* Administration CGI for the Common UNIX Printing System (CUPS).
*
* Contents:
*
* main() - Main entry for CGI.
+ * choose_device_cb() - Add a device to the device selection page.
* do_add_rss_subscription() - Add a RSS subscription.
* do_am_class() - Add or modify a class.
* do_am_printer() - Add or modify a printer.
* do_export() - Export printers to Samba.
* do_list_printers() - List available printers.
* do_menu() - Show the main menu.
- * do_printer_op() - Do a printer operation.
* do_set_allowed_users() - Set the allowed/denied users for a queue.
+ * do_set_default() - Set the server default printer/class.
* do_set_options() - Configure the default options for a queue.
* do_set_sharing() - Set printer-is-shared value.
* get_option_value() - Return the value of an option.
* get_points() - Get a value in points.
- * match_string() - Return the number of matching characters.
*/
/*
#include <limits.h>
+/*
+ * Local globals...
+ */
+
+static int current_device; /* Current device for add/modify */
+static time_t last_device_time; /* Last update time for device list */
+
+
/*
* Local functions...
*/
+static void choose_device_cb(const char *device_class,
+ const char *device_id, const char *device_info,
+ const char *device_make_and_model,
+ const char *device_uri,
+ const char *device_location,
+ const char *title);
static void do_add_rss_subscription(http_t *http);
static void do_am_class(http_t *http, int modify);
static void do_am_printer(http_t *http, int modify);
static void do_cancel_subscription(http_t *http);
-static void do_set_options(http_t *http, int is_class);
static void do_config_server(http_t *http);
static void do_delete_class(http_t *http);
static void do_delete_printer(http_t *http);
static void do_export(http_t *http);
static void do_list_printers(http_t *http);
static void do_menu(http_t *http);
-static void do_printer_op(http_t *http,
- ipp_op_t op, const char *title);
static void do_set_allowed_users(http_t *http);
+static void do_set_default(http_t *http);
+static void do_set_options(http_t *http, int is_class);
static void do_set_sharing(http_t *http);
static char *get_option_value(ppd_file_t *ppd, const char *name,
char *buffer, size_t bufsize);
static double get_points(double number, const char *uval);
-static int match_string(const char *a, const char *b);
/*
fprintf(stderr, "DEBUG: op=\"%s\"...\n", op);
- if (!strcmp(op, "start-printer"))
- do_printer_op(http, IPP_RESUME_PRINTER, cgiText(_("Start Printer")));
- else if (!strcmp(op, "stop-printer"))
- do_printer_op(http, IPP_PAUSE_PRINTER, cgiText(_("Stop Printer")));
- else if (!strcmp(op, "start-class"))
- do_printer_op(http, IPP_RESUME_PRINTER, cgiText(_("Start Class")));
- else if (!strcmp(op, "stop-class"))
- do_printer_op(http, IPP_PAUSE_PRINTER, cgiText(_("Stop Class")));
- else if (!strcmp(op, "accept-jobs"))
- do_printer_op(http, CUPS_ACCEPT_JOBS, cgiText(_("Accept Jobs")));
- else if (!strcmp(op, "reject-jobs"))
- do_printer_op(http, CUPS_REJECT_JOBS, cgiText(_("Reject Jobs")));
- else if (!strcmp(op, "purge-jobs"))
- do_printer_op(http, IPP_PURGE_JOBS, cgiText(_("Purge Jobs")));
- else if (!strcmp(op, "set-allowed-users"))
+ if (!strcmp(op, "set-allowed-users"))
do_set_allowed_users(http);
else if (!strcmp(op, "set-as-default"))
- do_printer_op(http, CUPS_SET_DEFAULT, cgiText(_("Set As Default")));
+ do_set_default(http);
else if (!strcmp(op, "set-sharing"))
do_set_sharing(http);
else if (!strcmp(op, "find-new-printers") ||
}
+/*
+ * 'choose_device_cb()' - Add a device to the device selection page.
+ */
+
+static void
+choose_device_cb(
+ const char *device_class, /* I - Class */
+ const char *device_id, /* I - 1284 device ID */
+ const char *device_info, /* I - Description */
+ const char *device_make_and_model, /* I - Make and model */
+ const char *device_uri, /* I - Device URI */
+ const char *device_location, /* I - Location */
+ const char *title) /* I - Page title */
+{
+ /*
+ * Add the device to the array...
+ */
+
+ cgiSetArray("device_class", current_device, device_class);
+ cgiSetArray("device_id", current_device, device_id);
+ cgiSetArray("device_info", current_device, device_info);
+ cgiSetArray("device_make_and_model", current_device, device_make_and_model);
+ cgiSetArray("device_uri", current_device, device_uri);
+ cgiSetArray("device_location", current_device, device_location);
+
+ current_device ++;
+
+ if (time(NULL) > last_device_time)
+ {
+ /*
+ * Update the page...
+ */
+
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("choose-device.tmpl");
+ cgiEndHTML();
+ fflush(stdout);
+
+ time(&last_device_time);
+ }
+}
+
+
/*
* 'do_add_rss_subscription()' - Add a RSS subscription.
*/
if (!var)
{
/*
- * Build a CUPS_GET_DEVICES request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
+ * Look for devices so the user can pick something...
*/
- fputs("DEBUG: Getting list of devices...\n", stderr);
+ if ((attr = ippFindAttribute(oldinfo, "device-uri", IPP_TAG_URI)) != NULL)
+ {
+ strlcpy(uri, attr->values[0].string.text, sizeof(uri));
+ if ((uriptr = strchr(uri, ':')) != NULL && strncmp(uriptr, "://", 3) == 0)
+ *uriptr = '\0';
- request = ippNewRequest(CUPS_GET_DEVICES);
+ cgiSetVariable("CURRENT_DEVICE_URI", attr->values[0].string.text);
+ cgiSetVariable("CURRENT_DEVICE_SCHEME", uri);
+ }
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, "ipp://localhost/printers/");
+ /*
+ * Prime the page with the current device listed...
+ */
+
+ cgiStartMultipart();
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("choose-device.tmpl");
+ cgiEndHTML();
+ fflush(stdout);
/*
- * Do the request and get back a response...
+ * Scan for devices for up to 30 seconds, updating the page as we find
+ * them...
*/
- if ((response = cupsDoRequest(http, request, "/")) != NULL)
- {
- fputs("DEBUG: Got device list!\n", stderr);
+ fputs("DEBUG: Getting list of devices...\n", stderr);
- cgiSetIPPVars(response, NULL, NULL, NULL, 0);
- ippDelete(response);
- }
+ time(&last_device_time);
+ current_device = 0;
+ if (cupsGetDevices(http, 30, NULL, (cups_device_cb_t)choose_device_cb,
+ (void *)title) == IPP_OK)
+ fputs("DEBUG: Got device list!\n", stderr);
else
fprintf(stderr,
"ERROR: CUPS-Get-Devices request failed with status %x: %s\n",
cupsLastError(), cupsLastErrorString());
/*
- * Let the user choose...
+ * Show the final selection page...
*/
- if ((attr = ippFindAttribute(oldinfo, "device-uri", IPP_TAG_URI)) != NULL)
- {
- strlcpy(uri, attr->values[0].string.text, sizeof(uri));
- if ((uriptr = strchr(uri, ':')) != NULL && strncmp(uriptr, "://", 3) == 0)
- *uriptr = '\0';
-
- cgiSetVariable("CURRENT_DEVICE_URI", attr->values[0].string.text);
- cgiSetVariable("CURRENT_DEVICE_SCHEME", uri);
- }
-
+ cgiSetVariable("CUPS_GET_DEVICES_DONE", "1");
cgiStartHTML(title);
cgiCopyTemplateLang("choose-device.tmpl");
cgiEndHTML();
+ cgiEndMultipart();
}
else if (strchr(var, '/') == NULL)
{
if ((var = cgiGetVariable("CURRENT_MAKE")) == NULL)
var = cgiGetVariable("PPD_MAKE");
if (var)
+ {
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
"ppd-make", NULL, var);
+
+ if ((var = cgiGetVariable("CURRENT_MAKE_AND_MODEL")) != NULL)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
+ "ppd-make-and-model", NULL, var);
+ }
else
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes", NULL, "ppd-make");
* Let the user choose a model...
*/
- const char *make_model; /* Current make/model string */
-
-
- if ((make_model = cgiGetVariable("CURRENT_MAKE_AND_MODEL")) != NULL)
- {
- /*
- * Scan for "close" matches...
- */
-
- int match, /* Current match */
- best_match, /* Best match so far */
- count; /* Number of drivers */
- const char *best, /* Best matching string */
- *current; /* Current string */
-
-
- count = cgiGetSize("PPD_MAKE_AND_MODEL");
-
- for (i = 0, best_match = 0, best = NULL; i < count; i ++)
- {
- current = cgiGetArray("PPD_MAKE_AND_MODEL", i);
- match = match_string(make_model, current);
-
- if (match > best_match)
- {
- best_match = match;
- best = current;
- }
- }
-
- if (best_match > strlen(var))
- {
- /*
- * Found a match longer than the make...
- */
-
- cgiSetVariable("CURRENT_MAKE_AND_MODEL", best);
- }
- }
-
cgiStartHTML(title);
+ cgiSetVariable("CURRENT_MAKE_AND_MODEL",
+ cgiGetArray("PPD_MAKE_AND_MODEL", 0));
cgiCopyTemplateLang("choose-model.tmpl");
cgiEndHTML();
}
/* BrowseLocalProtocols */
remote_protocols[255];
/* BrowseRemoteProtocols */
+ const char *current_browse_web_if,
+ /* BrowseWebIF value */
+ *current_preserve_job_history,
+ /* PreserveJobHistory value */
+ *current_preserve_job_files,
+ /* PreserveJobFiles value */
+ *current_max_clients,
+ /* MaxClients value */
+ *current_max_jobs,
+ /* MaxJobs value */
+ *current_max_log_size,
+ /* MaxLogSize value */
+ *current_local_protocols,
+ /* BrowseLocalProtocols */
+ *current_remote_protocols;
+ /* BrowseRemoteProtocols */
#ifdef HAVE_GSSAPI
char default_auth_type[255];
/* DefaultAuthType value */
fprintf(stderr, "DEBUG: DefaultAuthType %s\n", default_auth_type);
#endif /* HAVE_GSSAPI */
+ if ((current_browse_web_if = cupsGetOption("BrowseWebIF", num_settings,
+ settings)) == NULL)
+ current_browse_web_if = "No";
+
+ if ((current_preserve_job_history = cupsGetOption("PreserveJobHistory",
+ num_settings,
+ settings)) == NULL)
+ current_preserve_job_history = "Yes";
+
+ if ((current_preserve_job_files = cupsGetOption("PreserveJobFiles",
+ num_settings,
+ settings)) == NULL)
+ current_preserve_job_files = "No";
+
+ if ((current_max_clients = cupsGetOption("MaxClients", num_settings,
+ settings)) == NULL)
+ current_max_clients = "100";
+
+ if ((current_max_jobs = cupsGetOption("MaxJobs", num_settings,
+ settings)) == NULL)
+ current_max_jobs = "500";
+
+ if ((current_max_log_size = cupsGetOption("MaxLogSize", num_settings,
+ settings)) == NULL)
+ current_max_log_size = "1m";
+
+ if ((current_local_protocols = cupsGetOption("BrowseLocalProtocols",
+ num_settings,
+ settings)) == NULL)
+ current_local_protocols = CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS;
+
+ if ((current_remote_protocols = cupsGetOption("BrowseRemoteProtocols",
+ num_settings,
+ settings)) == NULL)
+ current_remote_protocols = CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS;
+
/*
* See if the settings have changed...
*/
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("MaxClients", num_settings, settings) ||
- strcasecmp(max_clients, "100") ||
- cupsGetOption("MaxJobs", num_settings, settings) ||
- strcasecmp(max_jobs, "500") ||
- cupsGetOption("MaxLogSize", num_settings, settings) ||
- strcasecmp(max_log_size, "1m");
+ changed = strcasecmp(local_protocols, current_local_protocols) ||
+ strcasecmp(remote_protocols, current_remote_protocols) ||
+ strcasecmp(browse_web_if, current_browse_web_if) ||
+ strcasecmp(preserve_job_history, current_preserve_job_history) ||
+ strcasecmp(preserve_job_files, current_preserve_job_files) ||
+ strcasecmp(max_clients, current_max_clients) ||
+ strcasecmp(max_jobs, current_max_jobs) ||
+ strcasecmp(max_log_size, current_max_log_size);
if (changed)
{
* Add advanced settings...
*/
- if (cupsGetOption("BrowseLocalProtocols", num_settings, settings) ||
- strcasecmp(local_protocols, CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS))
+ if (strcasecmp(local_protocols, current_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))
+ if (strcasecmp(remote_protocols, current_remote_protocols))
num_settings = cupsAddOption("BrowseRemoteProtocols", remote_protocols,
num_settings, &settings);
- if (cupsGetOption("BrowseWebIF", num_settings, settings) ||
- strcasecmp(browse_web_if, "No"))
+ if (strcasecmp(browse_web_if, current_browse_web_if))
num_settings = cupsAddOption("BrowseWebIF", browse_web_if,
num_settings, &settings);
- if (cupsGetOption("PreserveJobHistory", num_settings, settings) ||
- strcasecmp(preserve_job_history, "Yes"))
+ if (strcasecmp(preserve_job_history, current_preserve_job_history))
num_settings = cupsAddOption("PreserveJobHistory",
preserve_job_history, num_settings,
&settings);
- if (cupsGetOption("PreserveJobFiles", num_settings, settings) ||
- strcasecmp(preserve_job_files, "No"))
+ if (strcasecmp(preserve_job_files, current_preserve_job_files))
num_settings = cupsAddOption("PreserveJobFiles", preserve_job_files,
num_settings, &settings);
- if (cupsGetOption("MaxClients", num_settings, settings) ||
- strcasecmp(max_clients, "100"))
+ if (strcasecmp(max_clients, current_max_clients))
num_settings = cupsAddOption("MaxClients", max_clients, num_settings,
&settings);
- if (cupsGetOption("MaxJobs", num_settings, settings) ||
- strcasecmp(max_jobs, "500"))
+ if (strcasecmp(max_jobs, current_max_jobs))
num_settings = cupsAddOption("MaxJobs", max_jobs, num_settings,
&settings);
- if (cupsGetOption("MaxLogSize", num_settings, settings) ||
- strcasecmp(max_log_size, "1m"))
+ if (strcasecmp(max_log_size, current_max_log_size))
num_settings = cupsAddOption("MaxLogSize", max_log_size, num_settings,
&settings);
}
}
else
{
- cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect");
+ if (advanced)
+ cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&URL=/admin/?ADVANCEDSETTINGS=YES");
+ else
+ cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect");
cgiStartHTML(cgiText(_("Change Settings")));
cgiCopyTemplateLang("restart.tmpl");
}
}
-/*
- * 'do_printer_op()' - Do a printer operation.
- */
-
-static void
-do_printer_op(http_t *http, /* I - HTTP connection */
- ipp_op_t op, /* I - Operation to perform */
- const char *title) /* I - Title of page */
-{
- ipp_t *request; /* IPP request */
- char uri[HTTP_MAX_URI]; /* Printer URI */
- const char *printer, /* Printer name (purge-jobs) */
- *is_class; /* Is a class? */
-
-
- is_class = cgiGetVariable("IS_CLASS");
- printer = cgiGetVariable("PRINTER_NAME");
-
- if (!printer)
- {
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
- cgiStartHTML(title);
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
- return;
- }
-
- /*
- * Build a printer request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- */
-
- request = ippNewRequest(op);
-
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
- printer);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
-
- /*
- * Do the request and get back a response...
- */
-
- ippDelete(cupsDoRequest(http, request, "/admin/"));
-
- if (cupsLastError() == IPP_NOT_AUTHORIZED)
- {
- puts("Status: 401\n");
- exit(0);
- }
- else if (cupsLastError() > IPP_OK_CONFLICT)
- {
- cgiStartHTML(title);
- cgiShowIPPError(_("Unable to change printer:"));
- }
- else
- {
- /*
- * Redirect successful updates back to the printer page...
- */
-
- char url[1024], /* Printer/class URL */
- refresh[1024]; /* Refresh URL */
-
-
- cgiRewriteURL(uri, url, sizeof(url), NULL);
- cgiFormEncode(uri, url, sizeof(uri));
- snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s", uri);
- cgiSetVariable("refresh_page", refresh);
-
- cgiStartHTML(title);
-
- if (op == IPP_PAUSE_PRINTER)
- cgiCopyTemplateLang("printer-stop.tmpl");
- else if (op == IPP_RESUME_PRINTER)
- cgiCopyTemplateLang("printer-start.tmpl");
- else if (op == CUPS_ACCEPT_JOBS)
- cgiCopyTemplateLang("printer-accept.tmpl");
- else if (op == CUPS_REJECT_JOBS)
- cgiCopyTemplateLang("printer-reject.tmpl");
- else if (op == IPP_PURGE_JOBS)
- cgiCopyTemplateLang("printer-purge.tmpl");
- else if (op == CUPS_SET_DEFAULT)
- cgiCopyTemplateLang("printer-default.tmpl");
- }
-
- cgiEndHTML();
-}
-
-
/*
* 'do_set_allowed_users()' - Set the allowed/denied users for a queue.
*/
}
+/*
+ * 'do_set_default()' - Set the server default printer/class.
+ */
+
+static void
+do_set_default(http_t *http) /* I - HTTP connection */
+{
+ const char *title; /* Page title */
+ ipp_t *request; /* IPP request */
+ char uri[HTTP_MAX_URI]; /* Printer URI */
+ const char *printer, /* Printer name (purge-jobs) */
+ *is_class; /* Is a class? */
+
+
+ is_class = cgiGetVariable("IS_CLASS");
+ printer = cgiGetVariable("PRINTER_NAME");
+ title = cgiText(_("Set As Server Default"));
+
+ if (!printer)
+ {
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ return;
+ }
+
+ /*
+ * Build a printer request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNewRequest(CUPS_SET_DEFAULT);
+
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
+ printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
+
+ if (cupsLastError() == IPP_NOT_AUTHORIZED)
+ {
+ puts("Status: 401\n");
+ exit(0);
+ }
+ else if (cupsLastError() > IPP_OK_CONFLICT)
+ {
+ cgiStartHTML(title);
+ cgiShowIPPError(_("Unable to set server default:"));
+ }
+ else
+ {
+ /*
+ * Redirect successful updates back to the printer page...
+ */
+
+ char url[1024], /* Printer/class URL */
+ refresh[1024]; /* Refresh URL */
+
+
+ cgiRewriteURL(uri, url, sizeof(url), NULL);
+ cgiFormEncode(uri, url, sizeof(uri));
+ snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s", uri);
+ cgiSetVariable("refresh_page", refresh);
+
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("printer-default.tmpl");
+ }
+
+ cgiEndHTML();
+}
+
+
/*
* 'do_set_options()' - Configure the default options for a queue.
*/
if (cgiGetVariable("AUTOCONFIGURE"))
{
- int job_id; /* Command file job */
- char refresh[1024]; /* Refresh URL */
- http_status_t status; /* Document status */
- static const char *autoconfigure =/* Command file */
- "#CUPS-COMMAND\n"
- "AutoConfigure\n";
-
-
- if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer, "Auto-Configure",
- 0, NULL)) < 1)
- {
- cgiSetVariable("ERROR", cgiText(_("Unable to send auto-configure command "
- "to printer driver!")));
- cgiStartHTML(title);
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
- return;
- }
-
- status = cupsStartDocument(CUPS_HTTP_DEFAULT, printer, job_id,
- "AutoConfigure.command", CUPS_FORMAT_COMMAND, 1);
- if (status == HTTP_CONTINUE)
- status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, autoconfigure,
- strlen(autoconfigure));
- if (status == HTTP_CONTINUE)
- cupsFinishDocument(CUPS_HTTP_DEFAULT, printer);
-
- if (cupsLastError() >= IPP_REDIRECTION_OTHER_SITE)
- {
- cgiSetVariable("ERROR", cupsLastErrorString());
- cgiStartHTML(title);
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
-
- cupsCancelJob(printer, job_id);
- return;
- }
-
- /*
- * Redirect successful updates back to the printer page...
- */
-
- cgiFormEncode(uri, printer, sizeof(uri));
- snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=/%s/%s",
- is_class ? "classes" : "printers", uri);
- cgiSetVariable("refresh_page", refresh);
-
- cgiStartHTML(title);
-
- cgiCopyTemplateLang("printer-configured.tmpl");
- cgiEndHTML();
+ cgiPrintCommand(http, printer, "AutoConfigure", "Set Default Options");
return;
}
fputs("DEBUG: Showing options...\n", stderr);
+ /*
+ * Show auto-configure button if supported...
+ */
+
if (ppd)
{
if (ppd->num_filters == 0 ||
}
}
+ /*
+ * Get the printer attributes...
+ */
+
+ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
+
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, "/printers/%s", printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ response = cupsDoRequest(http, request, "/");
+
+ /*
+ * List the groups used as "tabs"...
+ */
+
+ i = 0;
+
+ if (ppd)
+ {
+ for (group = ppd->groups;
+ i < ppd->num_groups;
+ i ++, group ++)
+ {
+ cgiSetArray("GROUP_ID", i, group->name);
+
+ if (!strcmp(group->name, "InstallableOptions"))
+ cgiSetArray("GROUP", i, cgiText(_("Options Installed")));
+ else
+ cgiSetArray("GROUP", i, group->text);
+ }
+ }
+
+ if (ippFindAttribute(response, "job-sheets-supported", IPP_TAG_ZERO))
+ {
+ cgiSetArray("GROUP_ID", i, "CUPS_BANNERS");
+ cgiSetArray("GROUP", i ++, cgiText(_("Banners")));
+ }
+
+ if (ippFindAttribute(response, "printer-error-policy-supported",
+ IPP_TAG_ZERO) ||
+ ippFindAttribute(response, "printer-op-policy-supported",
+ IPP_TAG_ZERO))
+ {
+ cgiSetArray("GROUP_ID", i, "CUPS_POLICIES");
+ cgiSetArray("GROUP", i ++, cgiText(_("Policies")));
+ }
+
+ if ((attr = ippFindAttribute(response, "port-monitor-supported",
+ IPP_TAG_NAME)) != NULL && attr->num_values > 1)
+ {
+ cgiSetArray("GROUP_ID", i, "CUPS_PORT_MONITOR");
+ cgiSetArray("GROUP", i, cgiText(_("Port Monitor")));
+ }
+
cgiStartHTML(cgiText(_("Set Printer Options")));
cgiCopyTemplateLang("set-printer-options-header.tmpl");
i > 0;
i --, group ++)
{
+ cgiSetVariable("GROUP_ID", group->name);
+
if (!strcmp(group->name, "InstallableOptions"))
cgiSetVariable("GROUP", cgiText(_("Options Installed")));
else
}
}
- /*
- * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
- * following attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- */
+ if ((attr = ippFindAttribute(response, "job-sheets-supported",
+ IPP_TAG_ZERO)) != NULL)
+ {
+ /*
+ * Add the job sheets options...
+ */
- request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
+ cgiSetVariable("GROUP_ID", "CUPS_BANNERS");
+ cgiSetVariable("GROUP", cgiText(_("Banners")));
+ cgiCopyTemplateLang("option-header.tmpl");
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, "/printers/%s", printer);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
+ cgiSetSize("CHOICES", attr->num_values);
+ cgiSetSize("TEXT", attr->num_values);
+ for (k = 0; k < attr->num_values; k ++)
+ {
+ cgiSetArray("CHOICES", k, attr->values[k].string.text);
+ cgiSetArray("TEXT", k, attr->values[k].string.text);
+ }
- /*
- * Do the request and get back a response...
- */
+ attr = ippFindAttribute(response, "job-sheets-default", IPP_TAG_ZERO);
- if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ cgiSetVariable("KEYWORD", "job_sheets_start");
+ cgiSetVariable("KEYTEXT", cgiText(_("Starting Banner")));
+ cgiSetVariable("DEFCHOICE", attr != NULL ?
+ attr->values[0].string.text : "");
+
+ cgiCopyTemplateLang("option-pickone.tmpl");
+
+ cgiSetVariable("KEYWORD", "job_sheets_end");
+ cgiSetVariable("KEYTEXT", cgiText(_("Ending Banner")));
+ cgiSetVariable("DEFCHOICE", attr != NULL && attr->num_values > 1 ?
+ attr->values[1].string.text : "");
+
+ cgiCopyTemplateLang("option-pickone.tmpl");
+
+ cgiCopyTemplateLang("option-trailer.tmpl");
+ }
+
+ if (ippFindAttribute(response, "printer-error-policy-supported",
+ IPP_TAG_ZERO) ||
+ ippFindAttribute(response, "printer-op-policy-supported",
+ IPP_TAG_ZERO))
{
- if ((attr = ippFindAttribute(response, "job-sheets-supported",
- IPP_TAG_ZERO)) != NULL)
- {
- /*
- * Add the job sheets options...
- */
+ /*
+ * Add the error and operation policy options...
+ */
- cgiSetVariable("GROUP", cgiText(_("Banners")));
- cgiCopyTemplateLang("option-header.tmpl");
+ cgiSetVariable("GROUP_ID", "CUPS_POLICIES");
+ cgiSetVariable("GROUP", cgiText(_("Policies")));
+ cgiCopyTemplateLang("option-header.tmpl");
+
+ /*
+ * Error policy...
+ */
+ attr = ippFindAttribute(response, "printer-error-policy-supported",
+ IPP_TAG_ZERO);
+
+ if (attr)
+ {
cgiSetSize("CHOICES", attr->num_values);
cgiSetSize("TEXT", attr->num_values);
for (k = 0; k < attr->num_values; k ++)
cgiSetArray("TEXT", k, attr->values[k].string.text);
}
- attr = ippFindAttribute(response, "job-sheets-default", IPP_TAG_ZERO);
-
- cgiSetVariable("KEYWORD", "job_sheets_start");
- cgiSetVariable("KEYTEXT", cgiText(_("Starting Banner")));
- cgiSetVariable("DEFCHOICE", attr != NULL ?
- attr->values[0].string.text : "");
+ attr = ippFindAttribute(response, "printer-error-policy",
+ IPP_TAG_ZERO);
- cgiCopyTemplateLang("option-pickone.tmpl");
-
- cgiSetVariable("KEYWORD", "job_sheets_end");
- cgiSetVariable("KEYTEXT", cgiText(_("Ending Banner")));
- cgiSetVariable("DEFCHOICE", attr != NULL && attr->num_values > 1 ?
- attr->values[1].string.text : "");
-
- cgiCopyTemplateLang("option-pickone.tmpl");
-
- cgiCopyTemplateLang("option-trailer.tmpl");
+ cgiSetVariable("KEYWORD", "printer_error_policy");
+ cgiSetVariable("KEYTEXT", cgiText(_("Error Policy")));
+ cgiSetVariable("DEFCHOICE", attr == NULL ?
+ "" : attr->values[0].string.text);
}
- if (ippFindAttribute(response, "printer-error-policy-supported",
- IPP_TAG_ZERO) ||
- ippFindAttribute(response, "printer-op-policy-supported",
- IPP_TAG_ZERO))
- {
- /*
- * Add the error and operation policy options...
- */
-
- cgiSetVariable("GROUP", cgiText(_("Policies")));
- cgiCopyTemplateLang("option-header.tmpl");
+ cgiCopyTemplateLang("option-pickone.tmpl");
- /*
- * Error policy...
- */
+ /*
+ * Operation policy...
+ */
- attr = ippFindAttribute(response, "printer-error-policy-supported",
- IPP_TAG_ZERO);
+ attr = ippFindAttribute(response, "printer-op-policy-supported",
+ IPP_TAG_ZERO);
- if (attr)
+ if (attr)
+ {
+ cgiSetSize("CHOICES", attr->num_values);
+ cgiSetSize("TEXT", attr->num_values);
+ for (k = 0; k < attr->num_values; k ++)
{
- cgiSetSize("CHOICES", attr->num_values);
- cgiSetSize("TEXT", attr->num_values);
- for (k = 0; k < attr->num_values; k ++)
- {
- cgiSetArray("CHOICES", k, attr->values[k].string.text);
- cgiSetArray("TEXT", k, attr->values[k].string.text);
- }
+ cgiSetArray("CHOICES", k, attr->values[k].string.text);
+ cgiSetArray("TEXT", k, attr->values[k].string.text);
+ }
- attr = ippFindAttribute(response, "printer-error-policy",
- IPP_TAG_ZERO);
+ attr = ippFindAttribute(response, "printer-op-policy", IPP_TAG_ZERO);
- cgiSetVariable("KEYWORD", "printer_error_policy");
- cgiSetVariable("KEYTEXT", cgiText(_("Error Policy")));
- cgiSetVariable("DEFCHOICE", attr == NULL ?
- "" : attr->values[0].string.text);
- }
+ cgiSetVariable("KEYWORD", "printer_op_policy");
+ cgiSetVariable("KEYTEXT", cgiText(_("Operation Policy")));
+ cgiSetVariable("DEFCHOICE", attr == NULL ?
+ "" : attr->values[0].string.text);
cgiCopyTemplateLang("option-pickone.tmpl");
-
- /*
- * Operation policy...
- */
-
- attr = ippFindAttribute(response, "printer-op-policy-supported",
- IPP_TAG_ZERO);
-
- if (attr)
- {
- cgiSetSize("CHOICES", attr->num_values);
- cgiSetSize("TEXT", attr->num_values);
- for (k = 0; k < attr->num_values; k ++)
- {
- cgiSetArray("CHOICES", k, attr->values[k].string.text);
- cgiSetArray("TEXT", k, attr->values[k].string.text);
- }
-
- attr = ippFindAttribute(response, "printer-op-policy", IPP_TAG_ZERO);
-
- cgiSetVariable("KEYWORD", "printer_op_policy");
- cgiSetVariable("KEYTEXT", cgiText(_("Operation Policy")));
- cgiSetVariable("DEFCHOICE", attr == NULL ?
- "" : attr->values[0].string.text);
-
- cgiCopyTemplateLang("option-pickone.tmpl");
- }
-
- cgiCopyTemplateLang("option-trailer.tmpl");
}
- ippDelete(response);
+ cgiCopyTemplateLang("option-trailer.tmpl");
}
/*
* Binary protocol support...
*/
- if (ppd && ppd->protocols && strstr(ppd->protocols, "BCP"))
+ if ((attr = ippFindAttribute(response, "port-monitor-supported",
+ IPP_TAG_NAME)) != NULL && attr->num_values > 1)
{
- ppdattr = ppdFindAttr(ppd, "cupsProtocol", NULL);
+ cgiSetVariable("GROUP_ID", "CUPS_PORT_MONITOR");
+ cgiSetVariable("GROUP", cgiText(_("Port Monitor")));
- cgiSetVariable("GROUP", cgiText(_("PS Binary Protocol")));
- cgiCopyTemplateLang("option-header.tmpl");
+ cgiSetSize("CHOICES", attr->num_values);
+ cgiSetSize("TEXT", attr->num_values);
- cgiSetSize("CHOICES", 2);
- cgiSetSize("TEXT", 2);
- cgiSetArray("CHOICES", 0, "None");
- cgiSetArray("TEXT", 0, cgiText(_("None")));
-
- if (strstr(ppd->protocols, "TBCP"))
- {
- cgiSetArray("CHOICES", 1, "TBCP");
- cgiSetArray("TEXT", 1, "TBCP");
- }
- else
+ for (i = 0; i < attr->num_values; i ++)
{
- cgiSetArray("CHOICES", 1, "BCP");
- cgiSetArray("TEXT", 1, "BCP");
+ cgiSetArray("CHOICES", i, attr->values[i].string.text);
+ cgiSetArray("TEXT", i, attr->values[i].string.text);
}
- cgiSetVariable("KEYWORD", "protocol");
- cgiSetVariable("KEYTEXT", cgiText(_("PS Binary Protocol")));
- cgiSetVariable("DEFCHOICE", ppdattr ? ppdattr->value : "None");
+ attr = ippFindAttribute(response, "port-monitor", IPP_TAG_NAME);
+ cgiSetVariable("KEYWORD", "port_monitor");
+ cgiSetVariable("KEYTEXT", cgiText(_("Port Monitor")));
+ cgiSetVariable("DEFCHOICE", attr ? attr->values[0].string.text : "none");
+ cgiCopyTemplateLang("option-header.tmpl");
cgiCopyTemplateLang("option-pickone.tmpl");
-
cgiCopyTemplateLang("option-trailer.tmpl");
}
cgiCopyTemplateLang("set-printer-options-trailer.tmpl");
cgiEndHTML();
+
+ ippDelete(response);
}
else
{
while (cupsFileGets(in, line, sizeof(line)))
{
- if (!strncmp(line, "*cupsProtocol:", 14) && cgiGetVariable("protocol"))
+ if (!strncmp(line, "*cupsProtocol:", 14))
continue;
else if (strncmp(line, "*Default", 8))
cupsFilePrintf(out, "%s\n", line);
}
}
- /*
- * TODO: We need to set the port-monitor attribute!
- */
-
- if ((var = cgiGetVariable("protocol")) != NULL)
- cupsFilePrintf(out, "*cupsProtocol: %s\n", var);
-
cupsFileClose(in);
cupsFileClose(out);
}
ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
"printer-op-policy", NULL, var);
+ if ((var = cgiGetVariable("port_monitor")) != NULL)
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "port-monitor", NULL, var);
+
/*
* Do the request and get back a response...
*/
/*
- * 'match_string()' - Return the number of matching characters.
- */
-
-static int /* O - Number of matching characters */
-match_string(const char *a, /* I - First string */
- const char *b) /* I - Second string */
-{
- int count; /* Number of matching characters */
-
-
- /*
- * Loop through both strings until we hit the end of either or we find
- * a non-matching character. For the purposes of comparison, we ignore
- * whitespace and do a case-insensitive comparison so that we have a
- * better chance of finding a match...
- */
-
- for (count = 0; *a && *b; a++, b++, count ++)
- {
- /*
- * Skip leading whitespace characters...
- */
-
- while (isspace(*a & 255))
- a ++;
-
- while (isspace(*b & 255))
- b ++;
-
- /*
- * Break out if we run out of characters...
- */
-
- if (!*a || !*b)
- break;
-
- /*
- * Do a case-insensitive comparison of the next two chars...
- */
-
- if (tolower(*a & 255) != tolower(*b & 255))
- break;
- }
-
- return (count);
-}
-
-
-/*
- * End of "$Id: admin.c 7888 2008-08-29 21:16:56Z mike $".
+ * End of "$Id: admin.c 8029 2008-10-08 21:07:45Z mike $".
*/
*
* CGI support library definitions.
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
extern void cgiCopyTemplateLang(const char *tmpl);
extern int cgiDoSearch(void *search, const char *text);
extern void cgiEndHTML(void);
+extern void cgiEndMultipart(void);
extern char *cgiFormEncode(char *dst, const char *src, size_t dstsize);
extern void cgiFreeSearch(void *search);
extern const char *cgiGetArray(const char *name, int element);
extern int cgiInitialize(void);
extern int cgiIsPOST(void);
extern void cgiMoveJobs(http_t *http, const char *dest, int job_id);
+extern void cgiPrintCommand(http_t *http, const char *dest,
+ const char *command, const char *title);
extern void cgiPrintTestPage(http_t *http, const char *dest);
extern char *cgiRewriteURL(const char *uri, char *url, int urlsize,
const char *newresource);
extern void cgiShowIPPError(const char *message);
extern void cgiShowJobs(http_t *http, const char *dest);
extern void cgiStartHTML(const char *title);
+extern void cgiStartMultipart(void);
extern const char *cgiText(const char *message);
#endif /* !_CUPS_CGI_H_ */
*
* Contents:
*
- * main() - Main entry for CGI.
- * show_all_classes() - Show all classes...
- * show_class() - Show a single class.
*/
/*
* Local functions...
*/
-void show_all_classes(http_t *http, const char *username);
-void show_class(http_t *http, const char *printer);
+static void do_class_op(http_t *http, const char *printer, ipp_op_t op,
+ const char *title);
+static void show_all_classes(http_t *http, const char *username);
+static void show_class(http_t *http, const char *printer);
/*
if (!*pclass)
pclass = NULL;
+
+ if (pclass)
+ cgiSetVariable("PRINTER_NAME", pclass);
}
/*
else
show_class(http, pclass);
}
- else if (!strcasecmp(op, "print-test-page") && pclass)
- cgiPrintTestPage(http, pclass);
- else if (!strcasecmp(op, "move-jobs") && pclass)
- cgiMoveJobs(http, pclass, 0);
+ else if (pclass)
+ {
+ if (!strcmp(op, "start-class"))
+ do_class_op(http, pclass, IPP_RESUME_PRINTER, cgiText(_("Resume Class")));
+ else if (!strcmp(op, "stop-class"))
+ do_class_op(http, pclass, IPP_PAUSE_PRINTER, cgiText(_("Pause Class")));
+ else if (!strcmp(op, "accept-jobs"))
+ do_class_op(http, pclass, CUPS_ACCEPT_JOBS, cgiText(_("Accept Jobs")));
+ else if (!strcmp(op, "reject-jobs"))
+ do_class_op(http, pclass, CUPS_REJECT_JOBS, cgiText(_("Reject Jobs")));
+ else if (!strcmp(op, "purge-jobs"))
+ do_class_op(http, pclass, IPP_PURGE_JOBS, cgiText(_("Purge Jobs")));
+ else if (!strcasecmp(op, "print-test-page"))
+ cgiPrintTestPage(http, pclass);
+ else if (!strcasecmp(op, "move-jobs"))
+ cgiMoveJobs(http, pclass, 0);
+ else
+ {
+ /*
+ * Unknown/bad operation...
+ */
+
+ cgiStartHTML(pclass);
+ cgiCopyTemplateLang("error-op.tmpl");
+ cgiEndHTML();
+ }
+ }
else
{
/*
* Unknown/bad operation...
*/
- if (pclass)
- cgiStartHTML(pclass);
- else
- cgiStartHTML(cgiText(_("Classes")));
-
+ cgiStartHTML(cgiText(_("Classes")));
cgiCopyTemplateLang("error-op.tmpl");
cgiEndHTML();
}
}
+/*
+ * 'do_class_op()' - Do a class operation.
+ */
+
+static void
+do_class_op(http_t *http, /* I - HTTP connection */
+ const char *printer, /* I - Printer name */
+ ipp_op_t op, /* I - Operation to perform */
+ const char *title) /* I - Title of page */
+{
+ ipp_t *request; /* IPP request */
+ char uri[HTTP_MAX_URI], /* Printer URI */
+ resource[HTTP_MAX_URI]; /* Path for request */
+
+
+ /*
+ * Build a printer request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNewRequest(op);
+
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, "/classes/%s", printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ snprintf(resource, sizeof(resource), "/classes/%s", printer);
+ ippDelete(cupsDoRequest(http, request, resource));
+
+ if (cupsLastError() == IPP_NOT_AUTHORIZED)
+ {
+ puts("Status: 401\n");
+ exit(0);
+ }
+ else if (cupsLastError() > IPP_OK_CONFLICT)
+ {
+ cgiStartHTML(title);
+ cgiShowIPPError(_("Unable to do maintenance command:"));
+ }
+ else
+ {
+ /*
+ * Redirect successful updates back to the printer page...
+ */
+
+ char url[1024], /* Printer/class URL */
+ refresh[1024]; /* Refresh URL */
+
+
+ cgiRewriteURL(uri, url, sizeof(url), NULL);
+ cgiFormEncode(uri, url, sizeof(uri));
+ snprintf(refresh, sizeof(refresh), "5;URL=%s", uri);
+ cgiSetVariable("refresh_page", refresh);
+
+ cgiStartHTML(title);
+
+ cgiSetVariable("IS_CLASS", "YES");
+
+ if (op == IPP_PAUSE_PRINTER)
+ cgiCopyTemplateLang("printer-stop.tmpl");
+ else if (op == IPP_RESUME_PRINTER)
+ cgiCopyTemplateLang("printer-start.tmpl");
+ else if (op == CUPS_ACCEPT_JOBS)
+ cgiCopyTemplateLang("printer-accept.tmpl");
+ else if (op == CUPS_REJECT_JOBS)
+ cgiCopyTemplateLang("printer-reject.tmpl");
+ else if (op == IPP_PURGE_JOBS)
+ cgiCopyTemplateLang("printer-purge.tmpl");
+ }
+
+ cgiEndHTML();
+}
+
+
/*
* 'show_all_classes()' - Show all classes...
*/
-void
+static void
show_all_classes(http_t *http, /* I - Connection to server */
const char *user) /* I - Username */
{
* 'show_class()' - Show a single class.
*/
-void
+static void
show_class(http_t *http, /* I - Connection to server */
const char *pclass) /* I - Name of class */
{
* Show the class status...
*/
- cgiSetVariable("_SINGLE_DEST", "1");
cgiCopyTemplateLang("class.tmpl");
/*
*
* HTML support functions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
*
* Contents:
*
- * cgiEndHTML() - End a HTML page.
- * cgiFormEncode() - Encode a string as a form variable...
- * cgiStartHTML() - Start a HTML page.
- * cgi_null_passwd() - Return a NULL password for authentication.
+ * cgiEndHTML() - End a HTML page.
+ * cgiEndMultipart() - End the delivery of a multipart web page.
+ * cgiFormEncode() - Encode a string as a form variable...
+ * cgiStartHTML() - Start a HTML page.
+ * cgiStartMultipart() - Start a multipart delivery of a web page...
+ * cgi_null_passwd() - Return a NULL password for authentication.
*/
/*
#include "cgi-private.h"
+/*
+ * Local globals...
+ */
+
+static const char *cgi_multipart = NULL;
+ /* Multipart separator, if any */
+
+
/*
* Local functions...
*/
}
+/*
+ * 'cgiEndMultipart()' - End the delivery of a multipart web page.
+ */
+
+void
+cgiEndMultipart(void)
+{
+ if (cgi_multipart)
+ printf("\n%s--\n", cgi_multipart);
+}
+
+
/*
* 'cgiFormEncode()' - Encode a string as a form variable...
*/
* Tell the client to expect UTF-8 encoded HTML...
*/
+ if (cgi_multipart)
+ puts(cgi_multipart);
+
puts("Content-Type: text/html;charset=utf-8\n");
/*
}
+/*
+ * 'cgiStartMultipart()' - Start a multipart delivery of a web page...
+ */
+
+void
+cgiStartMultipart(void)
+{
+ puts("MIME-Version: 1.0");
+ puts("Content-Type: multipart/x-mixed-replace; boundary=\"CUPS-MULTIPART\"\n");
+ cgi_multipart = "--CUPS-MULTIPART";
+}
+
+
/*
* 'cgi_null_passwd()' - Return a NULL password for authentication.
*/
*
* Contents:
*
- * cgiGetAttributes() - Get the list of attributes that are needed
- * by the template file.
+ * cgiGetAttributes() - Get the list of attributes that are needed by the
+ * template file.
* cgiGetIPPObjects() - Get the objects in an IPP response.
* cgiMoveJobs() - Move one or more jobs.
+ * cgiPrintCommand() - Print a CUPS command job.
* cgiPrintTestPage() - Print a test page.
* cgiRewriteURL() - Rewrite a printer URI into a web browser URL...
* cgiSetIPPObjectVars() - Set CGI variables from an IPP object.
*/
for (nameptr = name; (ch = getc(in)) != EOF;)
- if (strchr("}]<>=! \t\n", ch))
+ if (strchr("}]<>=!~ \t\n", ch))
break;
else if (nameptr > name && ch == '?')
break;
}
+/*
+ * 'cgiPrintCommand()' - Print a CUPS command job.
+ */
+
+void
+cgiPrintCommand(http_t *http, /* I - Connection to server */
+ const char *dest, /* I - Destination printer */
+ const char *command, /* I - Command to send */
+ const char *title) /* I - Page/job title */
+{
+ int job_id; /* Command file job */
+ char uri[HTTP_MAX_URI], /* Job URI */
+ resource[1024], /* Printer resource path */
+ refresh[1024], /* Refresh URL */
+ command_file[1024]; /* Command "file" */
+ http_status_t status; /* Document status */
+ cups_option_t hold_option; /* job-hold-until option */
+ const char *user; /* User name */
+ ipp_t *request, /* Get-Job-Attributes request */
+ *response; /* Get-Job-Attributes response */
+ ipp_attribute_t *attr; /* Current job attribute */
+ static const char const *job_attrs[] =/* Job attributes we want */
+ {
+ "job-state",
+ "job-printer-state-message"
+ };
+
+
+ /*
+ * Create the CUPS command file...
+ */
+
+ snprintf(command_file, sizeof(command_file), "#CUPS-COMMAND\n%s\n", command);
+
+ /*
+ * Show status...
+ */
+
+ cgiStartMultipart();
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("command.tmpl");
+ cgiEndHTML();
+ fflush(stdout);
+
+ /*
+ * Send the command file job...
+ */
+
+ hold_option.name = "job-hold-until";
+ hold_option.value = "no-hold";
+
+ if ((user = getenv("REMOTE_USER")) != NULL)
+ cupsSetUser(user);
+ else
+ cupsSetUser("anonymous");
+
+ if ((job_id = cupsCreateJob(http, dest, title,
+ 1, &hold_option)) < 1)
+ {
+ cgiSetVariable("MESSAGE", cgiText(_("Unable to send command to printer driver!")));
+ cgiSetVariable("ERROR", cupsLastErrorString());
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ cgiEndMultipart();
+ return;
+ }
+
+ status = cupsStartDocument(http, dest, job_id, NULL, CUPS_FORMAT_COMMAND, 1);
+ if (status == HTTP_CONTINUE)
+ status = cupsWriteRequestData(http, command_file,
+ strlen(command_file));
+ if (status == HTTP_CONTINUE)
+ cupsFinishDocument(http, dest);
+
+ if (cupsLastError() >= IPP_REDIRECTION_OTHER_SITE)
+ {
+ cgiSetVariable("MESSAGE", cgiText(_("Unable to send command to printer driver!")));
+ cgiSetVariable("ERROR", cupsLastErrorString());
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ cgiEndMultipart();
+
+ cupsCancelJob(dest, job_id);
+ return;
+ }
+
+ /*
+ * Wait for the job to complete...
+ */
+
+ for (;;)
+ {
+ /*
+ * Get the current job state...
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
+ request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
+ NULL, uri);
+ if (user)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, user);
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", 2, NULL, job_attrs);
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+
+ attr = ippFindAttribute(response, "job-state", IPP_TAG_ENUM);
+ if (!attr || attr->values[0].integer >= IPP_JOB_STOPPED)
+ {
+ ippDelete(response);
+ break;
+ }
+
+ /*
+ * Job not complete, so update the status...
+ */
+
+ ippDelete(response);
+
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("command.tmpl");
+ cgiEndHTML();
+ fflush(stdout);
+
+ sleep(5);
+ }
+
+ /*
+ * Send the final page that reloads the printer's page...
+ */
+
+ snprintf(resource, sizeof(resource), "/printers/%s", dest);
+
+ cgiFormEncode(uri, resource, sizeof(uri));
+ snprintf(refresh, sizeof(refresh), "5;URL=%s", uri);
+ cgiSetVariable("refresh_page", refresh);
+
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("command.tmpl");
+ cgiEndHTML();
+ cgiEndMultipart();
+}
+
+
/*
* 'cgiPrintTestPage()' - Print a test page.
*/
* attributes-natural-language
* printer-uri
* requesting-user-name
- * document-format
*/
request = ippNewRequest(IPP_PRINT_JOB);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
NULL, "Test Page");
- ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
- NULL, "application/postscript");
-
/*
* Do the request and get back a response...
*/
_cgiCopyTemplateLang
_cgiDoSearch
_cgiEndHTML
+_cgiEndMultipart
_cgiFormEncode
_cgiFreeSearch
_cgiGetArray
_cgiInitialize
_cgiIsPOST
_cgiMoveJobs
+_cgiPrintCommand
_cgiPrintTestPage
_cgiRewriteURL
_cgiSetArray
_cgiShowIPPError
_cgiShowJobs
_cgiStartHTML
+_cgiStartMultipart
_cgiText
_helpDeleteIndex
_helpFindNode
*
* Contents:
*
- * main() - Main entry for CGI.
- * print_command() - Send a print command to the printer.
- * show_all_printers() - Show all printers...
- * show_printer() - Show a single printer.
*/
/*
* Local functions...
*/
-void print_command(http_t *http, const char *printer, const char *command);
-void show_all_printers(http_t *http, const char *username);
-void show_printer(http_t *http, const char *printer);
+static void do_printer_op(http_t *http, const char *printer, ipp_op_t op,
+ const char *title);
+static void show_all_printers(http_t *http, const char *username);
+static void show_printer(http_t *http, const char *printer);
/*
if (!*printer)
printer = NULL;
+
+ if (printer)
+ cgiSetVariable("PRINTER_NAME", printer);
}
/*
else
show_printer(http, printer);
}
- else if (!strcasecmp(op, "print-self-test-page") && printer)
- print_command(http, printer, "PrintSelfTestPage");
- else if (!strcasecmp(op, "clean-print-heads") && printer)
- print_command(http, printer, "Clean all");
- else if (!strcasecmp(op, "print-test-page") && printer)
- cgiPrintTestPage(http, printer);
- else if (!strcasecmp(op, "move-jobs") && printer)
- cgiMoveJobs(http, printer, 0);
+ else if (printer)
+ {
+ if (!strcmp(op, "start-printer"))
+ do_printer_op(http, printer, IPP_RESUME_PRINTER,
+ cgiText(_("Resume Printer")));
+ else if (!strcmp(op, "stop-printer"))
+ do_printer_op(http, printer, IPP_PAUSE_PRINTER,
+ cgiText(_("Pause Printer")));
+ else if (!strcmp(op, "accept-jobs"))
+ do_printer_op(http, printer, CUPS_ACCEPT_JOBS, cgiText(_("Accept Jobs")));
+ else if (!strcmp(op, "reject-jobs"))
+ do_printer_op(http, printer, CUPS_REJECT_JOBS, cgiText(_("Reject Jobs")));
+ else if (!strcmp(op, "purge-jobs"))
+ do_printer_op(http, printer, IPP_PURGE_JOBS, cgiText(_("Purge Jobs")));
+ else if (!strcasecmp(op, "print-self-test-page"))
+ cgiPrintCommand(http, printer, "PrintSelfTestPage",
+ cgiText(_("Print Self-Test Page")));
+ else if (!strcasecmp(op, "clean-print-heads"))
+ cgiPrintCommand(http, printer, "Clean all",
+ cgiText(_("Clean Print Heads")));
+ else if (!strcasecmp(op, "print-test-page"))
+ cgiPrintTestPage(http, printer);
+ else if (!strcasecmp(op, "move-jobs"))
+ cgiMoveJobs(http, printer, 0);
+ else
+ {
+ /*
+ * Unknown/bad operation...
+ */
+
+ cgiStartHTML(printer);
+ cgiCopyTemplateLang("error-op.tmpl");
+ cgiEndHTML();
+ }
+ }
else
{
/*
* Unknown/bad operation...
*/
- if (printer)
- cgiStartHTML(printer);
- else
- cgiStartHTML(cgiText(_("Printers")));
-
+ cgiStartHTML(cgiText(_("Printers")));
cgiCopyTemplateLang("error-op.tmpl");
cgiEndHTML();
}
/*
- * 'print_command()' - Send a print command to the printer.
+ * 'do_printer_op()' - Do a printer operation.
*/
-void
-print_command(http_t *http, /* I - Connection to server */
- const char *printer, /* I - Printer */
- const char *command) /* I - Command to send */
+static void
+do_printer_op(http_t *http, /* I - HTTP connection */
+ const char *printer, /* I - Printer name */
+ ipp_op_t op, /* I - Operation to perform */
+ const char *title) /* I - Title of page */
{
- cups_file_t *fp; /* File pointer */
- char filename[1024]; /* Temporary file */
- ipp_t *request, /* IPP request */
- *response; /* IPP response */
+ ipp_t *request; /* IPP request */
char uri[HTTP_MAX_URI], /* Printer URI */
- resource[1024], /* POST resource path */
- refresh[1024]; /* Refresh URL */
- const char *user; /* Username */
-
-
- /*
- * See who is logged in...
- */
-
- if ((user = getenv("REMOTE_USER")) == NULL)
- user = "guest";
-
- /*
- * Create the CUPS command file to print...
- */
-
- if ((fp = cupsTempFile2(filename, sizeof(filename))) == NULL)
- {
- cgiStartHTML(cgiText(_("Printer Maintenance")));
- cgiSetVariable("MESSAGE", _("Unable to create temporary file:"));
- cgiSetVariable("ERROR", strerror(errno));
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
- return;
- }
-
- cupsFilePuts(fp, "#CUPS-COMMAND\n");
- cupsFilePrintf(fp, "%s\n", command);
- cupsFileClose(fp);
-
- /*
- * Point to the printer...
- */
-
- snprintf(resource, sizeof(resource), "/printers/%s", printer);
+ resource[HTTP_MAX_URI]; /* Path for request */
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", ippPort(), "/printers/%s", printer);
/*
- * Build an IPP_PRINT_JOB request, which requires the following
+ * Build a printer request, which requires the following
* attributes:
*
* attributes-charset
* attributes-natural-language
* printer-uri
- * requesting-user-name
- * document-format
*/
- request = ippNewRequest(IPP_PRINT_JOB);
+ request = ippNewRequest(op);
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, "/printers/%s", printer);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requesting-user-name", NULL, user);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
- NULL, "Printer Maintenance");
-
- ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
- NULL, "application/postscript");
-
/*
* Do the request and get back a response...
*/
- if ((response = cupsDoFileRequest(http, request, resource,
- filename)) != NULL)
- {
- cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+ snprintf(resource, sizeof(resource), "/printers/%s", printer);
+ ippDelete(cupsDoRequest(http, request, resource));
- ippDelete(response);
+ if (cupsLastError() == IPP_NOT_AUTHORIZED)
+ {
+ puts("Status: 401\n");
+ exit(0);
}
-
- unlink(filename);
-
- if (cupsLastError() <= IPP_OK_CONFLICT)
+ else if (cupsLastError() > IPP_OK_CONFLICT)
+ {
+ cgiStartHTML(title);
+ cgiShowIPPError(_("Unable to do maintenance command:"));
+ }
+ else
{
/*
- * Automatically reload the printer status page...
+ * Redirect successful updates back to the printer page...
*/
- cgiFormEncode(uri, resource, sizeof(uri));
- snprintf(refresh, sizeof(refresh), "2;URL=%s", uri);
- cgiSetVariable("refresh_page", refresh);
- }
- else if (cupsLastError() == IPP_NOT_AUTHORIZED)
- {
- puts("Status: 401\n");
- exit(0);
- }
+ char url[1024], /* Printer/class URL */
+ refresh[1024]; /* Refresh URL */
- cgiStartHTML(cgiText(_("Printer Maintenance")));
- if (cupsLastError() > IPP_OK_CONFLICT)
- cgiShowIPPError(_("Unable to send maintenance job:"));
- else
- {
- cgiSetVariable("PRINTER_NAME", printer);
+ cgiRewriteURL(uri, url, sizeof(url), NULL);
+ cgiFormEncode(uri, url, sizeof(uri));
+ snprintf(refresh, sizeof(refresh), "5;URL=q%s", uri);
+ cgiSetVariable("refresh_page", refresh);
- cgiCopyTemplateLang("maintenance.tmpl");
+ cgiStartHTML(title);
+
+ if (op == IPP_PAUSE_PRINTER)
+ cgiCopyTemplateLang("printer-stop.tmpl");
+ else if (op == IPP_RESUME_PRINTER)
+ cgiCopyTemplateLang("printer-start.tmpl");
+ else if (op == CUPS_ACCEPT_JOBS)
+ cgiCopyTemplateLang("printer-accept.tmpl");
+ else if (op == CUPS_REJECT_JOBS)
+ cgiCopyTemplateLang("printer-reject.tmpl");
+ else if (op == IPP_PURGE_JOBS)
+ cgiCopyTemplateLang("printer-purge.tmpl");
}
cgiEndHTML();
* 'show_all_printers()' - Show all printers...
*/
-void
+static void
show_all_printers(http_t *http, /* I - Connection to server */
const char *user) /* I - Username */
{
for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, first);
i < CUPS_PAGE_MAX && printer;
i ++, printer = (ipp_attribute_t *)cupsArrayNext(printers))
- {
cgiSetIPPObjectVars(printer, NULL, i);
-
- cgiSetArray("cupscommand", i, "0");
-
- for (attr = printer; attr; attr = attr->next)
- if (attr->group_tag != IPP_TAG_PRINTER || !attr->name)
- break;
- else if (!strcmp(attr->name, "printer-type"))
- {
- if (attr->values[0].integer & CUPS_PRINTER_COMMANDS)
- cgiSetArray("cupscommand", i, "1");
- break;
- }
- }
}
else
{
for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, count - first - 1);
i < CUPS_PAGE_MAX && printer;
i ++, printer = (ipp_attribute_t *)cupsArrayPrev(printers))
- {
cgiSetIPPObjectVars(printer, NULL, i);
-
- cgiSetArray("cupscommand", i, "0");
-
- for (attr = printer; attr; attr = attr->next)
- if (attr->group_tag == IPP_TAG_ZERO || !attr->name)
- break;
- else if (!strcmp(attr->name, "printer-type"))
- {
- if (attr->values[0].integer & CUPS_PRINTER_COMMANDS)
- cgiSetArray("cupscommand", i, "1");
- break;
- }
- }
}
/*
* 'show_printer()' - Show a single printer.
*/
-void
+static void
show_printer(http_t *http, /* I - Connection to server */
const char *printer) /* I - Name of printer */
{
cgiSetIPPVars(response, NULL, NULL, NULL, 0);
- if ((attr = ippFindAttribute(response, "printer-type",
- IPP_TAG_ENUM)) != NULL)
- {
- cgiSetVariable("cupscommand",
- (attr->values[0].integer & CUPS_PRINTER_COMMANDS) ?
- "1" : "0");
- }
-
if (printer && (attr = ippFindAttribute(response, "printer-state",
IPP_TAG_ENUM)) != NULL &&
attr->values[0].integer == IPP_PRINTER_PROCESSING)
* Show the printer status...
*/
- cgiSetVariable("_SINGLE_DEST", "1");
cgiCopyTemplateLang("printer.tmpl");
/*
if (s > value)
s --;
- while (s >= value && *s == ' ')
+ while (s >= value && isspace(*s & 255))
*s-- = '\0';
/*
image/x-xpixmap application/vnd.cups-postscript 66 imagetops
#image/x-xwindowdump application/vnd.cups-postscript 66 imagetops
image/x-sun-raster application/vnd.cups-postscript 66 imagetops
-application/vnd.cups-banner application/vnd.cups-postscript 33 bannertops
+application/vnd.cups-banner application/postscript 33 bannertops
########################################################################
#
case $uname in
Darwin*)
- FONTS=""
+# FONTS=""
LEGACY_BACKENDS=""
BACKLIBS="$BACKLIBS -framework IOKit"
CUPSDLIBS="$CUPSDLIBS -sectorder __TEXT __text cupsd.order -e start -framework IOKit -framework SystemConfiguration -weak_framework ApplicationServices"
else if ((((in_admin_location || in_conf_location || in_root_location) &&
remote_admin >= 0) ||
(in_root_location && share_printers >= 0)) &&
- (((!strcasecmp(line, "Allow") || !strcasecmp(line, "Deny")) &&
- !strcasecmp(value, "@LOCAL")) ||
+ (!strcasecmp(line, "Allow") || !strcasecmp(line, "Deny") ||
!strcasecmp(line, "Order")))
continue;
else if (in_cancel_job == 2)
}
+/*
+ * 'cupsFilePutConf()' - Write a configuration line.
+ *
+ * This function handles any comment escaping of the value.
+ *
+ * @since CUPS 1.4@
+ */
+
+ssize_t /* O - Number of bytes written or -1 on error */
+cupsFilePutConf(cups_file_t *fp, /* I - CUPS file */
+ const char *directive, /* I - Directive */
+ const char *value) /* I - Value */
+{
+ ssize_t bytes, /* Number of bytes written */
+ temp; /* Temporary byte count */
+ const char *ptr; /* Pointer into value */
+
+
+ if (!fp || !directive || !*directive)
+ return (-1);
+
+ if ((bytes = cupsFilePuts(fp, directive)) < 0)
+ return (-1);
+
+ if (cupsFilePutChar(fp, ' ') < 0)
+ return (-1);
+ bytes ++;
+
+ if (value && *value)
+ {
+ if ((ptr = strchr(value, '#')) != NULL)
+ {
+ /*
+ * Need to quote the first # in the info string...
+ */
+
+ if ((temp = cupsFileWrite(fp, value, ptr - value)) < 0)
+ return (-1);
+ bytes += temp;
+
+ if (cupsFilePutChar(fp, '\\') < 0)
+ return (-1);
+ bytes ++;
+
+ if ((temp = cupsFilePuts(fp, ptr)) < 0)
+ return (-1);
+ bytes += temp;
+ }
+ else if ((temp = cupsFilePuts(fp, value)) < 0)
+ return (-1);
+ else
+ bytes += temp;
+ }
+
+ if (cupsFilePutChar(fp, '\n') < 0)
+ return (-1);
+ else
+ return (bytes + 1);
+}
+
+
/*
* 'cupsFilePuts()' - Write a string.
*
* our own file functions allows us to provide transparent support of
* gzip'd print files, PPD files, etc.
*
- * 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
#endif /* __GNUC__ */
_CUPS_API_1_2;
extern int cupsFilePutChar(cups_file_t *fp, int c) _CUPS_API_1_2;
+extern ssize_t cupsFilePutConf(cups_file_t *fp, const char *directive,
+ const char *value) _CUPS_API_1_4;
extern int cupsFilePuts(cups_file_t *fp, const char *s) _CUPS_API_1_2;
extern ssize_t cupsFileRead(cups_file_t *fp, char *buf, size_t bytes) _CUPS_API_1_2;
extern off_t cupsFileRewind(cups_file_t *fp) _CUPS_API_1_2;
_cupsFilePeekChar
_cupsFilePrintf
_cupsFilePutChar
+_cupsFilePutConf
_cupsFilePuts
_cupsFileRead
_cupsFileRewind
httpAddrFreeList(addrlist);
}
+ else if (isdigit(hostname[0] & 255))
+ {
+ puts("FAIL (ignored because hostname is numeric)");
+ }
else
{
failures ++;
*
* Internationalization test for Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
print_utf8(const char *msg, /* I - Message String */
const cups_utf8_t *src) /* I - UTF-8 Source String */
{
+ const char *prefix; /* Prefix string */
+
+
if (msg)
printf("%s:", msg);
- for (; *src; src ++)
- printf(" %02x", *src);
+ for (prefix = " "; *src; src ++)
+ {
+ printf("%s%02x", prefix, *src);
+
+ if ((src[0] & 0x80) && (src[1] & 0x80))
+ prefix = "";
+ else
+ prefix = " ";
+ }
putchar('\n');
}
* Convert internal UCS-4 to SBCS legacy charset (and delete BOM)...
*/
- for (workptr = work + 1, start = dest; *workptr && maxout > 1; maxout --)
+ for (workptr = work, start = dest; *workptr && maxout > 0; maxout --)
{
unichar = *workptr++;
if (!unichar)
* Convert internal UCS-4 to VBCS legacy charset (and delete BOM)...
*/
- for (start = dest, workptr = work + 1; *workptr && maxout > 1; maxout --)
+ for (start = dest, workptr = work; *workptr && maxout > 0; maxout --)
{
unichar = *workptr++;
/*
- * 'cups_get_printer_uri()' - Get the printer-uri-supported attribute for the first printer in a class.
+ * 'cups_get_printer_uri()' - Get the printer-uri-supported attribute for the
+ * first printer in a class.
*/
static int /* O - 1 on success, 0 on failure */
/* Hostname associated with connection */
static const char * const requested_attrs[] =
{ /* Requested attributes */
+ "member-uris",
"printer-uri-supported",
- "printer-type",
- "member-uris"
+ "printer-type"
};
else if ((attr = ippFindAttribute(response, "printer-uri-supported",
IPP_TAG_URI)) != NULL)
{
- httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text,
+ httpSeparateURI(HTTP_URI_CODING_ALL,
+ _httpResolveURI(attr->values[0].string.text, uri,
+ sizeof(uri), 0),
scheme, sizeof(scheme), username, sizeof(username),
host, hostsize, port, resource, resourcesize);
ippDelete(response);
+++ /dev/null
-charset 8bit
-
-#
-# This file defines the font and character mappings used for ISO-8859-10
-# (Latin6/Nordic) text printing.
-#
-# The first line consists of:
-#
-# direction width normal bold italic bold-italic
-#
-# Direction is the string "ltor" or "rtol", indicating left-to-right or
-# right-to-left text.
-#
-# Width is the string "single" or "double"; double means that the glyphs
-# are twice as wide as ASCII characters in the Courier typeface.
-#
-# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
-# for each presentation. If characters are only available in a single
-# style then only one typeface should be listed (e.g. "Symbol")
-#
-# Each font that is listed will be used (and downloaded if needed) when
-# printing.
-#
-
-00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
-
-#
-# The following lines define the mapping from the 8-bit character set to
-# the Unicode glyphs for each character:
-#
-# char glyph
-#
-# "Char" and "glyph" are hexadecimal values.
-#
-
-20 0020
-21 0021
-22 0022
-23 0023
-24 0024
-25 0025
-26 0026
-27 0027
-28 0028
-29 0029
-2A 002A
-2B 002B
-2C 002C
-2D 002D
-2E 002E
-2F 002F
-30 0030
-31 0031
-32 0032
-33 0033
-34 0034
-35 0035
-36 0036
-37 0037
-38 0038
-39 0039
-3A 003A
-3B 003B
-3C 003C
-3D 003D
-3E 003E
-3F 003F
-40 0040
-41 0041
-42 0042
-43 0043
-44 0044
-45 0045
-46 0046
-47 0047
-48 0048
-49 0049
-4A 004A
-4B 004B
-4C 004C
-4D 004D
-4E 004E
-4F 004F
-50 0050
-51 0051
-52 0052
-53 0053
-54 0054
-55 0055
-56 0056
-57 0057
-58 0058
-59 0059
-5A 005A
-5B 005B
-5C 005C
-5D 005D
-5E 005E
-5F 005F
-60 0060
-61 0061
-62 0062
-63 0063
-64 0064
-65 0065
-66 0066
-67 0067
-68 0068
-69 0069
-6A 006A
-6B 006B
-6C 006C
-6D 006D
-6E 006E
-6F 006F
-70 0070
-71 0071
-72 0072
-73 0073
-74 0074
-75 0075
-76 0076
-77 0077
-78 0078
-79 0079
-7A 007A
-7B 007B
-7C 007C
-7D 007D
-7E 007E
-80 20AC
-82 201A
-83 0192
-84 201E
-85 2026
-86 2020
-87 2021
-88 02C6
-89 2030
-8A 0160
-8B 2039
-8C 0152
-91 2018
-92 2019
-93 201C
-94 201D
-95 2022
-96 2013
-97 2014
-98 02DC
-99 2122
-9A 0161
-9B 203A
-9C 0153
-9F 0178
-A0 00A0
-A1 0104
-A2 0112
-A3 0122
-A4 012A
-A5 0128
-A6 0136
-A7 00A7
-A8 013B
-A9 0110
-AA 0160
-AB 0166
-AC 017D
-AD 00AD
-AE 016A
-AF 014A
-B0 00B0
-B1 0105
-B2 0113
-B3 0123
-B4 012B
-B5 0129
-B6 0137
-B7 00B7
-B8 013C
-B9 0111
-BA 0161
-BB 0167
-BC 017E
-BD 2015
-BE 016B
-BF 014B
-C0 0100
-C1 00C1
-C2 00C2
-C3 00C3
-C4 00C4
-C5 00C5
-C6 00C6
-C7 012E
-C8 010C
-C9 00C9
-CA 0118
-CB 00CB
-CC 0116
-CD 00CD
-CE 00CE
-CF 00CF
-D0 0110
-D1 0145
-D2 014C
-D3 00D3
-D4 00D4
-D5 00D5
-D6 00D6
-D7 0168
-D8 00D8
-D9 0172
-DA 00DA
-DB 00DB
-DC 00DC
-DD 00DD
-DE 00DE
-DF 00DF
-E0 0101
-E1 00E1
-E2 00E2
-E3 00E3
-E4 00E4
-E5 00E5
-E6 00E6
-E7 012F
-E8 010D
-E9 00E9
-EA 0119
-EB 00EB
-EC 0117
-ED 00ED
-EE 00EE
-EF 00EF
-F0 00F0
-F1 0146
-F2 014D
-F3 00F3
-F4 00F4
-F5 00F5
-F6 00F6
-F7 0169
-F8 00F8
-F9 0173
-FA 00FA
-FB 00FB
-FC 00FC
-FD 00FD
-FE 00FD
-FF 0138
+++ /dev/null
-charset 8bit
-
-#
-# This file defines the font and character mappings used for ISO-8859-13
-# (Latin7/Baltic Rim) text printing.
-#
-# The first line consists of:
-#
-# direction width normal bold italic bold-italic
-#
-# Direction is the string "ltor" or "rtol", indicating left-to-right or
-# right-to-left text.
-#
-# Width is the string "single" or "double"; double means that the glyphs
-# are twice as wide as ASCII characters in the Courier typeface.
-#
-# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
-# for each presentation. If characters are only available in a single
-# style then only one typeface should be listed (e.g. "Symbol")
-#
-# Each font that is listed will be used (and downloaded if needed) when
-# printing.
-#
-
-00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
-
-#
-# The following lines define the mapping from the 8-bit character set to
-# the Unicode glyphs for each character:
-#
-# char glyph
-#
-# "Char" and "glyph" are hexadecimal values.
-#
-
-20 0020
-21 0021
-22 0022
-23 0023
-24 0024
-25 0025
-26 0026
-27 0027
-28 0028
-29 0029
-2A 002A
-2B 002B
-2C 002C
-2D 002D
-2E 002E
-2F 002F
-30 0030
-31 0031
-32 0032
-33 0033
-34 0034
-35 0035
-36 0036
-37 0037
-38 0038
-39 0039
-3A 003A
-3B 003B
-3C 003C
-3D 003D
-3E 003E
-3F 003F
-40 0040
-41 0041
-42 0042
-43 0043
-44 0044
-45 0045
-46 0046
-47 0047
-48 0048
-49 0049
-4A 004A
-4B 004B
-4C 004C
-4D 004D
-4E 004E
-4F 004F
-50 0050
-51 0051
-52 0052
-53 0053
-54 0054
-55 0055
-56 0056
-57 0057
-58 0058
-59 0059
-5A 005A
-5B 005B
-5C 005C
-5D 005D
-5E 005E
-5F 005F
-60 0060
-61 0061
-62 0062
-63 0063
-64 0064
-65 0065
-66 0066
-67 0067
-68 0068
-69 0069
-6A 006A
-6B 006B
-6C 006C
-6D 006D
-6E 006E
-6F 006F
-70 0070
-71 0071
-72 0072
-73 0073
-74 0074
-75 0075
-76 0076
-77 0077
-78 0078
-79 0079
-7A 007A
-7B 007B
-7C 007C
-7D 007D
-7E 007E
-80 20AC
-82 201A
-83 0192
-84 201E
-85 2026
-86 2020
-87 2021
-88 02C6
-89 2030
-8A 0160
-8B 2039
-8C 0152
-91 2018
-92 2019
-93 201C
-94 201D
-95 2022
-96 2013
-97 2014
-98 02DC
-99 2122
-9A 0161
-9B 203A
-9C 0153
-9F 0178
-A0 00A0
-A1 201D
-A2 00A2
-A3 00A3
-A4 00A4
-A5 201E
-A6 00A6
-A7 00A7
-A8 00D8
-A9 00A9
-AA 0156
-AB 00AB
-AC 00AC
-AD 00AD
-AE 00AE
-AF 00C6
-B0 00B0
-B1 00B1
-B2 00B2
-B3 00B3
-B4 201C
-B5 00B5
-B6 00B6
-B7 00B7
-B8 00F8
-B9 00B9
-BA 0157
-BB 00BB
-BC 00BC
-BD 00BD
-BE 00BE
-BF 00E6
-C0 0104
-C1 012E
-C2 0100
-C3 0106
-C4 00C4
-C5 00C5
-C6 0118
-C7 0112
-C8 010C
-C9 00C9
-CA 0179
-CB 0116
-CC 0122
-CD 0136
-CE 012A
-CF 013B
-D0 0160
-D1 0143
-D2 0145
-D3 00D3
-D4 014C
-D5 00D5
-D6 00D6
-D7 00D7
-D8 0172
-D9 0141
-DA 015A
-DB 016A
-DC 00DC
-DD 017B
-DE 017D
-DF 00DF
-E0 0105
-E1 012F
-E2 0101
-E3 0107
-E4 00E4
-E5 00E5
-E6 0119
-E7 0113
-E8 010D
-E9 00E9
-EA 017A
-EB 0117
-EC 0123
-ED 0137
-EE 012B
-EF 013C
-F0 0161
-F1 0144
-F2 0146
-F3 00F3
-F4 014D
-F5 00F5
-F6 00F6
-F7 00F7
-F8 0173
-F9 0142
-FA 015B
-FB 016B
-FC 00FC
-FD 017C
-FE 017E
-FF 2019
+++ /dev/null
-charset 8bit
-
-#
-# This file defines the font and character mappings used for ISO-8859-14
-# (Latin8/Celtic) text printing.
-#
-# The first line consists of:
-#
-# direction width normal bold italic bold-italic
-#
-# Direction is the string "ltor" or "rtol", indicating left-to-right or
-# right-to-left text.
-#
-# Width is the string "single" or "double"; double means that the glyphs
-# are twice as wide as ASCII characters in the Courier typeface.
-#
-# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
-# for each presentation. If characters are only available in a single
-# style then only one typeface should be listed (e.g. "Symbol")
-#
-# Each font that is listed will be used (and downloaded if needed) when
-# printing.
-#
-
-00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
-
-#
-# The following lines define the mapping from the 8-bit character set to
-# the Unicode glyphs for each character:
-#
-# char glyph
-#
-# "Char" and "glyph" are hexadecimal values.
-#
-
-20 0020
-21 0021
-22 0022
-23 0023
-24 0024
-25 0025
-26 0026
-27 0027
-28 0028
-29 0029
-2A 002A
-2B 002B
-2C 002C
-2D 002D
-2E 002E
-2F 002F
-30 0030
-31 0031
-32 0032
-33 0033
-34 0034
-35 0035
-36 0036
-37 0037
-38 0038
-39 0039
-3A 003A
-3B 003B
-3C 003C
-3D 003D
-3E 003E
-3F 003F
-40 0040
-41 0041
-42 0042
-43 0043
-44 0044
-45 0045
-46 0046
-47 0047
-48 0048
-49 0049
-4A 004A
-4B 004B
-4C 004C
-4D 004D
-4E 004E
-4F 004F
-50 0050
-51 0051
-52 0052
-53 0053
-54 0054
-55 0055
-56 0056
-57 0057
-58 0058
-59 0059
-5A 005A
-5B 005B
-5C 005C
-5D 005D
-5E 005E
-5F 005F
-60 0060
-61 0061
-62 0062
-63 0063
-64 0064
-65 0065
-66 0066
-67 0067
-68 0068
-69 0069
-6A 006A
-6B 006B
-6C 006C
-6D 006D
-6E 006E
-6F 006F
-70 0070
-71 0071
-72 0072
-73 0073
-74 0074
-75 0075
-76 0076
-77 0077
-78 0078
-79 0079
-7A 007A
-7B 007B
-7C 007C
-7D 007D
-7E 007E
-80 20AC
-82 201A
-83 0192
-84 201E
-85 2026
-86 2020
-87 2021
-88 02C6
-89 2030
-8A 0160
-8B 2039
-8C 0152
-91 2018
-92 2019
-93 201C
-94 201D
-95 2022
-96 2013
-97 2014
-98 02DC
-99 2122
-9A 0161
-9B 203A
-9C 0153
-9F 0178
-A0 00A0
-A1 1E02
-A2 1E03
-A3 00A3
-A4 010A
-A5 010B
-A6 1E0A
-A7 00A7
-A8 1E80
-A9 00A9
-AA 1E82
-AB 1E0B
-AC 1EF2
-AD 00AD
-AE 00AE
-AF 0178
-B0 1E1E
-B1 1E1F
-B2 0120
-B3 0121
-B4 1E40
-B5 1E41
-B6 00B6
-B7 1E56
-B8 1E81
-B9 1E57
-BA 1E83
-BB 1E60
-BC 1EF3
-BD 1E84
-BE 1E85
-BF 1E61
-C0 00C0
-C1 00C1
-C2 00C2
-C3 00C3
-C4 00C4
-C5 00C5
-C6 00C6
-C7 00C7
-C8 00C8
-C9 00C9
-CA 00CA
-CB 00CB
-CC 00CC
-CD 00CD
-CE 00CE
-CF 00CF
-D0 0174
-D1 00D1
-D2 00D2
-D3 00D3
-D4 00D4
-D5 00D5
-D6 00D6
-D7 1E6A
-D8 00D8
-D9 00D9
-DA 00DA
-DB 00DB
-DC 00DC
-DD 00DD
-DE 0176
-DF 00DF
-E0 00E0
-E1 00E1
-E2 00E2
-E3 00E3
-E4 00E4
-E5 00E5
-E6 00E6
-E7 00E7
-E8 00E8
-E9 00E9
-EA 00EA
-EB 00EB
-EC 00EC
-ED 00ED
-EE 00EE
-EF 00EF
-F0 0175
-F1 00F1
-F2 00F2
-F3 00F3
-F4 00F4
-F5 00F5
-F6 00F6
-F7 1E6B
-F8 00F8
-F9 00F9
-FA 00FA
-FB 00FB
-FC 00FC
-FD 00FD
-FE 0177
-FF 00FF
+++ /dev/null
-charset 8bit
-
-#
-# This file defines the font and character mappings used for ISO-8859-15
-# (Latin9/West Europe + Euro) text printing.
-#
-# The first line consists of:
-#
-# direction width normal bold italic bold-italic
-#
-# Direction is the string "ltor" or "rtol", indicating left-to-right or
-# right-to-left text.
-#
-# Width is the string "single" or "double"; double means that the glyphs
-# are twice as wide as ASCII characters in the Courier typeface.
-#
-# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
-# for each presentation. If characters are only available in a single
-# style then only one typeface should be listed (e.g. "Symbol")
-#
-# Each font that is listed will be used (and downloaded if needed) when
-# printing.
-#
-
-00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
-
-#
-# The following lines define the mapping from the 8-bit character set to
-# the Unicode glyphs for each character:
-#
-# char glyph
-#
-# "Char" and "glyph" are hexadecimal values.
-#
-
-20 0020
-21 0021
-22 0022
-23 0023
-24 0024
-25 0025
-26 0026
-27 0027
-28 0028
-29 0029
-2A 002A
-2B 002B
-2C 002C
-2D 002D
-2E 002E
-2F 002F
-30 0030
-31 0031
-32 0032
-33 0033
-34 0034
-35 0035
-36 0036
-37 0037
-38 0038
-39 0039
-3A 003A
-3B 003B
-3C 003C
-3D 003D
-3E 003E
-3F 003F
-40 0040
-41 0041
-42 0042
-43 0043
-44 0044
-45 0045
-46 0046
-47 0047
-48 0048
-49 0049
-4A 004A
-4B 004B
-4C 004C
-4D 004D
-4E 004E
-4F 004F
-50 0050
-51 0051
-52 0052
-53 0053
-54 0054
-55 0055
-56 0056
-57 0057
-58 0058
-59 0059
-5A 005A
-5B 005B
-5C 005C
-5D 005D
-5E 005E
-5F 005F
-60 0060
-61 0061
-62 0062
-63 0063
-64 0064
-65 0065
-66 0066
-67 0067
-68 0068
-69 0069
-6A 006A
-6B 006B
-6C 006C
-6D 006D
-6E 006E
-6F 006F
-70 0070
-71 0071
-72 0072
-73 0073
-74 0074
-75 0075
-76 0076
-77 0077
-78 0078
-79 0079
-7A 007A
-7B 007B
-7C 007C
-7D 007D
-7E 007E
-80 20AC
-82 201A
-83 0192
-84 201E
-85 2026
-86 2020
-87 2021
-88 02C6
-89 2030
-8A 0160
-8B 2039
-8C 0152
-91 2018
-92 2019
-93 201C
-94 201D
-95 2022
-96 2013
-97 2014
-98 02DC
-99 2122
-9A 0161
-9B 203A
-9C 0153
-9F 0178
-A0 00A0
-A1 00A1
-A2 00A2
-A3 00A3
-A4 20AC
-A5 00A5
-A6 0160
-A7 00A7
-A8 0161
-A9 00A9
-AA 00AA
-AB 00AB
-AC 00AC
-AD 00AD
-AE 00AE
-AF 00AF
-B0 00B0
-B1 00B1
-B2 00B2
-B3 00B3
-B4 017D
-B5 00B5
-B6 00B6
-B7 00B7
-B8 017E
-B9 00B9
-BA 00BA
-BB 00BB
-BC 0152
-BD 0153
-BE 0178
-BF 00BF
-C0 00C0
-C1 00C1
-C2 00C2
-C3 00C3
-C4 00C4
-C5 00C5
-C6 00C6
-C7 00C7
-C8 00C8
-C9 00C9
-CA 00CA
-CB 00CB
-CC 00CC
-CD 00CD
-CE 00CE
-CF 00CF
-D0 00D0
-D1 00D1
-D2 00D2
-D3 00D3
-D4 00D4
-D5 00D5
-D6 00D6
-D7 00D7
-D8 00D8
-D9 00D9
-DA 00DA
-DB 00DB
-DC 00DC
-DD 00DD
-DE 00DE
-DF 00DF
-E0 00E0
-E1 00E1
-E2 00E2
-E3 00E3
-E4 00E4
-E5 00E5
-E6 00E6
-E7 00E7
-E8 00E8
-E9 00E9
-EA 00EA
-EB 00EB
-EC 00EC
-ED 00ED
-EE 00EE
-EF 00EF
-F0 00F0
-F1 00F1
-F2 00F2
-F3 00F3
-F4 00F4
-F5 00F5
-F6 00F6
-F7 00F7
-F8 00F8
-F9 00F9
-FA 00FA
-FB 00FB
-FC 00FC
-FD 00FD
-FE 00FE
-FF 00FF
images/sel.gif \
images/smiley.jpg \
images/unsel.gif \
- images/web-add-this-printer.gif \
- images/web-password.gif \
- images/web-printer-driver.gif \
- images/web-printer-status.gif \
- images/web-set-printer-options.gif \
- images/web-test-page.gif
+ images/wait.gif
HELPFILES = \
help/accounting.html \
help/api-array.html \
}
TABLE.list TH {
- border-bottom: solid 1pt #999999;
+ background: white;
+ border-bottom: solid thin #cccccc;
+ color: #444444;
padding-top: 10pt;
padding-left: 5pt;
text-align: left;
+ vertical-align: bottom;
white-space: nowrap;
}
+TABLE.list TH A {
+ color: #4444cc;
+}
+
TABLE.list TD {
border-bottom: solid thin #eeeeee;
padding-top: 5pt;
padding-left: 5pt;
}
+TABLE.list TR:nth-child(even) {
+ background: #f8f8f8;
+}
+
+TABLE.list TR:nth-child(odd) {
+ background: #f4f4f4;
+}
+
DIV.sidebar {
float: right;
min-width: 25%;
background: #f0f0f0;
}
+DIV.tabs {
+ height: 480px;
+ overflow: hidden;
+}
+
+DIV.tab {
+ float: left;
+ height: 100%;
+ overflow-y: auto;
+ width: 100%;
+}
+
/* API documentation styles... */
div.body h1 {
margin: 0;
</HEAD>
<BODY>
-<P>The Common UNIX Printing System<sup>TM</sup>, or CUPS, is the
-software you use to print from applications like the web browser
-you are using to read this page. It converts the <em>page
-descriptions</em> produced by your application (put a paragraph
-here, draw a line there, and so forth) into something your
-printer can understand and then sends the information to the
-printer for printing.</P>
+<P>The Common UNIX Printing System<sup>TM</sup>, or CUPS, is the software you
+use to print from applications like the web browser you are using to read this
+page. It converts the <em>page descriptions</em> produced by your application
+(put a paragraph here, draw a line there, and so forth) into something your
+printer can understand and then sends the information to the printer for
+printing.</P>
-<P>Now, since every printer manufacturer does things differently,
-printing can be very complicated. CUPS does its best to hide this
-from you and your application so that you can concentrate on
-printing and less on <em>how</em> to print. Generally, the only
-time you need to know anything about your printer is when you use
-it for the first time, and even then CUPS can often figure things
+<P>Now, since every printer manufacturer does things differently, printing can
+be very complicated. CUPS does its best to hide this from you and your
+application so that you can concentrate on printing and less on <em>how</em> to
+print. Generally, the only time you need to know anything about your printer is
+when you use it for the first time, and even then CUPS can often figure things
out on its own.</P>
<H2 CLASS="title"><A NAME="WORK">How Does It Work?</A></H2>
-<P>The first time you print to a printer, CUPS creates a
-<em>queue</em> to keep track of the current status of the printer
-(everything OK, out of paper, etc.) and any pages you have
-printed. Most of the time the queue points to a printer connected
-directly to your computer via a USB or parallel port, however it
-can also point to a printer on your network, a printer on the
-Internet, or multiple printers depending on the configuration.
-Regardless of <em>where</em> the queue points, it will look like
-any other printer to you and your applications.</P>
+<P>The first time you print to a printer, CUPS creates a <em>queue</em> to keep
+track of the current status of the printer (everything OK, out of paper, etc.)
+and any pages you have printed. Most of the time the queue points to a printer
+connected directly to your computer via a USB or parallel port, however it can
+also point to a printer on your network, a printer on the Internet, or multiple
+printers depending on the configuration. Regardless of <em>where</em> the queue
+points, it will look like any other printer to you and your applications.</P>
-<P>Every time you print something, CUPS creates a <em>job</em>
-which contains the queue you are sending the print to, the name
-of the document you are printing, and the page descriptions. Job
-are numbered (queue-1, queue-2, and so forth) so you can monitor
-the job as it is printed or cancel it if you see a mistake. When
-CUPS gets a job for printing, it determines the best programs
-(<em>filters</em>, <em>printer drivers</em>, <em>port
-monitors</em>, and <em>backends</em>) to convert the pages into a
-printable format and then runs them to actually print the
-job.</P>
+<P>Every time you print something, CUPS creates a <em>job</em> which contains
+the queue you are sending the print to, the name of the document you are
+printing, and the page descriptions. Job are numbered (queue-1, queue-2, and so
+forth) so you can monitor the job as it is printed or cancel it if you see a
+mistake. When CUPS gets a job for printing, it determines the best programs
+(<em>filters</em>, <em>printer drivers</em>, <em>port monitors</em>, and
+<em>backends</em>) to convert the pages into a printable format and then runs
+them to actually print the job.</P>
-<P>When the print job is completely printed, CUPS removes the job
-from the queue and moves on to any other jobs you have submitted.
-You can also be notified when the job is finished, or if there
-are any errors during printing, in several different ways.</P>
+<P>When the print job is completely printed, CUPS removes the job from the queue
+and moves on to any other jobs you have submitted. You can also be notified when
+the job is finished, or if there are any errors during printing, in several
+different ways.</P>
<H2 CLASS="title"><A NAME="BEGIN">Where Do I Begin?</A></H2>
-<P>Click on the <A HREF="/admin">Administration</A> tab at the
-top of this page. If you have a printer connected to a USB or
-parallel port, you will see it listed as a new printer - click on
-the <VAR>Add This Printer</VAR> button, verify the printer driver
-CUPS has chosen for you, and click on the <VAR>Add Printer</VAR>
-button. If you do not see your printer listed, or if you have a
-network printer, click on the <VAR>Add Printer</VAR> button and
-follow the prompts.</P>
+<P>Click on the <A HREF="/admin">Administration</A> tab at the top of this page.
+Click on the <VAR>Add Printer</VAR> button and follow the prompts.</P>
-<BLOCKQUOTE>If you are asked for a username and password, enter
-your login username and password or the "root" username and
-password. On MacOS X, the login username (or "short name") is
-typically your first name in lowercase.</BLOCKQUOTE>
+<BLOCKQUOTE>When you are asked for a username and password, enter your login
+username and password or the "root" username and password. On MacOS X, the login
+username (or "short name") is typically your first and last name in
+lowercase.</BLOCKQUOTE>
-<P>After the printer is added, CUPS will ask you to set the
-default printer options (paper size, output mode, etc.) for the
-printer. Make any changes as needed and then click on the
-<VAR>Set Printer Options</VAR> button to save them.</P>
+<P>After the printer is added, CUPS will ask you to set the default printer
+options (paper size, output mode, etc.) for the printer. Make any changes as
+needed and then click on the <VAR>Set Default Options</VAR> button to save
+them. Some printers also support auto-configuration - click on the <VAR>Query
+Printer for Default Options</VAR> button to update the options automaticaly.</P>
-<P>Finally, click on the <VAR>Print Test Page</VAR> button to
-print a simple test page and verify that everything is working
-properly.</P>
-
-<P>Once you have added the printer, you can print to it from any
-application.</P>
-
-<TABLE ALIGN="CENTER" CELLPADDING="10" SUMMARY="Screenshots">
-<TR VALIGN="TOP">
-<TD ALIGN="CENTER"><IMG SRC="../images/web-add-this-printer.gif"
-WIDTH="366" HEIGHT="300" ALT="CUPS Administration Web Page"><BR>
-<I>Figure 1: The CUPS Administration Web Page</I></TD>
-<TD ALIGN="CENTER"><IMG SRC="../images/web-printer-driver.gif"
-WIDTH="366" HEIGHT="300" ALT="CUPS Driver Selection Web Page"><BR>
-<I>Figure 2: The CUPS Driver Selection Web Page</I></TD>
-</TR>
-<TR VALIGN="TOP">
-<TD ALIGN="CENTER"><IMG SRC="../images/web-password.gif"
-WIDTH="366" HEIGHT="300" ALT="CUPS Password Dialog"><BR>
-<I>Figure 3: The CUPS Password Dialog</I></TD>
-<TD ALIGN="CENTER"><IMG SRC="../images/web-set-printer-options.gif"
-WIDTH="366" HEIGHT="300" ALT="CUPS Set Printer Options Web Page"><BR>
-<I>Figure 4: The CUPS Set Printer Options Web Page</I></TD>
-</TR>
-<TR VALIGN="TOP">
-<TD ALIGN="CENTER"><IMG SRC="../images/web-printer-status.gif"
-WIDTH="366" HEIGHT="300" ALT="CUPS Printer Status Page"><BR>
-<I>Figure 5: The CUPS Printer Status Page</I></TD>
-<TD ALIGN="CENTER"><IMG SRC="../images/web-test-page.gif"
-WIDTH="234" HEIGHT="300" ALT="CUPS Printer Test Page"><BR>
-<I>Figure 6: The CUPS Printer Test Page</I></TD>
-</TR>
-</TABLE>
+<P>Once you have added the printer, you can print to it from any application.
+You can also choose <VAR>Print Test Page</VAR> from the maintenance menu to print
+a simple test page and verify that everything is working properly.</P>
</BODY>
</HTML>
<P>The <CODE>Accepting</CODE> directive defines the initial state
of the <VAR>printer-is-accepting-jobs</VAR> attribute. This state
-is also set by the <CODE>accept(8)</CODE> and
-<CODE>reject(8)</CODE> commands:</P>
+is also set by the <CODE>cupsaccept(8)</CODE> and
+<CODE>cupsreject(8)</CODE> commands:</P>
<PRE CLASS="command">
-<KBD>/usr/sbin/accept printername
-/usr/sbin/reject printername</KBD>
+<KBD>/usr/sbin/cupsaccept printername
+/usr/sbin/cupsreject printername</KBD>
</PRE>
<P>This directive must appear inside a <A
section.</P>
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.4</SPAN><A NAME="Filter">Filter</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+<Printer name>
+ ...
+ Filter mime/type 100 program
+</Printer>
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>Filter</CODE> directive lists a single filter program as defined
+in the printer's PPD file.</P>
+
+<P>This directive must appear inside a
+<A HREF="#Printer"><CODE>Printer</CODE></A> or
+<A HREF="#DefaultPrinter"><CODE>DefaultPrinter</CODE></A> section.</P>
+
+
<H2 CLASS="title"><A NAME="Info">Info</A></H2>
<H3>Examples</H3>
section.</P>
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.4</SPAN><A NAME="PreFilter">PreFilter</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+<Printer name>
+ ...
+ PreFilter mime/type 100 program
+</Printer>
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>PreFilter</CODE> directive lists a single pre-filter program as
+defined in the printer's PPD file.</P>
+
+<P>This directive must appear inside a
+<A HREF="#Printer"><CODE>Printer</CODE></A> or
+<A HREF="#DefaultPrinter"><CODE>DefaultPrinter</CODE></A> section.</P>
+
+
<H2 CLASS="title"><A NAME="Printer">Printer</A></H2>
<H3>Examples</H3>
</PRE>
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.4</SPAN><A NAME="Product">Product</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+<Printer name>
+ ...
+ Product Acme PaperWriter
+</Printer>
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>Product</CODE> directive defines the main product string from the
+printer's PPD file and is used when advertising the queue via DNS-SD.</P>
+
+<P>This directive must appear inside a
+<A HREF="#Printer"><CODE>Printer</CODE></A> or
+<A HREF="#DefaultPrinter"><CODE>DefaultPrinter</CODE></A> section.</P>
+
+
<H2 CLASS="title"><A NAME="QuotaPeriod">QuotaPeriod</A></H2>
<H3>Examples</H3>
</blockquote>
-<h4><a name="columns">columns (integer(1:4))</a></h4>
+<h4><a name="columns">columns (integer(1:4))</a> <span class='info'>Deprecated</span></h4>
<p>The columns attribute specifies the number of columns to generate when
printing text files. The default value is 1.
*cupsPreFilter: "image/png 0 mypngprefilter"
</pre>
+<h3><span class='info'>CUPS 1.4</span><a name='cupsSNMPSupplies'>cupsSNMPSupplies</a></h3>
+
+<p class='summary'>*cupsSNMPSupplies: boolean</p>
+
+<p>This attribute tells the standard network backends whether they should query
+the standard SNMP Printer MIB OIDs for supply levels. The default value is
+<code>True</code>.
+
+<p>Example:</p>
+
+<pre class='command'>
+<em>*% Do not use SNMP queries to report supply levels</em>
+*cupsSNMPSupplies: False
+</pre>
+
<h3><a name='cupsVersion'>cupsVersion</a></h3>
<p class='summary'>*cupsVersion: major.minor</p>
<li>Added <a href='#cupsPJLDisplay'><tt>cupsPJLDisplay</tt></a>
attribute.</li>
+ <li>Added <a href='#cupsSNMPSupplies'><tt>cupsSNMPSupplies</tt></a>
+ attribute.</li>
+
<li>Added <a href='#cupsUIResolver'><tt>cupsUIResolver</tt></a> and
<a href='#cupsUIConstraints'><tt>cupsUIConstraints</tt></a>
attributes.</li>
</HEAD>
<BODY>
-<P>CUPS 1.4 adds over ?? changes and new features to CUPS 1.3.x. This page provides a high-level outline of these changes. If you have never used CUPS before, read the <A HREF="overview.html">"Overview of CUPS"</A> document instead.</P>
+<P>CUPS 1.4 adds over 64 changes and new features to CUPS 1.3.x. This page provides a high-level outline of these changes. If you have never used CUPS before, read the <A HREF="overview.html">"Overview of CUPS"</A> document instead.</P>
<H2 CLASS="title"><A NAME="COMMANDS">Commands</A></H2>
<OL START="1">
- <LI><EM>lppasswd;</EM> the lppasswd program is no longer installed setuid by default.</LI>
+ <LI><EM>accept and reject;</EM> the accept and reject commands have been officially renamed to cupsaccess and cupsreject. The old names are still supported via symlinks.</LI>
+
+ <LI><EM>cupsfilter;</EM> the cupsfilter program now supports filtering of already-queued print job files and can also run printer-specific filters specified in the PPD file.</LI>
- <LI><EM>cupsfilter;</EM> the cupsfilter program now supports filtering of already-queued print job files.</LI>
+ <LI><EM>cupstestdsc;</EM> the cupstestdsc utility has been improved to better detect problems with PostScript print files.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>cupstestppd;</EM> the cupstestppd utility has been improved to test new PPD keywords and better detect impossible contraints.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>lpadmin;</EM> the lpadmin command now supports options to hold and release new jobs on a printer or all printers.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>lpoptions;</EM> the lpoptions command now describes custom options and their parameters.</LI>
+
+ <LI><EM>lppasswd;</EM> the lppasswd program is no longer installed setuid by default.</LI>
+
+ <LI><EM>lpstat;</EM> the lpstat command now supports a -H option to show the current default server and no longer slows down when a printer is specified.</LI>
</OL>
<H2 CLASS="title"><A NAME="WEBIF">Web Interface</A></H2>
-<OL START="1">
+<OL START="9">
- <LI><EM>Look-n-feel;</EM> the web interface has been given a new look with a new CUPS logo.</LI>
+ <LI><EM>Look-n-feel;</EM> the web interface has been given a new look.</LI>
- <LI><EM>Security;</EM> the web interface has been updated to require authentication for printing of test pages and RSS subscription operations.</LI>
-
- <LI><EM>Printer sharing;</EM> the "share printer" and "unshare printer" buttons are now only shown when printer sharing is enabled in the scheduler.</LI>
+ <LI><EM>PHP support;</EM> the "php-cgi" program is used, when available, to process PHP pages in the CUPS web interface.</LI>
<LI><EM>Printer configuration;</EM> improvements have been made to the add and modify printer pages.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Printer options;</EM> the Set Default Options page now provides a "query" button that queries the default and installed options from the printer.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Printer sharing;</EM> the "share printer" and "unshare printer" buttons are now only shown when printer sharing is enabled in the scheduler.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Security;</EM> the web interface has been updated to support authentication for printing of test pages and RSS subscription operations.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Server settings;</EM> the Administration page now provides access to common "advanced" server settings.</LI>
</OL>
<H2 CLASS="title"><A NAME="NETWORKING">Networking</A></H2>
-<OL START="1">
+<OL START="16">
<LI><EM>Bonjour (DNS-SD) printing support;</EM> a new mdns backend provides Bonjour-based printer discovery and the ipp, lpd, and socket backends now support Bonjour address resolution.</LI>
<LI><EM>Bonjour (DNS-SD) perforance tuning;</EM> the scheduler now only uses a single file descriptor for printer sharing. It previously used one per printer.</LI>
- <LI><EM>Bonjour (DNS-SD) web interface registry;</EM> when remote access is enabled, the scheduler registers the web interface for easier access</LI>
+ <LI><EM>Bonjour (DNS-SD) web interface registry;</EM> when remote access is enabled, the scheduler can register the web interface for easier access.</LI>
- <LI><EM>SNMP-based monitoring;</EM> the ipp, lpd, and socket backends now report supply levels and printer status using SNMP queries.</LI>
-
- <LI><EM>SNMP port monitor MIB;</EM> the ipp, lpd, snmp, and socket now support the PWG port monitor MIB</LI>
+ <LI><EM>LPD client support;</EM> the cups-lpd mini-daemon now provides the document-name for print jobs and supports specification of a CUPS server.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>PWG Port Monitor MIB;</EM> the snmp backend now supports the PWG Port Monitor MIB to better choose the device URI to use.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>SNMP-based monitoring;</EM> the ipp, lpd, and socket backends now report supply levels and printer status using SNMP queries.</LI>
</OL>
<H2 CLASS="title"><A NAME="IPP">IPP Support</A></H2>
-<OL START="1"></EM></LI>
+<OL START="22">
- <LI><EM>CUPS-Get-Document operation;</EM> the scheduler now supports a "get document" operation to download files from a print job.</LI>
-
- <LI><EM>;</EM> </LI>
-
- <LI><EM>;</EM> </LI>
+ <LI><EM>CUPS-Add-Modify-Printer operation;</EM> the scheduler now supports setting the printer-state-reasons attribute using this operation.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>CUPS-Get-Document operation;</EM> the scheduler now supports a "get document" operation to download files from a print job.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Device location;</EM> the scheduler and backend discovery interface now support a device-location attribute.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Hold-New-Jobs and Release-Held-New-Jobs operations;</EM> the scheduler now supports the Hold-New-Jobs and Release-Held-New-Jobs operations.</LI>
</OL>
<H2 CLASS="title"><A NAME="SCHEDULER">Scheduler</A></H2>
-<OL START="1">
+<OL START="26">
+
+ <LI><EM>Access control;</EM> the scheduler now supports multiple addresses in Allow and Deny lines. It also now returns a HTTP 403 (forbidden) status when a user authenticates successfully but is not allowed to perform an operation.</LI>
- <LI><EM>Performance tuning;</EM> the scheduler now coalesces configuration and state file changes to reduce the amount of disk activity.</LI>
+ <LI><EM>Access logging;</EM> the scheduler now supports an AccessLogLevel directive to control what is logged in the access_log file.</LI>
<LI><EM>Configuration files;</EM> the default cupsd.conf file now provides an "authenticated" policy for easy authenticated sharing of printers.</LI>
- <LI><EM>Seatbelt support;</EM> the scheduler now runs child processes using restrictive policies on Mac OS X for improved security and job isolation.</LI>
+ <LI><EM>Default LogLevel;</EM> the default LogLevel is now "warn" instead of "info".</LI>
- <LI><EM>PAM support;</EM> the scheduler now sets more PAM attributes to better support third-party authentication schemes.</LI>
+ <LI><EM>Default paper size;</EM> the scheduler now supports a DefaultPaperSize directive to override the default paper size defined by the locale or libpaper configuration.</LI>
- <LI><EM>Test option;</EM> the scheduler now supports a test mode via the "-t" option.</LI>
+ <LI><EM>Encryption support;</EM> the scheduler now supports a SSLOptions directive to optionally support Windows clients in "FIPS" mode. It also now loads both the server and CA certificates (if present) from the ServerCertificate file.</LI>
- <LI><EM>Page logging;</EM> the scheduler now supports a <code>PageLogFormat</code> directive to control the format of the page_log file.</LI>
+ <LI><EM>Error logging;</EM> the scheduler now logs unsuccessful operations as errors in the error_log file.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Error policies;</EM> the scheduler now supports a retry-current-job error policy that retries the current job immediately.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Fatal error handling;</EM> the scheduler now supports a FatalErrors directive to control which startup errors should be considered fatal.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Filter command-line;</EM> the scheduer now passes the job-originating-host-name attribute as a CUPS option to filters and backends.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Filter environment;</EM> the scheduler now includes CUPS_JOBTYPE, PRINTER_INFO, and PRINTER_LOCATION variables in the environment passed to filters and backends.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Job progress;</EM> the scheduler now supports a job-media-progress attribute to track the printing progress of each page.</LI>
-</OL>
+ <LI><EM>MIME database;</EM> MIME types now support a priority attribute to override the default (alphabetical) rules of precedence.</LI>
+ <LI><EM>Page logging;</EM> the scheduler now supports a <code>PageLogFormat</code> directive to control the format of the page_log file.</LI>
-<H2 CLASS="title"><A NAME="DRIVERS">Printer Drivers</A></H2>
+ <LI><EM>PAM support;</EM> the scheduler now sets more PAM attributes to better support third-party authentication schemes.</LI>
-<OL START="1">
+ <LI><EM>PDF job ticket support;</EM> the scheduler now supports cupsJobTicket comments at the beginning of PDF print jobs.</LI>
- <LI><EM>Dynamic PPD support;</EM> drivers can now set PPD keywords
- dynamically using <code>PPD:</code> messages.</LI>
+ <LI><EM>Performance tuning;</EM> the scheduler now coalesces configuration and state file changes to reduce the amount of disk activity and caches printer attributes to further reduce startup time.</LI>
- <LI><EM>Generic PostScript command filter;</EM> a new CUPS command file filter for PostScript printers provides auto-configuration, self-test page, and status and supply level reporting functions.</LI>
+ <LI><EM>Printcap support;</EM> the scheduler no longer clears the printcap file when shutting down, and can now create XML "plist" printcap files as well.</LI>
- <LI><EM>PJL support;</EM> the cupsPJLDisplay PPD attribute controls the PJL commands used to display the current user and job on the printer.</LI>
+ <LI><EM>RSS subscriptions;</EM> the scheduler now starts the notifier for RSS subscriptions after creation so the feed is available immediately.</LI>
- <LI><EM>Driver development kit;</EM> the CUPS DDK is now a standard part of CUPS</LI>
+ <LI><EM>Sandbox support;</EM> the scheduler now runs child processes using restrictive policies on Mac OS X for improved security and job isolation.</LI>
- <LI><EM>PPD compiler improvements;</EM> the PPD compiler now supports Mac OS X .strings files for localization and ... </LI>
+ <LI><EM>Test option;</EM> the scheduler now supports a test mode via the "-t" option.</LI>
- <LI><EM>Generic PostScript and PCL drivers;</EM> new generic PostScript and PCL drivers provide improved support for laser printers.</LI>
+</OL>
- <LI><EM>;</EM> </LI>
- <LI><EM>;</EM> </LI>
+<H2 CLASS="title"><A NAME="DRIVERS">Printer Drivers</A></H2>
- <LI><EM>;</EM> </LI>
+<OL START="47">
- <LI><EM>;</EM> </LI>
+ <LI><EM>Device discovery;</EM> the cups-deviced helper now runs backends in parallel for faster discovery and streams the results of discovery as the backends provide them.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Driver development kit;</EM> the CUPS DDK is now a standard part of CUPS.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Driver information file support;</EM> the cups-driverd helper program now directly supports PPD compiler driver information files.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Dynamic PPD support;</EM> drivers can now set PPD keywords dynamically using <code>PPD:</code> messages.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Generic PostScript command filter;</EM> a new CUPS command file filter for PostScript printers provides auto-configuration, self-test page, and status and supply level reporting functions.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>New printer drivers;</EM> new generic PostScript and PCL drivers provide improved support for laser printers, the CUPS DDK drivers offer support for many HP DesignJet printers, and new label drivers offer support for Seiko and Tharo label printers.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>PJL support;</EM> the cupsPJLDisplay PPD attribute controls the PJL commands used to display the current user and job on the printer.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>PPD compiler improvements;</EM> the PPD compiler now supports Mac OS X .strings files, OID query strings, conditional directives, long file names, and a test mode. It also fixes many other bugs from the CUPS DDK 1.2.3 release.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>USB printer support;</EM> the usb backend now uses libusb when available to allow it to better work with third-party scanning and printing solutions.</LI>
</OL>
<H2 CLASS="title"><A NAME="FILTERS">Print Filters</A></H2>
-<OL START="1">
+<OL START="56">
- <LI><EM>Image filters;</EM> the standard image filters now support image files larger than 2GB.</LI>
+ <LI><EM>Banner filter;</EM> the bundled banner ("job-sheets") pages are now generated using a new banner filter provides easier customization and better support for UTF-8 text.</LI>
- <LI><EM>Device discovery;</EM> the cups-deviced helper now runs backends in parallel for faster discovery and streams the results of discovery as the backends provide them.</LI>
+ <LI><EM>Image filters;</EM> the standard image filters now support image files larger than 2GB.</LI>
<LI><EM>PDF filter;</EM> the pdftops filter has been replaced with a wrapper program that runs the Xpdf, poppler, or Ghostscript PDF to PostScript utilities.</LI>
- <LI><EM>;</EM> </LI>
-
- <LI><EM>;</EM> </LI>
-
- <LI><EM>;</EM> </LI>
-
- <LI><EM>;</EM> </LI>
-
</OL>
<H2 CLASS="title"><A NAME="CUPSAPI">CUPS API</A></H2>
-<OL START="1">
+<OL START="59">
- <LI><EM>Streaming API;</EM> a new streaming request API provides asynchronous job creation and request submission.</LI>
+ <LI><EM>Backend API;</EM> a new cupsBackendReport function is provided to report a device from a backend and handles any needed quoting of the make-and-model, info, device-id, and location strings.</LI>
<LI><EM>Device discovery;</EM> the new <code>cupsGetDevices</code> function streams discovered devices to an application-provided callback function.</LI>
- <LI><EM>PPD support;</EM> two new functions are provided, cupsGetPPD3 and ppdLocalizeMarkerName, to update the local copy of a printers's PPD file and get a localized marker (supply) name, respectively.</LI>
-
- <LI><EM>;</EM> </LI>
-
- <LI><EM>;</EM> </LI>
+ <LI><EM>IPP API;</EM> the IPP read and write functions no longer use a large stack-based buffer when reading and writing IPP attributes.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>PPD support;</EM> several new functions are provided: cupsGetPPD3, cupsResolveConflicts, ppdInstallableConflict, ppdLocalizeAttr, ppdLocalizeMarkerName and ppdPageSizeLimits.</LI>
- <LI><EM>;</EM> </LI>
+ <LI><EM>Side-Channel API;</EM> new cupsSideChannelSNMPGet and cupsSideChannelSNMPWalk functions allow printer drivers to do SNMP queries via the standard network backends.</LI>
- <LI><EM>;</EM> </LI>
-
- <LI><EM>;</EM> </LI>
-
- <LI><EM>;</EM> </LI>
+ <LI><EM>Streaming API;</EM> a new streaming request API provides asynchronous job creation and request submission.</LI>
</OL>
*
* Contents:
*
+ * main() - Generate PostScript cover pages.
+ * load_banner() - Load the banner file.
+ * ps_ascii85() - Print binary data as a series of base-85 numbers.
+ * write_banner() - Write a banner page...
+ * write_epilogue() - Write the PostScript file epilogue.
+ * write_prolog() - Write the PostScript file prolog with options.
*/
/*
{
images = NULL;
images_height = 0;
+ images_width = 0;
}
total_height = info_height + notices_height + images_height;
y -= line_height;
psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT,
_cupsLangString(language, _("Printer Name: ")));
- psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, getenv("PRINTER_NAME"));
+ psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, getenv("PRINTER"));
}
if (banner->show & SHOW_JOB_ID)
{
- snprintf(text, sizeof(text), "%s-%d", getenv("PRINTER_NAME"), job_id);
+ snprintf(text, sizeof(text), "%s-%d", getenv("PRINTER"), job_id);
printf("%.1f %.1f moveto", x, y);
y -= line_height;
psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT,
+++ /dev/null
-msgid "\t\t(all)\n"
-msgstr "\t\t(tudo)\n"
-msgid "\t\t(none)\n"
-msgstr "\t\t(sem)\n"
-msgid "\t%d entries\n"
-msgstr "\t%d entradas\n"
-msgid "\tAfter fault: continue\n"
-msgstr "\tApós falha: continuar\n"
-msgid "\tAlerts:"
-msgstr "\tAlertas:"
-msgid "\tBanner required\n"
-msgstr "\tFaixa publicitária requerida\n"
-msgid "\tCharset sets:\n"
-msgstr "\tConjuntos charset:\n"
-msgid "\tConnection: direct\n"
-msgstr "\tLigação: directa\n"
-msgid "\tConnection: remote\n"
-msgstr "\tLigação: remota\n"
-msgid "\tDefault page size:\n"
-msgstr "\tTamanho de página predefinido:\n"
-msgid "\tDefault pitch:\n"
-msgstr "\tPitch predefinido:\n"
-msgid "\tDefault port settings:\n"
-msgstr "\tPredefinições de porta:\n"
-msgid "\tDescription: %s\n"
-msgstr "\tDescrição: %s\n"
-msgid "\tForm mounted:\n\tContent types: any\n\tPrinter types: unknown\n"
-msgstr "\tFormato montado:\n\tTipos de conteúdo: qualquer\n\tTipos de impressora: desconhecido\n"
-msgid "\tForms allowed:\n"
-msgstr "\tFormatos permitidos:\n"
-msgid "\tInterface: %s.ppd\n"
-msgstr "\tInterface: %s.ppd\n"
-msgid "\tInterface: %s/interfaces/%s\n"
-msgstr "\tInterface: %s/interfaces/%s\n"
-msgid "\tInterface: %s/ppd/%s.ppd\n"
-msgstr "\tInterface: %s/ppd/%s.ppd\n"
-msgid "\tLocation: %s\n"
-msgstr "\tLocalização: %s\n"
-msgid "\tOn fault: no alert\n"
-msgstr "\tEm falha: sem alerta\n"
-msgid "\tUsers allowed:\n"
-msgstr "\tUtilizadores permitidos:\n"
-msgid "\tUsers denied:\n"
-msgstr "\tUtilizadores negados:\n"
-msgid "\tdaemon present\n"
-msgstr "\tdaemon presente\n"
-msgid "\tno entries\n"
-msgstr "\tsem entradas\n"
-msgid "\tprinter is on device '%s' speed -1\n"
-msgstr "\timpressora está no periférico '%s' velocidade -1\n"
-msgid "\tprinting is disabled\n"
-msgstr "\timpressão desactivada\n"
-msgid "\tprinting is enabled\n"
-msgstr "\timpressão activada\n"
-msgid "\tqueued for %s\n"
-msgstr "\tem fila para %s\n"
-msgid "\tqueuing is disabled\n"
-msgstr "\tcolocação em fila desactivada\n"
-msgid "\tqueuing is enabled\n"
-msgstr "\tcolocação em fila activada\n"
-msgid "\treason unknown\n"
-msgstr "\tmotivo desconhecido\n"
-msgid "\n DETAILED CONFORMANCE TEST RESULTS\n"
-msgstr "\n RESULTADOS DETALHADOS DO TESTE DE CONFORMIDADE\n"
-msgid " REF: Page 15, section 3.1.\n"
-msgstr " REF: Página 15, secção 3.1.\n"
-msgid " REF: Page 15, section 3.2.\n"
-msgstr " REF: Página 15, secção 3.2.\n"
-msgid " REF: Page 19, section 3.3.\n"
-msgstr " REF: Página 19, secção 3.3.\n"
-msgid " REF: Page 20, section 3.4.\n"
-msgstr " REF: Página 20, secção 3.4.\n"
-msgid " REF: Page 27, section 3.5.\n"
-msgstr " REF: Página 27, secção 3.5.\n"
-msgid " REF: Page 42, section 5.2.\n"
-msgstr " REF: Página 42, secção 5.2.\n"
-msgid " REF: Pages 16-17, section 3.2.\n"
-msgstr " REF: Páginas 16-17, secção 3.2.\n"
-msgid " REF: Pages 42-45, section 5.2.\n"
-msgstr " REF: Páginas 42-45, secção 5.2.\n"
-msgid " REF: Pages 45-46, section 5.2.\n"
-msgstr " REF: Páginas 45-46, secção 5.2.\n"
-msgid " REF: Pages 48-49, section 5.2.\n"
-msgstr " REF: Páginas 48-49, secção 5.2.\n"
-msgid " REF: Pages 52-54, section 5.2.\n"
-msgstr " REF: Páginas 52-54, secção 5.2.\n"
-msgid " %-39.39s %.0f bytes\n"
-msgstr " %-39.39s %.0f bytes\n"
-msgid " PASS Default%s\n"
-msgstr " PASS Predefinição%s\n"
-msgid " PASS DefaultImageableArea\n"
-msgstr " PASS DefaultImageableArea\n"
-msgid " PASS DefaultPaperDimension\n"
-msgstr " PASS DefaultPaperDimension\n"
-msgid " PASS FileVersion\n"
-msgstr " PASS FileVersion\n"
-msgid " PASS FormatVersion\n"
-msgstr " PASS FormatVersion\n"
-msgid " PASS LanguageEncoding\n"
-msgstr " PASS LanguageEncoding\n"
-msgid " PASS LanguageVersion\n"
-msgstr " PASS LanguageVersion\n"
-msgid " PASS Manufacturer\n"
-msgstr " PASS Fabricante\n"
-msgid " PASS ModelName\n"
-msgstr " PASS ModelName\n"
-msgid " PASS NickName\n"
-msgstr " PASS NickName\n"
-msgid " PASS PCFileName\n"
-msgstr " PASS PCFileName\n"
-msgid " PASS PSVersion\n"
-msgstr " PASS PSVersion\n"
-msgid " PASS PageRegion\n"
-msgstr " PASS PageRegion\n"
-msgid " PASS PageSize\n"
-msgstr " PASS PageSize\n"
-msgid " PASS Product\n"
-msgstr " PASS Produto\n"
-msgid " PASS ShortNickName\n"
-msgstr " PASS ShortNickName\n"
-msgid " WARN \"%s %s\" conflicts with \"%s %s\"\n (constraint=\"%s %s %s %s\")\n"
-msgstr " WARN \"%s %s\" em conflito com \"%s %s\"\n (restrição=\"%s %s %s %s\")\n"
-msgid " WARN %s has no corresponding options!\n"
-msgstr " WARN %s não tem opções correspondentes!\n"
-msgid " WARN %s shares a common prefix with %s\n REF: Page 15, section 3.2.\n"
-msgstr " WARN %s partilha um prefixo comum com %s\n REF: Página 15, secção 3.2.\n"
-msgid " WARN Default choices conflicting!\n"
-msgstr " WARN Escolhas predefinidas em conflito!\n"
-msgid " WARN Duplex option keyword %s should be named Duplex or JCLDuplex!\n REF: Page 122, section 5.17\n"
-msgstr " WARN Palavra-chave de opção de frente e verso %s deve ter o nome Duplex ou JCLDuplex!\n REF: Página 122, secção 5.17\n"
-msgid " WARN File contains a mix of CR, LF, and CR LF line endings!\n"
-msgstr " WARN Ficheiro contém um misto de fins de linha CR, LF e CR LF!\n"
-msgid " WARN LanguageEncoding required by PPD 4.3 spec.\n REF: Pages 56-57, section 5.3.\n"
-msgstr " WARN LanguageEncoding requerido por espec. de PPD 4.3\n REF: Páginas 56-57, secção 5.3.\n"
-msgid " WARN Line %d only contains whitespace!\n"
-msgstr " WARN Linha %d só contém espaço em branco!\n"
-msgid " WARN Manufacturer required by PPD 4.3 spec.\n REF: Pages 58-59, section 5.3.\n"
-msgstr " WARN Fabricante requerido por espec. de PPD 4.3\n REF: Páginas 58-59, secção 5.3.\n"
-msgid " WARN Missing APDialogExtension file \"%s\"\n"
-msgstr " WARN Ficheiro APDialogExtension inexistente \"%s\"\n"
-msgid " WARN Missing APPrinterIconPath file \"%s\"\n"
-msgstr " WARN Ficheiro APPrinterIconPath inexistente \"%s\"\n"
-msgid " WARN Missing cupsICCProfile file \"%s\"\n"
-msgstr " WARN Ficheiro cupsICCProfile inexistente \"%s\"\n"
-msgid " WARN Non-Windows PPD files should use lines ending with only LF, not CR LF!\n"
-msgstr " WARN Ficheiros PPD não Windows devem utilizar fins de linha com LF, e não CR LF!\n"
-msgid " WARN Obsolete PPD version %.1f!\n REF: Page 42, section 5.2.\n"
-msgstr " WARN Versão de PPD obsoleta %.1f!\n REF: Página 42, secção 5.2"
-msgid " WARN PCFileName longer than 8.3 in violation of PPD spec.\n REF: Pages 61-62, section 5.3.\n"
-msgstr " WARN PCFileName superior a 8.3 viola espec. de PPD\n REF: Páginas 61-62, secção 5.3.\n"
-msgid " WARN Protocols contains PJL but JCL attributes are not set.\n REF: Pages 78-79, section 5.7.\n"
-msgstr " WARN Protocolos contêm PJL, mas atributos JCL não estão especificados.\n REF: Páginas 78-79, secção 5.7.\n"
-msgid " WARN Protocols contains both PJL and BCP; expected TBCP.\n REF: Pages 78-79, section 5.7.\n"
-msgstr " WARN Protocolos contêm PJL e BCP; TBCP esperados.\n REF: Páginas 78-79, secção 5.7.\n"
-msgid " WARN ShortNickName required by PPD 4.3 spec.\n REF: Pages 64-65, section 5.3.\n"
-msgstr " WARN ShortNickName requerido por espec. de PPD 4.3\n REF: Páginas 64-65, secção 5.3.\n"
-msgid " %s %s %s does not exist!\n"
-msgstr " %s %s %s não existe!\n"
-msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n"
-msgstr " %s Cadeia de tradução UTF-8 \"%s\" inválida para opção %s!\n"
-msgid " %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n"
-msgstr " %s Cadeia de tradução UTF-8 \"%s\" inválida para opção %s, escolha %s!\n"
-msgid " %s Bad cupsFilter value \"%s\"!\n"
-msgstr " %s Valor cupsFilter inválido \"%s\"!\n"
-msgid " %s Bad cupsPreFilter value \"%s\"!\n"
-msgstr " %s Valor cupsPreFilter inválido \"%s\"!\n"
-msgid " %s Bad language \"%s\"!\n"
-msgstr " %s Idioma inválido \"%s\"!\n"
-msgid " %s Missing \"%s\" translation string for option %s!\n"
-msgstr " %s Cadeia de tradução inexistente \"%s\" para opção %s!\n"
-msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n"
-msgstr " %s Cadeia de tradução inexistente \"%s\" para opção %s, escolha %s!\n"
-msgid " %s Missing choice *%s %s in UIConstraint \"*%s %s *%s %s\"!\n"
-msgstr " %s Escolha inexistente *%s %s em UIConstraint \"*%s %s *%s %s\"!\n"
-msgid " %s Missing cupsFilter file \"%s\"\n"
-msgstr " %s Ficheiro cupsFilter inexistente \"%s\"!\n"
-msgid " %s Missing cupsPreFilter file \"%s\"\n"
-msgstr " %s Ficheiro cupsPreFilter inexistente \"%s\"!\n"
-msgid " %s Missing option %s in UIConstraint \"*%s %s *%s %s\"!\n"
-msgstr " %s Opção inexistente %s em UIConstraint \"*%s %s *%s %s\"!\n"
-msgid " %s No base translation \"%s\" is included in file!\n"
-msgstr " %s Sem tradução base \"%s\" incluÃda no ficheiro!\n"
-msgid " **FAIL** %s must be 1284DeviceID!\n REF: Page 72, section 5.5\n"
-msgstr " **FAIL** %s deve ser 1284DeviceID!\n REF: Página 72, secção 5.5\n"
-msgid " **FAIL** BAD Default%s %s\n REF: Page 40, section 4.5.\n"
-msgstr " **FAIL** Predefinição%s %s inválida\n REF: Página 40, secção 4.5\n"
-msgid " **FAIL** BAD DefaultImageableArea %s!\n REF: Page 102, section 5.15.\n"
-msgstr " **FAIL** DefaultImageableArea %s inválida!\n REF: Página 102, secção 5.15\n"
-msgid " **FAIL** BAD DefaultPaperDimension %s!\n REF: Page 103, section 5.15.\n"
-msgstr " **FAIL** DefaultPaperDimension %s inválida!\n REF: Página 103, secção 5.15\n"
-msgid " **FAIL** BAD JobPatchFile attribute in file\n REF: Page 24, section 3.4.\n"
-msgstr " **FAIL** Atributo JobPatchFile inválido no ficheiro!\n REF: Página 24, secção 3.4\n"
-msgid " **FAIL** BAD Manufacturer (should be \"HP\")\n REF: Page 211, table D.1.\n"
-msgstr " **FAIL** Fabricante inválido (deve ser \"HP\")\n REF: Página 211, tabela D.1.\n"
-msgid " **FAIL** BAD Manufacturer (should be \"Oki\")\n REF: Page 211, table D.1.\n"
-msgstr " **FAIL** Fabricante inválido (deve ser \"Oki\")\n REF: Página 211, tabela D.1.\n"
-msgid " **FAIL** BAD ModelName - \"%c\" not allowed in string.\n REF: Pages 59-60, section 5.3.\n"
-msgstr " **FAIL** ModelName inválido - \"%c\" não permitido na cadeia.\n REF: Páginas 59-60, secção 5.3\n"
-msgid " **FAIL** BAD PSVersion - not \"(string) int\".\n REF: Pages 62-64, section 5.3.\n"
-msgstr " **FAIL** PSVersion inválida - não \"(cadeia) int\".\n REF: Páginas 62-64, secção 5.3\n"
-msgid " **FAIL** BAD Product - not \"(string)\".\n REF: Page 62, section 5.3.\n"
-msgstr " **FAIL** Produto inválido - não \"(cadeia)\".\n REF: Página 62, secção 5.3\n"
-msgid " **FAIL** BAD ShortNickName - longer than 31 chars.\n REF: Pages 64-65, section 5.3.\n"
-msgstr " **FAIL** ShortNickName inválido - superior a 31 car.\n REF: Páginas 64-65, secção 5.3\n"
-msgid " **FAIL** Bad %s choice %s!\n REF: Page 122, section 5.17\n"
-msgstr " **FAIL** Escolha %s inválida %s!\n REF: Página 122, secção 5.17\n"
-msgid " **FAIL** Bad %s choice %s!\n REF: Page 84, section 5.9\n"
-msgstr " **FAIL** Escolha %s inválida %s!\n REF: Página 84, secção 5.9\n"
-msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n"
-msgstr " **FAIL** LanguageEncoding %s inválida - deve ser ISOLatin1!\n"
-msgid " **FAIL** Bad LanguageVersion %s - must be English!\n"
-msgstr " **FAIL** LanguageVersion %s inválida - deve ser Inglês!\n"
-msgid " **FAIL** Default option code cannot be interpreted: %s\n"
-msgstr " **FAIL** ImpossÃvel interpretar código de opção predefinida: %s\n"
-msgid " **FAIL** Default translation string for option %s choice %s contains 8-bit characters!\n"
-msgstr " **FAIL** Cadeia de tradução predefinida para opção %s escolha %s contém caracteres de 8 bits!\n"
-msgid " **FAIL** Default translation string for option %s contains 8-bit characters!\n"
-msgstr " **FAIL** Cadeia de tradução predefinida para opção %s contém caracteres de 8 bits!\n"
-msgid " **FAIL** REQUIRED %s does not define choice None!\n REF: Page 122, section 5.17\n"
-msgstr " **FAIL** %s requerido não define escolha Sem!\n REF: Página 122, secção 5.17\n"
-msgid " **FAIL** REQUIRED Default%s\n REF: Page 40, section 4.5.\n"
-msgstr " **FAIL** Predefinição%s requerida\n REF: Página 40, secção 4.5\n"
-msgid " **FAIL** REQUIRED DefaultImageableArea\n REF: Page 102, section 5.15.\n"
-msgstr " **FAIL** DefaultImageableArea requerida\n REF: Página 102, secção 5.15\n"
-msgid " **FAIL** REQUIRED DefaultPaperDimension\n REF: Page 103, section 5.15.\n"
-msgstr " **FAIL** DefaultPaperDimension requerida\n REF: Página 103, secção 5.15\n"
-msgid " **FAIL** REQUIRED FileVersion\n REF: Page 56, section 5.3.\n"
-msgstr " **FAIL** FileVersion requerida\n REF: Página 56, secção 5.3\n"
-msgid " **FAIL** REQUIRED FormatVersion\n REF: Page 56, section 5.3.\n"
-msgstr " **FAIL** FormatVersion requerida\n REF: Página 56, secção 5.3\n"
-msgid " **FAIL** REQUIRED ImageableArea for PageSize %s\n REF: Page 41, section 5.\n REF: Page 102, section 5.15.\n"
-msgstr " **FAIL** ImageableArea requerida para PageSize %s\n REF: Página 41, secção 5.\n REF: Página 102, secção 5.15.\n"
-msgid " **FAIL** REQUIRED LanguageEncoding\n REF: Pages 56-57, section 5.3.\n"
-msgstr " **FAIL** LanguageEncoding requerida\n REF: Páginas 56-57, secção 5.3\n"
-msgid " **FAIL** REQUIRED LanguageVersion\n REF: Pages 57-58, section 5.3.\n"
-msgstr " **FAIL** LanguageVersion requerida\n REF: Páginas 57-58, secção 5.3\n"
-msgid " **FAIL** REQUIRED Manufacturer\n REF: Pages 58-59, section 5.3.\n"
-msgstr " **FAIL** Fabricante requerido\n REF: Páginas 58-59, secção 5.3\n"
-msgid " **FAIL** REQUIRED ModelName\n REF: Pages 59-60, section 5.3.\n"
-msgstr " **FAIL** ModelName requerido\n REF: Páginas 59-60, secção 5.3\n"
-msgid " **FAIL** REQUIRED NickName\n REF: Page 60, section 5.3.\n"
-msgstr " **FAIL** NickName requerido\n REF: Página 60, secção 5.3\n"
-msgid " **FAIL** REQUIRED PCFileName\n REF: Pages 61-62, section 5.3.\n"
-msgstr " **FAIL** PCFileName requerido\n REF: Páginas 61-62, secção 5.3\n"
-msgid " **FAIL** REQUIRED PSVersion\n REF: Pages 62-64, section 5.3.\n"
-msgstr " **FAIL** PSVersion requerida\n REF: Páginas 62-64, secção 5.3\n"
-msgid " **FAIL** REQUIRED PageRegion\n REF: Page 100, section 5.14.\n"
-msgstr " **FAIL** PageRegion requerida\n REF: Página 100, secção 5.14\n"
-msgid " **FAIL** REQUIRED PageSize\n REF: Page 41, section 5.\n REF: Page 99, section 5.14.\n"
-msgstr " **FAIL** PageSize requerido\n REF: Página 41, secção 5.\n REF: Página 99, secção 5.14.\n"
-msgid " **FAIL** REQUIRED PageSize\n REF: Pages 99-100, section 5.14.\n"
-msgstr " **FAIL** PageSize requerido\n REF: Páginas 99-100, secção 5.14\n"
-msgid " **FAIL** REQUIRED PaperDimension for PageSize %s\n REF: Page 41, section 5.\n REF: Page 103, section 5.15.\n"
-msgstr " **FAIL** PaperDimension requerida para PageSize %s\n REF: Página 41, secção 5.\n REF: Página 103, secção 5.15.\n"
-msgid " **FAIL** REQUIRED Product\n REF: Page 62, section 5.3.\n"
-msgstr " **FAIL** Produto requerido\n REF: Página 62, secção 5.3\n"
-msgid " **FAIL** REQUIRED ShortNickName\n REF: Page 64-65, section 5.3.\n"
-msgstr " **FAIL** ShortNickName requerido\n REF: Páginas 64-65, secção 5.3\n"
-msgid " %d ERRORS FOUND\n"
-msgstr " %d ERROS ENCONTRADOS\n"
-msgid " Bad %%%%BoundingBox: on line %d!\n REF: Page 39, %%%%BoundingBox:\n"
-msgstr " %%%%BoundingBox: inválida na linha %d!\n REF: Página 39, %%%%BoundingBox:\n"
-msgid " Bad %%%%Page: on line %d!\n REF: Page 53, %%%%Page:\n"
-msgstr " %%%%Page: inválida na linha %d!\n REF: Página 53, %%%%Page:\n"
-msgid " Bad %%%%Pages: on line %d!\n REF: Page 43, %%%%Pages:\n"
-msgstr " %%%%Pages: inválidas na linha %d!\n REF: Página 43, %%%%Pages:\n"
-msgid " Line %d is longer than 255 characters (%d)!\n REF: Page 25, Line Length\n"
-msgstr " Linha %d tem mais de 255 caracteres (%d)!\n REF: Página 25, Comprimento da Linha\n"
-msgid " Missing %!PS-Adobe-3.0 on first line!\n REF: Page 17, 3.1 Conforming Documents\n"
-msgstr " %!PS-Adobe-3.0 inexistente na primeira linha!\n REF: Página 17, 3.1 Documentos de Conformidade\n"
-msgid " Missing %%EndComments comment!\n REF: Page 41, %%EndComments\n"
-msgstr " Comentário %%EndComments inexistente!\n REF: Página 41, %%EndComments\n"
-msgid " Missing or bad %%BoundingBox: comment!\n REF: Page 39, %%BoundingBox:\n"
-msgstr " Comentário %%BoundingBox: inexistente ou inválido!\n REF: Página 39, %%BoundingBox:\n"
-msgid " Missing or bad %%Page: comments!\n REF: Page 53, %%Page:\n"
-msgstr " Comentários %%Page: inexistentes ou inválidos!\n REF: Página 53, %%Page:\n"
-msgid " Missing or bad %%Pages: comment!\n REF: Page 43, %%Pages:\n"
-msgstr " Comentário %%Pages: inexistente ou inválido!\n REF: Página 43, %%Pages:\n"
-msgid " NO ERRORS FOUND\n"
-msgstr " SEM ERROS\n"
-msgid " Saw %d lines that exceeded 255 characters!\n"
-msgstr " Detectadas %d linhas que excedem 255 caracteres!\n"
-msgid " Too many %%BeginDocument comments!\n"
-msgstr " Demasiados comentários %%BeginDocument!\n"
-msgid " Too many %%EndDocument comments!\n"
-msgstr " Demasiados comentários %%EndDocument!\n"
-msgid " Warning: file contains binary data!\n"
-msgstr " Aviso: ficheiro contém dados binários!\n"
-msgid " Warning: no %%EndComments comment in file!\n"
-msgstr " Aviso: sem comentário %%EndComments no ficheiro!\n"
-msgid " Warning: obsolete DSC version %.1f in file!\n"
-msgstr " Aviso: versão obsoleta de DSC %.1f no ficheiro!\n"
-msgid " FAIL\n"
-msgstr " FAIL\n"
-msgid " FAIL\n **FAIL** Unable to open PPD file - %s\n"
-msgstr " FAIL\n **FAIL** ImpossÃvel abrir ficheiro PPD - %s\n"
-msgid " FAIL\n **FAIL** Unable to open PPD file - %s on line %d.\n"
-msgstr " FAIL\n **FAIL** ImpossÃvel abrir ficheiro PPD - %s na linha %d.\n"
-msgid " PASS\n"
-msgstr " PASS\n"
-msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n"
-msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n"
-msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n"
-msgstr "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n"
-msgid "%s accepting requests since %s\n"
-msgstr "%s aceita pedidos desde %s\n"
-msgid "%s cannot be changed."
-msgstr "ImpossÃvel alterar %s."
-msgid "%s is not implemented by the CUPS version of lpc.\n"
-msgstr "%s não é implementado pela versão CUPS de lpc.\n"
-msgid "%s is not ready\n"
-msgstr "%s não está preparada\n"
-msgid "%s is ready\n"
-msgstr "%s está preparada\n"
-msgid "%s is ready and printing\n"
-msgstr "%s está preparada e a imprimir\n"
-msgid "%s not accepting requests since %s -\n\t%s\n"
-msgstr "%s não aceita pedidos desde %s-\n\t%s\n"
-msgid "%s not supported!"
-msgstr "%s não suportado!"
-msgid "%s/%s accepting requests since %s\n"
-msgstr "%s/%s aceita pedidos desde %s\n"
-msgid "%s/%s not accepting requests since %s -\n\t%s\n"
-msgstr "%s/%s não aceita pedidos desde %s-\n\t%s\n"
-msgid "%s: %-33.33s [job %d localhost]\n"
-msgstr "%s: %-33.33s [trabalho %d localhost]\n"
-msgid "%s: %s failed: %s\n"
-msgstr "%s: %s falhou: %s\n"
-msgid "%s: Don't know what to do!\n"
-msgstr "%s: Não sei que fazer!\n"
-msgid "%s: Error - %s environment variable names non-existent destination \"%s\"!\n"
-msgstr "%s: Erro - nomes de variáveis de ambiente %s inexistentes no destino \"%s\"!\n"
-msgid "%s: Error - bad job ID!\n"
-msgstr "%s: Erro - ID de trabalho inválido!\n"
-msgid "%s: Error - cannot print files and alter jobs simultaneously!\n"
-msgstr "%s: Erro - impossÃvel imprimir ficheiros e alterar trabalhos em simultâneo!\n"
-msgid "%s: Error - cannot print from stdin if files or a job ID are provided!\n"
-msgstr "%s: Erro - impossÃvel imprimir a partir de stdin se fornecidos ficheiros ou ID do trabalho!\n"
-msgid "%s: Error - expected character set after '-S' option!\n"
-msgstr "%s: Erro - conjunto de caracteres esperado após opção '-S'!\n"
-msgid "%s: Error - expected content type after '-T' option!\n"
-msgstr "%s: Erro - tipo de conteúdo esperado após opção '-T'!\n"
-msgid "%s: Error - expected copies after '-n' option!\n"
-msgstr "%s: Erro - cópias esperadas após opção '-n'!\n"
-msgid "%s: Error - expected copy count after '-#' option!\n"
-msgstr "%s: Erro - contagem de cópias esperadas após opção '-#'!\n"
-msgid "%s: Error - expected destination after '-P' option!\n"
-msgstr "%s: Erro - destino esperado após opção '-P'!\n"
-msgid "%s: Error - expected destination after '-b' option!\n"
-msgstr "%s: Erro - destino esperado após opção '-b'!\n"
-msgid "%s: Error - expected destination after '-d' option!\n"
-msgstr "%s: Erro - destino esperado após opção '-d'!\n"
-msgid "%s: Error - expected form after '-f' option!\n"
-msgstr "%s: Erro - formato esperado após opção '-f'!\n"
-msgid "%s: Error - expected hold name after '-H' option!\n"
-msgstr "%s: Erro - nome para reter esperado após opção '-H'!\n"
-msgid "%s: Error - expected hostname after '-H' option!\n"
-msgstr "%s: Erro - nome de host esperado após opção '-H'!\n"
-msgid "%s: Error - expected hostname after '-h' option!\n"
-msgstr "%s: Erro - nome de host esperado após opção '-h'!\n"
-msgid "%s: Error - expected mode list after '-y' option!\n"
-msgstr "%s: Erro - lista de modo esperada após opção '-y'!\n"
-msgid "%s: Error - expected name after '-%c' option!\n"
-msgstr "%s: Erro - nome esperado após opção '-%c'!\n"
-msgid "%s: Error - expected option string after '-o' option!\n"
-msgstr "%s: Erro - cadeia de opção esperada após opção '-o'!\n"
-msgid "%s: Error - expected page list after '-P' option!\n"
-msgstr "%s: Erro - lista de página esperada após opção '-P'!\n"
-msgid "%s: Error - expected priority after '-%c' option!\n"
-msgstr "%s: Erro - prioridade esperada após opção '-%c'!\n"
-msgid "%s: Error - expected reason text after '-r' option!\n"
-msgstr "%s: Erro - texto de motivo esperado após opção '-r'!\n"
-msgid "%s: Error - expected title after '-t' option!\n"
-msgstr "%s: Erro - tÃtulo esperado após opção '-t'!\n"
-msgid "%s: Error - expected username after '-U' option!\n"
-msgstr "%s: Erro - nome de utilizador esperado após opção '-U'!\n"
-msgid "%s: Error - expected username after '-u' option!\n"
-msgstr "%s: Erro - nome de utilizador esperado após opção '-u'!\n"
-msgid "%s: Error - expected value after '-%c' option!\n"
-msgstr "%s: Erro - valor esperado após opção '-%c'!\n"
-msgid "%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' option!\n"
-msgstr "%s: Erro - necessário \"concluÃdo\", \"não concluÃdo\" ou \"tudo\" após opção '-W'!\n"
-msgid "%s: Error - no default destination available.\n"
-msgstr "%s: Erro - sem destino predefinido disponÃvel.\n"
-msgid "%s: Error - priority must be between 1 and 100.\n"
-msgstr "%s: Erro - prioridade deve ser entre 1 e 100.\n"
-msgid "%s: Error - scheduler not responding!\n"
-msgstr "%s: Erro - programador não responde!\n"
-msgid "%s: Error - stdin is empty, so no job has been sent.\n"
-msgstr "%s: Erro - stdin está vazio, por isso nenhum trabalho foi enviado.\n"
-msgid "%s: Error - too many files - \"%s\"\n"
-msgstr "%s: Erro - demasiados ficheiros - \"%s\"\n"
-msgid "%s: Error - unable to access \"%s\" - %s\n"
-msgstr "%s: Erro - impossÃvel aceder a \"%s\" - %s\n"
-msgid "%s: Error - unable to create temporary file \"%s\" - %s\n"
-msgstr "%s: Erro - impossÃvel criar ficheiro temporário \"%s\" - %s\n"
-msgid "%s: Error - unable to write to temporary file \"%s\" - %s\n"
-msgstr "%s: Erro - impossÃvel escrever no ficheiro temporário \"%s\" - %s\n"
-msgid "%s: Error - unknown destination \"%s\"!\n"
-msgstr "%s: Erro - destino desconhecido \"%s\"!\n"
-msgid "%s: Error - unknown destination \"%s/%s\"!\n"
-msgstr "%s: Erro - destino desconhecido \"%s/%s\"!\n"
-msgid "%s: Error - unknown option '%c'!\n"
-msgstr "%s: Erro - opção desconhecida '%c'!\n"
-msgid "%s: Expected job ID after '-i' option!\n"
-msgstr "%s: ID de trabalho esperado após opção '-i'!\n"
-msgid "%s: Invalid destination name in list \"%s\"!\n"
-msgstr "%s: Nome de destino inválido na lista \"%s\"!\n"
-msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n"
-msgstr "%s: Necessário ID do trabalho ('-i jobid') antes de '-H reiniciar'!\n"
-msgid "%s: Operation failed: %s\n"
-msgstr "%s: Operação falhou: %s\n"
-msgid "%s: Sorry, no encryption support compiled in!\n"
-msgstr "%s: Sem suporte de encriptação compilado!\n"
-msgid "%s: Unable to connect to server\n"
-msgstr "%s: ImpossÃvel ligar ao servidor\n"
-msgid "%s: Unable to connect to server: %s\n"
-msgstr "%s: ImpossÃvel ligar ao servidor: %s\n"
-msgid "%s: Unable to contact server!\n"
-msgstr "%s: ImpossÃvel contactar servidor!\n"
-msgid "%s: Unknown destination \"%s\"!\n"
-msgstr "%s: Destino desconhecido \"%s\"!\n"
-msgid "%s: Unknown option '%c'!\n"
-msgstr "%s: Opção desconhecida '%c'!\n"
-msgid "%s: Warning - '%c' format modifier not supported - output may not be correct!\n"
-msgstr "%s: Aviso - modificador de formato '%c' não suportado - saÃda pode ser incorrecta!\n"
-msgid "%s: Warning - character set option ignored!\n"
-msgstr "%s: Aviso - opção de conjunto de caracteres ignorada!\n"
-msgid "%s: Warning - content type option ignored!\n"
-msgstr "%s: Aviso - opção de tipo de conteúdo ignorada!\n"
-msgid "%s: Warning - form option ignored!\n"
-msgstr "%s: Aviso - opção de formato ignorada!\n"
-msgid "%s: Warning - mode option ignored!\n"
-msgstr "%s: Aviso - opção de modo ignorada!\n"
-msgid "%s: error - %s environment variable names non-existent destination \"%s\"!\n"
-msgstr "%s: Erro - nomes de variáveis de ambiente %s inexistentes no destino \"%s\"!\n"
-msgid "%s: error - expected option=value after '-o' option!\n"
-msgstr "%s: Erro - opção=valor esperada após opção '-o'!\n"
-msgid "%s: error - no default destination available.\n"
-msgstr "%s: Erro - sem destino predefinido disponÃvel.\n"
-msgid "?Invalid help command unknown\n"
-msgstr "?Comando de ajuda inválido desconhecido\n"
-msgid "A Samba password is required to export printer drivers!"
-msgstr "Palavra-passe Samba requerida para exportar recursos de impressora!"
-msgid "A Samba username is required to export printer drivers!"
-msgstr "Nome de utilizador Samba requerido para exportar recursos de impressora!"
-msgid "A class named \"%s\" already exists!"
-msgstr "Uma classe com o nome \"%s\" já existe!"
-msgid "A printer named \"%s\" already exists!"
-msgstr "Uma impressora com o nome \"%s\" já existe!"
-msgid "Accept Jobs"
-msgstr "Aceitar trabalhos"
-msgid "Add Class"
-msgstr "Adicionar classe"
-msgid "Add Printer"
-msgstr "Adicionar impressora"
-msgid "Add RSS Subscription"
-msgstr "Adicionar subscrição RSS"
-msgid "Administration"
-msgstr "Administração"
-msgid "Attempt to set %s printer-state to bad value %d!"
-msgstr "Tentativa de especificar %s printer-state para valor inválido %d!"
-msgid "Attribute groups are out of order (%x < %x)!"
-msgstr "Grupos de atributos desordenados (%x < %x)!"
-msgid "Bad OpenGroup"
-msgstr "OpenGroup inválido"
-msgid "Bad OpenUI/JCLOpenUI"
-msgstr "OpenUI/JCLOpenUI inválidos"
-msgid "Bad OrderDependency"
-msgstr "OrderDependency inválida"
-msgid "Bad UIConstraints"
-msgstr "UIConstraints inválidas"
-msgid "Bad copies value %d."
-msgstr "Valor de cópias inválido %d."
-msgid "Bad custom parameter"
-msgstr "Parâmetro personalizado inválido"
-msgid "Bad device-uri \"%s\"!"
-msgstr "Device-uri \"%s\" inválido!"
-msgid "Bad document-format \"%s\"!"
-msgstr "Document-format \"%s\" inválido!"
-msgid "Bad job-priority value!"
-msgstr "Valor job-priority inválido!"
-msgid "Bad job-state value!"
-msgstr "Valor job-state inválido!"
-msgid "Bad job-uri attribute \"%s\"!"
-msgstr "Atributo job-uri \"%s\" inválido!"
-msgid "Bad notify-pull-method \"%s\"!"
-msgstr "Notify-pull-method \"%s\" inválido!"
-msgid "Bad notify-recipient-uri URI \"%s\"!"
-msgstr "Notify-recipient-uri URI \"%s\" inválido!"
-msgid "Bad number-up value %d."
-msgstr "Valor number-up inválido %d."
-msgid "Bad option + choice on line %d!"
-msgstr "Opção + escolha inválidas na linha %d!"
-msgid "Bad page-ranges values %d-%d."
-msgstr "Valores page-ranges inválidos %d-%d."
-msgid "Bad port-monitor \"%s\"!"
-msgstr "Port-monitor \"%s\" inválido!"
-msgid "Bad printer-state value %d!"
-msgstr "Valor printer-state inválido %d!"
-msgid "Bad request version number %d.%d!"
-msgstr "Número de versão pedido inválido %d.%d!"
-msgid "Bad subscription ID!"
-msgstr "ID de subscrição inválido!"
-msgid "Banners"
-msgstr "Faixas publicitárias"
-msgid "Cancel RSS Subscription"
-msgstr "Cancelar subscrição RSS"
-msgid "Change Settings"
-msgstr "Alterar especificações"
-msgid "Character set \"%s\" not supported!"
-msgstr "Conjunto de caracteres \"%s\" não suportado!"
-msgid "Classes"
-msgstr "Classes"
-msgid "Commands may be abbreviated. Commands are:\n\nexit help quit status ?\n"
-msgstr "É possÃvel abreviar comandos. Comandos são:\n\nsair ajuda sair estado ?\n"
-msgid "Could not scan type \"%s\"!"
-msgstr "ImpossÃvel procurar tipo \"%s\"!"
-msgid "Cover open."
-msgstr "Tampa aberta."
-msgid "Custom"
-msgstr "Personalizar"
-msgid "Delete Class"
-msgstr "Apagar classe"
-msgid "Delete Printer"
-msgstr "Apagar impressora"
-msgid "Destination \"%s\" is not accepting jobs."
-msgstr "Destino \"%s\" não está a aceitar trabalhos."
-msgid "Developer almost empty."
-msgstr "Programador quase vazio."
-msgid "Developer empty!"
-msgstr "Programador vazio!"
-msgid "Device: uri = %s\n class = %s\n info = %s\n make-and-model = %s\n device-id = %s\n"
-msgstr "Periférico: uri = %s\n class = %s\n info = %s\n make-and-model = %s\n device-id = %s\n"
-msgid "Door open."
-msgstr "Porta aberta."
-msgid "EMERG: Unable to allocate memory for page info: %s\n"
-msgstr "EMERG: ImpossÃvel alocar memória para info de página: %s\n"
-msgid "EMERG: Unable to allocate memory for pages array: %s\n"
-msgstr "EMERG: ImpossÃvel alocar memória para matriz de páginas: %s\n"
-msgid "ERROR: %ld: (canceled:%ld)\n"
-msgstr "ERROR: %ld: (cancelado:%ld)\n"
-msgid "ERROR: Bad %%BoundingBox: comment seen!\n"
-msgstr "ERROR: Detectado comentário %%BoundingBox: inválido!\n"
-msgid "ERROR: Bad %%IncludeFeature: comment!\n"
-msgstr "ERROR: Detectado comentário %%IncludeFeature: inválido!\n"
-msgid "ERROR: Bad %%Page: comment in file!\n"
-msgstr "ERROR: Comentário %%Page: inválido no ficheiro!\n"
-msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n"
-msgstr "ERROR: Comentário %%PageBoundingBox: inválido no ficheiro!\n"
-msgid "ERROR: Bad SCSI device file \"%s\"!\n"
-msgstr "ERROR: Ficheiro de periférico SCSI inválido \"%s\"!\n"
-msgid "ERROR: Bad charset file %s\n"
-msgstr "ERROR: Ficheiro charset inválido %s\n"
-msgid "ERROR: Bad charset type %s\n"
-msgstr "ERROR: Tipo charset inválido %s\n"
-msgid "ERROR: Bad font description line: %s\n"
-msgstr "ERROR: Linha de descrição de tipo de letra inválida: %s\n"
-msgid "ERROR: Bad page setup!\n"
-msgstr "ERROR: Configuração de página inválida!\n"
-msgid "ERROR: Bad text direction %s\n"
-msgstr "ERROR: Orientação de texto inválida %s\n"
-msgid "ERROR: Bad text width %s\n"
-msgstr "ERROR: Largura de texto inválida %s\n"
-msgid "ERROR: Destination printer does not exist!\n"
-msgstr "ERROR: Impressora de destino não existe!\n"
-msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n"
-msgstr "ERROR: Detectado comentário %%BoundingBox: em duplicado!\n"
-msgid "ERROR: Duplicate %%Pages: comment seen!\n"
-msgstr "ERROR: Detectado comentário %%Pages: em duplicado!\n"
-msgid "ERROR: Empty print file!\n"
-msgstr "ERROR: Ficheiro de impressão vazio!\n"
-msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n"
-msgstr "ERROR: Detectado comando HP-GL/2 inválido; impossÃvel imprimir ficheiro!\n"
-msgid "ERROR: Missing %%EndProlog!\n"
-msgstr "ERROR: %%EndProlog inexistente!\n"
-msgid "ERROR: Missing %%EndSetup!\n"
-msgstr "ERROR: %%EndSetup inexistente!\n"
-msgid "ERROR: Missing device URI on command-line and no DEVICE_URI environment variable!\n"
-msgstr "ERROR: URI de periférico inexistente em command-line e sem variável de ambiente DEVICE_URI!\n"
-msgid "ERROR: No %%BoundingBox: comment in header!\n"
-msgstr "ERROR: Sem comentário %%BoundingBox: no cabeçalho!\n"
-msgid "ERROR: No %%Pages: comment in header!\n"
-msgstr "ERROR: Sem comentário %%Pages: no cabeçalho!\n"
-msgid "ERROR: No device URI found in argv[0] or in DEVICE_URI environment variable!\n"
-msgstr "ERROR: Sem URI de periférico em argv[0] ou na variável de ambiente DEVICE_URI!\n"
-msgid "ERROR: No pages found!\n"
-msgstr "ERROR: Sem páginas!\n"
-msgid "ERROR: Out of paper!\n"
-msgstr "ERROR: Sem papel!\n"
-msgid "ERROR: PRINTER environment variable not defined!\n"
-msgstr "ERROR: Variável de ambiente PRINTER não definida!\n"
-msgid "ERROR: Print file was not accepted (%s)!\n"
-msgstr "ERROR: Ficheiro de impressão não foi aceite (%s)!\n"
-msgid "ERROR: Printer not responding!\n"
-msgstr "ERROR: Impressora não responde!\n"
-msgid "ERROR: Remote host did not accept control file (%d)\n"
-msgstr "ERROR: Host remoto não aceitou ficheiro de controlo (%d)\n"
-msgid "ERROR: Remote host did not accept data file (%d)\n"
-msgstr "ERROR: Host remoto não aceitou ficheiro de dados (%d)\n"
-msgid "ERROR: Unable to add file %d to job: %s\n"
-msgstr "ERROR: ImpossÃvel adicionar ficheiro %d ao trabalho: %s\n"
-msgid "ERROR: Unable to cancel job %d: %s\n"
-msgstr "ERROR: ImpossÃvel cancelar trabalho %d: %s\n"
-msgid "ERROR: Unable to create temporary compressed print file: %s\n"
-msgstr "ERROR: ImpossÃvel criar ficheiro de impressão comprimido temporário: %s\n"
-msgid "ERROR: Unable to create temporary file - %s.\n"
-msgstr "ERROR: ImpossÃvel criar ficheiro temporário - %s.\n"
-msgid "ERROR: Unable to create temporary file: %s\n"
-msgstr "ERROR: ImpossÃvel criar ficheiro temporário: %s.\n"
-msgid "ERROR: Unable to exec pictwpstops: %s\n"
-msgstr "ERROR: ImpossÃvel executar pictwpstops: %s\n"
-msgid "ERROR: Unable to fork pictwpstops: %s\n"
-msgstr "ERROR: ImpossÃvel separar pictwpstops: %s\n"
-msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n"
-msgstr "ERROR: ImpossÃvel obter ficheiro PPD para impressora \"%s\" - %s.\n"
-msgid "ERROR: Unable to get job %d attributes (%s)!\n"
-msgstr "ERROR: ImpossÃvel obter atributos do trabalho %d (%s)!\n"
-msgid "ERROR: Unable to get printer status (%s)!\n"
-msgstr "ERROR: ImpossÃvel obter estado da impressora (%s)!\n"
-msgid "ERROR: Unable to locate printer '%s'!\n"
-msgstr "ERROR: ImpossÃvel localizar impressora '%s'!\n"
-msgid "ERROR: Unable to open \"%s\" - %s\n"
-msgstr "ERROR: ImpossÃvel abrir \"%s\" - %s\n"
-msgid "ERROR: Unable to open %s: %s\n"
-msgstr "ERROR: ImpossÃvel abrir %s: %s\n"
-msgid "ERROR: Unable to open device file \"%s\": %s\n"
-msgstr "ERROR: ImpossÃvel abrir ficheiro de periférico \"%s\": %s\n"
-msgid "ERROR: Unable to open file \"%s\" - %s\n"
-msgstr "ERROR: ImpossÃvel abrir ficheiro \"%s\" - %s\n"
-msgid "ERROR: Unable to open file \"%s\": %s\n"
-msgstr "ERROR: ImpossÃvel abrir ficheiro \"%s\": %s\n"
-msgid "ERROR: Unable to open image file for printing!\n"
-msgstr "ERROR: ImpossÃvel abrir ficheiro de imagem para impressão!\n"
-msgid "ERROR: Unable to open print file \"%s\": %s\n"
-msgstr "ERROR: ImpossÃvel abrir ficheiro de impressão \"%s\": %s\n"
-msgid "ERROR: Unable to open print file %s - %s\n"
-msgstr "ERROR: ImpossÃvel abrir ficheiro de impressão %s - %s\n"
-msgid "ERROR: Unable to open print file %s: %s\n"
-msgstr "ERROR: ImpossÃvel abrir ficheiro de impressão %s: %s\n"
-msgid "ERROR: Unable to open temporary compressed print file: %s\n"
-msgstr "ERROR: ImpossÃvel abrir ficheiro de impressão comprimido temporário: %s\n"
-msgid "ERROR: Unable to seek to offset %ld in file - %s\n"
-msgstr "ERROR: ImpossÃvel atingir offset %ld no ficheiro - %s\n"
-msgid "ERROR: Unable to seek to offset %lld in file - %s\n"
-msgstr "ERROR: ImpossÃvel atingir offset %lld no ficheiro - %s\n"
-msgid "ERROR: Unable to send print data (%d)\n"
-msgstr "ERROR: ImpossÃvel enviar dados de impressão (%d)\n"
-msgid "ERROR: Unable to wait for pictwpstops: %s\n"
-msgstr "ERROR: ImpossÃvel aguardar por pictwpstops: %s\n"
-msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n"
-msgstr "ERROR: ImpossÃvel escrever %d bytes em \"%s\": %s\n"
-msgid "ERROR: Unable to write print data: %s\n"
-msgstr "ERROR: ImpossÃvel escrever dados de impressão: %s\n"
-msgid "ERROR: Unable to write raster data to driver!\n"
-msgstr "ERROR: ImpossÃvel escrever dados de retÃcula no recurso!\n"
-msgid "ERROR: Unable to write uncompressed document data: %s\n"
-msgstr "ERROR: ImpossÃvel escrever dados de documento não comprimidos: %s\n"
-msgid "ERROR: Unknown encryption option value \"%s\"!\n"
-msgstr "ERROR: Valor de opção de encriptação desconhecido \"%s\"!\n"
-msgid "ERROR: Unknown file order \"%s\"\n"
-msgstr "ERROR: Ordem de ficheiro desconhecida \"%s\"\n"
-msgid "ERROR: Unknown format character \"%c\"\n"
-msgstr "ERROR: Caracteres de formato desconhecido \"%c\"\n"
-msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n"
-msgstr "ERROR: Opção desconhecida \"%s\" com valor \"%s\"!\n"
-msgid "ERROR: Unknown print mode \"%s\"\n"
-msgstr "ERROR: Modo de impressão desconhecido \"%s\"\n"
-msgid "ERROR: Unknown version option value \"%s\"!\n"
-msgstr "ERROR: Valor de opção de versão desconhecido \"%s\"!\n"
-msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n"
-msgstr "ERROR: Valor de brilho não suportado %s ao utilizar brilho=100!\n"
-msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n"
-msgstr "ERROR: Valor gama não suportado %s ao utilizar gama=1000!\n"
-msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n"
-msgstr "ERROR: Valor number-up não suportado %d ao utilizar number-up=1!\n"
-msgid "ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n"
-msgstr "ERROR: Valor number-up-layout não suportado %s ao utilizar number-up-layout=lrtb!\n"
-msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n"
-msgstr "ERROR: Valor page-border não suportado %s ao utilizar page-border=none!\n"
-msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n"
-msgstr "ERROR: Detectado excesso doc_printf (%d bytes); a interromper!\n"
-msgid "ERROR: pictwpstops exited on signal %d!\n"
-msgstr "ERROR: pictwpstops saiu ao sinal %d!\n"
-msgid "ERROR: pictwpstops exited with status %d!\n"
-msgstr "ERROR: pictwpstops saiu com o estado %d!\n"
-msgid "ERROR: recoverable: Unable to connect to printer; will retry in 30 seconds...\n"
-msgstr "ERROR: recuperável: ImpossÃvel ligar à impressora; nova tentativa dentro de 30 segundos...\n"
-msgid "ERROR: select() returned %d\n"
-msgstr "ERROR: selecção() devolveu %d\n"
-msgid "Edit Configuration File"
-msgstr "Editar ficheiro de configuração"
-msgid "Empty PPD file!"
-msgstr "Ficheiro PPD vazio!"
-msgid "Ending Banner"
-msgstr "Terminar faixa publicitária"
-msgid "Enter old password:"
-msgstr "Introduza palavra-passe antiga:"
-msgid "Enter password again:"
-msgstr "Introduza palavra-passe novamente:"
-msgid "Enter password:"
-msgstr "Introduza palavra-passe:"
-msgid "Enter your username and password or the root username and password to access this page. If you are using Kerberos authentication, make sure you have a valid Kerberos ticket."
-msgstr "Introduza o seu nome de utilizador e palavra-passe ou o nome de utilizador e palavra-passe da raiz para aceder a esta página. Se utilizar a autenticação Kerberos, certifique-se que tem um ticket de Kerberos válido."
-msgid "Error Policy"
-msgstr "PolÃtica de Erros"
-msgid "Error: need hostname after '-h' option!\n"
-msgstr "Erro: necessário nome de host após opção '-h'!\n"
-msgid "Export Printers to Samba"
-msgstr "Exportar Impressoras para Samba"
-msgid "FAIL\n"
-msgstr "FAIL\n"
-msgid "FATAL: Could not load %s\n"
-msgstr "FATAL: ImpossÃvel carregar %s\n"
-msgid "File device URIs have been disabled! To enable, see the FileDevice directive in \"%s/cupsd.conf\"."
-msgstr "URIs do periférico do ficheiro foram desactivados! Para activar, consulte a directiva FileDevice em \"%s/cupsd.conf\"."
-msgid "Fuser temperature high!"
-msgstr "Temperatura do fusor elevada!"
-msgid "Fuser temperature low!"
-msgstr "Temperatura do fusor baixa!"
-msgid "General"
-msgstr "Geral"
-msgid "Got a printer-uri attribute but no job-id!"
-msgstr "Obtive um atributo printer-uri, mas não job-id!"
-msgid "Help"
-msgstr "Ajuda"
-msgid "INFO: Attempting to connect to host %s for printer %s\n"
-msgstr "INFO: Tentativa de ligar ao host %s para impressora %s\n"
-msgid "INFO: Attempting to connect to host %s on port %d\n"
-msgstr "INFO: Tentativa de ligar ao host %s na porta %d\n"
-msgid "INFO: Canceling print job...\n"
-msgstr "INFO: A cancelar trabalho de impressão...\n"
-msgid "INFO: Connected to %s...\n"
-msgstr "INFO: Ligado a %s...\n"
-msgid "INFO: Connecting to %s on port %d...\n"
-msgstr "INFO: A ligar a %s na porta %d...\n"
-msgid "INFO: Control file sent successfully\n"
-msgstr "INFO: Ficheiro de controlo enviado com êxito\n"
-msgid "INFO: Data file sent successfully\n"
-msgstr "INFO: Ficheiro de dados enviado com êxito\n"
-msgid "INFO: Formatting page %d...\n"
-msgstr "INFO: A formatar página %d...\n"
-msgid "INFO: Loading image file...\n"
-msgstr "INFO: A carregar ficheiro de imagem...\n"
-msgid "INFO: Print file sent, waiting for printer to finish...\n"
-msgstr "INFO: Ficheiro de impressão enviado; a aguardar conclusão da impressora...\n"
-msgid "INFO: Printer busy (status:0x%08x)\n"
-msgstr "INFO: Impressora ocupada (estado:0x%08x)\n"
-msgid "INFO: Printer busy; will retry in 10 seconds...\n"
-msgstr "INFO: Impressora ocupada; nova tentativa dentro de 10 segundos...\n"
-msgid "INFO: Printer busy; will retry in 30 seconds...\n"
-msgstr "INFO: Impressora ocupada; nova tentativa dentro de 30 segundos...\n"
-msgid "INFO: Printer busy; will retry in 5 seconds...\n"
-msgstr "INFO: Impressora ocupada; nova tentativa dentro de 5 segundos...\n"
-msgid "INFO: Printer does not support IPP/1.1, trying IPP/1.0...\n"
-msgstr "INFO: Impressora não suporta IPP/1.1; a tentar IPP/1.0...\n"
-msgid "INFO: Printer is busy; will retry in 5 seconds...\n"
-msgstr "INFO: Impressora está ocupada; nova tentativa dentro de 5 segundos...\n"
-msgid "INFO: Printer is currently off-line.\n"
-msgstr "INFO: Impressora está actualmente sem ligação.\n"
-msgid "INFO: Printer is now on-line.\n"
-msgstr "INFO: Impressora tem agora ligação.\n"
-msgid "INFO: Printer not connected; will retry in 30 seconds...\n"
-msgstr "INFO: Impressora sem ligação; nova tentativa dentro de 30 segundos...\n"
-msgid "INFO: Printing page %d, %d%% complete...\n"
-msgstr "INFO: A imprimir página %d, %d%% concluÃdo...\n"
-msgid "INFO: Printing page %d...\n"
-msgstr "INFO: A imprimir página %d...\n"
-msgid "INFO: Ready to print.\n"
-msgstr "INFO: Preparada para imprimir.\n"
-msgid "INFO: Sending control file (%lu bytes)\n"
-msgstr "INFO: A enviar ficheiro de controlo (%lu bytes)\n"
-msgid "INFO: Sending control file (%u bytes)\n"
-msgstr "INFO: A enviar ficheiro de controlo (%u bytes)\n"
-msgid "INFO: Sending data\n"
-msgstr "INFO: A enviar dados\n"
-msgid "INFO: Sending data file (%ld bytes)\n"
-msgstr "INFO: A enviar ficheiro de dados (%ld bytes)\n"
-msgid "INFO: Sending data file (%lld bytes)\n"
-msgstr "INFO: A enviar ficheiro de dados (%lld bytes)\n"
-msgid "INFO: Sent print file, %ld bytes...\n"
-msgstr "INFO: Ficheiro de impressão enviado, %ld bytes...\n"
-msgid "INFO: Sent print file, %lld bytes...\n"
-msgstr "INFO: Ficheiro de impressão enviado, %lld bytes...\n"
-msgid "INFO: Spooling LPR job, %.0f%% complete...\n"
-msgstr "INFO: A processar trabalho LPR, %.0f%% concluÃdo...\n"
-msgid "INFO: Unable to contact printer, queuing on next printer in class...\n"
-msgstr "INFO: ImpossÃvel contactar impressora; a colocar em fila na próxima impressora na classe...\n"
-msgid "INFO: Waiting for job to complete...\n"
-msgstr "INFO: A aguardar conclusão do trabalho...\n"
-msgid "Illegal control character"
-msgstr "Carácter de controlo ilegal"
-msgid "Illegal main keyword string"
-msgstr "Cadeia de palavra-chave principal ilegal"
-msgid "Illegal option keyword string"
-msgstr "Cadeia de palavra-chave de opção ilegal"
-msgid "Illegal translation string"
-msgstr "Cadeia de tradução ilegal"
-msgid "Illegal whitespace character"
-msgstr "Carácter de espaço em branco ilegal"
-msgid "Ink/toner almost empty."
-msgstr "Tinta/toner quase vazio."
-msgid "Ink/toner empty!"
-msgstr "Tinta/toner vazio!"
-msgid "Ink/toner waste bin almost full."
-msgstr "Receptáculo de tinta/toner quase cheio."
-msgid "Ink/toner waste bin full!"
-msgstr "Receptáculo de tinta/toner cheio!"
-msgid "Interlock open."
-msgstr "Bloqueio aberto."
-msgid "Internal error"
-msgstr "Erro interno"
-msgid "JCL"
-msgstr "JCL"
-msgid "Job #%d cannot be restarted - no files!"
-msgstr "ImpossÃvel reiniciar trabalho #%d - sem ficheiros!"
-msgid "Job #%d does not exist!"
-msgstr "Trabalho #%d não existe!"
-msgid "Job #%d is already aborted - can't cancel."
-msgstr "Trabalho #%d já interrompido - impossÃvel cancelar."
-msgid "Job #%d is already canceled - can't cancel."
-msgstr "Trabalho #%d já cancelado - impossÃvel cancelar."
-msgid "Job #%d is already completed - can't cancel."
-msgstr "Trabalho #%d já concluÃdo - impossÃvel cancelar."
-msgid "Job #%d is finished and cannot be altered!"
-msgstr "Trabalho #%d concluÃdo; não é possÃvel alterar!"
-msgid "Job #%d is not complete!"
-msgstr "Trabalho #%d não concluÃdo!"
-msgid "Job #%d is not held for authentication!"
-msgstr "Trabalho #%d não retido para autenticação!"
-msgid "Job #%d is not held!"
-msgstr "Trabalho #%d não retido!"
-msgid "Job #%s does not exist!"
-msgstr "Trabalho #%s não existe!"
-msgid "Job %d not found!"
-msgstr "Trabalho %d não encontrado!"
-msgid "Job Completed"
-msgstr "Trabalho concluÃdo"
-msgid "Job Created"
-msgstr "Trabalho criado"
-msgid "Job Options Changed"
-msgstr "Opções de trabalho alteradas"
-msgid "Job Stopped"
-msgstr "Trabalho parado"
-msgid "Job is completed and cannot be changed."
-msgstr "Trabalho concluÃdo; não é possÃvel alterar."
-msgid "Job operation failed:"
-msgstr "Operação de trabalho falhou:"
-msgid "Job state cannot be changed."
-msgstr "ImpossÃvel alterar estado do trabalho."
-msgid "Job subscriptions cannot be renewed!"
-msgstr "ImpossÃvel renovar subscrições do trabalho!"
-msgid "Jobs"
-msgstr "Trabalhos"
-msgid "Language \"%s\" not supported!"
-msgstr "Idioma \"%s\" não suportado!"
-msgid "Line longer than the maximum allowed (255 characters)"
-msgstr "Linha excede máximo permitido (255 caracteres)"
-msgid "List Available Printers"
-msgstr "Apresentar impressoras disponÃveis"
-msgid "Media Size"
-msgstr "Tamanho do suporte"
-msgid "Media Source"
-msgstr "Origem do suporte"
-msgid "Media Type"
-msgstr "Tipo de suporte"
-msgid "Media jam!"
-msgstr "Suporte encravado!"
-msgid "Media tray almost empty."
-msgstr "Tabuleiro de suporte quase vazio."
-msgid "Media tray empty!"
-msgstr "Tabuleiro de suporte vazio!"
-msgid "Media tray missing!"
-msgstr "Tabuleiro de suporte inexistente!"
-msgid "Media tray needs to be filled."
-msgstr "É necessário encher o tabuleiro de suporte."
-msgid "Memory allocation error"
-msgstr "Erro de alocação de memória"
-msgid "Missing PPD-Adobe-4.x header"
-msgstr "Cabeçalho PPD-Adobe-4.x inexistente"
-msgid "Missing asterisk in column 1"
-msgstr "Asterisco inexistente na coluna 1"
-msgid "Missing double quote on line %d!"
-msgstr "Aspas inexistentes na linha %d!"
-msgid "Missing form variable!"
-msgstr "Variável de formato inexistente!"
-msgid "Missing notify-subscription-ids attribute!"
-msgstr "Atributo notify-subscription-ids inexistente!"
-msgid "Missing requesting-user-name attribute!"
-msgstr "Atributo requesting-user-name inexistente!"
-msgid "Missing required attributes!"
-msgstr "Atributos necessários inexistentes!"
-msgid "Missing value on line %d!"
-msgstr "Valor inexistente na linha %d!"
-msgid "Missing value string"
-msgstr "Cadeia de valor inexistente"
-msgid "Model: name = %s\n natural_language = %s\n make-and-model = %s\n device-id = %s\n"
-msgstr "Modelo: name = %s\n natural_language = %s\n make-and-model = %s\n device-id = %s\n"
-msgid "Modify Class"
-msgstr "Modificar classe"
-msgid "Modify Printer"
-msgstr "Modificar impressora"
-msgid "Move All Jobs"
-msgstr "Mover todos os trabalhos"
-msgid "Move Job"
-msgstr "Mover trabalho"
-msgid "NOTICE: Print file accepted - job ID %d.\n"
-msgstr "NOTICE: Ficheiro de impressão aceite - ID do trabalho %d.\n"
-msgid "NOTICE: Print file accepted - job ID unknown.\n"
-msgstr "NOTICE: Ficheiro de impressão aceite - ID do trabalho desconhecido.\n"
-msgid "NULL PPD file pointer"
-msgstr "Ponteiro do ficheiro PPD NULL"
-msgid "No"
-msgstr "Não"
-msgid "No Windows printer drivers are installed!"
-msgstr "Sem controladores de impressora Windows instalados!"
-msgid "No active jobs on %s!"
-msgstr "Sem trabalhos activos em %s!"
-msgid "No attributes in request!"
-msgstr "Sem atributos no pedido!"
-msgid "No authentication information provided!"
-msgstr "Sem informações de autenticação fornecidas!"
-msgid "No default printer"
-msgstr "Sem impressora predefinida"
-msgid "No destinations added."
-msgstr "Sem destinos adicionados."
-msgid "No file!?!"
-msgstr "Sem ficheiro!?!"
-msgid "No subscription attributes in request!"
-msgstr "Sem atributos de subscrição no pedido!"
-msgid "No subscriptions found."
-msgstr "Sem subscrições."
-msgid "None"
-msgstr "Sem"
-msgid "Not allowed to print."
-msgstr "Sem permissão para imprimir."
-msgid "OK"
-msgstr "OK"
-msgid "OPC almost at end-of-life."
-msgstr "OPC quase em fim de vida."
-msgid "OPC at end-of-life!"
-msgstr "OPC em fim de vida!"
-msgid "OpenGroup without a CloseGroup first"
-msgstr "OpenGroup sem um CloseGroup primeiro"
-msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first"
-msgstr "OpenUI/JCLOpenUI sem um CloseUI/JCLCloseUI primeiro"
-msgid "Operation Policy"
-msgstr "PolÃtica de Operação"
-msgid "Options Installed"
-msgstr "Opções instaladas"
-msgid "Out of toner!"
-msgstr "Sem toner!"
-msgid "Output Mode"
-msgstr "Modo de saÃda"
-msgid "Output bin almost full."
-msgstr "Receptáculo de saÃda quase cheio."
-msgid "Output bin full!"
-msgstr "Receptáculo de saÃda cheio!"
-msgid "Output for printer %s is sent to %s\n"
-msgstr "SaÃda de impressora %s enviada para %s\n"
-msgid "Output for printer %s is sent to remote printer %s on %s\n"
-msgstr "SaÃda de impressora %s enviada para impressora remota %s em %s\n"
-msgid "Output for printer %s/%s is sent to %s\n"
-msgstr "SaÃda de impressora %s/%s enviada para %s\n"
-msgid "Output for printer %s/%s is sent to remote printer %s on %s\n"
-msgstr "SaÃda de impressora %s/%s enviada para impressora remota %s em %s\n"
-msgid "Output tray missing!"
-msgstr "Tabuleiro de saÃda inexistente!"
-msgid "PASS\n"
-msgstr "PASS\n"
-msgid "PS Binary Protocol"
-msgstr "Protocolo Binário PS"
-msgid "Password for %s on %s? "
-msgstr "Palavra-passe para %s em %s? "
-msgid "Password for %s required to access %s via SAMBA: "
-msgstr "Palavra-passe para %s requerida para aceder a %s via SAMBA: "
-msgid "Policies"
-msgstr "PolÃticas"
-msgid "Print Job:"
-msgstr "Imprimir trabalho:"
-msgid "Print Test Page"
-msgstr "Imprimir página de teste"
-msgid "Printer Added"
-msgstr "Impressora adicionada"
-msgid "Printer Deleted"
-msgstr "Impressora apagada"
-msgid "Printer Maintenance"
-msgstr "Manutenção da impressora"
-msgid "Printer Modified"
-msgstr "Impressora modificada"
-msgid "Printer Stopped"
-msgstr "Impressora parada"
-msgid "Printer off-line."
-msgstr "Impressora sem ligação."
-msgid "Printer:"
-msgstr "Impressora:"
-msgid "Printers"
-msgstr "Impressoras"
-msgid "Purge Jobs"
-msgstr "Limpar trabalhos"
-msgid "Quota limit reached."
-msgstr "Quota atingida."
-msgid "Rank Owner Job File(s) Total Size\n"
-msgstr "Classificação Proprietário Trabalho Ficheiro(s) Tamanho total\n"
-msgid "Rank Owner Pri Job Files Total Size\n"
-msgstr "Classificação Proprietário Pri Trabalho Ficheiros Tamanho total\n"
-msgid "Reject Jobs"
-msgstr "Rejeitar trabalhos"
-msgid "Resolution"
-msgstr "Resolução"
-msgid "Running command: %s %s -N -A %s -c '%s'\n"
-msgstr "Comando em execução: %s %s -N -A %s -c '%s'\n"
-msgid "Server Restarted"
-msgstr "Servidor reiniciado"
-msgid "Server Security Auditing"
-msgstr "Auditoria de segurança do servidor"
-msgid "Server Started"
-msgstr "Servidor iniciado"
-msgid "Server Stopped"
-msgstr "Servidor parado"
-msgid "Set Allowed Users"
-msgstr "Especificar utilizadores permitidos"
-msgid "Set As Default"
-msgstr "Predefinir"
-msgid "Set Class Options"
-msgstr "Especificar opções de classe"
-msgid "Set Printer Options"
-msgstr "Especificar opções de impressora"
-msgid "Set Publishing"
-msgstr "Especificar publicação"
-msgid "Start Class"
-msgstr "Iniciar classe"
-msgid "Start Printer"
-msgstr "Iniciar impressora"
-msgid "Starting Banner"
-msgstr "Iniciar faixa publicitária"
-msgid "Stop Class"
-msgstr "Parar classe"
-msgid "Stop Printer"
-msgstr "Parar impressora"
-msgid "The PPD file \"%s\" could not be found."
-msgstr "ImpossÃvel localizar o ficheiro PPD \"%s\"."
-msgid "The PPD file \"%s\" could not be opened: %s"
-msgstr "ImpossÃvel abrir o ficheiro PPD \"%s\": %s"
-msgid "The class name may only contain up to 127 printable characters and may not contain spaces, slashes (/), or the pound sign (#)."
-msgstr "O nome de classe pode ter o máximo de 127 caracteres imprimÃveis e não pode ter espaços, barras (/) ou cardinal (#)."
-msgid "The notify-lease-duration attribute cannot be used with job subscriptions."
-msgstr "Não é possÃvel utilizar o atributo notify-lease-duration com subscrições de trabalho."
-msgid "The notify-user-data value is too large (%d > 63 octets)!"
-msgstr "O valor notify-user-data é demasiado grande (%d > 63 octetos)!"
-msgid "The printer name may only contain up to 127 printable characters and may not contain spaces, slashes (/), or the pound sign (#)."
-msgstr "O nome de impressora pode ter o máximo de 127 caracteres imprimÃveis e não pode ter espaços, barras (/) ou cardinal (#)."
-msgid "The printer or class is not shared!"
-msgstr "Impressora ou classe não partilhadas!"
-msgid "The printer or class was not found."
-msgstr "Impressora ou classe não localizadas."
-msgid "The printer-uri \"%s\" contains invalid characters."
-msgstr "O atributo printer-uri \"%s\" contém caracteres inválidos."
-msgid "The printer-uri attribute is required!"
-msgstr "Necessário atributo printer-uri!"
-msgid "The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"."
-msgstr "O atributo printer-uri deve ser do formato \"ipp://HOSTNAME/classes/CLASSNAME\"."
-msgid "The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"."
-msgstr "O atributo printer-uri deve ser do formato \"ipp://HOSTNAME/printers/PRINTERNAME\"."
-msgid "The subscription name may not contain spaces, slashes (/), question marks (?), or the pound sign (#)."
-msgstr "O nome de subscrição não pode ter espaços, barras (/), pontos de interrogação (?) ou cardinal (#)."
-msgid "Toner low."
-msgstr "Pouco toner."
-msgid "Too many active jobs."
-msgstr "Demasiados trabalhos activos."
-msgid "Unable to access cupsd.conf file:"
-msgstr "ImpossÃvel aceder ao ficheiro cupsd.conf:"
-msgid "Unable to add RSS subscription:"
-msgstr "ImpossÃvel adicionar subscrição RSS:"
-msgid "Unable to add class:"
-msgstr "ImpossÃvel adicionar classe:"
-msgid "Unable to add job for destination \"%s\"!"
-msgstr "ImpossÃvel adicionar trabalho ao destino \"%s\"!"
-msgid "Unable to add printer:"
-msgstr "ImpossÃvel adicionar impressora:"
-msgid "Unable to allocate memory for file types!"
-msgstr "ImpossÃvel alocar memória para tipos de ficheiros!"
-msgid "Unable to cancel RSS subscription:"
-msgstr "ImpossÃvel cancelar subscrição RSS:"
-msgid "Unable to change printer-is-shared attribute:"
-msgstr "ImpossÃvel alterar atributo printer-is-shared:"
-msgid "Unable to change printer:"
-msgstr "ImpossÃvel alterar impressora:"
-msgid "Unable to change server settings:"
-msgstr "ImpossÃvel alterar especificações do servidor:"
-msgid "Unable to copy CUPS printer driver files (%d)!"
-msgstr "ImpossÃvel copiar ficheiros de recurso de impressora CUPS (%d)!"
-msgid "Unable to copy PPD file - %s!"
-msgstr "ImpossÃvel copiar ficheiro PPD - %s!"
-msgid "Unable to copy PPD file!"
-msgstr "ImpossÃvel copiar ficheiro PPD!"
-msgid "Unable to copy Windows 2000 printer driver files (%d)!"
-msgstr "ImpossÃvel copiar ficheiros de controladores de impressora Windows 2000 (%d)!"
-msgid "Unable to copy Windows 9x printer driver files (%d)!"
-msgstr "ImpossÃvel copiar ficheiros de controladores de impressora Windows 9x (%d)!"
-msgid "Unable to copy interface script - %s!"
-msgstr "ImpossÃvel copiar script de interface - %s!"
-msgid "Unable to create temporary file:"
-msgstr "ImpossÃvel criar ficheiro temporário:"
-msgid "Unable to delete class:"
-msgstr "ImpossÃvel apagar classe:"
-msgid "Unable to delete printer:"
-msgstr "ImpossÃvel apagar impressora:"
-msgid "Unable to edit cupsd.conf files larger than 1MB!"
-msgstr "ImpossÃvel editar ficheiros cupsd.conf com mais de 1MB!"
-msgid "Unable to find destination for job!"
-msgstr "ImpossÃvel localizar destino para trabalho!"
-msgid "Unable to get class list:"
-msgstr "ImpossÃvel obter lista de classes:"
-msgid "Unable to get class status:"
-msgstr "ImpossÃvel obter estado da classe:"
-msgid "Unable to get list of printer drivers:"
-msgstr "ImpossÃvel obter lista de recursos da impressora:"
-msgid "Unable to get printer attributes:"
-msgstr "ImpossÃvel obter atributos da impressora:"
-msgid "Unable to get printer list:"
-msgstr "ImpossÃvel obter lista de impressoras:"
-msgid "Unable to get printer status:"
-msgstr "ImpossÃvel obter estado da impressora:"
-msgid "Unable to install Windows 2000 printer driver files (%d)!"
-msgstr "ImpossÃvel instalar ficheiros de controladores de impressora Windows 2000 (%d)!"
-msgid "Unable to install Windows 9x printer driver files (%d)!"
-msgstr "ImpossÃvel instalar ficheiros de controladores de impressora Windows 9x (%d)!"
-msgid "Unable to modify class:"
-msgstr "ImpossÃvel modificar classe:"
-msgid "Unable to modify printer:"
-msgstr "ImpossÃvel modificar impressora:"
-msgid "Unable to move job"
-msgstr "ImpossÃvel mover trabalho"
-msgid "Unable to move jobs"
-msgstr "ImpossÃvel mover trabalhos"
-msgid "Unable to open PPD file"
-msgstr "ImpossÃvel abrir ficheiro PPD"
-msgid "Unable to open PPD file:"
-msgstr "ImpossÃvel abrir ficheiro PPD:"
-msgid "Unable to open cupsd.conf file:"
-msgstr "ImpossÃvel abrir ficheiro cupsd.conf:"
-msgid "Unable to print test page:"
-msgstr "ImpossÃvel imprimir página de teste:"
-msgid "Unable to run \"%s\": %s\n"
-msgstr "ImpossÃvel executar \"%s\": %s\n"
-msgid "Unable to send maintenance job:"
-msgstr "ImpossÃvel enviar trabalho de manutenção:"
-msgid "Unable to set Windows printer driver (%d)!"
-msgstr "ImpossÃvel definir controlador de impressora Windows (%d)!"
-msgid "Unable to set options:"
-msgstr "ImpossÃvel especificar opções:"
-msgid "Unable to upload cupsd.conf file:"
-msgstr "ImpossÃvel carregar ficheiro cupsd.conf:"
-msgid "Unknown"
-msgstr "Desconhecida"
-msgid "Unknown printer error (%s)!"
-msgstr "Erro de impressora desconhecido (%s)!"
-msgid "Unknown printer-error-policy \"%s\"."
-msgstr "Printer-error-policy desconhecida \"%s\"."
-msgid "Unknown printer-op-policy \"%s\"."
-msgstr "Printer-op-policy desconhecida \"%s\"."
-msgid "Unsupported compression \"%s\"!"
-msgstr "Compressão não suportada \"%s\"!"
-msgid "Unsupported compression attribute %s!"
-msgstr "Atributo de compressão não suportado %s!"
-msgid "Unsupported format \"%s\"!"
-msgstr "Formato não suportado \"%s\"!"
-msgid "Unsupported format '%s'!"
-msgstr "Formato não suportado '%s'!"
-msgid "Unsupported format '%s/%s'!"
-msgstr "Formato não suportado %s/%s'!"
-msgid "Usage:\n\n lpadmin [-h server] -d destination\n lpadmin [-h server] -x destination\n lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n [-r remove-class] [-v device] [-D description]\n [-P ppd-file] [-o name=value]\n [-u allow:user,user] [-u deny:user,user]\n\n"
-msgstr "Utilização:\n\n lpadmin [-h server] -d destination\n lpadmin [-h server] -x destination\n lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n [-r remove-class] [-v device] [-D description]\n [-P ppd-file] [-o name=value]\n [-u allow:user,user] [-u deny:user,user]\n\n"
-msgid "Usage: %s job-id user title copies options [file]\n"
-msgstr "Utilização: opções de cópias de tÃtulo de utilizador %s job-id [ficheiro]\n"
-msgid "Usage: %s job-id user title copies options file\n"
-msgstr "Utilização: ficheiro de opções de cópias de tÃtulo de utilizador %s job-id\n"
-msgid "Usage: cupsaddsmb [options] printer1 ... printerN\n cupsaddsmb [options] -a\n\nOptions:\n -E Encrypt the connection to the server\n -H samba-server Use the named SAMBA server\n -U samba-user Authenticate using the named SAMBA user\n -a Export all printers\n -h cups-server Use the named CUPS server\n -v Be verbose (show commands)\n"
-msgstr "Utilização: cupsaddsmb [options] printer1 ... printerN\n cupsaddsmb [options] -a\n\nOpções:\n -E Encriptar a ligação ao servidor\n -H samba-server Utilizar o servidor SAMBA\n -U samba-user Autenticar utilizando utilizador SAMBA\n -a Exportar todas as impressoras\n -h cups-server Utilizar o servidor CUPS\n -v Verboso (mostrar comandos)\n"
-msgid "Usage: cupsctl [options] [param=value ... paramN=valueN]\n\nOptions:\n\n -E Enable encryption\n -U username Specify username\n -h server[:port] Specify server address\n\n --[no-]debug-logging Turn debug logging on/off\n --[no-]remote-admin Turn remote administration on/off\n --[no-]remote-any Allow/prevent access from the Internet\n --[no-]remote-printers Show/hide remote printers\n --[no-]share-printers Turn printer sharing on/off\n --[no-]user-cancel-any Allow/prevent users to cancel any job\n"
-msgstr "Utilização: cupsctl [options] [param=value ... paramN=valueN]\n\nOpções:\n\n -E Activar encriptação\n -U username Especificar nome de utilizador\n -h server[:port] Especificar endereço de servidor\n\n --[no-]debug-logging Activar/desactivar registo da depuração\n --[no-]remote-admin Activar/desactivar administração remota\n --[no-]remote-any Permitir/impedir acesso a partir da Internet\n --[no-]remote-printers Mostrar/ocultar impressoras remotas\n --[no-]share-printers Activar/desactivar partilha de impressora\n --[no-]user-cancel-any Permitir/impedir utilizadores de cancelar trabalhos\n"
-msgid "Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n\n-c config-file Load alternate configuration file\n-f Run in the foreground\n-F Run in the foreground but detach\n-h Show this usage message\n-l Run cupsd from launchd(8)\n"
-msgstr "Utilização: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n\n-c config-file Carregar ficheiro de configuração alternativa\n-f Executar em primeiro plano\n-F Executar em primeiro plano, mas separar\n-h Mostrar esta mensagem de utilização\n-l Executar cupsd a partir de launchd(8)\n"
-msgid "Usage: cupsfilter -m mime/type [ options ] filename(s)\n\nOptions:\n\n -c cupsd.conf Set cupsd.conf file to use\n -n copies Set number of copies\n -o name=value Set option(s)\n -p filename.ppd Set PPD file\n -t title Set title\n"
-msgstr "Utilização: cupsfilter -m mime/type [ options ] filename(s)\n\nOpções:\n\n -c cupsd.conf Especificar ficheiro cupsd.conf a utilizar\n -n copies Especificar número de cópias\n -o name=value Especificar opção(ões)\n -p filename.ppd Especificar ficheiro PPD\n -t title Especificar tÃtulo\n"
-msgid "Usage: cupstestdsc [options] filename.ps [... filename.ps]\n cupstestdsc [options] -\n\nOptions:\n\n -h Show program usage\n\n Note: this program only validates the DSC comments, not the PostScript itself.\n"
-msgstr "Utilização: cupstestdsc [options] filename.ps [... filename.ps]\n cupstestdsc [options] -\n\nOpções:\n\n -h Mostrar utilização de programa\n\n Nota: este programa só valida comentários DSC, não o próprio PostScript.\n"
-msgid "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n program | cupstestppd [options] -\n\nOptions:\n\n -R root-directory Set alternate root\n -W {all,none,constraints,defaults,filters,translations}\n Issue warnings instead of errors\n -q Run silently\n -r Use 'relaxed' open mode\n -v Be slightly verbose\n -vv Be very verbose\n"
-msgstr "Utilização: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n programa | cupstestppd [options] -\n\nOpções:\n\n -R root-directory Especificar raiz alternativa\n -W {tudo, sem, restrições, predefinições, filtros, traduções}\n Emitir avisos em vez de erros\n -q Executar silenciosamente\n -r Utilizar modo aberto 'descontraÃdo'\n -v Ligeiramente verboso\n -vv Muito verboso\n"
-msgid "Usage: lpmove job/src dest\n"
-msgstr "Utilização: lpmove job/src dest\n"
-msgid "Usage: lpoptions [-h server] [-E] -d printer\n lpoptions [-h server] [-E] [-p printer] -l\n lpoptions [-h server] [-E] -p printer -o option[=value] ...\n lpoptions [-h server] [-E] -x printer\n"
-msgstr "Utilização: lpoptions [-h server] [-E] -d printer\n lpoptions [-h server] [-E] [-p printer] -l\n lpoptions [-h server] [-E] -p printer -o option[=value] ...\n lpoptions [-h server] [-E] -x printer\n"
-msgid "Usage: lppasswd [-g groupname]\n"
-msgstr "Utilização: lppasswd [-g groupname]\n"
-msgid "Usage: lppasswd [-g groupname] [username]\n lppasswd [-g groupname] -a [username]\n lppasswd [-g groupname] -x [username]\n"
-msgstr "Utilização: lppasswd [-g groupname] [username]\n lppasswd [-g groupname] -a [username]\n lppasswd [-g groupname] -x [username]\n"
-msgid "Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n"
-msgstr "Utilização: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n"
-msgid "Usage: snmp [host-or-ip-address]\n"
-msgstr "Utilização: snmp [host-or-ip-address]\n"
-msgid "WARNING: Boolean expected for waiteof option \"%s\"\n"
-msgstr "WARNING: Booleano esperado para opção waiteof \"%s\"\n"
-msgid "WARNING: Couldn't create read channel\n"
-msgstr "WARNING: ImpossÃvel criar canal de leitura\n"
-msgid "WARNING: Couldn't create side channel\n"
-msgstr "WARNING: ImpossÃvel criar canal lateral\n"
-msgid "WARNING: Failed to read side-channel request!\n"
-msgstr "WARNING: Falha ao ler pedido de side-channel!\n"
-msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n"
-msgstr "WARNING: ImpossÃvel incluir opção \"%s\" via IncludeFeature!\n"
-msgid "WARNING: Remote host did not respond with command status byte after %d seconds!\n"
-msgstr "WARNING: Host remoto não respondeu com byte de estado de comando após %d segundos!\n"
-msgid "WARNING: Remote host did not respond with control status byte after %d seconds!\n"
-msgstr "WARNING: Host remoto não respondeu com byte de estado de controlo após %d segundos!\n"
-msgid "WARNING: Remote host did not respond with data status byte after %d seconds!\n"
-msgstr "WARNING: Host remoto não respondeu com byte de estado de dados após %d segundos!\n"
-msgid "WARNING: SCSI command timed out (%d); retrying...\n"
-msgstr "WARNING: Comando SCSI sem resposta (%d); a tentar de novo...\n"
-msgid "WARNING: This document does not conform to the Adobe Document Structuring Conventions and may not print correctly!\n"
-msgstr "WARNING: Este documento não está de acordo com ADSC e pode não ser impresso correctamente!\n"
-msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n"
-msgstr "WARNING: Escolha desconhecida \"%s\" para opção \"%s\"!\n"
-msgid "WARNING: Unknown option \"%s\"!\n"
-msgstr "WARNING: Opção desconhecida \"%s\"!\n"
-msgid "WARNING: Unsupported baud rate %s!\n"
-msgstr "WARNING: Taxa baud não suportada %s!\n"
-msgid "WARNING: recoverable: Network host '%s' is busy; will retry in %d seconds...\n"
-msgstr "WARNING: recuperável: host de rede '%s' ocupado; nova tentativa dentro de %d segundos...\n"
-msgid "Warning, no Windows 2000 printer drivers are installed!"
-msgstr "Aviso, sem controladores de impressora Windows 2000 instalados!"
-msgid "Yes"
-msgstr "Sim"
-msgid "You must access this page using the URL <A HREF=\"https://%s:%d%s\">https://%s:%d%s</A>."
-msgstr "Deve aceder a esta página utilizando o URL <A HREF=\"https://%s:%d%s\">https://%s:%d%s</A>."
-msgid "aborted"
-msgstr "interrompido"
-msgid "canceled"
-msgstr "cancelado"
-msgid "completed"
-msgstr "concluÃdo"
-msgid "cups-deviced failed to execute."
-msgstr "cups-deviced falhou a execução."
-msgid "cups-driverd failed to execute."
-msgstr "cups-driverd falhou a execução."
-msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n"
-msgstr "cupsaddsmb: Sem ficheiro PPD para impressora \"%s\" - %s\n"
-msgid "cupsctl: Unknown option \"%s\"!\n"
-msgstr "cupsctl: Opção desconhecida \"%s\"!\n"
-msgid "cupsctl: Unknown option \"-%c\"!\n"
-msgstr "cupsctl: Opção desconhecida \"-%c\"!\n"
-msgid "cupsd: Expected config filename after \"-c\" option!\n"
-msgstr "cupsd: Nome de ficheiro config esperado após opção \"-c\"!\n"
-msgid "cupsd: Unknown argument \"%s\" - aborting!\n"
-msgstr "cupsd: Argumento desconhecido \"%s\" - a interromper!\n"
-msgid "cupsd: Unknown option \"%c\" - aborting!\n"
-msgstr "cupsd: Opção desconhecida \"%c\" - a interromper!\n"
-msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n"
-msgstr "cupsd: suporte launchd(8) não compilado; execução em modo normal.\n"
-msgid "cupsfilter: No filter to convert from %s/%s to %s/%s!\n"
-msgstr "cupsfilter: Sem filtro para converter de %s/%s para %s/%s!\n"
-msgid "cupsfilter: Only one filename can be specified!\n"
-msgstr "cupsfilter: Só pode ser especificado um nome de ficheiro!\n"
-msgid "cupsfilter: Unable to determine MIME type of \"%s\"!\n"
-msgstr "cupsfilter: ImpossÃvel determinar tipo MIME de \"%s\"!\n"
-msgid "cupsfilter: Unable to read MIME database from \"%s\"!\n"
-msgstr "cupsfilter: ImpossÃvel ler base de dados MIME a partir de \"%s\"!\n"
-msgid "cupsfilter: Unknown destination MIME type %s/%s!\n"
-msgstr "cupsfilter: Destino desconhecido de tipo MIME %s/%s!\n"
-msgid "cupstestppd: The -q option is incompatible with the -v option.\n"
-msgstr "cupstestppd: Opção -q incompatÃvel com opção -v.\n"
-msgid "cupstestppd: The -v option is incompatible with the -q option.\n"
-msgstr "cupstestppd: Opção -v incompatÃvel com opção -q.\n"
-msgid "device for %s/%s: %s\n"
-msgstr "periférico para %s/%s: %s\n"
-msgid "device for %s: %s\n"
-msgstr "periférico para %s: %s\n"
-msgid "held"
-msgstr "reter"
-msgid "help\t\tget help on commands\n"
-msgstr "help\t\tobter ajuda sobre comandos\n"
-msgid "idle"
-msgstr "inactivo"
-msgid "job-printer-uri attribute missing!"
-msgstr "atributo job-printer-uri inexistente!"
-msgid "lpadmin: Class name can only contain printable characters!\n"
-msgstr "lpadmin: Nome de classe só pode ter caracteres imprimÃveis!\n"
-msgid "lpadmin: Expected PPD after '-P' option!\n"
-msgstr "lpadmin: PPD esperado após opção '-P'!\n"
-msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n"
-msgstr "lpadmin: Permitir/negar:lista de utilizadores esperado após opção '-u'!\n"
-msgid "lpadmin: Expected class after '-r' option!\n"
-msgstr "lpadmin: Classe esperada após opção '-r'!\n"
-msgid "lpadmin: Expected class name after '-c' option!\n"
-msgstr "lpadmin: Nome de classe esperado após opção '-c'!\n"
-msgid "lpadmin: Expected description after '-D' option!\n"
-msgstr "lpadmin: Descrição esperada após opção '-D'!\n"
-msgid "lpadmin: Expected device URI after '-v' option!\n"
-msgstr "lpadmin: URI de periférico esperado após opção '-v'!\n"
-msgid "lpadmin: Expected file type(s) after '-I' option!\n"
-msgstr "lpadmin: Tipo(s) de ficheiro esperados após opção '-I'!\n"
-msgid "lpadmin: Expected hostname after '-h' option!\n"
-msgstr "lpadmin: Nome de host esperado após opção '-h'!\n"
-msgid "lpadmin: Expected interface after '-i' option!\n"
-msgstr "lpadmin: Interface esperada após opção '-i'!\n"
-msgid "lpadmin: Expected location after '-L' option!\n"
-msgstr "lpadmin: Localização esperada após opção '-L'!\n"
-msgid "lpadmin: Expected model after '-m' option!\n"
-msgstr "lpadmin: Modelo esperado após opção '-m'!\n"
-msgid "lpadmin: Expected name=value after '-o' option!\n"
-msgstr "lpadmin: Nome=valor esperado após opção '-o'!\n"
-msgid "lpadmin: Expected printer after '-p' option!\n"
-msgstr "lpadmin: Impressora esperada após opção '-p'!\n"
-msgid "lpadmin: Expected printer name after '-d' option!\n"
-msgstr "lpadmin: Nome de impressora esperado após opção '-d'!\n"
-msgid "lpadmin: Expected printer or class after '-x' option!\n"
-msgstr "lpadmin: Impressora ou classe esperadas após opção '-x'!\n"
-msgid "lpadmin: No member names were seen!\n"
-msgstr "lpadmin: Sem nomes de membro detectados!\n"
-msgid "lpadmin: Printer %s is already a member of class %s.\n"
-msgstr "lpadmin: Impressora %s já é membro da classe %s.\n"
-msgid "lpadmin: Printer %s is not a member of class %s.\n"
-msgstr "lpadmin: Impressora %s não é membro da classe %s.\n"
-msgid "lpadmin: Printer name can only contain printable characters!\n"
-msgstr "lpadmin: Nome de impressora só pode ter caracteres imprimÃveis!\n"
-msgid "lpadmin: Unable to add a printer to the class:\n You must specify a printer name first!\n"
-msgstr "lpadmin: ImpossÃvel adicionar impressora à classe:\n Especifique primeiro um nome de impressora!\n"
-msgid "lpadmin: Unable to connect to server: %s\n"
-msgstr "lpadmin: ImpossÃvel ligar ao servidor: %s\n"
-msgid "lpadmin: Unable to create temporary file - %s\n"
-msgstr "lpadmin: ImpossÃvel criar ficheiro temporário - %s\n"
-msgid "lpadmin: Unable to create temporary file: %s\n"
-msgstr "lpadmin: ImpossÃvel criar ficheiro temporário: %s\n"
-msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n"
-msgstr "lpadmin: ImpossÃvel abrir ficheiro PPD \"%s\" - %s\n"
-msgid "lpadmin: Unable to open file \"%s\": %s\n"
-msgstr "lpadmin: ImpossÃvel abrir ficheiro \"%s\": %s\n"
-msgid "lpadmin: Unable to remove a printer from the class:\n You must specify a printer name first!\n"
-msgstr "lpadmin: ImpossÃvel remover impressora da classe:\n Especifique primeiro um nome de impressora!\n"
-msgid "lpadmin: Unable to set the PPD file:\n You must specify a printer name first!\n"
-msgstr "lpadmin: ImpossÃvel especificar ficheiro PPD:\n Especifique primeiro um nome de impressora!\n"
-msgid "lpadmin: Unable to set the device URI:\n You must specify a printer name first!\n"
-msgstr "lpadmin: ImpossÃvel especificar URI de periférico:\n Especifique primeiro um nome de impressora!\n"
-msgid "lpadmin: Unable to set the interface script or PPD file:\n You must specify a printer name first!\n"
-msgstr "lpadmin: ImpossÃvel especificar script de interface ou ficheiro PPD:\n Especifique primeiro um nome de impressora!\n"
-msgid "lpadmin: Unable to set the interface script:\n You must specify a printer name first!\n"
-msgstr "lpadmin: ImpossÃvel especificar script de interface:\n Especifique primeiro um nome de impressora!\n"
-msgid "lpadmin: Unable to set the printer description:\n You must specify a printer name first!\n"
-msgstr "lpadmin: ImpossÃvel especificar descrição de impressora:\n Especifique primeiro um nome de impressora!\n"
-msgid "lpadmin: Unable to set the printer location:\n You must specify a printer name first!\n"
-msgstr "lpadmin: ImpossÃvel especificar localização de impressora:\n Especifique primeiro um nome de impressora!\n"
-msgid "lpadmin: Unable to set the printer options:\n You must specify a printer name first!\n"
-msgstr "lpadmin: ImpossÃvel especificar opções de impressora:\n Especifique primeiro um nome de impressora!\n"
-msgid "lpadmin: Unknown allow/deny option \"%s\"!\n"
-msgstr "lpadmin: Opção permitir/negar desconhecida \"%s\"!\n"
-msgid "lpadmin: Unknown argument '%s'!\n"
-msgstr "lpadmin: Argumento desconhecido '%s'!\n"
-msgid "lpadmin: Unknown option '%c'!\n"
-msgstr "lpadmin: Opção desconhecida '%c'!\n"
-msgid "lpadmin: Warning - content type list ignored!\n"
-msgstr "lpadmin: Aviso - lista de tipo de conteúdo ignorada!\n"
-msgid "lpc> "
-msgstr "lpc> "
-msgid "lpinfo: Unable to connect to server: %s\n"
-msgstr "lpinfo: ImpossÃvel ligar ao servidor: %s\n"
-msgid "lpinfo: Unknown argument '%s'!\n"
-msgstr "lpinfo: Argumento desconhecido '%s'!\n"
-msgid "lpinfo: Unknown option '%c'!\n"
-msgstr "lpinfo: Opção desconhecida '%c'!\n"
-msgid "lpmove: Unable to connect to server: %s\n"
-msgstr "lpmove: ImpossÃvel ligar ao servidor: %s\n"
-msgid "lpmove: Unknown argument '%s'!\n"
-msgstr "lpmove: Argumento desconhecido '%s'!\n"
-msgid "lpmove: Unknown option '%c'!\n"
-msgstr "lpmove: Opção desconhecida '%c'!\n"
-msgid "lpoptions: No printers!?!\n"
-msgstr "lpoptions: Sem impressoras!?!\n"
-msgid "lpoptions: Unable to add printer or instance: %s\n"
-msgstr "lpoptions: ImpossÃvel adicionar impressora ou instância: %s\n"
-msgid "lpoptions: Unable to get PPD file for %s: %s\n"
-msgstr "lpoptions: ImpossÃvel obter ficheiro PPD para %s: %s\n"
-msgid "lpoptions: Unable to open PPD file for %s!\n"
-msgstr "lpoptions: ImpossÃvel abrir ficheiro PPD para %s!\n"
-msgid "lpoptions: Unknown printer or class!\n"
-msgstr "lpoptions: Impressora ou classe desconhecidas!\n"
-msgid "lppasswd: Only root can add or delete passwords!\n"
-msgstr "lppasswd: Só raiz pode adicionar ou apagar palavras-passe!\n"
-msgid "lppasswd: Password file busy!\n"
-msgstr "lppasswd: Ficheiro de palavra-passe ocupado!\n"
-msgid "lppasswd: Password file not updated!\n"
-msgstr "lppasswd: Ficheiro de palavra-passe não actualizado!\n"
-msgid "lppasswd: Sorry, password doesn't match!\n"
-msgstr "lppasswd: Palavra-passe não corresponde!\n"
-msgid "lppasswd: Sorry, password rejected.\nYour password must be at least 6 characters long, cannot contain\nyour username, and must contain at least one letter and number.\n"
-msgstr "lppasswd: Palavra-passe rejeitada.\nA palavra-passe deve ter o mÃnimo de 6 caracteres, sem conter\no nome de utilizador, e deve ter pelo menos uma letra e um número.\n"
-msgid "lppasswd: Sorry, passwords don't match!\n"
-msgstr "lppasswd: Palavras-passe não correspondem!\n"
-msgid "lppasswd: Unable to copy password string: %s\n"
-msgstr "lppasswd: ImpossÃvel copiar cadeia de palavra-passe: %s\n"
-msgid "lppasswd: Unable to open password file: %s\n"
-msgstr "lppasswd: ImpossÃvel abrir ficheiro de palavra-passe: %s\n"
-msgid "lppasswd: Unable to write to password file: %s\n"
-msgstr "lppasswd: ImpossÃvel escrever no ficheiro de palavra-passe: %s\n"
-msgid "lppasswd: failed to backup old password file: %s\n"
-msgstr "lppasswd: falha ao efectuar cópia de segurança de ficheiro de palavra-passe antigo: %s\n"
-msgid "lppasswd: failed to rename password file: %s\n"
-msgstr "lppasswd: falha ao alterar nome de ficheiro de palavra-passe: %s\n"
-msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n"
-msgstr "lppasswd: utilizador \"%s\" e grupo \"%s\" não existem.\n"
-msgid "lprm: Unable to contact server!\n"
-msgstr "lprm: ImpossÃvel contactar servidor!\n"
-msgid "lpstat: error - %s environment variable names non-existent destination \"%s\"!\n"
-msgstr "lpstat: erro - nomes de variáveis de ambiente %s inexistentes no destino \"%s\"!\n"
-msgid "members of class %s:\n"
-msgstr "membros da classe %s:\n"
-msgid "no entries\n"
-msgstr "sem entradas\n"
-msgid "no system default destination\n"
-msgstr "sem destino predefinido de sistema\n"
-msgid "notify-events not specified!"
-msgstr "notify-events não especificados!"
-msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!"
-msgstr "notify-recipient-uri URI \"%s\" utiliza esquema desconhecido!"
-msgid "notify-subscription-id %d no good!"
-msgstr "notify-subscription-id %d incorrecto!"
-msgid "open of %s failed: %s"
-msgstr "abertura de %s falhou: %s"
-msgid "pending"
-msgstr "pendente"
-msgid "printer %s disabled since %s -\n"
-msgstr "impressora %s desactivada desde %s -\n"
-msgid "printer %s is idle. enabled since %s\n"
-msgstr "impressora %s inactiva. activada desde %s\n"
-msgid "printer %s now printing %s-%d. enabled since %s\n"
-msgstr "impressora %s agora a imprimir %s-%d. activada desde %s\n"
-msgid "printer %s/%s disabled since %s -\n"
-msgstr "impressora %s/%s desactivada desde %s -\n"
-msgid "printer %s/%s is idle. enabled since %s\n"
-msgstr "impressora %s/%s inactiva. activada desde %s\n"
-msgid "printer %s/%s now printing %s-%d. enabled since %s\n"
-msgstr "impressora %s/%s agora a imprimir %s-%d. activada desde %s\n"
-msgid "processing"
-msgstr "a processar"
-msgid "request id is %s-%d (%d file(s))\n"
-msgstr "id de pedido é %s-%d (%d ficheiro(s))\n"
-msgid "scheduler is not running\n"
-msgstr "programador não está em execução\n"
-msgid "scheduler is running\n"
-msgstr "programador em execução\n"
-msgid "stat of %s failed: %s"
-msgstr "estatÃstica de %s falhou: %s"
-msgid "status\t\tshow status of daemon and queue\n"
-msgstr "status\t\tmostra estado de daemon e fila\n"
-msgid "stopped"
-msgstr "parado"
-msgid "system default destination: %s\n"
-msgstr "destino predefinido de sistema: %s\n"
-msgid "system default destination: %s/%s\n"
-msgstr "destino predefinido de sistema: %s/%s\n"
-msgid "unknown"
-msgstr "desconhecido"
-msgid "untitled"
-msgstr "sem nome"
.\"
.\" lpinfo man page for the Common UNIX Printing System (CUPS).
.\"
-.\" Copyright 2007 by Apple Inc.
+.\" Copyright 2007-2008 by Apple Inc.
.\" Copyright 1997-2006 by Easy Software Products.
.\"
.\" These coded instructions, statements, and computer programs are the
.\" 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 lpinfo 8 "Common UNIX Printing System" "12 February 2006" "Apple Inc."
+.TH lpinfo 8 "Common UNIX Printing System" "8 October 2008" "Apple Inc."
.SH NAME
lpinfo \- show available devices or drivers
.SH SYNOPSIS
.I username
] [ -h
.I server[:port]
-] [ -l ] -m
+] [ -l ] [ --device-id
+.I device-id-string
+] [ --language
+.I locale
+] [ --make-and-model
+.I name
+] [ --product
+.I name
+] -m
.br
.B lpinfo
[ -E ] [ -U
.I username
] [ -h
.I server[:port]
-] [ -l ] -v
+] [ -l ] [ --timeout
+.I seconds
+] -v
.SH DESCRIPTION
\fIlpinfo\fR lists the available devices or drivers known to the
CUPS server. The first form (\fI-m\fR) lists the available
-l
.br
Shows a "long" listing of devices or drivers.
+.TP 5
+--device-id device-id-string
+.br
+Specifies the IEEE-1284 device ID to match when listing drivers with the
+\fI-m\fR option.
+.TP 5
+--language locale
+.br
+Specifies the language to match when listing drivers with the \fI-m\fR option.
+.TP 5
+--make-and-model name
+.br
+Specifies the make and model to match when listing drivers with the \fI-m\fR
+option.
+.TP 5
+--product name
+.br
+Specifies the product to match when listing drivers with the \fI-m\fR option.
+.TP 5
+--timeout seconds
+.br
+Specifies the timeout when listing devices with the \fI-v\fR option.
.SH COMPATIBILITY
The \fIlpinfo\fR command is unique to CUPS.
.SH SEE ALSO
.br
http://localhost:631/help
.SH COPYRIGHT
-Copyright 2007 by Apple Inc.
+Copyright 2007-2008 by Apple Inc.
.\"
.\" End of "$Id: lpinfo.man 7600 2008-05-20 21:06:23Z mike $".
.\"
cupsdSaveAllClasses(void)
{
cups_file_t *fp; /* classes.conf file */
- char temp[1024]; /* Temporary string */
- char backup[1024]; /* classes.conf.O file */
+ char temp[1024], /* Temporary string */
+ backup[1024], /* printers.conf.O file */
+ value[2048]; /* Value string */
cupsd_printer_t *pclass; /* Current printer class */
int i; /* Looping var */
time_t curtime; /* Current time */
struct tm *curdate; /* Current date */
cups_option_t *option; /* Current option */
- const char *ptr; /* Pointer into info/location */
/*
if (pclass->num_auth_info_required > 0)
{
- cupsFilePrintf(fp, "AuthInfoRequired %s", pclass->auth_info_required[0]);
- for (i = 1; i < pclass->num_auth_info_required; i ++)
- cupsFilePrintf(fp, ",%s", pclass->auth_info_required[i]);
- cupsFilePutChar(fp, '\n');
- }
-
- if (pclass->info)
- {
- if ((ptr = strchr(pclass->info, '#')) != NULL)
+ switch (pclass->num_auth_info_required)
{
- /*
- * Need to quote the first # in the info string...
- */
-
- cupsFilePuts(fp, "Info ");
- cupsFileWrite(fp, pclass->info, ptr - pclass->info);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- cupsFilePutChar(fp, '\n');
+ case 1 :
+ strlcpy(value, pclass->auth_info_required[0], sizeof(value));
+ break;
+
+ case 2 :
+ snprintf(value, sizeof(value), "%s,%s",
+ pclass->auth_info_required[0],
+ pclass->auth_info_required[1]);
+ break;
+
+ case 3 :
+ default :
+ snprintf(value, sizeof(value), "%s,%s,%s",
+ pclass->auth_info_required[0],
+ pclass->auth_info_required[1],
+ pclass->auth_info_required[2]);
+ break;
}
- else
- cupsFilePrintf(fp, "Info %s\n", pclass->info);
+
+ cupsFilePutConf(fp, "AuthInfoRequired", value);
}
- if (pclass->location)
- {
- if ((ptr = strchr(pclass->info, '#')) != NULL)
- {
- /*
- * Need to quote the first # in the location string...
- */
+ if (pclass->info)
+ cupsFilePutConf(fp, "Info", pclass->info);
- cupsFilePuts(fp, "Location ");
- cupsFileWrite(fp, pclass->location, ptr - pclass->location);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- cupsFilePutChar(fp, '\n');
- }
- else
- cupsFilePrintf(fp, "Location %s\n", pclass->location);
- }
+ if (pclass->location)
+ cupsFilePutConf(fp, "Location", pclass->location);
if (pclass->state == IPP_PRINTER_STOPPED)
- {
cupsFilePuts(fp, "State Stopped\n");
- cupsFilePrintf(fp, "StateMessage %s\n", pclass->state_message);
- }
else
cupsFilePuts(fp, "State Idle\n");
else
cupsFilePuts(fp, "Shared No\n");
- cupsFilePrintf(fp, "JobSheets %s %s\n", pclass->job_sheets[0],
- pclass->job_sheets[1]);
-
- for (i = 0; i < pclass->num_users; i ++)
- {
- if ((ptr = strchr(pclass->users[i], '#')) != NULL)
- {
- /*
- * Need to quote the first # in the user string...
- */
-
- cupsFilePrintf(fp, "%sUser ", pclass->deny_users ? "Deny" : "Allow");
- cupsFileWrite(fp, pclass->users[i], ptr - pclass->users[i]);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- cupsFilePutChar(fp, '\n');
- }
- else
- cupsFilePrintf(fp, "%sUser %s\n",
- pclass->deny_users ? "Deny" : "Allow",
- pclass->users[i]);
- }
+ snprintf(value, sizeof(value), "%s %s", pclass->job_sheets[0],
+ pclass->job_sheets[1]);
+ cupsFilePutConf(fp, "JobSheets", value);
cupsFilePrintf(fp, "QuotaPeriod %d\n", pclass->quota_period);
cupsFilePrintf(fp, "PageLimit %d\n", pclass->page_limit);
cupsFilePrintf(fp, "KLimit %d\n", pclass->k_limit);
for (i = 0; i < pclass->num_users; i ++)
- cupsFilePrintf(fp, "%sUser %s\n", pclass->deny_users ? "Deny" : "Allow",
- pclass->users[i]);
+ cupsFilePutConf(fp, pclass->deny_users ? "DenyUser" : "AllowUser",
+ pclass->users[i]);
- if (pclass->op_policy)
- cupsFilePrintf(fp, "OpPolicy %s\n", pclass->op_policy);
+ if (pclass->op_policy)
+ cupsFilePutConf(fp, "OpPolicy", pclass->op_policy);
if (pclass->error_policy)
- cupsFilePrintf(fp, "ErrorPolicy %s\n", pclass->error_policy);
+ cupsFilePutConf(fp, "ErrorPolicy", pclass->error_policy);
for (i = pclass->num_options, option = pclass->options;
i > 0;
i --, option ++)
- cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+ {
+ snprintf(value, sizeof(value), "%s %s", option->name, option->value);
+ cupsFilePutConf(fp, "Option", value);
+ }
cupsFilePuts(fp, "</Class>\n");
}
SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
if (SSLOptions & CUPSD_SSL_NOEMPTY)
- SSL_CTX_set_options(context, SSL_OP_DONTS_INSERT_EMPTY_FRAGMENTS);
+ SSL_CTX_set_options(context, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
SSL_CTX_use_PrivateKey_file(context, ServerKey, SSL_FILETYPE_PEM);
- SSL_CTX_use_certificate_chain_file(context, ServerCertificate,
- SSL_FILETYPE_PEM);
+ SSL_CTX_use_certificate_chain_file(context, ServerCertificate);
bio = BIO_new(_httpBIOMethods());
BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)HTTP(con));
"Missing value for SetEnv directive on line %d.",
linenum);
}
+#ifdef HAVE_SSL
else if (!strcasecmp(line, "SSLOptions"))
{
/*
"Unknown value \"%s\" for SSLOptions directive on "
"line %d.", value, linenum);
}
+#endif /* HAVE_SSL */
else
{
/*
*
* Contents:
*
- * main() - Scan for drivers and return an IPP response.
- * add_ppd() - Add a PPD file.
- * cat_drv() - Generate a PPD from a driver info file.
- * cat_ppd() - Copy a PPD file to stdout.
- * copy_static() - Copy a static PPD file to stdout.
- * compare_names() - Compare PPD filenames for sorting.
- * compare_ppds() - Compare PPD file make and model names for sorting.
- * free_array() - Free an array of strings.
- * list_ppds() - List PPD files.
- * load_ppds() - Load PPD files recursively.
- * load_drv() - Load the PPDs from a driver information file.
- * load_drivers() - Load driver-generated PPD files.
+ * main() - Scan for drivers and return an IPP response.
+ * add_ppd() - Add a PPD file.
+ * cat_drv() - Generate a PPD from a driver info file.
+ * cat_ppd() - Copy a PPD file to stdout.
+ * copy_static() - Copy a static PPD file to stdout.
+ * compare_matches() - Compare PPD match scores for sorting.
+ * compare_names() - Compare PPD filenames for sorting.
+ * compare_ppds() - Compare PPD file make and model names for sorting.
+ * free_array() - Free an array of strings.
+ * list_ppds() - List PPD files.
+ * load_ppds() - Load PPD files recursively.
+ * load_drv() - Load the PPDs from a driver information file.
+ * load_drivers() - Load driver-generated PPD files.
+ * regex_device_id() - Compile a regular expression based on the 1284 device
+ * ID.
+ * regex_string() - Construct a regular expression to compare a simple
+ * string.
*/
/*
#include <cups/transcode.h>
#include <cups/ppd-private.h>
#include <ppdc/ppdc.h>
+#include <regex.h>
/*
typedef struct /**** In-memory record ****/
{
int found; /* 1 if PPD is found */
+ int matches; /* Match count */
ppd_rec_t record; /* PPDs.dat record */
} ppd_info_t;
static int cat_drv(const char *name, int request_id);
static int cat_ppd(const char *name, int request_id);
static int cat_static(const char *name, int request_id);
+static int compare_matches(const ppd_info_t *p0,
+ const ppd_info_t *p1);
static int compare_names(const ppd_info_t *p0,
const ppd_info_t *p1);
static int compare_ppds(const ppd_info_t *p0,
static int load_drv(const char *filename, const char *name,
cups_file_t *fp, time_t mtime, off_t size);
static int load_ppds(const char *d, const char *p, int descend);
+static regex_t *regex_device_id(const char *device_id);
+static regex_t *regex_string(const char *s);
/*
ppdcCatalog *catalog; // Message catalog in .drv file
- fprintf(stderr, "DEBUG: %d locales defined in \"%s\"...\n",
+ fprintf(stderr, "DEBUG: [cups-driverd] %d locales defined in \"%s\"...\n",
src->po_files->count, filename);
locales = new ppdcArray();
catalog;
catalog = (ppdcCatalog *)src->po_files->next())
{
- fprintf(stderr, "DEBUG: Adding locale \"%s\"...\n",
+ fprintf(stderr, "DEBUG: [cups-driverd] Adding locale \"%s\"...\n",
catalog->locale->value);
locales->add(catalog->locale);
}
}
+/*
+ * 'compare_matches()' - Compare PPD match scores for sorting.
+ */
+
+static int
+compare_matches(const ppd_info_t *p0, /* I - First PPD */
+ const ppd_info_t *p1) /* I - Second PPD */
+{
+ if (p1->matches != p0->matches)
+ return (p1->matches - p0->matches);
+ else
+ return (cupsdCompareNames(p1->record.make_and_model,
+ p0->record.make_and_model));
+}
+
+
/*
* 'compare_names()' - Compare PPD filenames for sorting.
*/
*type_str; /* ppd-type option */
int model_number, /* ppd-model-number value */
type, /* ppd-type value */
- mam_len, /* Length of ppd-make-and-model */
- device_id_len, /* Length of ppd-device-id */
+ make_and_model_len, /* Length of ppd-make-and-model */
+ product_len, /* Length of ppd-product */
send_device_id, /* Send ppd-device-id? */
send_make, /* Send ppd-make? */
send_make_and_model, /* Send ppd-make-and-model? */
send_psversion, /* Send ppd-psversion? */
send_type, /* Send ppd-type? */
sent_header; /* Sent the IPP header? */
+ regex_t *device_id_re, /* Regular expression for matching device ID */
+ *make_and_model_re; /* Regular expression for matching make and model */
+ regmatch_t re_matches[6]; /* Regular expression matches */
+ cups_array_t *matches; /* Matching PPDs */
fprintf(stderr,
type_str = cupsGetOption("ppd-type", num_options, options);
if (make_and_model)
- mam_len = strlen(make_and_model);
+ make_and_model_len = strlen(make_and_model);
else
- mam_len = 0;
+ make_and_model_len = 0;
- if (device_id)
- device_id_len = strlen(device_id);
+ if (product)
+ product_len = strlen(product);
else
- device_id_len = 0;
+ product_len = 0;
if (model_number_str)
model_number = atoi(model_number_str);
else
count = limit;
- for (ppd = (ppd_info_t *)cupsArrayFirst(PPDsByMakeModel);
- count > 0 && ppd;
- ppd = (ppd_info_t *)cupsArrayNext(PPDsByMakeModel))
+ if (device_id || language || make || make_and_model || model_number_str ||
+ product)
{
- /*
- * Filter PPDs based on make, model, or device ID...
- */
+ matches = cupsArrayNew((cups_array_func_t)compare_matches, NULL);
- if (ppd->record.type < PPD_TYPE_POSTSCRIPT ||
- ppd->record.type >= PPD_TYPE_DRV)
- continue;
+ if (device_id)
+ device_id_re = regex_device_id(device_id);
+ else
+ device_id_re = NULL;
- if (device_id && strncasecmp(ppd->record.device_id, device_id,
- device_id_len))
- continue; /* TODO: implement smart compare */
+ if (make_and_model)
+ make_and_model_re = regex_string(make_and_model);
+ else
+ make_and_model_re = NULL;
- if (language)
+ for (ppd = (ppd_info_t *)cupsArrayFirst(PPDsByMakeModel);
+ ppd;
+ ppd = (ppd_info_t *)cupsArrayNext(PPDsByMakeModel))
{
- for (i = 0; i < PPD_MAX_LANG; i ++)
- if (!ppd->record.languages[i][0] ||
- !strcasecmp(ppd->record.languages[i], language))
- break;
+ /*
+ * Filter PPDs based on make, model, product, language, model number,
+ * and/or device ID using the "matches" score value. An exact match
+ * for product, make-and-model, or device-id adds 3 to the score.
+ * Partial matches for make-and-model yield 1 or 2 points, and matches
+ * for the make and language add a single point. Results are then sorted
+ * by score, highest score first.
+ */
- if (i >= PPD_MAX_LANG || !ppd->record.languages[i][0])
+ if (ppd->record.type < PPD_TYPE_POSTSCRIPT ||
+ ppd->record.type >= PPD_TYPE_DRV)
continue;
- }
- if (make && strcasecmp(ppd->record.make, make))
- continue;
+ ppd->matches = 0;
- if (make_and_model && strncasecmp(ppd->record.make_and_model,
- make_and_model, mam_len))
- continue;
+ if (device_id_re &&
+ !regexec(device_id_re, ppd->record.device_id,
+ (int)(sizeof(re_matches) / sizeof(re_matches[0])),
+ re_matches, 0))
+ {
+ /*
+ * Add the number of matching values from the device ID - it will be
+ * at least 2 (manufacturer and model), and as much as 3 (command set).
+ */
- if (model_number_str && ppd->record.model_number != model_number)
- continue;
+ for (i = 1; i < (int)(sizeof(re_matches) / sizeof(re_matches[0])); i ++)
+ if (re_matches[i].rm_so >= 0)
+ ppd->matches ++;
+ }
- if (product)
- {
- for (i = 0; i < PPD_MAX_PROD; i ++)
- if (!ppd->record.products[i][0] ||
- !strcasecmp(ppd->record.products[i], product))
- break;
+ if (language)
+ {
+ for (i = 0; i < PPD_MAX_LANG; i ++)
+ if (!ppd->record.languages[i][0] ||
+ !strcasecmp(ppd->record.languages[i], language))
+ {
+ ppd->matches ++;
+ break;
+ }
+ }
- if (i >= PPD_MAX_PROD || !ppd->record.products[i][0])
- continue;
- }
+ if (make && !strcasecmp(ppd->record.make, make))
+ ppd->matches ++;
- if (psversion)
- {
- for (i = 0; i < PPD_MAX_VERS; i ++)
- if (!ppd->record.psversions[i][0] ||
- !strcasecmp(ppd->record.psversions[i], psversion))
- break;
+ if (make_and_model_re &&
+ !regexec(make_and_model_re, ppd->record.make_and_model,
+ (int)(sizeof(re_matches) / sizeof(re_matches[0])),
+ re_matches, 0))
+ {
+ // See how much of the make-and-model string we matched...
+ if (re_matches[0].rm_so == 0)
+ {
+ if (re_matches[0].rm_eo == make_and_model_len)
+ ppd->matches += 3; // Exact match
+ else
+ ppd->matches += 2; // Prefix match
+ }
+ else
+ ppd->matches ++; // Infix match
+ }
- if (i >= PPD_MAX_VERS || !ppd->record.psversions[i][0])
- continue;
+ if (model_number_str && ppd->record.model_number == model_number)
+ ppd->matches ++;
+
+ if (product)
+ {
+ for (i = 0; i < PPD_MAX_PROD; i ++)
+ if (!ppd->record.products[i][0] ||
+ !strcasecmp(ppd->record.products[i], product))
+ {
+ ppd->matches += 3;
+ break;
+ }
+ }
+
+ if (psversion)
+ {
+ for (i = 0; i < PPD_MAX_VERS; i ++)
+ if (!ppd->record.psversions[i][0] ||
+ !strcasecmp(ppd->record.psversions[i], psversion))
+ {
+ ppd->matches ++;
+ break;
+ }
+ }
+
+ if (type_str && ppd->record.type == type)
+ ppd->matches ++;
+
+ if (ppd->matches)
+ {
+ fprintf(stderr, "DEBUG: [cups-driverd] %s matches with score %d!\n",
+ ppd->record.name, ppd->matches);
+ cupsArrayAdd(matches, ppd);
+ }
}
+ }
+ else
+ matches = PPDsByMakeModel;
- if (type_str && ppd->record.type != type)
+ for (ppd = (ppd_info_t *)cupsArrayFirst(matches);
+ count > 0 && ppd;
+ ppd = (ppd_info_t *)cupsArrayNext(matches))
+ {
+ /*
+ * Skip invalid PPDs...
+ */
+
+ if (ppd->record.type < PPD_TYPE_POSTSCRIPT ||
+ ppd->record.type >= PPD_TYPE_DRV)
continue;
/*
cupsdSendIPPHeader(IPP_OK, request_id);
cupsdSendIPPGroup(IPP_TAG_OPERATION);
cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
- cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
}
fprintf(stderr, "DEBUG: [cups-driverd] Sending %s (%s)...\n",
for (this_make = ppd->record.make,
- ppd = (ppd_info_t *)cupsArrayNext(PPDsByMakeModel);
+ ppd = (ppd_info_t *)cupsArrayNext(matches);
ppd;
- ppd = (ppd_info_t *)cupsArrayNext(PPDsByMakeModel))
+ ppd = (ppd_info_t *)cupsArrayNext(matches))
if (strcasecmp(this_make, ppd->record.make))
break;
- cupsArrayPrev(PPDsByMakeModel);
+ cupsArrayPrev(matches);
}
}
else if (!strncmp(line, "*NickName:", 10))
sscanf(line, "%*[^\"]\"%255[^\"]", nick_name);
else if (!strncasecmp(line, "*1284DeviceID:", 14))
+ {
sscanf(line, "%*[^\"]\"%255[^\"]", device_id);
+
+ // Make sure device ID ends with a semicolon...
+ if (device_id[0] && device_id[strlen(device_id) - 1] != ';')
+ strlcat(device_id, ";", sizeof(device_id));
+ }
else if (!strncmp(line, "*Product:", 9))
{
if (sscanf(line, "%*[^\"]\"(%255[^)]", product) == 1)
}
+/*
+ * 'regex_device_id()' - Compile a regular expression based on the 1284 device
+ * ID.
+ */
+
+static regex_t * /* O - Regular expression */
+regex_device_id(const char *device_id) /* I - IEEE-1284 device ID */
+{
+ char res[2048], /* Regular expression string */
+ *ptr; /* Pointer into string */
+ regex_t *re; /* Regular expression */
+ int cmd; /* Command set string? */
+
+
+ fprintf(stderr, "DEBUG: [cups-driverd] regex_device_id(\"%s\")\n", device_id);
+
+ /*
+ * Scan the device ID string and insert class, command set, manufacturer, and
+ * model attributes to match. We assume that the device ID in the PPD and the
+ * device ID reported by the device itself use the same attribute names and
+ * order of attributes.
+ */
+
+ ptr = res;
+
+ while (*device_id && ptr < (res + sizeof(res) - 6))
+ {
+ cmd = !strncasecmp(device_id, "COMMAND SET:", 12) ||
+ !strncasecmp(device_id, "CMD:", 4);
+
+ if (cmd || !strncasecmp(device_id, "MANUFACTURER:", 13) ||
+ !strncasecmp(device_id, "MFG:", 4) ||
+ !strncasecmp(device_id, "MFR:", 4) ||
+ !strncasecmp(device_id, "MODEL:", 6) ||
+ !strncasecmp(device_id, "MDL:", 4))
+ {
+ if (ptr > res)
+ {
+ *ptr++ = '.';
+ *ptr++ = '*';
+ }
+
+ *ptr++ = '(';
+
+ while (*device_id && *device_id != ';' && ptr < (res + sizeof(res) - 4))
+ {
+ if (strchr("[]{}().*\\|", *device_id))
+ *ptr++ = '\\';
+ *ptr++ = *device_id++;
+ }
+
+ if (*device_id == ';' || !*device_id)
+ *ptr++ = ';';
+ *ptr++ = ')';
+ if (cmd)
+ *ptr++ = '?';
+ }
+ else if ((device_id = strchr(device_id, ';')) == NULL)
+ break;
+ else
+ device_id ++;
+ }
+
+ *ptr = '\0';
+
+ fprintf(stderr, "DEBUG: [cups-driverd] regex_device_id: \"%s\"\n", res);
+
+ /*
+ * Compile the regular expression and return...
+ */
+
+ if (res[0] && (re = (regex_t *)calloc(1, sizeof(regex_t))) != NULL)
+ {
+ if (!regcomp(re, res, REG_EXTENDED | REG_ICASE))
+ {
+ fputs("DEBUG: [cups-driverd] regex_device_id: OK\n", stderr);
+ return (re);
+ }
+
+ free(re);
+ }
+
+ return (NULL);
+}
+
+
+/*
+ * 'regex_string()' - Construct a regular expression to compare a simple string.
+ */
+
+static regex_t * /* O - Regular expression */
+regex_string(const char *s) /* I - String to compare */
+{
+ char res[2048], /* Regular expression string */
+ *ptr; /* Pointer into string */
+ regex_t *re; /* Regular expression */
+
+
+ fprintf(stderr, "DEBUG: [cups-driverd] regex_string(\"%s\")\n", s);
+
+ /*
+ * Convert the string to a regular expression, escaping special characters
+ * as needed.
+ */
+
+ ptr = res;
+
+ while (*s && ptr < (res + sizeof(res) - 2))
+ {
+ if (strchr("[]{}().*\\", *s))
+ *ptr++ = '\\';
+
+ *ptr++ = *s++;
+ }
+
+ *ptr = '\0';
+
+ fprintf(stderr, "DEBUG: [cups-driverd] regex_string: \"%s\"\n", res);
+
+ /*
+ * Create a case-insensitive regular expression...
+ */
+
+ if (res[0] && (re = (regex_t *)calloc(1, sizeof(regex_t))) != NULL)
+ {
+ if (!regcomp(re, res, REG_ICASE))
+ {
+ fputs("DEBUG: [cups-driverd] regex_string: OK\n", stderr);
+ return (re);
+ }
+
+ free(re);
+ }
+
+ return (NULL);
+}
+
+
/*
* End of "$Id$".
*/
*
* Main header file for the Common UNIX Printing System (CUPS) scheduler.
*
- * 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
extern int cupsdRemoveFile(const char *filename);
+
/*
* End of "$Id: cupsd.h 7928 2008-09-10 22:14:22Z mike $".
*/
{
int i; /* Looping var */
cups_file_t *fp; /* printers.conf file */
- char temp[1024]; /* Temporary string */
+ char temp[1024], /* Temporary string */
+ value[2048]; /* Value string */
cupsd_printer_t *printer; /* Current printer class */
time_t curtime; /* Current time */
struct tm *curdate; /* Current date */
else
cupsFilePrintf(fp, "Printer %s>\n", printer->name);
- cupsFilePrintf(fp, "Type %d\n", printer->type);
-
cupsFilePrintf(fp, "BrowseTime %d\n", (int)printer->browse_expire);
if (printer->info)
- cupsFilePrintf(fp, "Info %s\n", printer->info);
-
- if (printer->make_model)
- cupsFilePrintf(fp, "MakeModel %s\n", printer->make_model);
+ cupsFilePutConf(fp, "Info", printer->info);
if (printer->location)
- cupsFilePrintf(fp, "Location %s\n", printer->location);
+ cupsFilePutConf(fp, "Location", printer->location);
+
+ if (printer->make_model)
+ cupsFilePutConf(fp, "MakeModel", printer->make_model);
- cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri);
+ cupsFilePutConf(fp, "DeviceURI", printer->device_uri);
if (printer->state == IPP_PRINTER_STOPPED)
- {
cupsFilePuts(fp, "State Stopped\n");
- cupsFilePrintf(fp, "StateMessage %s\n", printer->state_message);
- }
else
cupsFilePuts(fp, "State Idle\n");
for (i = 0; i < printer->num_reasons; i ++)
- cupsFilePrintf(fp, "Reason %s\n", printer->reasons[i]);
+ cupsFilePutConf(fp, "Reason", printer->reasons[i]);
+
+ cupsFilePrintf(fp, "Type %d\n", printer->type);
if (printer->accepting)
cupsFilePuts(fp, "Accepting Yes\n");
else
cupsFilePuts(fp, "Accepting No\n");
- cupsFilePrintf(fp, "JobSheets %s %s\n", printer->job_sheets[0],
- printer->job_sheets[1]);
+ snprintf(value, sizeof(value), "%s %s", printer->job_sheets[0],
+ printer->job_sheets[1]);
+ cupsFilePutConf(fp, "JobSheets", value);
for (i = 0; i < printer->num_users; i ++)
- cupsFilePrintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow",
- printer->users[i]);
+ cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser",
+ printer->users[i]);
for (i = printer->num_options, option = printer->options;
i > 0;
i --, option ++)
- cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+ {
+ snprintf(value, sizeof(value), "%s %s", option->name, option->value);
+ cupsFilePutConf(fp, "Option", value);
+ }
if (printer->type & CUPS_PRINTER_CLASS)
cupsFilePuts(fp, "</Class>\n");
ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared",
printer->shared);
+ if ((!ra || cupsArrayFind(ra, "printer-more-info")) &&
+ !(printer->type & CUPS_PRINTER_DISCOVERED))
+ {
+ httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
+ "http", NULL, con->servername, con->serverport,
+ (printer->type & CUPS_PRINTER_CLASS) ?
+ "/classes/%s" : "/printers/%s", printer->name);
+ ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI,
+ "printer-more-info", NULL, printer_uri);
+ }
+
if (!ra || cupsArrayFind(ra, "printer-op-policy"))
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
"printer-op-policy", NULL, printer->op_policy);
"printer-up-time", curtime);
if ((!ra || cupsArrayFind(ra, "printer-uri-supported")) &&
- !ippFindAttribute(printer->attrs, "printer-uri-supported",
- IPP_TAG_URI))
+ !(printer->type & CUPS_PRINTER_DISCOVERED))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
"ipp", NULL, con->servername, con->serverport,
if (value)
cupsdSetString(&p->info, value);
}
+ else if (!strcasecmp(line, "MakeModel"))
+ {
+ if (value)
+ cupsdSetString(&p->make_model, value);
+ }
else if (!strcasecmp(line, "Location"))
{
if (value)
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
}
+ else if (!strcasecmp(line, "Type"))
+ {
+ if (value)
+ p->type = atoi(value);
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Syntax error on line %d of printers.conf.", linenum);
+ }
+ else if (!strcasecmp(line, "Product"))
+ {
+ if (value)
+ {
+#ifdef HAVE_DNSSD
+ p->product = _cupsStrAlloc(value);
+#endif /* HAVE_DNSSD */
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Syntax error on line %d of printers.conf.", linenum);
+ }
+ else if (!strcasecmp(line, "Filter"))
+ {
+ if (value)
+ {
+ if (!p->filters)
+ p->filters = cupsArrayNew(NULL, NULL);
+
+ cupsArrayAdd(p->filters, _cupsStrAlloc(value));
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Syntax error on line %d of printers.conf.", linenum);
+ }
+ else if (!strcasecmp(line, "PreFilter"))
+ {
+ if (value)
+ {
+ if (!p->pre_filters)
+ p->pre_filters = cupsArrayNew(NULL, NULL);
+
+ cupsArrayAdd(p->pre_filters, _cupsStrAlloc(value));
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Syntax error on line %d of printers.conf.", linenum);
+ }
else if (!strcasecmp(line, "Shared"))
{
/*
{
int i; /* Looping var */
cups_file_t *fp; /* printers.conf file */
- char temp[1024]; /* Temporary string */
- char backup[1024]; /* printers.conf.O file */
+ char temp[1024], /* Temporary string */
+ backup[1024], /* printers.conf.O file */
+ value[2048], /* Value string */
+ *ptr; /* Pointer into value */
cupsd_printer_t *printer; /* Current printer class */
time_t curtime; /* Current time */
struct tm *curdate; /* Current date */
cups_option_t *option; /* Current option */
- const char *ptr; /* Pointer into info/location */
ipp_attribute_t *marker; /* Current marker attribute */
if (printer->num_auth_info_required > 0)
{
- cupsFilePrintf(fp, "AuthInfoRequired %s", printer->auth_info_required[0]);
- for (i = 1; i < printer->num_auth_info_required; i ++)
- cupsFilePrintf(fp, ",%s", printer->auth_info_required[i]);
- cupsFilePutChar(fp, '\n');
- }
-
- if (printer->info)
- {
- if ((ptr = strchr(printer->info, '#')) != NULL)
+ switch (printer->num_auth_info_required)
{
- /*
- * Need to quote the first # in the info string...
- */
-
- cupsFilePuts(fp, "Info ");
- cupsFileWrite(fp, printer->info, ptr - printer->info);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- cupsFilePutChar(fp, '\n');
+ case 1 :
+ strlcpy(value, printer->auth_info_required[0], sizeof(value));
+ break;
+
+ case 2 :
+ snprintf(value, sizeof(value), "%s,%s",
+ printer->auth_info_required[0],
+ printer->auth_info_required[1]);
+ break;
+
+ case 3 :
+ default :
+ snprintf(value, sizeof(value), "%s,%s,%s",
+ printer->auth_info_required[0],
+ printer->auth_info_required[1],
+ printer->auth_info_required[2]);
+ break;
}
- else
- cupsFilePrintf(fp, "Info %s\n", printer->info);
+
+ cupsFilePutConf(fp, "AuthInfoRequired", value);
}
+ if (printer->info)
+ cupsFilePutConf(fp, "Info", printer->info);
+
if (printer->location)
- {
- if ((ptr = strchr(printer->info, '#')) != NULL)
- {
- /*
- * Need to quote the first # in the location string...
- */
+ cupsFilePutConf(fp, "Location", printer->location);
- cupsFilePuts(fp, "Location ");
- cupsFileWrite(fp, printer->location, ptr - printer->location);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- cupsFilePutChar(fp, '\n');
- }
- else
- cupsFilePrintf(fp, "Location %s\n", printer->location);
- }
- cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri);
+ if (printer->make_model)
+ cupsFilePutConf(fp, "MakeModel", printer->make_model);
+
+ cupsFilePutConf(fp, "DeviceURI", printer->device_uri);
if (printer->port_monitor)
- cupsFilePrintf(fp, "PortMonitor %s\n", printer->port_monitor);
+ cupsFilePutConf(fp, "PortMonitor", printer->port_monitor);
if (printer->state == IPP_PRINTER_STOPPED)
{
cupsFilePuts(fp, "State Stopped\n");
- cupsFilePrintf(fp, "StateMessage %s\n", printer->state_message);
+
+ if (printer->state_message)
+ cupsFilePutConf(fp, "StateMessage", printer->state_message);
}
else
cupsFilePuts(fp, "State Idle\n");
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]);
+ cupsFilePutConf(fp, "Reason", printer->reasons[i]);
+
+ cupsFilePrintf(fp, "Type %d", printer->type);
+
+#ifdef HAVE_DNSSD
+ if (printer->product)
+ cupsFilePutConf(fp, "Product", printer->product);
+#endif /* HAVE_DNSSD */
+
+ for (ptr = (char *)cupsArrayFirst(printer->filters);
+ ptr;
+ ptr = (char *)cupsArrayNext(printer->filters))
+ cupsFilePutConf(fp, "Filter", ptr);
+
+ for (ptr = (char *)cupsArrayFirst(printer->pre_filters);
+ ptr;
+ ptr = (char *)cupsArrayNext(printer->pre_filters))
+ cupsFilePutConf(fp, "PreFilter", ptr);
if (printer->accepting)
cupsFilePuts(fp, "Accepting Yes\n");
else
cupsFilePuts(fp, "Shared No\n");
- cupsFilePrintf(fp, "JobSheets %s %s\n", printer->job_sheets[0],
- printer->job_sheets[1]);
+ snprintf(value, sizeof(value), "%s %s", printer->job_sheets[0],
+ printer->job_sheets[1]);
+ cupsFilePutConf(fp, "JobSheets", value);
cupsFilePrintf(fp, "QuotaPeriod %d\n", printer->quota_period);
cupsFilePrintf(fp, "PageLimit %d\n", printer->page_limit);
cupsFilePrintf(fp, "KLimit %d\n", printer->k_limit);
for (i = 0; i < printer->num_users; i ++)
- {
- if ((ptr = strchr(printer->users[i], '#')) != NULL)
- {
- /*
- * Need to quote the first # in the user string...
- */
-
- cupsFilePrintf(fp, "%sUser ", printer->deny_users ? "Deny" : "Allow");
- cupsFileWrite(fp, printer->users[i], ptr - printer->users[i]);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- cupsFilePutChar(fp, '\n');
- }
- else
- cupsFilePrintf(fp, "%sUser %s\n",
- printer->deny_users ? "Deny" : "Allow",
- printer->users[i]);
- }
+ cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser",
+ printer->users[i]);
if (printer->op_policy)
- cupsFilePrintf(fp, "OpPolicy %s\n", printer->op_policy);
+ cupsFilePutConf(fp, "OpPolicy", printer->op_policy);
if (printer->error_policy)
- cupsFilePrintf(fp, "ErrorPolicy %s\n", printer->error_policy);
+ cupsFilePutConf(fp, "ErrorPolicy", printer->error_policy);
for (i = printer->num_options, option = printer->options;
i > 0;
i --, option ++)
{
- if ((ptr = strchr(option->value, '#')) != NULL)
- {
- /*
- * Need to quote the first # in the option string...
- */
-
- cupsFilePrintf(fp, "Option %s ", option->name);
- cupsFileWrite(fp, option->value, ptr - option->value);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- cupsFilePutChar(fp, '\n');
- }
- else
- cupsFilePrintf(fp, "Option %s %s\n", option->name, option->value);
+ snprintf(value, sizeof(value), "%s %s", option->name, option->value);
+ cupsFilePutConf(fp, "Option", value);
}
if ((marker = ippFindAttribute(printer->attrs, "marker-colors",
IPP_TAG_NAME)) != NULL)
{
- cupsFilePrintf(fp, "Attribute %s ", marker->name);
+ snprintf(value, sizeof(value), "%s ", marker->name);
- for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+ for (i = 0, ptr = value + strlen(value);
+ i < marker->num_values && ptr < (value + sizeof(value) - 1);
+ i ++)
{
if (i)
- cupsFilePutChar(fp, ',');
+ *ptr++ = ',';
- if (!ptr && (ptr = strchr(marker->values[i].string.text, '#')) != NULL)
- {
- cupsFileWrite(fp, marker->values[i].string.text,
- ptr - marker->values[i].string.text);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- }
- else
- cupsFilePuts(fp, marker->values[i].string.text);
+ strlcpy(ptr, marker->values[i].string.text,
+ value + sizeof(value) - ptr);
+ ptr += strlen(ptr);
}
- cupsFilePuts(fp, "\n");
+ *ptr = '\0';
+ cupsFilePutConf(fp, "Attribute", value);
}
if ((marker = ippFindAttribute(printer->attrs, "marker-levels",
if ((marker = ippFindAttribute(printer->attrs, "marker-message",
IPP_TAG_TEXT)) != NULL)
{
- cupsFilePrintf(fp, "Attribute %s ", marker->name);
+ snprintf(value, sizeof(value), "%s %s", marker->name,
+ marker->values[0].string.text);
- if ((ptr = strchr(marker->values[0].string.text, '#')) != NULL)
- {
- cupsFileWrite(fp, marker->values[0].string.text,
- ptr - marker->values[0].string.text);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- }
- else
- cupsFilePuts(fp, marker->values[0].string.text);
-
- cupsFilePuts(fp, "\n");
+ cupsFilePutConf(fp, "Attribute", value);
}
if ((marker = ippFindAttribute(printer->attrs, "marker-names",
IPP_TAG_NAME)) != NULL)
{
- cupsFilePrintf(fp, "Attribute %s ", marker->name);
+ snprintf(value, sizeof(value), "%s ", marker->name);
- for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+ for (i = 0, ptr = value + strlen(value);
+ i < marker->num_values && ptr < (value + sizeof(value) - 1);
+ i ++)
{
if (i)
- cupsFilePutChar(fp, ',');
+ *ptr++ = ',';
- if (!ptr && (ptr = strchr(marker->values[i].string.text, '#')) != NULL)
- {
- cupsFileWrite(fp, marker->values[i].string.text,
- ptr - marker->values[i].string.text);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- }
- else
- cupsFilePuts(fp, marker->values[i].string.text);
+ strlcpy(ptr, marker->values[i].string.text,
+ value + sizeof(value) - ptr);
+ ptr += strlen(ptr);
}
- cupsFilePuts(fp, "\n");
+ *ptr = '\0';
+ cupsFilePutConf(fp, "Attribute", value);
}
if ((marker = ippFindAttribute(printer->attrs, "marker-types",
IPP_TAG_KEYWORD)) != NULL)
{
- cupsFilePrintf(fp, "Attribute %s ", marker->name);
+ snprintf(value, sizeof(value), "%s ", marker->name);
- for (i = 0, ptr = NULL; i < marker->num_values; i ++)
+ for (i = 0, ptr = value + strlen(value);
+ i < marker->num_values && ptr < (value + sizeof(value) - 1);
+ i ++)
{
if (i)
- cupsFilePutChar(fp, ',');
+ *ptr++ = ',';
- if (!ptr && (ptr = strchr(marker->values[i].string.text, '#')) != NULL)
- {
- cupsFileWrite(fp, marker->values[i].string.text,
- ptr - marker->values[i].string.text);
- cupsFilePutChar(fp, '\\');
- cupsFilePuts(fp, ptr);
- }
- else
- cupsFilePuts(fp, marker->values[i].string.text);
+ strlcpy(ptr, marker->values[i].string.text,
+ value + sizeof(value) - ptr);
+ ptr += strlen(ptr);
}
- cupsFilePuts(fp, "\n");
+ *ptr = '\0';
+ cupsFilePutConf(fp, "Attribute", value);
}
cupsFilePuts(fp, "</Printer>\n");
NULL, p->location ? p->location : "");
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
NULL, p->info ? p->info : "");
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info",
- NULL, p->uri);
if (p->num_users)
{
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI,
"printer-uri-supported", NULL, p->uri);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info",
+ NULL, p->uri);
+
if (p->make_model)
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
"printer-make-and-model", NULL, p->make_model);
}
else if (!strncmp(p->device_uri, "ipp://", 6) &&
(strstr(p->device_uri, "/printers/") != NULL ||
- strstr(p->device_uri, "/classes/") != NULL))
+ strstr(p->device_uri, "/classes/") != NULL ||
+ (strstr(p->device_uri, "._ipp.") != NULL &&
+ !strcmp(p->device_uri + strlen(p->device_uri) - 5,
+ "/cups"))))
{
/*
* Tell the client this is really a hard-wired remote printer.
char *alert, /* PSX printer-alert value */
*alert_description; /* PSX printer-alert-description value */
time_t marker_time; /* Last time marker attributes were updated */
+ cups_array_t *filters, /* Filters for queue */
+ *pre_filters; /* Pre-filters for queue */
#ifdef __APPLE__
char *recoverable; /* com.apple.print.recoverable-message */
const char *device_make_and_model,
const char *device_uri, const char *device_location,
void *user_data);
-static int show_devices(http_t *, int);
-static int show_models(http_t *, int);
+static int show_devices(http_t *http, int long_status, int timeout);
+static int show_models(http_t *http, int long_status,
+ const char *device_id, const char *language,
+ const char *make_model, const char *product);
/*
int i; /* Looping var */
http_t *http; /* Connection to server */
int long_status; /* Long listing? */
+ const char *device_id, /* 1284 device ID */
+ *language, /* Language */
+ *make_model, /* Make and model */
+ *product; /* Product */
+ int timeout; /* Device timeout */
_cupsSetLocale(argv);
http = NULL;
long_status = 0;
+ device_id = NULL;
+ language = NULL;
+ make_model = NULL;
+ product = NULL;
+ timeout = CUPS_TIMEOUT_DEFAULT;
for (i = 1; i < argc; i ++)
if (argv[i][0] == '-')
#endif /* HAVE_SSL */
break;
+ case 'h' : /* Connect to host */
+ if (http)
+ {
+ httpClose(http);
+ http = NULL;
+ }
+
+ if (argv[i][2] != '\0')
+ cupsSetServer(argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ _cupsLangPuts(stderr,
+ _("Error: need hostname after \'-h\' option!\n"));
+ return (1);
+ }
+
+ cupsSetServer(argv[i]);
+ }
+ break;
+
case 'l' : /* Show long listing */
long_status = 1;
break;
}
}
- if (show_models(http, long_status))
+ if (show_models(http, long_status, device_id, language, make_model,
+ product))
return (1);
break;
}
}
- if (show_devices(http, long_status))
+ if (show_devices(http, long_status, timeout))
return (1);
break;
- case 'h' : /* Connect to host */
- if (http)
+ case '-' : /* --something */
+ if (!strcmp(argv[i], "--device-id"))
{
- httpClose(http);
- http = NULL;
- }
+ i ++;
- if (argv[i][2] != '\0')
- cupsSetServer(argv[i] + 2);
- else
+ if (i < argc)
+ device_id = argv[i];
+ else
+ {
+ _cupsLangPuts(stderr,
+ _("lpinfo: Expected 1284 device ID string "
+ "after --device-id!\n"));
+ return (1);
+ }
+ }
+ else if (!strncmp(argv[i], "--device-id=", 12) && argv[i][12])
+ {
+ device_id = argv[i] + 12;
+ }
+ else if (!strcmp(argv[i], "--language"))
{
i ++;
-
- if (i >= argc)
+ if (i < argc)
+ language = argv[i];
+ else
{
- _cupsLangPuts(stderr,
- _("Error: need hostname after \'-h\' option!\n"));
+ _cupsLangPuts(stderr,
+ _("lpinfo: Expected language after "
+ "--language!\n"));
return (1);
- }
-
- cupsSetServer(argv[i]);
+ }
+ }
+ else if (!strncmp(argv[i], "--language=", 11) && argv[i][11])
+ {
+ language = argv[i] + 11;
+ }
+ else if (!strcmp(argv[i], "--make-and-model"))
+ {
+ i ++;
+ if (i < argc)
+ make_model= argv[i];
+ else
+ {
+ _cupsLangPuts(stderr,
+ _("lpinfo: Expected make and model after "
+ "--make-and-model!\n"));
+ return (1);
+ }
+ }
+ else if (!strncmp(argv[i], "--make-and-model=", 17) && argv[i][17])
+ {
+ make_model = argv[i] + 17;
+ }
+ else if (!strcmp(argv[i], "--product"))
+ {
+ i ++;
+ if (i < argc)
+ product = argv[i];
+ else
+ {
+ _cupsLangPuts(stderr,
+ _("lpinfo: Expected product string after "
+ "--product!\n"));
+ return (1);
+ }
+ }
+ else if (!strncmp(argv[i], "--product=", 10) && argv[i][10])
+ {
+ product = argv[i] + 10;
+ }
+ else if (!strcmp(argv[i], "--timeout"))
+ {
+ i ++;
+ if (i < argc)
+ timeout = atoi(argv[i]);
+ else
+ {
+ _cupsLangPuts(stderr,
+ _("lpinfo: Expected timeout after --timeout!\n"));
+ return (1);
+ }
+ }
+ else if (!strncmp(argv[i], "--timeout=", 10) && argv[i][10])
+ {
+ timeout = atoi(argv[i] + 10);
+ }
+ else
+ {
+ _cupsLangPrintf(stderr, _("lpinfo: Unknown option \'%s\'!\n"),
+ argv[i]);
+ return (1);
}
break;
static int /* O - 0 on success, 1 on failure */
show_devices(http_t *http, /* I - HTTP connection to server */
- int long_status) /* I - Long status report? */
+ int long_status, /* I - Long status report? */
+ int timeout) /* I - Timeout */
{
- if (cupsGetDevices(http, CUPS_TIMEOUT_DEFAULT, CUPS_EXCLUDE_NONE, device_cb,
+ if (cupsGetDevices(http, timeout, CUPS_EXCLUDE_NONE, device_cb,
&long_status) != IPP_OK)
{
_cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString());
*/
static int /* O - 0 on success, 1 on failure */
-show_models(http_t *http, /* I - HTTP connection to server */
- int long_status) /* I - Long status report? */
+show_models(http_t *http, /* I - HTTP connection to server */
+ int long_status, /* I - Long status report? */
+ const char *device_id, /* I - 1284 device ID */
+ const char *language, /* I - Language */
+ const char *make_model, /* I - Make and model */
+ const char *product) /* I - Product */
{
ipp_t *request, /* IPP Request */
*response; /* IPP Response */
ipp_attribute_t *attr; /* Current attribute */
const char *ppd_device_id, /* Pointer to ppd-device-id */
*ppd_language, /* Pointer to ppd-natural-language */
- *ppd_make, /* Pointer to ppd-make-and-model */
+ *ppd_make_model, /* Pointer to ppd-make-and-model */
*ppd_name; /* Pointer to ppd-name */
return (1);
/*
- * Build a CUPS_GET_PPDS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
+ * Build a CUPS_GET_PPDS request...
*/
request = ippNewRequest(CUPS_GET_PPDS);
+ if (device_id)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-device-id",
+ NULL, device_id);
+ if (language)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "ppd-language",
+ NULL, language);
+ if (make_model)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-make-and-model",
+ NULL, make_model);
+ if (product)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-product",
+ NULL, product);
+
/*
* Do the request and get back a response...
*/
* Pull the needed attributes from this PPD...
*/
- ppd_device_id = "NONE";
- ppd_language = NULL;
- ppd_make = NULL;
- ppd_name = NULL;
+ ppd_device_id = "NONE";
+ ppd_language = NULL;
+ ppd_make_model = NULL;
+ ppd_name = NULL;
while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
{
ppd_language = attr->values[0].string.text;
else if (!strcmp(attr->name, "ppd-make-and-model") &&
attr->value_tag == IPP_TAG_TEXT)
- ppd_make = attr->values[0].string.text;
+ ppd_make_model = attr->values[0].string.text;
else if (!strcmp(attr->name, "ppd-name") &&
attr->value_tag == IPP_TAG_NAME)
ppd_name = attr->values[0].string.text;
* See if we have everything needed...
*/
- if (ppd_language == NULL || ppd_make == NULL || ppd_name == NULL)
+ if (ppd_language == NULL || ppd_make_model == NULL || ppd_name == NULL)
{
if (attr == NULL)
break;
" natural_language = %s\n"
" make-and-model = %s\n"
" device-id = %s\n"),
- ppd_name, ppd_language, ppd_make, ppd_device_id);
+ ppd_name, ppd_language, ppd_make_model, ppd_device_id);
}
else
- _cupsLangPrintf(stdout, "%s %s\n", ppd_name, ppd_make);
+ _cupsLangPrintf(stdout, "%s %s\n", ppd_name, ppd_make_model);
if (attr == NULL)
break;
class-modified.tmpl \
classes.tmpl \
classes-header.tmpl \
+ command.tmpl \
edit-config.tmpl \
error.tmpl \
error-op.tmpl \
jobs.tmpl \
jobs-header.tmpl \
list-available-printers.tmpl \
- maintenance.tmpl \
modify-class.tmpl \
modify-printer.tmpl \
norestart.tmpl \
<H2 CLASS="title">{op=modify-printer?Modify {printer_name}:Add Printer}</H2>
+{CUPS_GET_DEVICES_DONE?:<P><IMG SRC="/images/wait.gif" WIDTH="16" HEIGHT="16" ALIGN="ABSMIDDLE"
+ALT="Busy Indicator"> Looking for printers...</P>}
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
{printer_name?<INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{printer_name}">:}
<TH CLASS="label">Current Connection:</TH>
<TD><INPUT TYPE="RADIO" NAME="DEVICE_URI" VALUE="{current_device_uri}" CHECKED>
{current_device_uri}</TD>
-</TR>:}
+</TR>}
<TR>
<TH CLASS="label">Local Printers:</TH>
<TD>
<DIV CLASS="indent">
+<H2 CLASS="title">Add Class</H2>
+
<P>Class <A HREF="/classes/{printer_name}">{printer_name}</A> has been added
successfully.
<DIV CLASS="indent">
+<H2 CLASS="title">Delete Class {printer_name}</H2>
+
<P><B>Warning:</B> Are you sure you want to delete class
{printer_name}?</P>
<DIV CLASS="indent">
+<H2 CLASS="title">Delete Class {printer_name}</H2>
+
<P>Class {printer_name} has been deleted successfully.
</DIV>
\ No newline at end of file
<DIV CLASS="indent">
+<H2 CLASS="title">Modify Class {printer_name}</H2>
+
<P>Class <A HREF="/classes/{printer_name}">{printer_name}</A> has been
modified successfully.
<SELECT NAME="OP" ONCHANGE="document.maintenance.submit();">
<OPTION VALUE="">Maintenance</OPTION>
<OPTION VALUE="print-test-page">Print Test Page</OPTION>
-{printer_state=5?<OPTION VALUE="start-printer">Resume Class</OPTION>:<OPTION VALUE="stop-printer">Pause Class</OPTION>}
+{printer_state=5?<OPTION VALUE="start-class">Resume Class</OPTION>:<OPTION VALUE="stop-class">Pause Class</OPTION>}
{printer_is_accepting_jobs=0?<OPTION VALUE="accept-jobs">Accept Jobs</OPTION>:<OPTION VALUE="reject-jobs">Reject Jobs</OPTION>}
<OPTION VALUE="move-jobs">Move All Jobs</OPTION>
<OPTION VALUE="purge-jobs">Cancel All Jobs</OPTION>
</FORM>
<FORM METHOD="POST" ACTION="{admin_uri}" NAME="administration">
-<INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{%printer_name}">
+<INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{printer_name}">
<SELECT NAME="OP" ONCHANGE="document.administration.submit();">
<OPTION VALUE="">Administration</OPTION>
<OPTION VALUE="modify-class">Modify Class</OPTION>
<DIV CLASS="indent">
+<H2 CLASS="title">{?title} {?printer_name} Error</H2>
+
<P>Error:</P>
<BLOCKQUOTE>Unknown operation "{op}"!</BLOCKQUOTE>
<DIV CLASS="indent">
+<H2 CLASS="title">{?title} {?printer_name} Error</H2>
+
<P>{?message?{message}:Error:}</P>
<BLOCKQUOTE>{error}</BLOCKQUOTE>
<P ALIGN="CENTER"><B>Search in
{HELPTITLE?{HELPTITLE}:{TOPIC?{TOPIC}:All Documents}}:</B> <INPUT
-TYPE="SEARCH" NAME="QUERY" VALUE="{?QUERY}" SIZE="60" PLACEHOLDER=""
+TYPE="SEARCH" NAME="QUERY" VALUE="{?QUERY}" SIZE="40" PLACEHOLDER=""
AUTOSAVE="org.cups.help" RESULTS="20">
<INPUT TYPE="SUBMIT" NAME="SEARCH" VALUE="Search">
<INPUT TYPE="SUBMIT" NAME="CLEAR" VALUE="Clear"></P>
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Cancel Job {job_id}</H2>
+
<P><A HREF="{job_printer_uri}">Job {job_id}</A> has been canceled.
+
+</DIV>
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Hold Job {job_id}</H2>
+
<P><A HREF="{job_printer_uri}">Job {job_id}</A> has been held from printing.
+
+</DIV>
+<DIV CLASS="indent">
+
<FORM METHOD="POST" ACTION="/{SECTION}/{job_id?:{printer_name}}">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
{job_id?<INPUT TYPE="HIDDEN" NAME="JOB_ID" VALUE="{job_id}">:}
</TR>
<TR>
<TD></TD>
-<TD><INPUT TYPE="SUBMIT" VALUE="Move Job{job_id?:s}"></TD>
+<TD><INPUT TYPE="SUBMIT" VALUE="{job_id?Move Job:Move Jobs}"></TD>
</TR>
</TABLE>
</FORM>
+
+</DIV>
+<DIV CLASS="indent">
+
+<H2 CLASS="title">{job_id?Move Job {job_id}:Move All Jobs}</H2>
+
<P>{job_id?<A HREF="/jobs/{job_id}">Job {job_id}</A>:All jobs} moved to
<A HREF="{job_printer_uri}">{job_printer_name}</A>.</P>
+
+</DIV>
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Release Job {job_id}</H2>
+
<P><A HREF="{job_printer_uri}">Job {job_id}</A> has been released for printing.
+
+</DIV>
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Reprint Job {job_id}</H2>
+
<P><A HREF="{job_printer_uri}">Job {job_id}</A> has been restarted.
+
+</DIV>
{job_state=7?canceled at<BR>{time_at_completed}:{job_state=8?aborted:completed at<BR>{time_at_completed}}}}}}} {job_printer_state_message?<BR>
<EM>"{job_printer_state_message}"</EM>:}</TD>
<TD>
-{job_preserved>0?
+{job_preserved>0?{job_state>5?
<FORM ACTION="/jobs/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="restart-job"><INPUT TYPE="HIDDEN" NAME="job_id" VALUE="{job_id}"><INPUT TYPE="HIDDEN" NAME="job_printer_uri" VALUE="{job_printer_uri}">
-<INPUT TYPE="SUBMIT" VALUE="Reprint Job"></FORM>:}
+<INPUT TYPE="SUBMIT" VALUE="Reprint Job"></FORM>:}:}
{job_state=4?
<FORM ACTION="/jobs/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="release-job"><INPUT TYPE="HIDDEN" NAME="job_id" VALUE="{job_id}"><INPUT TYPE="HIDDEN" NAME="job_printer_uri" VALUE="{job_printer_uri}">
<INPUT TYPE="SUBMIT" VALUE="Release Job"></FORM>:}
-<DIV CLASS="indent">
-
-<P>Maintenance commands sent; job ID is <A HREF="/printers/{printer_name}">
-{printer_name}-{job_id}</A>.</P>
-
-</DIV>
-<p>The server was not restarted because no changes were made to
-the configuration...</p>
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Change Settings</H2>
+
+<P>The server was not restarted because no changes were made to
+the configuration...</P>
+
+</DIV>
<TR>
-<TH CLASS="label"{conflicted=1? CLASS="conflict":}><A NAME="{keyword}">{keytext}</A>:</TH>
+<TH {conflicted=1?CLASS="conflict":CLASS="label"} WIDTH="50%"><A NAME="{keyword}">{keytext}</A>:</TH>
<TD>
{[choices]<INPUT TYPE="RADIO" NAME="{keyword}" {choices={defchoice}?CHECKED:} VALUE="{choices}">{text}}
</TD>
-<H2 CLASS="title">{printer_name}: {group}</H2>
+<DIV CLASS="tab" ID="{group_id}">
-<TABLE>
+<H3 ALIGN="CENTER">{group}</H3>
+
+<TABLE WIDTH="100%">
<TR>
-<TH CLASS="label"{conflicted=1? CLASS="conflict":}><A NAME="{keyword}">{keytext}</A>:</TH>
+<TH {conflicted=1?CLASS="conflict":CLASS="label"} WIDTH="50%"><A NAME="{keyword}">{keytext}</A>:</TH>
<TD><SELECT NAME="{keyword}" MULTIPLE SIZE="10">
{[choices]<OPTION {choices={defchoice}?SELECTED:} VALUE="{choices}">{text}}
</SELECT></TD>
<TR>
-<TH CLASS="label"{conflicted=1? CLASS="conflict":}><A NAME="{keyword}">{keytext}</A>:</TH>
+<TH {conflicted=1?CLASS="conflict":CLASS="label"} WIDTH="50%"><A NAME="{keyword}">{keytext}</A>:</TH>
<TD><SELECT NAME="{keyword}" ID="select-{keyword}" ONCHANGE="update_paramtable('{keyword}')">
{[choices]<OPTION {choices={defchoice}?SELECTED:} VALUE="{choices}">{text}}
</SELECT>
-<TR>
-<TD></TD>
-<TD><INPUT TYPE="SUBMIT" VALUE="Set Printer Options"></TD>
-</TR>
</TABLE>
+
+<P ALIGN="CENTER"><INPUT TYPE="SUBMIT" VALUE="Set Default Options"></P>
+
+</DIV>
\ No newline at end of file
<DIV CLASS="indent">
+<H2 CLASS="title">Accept Jobs On {is_class?Class:Printer} {printer_name}</H2>
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
is now accepting jobs.</P>
<DIV CLASS="indent">
+<H2 CLASS="title">Add Printer</H2>
+
<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> has been added
successfully.
<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.
+<H2 CLASS="title">Set Default Options for {printer_name}</H2>
+
+<P>{OP=set-class-options?Class <A HREF="/classes/{printer_name}">:Printer <A HREF="/printers/{printer_name}">}{printer_name}</A>
+default options have been set successfully.
</DIV>
<DIV CLASS="indent">
+<H2 CLASS="title">Delete Printer {printer_name}</H2>
+
<P><B>Warning:</B> Are you sure you want to delete printer
{printer_name}?</P>
<DIV CLASS="indent">
+<H2 CLASS="title">Set {is_class?Class:Printer} {printer_name} As Default</H2>
+
<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>
<DIV CLASS="indent">
+<H2 CLASS="title">Delete Printer {printer_name}</H2>
+
<P>Printer {printer_name} has been deleted successfully.
</DIV>
<DIV CLASS="indent">
+<H2 CLASS="title">Modify Printer {printer_name}</H2>
+
<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> has been
modified successfully.
<DIV CLASS="indent">
+<H2 CLASS="title">Purge Jobs On {is_class?Class:Printer} {printer_name}</H2>
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
has been purged of all jobs.</P>
<DIV CLASS="indent">
+<H2 CLASS="title">Reject Jobs On {is_class?Class:Printer} {printer_name}</H2>
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
is no longer accepting jobs.</P>
<DIV CLASS="indent">
+<H2 CLASS="title">Resume {is_class?Class:Printer} {printer_name}</H2>
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
-has been started.</P>
+has been resumed.</P>
</DIV>
\ No newline at end of file
<DIV CLASS="indent">
+<H2 CLASS="title">Pause {is_class?Class:Printer} {printer_name}</H2>
+
<P>{is_class?Class:Printer} <A
HREF="/{is_class?classes:printers}/{printer_name}">{printer_name}</A>
-has been stopped.</P>
+has been paused.</P>
</DIV>
\ No newline at end of file
<DIV CLASS="indent">
+
<H2 CLASS="title"><A HREF="{printer_uri_supported}">{printer_name}</A>
({printer_state=3?Idle:{printer_state=4?Processing:Paused}},
{printer_is_accepting_jobs=0?Rejecting Jobs:Accepting Jobs},
<SELECT NAME="OP" ONCHANGE="document.maintenance.submit();">
<OPTION VALUE="">Maintenance</OPTION>
<OPTION VALUE="print-test-page">Print Test Page</OPTION>
-{?cupscommand=1?<OPTION VALUE="clean-print-heads">Clean Print Heads</OPTION>
-<OPTION VALUE="print-self-test-page">Print Self Test Page</OPTION>:}
+{printer_commands~.*Clean.*?<OPTION VALUE="clean-print-heads">Clean Print Heads</OPTION>:}
+{printer_commands~.*PrintSelfTestPage.*?<OPTION VALUE="print-self-test-page">Print Self Test Page</OPTION>:}
{printer_state=5?<OPTION VALUE="start-printer">Resume Printer</OPTION>:<OPTION VALUE="stop-printer">Pause Printer</OPTION>}
{printer_is_accepting_jobs=0?<OPTION VALUE="accept-jobs">Accept Jobs</OPTION>:<OPTION VALUE="reject-jobs">Reject Jobs</OPTION>}
<OPTION VALUE="move-jobs">Move All Jobs</OPTION>
</FORM>
<FORM METHOD="POST" ACTION="{admin_uri}" NAME="administration">
-<INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{%printer_name}">
+<INPUT TYPE="HIDDEN" NAME="printer_name" VALUE="{printer_name}">
<SELECT NAME="OP" ONCHANGE="document.administration.submit();">
<OPTION VALUE="">Administration</OPTION>
<OPTION VALUE="modify-printer">Modify Printer</OPTION>
-<p>Please stand by while the server restarts...</p>
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Change Settings</H2>
+
+<P><IMG SRC="/images/wait.gif" WIDTH="16" HEIGHT="16" ALIGN="ABSMIDDLE"
+ALT="Busy Indicator"> Please stand by while the server restarts...</P>
+
+</DIV>
<DIV CLASS="indent">
+<H2 CLASS="title">Set Default Options for {printer_name}</H2>
+
<FORM METHOD="POST" ACTION="/admin">
<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
-{HAVE_AUTOCONFIGURE?<INPUT TYPE="SUBMIT" NAME="AUTOCONFIGURE" VALUE="Auto-Configure Options">:}
+{HAVE_AUTOCONFIGURE?<INPUT TYPE="SUBMIT" NAME="AUTOCONFIGURE" VALUE="Query Printer for Default Options">:}
<SCRIPT TYPE="text/javascript"><!--
function update_paramtable(option)
}
--></SCRIPT>
+<H3 CLASS="title">{[group_id]
+<A HREF="#{group_id}">{group}</A> }</H3>
+
+<DIV CLASS="tabs">
+</DIV>
+
<SCRIPT TYPE="text/javascript"><!--
// Hide custom options parameters for browsers that understand Javascript
var paramtables = document.getElementsByName("paramtable");
+<DIV CLASS="indent">
+
+<H2 CLASS="title">Print Test Page On {printer_name}</H2>
+
<P>Test page sent; job ID is <A HREF="/{SECTION}/{printer_name}">
{printer_name}-{job_id}</A>.</P>
+
+</DIV>
+++ /dev/null
-#!/bin/sh
-#
-# Check .po files to see if there are untranslated or fuzzy strings.
-#
-# Usage: checkpo filename.po [ ... filenameN.po]
-#
-
-if test $# = 1; then
- echo Usage: checkpo filename.po ... filenameN.po
- exit 1
-fi
-
-echo "Catalog Untrans Fuzzy"
-echo "-------------------- ------- -------"
-
-for file in $*; do
- untranslated=`msgattrib --untranslated $file | grep 'msgid "..*"' | wc -l`
- fuzzy=`grep fuzzy $file | wc -l`
-
- printf "%-20.20s %7d %7d\n" $file $untranslated $fuzzy
-done
-