CHANGES IN CUPS V1.4.5
- Documentation fixes (STR #3542)
+ - PJL value substitution of more than 9 values was broken (STR #3621)
+ - Custom options with missing string values caused ppdEmit* to segfault
+ (STR #3620)
+ - Fixed an issue with the Italian version of the web interface
+ (STR #3624)
- Fixed the Solaris SMF configuration file for cups-lpd (STR #3611)
- The scheduler did not set the notify-subscribed-event attribute when
delivering printer-added or printer-modified events (STR #3608)
{
fprintf(stderr, "DEBUG: Read %d bytes...\n", (int)bytes);
- if ((http_status = cupsWriteRequestData(http, buffer, bytes))
- != HTTP_CONTINUE)
+ if (cupsWriteRequestData(http, buffer, bytes) != HTTP_CONTINUE)
break;
else
{
{
while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
{
- if ((http_status = cupsWriteRequestData(http, buffer, bytes))
- != HTTP_CONTINUE)
+ if (cupsWriteRequestData(http, buffer, bytes) != HTTP_CONTINUE)
break;
else
{
case PPD_CUSTOM_PASSCODE :
case PPD_CUSTOM_PASSWORD :
case PPD_CUSTOM_STRING :
- bufsize += strlen(cparam->current.custom_string);
+ if (cparam->current.custom_string)
+ bufsize += strlen(cparam->current.custom_string);
break;
}
}
case PPD_CUSTOM_PASSCODE :
case PPD_CUSTOM_PASSWORD :
case PPD_CUSTOM_STRING :
- bufsize += 3 + 4 * strlen(cparam->current.custom_string);
+ bufsize += 3;
+ if (cparam->current.custom_string)
+ bufsize += 4 * strlen(cparam->current.custom_string);
break;
}
}
*/
pnum = *cptr++ - '0';
- while (isalnum(*cptr & 255))
- pnum = pnum * 10 + *cptr - '0';
+ while (isdigit(*cptr & 255))
+ pnum = pnum * 10 + *cptr++ - '0';
for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
cparam;
case PPD_CUSTOM_PASSCODE :
case PPD_CUSTOM_PASSWORD :
case PPD_CUSTOM_STRING :
- strlcpy(bufptr, cparam->current.custom_string,
- bufend - bufptr);
- bufptr += strlen(bufptr);
+ if (cparam->current.custom_string)
+ {
+ strlcpy(bufptr, cparam->current.custom_string,
+ bufend - bufptr);
+ bufptr += strlen(bufptr);
+ }
break;
}
}
case PPD_CUSTOM_STRING :
*bufptr++ = '(';
- for (s = cparam->current.custom_string; *s; s ++)
- if (*s < ' ' || *s == '(' || *s == ')' || *s >= 127)
+ if (cparam->current.custom_string)
+ {
+ for (s = cparam->current.custom_string; *s; s ++)
{
- snprintf(bufptr, bufend - bufptr + 1, "\\%03o", *s & 255);
- bufptr += strlen(bufptr);
+ if (*s < ' ' || *s == '(' || *s == ')' || *s >= 127)
+ {
+ snprintf(bufptr, bufend - bufptr + 1, "\\%03o", *s & 255);
+ bufptr += strlen(bufptr);
+ }
+ else
+ *bufptr++ = *s;
}
- else
- *bufptr++ = *s;
+ }
*bufptr++ = ')';
*bufptr++ = '\n';
*custom_min_keyword, /* Minimum custom size PWG keyword */
custom_ppd_size[41]; /* Custom PPD size name */
_pwg_size_t custom_size; /* Custom size record */
+ char *source_option; /* PPD option for media source */
int num_sources; /* Number of media sources */
_pwg_map_t *sources; /* Media sources */
int num_types; /* Number of media types */
pwg->custom_min_width, pwg->custom_min_length);
pwg->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
}
+ else if (!strcasecmp(line, "SourceOption"))
+ {
+ pwg->source_option = _cupsStrAlloc(value);
+ }
else if (!strcasecmp(line, "NumSources"))
{
if (num_sources > 0)
free(pwg->sizes);
}
+ if (pwg->source_option)
+ _cupsStrFree(pwg->source_option);
+
if (pwg->sources)
{
for (i = pwg->num_sources, map = pwg->sources; i > 0; i --, map ++)
* Media sources...
*/
+ if (pwg->source_option)
+ cupsFilePrintf(fp, "SourceOption %s\n", pwg->source_option);
+
if (pwg->num_sources > 0)
{
cupsFilePrintf(fp, "NumSources %d\n", pwg->num_sources);
* Copy and convert InputSlot data...
*/
- if ((input_slot = ppdFindOption(ppd, "InputSlot")) != NULL)
+ if ((input_slot = ppdFindOption(ppd, "InputSlot")) == NULL)
+ input_slot = ppdFindOption(ppd, "HPPaperSource");
+
+ if (input_slot)
{
+ pwg->source_option = _cupsStrAlloc(input_slot->keyword);
+
if ((pwg->sources = calloc(input_slot->num_choices,
sizeof(_pwg_map_t))) == NULL)
{
pwg_name = "auto";
else if (!strcasecmp(choice->choice, "Cassette"))
pwg_name = "main";
+ else if (!strcasecmp(choice->choice, "PhotoTray"))
+ pwg_name = "photo";
+ else if (!strcasecmp(choice->choice, "CDTray"))
+ pwg_name = "disc";
else if (!strncasecmp(choice->choice, "Multipurpose", 12) ||
!strcasecmp(choice->choice, "MP") ||
!strcasecmp(choice->choice, "MPTray"))
if (!pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_DRAFT] &&
!pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_NORMAL] &&
- !pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_HIGH] &&
- (color_model = ppdFindOption(ppd, "ColorModel")) != NULL &&
- ppdFindChoice(color_model, "Gray"))
+ !pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_HIGH])
{
/*
- * Copy and convert ColorModel (output-mode) data...
+ * Try adding some common color options to create grayscale presets. These
+ * are listed in order of popularity...
*/
- cups_option_t *coption, /* Color option */
- *moption; /* Monochrome option */
+ const char *color_option = NULL, /* Color control option */
+ *gray_choice = NULL; /* Choice to select grayscale */
- for (pwg_print_quality = _PWG_PRINT_QUALITY_DRAFT;
- pwg_print_quality < _PWG_PRINT_QUALITY_MAX;
- pwg_print_quality ++)
+ if ((color_model = ppdFindOption(ppd, "ColorModel")) != NULL &&
+ ppdFindChoice(color_model, "Gray"))
{
- if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][pwg_print_quality])
- {
- /*
- * Copy the color options...
- */
+ color_option = "ColorModel";
+ gray_choice = "Gray";
+ }
+ else if ((color_model = ppdFindOption(ppd, "HPColorMode")) != NULL &&
+ ppdFindChoice(color_model, "grayscale"))
+ {
+ color_option = "HPColorMode";
+ gray_choice = "grayscale";
+ }
+ else if ((color_model = ppdFindOption(ppd, "BRMonoColor")) != NULL &&
+ ppdFindChoice(color_model, "Mono"))
+ {
+ color_option = "BRMonoColor";
+ gray_choice = "Mono";
+ }
+ else if ((color_model = ppdFindOption(ppd, "CNIJSGrayScale")) != NULL &&
+ ppdFindChoice(color_model, "1"))
+ {
+ color_option = "CNIJSGrayScale";
+ gray_choice = "1";
+ }
+ else if ((color_model = ppdFindOption(ppd, "HPColorAsGray")) != NULL &&
+ ppdFindChoice(color_model, "True"))
+ {
+ color_option = "HPColorAsGray";
+ gray_choice = "True";
+ }
- num_options = pwg->num_presets[_PWG_OUTPUT_MODE_COLOR]
- [pwg_print_quality];
- options = calloc(sizeof(cups_option_t), num_options);
+ if (color_option && gray_choice)
+ {
+ /*
+ * Copy and convert ColorModel (output-mode) data...
+ */
- if (options)
+ cups_option_t *coption, /* Color option */
+ *moption; /* Monochrome option */
+
+ for (pwg_print_quality = _PWG_PRINT_QUALITY_DRAFT;
+ pwg_print_quality < _PWG_PRINT_QUALITY_MAX;
+ pwg_print_quality ++)
+ {
+ if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][pwg_print_quality])
{
- for (i = num_options, moption = options,
- coption = pwg->presets[_PWG_OUTPUT_MODE_COLOR]
- [pwg_print_quality];
- i > 0;
- i --, moption ++, coption ++)
+ /*
+ * Copy the color options...
+ */
+
+ num_options = pwg->num_presets[_PWG_OUTPUT_MODE_COLOR]
+ [pwg_print_quality];
+ options = calloc(sizeof(cups_option_t), num_options);
+
+ if (options)
{
- moption->name = _cupsStrRetain(coption->name);
- moption->value = _cupsStrRetain(coption->value);
+ for (i = num_options, moption = options,
+ coption = pwg->presets[_PWG_OUTPUT_MODE_COLOR]
+ [pwg_print_quality];
+ i > 0;
+ i --, moption ++, coption ++)
+ {
+ moption->name = _cupsStrRetain(coption->name);
+ moption->value = _cupsStrRetain(coption->value);
+ }
+
+ pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+ num_options;
+ pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+ options;
}
-
- pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
- num_options;
- pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
- options;
}
- }
- else if (pwg_print_quality != _PWG_PRINT_QUALITY_NORMAL)
- continue;
+ else if (pwg_print_quality != _PWG_PRINT_QUALITY_NORMAL)
+ continue;
- /*
- * Add ColorModel=Gray to the preset...
- */
+ /*
+ * Add the grayscale option to the preset...
+ */
- pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
- cupsAddOption("ColorModel", "Gray",
- pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME]
- [pwg_print_quality],
- pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME] +
- pwg_print_quality);
+ pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+ cupsAddOption(color_option, gray_choice,
+ pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME]
+ [pwg_print_quality],
+ pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME] +
+ pwg_print_quality);
+ }
}
}
ipp_attribute_t *media_col, /* media-col attribute */
*media_source; /* media-source attribute */
+ _pwg_size_t size; /* Dimensional size */
+ int margins_set; /* Were the margins set? */
media_col = ippFindAttribute(job, "media-col", IPP_TAG_BEGIN_COLLECTION);
if (media_col &&
(media_source = ippFindAttribute(media_col->values[0].collection,
"media-source",
IPP_TAG_KEYWORD)) != NULL)
+ {
+ /*
+ * Use the media-source value from media-col...
+ */
+
keyword = media_source->values[0].string.text;
+ }
+ else if (_pwgInitSize(&size, job, &margins_set))
+ {
+ /*
+ * For media <= 5x7, look for a photo tray...
+ */
+
+ if (size.width <= (5 * 2540) && size.length <= (7 * 2540))
+ keyword = "photo";
+ }
}
if (keyword)
const cups_encoding_t encoding) /* I - Encoding */
{
cups_utf8_t *destptr; /* Pointer into UTF-8 buffer */
- int bytes; /* Number of bytes converted */
size_t srclen, /* Length of source string */
outBytesLeft; /* Bytes remaining in output buffer */
{
srclen = strlen(src);
outBytesLeft = maxout - 1;
- bytes = (int)iconv(map_to_utf8, (char **)&src, &srclen,
- (char **)&destptr, &outBytesLeft);
- *destptr = '\0';
+
+ iconv(map_to_utf8, (char **)&src, &srclen, (char **)&destptr,
+ &outBytesLeft);
+ *destptr = '\0';
_cupsMutexUnlock(&map_mutex);
const cups_encoding_t encoding) /* I - Encoding */
{
char *destptr; /* Pointer into destination */
- int bytes; /* Number of bytes converted */
size_t srclen, /* Length of source string */
outBytesLeft; /* Bytes remaining in output buffer */
{
srclen = strlen((char *)src);
outBytesLeft = maxout - 1;
- bytes = (int)iconv(map_from_utf8, (char **)&src, &srclen,
- &destptr, &outBytesLeft);
- *destptr = '\0';
+
+ iconv(map_from_utf8, (char **)&src, &srclen, &destptr, &outBytesLeft);
+ *destptr = '\0';
_cupsMutexUnlock(&map_mutex);
variable that should be passed to child processes.</P>
-<H2 CLASS="title"><A NAME="SSLOptions">SSLOptions</A></H2>
+<H2 CLASS="title"><A NAME="SSLListen">SSLListen</A></H2>
<H3>Examples</H3>
<PRE CLASS="command">
-SSLOptions 127.0.0.1:443
-SSLOptions 192.0.2.1:443
+SSLListen 127.0.0.1:443
+SSLListen 192.0.2.1:443
</PRE>
<H3>Description</H3>
-<P>The <CODE>SSLOptions</CODE> directive specifies a network
+<P>The <CODE>SSLListen</CODE> directive specifies a network
address and port to listen for secure connections. Multiple
-<CODE>SSLOptions</CODE> directives can be provided to listen on
+<CODE>SSLListen</CODE> directives can be provided to listen on
multiple addresses.</P>
-<P>The <CODE>SSLOptions</CODE> directive is similar to the <A
+<P>The <CODE>SSLListen</CODE> directive is similar to the <A
HREF="#SSLPort"><CODE>SSLPort</CODE></A> directive but allows you
to restrict access to specific interfaces or networks.</P>
int kbytes; /* Size of print file */
int i; /* Looping var */
int lowerpagerange; /* Page range bound */
- const char *ppd; /* PPD keyword for media selection */
int exact; /* Did we have an exact match? */
ipp_attribute_t *media_col, /* media-col attribute */
*media_margin; /* media-*-margin attribute */
if (!ippFindAttribute(con->request, "PageRegion", IPP_TAG_ZERO) &&
!ippFindAttribute(con->request, "PageSize", IPP_TAG_ZERO) &&
- (ppd = _pwgGetPageSize(printer->pwg, con->request, NULL, &exact)) != NULL)
+ _pwgGetPageSize(printer->pwg, con->request, NULL, &exact))
{
if (!exact &&
(media_col = ippFindAttribute(con->request, "media-col",
char cache_name[1024]; /* Cache filename for printer attrs */
- snprintf(cache_name, sizeof(cache_name), "%s/%s.ipp2", CacheDir,
+ snprintf(cache_name, sizeof(cache_name), "%s/%s.ipp3", CacheDir,
printer->name);
unlink(cache_name);
- snprintf(cache_name, sizeof(cache_name), "%s/%s.pwg", CacheDir,
+ snprintf(cache_name, sizeof(cache_name), "%s/%s.pwg2", CacheDir,
printer->name);
unlink(cache_name);
{
for (i = 0; i < job_ids->num_values; i ++)
{
- if ((job = cupsdFindJob(job_ids->values[i].integer)) == NULL)
+ if (!cupsdFindJob(job_ids->values[i].integer))
break;
}
ipp_attribute_t *uri) /* I - Printer URI */
{
cupsd_job_t *job; /* Job */
- cupsd_printer_t *printer; /* Printer */
ipp_attribute_t *attr; /* Attribute */
char job_uri[HTTP_MAX_URI],
/* Job URI */
return;
}
- printer = cupsdFindDest(job->dest);
-
/*
* See if the job is owned by the requesting user...
*/
printer->name);
unlink(filename);
- snprintf(filename, sizeof(filename), "%s/%s.ipp2", CacheDir, printer->name);
+ snprintf(filename, sizeof(filename), "%s/%s.ipp3", CacheDir, printer->name);
unlink(filename);
- snprintf(filename, sizeof(filename), "%s/%s.pwg", CacheDir, printer->name);
+ snprintf(filename, sizeof(filename), "%s/%s.pwg2", CacheDir, printer->name);
unlink(filename);
#ifdef __APPLE__
for (i = 0; i < job_ids->num_values; i ++)
{
- if ((job = cupsdFindJob(job_ids->values[i].integer)) == NULL)
+ if (!cupsdFindJob(job_ids->values[i].integer))
break;
}
num_pwgppds = cupsAddOption(pwg->sides_option, pwg->sides_2sided_short,
num_pwgppds, &pwgppds);
}
- }
-
- if (!ippFindAttribute(job->attrs, "InputSlot", IPP_TAG_ZERO) &&
- (ppd = _pwgGetInputSlot(job->printer->pwg, job->attrs, NULL)) != NULL)
- num_pwgppds = cupsAddOption("InputSlot", ppd, num_pwgppds, &pwgppds);
- if (!ippFindAttribute(job->attrs, "MediaType", IPP_TAG_ZERO) &&
- (ppd = _pwgGetMediaType(job->printer->pwg, job->attrs, NULL)) != NULL)
- num_pwgppds = cupsAddOption("MediaType", ppd, num_pwgppds, &pwgppds);
-
- if (!ippFindAttribute(job->attrs, "PageRegion", IPP_TAG_ZERO) &&
- !ippFindAttribute(job->attrs, "PageSize", IPP_TAG_ZERO) &&
- (ppd = _pwgGetPageSize(job->printer->pwg, job->attrs, NULL,
- &exact)) != NULL)
- num_pwgppds = cupsAddOption("PageSize", ppd, num_pwgppds, &pwgppds);
+ if (!ippFindAttribute(job->attrs, "InputSlot", IPP_TAG_ZERO) &&
+ !ippFindAttribute(job->attrs, "HPPaperSource", IPP_TAG_ZERO))
+ {
+ if ((ppd = _pwgGetInputSlot(pwg, job->attrs, NULL)) != NULL)
+ num_pwgppds = cupsAddOption(pwg->source_option, ppd, num_pwgppds,
+ &pwgppds);
+ else if (!ippFindAttribute(job->attrs, "AP_D_InputSlot", IPP_TAG_ZERO))
+ num_pwgppds = cupsAddOption("AP_D_InputSlot", "", num_pwgppds,
+ &pwgppds);
+ }
- if (!ippFindAttribute(job->attrs, "OutputBin", IPP_TAG_ZERO) &&
- (attr = ippFindAttribute(job->attrs, "output-bin",
- IPP_TAG_ZERO)) != NULL &&
- (attr->value_tag == IPP_TAG_KEYWORD || attr->value_tag == IPP_TAG_NAME) &&
- (ppd = _pwgGetOutputBin(pwg, attr->values[0].string.text)) != NULL)
- num_pwgppds = cupsAddOption("OutputBin", ppd, num_pwgppds, &pwgppds);
+ if (!ippFindAttribute(job->attrs, "MediaType", IPP_TAG_ZERO) &&
+ (ppd = _pwgGetMediaType(pwg, job->attrs, NULL)) != NULL)
+ num_pwgppds = cupsAddOption("MediaType", ppd, num_pwgppds, &pwgppds);
+
+ if (!ippFindAttribute(job->attrs, "PageRegion", IPP_TAG_ZERO) &&
+ !ippFindAttribute(job->attrs, "PageSize", IPP_TAG_ZERO) &&
+ (ppd = _pwgGetPageSize(pwg, job->attrs, NULL, &exact)) != NULL)
+ num_pwgppds = cupsAddOption("PageSize", ppd, num_pwgppds, &pwgppds);
+
+ if (!ippFindAttribute(job->attrs, "OutputBin", IPP_TAG_ZERO) &&
+ (attr = ippFindAttribute(job->attrs, "output-bin",
+ IPP_TAG_ZERO)) != NULL &&
+ (attr->value_tag == IPP_TAG_KEYWORD ||
+ attr->value_tag == IPP_TAG_NAME) &&
+ (ppd = _pwgGetOutputBin(pwg, attr->values[0].string.text)) != NULL)
+ num_pwgppds = cupsAddOption("OutputBin", ppd, num_pwgppds, &pwgppds);
+ }
/*
* Figure out how much room we need...
if (!attr->values[i].boolean)
strlcat(optptr, "no", optlength - (optptr - options));
+ strlcat(optptr, attr->name,
+ optlength - (optptr - options));
+ break;
+
case IPP_TAG_RANGE :
if (attr->values[i].range.lower == attr->values[i].range.upper)
snprintf(optptr, optlength - (optptr - options) - 1,
/*
* "$Id: printers.c 7968 2008-09-19 23:03:01Z mike $"
*
- * Printer routines for the Common UNIX Printing System (CUPS).
+ * Printer routines for the CUPS scheduler.
*
* Copyright 2007-2010 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
* Check to see if the cache is up-to-date...
*/
- snprintf(cache_name, sizeof(cache_name), "%s/%s.ipp2", CacheDir, p->name);
+ snprintf(cache_name, sizeof(cache_name), "%s/%s.ipp3", CacheDir, p->name);
if (stat(cache_name, &cache_info))
cache_info.st_mtime = 0;
- snprintf(pwg_name, sizeof(pwg_name), "%s/%s.pwg", CacheDir, p->name);
+ snprintf(pwg_name, sizeof(pwg_name), "%s/%s.pwg2", CacheDir, p->name);
if (stat(pwg_name, &pwg_info))
pwg_info.st_mtime = 0;
ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
"output-bin-default", NULL, p->pwg->bins[0].pwg);
}
- else if ((ppd_attr = ppdFindAttr(ppd, "DefaultOutputOrder",
+ else if (((ppd_attr = ppdFindAttr(ppd, "DefaultOutputOrder",
NULL)) != NULL &&
- !strcasecmp(ppd_attr->value, "Reverse"))
+ !strcasecmp(ppd_attr->value, "Reverse")) ||
+ (!ppd_attr && ppd->manufacturer && /* EPSON "compatibility heuristic" */
+ !strcasecmp(ppd->manufacturer, "epson")))
{
+ /*
+ * Report that this printer has a single output bin that leaves pages face
+ * up.
+ */
+
ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
"output-bin-supported", NULL, "face-up");
ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
<DIV CLASS="indent">{?which_jobs=?:<FORM ACTION="{?printer_name=?/jobs:{printer_uri_supported}}" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Mostra stampe attive"></FORM>}
-{?which_jobs=completed?:<FORM ACTION="{?printer_name=?/jobs:{printer_uri_supported}}" METHOD="GET"><INPUT TYPE="HIDDEN" NAME="which_jobs" VALUE="completate"><INPUT TYPE="SUBMIT" VALUE="Mostra stampe completate"></FORM>}
-{?which_jobs=all?:<FORM ACTION="{?printer_name=?/jobs:{printer_uri_supported}}" METHOD="GET"><INPUT TYPE="HIDDEN" NAME="which_jobs" VALUE="tutte"><INPUT TYPE="SUBMIT" VALUE="Mostra tutte le stampe"></FORM>}</DIV>
+{?which_jobs=completed?:<FORM ACTION="{?printer_name=?/jobs:{printer_uri_supported}}" METHOD="GET"><INPUT TYPE="HIDDEN" NAME="which_jobs" VALUE="completed"><INPUT TYPE="SUBMIT" VALUE="Mostra stampe completate"></FORM>}
+{?which_jobs=all?:<FORM ACTION="{?printer_name=?/jobs:{printer_uri_supported}}" METHOD="GET"><INPUT TYPE="HIDDEN" NAME="which_jobs" VALUE="all"><INPUT TYPE="SUBMIT" VALUE="Mostra tutte le stampe"></FORM>}</DIV>
<P ALIGN="CENTER">{total=0?Nessuna stampa:Mostrat{total=1?a:e} {#job_id} di {total} stamp{total=1?a:e} {?which_jobs=?attiva:{which_jobs=all?:completata}} }.</P>